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/
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 NMTAlgo_Builder::ComputeWithFiller(aDSF);
320 myIsComputed=Standard_True;
322 //=======================================================================
325 //=======================================================================
326 void NMTAlgo_Splitter::Build(const TopAbs_ShapeEnum aLimit)
332 myErrorStatus=102;// DS is not computed
336 TopoDS_Compound aCShape;
338 myBuilder.MakeCompound(aCShape);
343 if (myLimit==TopAbs_VERTEX) {
350 if (myLimit==TopAbs_EDGE) {
359 if (myLimit==TopAbs_WIRE) {
367 if (myLimit==TopAbs_FACE) {
373 // 5.6. SHELL / SOLID
375 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
377 //=======================================================================
378 // function: SplitsAndSections
380 //=======================================================================
381 void NMTAlgo_Splitter::SplitsAndSections()
383 Standard_Integer i, aNbE, aNbF;
384 TopTools_ListIteratorOfListOfShape aItLS, aIt;
385 TopTools_IndexedMapOfShape aME, aMF;
387 myQueryShapes.Clear();
389 // 1. Splits / no splits
390 aItLS.Initialize(myListShapes);
391 for ( ;aItLS.More(); aItLS.Next()) {
392 const TopoDS_Shape& aS=aItLS.Value();
394 if (myToolShapes.Contains(aS)) {
395 continue; // skip tool Shapes
398 TopExp::MapShapes(aS, TopAbs_EDGE, aME);
399 TopExp::MapShapes(aS, TopAbs_FACE, aMF);
402 // 1. Splits / no splits
404 for (i=1; i<=aNbE; ++i) {
405 const TopoDS_Shape& aE=aME(i);
407 if (!myImagesEdges.HasImage(aE)) {
408 myQueryShapes.Add(aE);
411 const TopTools_ListOfShape& aLSp=myImagesEdges.Image(aE);
413 aIt.Initialize(aLSp);
414 for (; aIt.More(); aIt.Next()) {
415 const TopoDS_Shape& aSp=aIt.Value();
416 myQueryShapes.Add(aSp);
423 for (i=1; i<=aNbF; ++i) {
424 const TopoDS_Shape& aF=aMF(i);
425 if (mySectionParts.Contains(aF)) {
426 const TopTools_ListOfShape& aLSc=mySectionParts.FindFromKey(aF);
427 aIt.Initialize(aLSc);
428 for (; aIt.More(); aIt.Next()) {
429 const TopoDS_Shape& aSc=aIt.Value();
430 myQueryShapes.Add(aSc);
435 //=======================================================================
436 // function: SplittedWires
438 //=======================================================================
439 void NMTAlgo_Splitter::SplittedWires()
441 Standard_Integer i, aNbF;
443 TopTools_IndexedMapOfShape aMF;
448 myQueryShapes.Clear();
451 for (i=1; i<=aNbF; ++i) {
452 const TopoDS_Shape& aF=aMF(i);
454 for (; aIt.More(); aIt.Next()) {
455 const TopoDS_Shape& aW=aIt.Value();
456 myQueryShapes.Add(aW);
460 //=======================================================================
461 // function: SplittedFaces
463 //=======================================================================
464 void NMTAlgo_Splitter::SplittedFaces()
466 TopTools_ListIteratorOfListOfShape aIt;
467 TopoDS_Iterator aItF;
469 myQueryShapes.Clear();
471 aIt.Initialize(myListShapes);
472 for (; aIt.More(); aIt.Next()) {
473 const TopoDS_Shape& aS=aIt.Value();
475 if (myToolShapes.Contains(aS)) {
479 const TopoDS_Shape& aFC = myImageShape.Image(aS).First();
480 aItF.Initialize(aFC);
481 for (; aItF.More(); aItF.Next()) {
482 const TopoDS_Shape& aF=aItF.Value();
483 myQueryShapes.Add(aF);
487 //=======================================================================
488 //function : FillImageShape
490 //=======================================================================
491 void NMTAlgo_Splitter::FillImageShape()
493 Standard_Integer i, aNbF, iSense;
494 TopTools_ListIteratorOfListOfShape aItS, aItFI;
495 TopExp_Explorer aExp;
496 TopAbs_Orientation aOriFS;
497 TopoDS_Face aFIx, aFIy;
500 myImageShape.Clear();
501 //modified by NIZNHY-PKV Mon Jan 24 09:48:15 2005f
502 myModifiedFaces.Clear();
503 //modified by NIZNHY-PKV Mon Jan 24 09:48:18 2005t
505 aItS.Initialize(myListShapes);
506 for ( ;aItS.More(); aItS.Next()) {
507 const TopoDS_Shape& aS=aItS.Value();
509 myQueryShapes.Clear();
511 aExp.Init(aS, TopAbs_FACE);
512 for (; aExp.More(); aExp.Next()) {
513 const TopoDS_Face& aFS=TopoDS::Face(aExp.Current());
514 aOriFS= aFS.Orientation();
516 if (!myImagesFaces.HasImage(aFS)) {
517 myQueryShapes.Add(aFS);
518 //modified by NIZNHY-PKV Mon Jan 24 09:50:42 2005 f
519 if (!myModifiedFaces.IsBound(aFS)) {
520 TopTools_ListOfShape aLS;
523 myModifiedFaces.Bind(aFS, aLS);
525 //modified by NIZNHY-PKV Mon Jan 24 09:50:44 2005 t
529 const TopTools_ListOfShape& aLFI=myImagesFaces.Image(aFS);
530 aItFI.Initialize(aLFI);
531 for (; aItFI.More(); aItFI.Next()) {
532 const TopoDS_Face& aFI=TopoDS::Face(aItFI.Value());
534 aFIx.Orientation(aOriFS);
536 if (mySDFaces.Contains(aFIx)) {
537 const TopoDS_Face& aFSDI=TopoDS::Face(mySDFaces.FindFromKey(aFIx));
538 TopoDS_Face aFSDIx=aFSDI;
540 iSense=NMTAlgo_Tools::Sense(aFIx, aFSDIx);
545 myQueryShapes.Add(aFSDIx);
546 //modified by NIZNHY-PKV Mon Jan 24 09:56:06 2005f
548 //modified by NIZNHY-PKV Mon Jan 24 09:56:09 2005t
551 myQueryShapes.Add(aFIx);
552 //modified by NIZNHY-PKV Mon Jan 24 09:56:06 2005f
554 //modified by NIZNHY-PKV Mon Jan 24 09:56:09 2005t
556 //modified by NIZNHY-PKV Mon Jan 24 09:53:38 2005f
557 if (!myModifiedFaces.IsBound(aFS)) {
558 TopTools_ListOfShape aLS;
561 myModifiedFaces.Bind(aFS, aLS);
564 TopTools_ListOfShape& aLS=myModifiedFaces.ChangeFind(aFS);
567 //modified by NIZNHY-PKV Mon Jan 24 09:53:43 2005t
569 }//for (; aExp.More(); aExp.Next()) {
571 TopoDS_Compound aCompound;
573 aBB.MakeCompound(aCompound);
575 aNbF=myQueryShapes.Extent();
576 for (i=1; i<=aNbF; ++i) {
577 const TopoDS_Shape& aF=myQueryShapes(i);
578 aBB.Add(aCompound, aF);
581 myImageShape.Bind(aS, aCompound);
582 }// for ( ;aItS.More(); aItS.Next())
584 myQueryShapes.Clear();
586 //=======================================================================
587 //function : FillResult
589 //=======================================================================
590 void NMTAlgo_Splitter::FillResult()
592 Standard_Integer i, aNb;
594 aNb=myQueryShapes.Extent();
595 for (i=1; i<=aNb; ++i) {
596 const TopoDS_Shape& aS=myQueryShapes(i);
597 myBuilder.Add (myShape, aS);
599 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
601 //=======================================================================
602 //function : isClosed
603 //purpose : check id a shape is closed, ie is a solid or a closed shell
604 //=======================================================================
605 Standard_Boolean isClosed(const TopoDS_Shape& theShape)
607 Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID);
609 if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) {
610 TopTools_IndexedDataMapOfShapeListOfShape MEF;
611 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF);
612 for (Standard_Integer i=1; isClosed && i<=MEF.Extent(); ++i)
613 isClosed = ( MEF(i).Extent() != 1 );
621 // 100 - DS is already computed
622 // 101 - Null shape is not allowed here
623 // 102 - DS is not computed
624 // 103 - No source shapes to treat