b311480e |
1 | // Created on: 1993-06-14 |
2 | // Created by: Jean Yves LEBEY |
3 | // Copyright (c) 1993-1999 Matra Datavision |
973c2be1 |
4 | // Copyright (c) 1999-2014 OPEN CASCADE SAS |
b311480e |
5 | // |
973c2be1 |
6 | // This file is part of Open CASCADE Technology software library. |
b311480e |
7 | // |
d5f74e42 |
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 |
973c2be1 |
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. |
b311480e |
13 | // |
973c2be1 |
14 | // Alternatively, this file may be used under the terms of Open CASCADE |
15 | // commercial license or contractual agreement. |
7fd59977 |
16 | |
42cf5bc1 |
17 | |
18 | #include <BRep_Builder.hxx> |
19 | #include <BRep_Tool.hxx> |
7fd59977 |
20 | #include <BRepClass3d_SolidClassifier.hxx> |
42cf5bc1 |
21 | #include <Geom2d_Curve.hxx> |
22 | #include <Geom_Curve.hxx> |
7fd59977 |
23 | #include <gp_Pnt.hxx> |
24 | #include <Precision.hxx> |
42cf5bc1 |
25 | #include <Standard_NoSuchObject.hxx> |
896faa72 |
26 | #include <Standard_ProgramError.hxx> |
42cf5bc1 |
27 | #include <TCollection_AsciiString.hxx> |
28 | #include <TopExp.hxx> |
29 | #include <TopoDS.hxx> |
7fd59977 |
30 | #include <TopoDS_Compound.hxx> |
42cf5bc1 |
31 | #include <TopoDS_Edge.hxx> |
32 | #include <TopoDS_Face.hxx> |
33 | #include <TopoDS_Shape.hxx> |
7fd59977 |
34 | #include <TopoDS_Shell.hxx> |
42cf5bc1 |
35 | #include <TopoDS_Vertex.hxx> |
7fd59977 |
36 | #include <TopoDS_Wire.hxx> |
42cf5bc1 |
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> |
7fd59977 |
55 | #include <TopOpeBRepDS_Filter.hxx> |
42cf5bc1 |
56 | #include <TopOpeBRepDS_HDataStructure.hxx> |
57 | #include <TopOpeBRepDS_ListOfShapeOn1State.hxx> |
58 | #include <TopOpeBRepDS_Point.hxx> |
59 | #include <TopOpeBRepDS_PointIterator.hxx> |
7fd59977 |
60 | #include <TopOpeBRepDS_Reducer.hxx> |
42cf5bc1 |
61 | #include <TopOpeBRepDS_Surface.hxx> |
62 | #include <TopOpeBRepDS_SurfaceIterator.hxx> |
63 | #include <TopOpeBRepTool_ShapeExplorer.hxx> |
7fd59977 |
64 | |
0797d9d3 |
65 | #ifdef OCCT_DEBUG |
1d0a9d4d |
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(); |
7fd59977 |
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;} |
896faa72 |
73 | Standard_EXPORT void debspf(const Standard_Integer i) {cout<<"++ debspf"<<i<<endl;} |
7fd59977 |
74 | #endif |
75 | |
76 | static Standard_Integer STATIC_SOLIDINDEX = 0; |
7fd59977 |
77 | |
78 | //======================================================================= |
79 | //function : TopOpeBRepBuild_Builder |
80 | //purpose : |
81 | //======================================================================= |
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 | { |
7fd59977 |
90 | InitSection(); |
91 | } |
92 | |
93 | //modified by NIZHNY-MZV Sat May 6 10:04:49 2000 |
94 | //======================================================================= |
e6f550da |
95 | //function : ~TopOpeBRepBuild_Builder |
7fd59977 |
96 | //purpose : virtual destructor |
97 | //======================================================================= |
e6f550da |
98 | TopOpeBRepBuild_Builder::~TopOpeBRepBuild_Builder() |
7fd59977 |
99 | { |
100 | } |
101 | |
102 | //======================================================================= |
103 | //function : ChangeBuildTool |
104 | //purpose : |
105 | //======================================================================= |
106 | TopOpeBRepDS_BuildTool& TopOpeBRepBuild_Builder::ChangeBuildTool() |
107 | { |
108 | return myBuildTool; |
109 | } |
110 | |
111 | //======================================================================= |
112 | //function : BuildTool |
113 | //purpose : |
114 | //======================================================================= |
115 | const TopOpeBRepDS_BuildTool& TopOpeBRepBuild_Builder::BuildTool() const |
116 | { |
117 | return myBuildTool; |
118 | } |
119 | |
120 | //======================================================================= |
121 | //function : DataStructure |
122 | //purpose : |
123 | //======================================================================= |
124 | Handle(TopOpeBRepDS_HDataStructure) TopOpeBRepBuild_Builder::DataStructure() const |
125 | { |
126 | return myDataStructure; |
127 | } |
128 | |
129 | //======================================================================= |
130 | //function : Perform |
131 | //purpose : |
132 | //======================================================================= |
133 | void TopOpeBRepBuild_Builder::Perform(const Handle(TopOpeBRepDS_HDataStructure)& HDS) |
134 | { |
0797d9d3 |
135 | #ifdef OCCT_DEBUG |
7fd59977 |
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 | //======================================================================= |
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 | //======================================================================= |
168 | 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(); |
7fd59977 |
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 | //======================================================================= |
195 | void TopOpeBRepBuild_Builder::Clear() |
196 | { |
197 | const TopOpeBRepDS_DataStructure& BDS = myDataStructure->DS(); |
198 | TopOpeBRepDS_DataMapIteratorOfDataMapOfShapeListOfShapeOn1State it; |
199 | for (it.Initialize(mySplitOUT); it.More(); it.Next()) { |
200 | const TopoDS_Shape& e = it.Key(); |
201 | if ( e.ShapeType() == TopAbs_EDGE ) { |
202 | Standard_Boolean isse = BDS.IsSectionEdge(TopoDS::Edge(e)); |
203 | if (!isse) mySplitOUT.ChangeFind(e).Clear(); |
204 | } |
205 | } |
206 | for (it.Initialize(mySplitIN); it.More(); it.Next()) { |
207 | const TopoDS_Shape& e = it.Key(); |
208 | if ( e.ShapeType() == TopAbs_EDGE ) { |
209 | Standard_Boolean isse = BDS.IsSectionEdge(TopoDS::Edge(e)); |
210 | if (!isse) mySplitIN.ChangeFind(e).Clear(); |
211 | } |
212 | } |
213 | for (it.Initialize(mySplitON); it.More(); it.Next()) { |
214 | const TopoDS_Shape& e = it.Key(); |
215 | if ( e.ShapeType() == TopAbs_EDGE ) { |
216 | Standard_Boolean isse = BDS.IsSectionEdge(TopoDS::Edge(e)); |
217 | if (!isse) mySplitON.ChangeFind(e).Clear(); |
218 | } |
219 | } |
220 | myMergedOUT.Clear(); |
221 | myMergedIN.Clear(); |
222 | myMergedON.Clear(); |
223 | } // Clear |
224 | |
225 | //======================================================================= |
226 | //function : NewFaces |
227 | //purpose : |
228 | //======================================================================= |
229 | const TopTools_ListOfShape& TopOpeBRepBuild_Builder::NewFaces(const Standard_Integer I) const |
230 | { |
231 | const TopTools_ListOfShape& L = myNewFaces->Array1().Value(I); |
232 | return L; |
233 | } // NewFaces |
234 | |
235 | //======================================================================= |
236 | //function : ChangeNewFaces |
237 | //purpose : private |
238 | //======================================================================= |
239 | TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeNewFaces(const Standard_Integer I) |
240 | { |
241 | TopTools_ListOfShape& L = myNewFaces->ChangeArray1().ChangeValue(I); |
242 | return L; |
243 | } // ChangeNewFaces |
244 | |
245 | //======================================================================= |
246 | //function : NewEdges |
247 | //purpose : |
248 | //======================================================================= |
249 | const TopTools_ListOfShape& TopOpeBRepBuild_Builder::NewEdges(const Standard_Integer I) const |
250 | { |
251 | if ( myNewEdges.IsBound(I) ) { |
252 | return myNewEdges.Find(I); |
253 | } |
254 | else { |
255 | return myEmptyShapeList; |
256 | } |
257 | } // NewEdges |
258 | |
259 | //======================================================================= |
260 | //function : ChangeNewEdges |
261 | //purpose : private |
262 | //======================================================================= |
263 | TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeNewEdges(const Standard_Integer I) |
264 | { |
265 | if ( ! myNewEdges.IsBound(I) ) { |
266 | TopTools_ListOfShape thelist; |
267 | myNewEdges.Bind(I, thelist); |
268 | } |
269 | TopTools_ListOfShape& L = myNewEdges.ChangeFind(I); |
270 | return L; |
271 | } // ChangeNewEdges |
272 | |
273 | //======================================================================= |
274 | //function : NewVertex |
275 | //purpose : |
276 | //======================================================================= |
277 | const TopoDS_Shape& TopOpeBRepBuild_Builder::NewVertex(const Standard_Integer I) const |
278 | { |
279 | const TopoDS_Shape& V = myNewVertices->Array1().Value(I); |
280 | return V; |
281 | } // NewVertex |
282 | |
283 | //======================================================================= |
284 | //function : ChangeNewVertex |
285 | //purpose : private |
286 | //======================================================================= |
287 | TopoDS_Shape& TopOpeBRepBuild_Builder::ChangeNewVertex(const Standard_Integer I) |
288 | { |
289 | TopoDS_Shape& V = myNewVertices->ChangeArray1().ChangeValue(I); |
290 | return V; |
291 | } // ChangeNewVertex |
292 | |
293 | //======================================================================= |
294 | //function : ToSplit |
295 | //purpose : private |
296 | //======================================================================= |
297 | Standard_Boolean TopOpeBRepBuild_Builder::ToSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild) const |
298 | { |
299 | Standard_Boolean issplit = IsSplit(S,ToBuild); |
300 | Standard_Boolean hasgeom = myDataStructure->HasGeometry(S); |
301 | Standard_Boolean hassame = myDataStructure->HasSameDomain(S); |
302 | Standard_Boolean tosplit = (!issplit) && (hasgeom || hassame); |
303 | |
0797d9d3 |
304 | #ifdef OCCT_DEBUG |
7fd59977 |
305 | Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS); |
306 | if (tSPS) { |
586db386 |
307 | cout<<"tosplit "<<tosplit<<" : !issplit "<<(!issplit); |
7fd59977 |
308 | cout<<" && (hasgeom || hassame) ("<<hasgeom<<" || "<<hassame<<")"<<endl; |
309 | } |
310 | #endif |
311 | |
312 | return tosplit; |
313 | } // ToSplit |
314 | |
315 | //======================================================================= |
316 | //function : MarkSplit |
317 | //purpose : private |
318 | //======================================================================= |
319 | void TopOpeBRepBuild_Builder::MarkSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild,const Standard_Boolean Bval) |
320 | { |
321 | TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL; |
322 | if ( ToBuild == TopAbs_OUT ) p = &mySplitOUT; |
323 | else if ( ToBuild == TopAbs_IN ) p = &mySplitIN; |
324 | else if ( ToBuild == TopAbs_ON ) p = &mySplitON; |
325 | if ( p == NULL ) return; |
326 | |
327 | TopOpeBRepDS_ListOfShapeOn1State thelist; |
328 | if (!(*p).IsBound(S)) (*p).Bind(S, thelist); |
329 | TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).ChangeFind(S); |
330 | losos.Split(Bval); |
331 | |
0797d9d3 |
332 | #ifdef OCCT_DEBUG |
7fd59977 |
333 | Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS); |
334 | if(tSPS){ |
335 | GdumpSHA(S, (char *) "MarkSplit "); |
336 | cout<<" ";TopAbs::Print(ToBuild,cout);cout<<" "<<Bval<<endl; |
337 | debmarksplit(iS); |
338 | } |
339 | #endif |
340 | |
341 | } // MarkSplit |
342 | |
343 | //======================================================================= |
344 | //function : IsSplit |
345 | //purpose : |
346 | //======================================================================= |
347 | Standard_Boolean TopOpeBRepBuild_Builder::IsSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild) const |
348 | { |
349 | Standard_Boolean res = Standard_False; |
350 | const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL; |
351 | if ( ToBuild == TopAbs_OUT ) p = &mySplitOUT; |
352 | else if ( ToBuild == TopAbs_IN ) p = &mySplitIN; |
353 | else if ( ToBuild == TopAbs_ON ) p = &mySplitON; |
354 | if ( p == NULL ) return res; |
355 | |
356 | if ((*p).IsBound(S)) { |
357 | const TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).Find(S); |
358 | res = losos.IsSplit(); |
0797d9d3 |
359 | #ifdef OCCT_DEBUG |
7fd59977 |
360 | // Standard_Integer n = losos.ListOnState().Extent(); |
361 | #endif |
362 | } |
363 | return res; |
364 | } // IsSplit |
365 | |
366 | //======================================================================= |
367 | //function : Splits |
368 | //purpose : |
369 | //======================================================================= |
370 | const TopTools_ListOfShape& TopOpeBRepBuild_Builder::Splits(const TopoDS_Shape& S, const TopAbs_State ToBuild) const |
371 | { |
372 | const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL; |
373 | if ( ToBuild == TopAbs_OUT ) p = &mySplitOUT; |
374 | else if ( ToBuild == TopAbs_IN ) p = &mySplitIN; |
375 | else if ( ToBuild == TopAbs_ON ) p = &mySplitON; |
376 | if ( p == NULL ) return myEmptyShapeList; |
377 | |
378 | if ((*p).IsBound(S)) { |
379 | const TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).Find(S); |
380 | const TopTools_ListOfShape& L = losos.ListOnState(); |
381 | return L; |
382 | } |
383 | return myEmptyShapeList; |
384 | } // Splits |
385 | |
386 | //======================================================================= |
387 | //function : ChangeSplit |
388 | //purpose : private |
389 | //======================================================================= |
390 | TopTools_ListOfShape& TopOpeBRepBuild_Builder::ChangeSplit(const TopoDS_Shape& S,const TopAbs_State ToBuild) |
391 | { |
0797d9d3 |
392 | #ifdef OCCT_DEBUG |
7fd59977 |
393 | Standard_Integer iS; Standard_Boolean tSPS = GtraceSPS(S,iS); |
394 | if(tSPS){ |
395 | GdumpSHA(S, (char *) "ChangeSplit "); |
396 | cout<<" ";TopAbs::Print(ToBuild,cout);cout<<endl; |
397 | debchangesplit(iS); |
398 | } |
399 | #endif |
400 | |
401 | TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State* p = NULL; |
402 | if ( ToBuild == TopAbs_OUT ) p = &mySplitOUT; |
403 | else if ( ToBuild == TopAbs_IN ) p = &mySplitIN; |
404 | else if ( ToBuild == TopAbs_ON ) p = &mySplitON; |
405 | if ( p == NULL ) return myEmptyShapeList; |
406 | TopOpeBRepDS_ListOfShapeOn1State thelist1; |
407 | if (!(*p).IsBound(S)) (*p).Bind(S, thelist1); |
408 | TopOpeBRepDS_ListOfShapeOn1State& losos = (*p).ChangeFind(S); |
409 | TopTools_ListOfShape& L = losos.ChangeListOnState(); |
410 | return L; |
411 | } // ChangeSplit |
412 | |
413 | //======================================================================= |
414 | //function : ShapePosition |
415 | //purpose : compute position of shape S compared with the shapes of list LS |
416 | // if S is found IN any shape of LS, return IN |
417 | // else return OUT |
418 | //======================================================================= |
419 | TopAbs_State TopOpeBRepBuild_Builder::ShapePosition(const TopoDS_Shape& S, const TopTools_ListOfShape& LS) |
420 | { |
421 | TopAbs_State state = TopAbs_UNKNOWN; |
422 | |
423 | // take the edges of myEdgeAvoid as shape to avoid |
424 | // during face classification |
425 | const TopTools_ListOfShape* PLOS = &myEmptyShapeList; |
426 | TopAbs_ShapeEnum tS = S.ShapeType(); |
427 | if (tS == TopAbs_FACE) PLOS = &myEdgeAvoid; |
428 | // NYI : idem with myFaceAvoid if (tS == TopAbs_SOLID) |
429 | |
430 | for (TopTools_ListIteratorOfListOfShape Iti(LS); Iti.More(); Iti.Next()) { |
431 | const TopoDS_Shape& SLS = Iti.Value(); |
0797d9d3 |
432 | #ifdef OCCT_DEBUG |
7fd59977 |
433 | // TopAbs_ShapeEnum tSLS = SLS.ShapeType(); |
434 | #endif |
435 | state = myShapeClassifier.StateShapeShape(S,(*PLOS),SLS); |
436 | if (state != TopAbs_OUT && state != TopAbs_UNKNOWN) return state; |
437 | } |
438 | if (state == TopAbs_UNKNOWN) return state; |
439 | return TopAbs_OUT; |
440 | } |
441 | |
442 | //======================================================================= |
443 | //function : KeepShape |
444 | //purpose : compute <pos2> = position of shape <S1> / shapes of list <LS2> |
445 | // shape S1 is kept |
446 | // - if LS2 is empty |
447 | // - if (pos2 == ToBuild1) |
448 | //======================================================================= |
449 | Standard_Boolean TopOpeBRepBuild_Builder::KeepShape(const TopoDS_Shape& S1,const TopTools_ListOfShape& LS2,const TopAbs_State ToBuild1) |
450 | { |
451 | Standard_Boolean keep = Standard_True; |
452 | if ( ! LS2.IsEmpty() ) { |
453 | TopAbs_State pos2 = ShapePosition(S1,LS2); |
454 | if ( pos2 != ToBuild1 ) keep = Standard_False; |
455 | } |
456 | return keep; |
457 | } |
458 | |
459 | //======================================================================= |
460 | //function : TopType |
461 | //purpose : return the type of upper subshape found in <S> |
462 | //======================================================================= |
463 | TopAbs_ShapeEnum TopOpeBRepBuild_Builder::TopType(const TopoDS_Shape& S) |
464 | { |
465 | TopAbs_ShapeEnum t; |
466 | TopOpeBRepTool_ShapeExplorer e; |
467 | |
468 | t = TopAbs_COMPOUND; e.Init(S,t); if (e.More()) return t; |
469 | t = TopAbs_COMPSOLID; e.Init(S,t); if (e.More()) return t; |
470 | t = TopAbs_SOLID; e.Init(S,t); if (e.More()) return t; |
471 | t = TopAbs_SHELL; e.Init(S,t); if (e.More()) return t; |
472 | t = TopAbs_FACE; e.Init(S,t); if (e.More()) return t; |
473 | t = TopAbs_WIRE; e.Init(S,t); if (e.More()) return t; |
474 | t = TopAbs_EDGE; e.Init(S,t); if (e.More()) return t; |
475 | t = TopAbs_VERTEX; e.Init(S,t); if (e.More()) return t; |
476 | |
477 | return TopAbs_SHAPE; |
478 | } |
479 | |
480 | //======================================================================= |
481 | //function : Reverse |
482 | //purpose : compute orientation reversibility according to build states |
483 | //======================================================================= |
484 | Standard_Boolean TopOpeBRepBuild_Builder::Reverse(const TopAbs_State ToBuild1,const TopAbs_State ToBuild2) |
485 | { |
486 | Standard_Boolean rev; |
487 | if (ToBuild1 == TopAbs_IN && ToBuild2 == TopAbs_IN) rev = Standard_False; |
488 | else rev = (ToBuild1 == TopAbs_IN); |
489 | return rev; |
490 | } |
491 | |
492 | //======================================================================= |
493 | //function : Orient |
494 | //purpose : reverse the orientation |
495 | //======================================================================= |
496 | TopAbs_Orientation TopOpeBRepBuild_Builder::Orient(const TopAbs_Orientation Ori,const Standard_Boolean Reverse) |
497 | { |
dde68833 |
498 | return !Reverse |
499 | ? Ori |
500 | : TopAbs::Complement(Ori); |
7fd59977 |
501 | } |
502 | |
503 | //======================================================================= |
504 | //function : FindSameDomain |
505 | //purpose : complete the lists L1,L2 with the shapes of the DS |
506 | // having same domain : |
507 | // L1 = shapes sharing the same domain of L2 shapes |
508 | // L2 = shapes sharing the same domain of L1 shapes |
509 | // (L1 contains a face) |
510 | //======================================================================= |
511 | void TopOpeBRepBuild_Builder::FindSameDomain(TopTools_ListOfShape& L1,TopTools_ListOfShape& L2) const |
512 | { |
513 | Standard_Integer i; |
514 | Standard_Integer nl1 = L1.Extent(), nl2 = L2.Extent(); |
515 | |
516 | while ( nl1 > 0 || nl2 > 0 ) { |
517 | |
518 | TopTools_ListIteratorOfListOfShape it1(L1); |
519 | for (i=1 ; i<=nl1; i++) { |
520 | const TopoDS_Shape& S1 = it1.Value(); |
0797d9d3 |
521 | #ifdef OCCT_DEBUG |
7fd59977 |
522 | // Standard_Integer iS1 = myDataStructure->Shape(S1); // DEB |
523 | #endif |
524 | TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S1)); |
525 | for (; itsd.More(); itsd.Next() ) { |
526 | const TopoDS_Shape& S2 = itsd.Value(); |
0797d9d3 |
527 | #ifdef OCCT_DEBUG |
7fd59977 |
528 | // Standard_Integer iS2 = myDataStructure->Shape(S2);// DEB |
529 | #endif |
530 | Standard_Boolean found = Contains(S2,L2); |
531 | if ( ! found ) { |
532 | L2.Prepend(S2); |
533 | nl2++; |
534 | } |
535 | } |
536 | it1.Next(); |
537 | } |
538 | nl1 = 0; |
539 | |
540 | TopTools_ListIteratorOfListOfShape it2(L2); |
541 | for (i=1 ; i<=nl2; i++) { |
542 | const TopoDS_Shape& S2 = it2.Value(); |
0797d9d3 |
543 | #ifdef OCCT_DEBUG |
7fd59977 |
544 | // Standard_Integer iS2 = myDataStructure->Shape(S2);// DEB |
545 | #endif |
546 | TopTools_ListIteratorOfListOfShape itsd(myDataStructure->SameDomain(S2)); |
547 | for (; itsd.More(); itsd.Next() ) { |
548 | const TopoDS_Shape& S1 = itsd.Value(); |
0797d9d3 |
549 | #ifdef OCCT_DEBUG |
7fd59977 |
550 | // Standard_Integer iS1 = myDataStructure->Shape(S1);// DEB |
551 | #endif |
552 | Standard_Boolean found = Contains(S1,L1); |
553 | if ( ! found ) { |
554 | L1.Prepend(S1); |
555 | nl1++; |
556 | } |
557 | } |
558 | it2.Next(); |
559 | } |
560 | nl2 = 0; |
561 | |
562 | } |
563 | |
564 | } |
565 | |
566 | |
567 | //======================================================================= |
568 | //function : FindSameDomainSameOrientation |
569 | //purpose : |
570 | //======================================================================= |
571 | void TopOpeBRepBuild_Builder::FindSameDomainSameOrientation(TopTools_ListOfShape& L1, TopTools_ListOfShape& L2) const |
572 | { |
573 | FindSameDomain(L1,L2); |
574 | TopTools_ListIteratorOfListOfShape it(L1); |
575 | if ( !it.More() ) return; |
576 | |
577 | const TopoDS_Shape& sref = it.Value(); |
0797d9d3 |
578 | #ifdef OCCT_DEBUG |
7fd59977 |
579 | // Standard_Integer iref = myDataStructure->SameDomainReference(sref); |
580 | #endif |
581 | TopOpeBRepDS_Config oref = myDataStructure->SameDomainOrientation(sref); |
582 | |
583 | TopTools_ListOfShape LL1,LL2; |
584 | |
585 | for (it.Initialize(L1); it.More(); it.Next() ) { |
586 | const TopoDS_Shape& s = it.Value(); |
587 | TopOpeBRepDS_Config o = myDataStructure->SameDomainOrientation(s); |
588 | if ( o == oref && !Contains(s,LL1) ) LL1.Append(s); |
589 | else if ( o != oref && !Contains(s,LL2) ) LL2.Append(s); |
590 | } |
591 | |
592 | for (it.Initialize(L2); it.More(); it.Next() ) { |
593 | const TopoDS_Shape& s = it.Value(); |
594 | TopOpeBRepDS_Config o = myDataStructure->SameDomainOrientation(s); |
595 | if ( o == oref && !Contains(s,LL1) ) LL1.Append(s); |
596 | else if ( o != oref && !Contains(s,LL2) ) LL2.Append(s); |
597 | } |
598 | |
599 | L1 = LL1; |
600 | L2 = LL2; |
601 | |
602 | } |
603 | |
604 | //======================================================================= |
605 | //function : MapShapes |
606 | //purpose : |
607 | //======================================================================= |
608 | void TopOpeBRepBuild_Builder::MapShapes(const TopoDS_Shape& S1,const TopoDS_Shape& S2) |
609 | { |
610 | Standard_Boolean S1null = S1.IsNull(); |
611 | Standard_Boolean S2null = S2.IsNull(); |
612 | ClearMaps(); |
613 | if ( ! S1null ) TopExp::MapShapes(S1,myMAP1); |
614 | if ( ! S2null ) TopExp::MapShapes(S2,myMAP2); |
615 | } |
616 | |
617 | //======================================================================= |
618 | //function : ClearMaps |
619 | //purpose : |
620 | //======================================================================= |
621 | void TopOpeBRepBuild_Builder::ClearMaps() |
622 | { |
623 | myMAP1.Clear(); |
624 | myMAP2.Clear(); |
625 | } |
626 | |
627 | //======================================================================= |
628 | //function : FindSameRank |
629 | //purpose : |
630 | //======================================================================= |
631 | void TopOpeBRepBuild_Builder::FindSameRank(const TopTools_ListOfShape& L1,const Standard_Integer rank,TopTools_ListOfShape& L2) const |
632 | { |
633 | for ( TopTools_ListIteratorOfListOfShape it1(L1); it1.More(); it1.Next() ) { |
634 | const TopoDS_Shape& s = it1.Value(); |
635 | Standard_Integer r = ShapeRank(s); |
636 | if ( r == rank && !Contains(s,L2) ) { |
637 | L2.Append(s); |
638 | } |
639 | } |
640 | } |
641 | |
642 | //======================================================================= |
643 | //function : ShapeRank |
644 | //purpose : |
645 | //======================================================================= |
646 | Standard_Integer TopOpeBRepBuild_Builder::ShapeRank(const TopoDS_Shape& s) const |
647 | { |
648 | Standard_Boolean isof1 = IsShapeOf(s,1); |
649 | Standard_Boolean isof2 = IsShapeOf(s,2); |
650 | Standard_Integer ancetre = (isof1 || isof2) ? ((isof1) ? 1 : 2) : 0; |
651 | return ancetre; |
652 | } |
653 | |
654 | //======================================================================= |
655 | //function : IsShapeOf |
656 | //purpose : |
657 | //======================================================================= |
658 | Standard_Boolean TopOpeBRepBuild_Builder::IsShapeOf(const TopoDS_Shape& s,const Standard_Integer i) const |
659 | { |
660 | Standard_Boolean b = Standard_False; |
661 | if (i == 1) b = myMAP1.Contains(s); |
662 | else if (i == 2) b = myMAP2.Contains(s); |
663 | return b; |
664 | } |
665 | |
666 | //======================================================================= |
667 | //function : Contains |
668 | //purpose : returns True if S is in the list L. |
669 | //======================================================================= |
670 | Standard_Boolean TopOpeBRepBuild_Builder::Contains(const TopoDS_Shape& S,const TopTools_ListOfShape& L) |
671 | { |
672 | for (TopTools_ListIteratorOfListOfShape it(L); it.More(); it.Next() ) { |
673 | TopoDS_Shape& SL = it.Value(); |
674 | Standard_Boolean issame = SL.IsSame(S); |
675 | if ( issame ) return Standard_True; |
676 | } |
677 | return Standard_False; |
678 | } |
679 | |
680 | //======================================================================= |
681 | //function : Opec12 |
682 | //purpose : |
683 | //======================================================================= |
684 | Standard_Boolean TopOpeBRepBuild_Builder::Opec12() const |
685 | { |
686 | Standard_Boolean b = (myState1 == TopAbs_OUT) && (myState2 == TopAbs_IN ); |
687 | return b; |
688 | } |
689 | |
690 | //======================================================================= |
691 | //function : Opec21 |
692 | //purpose : |
693 | //======================================================================= |
694 | Standard_Boolean TopOpeBRepBuild_Builder::Opec21() const |
695 | { |
696 | Standard_Boolean b = (myState1 == TopAbs_IN ) && (myState2 == TopAbs_OUT); |
697 | return b; |
698 | } |
699 | |
700 | //======================================================================= |
701 | //function : Opecom |
702 | //purpose : |
703 | //======================================================================= |
704 | Standard_Boolean TopOpeBRepBuild_Builder::Opecom() const |
705 | { |
706 | Standard_Boolean b = (myState1 == TopAbs_IN ) && (myState2 == TopAbs_IN ); |
707 | return b; |
708 | } |
709 | |
710 | //======================================================================= |
711 | //function : Opefus |
712 | //purpose : |
713 | //======================================================================= |
714 | Standard_Boolean TopOpeBRepBuild_Builder::Opefus() const |
715 | { |
716 | Standard_Boolean b = (myState1 == TopAbs_OUT) && (myState2 == TopAbs_OUT); |
717 | return b; |
718 | } |
719 | |
720 | //======================================================================= |
721 | //function : MSplit |
722 | //purpose : |
723 | //======================================================================= |
724 | const TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& TopOpeBRepBuild_Builder::MSplit(const TopAbs_State s) const |
725 | { |
726 | if (s == TopAbs_IN) return mySplitIN; |
727 | else if (s == TopAbs_OUT) return mySplitOUT; |
728 | else if (s == TopAbs_ON) return mySplitON; |
729 | return mySplitIN; |
730 | } |
731 | |
732 | //======================================================================= |
733 | //function : ChangeMSplit |
734 | //purpose : |
735 | //======================================================================= |
736 | TopOpeBRepDS_DataMapOfShapeListOfShapeOn1State& TopOpeBRepBuild_Builder::ChangeMSplit(const TopAbs_State s) |
737 | { |
738 | if (s == TopAbs_IN) return mySplitIN; |
739 | else if (s == TopAbs_OUT) return mySplitOUT; |
740 | else if (s == TopAbs_ON) return mySplitON; |
741 | return mySplitIN; |
742 | } |
896faa72 |
743 | |
744 | //======================================================================= |
745 | //function : SplitEdge |
746 | //purpose : |
747 | //======================================================================= |
748 | |
749 | void TopOpeBRepBuild_Builder::SplitEdge(const TopoDS_Shape& E, |
750 | const TopAbs_State ToBuild1, |
751 | const TopAbs_State ToBuild2) |
752 | { |
753 | #ifdef OCCT_DEBUG |
754 | if ( TopOpeBRepBuild_GetcontextSF2() ) { |
755 | SplitEdge2(E,ToBuild1,ToBuild2); |
756 | return; |
757 | } |
758 | #endif |
759 | SplitEdge1(E,ToBuild1,ToBuild2); |
760 | return; |
761 | } |
762 | |
763 | //======================================================================= |
764 | //function : SplitEdge1 |
765 | //purpose : |
766 | //======================================================================= |
767 | |
768 | void TopOpeBRepBuild_Builder::SplitEdge1(const TopoDS_Shape& Eoriented, |
769 | const TopAbs_State ToBuild1, |
770 | const TopAbs_State ToBuild2) |
771 | { |
772 | // work on a FORWARD edge <Eforward> |
773 | |
774 | TopoDS_Shape Eforward = Eoriented; |
775 | Eforward.Orientation(TopAbs_FORWARD); |
776 | |
777 | Standard_Boolean tosplit = ToSplit(Eoriented,ToBuild1); |
778 | |
779 | #ifdef OCCT_DEBUG |
780 | Standard_Integer iEdge; Standard_Boolean tSPS = GtraceSPS(Eoriented,iEdge); |
781 | if(tSPS){ |
782 | cout<<endl; |
783 | GdumpSHASTA(Eoriented,ToBuild1,"--- SplitEdge "); |
784 | cout<<endl; |
785 | } |
786 | #endif |
787 | |
788 | if ( ! tosplit ) return; |
789 | |
790 | Reverse(ToBuild1,ToBuild2); |
791 | Reverse(ToBuild2,ToBuild1); |
792 | Standard_Boolean ConnectTo1 = Standard_True; |
793 | Standard_Boolean ConnectTo2 = Standard_False; |
794 | |
795 | // build the list of edges to split : LE1, LE2 |
796 | TopTools_ListOfShape LE1,LE2; |
797 | LE1.Append(Eforward); |
798 | FindSameDomain(LE1,LE2); |
799 | |
800 | #ifdef OCCT_DEBUG |
801 | if(tSPS){GdumpSAMDOM(LE1, (char *) "1 : ");} |
802 | if(tSPS){GdumpSAMDOM(LE2, (char *) "2 : ");} |
803 | if(tSPS){cout<<endl;} |
804 | if(tSPS){cout<<"V of edge ";TopAbs::Print(Eforward.Orientation(),cout);} |
805 | if(tSPS){cout<<endl;} |
806 | if(tSPS){GdumpEDG(Eforward);} |
807 | #endif |
808 | |
809 | // SplitEdge on a edge having other same domained edges on the |
810 | // other shape : do not reverse orientation of edges in FillEdge |
811 | |
812 | // Make a PaveSet <PVS> on edge <Eforward> |
813 | TopOpeBRepBuild_PaveSet PVS(Eforward); |
814 | |
815 | // Add the points/vertices found on edge <Eforward> in <PVS> |
816 | TopOpeBRepDS_PointIterator EPIT(myDataStructure->EdgePoints(Eforward)); |
817 | FillVertexSet(EPIT,ToBuild1,PVS); |
818 | |
819 | TopOpeBRepBuild_PaveClassifier VCL(Eforward); |
820 | Standard_Boolean equalpar = PVS.HasEqualParameters(); |
821 | if (equalpar) VCL.SetFirstParameter(PVS.EqualParameters()); |
822 | |
823 | // ------------------------------------------ |
824 | // before return if PVS has no vertices, |
825 | // mark <Eforward> as split <ToBuild1> |
826 | // ------------------------------------------ |
827 | MarkSplit(Eforward,ToBuild1); |
828 | |
829 | PVS.InitLoop(); |
830 | if ( !PVS.MoreLoop() ) { |
831 | #ifdef OCCT_DEBUG |
832 | if(tSPS) { |
833 | cout<<"NO VERTEX split "; TopAbs::Print(ToBuild1,cout);cout<<endl; |
834 | } |
835 | #endif |
836 | return; |
837 | } |
838 | |
839 | // build the new edges |
840 | TopOpeBRepBuild_EdgeBuilder EBU(PVS,VCL); |
841 | |
842 | // Build the new edges |
843 | // ------------------- |
844 | TopTools_ListOfShape& EdgeList = ChangeMerged(Eforward,ToBuild1); |
845 | MakeEdges(Eforward,EBU,EdgeList); |
846 | |
847 | TopTools_ListIteratorOfListOfShape itLE1,itLE2; |
848 | |
849 | // connect new edges as edges built <ToBuild1> on LE1 edge |
850 | // -------------------------------------------------------- |
851 | for (itLE1.Initialize(LE1); itLE1.More(); itLE1.Next()) { |
852 | TopoDS_Shape Ecur = itLE1.Value(); |
853 | MarkSplit(Ecur,ToBuild1); |
854 | TopTools_ListOfShape& EL = ChangeSplit(Ecur,ToBuild1); |
855 | if ( ConnectTo1 ) EL = EdgeList; |
856 | } |
857 | |
858 | // connect new edges as edges built <ToBuild2> on LE2 edges |
859 | // -------------------------------------------------------- |
860 | for (itLE2.Initialize(LE2); itLE2.More(); itLE2.Next()) { |
861 | TopoDS_Shape Ecur = itLE2.Value(); |
862 | MarkSplit(Ecur,ToBuild2); |
863 | TopTools_ListOfShape& EL = ChangeSplit(Ecur,ToBuild2); |
864 | if ( ConnectTo2 ) EL = EdgeList; |
865 | } |
866 | |
867 | } // SplitEdge1 |
868 | |
869 | //======================================================================= |
870 | //function : SplitEdge2 |
871 | //purpose : |
872 | //======================================================================= |
873 | |
874 | void TopOpeBRepBuild_Builder::SplitEdge2(const TopoDS_Shape& Eoriented, |
875 | const TopAbs_State ToBuild1, |
876 | const TopAbs_State /*ToBuild2*/) |
877 | { |
878 | Standard_Boolean tosplit = ToSplit(Eoriented,ToBuild1); |
879 | if ( ! tosplit ) return; |
880 | |
881 | // work on a FORWARD edge <Eforward> |
882 | TopoDS_Shape Eforward = Eoriented; |
883 | myBuildTool.Orientation(Eforward,TopAbs_FORWARD); |
884 | |
885 | #ifdef OCCT_DEBUG |
886 | Standard_Integer iEdge; Standard_Boolean tSPS = GtraceSPS(Eoriented,iEdge); |
887 | if(tSPS){cout<<endl;} |
888 | if(tSPS){GdumpSHASTA(Eoriented,ToBuild1,"--- SplitEdge2 ");} |
889 | #endif |
890 | |
891 | // Make a PaveSet <PVS> on edge <Eforward> |
892 | // Add the points/vertices found on edge <Eforward> in <PVS> |
893 | TopOpeBRepBuild_PaveSet PVS(Eforward); |
894 | |
895 | TopOpeBRepDS_PointIterator EPIT(myDataStructure->EdgePoints(Eforward)); |
896 | FillVertexSet(EPIT,ToBuild1,PVS); |
897 | |
898 | TopOpeBRepBuild_PaveClassifier VCL(Eforward); |
899 | Standard_Boolean equalpar = PVS.HasEqualParameters(); |
900 | if (equalpar) VCL.SetFirstParameter(PVS.EqualParameters()); |
901 | |
902 | // ------------------------------------------ |
903 | // before return if PVS has no vertices, |
904 | // mark <Eforward> as split <ToBuild1> |
905 | // ------------------------------------------ |
906 | MarkSplit(Eforward,ToBuild1); |
907 | |
908 | PVS.InitLoop(); |
909 | if ( !PVS.MoreLoop() ) { |
910 | #ifdef OCCT_DEBUG |
911 | if(tSPS) {cout<<"NO VERTEX split ";TopAbs::Print(ToBuild1,cout);cout<<endl;} |
912 | #endif |
913 | return; |
914 | } |
915 | |
916 | // build the new edges |
917 | TopOpeBRepBuild_EdgeBuilder EBU(PVS,VCL); |
918 | |
919 | // connect the new edges as split parts <ToBuild1> built on <Eforward> |
920 | TopTools_ListOfShape& EL = ChangeSplit(Eforward,ToBuild1); |
921 | MakeEdges(Eforward,EBU,EL); |
922 | |
923 | } // SplitEdge2 |
924 | |
925 | //======================================================================= |
926 | //function : SplitFace |
927 | //purpose : |
928 | //======================================================================= |
929 | |
930 | void TopOpeBRepBuild_Builder::SplitFace(const TopoDS_Shape& Foriented, |
931 | const TopAbs_State ToBuild1, |
932 | const TopAbs_State ToBuild2) |
933 | { |
934 | #ifdef OCCT_DEBUG |
935 | if(TopOpeBRepBuild_GetcontextSF2()){ |
936 | SplitFace2(Foriented,ToBuild1,ToBuild2); |
937 | return; |
938 | } |
939 | #endif |
940 | SplitFace1(Foriented,ToBuild1,ToBuild2); |
941 | return; |
942 | } |
943 | |
944 | //======================================================================= |
945 | //function : SplitFace1 |
946 | //purpose : tout dans le meme edge set |
947 | //======================================================================= |
948 | |
949 | void TopOpeBRepBuild_Builder::SplitFace1(const TopoDS_Shape& Foriented, |
950 | const TopAbs_State ToBuild1, |
951 | const TopAbs_State ToBuild2) |
952 | { |
953 | // process connect connect |
954 | // operation tobuild1 tobuild2 face F to 1 to 2 |
955 | // --------- -------- -------- ------- ------- ------- |
956 | // common IN IN yes yes yes |
957 | // fuse OUT OUT yes yes yes |
958 | // cut 1-2 OUT IN yes yes no |
959 | // cut 2-1 IN OUT yes yes no |
960 | // |
961 | Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1); |
962 | if ( ! tosplit ) return; |
963 | |
964 | Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2); |
965 | Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1); |
966 | Standard_Boolean ConnectTo1 = Standard_True; |
967 | Standard_Boolean ConnectTo2 = Standard_False; |
968 | |
969 | // work on a FORWARD face <Fforward> |
970 | TopoDS_Shape Fforward = Foriented; |
971 | myBuildTool.Orientation(Fforward,TopAbs_FORWARD); |
972 | |
973 | // build the list of faces to split : LF1, LF2 |
974 | TopTools_ListOfShape LF1,LF2; |
975 | LF1.Append(Fforward); |
976 | FindSameDomain(LF1,LF2); |
977 | Standard_Integer n1 = LF1.Extent(); |
978 | Standard_Integer n2 = LF2.Extent(); |
979 | |
980 | // SplitFace on a face having other same domained faces on the |
981 | // other shape : do not reverse orientation of faces in FillFace |
982 | if (!n2) RevOri1 = Standard_False; |
983 | if (!n1) RevOri2 = Standard_False; |
984 | |
985 | // Create an edge set <WES> connected by vertices |
986 | // ---------------------------------------------- |
987 | TopOpeBRepBuild_WireEdgeSet WES(Fforward,this); |
988 | |
989 | #ifdef OCCT_DEBUG |
990 | Standard_Boolean tSPF=TopOpeBRepBuild_GettraceSPF(); |
991 | Standard_Integer iFace=myDataStructure->Shape(Foriented); |
992 | if(tSPF){cout<<endl;GdumpSHASTA(Foriented,ToBuild1,"=== SplitFace ");} |
993 | if(tSPF){GdumpSAMDOM(LF1, (char *) "1 : ");GdumpSAMDOM(LF2, (char *) "2 : ");} |
994 | if(tSPF) debspf(iFace); |
995 | #endif |
996 | |
997 | TopTools_ListIteratorOfListOfShape itLF1,itLF2; |
998 | |
999 | for (itLF1.Initialize(LF1); itLF1.More(); itLF1.Next()) { |
1000 | const TopoDS_Shape& Fcur = itLF1.Value(); |
1001 | // myDataStructure->Shape(Fcur);//DEB |
1002 | FillFace(Fcur,ToBuild1,LF2,ToBuild2,WES,RevOri1); |
1003 | } |
1004 | |
1005 | for (itLF2.Initialize(LF2); itLF2.More(); itLF2.Next()) { |
1006 | const TopoDS_Shape& Fcur = itLF2.Value(); |
1007 | // myDataStructure->Shape(Fcur);//DEB |
1008 | FillFace(Fcur,ToBuild2,LF1,ToBuild1,WES,RevOri2); |
1009 | } |
1010 | |
1011 | // Add the intersection edges to edge set WES |
1012 | // ----------------------------------------- |
1013 | AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES); |
1014 | |
1015 | #ifdef OCCT_DEBUG |
1016 | Standard_Integer iF; Standard_Boolean tSPS = GtraceSPS(Fforward,iF); |
1017 | if(tSPS) WES.DumpSS(); |
1018 | #endif |
1019 | |
1020 | // Create a Face Builder FBU |
1021 | // ------------------------ |
1022 | TopOpeBRepBuild_FaceBuilder FBU; |
1023 | FBU.InitFaceBuilder(WES,Fforward,Standard_False); //forceclass = False |
1024 | |
1025 | // Build the new faces |
1026 | // ------------------- |
1027 | TopTools_ListOfShape& FaceList = ChangeMerged(Fforward,ToBuild1); |
1028 | MakeFaces(Fforward,FBU,FaceList); |
1029 | |
1030 | // connect new faces as faces built <ToBuild1> on LF1 faces |
1031 | // -------------------------------------------------------- |
1032 | for (itLF1.Initialize(LF1); itLF1.More(); itLF1.Next()) { |
1033 | TopoDS_Shape Fcur = itLF1.Value(); |
1034 | MarkSplit(Fcur,ToBuild1); |
1035 | TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild1); |
1036 | if ( ConnectTo1 ) FL = FaceList; |
1037 | } |
1038 | |
1039 | // connect new faces as faces built <ToBuild2> on LF2 faces |
1040 | // -------------------------------------------------------- |
1041 | for (itLF2.Initialize(LF2); itLF2.More(); itLF2.Next()) { |
1042 | TopoDS_Shape Fcur = itLF2.Value(); |
1043 | MarkSplit(Fcur,ToBuild2); |
1044 | TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild2); |
1045 | if ( ConnectTo2 ) FL = FaceList; |
1046 | } |
1047 | |
1048 | } // SplitFace1 |
1049 | |
1050 | //======================================================================= |
1051 | //function : SplitFace2 |
1052 | //purpose : |
1053 | //======================================================================= |
1054 | |
1055 | void TopOpeBRepBuild_Builder::SplitFace2(const TopoDS_Shape& Foriented, |
1056 | const TopAbs_State ToBuild1, |
1057 | const TopAbs_State ToBuild2) |
1058 | { |
1059 | // process connect connect |
1060 | // operation tobuild1 tobuild2 face F to 1 to 2 |
1061 | // --------- -------- -------- ------- ------- ------- |
1062 | // common IN IN yes yes yes |
1063 | // fuse OUT OUT yes yes yes |
1064 | // cut 1-2 OUT IN yes yes no |
1065 | // cut 2-1 IN OUT yes yes no |
1066 | // |
1067 | Standard_Boolean tosplit = ToSplit(Foriented,ToBuild1); |
1068 | if ( ! tosplit ) return; |
1069 | |
1070 | Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2); |
1071 | Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1); |
1072 | Standard_Boolean ConnectTo1 = Standard_True; |
1073 | Standard_Boolean ConnectTo2 = Standard_False; |
1074 | |
1075 | // work on a FORWARD face <Fforward> |
1076 | TopoDS_Shape Fforward = Foriented; |
1077 | myBuildTool.Orientation(Fforward,TopAbs_FORWARD); |
1078 | |
1079 | TopTools_ListOfShape LF1 ; //liste des faces de 1 samedomain |
1080 | TopTools_ListOfShape LF2 ; //liste des faces de 2 samedomain |
1081 | LF1.Append(Fforward); |
1082 | FindSameDomain(LF1,LF2); |
1083 | Standard_Integer n1 = LF1.Extent(); |
1084 | Standard_Integer n2 = LF2.Extent(); |
1085 | |
1086 | #ifdef OCCT_DEBUG |
1087 | Standard_Boolean tSPF = TopOpeBRepBuild_GettraceSPF(); |
1088 | // Standard_Integer iFace = myDataStructure->Shape(Foriented); |
1089 | if (tSPF) { |
1090 | cout<<endl; |
1091 | GdumpSHASTA(Foriented,ToBuild1,"=== SplitFace "); |
1092 | GdumpSAMDOM(LF1, (char *) "samedomain 1 : "); |
1093 | GdumpSAMDOM(LF2, (char *) "samedomain 2 : "); |
1094 | } |
1095 | #endif |
1096 | |
1097 | // SplitFace on a face having other same domained faces on the |
1098 | // other shape : do not reverse orientation of faces in FillFace |
1099 | if (!n2) RevOri1 = Standard_False; |
1100 | if (!n1) RevOri2 = Standard_False; |
1101 | |
1102 | TopTools_ListOfShape LFSO; //liste des faces de 1,2 samedomainsameorientation |
1103 | TopTools_ListOfShape LFOO; //liste des faces de 1,2 samedomainoppositeorient |
1104 | |
1105 | // LFSO : faces des shapes 1 ou 2, de meme orientation que Fforward. |
1106 | // LFOO : faces des shapes 1 ou 2, d'orientation contraire que Fforward. |
1107 | LFSO.Append(Fforward); |
1108 | FindSameDomainSameOrientation(LFSO,LFOO); |
1109 | |
1110 | TopTools_ListOfShape LFSO1,LFOO1; // same domain, same orientation, et du shape de F |
1111 | TopTools_ListOfShape LFSO2,LFOO2; // "" "",du shape autre que celui de F |
1112 | |
1113 | // on construit les parties ToBuild1 de F |
1114 | Standard_Integer rankF = ShapeRank(Foriented); |
1115 | Standard_Integer rankX = (rankF) ? ((rankF == 1) ? 2 : 1) : 0; |
1116 | |
1117 | FindSameRank(LFSO,rankF,LFSO1); |
1118 | FindSameRank(LFOO,rankF,LFOO1); |
1119 | FindSameRank(LFSO,rankX,LFSO2); |
1120 | FindSameRank(LFOO,rankX,LFOO2); |
1121 | |
1122 | #ifdef OCCT_DEBUG |
1123 | if ( tSPF ) { |
1124 | GdumpSAMDOM(LFSO1, (char *) "LFSO1 : "); |
1125 | GdumpSAMDOM(LFOO1, (char *) "LFOO1 : "); |
1126 | GdumpSAMDOM(LFSO2, (char *) "LFSO2 : "); |
1127 | GdumpSAMDOM(LFOO2, (char *) "LFOO2 : "); |
1128 | } |
1129 | #endif |
1130 | |
1131 | TopAbs_State tob1 = ToBuild1; |
1132 | TopAbs_State tob2 = ToBuild2; |
1133 | TopAbs_State tob1comp = (ToBuild1 == TopAbs_IN) ? TopAbs_OUT : TopAbs_IN; |
1134 | TopAbs_State tob2comp = (ToBuild2 == TopAbs_IN) ? TopAbs_OUT : TopAbs_IN; |
1135 | TopTools_ListIteratorOfListOfShape itLF ; |
1136 | |
1137 | // -------------------------------------------------------------------- |
1138 | // traitement des faces de meme orientation que Fforward dans WireEdgeSet WES1 |
1139 | // -------------------------------------------------------------------- |
1140 | TopOpeBRepBuild_WireEdgeSet WES1(Fforward,this); |
1141 | |
1142 | // traitement des faces de 1 same domain, same orientation que F : LFSO1 |
1143 | for (itLF.Initialize(LFSO1); itLF.More(); itLF.Next()) { |
1144 | const TopoDS_Shape& Fcur = itLF.Value(); |
1145 | // myDataStructure->Shape(Fcur);//DEB |
1146 | // les wires de Fcur sont a comparer avec les faces de 2 |
1147 | FillFace(Fcur,tob1,LF2,tob2,WES1,RevOri1); |
1148 | } |
1149 | |
1150 | // traitement des faces de 2 same domain, same orientation que F : LFSO2 |
1151 | for (itLF.Initialize(LFSO2); itLF.More(); itLF.Next()) { |
1152 | const TopoDS_Shape& Fcur = itLF.Value(); |
1153 | // myDataStructure->Shape(Fcur);//DEB |
1154 | // les wires de Fcur sont a comparer avec les faces de 1 |
1155 | FillFace(Fcur,tob2,LF1,tob1,WES1,RevOri2); |
1156 | } |
1157 | |
1158 | // traitement des faces de 1 same domain, oppo orientation que F : LFOO1 |
1159 | for (itLF.Initialize(LFOO1); itLF.More(); itLF.Next()) { |
1160 | const TopoDS_Shape& Fcur = itLF.Value(); |
1161 | // myDataStructure->Shape(Fcur);//DEB |
1162 | // les wires de Fcur sont a comparer avec les faces de 2 |
1163 | FillFace(Fcur,tob1comp,LF2,ToBuild2,WES1,!RevOri1); |
1164 | } |
1165 | |
1166 | // traitement des faces de 2 same domain, oppo orientation que F : LFOO2 |
1167 | for (itLF.Initialize(LFOO2); itLF.More(); itLF.Next()) { |
1168 | const TopoDS_Shape& Fcur = itLF.Value(); |
1169 | // myDataStructure->Shape(Fcur);//DEB |
1170 | // les wires de Fcur sont a comparer avec les faces de 1 |
1171 | FillFace(Fcur,tob2comp,LF1,ToBuild1,WES1,!RevOri2); |
1172 | } |
1173 | |
1174 | // Add the intersection edges to edge set WES1 |
1175 | // ------------------------------------------ |
1176 | AddIntersectionEdges(Fforward,ToBuild1,RevOri1,WES1); |
1177 | |
1178 | // Create a Face Builder FBU1 |
1179 | // ------------------------ |
1180 | TopOpeBRepBuild_FaceBuilder FBU1(WES1,Fforward); |
1181 | |
1182 | // Build the new faces |
1183 | // ------------------- |
1184 | TopTools_ListOfShape& FaceList1 = ChangeMerged(Fforward,ToBuild1); |
1185 | MakeFaces(Fforward,FBU1,FaceList1); |
1186 | |
1187 | // connect new faces as faces built <ToBuild1> on LF1 faces |
1188 | // -------------------------------------------------------- |
1189 | for (itLF.Initialize(LF1); itLF.More(); itLF.Next()) { |
1190 | TopoDS_Shape Fcur = itLF.Value(); |
1191 | MarkSplit(Fcur,ToBuild1); |
1192 | TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild1); |
1193 | if ( ConnectTo1 ) FL = FaceList1; |
1194 | } |
1195 | |
1196 | // -------------------------------------------------------------------- |
1197 | // traitement des faces de meme orientation que Fforward dans WireEdgeSet WES2 |
1198 | // -------------------------------------------------------------------- |
1199 | TopOpeBRepBuild_WireEdgeSet WES2(Fforward,this); |
1200 | |
1201 | // traitement des faces de 1 same domain, same orientation que F : LFSO1 |
1202 | for (itLF.Initialize(LFSO1); itLF.More(); itLF.Next()) { |
1203 | const TopoDS_Shape& Fcur = itLF.Value(); |
1204 | // myDataStructure->Shape(Fcur);//DEB |
1205 | // les wires de Fcur sont a comparer avec les faces de 2 |
1206 | FillFace(Fcur,tob1comp,LF2,tob2,WES2,!RevOri1); |
1207 | } |
1208 | |
1209 | // traitement des faces de 2 same domain, same orientation que F : LFSO2 |
1210 | for (itLF.Initialize(LFSO2); itLF.More(); itLF.Next()) { |
1211 | const TopoDS_Shape& Fcur = itLF.Value(); |
1212 | // myDataStructure->Shape(Fcur);//DEB |
1213 | // les wires de Fcur sont a comparer avec les faces de 1 |
1214 | FillFace(Fcur,tob2comp,LF1,tob1,WES2,!RevOri2); |
1215 | } |
1216 | |
1217 | // traitement des faces de 1 same domain, oppo orientation que F : LFOO1 |
1218 | for (itLF.Initialize(LFOO1); itLF.More(); itLF.Next()) { |
1219 | const TopoDS_Shape& Fcur = itLF.Value(); |
1220 | // myDataStructure->Shape(Fcur);//DEB |
1221 | // les wires de Fcur sont a comparer avec les faces de 2 |
1222 | FillFace(Fcur,tob1,LF2,ToBuild2,WES2,RevOri1); |
1223 | } |
1224 | |
1225 | // traitement des faces de 2 same domain, oppo orientation que F : LFOO2 |
1226 | for (itLF.Initialize(LFOO2); itLF.More(); itLF.Next()) { |
1227 | const TopoDS_Shape& Fcur = itLF.Value(); |
1228 | // myDataStructure->Shape(Fcur);//DEB |
1229 | // les wires de Fcur sont a comparer avec les faces de 1 |
1230 | FillFace(Fcur,tob2,LF1,ToBuild1,WES2,RevOri2); |
1231 | } |
1232 | |
1233 | // Add the intersection edges to edge set WES2 |
1234 | // ------------------------------------------ |
1235 | AddIntersectionEdges(Fforward,ToBuild2,RevOri2,WES2); |
1236 | |
1237 | // Create a Face Builder FBU2 |
1238 | // ------------------------- |
1239 | TopOpeBRepBuild_FaceBuilder FBU2(WES2,Fforward); |
1240 | |
1241 | // Build the new faces |
1242 | // ------------------- |
1243 | TopTools_ListOfShape& FaceList2 = ChangeMerged(Fforward,ToBuild2); |
1244 | MakeFaces(Fforward,FBU2,FaceList2); |
1245 | |
1246 | // connect new faces as faces built <ToBuild2> on LF2 faces |
1247 | // -------------------------------------------------------- |
1248 | for (itLF.Initialize(LF2); itLF.More(); itLF.Next()) { |
1249 | TopoDS_Shape Fcur = itLF.Value(); |
1250 | MarkSplit(Fcur,ToBuild2); |
1251 | TopTools_ListOfShape& FL = ChangeSplit(Fcur,ToBuild2); |
1252 | if ( ConnectTo2 ) FL = FaceList2; |
1253 | } |
1254 | |
1255 | } // SplitFace2 |
1256 | |
1257 | //======================================================================= |
1258 | //function : SplitSolid |
1259 | //purpose : |
1260 | //======================================================================= |
1261 | |
1262 | void TopOpeBRepBuild_Builder::SplitSolid(const TopoDS_Shape& S1oriented, |
1263 | const TopAbs_State ToBuild1, |
1264 | const TopAbs_State ToBuild2) |
1265 | { |
1266 | //modified by IFV for treating shell |
1267 | Standard_Boolean tosplit = Standard_False; |
1268 | Standard_Boolean IsShell = (S1oriented.ShapeType() == TopAbs_SHELL); |
1269 | if(IsShell) { |
1270 | TopExp_Explorer ex; |
1271 | ex.Init(S1oriented, TopAbs_FACE); |
1272 | for (; ex.More(); ex.Next()) { |
1273 | const TopoDS_Shape& sh = ex.Current(); |
1274 | tosplit = ToSplit(sh,ToBuild1); |
1275 | if(tosplit) break; |
1276 | } |
1277 | } |
1278 | else tosplit = ToSplit(S1oriented,ToBuild1); |
1279 | |
1280 | if ( ! tosplit ) return; |
1281 | // end IFV |
1282 | |
1283 | Standard_Boolean RevOri1 = Reverse(ToBuild1,ToBuild2); |
1284 | Standard_Boolean RevOri2 = Reverse(ToBuild2,ToBuild1); |
1285 | Standard_Boolean ConnectTo1 = Standard_True; |
1286 | Standard_Boolean ConnectTo2 = Standard_False; |
1287 | |
1288 | // work on a FORWARD solid <S1forward> |
1289 | TopoDS_Shape S1forward = S1oriented; |
1290 | myBuildTool.Orientation(S1forward,TopAbs_FORWARD); |
1291 | |
1292 | // build the list of solids to split : LS1, LS2 |
1293 | TopTools_ListOfShape LS1,LS2; |
1294 | LS1.Append(S1forward); |
1295 | FindSameDomain(LS1,LS2); |
1296 | Standard_Integer n1 = LS1.Extent(); |
1297 | Standard_Integer n2 = LS2.Extent(); |
1298 | |
1299 | if (!n2) RevOri1 = Standard_False; |
1300 | if (!n1) RevOri2 = Standard_False; |
1301 | |
1302 | // Create a face set <FS> connected by edges |
1303 | // ----------------------------------------- |
1304 | TopOpeBRepBuild_ShellFaceSet SFS; |
1305 | |
1306 | #ifdef OCCT_DEBUG |
1307 | Standard_Boolean tSPS = TopOpeBRepBuild_GettraceSPS(); |
1308 | // Standard_Integer iSolid = myDataStructure->Shape(S1oriented); |
1309 | if (tSPS) { |
1310 | cout<<endl; |
1311 | GdumpSHASTA(S1oriented,ToBuild1,"___ SplitSolid "); |
1312 | GdumpSAMDOM(LS1, (char *) "1 : "); |
1313 | GdumpSAMDOM(LS2, (char *) "2 : "); |
1314 | } |
1315 | SFS.DEBNumber(GdumpSHASETindex()); |
1316 | #endif |
1317 | |
1318 | STATIC_SOLIDINDEX = 1; |
1319 | TopTools_ListIteratorOfListOfShape itLS1; |
1320 | for (itLS1.Initialize(LS1); itLS1.More(); itLS1.Next()) { |
1321 | TopoDS_Shape Scur = itLS1.Value(); |
1322 | FillSolid(Scur,ToBuild1,LS2,ToBuild2,SFS,RevOri1); |
1323 | } |
1324 | |
1325 | STATIC_SOLIDINDEX = 2; |
1326 | TopTools_ListIteratorOfListOfShape itLS2; |
1327 | for (itLS2.Initialize(LS2); itLS2.More(); itLS2.Next()) { |
1328 | TopoDS_Shape Scur = itLS2.Value(); |
1329 | FillSolid(Scur,ToBuild2,LS1,ToBuild1,SFS,RevOri2); |
1330 | } |
1331 | |
1332 | // Add the intersection surfaces |
1333 | // ----------------------------- |
1334 | if (myDataStructure->NbSurfaces() > 0) { |
1335 | TopOpeBRepDS_SurfaceIterator SSurfaces = myDataStructure->SolidSurfaces(S1forward); |
1336 | for (; SSurfaces.More(); SSurfaces.Next()) { |
1337 | Standard_Integer iS = SSurfaces.Current(); |
1338 | const TopTools_ListOfShape& LnewF = NewFaces(iS); |
1339 | for (TopTools_ListIteratorOfListOfShape Iti(LnewF); Iti.More(); Iti.Next()) { |
1340 | TopoDS_Shape aFace = Iti.Value(); |
1341 | TopAbs_Orientation ori = SSurfaces.Orientation(ToBuild1); |
1342 | myBuildTool.Orientation(aFace,ori); |
1343 | |
1344 | #ifdef OCCT_DEBUG |
1345 | if (tSPS){ |
1346 | TCollection_AsciiString ss("--- SplitSolid "); |
1347 | ss = ss + SFS.DEBNumber() + " AddElement SFS+ face "; |
1348 | GdumpSHA(aFace,(Standard_Address)ss.ToCString()); |
1349 | cout<<" ";TopAbs::Print(ToBuild1,cout)<<" : 1 face "; |
1350 | TopAbs::Print(ori,cout); cout<<endl; |
1351 | } |
1352 | #endif |
1353 | SFS.AddElement(aFace); |
1354 | } |
1355 | } |
1356 | } |
1357 | |
1358 | // Create a Solid Builder SOBU |
1359 | // ------------------------- |
1360 | TopOpeBRepBuild_SolidBuilder SOBU(SFS); |
1361 | |
1362 | // Build the new solids on S1 |
1363 | // -------------------------- |
1364 | TopTools_ListOfShape& SolidList = ChangeMerged(S1oriented,ToBuild1); |
1365 | if(IsShell) |
1366 | MakeShells(SOBU,SolidList); |
1367 | else |
1368 | MakeSolids(SOBU,SolidList); |
1369 | |
1370 | // connect list of new solids <SolidList> as solids built on LS1 solids |
1371 | // -------------------------------------------------------------------- |
1372 | |
1373 | for (itLS1.Initialize(LS1); itLS1.More(); itLS1.Next()) { |
1374 | TopoDS_Shape Scur = itLS1.Value(); |
1375 | MarkSplit(Scur,ToBuild1); |
1376 | TopTools_ListOfShape& SL = ChangeSplit(Scur,ToBuild1); |
1377 | if ( ConnectTo1 ) SL = SolidList; |
1378 | |
1379 | } |
1380 | |
1381 | // connect list of new solids <SolidList> as solids built on LS2 solids |
1382 | // -------------------------------------------------------------------- |
1383 | for (itLS2.Initialize(LS2); itLS2.More(); itLS2.Next()) { |
1384 | TopoDS_Shape Scur = itLS2.Value(); |
1385 | MarkSplit(Scur,ToBuild2); |
1386 | TopTools_ListOfShape& SL = ChangeSplit(Scur,ToBuild2); |
1387 | if ( ConnectTo2 ) SL = SolidList; |
1388 | } |
1389 | |
1390 | } // SplitSolid |
1391 | |
1392 | static Standard_Boolean FUN_touched(const TopOpeBRepDS_DataStructure& BDS,const TopoDS_Edge& EOR) |
1393 | { |
1394 | TopoDS_Vertex vf,vl; TopExp::Vertices(EOR,vf,vl); |
1395 | Standard_Boolean hvf = BDS.HasShape(vf); |
1396 | Standard_Boolean hvl = BDS.HasShape(vl); |
1397 | return (hvf || hvl); |
1398 | } |
1399 | |
1400 | //======================================================================= |
1401 | //function : SplitShapes |
1402 | //purpose : |
1403 | //======================================================================= |
1404 | void TopOpeBRepBuild_Builder::SplitShapes(TopOpeBRepTool_ShapeExplorer& Ex, |
1405 | const TopAbs_State ToBuild1, |
1406 | const TopAbs_State ToBuild2, |
1407 | TopOpeBRepBuild_ShapeSet& aSet, |
1408 | const Standard_Boolean RevOri) |
1409 | { |
1410 | TopoDS_Shape aShape; |
1411 | TopAbs_Orientation newori; |
1412 | |
1413 | for (; Ex.More(); Ex.Next()) { |
1414 | aShape = Ex.Current(); |
1415 | |
1416 | // compute new orientation <newori> to give to the new shapes |
1417 | newori = Orient(myBuildTool.Orientation(aShape),RevOri); |
1418 | |
1419 | TopAbs_ShapeEnum t = aShape.ShapeType(); |
1420 | |
1421 | if ( t == TopAbs_SOLID || t == TopAbs_SHELL ) |
1422 | SplitSolid(aShape,ToBuild1,ToBuild2); |
1423 | else if ( t == TopAbs_FACE ) SplitFace(aShape,ToBuild1,ToBuild2); |
1424 | else if ( t == TopAbs_EDGE ) SplitEdge(aShape,ToBuild1,ToBuild2); |
1425 | else continue; |
1426 | |
1427 | if ( IsSplit(aShape,ToBuild1) ) { |
1428 | TopoDS_Shape newShape; |
1429 | TopTools_ListIteratorOfListOfShape It; |
1430 | //----------------------- IFV |
1431 | Standard_Boolean IsLSon = Standard_False; |
1432 | //----------------------- IFV |
1433 | const TopTools_ListOfShape& LS = Splits(aShape,ToBuild1); |
1434 | //----------------------- IFV |
1435 | if(t == TopAbs_EDGE && ToBuild1 == TopAbs_IN && LS.Extent() == 0) { |
1436 | const TopTools_ListOfShape& LSon = Splits(aShape,TopAbs_ON); |
1437 | It.Initialize(LSon); |
1438 | IsLSon = Standard_True; |
1439 | } |
1440 | else { |
1441 | It.Initialize(LS); |
1442 | } |
1443 | //----------------------- IFV |
1444 | for (; It.More(); It.Next()) { |
1445 | newShape = It.Value(); |
1446 | myBuildTool.Orientation(newShape,newori); |
1447 | #ifdef OCCT_DEBUG |
1448 | // TopAbs_ShapeEnum tns = TopType(newShape); |
1449 | #endif |
1450 | //----------------------- IFV |
1451 | if(IsLSon) { |
1452 | Standard_Boolean add = Standard_True; |
1453 | if ( !myListOfFace.IsEmpty()) { // 2d pur |
1454 | add = KeepShape(newShape,myListOfFace,ToBuild1); |
1455 | } |
1456 | if(add) aSet.AddStartElement(newShape); |
1457 | |
1458 | } |
1459 | else { |
1460 | //----------------------- IFV |
1461 | aSet.AddStartElement(newShape); |
1462 | } |
1463 | } |
1464 | } |
1465 | else { |
1466 | // aShape n'a pas de devenir de split par ToBuild1 |
1467 | // on construit les parties ToBuild1 de aShape (de S1) |
1468 | Standard_Boolean add = Standard_True; |
1469 | Standard_Boolean testkeep = Standard_False; |
1470 | Standard_Boolean isedge = (t == TopAbs_EDGE); |
1471 | Standard_Boolean hs = (myDataStructure->HasShape(aShape)); |
1472 | Standard_Boolean hg = (myDataStructure->HasGeometry(aShape)); |
1473 | |
1474 | testkeep = isedge && hs && (!hg); |
1475 | |
1476 | // xpu010399 : USA60299 (!hs)&&(!hg), but vertex on bound is touched (v7) |
1477 | // -> testkeep |
1478 | Standard_Boolean istouched = isedge && (!hs) && (!hg); |
1479 | if (istouched) istouched = FUN_touched(myDataStructure->DS(),TopoDS::Edge(aShape)); |
1480 | testkeep = testkeep || istouched; |
1481 | |
1482 | if (testkeep) { |
1483 | if ( !myListOfFace.IsEmpty()) { // 2d pur |
1484 | Standard_Boolean keep = KeepShape(aShape,myListOfFace,ToBuild1); |
1485 | add = keep; |
1486 | } |
1487 | else { // 3d |
1488 | // on classifie en solide uniqt si |
1489 | // E dans la DS et E a ete purgee de ses interfs car en bout |
1490 | TopoDS_Shape sol; |
1491 | if (STATIC_SOLIDINDEX == 1) sol = myShape2; |
1492 | else sol = myShape1; |
1493 | if ( !sol.IsNull() ) { |
1494 | Standard_Real first,last; |
1495 | Handle(Geom_Curve) C3D; |
1496 | C3D = BRep_Tool::Curve(TopoDS::Edge(aShape),first,last); |
1497 | if ( !C3D.IsNull() ) { |
1498 | Standard_Real tt = 0.127956477; |
1499 | Standard_Real par = (1-tt)*first + tt*last; |
1500 | gp_Pnt P3D = C3D->Value(par); |
1501 | Standard_Real tol3d = Precision::Confusion(); |
1502 | BRepClass3d_SolidClassifier SCL(sol,P3D,tol3d); |
1503 | TopAbs_State state = SCL.State(); |
1504 | add = (state == ToBuild1); |
1505 | } |
1506 | else { |
1507 | throw Standard_ProgramError("SplitShapes no 3D curve on edge"); |
1508 | // NYI pas de courbe 3d : prendre un point sur (courbe 2d,face) |
1509 | } |
1510 | } |
1511 | else { // sol.IsNull |
1512 | add = Standard_True; |
1513 | } |
1514 | } |
1515 | } |
1516 | if ( add ) { |
1517 | myBuildTool.Orientation(aShape,newori); |
1518 | aSet.AddElement(aShape); |
1519 | } |
1520 | } |
1521 | |
1522 | } // Ex.More |
1523 | |
1524 | } // SplitShapes |
1525 | |
1526 | //======================================================================= |
1527 | //function : FillShape |
1528 | //purpose : |
1529 | //======================================================================= |
1530 | void TopOpeBRepBuild_Builder::FillShape(const TopoDS_Shape& S1, |
1531 | const TopAbs_State ToBuild1, |
1532 | const TopTools_ListOfShape& LS2, |
1533 | const TopAbs_State ToBuild2, |
1534 | TopOpeBRepBuild_ShapeSet& aSet, |
1535 | const Standard_Boolean In_RevOri) |
1536 | { |
1537 | Standard_Boolean RevOri = In_RevOri; |
1538 | TopAbs_ShapeEnum t = S1.ShapeType(); |
1539 | TopAbs_ShapeEnum t1=TopAbs_COMPOUND,t11=TopAbs_COMPOUND; |
1540 | |
1541 | if (t == TopAbs_FACE ) { |
1542 | t1 = TopAbs_WIRE; |
1543 | t11 = TopAbs_EDGE; |
1544 | } |
1545 | else if (t == TopAbs_SOLID || t == TopAbs_SHELL) { |
1546 | t1 = TopAbs_SHELL; |
1547 | t11 = TopAbs_FACE; |
1548 | } |
1549 | |
1550 | // if the shape S1 is a SameDomain one, get its orientation compared |
1551 | // with the shape taken as reference for all of the SameDomain shape of S1. |
1552 | Standard_Boolean hsd = myDataStructure->HasSameDomain(S1); |
1553 | if (hsd) { |
1554 | TopOpeBRepDS_Config ssc = myDataStructure->SameDomainOrientation(S1); |
1555 | if ( ssc == TopOpeBRepDS_DIFFORIENTED ) { |
1556 | RevOri = ! RevOri; |
1557 | #ifdef OCCT_DEBUG |
1558 | // Standard_Integer iFace = myDataStructure->Shape(S1); |
1559 | // cout<<endl<<"********** "; |
1560 | // cout<<"retournement d'orientation de ";TopAbs::Print(t,cout); |
1561 | // cout<<" "<<iFace<<endl; |
1562 | #endif |
1563 | } |
1564 | } |
1565 | |
1566 | // work on a FORWARD shape <aShape> |
1567 | TopoDS_Shape aShape = S1; |
1568 | myBuildTool.Orientation(aShape,TopAbs_FORWARD); |
1569 | |
1570 | TopoDS_Shape aSubShape; |
1571 | TopAbs_Orientation newori; |
1572 | |
1573 | // Explore the SubShapes of type <t1> |
1574 | for (TopOpeBRepTool_ShapeExplorer ex1(aShape,t1); ex1.More(); ex1.Next()) { |
1575 | aSubShape = ex1.Current(); |
1576 | |
1577 | if ( ! myDataStructure->HasShape(aSubShape) ) { |
1578 | // SubShape is not in DS : classify it with shapes of LS2 |
1579 | Standard_Boolean keep = KeepShape(aSubShape,LS2,ToBuild1); |
1580 | if (keep) { |
1581 | newori = Orient(myBuildTool.Orientation(aSubShape),RevOri); |
1582 | myBuildTool.Orientation(aSubShape,newori); |
1583 | aSet.AddShape(aSubShape); |
1584 | } |
1585 | } |
1586 | else { |
1587 | // SubShape has geometry : split the <t11> SubShapes of the SubShape |
1588 | TopOpeBRepTool_ShapeExplorer ex11(aSubShape,t11); |
1589 | SplitShapes(ex11,ToBuild1,ToBuild2,aSet,RevOri); |
1590 | } |
1591 | } // exploration ot SubShapes of type <t1> of shape <S1> |
1592 | |
1593 | } // FillShape |
1594 | |
1595 | |
1596 | //======================================================================= |
1597 | //function : FillFace |
1598 | //purpose : |
1599 | //======================================================================= |
1600 | void TopOpeBRepBuild_Builder::FillFace(const TopoDS_Shape& F1, |
1601 | const TopAbs_State ToBuild1, |
1602 | const TopTools_ListOfShape& LF2, |
1603 | const TopAbs_State ToBuild2, |
1604 | TopOpeBRepBuild_WireEdgeSet& WES, |
1605 | const Standard_Boolean RevOri) |
1606 | { |
1607 | #ifdef OCCT_DEBUG |
1608 | Standard_Boolean tSPF = TopOpeBRepBuild_GettraceSPF(); |
1609 | // Standard_Integer iFace = myDataStructure->Shape(F1); |
1610 | if(tSPF){cout<<endl;} |
1611 | if(tSPF){GdumpSHASTA(F1,ToBuild1,"=-= FillFace ");} |
1612 | #endif |
1613 | myListOfFace = LF2; |
1614 | FillShape(F1,ToBuild1,LF2,ToBuild2,WES,RevOri); |
1615 | myListOfFace.Clear(); |
1616 | } // FillFace |
1617 | |
1618 | |
1619 | //======================================================================= |
1620 | //function : FillSolid |
1621 | //purpose : load shells and faces from the solid in the ShellFaceSet <aSet> |
1622 | //======================================================================= |
1623 | void TopOpeBRepBuild_Builder::FillSolid(const TopoDS_Shape& S1, |
1624 | const TopAbs_State ToBuild1, |
1625 | const TopTools_ListOfShape& LS2, |
1626 | const TopAbs_State ToBuild2, |
1627 | TopOpeBRepBuild_ShapeSet& aSet, |
1628 | const Standard_Boolean RevOri) |
1629 | { |
1630 | FillShape(S1,ToBuild1,LS2,ToBuild2,aSet,RevOri); |
1631 | } // FillSolid |
1632 | |
1633 | |
1634 | //======================================================================= |
1635 | //function : FillVertexSet |
1636 | //purpose : private |
1637 | //======================================================================= |
1638 | void TopOpeBRepBuild_Builder::FillVertexSet(TopOpeBRepDS_PointIterator& IT, |
1639 | const TopAbs_State ToBuild, |
1640 | TopOpeBRepBuild_PaveSet& PVS) const |
1641 | { |
1642 | for (; IT.More(); IT.Next()) { |
1643 | FillVertexSetOnValue(IT,ToBuild,PVS); |
1644 | } |
1645 | } |
1646 | |
1647 | |
1648 | //======================================================================= |
1649 | //function : FillVertexSetOnValue |
1650 | //purpose : private |
1651 | //======================================================================= |
1652 | void TopOpeBRepBuild_Builder::FillVertexSetOnValue |
1653 | (const TopOpeBRepDS_PointIterator& IT, |
1654 | const TopAbs_State ToBuild, |
1655 | TopOpeBRepBuild_PaveSet& PVS) const |
1656 | { |
1657 | TopoDS_Shape V; |
1658 | |
1659 | // ind = index of new point or existing vertex |
1660 | Standard_Integer ind = IT.Current(); |
1661 | Standard_Boolean ispoint = IT.IsPoint(); |
1662 | //**! |
1663 | //if (ispoint) V = NewVertex(ind); |
1664 | if (ispoint && ind <= myDataStructure->NbPoints()) V = NewVertex(ind); |
1665 | //**! |
1666 | else V = myDataStructure->Shape(ind); |
1667 | Standard_Real par = IT.Parameter(); |
1668 | TopAbs_Orientation ori = IT.Orientation(ToBuild); |
1669 | |
1670 | Standard_Boolean keep = Standard_True; |
1671 | // if (ori==TopAbs_EXTERNAL || ori==TopAbs_INTERNAL) keep = Standard_False; |
1672 | |
1673 | if ( keep ) { |
1674 | myBuildTool.Orientation(V,ori); |
1675 | Handle(TopOpeBRepBuild_Pave) PV = new TopOpeBRepBuild_Pave(V,par,Standard_False); |
1676 | PVS.Append(PV); |
1677 | } |
1678 | |
1679 | #ifdef OCCT_DEBUG |
1680 | const TopoDS_Edge& EDEB = PVS.Edge(); |
1681 | Standard_Integer iE; Standard_Boolean tSPS = GtraceSPS(EDEB,iE); |
1682 | if (tSPS) { |
1683 | if (keep) cout<<"+"; else cout<<"-"; |
1684 | if (ispoint) cout<<" PDS "; else cout<<" VDS "; |
1685 | cout<<ind<<" : "; GdumpORIPARPNT(ori,par,BRep_Tool::Pnt(TopoDS::Vertex(V))); |
1686 | cout<<endl; |
1687 | } |
1688 | #endif |
1689 | } |