Salome HOME
17.12.2013. Added Partition algorithm (draft version).
[modules/hydro.git] / src / HYDROData / HYDROData_SplitToZonesTool.cxx
index 24e53396744d51f6a70987aa41ebf1689d1946fc..4960a9b741be3c17643236d8222c0b7d75ba00f7 100644 (file)
@@ -1,7 +1,7 @@
 
 #include "HYDROData_SplitToZonesTool.h"
 
-#include "HYDROData_Polyline.h"
+#include "HYDROData_PolylineXY.h"
 
 #include <BRepAlgoAPI_Common.hxx>
 #include <BRepAlgoAPI_Cut.hxx>
 #include <TopoDS.hxx>
 #include <TopoDS_Iterator.hxx>
 #include <TopoDS_Wire.hxx>
+#include <TopoDS_Iterator.hxx>
+#include <BRepCheck_Analyzer.hxx>
+#include <NCollection_IncAllocator.hxx>
+#include <BOPAlgo_Builder.hxx>
+#include <BOPAlgo_PaveFiller.hxx>
+#include <NCollection_DataMap.hxx>
+#include <TopTools_ListOfShape.hxx>
+#include <TopTools_ListIteratorofListOfShape.hxx>
+#include <TopTools_ShapeMapHasher.hxx>
+typedef NCollection_DataMap<TopoDS_Shape, TopTools_ListOfShape, TopTools_ShapeMapHasher> HYDROData_DataMapOfShapeListOfShape;
+typedef HYDROData_DataMapOfShapeListOfShape::Iterator HYDROData_DataMapIteratorOfDataMapOfShapeListOfShape;
+typedef NCollection_DataMap<TopoDS_Shape,  QStringList, TopTools_ShapeMapHasher> HYDROData_DataMapOfShapeListOfString;
+typedef HYDROData_DataMapOfShapeListOfString::Iterator HYDROData_DataMapIteratorOfDataMapOfShapeListOfString;
+#undef _NCollection_MapHasher
 
+#define DEB_SPLIT_TO_ZONES 1
+#ifdef DEB_SPLIT_TO_ZONES       
+#include <BRepTools.hxx>
+#endif
 TopoDS_Face HYDROData_SplitToZonesTool::SplitData::Face() const
 {
   TopoDS_Face aResFace;
@@ -35,38 +53,141 @@ TopoDS_Face HYDROData_SplitToZonesTool::SplitData::Face() const
 }
 
 HYDROData_SplitToZonesTool::SplitDataList
-HYDROData_SplitToZonesTool::SplitToZones( const HYDROData_SequenceOfObjects& theObjectList,
-                                          const Handle(HYDROData_Polyline)&  thePolyline )
+  HYDROData_SplitToZonesTool::Split( const HYDROData_SequenceOfObjects&  theObjectList,
+                                     const HYDROData_SequenceOfObjects&  theGroupsList,
+                                     const Handle(HYDROData_PolylineXY)& thePolyline )
 {
   SplitDataList anOutputSplitDataList;
 
-  // Preparation. Collect the object shapes to split.
+  // Preparation. Collect the object shapes to split. InputDataList will contain elements which will hold shape & name_of_shape.
   SplitDataList anInputSplitDataList;
   for( int anIndex = 1, aLength = theObjectList.Length(); anIndex <= aLength; anIndex++ )
   {
     Handle(HYDROData_Object) aGeomObj = 
       Handle(HYDROData_Object)::DownCast( theObjectList.Value( anIndex ) );
-    if( !aGeomObj.IsNull() )
-    {
-      TopoDS_Shape aShape = aGeomObj->GetTopShape();
-      if ( !aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND ) {
-        // Create split data for each face contained in the compound
-        TopExp_Explorer anExp( aShape, TopAbs_FACE );
-        for ( ; anExp.More(); anExp.Next() ) {
-          TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
-          if ( !aFace.IsNull() ) {
-            SplitData aSplitData( aFace, aGeomObj->GetName() );
-            anInputSplitDataList.append( aSplitData );
-          }
+    if( aGeomObj.IsNull() )
+      continue;
+
+    TopoDS_Shape aShape = aGeomObj->GetTopShape();
+    if ( aShape.IsNull() )
+      continue;
+        
+    if ( aShape.ShapeType() == TopAbs_COMPOUND ) {
+      // Create split data for each face contained in the compound
+      TopExp_Explorer anExp( aShape, TopAbs_FACE );
+      for ( ; anExp.More(); anExp.Next() ) {
+        TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
+        if ( !aFace.IsNull() ) {
+          SplitData aSplitData( SplitData::Data_Zone, aFace, aGeomObj->GetName() );
+          anInputSplitDataList.append( aSplitData );
         }
-      } else {
-        SplitData aSplitData( aShape, aGeomObj->GetName() );
-        anInputSplitDataList.append( aSplitData );
       }
+    } else {
+      SplitData aSplitData( SplitData::Data_Zone, aShape, aGeomObj->GetName() );
+      anInputSplitDataList.append( aSplitData );
     }
   }
 
-  // Step 1. Split the paths.
+  // Step 1. Prepare Partition structures.
+  Handle(NCollection_BaseAllocator) pA1 = new NCollection_IncAllocator, pA2 = new NCollection_IncAllocator;
+  BOPAlgo_PaveFiller* aPaveFiller      = new BOPAlgo_PaveFiller(pA1);
+  BOPAlgo_Builder* aBuilder            = new BOPAlgo_Builder(pA2);
+  BOPCol_ListOfShape aLS;  
+  HYDROData_DataMapOfShapeListOfString aDM3;
+  QStringList aListOfNames;
+  for (int i=0;i < anInputSplitDataList.size() ;i++) {
+       const TopoDS_Shape& aSh = anInputSplitDataList.at(i).Shape;     
+       aDM3.Bind(aSh, anInputSplitDataList.at(i).ObjectNames);
+    aLS.Append(aSh);    
+  }
+   aPaveFiller->SetArguments(aLS);
+   aPaveFiller->Perform();
+   Standard_Integer anErr = aPaveFiller->ErrorStatus();
+   if(anErr) 
+     return anOutputSplitDataList;
+   BOPDS_PDS pDS = aPaveFiller->PDS();
+   if (!pDS) 
+          return anOutputSplitDataList;
+   aBuilder->Clear();
+
+   // Step 2. Split faces 
+   BOPCol_ListIteratorOfListOfShape anIt(aPaveFiller->Arguments());
+   for (; anIt.More(); anIt.Next()) {
+     const TopoDS_Shape& aS = anIt.Value();
+     aBuilder->AddArgument(aS);
+   }
+    aBuilder->PerformWithFiller(*aPaveFiller);
+       anErr = aBuilder->ErrorStatus();
+    if(anErr) 
+      return anOutputSplitDataList;
+       const TopoDS_Shape& aResult = aBuilder->Shape();
+  if (aResult.IsNull()) 
+    return anOutputSplitDataList;
+  BRepCheck_Analyzer aCheck (aResult);
+  if(!aCheck.IsValid()) {
+#ifdef DEB_SPLIT_TO_ZONES      
+     cout << "result is not valid" <<endl;      
+        BRepTools::Write(aResult, "SplitFacesNV.brep");  
+#endif
+     return anOutputSplitDataList;
+  }
+#ifdef DEB_SPLIT_TO_ZONES      
+  BRepTools::Write(aResult, "SplitFacesV.brep");
+#endif
+  
+  // Step 3. Collect history  
+  HYDROData_DataMapOfShapeListOfShape aDM1;
+  anIt.Init(aLS);
+  for (;anIt.More();anIt.Next()) {
+       const TopTools_ListOfShape& aListOfNew = aBuilder->Modified(anIt.Value());
+       aDM1.Bind(anIt.Value(), aListOfNew);
+       //cout << "NB_Face = " << aList.Extent() <<endl;
+       //TopExp_Explorer exp (anIt.Value(), TopAbs_EDGE);
+       //for (;exp.More();exp.Next()) {
+         //const TopTools_ListOfShape& aList2 = aBuilder->Modified(exp.Current());
+        // cout << "NB_EDGE = " << aList2.Extent() <<endl;
+       //}
+  }
+  // aDM2: NewShape ==> ListOfOldShapes
+  HYDROData_DataMapOfShapeListOfShape aDM2;
+  HYDROData_DataMapIteratorOfDataMapOfShapeListOfShape aMIt(aDM1);
+  for(;aMIt.More();aMIt.Next()) {
+       const TopoDS_Shape& aKey = aMIt.Key();
+       TopTools_ListOfShape aList;
+       aList.Append(aKey);
+       const TopTools_ListOfShape& aListOfNew = aMIt.Value();
+       TopTools_ListIteratorOfListOfShape it(aListOfNew);
+       for(;it.More();it.Next()) {
+         if(!aDM2.IsBound(it.Value()))
+           aDM2.Bind(it.Value(), aList);
+         else {
+               TopTools_ListOfShape& aList = aDM2.ChangeFind(it.Value());
+               aList.Prepend(aKey);
+         }
+       }
+  }
+
+  // Step 4. Fill output structure.
+  aMIt.Initialize(aDM2);
+  for(;aMIt.More();aMIt.Next()) {
+       const TopoDS_Shape& aKey = aMIt.Key(); //new
+    const TopTools_ListOfShape& aListOfOld = aMIt.Value();
+       SplitData aDestSplitData;
+       QStringList aListOfNames;
+    TopTools_ListIteratorOfListOfShape it(aListOfOld);
+       for(;it.More();it.Next()) {     
+         const TopoDS_Shape& aSh = it.Value(); //old
+         if(aDM3.IsBound(aSh)) {
+           const QStringList& ObjectNames = aDM3.Find(aSh);
+               aListOfNames.append(ObjectNames);
+         }      
+       }
+       aDestSplitData.Shape = aKey;
+       aDestSplitData.ObjectNames = aListOfNames;
+       anOutputSplitDataList.append(aDestSplitData);
+  }
+  return anOutputSplitDataList;
+  /*
   SplitDataListIterator anInputIter( anInputSplitDataList );
   while( anInputIter.hasNext() )
   {
@@ -106,14 +227,14 @@ HYDROData_SplitToZonesTool::SplitToZones( const HYDROData_SequenceOfObjects& the
   // Step 2. Take into account the boundary polyline.
   if( !thePolyline.IsNull() )
   {
-    TopoDS_Wire aWire = TopoDS::Wire( thePolyline->GetTopShape() );
+    TopoDS_Wire aWire = TopoDS::Wire( thePolyline->GetShape() );
     if( !aWire.IsNull() )
     {
       BRepBuilderAPI_MakeFace aMakeFace( aWire, Standard_True );
       aMakeFace.Build();
       if( aMakeFace.IsDone() )
       {
-        SplitData aBoundarySplitData( aMakeFace.Face(), "" );
+        SplitData aBoundarySplitData( SplitData::Data_Zone, aMakeFace.Face(), "" );
 
         SplitDataList aCutSplitDataList;
         SplitDataListIterator anOutputIter( anOutputSplitDataList );
@@ -139,8 +260,8 @@ HYDROData_SplitToZonesTool::SplitToZones( const HYDROData_SequenceOfObjects& the
     const SplitData& anOutputSplitData = anOutputIter.next();
     anExtractedSplitDataList.append( ExtractSeparateData( anOutputSplitData ) );
   }
-
-  return anExtractedSplitDataList;
+*/
// return anExtractedSplitDataList;
 }
 
 bool HYDROData_SplitToZonesTool::SplitTwoData( const SplitData& theData1,
@@ -170,9 +291,9 @@ bool HYDROData_SplitToZonesTool::SplitTwoData( const SplitData& theData1,
   BRepAlgoAPI_Cut aCut2( aShape2, aShape1 );
   TopoDS_Shape aCut2Shape = aCut2.Shape();
 
-  theData1Subtracted = SplitData( aCut1Shape, anObjectNames1 );
-  theData2Subtracted = SplitData( aCut2Shape, anObjectNames2 );
-  theDataIntersected = SplitData( aCommonShape, anObjectNames1 + anObjectNames2 );
+  theData1Subtracted = SplitData( SplitData::Data_Zone, aCut1Shape, anObjectNames1 );
+  theData2Subtracted = SplitData( SplitData::Data_Zone, aCut2Shape, anObjectNames2 );
+  theDataIntersected = SplitData( SplitData::Data_Zone, aCommonShape, anObjectNames1 + anObjectNames2 );
 
   return true;
 }
@@ -190,7 +311,7 @@ HYDROData_SplitToZonesTool::ExtractSeparateData( const SplitData& theData )
       TopoDS_Face aFace = TopoDS::Face( aShape );
       if( !aFace.IsNull() )
       {
-        SplitData aSplitData( aFace, theData.ObjectNames );
+        SplitData aSplitData( SplitData::Data_Zone, aFace, theData.ObjectNames );
         aSplitDataList.append( aSplitData );
       }
     }