Salome HOME
Merge branch 'BR_MULTI_BATHS' into HEAD
[modules/hydro.git] / src / HYDROData / HYDROData_SplitToZonesTool.cxx
index 821db0edb99860f1e739183b781cf8169d4e203d..e5a1d8428aa7d3b87393a9bd3eb1f5e7eb896f5c 100644 (file)
@@ -1,8 +1,4 @@
-// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, OPEN CASCADE
-//
-// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
-//
+// Copyright (C) 2014-2015  EDF-R&D
 // This library is free software; you can redistribute it and/or
 // modify it under the terms of the GNU Lesser General Public
 // License as published by the Free Software Foundation; either
@@ -44,6 +40,9 @@
 #include <Geom_Plane.hxx>
 #include <BRepBuilderAPI_FindPlane.hxx>
 
+#include <BOPAlgo_BOP.hxx>
+#include <BOPAlgo_Builder.hxx>
+
 //#define DEB_SPLIT_TO_ZONES 1
 //#define DEB_SPLIT_TO_ZONES_CHECK_PARTITION 1
 #if (defined (DEB_SPLIT_TO_ZONES) || defined(DEB_SPLIT_TO_ZONES_CHECK_PARTITION))
@@ -51,6 +50,9 @@
 static TCollection_AsciiString fileNameBefore("BeforeTranslation");
 #endif
 
+#define _DEVDEBUG_
+#include "HYDRO_trace.hxx"
+
 TopoDS_Face HYDROData_SplitToZonesTool::SplitData::Face() const
 {
   TopoDS_Face aResFace;
@@ -131,8 +133,10 @@ Standard_Integer HYDROData_SplitToZonesTool::SplitFaces(const TopoDS_Compound& t
 HYDROData_SplitToZonesTool::SplitDataList
   HYDROData_SplitToZonesTool::Split( const HYDROData_SequenceOfObjects&  theObjectList,
                                      const HYDROData_SequenceOfObjects&  theGroupsList,
-                                     const Handle(HYDROData_PolylineXY)& thePolyline )
+                                     const Handle(HYDROData_PolylineXY)& thePolyline,
+                                     const HYDROData_SequenceOfObjects& InterPolys)
 {
+  DEBTRACE("Split");
   SplitDataList anOutputSplitDataList;
   if(theObjectList.IsEmpty()) return anOutputSplitDataList;
   // Preparation. 
@@ -143,16 +147,18 @@ HYDROData_SplitToZonesTool::SplitDataList
 #endif
   for( int anIndex = 1, aLength = theObjectList.Length(); anIndex <= aLength; anIndex++ )
   {
-    Handle(HYDROData_Object) aGeomObj = 
-      Handle(HYDROData_Object)::DownCast( theObjectList.Value( anIndex ) );
-    if( aGeomObj.IsNull() )
-      continue;
+    Handle(HYDROData_Entity) anObj = theObjectList.Value( anIndex );
+    TopoDS_Shape aShape;
+
+    Handle(HYDROData_Object) aGeomObj = Handle(HYDROData_Object)::DownCast( anObj );
+    if( !aGeomObj.IsNull() ) {
+      aShape = aGeomObj->GetTopShape();
+    }
 
-    TopoDS_Shape aShape = aGeomObj->GetTopShape();
     if ( aShape.IsNull() )
       continue;  
 #ifdef DEB_SPLIT_TO_ZONES
-   TCollection_AsciiString aName = aNam + anIndex + ".brep";
+   TCollection_AsciiString aName = aNam + anIndex + "_a.brep";
    BRepTools::Write(aShape, aName.ToCString());
 #endif
     if ( aShape.ShapeType() == TopAbs_COMPOUND ) {
@@ -161,12 +167,12 @@ HYDROData_SplitToZonesTool::SplitDataList
       for ( ; anExp.More(); anExp.Next() ) {
         const TopoDS_Face& aFace = TopoDS::Face( anExp.Current() );
         if ( !aFace.IsNull() ) {
-          SplitData aSplitData( SplitData::Data_Zone, aFace, aGeomObj->GetName() );
+          SplitData aSplitData( SplitData::Data_Zone, aFace, anObj->GetName() );
           anInputSplitDataList.append( aSplitData );
         }
       }
     } else {
-      SplitData aSplitData( SplitData::Data_Zone, aShape, aGeomObj->GetName() );
+      SplitData aSplitData( SplitData::Data_Zone, aShape, anObj->GetName() );
       anInputSplitDataList.append( aSplitData );
     }
   }
@@ -200,7 +206,7 @@ HYDROData_SplitToZonesTool::SplitDataList
         anInputGroupList.append( aSplitData );
 #ifdef DEB_SPLIT_TO_ZONES
         QString aStr = aSplitData.ObjectNames.join(" "); 
-        cout << "Group# = " <<anIndex <<" Nmb in grp = " << i<< " Names = "<<aStr.toStdString() << " size = " <<aSplitData.ObjectNames.size() <<endl;   
+        DEBTRACE("Group# = " <<anIndex <<" Nmb in grp = " << i<< " Names = "<<aStr.toStdString() << " size = " <<aSplitData.ObjectNames.size());
 #endif
       }
     }
@@ -239,12 +245,12 @@ HYDROData_SplitToZonesTool::SplitDataList
     aLS.Append(aSh);
     aBB.Add(aCmp,aSh);
 #ifdef DEB_SPLIT_TO_ZONES
-    //TCollection_AsciiString aName = aNam + i + ".brep";
-    //BRepTools::Write(aSh, aName.ToCString());
+    TCollection_AsciiString aName = aNam + i + "_b.brep";
+    BRepTools::Write(aSh, aName.ToCString());
 #endif
   }
 #ifdef DEB_SPLIT_TO_ZONES_CHECK_PARTITION
-  TCollection_AsciiString aNameBefore = fileNameBefore + ".brep";
+  TCollection_AsciiString aNameBefore = fileNameBefore + "_c.brep";
   BRepTools::Write(aCmp, aNameBefore.ToCString());
 #endif
 
@@ -260,7 +266,7 @@ HYDROData_SplitToZonesTool::SplitDataList
     BRepCheck_Analyzer aCheck (aResult);
     if(!aCheck.IsValid()) {
   #ifdef DEB_SPLIT_TO_ZONES
-      cout << "result is not valid" <<endl;
+      DEBTRACE("result is not valid");
       BRepTools::Write(aResult, "SplitFacesNV.brep");  
   #endif
       return anOutputSplitDataList;
@@ -308,14 +314,14 @@ HYDROData_SplitToZonesTool::SplitDataList
           aList.Clear();
           Standard_Boolean foundE(Standard_False);
           const TopTools_ListOfShape& aListM = splitTool.Modified(exp.Current());    
-          //cout << "NB_EDGE_M = " << aListM.Extent() <<endl;
+          DEBTRACE("NB_EDGE_M = " << aListM.Extent());
           if(aListM.Extent()) foundE = Standard_True;
           it.Initialize(aListM);    
           for(int k=1;it.More();it.Next(),k++) {    
             aList.Append(it.Value());
   #ifdef DEB_SPLIT_TO_ZONES
-            //aName = aNamM + i + j +k +".brep";
-            //BRepTools::Write(it.Value(),aName.ToCString());
+            aName = aNamM + i + j +k +"_d.brep";
+            BRepTools::Write(it.Value(),aName.ToCString());
   #endif
           }
           /* *********************************************************************
@@ -329,9 +335,9 @@ HYDROData_SplitToZonesTool::SplitDataList
           if(!foundE) {
             aList.Append (exp.Current());
   #ifdef DEB_SPLIT_TO_ZONES
-            aName = aNamG + i + j +".brep";
+            aName = aNamG + i + j +"_e.brep";
             BRepTools::Write(exp.Current(),aName.ToCString());
-            cout << aName.ToCString()<< " = " << exp.Current().TShape() <<endl;
+            DEBTRACE(aName.ToCString()<< " = " << exp.Current().TShape());
   #endif
           }
           aDM1.Add(exp.Current(), aList);
@@ -349,8 +355,10 @@ HYDROData_SplitToZonesTool::SplitDataList
   Standard_Boolean hasLimits(Standard_False);
   QString aBndName;
   HYDROData_MapOfShape aBndView;
-  if (! thePolyline.IsNull()) {    
-    const TopoDS_Wire aBndWire = TopoDS::Wire(thePolyline->GetShape());
+  if (! thePolyline.IsNull()) {
+    Handle(TopTools_HSequenceOfShape) aConnectedWires = new TopTools_HSequenceOfShape;
+    int nbWires = thePolyline->GetNbConnectedWires(aConnectedWires);
+    const TopoDS_Wire aBndWire = TopoDS::Wire(aConnectedWires->Value(1));
     if(!aBndWire.IsNull()) {
       TopoDS_Face limFace;       
       if(buildLimFace(aBndWire, limFace)) {
@@ -384,12 +392,12 @@ HYDROData_SplitToZonesTool::SplitDataList
               const TopoDS_Shape& aFace = exp.Current();
               if(!aFace.IsNull()) {
                 const TopTools_ListOfShape& aListOfNew = mkCom.Modified(aFace);
-                //cout << "Modified: " << aListOfNew.Extent() <<endl;                                    
+                DEBTRACE("Modified: " << aListOfNew.Extent());
                 if(!aListOfNew.IsEmpty()) {
                   aDM4.Add(aFace, aListOfNew);
 #ifdef DEB_SPLIT_TO_ZONES
-                  //TCollection_AsciiString aName = aNam + i + ".brep";
-                  //BRepTools::Write(aListOfNew.Last(), aName.ToCString());                
+                  TCollection_AsciiString aName = aNam + i + "_f.brep";
+                  BRepTools::Write(aListOfNew.Last(), aName.ToCString());
 #endif
                 }
                 else {
@@ -398,8 +406,8 @@ HYDROData_SplitToZonesTool::SplitDataList
                       if(!aListOfGen.IsEmpty()) {
                         /* aDM4.Bind(aFace, aListOfGen); ???   */
 #ifdef DEB_SPLIT_TO_ZONES
-                        //TCollection_AsciiString aName = aNam + i + "g.brep";
-                        //BRepTools::Write(aListOfGen.Last(), aName.ToCString());
+                        TCollection_AsciiString aName = aNam + i + "_g.brep";
+                        BRepTools::Write(aListOfGen.Last(), aName.ToCString());
 #endif
                       }
                        else {
@@ -447,9 +455,9 @@ HYDROData_SplitToZonesTool::SplitDataList
 #ifdef DEB_SPLIT_TO_ZONES
              TopTools_ListIteratorOfListOfShape itl(aListOfNewEd);
              for(int j=1;itl.More();itl.Next(),j++) {
-               TCollection_AsciiString aName = aNam + i + "_" + j + ".brep";
+               TCollection_AsciiString aName = aNam + i + "_" + j + "_j.brep";
                BRepTools::Write(itl.Value(), aName.ToCString());
-               cout <<aName.ToCString()<<" = "<< itl.Value().TShape() <<endl;
+               DEBTRACE(aName.ToCString()<<" = "<< itl.Value().TShape());
              }
 #endif
              if(!aListOfNewEd.IsEmpty())
@@ -543,6 +551,9 @@ HYDROData_SplitToZonesTool::SplitDataList
       }
     }
   }
+
+  AddInternalEdges(aDM2, InterPolys);
+
   // Step 4. Fill output structure.
 #ifdef DEB_SPLIT_TO_ZONES
   TCollection_AsciiString aNam4 ("SC_");
@@ -557,7 +568,7 @@ HYDROData_SplitToZonesTool::SplitDataList
     else {
       aDestSplitData.Type = SplitData::Data_Edge;
 #ifdef DEB_SPLIT_TO_ZONES
-      TCollection_AsciiString aName = aNam4 + i + ".brep";
+      TCollection_AsciiString aName = aNam4 + i + "_k.brep";
       BRepTools::Write(aKey,aName.ToCString());
 #endif    
     }
@@ -571,19 +582,19 @@ HYDROData_SplitToZonesTool::SplitDataList
         const QStringList& ObjectNames = aDM3.FindFromKey(aSh);    
         aListOfNames.append(ObjectNames);
 #ifdef DEB_SPLIT_TO_ZONES
-        TCollection_AsciiString aName = aNam4 + i +"_" + j + ".brep";
+        TCollection_AsciiString aName = aNam4 + i +"_" + j + "_l.brep";
         BRepTools::Write(aSh ,aName.ToCString());        
 #endif    
       }    else {
 #ifdef DEB_SPLIT_TO_ZONES
-        TCollection_AsciiString aName = aNam4 +"__" + i +"_" + j + ".brep";
+        TCollection_AsciiString aName = aNam4 +"__" + i +"_" + j + "_m.brep";
         BRepTools::Write(aSh ,aName.ToCString());        
-        cout <<aName.ToCString()<<" = "<< aSh.TShape() <<endl;
+        DEBTRACE(aName.ToCString()<<" = "<< aSh.TShape());
 #endif
           if(aBndView.Contains(aSh) && hasLimits) {            
             aListOfNames.append(aBndName);
 #ifdef DEB_SPLIT_TO_ZONES
-            cout << " BndName = "<<aBndName.toStdString() <<endl; 
+            DEBTRACE(" BndName = "<<aBndName.toStdString());
 #endif
           }
       }
@@ -593,10 +604,90 @@ HYDROData_SplitToZonesTool::SplitDataList
     anOutputSplitDataList.append(aDestSplitData);    
 #ifdef DEB_SPLIT_TO_ZONES
     QString aStr = aDestSplitData.ObjectNames.join(" "); 
-    cout << "New# = " << i<< " Names = "<<aStr.toStdString() << " size = " <<aDestSplitData.ObjectNames.size() <<endl; 
+    DEBTRACE("New# = " << i<< " Names = "<<aStr.toStdString() << " size = " <<aDestSplitData.ObjectNames.size());
 #endif
   }
 
   return anOutputSplitDataList;
 }
 
+HYDROData_SplitToZonesTool::SplitDataList
+  HYDROData_SplitToZonesTool::Split( const HYDROData_SequenceOfObjects& theObjectList )
+{
+  HYDROData_SequenceOfObjects aGeomGroups;
+  Handle(HYDROData_PolylineXY) aPolyline;
+  HYDROData_SequenceOfObjects InterPolys;
+
+  return Split( theObjectList, aGeomGroups, aPolyline, InterPolys );
+}
+
+void HYDROData_SplitToZonesTool::AddInternalEdges(HYDROData_DataMapOfShapeListOfShape& DM,
+   const HYDROData_SequenceOfObjects& thePolylines)
+{
+
+  HYDROData_SequenceOfObjects::Iterator it(thePolylines);
+  TopTools_ListOfShape Wires;
+  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));
+  }
+
+  HYDROData_DataMapOfShapeListOfShape newDM;
+
+  for (int i = 1; i <= DM.Extent();i++)
+  {
+    const TopoDS_Shape& K = DM.FindKey(i);
+    const TopTools_ListOfShape& V = DM.FindFromIndex(i);
+    TopTools_ListOfShape out;
+    if (K.ShapeType() == TopAbs_FACE)
+    {
+      CutByEdges(K, Wires, out);
+      TopTools_ListIteratorOfListOfShape it(out);
+      for (;it.More(); it.Next())
+      {
+        const TopoDS_Shape& NF = it.Value();
+        if (!NF.IsNull())
+          newDM.Add(NF, V);
+      }
+    }
+    else
+      newDM.Add(K, V); // ignore edges, wires...
+  }
+
+  DM = newDM;
+}
+
+
+int HYDROData_SplitToZonesTool::CutByEdges(const TopoDS_Shape& InSh, const TopTools_ListOfShape& InEdges,
+  TopTools_ListOfShape& outShs)
+{
+  int anError;
+  if (InSh.IsNull())
+    return -1;
+  if (InEdges.IsEmpty())
+  {
+    outShs.Clear();
+    outShs.Append(InSh);
+    return 0;
+  }
+  TopTools_ListIteratorOfListOfShape anIt;
+  BOPAlgo_Builder anAlgo;
+  anAlgo.AddArgument(InSh);
+  anIt.Initialize( InEdges );
+  for( ; anIt.More(); anIt.Next() )
+    anAlgo.AddArgument( anIt.Value() );
+
+  anAlgo.Perform(); 
+  anError = anAlgo.ErrorStatus();
+  if (anError)
+    return anError;
+
+  outShs = anAlgo.Modified( InSh );
+  if (outShs.IsEmpty())
+    outShs.Append(InSh);
+  return 0;
+}