1 // Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 // File: NMTAlgo_Splitter.cxx
21 // Created: Thu Jan 29 17:13:03 2004
22 // Author: Peter KURNEV
26 #include <NMTAlgo_Splitter.ixx>
28 #include <Precision.hxx>
29 #include <TopAbs_Orientation.hxx>
31 #include <TopExp_Explorer.hxx>
33 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
34 #include <TopTools_DataMapOfShapeListOfShape.hxx>
35 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
36 #include <TopTools_IndexedMapOfShape.hxx>
37 #include <TopTools_ListIteratorOfListOfShape.hxx>
38 #include <TopTools_ListOfShape.hxx>
39 #include <TopTools_MapIteratorOfMapOfShape.hxx>
40 #include <TopTools_SequenceOfShape.hxx>
42 #include <Geom2d_Curve.hxx>
43 #include <Geom_Curve.hxx>
44 #include <Geom_Surface.hxx>
45 #include <Geom_TrimmedCurve.hxx>
47 #include <gp_Pnt2d.hxx>
51 #include <TopoDS_Compound.hxx>
52 #include <TopoDS_Edge.hxx>
53 #include <TopoDS_Face.hxx>
54 #include <TopoDS_Iterator.hxx>
55 #include <TopoDS_Shell.hxx>
56 #include <TopoDS_Solid.hxx>
57 #include <TopoDS_Vertex.hxx>
58 #include <TopoDS_Wire.hxx>
60 #include <BRepBndLib.hxx>
61 #include <BRepClass3d_SolidClassifier.hxx>
62 #include <BRepLib.hxx>
63 #include <BRep_Tool.hxx>
65 #include <Extrema_ExtPC.hxx>
66 #include <GeomAdaptor_Curve.hxx>
67 #include <TopOpeBRepTool_CurveTool.hxx>
69 #include <NMTTools_DSFiller.hxx>
70 #include <NMTAlgo_Tools.hxx>
71 #include <NMTAlgo_Loop3d.hxx>
72 #include <BOP_CorrectTolerances.hxx>
76 Standard_Boolean isClosed(const TopoDS_Shape& theShape);
78 //=======================================================================
79 //function : NMTAlgo_Spliter::NMTAlgo_Splitter
81 //=======================================================================
82 NMTAlgo_Splitter::NMTAlgo_Splitter()
88 //=======================================================================
89 // function: ~NMTAlgo_Splitter
91 //=======================================================================
92 NMTAlgo_Splitter::~NMTAlgo_Splitter()
100 //=======================================================================
101 // function: SourceShapes
103 //=======================================================================
104 const TopTools_ListOfShape& NMTAlgo_Splitter::SourceShapes()const
106 return mySourceShapes;
108 //=======================================================================
111 //=======================================================================
112 void NMTAlgo_Splitter::Clear()
114 NMTAlgo_Builder::Clear();
116 myListShapes.Clear();
119 myClosedShapes.Clear();
120 myEqualEdges.Clear();
121 myNewSection.Clear();
122 myWrappingSolid.Clear();
123 myFaceShapeMap.Clear();
124 myInternalFaces.Clear();
125 myIntNotClFaces.Clear();
127 myImageShape.Clear();
128 myAddedFacesMap.Clear();
130 myDoneStep = TopAbs_SHAPE;
131 myIsComputed=Standard_False;
132 mySourceShapes.Clear();
134 myToolShapes.Clear();
136 //modified by NIZNHY-PKV Mon Jan 24 09:47:37 2005f
137 myModifiedFaces.Clear();
138 //modified by NIZNHY-PKV Mon Jan 24 09:47:41 2005t
141 //=======================================================================
142 //function : AddShape
143 //purpose : add object Shape to be splited
144 //=======================================================================
145 void NMTAlgo_Splitter::AddShape(const TopoDS_Shape& aS)
149 // DS is already computed
155 // Null shape is not allowed here
160 TopAbs_ShapeEnum aType=aS.ShapeType();
162 if (aType < TopAbs_SOLID) {
163 // compound or compsolid
164 TopoDS_Iterator it (aS);
165 for (; it.More(); it.Next()) {
166 const TopoDS_Shape& aSS=it.Value();
168 // to know compound by shape
169 myFaceShapeMap.Bind(aSS, aS);
175 mySourceShapes.Append(aS);
178 TopExp_Explorer exp(aS, TopAbs_FACE);
180 // do not split edges and vertices
183 // not to add twice the same S
184 Standard_Integer nbFacesBefore = myMapFaces.Extent();
186 for (; exp.More(); exp.Next()) {
187 const TopoDS_Shape& aFace = exp.Current();
188 if (!myFaceShapeMap.IsBound(aFace)) {
189 // keep shape of tool face added as object
190 myFaceShapeMap.Bind(aFace, aS);
192 if (myMapFaces.Add(aFace)){
193 myImagesFaces.SetRoot(aFace);
197 if (nbFacesBefore == myMapFaces.Extent()){
200 // solids must be processed before all
201 if (aType==TopAbs_SOLID){
202 myListShapes.Prepend(aS);
205 myListShapes.Append(aS);
208 myClosedShapes.Add(aS);
211 //=======================================================================
213 //purpose : add cutting tool that will _NOT_ be in result
214 //=======================================================================
215 void NMTAlgo_Splitter::AddTool(const TopoDS_Shape& aS)
219 // DS is already computed
225 // Null shape is not allowed here
230 TopAbs_ShapeEnum aType=aS.ShapeType();
232 if (aType < TopAbs_SOLID) { // compound or compsolid
233 TopoDS_Iterator it (aS);
234 for (; it.More(); it.Next()) {
235 const TopoDS_Shape& aSS=it.Value();
237 myFaceShapeMap.Bind(aSS, aS); // to know compound by shape
242 myToolShapes.Add(aS);
243 mySourceShapes.Append(aS);
246 TopExp_Explorer exp(aS, TopAbs_FACE);
247 for (; exp.More(); exp.Next()) {
248 const TopoDS_Shape& aFace = exp.Current();
249 myMapTools.Add(aFace);
250 myFaceShapeMap.Bind(aFace, aS);
253 // solids must be processed before all
254 if (aType==TopAbs_SOLID){
255 myListShapes.Prepend(aS);
258 myListShapes.Append(aS);
262 myClosedShapes.Add(aS);
265 //=======================================================================
268 //=======================================================================
269 void NMTAlgo_Splitter::Compute()
271 if (!mySourceShapes.Extent()){
272 // No source shapes to treat
279 TopTools_ListIteratorOfListOfShape aIt;
281 aBB.MakeCompound(aCS);
283 aIt.Initialize(mySourceShapes);
284 for (; aIt.More(); aIt.Next()) {
285 const TopoDS_Shape& aS=aIt.Value();
289 NMTTools_DSFiller* pDSF=new NMTTools_DSFiller;
291 pDSF->SetCompositeShape(aCS);
294 myIsComputed=Standard_False;
296 NMTAlgo_Splitter::ComputeWithFiller(*pDSF);
298 //=======================================================================
299 // function: ComputeWithFiller
301 //=======================================================================
302 void NMTAlgo_Splitter::ComputeWithFiller(const NMTTools_DSFiller& aDSF)
307 // DS is already computed
312 if (!mySourceShapes.Extent()) {
313 // No source shapes to treat
318 if (!aDSF.IsDone()) {
319 // NMTTools_DSFiller failed
324 NMTAlgo_Builder::ComputeWithFiller(aDSF);
326 myIsComputed=Standard_True;
328 //=======================================================================
331 //=======================================================================
332 void NMTAlgo_Splitter::Build(const TopAbs_ShapeEnum aLimit)
338 myErrorStatus=102;// DS is not computed
342 TopoDS_Compound aCShape;
344 myBuilder.MakeCompound(aCShape);
349 if (myLimit==TopAbs_VERTEX) {
356 if (myLimit==TopAbs_EDGE) {
365 if (myLimit==TopAbs_WIRE) {
373 if (myLimit==TopAbs_FACE) {
379 // 5.6. SHELL / SOLID
381 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
383 //=======================================================================
384 // function: SplitsAndSections
386 //=======================================================================
387 void NMTAlgo_Splitter::SplitsAndSections()
389 Standard_Integer i, aNbE, aNbF;
390 TopTools_ListIteratorOfListOfShape aItLS, aIt;
391 TopTools_IndexedMapOfShape aME, aMF;
393 myQueryShapes.Clear();
395 // 1. Splits / no splits
396 aItLS.Initialize(myListShapes);
397 for ( ;aItLS.More(); aItLS.Next()) {
398 const TopoDS_Shape& aS=aItLS.Value();
400 if (myToolShapes.Contains(aS)) {
401 continue; // skip tool Shapes
404 TopExp::MapShapes(aS, TopAbs_EDGE, aME);
405 TopExp::MapShapes(aS, TopAbs_FACE, aMF);
408 // 1. Splits / no splits
410 for (i=1; i<=aNbE; ++i) {
411 const TopoDS_Shape& aE=aME(i);
413 if (!myImagesEdges.HasImage(aE)) {
414 myQueryShapes.Add(aE);
417 const TopTools_ListOfShape& aLSp=myImagesEdges.Image(aE);
419 aIt.Initialize(aLSp);
420 for (; aIt.More(); aIt.Next()) {
421 const TopoDS_Shape& aSp=aIt.Value();
422 myQueryShapes.Add(aSp);
429 for (i=1; i<=aNbF; ++i) {
430 const TopoDS_Shape& aF=aMF(i);
431 if (mySectionParts.Contains(aF)) {
432 const TopTools_ListOfShape& aLSc=mySectionParts.FindFromKey(aF);
433 aIt.Initialize(aLSc);
434 for (; aIt.More(); aIt.Next()) {
435 const TopoDS_Shape& aSc=aIt.Value();
436 myQueryShapes.Add(aSc);
441 //=======================================================================
442 // function: SplittedWires
444 //=======================================================================
445 void NMTAlgo_Splitter::SplittedWires()
447 Standard_Integer i, aNbF;
449 TopTools_IndexedMapOfShape aMF;
454 myQueryShapes.Clear();
457 for (i=1; i<=aNbF; ++i) {
458 const TopoDS_Shape& aF=aMF(i);
460 for (; aIt.More(); aIt.Next()) {
461 const TopoDS_Shape& aW=aIt.Value();
462 myQueryShapes.Add(aW);
466 //=======================================================================
467 // function: SplittedFaces
469 //=======================================================================
470 void NMTAlgo_Splitter::SplittedFaces()
472 TopTools_ListIteratorOfListOfShape aIt;
473 TopoDS_Iterator aItF;
475 myQueryShapes.Clear();
477 aIt.Initialize(myListShapes);
478 for (; aIt.More(); aIt.Next()) {
479 const TopoDS_Shape& aS=aIt.Value();
481 if (myToolShapes.Contains(aS)) {
485 const TopoDS_Shape& aFC = myImageShape.Image(aS).First();
486 aItF.Initialize(aFC);
487 for (; aItF.More(); aItF.Next()) {
488 const TopoDS_Shape& aF=aItF.Value();
489 myQueryShapes.Add(aF);
493 //=======================================================================
494 //function : FillImageShape
496 //=======================================================================
497 void NMTAlgo_Splitter::FillImageShape()
499 Standard_Integer i, aNbF, iSense;
500 TopTools_ListIteratorOfListOfShape aItS, aItFI;
501 TopExp_Explorer aExp;
502 TopAbs_Orientation aOriFS;
503 TopoDS_Face aFIx, aFIy;
506 myImageShape.Clear();
507 //modified by NIZNHY-PKV Mon Jan 24 09:48:15 2005f
508 myModifiedFaces.Clear();
509 //modified by NIZNHY-PKV Mon Jan 24 09:48:18 2005t
511 aItS.Initialize(myListShapes);
512 for ( ;aItS.More(); aItS.Next()) {
513 const TopoDS_Shape& aS=aItS.Value();
515 myQueryShapes.Clear();
517 aExp.Init(aS, TopAbs_FACE);
518 for (; aExp.More(); aExp.Next()) {
519 const TopoDS_Face& aFS=TopoDS::Face(aExp.Current());
520 aOriFS= aFS.Orientation();
522 if (!myImagesFaces.HasImage(aFS)) {
523 myQueryShapes.Add(aFS);
524 //modified by NIZNHY-PKV Mon Jan 24 09:50:42 2005 f
525 if (!myModifiedFaces.IsBound(aFS)) {
526 TopTools_ListOfShape aLS;
529 myModifiedFaces.Bind(aFS, aLS);
531 //modified by NIZNHY-PKV Mon Jan 24 09:50:44 2005 t
535 const TopTools_ListOfShape& aLFI=myImagesFaces.Image(aFS);
536 aItFI.Initialize(aLFI);
537 for (; aItFI.More(); aItFI.Next()) {
538 const TopoDS_Face& aFI=TopoDS::Face(aItFI.Value());
540 aFIx.Orientation(aOriFS);
542 if (mySDFaces.Contains(aFIx)) {
543 const TopoDS_Face& aFSDI=TopoDS::Face(mySDFaces.FindFromKey(aFIx));
544 TopoDS_Face aFSDIx=aFSDI;
546 iSense=NMTAlgo_Tools::Sense(aFIx, aFSDIx);
551 myQueryShapes.Add(aFSDIx);
552 //modified by NIZNHY-PKV Mon Jan 24 09:56:06 2005f
554 //modified by NIZNHY-PKV Mon Jan 24 09:56:09 2005t
557 myQueryShapes.Add(aFIx);
558 //modified by NIZNHY-PKV Mon Jan 24 09:56:06 2005f
560 //modified by NIZNHY-PKV Mon Jan 24 09:56:09 2005t
562 //modified by NIZNHY-PKV Mon Jan 24 09:53:38 2005f
563 if (!myModifiedFaces.IsBound(aFS)) {
564 TopTools_ListOfShape aLS;
567 myModifiedFaces.Bind(aFS, aLS);
570 TopTools_ListOfShape& aLS=myModifiedFaces.ChangeFind(aFS);
573 //modified by NIZNHY-PKV Mon Jan 24 09:53:43 2005t
575 }//for (; aExp.More(); aExp.Next()) {
577 TopoDS_Compound aCompound;
579 aBB.MakeCompound(aCompound);
581 aNbF=myQueryShapes.Extent();
582 for (i=1; i<=aNbF; ++i) {
583 const TopoDS_Shape& aF=myQueryShapes(i);
584 aBB.Add(aCompound, aF);
587 myImageShape.Bind(aS, aCompound);
588 }// for ( ;aItS.More(); aItS.Next())
590 myQueryShapes.Clear();
592 //=======================================================================
593 //function : FillResult
595 //=======================================================================
596 void NMTAlgo_Splitter::FillResult()
598 Standard_Integer i, aNb;
600 aNb=myQueryShapes.Extent();
601 for (i=1; i<=aNb; ++i) {
602 const TopoDS_Shape& aS=myQueryShapes(i);
603 myBuilder.Add (myShape, aS);
605 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
607 //=======================================================================
608 //function : isClosed
609 //purpose : check id a shape is closed, ie is a solid or a closed shell
610 //=======================================================================
611 Standard_Boolean isClosed(const TopoDS_Shape& theShape)
613 Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID);
615 if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) {
616 TopTools_IndexedDataMapOfShapeListOfShape MEF;
617 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF);
618 for (Standard_Integer i=1; isClosed && i<=MEF.Extent(); ++i)
619 isClosed = ( MEF(i).Extent() != 1 );
627 // 100 - DS is already computed
628 // 101 - Null shape is not allowed here
629 // 102 - DS is not computed
630 // 103 - No source shapes to treat
631 // 104 - NMTTools_DSFiller failed