2 #include "HYDROData_SplitToZonesTool.h"
4 #include "HYDROData_PolylineXY.h"
5 #include "HYDROData_ShapesGroup.h"
6 #include <HYDROData_Transform.h>
7 #include <BRepAlgoAPI_Cut.hxx>
8 #include <BRepAlgoAPI_Common.hxx>
9 #include <BRepBuilderAPI_MakeFace.hxx>
10 #include <BRep_Builder.hxx>
11 #include <TopExp_Explorer.hxx>
13 #include <TopoDS_Shape.hxx>
14 #include <TopoDS_Compound.hxx>
15 #include <TopoDS_Wire.hxx>
16 #include <TopoDS_Edge.hxx>
17 #include <BRepCheck_Analyzer.hxx>
18 #include <TopTools_ListOfShape.hxx>
19 #include <TopTools_ListIteratorOfListOfShape.hxx>
21 #include <BRepGProp.hxx>
22 #include <GProp_GProps.hxx>
23 #include <Geom_Plane.hxx>
24 #include <BRepBuilderAPI_FindPlane.hxx>
26 #define DEB_SPLIT_TO_ZONES 1
27 #define DEB_SPLIT_TO_ZONES_CHECK_PARTITION 1
28 #if (defined (DEB_SPLIT_TO_ZONES) || defined(DEB_SPLIT_TO_ZONES_CHECK_PARTITION))
29 #include <BRepTools.hxx>
30 static TCollection_AsciiString fileNameBefore("BeforeTranslation");
33 TopoDS_Face HYDROData_SplitToZonesTool::SplitData::Face() const
39 if ( Shape.ShapeType() == TopAbs_FACE )
41 aResFace = TopoDS::Face( Shape );
43 else if ( Shape.ShapeType() == TopAbs_WIRE )
45 BRepBuilderAPI_MakeFace aMakeFace( TopoDS::Wire( Shape ), Standard_True );
47 if( aMakeFace.IsDone() )
48 aResFace = aMakeFace.Face();
55 Standard_Boolean buildLimFace(const TopoDS_Wire& theBndWire, TopoDS_Face& outFace)
58 BRepGProp::LinearProperties(theBndWire,G);
59 const gp_Pnt& aCPnt = G.CentreOfMass();
61 BRepBuilderAPI_FindPlane fndPlane (theBndWire, Precision::Confusion());
63 aPln = fndPlane.Plane()->Pln();
65 aPln = gp_Pln(aCPnt, gp::OZ().Direction());
66 BRepBuilderAPI_MakeFace aMkFace(aPln, theBndWire);
67 if(aMkFace.IsDone()) {
68 outFace = aMkFace.Face();
69 if(!outFace.IsNull()) {
70 #ifdef DEB_SPLIT_TO_ZONES
71 // BRepTools::Write(limFace,"FL.brep");
76 return Standard_False;
78 //======================================================================================
79 Standard_Integer HYDROData_SplitToZonesTool::SplitFaces(const TopoDS_Compound& theComp,
80 HYDROData_Transform& theTool)
83 theTool.SetArgument(theComp);
85 const Standard_Boolean bToTransform = theTool.ToTransform();
86 theTool.SetToTransform(bToTransform);
88 Standard_Integer anErr = theTool.ErrorStatus();
92 //======================================================================================
93 HYDROData_SplitToZonesTool::SplitDataList
94 HYDROData_SplitToZonesTool::Split( const HYDROData_SequenceOfObjects& theObjectList,
95 const HYDROData_SequenceOfObjects& theGroupsList,
96 const Handle(HYDROData_PolylineXY)& thePolyline )
98 SplitDataList anOutputSplitDataList;
99 if(theObjectList.IsEmpty()) return anOutputSplitDataList;
101 // Collect the object shapes to split. InputDataList will contain elements which will hold shape & name_of_shape.
102 SplitDataList anInputSplitDataList;
103 TCollection_AsciiString aNam("Faces_");
104 for( int anIndex = 1, aLength = theObjectList.Length(); anIndex <= aLength; anIndex++ )
106 Handle(HYDROData_Object) aGeomObj =
107 Handle(HYDROData_Object)::DownCast( theObjectList.Value( anIndex ) );
108 if( aGeomObj.IsNull() )
111 TopoDS_Shape aShape = aGeomObj->GetTopShape();
112 if ( aShape.IsNull() )
114 //TCollection_AsciiString aName = aNam + anIndex + ".brep";
115 //BRepTools::Write(aShape, aName.ToCString());
117 if ( aShape.ShapeType() == TopAbs_COMPOUND ) {
118 // Create split data for each face contained in the compound
119 TopExp_Explorer anExp( aShape, TopAbs_FACE );
120 for ( ; anExp.More(); anExp.Next() ) {
121 const TopoDS_Face& aFace = TopoDS::Face( anExp.Current() );
122 if ( !aFace.IsNull() ) {
123 SplitData aSplitData( SplitData::Data_Zone, aFace, aGeomObj->GetName() );
124 anInputSplitDataList.append( aSplitData );
128 SplitData aSplitData( SplitData::Data_Zone, aShape, aGeomObj->GetName() );
129 anInputSplitDataList.append( aSplitData );
133 SplitDataList anInputGroupList;
134 for( int anIndex = 1; anIndex <= theGroupsList.Length(); anIndex++ )
136 Handle(HYDROData_ShapesGroup) aGeomGroup =
137 Handle(HYDROData_ShapesGroup)::DownCast( theGroupsList.Value( anIndex ) );
138 if( aGeomGroup.IsNull() )
141 TopTools_SequenceOfShape aGroupShapes;
142 aGeomGroup->GetShapes( aGroupShapes );
143 for( int i = 1, aNbShapes = aGroupShapes.Length(); i <= aNbShapes; i++ ) {
144 const TopoDS_Shape& aGroupShape = aGroupShapes.Value( i );
145 if ( aGroupShape.IsNull() )
148 if ( aGroupShape.ShapeType() == TopAbs_COMPOUND ) {
149 TopExp_Explorer anExp( aGroupShape, TopAbs_EDGE );
150 for ( ; anExp.More(); anExp.Next() ) {
151 const TopoDS_Edge& anEdge = TopoDS::Edge( anExp.Current() );
152 if ( !anEdge.IsNull() ) {
153 SplitData aSplitData( SplitData::Data_Edge, anEdge, aGeomGroup->GetName() );
154 anInputGroupList.append( aSplitData );
158 SplitData aSplitData( SplitData::Data_Edge, aGroupShape, aGeomGroup->GetName() );
159 anInputGroupList.append( aSplitData );
163 // If only one shape is given we don't split it
164 // algorithm just returns the unpacked input data
165 if(theObjectList.Size() == 1) {
166 anOutputSplitDataList.append(anInputSplitDataList);
167 if(!theGroupsList.IsEmpty() )
168 anOutputSplitDataList.append(anInputGroupList);
169 return anOutputSplitDataList;
171 HYDROData_DataMapOfShapeListOfString aDM3;
172 if(!anInputGroupList.isEmpty()) {// Old edge ==> List_Of_Names
173 QStringList aListOfNames;
174 for (int i=0;i < anInputGroupList.size() ;i++) {
175 const TopoDS_Shape& aSh = anInputGroupList.at(i).Shape;
176 aDM3.Bind(aSh, anInputGroupList.at(i).ObjectNames);
179 // Step 1. Prepare Partition structures.
180 BOPCol_ListOfShape aLS;
181 QStringList aListOfNames;
182 TopoDS_Compound aCmp;
184 aBB.MakeCompound(aCmp);
185 for (int i=0;i < anInputSplitDataList.size() ;i++) {
186 const TopoDS_Shape& aSh = anInputSplitDataList.at(i).Shape;
187 aDM3.Bind(aSh, anInputSplitDataList.at(i).ObjectNames);
190 //TCollection_AsciiString aName = aNam + i + ".brep";
191 //BRepTools::Write(aSh, aName.ToCString());
193 #ifdef DEB_SPLIT_TO_ZONES_CHECK_PARTITION
194 TCollection_AsciiString aNameBefore = fileNameBefore + ".brep";
195 BRepTools::Write(aCmp, aNameBefore.ToCString());
198 HYDROData_Transform splitTool;
199 const Standard_Integer anErr = SplitFaces(aCmp, splitTool);
201 return anOutputSplitDataList;
202 const TopoDS_Shape& aResult = splitTool.Shape();
203 if (aResult.IsNull())
204 return anOutputSplitDataList;
205 BRepCheck_Analyzer aCheck (aResult);
206 if(!aCheck.IsValid()) {
207 #ifdef DEB_SPLIT_TO_ZONES
208 cout << "result is not valid" <<endl;
209 BRepTools::Write(aResult, "SplitFacesNV.brep");
211 return anOutputSplitDataList;
213 #ifdef DEB_SPLIT_TO_ZONES
214 BRepTools::Write(aResult, "SplitFacesV.brep");
217 // Step 3. Collect history
218 HYDROData_DataMapOfShapeListOfShape aDM1;
219 BOPCol_ListIteratorOfListOfShape anIt(aLS);
220 TCollection_AsciiString aNamM ("EdgM_");
221 TCollection_AsciiString aNamG ("EdgG_");
222 for (int i =1;anIt.More();anIt.Next(),i++) {
223 Standard_Boolean foundF(Standard_False);
224 const TopTools_ListOfShape& aListOfNew = splitTool.Modified(anIt.Value());
225 if(!aListOfNew.IsEmpty())
226 foundF = Standard_True;
227 TopTools_ListOfShape aList;
228 TopTools_ListIteratorOfListOfShape it(aListOfNew);
229 for(;it.More();it.Next())
230 aList.Append(it.Value());
231 // Bug in History: partition should give only modified entities! => temporary solution is used
232 const TopTools_ListOfShape& aListOfGen = splitTool.Generated(anIt.Value());
233 if(!aListOfGen.IsEmpty())
234 foundF = Standard_True;
235 it.Initialize(aListOfGen);
236 for(;it.More();it.Next())
237 aList.Append(it.Value());
238 if(!foundF) // face is not modified
239 aList.Append (anIt.Value());
240 aDM1.Bind(anIt.Value(), aList);
241 #ifdef DEB_SPLIT_TO_ZONES
242 TCollection_AsciiString aName;
244 if(!anInputGroupList.isEmpty() ) { // 1
246 TopExp_Explorer exp (anIt.Value(), TopAbs_EDGE);
247 for (int j =1;exp.More();exp.Next(),j++) {
248 Standard_Boolean foundE(Standard_False);
249 const TopTools_ListOfShape& aListM = splitTool.Modified(exp.Current());
250 //cout << "NB_EDGE_M = " << aListM.Extent() <<endl;
251 if(aListM.Extent()) foundE = Standard_True;
252 it.Initialize(aListM);
253 for(int k=1;it.More();it.Next(),k++) {
254 aList.Append(it.Value());
255 //aName = aNamM + i + j +k +".brep";
256 //BRepTools::Write(it.Value(),aName.ToCString());
258 const TopTools_ListOfShape& aListG = splitTool.Generated(exp.Current());
259 if(aListG.Extent()) foundE = Standard_True;
260 it.Initialize(aListG);
261 for(int k=1;it.More();it.Next(),k++) {
262 aList.Append(it.Value());
263 //aName = aNamG + i + j +k +".brep";
264 //BRepTools::Write(it.Value(),aName.ToCString());
266 //cout << "NB_EDGE = " << aList.Extent() <<endl;
268 aList.Append (exp.Current());
269 #ifdef DEB_SPLIT_TO_ZONES
270 aName = aNamG + i + j +".brep";
271 //BRepTools::Write(exp.Current(),aName.ToCString());
272 cout << aName.ToCString()<< " = " << exp.Current().TShape() <<endl;
275 aDM1.Bind(exp.Current(), aList);
280 // aDM2: NewShape ==> ListOfOldShapes
281 HYDROData_DataMapOfShapeListOfShape aDM2;
282 // make limiting face
283 HYDROData_DataMapOfShapeListOfShape aDM4;
284 Standard_Boolean hasLimits(Standard_False);
285 if (! thePolyline.IsNull()) {
286 //const TopoDS_Shape aShape = thePolyline->GetShape();
287 const TopoDS_Wire aBndWire = TopoDS::Wire(thePolyline->GetShape());
288 if(!aBndWire.IsNull()) {
290 if(buildLimFace(aBndWire, limFace)) {
291 TopoDS_Shape aComResult;
292 BRepAlgoAPI_Common mkCom(aResult, limFace);
294 aComResult = mkCom.Shape();
295 BRepCheck_Analyzer aCheck (aComResult);
296 if(aCheck.IsValid()) {
297 #ifdef DEB_SPLIT_TO_ZONES
298 BRepTools::Write(aComResult,"CommonV.brep");
301 hasLimits = Standard_True; // DM2 should filled here
302 HYDROData_MapOfShape aView;
303 TopExp_Explorer exp (aResult, TopAbs_FACE);
304 for (int i =1;exp.More();exp.Next(),i++) {
305 const TopoDS_Shape& aFace = exp.Current();
306 if(!aFace.IsNull()) {
307 const TopTools_ListOfShape& aListOfNew = mkCom.Modified(aFace);
308 //cout << "Modified: " << aListOfNew.Extent() <<endl;
309 const TopTools_ListOfShape& aListOfGen = mkCom.Generated(aFace);
310 if(!aListOfNew.IsEmpty()) {
311 aDM4.Bind(aFace, aListOfNew);
312 //TCollection_AsciiString aName = aNam + i + ".brep";
313 //BRepTools::Write(aListOfNew.Last(), aName.ToCString());
316 if(!mkCom.IsDeleted(aFace)) {
317 if(!aListOfGen.IsEmpty()) {
318 aDM4.Bind(aFace, aListOfGen);
319 //TCollection_AsciiString aName = aNam + i + "g.brep";
320 //BRepTools::Write(aListOfGen.Last(), aName.ToCString());
323 TopTools_ListOfShape aList;
325 aDM4.Bind(aFace, aList); //the same face - not modified
329 TopExp_Explorer exp2 (aFace, TopAbs_EDGE);
330 for (int j =1;exp2.More();exp2.Next(),j++) {
331 const TopoDS_Shape& anEdge = exp2.Current();
332 if(!anEdge.IsNull()) {
333 if(aView.Contains(anEdge)) continue;
335 const TopTools_ListOfShape& aListOfNewEd = mkCom.Modified(anEdge);
336 const TopTools_ListOfShape& aListOfGenEd = mkCom.Generated(anEdge);
337 if(!aListOfNewEd.IsEmpty())
338 aDM4.Bind(anEdge, aListOfNewEd);
340 if(!mkCom.IsDeleted(anEdge)) {
341 if(!aListOfGenEd.IsEmpty()) {
342 aDM4.Bind(anEdge, aListOfGenEd);
344 TopTools_ListOfShape aList;
345 aList.Append(anEdge);
346 aDM4.Bind(anEdge, aList);//the same edge - not modified
353 } //end DM4 filling (phase 1)
354 //cout << "DM4 Ext = " <<aDM4.Extent() <<endl;
355 // phase 2 (from tool)
356 TopExp_Explorer expt (limFace, TopAbs_EDGE);
357 for(;expt.More();expt.Next()) {
358 const TopoDS_Shape& anEdge = expt.Current();
359 if(!anEdge.IsNull()) {
360 const TopTools_ListOfShape& aListOfNewEd = mkCom.Modified(anEdge);
361 const TopTools_ListOfShape& aListOfGenEd = mkCom.Generated(anEdge);
362 if(!aListOfNewEd.IsEmpty())
363 aDM4.Bind(anEdge, aListOfNewEd);
365 if(!mkCom.IsDeleted(anEdge)) {
366 if(!aListOfGenEd.IsEmpty()) {
367 aDM4.Bind(anEdge, aListOfGenEd);
369 TopTools_ListOfShape aList;
370 aList.Append(anEdge);
371 aDM4.Bind(anEdge, aList);//the same edge - not modified
377 //cout << "DM4 Ext = " <<aDM4.Extent() <<endl;
378 HYDROData_DataMapIteratorOfDataMapOfShapeListOfShape aMIt(aDM1);
379 //DM4 contains Old - New after common op. DM1: old - new after Split op.
380 for(;aMIt.More();aMIt.Next()) {
381 const TopoDS_Shape& aKey = aMIt.Key();
382 TopTools_ListOfShape aList;
384 const TopTools_ListOfShape& aListOfNew = aMIt.Value();
385 TopTools_ListIteratorOfListOfShape it(aListOfNew);
386 for(;it.More();it.Next()) {// iterate new: b1, b2, b3...
387 if(!aDM4.IsBound(it.Value())) // bi - is deleted
388 continue; // go to the next bi
390 const TopTools_ListOfShape& aListOfNew4 = aDM4.Find(it.Value());
391 TopTools_ListIteratorOfListOfShape it4(aListOfNew4); // {c1, c2, c3,...}
392 for(;it4.More();it4.Next()) {
393 if(!aDM2.IsBound(it4.Value()))
394 aDM2.Bind(it4.Value(), aList);
396 TopTools_ListOfShape& aList = aDM2.ChangeFind(it4.Value());
404 hasLimits = Standard_False;
405 #ifdef DEB_SPLIT_TO_ZONES
406 BRepTools::Write(aComResult,"CommonNV.brep");
414 HYDROData_DataMapIteratorOfDataMapOfShapeListOfShape aMIt(aDM1);
415 for(;aMIt.More();aMIt.Next()) {
416 const TopoDS_Shape& aKey = aMIt.Key();
417 TopTools_ListOfShape aList;
419 const TopTools_ListOfShape& aListOfNew = aMIt.Value();
420 TopTools_ListIteratorOfListOfShape it(aListOfNew);
421 for(;it.More();it.Next()) {
422 if(!aDM2.IsBound(it.Value()))
423 aDM2.Bind(it.Value(), aList);
425 TopTools_ListOfShape& aList = aDM2.ChangeFind(it.Value());
431 // Step 4. Fill output structure.
432 #ifdef DEB_SPLIT_TO_ZONES
433 TCollection_AsciiString aNam4 ("SC_");
435 HYDROData_DataMapIteratorOfDataMapOfShapeListOfShape aMIt(aDM2);
436 for(int i =1;aMIt.More();aMIt.Next(),i++) {
437 SplitData aDestSplitData;
438 const TopoDS_Shape& aKey = aMIt.Key(); //new
439 aDestSplitData.Shape = aKey;
440 if(aKey.ShapeType() == TopAbs_FACE)
441 aDestSplitData.Type = SplitData::Data_Zone;
443 aDestSplitData.Type = SplitData::Data_Edge;
444 #ifdef DEB_SPLIT_TO_ZONES
445 TCollection_AsciiString aName = aNam4 + i + ".brep";
446 BRepTools::Write(aKey,aName.ToCString());
450 QStringList aListOfNames; // names processing
451 const TopTools_ListOfShape& aListOfOld = aMIt.Value();
452 TopTools_ListIteratorOfListOfShape it(aListOfOld);
453 for(;it.More();it.Next()) {
454 const TopoDS_Shape& aSh = it.Value(); //old
455 if(aDM3.IsBound(aSh)) {
456 const QStringList& ObjectNames = aDM3.Find(aSh);
457 aListOfNames.append(ObjectNames);
458 #ifdef DEB_SPLIT_TO_ZONES
460 for ( int k = 1;k <= ObjectNames.length(); ++k ) {
461 QString aStr = ObjectNames.last();
462 cout << "Indx = " << i<< " k = " << k << " size = " <<ObjectNames.size() << " Name = "<<aStr.toStdString() <<endl;
468 aDestSplitData.ObjectNames = aListOfNames;
469 anOutputSplitDataList.append(aDestSplitData);
472 return anOutputSplitDataList;
475 bool HYDROData_SplitToZonesTool::SplitTwoData( const SplitData& theData1,
476 const SplitData& theData2,
477 SplitData& theData1Subtracted,
478 SplitData& theData2Subtracted,
479 SplitData& theDataIntersected )
481 const TopoDS_Shape& aShape1 = theData1.Shape;
482 const TopoDS_Shape& aShape2 = theData2.Shape;
484 const QStringList& anObjectNames1 = theData1.ObjectNames;
485 const QStringList& anObjectNames2 = theData2.ObjectNames;
487 BRepAlgoAPI_Common aCommon( aShape1, aShape2 );
488 TopoDS_Shape aCommonShape = aCommon.Shape();
489 if( aCommonShape.IsNull() )
491 theData1Subtracted = theData1;
492 theData2Subtracted = theData2;
496 BRepAlgoAPI_Cut aCut1( aShape1, aShape2 );
497 TopoDS_Shape aCut1Shape = aCut1.Shape();
499 BRepAlgoAPI_Cut aCut2( aShape2, aShape1 );
500 TopoDS_Shape aCut2Shape = aCut2.Shape();
502 theData1Subtracted = SplitData( SplitData::Data_Zone, aCut1Shape, anObjectNames1 );
503 theData2Subtracted = SplitData( SplitData::Data_Zone, aCut2Shape, anObjectNames2 );
504 theDataIntersected = SplitData( SplitData::Data_Zone, aCommonShape, anObjectNames1 + anObjectNames2 );
509 HYDROData_SplitToZonesTool::SplitDataList
510 HYDROData_SplitToZonesTool::ExtractSeparateData( const SplitData& theData )
512 SplitDataList aSplitDataList;
513 TopExp_Explorer anExp( theData.Shape, TopAbs_FACE );
514 for( ; anExp.More(); anExp.Next() )
516 TopoDS_Shape aShape = anExp.Current();
517 if( aShape.ShapeType() == TopAbs_FACE )
519 TopoDS_Face aFace = TopoDS::Face( aShape );
520 if( !aFace.IsNull() )
522 SplitData aSplitData( SplitData::Data_Zone, aFace, theData.ObjectNames );
523 aSplitDataList.append( aSplitData );
527 return aSplitDataList;