Salome HOME
Implementation of color as integer array attribute
[modules/shaper.git] / src / Model / Model_ResultBody.cpp
index c958e6239fb22b92edfd0dde7cfa5f794301b2c9..7b7e3c3be3a8eab1722a97f0a049137e33274161 100644 (file)
@@ -7,6 +7,7 @@
 #include <Model_ResultBody.h>
 #include <Model_Data.h>
 #include <Model_Document.h>
+#include <ModelAPI_AttributeIntArray.h>
 #include <TNaming_Builder.hxx>
 #include <TNaming_NamedShape.hxx>
 #include <TDataStd_Name.hxx>
 #include <TopTools_DataMapOfShapeShape.hxx>
 #include <TopExp.hxx>
 #include <BRepTools.hxx>
+#include <BRep_Tool.hxx>
 #include <GeomAPI_Shape.h>
 #include <GeomAlgoAPI_MakeShape.h>
+#include <Config_PropManager.h>
 // DEB
 //#include <TCollection_AsciiString.hxx>
 //#include <TDF_Tool.hxx>
+//#define DEB_IMPORT 1
+
+#define RESULT_BODY_COLOR "#E0A01B"
+
 Model_ResultBody::Model_ResultBody()
 {
   setIsConcealed(false);
 }
 
+void Model_ResultBody::initAttributes()
+{
+  // append the color attribute
+  DataPtr aData = data();
+  aData->addAttribute(COLOR_ID(), ModelAPI_AttributeIntArray::type());
+  AttributeIntArrayPtr aColorAttr = aData->intArray(COLOR_ID());
+  std::vector<int> aRGB;
+  aRGB = Config_PropManager::color("Visualization", "result_body_color", RESULT_BODY_COLOR);
+  aColorAttr->setSize(3);
+  aColorAttr->setValue(0, aRGB[0]);
+  aColorAttr->setValue(1, aRGB[1]);
+  aColorAttr->setValue(2, aRGB[2]);
+}
+
 void Model_ResultBody::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
 {
   std::shared_ptr<Model_Data> aData = std::dynamic_pointer_cast<Model_Data>(data());
@@ -53,6 +74,17 @@ void Model_ResultBody::store(const std::shared_ptr<GeomAPI_Shape>& theShape)
       return;  // null shape inside
 
     aBuilder.Generated(aShape);        
+       // register name
+       if(!aBuilder.NamedShape()->IsEmpty()) {
+         Handle(TDataStd_Name) anAttr;
+         if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+               std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
+               if(!aName.empty()) {
+          std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+          aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
+               }
+         }
+       }
   }
 }
 
@@ -75,6 +107,17 @@ void Model_ResultBody::storeGenerated(const std::shared_ptr<GeomAPI_Shape>& theF
     if (aShapeNew.IsNull())
       return;  // null shape inside
     aBuilder.Generated(aShapeBasis, aShapeNew);
+               // register name
+       if(!aBuilder.NamedShape()->IsEmpty()) {
+         Handle(TDataStd_Name) anAttr;
+         if(aBuilder.NamedShape()->Label().FindAttribute(TDataStd_Name::GetID(),anAttr)) {
+               std::string aName (TCollection_AsciiString(anAttr->Get()).ToCString());
+               if(!aName.empty()) {
+          std::shared_ptr<Model_Document> aDoc = std::dynamic_pointer_cast<Model_Document>(document());
+          aDoc->addNamingName(aBuilder.NamedShape()->Label(), aName);
+               }
+         }
+       }
   }
 }
 
@@ -321,11 +364,13 @@ void Model_ResultBody::loadNextLevels(std::shared_ptr<GeomAPI_Shape> theShape,
   std::string aName;
   if (aShape.ShapeType() == TopAbs_SOLID) {                
     TopExp_Explorer expl(aShape, TopAbs_FACE);
-    for (; expl.More(); expl.Next())      
-         builder(++theTag)->Generated(expl.Current()); 
+    for (; expl.More(); expl.Next()) {  
+         builder(theTag)->Generated(expl.Current()); 
          TCollection_AsciiString aStr(theTag);
          aName = theName + aStr.ToCString();
          buildName(theTag, aName);
+         theTag++;
+       }
   }
   else if (aShape.ShapeType() == TopAbs_SHELL || aShape.ShapeType() == TopAbs_FACE) {
     // load faces and all the free edges
@@ -334,10 +379,11 @@ void Model_ResultBody::loadNextLevels(std::shared_ptr<GeomAPI_Shape> theShape,
     if (Faces.Extent() > 1 || (aShape.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) {
       TopExp_Explorer expl(aShape, TopAbs_FACE);
       for (; expl.More(); expl.Next()) {
-                 builder(++theTag)->Generated(expl.Current());          
+                 builder(theTag)->Generated(expl.Current());          
                  TCollection_AsciiString aStr(theTag);
              aName = theName + aStr.ToCString();
              buildName(theTag, aName);
+                 theTag++;
          }
        }
     TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces;
@@ -346,19 +392,23 @@ void Model_ResultBody::loadNextLevels(std::shared_ptr<GeomAPI_Shape> theShape,
        {
       const TopTools_ListOfShape& aLL = anEdgeAndNeighbourFaces.FindFromIndex(i);
       if (aLL.Extent() < 2) {
-           builder(++theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
+                 if (BRep_Tool::Degenerated(TopoDS::Edge(anEdgeAndNeighbourFaces.FindKey(i))))
+          continue;
+           builder(theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
                TCollection_AsciiString aStr(theTag);
            aName = theName + aStr.ToCString();
            buildName(theTag, aName);
+               theTag++;
       } else {
          TopTools_ListIteratorOfListOfShape anIter(aLL);
          const TopoDS_Face& aFace = TopoDS::Face(anIter.Value());
          anIter.Next();
          if(aFace.IsEqual(anIter.Value())) {
-               builder(++theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
+               builder(theTag)->Generated(anEdgeAndNeighbourFaces.FindKey(i));
                TCollection_AsciiString aStr(theTag);
            aName = theName + aStr.ToCString();
            buildName(theTag, aName);
+           theTag++;
          }
          }
        }
@@ -369,37 +419,83 @@ void Model_ResultBody::loadNextLevels(std::shared_ptr<GeomAPI_Shape> theShape,
          builder(++theTag)->Generated(Edges.FindKey(1));
       TopExp_Explorer expl(aShape, TopAbs_VERTEX);
       for (; expl.More(); expl.Next()) {
-           builder(++theTag)->Generated(expl.Current());
+           builder(theTag)->Generated(expl.Current());
                TCollection_AsciiString aStr(theTag);
            aName = theName + aStr.ToCString();
            buildName(theTag, aName);
+           theTag++;
          }
        } else {
       TopExp_Explorer expl(aShape, TopAbs_EDGE); 
       for (; expl.More(); expl.Next()) {       
-               builder(++theTag)->Generated(expl.Current());
+               builder(theTag)->Generated(expl.Current());
                TCollection_AsciiString aStr(theTag);
            aName = theName + aStr.ToCString();
            buildName(theTag, aName);
+               theTag++;
          }   
       // and load generated vertices.
       TopTools_DataMapOfShapeShape generated;
       if (getDangleShapes(aShape, TopAbs_EDGE, generated)) 
          {
-               TNaming_Builder* pBuilder = builder(++theTag);
+               TNaming_Builder* pBuilder = builder(theTag++);
                loadGeneratedDangleShapes(aShape, TopAbs_EDGE, pBuilder);  
          }
        }
   } else if (aShape.ShapeType() == TopAbs_EDGE) {
     TopExp_Explorer expl(aShape, TopAbs_VERTEX);
     for (; expl.More(); expl.Next()) {      
-               builder(++theTag)->Generated(expl.Current());
+               builder(theTag)->Generated(expl.Current());
                TCollection_AsciiString aStr(theTag);
            aName = theName + aStr.ToCString();
            buildName(theTag, aName);
+               theTag++;
        }
   }
 }
+
+//=======================================================================
+int findAmbiguities(const TopoDS_Shape&           theShapeIn,                                  
+                                         TopTools_ListOfShape&   theList) 
+{
+  int aNumEdges(0);
+  theList.Clear();
+  TopTools_IndexedDataMapOfShapeListOfShape subShapeAndAncestors;
+  TopAbs_ShapeEnum aTS(TopAbs_EDGE);
+  TopAbs_ShapeEnum aTA(TopAbs_FACE);
+  TopTools_MapOfShape aMap1, aMap2; // map1 - for edge ancestors; map2 - for keys => edges
+  TopTools_ListOfShape aKeyList;
+  TopExp::MapShapesAndAncestors(theShapeIn, aTS, aTA, subShapeAndAncestors);
+  for (Standard_Integer i = 1; i <= subShapeAndAncestors.Extent(); i++) {
+    const TopoDS_Shape& aKeyEdge1 = subShapeAndAncestors.FindKey(i);
+    const TopTools_ListOfShape& ancestors1 = subShapeAndAncestors.FindFromIndex(i);
+       aMap1.Clear();
+    TopTools_ListIteratorOfListOfShape it(ancestors1);
+       for(;it.More();it.Next()) aMap1.Add(it.Value()); // fill map with key ancestors => aKey1
+       for (Standard_Integer j = 1; j <= subShapeAndAncestors.Extent(); j++) {
+         if (i == j) continue;
+      const TopoDS_Shape& aKeyEdge2 = subShapeAndAncestors.FindKey(j);
+      const TopTools_ListOfShape& ancestors2 = subShapeAndAncestors.FindFromIndex(j);
+         if(ancestors1.Extent() == ancestors2.Extent() && ancestors1.Extent() > 1) {
+               int aNum (ancestors2.Extent());
+           TopTools_ListIteratorOfListOfShape it(ancestors2);
+           for(;it.More();it.Next()) 
+                       if(aMap1.Contains(it.Value())) aNum--;
+               if(aNum == 0) {
+                 if(aMap2.Add(aKeyEdge1)) 
+                       aKeyList.Append(aKeyEdge1);
+                 if(aMap2.Add(aKeyEdge2))
+                       aKeyList.Append(aKeyEdge2);
+               }
+         }
+       } // at the end ==> List of edges to be named in addition       
+  }
+  aNumEdges = aKeyList.Extent();
+  if(aNumEdges)
+       theList.Assign(aKeyList);       
+  return aNumEdges; 
+}
+
 //=======================================================================
 void Model_ResultBody::loadFirstLevel(
                     std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag)
@@ -409,8 +505,8 @@ void Model_ResultBody::loadFirstLevel(
   std::string aName;
   if (aShape.ShapeType() == TopAbs_COMPOUND || aShape.ShapeType() == TopAbs_COMPSOLID) {
     TopoDS_Iterator itr(aShape);
-    for (; itr.More(); itr.Next()) {
-         builder(++theTag)->Generated(itr.Value());
+    for (; itr.More(); itr.Next(),theTag++) {
+         builder(theTag)->Generated(itr.Value());
          TCollection_AsciiString aStr(theTag);
          aName = theName + aStr.ToCString();
          buildName(theTag, aName);
@@ -432,6 +528,16 @@ void Model_ResultBody::loadFirstLevel(
     itrShape->setImpl(new TopoDS_Shape(aShape));
        loadNextLevels(itrShape, theName, theTag); 
   }
+  TopTools_ListOfShape   aList;
+  if(findAmbiguities(aShape, aList)) {
+       TopTools_ListIteratorOfListOfShape it(aList);
+    for (; it.More(); it.Next(),theTag++) {
+         builder(theTag)->Generated(it.Value());
+         TCollection_AsciiString aStr(theTag);
+         aName = theName + aStr.ToCString();
+         buildName(theTag, aName);
+       }
+  }
 }
 
 //=======================================================================
@@ -461,7 +567,24 @@ void Model_ResultBody::loadDisconnectedEdges(
            edgeNaborFaces.ChangeFind(anEdge).Append(aFace);      
        }
   }
-  
+
+/*  TopTools_IndexedDataMapOfShapeListOfShape aDM;
+  TopExp::MapShapesAndAncestors(aShape, TopAbs_EDGE, TopAbs_FACE, aDM);
+  for(int i=1; i <= aDM.Extent(); i++) {
+       if(aDM.FindFromIndex(i).Extent() > 1) continue;
+       if (BRep_Tool::Degenerated(TopoDS::Edge(aDM.FindKey(i))))
+     continue;
+       builder(theTag)->Generated(aDM.FindKey(i));
+    TCollection_AsciiString aStr(theTag);
+       std::string aName = theName + aStr.ToCString();
+       buildName(theTag, aName);
+#ifdef DEB_IMPORT
+       aName +=  + ".brep";
+       BRepTools::Write(aDM.FindKey(i), aName.c_str());
+#endif
+       theTag++;
+  }
+*/
   TopTools_MapOfShape anEdgesToDelete;
   TopExp_Explorer anEx(aShape,TopAbs_EDGE); 
   std::string aName;
@@ -485,11 +608,12 @@ void Model_ResultBody::loadDisconnectedEdges(
                if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
                if (aMatches == aList1.Extent()) {
                  aC0=Standard_True;
-                         builder(++theTag)->Generated(anEdge2);
+                         builder(theTag)->Generated(anEdge2);
                  anEdgesToDelete.Add(anEdge2);
                          TCollection_AsciiString aStr(theTag);
                          aName = theName + aStr.ToCString();
                  buildName(theTag, aName);
+                         theTag++;
                        }
                }
          }      
@@ -499,49 +623,51 @@ void Model_ResultBody::loadDisconnectedEdges(
       edgeNaborFaces.UnBind(anEdge1);
        }
     if (aC0) {
-         builder(++theTag)->Generated(anEdge1);
+         builder(theTag)->Generated(anEdge1);
          TCollection_AsciiString aStr(theTag);
          aName = theName + aStr.ToCString();
          buildName(theTag, aName);      
+         theTag++;
        }
-  }
+  }  
 }
 
 void Model_ResultBody::loadDisconnectedVertexes(std::shared_ptr<GeomAPI_Shape> theShape, const std::string& theName, int&  theTag)
 {
   if(theShape->isNull()) return;
   TopoDS_Shape aShape = theShape->impl<TopoDS_Shape>();  
-  TopTools_DataMapOfShapeListOfShape vertexNaborFaces;
+  TopTools_DataMapOfShapeListOfShape vertexNaborEdges;
   TopTools_ListOfShape empty;
-  TopExp_Explorer explF(aShape, TopAbs_FACE);
+  TopExp_Explorer explF(aShape, TopAbs_EDGE);
   for (; explF.More(); explF.Next()) {
-    const TopoDS_Shape& aFace = explF.Current();
-    TopExp_Explorer explV(aFace, TopAbs_VERTEX);
+    const TopoDS_Shape& anEdge = explF.Current();
+    TopExp_Explorer explV(anEdge, TopAbs_VERTEX);
     for (; explV.More(); explV.Next()) {
       const TopoDS_Shape& aVertex = explV.Current();
-      if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty);
+      if (!vertexNaborEdges.IsBound(aVertex)) vertexNaborEdges.Bind(aVertex, empty);
       Standard_Boolean faceIsNew = Standard_True;
-      TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex));
+      TopTools_ListIteratorOfListOfShape itrF(vertexNaborEdges.Find(aVertex));
       for (; itrF.More(); itrF.Next()) {
-        if (itrF.Value().IsSame(aFace)) {
+        if (itrF.Value().IsSame(anEdge)) {
           faceIsNew = Standard_False;
           break;
         }
       }
       if (faceIsNew) {
-        vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
+        vertexNaborEdges.ChangeFind(aVertex).Append(anEdge);
       }
     }
   }
   std::string aName;
-  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces);
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborEdges);
   for (; itr.More(); itr.Next()) {
-    const TopTools_ListOfShape& naborFaces = itr.Value();
-    if (naborFaces.Extent() < 3) {
-               builder(++theTag)->Generated(itr.Key());
+    const TopTools_ListOfShape& naborEdges = itr.Value();
+    if (naborEdges.Extent() < 2) {             
+               builder(theTag)->Generated(itr.Key());
                TCollection_AsciiString aStr(theTag);
            aName = theName + aStr.ToCString();
            buildName(theTag, aName);    
+               theTag++;
        }
   }
-}
\ No newline at end of file
+}