1 // File: NMTAlgo_Splitter_1.cxx
2 // Created: Mon Feb 2 14:58:54 2004
3 // Author: Peter KURNEV
7 #include <NMTAlgo_Splitter.ixx>
9 #include <Precision.hxx>
13 #include <TopAbs_ShapeEnum.hxx>
16 #include <TopoDS_Edge.hxx>
17 #include <TopoDS_Face.hxx>
18 #include <TopoDS_Shape.hxx>
19 #include <TopoDS_Compound.hxx>
20 #include <TopoDS_Solid.hxx>
21 #include <TopoDS_Iterator.hxx>
24 #include <TopExp_Explorer.hxx>
26 #include <TopTools_MapOfShape.hxx>
27 #include <TopTools_DataMapOfShapeListOfShape.hxx>
28 #include <TopTools_MapIteratorOfMapOfShape.hxx>
29 #include <TopTools_ListOfShape.hxx>
30 #include <TopTools_ListIteratorOfListOfShape.hxx>
31 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
32 #include <TopTools_DataMapIteratorOfDataMapOfShapeShape.hxx>
33 #include <TopTools_IndexedMapOfShape.hxx>
34 #include <TopTools_IndexedDataMapOfShapeShape.hxx>
36 #include <BRep_Tool.hxx>
37 #include <BRepClass3d_SolidClassifier.hxx>
39 #include <NMTAlgo_Loop3d.hxx>
41 #include <BOPTools_Tools2D.hxx>
42 #include <Geom_Curve.hxx>
43 #include <TopAbs_Orientation.hxx>
44 #include <TopTools_ListOfShape.hxx>
45 #include <TopTools_ListIteratorOfListOfShape.hxx>
48 #include <BOPTools_Tools3D.hxx>
50 #include <BRep_Tool.hxx>
52 #include <TopAbs_State.hxx>
56 void RefineShells(const TopoDS_Shape& ,
57 TopTools_ListOfShape&);
59 void RefineSolids(const TopoDS_Shape& ,
60 TopTools_ListOfShape&);
62 //modified by NIZNHY-PKV Fri Feb 25 17:19:39 2005f XX
64 void GetPlanes (const TopoDS_Edge& anEx,
65 const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
66 const TopoDS_Face& aF1,
67 TopAbs_State& aStPF1);
68 //modified by NIZNHY-PKV Fri Feb 25 17:19:44 2005t XX
70 //=======================================================================
71 //function : ShellsAndSolids
73 //=======================================================================
74 void NMTAlgo_Splitter::ShellsAndSolids()
76 Standard_Boolean bMakeSolids;
77 TopAbs_ShapeEnum aType;
78 TopTools_ListIteratorOfListOfShape aItS;
79 TopTools_ListOfShape aLNS;
81 myAddedFacesMap.Clear();
82 bMakeSolids=(myLimit==TopAbs_SHAPE || myLimit<TopAbs_SHELL);
84 //modified by NIZNHY-PKV Thu Feb 24 17:22:32 2005 f XX
85 myInternalFaces.Clear(); // remove it after all modifs
86 //modified by NIZNHY-PKV Thu Feb 24 17:22:56 2005 t XX
87 aItS.Initialize(myListShapes);
88 for ( ;aItS.More(); aItS.Next()) {
89 const TopoDS_Shape& aS=aItS.Value();
91 if (myToolShapes.Contains(aS)) {
96 if (aType > TopAbs_SHELL) {
97 continue;//face,wire,...
102 MakeShells (aS, aLNS);
104 if (bMakeSolids && aType==TopAbs_SOLID) {
105 MakeSolids(aS, aLNS);
108 TopTools_ListIteratorOfListOfShape it (aLNS);
109 for (; it.More(); it.Next()) {
110 myBuilder.Add (myShape, it.Value());
115 aItS.Initialize(myListShapes);
116 for ( ;aItS.More(); aItS.Next()) {
117 const TopoDS_Shape& aS=aItS.Value();
119 aType=aS.ShapeType();
120 if (aType!=TopAbs_FACE || myMapTools.Contains(aS)) {
124 const TopoDS_Shape& aCSF=myImageShape.Image(aS).First();
125 TopoDS_Iterator itS(aCSF);
126 for (; itS.More(); itS.Next()){
127 const TopoDS_Shape& aF=itS.Value();
128 if (!myAddedFacesMap.Contains(aF)){
129 myBuilder.Add (myShape, aF);
134 //=======================================================================
135 //function : MakeShells
136 //purpose : split S into compound of shells
137 //=======================================================================
138 void NMTAlgo_Splitter::MakeShells(const TopoDS_Shape& aS,
139 TopTools_ListOfShape& aLNS)
141 NMTAlgo_Loop3d aShellMaker;
143 // get compound of split faces of aS
144 const TopoDS_Shape& aFC=myImageShape.Image(aS).First();
145 aShellMaker.AddConstFaces(aFC);
147 // add split faces inside aS
148 if (myClosedShapes.Contains(aS)) {
150 // internal faces compound
151 TopoDS_Shape aIFC=FindFacesInside(aS, Standard_True);
152 aShellMaker.AddSectionFaces(aIFC);
155 aLNS=aShellMaker.MakeShells(myAddedFacesMap);
157 RefineShells(aS, aLNS);
159 // Add faces added to new shell to myAddedFacesMap:
160 // avoid rebuilding twice common part of 2 solids.
162 TopTools_ListIteratorOfListOfShape itS(aLNS);
163 TopExp_Explorer expF;
164 for (; itS.More(); itS.Next()) {
165 const TopoDS_Shape& aSh=itS.Value();
166 expF.Init (aSh, TopAbs_FACE);
167 for (; expF.More(); expF.Next()){
168 myAddedFacesMap.Add (expF.Current());
173 //=======================================================================
174 //function : MakeSolids
175 //purpose : make solids out of Shells
176 //=======================================================================
177 void NMTAlgo_Splitter::MakeSolids(const TopoDS_Shape& theSolid,
178 TopTools_ListOfShape& theShellList)
180 // for a solid wrapping other shells or solids without intersection,
181 // it is necessary to find shells making holes in it
182 Standard_Boolean isWrapping;
183 TopTools_ListOfShape aNewSolids; // result
184 TopTools_ListOfShape aHoleShells;
185 TopoDS_Shape anInfinitePointShape;
186 TopTools_DataMapOfShapeShape aInOutMap;
187 TopTools_ListIteratorOfListOfShape aShellIt, aSolisIt;
189 isWrapping = myWrappingSolid.Contains(theSolid);
190 if (!isWrapping && !theShellList.IsEmpty()) {
191 // check if theSolid initially has internal shells
192 TopoDS_Iterator aShellExp (theSolid);
194 isWrapping = aShellExp.More();
197 aShellIt.Initialize(theShellList);
198 for ( ; aShellIt.More(); aShellIt.Next()) {
199 const TopoDS_Shape & aShell = aShellIt.Value();
200 // check if a shell is a hole of theSolid
201 if (isWrapping && IsInside(anInfinitePointShape, aShell)){
202 aHoleShells.Append(aShell);
205 // make a solid from a shell
207 myBuilder.MakeSolid( Solid );
208 myBuilder.Add (Solid, aShell);
210 aNewSolids.Append (Solid);
214 // find outer a shell most close to each hole shell
215 aShellIt.Initialize(aHoleShells);
216 for (; aShellIt.More(); aShellIt.Next()){
217 const TopoDS_Shape & aHole = aShellIt.Value();
219 aSolisIt.Initialize(aNewSolids);
220 for ( ; aSolisIt.More(); aSolisIt.Next()) {
221 const TopoDS_Shape & aSolid = aSolisIt.Value();
223 if (! IsInside(aHole, aSolid)){
227 if ( aInOutMap.IsBound (aHole)){
228 const TopoDS_Shape & aSolid2 = aInOutMap( aHole );
229 if ( IsInside( aSolid, aSolid2 )) {
230 aInOutMap.UnBind( aHole );
231 aInOutMap.Bind ( aHole, aSolid );
235 aInOutMap.Bind (aHole, aSolid);
239 // add aHole to a solid
240 if (aInOutMap.IsBound( aHole )){
241 TopoDS_Shape & aSolid=aInOutMap(aHole);
242 myBuilder.Add (aSolid, aHole);
246 theShellList.Clear();
248 RefineSolids(theSolid, aNewSolids);
250 theShellList.Append(aNewSolids);
253 //=======================================================================
254 //function : FindFacesInside
255 //purpose : return compound of faces of other shapes that are
256 // inside <theShape>.
257 // <theShape> is an object shape.
258 // <CheckClosed> makes avoid faces that do not form a
260 // <All> makes return already added faces
261 //=======================================================================
262 TopoDS_Shape NMTAlgo_Splitter::FindFacesInside(const TopoDS_Shape& theShape,
263 const Standard_Boolean CheckClosed,
264 const Standard_Boolean All)
266 TopExp_Explorer expl;
269 // ================================================
270 // check if internal faces have been already found
271 // ================================================
272 if (myInternalFaces.IsBound(theShape)) {
273 TopoDS_Shape aIntFComp = myInternalFaces.Find (theShape);
274 TopoDS_Shape aIntRemFComp = myIntNotClFaces.Find (theShape);
276 expl.Init( aIntRemFComp, TopAbs_FACE);
277 if (CheckClosed || !expl.More()){
282 myBuilder.MakeCompound( C );
284 for (; expl.More(); expl.Next()){
285 myBuilder.Add( C, expl.Current() );
287 // add good internal faces
288 expl.Init( aIntFComp, TopAbs_FACE);
289 for (; expl.More(); expl.Next()) {
290 myBuilder.Add( C, expl.Current() );
296 // ===================================
297 // get data for internal faces search
298 // ===================================
300 // compound of split faces of theShape
301 const TopoDS_Shape& CSF = myImageShape.Image(theShape).First();
303 TopTools_MapOfShape MSE, MFP;
304 TopTools_DataMapOfShapeListOfShape DMSEFP;
305 TopTools_MapIteratorOfMapOfShape itm;
306 TopTools_ListOfShape EmptyL;
307 TopTools_ListIteratorOfListOfShape itl;
309 // MSE filling: map of new section edges of CSF
310 expl.Init(CSF, TopAbs_EDGE);
311 for (; expl.More(); expl.Next()) {
312 const TopoDS_Shape& aE = expl.Current() ;
316 // DMEF: map edge of CSF - faces of CSF
317 TopTools_IndexedDataMapOfShapeListOfShape DMEF;
318 TopExp::MapShapesAndAncestors(CSF, TopAbs_EDGE, TopAbs_FACE, DMEF);
321 // 1. MFP - a map of faces to process: map of resulting faces except
322 // those of theShape; we`ll add to C those of them which are inside CSF
323 // 2. DMSEFP - edge of MSE => faces of MFP
325 itl.Initialize(myListShapes);
326 for (;itl.More(); itl.Next()) {
327 const TopoDS_Shape& aShape = itl.Value();
329 if ( theShape.IsSame(aShape)) {
333 // iterate on split faces of aShape
334 const TopoDS_Shape& CSF1 = myImageShape.Image(aShape).First();
335 TopoDS_Iterator itF (CSF1);
336 for ( ; itF.More(); itF.Next()) {
337 const TopoDS_Shape& aF1 = itF.Value();
339 // iterate on edges of split faces of aShape,
340 // add to DMSEFP edges that are new
341 expl.Init(aF1, TopAbs_EDGE);
342 for (; expl.More(); expl.Next()) {
343 TopoDS_Shape aE1 = expl.Current();
344 if ( MSE.Contains(aE1)) {// section edge
345 if (!DMSEFP.IsBound(aE1)) {
346 DMSEFP.Bind(aE1, EmptyL);
348 DMSEFP(aE1).Append(aF1);
352 }//for (;itl.More(); itl.Next())
354 // add tool faces... (is absent)
356 // ===========================
357 // find faces inside theShape
358 // ===========================
359 Standard_Boolean sameDom1, sameDom2;
360 Standard_Boolean skipAlreadyAdded = Standard_False;
361 Standard_Boolean GoodOri, inside;
363 TopTools_ListOfShape KeepFaces;
364 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
366 // iterate on section edges, check faces of other shapes
367 // sharing section edges and put internal faces to KeepFaces
368 Mapit.Initialize(DMSEFP);
369 for (; Mapit.More() ; Mapit.Next()) {
370 // a new edge of theShape
371 const TopoDS_Edge& E = TopoDS::Edge (Mapit.Key());
373 //Standard_Boolean isSectionE=IsSectionEdge(E);//(OrigE);
375 // split faces of other shapes sharing E
376 TopTools_ListOfShape& LSF = DMSEFP.ChangeFind(E);
378 itl.Initialize( LSF );
380 // a split faces of other shape
381 TopoDS_Face aFace1 = TopoDS::Face(itl.Value());
382 // remove aFace1 form DMSEFP and MFP
383 LSF.Remove( itl ); // == itl.Next();
384 if (!MFP.Remove(aFace1))
385 continue; // was not is MFP (i.e already checked)
387 // check if aFace1 was already added to 2 shells
389 myAddedFacesMap.Contains(aFace1) &&
390 myAddedFacesMap.Contains(aFace1.Reversed())) {
391 skipAlreadyAdded = Standard_True;
394 TopoDS_Shape anOrigFace = aFace1;
395 if (myImagesFaces.IsImage(aFace1)){
396 anOrigFace = myImagesFaces.Root(aFace1);
401 // check that anOrigFace is not same domain with CSF faces it intersects
403 const TopTools_ListOfShape& FL = DMEF.FindFromKey(E); //faces of CSF sharing E
405 const TopoDS_Shape& origF1 = myImagesFaces.IsImage(FL.First()) ?
406 myImagesFaces.Root(FL.First()) : FL.First();
408 const TopoDS_Shape& origF2 = myImagesFaces.IsImage(FL.Last()) ?
409 myImagesFaces.Root(FL.Last()) : FL.Last();
411 sameDom1 = anOrigFace.IsSame( origF1 );
412 sameDom2 = anOrigFace.IsSame( origF2 );
414 if (!(sameDom1 || sameDom2) && HasSameDomainF( TopoDS::Face(anOrigFace) )) {
415 sameDom1 = IsSameDomainF( TopoDS::Face(anOrigFace), TopoDS::Face(origF1));
416 if (origF1 == origF2) {
420 if (sameDom1 && sameDom2){
424 if (sameDom1 || sameDom2) {
425 inside = NMTAlgo_Loop3d::IsInside (E,
426 TopoDS::Face(FL.First()),
427 TopoDS::Face(FL.Last()),
429 if (inside || (dot + Precision::Angular() >= 1.0)) {
430 continue; // E is convex between origF1 and origF2 or they are tangent
434 GetPlanes(E, DMEF, aFace1, aState);
435 if (aState==TopAbs_IN) {
436 KeepFaces.Append(aFace1);
438 } //while (itl.More()) {
439 } //for (; Mapit.More() ; Mapit.Next() )
441 // ===================================================
442 // add not distributed faces connected with KeepFaces
443 // ===================================================
445 // ultimate list of internal faces
446 TopTools_ListOfShape KeptFaces;
448 // add to MFP not split tool faces as well, they may be connected with
449 // tool faces interfering with theShape
451 itm.Initialize(myMapTools);
452 for (; itm.More(); itm.Next() ) {
453 const TopoDS_Shape& aToolFace = itm.Key();
454 if (!myImageShape.HasImage(aToolFace)){
461 KeptFaces.Append (KeepFaces);
463 while (!KeepFaces.IsEmpty()) {
464 // KeepEdges : map of edges of faces kept last time
465 TopTools_IndexedMapOfShape KeepEdges;
466 for ( itl.Initialize(KeepFaces); itl.More(); itl.Next() ) {
467 TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges);
468 KeptFaces.Append( itl.Value() );
473 // keep faces connected with already kept faces by KeepEdges
474 for ( itm.Initialize(MFP); itm.More(); itm.Next() ) {
475 const TopoDS_Shape& FP = itm.Key();
476 for (expl.Init(FP,TopAbs_EDGE); expl.More(); expl.Next()) {
477 const TopoDS_Shape& se = expl.Current();
478 if (!MSE.Contains(se) && KeepEdges.Contains(se) ) {
479 KeepFaces.Append(FP);
487 // ===============================================================
488 // here MFP contains faces outer of theShape and those of shapes
489 // which do not interfere with theShape at all and between which
490 // there may be those wrapped by theShape and whose faces may be
491 // needed to be returned as well
492 // ===============================================================
494 Standard_Boolean isSolid = (theShape.ShapeType() == TopAbs_SOLID);
495 if (All || isSolid) // All is for sub-result removal
497 for ( itm.Initialize( MFP ); itm.More(); itm.Next() ) {
498 TopoDS_Shape aFace = itm.Key();
500 // find a shape aFace originates from
501 TopoDS_Shape anOrigShape = GetOriginalShape( aFace );
503 // find out if all faces of anOrigShape are not in MFP
504 // and by the way remove them from MFP
505 Standard_Boolean isAllOut = Standard_True;
506 TopoDS_Shape aSplitFaces = anOrigShape;
507 if (myImageShape.HasImage(anOrigShape))
508 aSplitFaces = myImageShape.Image(anOrigShape).First();
510 TopTools_ListOfShape aSplitFaceL;
511 for (expl.Init( aSplitFaces, TopAbs_FACE ); expl.More(); expl.Next())
513 const TopoDS_Shape & aSpFace = expl.Current();
514 // a tool face which become object has image but the whole tool shape has not
515 if (myImageShape.HasImage( aSpFace ))
517 TopExp_Explorer exF (myImageShape.Image( aSpFace ).First(), TopAbs_FACE );
518 for ( ; exF.More(); exF.Next() )
520 aSplitFaceL.Append( exF.Current() );
521 if ( ! MFP.Remove( exF.Current() ))
522 isAllOut = Standard_False;
527 aSplitFaceL.Append( aSpFace );
528 if ( ! MFP.Remove( aSpFace ))
529 isAllOut = Standard_False;
532 itm.Initialize( MFP );
536 // classify anOrigShape against theShape
537 if (IsInside (anOrigShape, theShape)) {
538 if (isSolid && myClosedShapes.Contains(anOrigShape)) {
539 // to make a special care at solid reconstruction
540 myWrappingSolid.Add ( theShape );
542 // keep faces of an internal shape anOrigShape
543 KeptFaces.Append( aSplitFaceL );
548 // ====================================================
549 // check if kept faces form a shell without free edges
550 // ====================================================
552 DMEF.Clear(); // edge - kept faces
553 MFP.Clear(); // reuse it for wrong faces
555 for (itl.Initialize(KeptFaces); itl.More(); itl.Next() )
556 TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, DMEF);
558 Standard_Integer i, nb = DMEF.Extent();
559 Standard_Boolean isClosed = Standard_False;
561 isClosed = Standard_True;
562 for (i=1; isClosed && i<=nb; ++i) {
563 const TopoDS_Shape& E = DMEF.FindKey( i );
564 if (! BRep_Tool::Degenerated( TopoDS::Edge( E )) &&
566 isClosed = ( DMEF(i).Extent() != 1 );
569 const TopoDS_Shape& F = DMEF.FindFromIndex( i-1 ).First(); // bad face
571 // remove bad face from DMEF
572 for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) {
573 const TopoDS_Shape& E = expl.Current();
574 TopTools_ListOfShape& FL = DMEF.ChangeFromKey( E );
575 for (itl.Initialize( FL ); itl.More(); itl.Next() ) {
576 if ( F.IsSame( itl.Value() )) {
591 // compound of removed internal faces
592 TopoDS_Compound CNotCl;
594 myBuilder.MakeCompound(C);
595 myBuilder.MakeCompound(CNotCl);
598 itl.Initialize(KeptFaces);
599 for (; itl.More(); itl.Next() ) {
600 TopoDS_Shape & aIntFace = itl.Value();
603 myAddedFacesMap.Contains(aIntFace) &&
604 myAddedFacesMap.Contains(aIntFace.Reversed())) {
608 if (! MFP.Contains( aIntFace )){
609 myBuilder.Add(C, aIntFace);
612 myBuilder.Add(CNotCl, aIntFace);
616 if (!skipAlreadyAdded && CheckClosed) {
617 myInternalFaces.Bind(theShape, C);
618 myIntNotClFaces.Bind(theShape, CNotCl);
622 if (!myMapSIFC.IsBound(theShape)) {
623 TopoDS_Compound aCIF;
624 myBuilder.MakeCompound(aCIF);
626 itl.Initialize(KeptFaces);
627 for (; itl.More(); itl.Next() ) {
628 TopoDS_Shape & aIntFace = itl.Value();
629 if (! MFP.Contains(aIntFace )){
630 myBuilder.Add(aCIF, aIntFace);
633 myMapSIFC.Bind(theShape, aCIF);
638 //=======================================================================
639 //function : IsInside
640 //purpose : Return True if the first vertex of S1 inside S2.
641 // If S1.IsNull(), check infinite point against S2.
642 //=======================================================================
643 Standard_Boolean NMTAlgo_Splitter::IsInside (const TopoDS_Shape& theS1,
644 const TopoDS_Shape& theS2)
646 BRepClass3d_SolidClassifier aClassifier( theS2 );
648 TopExp_Explorer expl(theS1, TopAbs_VERTEX);
651 aClassifier.PerformInfinitePoint( ::RealSmall());
654 const TopoDS_Vertex & aVertex = TopoDS::Vertex( expl.Current() );
655 aClassifier.Perform (BRep_Tool::Pnt( aVertex ),
656 BRep_Tool::Tolerance( aVertex ));
659 return ( aClassifier.State() == TopAbs_IN );
661 //=======================================================================
662 //function : GetOriginalShape
663 //purpose : Return the shape aShape originates from. aShape
664 // should be a face or more complex result shape
665 //=======================================================================
666 TopoDS_Shape NMTAlgo_Splitter::GetOriginalShape(const TopoDS_Shape& theShape) const
668 TopoDS_Shape anOrigShape;
670 TopExp_Explorer expl( theShape, TopAbs_FACE);
672 TopoDS_Shape aFace = expl.Current();
673 if (myImagesFaces.IsImage( aFace ))
674 aFace = myImagesFaces.Root( aFace );
675 anOrigShape = myFaceShapeMap.Find( aFace );
679 //=======================================================================
680 //function :RefineShells
682 //=======================================================================
683 void RefineShells(const TopoDS_Shape& aS,
684 TopTools_ListOfShape& aLNS)
686 Standard_Boolean bFound;
687 Standard_Integer iS, jS, aNbSOrs, aNbSIms, aNbFOrs, aNbFIms, kFOrs, aNb;
688 TopTools_ListIteratorOfListOfShape aIt;
689 TopTools_IndexedMapOfShape aMSOrs, aMSIms, aMFOrs, aMFIms;
690 TopTools_IndexedDataMapOfShapeShape aMImOr;
691 TopTools_ListOfShape aLS;
693 TopExp::MapShapes(aS, TopAbs_SHELL, aMSOrs);
694 aIt.Initialize(aLNS);
695 for (;aIt.More(); aIt.Next()) {
696 const TopoDS_Shape& aSh=aIt.Value();
700 aNbSOrs=aMSOrs.Extent();
701 aNbSIms=aMSIms.Extent();
703 for (iS=1; iS<=aNbSOrs; ++iS) {
704 const TopoDS_Shape& aSOr=aMSOrs(iS);
706 TopExp::MapShapes(aSOr, TopAbs_FACE, aMFOrs);
707 aNbFOrs=aMFOrs.Extent();
709 for (jS=1; jS<=aNbSIms; ++jS) {
710 const TopoDS_Shape& aSIm=aMSIms(jS);
711 if (aMImOr.Contains(aSIm)) {
716 TopExp::MapShapes(aSIm, TopAbs_FACE, aMFIms);
717 aNbFIms=aMFIms.Extent();
719 if (aNbFIms==aNbFOrs) {
720 bFound=Standard_True;
721 for (kFOrs=1; kFOrs<=aNbFOrs; ++kFOrs) {
722 const TopoDS_Shape& aFOr=aMFOrs(kFOrs);
723 if (!aMFIms.Contains(aFOr)) {
724 bFound=Standard_False;
729 aMImOr.Add(aSIm, aSOr);
732 } //if (aNbFIms==aNbFOrs)
737 aIt.Initialize(aLNS);
738 for (;aIt.More(); aIt.Next()) {
739 const TopoDS_Shape& aSh=aIt.Value();
740 if (aMImOr.Contains(aSh)) {
741 const TopoDS_Shape& aSOr=aMImOr.FindFromKey(aSh);
753 //=======================================================================
754 //function :RefineSolids
756 //=======================================================================
757 void RefineSolids(const TopoDS_Shape& aSolidOr,
758 TopTools_ListOfShape& aLNS)
760 Standard_Integer aNb, iS, aNbSOrs, aNbSIms;
761 TopoDS_Shape aSolidIm;
762 TopTools_IndexedMapOfShape aMSOrs, aMSIms;
769 aSolidIm=aLNS.First();
771 TopExp::MapShapes(aSolidOr, TopAbs_SHELL, aMSOrs);
772 TopExp::MapShapes(aSolidIm, TopAbs_SHELL, aMSIms);
773 aNbSOrs=aMSOrs.Extent();
774 aNbSIms=aMSIms.Extent();
775 if (aNbSOrs!=aNbSIms) {
779 for (iS=1; iS<=aNbSOrs; ++iS) {
780 const TopoDS_Shape& aSOr=aMSOrs(iS);
781 if (!aMSIms.Contains(aSOr)) {
787 aLNS.Append(aSolidOr);
789 //modified by NIZNHY-PKV Fri Feb 25 16:59:57 2005f XX
790 //=======================================================================
791 //function : GetPlanes
793 //=======================================================================
794 void GetPlanes (const TopoDS_Edge& anEx,
795 const TopTools_IndexedDataMapOfShapeListOfShape& anEFMapx,
796 const TopoDS_Face& aF1,
797 TopAbs_State& aStPF1)
800 Standard_Boolean bIsAdjExists;
801 Standard_Real aT, aT1, aT2;
802 TopAbs_Orientation anOrEx, anOr;
803 gp_Dir aDNFx1, aDNFx2, aDNF1;
804 gp_Pnt aPx, aPx1, aPx2, aPF1;
805 TopoDS_Edge aERight, aSpxSimm;
806 TopoDS_Face aFx1, aFx2, aFF1;
807 TopTools_ListIteratorOfListOfShape anIt;
810 Handle(Geom_Curve)aC3D =BRep_Tool::Curve(anEx, aT1, aT2);
811 aT=BOPTools_Tools2D::IntermediatePoint(aT1, aT2);
815 anOrEx=anEx.Orientation();
818 if (anOrEx==TopAbs_FORWARD) {
819 aSpxSimm.Orientation(TopAbs_REVERSED);
821 else if (anOrEx==TopAbs_REVERSED){
822 aSpxSimm.Orientation(TopAbs_FORWARD);
825 const TopTools_ListOfShape& aLF=anEFMapx.FindFromKey(anEx);
826 anIt.Initialize(aLF);
827 for (; anIt.More(); anIt.Next()) {
828 const TopoDS_Shape& aFE=anIt.Value();
829 aFx1=TopoDS::Face(aFE);
830 anOr=BOPTools_Tools3D::Orientation(anEx, aFx1);
836 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (anEx, aFx1, aT, aPx1, aDNFx1);
838 bIsAdjExists=BOPTools_Tools3D::GetAdjacentFace (aFx1, anEx, anEFMapx, aFx2);
840 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx1, aT, aPx2, aDNFx2);
843 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aSpxSimm, aFx2, aT, aPx2, aDNFx2);
847 aFF1.Orientation(TopAbs_FORWARD);
848 BOPTools_Tools3D::OrientEdgeOnFace (anEx, aFF1, aERight);
849 BOPTools_Tools3D::GetApproxNormalToFaceOnEdge (aERight, aFF1, aT, aPF1, aDNF1);
852 Standard_Real d12, d1, anAlfa12, anAlfa1, aTwoPI;
854 aTwoPI=Standard_PI+Standard_PI;
856 gp_Vec aVx1(aPx, aPx1);
858 gp_Pln aPlnToCompare (aPx, aDNFx1);
860 gp_Vec aVx2(aPx, aPx2);
863 anAlfa12=aDBx1.Angle(aDBx2);
864 d12=BOPTools_Tools3D::SignDistance(aPx2, aPlnToCompare);
866 anAlfa12=aTwoPI-anAlfa12;
869 gp_Vec aVF1(aPx, aPF1);
871 anAlfa1=aDBx1.Angle(aDBF1);
872 d1=BOPTools_Tools3D::SignDistance(aPF1, aPlnToCompare);
874 anAlfa1=aTwoPI-anAlfa1;
878 if (anAlfa1 > anAlfa12) {
883 //modified by NIZNHY-PKV Fri Feb 25 17:00:03 2005t XX
890 aFace2 = itl.Value();
892 TopoDS_Shape anOrigFace2 = aFace2;
893 if (myImagesFaces.IsImage(aFace2)) {
894 anOrigFace2 = myImagesFaces.Root(aFace2);
897 if (!MFP.Contains( aFace2 )) {
901 //if (anOrigFace.IsSame( myImagesFaces.Root( aFace2 )))
902 if (anOrigFace.IsSame(anOrigFace2)) {
907 if (itl.More()) { // aFace2 found, remove it from maps
914 itl.Initialize( LSF );