0023663: Removing 2D viewer library
[occt.git] / src / BRepCheck / BRepCheck_Wire.cxx
CommitLineData
b311480e 1// Created on: 1995-12-12
2// Created by: Jacques GOUSSARD
3// Copyright (c) 1995-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// Modified by dpf, Fri Dec 19 15:31:03 1997
0d969553 22// Processing of closing in 2d.
7fd59977 23// modified by eap Tue Dec 18 14:14:25 2001 (bug OCC23)
24// Check self-intersection in case of closed edge
7fd59977 25// modified by eap Fri Dec 21 17:36:55 2001 (bug OCC35)
26// Closed2d() added
27
28// Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764
29
30#include <BRepCheck_Wire.ixx>
31#include <BRepCheck_ListOfStatus.hxx>
32#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
33#include <TopTools_MapOfShape.hxx>
34#include <TopTools_MapIteratorOfMapOfShape.hxx>
35#include <TopTools_IndexedMapOfShape.hxx>
36#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
37#include <TopTools_DataMapOfShapeListOfShape.hxx>
38#include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
39#include <TopTools_ListOfShape.hxx>
40#include <TopTools_ListIteratorOfListOfShape.hxx>
41#include <TopExp_Explorer.hxx>
42#include <TopoDS_Iterator.hxx>
43#include <TopLoc_Location.hxx>
44#include <TColGeom2d_Array1OfCurve.hxx>
45#include <IntRes2d_Intersection.hxx>
46#include <IntRes2d_IntersectionPoint.hxx>
47#include <IntRes2d_IntersectionSegment.hxx>
48#include <IntRes2d_Transition.hxx>
49#include <IntRes2d_Domain.hxx>
50#include <Geom2dInt_GInter.hxx>
51#include <gp_Pnt2d.hxx>
52#include <gp_Pnt.hxx>
53#include <gp_Lin.hxx>
54#include <Geom2d_Curve.hxx>
55#include <Geom_Curve.hxx>
56#include <Geom2dAdaptor_Curve.hxx>
57#include <Geom2dAdaptor_HCurve.hxx>
58#include <BRep_Tool.hxx>
59#include <BRepAdaptor_Curve.hxx>
60#include <BRepAdaptor_Surface.hxx>
61#include <BRepAdaptor_HSurface.hxx>
62#include <BRepCheck.hxx>
63#include <TopoDS.hxx>
64#include <TopoDS_Vertex.hxx>
65#include <TopTools_MapOfOrientedShape.hxx>
66#include <TopTools_HArray1OfShape.hxx>
67#include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
68
69//Patch
70#include <Precision.hxx>
71#include <Bnd_Array1OfBox2d.hxx>
72#include <BndLib_Add2dCurve.hxx>
73
74//#ifdef WNT
75#include <stdio.h>
76#include <BRepTools_WireExplorer.hxx>
77#include <TopExp.hxx>
78//#endif
79
80#include <TopTools_IndexedMapOfOrientedShape.hxx>
81#include <ElCLib.hxx>
82
83
84static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape&,
85 const TopoDS_Shape&, // edge
86 TopTools_MapOfShape&); // mapofedge
87
88
89static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape&,
90 const TopoDS_Edge&);
91
92
93static
94 void ChoixUV(const TopoDS_Vertex&,
95 const TopoDS_Edge&,
96 const TopoDS_Face&,
97 TopTools_ListOfShape&);
98
99// 20/03/02 akm vvv (OCC234)
100// static
101// Standard_Boolean CheckLoopOrientation( const TopoDS_Vertex&,
102// const TopoDS_Edge&,
103// const TopoDS_Edge&,
104// const TopoDS_Face&,
105// TopTools_ListOfShape&);
106// 20/03/02 akm ^^^
107
108inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
109{
110 return (S.Orientation() == TopAbs_FORWARD ||
111 S.Orientation() == TopAbs_REVERSED);
112}
113
114static
115 void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
116 const Standard_Real aPrm,
117 gp_Pnt2d& Pnt,
118 gp_Vec2d& aVec2d);
119
120// Modified by Sergey KHROMOV - Thu Jun 20 11:21:51 2002 OCC325 Begin
121static Standard_Boolean IsClosed2dForPeriodicFace
122 (const TopoDS_Face &theFace,
123 const gp_Pnt2d &theP1,
124 const gp_Pnt2d &theP2,
125 const TopoDS_Vertex &theVertex);
126
127static Standard_Boolean GetPnt2d(const TopoDS_Vertex &theVertex,
128 const TopoDS_Edge &theEdge,
129 const TopoDS_Face &theFace,
130 gp_Pnt2d &aPnt);
131// Modified by Sergey KHROMOV - Wed May 22 10:44:08 2002 End
132
133//=======================================================================
134//function : BRepCheck_Wire
135//purpose :
136//=======================================================================
137BRepCheck_Wire::BRepCheck_Wire(const TopoDS_Wire& W)
138{
139 Init(W);
140}
141//=======================================================================
142//function : Minimum
143//purpose :
144//=======================================================================
145void BRepCheck_Wire::Minimum()
146{
147 myCdone = Standard_False;
148 myGctrl = Standard_True;
149 if (!myMin) {
150 BRepCheck_ListOfStatus thelist;
151 myMap.Bind(myShape, thelist);
152 BRepCheck_ListOfStatus& lst = myMap(myShape);
153
0d969553 154 // check that the wire is "connex"
7fd59977 155 TopExp_Explorer exp(myShape,TopAbs_EDGE);
156 Standard_Integer nbedge = 0;
157 myMapVE.Clear();
158 // fill myMapVE
159 for (; exp.More(); exp.Next()) {
160 nbedge++;
161 TopExp_Explorer expv;
162 for (expv.Init(exp.Current(),TopAbs_VERTEX);
163 expv.More(); expv.Next()) {
164 const TopoDS_Shape& vtx = expv.Current();
165 Standard_Integer index = myMapVE.FindIndex(vtx);
166 if (index == 0) {
167 TopTools_ListOfShape theListOfShape;
168 index = myMapVE.Add(vtx, theListOfShape);
169 }
170 myMapVE(index).Append(exp.Current());
171 }
172 }
173 // wire must have at least one edge
174 if (nbedge == 0) {
175 BRepCheck::Add(lst,BRepCheck_EmptyWire);
176 }
177 // check if all edges are connected through vertices
178 else if (nbedge >= 2) {
179 TopTools_MapOfShape mapE;
180 exp.ReInit();
181 Propagate(myMapVE,exp.Current(),mapE);
182 for (exp.ReInit(); exp.More(); exp.Next()) {
183 if (!mapE.Contains(exp.Current())) {
184 BRepCheck::Add(lst,BRepCheck_NotConnected);
185 break;
186 }
187 }
188 }
189 if (lst.IsEmpty()) {
190 lst.Append(BRepCheck_NoError);
191 }
192 myMapVE.Clear();
193 myMin = Standard_True;
194 }
195}
196//=======================================================================
197//function : InContext
198//purpose :
199//=======================================================================
200void BRepCheck_Wire::InContext(const TopoDS_Shape& S)
201{
202
203 if (myMap.IsBound(S)) {
204 return;
205 }
206 BRepCheck_ListOfStatus thelist;
207 myMap.Bind(S, thelist);
208
209 BRepCheck_ListOfStatus& lst = myMap(S);
210
211 // check if my wire is in <S>
212 TopExp_Explorer exp(S,TopAbs_WIRE);
213 for ( ; exp.More(); exp.Next()) {
214 if (exp.Current().IsSame(myShape)) {
215 break;
216 }
217 }
218 if (!exp.More()) {
219 BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
220 return;
221 }
222
223 BRepCheck_Status st = BRepCheck_NoError;
224 TopAbs_ShapeEnum styp = S.ShapeType();
225 switch (styp) {
226
227 case TopAbs_FACE:
228 {
0d969553 229 TopoDS_Edge ed1,ed2;
7fd59977 230 if (myGctrl)
231 st = SelfIntersect(TopoDS::Face(S),ed1,ed2,Standard_True);
232 if (st != BRepCheck_NoError) break;
233 st = Closed();
234 if (st != BRepCheck_NoError) break;
235 st = Orientation(TopoDS::Face(S));
236 if (st != BRepCheck_NoError) break;
237 st = Closed2d(TopoDS::Face(S));
238 }
239 break;
240 default:
241 break;
242 }
243
244 if (st != BRepCheck_NoError)
245 BRepCheck::Add(lst,st);
246
247 if (lst.IsEmpty())
248 lst.Append(BRepCheck_NoError);
249}
250//=======================================================================
251//function : Blind
252//purpose :
253//=======================================================================
254void BRepCheck_Wire::Blind()
255{
256 if (!myBlind) {
0d969553 257 // nothing more that the minimum
7fd59977 258 myBlind = Standard_True;
259 }
260}
261//=======================================================================
262//function : Closed
263//purpose :
264//=======================================================================
265BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
266{
267
268 if (myCdone) {
269 if (Update) {
270 BRepCheck::Add(myMap(myShape),myCstat);
271 }
272 return myCstat;
273 }
274
0d969553 275 myCdone = Standard_True;
7fd59977 276
277 BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
278 if (itl.Value() != BRepCheck_NoError) {
279 myCstat = itl.Value();
0d969553 280 return myCstat; // already saved
7fd59977 281 }
282
283 myCstat = BRepCheck_NoError;
284
285 TopExp_Explorer exp,expv;
286 TopTools_MapOfShape mapS;
287 TopTools_DataMapOfShapeListOfShape Cradoc;
288 myMapVE.Clear();
289 // Checks if the oriented edges of the wire give a "closed" wire,
290 // i-e if each oriented vertex on oriented edges is found 2 times...
291 // myNbori = 0;
292 for (exp.Init(myShape,TopAbs_EDGE);exp.More(); exp.Next()) {
293 if (IsOriented(exp.Current())) {
294 // myNbori++;
295 if (!Cradoc.IsBound(exp.Current())) {
296 TopTools_ListOfShape theListOfShape;
297 Cradoc.Bind(exp.Current(), theListOfShape);
298 }
299 Cradoc(exp.Current()).Append(exp.Current());
300
301 mapS.Add(exp.Current());
302 for (expv.Init(exp.Current(),TopAbs_VERTEX); expv.More(); expv.Next()) {
303 if (IsOriented(expv.Current())) {
304 Standard_Integer index = myMapVE.FindIndex(expv.Current());
305 if (index == 0) {
306 TopTools_ListOfShape theListOfShape1;
307 index = myMapVE.Add(expv.Current(), theListOfShape1);
308 }
309 myMapVE(index).Append(exp.Current());
310 }
311 }
312 }
313 }
314
315 Standard_Integer theNbori = mapS.Extent();
316 if (theNbori >= 2) {
317 mapS.Clear();
318 for (exp.ReInit(); exp.More(); exp.Next()) {
319 if (IsOriented(exp.Current())) {
320 break;
321 }
322 }
323 Propagate(myMapVE,exp.Current(),mapS);
324 }
325 if (theNbori != mapS.Extent()) {
326 myCstat = BRepCheck_NotConnected;
327 if (Update) {
328 BRepCheck::Add(myMap(myShape),myCstat);
329 }
330 return myCstat;
331 }
332
333 // Checks the number of occurence of an edge : maximum 2, and in this
334 // case, one time FORWARD and one time REVERSED
335
336 Standard_Boolean yabug = Standard_False;
337 for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm(Cradoc);
338 itdm.More(); itdm.Next()) {
339 if (itdm.Value().Extent() >= 3) {
340 yabug = Standard_True;
341 }
342 else if (itdm.Value().Extent() == 2) {
343 if (itdm.Value().First().Orientation() ==
344 itdm.Value().Last().Orientation()) {
345 yabug = Standard_True;
346 }
347 }
348 if (yabug) {
349 myCstat = BRepCheck_RedundantEdge;
350 if (Update) {
351 BRepCheck::Add(myMap(myShape),myCstat);
352 }
353 return myCstat;
354 }
355 }
356
357 for (Standard_Integer i = 1; i<= myMapVE.Extent(); i++) {
358 if (myMapVE(i).Extent()%2 != 0) {
359 myCstat=BRepCheck_NotClosed;
360 if (Update) {
361 BRepCheck::Add(myMap(myShape),myCstat);
362 }
363 return myCstat;
364 }
365 }
366
367 if (Update) {
368 BRepCheck::Add(myMap(myShape),myCstat);
369 }
370 return myCstat;
371}
372//=======================================================================
373//function : Closed2d
374//purpose : for periodic faces
375//=======================================================================
376BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
377 const Standard_Boolean Update)
378{
379
380 // 3d closure checked?
381 BRepCheck_Status aClosedStat = Closed();
382 if (aClosedStat != BRepCheck_NoError) {
383 if (Update)
384 BRepCheck::Add(myMap(myShape),aClosedStat);
385 return aClosedStat;
386 }
387
388 // 20/03/02 akm vvv : (OCC234) Hence this method will be used to check
389 // both periodic and non-periodic faces
390 // // this check is for periodic faces
391 BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
392 // if (!aFaceSurface.IsUPeriodic() && !aFaceSurface.IsVPeriodic())
393 // {
394 // if (Update)
395 // BRepCheck::Add(myMap(myShape),aClosedStat);
396 // return aClosedStat;
397 // }
398 // 20/03/02 akm ^^^
399
400 // count edges having FORWARD or REVERSED orientation
401 Standard_Integer aNbOrirntedEdges = 0;
402 TopExp_Explorer anEdgeExp(myShape,TopAbs_EDGE);
403 for (;anEdgeExp.More(); anEdgeExp.Next()) {
404 if (IsOriented(anEdgeExp.Current()))
405 aNbOrirntedEdges++;
406 }
407 if (aNbOrirntedEdges==0)
408 {
409 if (Update)
410 BRepCheck::Add(myMap(myShape),aClosedStat);
411 return aClosedStat;
412 }
413
414 // all those edges must form a closed 2d contour and be found by WireExplorer
415
416 Standard_Integer aNbFoundEdges = 0;
417
418 BRepTools_WireExplorer aWireExp(TopoDS::Wire(myShape), theFace);
419 TopoDS_Edge aFirstEdge = aWireExp.Current();
420 TopoDS_Vertex aFirstVertex = aWireExp.CurrentVertex();
421 TopoDS_Edge aLastEdge;
422 for (;aWireExp.More(); aWireExp.Next())
423 {
424 aNbFoundEdges++;
425 aLastEdge = aWireExp.Current();
426 }
427
428 if (aNbFoundEdges != aNbOrirntedEdges)
429 {
430 aClosedStat = BRepCheck_NotClosed;
431 if (Update)
432 BRepCheck::Add(myMap(myShape),aClosedStat);
433 return aClosedStat;
434 }
435
436 // Check distance between 2d ends of first and last edges
437// Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 Begin
438// First check if first and last edges are infinite:
439 Standard_Real aF;
440 Standard_Real aL;
441 Standard_Boolean isFirstInfinite = Standard_False;
442 Standard_Boolean isLastInfinite = Standard_False;
443 TopAbs_Orientation anOri;
444
445 anOri = aFirstEdge.Orientation();
446 BRep_Tool::Range(aFirstEdge, aF, aL);
447 if ((anOri == TopAbs_FORWARD && aF == -Precision::Infinite()) ||
448 (anOri == TopAbs_REVERSED && aL == Precision::Infinite()))
449 isFirstInfinite = Standard_True;
450
451 anOri = aLastEdge.Orientation();
452 BRep_Tool::Range(aLastEdge, aF, aL);
453 if ((anOri == TopAbs_FORWARD && aL == Precision::Infinite()) ||
454 (anOri == TopAbs_REVERSED && aF == -Precision::Infinite()))
455 isLastInfinite = Standard_True;
456
457 if (isFirstInfinite && isLastInfinite) {
458 if (Update)
459 BRepCheck::Add(myMap(myShape),aClosedStat);
460 return aClosedStat;
461 } else if (aFirstVertex.IsNull()) {
462 aClosedStat = BRepCheck_NotClosed;
463 if (Update)
464 BRepCheck::Add(myMap(myShape),aClosedStat);
465 return aClosedStat;
466 }
467// Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 End
468
469 gp_Pnt2d p, p1, p2; // ends of prev edge, next edge, bidon
470
471 // get first point
472 BRep_Tool::UVPoints(aLastEdge, theFace, p2, p);
473 if (aLastEdge.Orientation() == TopAbs_REVERSED) p = p2;
474
475// Modified by Sergey KHROMOV - Mon Apr 22 10:36:33 2002 Begin
476// Standard_Real aTol, aUResol, aVResol;
477
478// // find 2d tolerance
479// aTol = BRep_Tool::Tolerance(aFirstVertex);
480// aUResol = 2*aFaceSurface.UResolution(aTol);
481// aVResol = 2*aFaceSurface.VResolution(aTol);
482
483 // get second point
484 if (aFirstEdge.Orientation() == TopAbs_REVERSED)
485 BRep_Tool::UVPoints(aFirstEdge, theFace, p2, p1);
486 else
487 BRep_Tool::UVPoints(aFirstEdge, theFace, p1, p2);
488
489// Modified by Sergey KHROMOV - Thu Jun 20 10:55:42 2002 OCC325 Begin
490// Check 2d distance for periodic faces with seam edge
491 if (!IsClosed2dForPeriodicFace(theFace, p, p1, aFirstVertex)) {
492 aClosedStat = BRepCheck_NotClosed;
493 if (Update)
494 BRepCheck::Add(myMap(myShape),aClosedStat);
495 return aClosedStat;
496 }
497// Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End
498
499 // check distance
500// Standard_Real dfUDist=Abs(p.X()-p1.X());
501// Standard_Real dfVDist=Abs(p.Y()-p1.Y());
502// if (dfUDist > aUResol || dfVDist > aVResol)
503// {
504 Standard_Real aTol3d = BRep_Tool::Tolerance(aFirstVertex);
505 gp_Pnt aPRef = BRep_Tool::Pnt(aFirstVertex);
506 gp_Pnt aP1 = aFaceSurface.Value(p.X(), p.Y());
507 gp_Pnt aP2 = aFaceSurface.Value(p1.X(), p1.Y());
508 Standard_Real Dist1 = aPRef.Distance(aP1);
509 Standard_Real Dist2 = aPRef.Distance(aP2);
510
511 if (Dist1 > aTol3d || Dist2 > aTol3d) {
512// Modified by Sergey KHROMOV - Mon Apr 22 10:36:44 2002 End
513#ifdef DEB
514 cout << endl;
515 cout << "------------------------------------------------------" <<endl;
516 cout << "--- BRepCheck Wire: Closed2d -> Erreur" <<endl;
517 if (Dist1 > aTol3d)
518 cout << "--- Dist1 (" << Dist1 << ") > Tol3d (" << aTol3d << ")" <<endl;
519 if (Dist2 > aTol3d)
520 cout << "--- Dist2 (" << Dist2 << ") > Tol3d (" << aTol3d << ")" <<endl;
521 cout << "------------------------------------------------------" <<endl;
522#endif
523 aClosedStat = BRepCheck_NotClosed;
524 if (Update)
525 BRepCheck::Add(myMap(myShape),aClosedStat);
526 return aClosedStat;
527 }
528
529 if (Update)
530 BRepCheck::Add(myMap(myShape),aClosedStat);
531 return aClosedStat;
532}
533//=======================================================================
534//function : Orientation
535//purpose :
536//=======================================================================
537BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
538 const Standard_Boolean Update)
539{
540 BRepCheck_Status theOstat = Closed();
541 if (theOstat != BRepCheck_NotClosed && theOstat != BRepCheck_NoError) {
542 if (Update) {
543 BRepCheck::Add(myMap(myShape),theOstat);
544 }
545 return theOstat;
546 }
547
548 theOstat = BRepCheck_NoError;
549
550 TopoDS_Vertex VF,VL;
7fd59977 551 TopAbs_Orientation orient, ortmp = TopAbs_FORWARD;
7fd59977 552 TopTools_ListOfShape ledge, ListOfPassedEdge;
553 TopExp_Explorer exp,vte;
554 TopTools_MapOfShape mapS;
555 TopoDS_Edge theEdge,theRef;
556
557 // Checks the orientation of the edges
558 for (exp.Init(myShape,TopAbs_EDGE); exp.More(); exp.Next()) {
559 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
560 orient = edg.Orientation();
561 if (IsOriented(edg)) {
562 mapS.Add(edg);
563 theEdge = edg;
564 theRef = edg;
565 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
566 TopAbs_Orientation vto = vte.Current().Orientation();
567 if (vto == TopAbs_FORWARD) {
568 VF = TopoDS::Vertex(vte.Current());
569 }
570 else if (vto == TopAbs_REVERSED) {
571 VL = TopoDS::Vertex(vte.Current());
572 }
573 if (!VF.IsNull() && !VL.IsNull()) {
574 break;
575 }
576 }
577 if (VF.IsNull() && VL.IsNull())
578 theOstat = BRepCheck_InvalidDegeneratedFlag;
579 break;
580 }
581 }
582
583 if (theOstat == BRepCheck_NoError) {
584 Standard_Integer Index = 1;
585 Standard_Integer nbOriNoDegen=myMapVE.Extent();
586// Modified by Sergey KHROMOV - Tue May 21 17:12:45 2002 Begin
587 Standard_Boolean isGoFwd = Standard_True;
588
589 if (VL.IsNull())
590 isGoFwd = Standard_False;
591// Modified by Sergey KHROMOV - Tue May 21 17:12:45 2002 End
592
593 while (Index < nbOriNoDegen) {
594 ledge.Clear();
595 ListOfPassedEdge.Clear();
0d969553
Y
596 // find edges that make a chain on VL if !VL.IsNull
597 // otherwise on VF.
7fd59977 598
599 Standard_Integer ind;
600 if (!VL.IsNull()) {
601 ind = myMapVE.FindIndex(VL);
602 }
603 else if (!VF.IsNull()) {
604 ind = myMapVE.FindIndex(VF);
605 }
606 else {
607 theOstat = BRepCheck_InvalidDegeneratedFlag;
608 break;
609 }
610
611 for (TopTools_ListIteratorOfListOfShape itls(myMapVE(ind));
612 itls.More(); itls.Next()) {
613 const TopoDS_Edge & edg = TopoDS::Edge(itls.Value());
614
615 orient = edg.Orientation();
616 if (mapS.Contains(edg)) ortmp = GetOrientation(mapS,edg);
617
618 //Add to list already passed outcoming edges
619 if (mapS.Contains(edg) && ortmp == orient && !edg.IsSame(theEdge))
620 for (vte.Init(edg,TopAbs_VERTEX); vte.More(); vte.Next())
621 {
622 TopAbs_Orientation vto = vte.Current().Orientation();
623 if (!VL.IsNull())
624 {
625 if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current()))
626 {
627 ListOfPassedEdge.Append(edg);
628 break;
629 }
630 }
631 else // VF is not null
632 {
633 if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current()))
634 {
635 ListOfPassedEdge.Append(edg);
636 break;
637 }
638 }
639 }
640
641 if (!mapS.Contains(edg) || ortmp != orient) {
642 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
643 TopAbs_Orientation vto = vte.Current().Orientation();
644 if (!VL.IsNull()) {
645 if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current())) {
0d969553
Y
646 // If the processing is in 2d (face not null) or
647 // if the edge is not degenerated it is added
7fd59977 648 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
649 ledge.Append(edg);
650 break;
651 }
652 }
0d969553 653 else { // VF is not null
7fd59977 654 if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
0d969553
Y
655 // // If the processing is in 2d (face not null) or
656 // if the edge is not degenerated it is added
7fd59977 657 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
658 ledge.Append(edg);
659 break;
660 }
661 }
662 }
663 }
664 }
665 Standard_Integer nbconnex = ledge.Extent();
666 Standard_Boolean Changedesens = Standard_False;
667 if (nbconnex == 0) {
668 if (myCstat == BRepCheck_NotClosed) {
669 if (VL.IsNull()) {
670 if (Update) {
671 BRepCheck::Add(myMap(myShape),theOstat);
672 }
0d969553 673 return theOstat; // leave
7fd59977 674 }
675 else {
0d969553
Y
676 Index--; // because after Index++ and if there is no chain,
677 VL.Nullify(); // chain on VF is forced
7fd59977 678 theEdge = theRef;
679 Changedesens = Standard_True;
680 }
681 }
682 else {
683 theOstat = BRepCheck_BadOrientationOfSubshape;
684 if (Update) {
685 BRepCheck::Add(myMap(myShape),theOstat);
686 }
687 return theOstat;
688 }
689 }
690
0d969553
Y
691 // JAG 03/07 else if (nbconnex >= 2 && !F.IsNull()) // Try to see in 2d
692 else if (!F.IsNull()) { // Try to see in 2d
7fd59977 693 TopoDS_Vertex pivot;
694 if (!VL.IsNull()) {
695 pivot = VL;
696 }
697 else {
698 pivot = VF;
699 }
700
701 ChoixUV(pivot,theEdge,F,ledge);
702 nbconnex = ledge.Extent();
703// 20/03/02 akm vvv : (OCC234) - The 2d exploration of wire with necessary
704// checks is performed in Closed2d, here it's useless
705// if (nbconnex == 1 && !CheckLoopOrientation( pivot, theEdge, TopoDS::Edge(ledge.First()), F, ListOfPassedEdge ))
706// {
707// theOstat = BRepCheck_BadOrientationOfSubshape;
708// if (Update)
709// BRepCheck::Add(myMap(myShape),theOstat);
710// return theOstat;
711// }
712// 20/03/02 akm ^^^
713 }
714
715 if (nbconnex >= 2) {
716 theOstat = BRepCheck_BadOrientationOfSubshape;
717 if (Update) {
718 BRepCheck::Add(myMap(myShape),theOstat);
719 }
720 return theOstat;
721 }
722 else if (nbconnex == 1) {
0d969553 723 // offset the vertex
7fd59977 724 for (vte.Init(ledge.First(),TopAbs_VERTEX);vte.More(); vte.Next()) {
725 TopAbs_Orientation vto = vte.Current().Orientation();
726 if (!VL.IsNull()) {
727 if (vto == TopAbs_REVERSED) {
728 VL = TopoDS::Vertex(vte.Current());
729 break;
730 }
731 }
0d969553 732 else { // VF is not null
7fd59977 733 if (vto == TopAbs_FORWARD) {
734 VF = TopoDS::Vertex(vte.Current());
735 break;
736 }
737 }
738 }
739 mapS.Add(ledge.First());
740 theEdge = TopoDS::Edge(ledge.First());
741 if (!vte.More()) {
742 if (!VL.IsNull()) {
743 VL.Nullify();
744 }
745 else {
746 VF.Nullify();
747 }
748 }
749 }
750 else if (!Changedesens) { //nbconnex == 0
751 theOstat = BRepCheck_NotClosed;
752 if (Update) {
753 BRepCheck::Add(myMap(myShape),theOstat);
754 }
755 return theOstat;
756 }
757
0d969553 758 // Check the closure of the wire in 2d (not done in Closed())
7fd59977 759
760 TopoDS_Vertex aVRef;
761 Standard_Boolean isCheckClose = Standard_False;
762
763 if (isGoFwd && !VF.IsNull()) {
764 aVRef = VF;
765 isCheckClose = Standard_True;
766 } else if (!isGoFwd && !VL.IsNull()) {
767 aVRef = VL;
768 isCheckClose = Standard_True;
769 }
770
771// if (Index==1 && myCstat!=BRepCheck_NotClosed &&
772// !VF.IsNull() && !F.IsNull()) {
773 if (Index==1 && myCstat!=BRepCheck_NotClosed &&
774 isCheckClose && !F.IsNull()) {
775 ledge.Clear();
776// ind = myMapVE.FindIndex(VF);
777 ind = myMapVE.FindIndex(aVRef);
778 for (TopTools_ListIteratorOfListOfShape itlsh(myMapVE(ind));
779 itlsh.More(); itlsh.Next()) {
780 const TopoDS_Edge & edg = TopoDS::Edge(itlsh.Value());
781 orient = edg.Orientation();
782 if (!theRef.IsSame(edg)) {
783 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
784 TopAbs_Orientation vto = vte.Current().Orientation();
785// if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
786 if (vto == TopAbs_REVERSED && aVRef.IsSame(vte.Current())) {
787 ledge.Append(edg);
788 break;
789 }
790 }
791 }
792 }
793// ChoixUV(VF, theRef, F, ledge);
794 ChoixUV(aVRef, theRef, F, ledge);
795 if (ledge.Extent()==0) {
796 theOstat = BRepCheck_NotClosed;
797 if (Update) {
798 BRepCheck::Add(myMap(myShape),theOstat);
799 }
800 return theOstat;
801 }
802 }
0d969553 803 // End control closure 2d
7fd59977 804
805 Index ++;
806 }
807 }
808 if (Update) {
809 BRepCheck::Add(myMap(myShape),theOstat);
810 }
811 return theOstat;
812}
813//=======================================================================
814//function : SelfIntersect
815//purpose :
816//=======================================================================
817BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
818 TopoDS_Edge& retE1,
819 TopoDS_Edge& retE2,
820 const Standard_Boolean Update)
821{
822
823
824 Standard_Boolean ok;
825 Standard_Integer i,j,Nbedges;
826 Standard_Real first1,last1,first2,last2, tolint;
827 gp_Pnt2d pfirst1,plast1,pfirst2,plast2;
828 gp_Pnt P3d, P3d2;
829 Handle(BRepAdaptor_HSurface) HS;
830 Geom2dAdaptor_Curve C1, C2;
831 Geom2dInt_GInter Inter;
832 IntRes2d_Domain myDomain1;
833 TopTools_IndexedMapOfOrientedShape EMap;
834 TopTools_MapOfOrientedShape auxmape;
835 //
836 ok=Standard_True;
0d969553
Y
837 //-- check with proper tolerances if there is no
838 //-- point in the tolerance of a vertex.
7fd59977 839 tolint = 1.e-10;
840 HS = new BRepAdaptor_HSurface();
841 HS->ChangeSurface().Initialize(F,Standard_False);
842 //
843 for (TopoDS_Iterator Iter1(myShape);Iter1.More();Iter1.Next()) {
844 if (Iter1.Value().ShapeType() == TopAbs_EDGE) {
845 EMap.Add(Iter1.Value());
846 }
847 }
848 //
849 Nbedges=EMap.Extent();
850 if (!Nbedges) {
851 if (Update) {
852 BRepCheck::Add(myMap(myShape),BRepCheck_EmptyWire);
853 }
854 return(BRepCheck_EmptyWire);
855 }
856 //
857 IntRes2d_Domain *tabDom = new IntRes2d_Domain[Nbedges];
858 TColGeom2d_Array1OfCurve tabCur(1,Nbedges);
859 Bnd_Array1OfBox2d boxes(1,Nbedges);
860 //
861 for(i = 1; i <= Nbedges; i++) {
862 const TopoDS_Edge& E1 = TopoDS::Edge(EMap.FindKey(i));
863 if (i == 1) {
864 Handle(Geom2d_Curve) pcu = BRep_Tool::CurveOnSurface(E1, F, first1, last1);
865 if (pcu.IsNull()) {
866 retE1=E1;
867 if (Update) {
868 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
869 }
870 delete [] tabDom;
871 return(BRepCheck_SelfIntersectingWire);
872 }
873 //
874 C1.Load(pcu);
875 // To avoid exeption in Segment if C1 is BSpline - IFV
876 if(!C1.IsPeriodic()) {
877 if(C1.FirstParameter() > first1) {
878 first1 = C1.FirstParameter();
879 }
880 if(C1.LastParameter() < last1 ){
881 last1 = C1.LastParameter();
882 }
883 }
884 //
885 BRep_Tool::UVPoints(E1, F, pfirst1, plast1);
886 myDomain1.SetValues(pfirst1,first1,tolint, plast1,last1,tolint);
887 //
888 BndLib_Add2dCurve::Add(C1, first1, last1, Precision::PConfusion(), boxes(i));
889 }//if (i == 1) {
890 else {
891 C1.Load(tabCur(i));
892 myDomain1 = tabDom[i-1];
893 }
894 //
895 // Self intersect of C1
896 Inter.Perform(C1, myDomain1, tolint, tolint);
897 //
898 if(Inter.IsDone()) {
899 Standard_Integer nbp = Inter.NbPoints();
6e6cd5d9 900 //Standard_Integer nbs = Inter.NbSegments();
7fd59977 901 //
902 for(Standard_Integer p=1;p<=nbp;p++) {
903 const IntRes2d_IntersectionPoint& IP=Inter.Point(p);
904 const IntRes2d_Transition& Tr1 = IP.TransitionOfFirst();
905 const IntRes2d_Transition& Tr2 = IP.TransitionOfSecond();
906 if( Tr1.PositionOnCurve() == IntRes2d_Middle
907 || Tr2.PositionOnCurve() == IntRes2d_Middle) {
0d969553
Y
908 //-- Checking of points with true tolerances (ie Tol in 3d)
909 //-- If the point of intersection is within the tolearnce of a vertex
910 //-- this intersection is considered correct (no error)
7fd59977 911 Standard_Boolean localok = Standard_False;
912 Standard_Real f,l;
913 TopLoc_Location L;
914 const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f,l);
915 if(!ConS.IsNull()) {
0d969553 916 //-- try to test in 3d. (ParamOnSecond gives the same result)
7fd59977 917 P3d = ConS->Value(IP.ParamOnFirst());
918 P3d.Transform(L.Transformation());
919 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
920 }
921 else {
922 gp_Pnt2d aP2d = C1.Value(IP.ParamOnFirst());
923 P3d = HS->Value(aP2d.X(), aP2d.Y());
924 }
925 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
926 TopExp_Explorer ExplVtx;
927 for(ExplVtx.Init(E1,TopAbs_VERTEX);
928 localok==Standard_False && ExplVtx.More();
929 ExplVtx.Next()) {
930 gp_Pnt p3dvtt;
931 Standard_Real tolvtt, p3dvttDistanceP3d;
932 //
933 const TopoDS_Vertex& vtt = TopoDS::Vertex(ExplVtx.Current());
934 p3dvtt = BRep_Tool::Pnt(vtt);
935 tolvtt = BRep_Tool::Tolerance(vtt);
936 tolvtt=tolvtt*tolvtt;
937 p3dvttDistanceP3d=p3dvtt.SquareDistance(P3d);
938 if(p3dvttDistanceP3d <= tolvtt) {
939 localok=Standard_True;
940 }
941 }
942 if(localok==Standard_False) {
943 ok=0;
944 retE1=E1;
945 if (Update) {
946 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
947 }
948 delete [] tabDom;
949#ifdef DEB
950 static Standard_Integer numpoint=0;
951 cout<<"point p"<<++numpoint<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;cout.flush();
952#endif
953 return(BRepCheck_SelfIntersectingWire);
954 }
955 }
956 }
957 }// if(Inter.IsDone()) {
958 //
959 for(j=i+1; j<=Nbedges; j++) {
960 const TopoDS_Edge& E2 = TopoDS::Edge(EMap.FindKey(j));
961 if (i == 1) {
962 tabCur(j) = BRep_Tool::CurveOnSurface(E2,F,first2,last2);
963 if (!tabCur(j).IsNull() && last2 > first2) {
964 C2.Load(tabCur(j));
965 // To avoid exeption in Segment if C2 is BSpline - IFV
966 if(!C2.IsPeriodic()) {
967 if(C2.FirstParameter() > first2) {
968 first2 = C2.FirstParameter();
969 }
970 if(C2.LastParameter() < last2 ) {
971 last2 = C2.LastParameter();
972 }
973 }
974 //
975 BRep_Tool::UVPoints(E2,F,pfirst2,plast2);
976 tabDom[j-1].SetValues(pfirst2,first2,tolint,plast2,last2,tolint);
977
978 BndLib_Add2dCurve::Add( C2, first2, last2, Precision::PConfusion(), boxes(j) );
979 }
980 else {
981 delete [] tabDom;
982#ifdef DEB
983 cout<<"BRepCheck_NoCurveOnSurface or BRepCheck_InvalidRange"<<endl;cout.flush();
984#endif
985 if(tabCur(j).IsNull()) {
986 return(BRepCheck_NoCurveOnSurface);
987 }
988 return (BRepCheck_InvalidRange);
989 }
990 }// if (i == 1) {
991 else {
992 C2.Load(tabCur(j));
993 }
994 //
995 if (boxes(i).IsOut( boxes(j))) {
996 continue;
997 }
998 //modified by NIZNHY-PKV Fri Oct 29 10:09:01 2010f
999 if (E1.IsSame(E2)) {
1000 continue;
1001 }
1002 //modified by NIZNHY-PKV Fri Oct 29 10:09:02 2010t
1003 //
1004 //-- ************************************************************
0d969553 1005 //-- ******* I n t e r s e c t i o n C 1 and C 2 ********
7fd59977 1006 //-- ************************************************************
1007 Inter.Perform(C1,myDomain1,C2,tabDom[j-1],tolint,tolint);
1008 //
1009 if(Inter.IsDone()) {
1010 Standard_Integer nbp, nbs;
1011 Standard_Real IP_ParamOnFirst, IP_ParamOnSecond;
1012 IntRes2d_Transition Tr1,Tr2;
1013 TopTools_ListOfShape CommonVertices;
1014 TopTools_ListIteratorOfListOfShape itl;
1015 TopTools_MapOfShape Vmap;
1016 //
1017 TopoDS_Iterator it( E1 );
1018 for (; it.More(); it.Next()) {
1019 Vmap.Add( it.Value() );
1020 }
1021 //
1022 it.Initialize( E2 );
1023 for (; it.More(); it.Next()) {
1024 const TopoDS_Shape& V = it.Value();
1025 if (Vmap.Contains( V )) {
1026 CommonVertices.Append( V );
1027 }
1028 }
1029 //
1030 nbp = Inter.NbPoints();
1031 nbs = Inter.NbSegments();
1032 IP_ParamOnFirst = 0.;
1033 IP_ParamOnSecond = 0.;
1034 //
1035 //// **** Points of intersection **** ////
1036 for (Standard_Integer p = 1; p <= nbp; p++) {
1037 const IntRes2d_IntersectionPoint& IP = Inter.Point(p);
1038 IP_ParamOnFirst = IP.ParamOnFirst();
1039 IP_ParamOnSecond = IP.ParamOnSecond();
1040 Tr1 = IP.TransitionOfFirst();
1041 Tr2 = IP.TransitionOfSecond();
1042 if( Tr1.PositionOnCurve() == IntRes2d_Middle
1043 || Tr2.PositionOnCurve() == IntRes2d_Middle) {
0d969553
Y
1044 //-- Checking of points with true tolerances (ie Tol in 3d)
1045 //-- If the point of intersection is within the tolerance of a vertex
1046 //-- this intersection is considered correct (no error)
7fd59977 1047 Standard_Boolean localok = Standard_False;
1048 Standard_Real f1,l1, f2, l2;
1049 TopLoc_Location L, L2;
1050 //
1051 const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f1,l1);
1052 const Handle(Geom_Curve) ConS2 = BRep_Tool::Curve(E2,L2,f2,l2);
1053 //gka protect against working out of edge range
1054 if ( f1-IP_ParamOnFirst > ::Precision::PConfusion() ||
1055 IP_ParamOnFirst-l1 > ::Precision::PConfusion() ||
1056 f2-IP_ParamOnSecond > ::Precision::PConfusion() ||
1057 IP_ParamOnSecond-l2 > ::Precision::PConfusion() )
1058 continue;
1059 Standard_Real tolvtt;
1060 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1061 if (!ConS.IsNull()) {
1062 P3d = ConS->Value(IP_ParamOnFirst);
1063 P3d.Transform(L.Transformation());
1064 }
1065 else {
1066 gp_Pnt2d aP2d = C1.Value(IP_ParamOnFirst);
1067 P3d = HS->Value(aP2d.X(), aP2d.Y());
1068 }
1069 //
1070 if (!ConS2.IsNull()) {
1071 P3d2 = ConS2->Value(IP_ParamOnSecond);
1072 P3d2.Transform(L2.Transformation());
1073 }
1074 else {
1075 gp_Pnt2d aP2d = C2.Value(IP_ParamOnSecond);
1076 P3d2 = HS->Value(aP2d.X(), aP2d.Y());
1077 }
1078 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1079 itl.Initialize( CommonVertices );
1080 for (; itl.More(); itl.Next()) {
1081 Standard_Real p3dvttDistanceP3d, p3dvttDistanceP3d2;
1082 gp_Pnt p3dvtt;
1083 //
1084 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1085 p3dvtt = BRep_Tool::Pnt(vtt);
1086 tolvtt = BRep_Tool::Tolerance(vtt);
1087 tolvtt=1.1*tolvtt;
1088 tolvtt=tolvtt*tolvtt;
1089 p3dvttDistanceP3d = p3dvtt.SquareDistance(P3d);
1090 p3dvttDistanceP3d2 = p3dvtt.SquareDistance(P3d2);
1091 //
1092 if (p3dvttDistanceP3d<=tolvtt && p3dvttDistanceP3d2<=tolvtt) {
1093 localok = Standard_True;
1094 break;
1095 }
1096 }
1097
1098 //-- --------------------------------------------------------
0d969553 1099 //-- Check maximum yawn between 2 edges
7fd59977 1100 //--
0d969553
Y
1101 //-- Check distance from edges to the curve joining
1102 //-- the point of intersection with vertex (if exists)
7fd59977 1103 if (localok == Standard_False && !CommonVertices.IsEmpty()) {
1104#ifdef DEB
1105 cout << "\n------------------------------------------------------\n" <<endl;
1106 cout << "\n--- BRepCheck Wire: AutoIntersection Phase1 -> Erreur \n" <<endl;
1107
1108#endif
1109 Standard_Boolean yaunvtxproche;
1110 Standard_Real distauvtxleplusproche,VParaOnEdge1,VParaOnEdge2;
1111 gp_Pnt VertexLePlusProche;
1112 //
1113 yaunvtxproche=Standard_False;
1114 VParaOnEdge1 =0.;
1115 VParaOnEdge2 =0.;
1116 distauvtxleplusproche=RealLast();
1117 //Find the nearest common vertex
1118 itl.Initialize( CommonVertices );
1119 for (; itl.More(); itl.Next()) {
1120 Standard_Real tolvtt, disptvtx;
1121 gp_Pnt p3dvtt;
1122 //
1123 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1124 p3dvtt = BRep_Tool::Pnt(vtt);
1125 tolvtt = BRep_Tool::Tolerance(vtt);
1126 disptvtx = P3d.Distance(p3dvtt);
1127 if (disptvtx < distauvtxleplusproche) {
1128 VertexLePlusProche = p3dvtt;
1129 distauvtxleplusproche = disptvtx;
1130 VParaOnEdge1 = BRep_Tool::Parameter(vtt,E1);
1131 VParaOnEdge2 = BRep_Tool::Parameter(vtt,E2);
1132 }
1133 // eap: case of closed edge
1134 else if (IsEqual(distauvtxleplusproche, disptvtx)) {
1135 Standard_Real newVParaOnEdge1 = BRep_Tool::Parameter(vtt,E1);
1136 Standard_Real newVParaOnEdge2 = BRep_Tool::Parameter(vtt,E2);
1137 if (Abs(IP_ParamOnFirst - VParaOnEdge1) + Abs(IP_ParamOnSecond - VParaOnEdge2)
1138 >
1139 Abs(IP_ParamOnFirst - newVParaOnEdge1) + Abs(IP_ParamOnSecond - newVParaOnEdge2)) {
1140 VertexLePlusProche = p3dvtt;
1141 VParaOnEdge1 = newVParaOnEdge1;
1142 VParaOnEdge2 = newVParaOnEdge2;
1143 }
1144 }
1145 }
1146 //Patch: extraordinar situation (e.g. tolerance(v) == 0.)
1147 // Modified by skv - Wed Jul 23 12:28:11 2003 OCC1764 Begin
1148 // if (VertexLePlusProche.Distance( P3d ) <= gp::Resolution())
1149 if (VertexLePlusProche.Distance(P3d) <= gp::Resolution() ||
1150 VertexLePlusProche.Distance(P3d2) <= gp::Resolution()) {
1151 // Modified by skv - Wed Jul 23 12:28:12 2003 OCC1764 End
1152 localok = Standard_True;
1153 }
1154 else {
1155 gp_Lin Lig( VertexLePlusProche, gp_Vec(VertexLePlusProche,P3d) );
1156 Standard_Real du1 = 0.1*(IP_ParamOnFirst -VParaOnEdge1);
1157 Standard_Real du2 = 0.1*(IP_ParamOnSecond-VParaOnEdge2);
1158 Standard_Real maxd1 = 0., maxd2 = 0.;
1159 Standard_Integer k;
1160
1161 localok = Standard_True;
1162 Standard_Real tole1 = BRep_Tool::Tolerance(E1);
1163 for (k = 2; localok && k < 9; k++) {
0d969553 1164 Standard_Real u = VParaOnEdge1 + k*du1; // check if it works
7fd59977 1165 gp_Pnt P1;
1166 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1167 if (!ConS.IsNull()) {
1168 P1 = ConS->Value(u);
1169 P1.Transform(L.Transformation());
1170 }
1171 else {
1172 gp_Pnt2d aP2d = C1.Value(u);
1173 P1 = HS->Value(aP2d.X(), aP2d.Y());
1174 }
1175 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1176 Standard_Real d1 = Lig.Distance(P1);
1177 if (d1 > maxd1) {
1178 maxd1 = d1;
1179 }
1180 if (d1 > tole1*2.0){
1181 localok = Standard_False;
1182 }
1183 }
0d969553 1184 //-- same for edge2
7fd59977 1185 // Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764 Begin
1186 gp_Dir aTmpDir(P3d2.XYZ().Subtracted(VertexLePlusProche.XYZ()));
1187
1188 Lig.SetDirection(aTmpDir);
1189 // Modified by skv - Wed Jul 23 12:22:23 2003 OCC1764 End
1190 Standard_Real tole2 = BRep_Tool::Tolerance(E2);
1191 for (k = 2; localok && k < 9; k++) {
0d969553 1192 Standard_Real u = VParaOnEdge2 + k*du2; // check if it works
7fd59977 1193 gp_Pnt P2;
1194 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1195 if (!ConS2.IsNull()) {
1196 P2 = ConS2->Value(u);
1197 P2.Transform(L2.Transformation());
1198 }
1199 else {
1200 gp_Pnt2d aP2d = C2.Value(u);
1201 P2 = HS->Value(aP2d.X(), aP2d.Y());
1202 }
1203 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1204 Standard_Real d2 = Lig.Distance(P2);
1205 if (d2 > maxd2) {
1206 maxd2 = d2;
1207 }
1208 if (d2 > tole2*2.0){
1209 localok = Standard_False;
1210 }
1211 }
1212#ifdef DEB
1213 if(localok) {
1214 printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Bon \n");
1215 printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
1216 printf("--- Erreur Max sur E1 : %10.7g Tol_Edge:%10.7g\n",maxd1,tole1);
1217 printf("--- Erreur Max sur E2 : %10.7g Tol_Edge:%10.7g\n",maxd2,tole2);
1218 fflush(stdout);
1219 }
1220 else {
1221 printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Erreur \n");
1222 printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
1223 printf("--- Erreur Max sur E1 : %10.7g Tol_Edge:%10.7g\n",maxd1,tole1);
1224 printf("--- Erreur Max sur E2 : %10.7g Tol_Edge:%10.7g\n",maxd2,tole2);
1225 fflush(stdout);
1226 }
1227#endif
1228 } //end of else (construction of the line Lig)
1229 } //end of if (localok == Standard_False && !CommonVertices.IsEmpty())
1230 //
1231 if(localok==Standard_False) {
1232 ok=0;
1233 retE1=E1;
1234 retE2=E2;
1235 if (Update) {
1236 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1237 }
1238#ifdef DEB
1239 static Standard_Integer numpoint1=0;
1240 cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
1241 cout.flush();
1242#endif
1243 delete [] tabDom;
1244 return(BRepCheck_SelfIntersectingWire);
1245 } //-- localok == False
1246 } //end of if(Tr1.PositionOnCurve() == IntRes2d_Middle || Tr2.PositionOnCurve() == IntRes2d_Middle)
1247 } //end of for (Standard_Integer p=1; p <= nbp; p++)
1248 ////
1249 //// **** Segments of intersection **** ////
1250 for (Standard_Integer s = 1; s <= nbs; ++s) {
1251 const IntRes2d_IntersectionSegment& Seg = Inter.Segment(s);
1252 if (Seg.HasFirstPoint() && Seg.HasLastPoint()) {
1253 Standard_Boolean localok;
1254 Standard_Integer k;
1255 IntRes2d_IntersectionPoint PSeg [2];
1256 IntRes2d_Position aPCR1, aPCR2;
1257 //
1258 localok = Standard_False;
1259 PSeg[0] = Seg.FirstPoint();
1260 PSeg[1] = Seg.LastPoint();
1261 // At least one of extremities of the segment must be inside
1262 // the tolerance of a common vertex
1263 for (k = 0; k < 2; ++k) {
1264 IP_ParamOnFirst = PSeg[k].ParamOnFirst();
1265 IP_ParamOnSecond = PSeg[k].ParamOnSecond();
1266 Tr1 = PSeg[k].TransitionOfFirst();
1267 Tr2 = PSeg[k].TransitionOfSecond();
1268 aPCR1=Tr1.PositionOnCurve();
1269 aPCR2=Tr2.PositionOnCurve();
1270 //
1271 if(aPCR1!=IntRes2d_Middle && aPCR2!=IntRes2d_Middle) {
1272 GeomAbs_CurveType aCT1, aCT2;
1273 //ZZ
1274 aCT1=C1.GetType();
1275 aCT2=C2.GetType();
1276 if (aCT1==GeomAbs_Line && aCT2==GeomAbs_Line) {
1277 // check for the two lines coincidence
1278 Standard_Real aPAR_T, aT11, aT12, aT21, aT22, aT1m, aT2m;
1279 Standard_Real aD2, aTolE1, aTolE2, aTol2, aDot;
1280 gp_Lin2d aL1, aL2;
1281 gp_Pnt2d aP1m;
1282 //
1283 aPAR_T=0.43213918;
1284 //
1285 aTolE1=BRep_Tool::Tolerance(E1);
1286 aTolE2=BRep_Tool::Tolerance(E2);
1287 aTol2=aTolE1+aTolE2;
1288 aTol2=aTol2*aTol2;
1289 //
1290 aL1=C1.Line();
1291 aL2=C2.Line();
1292 //
1293 aT11=PSeg[0].ParamOnFirst();
1294 aT12=PSeg[1].ParamOnFirst();
1295 aT21=PSeg[0].ParamOnSecond();
1296 aT22=PSeg[1].ParamOnSecond();
1297 //
1298 aT1m=(1.-aPAR_T)*aT11 + aPAR_T*aT12;
1299 aP1m=C1.Value(aT1m);
1300 //
1301 aD2=aL2.SquareDistance(aP1m);
1302 if (aD2<aTol2) {
1303 aT2m=ElCLib::Parameter(aL2, aP1m);
1304 if (aT2m>aT21 && aT2m<aT22) {
1305 const gp_Dir2d& aDir1=aL1.Direction();
1306 const gp_Dir2d& aDir2=aL2.Direction();
1307 aDot=aDir1*aDir2;
1308 if (aDot<0.) {
1309 aDot=-aDot;
1310 }
1311 //
1312 if ((1.-aDot)<5.e-11){//0.00001 rad
1313 localok = Standard_False;
1314 break;// from for (k = 0; k < 2; ++k){...
1315 }
1316 }//if (aT2m>aT21 && aT2m<aT22) {
1317 }//if (aD2<aTol2) {
1318 }//if (aCT1==GeomAbs_Line && aCT2==GeomAbs_Line) {
1319 //ZZ
1320 localok = Standard_True;
1321 break;
1322 }
1323 //
1324 Standard_Real f,l, tolvtt;
1325 TopLoc_Location L, L2;
1326 const Handle(Geom_Curve)& ConS = BRep_Tool::Curve(E1,L,f,l);
1327 const Handle(Geom_Curve)& ConS2 = BRep_Tool::Curve(E2,L2,f,l);
1328 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1329 if (!ConS.IsNull()) {
1330 P3d = ConS->Value(IP_ParamOnFirst);
1331 P3d.Transform(L.Transformation());
1332 } else {
1333 gp_Pnt2d aP2d = C1.Value(IP_ParamOnFirst);
1334 P3d = HS->Value(aP2d.X(), aP2d.Y());
1335 }
1336 if (!ConS2.IsNull()) {
1337 P3d2 = ConS2->Value(IP_ParamOnSecond);
1338 P3d2.Transform(L2.Transformation());
1339 } else {
1340 gp_Pnt2d aP2d = C2.Value(IP_ParamOnSecond);
1341 P3d2 = HS->Value(aP2d.X(), aP2d.Y());
1342 }
1343 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1344 itl.Initialize( CommonVertices );
1345 for (; itl.More(); itl.Next()) {
1346 Standard_Real p3dvttDistanceP3d, p3dvttDistanceP3d2;
1347 gp_Pnt p3dvtt;
1348 //
1349 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1350 p3dvtt = BRep_Tool::Pnt(vtt);
1351 tolvtt = BRep_Tool::Tolerance(vtt);
1352 tolvtt=1.1*tolvtt;
1353 tolvtt=tolvtt*tolvtt;
1354 p3dvttDistanceP3d = p3dvtt.SquareDistance(P3d);
1355 p3dvttDistanceP3d2 = p3dvtt.SquareDistance(P3d2);
1356 if (p3dvttDistanceP3d <= tolvtt && p3dvttDistanceP3d2 <= tolvtt) {
1357 localok = Standard_True;
1358 break;
1359 }
1360 }
1361 if (localok == Standard_True) {
1362 break;
1363 }
1364 } //end of for (k = 0; k < 2; k++)
1365 //
1366 if(localok==Standard_False) {
1367 ok=0;
1368 retE1=E1;
1369 retE2=E2;
1370 if (Update) {
1371 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1372 }
1373#ifdef DEB
1374 static Standard_Integer numpoint1=0;
1375 cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
1376 cout.flush();
1377#endif
1378 delete [] tabDom;
1379 return(BRepCheck_SelfIntersectingWire);
1380 } //-- localok == False
1381 } //end of if(Seg.HasFirstPoint() && Seg.HasLastPoint())
1382 } //end of for (Standard_Integer s = 1; s <= nbs; p++)
1383 } //-- Inter.IsDone()
1384 } //end of for( j = i+1; j<=Nbedges; j++)
1385 } //end of for(i = 1; i <= Nbedges; i++)
1386 //
1387 delete [] tabDom;
1388 if (Update) {
1389 BRepCheck::Add(myMap(myShape),BRepCheck_NoError);
1390 }
1391 //
1392 return (BRepCheck_NoError);
1393}
1394//=======================================================================
1395//function : GeometricControls
1396//purpose :
1397//=======================================================================
1398void BRepCheck_Wire::GeometricControls(const Standard_Boolean B)
1399{
1400 if (myGctrl != B) {
1401 if (B) {
1402 myCdone = Standard_False;
1403 }
1404 myGctrl = B;
1405 }
1406}
1407//=======================================================================
1408//function : GeometricControls
1409//purpose :
1410//=======================================================================
1411Standard_Boolean BRepCheck_Wire::GeometricControls() const
1412{
1413 return myGctrl;
1414}
1415
1416
1417//=======================================================================
1418//function : Propagate
1419//purpose : fill <mapE> with edges connected to <edg> through vertices
1420// contained in <mapVE>
1421//=======================================================================
1422static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape& mapVE,
1423 const TopoDS_Shape& edg,
1424 TopTools_MapOfShape& mapE)
1425{
1426 if (mapE.Contains(edg)) {
1427 return;
1428 }
0d969553
Y
1429 mapE.Add(edg); // attention, if oriented == Standard_True, edge should
1430 // be FORWARD or REVERSED. It is not checked.
7fd59977 1431 // =============
1432 // attention, if oriented == Standard_True, <edg> must
1433 // be FORWARD or REVERSED. That is not checked.
1434
1435 TopExp_Explorer ex;
1436 for (ex.Init(edg,TopAbs_VERTEX); ex.More(); ex.Next()) {
1437 const TopoDS_Vertex& vtx = TopoDS::Vertex(ex.Current());
0d969553 1438 // debug on vertex
7fd59977 1439 Standard_Integer indv = mapVE.FindIndex(vtx);
1440 if (indv != 0) {
1441 for (TopTools_ListIteratorOfListOfShape itl(mapVE(indv)); itl.More(); itl.Next()) {
1442 if (!itl.Value().IsSame(edg) &&
1443 !mapE.Contains(itl.Value())) {
1444 Propagate(mapVE,itl.Value(),mapE);
1445 }
1446 }
1447 }
1448 }
1449}
1450//=======================================================================
1451//function : GetOrientation
1452//purpose :
1453//=======================================================================
1454
1455static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape& mapE,
1456 const TopoDS_Edge& edg)
1457{
1458 TopTools_MapIteratorOfMapOfShape itm(mapE);
1459 for ( ; itm.More(); itm.Next()) {
1460 if (itm.Key().IsSame(edg)) {
1461 break;
1462 }
1463 }
1464 return itm.Key().Orientation();
1465}
1466//=======================================================================
1467//function : ChoixUV
1468//purpose :
1469//=======================================================================
1470 void ChoixUV(const TopoDS_Vertex& V,
1471 const TopoDS_Edge& Edg,
1472 const TopoDS_Face& F,
1473 TopTools_ListOfShape& L)
1474{
1475 TopTools_ListIteratorOfListOfShape It( L );
1476 while (It.More())
1477 {
1478 if (Edg.IsSame( It.Value() ))
1479 L.Remove( It );
1480 else
1481 It.Next();
1482 }
1483
1484 Standard_Integer index = 0, imin = 0;
1485 TopoDS_Edge Evois;
1486 gp_Pnt2d PntRef, Pnt;
1487 gp_Vec2d DerRef, Der;
1488 Standard_Real MinAngle, MaxAngle, angle;
1489 Standard_Real gpResolution=gp::Resolution();
1490 TopAbs_Orientation aVOrientation, aEdgOrientation;
7fd59977 1491 Standard_Real dist2d = 0, p = 0;
7fd59977 1492 Standard_Real f, l, parpiv;
1493 Standard_Real tolv = BRep_Tool::Tolerance(V);
1494 BRepAdaptor_Surface Ads(F,Standard_False); // no restriction
1495 Standard_Real ures = Ads.UResolution(tolv);
1496 Standard_Real vres = Ads.VResolution(tolv);
1497 Standard_Real tol = Max(ures,vres);
1498 if(tol<=0.0) {
1499#ifdef DEB
0d969553
Y
1500
1501 cout<<"BRepCheck_Wire : UResolution and VResolution = 0.0 (Face too small ?)"<<endl;cout.flush();
7fd59977 1502#endif
1503 }
1504 else {
0d969553 1505 tol += tol;
7fd59977 1506 }
1507 //
1508 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(Edg, F, f, l);
1509 if (C2d.IsNull()) {// JAG 10.12.96
1510 return;
1511 }
1512
1513 aVOrientation=V.Orientation();
1514 aEdgOrientation=Edg.Orientation();
1515
1516 parpiv =(aVOrientation==aEdgOrientation) ? f : l;
1517
1518 MinAngle = RealLast();
1519 MaxAngle = RealFirst();
1520
1521 CurveDirForParameter(C2d, parpiv, PntRef, DerRef);
1522
1523 if (aVOrientation != aEdgOrientation){
1524 DerRef.Reverse();
1525 }
1526 //
1527 It.Initialize(L);
1528 for (; It.More(); It.Next()) {
1529 index++;
1530 const TopoDS_Edge& aE=TopoDS::Edge(It.Value());
1531 C2d = BRep_Tool::CurveOnSurface(aE, F, f, l);
1532 if(C2d.IsNull()) {
1533 continue;
1534 }
1535
1536 p =(aVOrientation != aE.Orientation()) ? f : l;
1537 //
1538 Pnt = C2d->Value(p);
1539 dist2d = Pnt.Distance( PntRef );
1540 if (dist2d > tol){
1541 continue;
1542 }
1543 //
1544 CurveDirForParameter(C2d, p, Pnt, Der);
1545
1546 if (aVOrientation == aE.Orientation()){
1547 Der.Reverse();
1548 }
1549
1550 if (DerRef.Magnitude() <= gpResolution ||
1551 Der.Magnitude() <= gpResolution){
1552 continue;
1553 }
1554 //
1555 angle = DerRef.Angle( Der );
1556 angle *= -1.;
1557 if (angle < 0.)
c6541a0c 1558 angle += 2.*M_PI;
7fd59977 1559
1560 if (F.Orientation() == TopAbs_FORWARD) {
1561 if (angle < MinAngle) {
1562 imin = index;
1563 MinAngle = angle;
1564 }
1565 }
1566 else { //F.Orientation() != TopAbs_FORWARD
1567 if (angle > MaxAngle){
1568 imin = index;
1569 MaxAngle = angle;
1570 }
1571 }
1572 }//end of for
1573 //
0d969553 1574 // Update edge
7fd59977 1575 if (imin == 0)
1576 if (L.Extent() == 1) {
1577 Standard_Boolean onjette = 0; //all right
1578 Evois = TopoDS::Edge(L.First());
1579 if (dist2d > tol) {
1580#ifdef DEB
0d969553 1581 cout<<"BRepCheckWire : control closure in 2d --> false"<<endl;cout.flush();
7fd59977 1582#endif
1583 if(Evois.IsNull() || BRep_Tool::Degenerated(Edg) ||
1584 BRep_Tool::Degenerated(Evois)){
1585 onjette = 1; //bad
1586 }
1587 else {
1588 Ads.Initialize(F);
1589 Standard_Real dumax = 0.01 * (Ads.LastUParameter() - Ads.FirstUParameter());
1590 Standard_Real dvmax = 0.01 * (Ads.LastVParameter() - Ads.FirstVParameter());
1591 Standard_Real dumin = Abs(Pnt.X() - PntRef.X());
1592 Standard_Real dvmin = Abs(Pnt.Y() - PntRef.Y());
1593 if(dumin > dumax || dvmin > dvmax){
1594 onjette = 1;
1595 }
1596 else {
1597 BRepAdaptor_Curve bcEdg(Edg,F);
1598 BRepAdaptor_Curve bcEvois(Evois,F);
1599 gp_Pnt pEdg = bcEdg.Value(parpiv);
1600 gp_Pnt pEvois = bcEvois.Value(p);
1601 Standard_Real d3d = pEvois.Distance(pEdg);
1602#ifdef DEB
1603 cout<<"point P "<<pEdg.X()<<" "<<pEdg.Y()<<" "<<pEdg.Z()<<endl;
1604 cout<<"distance 3d : "<<d3d<<endl;
1605 cout<<"tolerance vertex : "<<tolv<<endl;
1606 cout.flush();
1607#endif
1608 //if(d3d > tolv){
1609 if(d3d > 2.*tolv){
1610 onjette = 1;
1611 }
1612#ifdef DEB
1613 else
0d969553 1614 cout<<"control closure in 3d --> ok"<<endl;cout.flush();
7fd59977 1615#endif
1616 }
1617 }
1618 } //if (dist2d > tol)
1619 else {//angle was not defined but points are close
1620 onjette = 0;
1621 }
1622 if(onjette) {
1623#ifdef DEB
0d969553 1624 cout<<"control closure in 3d --> false"<<endl;cout.flush();
7fd59977 1625#endif
1626 L.Clear();
1627 }
1628 }
1629 else {
1630 L.Clear();
1631 }
1632 else {
1633 index = 1;
1634 while (index < imin) {
1635 L.RemoveFirst();
1636 index++;
1637 }
1638 It.Initialize(L);
1639 It.Next();
1640 while (It.More())
1641 L.Remove(It);
1642 }
1643}
1644//=======================================================================
1645//function : CurveDirForParameter
1646//purpose :
1647//=======================================================================
1648void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
1649 const Standard_Real aPrm,
1650 gp_Pnt2d& Pnt,
1651 gp_Vec2d& aVec2d)
1652{
1653 Standard_Real aTol=gp::Resolution();
1654 Standard_Integer i;
1655
1656 aC2d->D1(aPrm, Pnt, aVec2d);
1657 //
1658 if (aVec2d.Magnitude() <= aTol) {
1659 for (i = 2; i <= 100; i++){
1660 aVec2d = aC2d->DN(aPrm, i);
1661 if (aVec2d.Magnitude() > aTol) {
1662 break;
1663 }
1664 }
1665 }
1666}
1667
1668// Modified by Sergey KHROMOV - Wed May 22 10:44:06 2002 OCC325 Begin
1669//=======================================================================
1670//function : GetPnts2d
1671//purpose : this function returns the parametric points of theVertex on theFace.
1672// If theVertex is a start and end vertex of theEdge hasSecondPnt
1673// becomes Standard_True and aPnt2 returns the second parametric point.
1674// Returns Standard_True if paraametric points are successfully found.
1675//=======================================================================
1676
1677static Standard_Boolean GetPnt2d(const TopoDS_Vertex &theVertex,
1678 const TopoDS_Edge &theEdge,
1679 const TopoDS_Face &theFace,
1680 gp_Pnt2d &aPnt)
1681{
1682 Handle(Geom2d_Curve) aPCurve;
1683 Standard_Real aFPar;
1684 Standard_Real aLPar;
1685 Standard_Real aParOnEdge;
1686 TopoDS_Vertex aFirstVtx;
1687 TopoDS_Vertex aLastVtx;
1688
1689 TopExp::Vertices(theEdge, aFirstVtx, aLastVtx);
1690
1691 if (!theVertex.IsSame(aFirstVtx) && !theVertex.IsSame(aLastVtx))
1692 return Standard_False;
1693
1694 aPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFPar, aLPar);
1695
1696 if (aPCurve.IsNull())
1697 return Standard_False;
1698
1699 aParOnEdge = BRep_Tool::Parameter(theVertex, theEdge);
1700 aPnt = aPCurve->Value(aParOnEdge);
1701
1702 return Standard_True;
1703}
1704
1705//=======================================================================
1706//function : Closed2dForPeriodicFace
1707//purpose : Checks the distance between first point of the first edge
1708// and last point of the last edge in 2d for periodic face.
1709//=======================================================================
1710static Standard_Boolean IsClosed2dForPeriodicFace
1711 (const TopoDS_Face &theFace,
1712 const gp_Pnt2d &theP1,
1713 const gp_Pnt2d &theP2,
1714 const TopoDS_Vertex &theVertex)
1715{
1716// Check 2d distance for periodic faces with seam edge.
1717// Searching for seam edges
1718 TopTools_ListOfShape aSeamEdges;
1719 TopTools_MapOfShape NotSeams;
1720 TopTools_MapOfShape ClosedEdges;
1721 TopExp_Explorer anExp(theFace, TopAbs_EDGE);
1722
1723 for (;anExp.More(); anExp.Next()) {
1724 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
1725
1726 if (NotSeams.Contains(anEdge))
1727 continue;
1728
1729 if (!IsOriented(anEdge) ||
1730 !BRep_Tool::IsClosed(anEdge, theFace)) {
1731 NotSeams.Add(anEdge);
1732 continue;
1733 }
1734
1735 if (!ClosedEdges.Add(anEdge))
1736 aSeamEdges.Append(anEdge);
1737 }
1738
1739 if (aSeamEdges.Extent() == 0)
1740 return Standard_True;
1741
1742// check if theVertex lies on one of the seam edges
1743 BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
1744 Standard_Real aTol = BRep_Tool::Tolerance(theVertex);
1745 Standard_Real aUResol = aFaceSurface.UResolution(aTol);
1746 Standard_Real aVResol = aFaceSurface.VResolution(aTol);
1747 Standard_Real aVicinity = Sqrt(aUResol*aUResol + aVResol*aVResol);
1748 Standard_Real aDistP1P2 = theP1.Distance(theP2);
1749
1750
1751 TopTools_ListIteratorOfListOfShape anIter(aSeamEdges);
1752
1753 for (; anIter.More(); anIter.Next()) {
1754 TopoDS_Edge aSeamEdge = TopoDS::Edge(anIter.Value());
1755
1756 anExp.Init(aSeamEdge, TopAbs_VERTEX);
1757 for (; anExp.More(); anExp.Next()) {
1758 const TopoDS_Shape &aVtx = anExp.Current();
1759
1760// We found an edge. Check the distance between two given points
1761// to be lower than the computed tolerance.
1762 if (IsOriented(aVtx) && aVtx.IsSame(theVertex)) {
1763 gp_Pnt2d aPnt1;
1764 gp_Pnt2d aPnt2;
1765 Standard_Real a2dTol;
1766
1767 if (!GetPnt2d(theVertex, aSeamEdge, theFace, aPnt1))
1768 continue;
1769
1770 aSeamEdge = TopoDS::Edge(aSeamEdge.Reversed());
1771
1772 if (!GetPnt2d(theVertex, aSeamEdge, theFace, aPnt2))
1773 continue;
1774
1775 a2dTol = aPnt1.Distance(aPnt2)*1.e-2;
1776 a2dTol = Max(a2dTol, aVicinity);
1777
1778 if (aDistP1P2 > a2dTol)
1779 return Standard_False;
1780 }
1781 }
1782 }
1783
1784 return Standard_True;
1785}
1786// Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End