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();
119 //=======================================================================
120 //function : AddShape
121 //purpose : add object Shape to be splited
122 //=======================================================================
123 void NMTAlgo_Splitter::AddShape(const TopoDS_Shape& aS)
127 // DS is already computed
133 // Null shape is not allowed here
138 TopAbs_ShapeEnum aType=aS.ShapeType();
140 if (aType < TopAbs_SOLID) {
141 // compound or compsolid
142 TopoDS_Iterator it (aS);
143 for (; it.More(); it.Next()) {
144 const TopoDS_Shape& aSS=it.Value();
146 // to know compound by shape
147 myFaceShapeMap.Bind(aSS, aS);
153 mySourceShapes.Append(aS);
156 TopExp_Explorer exp(aS, TopAbs_FACE);
158 // do not split edges and vertices
161 // not to add twice the same S
162 Standard_Integer nbFacesBefore = myMapFaces.Extent();
164 for (; exp.More(); exp.Next()) {
165 const TopoDS_Shape& aFace = exp.Current();
166 if (!myFaceShapeMap.IsBound(aFace)) {
167 // keep shape of tool face added as object
168 myFaceShapeMap.Bind(aFace, aS);
170 if (myMapFaces.Add(aFace)){
171 myImagesFaces.SetRoot(aFace);
175 if (nbFacesBefore == myMapFaces.Extent()){
178 // solids must be processed before all
179 if (aType==TopAbs_SOLID){
180 myListShapes.Prepend(aS);
183 myListShapes.Append(aS);
186 myClosedShapes.Add(aS);
189 //=======================================================================
191 //purpose : add cutting tool that will _NOT_ be in result
192 //=======================================================================
193 void NMTAlgo_Splitter::AddTool(const TopoDS_Shape& aS)
197 // DS is already computed
203 // Null shape is not allowed here
208 TopAbs_ShapeEnum aType=aS.ShapeType();
210 if (aType < TopAbs_SOLID) { // compound or compsolid
211 TopoDS_Iterator it (aS);
212 for (; it.More(); it.Next()) {
213 const TopoDS_Shape& aSS=it.Value();
215 myFaceShapeMap.Bind(aSS, aS); // to know compound by shape
220 myToolShapes.Add(aS);
221 mySourceShapes.Append(aS);
224 TopExp_Explorer exp(aS, TopAbs_FACE);
225 for (; exp.More(); exp.Next()) {
226 const TopoDS_Shape& aFace = exp.Current();
227 myMapTools.Add(aFace);
228 myFaceShapeMap.Bind(aFace, aS);
231 // solids must be processed before all
232 if (aType==TopAbs_SOLID){
233 myListShapes.Prepend(aS);
236 myListShapes.Append(aS);
240 myClosedShapes.Add(aS);
243 //=======================================================================
246 //=======================================================================
247 void NMTAlgo_Splitter::Compute()
249 if (!mySourceShapes.Extent()){
250 // No source shapes to treat
257 TopTools_ListIteratorOfListOfShape aIt;
259 aBB.MakeCompound(aCS);
261 aIt.Initialize(mySourceShapes);
262 for (; aIt.More(); aIt.Next()) {
263 const TopoDS_Shape& aS=aIt.Value();
267 NMTTools_DSFiller* pDSF=new NMTTools_DSFiller;
269 pDSF->SetCompositeShape(aCS);
272 myIsComputed=Standard_False;
274 NMTAlgo_Splitter::ComputeWithFiller(*pDSF);
276 //=======================================================================
277 // function: ComputeWithFiller
279 //=======================================================================
280 void NMTAlgo_Splitter::ComputeWithFiller(const NMTTools_DSFiller& aDSF)
285 // DS is already computed
290 if (!mySourceShapes.Extent()){
291 // No source shapes to treat
296 NMTAlgo_Builder::ComputeWithFiller(aDSF);
298 myIsComputed=Standard_True;
300 //=======================================================================
303 //=======================================================================
304 void NMTAlgo_Splitter::Build(const TopAbs_ShapeEnum aLimit)
310 myErrorStatus=102;// DS is not computed
314 TopoDS_Compound aCShape;
316 myBuilder.MakeCompound(aCShape);
321 if (myLimit==TopAbs_VERTEX) {
328 if (myLimit==TopAbs_EDGE) {
337 if (myLimit==TopAbs_WIRE) {
345 if (myLimit==TopAbs_FACE) {
351 // 5.6. SHELL / SOLID
353 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
355 //=======================================================================
356 // function: SplitsAndSections
358 //=======================================================================
359 void NMTAlgo_Splitter::SplitsAndSections()
361 Standard_Integer i, aNbE, aNbF;
362 TopTools_ListIteratorOfListOfShape aItLS, aIt;
363 TopTools_IndexedMapOfShape aME, aMF;
365 myQueryShapes.Clear();
367 // 1. Splits / no splits
368 aItLS.Initialize(myListShapes);
369 for ( ;aItLS.More(); aItLS.Next()) {
370 const TopoDS_Shape& aS=aItLS.Value();
372 if (myToolShapes.Contains(aS)) {
373 continue; // skip tool Shapes
376 TopExp::MapShapes(aS, TopAbs_EDGE, aME);
377 TopExp::MapShapes(aS, TopAbs_FACE, aMF);
380 // 1. Splits / no splits
382 for (i=1; i<=aNbE; ++i) {
383 const TopoDS_Shape& aE=aME(i);
385 if (!myImagesEdges.HasImage(aE)) {
386 myQueryShapes.Add(aE);
389 const TopTools_ListOfShape& aLSp=myImagesEdges.Image(aE);
391 aIt.Initialize(aLSp);
392 for (; aIt.More(); aIt.Next()) {
393 const TopoDS_Shape& aSp=aIt.Value();
394 myQueryShapes.Add(aSp);
401 for (i=1; i<=aNbF; ++i) {
402 const TopoDS_Shape& aF=aMF(i);
403 if (mySectionParts.Contains(aF)) {
404 const TopTools_ListOfShape& aLSc=mySectionParts.FindFromKey(aF);
405 aIt.Initialize(aLSc);
406 for (; aIt.More(); aIt.Next()) {
407 const TopoDS_Shape& aSc=aIt.Value();
408 myQueryShapes.Add(aSc);
413 //=======================================================================
414 // function: SplittedWires
416 //=======================================================================
417 void NMTAlgo_Splitter::SplittedWires()
419 Standard_Integer i, aNbF;
421 TopTools_IndexedMapOfShape aMF;
426 myQueryShapes.Clear();
429 for (i=1; i<=aNbF; ++i) {
430 const TopoDS_Shape& aF=aMF(i);
432 for (; aIt.More(); aIt.Next()) {
433 const TopoDS_Shape& aW=aIt.Value();
434 myQueryShapes.Add(aW);
438 //=======================================================================
439 // function: SplittedFaces
441 //=======================================================================
442 void NMTAlgo_Splitter::SplittedFaces()
444 TopTools_ListIteratorOfListOfShape aIt;
445 TopoDS_Iterator aItF;
447 myQueryShapes.Clear();
449 aIt.Initialize(myListShapes);
450 for (; aIt.More(); aIt.Next()) {
451 const TopoDS_Shape& aS=aIt.Value();
453 if (myToolShapes.Contains(aS)) {
457 const TopoDS_Shape& aFC = myImageShape.Image(aS).First();
458 aItF.Initialize(aFC);
459 for (; aItF.More(); aItF.Next()) {
460 const TopoDS_Shape& aF=aItF.Value();
461 myQueryShapes.Add(aF);
465 //=======================================================================
466 //function : FillImageShape
468 //=======================================================================
469 void NMTAlgo_Splitter::FillImageShape()
471 Standard_Integer i, aNbF, iSense;
472 TopTools_ListIteratorOfListOfShape aItS, aItFI;
473 TopExp_Explorer aExp;
474 TopAbs_Orientation aOriFS;
478 myImageShape.Clear();
480 aItS.Initialize(myListShapes);
481 for ( ;aItS.More(); aItS.Next()) {
482 const TopoDS_Shape& aS=aItS.Value();
484 myQueryShapes.Clear();
486 aExp.Init(aS, TopAbs_FACE);
487 for (; aExp.More(); aExp.Next()) {
488 const TopoDS_Face& aFS=TopoDS::Face(aExp.Current());
489 aOriFS= aFS.Orientation();
491 if (!myImagesFaces.HasImage(aFS)) {
492 myQueryShapes.Add(aFS);
496 const TopTools_ListOfShape& aLFI=myImagesFaces.Image(aFS);
497 aItFI.Initialize(aLFI);
498 for (; aItFI.More(); aItFI.Next()) {
499 const TopoDS_Face& aFI=TopoDS::Face(aItFI.Value());
501 aFIx.Orientation(aOriFS);
503 if (mySDFaces.Contains(aFIx)) {
504 const TopoDS_Face& aFSDI=TopoDS::Face(mySDFaces.FindFromKey(aFIx));
505 TopoDS_Face aFSDIx=aFSDI;
507 iSense=NMTAlgo_Tools::Sense(aFIx, aFSDIx);
512 myQueryShapes.Add(aFSDIx);
515 myQueryShapes.Add(aFIx);
518 }//for (; aExp.More(); aExp.Next()) {
520 TopoDS_Compound aCompound;
522 aBB.MakeCompound(aCompound);
524 aNbF=myQueryShapes.Extent();
525 for (i=1; i<=aNbF; ++i) {
526 const TopoDS_Shape& aF=myQueryShapes(i);
527 aBB.Add(aCompound, aF);
530 myImageShape.Bind(aS, aCompound);
531 }// for ( ;aItS.More(); aItS.Next())
533 myQueryShapes.Clear();
535 //=======================================================================
536 //function : FillResult
538 //=======================================================================
539 void NMTAlgo_Splitter::FillResult()
541 Standard_Integer i, aNb;
543 aNb=myQueryShapes.Extent();
544 for (i=1; i<=aNb; ++i) {
545 const TopoDS_Shape& aS=myQueryShapes(i);
546 myBuilder.Add (myShape, aS);
548 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
550 //=======================================================================
551 //function : isClosed
552 //purpose : check id a shape is closed, ie is a solid or a closed shell
553 //=======================================================================
554 Standard_Boolean isClosed(const TopoDS_Shape& theShape)
556 Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID);
558 if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) {
559 TopTools_IndexedDataMapOfShapeListOfShape MEF;
560 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF);
561 for (Standard_Integer i=1; isClosed && i<=MEF.Extent(); ++i)
562 isClosed = ( MEF(i).Extent() != 1 );
570 // 100 - DS is already computed
571 // 101 - Null shape is not allowed here
572 // 102 - DS is not computed
573 // 103 - No source shapes to treat