2 // File : Partition_Spliter.cxx
3 // Created : Thu Aug 02 16:07:39 2001
4 // Author : Benedicte MARTIN
7 // Copyright : Open CASCADE
10 #include "Partition_Spliter.ixx"
11 #include "Partition_Inter2d.hxx"
12 #include "Partition_Inter3d.hxx"
13 #include "Partition_Loop2d.hxx"
14 #include "Partition_Loop3d.hxx"
16 #include "utilities.h"
18 #include <TopExp_Explorer.hxx>
20 #include <Precision.hxx>
21 #include <TopAbs_Orientation.hxx>
23 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
24 #include <TopTools_DataMapOfShapeListOfShape.hxx>
25 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
26 #include <TopTools_IndexedMapOfShape.hxx>
27 #include <TopTools_ListIteratorOfListOfShape.hxx>
28 #include <TopTools_ListOfShape.hxx>
29 #include <TopTools_MapIteratorOfMapOfShape.hxx>
30 #include <TopTools_SequenceOfShape.hxx>
32 #include <gp_Pnt2d.hxx>
35 #include <Geom2d_Curve.hxx>
36 #include <Geom_Curve.hxx>
37 #include <Geom_Surface.hxx>
38 #include <Geom_TrimmedCurve.hxx>
41 #include <TopoDS_Compound.hxx>
42 #include <TopoDS_Edge.hxx>
43 #include <TopoDS_Face.hxx>
44 #include <TopoDS_Iterator.hxx>
45 #include <TopoDS_Shell.hxx>
46 #include <TopoDS_Solid.hxx>
47 #include <TopoDS_Vertex.hxx>
48 #include <TopoDS_Wire.hxx>
50 #include <BRep_Tool.hxx>
51 #include <BRepLib.hxx>
52 #include <BRepBndLib.hxx>
55 #include <Extrema_ExtPC.hxx>
56 #include <GeomAdaptor_Curve.hxx>
57 #include <TopOpeBRepTool_CurveTool.hxx>
65 Standard_IMPORT Standard_Boolean AffichInter3d ;
66 Standard_IMPORT Standard_Boolean AffichInter2d ;
67 Standard_IMPORT Standard_Boolean AffichVertex;
68 Standard_IMPORT Standard_Boolean AffichFace;
69 Standard_IMPORT Standard_Boolean AffichWire;
70 Standard_IMPORT Standard_Boolean SelectFace;
72 static char* names = new char[100];
76 //=======================================================================
77 //function : Partition_Spliter
78 //purpose : constructor
79 //=======================================================================
81 Partition_Spliter::Partition_Spliter()
83 myAsDes = new BRepAlgo_AsDes;
87 //=======================================================================
89 //purpose : add cutting tool that will _NOT_ be in result
90 //=======================================================================
92 void Partition_Spliter::AddTool(const TopoDS_Shape& S)
94 for (TopExp_Explorer exp(S,TopAbs_FACE); exp.More(); exp.Next())
95 myMapTools.Add(exp.Current());
98 //=======================================================================
100 //purpose : add object Shape to be splited
101 //=======================================================================
103 void Partition_Spliter::AddShape(const TopoDS_Shape& S)
105 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
106 TopoDS_Iterator it (S);
107 for (; it.More(); it.Next())
108 AddShape( it.Value());
112 TopExp_Explorer exp(S,TopAbs_FACE);
113 if (!exp.More()) { // do not split edges and vertices
114 //myBuilder.Add( myShape, S );
118 myListShapes.Append(S);
120 for (; exp.More(); exp.Next()) {
121 myFaceShapeMap.Bind( exp.Current(), S );
122 myMapFaces.Add(exp.Current());
123 myImagesFaces.SetRoot(exp.Current());
127 //=======================================================================
129 //purpose : return resulting compound
130 //=======================================================================
132 TopoDS_Shape Partition_Spliter::Shape() const
137 //=======================================================================
139 //purpose : clear fields
140 //=======================================================================
142 void Partition_Spliter::Clear()
144 myDoneStep = TopAbs_SHAPE;
146 myListShapes.Clear();
149 myFaceShapeMap.Clear();
151 myNewSection.Clear();
154 myImagesFaces.Clear();
155 myImagesEdges.Clear();
156 myImageShape.Clear();
158 myInter3d = Partition_Inter3d(myAsDes);
160 myAddedFacesMap.Clear();
162 myInternalFaces.Clear();
165 //=======================================================================
167 //purpose : produce a result
168 //=======================================================================
170 void Partition_Spliter::Compute(const TopAbs_ShapeEnum Limit)
172 if ((Limit != TopAbs_SHAPE && myDoneStep == Limit) ||
173 (Limit == TopAbs_SHAPE && myDoneStep == TopAbs_SOLID))
176 myBuilder.MakeCompound( myShape );
178 TopTools_MapIteratorOfMapOfShape it;
179 TopTools_ListIteratorOfListOfShape itl;
182 if (myDoneStep > TopAbs_VERTEX) {
184 TopTools_ListOfShape aListFaces;
185 aListFaces = myImagesFaces.Roots();
186 for (it.Initialize(myMapTools); it.More(); it.Next())
187 aListFaces.Append(it.Key());
189 //-----------------------------------------------
190 // Intersection between faces
191 //-----------------------------------------------
192 // result is in myAsDes as a map Face - list of new edges;
193 // special care is done for section edges, same domain faces and vertices:
194 // data about them is inside myInter3d
196 myInter3d.CompletPart3d(aListFaces, myFaceShapeMap);
198 TopTools_MapOfShape& Modif = myInter3d.TouchedFaces();
199 TopTools_MapOfShape& NewEdges = myInter3d.NewEdges();
200 Handle(BRepAlgo_AsDes) SectionEdgesAD = myInter3d.SectionEdgesAD();
204 Standard_Integer i=0;
205 for (it.Initialize(NewEdges); it.More(); it.Next(), i++) {
206 sprintf(names,"e_%d",i);
207 cout << "donly " << names << endl;
208 DBRep::Set(names,it.Key());
212 //if (Modif.IsEmpty()) return;
214 // -----------------------------------------------
215 // store tools intersecting solids as object shapes,
216 // they must split into faces too
217 // -----------------------------------------------
219 // build edge - face map for tool faces
220 TopTools_IndexedDataMapOfShapeListOfShape EFM;
221 for (it.Initialize(myMapTools); it.More(); it.Next())
222 TopExp::MapShapesAndAncestors( it.Key(), TopAbs_EDGE, TopAbs_FACE, EFM);
224 TopTools_MapOfShape checkedEdgeMap;
225 for (itl.Initialize( myListShapes ); itl.More(); itl.Next()) {
226 TopExp_Explorer expSo (itl.Value(), TopAbs_SOLID);
227 for (; expSo.More(); expSo.Next()) {
229 TopTools_ListOfShape checkFL; // faces to check
230 for ( exp.Init( expSo.Current(), TopAbs_FACE); exp.More(); exp.Next())
231 checkFL.Append ( exp.Current());
233 // iterate a list while appending new items
234 TopTools_ListIteratorOfListOfShape itF, itCF;
235 for (itCF.Initialize (checkFL) ; itCF.More(); itCF.Next()) {
236 const TopoDS_Shape& F = itCF.Value();
237 if ( myAsDes->HasDescendant( F )) {
238 // new edges on face to check
239 const TopTools_ListOfShape& NEL = myAsDes->Descendant( F );
240 TopTools_ListIteratorOfListOfShape itE (NEL);
241 for (; itE.More(); itE.Next()) {
242 if (checkedEdgeMap.Add( itE.Value() )) {
243 // intersected faces originating an edge
244 itF.Initialize (myAsDes->Ascendant( itE.Value() ));
245 for (; itF.More(); itF.Next()) {
246 if (!myMapFaces.Contains( itF.Value())) {
247 AddShape( itF.Value() );
248 checkFL.Append( itF.Value() );
251 // faces having section edges on F
252 if (EFM.Contains( itE.Value()))
253 itF.Initialize ( EFM.FindFromKey (itE.Value()));
254 for (; itF.More(); itF.Next()) {
255 if (!myMapFaces.Contains( itF.Value())) {
256 AddShape( itF.Value() );
257 checkFL.Append( itF.Value() );
263 // find faces cut by edges of F
264 TopExp_Explorer expE(F, TopAbs_EDGE);
265 for (; expE.More();expE.Next()) {
266 if ( SectionEdgesAD->HasAscendant( expE.Current() )
267 && checkedEdgeMap.Add( expE.Current() )) {
268 itF.Initialize( SectionEdgesAD->Ascendant( expE.Current()) );
269 for (; itF.More(); itF.Next()) {
270 if (!myMapFaces.Contains( itF.Value())) {
271 AddShape( itF.Value() );
272 checkFL.Append( itF.Value() );
281 //-----------------------------------------------
282 // Intersection of edges
283 //-----------------------------------------------
285 // add existing vertices to edges of object faces in myAsDes
286 TopTools_MapOfShape DoneEM;
287 for ( it.Initialize(myMapFaces); it.More(); it.Next()) {
288 const TopoDS_Shape& F = it.Key();
289 TopoDS_Face FForward = TopoDS::Face(F.Oriented(TopAbs_FORWARD));
290 for (exp.Init(FForward,TopAbs_EDGE); exp.More(); exp.Next()) {
291 const TopoDS_Edge& E = TopoDS::Edge( exp.Current() );
292 myAsDes->Add(FForward,E);
294 TopoDS_Iterator itV(E);
295 for (; itV.More(); itV.Next()) {
296 const TopoDS_Vertex& V = TopoDS::Vertex( itV.Value());
297 myAsDes->Add(E, myInter3d.ReplaceSameDomainV( V, E ));
303 // intersect edges that are descendants of a face in myAsDes
304 for ( it.Initialize(Modif); it.More(); it.Next()) {
305 const TopoDS_Face& F = TopoDS::Face(it.Key());
306 Partition_Inter2d::CompletPart2d (myAsDes, F, NewEdges);
308 // now myAsDes contains also new vertices made at edge intersection as
309 // descendant of edges both new and old
311 myDoneStep = TopAbs_VERTEX;
313 } // if (myDoneStep > TopAbs_VERTEX)
315 if (Limit == TopAbs_VERTEX) {
316 // add new vertices to myShape
317 for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) {
318 if (! myAsDes->HasDescendant( it.Key() ))
320 itl.Initialize( myAsDes->Descendant( it.Key() ));
321 for (; itl.More(); itl.Next())
322 myBuilder.Add ( myShape, itl.Value() );
327 if (myDoneStep > TopAbs_EDGE) {
329 //-----------------------------------------------
330 // Reconstruction of all the edges.
331 //-----------------------------------------------
333 // Add to myAsDes end vertices of new edges and cut new edges
335 TopTools_MapOfShape& NewEdges = myInter3d.NewEdges();
336 TopTools_ListOfShape LSE; // all edge splits
337 for ( it.Initialize(NewEdges); it.More(); it.Next()) {
340 TopoDS_Edge EE = TopoDS::Edge(it.Key());
342 TopTools_ListOfShape aListV, aListF;
343 aListV = myAsDes->Descendant(EE); // intersection vertices
344 aListF = myAsDes->Ascendant(EE); // intersected faces
346 if (aListV.IsEmpty())
347 continue; // new edge does not intersect any other edge
349 // one face is Tool, the other is Shape:
350 if ( (myMapTools.Contains(aListF.First()) && myMapFaces.Contains(aListF.Last()) ) ||
351 ( myMapFaces.Contains(aListF.First()) && myMapTools.Contains(aListF.Last()) ) )
353 TopExp::Vertices(EE,V1,V2);
354 Standard_Real Tol = Max (BRep_Tool::Tolerance( V1 ),
355 BRep_Tool::Tolerance( V2 ));
357 gp_Pnt P1 = BRep_Tool::Pnt(V1);
358 gp_Pnt P2 = BRep_Tool::Pnt(V2);
359 Standard_Boolean AddV1 = Standard_True;
360 Standard_Boolean AddV2 = Standard_True;
362 // add only if there is no intersection at end vertex
363 for (itl.Initialize(aListV); itl.More(); itl.Next()) {
364 const TopoDS_Vertex& Ve = TopoDS::Vertex(itl.Value()) ;
365 Standard_Real Tol2 = Max ( Tol, BRep_Tool::Tolerance( Ve ));
367 gp_Pnt P = BRep_Tool::Pnt(Ve);
368 if (AddV1 && P.SquareDistance(P1) <= Tol2)
369 AddV1 = Standard_False;
371 if (AddV2 && P.SquareDistance(P2) <= Tol2)
372 AddV2 = Standard_False;
387 for(itl.Initialize(aListV);itl.More();itl.Next(), j++) {
388 sprintf(names,"v_%d",j);
389 cout << "donly " << names << endl;
390 DBRep::Set(names,itl.Value());
395 Standard_Integer NbV=aListV.Extent() ;
396 if (NbV>1 || (NbV==1 && V1.IsSame(V2)) ) {
398 TopTools_ListOfShape LNE;
399 MakeEdges (EE,aListV, LNE);
400 myImagesEdges.Bind(EE,LNE);
406 for ( it.Initialize(myMapFaces); it.More(); it.Next()) {
407 for (exp.Init( it.Key(), TopAbs_EDGE); exp.More(); exp.Next()) {
408 const TopoDS_Edge& EE = TopoDS::Edge( exp.Current() );
409 if ( myImagesEdges.HasImage( EE ))
411 TopTools_ListOfShape LNE;
412 const TopTools_ListOfShape& aListVV = myAsDes->Descendant(EE);
413 MakeEdges (EE, aListVV, LNE);
414 myImagesEdges.Bind(EE,LNE);
419 MergeEqualEdges( LSE );
421 myDoneStep = TopAbs_EDGE;
423 } // if (myDoneStep > TopAbs_EDGE)
425 if (Limit == TopAbs_EDGE) {
426 // add splits of old edges
427 TopTools_ListIteratorOfListOfShape itNE;
428 for (itl.Initialize( myListShapes );itl.More();itl.Next()) {
429 for ( exp.Init( itl.Value(), TopAbs_EDGE ); exp.More(); exp.Next()) {
430 itNE.Initialize( myImagesEdges.Image( exp.Current() ));
431 for ( ; itNE.More(); itNE.Next())
432 myBuilder.Add ( myShape, itNE.Value() );
435 // add splits of new edges
436 for ( it.Initialize( myInter3d.NewEdges() ); it.More(); it.Next()) {
437 itNE.Initialize( myImagesEdges.Image( it.Key() ));
438 for (; itNE.More(); itNE.Next())
439 myBuilder.Add ( myShape, itNE.Value() );
444 // make faces interfering by section edges share the same splits
445 //ProcessSectionEdges( SectionEdgesAD );
448 //-----------------------------------------------
450 //-----------------------------------------------
452 if (myDoneStep > TopAbs_FACE) {
454 for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
455 TopoDS_Shape FacesComp = MakeFaces ( itl.Value());
456 // there is a cunning here: myImagesFaces keeps faces made by Loop2d
457 // but some of them may be replaced with splits of same domain face
458 // and myImageShape keeps ultimate result
459 myImageShape.Bind( itl.Value(), FacesComp );
462 myDoneStep = TopAbs_FACE;
465 if (Limit == TopAbs_WIRE ||
466 Limit == TopAbs_FACE) {
467 for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
468 if ( myMapTools.Contains( itl.Value() ))
469 continue; // no result needed for a tool face
470 const TopoDS_Shape& FacesComp = myImageShape.Image( itl.Value() ).First();
471 for ( exp.Init( FacesComp, Limit); exp.More(); exp.Next())
472 myBuilder.Add ( myShape, exp.Current());
478 //-----------------------------------------------
480 //-----------------------------------------------
482 // solids must remains closed, so process them first
483 Standard_Boolean makeSolids = (Limit == TopAbs_SHAPE ||
484 Limit < TopAbs_SHELL);
486 for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
487 if (itl.Value().ShapeType() == TopAbs_SOLID) {
488 TopTools_ListOfShape NSL;
489 MakeShells (itl.Value() , NSL);
490 TopTools_ListIteratorOfListOfShape itS(NSL);
491 for ( ; itS.More(); itS.Next())
493 // make a solid from a shell
495 myBuilder.MakeSolid( Solid );
496 myBuilder.Add (Solid, itS.Value());
497 myBuilder.Add (myShape, Solid);
500 myBuilder.Add (myShape, itS.Value());
504 //-----------------------------------------------
506 //-----------------------------------------------
508 for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
509 if (itl.Value().ShapeType() == TopAbs_SHELL) {
510 TopTools_ListOfShape NSL;
511 MakeShells (itl.Value() , NSL);
512 TopTools_ListIteratorOfListOfShape itS(NSL);
513 for ( ; itS.More(); itS.Next())
514 myBuilder.Add (myShape, itS.Value());
518 //-----------------------------------------------
520 //-----------------------------------------------
522 for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
523 const TopoDS_Shape& S = itl.Value();
524 if (S.ShapeType() != TopAbs_FACE ||
525 myMapTools.Contains( S ))
527 TopoDS_Iterator itS( myImageShape.Image(S).First() );
528 for (; itS.More(); itS.Next())
529 if (! myAddedFacesMap.Contains( itS.Value() ))
530 myBuilder.Add (myShape, itS.Value());
533 myDoneStep = makeSolids ? TopAbs_SOLID : TopAbs_SHELL;
538 //=======================================================================
541 //=======================================================================
543 static void Tri(const TopoDS_Edge& E,
544 TopTools_SequenceOfShape& Seq)
546 Standard_Boolean Invert = Standard_True;
547 Standard_Integer NbPoints = Seq.Length();
552 Invert = Standard_False;
553 for ( Standard_Integer i = 1; i < Seq.Length(); i++) {
555 V1 = TopoDS::Vertex(Seq.Value(i));
556 V2 = TopoDS::Vertex(Seq.Value(i+1));
558 V1.Orientation(TopAbs_INTERNAL);
559 V2.Orientation(TopAbs_INTERNAL);
561 U1 = BRep_Tool::Parameter(V1,E);
562 U2 = BRep_Tool::Parameter(V2,E);
564 if (IsEqual(U1,U2)) {
571 Invert = Standard_True;
577 //=======================================================================
578 //function : MakeEdges
579 //purpose : cut E by vertices VOnE, return list of new edges NE
580 //=======================================================================
582 void Partition_Spliter::MakeEdges (const TopoDS_Edge& E,
583 const TopTools_ListOfShape& VOnE,
584 TopTools_ListOfShape& NE ) const
587 WE.Orientation(TopAbs_FORWARD);
589 TopTools_ListIteratorOfListOfShape itv(VOnE);
590 TopTools_SequenceOfShape SV;
592 Standard_Real U1,U2, f, l;
593 TopoDS_Vertex V1,V2,VF,VL;
595 BRep_Tool::Range(WE,f,l);
596 TopExp::Vertices(WE,VF,VL);
598 if (VOnE.Extent() < 3) { // do not rebuild not cut edge
599 if (( VF.IsSame( VOnE.First() ) && VL.IsSame( VOnE.Last() )) ||
600 VL.IsSame( VOnE.First() ) && VF.IsSame( VOnE.Last() ) ) {
606 for (; itv.More(); itv.Next())
607 SV.Append(itv.Value());
611 Standard_Integer iVer, NbVer = SV.Length();
614 //----------------------------------------------------------------
615 // Construction of the new edges .
616 //----------------------------------------------------------------
618 if (VF.IsSame(VL)) { // closed edge
620 SV.Append( SV.First() );
621 else if (!SV.First().IsSame(SV.Last())) {
622 Standard_Boolean isFirst=0;
623 Standard_Real minDU = 1.e10;
624 TopoDS_Vertex endV = Partition_Inter2d::FindEndVertex(VOnE, f,l, E, isFirst,minDU);
625 if (endV.IsSame(SV.First()))
627 else if (endV.IsSame(SV.Last()))
630 MESSAGE ("END VERTEX IS IN SEQUNCE MIDDLE");
635 for (iVer=1; iVer < NbVer; iVer++) {
636 V1 = TopoDS::Vertex(SV(iVer));
637 V2 = TopoDS::Vertex(SV(iVer+1));
639 TopoDS_Shape NewEdge = WE.EmptyCopied();
640 V1.Orientation(TopAbs_FORWARD);
641 myBuilder.Add (NewEdge,V1);
642 V2.Orientation(TopAbs_REVERSED);
643 myBuilder.Add (NewEdge,V2);
648 V1.Orientation(TopAbs_INTERNAL);
649 U1=BRep_Tool::Parameter(V1,WE);
654 V2.Orientation(TopAbs_INTERNAL);
655 U2=BRep_Tool::Parameter(V2,WE);
657 if (Abs(U1-U2) <= Precision::PConfusion()) {
658 MESSAGE( "MakeEdges(), EQUAL PARAMETERS OF DIFFERENT VERTICES");
661 TopoDS_Edge EE=TopoDS::Edge(NewEdge);
662 myBuilder.Range (EE,U1,U2);
664 TopoDS_Edge NEdge = TopoDS::Edge(NewEdge);
665 myBuilder.SameParameter(NEdge,Standard_False);
667 Standard_Real tol = 1.0e-2;
668 Standard_Boolean flag = BRep_Tool::SameParameter(NEdge);
670 BRepLib::SameParameter(NEdge,tol);
672 NE.Append(NEdge.Oriented(E.Orientation()));
676 //=======================================================================
677 //function : FindFacesInside
678 //purpose : return compound of faces of other shapes that are
680 // <S> is an object shape.
681 // <CheckClosed> makes avoid faces that do not form a
683 // <All> makes return already added faces
684 //=======================================================================
686 TopoDS_Shape Partition_Spliter::FindFacesInside(const TopoDS_Shape& S,
687 const Standard_Boolean CheckClosed,
688 const Standard_Boolean All)
690 if (myInternalFaces.IsBound( S ))
691 return myInternalFaces.Find ( S );
694 myBuilder.MakeCompound(C);
696 const TopoDS_Shape& SS = myImageShape.Image(S).First(); // compound of split faces of S
698 TopTools_MapOfShape MSE, MPF;
699 TopTools_DataMapOfShapeListOfShape MEF;
700 TopTools_MapIteratorOfMapOfShape itm;
701 TopExp_Explorer expl;
702 TopTools_ListOfShape Empty;
704 // MSE filling: map of section edges of SS
705 for (expl.Init(SS,TopAbs_EDGE); expl.More(); expl.Next()) {
706 TopoDS_Shape resE = expl.Current() ;
707 if (myNewSection.Contains( resE ))
711 // 1. MPF filling: map of resulting faces except those of S,
712 // we`ll add to C those of them which are inside SS
713 // 2. MEF filling: edge of MSE => faces of MPF
714 TopTools_ListIteratorOfListOfShape itl;
715 for (itl.Initialize(myListShapes);itl.More();itl.Next()) {
716 const TopoDS_Shape& SL = itl.Value();
717 if ( S.IsSame( SL )) continue;
719 TopoDS_Iterator itF ( myImageShape.Image(SL).First() );
720 for ( ; itF.More(); itF.Next()) {
721 const TopoDS_Shape& snf = itF.Value();
723 for (expl.Init( snf, TopAbs_EDGE ); expl.More(); expl.Next()) {
724 TopoDS_Shape se = expl.Current();
725 if ( MSE.Contains(se)) {// section edge
726 if (!MEF.IsBound(se))
734 // MSEF: map edge of SS - faces of SS
735 TopTools_IndexedDataMapOfShapeListOfShape MSEF;
736 TopExp::MapShapesAndAncestors(SS, TopAbs_EDGE, TopAbs_FACE, MSEF);
738 // find faces inside S
740 Standard_Boolean skipAlreadyAdded = Standard_False;
741 Standard_Boolean GoodOri, inside;
743 TopTools_ListOfShape KeepFaces;
744 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape Mapit;
746 for (Mapit.Initialize(MEF); Mapit.More() ; Mapit.Next() ) {
747 TopoDS_Edge E = TopoDS::Edge (Mapit.Key());
748 TopoDS_Edge OrigE = TopoDS::Edge ( myImagesEdges.Root( E ));
749 Standard_Boolean isSectionE = myInter3d.IsSectionEdge ( OrigE );
751 TopTools_ListOfShape& EF = MEF.ChangeFind(E);
752 itl.Initialize( EF );
754 TopoDS_Face face1 = TopoDS::Face(itl.Value());
755 EF.Remove( itl ); // == itl.Next();
756 if (!MPF.Remove( face1 ))
757 continue; // was not is MPF ( i.e already checked)
759 myAddedFacesMap.Contains( face1 ) &&
760 myAddedFacesMap.Contains( face1.Reversed() )) {
761 skipAlreadyAdded = Standard_True;
762 continue; // already added to 2 shells
765 // find another face which originates from the same face as <face1>
766 const TopoDS_Shape& origS = myImagesFaces.Root(face1);
771 if (!MPF.Contains( face2 )) {
775 if (origS.IsSame( myImagesFaces.Root( face2 )))
779 if (itl.More()) { // face2 found
785 itl.Initialize( EF );
788 // check that origS is not same domain with SS
789 Standard_Boolean sameDom1 = 0, sameDom2 = 0;
790 const TopTools_ListOfShape& FL = MSEF.FindFromKey(E); //faces of SS sharing E
791 const TopoDS_Shape& origF1 = myImagesFaces.Root(FL.First());
792 const TopoDS_Shape& origF2 = myImagesFaces.Root(FL.Last());
793 if (origS.IsSame( origF1 ))
794 sameDom1 = Standard_True;
795 if ( origS.IsSame( origF2 ))
796 sameDom2 = Standard_True;
797 if (!(sameDom1 || sameDom2) && myInter3d.HasSameDomainF( origS )) {
798 sameDom1 = myInter3d.IsSameDomainF( origS, origF1);
799 sameDom2 = (origF1 == origF2) ? sameDom1 : myInter3d.IsSameDomainF( origS, origF2);
801 if (sameDom1 && sameDom2)
803 if ((sameDom1 || sameDom2)) {
804 inside = Partition_Loop3d::IsInside (E,
805 TopoDS::Face(FL.First()),
806 TopoDS::Face(FL.Last()),
808 if (inside || (dot + Precision::Angular() >= 1.0))
809 continue; // E is convex between origF1 and origF2 or they are tangent
813 // keep one of found faces
814 const TopoDS_Shape& SFace = sameDom1 ? FL.Last() : FL.First(); //face of SS sharing E
815 inside = Partition_Loop3d::IsInside (E, TopoDS::Face(SFace), face1,
817 if ((dot + Precision::Angular() >= 1.0) &&
818 !face2.IsNull()) { // face2 position is not clear, it will be analysed alone
824 KeepFaces.Append(face1);
827 KeepFaces.Append(face2);
831 TopTools_ListOfShape KeptFaces;
833 KeptFaces.Append (KeepFaces);
835 while (!KeepFaces.IsEmpty()) {
836 // add to KeepFaces not distributed faces connected with KeepFaces
838 // KeepEdges : map of edges of kept faces
839 TopTools_IndexedMapOfShape KeepEdges;
840 for (itl.Initialize(KeepFaces);itl.More();itl.Next() )
841 TopExp::MapShapes( itl.Value(), TopAbs_EDGE, KeepEdges);
843 KeptFaces.Append (KeepFaces); // == KeepFaces.Clear()
845 // keep faces connected with already kept faces
846 for (itm.Initialize(MPF);itm.More();itm.Next() ) {
847 const TopoDS_Shape& PF = itm.Key();
848 for (expl.Init(PF,TopAbs_EDGE); expl.More(); expl.Next()) {
849 const TopoDS_Shape& se = expl.Current();
850 if (!MSE.Contains(se) && KeepEdges.Contains(se) ) {
851 KeepFaces.Append(PF);
859 // check if kept faces make shell without free edges
860 MSEF.Clear(); // edge - kept faces
861 MPF.Clear(); // wrong faces
863 for (itl.Initialize(KeptFaces); itl.More(); itl.Next() )
864 TopExp::MapShapesAndAncestors(itl.Value(), TopAbs_EDGE, TopAbs_FACE, MSEF);
866 Standard_Integer i, nb = MSEF.Extent();
867 Standard_Boolean isClosed = Standard_False;
869 isClosed = Standard_True;
870 for (i=1; isClosed && i<=nb; ++i) {
871 const TopoDS_Shape& E = MSEF.FindKey( i );
872 if (! MSE.Contains( E ))
873 isClosed = ( MSEF(i).Extent() != 1 );
876 const TopoDS_Shape& F = MSEF.FindFromIndex( i-1 ).First(); // bad face
878 // remove bad face from MSEF
879 for (expl.Init( F, TopAbs_EDGE); expl.More(); expl.Next()) {
880 const TopoDS_Shape& E = expl.Current();
881 TopTools_ListOfShape& FL = MSEF.ChangeFromKey( E );
882 for (itl.Initialize( FL ); itl.More(); itl.Next() ) {
883 if ( F.IsSame( itl.Value() )) {
893 // add to the compound kept faces except bad ones in MPF
894 if (KeptFaces.Extent() > MPF.Extent()) {
895 for (itl.Initialize(KeptFaces); itl.More(); itl.Next() )
896 if (! MPF.Contains( itl.Value() )) {
897 myBuilder.Add( C, itl.Value());
898 //myBuilder.Add( C, itl.Value().Reversed());
902 if (!skipAlreadyAdded)
903 myInternalFaces.Bind( S, C );
908 //=======================================================================
909 //function : MakeShell
910 //purpose : split S into compound of shells
911 //=======================================================================
913 void Partition_Spliter::MakeShells(const TopoDS_Shape& S,
914 TopTools_ListOfShape& NS)
916 // check if S is closed shape
917 Standard_Boolean isClosed = Standard_True;
919 TopTools_IndexedDataMapOfShapeListOfShape MEF;
921 if (S.ShapeType() != TopAbs_SOLID) {
922 TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF);
923 for (i=1; isClosed && i<=MEF.Extent(); ++i)
924 isClosed = ( MEF(i).Extent() != 1 );
926 Partition_Loop3d ShellMaker;
927 // get compound of split faces of S
928 const TopoDS_Shape& FacesComp = myImageShape.Image(S).First();
929 ShellMaker.AddConstFaces( FacesComp );
930 // split faces inside S
932 TopoDS_Shape InternalFacesComp = FindFacesInside(S, Standard_True);
933 ShellMaker.AddSectionFaces( InternalFacesComp );
934 // } else { // a shell may become closed
935 // ShellMaker.AddConstFaces( InternalFacesComp );
938 NS = ShellMaker.MakeShells( myAddedFacesMap );
940 // 1. Add faces added to new shell to myAddedFacesMap:
941 // avoid rebuilding twice commont part of 2 solids.
942 // 2. Check shell closeness (DEBUG)
943 TopTools_ListIteratorOfListOfShape itS(NS);
944 while ( itS.More()) {
946 Standard_Boolean checkCloseness = Standard_True;
948 TopExp_Explorer expF (itS.Value(), TopAbs_FACE);
949 for (; expF.More(); expF.Next()) {
951 myAddedFacesMap.Add (expF.Current());
954 if (checkCloseness &&
955 ! myInter3d.HasSameDomainF( myImagesFaces.Root(expF.Current()) ))
956 checkCloseness = Standard_False;
961 if (checkCloseness) {
962 // if S is closed, a new shell must be closed too;
964 // check that a new shell is closed
966 TopExp::MapShapesAndAncestors(itS.Value(), TopAbs_EDGE, TopAbs_FACE, MEF);
967 for (i=1; isClosed && i<=MEF.Extent(); ++i)
968 isClosed = ( MEF(i).Extent() != 1 );
969 if (!isClosed) { // remove not closed shell
970 MESSAGE (" NOT CLOSED SHELL " );
979 } // loop on new shells
982 //=======================================================================
983 //function : findEqual
984 //purpose : compare edges form EL1 against edges from EL2,
985 // Result is in EMM binding edge form EL1 to list of equal edges
986 // Edges are considered equall only if they have same vertices
987 // <addSame>==True makes consider same edges as equal
988 // Put in <AllEqMap> all equal edges
989 //=======================================================================
991 static void findEqual (const TopTools_ListOfShape& EL1,
992 const TopTools_ListOfShape& EL2,
993 const Standard_Boolean addSame,
994 TopTools_DataMapOfShapeListOfShape& EEM,
995 TopTools_MapOfShape& AllEqMap)
997 // map vertices to edges for EL2
998 TopTools_DataMapOfShapeListOfShape VEM;
999 TopTools_ListIteratorOfListOfShape itE1, itE2(EL2);
1000 TopoDS_Iterator itV;
1001 TopTools_ListOfShape emptyL;
1002 for (; itE2.More(); itE2.Next()) {
1003 for (itV.Initialize( itE2.Value() ); itV.More(); itV.Next()) {
1004 const TopoDS_Shape& V = itV.Value();
1005 if (! VEM.IsBound( V ) )
1006 VEM.Bind( V, emptyL);
1007 VEM( V ).Append( itE2.Value());
1013 Standard_Real f,l,u,tol;
1014 Handle(Geom_Curve) C1, C2;
1015 Extrema_ExtPC Extrema;
1016 TopoDS_Vertex V1, V2, V3, V4;
1020 for (itE1.Initialize(EL1); itE1.More(); itE1.Next()) {
1021 const TopoDS_Edge& E1 = TopoDS::Edge( itE1.Value());
1022 if (BRep_Tool::Degenerated( E1 ) || AllEqMap.Contains (E1))
1024 TopExp::Vertices( E1, V1, V2 );
1026 if (VEM.IsBound(V1))
1027 itE2.Initialize( VEM(V1) );
1028 for (; itE2.More(); itE2.Next()) {
1029 const TopoDS_Edge& E2 = TopoDS::Edge( itE2.Value());
1030 if (BRep_Tool::Degenerated( E2 ))
1033 if (E1.IsSame(E2)) {
1038 TopExp::Vertices( E2, V3, V4);
1039 if (!V2.IsSame(V4) && !V2.IsSame(V3))
1041 // E1 and E2 have same vertices
1042 // check D1 at end points.
1043 C2 = BRep_Tool::Curve( E2, f,l);
1044 C1 = BRep_Tool::Curve( E1, f,l);
1045 u = BRep_Tool::Parameter(V1,E1);
1047 u = BRep_Tool::Parameter(V1.IsSame(V3) ? V3 : V4, E2);
1049 D1.Normalize(); D2.Normalize();
1050 if (Abs(D1*D2) + Precision::Angular() < 1.0)
1052 if (! V1.IsSame(V2)) {
1053 u = BRep_Tool::Parameter(V2,E1);
1055 u = BRep_Tool::Parameter(V2.IsSame(V3) ? V3 : V4, E2);
1057 D1.Normalize(); D2.Normalize();
1058 if (Abs(D1*D2) + Precision::Angular() < 1.0)
1061 // check distance at a couple of internal points
1062 tol = Max(BRep_Tool::Tolerance(E1),
1063 BRep_Tool::Tolerance(E2));
1064 GeomAdaptor_Curve AC1(C1);
1065 Extrema.Initialize(AC1,f,l);
1066 Standard_Boolean ok = Standard_True, hasMin = Standard_False;
1067 BRep_Tool::Range( E2, f, l);
1068 Standard_Integer i=1, nbi=3;
1069 for (; i<nbi && ok; ++i) {
1070 Extrema.Perform( C2->Value( f+(l-f)*i/nbi ));
1071 Standard_Integer j=1, nbj=Extrema.NbExt();
1072 for (; j<=nbj && ok; ++j) {
1073 if (Extrema.IsMin(j)) {
1074 hasMin = Standard_True;
1075 ok = Extrema.Value(j) <= tol;
1079 if ( !hasMin || !ok)
1082 // bind E2 to E1 in EEM
1083 if (!EEM.IsBound(E1)) {
1084 EEM.Bind (E1, emptyL);
1093 //=======================================================================
1094 //function : MakeFaces
1095 //purpose : split faces of S, return compound of new faces
1096 //=======================================================================
1098 TopoDS_Shape Partition_Spliter::MakeFaces (const TopoDS_Shape& S)
1101 myBuilder.MakeCompound(C);
1103 TopTools_ListIteratorOfListOfShape itl, itNE;
1105 TopExp_Explorer exp(S,TopAbs_FACE);
1106 for (; exp.More(); exp.Next()) {
1108 const TopoDS_Face& F = TopoDS::Face(exp.Current());
1110 TopTools_ListOfShape LNF;
1112 if (myImagesFaces.HasImage( F )) {
1113 myImagesFaces.LastImage( F, LNF );
1114 TopAbs_Orientation oriF = F.Orientation();
1115 for ( itl.Initialize( LNF ); itl.More(); itl.Next())
1116 itl.Value().Orientation( oriF );
1120 Partition_Loop2d loops;
1123 TopTools_IndexedMapOfShape EM;
1124 TopExp::MapShapes( F, TopAbs_EDGE, EM);
1126 TopTools_MapOfShape AddedEqualM;
1127 Standard_Boolean needRebuild = Standard_False;
1129 // add splits to loops
1131 // LE: old edges + new not splitted edges
1132 const TopTools_ListOfShape& LE = myAsDes->Descendant(F);
1133 for (itl.Initialize(LE); itl.More(); itl.Next()) {
1134 const TopoDS_Edge& E = TopoDS::Edge( itl.Value() );
1136 Standard_Boolean isSectionE = myInter3d.IsSectionEdge(E);
1137 Standard_Boolean isNewE = !EM.Contains( E );
1139 // LSE: list of split edges
1140 TopTools_ListOfShape LSE;
1141 myImagesEdges.LastImage(E,LSE); // splits of E or E itself
1143 for (itNE.Initialize(LSE); itNE.More(); itNE.Next()) {
1145 TopoDS_Edge NE = TopoDS::Edge( itNE.Value() );
1146 Standard_Boolean isSameE = NE.IsSame ( E );
1148 if ( isNewE || isSectionE || !isSameE) {
1149 if (AddedEqualM.Contains( NE ))
1154 if ( ! myInter3d.IsSplitOn( NE, E, F) )
1158 TopoDS_Vertex V1,V2;
1159 TopExp::Vertices(NE,V1,V2);
1160 const TopTools_ListOfShape& EL1 = myAsDes->Ascendant(V1);
1161 const TopTools_ListOfShape& EL2 = myAsDes->Ascendant(V2);
1162 if ( EL1.Extent() < 2 && EL2.Extent() < 2 )
1167 NE.Orientation( E.Orientation());
1169 // orient NE because it may be a split of other edge
1170 Standard_Real f,l,u;
1171 Handle(Geom_Curve) C3d = BRep_Tool::Curve( E,f,l );
1172 Handle(Geom_Curve) NC3d = BRep_Tool::Curve( NE,f,l);
1174 gp_Vec D1, ND1; gp_Pnt P;
1175 TopoDS_Vertex V = TopExp::FirstVertex(NE);
1176 u = BRep_Tool::Parameter(V,NE);
1177 NC3d->D1 (u, P, ND1);
1178 u = BRep_Tool::Parameter(V,E);
1179 C3d ->D1 (u, P, D1);
1180 if (ND1.Dot(D1) < 0)
1185 if (myEqualEdges.Contains( NE ) && !AddedEqualM.Add( NE ))
1188 needRebuild = Standard_True;
1191 if (isNewE || isSectionE)
1192 myNewSection.Add( NE );
1195 loops.AddSectionEdge(NE);
1197 loops.AddConstEdge(NE);
1201 //-------------------
1203 //-------------------
1208 loops.WiresToFaces(myImagesEdges);
1210 LNF = loops.NewFaces();
1212 myImagesFaces.Bind(F,LNF);
1214 // replace the result faces that have already been built
1215 // during same domain faces reconstruction
1216 if (myInter3d.HasSameDomainF( F )) {
1217 // build map edge to same domain faces
1218 TopTools_IndexedDataMapOfShapeListOfShape EFM;
1219 TopTools_MapOfShape SDFM; // avoid doubling
1220 itl.Initialize( myInter3d.SameDomain( F ));
1221 for (; itl.More(); itl.Next()) {
1222 if ( !myImagesFaces.HasImage( itl.Value() ))
1224 TopTools_ListIteratorOfListOfShape itNF;
1225 itNF.Initialize (myImagesFaces.Image( itl.Value() ));
1226 for ( ; itNF.More(); itNF.Next()) {
1227 TopoDS_Shape SDF = itNF.Value();
1228 if (myImagesFaces.HasImage( SDF )) // already replaced
1229 SDF = myImagesFaces.Image( SDF ).First();
1231 TopExp::MapShapesAndAncestors(SDF, TopAbs_EDGE, TopAbs_FACE, EFM);
1235 TopTools_ListOfShape LOF;
1236 if ( !EFM.IsEmpty() )
1237 itl.Initialize( LNF );
1238 while (itl.More()) {
1239 const TopoDS_Shape& NF = itl.Value();
1240 TopExp_Explorer expE ( NF, TopAbs_EDGE );
1241 const TopoDS_Edge& E = TopoDS::Edge (expE.Current());
1242 if (EFM.Contains( E )) {
1243 const TopTools_ListOfShape& SDFL = EFM.FindFromKey( E );
1244 TopoDS_Shape SDF = SDFL.First();
1245 Standard_Boolean GoodOri;
1247 Partition_Loop3d::IsInside (E, TopoDS::Face(NF), TopoDS::Face(SDF),
1250 if (SDFL.Extent() == 1) {
1257 gp_Vec V1 = Partition_Loop3d::Normal( E, TopoDS::Face( NF ));
1258 gp_Vec V2 = Partition_Loop3d::Normal( E, TopoDS::Face( SDF ));
1262 if (!myImagesFaces.HasImage( NF ))
1263 myImagesFaces.Bind( NF, SDF );
1265 LOF.Prepend ( SDF );
1274 } // if (needRebuild)
1278 myImagesFaces.Bind(F,LNF);
1280 } // if (myImagesFaces.HasImage( F ))
1282 for (itl.Initialize(LNF); itl.More(); itl.Next())
1283 myBuilder.Add ( C, itl.Value());
1284 } // loop on faces of S
1289 //=======================================================================
1290 //function : MergeEqualEdges
1291 //purpose : find equal edges, choose ones to keep and make
1292 // them have pcurves on all faces they are shared by
1293 //=======================================================================
1295 void Partition_Spliter::MergeEqualEdges (const TopTools_ListOfShape& LSE)
1298 // map: edge - equal edges
1299 TopTools_DataMapOfShapeListOfShape EEM( LSE.Extent() );
1300 findEqual (LSE, LSE, 0, EEM, myEqualEdges);
1302 TopTools_ListOfShape EEL; // list of equal edges
1303 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itM (EEM);
1304 for ( ; itM.More(); itM.Next()) {
1306 EEL.Append( itM.Key() );
1307 // choose an edge to keep, section edges have priority
1309 TopTools_ListIteratorOfListOfShape itEE (EEL);
1310 for (; itEE.More(); itEE.Next()) {
1311 EKeep = TopoDS::Edge( itEE.Value() );
1312 const TopoDS_Edge& EKeepOrig = TopoDS::Edge( myImagesEdges.Root( EKeep ));
1313 if (myInter3d.IsSectionEdge( EKeepOrig ))
1317 Standard_Real f,l, tol;
1318 for (itEE.Initialize (EEL); itEE.More(); itEE.Next()) {
1319 const TopoDS_Edge& E = TopoDS::Edge( itEE.Value() );
1320 if ( E.IsSame( EKeep ))
1322 const TopoDS_Edge& EReplOrig = TopoDS::Edge( myImagesEdges.Root( E ));
1323 TopTools_ListOfShape FL;
1324 if (myInter3d.IsSectionEdge( EReplOrig ))
1325 FL = myInter3d.SectionEdgeFaces ( EReplOrig );
1327 FL = myAsDes->Ascendant( EReplOrig );
1329 TopTools_ListIteratorOfListOfShape itF (FL);
1330 for ( ; itF.More(); itF.Next()) {
1331 const TopoDS_Face& F = TopoDS::Face( itF.Value());
1333 Handle(Geom2d_Curve) pc = BRep_Tool::CurveOnSurface( EKeep, F, f,l);
1335 Handle(Geom_Curve) C3d = BRep_Tool::Curve( EKeep, f, l);
1336 C3d = new Geom_TrimmedCurve( C3d, f,l);
1337 pc = TopOpeBRepTool_CurveTool::MakePCurveOnFace (F,C3d,tol);
1339 MESSAGE (" CANT BUILD PCURVE ");
1341 myBuilder.UpdateEdge( EKeep, pc, F, tol);
1344 // replace edges in faces
1345 if (!myImagesEdges.HasImage( E ))
1346 myImagesEdges.Bind( E, EKeep );
1351 //=======================================================================
1352 //function : KeepShapesInside
1353 //purpose : remove shapes that are outside of S from resul
1354 //=======================================================================
1356 void Partition_Spliter::KeepShapesInside (const TopoDS_Shape& S)
1359 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
1360 for (it.Initialize( S ); it.More(); it.Next())
1361 KeepShapesInside( it.Value());
1364 if (!myImageShape.HasImage( S ) && ! CheckTool( S ))
1367 TopoDS_Shape InsFacesComp = FindFacesInside( S, Standard_False, Standard_True);
1368 TopTools_IndexedMapOfShape MIF; // map of internal faces;
1369 TopExp::MapShapes( InsFacesComp, TopAbs_FACE, MIF );
1371 if (MIF.IsEmpty()) return;
1373 // leave in the result only those shapes having a face in MIF
1375 myBuilder.MakeCompound(C);
1377 for (it.Initialize( myShape ); it.More(); it.Next()) {
1379 TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
1380 for (; expResF.More(); expResF.Next()) {
1381 if ( MIF.Contains( expResF.Current())) {
1382 myBuilder.Add( C, it.Value() );
1391 //=======================================================================
1392 //function : RemoveShapesInside
1393 //purpose : remove shapes that are inside S from resul
1394 //=======================================================================
1396 void Partition_Spliter::RemoveShapesInside (const TopoDS_Shape& S)
1399 if (S.ShapeType() < TopAbs_SOLID) { // compound or compsolid
1400 for (it.Initialize( S ); it.More(); it.Next())
1401 RemoveShapesInside( it.Value());
1404 Standard_Boolean isTool = Standard_False;
1405 if (!myImageShape.HasImage( S )) {
1406 isTool = CheckTool( S );
1407 if (!isTool) return;
1410 TopoDS_Shape InsFacesComp = FindFacesInside( S, Standard_False, Standard_True);
1411 TopTools_IndexedMapOfShape MIF; // map of internal faces
1412 TopExp::MapShapes( InsFacesComp, TopAbs_FACE, MIF);
1414 if (MIF.IsEmpty()) return;
1416 // add to MIF split faces of S
1417 if (myImageShape.HasImage( S ))
1418 TopExp::MapShapes( myImageShape.Image(S).First(), TopAbs_FACE, MIF);
1420 // leave in the result only those shapes not having all face in MIF
1423 myBuilder.MakeCompound(C);
1425 // RMF : faces of removed shapes that encounter once
1426 TopTools_MapOfShape RFM;
1428 for (it.Initialize( myShape ); it.More(); it.Next()) {
1430 TopExp_Explorer expResF( it.Value(), TopAbs_FACE );
1431 for (; expResF.More(); expResF.Next())
1432 if (!MIF.Contains( expResF.Current()))
1436 // add shape to result
1437 myBuilder.Add( C, it.Value() );
1439 // add faces of a removed shape to RFM
1440 for (expResF.ReInit(); expResF.More(); expResF.Next()) {
1441 const TopoDS_Shape& F = expResF.Current();
1442 if ( ! RFM.Remove ( F ))
1448 // rebuild S, it must remain in the result
1449 Standard_Boolean isClosed = Standard_False;
1450 switch (S.ShapeType()) {
1452 isClosed = Standard_True; break;
1453 case TopAbs_SHELL: {
1454 TopTools_IndexedDataMapOfShapeListOfShape MEF;
1456 TopExp::MapShapesAndAncestors(S, TopAbs_EDGE, TopAbs_FACE, MEF);
1457 for (i=1; isClosed && i<=MEF.Extent(); ++i)
1458 isClosed = ( MEF(i).Extent() != 1 );
1462 isClosed = Standard_False;
1465 // add to a new shape external faces of removed shapes, ie those in RFM
1467 myBuilder.MakeShell( Shell );
1469 TopTools_MapIteratorOfMapOfShape itF (RFM);
1470 for ( ; itF.More(); itF.Next())
1471 myBuilder.Add( Shell, itF.Key());
1473 if (S.ShapeType() == TopAbs_SOLID) {
1475 myBuilder.MakeSolid( Solid );
1476 myBuilder.Add (Solid, Shell);
1477 myBuilder.Add (C, Solid);
1480 myBuilder.Add (C, Shell);
1483 if (myImageShape.HasImage( S )) {
1484 for (it.Initialize( myImageShape.Image(S).First()); it.More(); it.Next())
1485 myBuilder.Add (C, it.Value());
1493 //=======================================================================
1494 //function : CheckTool
1495 //purpose : Return True if <S> is a tool shape. Prepare tool
1496 // faces of <S> for the search of internal faces.
1497 //=======================================================================
1499 Standard_Boolean Partition_Spliter::CheckTool(const TopoDS_Shape& S)
1501 // suppose S has not an image
1503 Standard_Boolean isTool = Standard_False;
1505 myBuilder.MakeCompound( C );
1507 TopExp_Explorer expF( S, TopAbs_FACE);
1508 for (; expF.More(); expF.Next()) {
1510 const TopoDS_Face& F = TopoDS::Face( expF.Current() );
1511 if (myMapTools.Contains( F ))
1512 isTool = Standard_True;
1516 if (myImagesFaces.HasImage( F )) {
1517 // F has been reconstructed
1518 TopAbs_Orientation Fori = F.Orientation();
1519 TopTools_ListOfShape LNF;
1520 myImagesFaces.LastImage( F, LNF);
1521 TopTools_ListIteratorOfListOfShape itF (LNF);
1522 for ( ; itF.More(); itF.Next())
1523 myBuilder.Add( C, itF.Value().Oriented(Fori) );
1527 Standard_Boolean hasSectionE = myInter3d.HasSectionEdge( F );
1528 Standard_Boolean hasNewE = myAsDes->HasDescendant( F );
1529 if (!hasSectionE && !hasNewE)
1530 continue; // F intersects nothing
1532 // make an image for F
1535 NF.Orientation(TopAbs_FORWARD);
1536 NF = TopoDS::Face( NF.EmptyCopied() ); // make a copy
1538 myBuilder.MakeWire( NW );
1540 // add edges, as less as possible
1541 TopTools_ListOfShape NEL;
1542 TopTools_ListIteratorOfListOfShape itNE;
1544 // add section edges
1545 TopExp_Explorer expE;
1546 for ( ; expE.More(); expE.Next()) {
1547 if (! myImagesEdges.HasImage( expE.Current() ))
1549 myImagesEdges.LastImage( expE.Current(), NEL );
1550 for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next())
1551 myBuilder.Add ( NW, itNE.Value());
1556 NEL = myAsDes->Descendant( F );
1557 for ( itNE.Initialize( NEL ); itNE.More(); itNE.Next()) {
1558 TopTools_ListOfShape SEL; // splits
1559 myImagesEdges.LastImage( itNE.Value(), SEL );
1560 TopTools_ListIteratorOfListOfShape itSE (SEL);
1561 for ( ; itSE.More(); itSE.Next())
1562 myBuilder.Add ( NW, itSE.Value());
1565 myBuilder.Add( NF, NW );
1566 myBuilder.Add (C, NF);
1568 NF.Orientation( F.Orientation() ); // NF is most probably invalid
1569 myImagesFaces.Bind (F, NF);
1572 myImageShape.Bind (S, C);