1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "HYDROGUI_SplitZonesTool.h"
25 #include <HYDROData_Polyline.h>
26 #include <HYDROData_Zone.h>
28 #include <BRepAlgoAPI_Common.hxx>
29 #include <BRepAlgoAPI_Cut.hxx>
30 #include <BRepBuilderAPI_MakeFace.hxx>
31 #include <TopExp_Explorer.hxx>
33 #include <TopoDS_Iterator.hxx>
34 #include <TopoDS_Wire.hxx>
36 TopoDS_Face HYDROGUI_SplitZonesTool::SplitData::Face() const
38 if( !Shape.IsNull() && Shape.ShapeType() == TopAbs_FACE )
39 return TopoDS::Face( Shape );
43 HYDROGUI_SplitZonesTool::SplitDataList
44 HYDROGUI_SplitZonesTool::SplitZones( const HYDROData_SequenceOfObjects& theZoneList,
45 const Handle(HYDROData_Polyline)& thePolyline )
47 SplitDataList anOutputSplitDataList;
49 // Preparation. Collect the zone paths to split.
50 SplitDataList anInputSplitDataList;
51 for( int anIndex = 1, aLength = theZoneList.Length(); anIndex <= aLength; anIndex++ )
53 Handle(HYDROData_Zone) aZone = Handle(HYDROData_Zone)::DownCast( theZoneList.Value( anIndex ) );
56 SplitData aSplitData( aZone->Face(), aZone->GetName() );
57 anInputSplitDataList.append( aSplitData );
61 // Step 1. Split the paths.
62 SplitDataListIterator anInputIter( anInputSplitDataList );
63 while( anInputIter.hasNext() )
65 const SplitData& anInputSplitData = anInputIter.next();
66 if( anOutputSplitDataList.isEmpty() )
67 anOutputSplitDataList.append( anInputSplitData );
70 SplitDataList aSplitDataList;
72 SplitDataList aSrcSplitDataList;
73 aSrcSplitDataList.append( anInputSplitData );
75 SplitDataList aDestSplitDataList = anOutputSplitDataList;
76 anOutputSplitDataList.clear();
78 while( !aDestSplitDataList.isEmpty() )
80 SplitData aSrcSplitData = aSrcSplitDataList.last();
82 SplitData aDestSplitData = aDestSplitDataList.first();
83 aDestSplitDataList.pop_front();
85 SplitData aData1Subtracted, aData2Subtracted, aDataIntersected;
86 if( SplitTwoData( aSrcSplitData, aDestSplitData,
87 aData1Subtracted, aData2Subtracted, aDataIntersected ) )
88 anOutputSplitDataList.append( aDataIntersected );
89 anOutputSplitDataList.append( aData2Subtracted );
90 aSrcSplitDataList.append( aData1Subtracted );
93 if( !aSrcSplitDataList.isEmpty() )
94 anOutputSplitDataList.append( aSrcSplitDataList.last() );
98 // Step 2. Take into account the boundary polyline.
99 if( !thePolyline.IsNull() )
101 const TopoDS_Wire& aWire = thePolyline->Wire();
102 if( !aWire.IsNull() )
104 BRepBuilderAPI_MakeFace aMakeFace( aWire, Standard_True );
106 if( aMakeFace.IsDone() )
108 SplitData aBoundarySplitData( aMakeFace.Face(), "" );
110 SplitDataList aCutSplitDataList;
111 SplitDataListIterator anOutputIter( anOutputSplitDataList );
112 while( anOutputIter.hasNext() )
114 const SplitData& anOutputSplitData = anOutputIter.next();
116 SplitData aData1Subtracted, aData2Subtracted, aDataIntersected;
117 if( SplitTwoData( anOutputSplitData, aBoundarySplitData,
118 aData1Subtracted, aData2Subtracted, aDataIntersected ) )
119 aCutSplitDataList.append( aDataIntersected );
121 anOutputSplitDataList = aCutSplitDataList;
126 // Step 3. Extract the separate regions.
127 SplitDataList anExtractedSplitDataList;
128 SplitDataListIterator anOutputIter( anOutputSplitDataList );
129 while( anOutputIter.hasNext() )
131 const SplitData& anOutputSplitData = anOutputIter.next();
132 anExtractedSplitDataList.append( ExtractSeparateData( anOutputSplitData ) );
134 return anExtractedSplitDataList;
137 bool HYDROGUI_SplitZonesTool::SplitTwoData( const SplitData& theData1,
138 const SplitData& theData2,
139 SplitData& theData1Subtracted,
140 SplitData& theData2Subtracted,
141 SplitData& theDataIntersected )
143 const TopoDS_Shape& aShape1 = theData1.Shape;
144 const TopoDS_Shape& aShape2 = theData2.Shape;
146 const QStringList& aZoneNames1 = theData1.ZoneNames;
147 const QStringList& aZoneNames2 = theData2.ZoneNames;
149 BRepAlgoAPI_Common aCommon( aShape1, aShape2 );
150 TopoDS_Shape aCommonShape = aCommon.Shape();
151 if( aCommonShape.IsNull() )
153 theData1Subtracted = theData1;
154 theData2Subtracted = theData2;
158 BRepAlgoAPI_Cut aCut1( aShape1, aShape2 );
159 TopoDS_Shape aCut1Shape = aCut1.Shape();
161 BRepAlgoAPI_Cut aCut2( aShape2, aShape1 );
162 TopoDS_Shape aCut2Shape = aCut2.Shape();
164 theData1Subtracted = SplitData( aCut1Shape, aZoneNames1 );
165 theData2Subtracted = SplitData( aCut2Shape, aZoneNames2 );
166 theDataIntersected = SplitData( aCommonShape, aZoneNames1 + aZoneNames2 );
171 HYDROGUI_SplitZonesTool::SplitDataList
172 HYDROGUI_SplitZonesTool::ExtractSeparateData( const SplitData& theData )
174 SplitDataList aSplitDataList;
175 TopExp_Explorer anExp( theData.Shape, TopAbs_FACE );
176 for( ; anExp.More(); anExp.Next() )
178 TopoDS_Shape aShape = anExp.Current();
179 if( aShape.ShapeType() == TopAbs_FACE )
181 TopoDS_Face aFace = TopoDS::Face( aShape );
182 if( !aFace.IsNull() )
184 SplitData aSplitData( aFace, theData.ZoneNames );
185 aSplitDataList.append( aSplitData );
189 return aSplitDataList;