0022922: Clean up warnings on uninitialized / unused variables
[occt.git] / src / BRepCheck / BRepCheck_Face.cxx
CommitLineData
7fd59977 1// File: BRepCheck_Face.cxx
2// Created: Fri Dec 15 11:49:58 1995
3// Author: Jacques GOUSSARD
4// <jag@bravox>
5
6
7#include <BRepCheck_Face.ixx>
8
9#include <BRepCheck_ListOfStatus.hxx>
10#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
11
12#include <BRep_TFace.hxx>
13#include <BRep_Builder.hxx>
14#include <BRep_Tool.hxx>
15
16#include <TopExp.hxx>
17#include <TopExp_Explorer.hxx>
18
19#include <TopTools_ListOfShape.hxx>
20#include <TopTools_ListIteratorOfListOfShape.hxx>
21#include <TopTools_DataMapOfShapeListOfShape.hxx>
22#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
23
24//#include <BRepAdaptor_Curve2d.hxx>
25#include <BRepClass_FaceClassifier.hxx>
26//#include <Geom2dInt_GInter.hxx>
27#include <Geom2d_Curve.hxx>
28#include <GProp_GProps.hxx>
29
30#include <IntRes2d_Domain.hxx>
31#include <Geom2dInt_GInter.hxx>
32#include <Geom2dAdaptor_Curve.hxx>
33#include <gp_Pnt2d.hxx>
34
35
36
37#include <BRepCheck.hxx>
38#include <Precision.hxx>
39#include <TopoDS.hxx>
40#include <TopoDS_Wire.hxx>
41
42#include <BRepTopAdaptor_FClass2d.hxx>
43#include <TopAbs_State.hxx>
44
45#include <Bnd_Box2d.hxx>
46#include <BndLib_Add2dCurve.hxx>
47#include <TopTools_MapOfShape.hxx>
48#include <TopTools_SequenceOfShape.hxx>
49#include <TColgp_SequenceOfPnt.hxx>
50#include <TopoDS_Vertex.hxx>
51#include <IntRes2d_IntersectionPoint.hxx>
52#include <IntRes2d_IntersectionSegment.hxx>
53#include <BRepAdaptor_HSurface.hxx>
54
55
56static Standard_Boolean Intersect(const TopoDS_Wire&,
57 const TopoDS_Wire&,
58 const TopoDS_Face&);
59
60
61static Standard_Boolean IsInside(const TopoDS_Wire& wir,
62 const Standard_Boolean Inside,
63 const BRepTopAdaptor_FClass2d& FClass2d,
64 const TopoDS_Face& F);
65
66static Standard_Boolean CheckThin(const TopoDS_Shape& w,
67 const TopoDS_Shape& f);
68
69//=======================================================================
70//function : BRepCheck_Face
71//purpose :
72//=======================================================================
73
74BRepCheck_Face::BRepCheck_Face (const TopoDS_Face& F)
75{
76 Init(F);
77 myIntdone = Standard_False;
78 myImbdone = Standard_False;
79 myOridone = Standard_False;
80 myGctrl = Standard_True;
81}
82
83//=======================================================================
84//function : Minimum
85//purpose :
86//=======================================================================
87
88void BRepCheck_Face::Minimum()
89{
90 if (!myMin) {
91 BRepCheck_ListOfStatus thelist;
92 myMap.Bind(myShape, thelist);
93 BRepCheck_ListOfStatus& lst = myMap(myShape);
94
95 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &myShape.TShape());
96 if (TF->Surface().IsNull()) {
97 BRepCheck::Add(lst,BRepCheck_NoSurface);
98 }
99 else {
100 // Flag natural restriction???
101 }
102 if (lst.IsEmpty()) {
103 lst.Append(BRepCheck_NoError);
104 }
105 myMin = Standard_True;
106 }
107}
108
109
110//=======================================================================
111//function : InContext
112//purpose :
113//=======================================================================
114
115void BRepCheck_Face::InContext(const TopoDS_Shape& S)
116{
117 if (myMap.IsBound(S)) {
118 return;
119 }
120 BRepCheck_ListOfStatus thelist;
121 myMap.Bind(S, thelist);
122
123 BRepCheck_ListOfStatus& lst = myMap(S);
124
125 TopExp_Explorer exp(S,TopAbs_FACE);
126 for (; exp.More(); exp.Next()) {
127 if (exp.Current().IsSame(myShape)) {
128 break;
129 }
130 }
131 if (!exp.More()) {
132 BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
133 return;
134 }
135
136 if (lst.IsEmpty()) {
137 lst.Append(BRepCheck_NoError);
138 }
139}
140
141
142//=======================================================================
143//function : Blind
144//purpose :
145//=======================================================================
146
147void BRepCheck_Face::Blind()
148{
149 if (!myBlind) {
0d969553 150 // nothing more than in the minimum
7fd59977 151 myBlind = Standard_True;
152 }
153}
154
155
156//=======================================================================
157//function : IntersectWires
158//purpose :
159//=======================================================================
160
161BRepCheck_Status BRepCheck_Face::IntersectWires(const Standard_Boolean Update)
162{
163 if (myIntdone) {
164 if (Update) {
165 BRepCheck::Add(myMap(myShape),myIntres);
166 }
167 return myIntres;
168 }
169
170 myIntdone = Standard_True;
171 myIntres = BRepCheck_NoError;
172 // This method has to be called by an analyzer. It is assumed that
173 // each edge has a correct 2d representation on the face.
174
175 TopExp_Explorer exp1,exp2;
176
0d969553 177 // the wires are mapped
7fd59977 178 exp1.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
179 TopTools_ListOfShape theListOfShape;
180 while (exp1.More()) {
181 if (!myMapImb.IsBound(exp1.Current())) {
182 myMapImb.Bind(exp1.Current(), theListOfShape);
183 }
0d969553 184 else { // the same wire is met twice...
7fd59977 185 myIntres = BRepCheck_RedundantWire;
186 if (Update) {
187 BRepCheck::Add(myMap(myShape),myIntres);
188 }
189 return myIntres;
190 }
191 exp1.Next();
192 }
193
194 Standard_Integer Nbwire, Index,Indexbis;
195 Nbwire = myMapImb.Extent();
196
197 Index = 1;
198 while (Index < Nbwire) {
199 for (exp1.Init(myShape,TopAbs_WIRE),Indexbis = 0;
200 exp1.More();exp1.Next()) {
201 Indexbis++;
202 if (Indexbis == Index) {
203 break;
204 }
205 }
206 TopoDS_Wire wir1 = TopoDS::Wire(exp1.Current());
207 exp1.Next();
208 for (; exp1.More(); exp1.Next()) {
209 const TopoDS_Wire& wir2 = TopoDS::Wire(exp1.Current());
210 if (Intersect(wir1,wir2,TopoDS::Face(myShape))) {
211 myIntres = BRepCheck_IntersectingWires;
212 if (Update) {
213 BRepCheck::Add(myMap(myShape),myIntres);
214 }
215 return myIntres;
216 }
217 }
218 Index++;
219 }
220 if (Update) {
221 BRepCheck::Add(myMap(myShape),myIntres);
222 }
223 return myIntres;
224}
225
226
227//=======================================================================
228//function : ClassifyWires
229//purpose :
230//=======================================================================
231
232BRepCheck_Status BRepCheck_Face::ClassifyWires(const Standard_Boolean Update)
233{
234 // It is assumed that each wire does not intersect any other one.
235 if (myImbdone) {
236 if (Update) {
237 BRepCheck::Add(myMap(myShape),myImbres);
238 }
239 return myImbres;
240 }
241
242 myImbdone = Standard_True;
243 myImbres = IntersectWires();
244 if (myImbres != BRepCheck_NoError) {
245 if (Update) {
246 BRepCheck::Add(myMap(myShape),myImbres);
247 }
248 return myImbres;
249 }
250
251 Standard_Integer Nbwire = myMapImb.Extent();
252 if (Nbwire < 1) {
253 if (Update) {
254 BRepCheck::Add(myMap(myShape),myImbres);
255 }
256 return myImbres;
257 }
258
259 BRep_Builder B;
260 TopExp_Explorer exp1,exp2;
261 TopTools_ListOfShape theListOfShape;
262 for (exp1.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
263 exp1.More();exp1.Next()) {
264
265 const TopoDS_Wire& wir1 = TopoDS::Wire(exp1.Current());
266 TopoDS_Shape aLocalShape = myShape.EmptyCopied();
267 TopoDS_Face newFace = TopoDS::Face(aLocalShape);
268// TopoDS_Face newFace = TopoDS::Face(myShape.EmptyCopied());
6e6cd5d9 269
7fd59977 270 newFace.Orientation(TopAbs_FORWARD);
271 B.Add(newFace,wir1);
272
273 BRepTopAdaptor_FClass2d FClass2d(newFace,Precision::PConfusion());
274 Standard_Boolean WireBienOriente = Standard_False;
275 if(FClass2d.PerformInfinitePoint() != TopAbs_OUT) {
276 WireBienOriente=Standard_True;
0d969553 277 // the given wire defines a hole
7fd59977 278 myMapImb.UnBind(wir1);
279 myMapImb.Bind(wir1.Reversed(), theListOfShape);
280 }
281
282 for (exp2.Init(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
283 exp2.More();exp2.Next()) {
284 const TopoDS_Wire& wir2 = TopoDS::Wire(exp2.Current());
285 if (!wir2.IsSame(wir1)) {
286
287 if (IsInside(wir2,WireBienOriente,FClass2d,newFace)) {
288 myMapImb(wir1).Append(wir2);
289 }
290 }
291 }
292 }
0d969553
Y
293 // It is required to have 1 wire that contains all others, and the others should not
294 // contain anything (case solid ended) or
295 // the wires do not contain anything : in this case the wires should be
296 // holes in an infinite face.
7fd59977 297 TopoDS_Wire Wext;
298 for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMapImb);
299 itm.More();
300 itm.Next()) {
301 if (!itm.Value().IsEmpty()) {
302 if (Wext.IsNull()) {
303 Wext = TopoDS::Wire(itm.Key());
304 }
305 else {
306 myImbres = BRepCheck_InvalidImbricationOfWires;
307 if (Update) {
308 BRepCheck::Add(myMap(myShape),myImbres);
309 }
310 return myImbres;
311 }
312 }
313 }
314
315 if (!Wext.IsNull()) {
316 // verifies that the list contains nbwire-1 elements
317 if (myMapImb(Wext).Extent() != Nbwire-1) {
318 myImbres = BRepCheck_InvalidImbricationOfWires;
319 if (Update) {
320 BRepCheck::Add(myMap(myShape),myImbres);
321 }
322 return myImbres;
323 }
324 }
0d969553 325 // quit without errors
7fd59977 326 if (Update) {
327 BRepCheck::Add(myMap(myShape),myImbres);
328 }
329 return myImbres;
330
331}
332
333
334//=======================================================================
335//function : OrientationOfWires
336//purpose :
337//=======================================================================
338
339BRepCheck_Status BRepCheck_Face::OrientationOfWires
340 (const Standard_Boolean Update)
341{
342 // WARNING : it is assumed that the edges of a wire are correctly oriented
343
344
345 Standard_Boolean Infinite = myShape.Infinite();
346
347 if (myOridone) {
348 if (Update) {
349 BRepCheck::Add(myMap(myShape),myOrires);
350 }
351 return myOrires;
352 }
353
354 myOridone = Standard_True;
355 myOrires = ClassifyWires();
356 if (myOrires != BRepCheck_NoError) {
357 if (Update) {
358 BRepCheck::Add(myMap(myShape),myOrires);
359 }
360 return myOrires;
361 }
362
363 Standard_Integer Nbwire = myMapImb.Extent();
364 TopoDS_Wire Wext;
365 TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itm(myMapImb);
366 if (Nbwire == 1) {
367 if (!Infinite) {
368 Wext = TopoDS::Wire(itm.Key());
369 }
370 }
371 else {
372 for (;itm.More();itm.Next()) {
373 if (!itm.Value().IsEmpty()) {
374 Wext = TopoDS::Wire(itm.Key());
375 }
376 }
377 }
378
379 if (Wext.IsNull() && !Infinite) {
380 if (Nbwire>0) myOrires = BRepCheck_InvalidImbricationOfWires;
381 if (Update) {
382 BRepCheck::Add(myMap(myShape),myOrires);
383 }
384 return myOrires;
385 }
386
387 // BRep_Builder B;
388 TopExp_Explorer exp(myShape.Oriented(TopAbs_FORWARD),TopAbs_WIRE);
389 for (; exp.More(); exp.Next()) {
390 const TopoDS_Wire& wir = TopoDS::Wire(exp.Current());
391 if (!Wext.IsNull() && wir.IsSame(Wext)) {
392 if (wir.Orientation() != Wext.Orientation()) {
0d969553 393 //the exterior wire defines a hole
7fd59977 394 if( CheckThin(wir,myShape.Oriented(TopAbs_FORWARD)) )
395 return myOrires;
396 myOrires = BRepCheck_BadOrientationOfSubshape;
397 if (Update) {
398 BRepCheck::Add(myMap(myShape),myOrires);
399 }
400 return myOrires;
401 }
402 }
403 else {
404 for (itm.Reset(); itm.More(); itm.Next()) {
405 if (itm.Key().IsSame(wir)) {
406 break;
407 }
408 }
0d969553 409 // No control on More()
7fd59977 410 if (itm.Key().Orientation() == wir.Orientation()) {
0d969553 411 // the given wire does not define a hole
7fd59977 412 myOrires = BRepCheck_BadOrientationOfSubshape;
413 if (Update) {
414 BRepCheck::Add(myMap(myShape),myOrires);
415 }
416 return myOrires;
417 }
418 }
419 }
0d969553 420 // quit withour error
7fd59977 421 if (Update) {
422 BRepCheck::Add(myMap(myShape),myOrires);
423 }
424 return myOrires;
425}
426
427
428//=======================================================================
429//function : SetUnorientable
430//purpose :
431//=======================================================================
432
433void BRepCheck_Face::SetUnorientable()
434{
435 BRepCheck::Add(myMap(myShape),BRepCheck_UnorientableShape);
436}
437
438
439//=======================================================================
440//function : IsUnorientable
441//purpose :
442//=======================================================================
443
444Standard_Boolean BRepCheck_Face::IsUnorientable() const
445{
446 if (myOridone) {
447 return (myOrires != BRepCheck_NoError);
448 }
449 for (BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
450 itl.More();
451 itl.Next()) {
452 if (itl.Value() == BRepCheck_UnorientableShape) {
453 return Standard_True;
454 }
455 }
456 return Standard_False;
457}
458
459//=======================================================================
460//function : GeometricControls
461//purpose :
462//=======================================================================
463
464void BRepCheck_Face::GeometricControls(const Standard_Boolean B)
465{
466 if (myGctrl != B) {
467 if (B) {
468 myIntdone = Standard_False;
469 myImbdone = Standard_False;
470 myOridone = Standard_False;
471 }
472 myGctrl = B;
473 }
474}
475
476
477//=======================================================================
478//function : GeometricControls
479//purpose :
480//=======================================================================
481
482Standard_Boolean BRepCheck_Face::GeometricControls() const
483{
484 return myGctrl;
485}
486
487
488//=======================================================================
489//function : Intersect
490//purpose :
491//=======================================================================
492
493static Standard_Boolean Intersect(const TopoDS_Wire& wir1,
494 const TopoDS_Wire& wir2,
495 const TopoDS_Face& F)
496{
497 Standard_Real Inter2dTol = 1.e-10;
498 TopExp_Explorer exp1,exp2;
499// BRepAdaptor_Curve2d cur1,cur2;
500
501 //Find common vertices of two wires - non-manifold case
502 TopTools_MapOfShape MapW1;
503 TopTools_SequenceOfShape CommonVertices;
504 for (exp1.Init( wir1, TopAbs_VERTEX ); exp1.More(); exp1.Next())
505 MapW1.Add( exp1.Current() );
506 for (exp2.Init( wir2, TopAbs_VERTEX ); exp2.More(); exp2.Next())
507 {
508 TopoDS_Shape V = exp2.Current();
509 if (MapW1.Contains( V ))
510 CommonVertices.Append( V );
511 }
512
513 // MSV 03.04.2002: create pure surface adaptor to avoid UVBounds computation
514 // due to performance problem
515 BRepAdaptor_Surface Surf(F,Standard_False);
516
517 TColgp_SequenceOfPnt PntSeq;
518 Standard_Integer i;
519 for (i = 1; i <= CommonVertices.Length(); i++)
520 {
521 TopoDS_Vertex V = TopoDS::Vertex( CommonVertices(i) );
522 gp_Pnt2d P2d = BRep_Tool::Parameters( V, F );
523 gp_Pnt P = Surf.Value( P2d.X(), P2d.Y() );
524 PntSeq.Append( P );
525 }
526
527 Geom2dAdaptor_Curve C1,C2;
528 gp_Pnt2d pfirst1,plast1,pfirst2,plast2;
529 Standard_Real first1,last1,first2,last2;
530 Geom2dInt_GInter Inter;
531 IntRes2d_Domain myDomain1,myDomain2;
532 Bnd_Box2d Box1, Box2;
533
534 for (exp1.Init(wir1,TopAbs_EDGE); exp1.More(); exp1.Next())
535 {
536 const TopoDS_Edge& edg1 = TopoDS::Edge(exp1.Current());
537 // cur1.Initialize(edg1,F);
538 C1.Load( BRep_Tool::CurveOnSurface(edg1,F,first1,last1) );
539 // To avoid exeption in Segment if C1 is BSpline - IFV
540 if(C1.FirstParameter() > first1) first1 = C1.FirstParameter();
541 if(C1.LastParameter() < last1 ) last1 = C1.LastParameter();
542
543 BRep_Tool::UVPoints(edg1,F,pfirst1,plast1);
544 myDomain1.SetValues( pfirst1, first1, Inter2dTol, plast1, last1, Inter2dTol );
545 Box1.SetVoid();
546 BndLib_Add2dCurve::Add( C1, first1, last1, 0., Box1 );
547
548 for (exp2.Init(wir2,TopAbs_EDGE); exp2.More(); exp2.Next())
549 {
550 const TopoDS_Edge& edg2 = TopoDS::Edge(exp2.Current());
551 if (!edg1.IsSame(edg2))
552 {
553 //cur2.Initialize(edg2,F);
554 C2.Load( BRep_Tool::CurveOnSurface(edg2,F,first2,last2) );
555 // To avoid exeption in Segment if C2 is BSpline - IFV
556 if(C2.FirstParameter() > first2) first2 = C2.FirstParameter();
557 if(C2.LastParameter() < last2 ) last2 = C2.LastParameter();
558
559 Box2.SetVoid();
560 BndLib_Add2dCurve::Add( C2, first2, last2, 0., Box2 );
561 if (! Box1.IsOut( Box2 ))
562 {
563 BRep_Tool::UVPoints(edg2,F,pfirst2,plast2);
564 myDomain2.SetValues( pfirst2, first2, Inter2dTol, plast2, last2, Inter2dTol );
565 Inter.Perform( C1, myDomain1, C2, myDomain2, Inter2dTol, Inter2dTol );
566 if (!Inter.IsDone())
567 return Standard_True;
568 if (Inter.NbSegments() > 0)
569 {
570 if (PntSeq.IsEmpty())
571 return Standard_True;
572 else
573 {
574 Standard_Integer NbCoinc = 0;
575 for (i = 1; i <= Inter.NbSegments(); i++)
576 {
577 if (!Inter.Segment(i).HasFirstPoint() || !Inter.Segment(i).HasLastPoint())
578 return Standard_True;
579 gp_Pnt2d FirstP2d = Inter.Segment(i).FirstPoint().Value();
580 gp_Pnt2d LastP2d = Inter.Segment(i).LastPoint().Value();
581 gp_Pnt FirstP = Surf.Value( FirstP2d.X(), FirstP2d.Y() );
582 gp_Pnt LastP = Surf.Value( LastP2d.X(), LastP2d.Y() );
583 for (Standard_Integer j = 1; j <= PntSeq.Length(); j++)
584 {
585 Standard_Real tolv = BRep_Tool::Tolerance( TopoDS::Vertex(CommonVertices(j)) );
586 if (FirstP.IsEqual( PntSeq(j), tolv ) || LastP.IsEqual( PntSeq(j), tolv ))
587 {
588 NbCoinc++;
589 break;
590 }
591 }
592 }
593 if (NbCoinc == Inter.NbSegments())
594 return Standard_False;
595 return Standard_True;
596 }
597 }
598 if (Inter.NbPoints() > 0)
599 {
600 if (PntSeq.IsEmpty())
601 return Standard_True;
602 else
603 {
604 Standard_Integer NbCoinc = 0;
605 for (i = 1; i <= Inter.NbPoints(); i++)
606 {
607 gp_Pnt2d P2d = Inter.Point(i).Value();
608 gp_Pnt P = Surf.Value( P2d.X(), P2d.Y() );
609 for (Standard_Integer j = 1; j <= PntSeq.Length(); j++)
610 {
611 Standard_Real tolv = BRep_Tool::Tolerance( TopoDS::Vertex(CommonVertices(j)) );
612 if (P.IsEqual( PntSeq(j), tolv ))
613 {
614 NbCoinc++;
615 break;
616 }
617 }
618 }
619 if (NbCoinc == Inter.NbPoints())
620 return Standard_False;
621 return Standard_True;
622 }
623 }
624 }
625 }
626 }
627 }
628 return Standard_False;
629}
630
631
632//=======================================================================
633//function : IsInside
634//purpose :
635//=======================================================================
636
637static Standard_Boolean IsInside(const TopoDS_Wire& wir,
638 const Standard_Boolean WireBienOriente,
639 const BRepTopAdaptor_FClass2d& FClass2d,
640 const TopoDS_Face& F)
641{
642 // Standard_Real U,V;
643 TopExp_Explorer exp;
644 for (exp.Init(wir,TopAbs_EDGE);
645 exp.More();
646 exp.Next()) {
647
648 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
649 Standard_Real f,l;
650 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(edg,F,f,l);
651 Standard_Real prm;
652
653 if (!Precision::IsNegativeInfinite(f) &&
654 !Precision::IsPositiveInfinite(l)) {
655 prm = (f+l)/2.;
656 }
657 else {
658 if (Precision::IsNegativeInfinite(f) &&
659 Precision::IsPositiveInfinite(l)){
660 prm = 0.;
661 }
662 else if (Precision::IsNegativeInfinite(f)) {
663 prm = l-1.;
664 }
665 else {
666 prm = f+1.;
667 }
668 }
669
670 gp_Pnt2d pt2d(C2d->Value(prm));
671#ifdef DEB
672 TopAbs_State st2=
673#endif
674 FClass2d.Perform(pt2d,Standard_False);
675//-- if(st1!=st2) {
676//-- static int p=0;
677//-- printf("\n point p%d %g %g \n",++p,pt2d.X(),pt2d.Y());
678//-- }
679
680 if(WireBienOriente) {
681#ifndef DEB
682 return(FClass2d.Perform(pt2d,Standard_False) == TopAbs_OUT);
683 }
684 else {
685 return(FClass2d.Perform(pt2d,Standard_False) == TopAbs_IN);
686 }
687#else
688 return(st2 == TopAbs_OUT);
689 }
690 else {
691 return(st2 == TopAbs_IN);
692 }
693#endif
694 }
695 return Standard_False;
696}
697
698Standard_Boolean CheckThin(const TopoDS_Shape& w, const TopoDS_Shape& f)
699{
700 TopoDS_Face aF = TopoDS::Face(f);
701 TopoDS_Wire aW = TopoDS::Wire(w);
702
703 Standard_Integer nbE = 0;
704 TopTools_ListOfShape lE;
705 TopExp_Explorer exp(aW,TopAbs_EDGE);
706 for(; exp.More(); exp.Next()) {
707 const TopoDS_Shape& s = exp.Current();
708 lE.Append(s);
709 nbE++;
710 }
711
712 if( nbE != 2 ) return Standard_False;
713 TopoDS_Edge e1 = TopoDS::Edge(lE.First());
714 TopoDS_Edge e2 = TopoDS::Edge(lE.Last());
715
716 TopoDS_Vertex v1, v2, v3, v4;
717 TopExp::Vertices(e1,v1,v2);
718 TopExp::Vertices(e2,v3,v4);
719
720 if( v1.IsNull() || v2.IsNull() ||
721 v3.IsNull() || v4.IsNull() ) return Standard_False;
722
723 if( v1.IsSame(v2) || v3.IsSame(v4) )
724 return Standard_False;
725
726 Standard_Boolean sF = Standard_False, sL = Standard_False;
727 if( v1.IsSame(v3) || v1.IsSame(v4) ) sF = Standard_True;
728 if( v2.IsSame(v3) || v2.IsSame(v4) ) sL = Standard_True;
729
730 if( !sF || !sL ) return Standard_False;
731
732 TopAbs_Orientation e1or = e1.Orientation();
733 TopAbs_Orientation e2or = e2.Orientation();
734
735 Standard_Real f1 = 0., l1 = 0., f2 = 0., l2 = 0.;
736 Handle(Geom2d_Curve) pc1 = BRep_Tool::CurveOnSurface(e1,aF,f1,l1);
737 Handle(Geom2d_Curve) pc2 = BRep_Tool::CurveOnSurface(e2,aF,f2,l2);
738
739 if( pc1.IsNull() || pc2.IsNull() ) return Standard_False;
740
741 Standard_Real d1 = Abs(l1-f1)/100.;
742 Standard_Real d2 = Abs(l2-f2)/100.;
743 Standard_Real m1 = (l1+f1)*0.5;
744 Standard_Real m2 = (l2+f2)*0.5;
745
746 gp_Pnt2d p1f(pc1->Value(m1-d1));
747 gp_Pnt2d p1l(pc1->Value(m1+d1));
748 gp_Pnt2d p2f(pc2->Value(m2-d2));
749 gp_Pnt2d p2l(pc2->Value(m2+d2));
750
751 gp_Vec2d vc1(p1f,p1l);
752 gp_Vec2d vc2(p2f,p2l);
753
754 if( (vc1*vc2) >= 0. && e1or == e2or ) return Standard_False;
755
756 return Standard_True;
757}