1 // File: NMTAlgo_Splitter.cxx
2 // Created: Thu Jan 29 17:13:03 2004
3 // Author: Peter KURNEV
7 #include <NMTAlgo_Splitter.ixx>
9 #include <Precision.hxx>
10 #include <TopAbs_Orientation.hxx>
12 #include <TopExp_Explorer.hxx>
14 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
15 #include <TopTools_DataMapOfShapeListOfShape.hxx>
16 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
17 #include <TopTools_IndexedMapOfShape.hxx>
18 #include <TopTools_ListIteratorOfListOfShape.hxx>
19 #include <TopTools_ListOfShape.hxx>
20 #include <TopTools_MapIteratorOfMapOfShape.hxx>
21 #include <TopTools_SequenceOfShape.hxx>
23 #include <Geom2d_Curve.hxx>
24 #include <Geom_Curve.hxx>
25 #include <Geom_Surface.hxx>
26 #include <Geom_TrimmedCurve.hxx>
28 #include <gp_Pnt2d.hxx>
32 #include <TopoDS_Compound.hxx>
33 #include <TopoDS_Edge.hxx>
34 #include <TopoDS_Face.hxx>
35 #include <TopoDS_Iterator.hxx>
36 #include <TopoDS_Shell.hxx>
37 #include <TopoDS_Solid.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Wire.hxx>
41 #include <BRepBndLib.hxx>
42 #include <BRepClass3d_SolidClassifier.hxx>
43 #include <BRepLib.hxx>
44 #include <BRep_Tool.hxx>
46 #include <Extrema_ExtPC.hxx>
47 #include <GeomAdaptor_Curve.hxx>
48 #include <TopOpeBRepTool_CurveTool.hxx>
50 #include <NMTTools_DSFiller.hxx>
51 #include <NMTAlgo_Tools.hxx>
52 #include <NMTAlgo_Loop3d.hxx>
53 #include <BOP_CorrectTolerances.hxx>
57 Standard_Boolean isClosed(const TopoDS_Shape& theShape);
59 //=======================================================================
60 //function : NMTAlgo_Spliter::NMTAlgo_Splitter
62 //=======================================================================
63 NMTAlgo_Splitter::NMTAlgo_Splitter()
69 //=======================================================================
70 // function: ~NMTAlgo_Splitter
72 //=======================================================================
73 NMTAlgo_Splitter::~NMTAlgo_Splitter()
81 //=======================================================================
82 // function: SourceShapes
84 //=======================================================================
85 const TopTools_ListOfShape& NMTAlgo_Splitter::SourceShapes()const
87 return mySourceShapes;
89 //=======================================================================
92 //=======================================================================
93 void NMTAlgo_Splitter::Clear()
95 NMTAlgo_Builder::Clear();
100 myClosedShapes.Clear();
101 myEqualEdges.Clear();
102 myNewSection.Clear();
103 myWrappingSolid.Clear();
104 myFaceShapeMap.Clear();
105 myInternalFaces.Clear();
106 myIntNotClFaces.Clear();
108 myImageShape.Clear();
109 myAddedFacesMap.Clear();
111 myDoneStep = TopAbs_SHAPE;
112 myIsComputed=Standard_False;
113 mySourceShapes.Clear();
115 myToolShapes.Clear();
117 //modified by NIZNHY-PKV Mon Jan 24 09:47:37 2005f
118 myModifiedFaces.Clear();
119 //modified by NIZNHY-PKV Mon Jan 24 09:47:41 2005t
122 //=======================================================================
123 //function : AddShape
124 //purpose : add object Shape to be splited
125 //=======================================================================
126 void NMTAlgo_Splitter::AddShape(const TopoDS_Shape& aS)
130 // DS is already computed
136 // Null shape is not allowed here
141 TopAbs_ShapeEnum aType=aS.ShapeType();
143 if (aType < TopAbs_SOLID) {
144 // compound or compsolid
145 TopoDS_Iterator it (aS);
146 for (; it.More(); it.Next()) {
147 const TopoDS_Shape& aSS=it.Value();
149 // to know compound by shape
150 myFaceShapeMap.Bind(aSS, aS);
156 mySourceShapes.Append(aS);
159 TopExp_Explorer exp(aS, TopAbs_FACE);
161 // do not split edges and vertices
164 // not to add twice the same S
165 Standard_Integer nbFacesBefore = myMapFaces.Extent();
167 for (; exp.More(); exp.Next()) {
168 const TopoDS_Shape& aFace = exp.Current();
169 if (!myFaceShapeMap.IsBound(aFace)) {
170 // keep shape of tool face added as object
171 myFaceShapeMap.Bind(aFace, aS);
173 if (myMapFaces.Add(aFace)){
174 myImagesFaces.SetRoot(aFace);
178 if (nbFacesBefore == myMapFaces.Extent()){
181 // solids must be processed before all
182 if (aType==TopAbs_SOLID){
183 myListShapes.Prepend(aS);
186 myListShapes.Append(aS);
189 myClosedShapes.Add(aS);
192 //=======================================================================
194 //purpose : add cutting tool that will _NOT_ be in result
195 //=======================================================================
196 void NMTAlgo_Splitter::AddTool(const TopoDS_Shape& aS)
200 // DS is already computed
206 // Null shape is not allowed here
211 TopAbs_ShapeEnum aType=aS.ShapeType();
213 if (aType < TopAbs_SOLID) { // compound or compsolid
214 TopoDS_Iterator it (aS);
215 for (; it.More(); it.Next()) {
216 const TopoDS_Shape& aSS=it.Value();
218 myFaceShapeMap.Bind(aSS, aS); // to know compound by shape
223 myToolShapes.Add(aS);
224 mySourceShapes.Append(aS);
227 TopExp_Explorer exp(aS, TopAbs_FACE);
228 for (; exp.More(); exp.Next()) {
229 const TopoDS_Shape& aFace = exp.Current();
230 myMapTools.Add(aFace);
231 myFaceShapeMap.Bind(aFace, aS);
234 // solids must be processed before all
235 if (aType==TopAbs_SOLID){
236 myListShapes.Prepend(aS);
239 myListShapes.Append(aS);
243 myClosedShapes.Add(aS);
246 //=======================================================================
249 //=======================================================================
250 void NMTAlgo_Splitter::Compute()
252 if (!mySourceShapes.Extent()){
253 // No source shapes to treat
260 TopTools_ListIteratorOfListOfShape aIt;
262 aBB.MakeCompound(aCS);
264 aIt.Initialize(mySourceShapes);
265 for (; aIt.More(); aIt.Next()) {
266 const TopoDS_Shape& aS=aIt.Value();
270 NMTTools_DSFiller* pDSF=new NMTTools_DSFiller;
272 pDSF->SetCompositeShape(aCS);
275 myIsComputed=Standard_False;
277 NMTAlgo_Splitter::ComputeWithFiller(*pDSF);
279 //=======================================================================
280 // function: ComputeWithFiller
282 //=======================================================================
283 void NMTAlgo_Splitter::ComputeWithFiller(const NMTTools_DSFiller& aDSF)
288 // DS is already computed
293 if (!mySourceShapes.Extent()){
294 // No source shapes to treat
299 NMTAlgo_Builder::ComputeWithFiller(aDSF);
301 myIsComputed=Standard_True;
303 //=======================================================================
306 //=======================================================================
307 void NMTAlgo_Splitter::Build(const TopAbs_ShapeEnum aLimit)
313 myErrorStatus=102;// DS is not computed
317 TopoDS_Compound aCShape;
319 myBuilder.MakeCompound(aCShape);
324 if (myLimit==TopAbs_VERTEX) {
331 if (myLimit==TopAbs_EDGE) {
340 if (myLimit==TopAbs_WIRE) {
348 if (myLimit==TopAbs_FACE) {
354 // 5.6. SHELL / SOLID
356 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
358 //=======================================================================
359 // function: SplitsAndSections
361 //=======================================================================
362 void NMTAlgo_Splitter::SplitsAndSections()
364 Standard_Integer i, aNbE, aNbF;
365 TopTools_ListIteratorOfListOfShape aItLS, aIt;
366 TopTools_IndexedMapOfShape aME, aMF;
368 myQueryShapes.Clear();
370 // 1. Splits / no splits
371 aItLS.Initialize(myListShapes);
372 for ( ;aItLS.More(); aItLS.Next()) {
373 const TopoDS_Shape& aS=aItLS.Value();
375 if (myToolShapes.Contains(aS)) {
376 continue; // skip tool Shapes
379 TopExp::MapShapes(aS, TopAbs_EDGE, aME);
380 TopExp::MapShapes(aS, TopAbs_FACE, aMF);
383 // 1. Splits / no splits
385 for (i=1; i<=aNbE; ++i) {
386 const TopoDS_Shape& aE=aME(i);
388 if (!myImagesEdges.HasImage(aE)) {
389 myQueryShapes.Add(aE);
392 const TopTools_ListOfShape& aLSp=myImagesEdges.Image(aE);
394 aIt.Initialize(aLSp);
395 for (; aIt.More(); aIt.Next()) {
396 const TopoDS_Shape& aSp=aIt.Value();
397 myQueryShapes.Add(aSp);
404 for (i=1; i<=aNbF; ++i) {
405 const TopoDS_Shape& aF=aMF(i);
406 if (mySectionParts.Contains(aF)) {
407 const TopTools_ListOfShape& aLSc=mySectionParts.FindFromKey(aF);
408 aIt.Initialize(aLSc);
409 for (; aIt.More(); aIt.Next()) {
410 const TopoDS_Shape& aSc=aIt.Value();
411 myQueryShapes.Add(aSc);
416 //=======================================================================
417 // function: SplittedWires
419 //=======================================================================
420 void NMTAlgo_Splitter::SplittedWires()
422 Standard_Integer i, aNbF;
424 TopTools_IndexedMapOfShape aMF;
429 myQueryShapes.Clear();
432 for (i=1; i<=aNbF; ++i) {
433 const TopoDS_Shape& aF=aMF(i);
435 for (; aIt.More(); aIt.Next()) {
436 const TopoDS_Shape& aW=aIt.Value();
437 myQueryShapes.Add(aW);
441 //=======================================================================
442 // function: SplittedFaces
444 //=======================================================================
445 void NMTAlgo_Splitter::SplittedFaces()
447 TopTools_ListIteratorOfListOfShape aIt;
448 TopoDS_Iterator aItF;
450 myQueryShapes.Clear();
452 aIt.Initialize(myListShapes);
453 for (; aIt.More(); aIt.Next()) {
454 const TopoDS_Shape& aS=aIt.Value();
456 if (myToolShapes.Contains(aS)) {
460 const TopoDS_Shape& aFC = myImageShape.Image(aS).First();
461 aItF.Initialize(aFC);
462 for (; aItF.More(); aItF.Next()) {
463 const TopoDS_Shape& aF=aItF.Value();
464 myQueryShapes.Add(aF);
468 //=======================================================================
469 //function : FillImageShape
471 //=======================================================================
472 void NMTAlgo_Splitter::FillImageShape()
474 Standard_Integer i, aNbF, iSense;
475 TopTools_ListIteratorOfListOfShape aItS, aItFI;
476 TopExp_Explorer aExp;
477 TopAbs_Orientation aOriFS;
478 TopoDS_Face aFIx, aFIy;
481 myImageShape.Clear();
482 //modified by NIZNHY-PKV Mon Jan 24 09:48:15 2005f
483 myModifiedFaces.Clear();
484 //modified by NIZNHY-PKV Mon Jan 24 09:48:18 2005t
486 aItS.Initialize(myListShapes);
487 for ( ;aItS.More(); aItS.Next()) {
488 const TopoDS_Shape& aS=aItS.Value();
490 myQueryShapes.Clear();
492 aExp.Init(aS, TopAbs_FACE);
493 for (; aExp.More(); aExp.Next()) {
494 const TopoDS_Face& aFS=TopoDS::Face(aExp.Current());
495 aOriFS= aFS.Orientation();
497 if (!myImagesFaces.HasImage(aFS)) {
498 myQueryShapes.Add(aFS);
499 //modified by NIZNHY-PKV Mon Jan 24 09:50:42 2005 f
500 if (!myModifiedFaces.IsBound(aFS)) {
501 TopTools_ListOfShape aLS;
504 myModifiedFaces.Bind(aFS, aLS);
506 //modified by NIZNHY-PKV Mon Jan 24 09:50:44 2005 t
510 const TopTools_ListOfShape& aLFI=myImagesFaces.Image(aFS);
511 aItFI.Initialize(aLFI);
512 for (; aItFI.More(); aItFI.Next()) {
513 const TopoDS_Face& aFI=TopoDS::Face(aItFI.Value());
515 aFIx.Orientation(aOriFS);
517 if (mySDFaces.Contains(aFIx)) {
518 const TopoDS_Face& aFSDI=TopoDS::Face(mySDFaces.FindFromKey(aFIx));
519 TopoDS_Face aFSDIx=aFSDI;
521 iSense=NMTAlgo_Tools::Sense(aFIx, aFSDIx);
526 myQueryShapes.Add(aFSDIx);
527 //modified by NIZNHY-PKV Mon Jan 24 09:56:06 2005f
529 //modified by NIZNHY-PKV Mon Jan 24 09:56:09 2005t
532 myQueryShapes.Add(aFIx);
533 //modified by NIZNHY-PKV Mon Jan 24 09:56:06 2005f
535 //modified by NIZNHY-PKV Mon Jan 24 09:56:09 2005t
537 //modified by NIZNHY-PKV Mon Jan 24 09:53:38 2005f
538 if (!myModifiedFaces.IsBound(aFS)) {
539 TopTools_ListOfShape aLS;
542 myModifiedFaces.Bind(aFS, aLS);
545 TopTools_ListOfShape& aLS=myModifiedFaces.ChangeFind(aFS);
548 //modified by NIZNHY-PKV Mon Jan 24 09:53:43 2005t
550 }//for (; aExp.More(); aExp.Next()) {
552 TopoDS_Compound aCompound;
554 aBB.MakeCompound(aCompound);
556 aNbF=myQueryShapes.Extent();
557 for (i=1; i<=aNbF; ++i) {
558 const TopoDS_Shape& aF=myQueryShapes(i);
559 aBB.Add(aCompound, aF);
562 myImageShape.Bind(aS, aCompound);
563 }// for ( ;aItS.More(); aItS.Next())
565 myQueryShapes.Clear();
567 //=======================================================================
568 //function : FillResult
570 //=======================================================================
571 void NMTAlgo_Splitter::FillResult()
573 Standard_Integer i, aNb;
575 aNb=myQueryShapes.Extent();
576 for (i=1; i<=aNb; ++i) {
577 const TopoDS_Shape& aS=myQueryShapes(i);
578 myBuilder.Add (myShape, aS);
580 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
582 //=======================================================================
583 //function : isClosed
584 //purpose : check id a shape is closed, ie is a solid or a closed shell
585 //=======================================================================
586 Standard_Boolean isClosed(const TopoDS_Shape& theShape)
588 Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID);
590 if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) {
591 TopTools_IndexedDataMapOfShapeListOfShape MEF;
592 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF);
593 for (Standard_Integer i=1; isClosed && i<=MEF.Extent(); ++i)
594 isClosed = ( MEF(i).Extent() != 1 );
602 // 100 - DS is already computed
603 // 101 - Null shape is not allowed here
604 // 102 - DS is not computed
605 // 103 - No source shapes to treat