Salome HOME
quick optimization patch (bytearray for images)
[modules/hydro.git] / src / HYDROData / HYDROData_SplitToZonesTool.cxx
index e5a1d8428aa7d3b87393a9bd3eb1f5e7eb896f5c..07a515ff296c6723f1a6d9c14a4da6bc5785204b 100644 (file)
@@ -34,6 +34,7 @@
 #include <BRepCheck_Analyzer.hxx>
 #include <TopTools_ListOfShape.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
+#include <TopTools_IndexedMapOfShape.hxx>
 #include <gp_Pln.hxx>
 #include <BRepGProp.hxx>
 #include <GProp_GProps.hxx>
@@ -42,6 +43,8 @@
 
 #include <BOPAlgo_BOP.hxx>
 #include <BOPAlgo_Builder.hxx>
+#include <TopExp.hxx>
+#include <assert.h>
 
 //#define DEB_SPLIT_TO_ZONES 1
 //#define DEB_SPLIT_TO_ZONES_CHECK_PARTITION 1
@@ -50,7 +53,7 @@
 static TCollection_AsciiString fileNameBefore("BeforeTranslation");
 #endif
 
-#define _DEVDEBUG_
+//#define _DEVDEBUG_
 #include "HYDRO_trace.hxx"
 
 TopoDS_Face HYDROData_SplitToZonesTool::SplitData::Face() const
@@ -136,9 +139,13 @@ HYDROData_SplitToZonesTool::SplitDataList
                                      const Handle(HYDROData_PolylineXY)& thePolyline,
                                      const HYDROData_SequenceOfObjects& InterPolys)
 {
+#ifndef NDEBUG
   DEBTRACE("Split");
+#endif
   SplitDataList anOutputSplitDataList;
-  if(theObjectList.IsEmpty()) return anOutputSplitDataList;
+  NCollection_DataMap<TopoDS_Shape, Handle(HYDROData_PolylineXY), TopTools_ShapeMapHasher> OutNE;
+  if(theObjectList.IsEmpty())
+    return anOutputSplitDataList;
   // Preparation. 
   // Collect the object shapes to split. InputDataList will contain elements which will hold shape & name_of_shape.
   SplitDataList anInputSplitDataList;
@@ -214,14 +221,96 @@ HYDROData_SplitToZonesTool::SplitDataList
   // If only one shape is given we don't split it 
   // algorithm just returns the unpacked input data
   bool limplus1Object(false);
-  if(theObjectList.Size() == 1 )  {
-    if(thePolyline.IsNull()) {
-      anOutputSplitDataList.append(anInputSplitDataList); 
+  if(theObjectList.Size() == 1 ) 
+  {
+    if(thePolyline.IsNull()) 
+    {
+      //anOutputSplitDataList.append(anInputSplitDataList); 
+      SplitData SD = anInputSplitDataList.at(0);
+      TopTools_ListOfShape newshs;
+      TopTools_IndexedDataMapOfShapeListOfShape OutOrSh2M;
+      CutFaceByEdges(SD.Face(), newshs, InterPolys, &OutNE, &OutOrSh2M);
+      for (TopTools_ListIteratorOfListOfShape it(newshs); it.More(); it.Next())
+      {
+        SplitData NSD = SD;
+        NSD.Shape = it.Value();
+        anOutputSplitDataList.append(NSD);
+      }
+
+      NCollection_DataMap<TopoDS_Shape, Handle(HYDROData_PolylineXY), TopTools_ShapeMapHasher>::Iterator spit(OutNE);
+      for (;spit.More();spit.Next())
+      {
+        const TopoDS_Edge& E = TopoDS::Edge(spit.Key());
+        if (E.IsNull())
+          continue;
+        SplitData SDI(SplitData::Data_IntEdge, E, spit.Value()->GetName());   
+        anOutputSplitDataList.append(SDI);
+      }
+
+#ifndef NDEBUG
+      //check CutFaceByEdges method: ensure that SD.Face() edges fully covered by
+      //history map (OutOrSh2M)
+      if (!OutOrSh2M.IsEmpty())
+      {
+        TopTools_IndexedMapOfShape EE;
+        TopExp::MapShapes(SD.Face(), TopAbs_EDGE, EE);
+        int noncontNb = 0;      
+        for (int i = 1; i <= EE.Extent(); i++)
+        {
+          const TopoDS_Shape& E = EE(i);
+          noncontNb += !OutOrSh2M.Contains(E);
+        }
+        //noncontNb > 0 => some problem with edge history
+        assert(noncontNb == 0);
+      }
+#endif
+
       if(!theGroupsList.IsEmpty() ) 
-        anOutputSplitDataList.append(anInputGroupList);
+      {
+        SplitDataList ModifInpGroupList;
+        SplitDataListIterator it(anInputGroupList);
+        while( it.hasNext() )
+        {
+          const SplitData& SData = it.next();
+          if (SData.Type != SplitData::Data_Edge)
+            ModifInpGroupList.append(SData); //add as is
+          const TopoDS_Shape& SData_sh = SData.Shape;
+          TopTools_ListOfShape modif_ls;
+          if (!InterPolys.IsEmpty())
+            if (OutOrSh2M.Contains(SData_sh))
+              modif_ls = OutOrSh2M.FindFromKey(SData_sh);
+            //else TODO -  show message that one of the object should be updated
+
+#ifndef NDEBUG
+          if (!InterPolys.IsEmpty() && OutOrSh2M.IsEmpty())
+            assert (true);
+#endif
+          if (modif_ls.IsEmpty())
+            ModifInpGroupList.append(SData); //non modified
+          else
+          {
+            TopTools_ListIteratorOfListOfShape itl_modif(modif_ls);
+            for (;itl_modif.More();itl_modif.Next())
+            {
+              const TopoDS_Shape& CSH = itl_modif.Value();
+              if (CSH.ShapeType() == TopAbs_EDGE)
+              {
+                SplitData NewSData;
+                NewSData.ObjectNames = SData.ObjectNames;
+                NewSData.Type = SData.Type;
+                NewSData.Shape = CSH;
+                ModifInpGroupList.append(NewSData);
+              }
+            }
+          }
+
+        }
+        anOutputSplitDataList.append(ModifInpGroupList);
+      }
       return anOutputSplitDataList;
-    } else
-        limplus1Object = true;// size =1 && hasLimits
+    }
+    else
+      limplus1Object = true;// size =1 && hasLimits
   }
   HYDROData_DataMapOfShapeListOfString aDM3;
   if(!anInputGroupList.isEmpty()) {// Old edge ==> List_Of_Names
@@ -313,8 +402,10 @@ HYDROData_SplitToZonesTool::SplitDataList
         for (int j =1;exp.More();exp.Next(),j++) {
           aList.Clear();
           Standard_Boolean foundE(Standard_False);
-          const TopTools_ListOfShape& aListM = splitTool.Modified(exp.Current());    
+          const TopTools_ListOfShape& aListM = splitTool.Modified(exp.Current()); 
+#ifndef NDEBUG
           DEBTRACE("NB_EDGE_M = " << aListM.Extent());
+#endif
           if(aListM.Extent()) foundE = Standard_True;
           it.Initialize(aListM);    
           for(int k=1;it.More();it.Next(),k++) {    
@@ -392,7 +483,9 @@ HYDROData_SplitToZonesTool::SplitDataList
               const TopoDS_Shape& aFace = exp.Current();
               if(!aFace.IsNull()) {
                 const TopTools_ListOfShape& aListOfNew = mkCom.Modified(aFace);
+#ifndef NDEBUG
                 DEBTRACE("Modified: " << aListOfNew.Extent());
+#endif
                 if(!aListOfNew.IsEmpty()) {
                   aDM4.Add(aFace, aListOfNew);
 #ifdef DEB_SPLIT_TO_ZONES
@@ -552,7 +645,16 @@ HYDROData_SplitToZonesTool::SplitDataList
     }
   }
 
-  AddInternalEdges(aDM2, InterPolys);
+  AddInternalEdges(aDM2, InterPolys, &OutNE);
+  NCollection_DataMap<TopoDS_Shape, Handle(HYDROData_PolylineXY), TopTools_ShapeMapHasher>::Iterator spit(OutNE);
+  for (;spit.More();spit.Next())
+  {
+    const TopoDS_Edge& E = TopoDS::Edge(spit.Key());
+    if (E.IsNull())
+      continue;
+    SplitData SDI(SplitData::Data_IntEdge, E, spit.Value()->GetName());   
+    anOutputSplitDataList.append(SDI);
+  }
 
   // Step 4. Fill output structure.
 #ifdef DEB_SPLIT_TO_ZONES
@@ -622,22 +724,23 @@ HYDROData_SplitToZonesTool::SplitDataList
 }
 
 void HYDROData_SplitToZonesTool::AddInternalEdges(HYDROData_DataMapOfShapeListOfShape& DM,
-   const HYDROData_SequenceOfObjects& thePolylines)
+   const HYDROData_SequenceOfObjects& thePolylines,
+   NCollection_DataMap<TopoDS_Shape, Handle(HYDROData_PolylineXY), TopTools_ShapeMapHasher>* OutNE)
 {
 
   HYDROData_SequenceOfObjects::Iterator it(thePolylines);
   TopTools_ListOfShape Wires;
+  NCollection_DataMap<TopoDS_Shape, Handle(HYDROData_PolylineXY), TopTools_ShapeMapHasher> W2P;
   for (;it.More();it.Next())
   {
     Handle(HYDROData_PolylineXY) P = Handle(HYDROData_PolylineXY)::DownCast(it.Value());
-    Wires.Append(P->GetShape());
-    //Handle(TopTools_HSequenceOfShape) aConnectedWires = new TopTools_HSequenceOfShape;
-    //if (P->GetNbConnectedWires(aConnectedWires) > 0)
-    //  Wires.Append(aConnectedWires->Value(1));
+    const TopoDS_Shape& CW = P->GetShape();
+    Wires.Append(CW);
+    W2P.Bind(CW, P);
   }
 
   HYDROData_DataMapOfShapeListOfShape newDM;
-
+  TopTools_IndexedDataMapOfShapeShape OutNE1;
   for (int i = 1; i <= DM.Extent();i++)
   {
     const TopoDS_Shape& K = DM.FindKey(i);
@@ -645,7 +748,7 @@ void HYDROData_SplitToZonesTool::AddInternalEdges(HYDROData_DataMapOfShapeListOf
     TopTools_ListOfShape out;
     if (K.ShapeType() == TopAbs_FACE)
     {
-      CutByEdges(K, Wires, out);
+      CutByEdges(K, Wires, out, &OutNE1, NULL);
       TopTools_ListIteratorOfListOfShape it(out);
       for (;it.More(); it.Next())
       {
@@ -658,17 +761,47 @@ void HYDROData_SplitToZonesTool::AddInternalEdges(HYDROData_DataMapOfShapeListOf
       newDM.Add(K, V); // ignore edges, wires...
   }
 
+  for (int i = 1; i <= OutNE1.Extent(); i++)
+    OutNE->Bind(OutNE1.FindKey(i), W2P(OutNE1.FindFromIndex(i)));
+
   DM = newDM;
 }
 
+void HYDROData_SplitToZonesTool::CutFaceByEdges(const TopoDS_Face& in, 
+                                                TopTools_ListOfShape& out, 
+                                                const HYDROData_SequenceOfObjects& thePolylines,
+                                                NCollection_DataMap<TopoDS_Shape, Handle(HYDROData_PolylineXY), TopTools_ShapeMapHasher>* OutNE,                                                
+                                                TopTools_IndexedDataMapOfShapeListOfShape* OutOrSh2M)
+{
+
+  HYDROData_SequenceOfObjects::Iterator it(thePolylines);
+  TopTools_ListOfShape Wires;
+  NCollection_DataMap<TopoDS_Shape, Handle(HYDROData_PolylineXY), TopTools_ShapeMapHasher> W2P;
+  for (;it.More();it.Next())
+  {
+    Handle(HYDROData_PolylineXY) P = Handle(HYDROData_PolylineXY)::DownCast(it.Value());
+    const TopoDS_Shape& CW = P->GetShape();
+    Wires.Append(CW);
+    W2P.Bind(CW, P);
+  }
 
-int HYDROData_SplitToZonesTool::CutByEdges(const TopoDS_Shape& InSh, const TopTools_ListOfShape& InEdges,
-  TopTools_ListOfShape& outShs)
+  TopTools_IndexedDataMapOfShapeShape OutNE1;
+  CutByEdges(in, Wires, out, &OutNE1, OutOrSh2M);
+
+  for (int i = 1; i <= OutNE1.Extent(); i++)
+    OutNE->Bind(OutNE1.FindKey(i), W2P(OutNE1.FindFromIndex(i)));
+
+}
+
+int HYDROData_SplitToZonesTool::CutByEdges(const TopoDS_Shape& InSh, const TopTools_ListOfShape& InW,
+                                           TopTools_ListOfShape& outShs, 
+                                           TopTools_IndexedDataMapOfShapeShape* OutNE, 
+                                           TopTools_IndexedDataMapOfShapeListOfShape* OInSH2MSH)
 {
   int anError;
   if (InSh.IsNull())
     return -1;
-  if (InEdges.IsEmpty())
+  if (InW.IsEmpty())
   {
     outShs.Clear();
     outShs.Append(InSh);
@@ -677,7 +810,8 @@ int HYDROData_SplitToZonesTool::CutByEdges(const TopoDS_Shape& InSh, const TopTo
   TopTools_ListIteratorOfListOfShape anIt;
   BOPAlgo_Builder anAlgo;
   anAlgo.AddArgument(InSh);
-  anIt.Initialize( InEdges );
+
+  anIt.Initialize( InW );
   for( ; anIt.More(); anIt.Next() )
     anAlgo.AddArgument( anIt.Value() );
 
@@ -689,5 +823,51 @@ int HYDROData_SplitToZonesTool::CutByEdges(const TopoDS_Shape& InSh, const TopTo
   outShs = anAlgo.Modified( InSh );
   if (outShs.IsEmpty())
     outShs.Append(InSh);
+
+  if (OutNE)
+  {
+    TopTools_IndexedDataMapOfShapeShape NonFOutNE;
+    anIt.Initialize( InW );
+    for( ; anIt.More(); anIt.Next() )
+    {
+      const TopoDS_Shape& OSH = anIt.Value(); 
+      TopExp_Explorer exp(OSH, TopAbs_EDGE);
+      for (;exp.More();exp.Next())
+      {
+        const TopoDS_Edge& OE = TopoDS::Edge(exp.Current());
+        const TopTools_ListOfShape& ls = anAlgo.Modified(OE);
+        TopTools_ListIteratorOfListOfShape itls(ls);
+        for (;itls.More();itls.Next())
+          NonFOutNE.Add(itls.Value(), OSH);
+      }
+    }
+
+    //filter edges; if face contain an edge => keep it
+    TopTools_IndexedMapOfShape AllEdges; //edges from output shape
+    for (anIt.Initialize(outShs); anIt.More();anIt.Next())
+      TopExp::MapShapes(anIt.Value(), TopAbs_EDGE, AllEdges);
+
+    for (int i = 1; i <= NonFOutNE.Extent(); i++)
+    {
+      const TopoDS_Shape& CE = NonFOutNE.FindKey(i);
+      const TopoDS_Shape& V = NonFOutNE.FindFromIndex(i);
+      if (AllEdges.Contains(CE))
+        OutNE->Add(CE, V);
+    }
+  }
+
+  //map all sub-shapes from the original InSh to modified shapes  
+  if (OInSH2MSH)
+  {
+    TopTools_IndexedMapOfShape allSh;
+    TopExp::MapShapes(InSh, allSh);
+    for(int i = 1; i <= allSh.Extent(); i++ )
+    {
+      const TopoDS_Shape& or_sh = allSh(i); 
+      const TopTools_ListOfShape& ls = anAlgo.Modified(or_sh);
+      OInSH2MSH->Add(or_sh, ls);
+    }
+  }
+
   return 0;
 }