Test for 0022778: Bug in BRepMesh
[occt.git] / src / TopOpeBRepBuild / TopOpeBRepBuild_FuseFace.cxx
CommitLineData
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
65Standard_IMPORT Standard_Boolean TopOpeBRepBuild_GettraceFUFA();
66#endif
67
68static void GroupShape(TopTools_ListOfShape&,
69 Standard_Boolean,
70 TopTools_DataMapOfShapeListOfShape&);
71
72static void GroupEdge(TopTools_DataMapOfShapeListOfShape&,
73 TopTools_DataMapOfShapeListOfShape&);
74
75static void MakeEdge(TopTools_DataMapOfShapeListOfShape&);
76
77static Standard_Boolean SameSupport(const TopoDS_Edge&,
78 const TopoDS_Edge&);
79
80//=======================================================================
81//function : Init
82//purpose :
83//=======================================================================
84void 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
131void 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
517void 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
601void 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
722void 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
739static 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
849static 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
936static 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
1030Standard_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}