1 // Created on: 1996-03-07
2 // Created by: Jean Yves LEBEY
3 // Copyright (c) 1996-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 <gp_Pnt.hxx>
19 #include <Standard_NoSuchObject.hxx>
20 #include <TCollection_AsciiString.hxx>
21 #include <TopExp.hxx>
22 #include <TopoDS.hxx>
23 #include <TopoDS_Edge.hxx>
24 #include <TopoDS_Face.hxx>
25 #include <TopoDS_Shape.hxx>
26 #include <TopoDS_Vertex.hxx>
27 #include <TopOpeBRepBuild_Builder.hxx>
28 #include <TopOpeBRepBuild_define.hxx>
29 #include <TopOpeBRepBuild_EdgeBuilder.hxx>
30 #include <TopOpeBRepBuild_FaceBuilder.hxx>
31 #include <TopOpeBRepBuild_GTopo.hxx>
32 #include <TopOpeBRepBuild_HBuilder.hxx>
33 #include <TopOpeBRepBuild_PaveSet.hxx>
34 #include <TopOpeBRepBuild_ShapeSet.hxx>
35 #include <TopOpeBRepBuild_ShellFaceSet.hxx>
36 #include <TopOpeBRepBuild_SolidBuilder.hxx>
37 #include <TopOpeBRepBuild_WireEdgeSet.hxx>
38 #include <TopOpeBRepDS_BuildTool.hxx>
39 #include <TopOpeBRepDS_CurveIterator.hxx>
40 #include <TopOpeBRepDS_HDataStructure.hxx>
41 #include <TopOpeBRepDS_PointIterator.hxx>
42 #include <TopOpeBRepDS_SurfaceIterator.hxx>
43 #include <TopOpeBRepTool_ShapeExplorer.hxx>
44 
45 #ifdef OCCT_DEBUG
46 extern Standard_Boolean TopOpeBRepBuild_GetcontextSPEON();
47 #endif
48 
49 //=======================================================================
50 //function : GToSplit
51 //purpose  :
52 //=======================================================================
GToSplit(const TopoDS_Shape & S,const TopAbs_State TB) const53 Standard_Boolean TopOpeBRepBuild_Builder::GToSplit(const TopoDS_Shape& S,const TopAbs_State TB) const
54 {
55   Standard_Boolean issplit = IsSplit(S,TB);
56   Standard_Boolean facshap = myDataStructure->HasShape(S) && (S.ShapeType() == TopAbs_FACE);
57   Standard_Boolean hasgeom = myDataStructure->HasGeometry(S);
58   Standard_Boolean hassame = myDataStructure->HasSameDomain(S);
59   Standard_Boolean tosplit = (!issplit) && (facshap || hasgeom || hassame);
60 
61 #ifdef OCCT_DEBUG
62   Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
63   if (tSPS) {
64     std::cout<<"GToSplit ";GdumpSHA(S);std::cout<<" ";TopAbs::Print(TB,std::cout);
65     std::cout<<" "<<tosplit<<" : !issplit "<<(!issplit);
66     std::cout<<" && (facshap || hasgeom || hassame) ";
67     std::cout<<"("<<facshap<<" || "<<hasgeom<<" || "<<hassame<<")"<<std::endl;
68     std::cout.flush();
69   }
70 #endif
71 
72 #ifdef OCCT_DEBUG
73   if (TopOpeBRepBuild_GetcontextSPEON()) { //CONTEXT
74     tSPS = Standard_True; //CONTEXT
75     Standard_Boolean hasON = Standard_False; //CONTEXT
76     Standard_Boolean isE = (S.ShapeType() == TopAbs_EDGE); //CONTEXT
77     if (isE) { //CONTEXT
78       const TopoDS_Edge& E = TopoDS::Edge(S); //CONTEXT
79       Standard_Boolean issE = myDataStructure->DS().IsSectionEdge(E); //CONTEXT
80       if (issE) { //CONTEXT
81 	Standard_Boolean issplitON = IsSplit(E,TopAbs_ON); //CONTEXT
82 	if (issplitON) { //CONTEXT
83 	  Standard_Integer n = Splits(E,TopAbs_ON).Extent(); //CONTEXT
84 	  hasON = (n>0); //CONTEXT
85 	} //CONTEXT
86       } //CONTEXT
87     } //CONTEXT
88     Standard_Boolean tosplitH = tosplit || hasON; //CONTEXT
89     if(tSPS){std::cout<<"GToSplit context SPEON";} //CONTEXT
90     if(tSPS){std::cout<<" "<<tosplitH<<" : tosplit "<<tosplit;} //CONTEXT
91     if(tSPS){std::cout<<" || hasON "<<hasON<<std::endl;} //CONTEXT
92   } //CONTEXT
93 #endif
94 
95   return tosplit;
96 } // GToSplit
97 
98 
99 //=======================================================================
100 //function : GToMerge
101 //purpose  :
102 //=======================================================================
GToMerge(const TopoDS_Shape & S) const103 Standard_Boolean TopOpeBRepBuild_Builder::GToMerge(const TopoDS_Shape& S) const
104 {
105   TopAbs_State TB = TopAbs_IN;
106 
107   Standard_Boolean ismerged = IsMerged(S,TB);
108   Standard_Boolean hassame = myDataStructure->HasSameDomain(S);
109   Standard_Boolean tomerge = (!ismerged && hassame);
110 
111 #ifdef OCCT_DEBUG
112   Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS);
113   if(tSPS){std::cout<<"GToMerge ";GdumpSHA(S);std::cout<<" ";TopAbs::Print(TB,std::cout);}
114   if(tSPS){std::cout<<" "<<tomerge<<" : !ismerged "<<(!ismerged)<<" && hassame "<<hassame<<std::endl;}
115 #endif
116 
117   return tomerge;
118 } // GToMerge
119 
120 //=======================================================================
121 //function : GTakeCommonOfSame
122 //purpose  :
123 //=======================================================================
GTakeCommonOfSame(const TopOpeBRepBuild_GTopo & G)124 Standard_Boolean TopOpeBRepBuild_Builder::GTakeCommonOfSame(const TopOpeBRepBuild_GTopo& G)
125 {
126   TopAbs_State t1,t2; G.StatesON(t1,t2);
127   Standard_Boolean sam = Standard_False;
128   if      (t1 == TopAbs_OUT && t2 == TopAbs_OUT) sam = Standard_True;
129   else if (t1 == TopAbs_OUT && t2 == TopAbs_IN ) sam = Standard_False;
130   else if (t1 == TopAbs_IN  && t2 == TopAbs_OUT) sam = Standard_False;
131   else if (t1 == TopAbs_IN  && t2 == TopAbs_IN ) sam = Standard_True;
132 
133   return sam;
134 }
135 
136 //=======================================================================
137 //function : GTakeCommonOfDiff
138 //purpose  :
139 //=======================================================================
GTakeCommonOfDiff(const TopOpeBRepBuild_GTopo & G)140 Standard_Boolean TopOpeBRepBuild_Builder::GTakeCommonOfDiff(const TopOpeBRepBuild_GTopo& G)
141 {
142   TopAbs_State t1,t2; G.StatesON(t1,t2);
143   Standard_Boolean dif = Standard_False;
144   if      (t1 == TopAbs_OUT && t2 == TopAbs_OUT) dif = Standard_False;
145   else if (t1 == TopAbs_OUT && t2 == TopAbs_IN ) dif = Standard_True;
146   else if (t1 == TopAbs_IN  && t2 == TopAbs_OUT) dif = Standard_True;
147   else if (t1 == TopAbs_IN  && t2 == TopAbs_IN ) dif = Standard_False;
148 
149   return dif;
150 }
151 
152 //=======================================================================
153 //function : GFindSamDom
154 //purpose  : complete the lists L1,L2 with the shapes of the DS
155 //           having same domain
156 //=======================================================================
GFindSamDom(const TopoDS_Shape & S,TopTools_ListOfShape & L1,TopTools_ListOfShape & L2) const157 void TopOpeBRepBuild_Builder::GFindSamDom(const TopoDS_Shape& S,TopTools_ListOfShape& L1,TopTools_ListOfShape& L2) const
158 {
159   L1.Clear(); L2.Clear();
160   L1.Append(S);
161   GFindSamDom(L1,L2);
162 }
163 
164 //=======================================================================
165 //function : GFindSamDom
166 //purpose  : complete the lists L1,L2 with the shapes of the DS
167 //           having same domain
168 //=======================================================================
GFindSamDom(TopTools_ListOfShape & L1,TopTools_ListOfShape & L2) const169 void TopOpeBRepBuild_Builder::GFindSamDom(TopTools_ListOfShape& L1,TopTools_ListOfShape& L2) const
170 {
171   Standard_Integer i;
172   Standard_Integer nl1 = L1.Extent(), nl2 = L2.Extent();
173 
174   while ( nl1 > 0 || nl2 > 0 )  {
175 
176     TopTools_ListIteratorOfListOfShape it1(L1);
177     for (i=1 ; i<=nl1; i++) {
178       const TopoDS_Shape& S1 = it1.Value();
179 #ifdef OCCT_DEBUG
180 //      Standard_Integer iS1 = myDataStructure->Shape(S1);
181 #endif
182       TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S1));
183       for (; itsd.More(); itsd.Next() ) {
184 	const TopoDS_Shape& S2 = itsd.Value();
185 #ifdef OCCT_DEBUG
186 //	Standard_Integer iS2 = myDataStructure->Shape(S2);
187 #endif
188 	Standard_Boolean found = GContains(S2,L2);
189 	if ( ! found ) {
190 	  L2.Prepend(S2);
191 	  nl2++;
192 	}
193       }
194       it1.Next();
195     }
196     nl1 = 0;
197 
198     TopTools_ListIteratorOfListOfShape it2(L2);
199     for (i=1 ; i<=nl2; i++) {
200       const TopoDS_Shape& S2 = it2.Value();
201 #ifdef OCCT_DEBUG
202 //      Standard_Integer iS2 = myDataStructure->Shape(S2);
203 #endif
204       TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S2));
205       for (; itsd.More(); itsd.Next() ) {
206 	const TopoDS_Shape& S1 = itsd.Value();
207 #ifdef OCCT_DEBUG
208 //	Standard_Integer iS1 = myDataStructure->Shape(S1);
209 #endif
210 	Standard_Boolean found = GContains(S1,L1);
211 	if ( ! found ) {
212 	  L1.Prepend(S1);
213 	  nl1++;
214 	}
215       }
216       it2.Next();
217     }
218     nl2 = 0;
219 
220   }
221 
222 }
223 
224 //=======================================================================
225 //function : GFindSamDomSODO
226 //purpose  :
227 //=======================================================================
GFindSamDomSODO(const TopoDS_Shape & S,TopTools_ListOfShape & LSO,TopTools_ListOfShape & LDO) const228 void TopOpeBRepBuild_Builder::GFindSamDomSODO(const TopoDS_Shape& S,TopTools_ListOfShape& LSO,TopTools_ListOfShape& LDO) const
229 {
230   LSO.Clear();
231   LDO.Clear();
232   LSO.Append(S);
233   GFindSamDomSODO(LSO,LDO);
234 }
235 
236 //=======================================================================
237 //function : GFindSamDomSODO
238 //purpose  :
239 //=======================================================================
GFindSamDomSODO(TopTools_ListOfShape & LSO,TopTools_ListOfShape & LDO) const240 void TopOpeBRepBuild_Builder::GFindSamDomSODO(TopTools_ListOfShape& LSO,TopTools_ListOfShape& LDO) const
241 {
242   TopTools_ListIteratorOfListOfShape it;
243   it.Initialize(LSO);
244   if ( ! it.More() ) return;
245   const TopoDS_Shape& sref = it.Value();
246 #ifdef OCCT_DEBUG
247 //  Standard_Integer  iref = myDataStructure->SameDomainReference(sref);
248 #endif
249   TopOpeBRepDS_Config oref = myDataStructure->SameDomainOrientation(sref);
250 
251   GFindSamDom(LSO,LDO);
252 
253 #ifdef OCCT_DEBUG
254   Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(sref,iS);
255   if(tSPS) {
256     TCollection_AsciiString ss("GFindSamDom result on ");
257     GdumpSHA(sref,(Standard_Address)ss.ToCString());std::cout<<std::endl;
258     GdumpSAMDOM(LSO, (char *) "L1 : ");
259     GdumpSAMDOM(LDO, (char *) "L2 : ");
260   }
261 #endif
262 
263   TopTools_ListOfShape LLSO,LLDO;
264 
265   for (it.Initialize(LSO); it.More(); it.Next() ) {
266     const TopoDS_Shape& s = it.Value();
267     TopOpeBRepDS_Config o = myDataStructure->SameDomainOrientation(s);
268 #ifdef OCCT_DEBUG
269 //    Standard_Integer iS = myDataStructure->Shape(s);
270 #endif
271     if      ( o == oref && !GContains(s,LLSO) ) LLSO.Append(s);
272     else if ( o != oref && !GContains(s,LLDO) ) LLDO.Append(s);
273   }
274 
275   for (it.Initialize(LDO); it.More(); it.Next() ) {
276     const TopoDS_Shape& s = it.Value();
277     TopOpeBRepDS_Config o = myDataStructure->SameDomainOrientation(s);
278 #ifdef OCCT_DEBUG
279 //    Standard_Integer iS = myDataStructure->Shape(s);
280 #endif
281     if      ( o == oref && !GContains(s,LLSO) ) LLSO.Append(s);
282     else if ( o != oref && !GContains(s,LLDO) ) LLDO.Append(s);
283   }
284 
285   LSO = LLSO;
286   LDO = LLDO;
287 }
288 
289 //=======================================================================
290 //function : GMapShapes
291 //purpose  :
292 //=======================================================================
GMapShapes(const TopoDS_Shape & S1,const TopoDS_Shape & S2)293 void TopOpeBRepBuild_Builder::GMapShapes(const TopoDS_Shape& S1,const TopoDS_Shape& S2)
294 {
295   Standard_Boolean S1null = S1.IsNull();
296   Standard_Boolean S2null = S2.IsNull();
297   GClearMaps();
298   if ( ! S1null ) TopExp::MapShapes(S1,myMAP1);
299   if ( ! S2null ) TopExp::MapShapes(S2,myMAP2);
300 }
301 
302 //=======================================================================
303 //function : GClearMaps
304 //purpose  :
305 //=======================================================================
GClearMaps()306 void TopOpeBRepBuild_Builder::GClearMaps()
307 {
308   myMAP1.Clear();
309   myMAP2.Clear();
310 }
311 
312 //=======================================================================
313 //function : GFindSameRank
314 //purpose  :
315 //=======================================================================
GFindSameRank(const TopTools_ListOfShape & L1,const Standard_Integer Rank,TopTools_ListOfShape & L2) const316 void TopOpeBRepBuild_Builder::GFindSameRank
317 (const TopTools_ListOfShape& L1,const Standard_Integer Rank,TopTools_ListOfShape& L2) const
318 {
319   for (  TopTools_ListIteratorOfListOfShape it1(L1); it1.More(); it1.Next() ) {
320     const TopoDS_Shape& s = it1.Value();
321 #ifdef OCCT_DEBUG
322 //    Standard_Integer iS = myDataStructure->Shape(s);
323 #endif
324     Standard_Integer r = GShapeRank(s);
325     if ( r == Rank && !GContains(s,L2) ) {
326       L2.Append(s);
327     }
328   }
329 }
330 
331 //=======================================================================
332 //function : GShapeRank
333 //purpose  :
334 //=======================================================================
GShapeRank(const TopoDS_Shape & S) const335 Standard_Integer TopOpeBRepBuild_Builder::GShapeRank(const TopoDS_Shape& S) const
336 {
337   Standard_Boolean isof1 = GIsShapeOf(S,1);
338   Standard_Boolean isof2 = GIsShapeOf(S,2);
339   Standard_Integer ancetre = (isof1 || isof2) ? ((isof1) ? 1 : 2) : 0;
340   return ancetre;
341 }
342 
343 //=======================================================================
344 //function : GIsShapeOf
345 //purpose  :
346 //=======================================================================
GIsShapeOf(const TopoDS_Shape & S,const Standard_Integer I) const347 Standard_Boolean TopOpeBRepBuild_Builder::GIsShapeOf(const TopoDS_Shape& S,const Standard_Integer I) const
348 {
349   if (S.IsNull()) return Standard_False;
350   Standard_Boolean b = Standard_False;
351   if      (I == 1) b = myMAP1.Contains(S);
352   else if (I == 2) b = myMAP2.Contains(S);
353   return b;
354 }
355 
356 //=======================================================================
357 //function : GContains
358 //purpose  : returns True if S is in the list L.
359 //=======================================================================
GContains(const TopoDS_Shape & S,const TopTools_ListOfShape & L)360 Standard_Boolean TopOpeBRepBuild_Builder::GContains(const TopoDS_Shape& S,const TopTools_ListOfShape& L)
361 {
362   for (TopTools_ListIteratorOfListOfShape it(L); it.More(); it.Next() ) {
363     const TopoDS_Shape& SL = it.Value();
364     Standard_Boolean issame = SL.IsSame(S);
365     if ( issame ) return Standard_True;
366   }
367   return Standard_False;
368 }
369 
370 
371 //=======================================================================
372 //function : GCopyList
373 //purpose  :
374 // copy des elements [i1..i2] de Lin dans Lou. 1er element de Lin = index 1
375 //=======================================================================
GCopyList(const TopTools_ListOfShape & Lin,const Standard_Integer I1,const Standard_Integer I2,TopTools_ListOfShape & Lou)376 void TopOpeBRepBuild_Builder::GCopyList(const TopTools_ListOfShape& Lin,const Standard_Integer I1,const Standard_Integer I2,TopTools_ListOfShape& Lou)
377 {
378   TopTools_ListIteratorOfListOfShape it(Lin);
379   Standard_Integer nadd = 0;
380   for ( Standard_Integer i = 1; it.More(); it.Next(),i++ ) {
381     const TopoDS_Shape& EL = it.Value();
382     if ( i >= I1 && i <= I2 ) {
383       Lou.Append(EL);
384       nadd++;
385     }
386   }
387 }
388 
389 
390 //=======================================================================
391 //function : GCopyList
392 //purpose  :
393 // copy de Lin dans Lou
394 //=======================================================================
GCopyList(const TopTools_ListOfShape & Lin,TopTools_ListOfShape & Lou)395 void TopOpeBRepBuild_Builder::GCopyList(const TopTools_ListOfShape& Lin,TopTools_ListOfShape& Lou)
396 {
397   const Standard_Integer I1 = 1;
398   const Standard_Integer I2 = Lin.Extent();
399   GCopyList(Lin,I1,I2,Lou);
400 }
401