Salome HOME
Increase sensitivity for vertexes selection
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Placement.cpp
index 9933454463b8291eeb282c427c6cda2f7708dcc0..4e29cdb305d6df989964137f3b9a8ecbba547c9d 100644 (file)
 #include <BRepGProp.hxx>
 #include <Precision.hxx>
 
-#define DEB_PLACEMENT 1
 GeomAlgoAPI_Placement::GeomAlgoAPI_Placement(
-    std::shared_ptr<GeomAPI_Shape> theSourceSolid,
-    std::shared_ptr<GeomAPI_Shape> theDestSolid,
-    std::shared_ptr<GeomAPI_Shape> theSourceShape,
-    std::shared_ptr<GeomAPI_Shape> theDestShape,
-    bool theIsReverse,
-    bool theIsCentering)
+  std::shared_ptr<GeomAPI_Shape> theSourceSolid,
+  std::shared_ptr<GeomAPI_Shape> theDestSolid,
+  std::shared_ptr<GeomAPI_Shape> theSourceShape,
+  std::shared_ptr<GeomAPI_Shape> theDestShape,
+  bool theIsReverse,
+  bool theIsCentering, 
+  bool theSimpleTransform)
   : myDone(false),
-    myShape(new GeomAPI_Shape())
+  myShape(new GeomAPI_Shape())
 {
-  build(theSourceSolid, theDestSolid, theSourceShape, theDestShape, theIsReverse, theIsCentering);
+  build(theSourceSolid, theDestSolid, theSourceShape, theDestShape, 
+    theIsReverse, theIsCentering, theSimpleTransform);
 }
 
 void GeomAlgoAPI_Placement::build(
-    const std::shared_ptr<GeomAPI_Shape>& theSourceSolid,
-    const std::shared_ptr<GeomAPI_Shape>& theDestSolid,
-    const std::shared_ptr<GeomAPI_Shape>& theSourceShape,
-    const std::shared_ptr<GeomAPI_Shape>& theDestShape,
-    bool theIsReverse,
-    bool theIsCentering)
+  const std::shared_ptr<GeomAPI_Shape>& theSourceSolid,
+  const std::shared_ptr<GeomAPI_Shape>& theDestSolid,
+  const std::shared_ptr<GeomAPI_Shape>& theSourceShape,
+  const std::shared_ptr<GeomAPI_Shape>& theDestShape,
+  bool theIsReverse,
+  bool theIsCentering,
+  bool theSimpleTransform)
 {
   // Filling the parameters of the objects
   static const int aNbObjects = 2;
@@ -94,7 +96,7 @@ void GeomAlgoAPI_Placement::build(
     aPoint.Translate(aSrcDstNormals[0] * aTransStep);
     aClassifier.Perform(aPoint, Precision::Confusion());
     if ((aClassifier.State() == TopAbs_OUT && !theIsReverse) ||
-        (aClassifier.State() == TopAbs_IN && theIsReverse))
+      (aClassifier.State() == TopAbs_IN && theIsReverse))
       aSrcDstNormals[0].Reverse();
   }
   if (hasNormal[1]) {
@@ -114,10 +116,10 @@ void GeomAlgoAPI_Placement::build(
         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]));
+            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())
+              Abs(aSrcDstNormals[1 - anInd].Z()) >= Precision::Confusion())
               aVec = gp::DX();
             else
               aVec = gp::DY();
@@ -135,7 +137,7 @@ void GeomAlgoAPI_Placement::build(
           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())
+              Abs(aSrcDstDirections[0].Z()) >= Precision::Confusion())
               aVec = gp::DX();
             else
               aVec = gp::DY();
@@ -157,7 +159,7 @@ void GeomAlgoAPI_Placement::build(
         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())
+            Abs(aSrcDstDirections[1 - anInd].Z()) >= Precision::Confusion())
             aVec = gp::DX();
           else
             aVec = gp::DY();
@@ -176,8 +178,6 @@ void GeomAlgoAPI_Placement::build(
   gp_Trsf aTrsf;
   gp_Vec aSrcDir = aSrcDstNormals[0];
   gp_Vec aDstDir = aSrcDstNormals[1];
-  gp_Vec aSrcDir = aSrcDstNormals[0];
-  gp_Vec aDstDir = aSrcDstNormals[1];
   // Calculate rotation
   gp_Quaternion aRot(aSrcDir, aDstDir);
   aTrsf.SetRotation(aRot);
@@ -190,27 +190,31 @@ void GeomAlgoAPI_Placement::build(
   gp_Vec aTrans = aDstLoc - aSrcLoc;
   aTrsf.SetTransformation(aRot, aTrans);
 
-  // Transform the shape with copying it
-  BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
-  if(aBuilder) {
-    setImpl(aBuilder);
-    myDone = aBuilder->IsDone() == Standard_True;
-    if (myDone) {
-      TopoDS_Shape aResult = aBuilder->Shape();
-      // fill data map to keep correct orientation of sub-shapes 
-      for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
-        std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
-        aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
-        myMap.bind(aCurrentShape, aCurrentShape);
+  if (theSimpleTransform) { // just add transformation
+    TopLoc_Location aDelta(aTrsf);
+    TopoDS_Shape aResult = aSourceShape.Moved(aDelta);
+    myShape->setImpl(new TopoDS_Shape(aResult));
+    // store the accumulated information about the result and this delta
+    //myTrsf = std::shared_ptr<GeomAPI_Trsf>(new GeomAPI_Trsf(new gp_Trsf(aTrsf * aSourceShape.Location().Transformation())));
+    myTrsf = std::shared_ptr<GeomAPI_Trsf>(new GeomAPI_Trsf(new gp_Trsf(aTrsf)));
+    myDone = true; // it is allways true for simple transformation generation
+  } else { // internal rebuild of the shape
+    // Transform the shape with copying it
+    BRepBuilderAPI_Transform* aBuilder = new BRepBuilderAPI_Transform(aSourceShape, aTrsf, true);
+    if(aBuilder) {
+      setImpl(aBuilder);
+      myDone = aBuilder->IsDone() == Standard_True;
+      if (myDone) {
+        TopoDS_Shape aResult = aBuilder->Shape();
+        // fill data map to keep correct orientation of sub-shapes 
+        for (TopExp_Explorer Exp(aResult,TopAbs_FACE); Exp.More(); Exp.Next()) {
+          std::shared_ptr<GeomAPI_Shape> aCurrentShape(new GeomAPI_Shape());
+          aCurrentShape->setImpl(new TopoDS_Shape(Exp.Current()));
+          myMap.bind(aCurrentShape, aCurrentShape);
+        }
+        myShape->setImpl(new TopoDS_Shape(aResult));
+        myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
       }
-#ifdef DEB_PLACEMENT
-         int aNum = myMap.size();
-         cout << "MAP of Oriented shapes =" << aNum <<endl;
-
-#endif
-
-      myShape->setImpl(new TopoDS_Shape(aResult));
-      myMkShape = new GeomAlgoAPI_MakeShape (aBuilder);
     }
   }
 }
@@ -218,8 +222,11 @@ void GeomAlgoAPI_Placement::build(
 //============================================================================
 const bool GeomAlgoAPI_Placement::isValid() const
 {
-  BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
-  return (aChecker.IsValid() == Standard_True);
+  if (myShape.get()) { // only for not-simple transform
+    BRepCheck_Analyzer aChecker(myShape->impl<TopoDS_Shape>());
+    return (aChecker.IsValid() == Standard_True);
+  }
+  return true;
 }
 
 //============================================================================
@@ -254,9 +261,14 @@ GeomAlgoAPI_MakeShape * GeomAlgoAPI_Placement::makeShape() const
   return myMkShape;
 }
 
+std::shared_ptr<GeomAPI_Trsf> GeomAlgoAPI_Placement::transformation() const
+{
+  return myTrsf;
+}
+
 //============================================================================
 GeomAlgoAPI_Placement::~GeomAlgoAPI_Placement()
 {
-  if (myImpl)
+  if (!empty())
     myMap.clear();
-}
\ No newline at end of file
+}