1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // File: NMTAlgo_Splitter.cxx
23 // Created: Thu Jan 29 17:13:03 2004
24 // Author: Peter KURNEV
27 #include <NMTAlgo_Splitter.ixx>
29 #include <Precision.hxx>
30 #include <TopAbs_Orientation.hxx>
32 #include <TopExp_Explorer.hxx>
34 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
35 #include <TopTools_DataMapOfShapeListOfShape.hxx>
36 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
37 #include <TopTools_IndexedMapOfShape.hxx>
38 #include <TopTools_ListIteratorOfListOfShape.hxx>
39 #include <TopTools_ListOfShape.hxx>
40 #include <TopTools_MapIteratorOfMapOfShape.hxx>
41 #include <TopTools_SequenceOfShape.hxx>
43 #include <Geom2d_Curve.hxx>
44 #include <Geom_Curve.hxx>
45 #include <Geom_Surface.hxx>
46 #include <Geom_TrimmedCurve.hxx>
48 #include <gp_Pnt2d.hxx>
52 #include <TopoDS_Compound.hxx>
53 #include <TopoDS_Edge.hxx>
54 #include <TopoDS_Face.hxx>
55 #include <TopoDS_Iterator.hxx>
56 #include <TopoDS_Shell.hxx>
57 #include <TopoDS_Solid.hxx>
58 #include <TopoDS_Vertex.hxx>
59 #include <TopoDS_Wire.hxx>
61 #include <BRepBndLib.hxx>
62 #include <BRepClass3d_SolidClassifier.hxx>
63 #include <BRepLib.hxx>
64 #include <BRep_Tool.hxx>
66 #include <Extrema_ExtPC.hxx>
67 #include <GeomAdaptor_Curve.hxx>
68 #include <TopOpeBRepTool_CurveTool.hxx>
70 #include <NMTTools_DSFiller.hxx>
71 #include <NMTAlgo_Tools.hxx>
72 #include <NMTAlgo_Loop3d.hxx>
73 #include <BOP_CorrectTolerances.hxx>
77 Standard_Boolean isClosed(const TopoDS_Shape& theShape);
79 //=======================================================================
80 //function : NMTAlgo_Spliter::NMTAlgo_Splitter
82 //=======================================================================
83 NMTAlgo_Splitter::NMTAlgo_Splitter()
89 //=======================================================================
90 // function: ~NMTAlgo_Splitter
92 //=======================================================================
93 NMTAlgo_Splitter::~NMTAlgo_Splitter()
101 //=======================================================================
102 // function: SourceShapes
104 //=======================================================================
105 const TopTools_ListOfShape& NMTAlgo_Splitter::SourceShapes()const
107 return mySourceShapes;
109 //=======================================================================
112 //=======================================================================
113 void NMTAlgo_Splitter::Clear()
115 NMTAlgo_Builder::Clear();
117 myListShapes.Clear();
120 myClosedShapes.Clear();
121 myEqualEdges.Clear();
122 myNewSection.Clear();
123 myWrappingSolid.Clear();
124 myFaceShapeMap.Clear();
125 myInternalFaces.Clear();
126 myIntNotClFaces.Clear();
128 myImageShape.Clear();
129 myAddedFacesMap.Clear();
131 myDoneStep = TopAbs_SHAPE;
132 myIsComputed=Standard_False;
133 mySourceShapes.Clear();
135 myToolShapes.Clear();
137 //modified by NIZNHY-PKV Mon Jan 24 09:47:37 2005f
138 myModifiedFaces.Clear();
139 //modified by NIZNHY-PKV Mon Jan 24 09:47:41 2005t
142 //=======================================================================
143 //function : AddShape
144 //purpose : add object Shape to be splited
145 //=======================================================================
146 void NMTAlgo_Splitter::AddShape(const TopoDS_Shape& aS)
150 // DS is already computed
156 // Null shape is not allowed here
161 TopAbs_ShapeEnum aType=aS.ShapeType();
163 if (aType < TopAbs_SOLID) {
164 // compound or compsolid
165 TopoDS_Iterator it (aS);
166 for (; it.More(); it.Next()) {
167 const TopoDS_Shape& aSS=it.Value();
169 // to know compound by shape
170 myFaceShapeMap.Bind(aSS, aS);
176 mySourceShapes.Append(aS);
179 TopExp_Explorer exp(aS, TopAbs_FACE);
181 // do not split edges and vertices
184 // not to add twice the same S
185 Standard_Integer nbFacesBefore = myMapFaces.Extent();
187 for (; exp.More(); exp.Next()) {
188 const TopoDS_Shape& aFace = exp.Current();
189 if (!myFaceShapeMap.IsBound(aFace)) {
190 // keep shape of tool face added as object
191 myFaceShapeMap.Bind(aFace, aS);
193 if (myMapFaces.Add(aFace)){
194 myImagesFaces.SetRoot(aFace);
198 if (nbFacesBefore == myMapFaces.Extent()){
201 // solids must be processed before all
202 if (aType==TopAbs_SOLID){
203 myListShapes.Prepend(aS);
206 myListShapes.Append(aS);
209 myClosedShapes.Add(aS);
212 //=======================================================================
214 //purpose : add cutting tool that will _NOT_ be in result
215 //=======================================================================
216 void NMTAlgo_Splitter::AddTool(const TopoDS_Shape& aS)
220 // DS is already computed
226 // Null shape is not allowed here
231 TopAbs_ShapeEnum aType=aS.ShapeType();
233 if (aType < TopAbs_SOLID) { // compound or compsolid
234 TopoDS_Iterator it (aS);
235 for (; it.More(); it.Next()) {
236 const TopoDS_Shape& aSS=it.Value();
238 myFaceShapeMap.Bind(aSS, aS); // to know compound by shape
243 myToolShapes.Add(aS);
244 mySourceShapes.Append(aS);
247 TopExp_Explorer exp(aS, TopAbs_FACE);
248 for (; exp.More(); exp.Next()) {
249 const TopoDS_Shape& aFace = exp.Current();
250 myMapTools.Add(aFace);
251 myFaceShapeMap.Bind(aFace, aS);
254 // solids must be processed before all
255 if (aType==TopAbs_SOLID){
256 myListShapes.Prepend(aS);
259 myListShapes.Append(aS);
263 myClosedShapes.Add(aS);
266 //=======================================================================
269 //=======================================================================
270 void NMTAlgo_Splitter::Compute()
272 if (!mySourceShapes.Extent()){
273 // No source shapes to treat
280 TopTools_ListIteratorOfListOfShape aIt;
282 aBB.MakeCompound(aCS);
284 aIt.Initialize(mySourceShapes);
285 for (; aIt.More(); aIt.Next()) {
286 const TopoDS_Shape& aS=aIt.Value();
290 NMTTools_DSFiller* pDSF=new NMTTools_DSFiller;
292 pDSF->SetCompositeShape(aCS);
295 myIsComputed=Standard_False;
297 NMTAlgo_Splitter::ComputeWithFiller(*pDSF);
299 //=======================================================================
300 // function: ComputeWithFiller
302 //=======================================================================
303 void NMTAlgo_Splitter::ComputeWithFiller(const NMTTools_DSFiller& aDSF)
308 // DS is already computed
313 if (!mySourceShapes.Extent()) {
314 // No source shapes to treat
319 if (!aDSF.IsDone()) {
320 // NMTTools_DSFiller failed
325 NMTAlgo_Builder::ComputeWithFiller(aDSF);
327 myIsComputed=Standard_True;
329 //=======================================================================
332 //=======================================================================
333 void NMTAlgo_Splitter::Build(const TopAbs_ShapeEnum aLimit)
339 myErrorStatus=102;// DS is not computed
343 TopoDS_Compound aCShape;
345 myBuilder.MakeCompound(aCShape);
350 if (myLimit==TopAbs_VERTEX) {
357 if (myLimit==TopAbs_EDGE) {
366 if (myLimit==TopAbs_WIRE) {
374 if (myLimit==TopAbs_FACE) {
380 // 5.6. SHELL / SOLID
382 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
384 //=======================================================================
385 // function: SplitsAndSections
387 //=======================================================================
388 void NMTAlgo_Splitter::SplitsAndSections()
390 Standard_Integer i, aNbE, aNbF;
391 TopTools_ListIteratorOfListOfShape aItLS, aIt;
392 TopTools_IndexedMapOfShape aME, aMF;
394 myQueryShapes.Clear();
396 // 1. Splits / no splits
397 aItLS.Initialize(myListShapes);
398 for ( ;aItLS.More(); aItLS.Next()) {
399 const TopoDS_Shape& aS=aItLS.Value();
401 if (myToolShapes.Contains(aS)) {
402 continue; // skip tool Shapes
405 TopExp::MapShapes(aS, TopAbs_EDGE, aME);
406 TopExp::MapShapes(aS, TopAbs_FACE, aMF);
409 // 1. Splits / no splits
411 for (i=1; i<=aNbE; ++i) {
412 const TopoDS_Shape& aE=aME(i);
414 if (!myImagesEdges.HasImage(aE)) {
415 myQueryShapes.Add(aE);
418 const TopTools_ListOfShape& aLSp=myImagesEdges.Image(aE);
420 aIt.Initialize(aLSp);
421 for (; aIt.More(); aIt.Next()) {
422 const TopoDS_Shape& aSp=aIt.Value();
423 myQueryShapes.Add(aSp);
430 for (i=1; i<=aNbF; ++i) {
431 const TopoDS_Shape& aF=aMF(i);
432 if (mySectionParts.Contains(aF)) {
433 const TopTools_ListOfShape& aLSc=mySectionParts.FindFromKey(aF);
434 aIt.Initialize(aLSc);
435 for (; aIt.More(); aIt.Next()) {
436 const TopoDS_Shape& aSc=aIt.Value();
437 myQueryShapes.Add(aSc);
442 //=======================================================================
443 // function: SplittedWires
445 //=======================================================================
446 void NMTAlgo_Splitter::SplittedWires()
448 Standard_Integer i, aNbF;
450 TopTools_IndexedMapOfShape aMF;
455 myQueryShapes.Clear();
458 for (i=1; i<=aNbF; ++i) {
459 const TopoDS_Shape& aF=aMF(i);
461 for (; aIt.More(); aIt.Next()) {
462 const TopoDS_Shape& aW=aIt.Value();
463 myQueryShapes.Add(aW);
467 //=======================================================================
468 // function: SplittedFaces
470 //=======================================================================
471 void NMTAlgo_Splitter::SplittedFaces()
473 TopTools_ListIteratorOfListOfShape aIt;
474 TopoDS_Iterator aItF;
476 myQueryShapes.Clear();
478 aIt.Initialize(myListShapes);
479 for (; aIt.More(); aIt.Next()) {
480 const TopoDS_Shape& aS=aIt.Value();
482 if (myToolShapes.Contains(aS)) {
486 const TopoDS_Shape& aFC = myImageShape.Image(aS).First();
487 aItF.Initialize(aFC);
488 for (; aItF.More(); aItF.Next()) {
489 const TopoDS_Shape& aF=aItF.Value();
490 myQueryShapes.Add(aF);
494 //=======================================================================
495 //function : FillImageShape
497 //=======================================================================
498 void NMTAlgo_Splitter::FillImageShape()
500 Standard_Integer i, aNbF, iSense;
501 TopTools_ListIteratorOfListOfShape aItS, aItFI;
502 TopExp_Explorer aExp;
503 TopAbs_Orientation aOriFS;
504 TopoDS_Face aFIx, aFIy;
507 myImageShape.Clear();
508 //modified by NIZNHY-PKV Mon Jan 24 09:48:15 2005f
509 myModifiedFaces.Clear();
510 //modified by NIZNHY-PKV Mon Jan 24 09:48:18 2005t
512 aItS.Initialize(myListShapes);
513 for ( ;aItS.More(); aItS.Next()) {
514 const TopoDS_Shape& aS=aItS.Value();
516 myQueryShapes.Clear();
518 aExp.Init(aS, TopAbs_FACE);
519 for (; aExp.More(); aExp.Next()) {
520 const TopoDS_Face& aFS=TopoDS::Face(aExp.Current());
521 aOriFS= aFS.Orientation();
523 if (!myImagesFaces.HasImage(aFS)) {
524 myQueryShapes.Add(aFS);
525 //modified by NIZNHY-PKV Mon Jan 24 09:50:42 2005 f
526 if (!myModifiedFaces.IsBound(aFS)) {
527 TopTools_ListOfShape aLS;
530 myModifiedFaces.Bind(aFS, aLS);
532 //modified by NIZNHY-PKV Mon Jan 24 09:50:44 2005 t
536 const TopTools_ListOfShape& aLFI=myImagesFaces.Image(aFS);
537 aItFI.Initialize(aLFI);
538 for (; aItFI.More(); aItFI.Next()) {
539 const TopoDS_Face& aFI=TopoDS::Face(aItFI.Value());
541 aFIx.Orientation(aOriFS);
543 if (mySDFaces.Contains(aFIx)) {
544 const TopoDS_Face& aFSDI=TopoDS::Face(mySDFaces.FindFromKey(aFIx));
545 TopoDS_Face aFSDIx=aFSDI;
547 iSense=NMTAlgo_Tools::Sense(aFIx, aFSDIx);
552 myQueryShapes.Add(aFSDIx);
553 //modified by NIZNHY-PKV Mon Jan 24 09:56:06 2005f
555 //modified by NIZNHY-PKV Mon Jan 24 09:56:09 2005t
558 myQueryShapes.Add(aFIx);
559 //modified by NIZNHY-PKV Mon Jan 24 09:56:06 2005f
561 //modified by NIZNHY-PKV Mon Jan 24 09:56:09 2005t
563 //modified by NIZNHY-PKV Mon Jan 24 09:53:38 2005f
564 if (!myModifiedFaces.IsBound(aFS)) {
565 TopTools_ListOfShape aLS;
568 myModifiedFaces.Bind(aFS, aLS);
571 TopTools_ListOfShape& aLS=myModifiedFaces.ChangeFind(aFS);
574 //modified by NIZNHY-PKV Mon Jan 24 09:53:43 2005t
576 }//for (; aExp.More(); aExp.Next()) {
578 TopoDS_Compound aCompound;
580 aBB.MakeCompound(aCompound);
582 aNbF=myQueryShapes.Extent();
583 for (i=1; i<=aNbF; ++i) {
584 const TopoDS_Shape& aF=myQueryShapes(i);
585 aBB.Add(aCompound, aF);
588 myImageShape.Bind(aS, aCompound);
589 }// for ( ;aItS.More(); aItS.Next())
591 myQueryShapes.Clear();
593 //=======================================================================
594 //function : FillResult
596 //=======================================================================
597 void NMTAlgo_Splitter::FillResult()
599 Standard_Integer i, aNb;
601 aNb=myQueryShapes.Extent();
602 for (i=1; i<=aNb; ++i) {
603 const TopoDS_Shape& aS=myQueryShapes(i);
604 myBuilder.Add (myShape, aS);
606 BOP_CorrectTolerances::CorrectTolerances(myShape, 0.01);
608 //=======================================================================
609 //function : isClosed
610 //purpose : check id a shape is closed, ie is a solid or a closed shell
611 //=======================================================================
612 Standard_Boolean isClosed(const TopoDS_Shape& theShape)
614 Standard_Boolean isClosed = (theShape.ShapeType() == TopAbs_SOLID);
616 if (!isClosed && theShape.ShapeType() == TopAbs_SHELL) {
617 TopTools_IndexedDataMapOfShapeListOfShape MEF;
618 TopExp::MapShapesAndAncestors(theShape, TopAbs_EDGE, TopAbs_FACE, MEF);
619 for (Standard_Integer i=1; isClosed && i<=MEF.Extent(); ++i)
620 isClosed = ( MEF(i).Extent() != 1 );
628 // 100 - DS is already computed
629 // 101 - Null shape is not allowed here
630 // 102 - DS is not computed
631 // 103 - No source shapes to treat
632 // 104 - NMTTools_DSFiller failed