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
5 //
6 // This file is part of Open CASCADE Technology software library.
7 //
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.
13 //
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
16 
17 
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>
23 #include <gp_Pnt.hxx>
24 #include <Precision.hxx>
25 #include <Standard_NoSuchObject.hxx>
26 #include <Standard_ProgramError.hxx>
27 #include <TCollection_AsciiString.hxx>
28 #include <TopExp.hxx>
29 #include <TopoDS.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>
64 
65 #ifdef OCCT_DEBUG
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();
debmarksplit(const Standard_Integer i)71 Standard_EXPORT void debmarksplit(const Standard_Integer i) {std::cout<<"++ debmarksplit "<<i<<std::endl;}
debchangesplit(const Standard_Integer i)72 Standard_EXPORT void debchangesplit(const Standard_Integer i) {std::cout<<"++ debchangesplit "<<i<<std::endl;}
debspf(const Standard_Integer i)73 Standard_EXPORT void debspf(const Standard_Integer i) {std::cout<<"++  debspf"<<i<<std::endl;}
74 #endif
75 
76 static  Standard_Integer STATIC_SOLIDINDEX = 0;
77 
78 //=======================================================================
79 //function : TopOpeBRepBuild_Builder
80 //purpose  :
81 //=======================================================================
TopOpeBRepBuild_Builder(const TopOpeBRepDS_BuildTool & BT)82 TopOpeBRepBuild_Builder::TopOpeBRepBuild_Builder(const TopOpeBRepDS_BuildTool& BT)
83 : myBuildTool(BT),
84   mySectionDone(Standard_False),
85   myIsKPart(0),
86   myClassifyDef(Standard_False),
87   myClassifyVal(Standard_True),
88   myProcessON(Standard_False)
89 {
90   InitSection();
91 }
92 
93 //modified by NIZHNY-MZV  Sat May  6 10:04:49 2000
94 //=======================================================================
95 //function : ~TopOpeBRepBuild_Builder
96 //purpose  : virtual destructor
97 //=======================================================================
~TopOpeBRepBuild_Builder()98 TopOpeBRepBuild_Builder::~TopOpeBRepBuild_Builder()
99 {
100 }
101 
102 //=======================================================================
103 //function : ChangeBuildTool
104 //purpose  :
105 //=======================================================================
ChangeBuildTool()106 TopOpeBRepDS_BuildTool& TopOpeBRepBuild_Builder::ChangeBuildTool()
107 {
108   return myBuildTool;
109 }
110 
111 //=======================================================================
112 //function : BuildTool
113 //purpose  :
114 //=======================================================================
BuildTool() const115 const TopOpeBRepDS_BuildTool& TopOpeBRepBuild_Builder::BuildTool() const
116 {
117   return myBuildTool;
118 }
119 
120 //=======================================================================
121 //function : DataStructure
122 //purpose  :
123 //=======================================================================
Handle(TopOpeBRepDS_HDataStructure)124 Handle(TopOpeBRepDS_HDataStructure) TopOpeBRepBuild_Builder::DataStructure() const
125 {
126   return myDataStructure;
127 }
128 
129 //=======================================================================
130 //function : Perform
131 //purpose  :
132 //=======================================================================
Perform(const Handle (TopOpeBRepDS_HDataStructure)& HDS)133 void TopOpeBRepBuild_Builder::Perform(const Handle(TopOpeBRepDS_HDataStructure)& HDS)
134 {
135 #ifdef OCCT_DEBUG
136   GdumpSHASETreset();
137 #endif
138   Clear();
139   myDataStructure = HDS;
140   BuildVertices(HDS);
141   SplitEvisoONperiodicF();
142   BuildEdges(HDS);
143   BuildFaces(HDS);
144   myIsKPart = 0;
145   InitSection();
146   SplitSectionEdges();
147   TopOpeBRepDS_Filter F(HDS, &myShapeClassifier);
148   F.ProcessFaceInterferences(mySplitON);
149   TopOpeBRepDS_Reducer R(HDS);
150   R.ProcessFaceInterferences(mySplitON);
151 } // Perform
152 
153 //=======================================================================
154 //function : Perform
155 //purpose  :
156 //=======================================================================
Perform(const Handle (TopOpeBRepDS_HDataStructure)& HDS,const TopoDS_Shape & S1,const TopoDS_Shape & S2)157 void TopOpeBRepBuild_Builder::Perform(const Handle(TopOpeBRepDS_HDataStructure)& HDS,const TopoDS_Shape& S1, const TopoDS_Shape& S2)
158 {
159   Perform(HDS);
160   myShape1 = S1; myShape2 = S2;
161   myIsKPart = FindIsKPart();
162 } // Perform
163 
164 //=======================================================================
165 //function : AddIntersectionEdges
166 //purpose  :
167 //=======================================================================
AddIntersectionEdges(TopoDS_Shape & aFace,const TopAbs_State ToBuild1,const Standard_Boolean RevOri1,TopOpeBRepBuild_ShapeSet & WES) const168 void TopOpeBRepBuild_Builder::AddIntersectionEdges
169 (TopoDS_Shape& aFace,const TopAbs_State ToBuild1,const Standard_Boolean RevOri1,TopOpeBRepBuild_ShapeSet& WES) const
170 {
171   TopoDS_Shape anEdge;
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);
180 
181       if(newori == TopAbs_EXTERNAL) continue;
182 
183       myBuildTool.Orientation(anEdge,newori);
184       const Handle(Geom2d_Curve)& PC = FCurves.PCurve();
185       myBuildTool.PCurve(aFace,anEdge,PC);
186       WES.AddStartElement(anEdge);
187     }
188   }
189 }
190 
191 //=======================================================================
192 //function : Clear
193 //purpose  :
194 //=======================================================================
Clear()195 void TopOpeBRepBuild_Builder::Clear()
196 {
197   if (myDataStructure.IsNull())
198   {
199     myMergedOUT.Clear();
200     myMergedIN.Clear();
201     myMergedON.Clear();
202     return;
203   }
204 
205   const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS();
206   for (TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State it (mySplitOUT); it.More(); it.Next())
207   {
208     const TopoDS_Shape& e = it.Key();
209     if (e.ShapeType() == TopAbs_EDGE)
210     {
211       Standard_Boolean isse =  BDS.IsSectionEdge(TopoDS::Edge(e));
212       if (!isse) mySplitOUT.ChangeFind(e).Clear();
213     }
214   }
215   for (TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State it (mySplitIN); it.More(); it.Next())
216   {
217     const TopoDS_Shape& e = it.Key();
218     if (e.ShapeType() == TopAbs_EDGE)
219     {
220       Standard_Boolean isse =  BDS.IsSectionEdge(TopoDS::Edge(e));
221       if (!isse) mySplitIN.ChangeFind(e).Clear();
222     }
223   }
224   for (TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State it (mySplitON); it.More(); it.Next())
225   {
226     const TopoDS_Shape& e = it.Key();
227     if (e.ShapeType() == TopAbs_EDGE)
228     {
229       Standard_Boolean isse =  BDS.IsSectionEdge(TopoDS::Edge(e));
230       if (!isse) mySplitON.ChangeFind(e).Clear();
231     }
232   }
233 
234   myMergedOUT.Clear();
235   myMergedIN.Clear();
236   myMergedON.Clear();
237 } // Clear
238 
239 //=======================================================================
240 //function : NewFaces
241 //purpose  :
242 //=======================================================================
NewFaces(const Standard_Integer I) const243 const TopTools_ListOfShape& TopOpeBRepBuild_Builder::NewFaces(const Standard_Integer I) const
244 {
245   const TopTools_ListOfShape& L = myNewFaces->Array1().Value(I);
246   return L;
247 } // NewFaces
248 
249 //=======================================================================
250 //function : ChangeNewFaces
251 //purpose  : private
252 //=======================================================================
ChangeNewFaces(const Standard_Integer I)253 TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeNewFaces(const Standard_Integer I)
254 {
255   TopTools_ListOfShape& L = myNewFaces->ChangeArray1().ChangeValue(I);
256   return L;
257 } // ChangeNewFaces
258 
259 //=======================================================================
260 //function : NewEdges
261 //purpose  :
262 //=======================================================================
NewEdges(const Standard_Integer I) const263 const TopTools_ListOfShape& TopOpeBRepBuild_Builder::NewEdges(const Standard_Integer I) const
264 {
265   if ( myNewEdges.IsBound(I) ) {
266     return myNewEdges.Find(I);
267   }
268   else {
269     return myEmptyShapeList;
270   }
271 } // NewEdges
272 
273 //=======================================================================
274 //function : ChangeNewEdges
275 //purpose  : private
276 //=======================================================================
ChangeNewEdges(const Standard_Integer I)277 TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeNewEdges(const Standard_Integer I)
278 {
279   if ( ! myNewEdges.IsBound(I) ) {
280     TopTools_ListOfShape thelist;
281     myNewEdges.Bind(I, thelist);
282   }
283   TopTools_ListOfShape& L = myNewEdges.ChangeFind(I);
284   return L;
285 } // ChangeNewEdges
286 
287 //=======================================================================
288 //function : NewVertex
289 //purpose  :
290 //=======================================================================
NewVertex(const Standard_Integer I) const291 const TopoDS_Shape& TopOpeBRepBuild_Builder::NewVertex(const Standard_Integer I) const
292 {
293   const TopoDS_Shape& V = myNewVertices->Array1().Value(I);
294   return V;
295 } // NewVertex
296 
297 //=======================================================================
298 //function : ChangeNewVertex
299 //purpose  : private
300 //=======================================================================
ChangeNewVertex(const Standard_Integer I)301 TopoDS_Shape& TopOpeBRepBuild_Builder::ChangeNewVertex(const Standard_Integer I)
302 {
303   TopoDS_Shape& V = myNewVertices->ChangeArray1().ChangeValue(I);
304   return V;
305 } // ChangeNewVertex
306 
307 //=======================================================================
308 //function : ToSplit
309 //purpose  : private
310 //=======================================================================
ToSplit(const TopoDS_Shape & S,const TopAbs_State ToBuild) const311 Standard_Boolean TopOpeBRepBuild_Builder::ToSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild) const
312 {
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);
317 
318 #ifdef OCCT_DEBUG
319   Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
320   if (tSPS) {
321     std::cout<<"tosplit "<<tosplit<<" : !issplit "<<(!issplit);
322     std::cout<<" && (hasgeom || hassame) ("<<hasgeom<<" || "<<hassame<<")"<<std::endl;
323   }
324 #endif
325 
326   return tosplit;
327 } // ToSplit
328 
329 //=======================================================================
330 //function : MarkSplit
331 //purpose  : private
332 //=======================================================================
MarkSplit(const TopoDS_Shape & S,const TopAbs_State ToBuild,const Standard_Boolean Bval)333 void TopOpeBRepBuild_Builder::MarkSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild,const Standard_Boolean Bval)
334 {
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;
340 
341   TopOpeBRepDS_ListOfShapeOn1State thelist;
342   if (!(*p).IsBound(S)) (*p).Bind(S, thelist);
343   TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).ChangeFind(S);
344   losos.Split(Bval);
345 
346 #ifdef OCCT_DEBUG
347   Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
348   if(tSPS){
349     GdumpSHA(S, (char *) "MarkSplit ");
350     std::cout<<" ";TopAbs::Print(ToBuild,std::cout);std::cout<<" "<<Bval<<std::endl;
351     debmarksplit(iS);
352   }
353 #endif
354 
355 } // MarkSplit
356 
357 //=======================================================================
358 //function : IsSplit
359 //purpose  :
360 //=======================================================================
IsSplit(const TopoDS_Shape & S,const TopAbs_State ToBuild) const361 Standard_Boolean TopOpeBRepBuild_Builder::IsSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild) const
362 {
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;
369 
370   if ((*p).IsBound(S)) {
371     const TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).Find(S);
372     res = losos.IsSplit();
373 #ifdef OCCT_DEBUG
374 //    Standard_Integer n = losos.ListOnState().Extent();
375 #endif
376   }
377   return res;
378 } // IsSplit
379 
380 //=======================================================================
381 //function : Splits
382 //purpose  :
383 //=======================================================================
Splits(const TopoDS_Shape & S,const TopAbs_State ToBuild) const384 const TopTools_ListOfShape& TopOpeBRepBuild_Builder::Splits(const TopoDS_Shape& S, const TopAbs_State ToBuild) const
385 {
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;
391 
392   if ((*p).IsBound(S)) {
393     const TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).Find(S);
394     const TopTools_ListOfShape& L = losos.ListOnState();
395     return L;
396   }
397   return myEmptyShapeList;
398 } // Splits
399 
400 //=======================================================================
401 //function : ChangeSplit
402 //purpose  : private
403 //=======================================================================
ChangeSplit(const TopoDS_Shape & S,const TopAbs_State ToBuild)404 TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild)
405 {
406 #ifdef OCCT_DEBUG
407   Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
408   if(tSPS){
409     GdumpSHA(S, (char *) "ChangeSplit ");
410     std::cout<<" ";TopAbs::Print(ToBuild,std::cout);std::cout<<std::endl;
411     debchangesplit(iS);
412   }
413 #endif
414 
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();
424   return L;
425 } // ChangeSplit
426 
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
431 //           else return OUT
432 //=======================================================================
ShapePosition(const TopoDS_Shape & S,const TopTools_ListOfShape & LS)433 TopAbs_State TopOpeBRepBuild_Builder::ShapePosition(const TopoDS_Shape& S, const TopTools_ListOfShape& LS)
434 {
435   TopAbs_State state = TopAbs_UNKNOWN;
436 
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)
443 
444   for (TopTools_ListIteratorOfListOfShape Iti(LS); Iti.More(); Iti.Next()) {
445     const TopoDS_Shape& SLS = Iti.Value();
446 #ifdef OCCT_DEBUG
447 //    TopAbs_ShapeEnum tSLS = SLS.ShapeType();
448 #endif
449     state = myShapeClassifier.StateShapeShape(S,(*PLOS),SLS);
450     if (state != TopAbs_OUT && state != TopAbs_UNKNOWN) return state;
451   }
452   if (state == TopAbs_UNKNOWN) return state;
453   return TopAbs_OUT;
454 }
455 
456 //=======================================================================
457 //function : KeepShape
458 //purpose  : compute <pos2> = position of shape <S1> / shapes of list <LS2>
459 //           shape S1 is kept
460 //           - if LS2 is empty
461 //           - if (pos2 == ToBuild1)
462 //=======================================================================
KeepShape(const TopoDS_Shape & S1,const TopTools_ListOfShape & LS2,const TopAbs_State ToBuild1)463 Standard_Boolean TopOpeBRepBuild_Builder::KeepShape(const TopoDS_Shape& S1,const TopTools_ListOfShape& LS2,const TopAbs_State ToBuild1)
464 {
465   Standard_Boolean keep = Standard_True;
466   if ( ! LS2.IsEmpty() ) {
467     TopAbs_State pos2 = ShapePosition(S1,LS2);
468     if ( pos2 != ToBuild1 ) keep = Standard_False;
469   }
470   return keep;
471 }
472 
473 //=======================================================================
474 //function : TopType
475 //purpose  : return the type of upper subshape found in <S>
476 //=======================================================================
TopType(const TopoDS_Shape & S)477 TopAbs_ShapeEnum TopOpeBRepBuild_Builder::TopType(const TopoDS_Shape& S)
478 {
479   TopAbs_ShapeEnum t;
480   TopOpeBRepTool_ShapeExplorer e;
481 
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;
490 
491   return TopAbs_SHAPE;
492 }
493 
494 //=======================================================================
495 //function : Reverse
496 //purpose  : compute orientation reversibility according to build states
497 //=======================================================================
Reverse(const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)498 Standard_Boolean TopOpeBRepBuild_Builder::Reverse(const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)
499 {
500   Standard_Boolean rev;
501   if (ToBuild1 == TopAbs_IN && ToBuild2 == TopAbs_IN) rev = Standard_False;
502   else rev = (ToBuild1 == TopAbs_IN);
503   return rev;
504 }
505 
506 //=======================================================================
507 //function : Orient
508 //purpose  : reverse the orientation
509 //=======================================================================
Orient(const TopAbs_Orientation Ori,const Standard_Boolean Reverse)510 TopAbs_Orientation TopOpeBRepBuild_Builder::Orient(const TopAbs_Orientation Ori,const Standard_Boolean Reverse)
511 {
512   return !Reverse
513        ? Ori
514        : TopAbs::Complement(Ori);
515 }
516 
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 //=======================================================================
FindSameDomain(TopTools_ListOfShape & L1,TopTools_ListOfShape & L2) const525 void TopOpeBRepBuild_Builder::FindSameDomain(TopTools_ListOfShape& L1,TopTools_ListOfShape& L2) const
526 {
527   Standard_Integer i;
528   Standard_Integer nl1 = L1.Extent(), nl2 = L2.Extent();
529 
530   while ( nl1 > 0 || nl2 > 0 )  {
531 
532     TopTools_ListIteratorOfListOfShape it1(L1);
533     for (i=1 ; i<=nl1; i++) {
534       const TopoDS_Shape& S1 = it1.Value();
535 #ifdef OCCT_DEBUG
536 //      Standard_Integer iS1 = myDataStructure->Shape(S1);  // DEB
537 #endif
538       TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S1));
539       for (; itsd.More(); itsd.Next() ) {
540 	const TopoDS_Shape& S2 = itsd.Value();
541 #ifdef OCCT_DEBUG
542 //	Standard_Integer iS2 = myDataStructure->Shape(S2);// DEB
543 #endif
544 	Standard_Boolean found = Contains(S2,L2);
545 	if ( ! found ) {
546 	  L2.Prepend(S2);
547 	  nl2++;
548 	}
549       }
550       it1.Next();
551     }
552     nl1 = 0;
553 
554     TopTools_ListIteratorOfListOfShape it2(L2);
555     for (i=1 ; i<=nl2; i++) {
556       const TopoDS_Shape& S2 = it2.Value();
557 #ifdef OCCT_DEBUG
558 //      Standard_Integer iS2 = myDataStructure->Shape(S2);// DEB
559 #endif
560       TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S2));
561       for (; itsd.More(); itsd.Next() ) {
562 	const TopoDS_Shape& S1 = itsd.Value();
563 #ifdef OCCT_DEBUG
564 //	Standard_Integer iS1 = myDataStructure->Shape(S1);// DEB
565 #endif
566 	Standard_Boolean found = Contains(S1,L1);
567 	if ( ! found ) {
568 	  L1.Prepend(S1);
569 	  nl1++;
570 	}
571       }
572       it2.Next();
573     }
574     nl2 = 0;
575 
576   }
577 
578 }
579 
580 
581 //=======================================================================
582 //function : FindSameDomainSameOrientation
583 //purpose  :
584 //=======================================================================
FindSameDomainSameOrientation(TopTools_ListOfShape & L1,TopTools_ListOfShape & L2) const585 void TopOpeBRepBuild_Builder::FindSameDomainSameOrientation(TopTools_ListOfShape& L1, TopTools_ListOfShape& L2) const
586 {
587   FindSameDomain(L1,L2);
588   TopTools_ListIteratorOfListOfShape it(L1);
589   if ( !it.More() ) return;
590 
591   const TopoDS_Shape& sref = it.Value();
592 #ifdef OCCT_DEBUG
593 //  Standard_Integer  iref = myDataStructure->SameDomainReference(sref);
594 #endif
595   TopOpeBRepDS_Config oref = myDataStructure->SameDomainOrientation(sref);
596 
597   TopTools_ListOfShape LL1,LL2;
598 
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);
604   }
605 
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);
611   }
612 
613   L1 = LL1;
614   L2 = LL2;
615 
616 }
617 
618 //=======================================================================
619 //function : MapShapes
620 //purpose  :
621 //=======================================================================
MapShapes(const TopoDS_Shape & S1,const TopoDS_Shape & S2)622 void TopOpeBRepBuild_Builder::MapShapes(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
623 {
624   Standard_Boolean S1null = S1.IsNull();
625   Standard_Boolean S2null = S2.IsNull();
626   ClearMaps();
627   if ( ! S1null ) TopExp::MapShapes(S1,myMAP1);
628   if ( ! S2null ) TopExp::MapShapes(S2,myMAP2);
629 }
630 
631 //=======================================================================
632 //function : ClearMaps
633 //purpose  :
634 //=======================================================================
ClearMaps()635 void TopOpeBRepBuild_Builder::ClearMaps()
636 {
637   myMAP1.Clear();
638   myMAP2.Clear();
639 }
640 
641 //=======================================================================
642 //function : FindSameRank
643 //purpose  :
644 //=======================================================================
FindSameRank(const TopTools_ListOfShape & L1,const Standard_Integer rank,TopTools_ListOfShape & L2) const645 void TopOpeBRepBuild_Builder::FindSameRank(const TopTools_ListOfShape& L1,const Standard_Integer rank,TopTools_ListOfShape& L2) const
646 {
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) ) {
651       L2.Append(s);
652     }
653   }
654 }
655 
656 //=======================================================================
657 //function : ShapeRank
658 //purpose  :
659 //=======================================================================
ShapeRank(const TopoDS_Shape & s) const660 Standard_Integer TopOpeBRepBuild_Builder::ShapeRank(const TopoDS_Shape& s) const
661 {
662   Standard_Boolean isof1 = IsShapeOf(s,1);
663   Standard_Boolean isof2 = IsShapeOf(s,2);
664   Standard_Integer ancetre = (isof1 || isof2) ? ((isof1) ? 1 : 2) : 0;
665   return ancetre;
666 }
667 
668 //=======================================================================
669 //function : IsShapeOf
670 //purpose  :
671 //=======================================================================
IsShapeOf(const TopoDS_Shape & s,const Standard_Integer i) const672 Standard_Boolean TopOpeBRepBuild_Builder::IsShapeOf(const TopoDS_Shape& s,const Standard_Integer i) const
673 {
674   Standard_Boolean b = Standard_False;
675   if      (i == 1) b = myMAP1.Contains(s);
676   else if (i == 2) b = myMAP2.Contains(s);
677   return b;
678 }
679 
680 //=======================================================================
681 //function : Contains
682 //purpose  : returns True if S is in the list L.
683 //=======================================================================
Contains(const TopoDS_Shape & S,const TopTools_ListOfShape & L)684 Standard_Boolean TopOpeBRepBuild_Builder::Contains(const TopoDS_Shape& S,const TopTools_ListOfShape& L)
685 {
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;
690   }
691   return Standard_False;
692 }
693 
694 //=======================================================================
695 //function : Opec12
696 //purpose  :
697 //=======================================================================
Opec12() const698 Standard_Boolean TopOpeBRepBuild_Builder::Opec12() const
699 {
700   Standard_Boolean b = (myState1 == TopAbs_OUT) && (myState2 == TopAbs_IN );
701   return b;
702 }
703 
704 //=======================================================================
705 //function : Opec21
706 //purpose  :
707 //=======================================================================
Opec21() const708 Standard_Boolean TopOpeBRepBuild_Builder::Opec21() const
709 {
710   Standard_Boolean b = (myState1 == TopAbs_IN ) && (myState2 == TopAbs_OUT);
711   return b;
712 }
713 
714 //=======================================================================
715 //function : Opecom
716 //purpose  :
717 //=======================================================================
Opecom() const718 Standard_Boolean TopOpeBRepBuild_Builder::Opecom() const
719 {
720   Standard_Boolean b = (myState1 == TopAbs_IN ) && (myState2 == TopAbs_IN );
721   return b;
722 }
723 
724 //=======================================================================
725 //function : Opefus
726 //purpose  :
727 //=======================================================================
Opefus() const728 Standard_Boolean TopOpeBRepBuild_Builder::Opefus() const
729 {
730   Standard_Boolean b = (myState1 == TopAbs_OUT) && (myState2 == TopAbs_OUT);
731   return b;
732 }
733 
734 //=======================================================================
735 //function : MSplit
736 //purpose  :
737 //=======================================================================
MSplit(const TopAbs_State s) const738 const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& TopOpeBRepBuild_Builder::MSplit(const TopAbs_State s) const
739 {
740   if      (s == TopAbs_IN)  return mySplitIN;
741   else if (s == TopAbs_OUT) return mySplitOUT;
742   else if (s == TopAbs_ON)  return mySplitON;
743   return mySplitIN;
744 }
745 
746 //=======================================================================
747 //function : ChangeMSplit
748 //purpose  :
749 //=======================================================================
ChangeMSplit(const TopAbs_State s)750 TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& TopOpeBRepBuild_Builder::ChangeMSplit(const TopAbs_State s)
751 {
752   if      (s == TopAbs_IN)  return mySplitIN;
753   else if (s == TopAbs_OUT) return mySplitOUT;
754   else if (s == TopAbs_ON)  return mySplitON;
755   return mySplitIN;
756 }
757 
758 //=======================================================================
759 //function : SplitEdge
760 //purpose  :
761 //=======================================================================
762 
SplitEdge(const TopoDS_Shape & E,const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)763 void TopOpeBRepBuild_Builder::SplitEdge(const TopoDS_Shape& E,
764 					const TopAbs_State ToBuild1,
765 					const TopAbs_State ToBuild2)
766 {
767 #ifdef OCCT_DEBUG
768   if ( TopOpeBRepBuild_GetcontextSF2() ) {
769     SplitEdge2(E,ToBuild1,ToBuild2);
770     return;
771   }
772 #endif
773   SplitEdge1(E,ToBuild1,ToBuild2);
774   return;
775 }
776 
777 //=======================================================================
778 //function : SplitEdge1
779 //purpose  :
780 //=======================================================================
781 
SplitEdge1(const TopoDS_Shape & Eoriented,const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)782 void TopOpeBRepBuild_Builder::SplitEdge1(const TopoDS_Shape& Eoriented,
783 					 const TopAbs_State ToBuild1,
784 					 const TopAbs_State ToBuild2)
785 {
786   // work on a FORWARD edge <Eforward>
787 
788   TopoDS_Shape Eforward = Eoriented;
789   Eforward.Orientation(TopAbs_FORWARD);
790 
791   Standard_Boolean tosplit = ToSplit(Eoriented,ToBuild1);
792 
793 #ifdef OCCT_DEBUG
794   Standard_Integer iEdge; Standard_Boolean tSPS = GtraceSPS(Eoriented,iEdge);
795   if(tSPS){
796     std::cout<<std::endl;
797     GdumpSHASTA(Eoriented,ToBuild1,"--- SplitEdge ");
798     std::cout<<std::endl;
799   }
800 #endif
801 
802   if ( ! tosplit ) return;
803 
804   Reverse(ToBuild1,ToBuild2);
805   Reverse(ToBuild2,ToBuild1);
806   Standard_Boolean ConnectTo1 = Standard_True;
807   Standard_Boolean ConnectTo2 = Standard_False;
808 
809   // build the list of edges to split : LE1, LE2
810   TopTools_ListOfShape LE1,LE2;
811   LE1.Append(Eforward);
812   FindSameDomain(LE1,LE2);
813 
814 #ifdef OCCT_DEBUG
815   if(tSPS){GdumpSAMDOM(LE1, (char *) "1 : ");}
816   if(tSPS){GdumpSAMDOM(LE2, (char *) "2 : ");}
817   if(tSPS){std::cout<<std::endl;}
818   if(tSPS){std::cout<<"V of edge ";TopAbs::Print(Eforward.Orientation(),std::cout);}
819   if(tSPS){std::cout<<std::endl;}
820   if(tSPS){GdumpEDG(Eforward);}
821 #endif
822 
823   // SplitEdge on a edge having other same domained edges on the
824   // other shape : do not reverse orientation of edges in FillEdge
825 
826   // Make a PaveSet <PVS> on edge <Eforward>
827   TopOpeBRepBuild_PaveSet PVS(Eforward);
828 
829   // Add the points/vertices found on edge <Eforward> in <PVS>
830   TopOpeBRepDS_PointIterator EPIT(myDataStructure->EdgePoints(Eforward));
831   FillVertexSet(EPIT,ToBuild1,PVS);
832 
833   TopOpeBRepBuild_PaveClassifier VCL(Eforward);
834   Standard_Boolean equalpar = PVS.HasEqualParameters();
835   if (equalpar) VCL.SetFirstParameter(PVS.EqualParameters());
836 
837   // ------------------------------------------
838   // before return if PVS has no vertices,
839   // mark <Eforward> as split <ToBuild1>
840   // ------------------------------------------
841   MarkSplit(Eforward,ToBuild1);
842 
843   PVS.InitLoop();
844   if ( !PVS.MoreLoop() ) {
845 #ifdef OCCT_DEBUG
846     if(tSPS) {
847       std::cout<<"NO VERTEX split "; TopAbs::Print(ToBuild1,std::cout);std::cout<<std::endl;
848     }
849 #endif
850     return;
851   }
852 
853   // build the new edges
854   TopOpeBRepBuild_EdgeBuilder EBU(PVS,VCL);
855 
856   // Build the new edges
857   // -------------------
858   TopTools_ListOfShape& EdgeList = ChangeMerged(Eforward,ToBuild1);
859   MakeEdges(Eforward,EBU,EdgeList);
860 
861   TopTools_ListIteratorOfListOfShape itLE1,itLE2;
862 
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;
870   }
871 
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;
879   }
880 
881 } // SplitEdge1
882 
883 //=======================================================================
884 //function : SplitEdge2
885 //purpose  :
886 //=======================================================================
887 
SplitEdge2(const TopoDS_Shape & Eoriented,const TopAbs_State ToBuild1,const TopAbs_State)888 void TopOpeBRepBuild_Builder::SplitEdge2(const TopoDS_Shape& Eoriented,
889 					 const TopAbs_State ToBuild1,
890 					 const TopAbs_State /*ToBuild2*/)
891 {
892   Standard_Boolean tosplit = ToSplit(Eoriented,ToBuild1);
893   if ( ! tosplit ) return;
894 
895   // work on a FORWARD edge <Eforward>
896   TopoDS_Shape Eforward = Eoriented;
897   myBuildTool.Orientation(Eforward,TopAbs_FORWARD);
898 
899 #ifdef OCCT_DEBUG
900   Standard_Integer iEdge; Standard_Boolean tSPS = GtraceSPS(Eoriented,iEdge);
901   if(tSPS){std::cout<<std::endl;}
902   if(tSPS){GdumpSHASTA(Eoriented,ToBuild1,"--- SplitEdge2 ");}
903 #endif
904 
905   // Make a PaveSet <PVS> on edge <Eforward>
906   // Add the points/vertices found on edge <Eforward> in <PVS>
907   TopOpeBRepBuild_PaveSet PVS(Eforward);
908 
909   TopOpeBRepDS_PointIterator EPIT(myDataStructure->EdgePoints(Eforward));
910   FillVertexSet(EPIT,ToBuild1,PVS);
911 
912   TopOpeBRepBuild_PaveClassifier VCL(Eforward);
913   Standard_Boolean equalpar = PVS.HasEqualParameters();
914   if (equalpar) VCL.SetFirstParameter(PVS.EqualParameters());
915 
916   // ------------------------------------------
917   // before return if PVS has no vertices,
918   // mark <Eforward> as split <ToBuild1>
919   // ------------------------------------------
920   MarkSplit(Eforward,ToBuild1);
921 
922   PVS.InitLoop();
923   if ( !PVS.MoreLoop() ) {
924 #ifdef OCCT_DEBUG
925     if(tSPS) {std::cout<<"NO VERTEX split ";TopAbs::Print(ToBuild1,std::cout);std::cout<<std::endl;}
926 #endif
927     return;
928   }
929 
930   // build the new edges
931   TopOpeBRepBuild_EdgeBuilder EBU(PVS,VCL);
932 
933   // connect the new edges as split parts <ToBuild1> built on <Eforward>
934   TopTools_ListOfShape& EL = ChangeSplit(Eforward,ToBuild1);
935   MakeEdges(Eforward,EBU,EL);
936 
937 } // SplitEdge2
938 
939 //=======================================================================
940 //function : SplitFace
941 //purpose  :
942 //=======================================================================
943 
SplitFace(const TopoDS_Shape & Foriented,const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)944 void TopOpeBRepBuild_Builder::SplitFace(const TopoDS_Shape& Foriented,
945 					const TopAbs_State ToBuild1,
946 					const TopAbs_State ToBuild2)
947 {
948 #ifdef OCCT_DEBUG
949   if(TopOpeBRepBuild_GetcontextSF2()){
950     SplitFace2(Foriented,ToBuild1,ToBuild2);
951     return;
952   }
953 #endif
954   SplitFace1(Foriented,ToBuild1,ToBuild2);
955   return;
956 }
957 
958 //=======================================================================
959 //function : SplitFace1
960 //purpose  : tout dans le meme edge set
961 //=======================================================================
962 
SplitFace1(const TopoDS_Shape & Foriented,const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)963 void TopOpeBRepBuild_Builder::SplitFace1(const TopoDS_Shape& Foriented,
964 					 const TopAbs_State ToBuild1,
965 					 const TopAbs_State ToBuild2)
966 {
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
974   //
975   Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1);
976   if ( ! tosplit ) return;
977 
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;
982 
983   // work on a FORWARD face <Fforward>
984   TopoDS_Shape Fforward = Foriented;
985   myBuildTool.Orientation(Fforward,TopAbs_FORWARD);
986 
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();
993 
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;
998 
999   // Create an edge set <WES> connected by vertices
1000   // ----------------------------------------------
1001   TopOpeBRepBuild_WireEdgeSet WES(Fforward,this);
1002 
1003 #ifdef OCCT_DEBUG
1004   Standard_Boolean tSPF=TopOpeBRepBuild_GettraceSPF();
1005   Standard_Integer iFace=myDataStructure->Shape(Foriented);
1006   if(tSPF){std::cout<<std::endl;GdumpSHASTA(Foriented,ToBuild1,"=== SplitFace ");}
1007   if(tSPF){GdumpSAMDOM(LF1, (char *) "1 : ");GdumpSAMDOM(LF2, (char *) "2 : ");}
1008   if(tSPF) debspf(iFace);
1009 #endif
1010 
1011   TopTools_ListIteratorOfListOfShape itLF1,itLF2;
1012 
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);
1017   }
1018 
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);
1023   }
1024 
1025   // Add the intersection edges to edge set WES
1026   // -----------------------------------------
1027   AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES);
1028 
1029 #ifdef OCCT_DEBUG
1030   Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(Fforward,iF);
1031   if(tSPS) WES.DumpSS();
1032 #endif
1033 
1034   // Create a Face Builder FBU
1035   // ------------------------
1036   TopOpeBRepBuild_FaceBuilder FBU;
1037   FBU.InitFaceBuilder(WES,Fforward,Standard_False); //forceclass = False
1038 
1039   // Build the new faces
1040   // -------------------
1041   TopTools_ListOfShape& FaceList = ChangeMerged(Fforward,ToBuild1);
1042   MakeFaces(Fforward,FBU,FaceList);
1043 
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;
1051   }
1052 
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;
1060   }
1061 
1062 } // SplitFace1
1063 
1064 //=======================================================================
1065 //function : SplitFace2
1066 //purpose  :
1067 //=======================================================================
1068 
SplitFace2(const TopoDS_Shape & Foriented,const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)1069 void TopOpeBRepBuild_Builder::SplitFace2(const TopoDS_Shape& Foriented,
1070 					 const TopAbs_State ToBuild1,
1071 					 const TopAbs_State ToBuild2)
1072 {
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
1080   //
1081   Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1);
1082   if ( ! tosplit ) return;
1083 
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;
1088 
1089   // work on a FORWARD face <Fforward>
1090   TopoDS_Shape Fforward = Foriented;
1091   myBuildTool.Orientation(Fforward,TopAbs_FORWARD);
1092 
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();
1099 
1100 #ifdef OCCT_DEBUG
1101   Standard_Boolean tSPF = TopOpeBRepBuild_GettraceSPF();
1102 //  Standard_Integer iFace = myDataStructure->Shape(Foriented);
1103   if (tSPF) {
1104     std::cout<<std::endl;
1105     GdumpSHASTA(Foriented,ToBuild1,"=== SplitFace ");
1106     GdumpSAMDOM(LF1, (char *) "samedomain 1 : ");
1107     GdumpSAMDOM(LF2, (char *) "samedomain 2 : ");
1108   }
1109 #endif
1110 
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;
1115 
1116   TopTools_ListOfShape LFSO; //liste des faces de 1,2 samedomainsameorientation
1117   TopTools_ListOfShape LFOO; //liste des faces de 1,2 samedomainoppositeorient
1118 
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);
1123 
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
1126 
1127   // on construit les parties ToBuild1 de F
1128   Standard_Integer rankF = ShapeRank(Foriented);
1129   Standard_Integer rankX = (rankF) ? ((rankF == 1) ? 2 : 1) : 0;
1130 
1131   FindSameRank(LFSO,rankF,LFSO1);
1132   FindSameRank(LFOO,rankF,LFOO1);
1133   FindSameRank(LFSO,rankX,LFSO2);
1134   FindSameRank(LFOO,rankX,LFOO2);
1135 
1136 #ifdef OCCT_DEBUG
1137   if ( tSPF ) {
1138     GdumpSAMDOM(LFSO1, (char *) "LFSO1 : ");
1139     GdumpSAMDOM(LFOO1, (char *) "LFOO1 : ");
1140     GdumpSAMDOM(LFSO2, (char *) "LFSO2 : ");
1141     GdumpSAMDOM(LFOO2, (char *) "LFOO2 : ");
1142   }
1143 #endif
1144 
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 ;
1150 
1151   // --------------------------------------------------------------------
1152   // traitement des faces de meme orientation que Fforward dans WireEdgeSet WES1
1153   // --------------------------------------------------------------------
1154   TopOpeBRepBuild_WireEdgeSet WES1(Fforward,this);
1155 
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);
1162   }
1163 
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);
1170   }
1171 
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);
1178   }
1179 
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);
1186   }
1187 
1188   // Add the intersection edges to edge set WES1
1189   // ------------------------------------------
1190   AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES1);
1191 
1192   // Create a Face Builder FBU1
1193   // ------------------------
1194   TopOpeBRepBuild_FaceBuilder FBU1(WES1,Fforward);
1195 
1196   // Build the new faces
1197   // -------------------
1198   TopTools_ListOfShape& FaceList1 = ChangeMerged(Fforward,ToBuild1);
1199   MakeFaces(Fforward,FBU1,FaceList1);
1200 
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;
1208   }
1209 
1210   // --------------------------------------------------------------------
1211   // traitement des faces de meme orientation que Fforward dans WireEdgeSet WES2
1212   // --------------------------------------------------------------------
1213   TopOpeBRepBuild_WireEdgeSet WES2(Fforward,this);
1214 
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);
1221   }
1222 
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);
1229   }
1230 
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);
1237   }
1238 
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);
1245   }
1246 
1247   // Add the intersection edges to edge set WES2
1248   // ------------------------------------------
1249   AddIntersectionEdges(Fforward,ToBuild2,RevOri2,WES2);
1250 
1251   // Create a Face Builder FBU2
1252   // -------------------------
1253   TopOpeBRepBuild_FaceBuilder FBU2(WES2,Fforward);
1254 
1255   // Build the new faces
1256   // -------------------
1257   TopTools_ListOfShape& FaceList2 = ChangeMerged(Fforward,ToBuild2);
1258   MakeFaces(Fforward,FBU2,FaceList2);
1259 
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;
1267   }
1268 
1269 } // SplitFace2
1270 
1271 //=======================================================================
1272 //function : SplitSolid
1273 //purpose  :
1274 //=======================================================================
1275 
SplitSolid(const TopoDS_Shape & S1oriented,const TopAbs_State ToBuild1,const TopAbs_State ToBuild2)1276 void TopOpeBRepBuild_Builder::SplitSolid(const TopoDS_Shape& S1oriented,
1277 					 const TopAbs_State ToBuild1,
1278 					 const TopAbs_State ToBuild2)
1279 {
1280   //modified by IFV for treating shell
1281   Standard_Boolean tosplit = Standard_False;
1282   Standard_Boolean IsShell = (S1oriented.ShapeType() == TopAbs_SHELL);
1283   if(IsShell) {
1284     TopExp_Explorer ex;
1285     ex.Init(S1oriented, TopAbs_FACE);
1286     for (; ex.More(); ex.Next()) {
1287       const TopoDS_Shape& sh = ex.Current();
1288       tosplit = ToSplit(sh,ToBuild1);
1289       if(tosplit) break;
1290     }
1291   }
1292   else tosplit = ToSplit(S1oriented,ToBuild1);
1293 
1294   if ( ! tosplit ) return;
1295   // end IFV
1296 
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;
1301 
1302   // work on a FORWARD solid <S1forward>
1303   TopoDS_Shape S1forward = S1oriented;
1304   myBuildTool.Orientation(S1forward,TopAbs_FORWARD);
1305 
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();
1312 
1313   if (!n2) RevOri1 = Standard_False;
1314   if (!n1) RevOri2 = Standard_False;
1315 
1316   // Create a face set <FS> connected by edges
1317   // -----------------------------------------
1318   TopOpeBRepBuild_ShellFaceSet SFS;
1319 
1320 #ifdef OCCT_DEBUG
1321   Standard_Boolean tSPS = TopOpeBRepBuild_GettraceSPS();
1322 //  Standard_Integer iSolid = myDataStructure->Shape(S1oriented);
1323   if (tSPS) {
1324     std::cout<<std::endl;
1325     GdumpSHASTA(S1oriented,ToBuild1,"___ SplitSolid ");
1326     GdumpSAMDOM(LS1, (char *) "1 : ");
1327     GdumpSAMDOM(LS2, (char *) "2 : ");
1328   }
1329   SFS.DEBNumber(GdumpSHASETindex());
1330 #endif
1331 
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);
1337   }
1338 
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);
1344   }
1345 
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);
1357 
1358 #ifdef OCCT_DEBUG
1359 	if (tSPS){
1360           TCollection_AsciiString ss("--- SplitSolid ");
1361           ss = ss + SFS.DEBNumber() + " AddElement SFS+ face ";
1362 	  GdumpSHA(aFace,(Standard_Address)ss.ToCString());
1363 	  std::cout<<" ";TopAbs::Print(ToBuild1,std::cout)<<" : 1 face ";
1364 	  TopAbs::Print(ori,std::cout); std::cout<<std::endl;
1365 	}
1366 #endif
1367 	SFS.AddElement(aFace);
1368       }
1369     }
1370   }
1371 
1372   // Create a Solid Builder SOBU
1373   // -------------------------
1374   TopOpeBRepBuild_SolidBuilder SOBU(SFS);
1375 
1376   // Build the new solids on S1
1377   // --------------------------
1378   TopTools_ListOfShape& SolidList = ChangeMerged(S1oriented,ToBuild1);
1379   if(IsShell)
1380     MakeShells(SOBU,SolidList);
1381   else
1382     MakeSolids(SOBU,SolidList);
1383 
1384   // connect list of new solids <SolidList> as solids built on LS1 solids
1385   // --------------------------------------------------------------------
1386 
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;
1392 
1393   }
1394 
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;
1402   }
1403 
1404 } // SplitSolid
1405 
FUN_touched(const TopOpeBRepDS_DataStructure & BDS,const TopoDS_Edge & EOR)1406 static Standard_Boolean FUN_touched(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& EOR)
1407 {
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);
1412 }
1413 
1414 //=======================================================================
1415 //function : SplitShapes
1416 //purpose  :
1417 //=======================================================================
SplitShapes(TopOpeBRepTool_ShapeExplorer & Ex,const TopAbs_State ToBuild1,const TopAbs_State ToBuild2,TopOpeBRepBuild_ShapeSet & aSet,const Standard_Boolean RevOri)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)
1423 {
1424   TopoDS_Shape aShape;
1425   TopAbs_Orientation newori;
1426 
1427   for (; Ex.More(); Ex.Next()) {
1428     aShape = Ex.Current();
1429 
1430     // compute new orientation <newori> to give to the new shapes
1431     newori = Orient(myBuildTool.Orientation(aShape),RevOri);
1432 
1433     TopAbs_ShapeEnum t = aShape.ShapeType();
1434 
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);
1439     else continue;
1440 
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;
1453       }
1454       else {
1455 	It.Initialize(LS);
1456       }
1457       //----------------------- IFV
1458       for (; It.More(); It.Next()) {
1459 	newShape = It.Value();
1460 	myBuildTool.Orientation(newShape,newori);
1461 #ifdef OCCT_DEBUG
1462 //	TopAbs_ShapeEnum tns = TopType(newShape);
1463 #endif
1464 	//----------------------- IFV
1465 	if(IsLSon) {
1466 	  Standard_Boolean add = Standard_True;
1467 	  if ( !myListOfFace.IsEmpty()) { // 2d pur
1468 	    add = KeepShape(newShape,myListOfFace,ToBuild1);
1469 	  }
1470 	  if(add) aSet.AddStartElement(newShape);
1471 
1472 	}
1473 	else {
1474 	//----------------------- IFV
1475 	  aSet.AddStartElement(newShape);
1476 	}
1477       }
1478     }
1479     else {
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));
1487 
1488       testkeep = isedge && hs && (!hg);
1489 
1490       // xpu010399 : USA60299 (!hs)&&(!hg), but vertex on bound is touched (v7)
1491       //             -> testkeep
1492       Standard_Boolean istouched = isedge && (!hs) && (!hg);
1493       if (istouched) istouched = FUN_touched(myDataStructure->DS(),TopoDS::Edge(aShape));
1494       testkeep = testkeep || istouched;
1495 
1496       if (testkeep) {
1497 	if ( !myListOfFace.IsEmpty()) { // 2d pur
1498 	  Standard_Boolean keep = KeepShape(aShape,myListOfFace,ToBuild1);
1499 	  add = keep;
1500 	}
1501 	else { // 3d
1502 	  // on classifie en solide uniqt si
1503 	  // E dans la DS et E a ete purgee de ses interfs car en bout
1504 	  TopoDS_Shape sol;
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);
1519 	    }
1520 	    else {
1521 	      throw Standard_ProgramError("SplitShapes no 3D curve on edge");
1522 	      // NYI pas de courbe 3d : prendre un point sur (courbe 2d,face)
1523 	    }
1524 	  }
1525 	  else { //  sol.IsNull
1526 	    add = Standard_True;
1527 	  }
1528 	}
1529       }
1530       if ( add ) {
1531 	myBuildTool.Orientation(aShape,newori);
1532 	aSet.AddElement(aShape);
1533       }
1534     }
1535 
1536   } // Ex.More
1537 
1538 } // SplitShapes
1539 
1540 //=======================================================================
1541 //function : FillShape
1542 //purpose  :
1543 //=======================================================================
FillShape(const TopoDS_Shape & S1,const TopAbs_State ToBuild1,const TopTools_ListOfShape & LS2,const TopAbs_State ToBuild2,TopOpeBRepBuild_ShapeSet & aSet,const Standard_Boolean In_RevOri)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)
1550 {
1551   Standard_Boolean RevOri = In_RevOri;
1552   TopAbs_ShapeEnum t = S1.ShapeType();
1553   TopAbs_ShapeEnum t1=TopAbs_COMPOUND,t11=TopAbs_COMPOUND;
1554 
1555   if      (t == TopAbs_FACE )  {
1556     t1 = TopAbs_WIRE;
1557     t11 = TopAbs_EDGE;
1558   }
1559   else if (t == TopAbs_SOLID || t == TopAbs_SHELL) {
1560     t1 = TopAbs_SHELL;
1561     t11 = TopAbs_FACE;
1562   }
1563 
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);
1567   if (hsd) {
1568     TopOpeBRepDS_Config ssc = myDataStructure->SameDomainOrientation(S1);
1569     if ( ssc == TopOpeBRepDS_DIFFORIENTED ) {
1570       RevOri = ! RevOri;
1571 #ifdef OCCT_DEBUG
1572 //      Standard_Integer iFace = myDataStructure->Shape(S1);
1573 //      std::cout<<std::endl<<"********** ";
1574 //      std::cout<<"retournement d'orientation de ";TopAbs::Print(t,std::cout);
1575 //      std::cout<<" "<<iFace<<std::endl;
1576 #endif
1577     }
1578   }
1579 
1580   // work on a FORWARD shape <aShape>
1581   TopoDS_Shape aShape = S1;
1582   myBuildTool.Orientation(aShape,TopAbs_FORWARD);
1583 
1584   TopoDS_Shape aSubShape;
1585   TopAbs_Orientation newori;
1586 
1587   // Explore the SubShapes of type <t1>
1588   for (TopOpeBRepTool_ShapeExplorer ex1(aShape,t1); ex1.More(); ex1.Next()) {
1589     aSubShape = ex1.Current();
1590 
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);
1594       if (keep) {
1595 	newori = Orient(myBuildTool.Orientation(aSubShape),RevOri);
1596 	myBuildTool.Orientation(aSubShape,newori);
1597 	aSet.AddShape(aSubShape);
1598       }
1599     }
1600     else {
1601       // SubShape has geometry : split the <t11> SubShapes of the SubShape
1602       TopOpeBRepTool_ShapeExplorer ex11(aSubShape,t11);
1603       SplitShapes(ex11,ToBuild1,ToBuild2,aSet,RevOri);
1604     }
1605   } // exploration ot SubShapes of type <t1> of shape <S1>
1606 
1607 } // FillShape
1608 
1609 
1610 //=======================================================================
1611 //function : FillFace
1612 //purpose  :
1613 //=======================================================================
FillFace(const TopoDS_Shape & F1,const TopAbs_State ToBuild1,const TopTools_ListOfShape & LF2,const TopAbs_State ToBuild2,TopOpeBRepBuild_WireEdgeSet & WES,const Standard_Boolean RevOri)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)
1620 {
1621 #ifdef OCCT_DEBUG
1622   Standard_Boolean tSPF = TopOpeBRepBuild_GettraceSPF();
1623 //  Standard_Integer iFace = myDataStructure->Shape(F1);
1624   if(tSPF){std::cout<<std::endl;}
1625   if(tSPF){GdumpSHASTA(F1,ToBuild1,"=-= FillFace ");}
1626 #endif
1627   myListOfFace = LF2;
1628   FillShape(F1,ToBuild1,LF2,ToBuild2,WES,RevOri);
1629   myListOfFace.Clear();
1630 } // FillFace
1631 
1632 
1633 //=======================================================================
1634 //function : FillSolid
1635 //purpose  : load shells and faces from the solid in the ShellFaceSet <aSet>
1636 //=======================================================================
FillSolid(const TopoDS_Shape & S1,const TopAbs_State ToBuild1,const TopTools_ListOfShape & LS2,const TopAbs_State ToBuild2,TopOpeBRepBuild_ShapeSet & aSet,const Standard_Boolean RevOri)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)
1643 {
1644   FillShape(S1,ToBuild1,LS2,ToBuild2,aSet,RevOri);
1645 } // FillSolid
1646 
1647 
1648 //=======================================================================
1649 //function : FillVertexSet
1650 //purpose  : private
1651 //=======================================================================
FillVertexSet(TopOpeBRepDS_PointIterator & IT,const TopAbs_State ToBuild,TopOpeBRepBuild_PaveSet & PVS) const1652 void TopOpeBRepBuild_Builder::FillVertexSet(TopOpeBRepDS_PointIterator& IT,
1653 					    const TopAbs_State ToBuild,
1654 					    TopOpeBRepBuild_PaveSet& PVS) const
1655 {
1656   for (; IT.More(); IT.Next()) {
1657     FillVertexSetOnValue(IT,ToBuild,PVS);
1658   }
1659 }
1660 
1661 
1662 //=======================================================================
1663 //function : FillVertexSetOnValue
1664 //purpose  : private
1665 //=======================================================================
FillVertexSetOnValue(const TopOpeBRepDS_PointIterator & IT,const TopAbs_State ToBuild,TopOpeBRepBuild_PaveSet & PVS) const1666 void TopOpeBRepBuild_Builder::FillVertexSetOnValue
1667 (const TopOpeBRepDS_PointIterator& IT,
1668  const TopAbs_State ToBuild,
1669  TopOpeBRepBuild_PaveSet& PVS) const
1670 {
1671   TopoDS_Shape V;
1672 
1673   // ind = index of new point or existing vertex
1674   Standard_Integer ind = IT.Current();
1675   Standard_Boolean ispoint  = IT.IsPoint();
1676   //**!
1677   //if (ispoint) V = NewVertex(ind);
1678   if (ispoint && ind <= myDataStructure->NbPoints()) V = NewVertex(ind);
1679   //**!
1680   else         V = myDataStructure->Shape(ind);
1681   Standard_Real      par = IT.Parameter();
1682   TopAbs_Orientation ori = IT.Orientation(ToBuild);
1683 
1684   Standard_Boolean keep = Standard_True;
1685   //    if (ori==TopAbs_EXTERNAL || ori==TopAbs_INTERNAL) keep = Standard_False;
1686 
1687   if ( keep ) {
1688     myBuildTool.Orientation(V,ori);
1689     Handle(TopOpeBRepBuild_Pave) PV = new TopOpeBRepBuild_Pave(V,par,Standard_False);
1690     PVS.Append(PV);
1691   }
1692 
1693 #ifdef OCCT_DEBUG
1694   const TopoDS_Edge& EDEB = PVS.Edge();
1695   Standard_Integer iE; Standard_Boolean tSPS = GtraceSPS(EDEB,iE);
1696   if (tSPS) {
1697     if (keep) std::cout<<"+"; else std::cout<<"-";
1698     if (ispoint) std::cout<<" PDS "; else std::cout<<" VDS ";
1699     std::cout<<ind<<" : "; GdumpORIPARPNT(ori,par,BRep_Tool::Pnt(TopoDS::Vertex(V)));
1700     std::cout<<std::endl;
1701   }
1702 #endif
1703 }
1704