+ aSrcDstNormals[0].Reverse();
+ }
+ if (hasNormal[1]) {
+ aClassifier.Load(aDestShape);
+ gp_Pnt aPoint = aSrcDstPoints[1];
+ aPoint.Translate(aSrcDstNormals[1] * aTransStep);
+ aClassifier.Perform(aPoint, Precision::Confusion());
+ if (aClassifier.State() == TopAbs_IN)
+ aSrcDstNormals[1].Reverse();
+ }
+
+ // Calculate directions, which comply the normal, for vertices and edges
+ if (!hasNormal[0] || !hasNormal[1]) {
+ if (hasNormal[0] || hasNormal[1]) { // plane with line or vertex
+ if (hasDirection[0] || hasDirection[1]) { // plane - line
+ int anInd = hasDirection[0] ? 0 : 1;
+ gp_Vec aVec = aSrcDstNormals[1 - anInd].Crossed(aSrcDstDirections[anInd]);
+ if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // normal and direction are collinear
+ aVec = aSrcDstNormals[1 - anInd].Crossed(
+ gp_Vec(aSrcDstPoints[1 - anInd], aSrcDstPoints[anInd]));
+ if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // normal and points direction are collinear
+ if (Abs(aSrcDstNormals[1 - anInd].Y()) >= Precision::Confusion() ||
+ Abs(aSrcDstNormals[1 - anInd].Z()) >= Precision::Confusion())
+ aVec = gp::DX();
+ else
+ aVec = gp::DY();
+ }
+ }
+ aSrcDstNormals[anInd] = aSrcDstDirections[anInd].Crossed(aVec).Normalized();
+ } else { // plane - point
+ int anInd = hasNormal[0] ? 1 : 0;
+ aSrcDstNormals[anInd] = aSrcDstNormals[1 - anInd];
+ }
+ } else {
+ if (hasDirection[0] && hasDirection[1]) { // line - line
+ gp_Vec aVec = aSrcDstDirections[0].Crossed(aSrcDstDirections[1]);
+ if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // lines are parallel
+ aVec = aSrcDstDirections[0].Crossed(gp_Vec(aSrcDstPoints[0], aSrcDstPoints[1]));
+ if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // lines are equal
+ if (Abs(aSrcDstDirections[0].Y()) >= Precision::Confusion() ||
+ Abs(aSrcDstDirections[0].Z()) >= Precision::Confusion())
+ aVec = gp::DX();
+ else
+ aVec = gp::DY();
+ }
+ }
+ aSrcDstNormals[0] = aSrcDstDirections[0].Crossed(aVec);
+ aSrcDstNormals[0].Normalize();
+ aSrcDstNormals[1] = aSrcDstDirections[1].Crossed(aVec);
+ aSrcDstNormals[1].Normalize();
+ if (aSrcDstDirections[0].Dot(aSrcDstDirections[1]) < -Precision::Confusion())
+ aSrcDstNormals[1].Reverse();
+ } else if (!hasDirection[0] && !hasDirection[1]) { // point - point
+ aSrcDstNormals[0] = gp_Vec(aSrcDstPoints[0], aSrcDstPoints[1]);
+ aSrcDstNormals[0].Normalize();
+ aSrcDstNormals[1] = -aSrcDstNormals[0];
+ } else { // line - point
+ int anInd = hasDirection[0] ? 0 : 1;
+ gp_Vec aVec(aSrcDstPoints[anInd], aSrcDstPoints[1 - anInd]);
+ aVec.Cross(aSrcDstDirections[anInd]);
+ if (aVec.SquareMagnitude() < Precision::SquareConfusion()) { // point is on line
+ if (Abs(aSrcDstDirections[1 - anInd].Y()) >= Precision::Confusion() ||
+ Abs(aSrcDstDirections[1 - anInd].Z()) >= Precision::Confusion())
+ aVec = gp::DX();
+ else
+ aVec = gp::DY();
+ }
+ aSrcDstNormals[anInd] = aSrcDstDirections[anInd].Crossed(aVec).Normalized();
+ aSrcDstNormals[1 - anInd] = aSrcDstNormals[anInd];
+ }
+ }
+ }
+
+ // Reverse the normal if it was not done before
+ if (!hasNormal[0] && theIsReverse)
+ aSrcDstNormals[0].Reverse();
+
+ // Calculate transformation
+ gp_Trsf aTrsf;
+ gp_Vec aSrcDir = aSrcDstNormals[0];
+ gp_Vec aDstDir = aSrcDstNormals[1];