Salome HOME
Fix the problem of the sketch plane update
[modules/shaper.git] / src / Model / Model_ResultConstruction.cpp
index 103c5425904bf65d8e8bb299ee2a43c6f5bda36b..272cb7338a24527bc298cd3b8807e42d9544fce8 100644 (file)
 #include <Model_Data.h>
 #include <ModelAPI_CompositeFeature.h>
 #include <GeomAlgoAPI_SketchBuilder.h>
+#include <GeomAPI_Tools.h>
 #include <ModelAPI_Events.h>
 #include <Model_Document.h>
 #include <GeomAPI_PlanarEdges.h>
 #include <GeomAPI_Shape.h>
 #include <Events_Loop.h>
+#include <GeomDataAPI_Point.h>
+#include <GeomDataAPI_Dir.h>
 
 #include <TDF_ChildIDIterator.hxx>
 #include <TNaming_NamedShape.hxx>
@@ -52,7 +55,6 @@ Standard_GUID kIS_INFINITE("dea8cc5a-53f2-49c1-94e8-a947bed20a9f");
 // identifier of the result not in history
 Standard_GUID kIS_IN_HISTORY("a9aec01c-805e-44d1-b5d2-a63f06522f8a");
 
-
 void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::string& theName,
                                        std::string& theDefault)
 {
@@ -64,8 +66,7 @@ void Model_ResultConstruction::colorConfigInfo(std::string& theSection, std::str
 void Model_ResultConstruction::setShape(std::shared_ptr<GeomAPI_Shape> theShape)
 {
   if (myShape != theShape) {
-    if (!isInfinite())
-      storeShape(theShape);
+    storeShape(theShape);
     if (!theShape.get() || !theShape->isEqual(myShape)) {
       static const Events_ID anEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
       ModelAPI_EventCreator::get()->sendUpdated(data()->owner(), anEvent);
@@ -88,7 +89,7 @@ static std::string shortName(
   aName.erase(std::remove(aName.begin(), aName.end(), '/'), aName.end());
   aName.erase(std::remove(aName.begin(), aName.end(), '&'), aName.end());
   // remove the last 's', 'e', 'f' and 'r' symbols:
-  // they are used as markers of start/end/forward/rewersed indicators
+  // they are used as markers of start/end/forward/reversed indicators
   static const std::string aSyms("sefr");
   std::string::iterator aSuffix = aName.end() - 1;
   while(aSyms.find(*aSuffix) != std::string::npos) {
@@ -98,7 +99,6 @@ static std::string shortName(
   return aName;
 }
 
-
 bool Model_ResultConstruction::updateShape()
 {
   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
@@ -108,9 +108,28 @@ bool Model_ResultConstruction::updateShape()
     if (aShapeLab.FindAttribute(TNaming_NamedShape::GetID(), aNS)) {
       TopoDS_Shape aShape = aNS->Get();
       if (!aShape.IsNull()) {
+        if (aShape.ShapeType() == TopAbs_COMPOUND) {
+          // restore the sketch planar edges object
+          std::shared_ptr<GeomAPI_PlanarEdges> aBigWire(new GeomAPI_PlanarEdges);
+          aBigWire->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
+          FeaturePtr aSketch =
+            document()->feature(std::dynamic_pointer_cast<ModelAPI_Result>(data()->owner()));
+          std::shared_ptr<GeomDataAPI_Point> anOrigin =
+            std::dynamic_pointer_cast<GeomDataAPI_Point>(aSketch->data()->attribute("Origin"));
+          std::shared_ptr<GeomDataAPI_Dir> aDirX =
+            std::dynamic_pointer_cast<GeomDataAPI_Dir>(aSketch->data()->attribute("DirX"));
+          std::shared_ptr<GeomDataAPI_Dir> aNorm =
+            std::dynamic_pointer_cast<GeomDataAPI_Dir>(aSketch->data()->attribute("Norm"));
+          if (anOrigin.get() && aDirX.get() && aNorm.get()) {
+            aBigWire->setPlane(anOrigin->pnt(), aDirX->dir(), aNorm->dir());
+            myShape = aBigWire;
+            return true;
+          }
+        }
+        // just restore shape
         GeomShapePtr aGShape(new GeomAPI_Shape);
         aGShape->setImpl<TopoDS_Shape>(new TopoDS_Shape(aShape));
-        myShape = aGShape; // restore the sketch sub-components
+        myShape = GeomAPI_Tools::getTypedShape(aGShape); // restore the sketch sub-components
         return true;
       }
     }
@@ -217,7 +236,7 @@ void Model_ResultConstruction::storeShape(std::shared_ptr<GeomAPI_Shape> theShap
     std::shared_ptr<Model_Document> aMyDoc =
       std::dynamic_pointer_cast<Model_Document>(document());
     const TopoDS_Shape& aShape = theShape->impl<TopoDS_Shape>();
-    if (aShape.ShapeType() == TopAbs_VERTEX) {
+    if (isInfinite() || aShape.ShapeType() == TopAbs_VERTEX) {
       aShapeLab.ForgetAllAttributes(); // clear all previously stored
       TNaming_Builder aBuilder(aShapeLab);
       aBuilder.Generated(aShape);
@@ -376,7 +395,7 @@ void Model_ResultConstruction::storeShape(std::shared_ptr<GeomAPI_Shape> theShap
           std::stringstream aName;
           aName<<"Face";
           TopExp_Explorer aPutEdges(aFaceToPut, TopAbs_EDGE);
-          TNaming_Builder* anEdgesBuilder = 0;
+          TNaming_Builder *anEdgesBuilder = 0, *aVerticesBuilder = 0;
           for(TColStd_ListOfInteger::Iterator anIter(aNewInd); anIter.More(); anIter.Next()) {
             int anIndex = anIter.Value();
             int aModIndex = anIndex > 0 ? anIndex : -anIndex;
@@ -393,26 +412,49 @@ void Model_ResultConstruction::storeShape(std::shared_ptr<GeomAPI_Shape> theShap
                 TDF_Label anEdgesLabel = aLab.FindChild(1);
                 anEdgesBuilder = new TNaming_Builder(anEdgesLabel);
                 std::ostringstream aSubName;
-                // tag is needed for Test1922 to distinguish subedges of different faces
+                // tag is needed for Test1922 to distinguish sub-edges of different faces
                 aSubName<<"SubEdge_"<<aCurrentTag;
                 TDataStd_Name::Set(anEdgesLabel, aSubName.str().c_str());
               }
               anEdgesBuilder->Modify(anEdgeIndices.Find(aModIndex), aPutEdges.Current());
             }
+            // put also modified vertices, otherwise vertex of original edge has no history
+            if (anEdgeIndices.IsBound(aModIndex)) {
+              TopExp_Explorer aVExpOld(anEdgeIndices.Find(aModIndex), TopAbs_VERTEX);
+              TopExp_Explorer aVExpNew(aPutEdges.Current(), TopAbs_VERTEX);
+              for(; aVExpNew.More() && aVExpOld.More(); aVExpNew.Next(), aVExpOld.Next()) {
+                if (!aVExpOld.Current().IsSame(aVExpNew.Current())) {
+                  if (!aVerticesBuilder) {
+                    TDF_Label aVertLabel = aLab.FindChild(2);
+                    aVerticesBuilder = new TNaming_Builder(aVertLabel);
+                    std::ostringstream aSubName;
+                    // tag is needed for Test1922 to distinguish sub-edges of different faces
+                    aSubName<<"SubVertex_"<<aCurrentTag;
+                    TDataStd_Name::Set(aVertLabel, aSubName.str().c_str());
+                  }
+                  aVerticesBuilder->Modify(aVExpOld.Current(), aVExpNew.Current());
+
+                }
+              }
+            }
             aPutEdges.Next();
           }
+          if (anEdgesBuilder)
+            delete anEdgesBuilder;
+          if (aVerticesBuilder)
+            delete aVerticesBuilder;
           TDataStd_Name::Set(aLab, TCollection_ExtendedString(aName.str().c_str()));
           aMyDoc->addNamingName(aLab, aName.str());
           // put also wires to sub-labels to correctly select them instead of collection by edges
-          int aWireTag = 2; // first tag is for SubEdge-s
+          int aWireTag = 3; // first tag is for SubEdge-s, second - for vertices
           for(TopExp_Explorer aWires(aFaceToPut, TopAbs_WIRE); aWires.More(); aWires.Next()) {
             TDF_Label aWireLab = aLab.FindChild(aWireTag);
             TNaming_Builder aWireBuilder(aWireLab);
             aWireBuilder.Generated(aWires.Current());
             std::ostringstream aWireName;
             aWireName<<aName.str()<<"_wire";
-            if (aWireTag > 2)
-              aWireName<<"_"<<aWireTag - 1;
+            if (aWireTag > 3)
+              aWireName<<"_"<<aWireTag - 2;
             TDataStd_Name::Set(aWireLab, aWireName.str().c_str());
             aMyDoc->addNamingName(aWireLab, aWireName.str());
             aWireTag++;