b311480e |
1 | // Created on: 1998-07-28 |
2 | // Created by: LECLERE Florence |
3 | // Copyright (c) 1998-1999 Matra Datavision |
4 | // Copyright (c) 1999-2012 OPEN CASCADE SAS |
5 | // |
6 | // The content of this file is subject to the Open CASCADE Technology Public |
7 | // License Version 6.5 (the "License"). You may not use the content of this file |
8 | // except in compliance with the License. Please obtain a copy of the License |
9 | // at http://www.opencascade.org and read it completely before using this file. |
10 | // |
11 | // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its |
12 | // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France. |
13 | // |
14 | // The Original Code and all software distributed under the License is |
15 | // distributed on an "AS IS" basis, without warranty of any kind, and the |
16 | // Initial Developer hereby disclaims all such warranties, including without |
17 | // limitation, any warranties of merchantability, fitness for a particular |
18 | // purpose or non-infringement. Please see the License for the specific terms |
19 | // and conditions governing the rights and limitations under the License. |
20 | |
7fd59977 |
21 | |
22 | |
23 | #include <TopOpeBRepBuild_FuseFace.hxx> |
24 | |
25 | #include <TopTools_ListOfShape.hxx> |
26 | #include <TopTools_ListIteratorOfListOfShape.hxx> |
27 | #include <TopTools_MapOfShape.hxx> |
28 | |
29 | #include <TopTools_DataMapOfShapeListOfShape.hxx> |
30 | #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx> |
31 | #include <TopTools_DataMapOfShapeInteger.hxx> |
32 | #include <TopTools_DataMapIteratorOfDataMapOfShapeInteger.hxx> |
33 | |
34 | #include <TopExp_Explorer.hxx> |
35 | |
36 | #include <TopoDS.hxx> |
37 | #include <TopoDS_Face.hxx> |
38 | #include <TopoDS_Wire.hxx> |
39 | #include <TopoDS_Edge.hxx> |
40 | |
41 | #include <BRepLib_MakeWire.hxx> |
42 | #include <BRepLib_MakeFace.hxx> |
43 | #include <BRepLib_MakeEdge.hxx> |
44 | |
45 | #include <BRep_Builder.hxx> |
46 | #include <BRep_Tool.hxx> |
47 | #include <BRepCheck_Analyzer.hxx> |
48 | |
49 | #include <Geom_Surface.hxx> |
50 | #include <Geom_RectangularTrimmedSurface.hxx> |
51 | #include <Geom_Curve.hxx> |
52 | #include <Geom_TrimmedCurve.hxx> |
53 | #include <Geom_Line.hxx> |
54 | #include <Geom_Circle.hxx> |
55 | #include <Geom_Ellipse.hxx> |
56 | #include <Geom_BSplineCurve.hxx> |
57 | #include <Geom_BezierCurve.hxx> |
58 | #include <TColgp_Array1OfPnt.hxx> |
59 | #include <TColStd_Array1OfReal.hxx> |
60 | #include <TColStd_Array1OfInteger.hxx> |
61 | #include <ElCLib.hxx> |
62 | #include <Precision.hxx> |
63 | |
64 | #ifdef DEB |
65 | Standard_IMPORT Standard_Boolean TopOpeBRepBuild_GettraceFUFA(); |
66 | #endif |
67 | |
68 | static void GroupShape(TopTools_ListOfShape&, |
69 | Standard_Boolean, |
70 | TopTools_DataMapOfShapeListOfShape&); |
71 | |
72 | static void GroupEdge(TopTools_DataMapOfShapeListOfShape&, |
73 | TopTools_DataMapOfShapeListOfShape&); |
74 | |
75 | static void MakeEdge(TopTools_DataMapOfShapeListOfShape&); |
76 | |
77 | static Standard_Boolean SameSupport(const TopoDS_Edge&, |
78 | const TopoDS_Edge&); |
79 | |
80 | //======================================================================= |
81 | //function : Init |
82 | //purpose : |
83 | //======================================================================= |
84 | void TopOpeBRepBuild_FuseFace::Init(const TopTools_ListOfShape& LIF, |
85 | const TopTools_ListOfShape& LRF, |
86 | const Standard_Integer CXM) |
87 | { |
88 | #ifdef DEB |
89 | Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); |
90 | if (trc) cout << "TopOpeBRepBuild_FuseFace::Init" << endl; |
91 | #endif |
92 | myLIF = LIF; |
93 | myLRF = LRF; |
94 | if(CXM == 1) { |
95 | myInternal = Standard_False; |
96 | } |
97 | else if(CXM == 2) { |
98 | myInternal = Standard_True; |
99 | } // CXM |
100 | #ifdef DEB |
101 | if (trc) { |
102 | if (myInternal) { |
103 | cout << " TopOpeBRepBuild_FuseFace::Init : Keep internal connections" << endl; |
104 | } else { |
105 | cout << " TopOpeBRepBuild_FuseFace::Init : Suppress internal connections" << endl; |
106 | } |
107 | } |
108 | #endif |
109 | |
110 | myLFF.Clear(); |
111 | |
112 | myLIE.Clear(); |
113 | myLEE.Clear(); |
114 | myLME.Clear(); |
115 | |
116 | myLIV.Clear(); |
117 | myLEV.Clear(); |
118 | myLMV.Clear(); |
119 | |
120 | myModified = Standard_False; |
121 | myDone = Standard_False; |
122 | |
123 | } |
124 | |
125 | //======================================================================= |
126 | //function : PerformFace |
127 | //purpose : fusion des faces cosurfaciques, connexes par une ou |
128 | //plusieurs aretes |
129 | //======================================================================= |
130 | |
131 | void TopOpeBRepBuild_FuseFace::PerformFace() |
132 | { |
133 | #ifdef DEB |
134 | Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); |
135 | if (trc) cout << "TopOpeBRepBuild_FuseFace::PerformFace()" << endl; |
136 | #endif |
137 | |
138 | myModified = Standard_False; |
139 | myLFF.Clear(); |
140 | if (myLRF.IsEmpty()) { |
141 | #ifdef DEB |
142 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of reconstructed faces"<<endl; |
143 | #endif |
144 | myModified = Standard_False; |
145 | myDone = Standard_True; |
146 | myLFF = myLRF; |
147 | return; |
148 | } |
149 | |
150 | Standard_Integer number = myLRF.Extent(); |
151 | if (number == 1) { |
152 | #ifdef DEB |
153 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : only 1 reconstructed face"<<endl; |
154 | #endif |
155 | myModified = Standard_False; |
156 | myDone = Standard_True; |
157 | myLFF = myLRF; |
158 | return; |
159 | } |
160 | |
161 | TopTools_ListIteratorOfListOfShape it2,it3,it4; |
162 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt1,itt2,itt3; |
163 | TopAbs_Orientation ori,ori1; |
164 | |
165 | Standard_Boolean Ori3dReversed = Standard_False; |
166 | Standard_Boolean Ori3dForward = Standard_False; |
167 | TopTools_ListOfShape mylist; |
168 | for(it2.Initialize(myLRF); it2.More(); it2.Next()) { |
169 | TopoDS_Shape fac = it2.Value(); |
170 | ori1 = fac.Orientation(); |
171 | if (ori1 == TopAbs_FORWARD) { |
172 | Ori3dForward = Standard_True; |
173 | } |
174 | if (ori1 == TopAbs_REVERSED) { |
175 | Ori3dReversed = Standard_True; |
176 | } |
177 | BRepCheck_Analyzer ana(fac); |
178 | if (!ana.IsValid(fac)) { |
179 | // if (!BRepCheck_Analyzer::IsValid(fac)) { |
180 | #ifdef DEB |
181 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Invalid reconstructed face"<<endl; |
182 | #endif |
183 | myModified = Standard_False; |
184 | myDone = Standard_True; |
185 | myLFF = myLRF; |
186 | return; |
187 | } |
188 | fac.Orientation(TopAbs_FORWARD); |
189 | mylist.Append(fac); |
190 | } |
191 | |
192 | // Orientation 3d de l'espace limite par la face |
193 | if (Ori3dForward && Ori3dReversed) { |
194 | #ifdef DEB |
195 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Bad faces 3d orientation"<<endl; |
196 | #endif |
197 | myModified = Standard_False; |
198 | myDone = Standard_True; |
199 | myLFF = myLRF; |
200 | return; |
201 | } |
202 | |
203 | // listes de faces avec edges communes. |
204 | Standard_Boolean Keep_Edge; |
205 | Keep_Edge = Standard_False; |
206 | TopTools_DataMapOfShapeListOfShape mapFacLFac; |
207 | GroupShape(mylist,Keep_Edge,mapFacLFac); |
208 | if (mapFacLFac.IsEmpty()) { |
209 | #ifdef DEB |
210 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of faces"<<endl; |
211 | #endif |
212 | myModified = Standard_False; |
213 | myDone = Standard_True; |
214 | myLFF = myLRF; |
215 | return; |
216 | } |
217 | Standard_Integer n1 = myLRF.Extent(); |
218 | Standard_Integer n2 = mapFacLFac.Extent(); |
219 | if (n1 == n2) { |
220 | #ifdef DEB |
221 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : No connection"<<endl; |
222 | #endif |
223 | myModified = Standard_False; |
224 | myDone = Standard_True; |
225 | myLFF = myLRF; |
226 | return; |
227 | } |
228 | |
229 | |
230 | //boucle sur les listes des faces de 1 face de LRF |
231 | |
232 | for (itt1.Initialize(mapFacLFac); itt1.More(); itt1.Next()) { |
233 | const TopoDS_Shape& fac = itt1.Key(); |
234 | TopoDS_Face facref = TopoDS::Face(fac); |
235 | const TopTools_ListOfShape& LFac = mapFacLFac.Find(fac); |
236 | |
237 | Standard_Integer n11 = LFac.Extent(); |
238 | if (n11 != 1) { |
239 | TopTools_ListOfShape LWir; |
240 | for(it2.Initialize(LFac); it2.More(); it2.Next()) { |
241 | const TopoDS_Shape& fac1 = it2.Value(); |
242 | |
243 | TopExp_Explorer exp; |
244 | for (exp.Init(fac1,TopAbs_WIRE); exp.More(); exp.Next()) { |
245 | const TopoDS_Shape& wir = exp.Current(); |
246 | LWir.Append(wir); |
247 | } |
248 | } // LFac |
249 | // listes des wires avec edges communes. |
250 | Keep_Edge = Standard_False; |
251 | TopTools_DataMapOfShapeListOfShape mapWirLWir; |
252 | GroupShape(LWir,Keep_Edge,mapWirLWir); |
253 | if (mapWirLWir.IsEmpty()) { |
254 | #ifdef DEB |
255 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of wires"<<endl; |
256 | #endif |
257 | myModified = Standard_False; |
258 | myDone = Standard_True; |
259 | myLFF = myLRF; |
260 | return; |
261 | } |
262 | |
263 | // boucle sur les listes des wires de 1 face de LRF |
264 | TopTools_ListOfShape myFaceLIE,myFaceLEE,myFaceLME,myFaceLW; |
265 | for (itt2.Initialize(mapWirLWir); itt2.More(); itt2.Next()) { |
266 | const TopoDS_Shape& wir = itt2.Key(); |
267 | const TopTools_ListOfShape& LWir1 = mapWirLWir.Find(wir); |
268 | |
269 | Standard_Integer n22 = LWir1.Extent(); |
270 | if (n22 != 1) { |
271 | // boucle sur 1 liste des wires avec edges communes. |
272 | TopTools_ListOfShape LEdg; |
273 | for(it3.Initialize(LWir1); it3.More(); it3.Next()) { |
274 | const TopoDS_Shape& wir1 = it3.Value(); |
275 | |
276 | TopExp_Explorer exp; |
277 | for (exp.Init(wir1,TopAbs_EDGE); exp.More(); exp.Next()) { |
278 | const TopoDS_Shape& edg = exp.Current(); |
279 | LEdg.Append(edg); |
280 | } |
281 | } // LWir1 |
282 | // listes des edges avec edges communes. |
283 | Keep_Edge = Standard_True; |
284 | TopTools_DataMapOfShapeListOfShape mapEdgLEdg; |
285 | GroupShape(LEdg,Keep_Edge,mapEdgLEdg); |
286 | if (mapEdgLEdg.IsEmpty()) { |
287 | #ifdef DEB |
288 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of edges"<<endl; |
289 | #endif |
290 | myModified = Standard_False; |
291 | myDone = Standard_True; |
292 | myLFF = myLRF; |
293 | return; |
294 | } |
295 | |
296 | // Elimination selon logique pure |
297 | // boucle sur les listes des egdes de 1 wire de 1 face de LRF |
298 | TopTools_ListOfShape myWireLE; |
299 | for (itt3.Initialize(mapEdgLEdg); itt3.More(); itt3.Next()) { |
300 | const TopoDS_Shape& edg = itt3.Key(); |
301 | ori = edg.Orientation(); |
302 | const TopTools_ListOfShape& LEdg1 = mapEdgLEdg.Find(edg); |
303 | Standard_Boolean OriReversed = Standard_False; |
304 | Standard_Boolean OriForward = Standard_False; |
305 | Standard_Boolean OriInternal = Standard_False; |
306 | Standard_Boolean OriExternal = Standard_False; |
307 | for(it4.Initialize(LEdg1); it4.More(); it4.Next()) { |
308 | const TopoDS_Shape& edg1 = it4.Value(); |
309 | ori1 = edg1.Orientation(); |
310 | if (ori1 == TopAbs_REVERSED) { |
311 | if (OriReversed) { |
312 | #ifdef DEB |
313 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Bad faces orientation"<<endl; |
314 | #endif |
315 | myModified = Standard_False; |
316 | myDone = Standard_True; |
317 | myLFF = myLRF; |
318 | return; |
319 | } |
320 | OriReversed = Standard_True; |
321 | } |
322 | else if (ori1 == TopAbs_FORWARD) { |
323 | if (OriForward) { |
324 | #ifdef DEB |
325 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Bad faces orientation"<<endl; |
326 | #endif |
327 | myModified = Standard_False; |
328 | myDone = Standard_True; |
329 | myLFF = myLRF; |
330 | return; |
331 | } |
332 | OriForward = Standard_True; |
333 | } |
334 | else if (ori1 == TopAbs_INTERNAL) { |
335 | OriInternal = Standard_True; |
336 | } |
337 | else if (ori1 == TopAbs_EXTERNAL) { |
338 | OriExternal = Standard_True; |
339 | } |
340 | } // LEdg1 |
341 | |
342 | // - Traitement edge selon orientation |
343 | // On privilegie orientation selon 1) reversed ou forward |
344 | // 2) internal |
345 | // 3) external |
346 | // pour traiter cas ou l'on a au moins 2 orientations differentes parmi |
347 | // forward et reversed - interne - externe |
348 | |
349 | if (OriReversed || OriForward) { |
350 | if (OriReversed && OriForward) { |
351 | // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_INTERNAL); |
352 | const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_INTERNAL); |
353 | myLME.Append(edg1); |
354 | myFaceLME.Append(edg1); |
355 | } else if (OriReversed) { |
356 | // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_REVERSED); |
357 | const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_REVERSED); |
358 | myWireLE.Append(edg1); |
359 | } else { |
360 | // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_FORWARD); |
361 | const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_FORWARD); |
362 | myWireLE.Append(edg1); |
363 | } |
364 | } |
365 | else if (OriInternal) { |
366 | // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_INTERNAL); |
367 | const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_INTERNAL); |
368 | myLIE.Append(edg1); |
369 | myFaceLIE.Append(edg1); |
370 | } |
371 | else if (OriExternal) { |
372 | // TopoDS_Shape& edg1 = edg.Oriented(TopAbs_EXTERNAL); |
373 | const TopoDS_Shape& edg1 = edg.Oriented(TopAbs_EXTERNAL); |
374 | myLEE.Append(edg1); |
375 | myFaceLEE.Append(edg1); |
376 | } // Ori |
377 | } // mapEdgLEdg |
378 | |
379 | // Reconstrution de 1 wire de 1 face de LRF |
380 | // Attention cas ou une liste de wire connectes conduit a plusieurs Wires |
381 | Standard_Integer number1 = myWireLE.Extent(); |
382 | while (number1 > 0) { |
383 | BRepLib_MakeWire MW; |
384 | MW.Add(myWireLE); |
385 | if (!MW.IsDone()) { |
386 | #ifdef DEB |
387 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Failure in making wire"<<endl; |
388 | #endif |
389 | myModified = Standard_False; |
390 | myDone = Standard_True; |
391 | myLFF = myLRF; |
392 | return; |
393 | } |
394 | |
395 | // Astuce pour contourner Wire Not Closed |
396 | TopoDS_Wire W = MW.Wire(); |
397 | BRepLib_MakeWire MW1(W); |
398 | W = MW1.Wire(); |
399 | |
400 | myFaceLW.Append(W); |
401 | |
402 | TopExp_Explorer exp; |
403 | TopTools_MapOfShape M; |
404 | Standard_Integer nb = 0; |
405 | for (exp.Init(W,TopAbs_EDGE); exp.More(); exp.Next()) { |
406 | const TopoDS_Shape& edg3 = exp.Current(); |
407 | M.Add(edg3); |
408 | nb++; |
409 | } |
410 | |
411 | if (nb == number1) { |
412 | number1 = 0 ; |
413 | } |
414 | else { |
415 | TopTools_ListOfShape ListEdge; |
416 | for(it3.Initialize(myWireLE); it3.More(); it3.Next()) { |
417 | const TopoDS_Shape& edg2 = it3.Value(); |
418 | if (M.Add(edg2)) { |
419 | ListEdge.Append(edg2); |
420 | } |
421 | } |
422 | myWireLE.Assign(ListEdge); |
423 | number1 = myWireLE.Extent(); |
424 | } // nb |
425 | } // number |
426 | } |
427 | else { |
428 | myFaceLW.Append(wir); |
429 | } // n2 =1 |
430 | } // mapWirLWir |
431 | |
432 | // Reconstrution de 1 face de LRF |
433 | Handle(Geom_Surface) S = BRep_Tool::Surface(facref); |
434 | if (S->DynamicType() == |
435 | STANDARD_TYPE(Geom_RectangularTrimmedSurface)) { |
436 | S = Handle(Geom_RectangularTrimmedSurface):: |
437 | DownCast(S)->BasisSurface(); |
438 | } |
1c72dff6 |
439 | BRepLib_MakeFace MF(S, Precision::Confusion()); |
7fd59977 |
440 | |
441 | for(it2.Initialize(myFaceLW); it2.More(); it2.Next()) { |
442 | const TopoDS_Wire& wir1 = TopoDS::Wire(it2.Value()); |
443 | MF.Add(wir1); |
444 | } |
445 | |
446 | // Ajout des Edges Internes |
447 | // Externes |
448 | // Modifiees |
449 | for (it2.Initialize(myFaceLIE); it2.More(); it2.Next()) { |
450 | const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value()); |
451 | BRepLib_MakeWire MW(edg1); |
452 | // MW.Add(edg1); |
453 | const TopoDS_Wire& W = MW.Wire(); |
454 | MF.Add(W); |
455 | } |
456 | for (it2.Initialize(myFaceLEE); it2.More(); it2.Next()) { |
457 | const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value()); |
458 | BRepLib_MakeWire MW(edg1); |
459 | // MW.Add(edg1); |
460 | const TopoDS_Wire& W = MW.Wire(); |
461 | MF.Add(W); |
462 | } |
463 | if (myInternal) { |
464 | for (it2.Initialize(myFaceLME); it2.More(); it2.Next()) { |
465 | const TopoDS_Edge& edg1 = TopoDS::Edge(it2.Value()); |
466 | BRepLib_MakeWire MW(edg1); |
467 | // MW.Add(edg1); |
468 | const TopoDS_Wire& W = MW.Wire(); |
469 | MF.Add(W); |
470 | } |
471 | } |
472 | |
473 | if (!MF.IsDone()) { |
474 | #ifdef DEB |
475 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Failure in making face"<<endl; |
476 | #endif |
477 | myModified = Standard_False; |
478 | myDone = Standard_True; |
479 | myLFF = myLRF; |
480 | return; |
481 | } |
482 | TopoDS_Face F = MF.Face(); |
483 | if (Ori3dReversed) { |
484 | F.Reverse(); |
485 | } |
486 | myLFF.Append(F); |
487 | } |
488 | else { |
489 | myLFF.Append(facref); |
490 | } // n1 = 1 |
491 | } // mapFacLFac |
492 | |
493 | if (myLFF.IsEmpty()) { |
494 | #ifdef DEB |
495 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::PerformFace : Empty list of fusionned faces"<<endl; |
496 | #endif |
497 | myModified = Standard_False; |
498 | myDone = Standard_True; |
499 | myLFF = myLRF; |
500 | return; |
501 | } |
502 | |
503 | myModified = Standard_True; |
504 | myDone = Standard_True; |
505 | |
506 | #ifdef DEB |
507 | if (trc) cout << " TopOpeBRepBuild_FuseFace::PerformFace() : Done" << endl; |
508 | #endif |
509 | } |
510 | |
511 | //======================================================================= |
512 | //function : PerformEdge |
513 | //purpose : fusion des edges cosurfaciques, connexes par une ou |
514 | //plusieurs aretes |
515 | //======================================================================= |
516 | |
517 | void TopOpeBRepBuild_FuseFace::PerformEdge() |
518 | { |
519 | #ifdef DEB |
520 | Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); |
521 | if (trc) cout << "TopOpeBRepBuild_FuseFace::PerformEdge()" << endl; |
522 | #endif |
523 | TopTools_DataMapOfShapeListOfShape mapVerLEdg,mapTampon; |
524 | |
525 | TopTools_ListIteratorOfListOfShape it1; |
526 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt1; |
527 | // TopAbs_Orientation ori,ori1; |
528 | |
529 | //Niveau 1 |
530 | //boucle sur les listes des faces de 1 face de LRF |
531 | |
532 | for (it1.Initialize(myLFF); it1.More(); it1.Next()) { |
533 | const TopoDS_Shape& fac = it1.Value(); |
534 | |
535 | TopExp_Explorer expw; |
536 | for (expw.Init(fac,TopAbs_WIRE); expw.More(); expw.Next()) { |
537 | const TopoDS_Shape& wir = expw.Current(); |
538 | |
539 | TopExp_Explorer expe; |
540 | for (expe.Init(wir,TopAbs_EDGE); expe.More(); expe.Next()) { |
541 | const TopoDS_Shape& edg = expe.Current(); |
542 | |
543 | TopExp_Explorer expv; |
544 | for (expv.Init(edg,TopAbs_VERTEX); expv.More(); expv.Next()) { |
545 | const TopoDS_Shape& ver = expv.Current(); |
546 | if (!mapVerLEdg.IsBound(ver)) { |
547 | TopTools_ListOfShape LmapEdg; |
548 | LmapEdg.Append(edg); |
549 | mapVerLEdg.Bind(ver,LmapEdg); |
550 | } |
551 | else { |
552 | TopTools_ListOfShape& LmapEdg = mapVerLEdg.ChangeFind(ver); |
553 | LmapEdg.Append(edg); |
554 | } |
555 | } |
556 | } |
557 | } |
558 | } |
559 | |
560 | //nettoyage du tableau mapVerLSh : shap1 : shap1 shap2 shap3 |
561 | //On ne garde que les vertex qui appartiennent a - exactement 2 edges |
562 | // - de meme support geometrique |
563 | mapTampon = mapVerLEdg; |
564 | mapVerLEdg.Clear(); |
565 | |
566 | for (itt1.Initialize(mapTampon); itt1.More(); itt1.Next()) { |
567 | const TopoDS_Shape& ver = itt1.Key(); |
568 | const TopTools_ListOfShape& LmapEdg = mapTampon.Find(ver); |
569 | Standard_Integer number = LmapEdg.Extent(); |
570 | if (number == 2){ |
571 | it1.Initialize(LmapEdg); |
572 | const TopoDS_Edge& edg1 = TopoDS::Edge(it1.Value()); |
573 | it1.Next(); |
574 | const TopoDS_Edge& edg2 = TopoDS::Edge(it1.Value()); |
575 | if (SameSupport(edg1,edg2)) { |
576 | mapVerLEdg.Bind(ver,LmapEdg); |
577 | } |
578 | } |
579 | } |
580 | |
581 | //On regroupe ensemble tous les edges consecutifs et SameSupport |
582 | TopTools_DataMapOfShapeListOfShape mapEdgLEdg; |
583 | GroupEdge(mapVerLEdg,mapEdgLEdg); |
584 | |
585 | //On construit les edges somme des edges consecutifs et SameSupport |
586 | MakeEdge(mapEdgLEdg); |
587 | |
588 | myModified = Standard_True; |
589 | myDone = Standard_True; |
590 | |
591 | #ifdef DEB |
592 | if (trc) cout << " TopOpeBRepBuild_FuseFace::PerformEdge() : Done" << endl; |
593 | #endif |
594 | } |
595 | |
596 | //======================================================================= |
597 | //function : ClearEdge |
598 | //purpose : Nettoyage des Faces : Suppression des edges internes et externes |
599 | //======================================================================= |
600 | |
601 | void TopOpeBRepBuild_FuseFace::ClearEdge() |
602 | { |
603 | #ifdef DEB |
604 | Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); |
605 | if (trc) cout << "TopOpeBRepBuild_FuseFace::ClearEdge()" << endl; |
606 | #endif |
607 | |
608 | TopTools_ListIteratorOfListOfShape it1,it2; |
609 | TopAbs_Orientation ori; |
610 | TopTools_ListOfShape myLFFnew; |
611 | |
612 | //Niveau 1 |
613 | //boucle sur les listes des faces de 1 face de LRF |
614 | |
615 | for (it1.Initialize(myLFF); it1.More(); it1.Next()) { |
616 | const TopoDS_Shape& fac = it1.Value(); |
617 | |
618 | TopTools_ListOfShape myFaceLW; |
619 | TopExp_Explorer expw; |
620 | for (expw.Init(fac,TopAbs_WIRE); expw.More(); expw.Next()) { |
621 | const TopoDS_Shape& wir = expw.Current(); |
622 | |
623 | TopTools_ListOfShape myWireLE; |
624 | TopExp_Explorer expe; |
625 | for (expe.Init(wir,TopAbs_EDGE); expe.More(); expe.Next()) { |
626 | const TopoDS_Shape& edg = expe.Current(); |
627 | |
628 | // Elimination selon des edges interne et externe |
629 | |
630 | ori = edg.Orientation(); |
631 | if (ori == TopAbs_INTERNAL) { |
632 | myLIE.Append(edg); |
633 | } |
634 | else if (ori == TopAbs_EXTERNAL) { |
635 | myLEE.Append(edg); |
636 | } |
637 | else { |
638 | myWireLE.Append(edg); |
639 | } |
640 | } |
641 | // Fin Niveau 3 |
642 | // Reconstrution de 1 wire de 1 face de LRF |
643 | if (!myWireLE.IsEmpty()) { |
644 | BRepLib_MakeWire MW; |
645 | MW.Add(myWireLE); |
646 | if (!MW.IsDone()) { |
647 | #ifdef DEB |
648 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::ClearEdge : Failure in making wire"<<endl; |
649 | #endif |
650 | myModified = Standard_False; |
651 | myDone = Standard_True; |
652 | myLFF = myLRF; |
653 | return; |
654 | } |
655 | |
656 | // Astuce pour contourner Wire Not Closed |
657 | TopoDS_Wire W = MW.Wire(); |
658 | BRepLib_MakeWire MW1(W); |
659 | W = MW1.Wire(); |
660 | |
661 | myFaceLW.Append(W); |
662 | } |
663 | } |
664 | // Fin Niveau 2 |
665 | // Reconstrution de 1 face de LRF |
666 | if (myFaceLW.IsEmpty()) { |
667 | #ifdef DEB |
668 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::ClearEdge : Empty list of wires"<<endl; |
669 | #endif |
670 | myModified = Standard_False; |
671 | myDone = Standard_True; |
672 | myLFF = myLRF; |
673 | return; |
674 | } |
675 | it2.Initialize(myFaceLW); |
676 | const TopoDS_Wire& wir = TopoDS::Wire(it2.Value()); |
677 | const Standard_Boolean OnlyPlane = Standard_False; |
678 | BRepLib_MakeFace MF(wir,OnlyPlane); |
679 | |
680 | it2.Next(); |
681 | for( ; it2.More(); it2.Next()) { |
682 | const TopoDS_Wire& wir1 = TopoDS::Wire(it2.Value()); |
683 | MF.Add(wir1); |
684 | } |
685 | if (!MF.IsDone()) { |
686 | #ifdef DEB |
687 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::ClearEdge : Failure in making face"<<endl; |
688 | #endif |
689 | myModified = Standard_False; |
690 | myDone = Standard_True; |
691 | myLFF = myLRF; |
692 | return; |
693 | } |
694 | const TopoDS_Face& F = MF.Face(); |
695 | myLFFnew.Append(F); |
696 | } |
697 | //Fin Niveau 1 |
698 | if (myLFFnew.IsEmpty()) { |
699 | #ifdef DEB |
700 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::ClearEdge : Empty list of fusionned faces"<<endl; |
701 | #endif |
702 | myModified = Standard_False; |
703 | myDone = Standard_True; |
704 | myLFF = myLRF; |
705 | return; |
706 | } |
707 | myLFF = myLFFnew; |
708 | |
709 | myModified = Standard_True; |
710 | myDone = Standard_True; |
711 | |
712 | #ifdef DEB |
713 | if (trc) cout << " TopOpeBRepBuild_FuseFace::ClearEdge() : Done" << endl; |
714 | #endif |
715 | } |
716 | |
717 | //======================================================================= |
718 | //function : ClearVertex |
719 | //purpose : Nettoyage des Faces : Suppression des vertex internes et externes |
720 | //======================================================================= |
721 | |
722 | void TopOpeBRepBuild_FuseFace::ClearVertex() |
723 | { |
724 | #ifdef DEB |
725 | Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); |
726 | if (trc) cout << "TopOpeBRepBuild_FuseFace::ClearVertex()" << endl; |
727 | #endif |
728 | |
729 | #ifdef DEB |
730 | if (trc) cout << " TopOpeBRepBuild_FuseFace::ClearVertex() : Done" << endl; |
731 | #endif |
732 | } |
733 | |
734 | //======================================================================= |
735 | //function : GroupShape |
736 | //purpose : |
737 | //======================================================================= |
738 | |
739 | static void GroupShape(TopTools_ListOfShape& mylist,Standard_Boolean Keep_Edge, TopTools_DataMapOfShapeListOfShape& mymapShLSh) |
740 | { |
741 | TopTools_ListIteratorOfListOfShape it,it1,it2; |
742 | TopTools_DataMapOfShapeListOfShape mapEdgLSh,mapShLSh; |
743 | TopTools_ListOfShape LmapSh4; |
744 | TopAbs_Orientation ori; |
745 | |
746 | // construction du tableau C=locmapEdgLSh : egde1 - shap1 shap2 shap3 |
747 | // construction du tableau locmapShLSh : shap1 - shap1 shap2 shap3 |
748 | LmapSh4.Clear(); |
749 | for(it.Initialize(mylist); it.More(); it.Next()) { |
750 | const TopoDS_Shape& shap1 = it.Value(); |
751 | TopTools_ListOfShape LmapSh; |
752 | LmapSh.Append(shap1); |
753 | |
754 | mapShLSh.Bind(shap1,LmapSh); |
755 | |
756 | TopExp_Explorer expe; |
757 | for (expe.Init(shap1,TopAbs_EDGE); expe.More(); expe.Next()) { |
758 | const TopoDS_Shape& edg1 = expe.Current(); |
759 | // verification si Edge a prendre en compte |
760 | ori = edg1.Orientation(); |
761 | Standard_Boolean Edge_OK = Standard_True; |
762 | if (ori == TopAbs_INTERNAL || ori == TopAbs_EXTERNAL) { |
763 | Edge_OK = Standard_False; |
764 | } |
765 | if (Edge_OK || Keep_Edge) { |
766 | if (!mapEdgLSh.IsBound(edg1)) { |
767 | TopTools_ListOfShape LmapEdg; |
768 | LmapEdg.Append(shap1); |
769 | mapEdgLSh.Bind(edg1,LmapEdg); |
770 | } |
771 | else { |
772 | TopTools_ListOfShape& LmapEdg = mapEdgLSh.ChangeFind(edg1); |
773 | LmapEdg.Append(shap1); |
774 | |
775 | if (!Keep_Edge) { |
776 | |
777 | // Recuperation premier shape de liste liee a edg1 |
778 | it1.Initialize(LmapEdg); |
779 | const TopoDS_Shape& shap2 = it1.Value(); |
780 | |
781 | // Controle si premier shape et shape courant sont deja lies |
782 | TopTools_ListOfShape LmapSh1; |
783 | LmapSh1 = mapShLSh.Find(shap2); |
784 | for(it1.Initialize(LmapSh1); it1.More(); it1.Next()) { |
785 | const TopoDS_Shape& shap = it1.Value(); |
786 | if (shap.IsSame(shap1)) { |
787 | break; |
788 | } |
789 | } |
790 | // Premier shape et Shape courant ne sont pas deja lies |
791 | if (!it1.More()){ |
792 | const TopTools_ListOfShape& LmapSh11 = mapShLSh.Find(shap1); |
793 | const TopTools_ListOfShape& LmapSh2 = mapShLSh.Find(shap2); |
794 | TopTools_ListOfShape Lmap1; |
795 | TopTools_ListOfShape Lmap2; |
796 | Lmap1.Assign(LmapSh11); |
797 | Lmap2.Assign(LmapSh2); |
798 | |
799 | for(it2.Initialize(Lmap1); it2.More(); it2.Next()) { |
800 | const TopoDS_Shape& shap = it2.Value(); |
801 | TopTools_ListOfShape& Lmap = mapShLSh.ChangeFind(shap); |
802 | TopTools_ListOfShape Lmap3; |
803 | Lmap3.Assign(Lmap2); |
804 | Lmap.Append(Lmap3); |
805 | } |
806 | for(it2.Initialize(Lmap2); it2.More(); it2.Next()) { |
807 | const TopoDS_Shape& shap = it2.Value(); |
808 | TopTools_ListOfShape& Lmap = mapShLSh.ChangeFind(shap); |
809 | TopTools_ListOfShape Lmap3; |
810 | Lmap3.Assign(Lmap1); |
811 | Lmap.Append(Lmap3); |
812 | } |
813 | } |
814 | } |
815 | } |
816 | } |
817 | } |
818 | } |
819 | |
820 | // nettoyage du tableau mapShLSh : shap1 : shap1 shap2 shap3 |
821 | mymapShLSh.Clear(); |
822 | |
823 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt; |
824 | if (!Keep_Edge) { |
825 | TopTools_MapOfShape M; |
826 | for (itt.Initialize(mapShLSh); itt.More(); itt.Next()) { |
827 | const TopoDS_Shape& shap1 = itt.Key(); |
828 | if (M.Add(shap1)) { |
829 | const TopTools_ListOfShape& LmapSh = mapShLSh.Find(shap1); |
830 | mymapShLSh.Bind(shap1,LmapSh); |
831 | |
832 | for(it1.Initialize(LmapSh); it1.More(); it1.Next()) { |
833 | const TopoDS_Shape& shap2 = it1.Value(); |
834 | M.Add(shap2); |
835 | } |
836 | } |
837 | } |
838 | } |
839 | else { |
840 | mymapShLSh = mapEdgLSh; |
841 | } |
842 | } |
843 | |
844 | //======================================================================= |
845 | //function : GroupEdge |
846 | //purpose : |
847 | //======================================================================= |
848 | |
849 | static void GroupEdge(TopTools_DataMapOfShapeListOfShape& mymapVerLEdg, TopTools_DataMapOfShapeListOfShape& mymapEdgLEdg) |
850 | { |
851 | TopTools_ListIteratorOfListOfShape it1,it2; |
852 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt; |
853 | TopTools_DataMapOfShapeListOfShape mapEdgLEdg; |
854 | |
855 | // construction du tableau C=locmapEdgLSh : egde1 - shap1 shap2 shap3 |
856 | // construction du tableau locmapShLSh : shap1 - shap1 shap2 shap3 |
857 | for(itt.Initialize(mymapVerLEdg); itt.More(); itt.Next()) { |
858 | const TopoDS_Shape& ver1 = itt.Key(); |
859 | TopTools_ListOfShape LmapEdg; |
860 | LmapEdg = mymapVerLEdg.Find(ver1); |
861 | |
862 | it1.Initialize(LmapEdg); |
863 | const TopoDS_Edge& edg1 = TopoDS::Edge(it1.Value()); |
864 | it1.Next(); |
865 | const TopoDS_Edge& edg2 = TopoDS::Edge(it1.Value()); |
866 | |
867 | Standard_Boolean Edge1Add,Edge2Add; |
868 | TopoDS_Edge edgold,edgnew; |
869 | if (mapEdgLEdg.IsBound(edg1)) { |
870 | Edge1Add = Standard_False; |
871 | edgold = edg1; |
872 | } else { |
873 | Edge1Add = Standard_True; |
874 | edgnew = edg1; |
875 | } |
876 | if (mapEdgLEdg.IsBound(edg2)) { |
877 | Edge2Add = Standard_False; |
878 | edgold = edg2; |
879 | } else { |
880 | Edge2Add = Standard_True; |
881 | edgnew = edg2; |
882 | } |
883 | |
884 | if (!(Edge1Add || Edge2Add)) { |
885 | continue; |
886 | } |
887 | else if (Edge1Add && Edge2Add) { |
888 | mapEdgLEdg.Bind(edg1,LmapEdg); |
889 | mapEdgLEdg.Bind(edg2,LmapEdg); |
890 | } |
891 | else { |
892 | |
893 | |
894 | // Recuperation premier shape de liste liee a edg1 et mise a jour |
895 | |
896 | TopTools_ListOfShape LmapEdg11; |
897 | LmapEdg11.Append(edgnew); |
898 | mapEdgLEdg.Bind(edgnew,LmapEdg11); |
899 | |
900 | TopTools_ListOfShape LmapEdg1; |
901 | LmapEdg1 = mapEdgLEdg.Find(edgold); |
902 | |
903 | for(it2.Initialize(LmapEdg1); it2.More(); it2.Next()) { |
904 | const TopoDS_Shape& edg22 = it2.Value(); |
905 | TopTools_ListOfShape& LmapEdg2 = mapEdgLEdg.ChangeFind(edgnew); |
906 | LmapEdg2.Append(edg22); |
907 | TopTools_ListOfShape& LmapEdg3 = mapEdgLEdg.ChangeFind(edg22); |
908 | LmapEdg3.Append(edgnew); |
909 | } |
910 | } |
911 | } |
912 | |
913 | // nettoyage du tableau mapEdgLedg : edg1 : edg1 edg2 edg3 |
914 | |
915 | TopTools_MapOfShape M; |
916 | |
917 | for (itt.Initialize(mapEdgLEdg); itt.More(); itt.Next()) { |
918 | const TopoDS_Shape& edg1 = itt.Key(); |
919 | if (M.Add(edg1)) { |
920 | const TopTools_ListOfShape& LmapEdg = mapEdgLEdg.Find(edg1); |
921 | mymapEdgLEdg.Bind(edg1,LmapEdg); |
922 | |
923 | for(it1.Initialize(LmapEdg); it1.More(); it1.Next()) { |
924 | const TopoDS_Shape& edg2 = it1.Value(); |
925 | M.Add(edg2); |
926 | } |
927 | } |
928 | } |
929 | } |
930 | |
931 | //======================================================================= |
932 | //function : MakeEdge |
933 | //purpose : |
934 | //======================================================================= |
935 | |
936 | static void MakeEdge(TopTools_DataMapOfShapeListOfShape& mymapEdgLEdg) |
937 | { |
938 | #ifdef DEB |
939 | Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); |
940 | #endif |
941 | |
942 | TopTools_ListIteratorOfListOfShape it; |
943 | TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itt1; |
944 | TopTools_DataMapIteratorOfDataMapOfShapeInteger itt2; |
945 | TopTools_DataMapOfShapeListOfShape mapEdgLEdg; |
946 | |
947 | // construction du tableau C=locmapEdgLSh : egde1 - shap1 shap2 shap3 |
948 | // construction du tableau locmapShLSh : shap1 - shap1 shap2 shap3 |
949 | for(itt1.Initialize(mymapEdgLEdg); itt1.More(); itt1.Next()) { |
950 | const TopoDS_Shape& edg1 = itt1.Key(); |
951 | TopTools_ListOfShape LmapEdg; |
952 | LmapEdg = mymapEdgLEdg.Find(edg1); |
953 | TopTools_DataMapOfShapeInteger mapVerInt; |
954 | |
955 | Standard_Integer VertexExtrem; |
956 | TopoDS_Vertex V1,V2; |
957 | for(it.Initialize(LmapEdg); it.More(); it.Next()) { |
958 | const TopoDS_Edge& edg2 = TopoDS::Edge(it.Value()); |
959 | |
960 | TopExp_Explorer expv; |
961 | for (expv.Init(edg2,TopAbs_VERTEX); expv.More(); expv.Next()) { |
962 | const TopoDS_Shape& ver = expv.Current(); |
963 | |
964 | VertexExtrem = 1; |
965 | if (mapVerInt.IsBound(ver)) { |
966 | VertexExtrem = 0; |
967 | } |
968 | mapVerInt.Bind(ver,VertexExtrem); |
969 | |
970 | } |
971 | } |
972 | |
973 | TopTools_ListOfShape myEdgeLV,myEdgeLMV; |
974 | for(itt2.Initialize(mapVerInt); itt2.More(); itt2.Next()) { |
975 | const TopoDS_Shape& ver = itt2.Key(); |
976 | VertexExtrem = mapVerInt.Find(ver); |
977 | if (VertexExtrem == 1) { |
978 | myEdgeLV.Append(ver); |
979 | } |
980 | else { |
981 | // TopoDS_Shape& ver1 = ver.Oriented(TopAbs_INTERNAL); |
982 | const TopoDS_Shape& ver1 = ver.Oriented(TopAbs_INTERNAL); |
983 | myEdgeLMV.Append(ver1); |
984 | } |
985 | } |
986 | Standard_Integer number = myEdgeLV.Extent(); |
987 | if (!(number == 2)){ |
988 | #ifdef DEB |
989 | if (trc) cout<<" TopOpeBRepBuild_FuseFace::MakeEdge : Failure in reconstructing new edge"<<endl; |
990 | #endif |
991 | return; |
992 | } |
993 | it.Initialize(myEdgeLV); |
994 | const TopoDS_Vertex& ver1 = TopoDS::Vertex(it.Value()); |
995 | // TopoDS_Shape& verf = ver1.Oriented(TopAbs_FORWARD); |
996 | const TopoDS_Shape& verf = ver1.Oriented(TopAbs_FORWARD); |
997 | it.Next(); |
998 | const TopoDS_Vertex& ver2 = TopoDS::Vertex(it.Value()); |
999 | // TopoDS_Shape& verl = ver2.Oriented(TopAbs_FORWARD); |
1000 | const TopoDS_Shape& verl = ver2.Oriented(TopAbs_FORWARD); |
1001 | |
1002 | Handle(Geom_Curve) curv; |
1003 | const TopoDS_Edge& edg = TopoDS::Edge(edg1); |
1004 | TopLoc_Location loc; |
1005 | Standard_Real first,last; |
1006 | curv = BRep_Tool::Curve(edg,loc,first,last); |
1007 | |
1008 | BRepLib_MakeEdge ME(curv,TopoDS::Vertex(verf),TopoDS::Vertex(verl)); |
1009 | const TopoDS_Edge& edgnew = ME.Edge(); |
1010 | |
1011 | // if (myInternal) { |
1012 | // for (it.Initialize(myEdgeLMV); it.More(); it.Next()) { |
1013 | // const TopoDS_Vertex& ver1 = TopoDS::Vertex(it.Value()); |
1014 | // BRep_Builder B; |
1015 | // B.MakeEdge(edgnew); |
1016 | // B.Add(edgnew,ver1); |
1017 | // } |
1018 | // } |
1019 | mapEdgLEdg.Bind(edgnew,LmapEdg); |
1020 | |
1021 | } |
1022 | mymapEdgLEdg = mapEdgLEdg; |
1023 | } |
1024 | |
1025 | //======================================================================= |
1026 | //function : SameSupport |
1027 | //purpose : Edges SameSupport ou pas |
1028 | //======================================================================= |
1029 | |
1030 | Standard_Boolean SameSupport(const TopoDS_Edge& E1, |
1031 | const TopoDS_Edge& E2) |
1032 | { |
1033 | #ifdef DEB |
1034 | Standard_Boolean trc = TopOpeBRepBuild_GettraceFUFA(); |
1035 | #endif |
1036 | |
1037 | if (E1.IsNull() || E2.IsNull()) { |
1038 | return Standard_False; |
1039 | } |
1040 | |
1041 | |
1042 | Handle(Geom_Curve) C1,C2; |
1043 | TopLoc_Location loc; |
1044 | Standard_Real f1,l1,f2,l2; |
1045 | Handle(Standard_Type) typC1,typC2; |
1046 | |
1047 | C1 = BRep_Tool::Curve(E1,loc,f1,l1); |
1048 | if (!loc.IsIdentity()) { |
1049 | Handle(Geom_Geometry) GG1 = C1->Transformed(loc.Transformation()); |
1050 | C1 = *((Handle(Geom_Curve)*)&GG1); |
1051 | } |
1052 | C2 = BRep_Tool::Curve(E2,loc,f2,l2); |
1053 | if (!loc.IsIdentity()) { |
1054 | Handle(Geom_Geometry) GG2 = C2->Transformed(loc.Transformation()); |
1055 | C2 = *((Handle(Geom_Curve)*)&GG2); |
1056 | } |
1057 | |
1058 | typC1 = C1->DynamicType(); |
1059 | typC2 = C2->DynamicType(); |
1060 | |
1061 | if (typC1 == STANDARD_TYPE(Geom_TrimmedCurve)) { |
1062 | C1 = (*((Handle(Geom_TrimmedCurve)*)&C1))->BasisCurve(); |
1063 | typC1 = C1->DynamicType(); |
1064 | } |
1065 | |
1066 | if (typC2 == STANDARD_TYPE(Geom_TrimmedCurve)) { |
1067 | C2 = (*((Handle(Geom_TrimmedCurve)*)&C2))->BasisCurve(); |
1068 | typC2 = C2->DynamicType(); |
1069 | } |
1070 | |
1071 | if (typC1 != typC2) { |
1072 | return Standard_False; |
1073 | } |
1074 | |
1075 | if (typC1 != STANDARD_TYPE(Geom_Line) && |
1076 | typC1 != STANDARD_TYPE(Geom_Circle) && |
1077 | typC1 != STANDARD_TYPE(Geom_Ellipse) && |
1078 | typC1 != STANDARD_TYPE(Geom_BSplineCurve) && |
1079 | typC1 != STANDARD_TYPE(Geom_BezierCurve)) { |
1080 | #ifdef DEB |
1081 | if (trc) cout << " TopOpeBRepBuild_FuseFace : Type de Support non traite" << endl; |
1082 | #endif |
1083 | return Standard_False; |
1084 | } |
1085 | |
1086 | // On a presomption de confusion |
1087 | const Standard_Real tollin = Precision::Confusion(); |
1088 | const Standard_Real tolang = Precision::Angular(); |
1089 | if (typC1 == STANDARD_TYPE(Geom_Line)) { |
1090 | gp_Lin li1( (*((Handle(Geom_Line)*)&C1))->Lin()); |
1091 | gp_Lin li2( (*((Handle(Geom_Line)*)&C2))->Lin()); |
1092 | |
1093 | if (Abs(li1.Angle(li2)) <= tolang && |
1094 | li1.Location().SquareDistance(li2.Location()) <= tollin*tollin) { |
1095 | return Standard_True; |
1096 | } |
1097 | return Standard_False; |
1098 | } |
1099 | else if (typC1 == STANDARD_TYPE(Geom_Circle)) { |
1100 | gp_Circ ci1 = (*((Handle(Geom_Circle)*)&C1))->Circ(); |
1101 | gp_Circ ci2 = (*((Handle(Geom_Circle)*)&C2))->Circ(); |
1102 | if (Abs(ci1.Radius()-ci2.Radius()) <= tollin && |
1103 | ci1.Location().SquareDistance(ci2.Location()) <= tollin*tollin) { |
1104 | // Point debut, calage dans periode, et detection meme sens |
1105 | return Standard_True; |
1106 | } |
1107 | return Standard_False; |
1108 | } |
1109 | else if (typC1 == STANDARD_TYPE(Geom_Ellipse)) { |
1110 | gp_Elips ci1 = (*((Handle(Geom_Ellipse)*)&C1))->Elips(); |
1111 | gp_Elips ci2 = (*((Handle(Geom_Ellipse)*)&C2))->Elips(); |
1112 | |
1113 | if (Abs(ci1.MajorRadius()-ci2.MajorRadius()) <= tollin && |
1114 | Abs(ci1.MinorRadius()-ci2.MinorRadius()) <= tollin && |
1115 | ci1.Location().SquareDistance(ci2.Location()) <= tollin*tollin) { |
1116 | // Point debut, calage dans periode, et detection meme sens |
1117 | return Standard_True; |
1118 | } |
1119 | return Standard_False; |
1120 | } |
1121 | else if (typC1 == STANDARD_TYPE(Geom_BSplineCurve)) { |
1122 | Handle(Geom_BSplineCurve) B1 = *((Handle(Geom_BSplineCurve)*)&C1); |
1123 | Handle(Geom_BSplineCurve) B2 = *((Handle(Geom_BSplineCurve)*)&C2); |
1124 | |
1125 | Standard_Integer nbpoles = B1->NbPoles(); |
1126 | if (nbpoles != B2->NbPoles()) { |
1127 | return Standard_False; |
1128 | } |
1129 | |
1130 | Standard_Integer nbknots = B1->NbKnots(); |
1131 | if (nbknots != B2->NbKnots()) { |
1132 | return Standard_False; |
1133 | } |
1134 | |
1135 | TColgp_Array1OfPnt P1(1, nbpoles), P2(1, nbpoles); |
1136 | B1->Poles(P1); |
1137 | B2->Poles(P2); |
1138 | |
1139 | Standard_Real tol3d = BRep_Tool::Tolerance(E1); |
1140 | for (Standard_Integer p = 1; p <= nbpoles; p++) { |
1141 | if ( (P1(p)).Distance(P2(p)) > tol3d) { |
1142 | return Standard_False; |
1143 | } |
1144 | } |
1145 | |
1146 | TColStd_Array1OfReal K1(1, nbknots), K2(1, nbknots); |
1147 | B1->Knots(K1); |
1148 | B2->Knots(K2); |
1149 | |
1150 | TColStd_Array1OfInteger M1(1, nbknots), M2(1, nbknots); |
1151 | B1->Multiplicities(M1); |
1152 | B2->Multiplicities(M2); |
1153 | |
1154 | for (Standard_Integer k = 1; k <= nbknots; k++) { |
1155 | if ((K1(k)-K2(k)) > tollin) { |
1156 | return Standard_False; |
1157 | } |
1158 | if (Abs(M1(k)-M2(k)) > tollin) { |
1159 | return Standard_False; |
1160 | } |
1161 | } |
1162 | |
1163 | if (!B1->IsRational()) { |
1164 | if (B2->IsRational()) { |
1165 | return Standard_False; |
1166 | } |
1167 | } |
1168 | else { |
1169 | if (!B2->IsRational()) { |
1170 | return Standard_False; |
1171 | } |
1172 | } |
1173 | |
1174 | if (B1->IsRational()) { |
1175 | TColStd_Array1OfReal W1(1, nbpoles), W2(1, nbpoles); |
1176 | B1->Weights(W1); |
1177 | B2->Weights(W2); |
1178 | |
1179 | for (Standard_Integer w = 1; w <= nbpoles; w++) { |
1180 | if (Abs(W1(w)-W2(w)) > tollin) { |
1181 | return Standard_False; |
1182 | } |
1183 | } |
1184 | } |
1185 | return Standard_True; |
1186 | } |
1187 | else if (typC1 == STANDARD_TYPE(Geom_BezierCurve)) { |
1188 | Handle(Geom_BezierCurve) B1 = *((Handle(Geom_BezierCurve)*)&C1); |
1189 | Handle(Geom_BezierCurve) B2 = *((Handle(Geom_BezierCurve)*)&C2); |
1190 | |
1191 | Standard_Integer nbpoles = B1->NbPoles(); |
1192 | if (nbpoles != B2->NbPoles()) { |
1193 | return Standard_False; |
1194 | } |
1195 | |
1196 | TColgp_Array1OfPnt P1(1, nbpoles), P2(1, nbpoles); |
1197 | B1->Poles(P1); |
1198 | B2->Poles(P2); |
1199 | |
1200 | for (Standard_Integer p = 1; p <= nbpoles; p++) { |
1201 | if ( (P1(p)).Distance(P2(p)) > tollin) { |
1202 | return Standard_False; |
1203 | } |
1204 | } |
1205 | |
1206 | if (!B1->IsRational()) { |
1207 | if (B2->IsRational()) { |
1208 | return Standard_False; |
1209 | } |
1210 | } |
1211 | else { |
1212 | if (!B2->IsRational()) { |
1213 | return Standard_False; |
1214 | } |
1215 | } |
1216 | |
1217 | if (B1->IsRational()) { |
1218 | TColStd_Array1OfReal W1(1, nbpoles), W2(1, nbpoles); |
1219 | B1->Weights(W1); |
1220 | B2->Weights(W2); |
1221 | |
1222 | for (Standard_Integer w = 1; w <= nbpoles; w++) { |
1223 | if (Abs(W1(w)-W2(w)) > tollin) { |
1224 | return Standard_False; |
1225 | } |
1226 | } |
1227 | } |
1228 | return Standard_True; |
1229 | } |
1230 | return Standard_False; |
1231 | } |