Salome HOME
Issue #1315 Middle point constraint problem
[modules/shaper.git] / src / Model / Model_BodyBuilder.cpp
index 0efc177974662432e046e31a3bcbb562d2f2456c..1d3b8a4d506d48ef85e711e995ad7c75e8568f93 100755 (executable)
 #include <TNaming_Builder.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TNaming_Iterator.hxx>
+#include <TNaming_Tool.hxx>
 #include <TDataStd_Name.hxx>
 #include <TDataStd_Integer.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Face.hxx>
 #include <TDF_ChildIterator.hxx>
+#include <TDF_Reference.hxx>
 #include <TopTools_MapOfShape.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListOfShape.hxx>
@@ -77,7 +79,7 @@ static void evolutionToSelectionRec(TDF_Label theLab, const bool theFlag) {
   std::list<std::pair<TopoDS_Shape, TopoDS_Shape> >::iterator aPairsIter = aShapePairs.begin();
   for(; aPairsIter != aShapePairs.end(); aPairsIter++) {
     if (theFlag) { // disabled => make selection
-      aBuilder.Select(aPairsIter->first, aPairsIter->second);
+      aBuilder.Select(aPairsIter->second, aPairsIter->first);
     } else if (anEvol == TNaming_GENERATED) {
       aBuilder.Generated(aPairsIter->first, aPairsIter->second);
     } else if (anEvol == TNaming_MODIFY) {
@@ -86,6 +88,8 @@ static void evolutionToSelectionRec(TDF_Label theLab, const bool theFlag) {
       aBuilder.Delete(aPairsIter->first);
     } else if (anEvol == TNaming_PRIMITIVE) {
       aBuilder.Generated(aPairsIter->second);
+    } else if (anEvol == TNaming_SELECTED) {
+      aBuilder.Select(aPairsIter->second, aPairsIter->first);
     }
   }
   // recursive call for all sub-labels
@@ -104,7 +108,8 @@ void Model_BodyBuilder::evolutionToSelection(const bool theFlag)
   evolutionToSelectionRec(aShapeLab, theFlag);
 }
 
-void Model_BodyBuilder::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
+void Model_BodyBuilder::store(const std::shared_ptr<GeomAPI_Shape>& theShape,
+                              const bool theIsStoreSameShapes)
 {
   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
   if (aData) {
@@ -119,8 +124,20 @@ void Model_BodyBuilder::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
     if (aShape.IsNull())
       return;  // null shape inside
 
+    if(!theIsStoreSameShapes) {
+      Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aShape, aShapeLab);
+      if(!aNS.IsNull() && !aNS->IsEmpty()) {
+        // This shape is already in document, store reference instead of shape;
+        const TDF_Label aFoundLabel = aNS->Label();
+        TDF_Reference::Set(aShapeLab, aFoundLabel);
+        aShapeLab.ForgetAttribute(TNaming_NamedShape::GetID());
+        return;
+      }
+    }
+
     aBuilder.Generated(aShape);        
     // register name
+    aShapeLab.ForgetAttribute(TDF_Reference::GetID());
     if(!aBuilder.NamedShape()->IsEmpty()) {
       Handle(TDataStd_Name) anAttr;
       if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
@@ -199,11 +216,20 @@ void Model_BodyBuilder::storeModified(const std::shared_ptr<GeomAPI_Shape>& theO
 
       TopoDS_Iterator aSubIter(aShapeNew);
       for(int aTag = theDecomposeSolidsTag; aSubIter.More(); aSubIter.Next()) {
+        const TopoDS_Shape& aShape = aSubIter.Value();
+        Handle(TNaming_NamedShape) aNS = TNaming_Tool::NamedShape(aShape, aShapeLab);
+        if(!aNS.IsNull() && !aNS->IsEmpty()) {
+          // This shape is already in document, don't add it.
+          continue;
+        }
         TNaming_Builder aSubBuilder(aShapeLab.FindChild(aTag++));
         aSubBuilder.Generated(aSubIter.Value());
         if(!aName.IsEmpty()) {
+          TCollection_AsciiString aShapeType = aShape.ShapeType() == TopAbs_EDGE ? "_Edge_" :
+                                               aShape.ShapeType() == TopAbs_FACE ? "_Face_" :
+                                               aShape.ShapeType() == TopAbs_SOLID ? "_Solid_" : "_Shape_";
           std::string aSolidName = 
-            (aName + "_Solid_" + TCollection_AsciiString(aTag - theDecomposeSolidsTag)).ToCString(); 
+            (aName + aShapeType + TCollection_AsciiString(aTag - theDecomposeSolidsTag)).ToCString(); 
           std::shared_ptr<Model_Document> aDoc = 
             std::dynamic_pointer_cast<Model_Document>(document());
           aDoc->addNamingName(aSubBuilder.NamedShape()->Label(), aSolidName);
@@ -213,6 +239,22 @@ void Model_BodyBuilder::storeModified(const std::shared_ptr<GeomAPI_Shape>& theO
     }
   }
 }
+
+void  Model_BodyBuilder::storeWithoutNaming(const std::shared_ptr<GeomAPI_Shape>& theShape)
+{
+  std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
+  if (aData) {
+    clean();   
+    if (!theShape.get())
+      return; // bad shape
+    TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();
+    if (aShape.IsNull())
+      return;  // null shape inside
+    TNaming_Builder aBuilder(aData->shapeLab());
+    aBuilder.Select(aShape, aShape);
+  }
+}
+
 void Model_BodyBuilder::clean()
 {
   std::vector<TNaming_Builder*>::iterator aBuilder = myBuilders.begin();
@@ -310,8 +352,13 @@ void Model_BodyBuilder::loadAndOrientModifiedShapes (
   const int  theKindOfShape,
   const int  theTag,
   const std::string& theName,
-  GeomAPI_DataMapOfShapeShape& theSubShapes)
+  GeomAPI_DataMapOfShapeShape& theSubShapes,
+  const bool theIsStoreSeparate)
 {
+  int aTag = theTag;
+  std::string aName = theName;
+  std::ostringstream aStream;
+  int anIndex = 1;
   TopoDS_Shape aShapeIn = theShapeIn->impl<TopoDS_Shape>();
   TopTools_MapOfShape aView;
   bool isBuilt = theName.empty();
@@ -331,9 +378,19 @@ void Model_BodyBuilder::loadAndOrientModifiedShapes (
         aNewShape.Orientation(aMapShape->impl<TopoDS_Shape>().Orientation());
       }
       if (!aRoot.IsSame (aNewShape)) {
-        builder(theTag)->Modify(aRoot,aNewShape);
-        if(!isBuilt) 
-          buildName(theTag, theName);          
+        builder(aTag)->Modify(aRoot,aNewShape);
+        if(!isBuilt) {
+          if(theIsStoreSeparate) {
+            aStream.str(std::string());
+            aStream.clear();
+            aStream << theName << "_" << anIndex++;
+            aName = aStream.str();
+          }
+          buildName(aTag, aName);
+        }
+        if(theIsStoreSeparate) {
+          aTag++;
+        }
       }
     }
   }
@@ -728,7 +785,11 @@ std::shared_ptr<GeomAPI_Shape> Model_BodyBuilder::shape()
 {
   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
   if (aData) {
-    TDF_Label& aShapeLab = aData->shapeLab();
+    TDF_Label aShapeLab = aData->shapeLab();
+    Handle(TDF_Reference) aRef;
+    if (aShapeLab.FindAttribute(TDF_Reference::GetID(), aRef)) {
+      aShapeLab = aRef->Get();
+    }
     Handle(TNaming_NamedShape) aName;
     if (aShapeLab.FindAttribute(TNaming_NamedShape::GetID(), aName)) {
       TopoDS_Shape aShape = aName->Get();
@@ -741,3 +802,28 @@ std::shared_ptr<GeomAPI_Shape> Model_BodyBuilder::shape()
   }
   return std::shared_ptr<GeomAPI_Shape>();
 }
+
+bool Model_BodyBuilder::isLatestEqual(const std::shared_ptr<GeomAPI_Shape>& theShape)
+{
+  if (theShape.get()) {
+    TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();  
+    std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
+    if (aData) {
+      TDF_Label& aShapeLab = aData->shapeLab();
+      Handle(TNaming_NamedShape) aName;
+      if (aShapeLab.FindAttribute(TNaming_NamedShape::GetID(), aName)) {
+        TopoDS_Shape aLatest = TNaming_Tool::CurrentShape(aName);
+        if (aLatest.IsNull())
+          return false;
+        if (aLatest.IsEqual(aShape))
+          return true;
+        // check sub-shapes for comp-solids:
+        for (TopExp_Explorer anExp(aShape, aLatest.ShapeType()); anExp.More(); anExp.Next()) {
+          if (aLatest.IsEqual(anExp.Current()))
+            return true;
+        }
+      }
+    }
+  }
+  return false;
+}