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_1.cxx
21 // Created: Mon Feb 2 14:58:54 2004
22 // Author: Peter KURNEV
26 #include <NMTAlgo_Splitter.ixx>
28 #include <Precision.hxx>
32 #include <TopAbs_ShapeEnum.hxx>
35 #include <TopoDS_Edge.hxx>
36 #include <TopoDS_Face.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Compound.hxx>
39 #include <TopoDS_Solid.hxx>
40 #include <TopoDS_Iterator.hxx>
43 #include <TopExp_Explorer.hxx>
45 #include <TopTools_MapOfShape.hxx>
46 #include <TopTools_DataMapOfShapeListOfShape.hxx>
47 #include <TopTools_MapIteratorOfMapOfShape.hxx>
48 #include <TopTools_ListOfShape.hxx>
49 #include <TopTools_ListIteratorOfListOfShape.hxx>
50 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
51 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
52 #include <TopTools_IndexedMapOfShape.hxx>
53 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
55 #include <BRep_Tool.hxx>
56 #include <BRepClass3d_SolidClassifier.hxx>
58 #include <NMTAlgo_Loop3d.hxx>
60 #include <BOPTools_Tools2D.hxx>
61 #include <Geom_Curve.hxx>
62 #include <TopAbs_Orientation.hxx>
63 #include <TopTools_ListOfShape.hxx>
64 #include <TopTools_ListIteratorOfListOfShape.hxx>
67 #include <BOPTools_Tools3D.hxx>
69 #include <BRep_Tool.hxx>
71 #include <TopAbs_State.hxx>
75 void RefineShells(const TopoDS_Shape& ,
76 TopTools_ListOfShape&);
78 void RefineSolids(const TopoDS_Shape& ,
79 TopTools_ListOfShape&);
82 void GetPlanes (const TopoDS_Edge& anEx,
83 const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
84 const TopoDS_Face& aF1,
85 TopAbs_State& aStPF1);
87 //=======================================================================
88 //function : ShellsAndSolids
90 //=======================================================================
91 void NMTAlgo_Splitter::ShellsAndSolids()
93 Standard_Boolean bMakeSolids;
94 TopAbs_ShapeEnum aType;
95 TopTools_ListIteratorOfListOfShape aItS;
96 TopTools_ListOfShape aLNS;
98 myAddedFacesMap.Clear();
99 bMakeSolids=(myLimit==TopAbs_SHAPE || myLimit<TopAbs_SHELL);
101 myInternalFaces.Clear(); // remove it after all modifs
103 aItS.Initialize(myListShapes);
104 for ( ;aItS.More(); aItS.Next()) {
105 const TopoDS_Shape& aS=aItS.Value();
107 if (myToolShapes.Contains(aS)) {
111 aType=aS.ShapeType();
112 if (aType > TopAbs_SHELL) {
113 continue;//face,wire,...
118 MakeShells (aS, aLNS);
120 if (bMakeSolids && aType==TopAbs_SOLID) {
121 MakeSolids(aS, aLNS);
124 TopTools_ListIteratorOfListOfShape it (aLNS);
125 for (; it.More(); it.Next()) {
126 myBuilder.Add (myShape, it.Value());
131 aItS.Initialize(myListShapes);
132 for ( ;aItS.More(); aItS.Next()) {
133 const TopoDS_Shape& aS=aItS.Value();
135 aType=aS.ShapeType();
136 if (aType!=TopAbs_FACE || myMapTools.Contains(aS)) {
140 const TopoDS_Shape& aCSF=myImageShape.Image(aS).First();
141 TopoDS_Iterator itS(aCSF);
142 for (; itS.More(); itS.Next()){
143 const TopoDS_Shape& aF=itS.Value();
144 if (!myAddedFacesMap.Contains(aF)){
145 myBuilder.Add (myShape, aF);
150 //=======================================================================
151 //function : MakeShells
152 //purpose : split S into compound of shells
153 //=======================================================================
154 void NMTAlgo_Splitter::MakeShells(const TopoDS_Shape& aS,
155 TopTools_ListOfShape& aLNS)
157 NMTAlgo_Loop3d aShellMaker;
159 // get compound of split faces of aS
160 const TopoDS_Shape& aFC=myImageShape.Image(aS).First();
161 aShellMaker.AddConstFaces(aFC);
163 // add split faces inside aS
165 if (myClosedShapes.Contains(aS)) {
167 // internal faces compound
168 aIFC=FindFacesInside(aS, Standard_True);
169 aShellMaker.AddSectionFaces(aIFC);
172 aLNS=aShellMaker.MakeShells(myAddedFacesMap);
174 RefineShells(aS, aLNS);
176 // Add faces added to new shell to myAddedFacesMap:
177 // avoid rebuilding twice common part of 2 solids.
178 TopTools_ListIteratorOfListOfShape itS(aLNS);
179 TopExp_Explorer expF;
180 for (; itS.More(); itS.Next()) {
181 const TopoDS_Shape& aSh=itS.Value();
182 expF.Init (aSh, TopAbs_FACE);
183 for (; expF.More(); expF.Next()){
184 const TopoDS_Shape& aFx=expF.Current();
185 myAddedFacesMap.Add (aFx);
189 //=======================================================================
190 //function : MakeSolids
191 //purpose : make solids out of Shells
192 //=======================================================================
193 void NMTAlgo_Splitter::MakeSolids(const TopoDS_Shape& theSolid,
194 TopTools_ListOfShape& theShellList)
196 // for a solid wrapping other shells or solids without intersection,
197 // it is necessary to find shells making holes in it
198 Standard_Boolean isWrapping;
199 TopTools_ListOfShape aNewSolids; // result
200 TopTools_ListOfShape aHoleShells;
201 TopoDS_Shape anInfinitePointShape;
202 TopTools_DataMapOfShapeShape aInOutMap;
203 TopTools_ListIteratorOfListOfShape aShellIt, aSolisIt;
205 isWrapping = myWrappingSolid.Contains(theSolid);
206 if (!isWrapping && !theShellList.IsEmpty()) {
207 // check if theSolid initially has internal shells
208 TopoDS_Iterator aShellExp (theSolid);
210 isWrapping = aShellExp.More();
213 aShellIt.Initialize(theShellList);
214 for ( ; aShellIt.More(); aShellIt.Next()) {
215 const TopoDS_Shape & aShell = aShellIt.Value();
216 // check if a shell is a hole of theSolid
217 if (isWrapping && IsInside(anInfinitePointShape, aShell)){
218 aHoleShells.Append(aShell);
221 // make a solid from a shell
223 myBuilder.MakeSolid( Solid );
224 myBuilder.Add (Solid, aShell);
226 aNewSolids.Append (Solid);
230 // find outer a shell most close to each hole shell
231 aShellIt.Initialize(aHoleShells);
232 for (; aShellIt.More(); aShellIt.Next()){
233 const TopoDS_Shape & aHole = aShellIt.Value();
235 aSolisIt.Initialize(aNewSolids);
236 for ( ; aSolisIt.More(); aSolisIt.Next()) {
237 const TopoDS_Shape & aSolid = aSolisIt.Value();
239 if (! IsInside(aHole, aSolid)){
243 if ( aInOutMap.IsBound (aHole)){
244 const TopoDS_Shape & aSolid2 = aInOutMap( aHole );
245 if ( IsInside( aSolid, aSolid2 )) {
246 aInOutMap.UnBind( aHole );
247 aInOutMap.Bind ( aHole, aSolid );
251 aInOutMap.Bind (aHole, aSolid);
255 // add aHole to a solid
256 if (aInOutMap.IsBound( aHole )){
257 TopoDS_Shape & aSolid=aInOutMap(aHole);
258 myBuilder.Add (aSolid, aHole);
262 theShellList.Clear();
264 RefineSolids(theSolid, aNewSolids);
266 theShellList.Append(aNewSolids);
269 //=======================================================================
270 //function : FindFacesInside
271 //purpose : return compound of faces of other shapes that are
272 // inside <theShape>.
273 // <theShape> is an object shape.
274 // <CheckClosed> makes avoid faces that do not form a
276 // <All> makes return already added faces
277 //=======================================================================
278 TopoDS_Shape NMTAlgo_Splitter::FindFacesInside(const TopoDS_Shape& theShape,
279 const Standard_Boolean CheckClosed,
280 const Standard_Boolean All)
282 TopExp_Explorer expl;
285 // ================================================
286 // check if internal faces have been already found
287 // ================================================
288 if (myInternalFaces.IsBound(theShape)) {
289 TopoDS_Shape aIntFComp = myInternalFaces.Find (theShape);
290 TopoDS_Shape aIntRemFComp = myIntNotClFaces.Find (theShape);
292 expl.Init( aIntRemFComp, TopAbs_FACE);
293 if (CheckClosed || !expl.More()){
298 myBuilder.MakeCompound( C );
300 for (; expl.More(); expl.Next()){
301 myBuilder.Add( C, expl.Current() );
303 // add good internal faces
304 expl.Init( aIntFComp, TopAbs_FACE);
305 for (; expl.More(); expl.Next()) {
306 myBuilder.Add( C, expl.Current() );
312 // ===================================
313 // get data for internal faces search
314 // ===================================
316 // compound of split faces of theShape
317 const TopoDS_Shape& CSF = myImageShape.Image(theShape).First();
319 TopTools_MapOfShape MSE, MFP;
321 TopTools_IndexedMapOfShape aMFCSF;
323 TopTools_DataMapOfShapeListOfShape DMSEFP;
324 TopTools_MapIteratorOfMapOfShape itm;
325 TopTools_ListOfShape EmptyL;
326 TopTools_ListIteratorOfListOfShape itl;
327 TopTools_IndexedDataMapOfShapeListOfShape DMEF;
329 // MSE filling: map of new section edges of CSF
330 expl.Init(CSF, TopAbs_EDGE);
331 for (; expl.More(); expl.Next()) {
332 const TopoDS_Shape& aE = expl.Current() ;
336 // DMEF: map edge of CSF - faces of CSF
337 TopExp::MapShapesAndAncestors(CSF, TopAbs_EDGE, TopAbs_FACE, DMEF);
339 TopExp::MapShapes(CSF, TopAbs_FACE, aMFCSF);
343 // 1. MFP - a map of faces to process: map of resulting faces except
344 // those of theShape; we`ll add to C those of them which are inside CSF
345 // 2. DMSEFP - edge of MSE => faces of MFP
347 itl.Initialize(myListShapes);
348 for (;itl.More(); itl.Next()) {
349 const TopoDS_Shape& aShape = itl.Value();
351 if ( theShape.IsSame(aShape)) {
355 // iterate on split faces of aShape
356 const TopoDS_Shape& CSF1 = myImageShape.Image(aShape).First();
357 TopoDS_Iterator itF (CSF1);
358 for ( ; itF.More(); itF.Next()) {
359 const TopoDS_Shape& aF1 = itF.Value();
361 // iterate on edges of split faces of aShape,
362 // add to DMSEFP edges that are new
363 expl.Init(aF1, TopAbs_EDGE);
364 for (; expl.More(); expl.Next()) {
365 TopoDS_Shape aE1 = expl.Current();
366 if ( MSE.Contains(aE1)) {// section edge
367 if (!DMSEFP.IsBound(aE1)) {
368 DMSEFP.Bind(aE1, EmptyL);
370 DMSEFP(aE1).Append(aF1);
374 }//for (;itl.More(); itl.Next())
376 // add tool faces... (is absent)
378 // ===========================
379 // find faces inside theShape
380 // ===========================
381 Standard_Boolean sameDom1, sameDom2;
382 Standard_Boolean skipAlreadyAdded = Standard_False;
383 Standard_Boolean GoodOri, inside;
385 TopTools_ListOfShape KeepFaces;
386 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
388 // iterate on section edges, check faces of other shapes
389 // sharing section edges and put internal faces to KeepFaces
390 Mapit.Initialize(DMSEFP);
391 for (; Mapit.More() ; Mapit.Next()) {
392 // a new edge of theShape
393 const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key());
395 //Standard_Boolean isSectionE=IsSectionEdge(E);//(OrigE);
397 // split faces of other shapes sharing E
398 TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E);
400 itl.Initialize( LSF );
402 // a split faces of other shape
403 TopoDS_Face aFace1 = TopoDS::Face(itl.Value());
404 // remove aFace1 form DMSEFP and MFP
405 LSF.Remove( itl ); // == itl.Next();
406 if (!MFP.Remove(aFace1)) {
407 continue; // was not is MFP (i.e already checked)
410 // check if aFace1 was already added to 2 shells
412 myAddedFacesMap.Contains(aFace1) &&
413 myAddedFacesMap.Contains(aFace1.Reversed())) {
414 skipAlreadyAdded = Standard_True;
418 if (aMFCSF.Contains(aFace1)) {
419 // the face aFace1 can not be inside CSF
420 // if CSF contains the aFace1
425 TopoDS_Shape anOrigFace = aFace1;
426 if (myImagesFaces.IsImage(aFace1)){
427 anOrigFace = myImagesFaces.Root(aFace1);
432 // check that anOrigFace is not same domain with CSF faces it intersects
434 const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); //faces of CSF sharing E
436 const TopoDS_Shape& origF1 = myImagesFaces.IsImage(FL.First()) ?
437 myImagesFaces.Root(FL.First()) : FL.First();
439 const TopoDS_Shape& origF2 = myImagesFaces.IsImage(FL.Last()) ?
440 myImagesFaces.Root(FL.Last()) : FL.Last();
442 sameDom1 = anOrigFace.IsSame( origF1 );
443 sameDom2 = anOrigFace.IsSame( origF2 );
445 if (!(sameDom1 || sameDom2) && HasSameDomainF( TopoDS::Face(anOrigFace) )) {
446 sameDom1 = IsSameDomainF( TopoDS::Face(anOrigFace), TopoDS::Face(origF1));
447 if (origF1 == origF2) {
451 if (sameDom1 && sameDom2){
455 if (sameDom1 || sameDom2) {
456 inside = NMTAlgo_Loop3d::IsInside (E,
457 TopoDS::Face(FL.First()),
458 TopoDS::Face(FL.Last()),
460 if (inside || (dot + Precision::Angular() >= 1.0)) {
461 continue; // E is convex between origF1 and origF2 or they are tangent
465 GetPlanes(E, DMEF, aFace1, aState);
466 if (aState==TopAbs_IN) {
467 KeepFaces.Append(aFace1);
469 } //while (itl.More()) {
470 } //for (; Mapit.More() ; Mapit.Next() )
472 // ===================================================
473 // add not distributed faces connected with KeepFaces
474 // ===================================================
476 // ultimate list of internal faces
477 TopTools_ListOfShape KeptFaces;
479 // add to MFP not split tool faces as well, they may be connected with
480 // tool faces interfering with theShape
482 itm.Initialize(myMapTools);
483 for (; itm.More(); itm.Next() ) {
484 const TopoDS_Shape& aToolFace = itm.Key();
485 if (!myImageShape.HasImage(aToolFace)){
492 KeptFaces.Append (KeepFaces);
494 while (!KeepFaces.IsEmpty()) {
495 // KeepEdges : map of edges of faces kept last time
496 TopTools_IndexedMapOfShape KeepEdges;
497 for ( itl.Initialize(KeepFaces); itl.More(); itl.Next() ) {
498 TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges);
499 KeptFaces.Append( itl.Value() );
504 // keep faces connected with already kept faces by KeepEdges
505 for ( itm.Initialize(MFP); itm.More(); itm.Next() ) {
506 const TopoDS_Shape& FP = itm.Key();
507 for (expl.Init(FP,TopAbs_EDGE); expl.More(); expl.Next()) {
508 const TopoDS_Shape& se = expl.Current();
509 if (!MSE.Contains(se) && KeepEdges.Contains(se) ) {
510 KeepFaces.Append(FP);
518 // ===============================================================
519 // here MFP contains faces outer of theShape and those of shapes
520 // which do not interfere with theShape at all and between which
521 // there may be those wrapped by theShape and whose faces may be
522 // needed to be returned as well
523 // ===============================================================
525 Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID);
526 if (All || isSolid) // All is for sub-result removal
528 for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) {
529 TopoDS_Shape aFace = itm.Key();
531 // find a shape aFace originates from
532 TopoDS_Shape anOrigShape = GetOriginalShape( aFace );
534 // find out if all faces of anOrigShape are not in MFP
535 // and by the way remove them from MFP
536 Standard_Boolean isAllOut = Standard_True;
537 TopoDS_Shape aSplitFaces = anOrigShape;
538 if (myImageShape.HasImage(anOrigShape))
539 aSplitFaces = myImageShape.Image(anOrigShape).First();
541 TopTools_ListOfShape aSplitFaceL;
542 for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next())
544 const TopoDS_Shape & aSpFace = expl.Current();
545 // a tool face which become object has image but the whole tool shape has not
546 if (myImageShape.HasImage( aSpFace ))
548 TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE );
549 for ( ; exF.More(); exF.Next() )
551 aSplitFaceL.Append( exF.Current() );
552 if ( ! MFP.Remove( exF.Current() ))
553 isAllOut = Standard_False;
558 aSplitFaceL.Append( aSpFace );
559 if ( ! MFP.Remove( aSpFace ))
560 isAllOut = Standard_False;
563 itm.Initialize( MFP );
567 // classify anOrigShape against theShape
568 if (IsInside (anOrigShape, theShape)) {
569 if (isSolid && myClosedShapes.Contains(anOrigShape)) {
570 // to make a special care at solid reconstruction
571 myWrappingSolid.Add ( theShape );
573 // keep faces of an internal shape anOrigShape
574 KeptFaces.Append( aSplitFaceL );
579 // ====================================================
580 // check if kept faces form a shell without free edges
581 // ====================================================
583 DMEF.Clear(); // edge - kept faces
584 MFP.Clear(); // reuse it for wrong faces
586 for (itl.Initialize(KeptFaces); itl.More(); itl.Next() )
587 TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF);
589 Standard_Integer i, nb = DMEF.Extent();
590 Standard_Boolean isClosed = Standard_False;
592 isClosed = Standard_True;
593 for (i=1; isClosed && i<=nb; ++i) {
594 const TopoDS_Shape& E = DMEF.FindKey( i );
595 if (! BRep_Tool::Degenerated( TopoDS::Edge( E )) &&
597 isClosed = ( DMEF(i).Extent() != 1 );
600 const TopoDS_Shape& F = DMEF.FindFromIndex( i-1 ).First(); // bad face
602 // remove bad face from DMEF
603 for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) {
604 const TopoDS_Shape& E = expl.Current();
605 TopTools_ListOfShape& FL = DMEF.ChangeFromKey( E );
606 for (itl.Initialize( FL ); itl.More(); itl.Next() ) {
607 if ( F.IsSame( itl.Value() )) {
622 // compound of removed internal faces
623 TopoDS_Compound CNotCl;
625 myBuilder.MakeCompound(C);
626 myBuilder.MakeCompound(CNotCl);
629 itl.Initialize(KeptFaces);
630 for (; itl.More(); itl.Next() ) {
631 TopoDS_Shape & aIntFace = itl.Value();
634 myAddedFacesMap.Contains(aIntFace) &&
635 myAddedFacesMap.Contains(aIntFace.Reversed())) {
639 if (! MFP.Contains( aIntFace )){
640 myBuilder.Add(C, aIntFace);
643 myBuilder.Add(CNotCl, aIntFace);
647 if (!skipAlreadyAdded && CheckClosed) {
648 myInternalFaces.Bind(theShape, C);
649 myIntNotClFaces.Bind(theShape, CNotCl);
653 if (!myMapSIFC.IsBound(theShape)) {
654 TopoDS_Compound aCIF;
655 myBuilder.MakeCompound(aCIF);
657 itl.Initialize(KeptFaces);
658 for (; itl.More(); itl.Next() ) {
659 TopoDS_Shape & aIntFace = itl.Value();
660 if (! MFP.Contains(aIntFace )){
661 myBuilder.Add(aCIF, aIntFace);
664 myMapSIFC.Bind(theShape, aCIF);
669 //=======================================================================
670 //function : IsInside
671 //purpose : Return True if the first vertex of S1 inside S2.
672 // If S1.IsNull(), check infinite point against S2.
673 //=======================================================================
674 Standard_Boolean NMTAlgo_Splitter::IsInside (const TopoDS_Shape& theS1,
675 const TopoDS_Shape& theS2)
677 BRepClass3d_SolidClassifier aClassifier( theS2 );
679 TopExp_Explorer expl(theS1, TopAbs_VERTEX);
682 aClassifier.PerformInfinitePoint( ::RealSmall());
685 const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() );
686 aClassifier.Perform (BRep_Tool::Pnt( aVertex ),
687 BRep_Tool::Tolerance( aVertex ));
690 return ( aClassifier.State() == TopAbs_IN );
692 //=======================================================================
693 //function : GetOriginalShape
694 //purpose : Return the shape aShape originates from. aShape
695 // should be a face or more complex result shape
696 //=======================================================================
697 TopoDS_Shape NMTAlgo_Splitter::GetOriginalShape(const TopoDS_Shape& theShape) const
699 TopoDS_Shape anOrigShape;
701 TopExp_Explorer expl( theShape, TopAbs_FACE);
703 TopoDS_Shape aFace = expl.Current();
704 if (myImagesFaces.IsImage( aFace ))
705 aFace = myImagesFaces.Root( aFace );
706 anOrigShape = myFaceShapeMap.Find( aFace );
710 //=======================================================================
711 //function :RefineShells
713 //=======================================================================
714 void RefineShells(const TopoDS_Shape& aS,
715 TopTools_ListOfShape& aLNS)
717 Standard_Boolean bFound;
718 Standard_Integer iS, jS, aNbSOrs, aNbSIms, aNbFOrs, aNbFIms, kFOrs, aNb;
719 TopTools_ListIteratorOfListOfShape aIt;
720 TopTools_IndexedMapOfShape aMSOrs, aMSIms, aMFOrs, aMFIms;
721 TopTools_IndexedDataMapOfShapeShape aMImOr;
722 TopTools_ListOfShape aLS;
724 TopExp::MapShapes(aS, TopAbs_SHELL, aMSOrs);
725 aIt.Initialize(aLNS);
726 for (;aIt.More(); aIt.Next()) {
727 const TopoDS_Shape& aSh=aIt.Value();
731 aNbSOrs=aMSOrs.Extent();
732 aNbSIms=aMSIms.Extent();
734 for (iS=1; iS<=aNbSOrs; ++iS) {
735 const TopoDS_Shape& aSOr=aMSOrs(iS);
737 TopExp::MapShapes(aSOr, TopAbs_FACE, aMFOrs);
738 aNbFOrs=aMFOrs.Extent();
740 for (jS=1; jS<=aNbSIms; ++jS) {
741 const TopoDS_Shape& aSIm=aMSIms(jS);
742 if (aMImOr.Contains(aSIm)) {
747 TopExp::MapShapes(aSIm, TopAbs_FACE, aMFIms);
748 aNbFIms=aMFIms.Extent();
750 if (aNbFIms==aNbFOrs) {
751 bFound=Standard_True;
752 for (kFOrs=1; kFOrs<=aNbFOrs; ++kFOrs) {
753 const TopoDS_Shape& aFOr=aMFOrs(kFOrs);
754 if (!aMFIms.Contains(aFOr)) {
755 bFound=Standard_False;
760 aMImOr.Add(aSIm, aSOr);
763 } //if (aNbFIms==aNbFOrs)
768 aIt.Initialize(aLNS);
769 for (;aIt.More(); aIt.Next()) {
770 const TopoDS_Shape& aSh=aIt.Value();
771 if (aMImOr.Contains(aSh)) {
772 const TopoDS_Shape& aSOr=aMImOr.FindFromKey(aSh);
784 //=======================================================================
785 //function :RefineSolids
787 //=======================================================================
788 void RefineSolids(const TopoDS_Shape& aSolidOr,
789 TopTools_ListOfShape& aLNS)
791 Standard_Integer aNb, iS, aNbSOrs, aNbSIms;
792 TopoDS_Shape aSolidIm;
793 TopTools_IndexedMapOfShape aMSOrs, aMSIms;
800 aSolidIm=aLNS.First();
802 TopExp::MapShapes(aSolidOr, TopAbs_SHELL, aMSOrs);
803 TopExp::MapShapes(aSolidIm, TopAbs_SHELL, aMSIms);
804 aNbSOrs=aMSOrs.Extent();
805 aNbSIms=aMSIms.Extent();
806 if (aNbSOrs!=aNbSIms) {
810 for (iS=1; iS<=aNbSOrs; ++iS) {
811 const TopoDS_Shape& aSOr=aMSOrs(iS);
812 if (!aMSIms.Contains(aSOr)) {
818 aLNS.Append(aSolidOr);
820 //=======================================================================
821 //function : GetPlanes
823 //=======================================================================
824 void GetPlanes (const TopoDS_Edge& anEx,
825 const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
826 const TopoDS_Face& aF1,
827 TopAbs_State& aStPF1)
830 Standard_Boolean bIsAdjExists;
831 Standard_Real aT, aT1, aT2;
832 TopAbs_Orientation anOrEx, anOr;
833 gp_Dir aDNFx1, aDNFx2, aDNF1;
834 gp_Pnt aPx, aPx1, aPx2, aPF1;
835 TopoDS_Edge aERight, aSpxSimm;
836 TopoDS_Face aFx1, aFx2, aFF1;
837 TopTools_ListIteratorOfListOfShape anIt;
840 Handle(Geom_Curve)aC3D =BRep_Tool::Curve(anEx, aT1, aT2);
841 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
845 anOrEx=anEx.Orientation();
848 if (anOrEx==TopAbs_FORWARD) {
849 aSpxSimm.Orientation(TopAbs_REVERSED);
851 else if (anOrEx==TopAbs_REVERSED){
852 aSpxSimm.Orientation(TopAbs_FORWARD);
855 const TopTools_ListOfShape& aLF=anEFMapx.FindFromKey(anEx);
856 anIt.Initialize(aLF);
857 for (; anIt.More(); anIt.Next()) {
858 const TopoDS_Shape& aFE=anIt.Value();
859 aFx1=TopoDS::Face(aFE);
860 anOr=BOPTools_Tools3D::Orientation(anEx, aFx1);
866 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (anEx, aFx1, aT, aPx1, aDNFx1);
868 bIsAdjExists=BOPTools_Tools3D::GetAdjacentFace (aFx1, anEx, anEFMapx, aFx2);
870 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx1, aT, aPx2, aDNFx2);
873 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx2, aT, aPx2, aDNFx2);
877 aFF1.Orientation(TopAbs_FORWARD);
878 BOPTools_Tools3D::OrientEdgeOnFace (anEx, aFF1, aERight);
879 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aERight, aFF1, aT, aPF1, aDNF1);
882 Standard_Real d12, d1, anAlfa12, anAlfa1, aTwoPI;
884 aTwoPI=Standard_PI+Standard_PI;
886 gp_Vec aVx1(aPx, aPx1);
888 gp_Pln aPlnToCompare (aPx, aDNFx1);
890 gp_Vec aVx2(aPx, aPx2);
893 anAlfa12=aDBx1.Angle(aDBx2);
894 d12=BOPTools_Tools3D::SignDistance(aPx2, aPlnToCompare);
896 anAlfa12=aTwoPI-anAlfa12;
899 gp_Vec aVF1(aPx, aPF1);
901 anAlfa1=aDBx1.Angle(aDBF1);
902 d1=BOPTools_Tools3D::SignDistance(aPF1, aPlnToCompare);
904 anAlfa1=aTwoPI-anAlfa1;
908 if (anAlfa1 > anAlfa12) {
914 //modified by NIZNHY-PKV Fri Feb 25 17:00:03 2005t XX
921 aFace2 = itl.Value();
923 TopoDS_Shape anOrigFace2 = aFace2;
924 if (myImagesFaces.IsImage(aFace2)) {
925 anOrigFace2 = myImagesFaces.Root(aFace2);
928 if (!MFP.Contains( aFace2 )) {
932 //if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 )))
933 if (anOrigFace.IsSame(anOrigFace2)) {
938 if (itl.More()) { // aFace2 found, remove it from maps
945 itl.Initialize( LSF );