Salome HOME
refs #1813 ... lot 14 combined commit : parts : 1 - 16
[modules/hydro.git] / src / HYDROData / HYDROData_CalculationCase.cxx
index ff5dd2980a6078f20982a483ab1d1b56403585eb..12aca20da9df2a77b0a89344036dcfe8acc52472 100644 (file)
@@ -30,6 +30,9 @@
 #include "HYDROData_Region.h"
 #include "HYDROData_Tool.h"
 #include "HYDROData_GeomTool.h"
+#include <HYDROData_Tool.h>
+#include <HYDROData_BCPolygon.h>
+#include <HYDROData_BoundaryPolygonTools.h>
 
 #ifdef WIN32
   #pragma warning ( disable: 4251 )
@@ -52,6 +55,8 @@
 #include <BRep_Builder.hxx>
 #include <BRepBuilderAPI_Sewing.hxx>
 #include <BRepTopAdaptor_FClass2d.hxx>
+#include <BRepTools_ReShape.hxx>
+#include <BRepLib_MakeWire.hxx>
 
 #include <BRepTools.hxx>
 
@@ -270,6 +275,142 @@ HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetAllReferenceObjects()
   return aResSeq;
 }
 
+static void FilterEdgesByIncludeSelectionBoundaryPolygons( const HYDROData_SplitToZonesTool::SplitDataList& anEdgesList,
+                                                           HYDROData_SequenceOfObjects aBoundaryPolygons,
+                                                           HYDROData_SplitToZonesTool::SplitDataList& outEdgesList)
+{
+  //perform boundary condition polygons on EdgesList
+  TopTools_SequenceOfShape IncTools, SelectionTools;
+  HYDROData_SplitToZonesTool::SplitDataListIterator anIter(anEdgesList);
+  for (int i=1; i<=aBoundaryPolygons.Size();i++)
+  {
+    Handle(HYDROData_BCPolygon) aBCPoly = Handle(HYDROData_BCPolygon)::DownCast( aBoundaryPolygons(i));
+    TopoDS_Shape aPolyTopShape = aBCPoly->GetTopShape();
+    int bType = aBCPoly->GetBoundaryType();
+    if (bType == 2) 
+      IncTools.Append(aPolyTopShape);
+    else if (bType == 3)
+      SelectionTools.Append(aPolyTopShape);
+  }
+  
+  while( anIter.hasNext() )
+  {
+    const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
+    if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
+      continue;
+    if (aSplitData.Shape.ShapeType() != TopAbs_EDGE)
+      continue;
+    if (HYDROData_BoundaryPolygonTools::IncludeTool(IncTools, aSplitData.Shape) && HYDROData_BoundaryPolygonTools::SelectionTool(SelectionTools, aSplitData.Shape))
+      outEdgesList.append(aSplitData);
+  }
+}
+
+
+static void SplitEdgesByBoundaryPolygons( const HYDROData_SplitToZonesTool::SplitDataList& anEdgesList,
+                                          const HYDROData_SequenceOfObjects& aBoundaryPolygons,
+                                          NCollection_IndexedDataMap<TopoDS_Shape, TopoDS_Shape>& ObjToRes)
+{
+  //perform boundary condition polygons on EdgesList
+  TopTools_SequenceOfShape CutTools;
+  ObjToRes.Clear();
+  HYDROData_SplitToZonesTool::SplitDataListIterator anIter(anEdgesList);
+  for (int i=1; i<=aBoundaryPolygons.Size();i++)
+  {
+    Handle(HYDROData_BCPolygon) aBCPoly = Handle(HYDROData_BCPolygon)::DownCast( aBoundaryPolygons(i));
+    TopoDS_Shape aPolyTopShape = aBCPoly->GetTopShape();
+    int bType = aBCPoly->GetBoundaryType();
+    if (bType == 1) 
+      CutTools.Append(aPolyTopShape);
+  }
+  
+  while( anIter.hasNext() )
+  {
+    const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
+    if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
+      continue;
+    if (aSplitData.Shape.ShapeType() != TopAbs_EDGE)
+      continue;
+    ObjToRes.Add(aSplitData.Shape, TopoDS_Shape());
+  }
+
+  HYDROData_BoundaryPolygonTools::CutTool(CutTools, ObjToRes);
+}
+
+
+static void PerformEdgeReplInZones(const HYDROData_SplitToZonesTool::SplitDataList& ZoneList,
+                                   const NCollection_IndexedDataMap<TopoDS_Shape, TopoDS_Shape>& ObjToRes,
+                                   HYDROData_SplitToZonesTool::SplitDataList& outZoneList)
+{
+  HYDROData_SplitToZonesTool::SplitDataListIterator it( ZoneList ); 
+  BRepTools_ReShape reshaper;
+  for (;it.hasNext();)
+  {
+    const HYDROData_SplitToZonesTool::SplitData& aSplitData = it.next();
+    if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
+      continue;
+
+    TopoDS_Shape mS = aSplitData.Shape;
+    for (int i=1; i<=ObjToRes.Extent();i++)
+    {
+      TopoDS_Shape K = ObjToRes.FindKey(i);
+      TopoDS_Shape V = ObjToRes.FindFromIndex(i);
+      if (V.ShapeType() != TopAbs_EDGE && V.ShapeType() != TopAbs_WIRE && V.ShapeType() != TopAbs_COMPOUND)
+        continue;
+      if (V.ShapeType() == TopAbs_COMPOUND)
+      {
+        TopExp_Explorer exp(V, TopAbs_EDGE);
+        TopTools_ListOfShape lE;
+        for (;exp.More();exp.Next())
+          lE.Append(exp.Current());
+        if (lE.Extent() == 1)
+          V = lE.First();
+        else if (lE.Extent() > 1)
+        {
+          BRepLib_MakeWire MW;
+          MW.Add(lE);
+          if (MW.IsDone())
+            V = MW.Wire();
+          else
+            continue;
+        }
+        else 
+          continue;
+      }
+      reshaper.Replace(K, V);
+    }
+    TopoDS_Shape nS = reshaper.Apply(mS);
+    HYDROData_SplitToZonesTool::SplitData aNS(aSplitData.Type, nS, aSplitData.ObjectNames);
+    outZoneList.append(aNS);
+  } 
+}
+
+static void CreateNewEdgeList( const HYDROData_SplitToZonesTool::SplitDataList& theEdges,
+                               const NCollection_IndexedDataMap<TopoDS_Shape, TopoDS_Shape>& ObjToRes,
+                               HYDROData_SplitToZonesTool::SplitDataList& newEdges)
+{
+  HYDROData_SplitToZonesTool::SplitDataListIterator anIter( theEdges );
+  while( anIter.hasNext() )
+  {
+    const HYDROData_SplitToZonesTool::SplitData& aSplitData = anIter.next();
+    if ( aSplitData.ObjectNames.isEmpty() || aSplitData.Shape.IsNull() )
+      continue;
+
+    const TopoDS_Shape* aDivShape = ObjToRes.Seek(aSplitData.Shape);
+    if (aDivShape)
+    {
+      TopExp_Explorer exp(*aDivShape, TopAbs_EDGE);
+      for (;exp.More();exp.Next())
+      {
+        HYDROData_SplitToZonesTool::SplitData anNewSData(aSplitData.Type, exp.Current(), aSplitData.ObjectNames);
+        newEdges.append(anNewSData);
+      }
+    }
+    else
+      newEdges.append(aSplitData);
+  }
+}
+
+
 void HYDROData_CalculationCase::Update()
 {
   HYDROData_Entity::Update();
@@ -309,17 +450,34 @@ void HYDROData_CalculationCase::Update()
     }
   }
 
+  //
+  //split edges by boundary polygons
+  HYDROData_SequenceOfObjects aBoundaryPolygons = GetBoundaryPolygons();
+  //edge to splitted edge (compound of edges or original edge)
+  NCollection_IndexedDataMap<TopoDS_Shape, TopoDS_Shape> ObjToRes;
+  //split edge list by BP
+  SplitEdgesByBoundaryPolygons(anEdgesList, aBoundaryPolygons, ObjToRes);
+  HYDROData_SplitToZonesTool::SplitDataList aNewZonesList;
+  //replace splitted edges in zone list (faces)
+  PerformEdgeReplInZones(aZonesList, ObjToRes, aNewZonesList);
+  //
+  //create new edges list based on splitting info from ObjToRes
+  HYDROData_SplitToZonesTool::SplitDataList newEdgesList1,newEdgesList2;
+  CreateNewEdgeList(anEdgesList, ObjToRes, newEdgesList1);
+  //filter out edges list by include&selection tools 
+  FilterEdgesByIncludeSelectionBoundaryPolygons(newEdgesList1,aBoundaryPolygons,newEdgesList2);
+  
   switch( GetAssignmentMode() )
   {
   case MANUAL:
-    CreateRegionsDef( aDocument, aZonesList );    
+    CreateRegionsDef( aDocument,aNewZonesList );    
     break;
   case AUTOMATIC:
-    CreateRegionsAuto( aDocument, aZonesList );    
+    CreateRegionsAuto( aDocument,aNewZonesList );    
     break;
   }
 
-  CreateEdgeGroupsDef( aDocument, anEdgesList );
+  CreateEdgeGroupsDef( aDocument, newEdgesList2 );
 }
 
 void HYDROData_CalculationCase::CreateRegionsDef( const Handle(HYDROData_Document)& theDoc,
@@ -459,7 +617,7 @@ void HYDROData_CalculationCase::CreateEdgeGroupsDef( const Handle(HYDROData_Docu
     if ( aSplitGroup.IsNull() )
       continue;
 
-    aSplitGroup->AddShape( aSplitData.Shape );
+      aSplitGroup->AddShape( aSplitData.Shape );
 
     TopTools_SequenceOfShape theShapes;
     aSplitGroup->GetShapes(theShapes);
@@ -1074,6 +1232,7 @@ bool HYDROData_CalculationCase::Export( GEOM::GEOM_Gen_var  theGeomEngine,
                                         QString& theErrorMsg,
                                         QString& statMess) const
 {
+  DEBTRACE("Export");
   HYDROData_ShapesGroup::SeqOfGroupsDefs aSeqOfGroupsDefs;
 
   // Get groups definitions
@@ -1352,8 +1511,8 @@ QString HYDROData_CalculationCase::DumpRules() const
 void HYDROData_CalculationCase::SetAssignmentMode( AssignmentMode theMode )
 {
   TDF_Label aModeLab = myLab.FindChild( DataTag_AssignmentMode );
-  TDataStd_Integer::Set( aModeLab, ( int ) theMode );
-
+  Handle(TDataStd_Integer) anAttr = TDataStd_Integer::Set( aModeLab, ( int ) theMode );
+  anAttr->SetID(TDataStd_Integer::GetID());
   // Indicate model of the need to update splitting
   Changed( Geom_2d );
 }
@@ -1485,5 +1644,35 @@ void HYDROData_CalculationCase::RemoveInterPolyObject( const Handle(HYDROData_Po
   Changed( Geom_2d );
 }
 
+bool HYDROData_CalculationCase::AddBoundaryPolygon( const Handle(HYDROData_BCPolygon)& theBCPolygon )
+{
+  HYDROData_CalculationCase::DataTag aDataTag = DataTag_BCPolygon;
+
+  if ( HasReference( theBCPolygon, aDataTag ) )
+    return false; 
+
+  AddReferenceObject( theBCPolygon, aDataTag );
+
+  Changed( Geom_2d );
+
+  return true;
+}
+
+HYDROData_SequenceOfObjects HYDROData_CalculationCase::GetBoundaryPolygons() const
+{
+  return GetReferenceObjects( DataTag_BCPolygon ); 
+}
+
+void HYDROData_CalculationCase::RemoveBoundaryPolygon( const Handle(HYDROData_BCPolygon)& theBCPolygon ) 
+{
+  if ( theBCPolygon.IsNull() )
+    return;
+
+  RemoveReferenceObject( theBCPolygon->Label(), DataTag_BCPolygon );
+
+  Changed( Geom_2d );
+}
+
+