1 // Created on: 1993-06-14
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1993-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
18 #include <BRep_Builder.hxx>
19 #include <BRep_Tool.hxx>
20 #include <BRepClass3d_SolidClassifier.hxx>
21 #include <Geom2d_Curve.hxx>
22 #include <Geom_Curve.hxx>
24 #include <Precision.hxx>
25 #include <Standard_NoSuchObject.hxx>
26 #include <Standard_ProgramError.hxx>
27 #include <TCollection_AsciiString.hxx>
30 #include <TopoDS_Compound.hxx>
31 #include <TopoDS_Edge.hxx>
32 #include <TopoDS_Face.hxx>
33 #include <TopoDS_Shape.hxx>
34 #include <TopoDS_Shell.hxx>
35 #include <TopoDS_Vertex.hxx>
36 #include <TopoDS_Wire.hxx>
37 #include <TopOpeBRepBuild_Builder.hxx>
38 #include <TopOpeBRepBuild_define.hxx>
39 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
40 #include <TopOpeBRepBuild_FaceBuilder.hxx>
41 #include <TopOpeBRepBuild_GTool.hxx>
42 #include <TopOpeBRepBuild_GTopo.hxx>
43 #include <TopOpeBRepBuild_HBuilder.hxx>
44 #include <TopOpeBRepBuild_PaveSet.hxx>
45 #include <TopOpeBRepBuild_ShapeSet.hxx>
46 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
47 #include <TopOpeBRepBuild_SolidBuilder.hxx>
48 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
49 #include <TopOpeBRepDS_BuildTool.hxx>
50 #include <TopOpeBRepDS_Config.hxx>
51 #include <TopOpeBRepDS_Curve.hxx>
52 #include <TopOpeBRepDS_CurveExplorer.hxx>
53 #include <TopOpeBRepDS_CurveIterator.hxx>
54 #include <TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State.hxx>
55 #include <TopOpeBRepDS_Filter.hxx>
56 #include <TopOpeBRepDS_HDataStructure.hxx>
57 #include <TopOpeBRepDS_ListOfShapeOn1State.hxx>
58 #include <TopOpeBRepDS_Point.hxx>
59 #include <TopOpeBRepDS_PointIterator.hxx>
60 #include <TopOpeBRepDS_Reducer.hxx>
61 #include <TopOpeBRepDS_Surface.hxx>
62 #include <TopOpeBRepDS_SurfaceIterator.hxx>
63 #include <TopOpeBRepTool_ShapeExplorer.hxx>
66 extern Standard_Boolean TopOpeBRepBuild_GettraceCU();
67 extern Standard_Boolean TopOpeBRepBuild_GettraceCUV();
68 extern Standard_Boolean TopOpeBRepBuild_GettraceSPF();
69 extern Standard_Boolean TopOpeBRepBuild_GettraceSPS();
70 extern Standard_Boolean TopOpeBRepBuild_GetcontextSF2();
71 Standard_EXPORT void debmarksplit(const Standard_Integer i) {cout<<"++ debmarksplit "<<i<<endl;}
72 Standard_EXPORT void debchangesplit(const Standard_Integer i) {cout<<"++ debchangesplit "<<i<<endl;}
73 Standard_EXPORT void debspf(const Standard_Integer i) {cout<<"++ debspf"<<i<<endl;}
76 static Standard_Integer STATIC_SOLIDINDEX = 0;
78 //=======================================================================
79 //function : TopOpeBRepBuild_Builder
81 //=======================================================================
82 TopOpeBRepBuild_Builder::TopOpeBRepBuild_Builder(const TopOpeBRepDS_BuildTool& BT)
84 mySectionDone(Standard_False),
86 myClassifyDef(Standard_False),
87 myClassifyVal(Standard_True),
88 myProcessON(Standard_False)
93 //modified by NIZHNY-MZV Sat May 6 10:04:49 2000
94 //=======================================================================
95 //function : ~TopOpeBRepBuild_Builder
96 //purpose : virtual destructor
97 //=======================================================================
98 TopOpeBRepBuild_Builder::~TopOpeBRepBuild_Builder()
102 //=======================================================================
103 //function : ChangeBuildTool
105 //=======================================================================
106 TopOpeBRepDS_BuildTool& TopOpeBRepBuild_Builder::ChangeBuildTool()
111 //=======================================================================
112 //function : BuildTool
114 //=======================================================================
115 const TopOpeBRepDS_BuildTool& TopOpeBRepBuild_Builder::BuildTool() const
120 //=======================================================================
121 //function : DataStructure
123 //=======================================================================
124 Handle(TopOpeBRepDS_HDataStructure) TopOpeBRepBuild_Builder::DataStructure() const
126 return myDataStructure;
129 //=======================================================================
132 //=======================================================================
133 void TopOpeBRepBuild_Builder::Perform(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
139 myDataStructure = HDS;
141 SplitEvisoONperiodicF();
147 TopOpeBRepDS_Filter F(HDS, &myShapeClassifier);
148 F.ProcessFaceInterferences(mySplitON);
149 TopOpeBRepDS_Reducer R(HDS);
150 R.ProcessFaceInterferences(mySplitON);
153 //=======================================================================
156 //=======================================================================
157 void TopOpeBRepBuild_Builder::Perform(const Handle(TopOpeBRepDS_HDataStructure)& HDS,const TopoDS_Shape& S1, const TopoDS_Shape& S2)
160 myShape1 = S1; myShape2 = S2;
161 myIsKPart = FindIsKPart();
164 //=======================================================================
165 //function : AddIntersectionEdges
167 //=======================================================================
168 void TopOpeBRepBuild_Builder::AddIntersectionEdges
169 (TopoDS_Shape& aFace,const TopAbs_State ToBuild1,const Standard_Boolean RevOri1,TopOpeBRepBuild_ShapeSet& WES) const
172 TopOpeBRepDS_CurveIterator FCurves = myDataStructure->FaceCurves(aFace);
173 for (; FCurves.More(); FCurves.Next()) {
174 Standard_Integer iC = FCurves.Current();
175 const TopTools_ListOfShape& LnewE = NewEdges(iC);
176 for (TopTools_ListIteratorOfListOfShape Iti(LnewE); Iti.More(); Iti.Next()) {
177 anEdge = Iti.Value();
178 TopAbs_Orientation ori = FCurves.Orientation(ToBuild1);
179 TopAbs_Orientation newori = Orient(ori,RevOri1);
181 if(newori == TopAbs_EXTERNAL) continue;
183 myBuildTool.Orientation(anEdge,newori);
184 const Handle(Geom2d_Curve)& PC = FCurves.PCurve();
185 myBuildTool.PCurve(aFace,anEdge,PC);
186 WES.AddStartElement(anEdge);
191 //=======================================================================
194 //=======================================================================
195 void TopOpeBRepBuild_Builder::Clear()
197 if (myDataStructure.IsNull())
205 const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
206 for (TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State it (mySplitOUT); it.More(); it.Next())
208 const TopoDS_Shape& e = it.Key();
209 if (e.ShapeType() == TopAbs_EDGE)
211 Standard_Boolean isse = BDS.IsSectionEdge(TopoDS::Edge(e));
212 if (!isse) mySplitOUT.ChangeFind(e).Clear();
215 for (TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State it (mySplitIN); it.More(); it.Next())
217 const TopoDS_Shape& e = it.Key();
218 if (e.ShapeType() == TopAbs_EDGE)
220 Standard_Boolean isse = BDS.IsSectionEdge(TopoDS::Edge(e));
221 if (!isse) mySplitIN.ChangeFind(e).Clear();
224 for (TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State it (mySplitON); it.More(); it.Next())
226 const TopoDS_Shape& e = it.Key();
227 if (e.ShapeType() == TopAbs_EDGE)
229 Standard_Boolean isse = BDS.IsSectionEdge(TopoDS::Edge(e));
230 if (!isse) mySplitON.ChangeFind(e).Clear();
239 //=======================================================================
240 //function : NewFaces
242 //=======================================================================
243 const TopTools_ListOfShape& TopOpeBRepBuild_Builder::NewFaces(const Standard_Integer I) const
245 const TopTools_ListOfShape& L = myNewFaces->Array1().Value(I);
249 //=======================================================================
250 //function : ChangeNewFaces
252 //=======================================================================
253 TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeNewFaces(const Standard_Integer I)
255 TopTools_ListOfShape& L = myNewFaces->ChangeArray1().ChangeValue(I);
259 //=======================================================================
260 //function : NewEdges
262 //=======================================================================
263 const TopTools_ListOfShape& TopOpeBRepBuild_Builder::NewEdges(const Standard_Integer I) const
265 if ( myNewEdges.IsBound(I) ) {
266 return myNewEdges.Find(I);
269 return myEmptyShapeList;
273 //=======================================================================
274 //function : ChangeNewEdges
276 //=======================================================================
277 TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeNewEdges(const Standard_Integer I)
279 if ( ! myNewEdges.IsBound(I) ) {
280 TopTools_ListOfShape thelist;
281 myNewEdges.Bind(I, thelist);
283 TopTools_ListOfShape& L = myNewEdges.ChangeFind(I);
287 //=======================================================================
288 //function : NewVertex
290 //=======================================================================
291 const TopoDS_Shape& TopOpeBRepBuild_Builder::NewVertex(const Standard_Integer I) const
293 const TopoDS_Shape& V = myNewVertices->Array1().Value(I);
297 //=======================================================================
298 //function : ChangeNewVertex
300 //=======================================================================
301 TopoDS_Shape& TopOpeBRepBuild_Builder::ChangeNewVertex(const Standard_Integer I)
303 TopoDS_Shape& V = myNewVertices->ChangeArray1().ChangeValue(I);
307 //=======================================================================
310 //=======================================================================
311 Standard_Boolean TopOpeBRepBuild_Builder::ToSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild) const
313 Standard_Boolean issplit = IsSplit(S,ToBuild);
314 Standard_Boolean hasgeom = myDataStructure->HasGeometry(S);
315 Standard_Boolean hassame = myDataStructure->HasSameDomain(S);
316 Standard_Boolean tosplit = (!issplit) && (hasgeom || hassame);
319 Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
321 cout<<"tosplit "<<tosplit<<" : !issplit "<<(!issplit);
322 cout<<" && (hasgeom || hassame) ("<<hasgeom<<" || "<<hassame<<")"<<endl;
329 //=======================================================================
330 //function : MarkSplit
332 //=======================================================================
333 void TopOpeBRepBuild_Builder::MarkSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild,const Standard_Boolean Bval)
335 TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
336 if ( ToBuild == TopAbs_OUT ) p = &mySplitOUT;
337 else if ( ToBuild == TopAbs_IN ) p = &mySplitIN;
338 else if ( ToBuild == TopAbs_ON ) p = &mySplitON;
339 if ( p == NULL ) return;
341 TopOpeBRepDS_ListOfShapeOn1State thelist;
342 if (!(*p).IsBound(S)) (*p).Bind(S, thelist);
343 TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).ChangeFind(S);
347 Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
349 GdumpSHA(S, (char *) "MarkSplit ");
350 cout<<" ";TopAbs::Print(ToBuild,cout);cout<<" "<<Bval<<endl;
357 //=======================================================================
360 //=======================================================================
361 Standard_Boolean TopOpeBRepBuild_Builder::IsSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild) const
363 Standard_Boolean res = Standard_False;
364 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
365 if ( ToBuild == TopAbs_OUT ) p = &mySplitOUT;
366 else if ( ToBuild == TopAbs_IN ) p = &mySplitIN;
367 else if ( ToBuild == TopAbs_ON ) p = &mySplitON;
368 if ( p == NULL ) return res;
370 if ((*p).IsBound(S)) {
371 const TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).Find(S);
372 res = losos.IsSplit();
374 // Standard_Integer n = losos.ListOnState().Extent();
380 //=======================================================================
383 //=======================================================================
384 const TopTools_ListOfShape& TopOpeBRepBuild_Builder::Splits(const TopoDS_Shape& S, const TopAbs_State ToBuild) const
386 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
387 if ( ToBuild == TopAbs_OUT ) p = &mySplitOUT;
388 else if ( ToBuild == TopAbs_IN ) p = &mySplitIN;
389 else if ( ToBuild == TopAbs_ON ) p = &mySplitON;
390 if ( p == NULL ) return myEmptyShapeList;
392 if ((*p).IsBound(S)) {
393 const TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).Find(S);
394 const TopTools_ListOfShape& L = losos.ListOnState();
397 return myEmptyShapeList;
400 //=======================================================================
401 //function : ChangeSplit
403 //=======================================================================
404 TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild)
407 Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
409 GdumpSHA(S, (char *) "ChangeSplit ");
410 cout<<" ";TopAbs::Print(ToBuild,cout);cout<<endl;
415 TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL;
416 if ( ToBuild == TopAbs_OUT ) p = &mySplitOUT;
417 else if ( ToBuild == TopAbs_IN ) p = &mySplitIN;
418 else if ( ToBuild == TopAbs_ON ) p = &mySplitON;
419 if ( p == NULL ) return myEmptyShapeList;
420 TopOpeBRepDS_ListOfShapeOn1State thelist1;
421 if (!(*p).IsBound(S)) (*p).Bind(S, thelist1);
422 TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).ChangeFind(S);
423 TopTools_ListOfShape& L = losos.ChangeListOnState();
427 //=======================================================================
428 //function : ShapePosition
429 //purpose : compute position of shape S compared with the shapes of list LS
430 // if S is found IN any shape of LS, return IN
432 //=======================================================================
433 TopAbs_State TopOpeBRepBuild_Builder::ShapePosition(const TopoDS_Shape& S, const TopTools_ListOfShape& LS)
435 TopAbs_State state = TopAbs_UNKNOWN;
437 // take the edges of myEdgeAvoid as shape to avoid
438 // during face classification
439 const TopTools_ListOfShape* PLOS = &myEmptyShapeList;
440 TopAbs_ShapeEnum tS = S.ShapeType();
441 if (tS == TopAbs_FACE) PLOS = &myEdgeAvoid;
442 // NYI : idem with myFaceAvoid if (tS == TopAbs_SOLID)
444 for (TopTools_ListIteratorOfListOfShape Iti(LS); Iti.More(); Iti.Next()) {
445 const TopoDS_Shape& SLS = Iti.Value();
447 // TopAbs_ShapeEnum tSLS = SLS.ShapeType();
449 state = myShapeClassifier.StateShapeShape(S,(*PLOS),SLS);
450 if (state != TopAbs_OUT && state != TopAbs_UNKNOWN) return state;
452 if (state == TopAbs_UNKNOWN) return state;
456 //=======================================================================
457 //function : KeepShape
458 //purpose : compute <pos2> = position of shape <S1> / shapes of list <LS2>
461 // - if (pos2 == ToBuild1)
462 //=======================================================================
463 Standard_Boolean TopOpeBRepBuild_Builder::KeepShape(const TopoDS_Shape& S1,const TopTools_ListOfShape& LS2,const TopAbs_State ToBuild1)
465 Standard_Boolean keep = Standard_True;
466 if ( ! LS2.IsEmpty() ) {
467 TopAbs_State pos2 = ShapePosition(S1,LS2);
468 if ( pos2 != ToBuild1 ) keep = Standard_False;
473 //=======================================================================
475 //purpose : return the type of upper subshape found in <S>
476 //=======================================================================
477 TopAbs_ShapeEnum TopOpeBRepBuild_Builder::TopType(const TopoDS_Shape& S)
480 TopOpeBRepTool_ShapeExplorer e;
482 t = TopAbs_COMPOUND; e.Init(S,t); if (e.More()) return t;
483 t = TopAbs_COMPSOLID; e.Init(S,t); if (e.More()) return t;
484 t = TopAbs_SOLID; e.Init(S,t); if (e.More()) return t;
485 t = TopAbs_SHELL; e.Init(S,t); if (e.More()) return t;
486 t = TopAbs_FACE; e.Init(S,t); if (e.More()) return t;
487 t = TopAbs_WIRE; e.Init(S,t); if (e.More()) return t;
488 t = TopAbs_EDGE; e.Init(S,t); if (e.More()) return t;
489 t = TopAbs_VERTEX; e.Init(S,t); if (e.More()) return t;
494 //=======================================================================
496 //purpose : compute orientation reversibility according to build states
497 //=======================================================================
498 Standard_Boolean TopOpeBRepBuild_Builder::Reverse(const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)
500 Standard_Boolean rev;
501 if (ToBuild1 == TopAbs_IN && ToBuild2 == TopAbs_IN) rev = Standard_False;
502 else rev = (ToBuild1 == TopAbs_IN);
506 //=======================================================================
508 //purpose : reverse the orientation
509 //=======================================================================
510 TopAbs_Orientation TopOpeBRepBuild_Builder::Orient(const TopAbs_Orientation Ori,const Standard_Boolean Reverse)
514 : TopAbs::Complement(Ori);
517 //=======================================================================
518 //function : FindSameDomain
519 //purpose : complete the lists L1,L2 with the shapes of the DS
520 // having same domain :
521 // L1 = shapes sharing the same domain of L2 shapes
522 // L2 = shapes sharing the same domain of L1 shapes
523 // (L1 contains a face)
524 //=======================================================================
525 void TopOpeBRepBuild_Builder::FindSameDomain(TopTools_ListOfShape& L1,TopTools_ListOfShape& L2) const
528 Standard_Integer nl1 = L1.Extent(), nl2 = L2.Extent();
530 while ( nl1 > 0 || nl2 > 0 ) {
532 TopTools_ListIteratorOfListOfShape it1(L1);
533 for (i=1 ; i<=nl1; i++) {
534 const TopoDS_Shape& S1 = it1.Value();
536 // Standard_Integer iS1 = myDataStructure->Shape(S1); // DEB
538 TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S1));
539 for (; itsd.More(); itsd.Next() ) {
540 const TopoDS_Shape& S2 = itsd.Value();
542 // Standard_Integer iS2 = myDataStructure->Shape(S2);// DEB
544 Standard_Boolean found = Contains(S2,L2);
554 TopTools_ListIteratorOfListOfShape it2(L2);
555 for (i=1 ; i<=nl2; i++) {
556 const TopoDS_Shape& S2 = it2.Value();
558 // Standard_Integer iS2 = myDataStructure->Shape(S2);// DEB
560 TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S2));
561 for (; itsd.More(); itsd.Next() ) {
562 const TopoDS_Shape& S1 = itsd.Value();
564 // Standard_Integer iS1 = myDataStructure->Shape(S1);// DEB
566 Standard_Boolean found = Contains(S1,L1);
581 //=======================================================================
582 //function : FindSameDomainSameOrientation
584 //=======================================================================
585 void TopOpeBRepBuild_Builder::FindSameDomainSameOrientation(TopTools_ListOfShape& L1, TopTools_ListOfShape& L2) const
587 FindSameDomain(L1,L2);
588 TopTools_ListIteratorOfListOfShape it(L1);
589 if ( !it.More() ) return;
591 const TopoDS_Shape& sref = it.Value();
593 // Standard_Integer iref = myDataStructure->SameDomainReference(sref);
595 TopOpeBRepDS_Config oref = myDataStructure->SameDomainOrientation(sref);
597 TopTools_ListOfShape LL1,LL2;
599 for (it.Initialize(L1); it.More(); it.Next() ) {
600 const TopoDS_Shape& s = it.Value();
601 TopOpeBRepDS_Config o = myDataStructure->SameDomainOrientation(s);
602 if ( o == oref && !Contains(s,LL1) ) LL1.Append(s);
603 else if ( o != oref && !Contains(s,LL2) ) LL2.Append(s);
606 for (it.Initialize(L2); it.More(); it.Next() ) {
607 const TopoDS_Shape& s = it.Value();
608 TopOpeBRepDS_Config o = myDataStructure->SameDomainOrientation(s);
609 if ( o == oref && !Contains(s,LL1) ) LL1.Append(s);
610 else if ( o != oref && !Contains(s,LL2) ) LL2.Append(s);
618 //=======================================================================
619 //function : MapShapes
621 //=======================================================================
622 void TopOpeBRepBuild_Builder::MapShapes(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
624 Standard_Boolean S1null = S1.IsNull();
625 Standard_Boolean S2null = S2.IsNull();
627 if ( ! S1null ) TopExp::MapShapes(S1,myMAP1);
628 if ( ! S2null ) TopExp::MapShapes(S2,myMAP2);
631 //=======================================================================
632 //function : ClearMaps
634 //=======================================================================
635 void TopOpeBRepBuild_Builder::ClearMaps()
641 //=======================================================================
642 //function : FindSameRank
644 //=======================================================================
645 void TopOpeBRepBuild_Builder::FindSameRank(const TopTools_ListOfShape& L1,const Standard_Integer rank,TopTools_ListOfShape& L2) const
647 for ( TopTools_ListIteratorOfListOfShape it1(L1); it1.More(); it1.Next() ) {
648 const TopoDS_Shape& s = it1.Value();
649 Standard_Integer r = ShapeRank(s);
650 if ( r == rank && !Contains(s,L2) ) {
656 //=======================================================================
657 //function : ShapeRank
659 //=======================================================================
660 Standard_Integer TopOpeBRepBuild_Builder::ShapeRank(const TopoDS_Shape& s) const
662 Standard_Boolean isof1 = IsShapeOf(s,1);
663 Standard_Boolean isof2 = IsShapeOf(s,2);
664 Standard_Integer ancetre = (isof1 || isof2) ? ((isof1) ? 1 : 2) : 0;
668 //=======================================================================
669 //function : IsShapeOf
671 //=======================================================================
672 Standard_Boolean TopOpeBRepBuild_Builder::IsShapeOf(const TopoDS_Shape& s,const Standard_Integer i) const
674 Standard_Boolean b = Standard_False;
675 if (i == 1) b = myMAP1.Contains(s);
676 else if (i == 2) b = myMAP2.Contains(s);
680 //=======================================================================
681 //function : Contains
682 //purpose : returns True if S is in the list L.
683 //=======================================================================
684 Standard_Boolean TopOpeBRepBuild_Builder::Contains(const TopoDS_Shape& S,const TopTools_ListOfShape& L)
686 for (TopTools_ListIteratorOfListOfShape it(L); it.More(); it.Next() ) {
687 TopoDS_Shape& SL = it.Value();
688 Standard_Boolean issame = SL.IsSame(S);
689 if ( issame ) return Standard_True;
691 return Standard_False;
694 //=======================================================================
697 //=======================================================================
698 Standard_Boolean TopOpeBRepBuild_Builder::Opec12() const
700 Standard_Boolean b = (myState1 == TopAbs_OUT) && (myState2 == TopAbs_IN );
704 //=======================================================================
707 //=======================================================================
708 Standard_Boolean TopOpeBRepBuild_Builder::Opec21() const
710 Standard_Boolean b = (myState1 == TopAbs_IN ) && (myState2 == TopAbs_OUT);
714 //=======================================================================
717 //=======================================================================
718 Standard_Boolean TopOpeBRepBuild_Builder::Opecom() const
720 Standard_Boolean b = (myState1 == TopAbs_IN ) && (myState2 == TopAbs_IN );
724 //=======================================================================
727 //=======================================================================
728 Standard_Boolean TopOpeBRepBuild_Builder::Opefus() const
730 Standard_Boolean b = (myState1 == TopAbs_OUT) && (myState2 == TopAbs_OUT);
734 //=======================================================================
737 //=======================================================================
738 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& TopOpeBRepBuild_Builder::MSplit(const TopAbs_State s) const
740 if (s == TopAbs_IN) return mySplitIN;
741 else if (s == TopAbs_OUT) return mySplitOUT;
742 else if (s == TopAbs_ON) return mySplitON;
746 //=======================================================================
747 //function : ChangeMSplit
749 //=======================================================================
750 TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& TopOpeBRepBuild_Builder::ChangeMSplit(const TopAbs_State s)
752 if (s == TopAbs_IN) return mySplitIN;
753 else if (s == TopAbs_OUT) return mySplitOUT;
754 else if (s == TopAbs_ON) return mySplitON;
758 //=======================================================================
759 //function : SplitEdge
761 //=======================================================================
763 void TopOpeBRepBuild_Builder::SplitEdge(const TopoDS_Shape& E,
764 const TopAbs_State ToBuild1,
765 const TopAbs_State ToBuild2)
768 if ( TopOpeBRepBuild_GetcontextSF2() ) {
769 SplitEdge2(E,ToBuild1,ToBuild2);
773 SplitEdge1(E,ToBuild1,ToBuild2);
777 //=======================================================================
778 //function : SplitEdge1
780 //=======================================================================
782 void TopOpeBRepBuild_Builder::SplitEdge1(const TopoDS_Shape& Eoriented,
783 const TopAbs_State ToBuild1,
784 const TopAbs_State ToBuild2)
786 // work on a FORWARD edge <Eforward>
788 TopoDS_Shape Eforward = Eoriented;
789 Eforward.Orientation(TopAbs_FORWARD);
791 Standard_Boolean tosplit = ToSplit(Eoriented,ToBuild1);
794 Standard_Integer iEdge; Standard_Boolean tSPS = GtraceSPS(Eoriented,iEdge);
797 GdumpSHASTA(Eoriented,ToBuild1,"--- SplitEdge ");
802 if ( ! tosplit ) return;
804 Reverse(ToBuild1,ToBuild2);
805 Reverse(ToBuild2,ToBuild1);
806 Standard_Boolean ConnectTo1 = Standard_True;
807 Standard_Boolean ConnectTo2 = Standard_False;
809 // build the list of edges to split : LE1, LE2
810 TopTools_ListOfShape LE1,LE2;
811 LE1.Append(Eforward);
812 FindSameDomain(LE1,LE2);
815 if(tSPS){GdumpSAMDOM(LE1, (char *) "1 : ");}
816 if(tSPS){GdumpSAMDOM(LE2, (char *) "2 : ");}
817 if(tSPS){cout<<endl;}
818 if(tSPS){cout<<"V of edge ";TopAbs::Print(Eforward.Orientation(),cout);}
819 if(tSPS){cout<<endl;}
820 if(tSPS){GdumpEDG(Eforward);}
823 // SplitEdge on a edge having other same domained edges on the
824 // other shape : do not reverse orientation of edges in FillEdge
826 // Make a PaveSet <PVS> on edge <Eforward>
827 TopOpeBRepBuild_PaveSet PVS(Eforward);
829 // Add the points/vertices found on edge <Eforward> in <PVS>
830 TopOpeBRepDS_PointIterator EPIT(myDataStructure->EdgePoints(Eforward));
831 FillVertexSet(EPIT,ToBuild1,PVS);
833 TopOpeBRepBuild_PaveClassifier VCL(Eforward);
834 Standard_Boolean equalpar = PVS.HasEqualParameters();
835 if (equalpar) VCL.SetFirstParameter(PVS.EqualParameters());
837 // ------------------------------------------
838 // before return if PVS has no vertices,
839 // mark <Eforward> as split <ToBuild1>
840 // ------------------------------------------
841 MarkSplit(Eforward,ToBuild1);
844 if ( !PVS.MoreLoop() ) {
847 cout<<"NO VERTEX split "; TopAbs::Print(ToBuild1,cout);cout<<endl;
853 // build the new edges
854 TopOpeBRepBuild_EdgeBuilder EBU(PVS,VCL);
856 // Build the new edges
857 // -------------------
858 TopTools_ListOfShape& EdgeList = ChangeMerged(Eforward,ToBuild1);
859 MakeEdges(Eforward,EBU,EdgeList);
861 TopTools_ListIteratorOfListOfShape itLE1,itLE2;
863 // connect new edges as edges built <ToBuild1> on LE1 edge
864 // --------------------------------------------------------
865 for (itLE1.Initialize(LE1); itLE1.More(); itLE1.Next()) {
866 TopoDS_Shape Ecur = itLE1.Value();
867 MarkSplit(Ecur,ToBuild1);
868 TopTools_ListOfShape& EL = ChangeSplit(Ecur,ToBuild1);
869 if ( ConnectTo1 ) EL = EdgeList;
872 // connect new edges as edges built <ToBuild2> on LE2 edges
873 // --------------------------------------------------------
874 for (itLE2.Initialize(LE2); itLE2.More(); itLE2.Next()) {
875 TopoDS_Shape Ecur = itLE2.Value();
876 MarkSplit(Ecur,ToBuild2);
877 TopTools_ListOfShape& EL = ChangeSplit(Ecur,ToBuild2);
878 if ( ConnectTo2 ) EL = EdgeList;
883 //=======================================================================
884 //function : SplitEdge2
886 //=======================================================================
888 void TopOpeBRepBuild_Builder::SplitEdge2(const TopoDS_Shape& Eoriented,
889 const TopAbs_State ToBuild1,
890 const TopAbs_State /*ToBuild2*/)
892 Standard_Boolean tosplit = ToSplit(Eoriented,ToBuild1);
893 if ( ! tosplit ) return;
895 // work on a FORWARD edge <Eforward>
896 TopoDS_Shape Eforward = Eoriented;
897 myBuildTool.Orientation(Eforward,TopAbs_FORWARD);
900 Standard_Integer iEdge; Standard_Boolean tSPS = GtraceSPS(Eoriented,iEdge);
901 if(tSPS){cout<<endl;}
902 if(tSPS){GdumpSHASTA(Eoriented,ToBuild1,"--- SplitEdge2 ");}
905 // Make a PaveSet <PVS> on edge <Eforward>
906 // Add the points/vertices found on edge <Eforward> in <PVS>
907 TopOpeBRepBuild_PaveSet PVS(Eforward);
909 TopOpeBRepDS_PointIterator EPIT(myDataStructure->EdgePoints(Eforward));
910 FillVertexSet(EPIT,ToBuild1,PVS);
912 TopOpeBRepBuild_PaveClassifier VCL(Eforward);
913 Standard_Boolean equalpar = PVS.HasEqualParameters();
914 if (equalpar) VCL.SetFirstParameter(PVS.EqualParameters());
916 // ------------------------------------------
917 // before return if PVS has no vertices,
918 // mark <Eforward> as split <ToBuild1>
919 // ------------------------------------------
920 MarkSplit(Eforward,ToBuild1);
923 if ( !PVS.MoreLoop() ) {
925 if(tSPS) {cout<<"NO VERTEX split ";TopAbs::Print(ToBuild1,cout);cout<<endl;}
930 // build the new edges
931 TopOpeBRepBuild_EdgeBuilder EBU(PVS,VCL);
933 // connect the new edges as split parts <ToBuild1> built on <Eforward>
934 TopTools_ListOfShape& EL = ChangeSplit(Eforward,ToBuild1);
935 MakeEdges(Eforward,EBU,EL);
939 //=======================================================================
940 //function : SplitFace
942 //=======================================================================
944 void TopOpeBRepBuild_Builder::SplitFace(const TopoDS_Shape& Foriented,
945 const TopAbs_State ToBuild1,
946 const TopAbs_State ToBuild2)
949 if(TopOpeBRepBuild_GetcontextSF2()){
950 SplitFace2(Foriented,ToBuild1,ToBuild2);
954 SplitFace1(Foriented,ToBuild1,ToBuild2);
958 //=======================================================================
959 //function : SplitFace1
960 //purpose : tout dans le meme edge set
961 //=======================================================================
963 void TopOpeBRepBuild_Builder::SplitFace1(const TopoDS_Shape& Foriented,
964 const TopAbs_State ToBuild1,
965 const TopAbs_State ToBuild2)
967 // process connect connect
968 // operation tobuild1 tobuild2 face F to 1 to 2
969 // --------- -------- -------- ------- ------- -------
970 // common IN IN yes yes yes
971 // fuse OUT OUT yes yes yes
972 // cut 1-2 OUT IN yes yes no
973 // cut 2-1 IN OUT yes yes no
975 Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1);
976 if ( ! tosplit ) return;
978 Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2);
979 Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1);
980 Standard_Boolean ConnectTo1 = Standard_True;
981 Standard_Boolean ConnectTo2 = Standard_False;
983 // work on a FORWARD face <Fforward>
984 TopoDS_Shape Fforward = Foriented;
985 myBuildTool.Orientation(Fforward,TopAbs_FORWARD);
987 // build the list of faces to split : LF1, LF2
988 TopTools_ListOfShape LF1,LF2;
989 LF1.Append(Fforward);
990 FindSameDomain(LF1,LF2);
991 Standard_Integer n1 = LF1.Extent();
992 Standard_Integer n2 = LF2.Extent();
994 // SplitFace on a face having other same domained faces on the
995 // other shape : do not reverse orientation of faces in FillFace
996 if (!n2) RevOri1 = Standard_False;
997 if (!n1) RevOri2 = Standard_False;
999 // Create an edge set <WES> connected by vertices
1000 // ----------------------------------------------
1001 TopOpeBRepBuild_WireEdgeSet WES(Fforward,this);
1004 Standard_Boolean tSPF=TopOpeBRepBuild_GettraceSPF();
1005 Standard_Integer iFace=myDataStructure->Shape(Foriented);
1006 if(tSPF){cout<<endl;GdumpSHASTA(Foriented,ToBuild1,"=== SplitFace ");}
1007 if(tSPF){GdumpSAMDOM(LF1, (char *) "1 : ");GdumpSAMDOM(LF2, (char *) "2 : ");}
1008 if(tSPF) debspf(iFace);
1011 TopTools_ListIteratorOfListOfShape itLF1,itLF2;
1013 for (itLF1.Initialize(LF1); itLF1.More(); itLF1.Next()) {
1014 const TopoDS_Shape& Fcur = itLF1.Value();
1015 // myDataStructure->Shape(Fcur);//DEB
1016 FillFace(Fcur,ToBuild1,LF2,ToBuild2,WES,RevOri1);
1019 for (itLF2.Initialize(LF2); itLF2.More(); itLF2.Next()) {
1020 const TopoDS_Shape& Fcur = itLF2.Value();
1021 // myDataStructure->Shape(Fcur);//DEB
1022 FillFace(Fcur,ToBuild2,LF1,ToBuild1,WES,RevOri2);
1025 // Add the intersection edges to edge set WES
1026 // -----------------------------------------
1027 AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES);
1030 Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(Fforward,iF);
1031 if(tSPS) WES.DumpSS();
1034 // Create a Face Builder FBU
1035 // ------------------------
1036 TopOpeBRepBuild_FaceBuilder FBU;
1037 FBU.InitFaceBuilder(WES,Fforward,Standard_False); //forceclass = False
1039 // Build the new faces
1040 // -------------------
1041 TopTools_ListOfShape& FaceList = ChangeMerged(Fforward,ToBuild1);
1042 MakeFaces(Fforward,FBU,FaceList);
1044 // connect new faces as faces built <ToBuild1> on LF1 faces
1045 // --------------------------------------------------------
1046 for (itLF1.Initialize(LF1); itLF1.More(); itLF1.Next()) {
1047 TopoDS_Shape Fcur = itLF1.Value();
1048 MarkSplit(Fcur,ToBuild1);
1049 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild1);
1050 if ( ConnectTo1 ) FL = FaceList;
1053 // connect new faces as faces built <ToBuild2> on LF2 faces
1054 // --------------------------------------------------------
1055 for (itLF2.Initialize(LF2); itLF2.More(); itLF2.Next()) {
1056 TopoDS_Shape Fcur = itLF2.Value();
1057 MarkSplit(Fcur,ToBuild2);
1058 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild2);
1059 if ( ConnectTo2 ) FL = FaceList;
1064 //=======================================================================
1065 //function : SplitFace2
1067 //=======================================================================
1069 void TopOpeBRepBuild_Builder::SplitFace2(const TopoDS_Shape& Foriented,
1070 const TopAbs_State ToBuild1,
1071 const TopAbs_State ToBuild2)
1073 // process connect connect
1074 // operation tobuild1 tobuild2 face F to 1 to 2
1075 // --------- -------- -------- ------- ------- -------
1076 // common IN IN yes yes yes
1077 // fuse OUT OUT yes yes yes
1078 // cut 1-2 OUT IN yes yes no
1079 // cut 2-1 IN OUT yes yes no
1081 Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1);
1082 if ( ! tosplit ) return;
1084 Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2);
1085 Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1);
1086 Standard_Boolean ConnectTo1 = Standard_True;
1087 Standard_Boolean ConnectTo2 = Standard_False;
1089 // work on a FORWARD face <Fforward>
1090 TopoDS_Shape Fforward = Foriented;
1091 myBuildTool.Orientation(Fforward,TopAbs_FORWARD);
1093 TopTools_ListOfShape LF1 ; //liste des faces de 1 samedomain
1094 TopTools_ListOfShape LF2 ; //liste des faces de 2 samedomain
1095 LF1.Append(Fforward);
1096 FindSameDomain(LF1,LF2);
1097 Standard_Integer n1 = LF1.Extent();
1098 Standard_Integer n2 = LF2.Extent();
1101 Standard_Boolean tSPF = TopOpeBRepBuild_GettraceSPF();
1102 // Standard_Integer iFace = myDataStructure->Shape(Foriented);
1105 GdumpSHASTA(Foriented,ToBuild1,"=== SplitFace ");
1106 GdumpSAMDOM(LF1, (char *) "samedomain 1 : ");
1107 GdumpSAMDOM(LF2, (char *) "samedomain 2 : ");
1111 // SplitFace on a face having other same domained faces on the
1112 // other shape : do not reverse orientation of faces in FillFace
1113 if (!n2) RevOri1 = Standard_False;
1114 if (!n1) RevOri2 = Standard_False;
1116 TopTools_ListOfShape LFSO; //liste des faces de 1,2 samedomainsameorientation
1117 TopTools_ListOfShape LFOO; //liste des faces de 1,2 samedomainoppositeorient
1119 // LFSO : faces des shapes 1 ou 2, de meme orientation que Fforward.
1120 // LFOO : faces des shapes 1 ou 2, d'orientation contraire que Fforward.
1121 LFSO.Append(Fforward);
1122 FindSameDomainSameOrientation(LFSO,LFOO);
1124 TopTools_ListOfShape LFSO1,LFOO1; // same domain, same orientation, et du shape de F
1125 TopTools_ListOfShape LFSO2,LFOO2; // "" "",du shape autre que celui de F
1127 // on construit les parties ToBuild1 de F
1128 Standard_Integer rankF = ShapeRank(Foriented);
1129 Standard_Integer rankX = (rankF) ? ((rankF == 1) ? 2 : 1) : 0;
1131 FindSameRank(LFSO,rankF,LFSO1);
1132 FindSameRank(LFOO,rankF,LFOO1);
1133 FindSameRank(LFSO,rankX,LFSO2);
1134 FindSameRank(LFOO,rankX,LFOO2);
1138 GdumpSAMDOM(LFSO1, (char *) "LFSO1 : ");
1139 GdumpSAMDOM(LFOO1, (char *) "LFOO1 : ");
1140 GdumpSAMDOM(LFSO2, (char *) "LFSO2 : ");
1141 GdumpSAMDOM(LFOO2, (char *) "LFOO2 : ");
1145 TopAbs_State tob1 = ToBuild1;
1146 TopAbs_State tob2 = ToBuild2;
1147 TopAbs_State tob1comp = (ToBuild1 == TopAbs_IN) ? TopAbs_OUT : TopAbs_IN;
1148 TopAbs_State tob2comp = (ToBuild2 == TopAbs_IN) ? TopAbs_OUT : TopAbs_IN;
1149 TopTools_ListIteratorOfListOfShape itLF ;
1151 // --------------------------------------------------------------------
1152 // traitement des faces de meme orientation que Fforward dans WireEdgeSet WES1
1153 // --------------------------------------------------------------------
1154 TopOpeBRepBuild_WireEdgeSet WES1(Fforward,this);
1156 // traitement des faces de 1 same domain, same orientation que F : LFSO1
1157 for (itLF.Initialize(LFSO1); itLF.More(); itLF.Next()) {
1158 const TopoDS_Shape& Fcur = itLF.Value();
1159 // myDataStructure->Shape(Fcur);//DEB
1160 // les wires de Fcur sont a comparer avec les faces de 2
1161 FillFace(Fcur,tob1,LF2,tob2,WES1,RevOri1);
1164 // traitement des faces de 2 same domain, same orientation que F : LFSO2
1165 for (itLF.Initialize(LFSO2); itLF.More(); itLF.Next()) {
1166 const TopoDS_Shape& Fcur = itLF.Value();
1167 // myDataStructure->Shape(Fcur);//DEB
1168 // les wires de Fcur sont a comparer avec les faces de 1
1169 FillFace(Fcur,tob2,LF1,tob1,WES1,RevOri2);
1172 // traitement des faces de 1 same domain, oppo orientation que F : LFOO1
1173 for (itLF.Initialize(LFOO1); itLF.More(); itLF.Next()) {
1174 const TopoDS_Shape& Fcur = itLF.Value();
1175 // myDataStructure->Shape(Fcur);//DEB
1176 // les wires de Fcur sont a comparer avec les faces de 2
1177 FillFace(Fcur,tob1comp,LF2,ToBuild2,WES1,!RevOri1);
1180 // traitement des faces de 2 same domain, oppo orientation que F : LFOO2
1181 for (itLF.Initialize(LFOO2); itLF.More(); itLF.Next()) {
1182 const TopoDS_Shape& Fcur = itLF.Value();
1183 // myDataStructure->Shape(Fcur);//DEB
1184 // les wires de Fcur sont a comparer avec les faces de 1
1185 FillFace(Fcur,tob2comp,LF1,ToBuild1,WES1,!RevOri2);
1188 // Add the intersection edges to edge set WES1
1189 // ------------------------------------------
1190 AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES1);
1192 // Create a Face Builder FBU1
1193 // ------------------------
1194 TopOpeBRepBuild_FaceBuilder FBU1(WES1,Fforward);
1196 // Build the new faces
1197 // -------------------
1198 TopTools_ListOfShape& FaceList1 = ChangeMerged(Fforward,ToBuild1);
1199 MakeFaces(Fforward,FBU1,FaceList1);
1201 // connect new faces as faces built <ToBuild1> on LF1 faces
1202 // --------------------------------------------------------
1203 for (itLF.Initialize(LF1); itLF.More(); itLF.Next()) {
1204 TopoDS_Shape Fcur = itLF.Value();
1205 MarkSplit(Fcur,ToBuild1);
1206 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild1);
1207 if ( ConnectTo1 ) FL = FaceList1;
1210 // --------------------------------------------------------------------
1211 // traitement des faces de meme orientation que Fforward dans WireEdgeSet WES2
1212 // --------------------------------------------------------------------
1213 TopOpeBRepBuild_WireEdgeSet WES2(Fforward,this);
1215 // traitement des faces de 1 same domain, same orientation que F : LFSO1
1216 for (itLF.Initialize(LFSO1); itLF.More(); itLF.Next()) {
1217 const TopoDS_Shape& Fcur = itLF.Value();
1218 // myDataStructure->Shape(Fcur);//DEB
1219 // les wires de Fcur sont a comparer avec les faces de 2
1220 FillFace(Fcur,tob1comp,LF2,tob2,WES2,!RevOri1);
1223 // traitement des faces de 2 same domain, same orientation que F : LFSO2
1224 for (itLF.Initialize(LFSO2); itLF.More(); itLF.Next()) {
1225 const TopoDS_Shape& Fcur = itLF.Value();
1226 // myDataStructure->Shape(Fcur);//DEB
1227 // les wires de Fcur sont a comparer avec les faces de 1
1228 FillFace(Fcur,tob2comp,LF1,tob1,WES2,!RevOri2);
1231 // traitement des faces de 1 same domain, oppo orientation que F : LFOO1
1232 for (itLF.Initialize(LFOO1); itLF.More(); itLF.Next()) {
1233 const TopoDS_Shape& Fcur = itLF.Value();
1234 // myDataStructure->Shape(Fcur);//DEB
1235 // les wires de Fcur sont a comparer avec les faces de 2
1236 FillFace(Fcur,tob1,LF2,ToBuild2,WES2,RevOri1);
1239 // traitement des faces de 2 same domain, oppo orientation que F : LFOO2
1240 for (itLF.Initialize(LFOO2); itLF.More(); itLF.Next()) {
1241 const TopoDS_Shape& Fcur = itLF.Value();
1242 // myDataStructure->Shape(Fcur);//DEB
1243 // les wires de Fcur sont a comparer avec les faces de 1
1244 FillFace(Fcur,tob2,LF1,ToBuild1,WES2,RevOri2);
1247 // Add the intersection edges to edge set WES2
1248 // ------------------------------------------
1249 AddIntersectionEdges(Fforward,ToBuild2,RevOri2,WES2);
1251 // Create a Face Builder FBU2
1252 // -------------------------
1253 TopOpeBRepBuild_FaceBuilder FBU2(WES2,Fforward);
1255 // Build the new faces
1256 // -------------------
1257 TopTools_ListOfShape& FaceList2 = ChangeMerged(Fforward,ToBuild2);
1258 MakeFaces(Fforward,FBU2,FaceList2);
1260 // connect new faces as faces built <ToBuild2> on LF2 faces
1261 // --------------------------------------------------------
1262 for (itLF.Initialize(LF2); itLF.More(); itLF.Next()) {
1263 TopoDS_Shape Fcur = itLF.Value();
1264 MarkSplit(Fcur,ToBuild2);
1265 TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild2);
1266 if ( ConnectTo2 ) FL = FaceList2;
1271 //=======================================================================
1272 //function : SplitSolid
1274 //=======================================================================
1276 void TopOpeBRepBuild_Builder::SplitSolid(const TopoDS_Shape& S1oriented,
1277 const TopAbs_State ToBuild1,
1278 const TopAbs_State ToBuild2)
1280 //modified by IFV for treating shell
1281 Standard_Boolean tosplit = Standard_False;
1282 Standard_Boolean IsShell = (S1oriented.ShapeType() == TopAbs_SHELL);
1285 ex.Init(S1oriented, TopAbs_FACE);
1286 for (; ex.More(); ex.Next()) {
1287 const TopoDS_Shape& sh = ex.Current();
1288 tosplit = ToSplit(sh,ToBuild1);
1292 else tosplit = ToSplit(S1oriented,ToBuild1);
1294 if ( ! tosplit ) return;
1297 Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2);
1298 Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1);
1299 Standard_Boolean ConnectTo1 = Standard_True;
1300 Standard_Boolean ConnectTo2 = Standard_False;
1302 // work on a FORWARD solid <S1forward>
1303 TopoDS_Shape S1forward = S1oriented;
1304 myBuildTool.Orientation(S1forward,TopAbs_FORWARD);
1306 // build the list of solids to split : LS1, LS2
1307 TopTools_ListOfShape LS1,LS2;
1308 LS1.Append(S1forward);
1309 FindSameDomain(LS1,LS2);
1310 Standard_Integer n1 = LS1.Extent();
1311 Standard_Integer n2 = LS2.Extent();
1313 if (!n2) RevOri1 = Standard_False;
1314 if (!n1) RevOri2 = Standard_False;
1316 // Create a face set <FS> connected by edges
1317 // -----------------------------------------
1318 TopOpeBRepBuild_ShellFaceSet SFS;
1321 Standard_Boolean tSPS = TopOpeBRepBuild_GettraceSPS();
1322 // Standard_Integer iSolid = myDataStructure->Shape(S1oriented);
1325 GdumpSHASTA(S1oriented,ToBuild1,"___ SplitSolid ");
1326 GdumpSAMDOM(LS1, (char *) "1 : ");
1327 GdumpSAMDOM(LS2, (char *) "2 : ");
1329 SFS.DEBNumber(GdumpSHASETindex());
1332 STATIC_SOLIDINDEX = 1;
1333 TopTools_ListIteratorOfListOfShape itLS1;
1334 for (itLS1.Initialize(LS1); itLS1.More(); itLS1.Next()) {
1335 TopoDS_Shape Scur = itLS1.Value();
1336 FillSolid(Scur,ToBuild1,LS2,ToBuild2,SFS,RevOri1);
1339 STATIC_SOLIDINDEX = 2;
1340 TopTools_ListIteratorOfListOfShape itLS2;
1341 for (itLS2.Initialize(LS2); itLS2.More(); itLS2.Next()) {
1342 TopoDS_Shape Scur = itLS2.Value();
1343 FillSolid(Scur,ToBuild2,LS1,ToBuild1,SFS,RevOri2);
1346 // Add the intersection surfaces
1347 // -----------------------------
1348 if (myDataStructure->NbSurfaces() > 0) {
1349 TopOpeBRepDS_SurfaceIterator SSurfaces = myDataStructure->SolidSurfaces(S1forward);
1350 for (; SSurfaces.More(); SSurfaces.Next()) {
1351 Standard_Integer iS = SSurfaces.Current();
1352 const TopTools_ListOfShape& LnewF = NewFaces(iS);
1353 for (TopTools_ListIteratorOfListOfShape Iti(LnewF); Iti.More(); Iti.Next()) {
1354 TopoDS_Shape aFace = Iti.Value();
1355 TopAbs_Orientation ori = SSurfaces.Orientation(ToBuild1);
1356 myBuildTool.Orientation(aFace,ori);
1360 TCollection_AsciiString ss("--- SplitSolid ");
1361 ss = ss + SFS.DEBNumber() + " AddElement SFS+ face ";
1362 GdumpSHA(aFace,(Standard_Address)ss.ToCString());
1363 cout<<" ";TopAbs::Print(ToBuild1,cout)<<" : 1 face ";
1364 TopAbs::Print(ori,cout); cout<<endl;
1367 SFS.AddElement(aFace);
1372 // Create a Solid Builder SOBU
1373 // -------------------------
1374 TopOpeBRepBuild_SolidBuilder SOBU(SFS);
1376 // Build the new solids on S1
1377 // --------------------------
1378 TopTools_ListOfShape& SolidList = ChangeMerged(S1oriented,ToBuild1);
1380 MakeShells(SOBU,SolidList);
1382 MakeSolids(SOBU,SolidList);
1384 // connect list of new solids <SolidList> as solids built on LS1 solids
1385 // --------------------------------------------------------------------
1387 for (itLS1.Initialize(LS1); itLS1.More(); itLS1.Next()) {
1388 TopoDS_Shape Scur = itLS1.Value();
1389 MarkSplit(Scur,ToBuild1);
1390 TopTools_ListOfShape& SL = ChangeSplit(Scur,ToBuild1);
1391 if ( ConnectTo1 ) SL = SolidList;
1395 // connect list of new solids <SolidList> as solids built on LS2 solids
1396 // --------------------------------------------------------------------
1397 for (itLS2.Initialize(LS2); itLS2.More(); itLS2.Next()) {
1398 TopoDS_Shape Scur = itLS2.Value();
1399 MarkSplit(Scur,ToBuild2);
1400 TopTools_ListOfShape& SL = ChangeSplit(Scur,ToBuild2);
1401 if ( ConnectTo2 ) SL = SolidList;
1406 static Standard_Boolean FUN_touched(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& EOR)
1408 TopoDS_Vertex vf,vl; TopExp::Vertices(EOR,vf,vl);
1409 Standard_Boolean hvf = BDS.HasShape(vf);
1410 Standard_Boolean hvl = BDS.HasShape(vl);
1411 return (hvf || hvl);
1414 //=======================================================================
1415 //function : SplitShapes
1417 //=======================================================================
1418 void TopOpeBRepBuild_Builder::SplitShapes(TopOpeBRepTool_ShapeExplorer& Ex,
1419 const TopAbs_State ToBuild1,
1420 const TopAbs_State ToBuild2,
1421 TopOpeBRepBuild_ShapeSet& aSet,
1422 const Standard_Boolean RevOri)
1424 TopoDS_Shape aShape;
1425 TopAbs_Orientation newori;
1427 for (; Ex.More(); Ex.Next()) {
1428 aShape = Ex.Current();
1430 // compute new orientation <newori> to give to the new shapes
1431 newori = Orient(myBuildTool.Orientation(aShape),RevOri);
1433 TopAbs_ShapeEnum t = aShape.ShapeType();
1435 if ( t == TopAbs_SOLID || t == TopAbs_SHELL )
1436 SplitSolid(aShape,ToBuild1,ToBuild2);
1437 else if ( t == TopAbs_FACE ) SplitFace(aShape,ToBuild1,ToBuild2);
1438 else if ( t == TopAbs_EDGE ) SplitEdge(aShape,ToBuild1,ToBuild2);
1441 if ( IsSplit(aShape,ToBuild1) ) {
1442 TopoDS_Shape newShape;
1443 TopTools_ListIteratorOfListOfShape It;
1444 //----------------------- IFV
1445 Standard_Boolean IsLSon = Standard_False;
1446 //----------------------- IFV
1447 const TopTools_ListOfShape& LS = Splits(aShape,ToBuild1);
1448 //----------------------- IFV
1449 if(t == TopAbs_EDGE && ToBuild1 == TopAbs_IN && LS.Extent() == 0) {
1450 const TopTools_ListOfShape& LSon = Splits(aShape,TopAbs_ON);
1451 It.Initialize(LSon);
1452 IsLSon = Standard_True;
1457 //----------------------- IFV
1458 for (; It.More(); It.Next()) {
1459 newShape = It.Value();
1460 myBuildTool.Orientation(newShape,newori);
1462 // TopAbs_ShapeEnum tns = TopType(newShape);
1464 //----------------------- IFV
1466 Standard_Boolean add = Standard_True;
1467 if ( !myListOfFace.IsEmpty()) { // 2d pur
1468 add = KeepShape(newShape,myListOfFace,ToBuild1);
1470 if(add) aSet.AddStartElement(newShape);
1474 //----------------------- IFV
1475 aSet.AddStartElement(newShape);
1480 // aShape n'a pas de devenir de split par ToBuild1
1481 // on construit les parties ToBuild1 de aShape (de S1)
1482 Standard_Boolean add = Standard_True;
1483 Standard_Boolean testkeep = Standard_False;
1484 Standard_Boolean isedge = (t == TopAbs_EDGE);
1485 Standard_Boolean hs = (myDataStructure->HasShape(aShape));
1486 Standard_Boolean hg = (myDataStructure->HasGeometry(aShape));
1488 testkeep = isedge && hs && (!hg);
1490 // xpu010399 : USA60299 (!hs)&&(!hg), but vertex on bound is touched (v7)
1492 Standard_Boolean istouched = isedge && (!hs) && (!hg);
1493 if (istouched) istouched = FUN_touched(myDataStructure->DS(),TopoDS::Edge(aShape));
1494 testkeep = testkeep || istouched;
1497 if ( !myListOfFace.IsEmpty()) { // 2d pur
1498 Standard_Boolean keep = KeepShape(aShape,myListOfFace,ToBuild1);
1502 // on classifie en solide uniqt si
1503 // E dans la DS et E a ete purgee de ses interfs car en bout
1505 if (STATIC_SOLIDINDEX == 1) sol = myShape2;
1506 else sol = myShape1;
1507 if ( !sol.IsNull() ) {
1508 Standard_Real first,last;
1509 Handle(Geom_Curve) C3D;
1510 C3D = BRep_Tool::Curve(TopoDS::Edge(aShape),first,last);
1511 if ( !C3D.IsNull() ) {
1512 Standard_Real tt = 0.127956477;
1513 Standard_Real par = (1-tt)*first + tt*last;
1514 gp_Pnt P3D = C3D->Value(par);
1515 Standard_Real tol3d = Precision::Confusion();
1516 BRepClass3d_SolidClassifier SCL(sol,P3D,tol3d);
1517 TopAbs_State state = SCL.State();
1518 add = (state == ToBuild1);
1521 throw Standard_ProgramError("SplitShapes no 3D curve on edge");
1522 // NYI pas de courbe 3d : prendre un point sur (courbe 2d,face)
1525 else { // sol.IsNull
1526 add = Standard_True;
1531 myBuildTool.Orientation(aShape,newori);
1532 aSet.AddElement(aShape);
1540 //=======================================================================
1541 //function : FillShape
1543 //=======================================================================
1544 void TopOpeBRepBuild_Builder::FillShape(const TopoDS_Shape& S1,
1545 const TopAbs_State ToBuild1,
1546 const TopTools_ListOfShape& LS2,
1547 const TopAbs_State ToBuild2,
1548 TopOpeBRepBuild_ShapeSet& aSet,
1549 const Standard_Boolean In_RevOri)
1551 Standard_Boolean RevOri = In_RevOri;
1552 TopAbs_ShapeEnum t = S1.ShapeType();
1553 TopAbs_ShapeEnum t1=TopAbs_COMPOUND,t11=TopAbs_COMPOUND;
1555 if (t == TopAbs_FACE ) {
1559 else if (t == TopAbs_SOLID || t == TopAbs_SHELL) {
1564 // if the shape S1 is a SameDomain one, get its orientation compared
1565 // with the shape taken as reference for all of the SameDomain shape of S1.
1566 Standard_Boolean hsd = myDataStructure->HasSameDomain(S1);
1568 TopOpeBRepDS_Config ssc = myDataStructure->SameDomainOrientation(S1);
1569 if ( ssc == TopOpeBRepDS_DIFFORIENTED ) {
1572 // Standard_Integer iFace = myDataStructure->Shape(S1);
1573 // cout<<endl<<"********** ";
1574 // cout<<"retournement d'orientation de ";TopAbs::Print(t,cout);
1575 // cout<<" "<<iFace<<endl;
1580 // work on a FORWARD shape <aShape>
1581 TopoDS_Shape aShape = S1;
1582 myBuildTool.Orientation(aShape,TopAbs_FORWARD);
1584 TopoDS_Shape aSubShape;
1585 TopAbs_Orientation newori;
1587 // Explore the SubShapes of type <t1>
1588 for (TopOpeBRepTool_ShapeExplorer ex1(aShape,t1); ex1.More(); ex1.Next()) {
1589 aSubShape = ex1.Current();
1591 if ( ! myDataStructure->HasShape(aSubShape) ) {
1592 // SubShape is not in DS : classify it with shapes of LS2
1593 Standard_Boolean keep = KeepShape(aSubShape,LS2,ToBuild1);
1595 newori = Orient(myBuildTool.Orientation(aSubShape),RevOri);
1596 myBuildTool.Orientation(aSubShape,newori);
1597 aSet.AddShape(aSubShape);
1601 // SubShape has geometry : split the <t11> SubShapes of the SubShape
1602 TopOpeBRepTool_ShapeExplorer ex11(aSubShape,t11);
1603 SplitShapes(ex11,ToBuild1,ToBuild2,aSet,RevOri);
1605 } // exploration ot SubShapes of type <t1> of shape <S1>
1610 //=======================================================================
1611 //function : FillFace
1613 //=======================================================================
1614 void TopOpeBRepBuild_Builder::FillFace(const TopoDS_Shape& F1,
1615 const TopAbs_State ToBuild1,
1616 const TopTools_ListOfShape& LF2,
1617 const TopAbs_State ToBuild2,
1618 TopOpeBRepBuild_WireEdgeSet& WES,
1619 const Standard_Boolean RevOri)
1622 Standard_Boolean tSPF = TopOpeBRepBuild_GettraceSPF();
1623 // Standard_Integer iFace = myDataStructure->Shape(F1);
1624 if(tSPF){cout<<endl;}
1625 if(tSPF){GdumpSHASTA(F1,ToBuild1,"=-= FillFace ");}
1628 FillShape(F1,ToBuild1,LF2,ToBuild2,WES,RevOri);
1629 myListOfFace.Clear();
1633 //=======================================================================
1634 //function : FillSolid
1635 //purpose : load shells and faces from the solid in the ShellFaceSet <aSet>
1636 //=======================================================================
1637 void TopOpeBRepBuild_Builder::FillSolid(const TopoDS_Shape& S1,
1638 const TopAbs_State ToBuild1,
1639 const TopTools_ListOfShape& LS2,
1640 const TopAbs_State ToBuild2,
1641 TopOpeBRepBuild_ShapeSet& aSet,
1642 const Standard_Boolean RevOri)
1644 FillShape(S1,ToBuild1,LS2,ToBuild2,aSet,RevOri);
1648 //=======================================================================
1649 //function : FillVertexSet
1651 //=======================================================================
1652 void TopOpeBRepBuild_Builder::FillVertexSet(TopOpeBRepDS_PointIterator& IT,
1653 const TopAbs_State ToBuild,
1654 TopOpeBRepBuild_PaveSet& PVS) const
1656 for (; IT.More(); IT.Next()) {
1657 FillVertexSetOnValue(IT,ToBuild,PVS);
1662 //=======================================================================
1663 //function : FillVertexSetOnValue
1665 //=======================================================================
1666 void TopOpeBRepBuild_Builder::FillVertexSetOnValue
1667 (const TopOpeBRepDS_PointIterator& IT,
1668 const TopAbs_State ToBuild,
1669 TopOpeBRepBuild_PaveSet& PVS) const
1673 // ind = index of new point or existing vertex
1674 Standard_Integer ind = IT.Current();
1675 Standard_Boolean ispoint = IT.IsPoint();
1677 //if (ispoint) V = NewVertex(ind);
1678 if (ispoint && ind <= myDataStructure->NbPoints()) V = NewVertex(ind);
1680 else V = myDataStructure->Shape(ind);
1681 Standard_Real par = IT.Parameter();
1682 TopAbs_Orientation ori = IT.Orientation(ToBuild);
1684 Standard_Boolean keep = Standard_True;
1685 // if (ori==TopAbs_EXTERNAL || ori==TopAbs_INTERNAL) keep = Standard_False;
1688 myBuildTool.Orientation(V,ori);
1689 Handle(TopOpeBRepBuild_Pave) PV = new TopOpeBRepBuild_Pave(V,par,Standard_False);
1694 const TopoDS_Edge& EDEB = PVS.Edge();
1695 Standard_Integer iE; Standard_Boolean tSPS = GtraceSPS(EDEB,iE);
1697 if (keep) cout<<"+"; else cout<<"-";
1698 if (ispoint) cout<<" PDS "; else cout<<" VDS ";
1699 cout<<ind<<" : "; GdumpORIPARPNT(ori,par,BRep_Tool::Pnt(TopoDS::Vertex(V)));