Integration of OCCT 6.5.0 from SVN
[occt.git] / src / QANewBRepNaming / QANewBRepNaming_ImportShape.cxx
diff --git a/src/QANewBRepNaming/QANewBRepNaming_ImportShape.cxx b/src/QANewBRepNaming/QANewBRepNaming_ImportShape.cxx
new file mode 100755 (executable)
index 0000000..9032072
--- /dev/null
@@ -0,0 +1,356 @@
+// File:       QANewBRepNaming_ImportShape.cxx
+// Created:    Tue Oct  5 14:31:29 1999
+// Author:     Vladislav ROMASHKO
+//             <v-romashko@opencascade.com>
+// Copyright:  Open CASCADE 2003
+
+
+#include <QANewBRepNaming_ImportShape.ixx>
+
+#include <Standard_NullObject.hxx>
+#include <BRepTools.hxx>
+
+#include <TopoDS.hxx>
+#include <TopoDS_Shape.hxx>
+#include <TopoDS_Face.hxx>
+#include <TopoDS_Wire.hxx>
+#include <TopoDS_Edge.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <TopExp.hxx>
+#include <TopExp_Explorer.hxx>
+
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
+#include <TopTools_DataMapOfShapeShape.hxx>
+#include <TopTools_DataMapOfShapeListOfShape.hxx>
+#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
+#include <ShapeExtend_WireData.hxx>
+
+#include <TDF_Label.hxx>
+#include <TDF_LabelMap.hxx>
+#include <TDF_TagSource.hxx>
+#include <TDF_ChildIterator.hxx>
+#include <TNaming_Builder.hxx>
+#include <TNaming_NamedShape.hxx>
+#include <QANewBRepNaming_LoaderParent.hxx>
+//=======================================================================
+//function : QANewBRepNaming_ImportShape
+//purpose  : Constructor
+//=======================================================================
+
+QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape() {}
+
+//=======================================================================
+//function : QANewBRepNaming_ImportShape
+//purpose  : Constructor
+//=======================================================================
+
+QANewBRepNaming_ImportShape::QANewBRepNaming_ImportShape(const TDF_Label& L):QANewBRepNaming_TopNaming(L) {}
+
+//=======================================================================
+//function : Init
+//purpose  : Initialization
+//=======================================================================
+
+void QANewBRepNaming_ImportShape::Init(const TDF_Label& Label) {
+  if(Label.IsNull()) 
+    Standard_NullObject::Raise("QANewBRepNaming_ImportShape::Init The Result label is Null ..."); 
+  myResultLabel = Label;
+}  
+
+//=======================================================================
+//function : Load
+//purpose  : To load an ImportShape
+//           Use this method for a topological naming of an imported shape
+//=======================================================================
+
+void QANewBRepNaming_ImportShape::Load(const TopoDS_Shape& theShape) const {
+  ResultLabel().ForgetAllAttributes();
+  TNaming_Builder b(ResultLabel());
+  b.Generated(theShape);
+
+  Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
+  if (Tagger.IsNull()) return;
+  Tagger->Set(0);
+
+  LoadFirstLevel(theShape, Tagger);
+  LoadC0Edges(theShape, Tagger);
+  LoadC0Vertices(theShape, Tagger);
+}  
+
+//=======================================================================
+//function : LoadPrime
+//purpose  : 
+//=======================================================================
+
+void QANewBRepNaming_ImportShape::LoadPrime(const TopoDS_Shape& theShape) const {
+
+  Handle(TDF_TagSource) Tagger = TDF_TagSource::Set(ResultLabel());
+  if (Tagger.IsNull()) return;
+  Tagger->Set(0);
+
+  LoadFirstLevel(theShape, Tagger);
+  LoadC0Edges(theShape, Tagger);
+  LoadC0Vertices(theShape, Tagger);
+}  
+    
+//=======================================================================
+//function : LoadFirstLevel
+//purpose  : Method for internal use. Is used by Load()
+//=======================================================================
+
+void QANewBRepNaming_ImportShape::LoadFirstLevel(const TopoDS_Shape& S,
+                                           const Handle(TDF_TagSource)& Tagger) const {
+  if (S.ShapeType() == TopAbs_COMPOUND || S.ShapeType() == TopAbs_COMPSOLID) {
+    TopoDS_Iterator itr(S);
+    for (; itr.More(); itr.Next()) {
+      TNaming_Builder bIndependantShapes(Tagger->NewChild());
+      bIndependantShapes.Generated(itr.Value());
+      if (itr.Value().ShapeType() == TopAbs_COMPOUND || itr.Value().ShapeType() == TopAbs_COMPSOLID) {
+       LoadFirstLevel(itr.Value(), Tagger);
+      } else LoadNextLevels(itr.Value(), Tagger);
+    }
+  } else LoadNextLevels(S, Tagger); 
+} 
+
+//=======================================================================
+//function : LoadNextLevels
+//purpose  : Method for internal use. Is used by LoadFirstLevel()
+//=======================================================================
+
+void QANewBRepNaming_ImportShape::LoadNextLevels(const TopoDS_Shape& S,
+                                           const Handle(TDF_TagSource)& Tagger) const {
+
+  if (S.ShapeType() == TopAbs_SOLID) {             
+    TopExp_Explorer expl(S, TopAbs_FACE);
+    for (; expl.More(); expl.Next()) {
+      TNaming_Builder bFace(Tagger->NewChild());
+      bFace.Generated(expl.Current());
+    }
+  } else if (S.ShapeType() == TopAbs_SHELL || S.ShapeType() == TopAbs_FACE) {
+    // load faces and all the free edges
+    TopTools_IndexedMapOfShape Faces;
+    TopExp::MapShapes(S, TopAbs_FACE, Faces);
+    if (Faces.Extent() > 1 || (S.ShapeType() == TopAbs_SHELL && Faces.Extent() == 1)) {
+      TopExp_Explorer expl(S, TopAbs_FACE);
+      for (; expl.More(); expl.Next()) {
+       TNaming_Builder bFace(Tagger->NewChild());
+       bFace.Generated(expl.Current());
+      }
+    }
+    TopTools_IndexedDataMapOfShapeListOfShape anEdgeAndNeighbourFaces;
+    TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, anEdgeAndNeighbourFaces);
+    for (Standard_Integer i = 1; i <= anEdgeAndNeighbourFaces.Extent(); i++) {
+      const TopTools_ListOfShape& aLL = anEdgeAndNeighbourFaces.FindFromIndex(i);
+      if (aLL.Extent() < 2) {
+       TNaming_Builder bFreeEdges(Tagger->NewChild());
+       bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i));
+      } else {
+       TopTools_ListIteratorOfListOfShape anIter(aLL);
+       const TopoDS_Face aFace = TopoDS::Face(anIter.Value());
+       anIter.Next();
+       if(aFace.IsEqual(anIter.Value())) {
+         TNaming_Builder bFreeEdges(Tagger->NewChild());
+         bFreeEdges.Generated(anEdgeAndNeighbourFaces.FindKey(i));
+       }
+      }
+    }
+  } else if (S.ShapeType() == TopAbs_WIRE) {
+    TopTools_IndexedMapOfShape Edges;
+    BRepTools::Map3DEdges(S, Edges);
+    if (Edges.Extent() == 1) {
+      TNaming_Builder bEdge(Tagger->NewChild());
+      bEdge.Generated(Edges.FindKey(1));
+      TopExp_Explorer expl(S, TopAbs_VERTEX);
+      for (; expl.More(); expl.Next()) {
+       TNaming_Builder bVertex(Tagger->NewChild());
+       bVertex.Generated(expl.Current());    
+      }
+    } else {
+      TopExp_Explorer expl(S, TopAbs_EDGE); 
+      for (; expl.More(); expl.Next()) {
+       TNaming_Builder bEdge(Tagger->NewChild());
+       bEdge.Generated(expl.Current());
+      }   
+      // and load generated vertices.
+      TopTools_DataMapOfShapeShape generated;
+      if (QANewBRepNaming_LoaderParent::GetDangleShapes(S, TopAbs_EDGE, generated)) {
+       TNaming_Builder bGenVertices(Tagger->NewChild());
+       QANewBRepNaming_LoaderParent::LoadGeneratedDangleShapes(S, TopAbs_EDGE, bGenVertices);
+      }
+    }
+  } else if (S.ShapeType() == TopAbs_EDGE) {
+    TopExp_Explorer expl(S, TopAbs_VERTEX);
+    for (; expl.More(); expl.Next()) {
+      TNaming_Builder bVertex(Tagger->NewChild());
+      bVertex.Generated(expl.Current());    
+    }
+  }
+}
+
+
+//=======================================================================
+//function : LoadC0Edges
+//purpose  : Method for internal use. It is used by Load() method.
+//=======================================================================
+
+void QANewBRepNaming_ImportShape::LoadC0Edges(const TopoDS_Shape& S,
+                                             const Handle(TDF_TagSource)& Tagger) const 
+{
+// vro: It sets vertices twicely:
+//   TopTools_IndexedDataMapOfShapeListOfShape vertexNaborFaces;
+//   TopExp::MapShapesAndAncestors(S, TopAbs_VERTEX, TopAbs_FACE, vertexNaborFaces);
+  TopTools_DataMapOfShapeListOfShape edgeNaborFaces;
+  TopTools_ListOfShape empty;
+  TopExp_Explorer explF(S, TopAbs_FACE);
+  for (; explF.More(); explF.Next()) {
+    const TopoDS_Shape& aFace = explF.Current();
+    TopExp_Explorer explV(aFace, TopAbs_EDGE);
+    for (; explV.More(); explV.Next()) {
+      const TopoDS_Shape& anEdge = explV.Current();
+      if (!edgeNaborFaces.IsBound(anEdge)) edgeNaborFaces.Bind(anEdge, empty);
+      Standard_Boolean faceIsNew = Standard_True;
+      TopTools_ListIteratorOfListOfShape itrF(edgeNaborFaces.Find(anEdge));
+      for (; itrF.More(); itrF.Next()) {
+       if (itrF.Value().IsSame(aFace)) {
+         faceIsNew = Standard_False;
+         break;
+       }
+      }
+      if (faceIsNew) {
+       edgeNaborFaces.ChangeFind(anEdge).Append(aFace);
+      }
+    }
+  }
+  
+  TopExp_Explorer anEx(S,TopAbs_EDGE); // mpv: new explorer iterator becouse we need keep edges order
+  for(;anEx.More();anEx.Next()) {
+    Standard_Boolean aC0 = Standard_False;
+    TopoDS_Shape anEdge1 = anEx.Current();
+    if (edgeNaborFaces.IsBound(anEdge1)) {
+      const TopTools_ListOfShape& aList1 = edgeNaborFaces.Find(anEdge1);
+      TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(edgeNaborFaces);
+      for (; itr.More(); itr.Next()) {
+       TopoDS_Shape anEdge2 = itr.Key();
+       if (anEdge1.IsSame(anEdge2)) continue;
+       const TopTools_ListOfShape& aList2 = itr.Value();
+       // compare lists of the neighbour faces of edge1 and edge2
+       if (aList1.Extent() == aList2.Extent()) {
+         Standard_Integer aMatches = 0;
+         for(TopTools_ListIteratorOfListOfShape aLIter1(aList1);aLIter1.More();aLIter1.Next())
+           for(TopTools_ListIteratorOfListOfShape aLIter2(aList2);aLIter2.More();aLIter2.Next())
+             if (aLIter1.Value().IsSame(aLIter2.Value())) aMatches++;
+         if (aMatches == aList1.Extent()) {
+           aC0=Standard_True;
+           TNaming_Builder bC0Edge(Tagger->NewChild());
+           bC0Edge.Generated(anEdge2);
+           edgeNaborFaces.UnBind(anEdge2);
+         }
+       }
+      }
+      edgeNaborFaces.UnBind(anEdge1);
+    }
+    if (aC0) {
+      TNaming_Builder bC0Edge(Tagger->NewChild());
+      bC0Edge.Generated(anEdge1);
+    }
+  }
+}
+
+
+//=======================================================================
+//function : LoadC0Vertices
+//purpose  : Method for internal use. It is used by Load() method.
+//=======================================================================
+
+void QANewBRepNaming_ImportShape::LoadC0Vertices(const TopoDS_Shape& S,
+                                           const Handle(TDF_TagSource)& Tagger) const 
+{
+  TopTools_DataMapOfShapeListOfShape vertexNaborFaces;
+  TopTools_ListOfShape empty;
+  TopExp_Explorer explF(S, TopAbs_FACE);
+  for (; explF.More(); explF.Next()) {
+    const TopoDS_Shape& aFace = explF.Current();
+    TopExp_Explorer explV(aFace, TopAbs_VERTEX);
+    for (; explV.More(); explV.Next()) {
+      const TopoDS_Shape& aVertex = explV.Current();
+      if (!vertexNaborFaces.IsBound(aVertex)) vertexNaborFaces.Bind(aVertex, empty);
+      Standard_Boolean faceIsNew = Standard_True;
+      TopTools_ListIteratorOfListOfShape itrF(vertexNaborFaces.Find(aVertex));
+      for (; itrF.More(); itrF.Next()) {
+       if (itrF.Value().IsSame(aFace)) {
+         faceIsNew = Standard_False;
+         break;
+       }
+      }
+      if (faceIsNew) {
+       vertexNaborFaces.ChangeFind(aVertex).Append(aFace);
+      }
+    }
+  }
+
+  TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itr(vertexNaborFaces);
+  for (; itr.More(); itr.Next()) {
+    const TopTools_ListOfShape& naborFaces = itr.Value();
+    if (naborFaces.Extent() < 3) {
+      TNaming_Builder bC0Vertex(Tagger->NewChild());
+      bC0Vertex.Generated(itr.Key());
+    }
+  }
+}
+
+//=======================================================================
+//function : NamedFaces
+//purpose  : Returns the labels of all the named faces. Returns the number of faces.
+//=======================================================================
+
+Standard_Integer QANewBRepNaming_ImportShape::NamedFaces(TDF_LabelMap& theNamedFaces) const {
+  theNamedFaces.Clear();
+  Handle(TNaming_NamedShape) aFace;
+  TDF_ChildIterator itr(ResultLabel());
+  for (; itr.More(); itr.Next()) {
+    if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aFace) &&
+       !aFace->IsEmpty() && aFace->Get().ShapeType() == TopAbs_FACE)
+      theNamedFaces.Add(itr.Value());
+  }
+  return theNamedFaces.Extent();
+}
+
+//=======================================================================
+//function : NamedEdges
+//purpose  : Returns the labels of all the named free edges.
+//           Returns the number of edges.
+//=======================================================================
+
+Standard_Integer QANewBRepNaming_ImportShape::NamedEdges(TDF_LabelMap& theNamedEdges) const {
+  theNamedEdges.Clear();
+  Handle(TNaming_NamedShape) anEdge;
+  TDF_ChildIterator itr(ResultLabel());
+  for (; itr.More(); itr.Next()) {
+    if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), anEdge) &&
+       !anEdge->IsEmpty() && anEdge->Get().ShapeType() == TopAbs_EDGE)
+      theNamedEdges.Add(itr.Value());
+  }
+  return theNamedEdges.Extent();
+}
+
+//=======================================================================
+//function : NamedVertices
+//purpose  : Returns the labels of all the named free vertices.
+//           Returns the number of verices.
+//=======================================================================
+
+Standard_Integer QANewBRepNaming_ImportShape::NamedVertices(TDF_LabelMap& theNamedVertices) const {
+  theNamedVertices.Clear();
+  Handle(TNaming_NamedShape) aVertex;
+  TDF_ChildIterator itr(ResultLabel());
+  for (; itr.More(); itr.Next()) {
+    if (itr.Value().FindAttribute(TNaming_NamedShape::GetID(), aVertex) &&
+       !aVertex->IsEmpty() && aVertex->Get().ShapeType() == TopAbs_VERTEX)
+      theNamedVertices.Add(itr.Value());
+  }
+  return theNamedVertices.Extent();
+}
+