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_1.cxx
23 // Created: Mon Feb 2 14:58:54 2004
24 // Author: Peter KURNEV
27 #include <NMTAlgo_Splitter.ixx>
29 #include <Precision.hxx>
33 #include <TopAbs_ShapeEnum.hxx>
36 #include <TopoDS_Edge.hxx>
37 #include <TopoDS_Face.hxx>
38 #include <TopoDS_Shape.hxx>
39 #include <TopoDS_Compound.hxx>
40 #include <TopoDS_Solid.hxx>
41 #include <TopoDS_Iterator.hxx>
44 #include <TopExp_Explorer.hxx>
46 #include <TopTools_MapOfShape.hxx>
47 #include <TopTools_DataMapOfShapeListOfShape.hxx>
48 #include <TopTools_MapIteratorOfMapOfShape.hxx>
49 #include <TopTools_ListOfShape.hxx>
50 #include <TopTools_ListIteratorOfListOfShape.hxx>
51 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
52 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
53 #include <TopTools_IndexedMapOfShape.hxx>
54 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
56 #include <BRep_Tool.hxx>
57 #include <BRepClass3d_SolidClassifier.hxx>
59 #include <NMTAlgo_Loop3d.hxx>
61 #include <BOPTools_Tools2D.hxx>
62 #include <Geom_Curve.hxx>
63 #include <TopAbs_Orientation.hxx>
64 #include <TopTools_ListOfShape.hxx>
65 #include <TopTools_ListIteratorOfListOfShape.hxx>
68 #include <BOPTools_Tools3D.hxx>
70 #include <BRep_Tool.hxx>
72 #include <TopAbs_State.hxx>
76 void RefineShells(const TopoDS_Shape& ,
77 TopTools_ListOfShape&);
79 void RefineSolids(const TopoDS_Shape& ,
80 TopTools_ListOfShape&);
83 void GetPlanes (const TopoDS_Edge& anEx,
84 const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
85 const TopoDS_Face& aF1,
86 TopAbs_State& aStPF1);
88 //=======================================================================
89 //function : ShellsAndSolids
91 //=======================================================================
92 void NMTAlgo_Splitter::ShellsAndSolids()
94 Standard_Boolean bMakeSolids;
95 TopAbs_ShapeEnum aType;
96 TopTools_ListIteratorOfListOfShape aItS;
97 TopTools_ListOfShape aLNS;
99 myAddedFacesMap.Clear();
100 bMakeSolids=(myLimit==TopAbs_SHAPE || myLimit<TopAbs_SHELL);
102 myInternalFaces.Clear(); // remove it after all modifs
104 aItS.Initialize(myListShapes);
105 for ( ;aItS.More(); aItS.Next()) {
106 const TopoDS_Shape& aS=aItS.Value();
108 if (myToolShapes.Contains(aS)) {
112 aType=aS.ShapeType();
113 if (aType > TopAbs_SHELL) {
114 continue;//face,wire,...
119 MakeShells (aS, aLNS);
121 if (bMakeSolids && aType==TopAbs_SOLID) {
122 MakeSolids(aS, aLNS);
125 TopTools_ListIteratorOfListOfShape it (aLNS);
126 for (; it.More(); it.Next()) {
127 myBuilder.Add (myShape, it.Value());
132 aItS.Initialize(myListShapes);
133 for ( ;aItS.More(); aItS.Next()) {
134 const TopoDS_Shape& aS=aItS.Value();
136 aType=aS.ShapeType();
137 if (aType!=TopAbs_FACE || myMapTools.Contains(aS)) {
141 const TopoDS_Shape& aCSF=myImageShape.Image(aS).First();
142 TopoDS_Iterator itS(aCSF);
143 for (; itS.More(); itS.Next()){
144 const TopoDS_Shape& aF=itS.Value();
145 if (!myAddedFacesMap.Contains(aF)){
146 myBuilder.Add (myShape, aF);
151 //=======================================================================
152 //function : MakeShells
153 //purpose : split S into compound of shells
154 //=======================================================================
155 void NMTAlgo_Splitter::MakeShells(const TopoDS_Shape& aS,
156 TopTools_ListOfShape& aLNS)
158 NMTAlgo_Loop3d aShellMaker;
160 // get compound of split faces of aS
161 const TopoDS_Shape& aFC=myImageShape.Image(aS).First();
162 aShellMaker.AddConstFaces(aFC);
164 // add split faces inside aS
166 if (myClosedShapes.Contains(aS)) {
168 // internal faces compound
169 aIFC=FindFacesInside(aS, Standard_True);
170 aShellMaker.AddSectionFaces(aIFC);
173 aLNS=aShellMaker.MakeShells(myAddedFacesMap);
175 RefineShells(aS, aLNS);
177 // Add faces added to new shell to myAddedFacesMap:
178 // avoid rebuilding twice common part of 2 solids.
179 TopTools_ListIteratorOfListOfShape itS(aLNS);
180 TopExp_Explorer expF;
181 for (; itS.More(); itS.Next()) {
182 const TopoDS_Shape& aSh=itS.Value();
183 expF.Init (aSh, TopAbs_FACE);
184 for (; expF.More(); expF.Next()){
185 const TopoDS_Shape& aFx=expF.Current();
186 myAddedFacesMap.Add (aFx);
190 //=======================================================================
191 //function : MakeSolids
192 //purpose : make solids out of Shells
193 //=======================================================================
194 void NMTAlgo_Splitter::MakeSolids(const TopoDS_Shape& theSolid,
195 TopTools_ListOfShape& theShellList)
197 // for a solid wrapping other shells or solids without intersection,
198 // it is necessary to find shells making holes in it
199 Standard_Boolean isWrapping;
200 TopTools_ListOfShape aNewSolids; // result
201 TopTools_ListOfShape aHoleShells;
202 TopoDS_Shape anInfinitePointShape;
203 TopTools_DataMapOfShapeShape aInOutMap;
204 TopTools_ListIteratorOfListOfShape aShellIt, aSolisIt;
206 isWrapping = myWrappingSolid.Contains(theSolid);
207 if (!isWrapping && !theShellList.IsEmpty()) {
208 // check if theSolid initially has internal shells
209 TopoDS_Iterator aShellExp (theSolid);
211 isWrapping = aShellExp.More();
214 aShellIt.Initialize(theShellList);
215 for ( ; aShellIt.More(); aShellIt.Next()) {
216 const TopoDS_Shape & aShell = aShellIt.Value();
217 // check if a shell is a hole of theSolid
218 if (isWrapping && IsInside(anInfinitePointShape, aShell)){
219 aHoleShells.Append(aShell);
222 // make a solid from a shell
224 myBuilder.MakeSolid( Solid );
225 myBuilder.Add (Solid, aShell);
227 aNewSolids.Append (Solid);
231 // find outer a shell most close to each hole shell
232 aShellIt.Initialize(aHoleShells);
233 for (; aShellIt.More(); aShellIt.Next()){
234 const TopoDS_Shape & aHole = aShellIt.Value();
236 aSolisIt.Initialize(aNewSolids);
237 for ( ; aSolisIt.More(); aSolisIt.Next()) {
238 const TopoDS_Shape & aSolid = aSolisIt.Value();
240 if (! IsInside(aHole, aSolid)){
244 if ( aInOutMap.IsBound (aHole)){
245 const TopoDS_Shape & aSolid2 = aInOutMap( aHole );
246 if ( IsInside( aSolid, aSolid2 )) {
247 aInOutMap.UnBind( aHole );
248 aInOutMap.Bind ( aHole, aSolid );
252 aInOutMap.Bind (aHole, aSolid);
256 // add aHole to a solid
257 if (aInOutMap.IsBound( aHole )){
258 TopoDS_Shape & aSolid=aInOutMap(aHole);
259 myBuilder.Add (aSolid, aHole);
263 theShellList.Clear();
265 RefineSolids(theSolid, aNewSolids);
267 theShellList.Append(aNewSolids);
270 //=======================================================================
271 //function : FindFacesInside
272 //purpose : return compound of faces of other shapes that are
273 // inside <theShape>.
274 // <theShape> is an object shape.
275 // <CheckClosed> makes avoid faces that do not form a
277 // <All> makes return already added faces
278 //=======================================================================
279 TopoDS_Shape NMTAlgo_Splitter::FindFacesInside(const TopoDS_Shape& theShape,
280 const Standard_Boolean CheckClosed,
281 const Standard_Boolean All)
283 TopExp_Explorer expl;
286 // ================================================
287 // check if internal faces have been already found
288 // ================================================
289 if (myInternalFaces.IsBound(theShape)) {
290 TopoDS_Shape aIntFComp = myInternalFaces.Find (theShape);
291 TopoDS_Shape aIntRemFComp = myIntNotClFaces.Find (theShape);
293 expl.Init( aIntRemFComp, TopAbs_FACE);
294 if (CheckClosed || !expl.More()){
299 myBuilder.MakeCompound( C );
301 for (; expl.More(); expl.Next()){
302 myBuilder.Add( C, expl.Current() );
304 // add good internal faces
305 expl.Init( aIntFComp, TopAbs_FACE);
306 for (; expl.More(); expl.Next()) {
307 myBuilder.Add( C, expl.Current() );
313 // ===================================
314 // get data for internal faces search
315 // ===================================
317 // compound of split faces of theShape
318 const TopoDS_Shape& CSF = myImageShape.Image(theShape).First();
320 TopTools_MapOfShape MSE, MFP;
322 TopTools_IndexedMapOfShape aMFCSF;
324 TopTools_DataMapOfShapeListOfShape DMSEFP;
325 TopTools_MapIteratorOfMapOfShape itm;
326 TopTools_ListOfShape EmptyL;
327 TopTools_ListIteratorOfListOfShape itl;
328 TopTools_IndexedDataMapOfShapeListOfShape DMEF;
330 // MSE filling: map of new section edges of CSF
331 expl.Init(CSF, TopAbs_EDGE);
332 for (; expl.More(); expl.Next()) {
333 const TopoDS_Shape& aE = expl.Current() ;
337 // DMEF: map edge of CSF - faces of CSF
338 TopExp::MapShapesAndAncestors(CSF, TopAbs_EDGE, TopAbs_FACE, DMEF);
340 TopExp::MapShapes(CSF, TopAbs_FACE, aMFCSF);
344 // 1. MFP - a map of faces to process: map of resulting faces except
345 // those of theShape; we`ll add to C those of them which are inside CSF
346 // 2. DMSEFP - edge of MSE => faces of MFP
348 itl.Initialize(myListShapes);
349 for (;itl.More(); itl.Next()) {
350 const TopoDS_Shape& aShape = itl.Value();
352 if ( theShape.IsSame(aShape)) {
356 // iterate on split faces of aShape
357 const TopoDS_Shape& CSF1 = myImageShape.Image(aShape).First();
358 TopoDS_Iterator itF (CSF1);
359 for ( ; itF.More(); itF.Next()) {
360 const TopoDS_Shape& aF1 = itF.Value();
362 // iterate on edges of split faces of aShape,
363 // add to DMSEFP edges that are new
364 expl.Init(aF1, TopAbs_EDGE);
365 for (; expl.More(); expl.Next()) {
366 TopoDS_Shape aE1 = expl.Current();
367 if ( MSE.Contains(aE1)) {// section edge
368 if (!DMSEFP.IsBound(aE1)) {
369 DMSEFP.Bind(aE1, EmptyL);
371 DMSEFP(aE1).Append(aF1);
375 }//for (;itl.More(); itl.Next())
377 // add tool faces... (is absent)
379 // ===========================
380 // find faces inside theShape
381 // ===========================
382 Standard_Boolean sameDom1, sameDom2;
383 Standard_Boolean skipAlreadyAdded = Standard_False;
384 Standard_Boolean GoodOri, inside;
386 TopTools_ListOfShape KeepFaces;
387 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
389 // iterate on section edges, check faces of other shapes
390 // sharing section edges and put internal faces to KeepFaces
391 Mapit.Initialize(DMSEFP);
392 for (; Mapit.More() ; Mapit.Next()) {
393 // a new edge of theShape
394 const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key());
396 //Standard_Boolean isSectionE=IsSectionEdge(E);//(OrigE);
398 // split faces of other shapes sharing E
399 TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E);
401 itl.Initialize( LSF );
403 // a split faces of other shape
404 TopoDS_Face aFace1 = TopoDS::Face(itl.Value());
405 // remove aFace1 form DMSEFP and MFP
406 LSF.Remove( itl ); // == itl.Next();
407 if (!MFP.Remove(aFace1)) {
408 continue; // was not is MFP (i.e already checked)
411 // check if aFace1 was already added to 2 shells
413 myAddedFacesMap.Contains(aFace1) &&
414 myAddedFacesMap.Contains(aFace1.Reversed())) {
415 skipAlreadyAdded = Standard_True;
419 if (aMFCSF.Contains(aFace1)) {
420 // the face aFace1 can not be inside CSF
421 // if CSF contains the aFace1
426 TopoDS_Shape anOrigFace = aFace1;
427 if (myImagesFaces.IsImage(aFace1)){
428 anOrigFace = myImagesFaces.Root(aFace1);
433 // check that anOrigFace is not same domain with CSF faces it intersects
435 const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); //faces of CSF sharing E
437 const TopoDS_Shape& origF1 = myImagesFaces.IsImage(FL.First()) ?
438 myImagesFaces.Root(FL.First()) : FL.First();
440 const TopoDS_Shape& origF2 = myImagesFaces.IsImage(FL.Last()) ?
441 myImagesFaces.Root(FL.Last()) : FL.Last();
443 sameDom1 = anOrigFace.IsSame( origF1 );
444 sameDom2 = anOrigFace.IsSame( origF2 );
446 if (!(sameDom1 || sameDom2) && HasSameDomainF( TopoDS::Face(anOrigFace) )) {
447 sameDom1 = IsSameDomainF( TopoDS::Face(anOrigFace), TopoDS::Face(origF1));
448 if (origF1 == origF2) {
452 if (sameDom1 && sameDom2){
456 if (sameDom1 || sameDom2) {
457 inside = NMTAlgo_Loop3d::IsInside (E,
458 TopoDS::Face(FL.First()),
459 TopoDS::Face(FL.Last()),
461 if (inside || (dot + Precision::Angular() >= 1.0)) {
462 continue; // E is convex between origF1 and origF2 or they are tangent
466 GetPlanes(E, DMEF, aFace1, aState);
467 if (aState==TopAbs_IN) {
468 KeepFaces.Append(aFace1);
470 } //while (itl.More()) {
471 } //for (; Mapit.More() ; Mapit.Next() )
473 // ===================================================
474 // add not distributed faces connected with KeepFaces
475 // ===================================================
477 // ultimate list of internal faces
478 TopTools_ListOfShape KeptFaces;
480 // add to MFP not split tool faces as well, they may be connected with
481 // tool faces interfering with theShape
483 itm.Initialize(myMapTools);
484 for (; itm.More(); itm.Next() ) {
485 const TopoDS_Shape& aToolFace = itm.Key();
486 if (!myImageShape.HasImage(aToolFace)){
493 KeptFaces.Append (KeepFaces);
495 while (!KeepFaces.IsEmpty()) {
496 // KeepEdges : map of edges of faces kept last time
497 TopTools_IndexedMapOfShape KeepEdges;
498 for ( itl.Initialize(KeepFaces); itl.More(); itl.Next() ) {
499 TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges);
500 KeptFaces.Append( itl.Value() );
505 // keep faces connected with already kept faces by KeepEdges
506 for ( itm.Initialize(MFP); itm.More(); itm.Next() ) {
507 const TopoDS_Shape& FP = itm.Key();
508 for (expl.Init(FP,TopAbs_EDGE); expl.More(); expl.Next()) {
509 const TopoDS_Shape& se = expl.Current();
510 if (!MSE.Contains(se) && KeepEdges.Contains(se) ) {
511 KeepFaces.Append(FP);
519 // ===============================================================
520 // here MFP contains faces outer of theShape and those of shapes
521 // which do not interfere with theShape at all and between which
522 // there may be those wrapped by theShape and whose faces may be
523 // needed to be returned as well
524 // ===============================================================
526 Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID);
527 if (All || isSolid) // All is for sub-result removal
529 for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) {
530 TopoDS_Shape aFace = itm.Key();
532 // find a shape aFace originates from
533 TopoDS_Shape anOrigShape = GetOriginalShape( aFace );
535 // find out if all faces of anOrigShape are not in MFP
536 // and by the way remove them from MFP
537 Standard_Boolean isAllOut = Standard_True;
538 TopoDS_Shape aSplitFaces = anOrigShape;
539 if (myImageShape.HasImage(anOrigShape))
540 aSplitFaces = myImageShape.Image(anOrigShape).First();
542 TopTools_ListOfShape aSplitFaceL;
543 for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next())
545 const TopoDS_Shape & aSpFace = expl.Current();
546 // a tool face which become object has image but the whole tool shape has not
547 if (myImageShape.HasImage( aSpFace ))
549 TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE );
550 for ( ; exF.More(); exF.Next() )
552 aSplitFaceL.Append( exF.Current() );
553 if ( ! MFP.Remove( exF.Current() ))
554 isAllOut = Standard_False;
559 aSplitFaceL.Append( aSpFace );
560 if ( ! MFP.Remove( aSpFace ))
561 isAllOut = Standard_False;
564 itm.Initialize( MFP );
568 // classify anOrigShape against theShape
569 if (IsInside (anOrigShape, theShape)) {
570 if (isSolid && myClosedShapes.Contains(anOrigShape)) {
571 // to make a special care at solid reconstruction
572 myWrappingSolid.Add ( theShape );
574 // keep faces of an internal shape anOrigShape
575 KeptFaces.Append( aSplitFaceL );
580 // ====================================================
581 // check if kept faces form a shell without free edges
582 // ====================================================
584 DMEF.Clear(); // edge - kept faces
585 MFP.Clear(); // reuse it for wrong faces
587 for (itl.Initialize(KeptFaces); itl.More(); itl.Next() )
588 TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF);
590 Standard_Integer i, nb = DMEF.Extent();
591 Standard_Boolean isClosed = Standard_False;
593 isClosed = Standard_True;
594 for (i=1; isClosed && i<=nb; ++i) {
595 const TopoDS_Shape& E = DMEF.FindKey( i );
596 if (! BRep_Tool::Degenerated( TopoDS::Edge( E )) &&
598 isClosed = ( DMEF(i).Extent() != 1 );
601 const TopoDS_Shape& F = DMEF.FindFromIndex( i-1 ).First(); // bad face
603 // remove bad face from DMEF
604 for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) {
605 const TopoDS_Shape& E = expl.Current();
606 TopTools_ListOfShape& FL = DMEF.ChangeFromKey( E );
607 for (itl.Initialize( FL ); itl.More(); itl.Next() ) {
608 if ( F.IsSame( itl.Value() )) {
623 // compound of removed internal faces
624 TopoDS_Compound CNotCl;
626 myBuilder.MakeCompound(C);
627 myBuilder.MakeCompound(CNotCl);
630 itl.Initialize(KeptFaces);
631 for (; itl.More(); itl.Next() ) {
632 TopoDS_Shape & aIntFace = itl.Value();
635 myAddedFacesMap.Contains(aIntFace) &&
636 myAddedFacesMap.Contains(aIntFace.Reversed())) {
640 if (! MFP.Contains( aIntFace )){
641 myBuilder.Add(C, aIntFace);
644 myBuilder.Add(CNotCl, aIntFace);
648 if (!skipAlreadyAdded && CheckClosed) {
649 myInternalFaces.Bind(theShape, C);
650 myIntNotClFaces.Bind(theShape, CNotCl);
654 if (!myMapSIFC.IsBound(theShape)) {
655 TopoDS_Compound aCIF;
656 myBuilder.MakeCompound(aCIF);
658 itl.Initialize(KeptFaces);
659 for (; itl.More(); itl.Next() ) {
660 TopoDS_Shape & aIntFace = itl.Value();
661 if (! MFP.Contains(aIntFace )){
662 myBuilder.Add(aCIF, aIntFace);
665 myMapSIFC.Bind(theShape, aCIF);
670 //=======================================================================
671 //function : IsInside
672 //purpose : Return True if the first vertex of S1 inside S2.
673 // If S1.IsNull(), check infinite point against S2.
674 //=======================================================================
675 Standard_Boolean NMTAlgo_Splitter::IsInside (const TopoDS_Shape& theS1,
676 const TopoDS_Shape& theS2)
678 BRepClass3d_SolidClassifier aClassifier( theS2 );
680 TopExp_Explorer expl(theS1, TopAbs_VERTEX);
683 aClassifier.PerformInfinitePoint( ::RealSmall());
686 const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() );
687 aClassifier.Perform (BRep_Tool::Pnt( aVertex ),
688 BRep_Tool::Tolerance( aVertex ));
691 return ( aClassifier.State() == TopAbs_IN );
693 //=======================================================================
694 //function : GetOriginalShape
695 //purpose : Return the shape aShape originates from. aShape
696 // should be a face or more complex result shape
697 //=======================================================================
698 TopoDS_Shape NMTAlgo_Splitter::GetOriginalShape(const TopoDS_Shape& theShape) const
700 TopoDS_Shape anOrigShape;
702 TopExp_Explorer expl( theShape, TopAbs_FACE);
704 TopoDS_Shape aFace = expl.Current();
705 if (myImagesFaces.IsImage( aFace ))
706 aFace = myImagesFaces.Root( aFace );
707 anOrigShape = myFaceShapeMap.Find( aFace );
711 //=======================================================================
712 //function :RefineShells
714 //=======================================================================
715 void RefineShells(const TopoDS_Shape& aS,
716 TopTools_ListOfShape& aLNS)
718 Standard_Boolean bFound;
719 Standard_Integer iS, jS, aNbSOrs, aNbSIms, aNbFOrs, aNbFIms, kFOrs, aNb;
720 TopTools_ListIteratorOfListOfShape aIt;
721 TopTools_IndexedMapOfShape aMSOrs, aMSIms, aMFOrs, aMFIms;
722 TopTools_IndexedDataMapOfShapeShape aMImOr;
723 TopTools_ListOfShape aLS;
725 TopExp::MapShapes(aS, TopAbs_SHELL, aMSOrs);
726 aIt.Initialize(aLNS);
727 for (;aIt.More(); aIt.Next()) {
728 const TopoDS_Shape& aSh=aIt.Value();
732 aNbSOrs=aMSOrs.Extent();
733 aNbSIms=aMSIms.Extent();
735 for (iS=1; iS<=aNbSOrs; ++iS) {
736 const TopoDS_Shape& aSOr=aMSOrs(iS);
738 TopExp::MapShapes(aSOr, TopAbs_FACE, aMFOrs);
739 aNbFOrs=aMFOrs.Extent();
741 for (jS=1; jS<=aNbSIms; ++jS) {
742 const TopoDS_Shape& aSIm=aMSIms(jS);
743 if (aMImOr.Contains(aSIm)) {
748 TopExp::MapShapes(aSIm, TopAbs_FACE, aMFIms);
749 aNbFIms=aMFIms.Extent();
751 if (aNbFIms==aNbFOrs) {
752 bFound=Standard_True;
753 for (kFOrs=1; kFOrs<=aNbFOrs; ++kFOrs) {
754 const TopoDS_Shape& aFOr=aMFOrs(kFOrs);
755 if (!aMFIms.Contains(aFOr)) {
756 bFound=Standard_False;
761 aMImOr.Add(aSIm, aSOr);
764 } //if (aNbFIms==aNbFOrs)
769 aIt.Initialize(aLNS);
770 for (;aIt.More(); aIt.Next()) {
771 const TopoDS_Shape& aSh=aIt.Value();
772 if (aMImOr.Contains(aSh)) {
773 const TopoDS_Shape& aSOr=aMImOr.FindFromKey(aSh);
785 //=======================================================================
786 //function :RefineSolids
788 //=======================================================================
789 void RefineSolids(const TopoDS_Shape& aSolidOr,
790 TopTools_ListOfShape& aLNS)
792 Standard_Integer aNb, iS, aNbSOrs, aNbSIms;
793 TopoDS_Shape aSolidIm;
794 TopTools_IndexedMapOfShape aMSOrs, aMSIms;
801 aSolidIm=aLNS.First();
803 TopExp::MapShapes(aSolidOr, TopAbs_SHELL, aMSOrs);
804 TopExp::MapShapes(aSolidIm, TopAbs_SHELL, aMSIms);
805 aNbSOrs=aMSOrs.Extent();
806 aNbSIms=aMSIms.Extent();
807 if (aNbSOrs!=aNbSIms) {
811 for (iS=1; iS<=aNbSOrs; ++iS) {
812 const TopoDS_Shape& aSOr=aMSOrs(iS);
813 if (!aMSIms.Contains(aSOr)) {
819 aLNS.Append(aSolidOr);
821 //=======================================================================
822 //function : GetPlanes
824 //=======================================================================
825 void GetPlanes (const TopoDS_Edge& anEx,
826 const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
827 const TopoDS_Face& aF1,
828 TopAbs_State& aStPF1)
831 Standard_Boolean bIsAdjExists;
832 Standard_Real aT, aT1, aT2;
833 TopAbs_Orientation anOrEx, anOr;
834 gp_Dir aDNFx1, aDNFx2, aDNF1;
835 gp_Pnt aPx, aPx1, aPx2, aPF1;
836 TopoDS_Edge aERight, aSpxSimm;
837 TopoDS_Face aFx1, aFx2, aFF1;
838 TopTools_ListIteratorOfListOfShape anIt;
841 Handle(Geom_Curve)aC3D =BRep_Tool::Curve(anEx, aT1, aT2);
842 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
846 anOrEx=anEx.Orientation();
849 if (anOrEx==TopAbs_FORWARD) {
850 aSpxSimm.Orientation(TopAbs_REVERSED);
852 else if (anOrEx==TopAbs_REVERSED){
853 aSpxSimm.Orientation(TopAbs_FORWARD);
856 const TopTools_ListOfShape& aLF=anEFMapx.FindFromKey(anEx);
857 anIt.Initialize(aLF);
858 for (; anIt.More(); anIt.Next()) {
859 const TopoDS_Shape& aFE=anIt.Value();
860 aFx1=TopoDS::Face(aFE);
861 anOr=BOPTools_Tools3D::Orientation(anEx, aFx1);
867 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (anEx, aFx1, aT, aPx1, aDNFx1);
869 bIsAdjExists=BOPTools_Tools3D::GetAdjacentFace (aFx1, anEx, anEFMapx, aFx2);
871 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx1, aT, aPx2, aDNFx2);
874 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx2, aT, aPx2, aDNFx2);
878 aFF1.Orientation(TopAbs_FORWARD);
879 BOPTools_Tools3D::OrientEdgeOnFace (anEx, aFF1, aERight);
880 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aERight, aFF1, aT, aPF1, aDNF1);
883 Standard_Real d12, d1, anAlfa12, anAlfa1, aTwoPI;
885 aTwoPI=Standard_PI+Standard_PI;
887 gp_Vec aVx1(aPx, aPx1);
889 gp_Pln aPlnToCompare (aPx, aDNFx1);
891 gp_Vec aVx2(aPx, aPx2);
894 anAlfa12=aDBx1.Angle(aDBx2);
895 d12=BOPTools_Tools3D::SignDistance(aPx2, aPlnToCompare);
897 anAlfa12=aTwoPI-anAlfa12;
900 gp_Vec aVF1(aPx, aPF1);
902 anAlfa1=aDBx1.Angle(aDBF1);
903 d1=BOPTools_Tools3D::SignDistance(aPF1, aPlnToCompare);
905 anAlfa1=aTwoPI-anAlfa1;
909 if (anAlfa1 > anAlfa12) {
915 //modified by NIZNHY-PKV Fri Feb 25 17:00:03 2005t XX
922 aFace2 = itl.Value();
924 TopoDS_Shape anOrigFace2 = aFace2;
925 if (myImagesFaces.IsImage(aFace2)) {
926 anOrigFace2 = myImagesFaces.Root(aFace2);
929 if (!MFP.Contains( aFace2 )) {
933 //if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 )))
934 if (anOrigFace.IsSame(anOrigFace2)) {
939 if (itl.More()) { // aFace2 found, remove it from maps
946 itl.Initialize( LSF );