Salome HOME
Methods to work with imagw references:
[modules/hydro.git] / src / HYDROData / HYDROData_SplitToZonesTool.cxx
1
2 #include "HYDROData_SplitToZonesTool.h"
3
4 #include "HYDROData_Object.h"
5
6 #include <BRepAlgoAPI_Common.hxx>
7 #include <BRepAlgoAPI_Cut.hxx>
8 #include <BRepBuilderAPI_MakeFace.hxx>
9
10 #include <TopExp_Explorer.hxx>
11 #include <TopoDS.hxx>
12 #include <TopoDS_Iterator.hxx>
13 #include <TopoDS_Wire.hxx>
14
15 TopoDS_Face HYDROData_SplitToZonesTool::SplitData::Face() const
16 {
17   TopoDS_Face aResFace;
18
19   if( !Shape.IsNull() )
20   {
21     if ( Shape.ShapeType() == TopAbs_FACE )
22     {
23       aResFace = TopoDS::Face( Shape );
24     }
25     else if ( Shape.ShapeType() == TopAbs_WIRE )
26     {
27       BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire( Shape ), Standard_True );
28       aMakeFace.Build();
29       if( aMakeFace.IsDone() )
30         aResFace = aMakeFace.Face();
31     }
32   }
33
34   return aResFace;
35 }
36
37 HYDROData_SplitToZonesTool::SplitDataList
38 HYDROData_SplitToZonesTool::SplitToZones( const HYDROData_SequenceOfObjects& theObjectList )
39 {
40   SplitDataList anOutputSplitDataList;
41
42   // Preparation. Collect the object shapes to split.
43   SplitDataList anInputSplitDataList;
44   for( int anIndex = 1, aLength = theObjectList.Length(); anIndex <= aLength; anIndex++ )
45   {
46     Handle(HYDROData_Object) aGeomObj = 
47       Handle(HYDROData_Object)::DownCast( theObjectList.Value( anIndex ) );
48     if( !aGeomObj.IsNull() )
49     {
50       SplitData aSplitData( aGeomObj->GetTopShape(), aGeomObj->GetName() );
51       anInputSplitDataList.append( aSplitData );
52     }
53   }
54
55   // Step 1. Split the paths.
56   SplitDataListIterator anInputIter( anInputSplitDataList );
57   while( anInputIter.hasNext() )
58   {
59     const SplitData& anInputSplitData = anInputIter.next();
60     if( anOutputSplitDataList.isEmpty() )
61       anOutputSplitDataList.append( anInputSplitData );
62     else
63     {
64       SplitDataList aSplitDataList;
65
66       SplitDataList aSrcSplitDataList;
67       aSrcSplitDataList.append( anInputSplitData );
68
69       SplitDataList aDestSplitDataList = anOutputSplitDataList;
70       anOutputSplitDataList.clear();
71
72       while( !aDestSplitDataList.isEmpty() )
73       {
74         SplitData aSrcSplitData = aSrcSplitDataList.last();
75
76         SplitData aDestSplitData = aDestSplitDataList.first();
77         aDestSplitDataList.pop_front();
78
79         SplitData aData1Subtracted, aData2Subtracted, aDataIntersected;
80         if( SplitTwoData( aSrcSplitData, aDestSplitData,
81                           aData1Subtracted, aData2Subtracted, aDataIntersected ) )
82           anOutputSplitDataList.append( aDataIntersected );
83         anOutputSplitDataList.append( aData2Subtracted );
84         aSrcSplitDataList.append( aData1Subtracted );
85       }
86
87       if( !aSrcSplitDataList.isEmpty() )
88         anOutputSplitDataList.append( aSrcSplitDataList.last() );
89     }
90   }
91
92   // Step 2. Take into account the boundary polyline.
93   /*
94   if( !thePolyline.IsNull() )
95   {
96     TopoDS_Wire aWire = TopoDS::Wire( thePolyline->GetTopShape() );
97     if( !aWire.IsNull() )
98     {
99       BRepBuilderAPI_MakeFace aMakeFace( aWire, Standard_True );
100       aMakeFace.Build();
101       if( aMakeFace.IsDone() )
102       {
103         SplitData aBoundarySplitData( aMakeFace.Face(), "" );
104
105         SplitDataList aCutSplitDataList;
106         SplitDataListIterator anOutputIter( anOutputSplitDataList );
107         while( anOutputIter.hasNext() )
108         {
109           const SplitData& anOutputSplitData = anOutputIter.next();
110
111           SplitData aData1Subtracted, aData2Subtracted, aDataIntersected;
112           if( SplitTwoData( anOutputSplitData, aBoundarySplitData,
113                             aData1Subtracted, aData2Subtracted, aDataIntersected ) )
114             aCutSplitDataList.append( aDataIntersected );
115         }
116         anOutputSplitDataList = aCutSplitDataList;
117       }
118     }
119   }
120   */
121
122   // Step 3. Extract the separate regions.
123   SplitDataList anExtractedSplitDataList;
124   SplitDataListIterator anOutputIter( anOutputSplitDataList );
125   while( anOutputIter.hasNext() )
126   {
127     const SplitData& anOutputSplitData = anOutputIter.next();
128     anExtractedSplitDataList.append( ExtractSeparateData( anOutputSplitData ) );
129   }
130
131   return anExtractedSplitDataList;
132 }
133
134 bool HYDROData_SplitToZonesTool::SplitTwoData( const SplitData& theData1,
135                                                const SplitData& theData2,
136                                                SplitData& theData1Subtracted,
137                                                SplitData& theData2Subtracted,
138                                                SplitData& theDataIntersected )
139 {
140   const TopoDS_Shape& aShape1 = theData1.Shape;
141   const TopoDS_Shape& aShape2 = theData2.Shape;
142
143   const QStringList& anObjectNames1 = theData1.ObjectNames;
144   const QStringList& anObjectNames2 = theData2.ObjectNames;
145
146   BRepAlgoAPI_Common aCommon( aShape1, aShape2 );
147   TopoDS_Shape aCommonShape = aCommon.Shape();
148   if( aCommonShape.IsNull() )
149   {
150     theData1Subtracted = theData1;
151     theData2Subtracted = theData2;
152     return false;
153   }
154
155   BRepAlgoAPI_Cut aCut1( aShape1, aShape2 );
156   TopoDS_Shape aCut1Shape = aCut1.Shape();
157
158   BRepAlgoAPI_Cut aCut2( aShape2, aShape1 );
159   TopoDS_Shape aCut2Shape = aCut2.Shape();
160
161   theData1Subtracted = SplitData( aCut1Shape, anObjectNames1 );
162   theData2Subtracted = SplitData( aCut2Shape, anObjectNames2 );
163   theDataIntersected = SplitData( aCommonShape, anObjectNames1 + anObjectNames2 );
164
165   return true;
166 }
167
168 HYDROData_SplitToZonesTool::SplitDataList
169 HYDROData_SplitToZonesTool::ExtractSeparateData( const SplitData& theData )
170 {
171   SplitDataList aSplitDataList;
172   TopExp_Explorer anExp( theData.Shape, TopAbs_FACE );
173   for( ; anExp.More(); anExp.Next() )
174   {
175     TopoDS_Shape aShape = anExp.Current();
176     if( aShape.ShapeType() == TopAbs_FACE )
177     {
178       TopoDS_Face aFace = TopoDS::Face( aShape );
179       if( !aFace.IsNull() )
180       {
181         SplitData aSplitData( aFace, theData.ObjectNames );
182         aSplitDataList.append( aSplitData );
183       }
184     }
185   }
186   return aSplitDataList;
187 }