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