2 #include "HYDROData_SplitToZonesTool.h"
4 #include "HYDROData_PolylineXY.h"
6 #include <BRepAlgoAPI_Common.hxx>
7 #include <BRepAlgoAPI_Cut.hxx>
8 #include <BRepBuilderAPI_MakeFace.hxx>
10 #include <TopExp_Explorer.hxx>
12 #include <TopoDS_Iterator.hxx>
13 #include <TopoDS_Wire.hxx>
15 TopoDS_Face HYDROData_SplitToZonesTool::SplitData::Face() const
21 if ( Shape.ShapeType() == TopAbs_FACE )
23 aResFace = TopoDS::Face( Shape );
25 else if ( Shape.ShapeType() == TopAbs_WIRE )
27 BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire( Shape ), Standard_True );
29 if( aMakeFace.IsDone() )
30 aResFace = aMakeFace.Face();
37 HYDROData_SplitToZonesTool::SplitDataList
38 HYDROData_SplitToZonesTool::Split( const HYDROData_SequenceOfObjects& theObjectList,
39 const HYDROData_SequenceOfObjects& theGroupsList,
40 const Handle(HYDROData_PolylineXY)& thePolyline )
42 SplitDataList anOutputSplitDataList;
44 // Preparation. Collect the object shapes to split.
45 SplitDataList anInputSplitDataList;
46 for( int anIndex = 1, aLength = theObjectList.Length(); anIndex <= aLength; anIndex++ )
48 Handle(HYDROData_Object) aGeomObj =
49 Handle(HYDROData_Object)::DownCast( theObjectList.Value( anIndex ) );
50 if( aGeomObj.IsNull() )
53 TopoDS_Shape aShape = aGeomObj->GetTopShape();
54 if ( aShape.IsNull() )
57 if ( aShape.ShapeType() == TopAbs_COMPOUND ) {
58 // Create split data for each face contained in the compound
59 TopExp_Explorer anExp( aShape, TopAbs_FACE );
60 for ( ; anExp.More(); anExp.Next() ) {
61 TopoDS_Face aFace = TopoDS::Face( anExp.Current() );
62 if ( !aFace.IsNull() ) {
63 SplitData aSplitData( SplitData::Data_Zone, aFace, aGeomObj->GetName() );
64 anInputSplitDataList.append( aSplitData );
68 SplitData aSplitData( SplitData::Data_Zone, aShape, aGeomObj->GetName() );
69 anInputSplitDataList.append( aSplitData );
73 // Step 1. Split the paths.
74 SplitDataListIterator anInputIter( anInputSplitDataList );
75 while( anInputIter.hasNext() )
77 const SplitData& anInputSplitData = anInputIter.next();
78 if( anOutputSplitDataList.isEmpty() )
79 anOutputSplitDataList.append( anInputSplitData );
82 SplitDataList aSplitDataList;
84 SplitDataList aSrcSplitDataList;
85 aSrcSplitDataList.append( anInputSplitData );
87 SplitDataList aDestSplitDataList = anOutputSplitDataList;
88 anOutputSplitDataList.clear();
90 while( !aDestSplitDataList.isEmpty() )
92 SplitData aSrcSplitData = aSrcSplitDataList.last();
94 SplitData aDestSplitData = aDestSplitDataList.first();
95 aDestSplitDataList.pop_front();
97 SplitData aData1Subtracted, aData2Subtracted, aDataIntersected;
98 if( SplitTwoData( aSrcSplitData, aDestSplitData,
99 aData1Subtracted, aData2Subtracted, aDataIntersected ) )
100 anOutputSplitDataList.append( aDataIntersected );
101 anOutputSplitDataList.append( aData2Subtracted );
102 aSrcSplitDataList.append( aData1Subtracted );
105 if( !aSrcSplitDataList.isEmpty() )
106 anOutputSplitDataList.append( aSrcSplitDataList.last() );
110 // Step 2. Take into account the boundary polyline.
111 if( !thePolyline.IsNull() )
113 TopoDS_Wire aWire = TopoDS::Wire( thePolyline->GetShape() );
114 if( !aWire.IsNull() )
116 BRepBuilderAPI_MakeFace aMakeFace( aWire, Standard_True );
118 if( aMakeFace.IsDone() )
120 SplitData aBoundarySplitData( SplitData::Data_Zone, aMakeFace.Face(), "" );
122 SplitDataList aCutSplitDataList;
123 SplitDataListIterator anOutputIter( anOutputSplitDataList );
124 while( anOutputIter.hasNext() )
126 const SplitData& anOutputSplitData = anOutputIter.next();
128 SplitData aData1Subtracted, aData2Subtracted, aDataIntersected;
129 if( SplitTwoData( anOutputSplitData, aBoundarySplitData,
130 aData1Subtracted, aData2Subtracted, aDataIntersected ) )
131 aCutSplitDataList.append( aDataIntersected );
133 anOutputSplitDataList = aCutSplitDataList;
138 // Step 3. Extract the separate regions.
139 SplitDataList anExtractedSplitDataList;
140 SplitDataListIterator anOutputIter( anOutputSplitDataList );
141 while( anOutputIter.hasNext() )
143 const SplitData& anOutputSplitData = anOutputIter.next();
144 anExtractedSplitDataList.append( ExtractSeparateData( anOutputSplitData ) );
147 return anExtractedSplitDataList;
150 bool HYDROData_SplitToZonesTool::SplitTwoData( const SplitData& theData1,
151 const SplitData& theData2,
152 SplitData& theData1Subtracted,
153 SplitData& theData2Subtracted,
154 SplitData& theDataIntersected )
156 const TopoDS_Shape& aShape1 = theData1.Shape;
157 const TopoDS_Shape& aShape2 = theData2.Shape;
159 const QStringList& anObjectNames1 = theData1.ObjectNames;
160 const QStringList& anObjectNames2 = theData2.ObjectNames;
162 BRepAlgoAPI_Common aCommon( aShape1, aShape2 );
163 TopoDS_Shape aCommonShape = aCommon.Shape();
164 if( aCommonShape.IsNull() )
166 theData1Subtracted = theData1;
167 theData2Subtracted = theData2;
171 BRepAlgoAPI_Cut aCut1( aShape1, aShape2 );
172 TopoDS_Shape aCut1Shape = aCut1.Shape();
174 BRepAlgoAPI_Cut aCut2( aShape2, aShape1 );
175 TopoDS_Shape aCut2Shape = aCut2.Shape();
177 theData1Subtracted = SplitData( SplitData::Data_Zone, aCut1Shape, anObjectNames1 );
178 theData2Subtracted = SplitData( SplitData::Data_Zone, aCut2Shape, anObjectNames2 );
179 theDataIntersected = SplitData( SplitData::Data_Zone, aCommonShape, anObjectNames1 + anObjectNames2 );
184 HYDROData_SplitToZonesTool::SplitDataList
185 HYDROData_SplitToZonesTool::ExtractSeparateData( const SplitData& theData )
187 SplitDataList aSplitDataList;
188 TopExp_Explorer anExp( theData.Shape, TopAbs_FACE );
189 for( ; anExp.More(); anExp.Next() )
191 TopoDS_Shape aShape = anExp.Current();
192 if( aShape.ShapeType() == TopAbs_FACE )
194 TopoDS_Face aFace = TopoDS::Face( aShape );
195 if( !aFace.IsNull() )
197 SplitData aSplitData( SplitData::Data_Zone, aFace, theData.ObjectNames );
198 aSplitDataList.append( aSplitData );
202 return aSplitDataList;