1 // Created on: 1995-12-12
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2014 OPEN CASCADE SAS
6 // This file is part of Open CASCADE Technology software library.
8 // This library is free software; you can redistribute it and/or modify it under
9 // the terms of the GNU Lesser General Public License version 2.1 as published
10 // by the Free Software Foundation, with special exception defined in the file
11 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
12 // distribution for complete text of the license and disclaimer of any warranty.
14 // Alternatively, this file may be used under the terms of Open CASCADE
15 // commercial license or contractual agreement.
17 // Modified by dpf, Fri Dec 19 15:31:03 1997
18 // Processing of closing in 2d.
19 // modified by eap Tue Dec 18 14:14:25 2001 (bug OCC23)
20 // Check self-intersection in case of closed edge
21 // modified by eap Fri Dec 21 17:36:55 2001 (bug OCC35)
24 // Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764
26 #include <BRepCheck_Wire.ixx>
27 #include <BRepCheck_ListOfStatus.hxx>
28 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
29 #include <TopTools_MapOfShape.hxx>
30 #include <TopTools_MapIteratorOfMapOfShape.hxx>
31 #include <TopTools_IndexedMapOfShape.hxx>
32 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
33 #include <TopTools_DataMapOfShapeListOfShape.hxx>
34 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
35 #include <TopTools_ListOfShape.hxx>
36 #include <TopTools_ListIteratorOfListOfShape.hxx>
37 #include <TopExp_Explorer.hxx>
38 #include <TopoDS_Iterator.hxx>
39 #include <TopLoc_Location.hxx>
40 #include <TColGeom2d_Array1OfCurve.hxx>
41 #include <IntRes2d_Intersection.hxx>
42 #include <IntRes2d_IntersectionPoint.hxx>
43 #include <IntRes2d_IntersectionSegment.hxx>
44 #include <IntRes2d_Transition.hxx>
45 #include <IntRes2d_Domain.hxx>
46 #include <Geom2dInt_GInter.hxx>
47 #include <gp_Pnt2d.hxx>
50 #include <Geom2d_Curve.hxx>
51 #include <Geom_Curve.hxx>
52 #include <Geom2dAdaptor_Curve.hxx>
53 #include <Geom2dAdaptor_HCurve.hxx>
54 #include <BRep_Tool.hxx>
55 #include <BRepAdaptor_Curve.hxx>
56 #include <BRepAdaptor_Surface.hxx>
57 #include <BRepAdaptor_HSurface.hxx>
58 #include <BRepCheck.hxx>
60 #include <TopoDS_Vertex.hxx>
61 #include <TopTools_MapOfOrientedShape.hxx>
62 #include <TopTools_HArray1OfShape.hxx>
63 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
66 #include <Precision.hxx>
67 #include <Bnd_Array1OfBox2d.hxx>
68 #include <BndLib_Add2dCurve.hxx>
72 #include <BRepTools_WireExplorer.hxx>
76 #include <TopTools_IndexedMapOfOrientedShape.hxx>
80 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape&,
81 const TopoDS_Shape&, // edge
82 TopTools_MapOfShape&); // mapofedge
85 static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape&,
90 void ChoixUV(const TopoDS_Vertex&,
93 TopTools_ListOfShape&);
95 // 20/03/02 akm vvv (OCC234)
97 // Standard_Boolean CheckLoopOrientation( const TopoDS_Vertex&,
98 // const TopoDS_Edge&,
99 // const TopoDS_Edge&,
100 // const TopoDS_Face&,
101 // TopTools_ListOfShape&);
104 inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
106 return (S.Orientation() == TopAbs_FORWARD ||
107 S.Orientation() == TopAbs_REVERSED);
111 void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
112 const Standard_Real aPrm,
116 // Modified by Sergey KHROMOV - Thu Jun 20 11:21:51 2002 OCC325 Begin
117 static Standard_Boolean IsClosed2dForPeriodicFace
118 (const TopoDS_Face &theFace,
119 const gp_Pnt2d &theP1,
120 const gp_Pnt2d &theP2,
121 const TopoDS_Vertex &theVertex);
123 static Standard_Boolean GetPnt2d(const TopoDS_Vertex &theVertex,
124 const TopoDS_Edge &theEdge,
125 const TopoDS_Face &theFace,
127 // Modified by Sergey KHROMOV - Wed May 22 10:44:08 2002 End
129 //=======================================================================
130 //function : BRepCheck_Wire
132 //=======================================================================
133 BRepCheck_Wire::BRepCheck_Wire(const TopoDS_Wire& W)
137 //=======================================================================
140 //=======================================================================
141 void BRepCheck_Wire::Minimum()
143 myCdone = Standard_False;
144 myGctrl = Standard_True;
146 BRepCheck_ListOfStatus thelist;
147 myMap.Bind(myShape, thelist);
148 BRepCheck_ListOfStatus& lst = myMap(myShape);
150 // check that the wire is "connex"
151 TopExp_Explorer exp(myShape,TopAbs_EDGE);
152 Standard_Integer nbedge = 0;
155 for (; exp.More(); exp.Next()) {
157 TopExp_Explorer expv;
158 for (expv.Init(exp.Current(),TopAbs_VERTEX);
159 expv.More(); expv.Next()) {
160 const TopoDS_Shape& vtx = expv.Current();
161 Standard_Integer index = myMapVE.FindIndex(vtx);
163 TopTools_ListOfShape theListOfShape;
164 index = myMapVE.Add(vtx, theListOfShape);
166 myMapVE(index).Append(exp.Current());
169 // wire must have at least one edge
171 BRepCheck::Add(lst,BRepCheck_EmptyWire);
173 // check if all edges are connected through vertices
174 else if (nbedge >= 2) {
175 TopTools_MapOfShape mapE;
177 Propagate(myMapVE,exp.Current(),mapE);
178 for (exp.ReInit(); exp.More(); exp.Next()) {
179 if (!mapE.Contains(exp.Current())) {
180 BRepCheck::Add(lst,BRepCheck_NotConnected);
186 lst.Append(BRepCheck_NoError);
189 myMin = Standard_True;
192 //=======================================================================
193 //function : InContext
195 //=======================================================================
196 void BRepCheck_Wire::InContext(const TopoDS_Shape& S)
199 if (myMap.IsBound(S)) {
202 BRepCheck_ListOfStatus thelist;
203 myMap.Bind(S, thelist);
205 BRepCheck_ListOfStatus& lst = myMap(S);
207 // check if my wire is in <S>
208 TopExp_Explorer exp(S,TopAbs_WIRE);
209 for ( ; exp.More(); exp.Next()) {
210 if (exp.Current().IsSame(myShape)) {
215 BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
219 BRepCheck_Status st = BRepCheck_NoError;
220 TopAbs_ShapeEnum styp = S.ShapeType();
227 st = SelfIntersect(TopoDS::Face(S),ed1,ed2,Standard_True);
228 if (st != BRepCheck_NoError) break;
230 if (st != BRepCheck_NoError) break;
231 st = Orientation(TopoDS::Face(S));
232 if (st != BRepCheck_NoError) break;
233 st = Closed2d(TopoDS::Face(S));
240 if (st != BRepCheck_NoError)
241 BRepCheck::Add(lst,st);
244 lst.Append(BRepCheck_NoError);
246 //=======================================================================
249 //=======================================================================
250 void BRepCheck_Wire::Blind()
253 // nothing more that the minimum
254 myBlind = Standard_True;
257 //=======================================================================
260 //=======================================================================
261 BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
266 BRepCheck::Add(myMap(myShape),myCstat);
271 myCdone = Standard_True;
273 BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
274 if (itl.Value() != BRepCheck_NoError) {
275 myCstat = itl.Value();
276 return myCstat; // already saved
279 myCstat = BRepCheck_NoError;
281 TopExp_Explorer exp,expv;
282 TopTools_MapOfShape mapS;
283 TopTools_DataMapOfShapeListOfShape Cradoc;
285 // Checks if the oriented edges of the wire give a "closed" wire,
286 // i-e if each oriented vertex on oriented edges is found 2 times...
288 for (exp.Init(myShape,TopAbs_EDGE);exp.More(); exp.Next()) {
289 if (IsOriented(exp.Current())) {
291 if (!Cradoc.IsBound(exp.Current())) {
292 TopTools_ListOfShape theListOfShape;
293 Cradoc.Bind(exp.Current(), theListOfShape);
295 Cradoc(exp.Current()).Append(exp.Current());
297 mapS.Add(exp.Current());
298 for (expv.Init(exp.Current(),TopAbs_VERTEX); expv.More(); expv.Next()) {
299 if (IsOriented(expv.Current())) {
300 Standard_Integer index = myMapVE.FindIndex(expv.Current());
302 TopTools_ListOfShape theListOfShape1;
303 index = myMapVE.Add(expv.Current(), theListOfShape1);
305 myMapVE(index).Append(exp.Current());
311 Standard_Integer theNbori = mapS.Extent();
314 for (exp.ReInit(); exp.More(); exp.Next()) {
315 if (IsOriented(exp.Current())) {
319 Propagate(myMapVE,exp.Current(),mapS);
321 if (theNbori != mapS.Extent()) {
322 myCstat = BRepCheck_NotConnected;
324 BRepCheck::Add(myMap(myShape),myCstat);
329 // Checks the number of occurence of an edge : maximum 2, and in this
330 // case, one time FORWARD and one time REVERSED
332 Standard_Boolean yabug = Standard_False;
333 for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm(Cradoc);
334 itdm.More(); itdm.Next()) {
335 if (itdm.Value().Extent() >= 3) {
336 yabug = Standard_True;
338 else if (itdm.Value().Extent() == 2) {
339 if (itdm.Value().First().Orientation() ==
340 itdm.Value().Last().Orientation()) {
341 yabug = Standard_True;
345 myCstat = BRepCheck_RedundantEdge;
347 BRepCheck::Add(myMap(myShape),myCstat);
353 for (Standard_Integer i = 1; i<= myMapVE.Extent(); i++) {
354 if (myMapVE(i).Extent()%2 != 0) {
355 myCstat=BRepCheck_NotClosed;
357 BRepCheck::Add(myMap(myShape),myCstat);
364 BRepCheck::Add(myMap(myShape),myCstat);
369 //=======================================================================
370 //function : IsDistanceIn3DTolerance
371 //purpose : Return Standard_True if distance between thePnt_f and
372 // thePnt_l is not more, than aTol3d
373 //=======================================================================
374 Standard_Boolean IsDistanceIn3DTolerance (const gp_Pnt& thePnt_f,
375 const gp_Pnt& thePnt_l,
376 const Standard_Real aTol3d)
378 Standard_Real Dist = thePnt_f.Distance(thePnt_l);
381 return Standard_True;
385 cout << "--------Function IsDistanceIn3DTolerance(...)----------" << endl;
386 cout << "--- BRepCheck Wire: Closed3d -> Error" << endl;
387 cout << "--- Dist (" << Dist << ") > Tol3d (" << aTol3d << ")" << endl;
388 cout << "Pnt1(" << thePnt_f.X() << "; " << thePnt_f.Y() << "; " << thePnt_f.Z() << ")" << endl;
389 cout << "Pnt2(" << thePnt_l.X() << "; " << thePnt_l.Y() << "; " << thePnt_l.Z() << ")" << endl;
390 cout << "------------------------------------------------------" << endl;
393 return Standard_False;
396 //=======================================================================
397 //function : IsDistanceIn3DTolerance
399 //=======================================================================
401 Standard_Boolean IsDistanceIn2DTolerance (const BRepAdaptor_Surface& aFaceSurface,
402 const gp_Pnt2d& thePnt,
403 const gp_Pnt2d& thePntRef,
404 const Standard_Real aTol3d,
406 const Standard_Boolean PrintWarnings = Standard_True)
408 const Standard_Boolean = Standard_True)
411 Standard_Real dumax = 0.01 * (aFaceSurface.LastUParameter() - aFaceSurface.FirstUParameter());
412 Standard_Real dvmax = 0.01 * (aFaceSurface.LastVParameter() - aFaceSurface.FirstVParameter());
413 Standard_Real dumin = Abs(thePnt.X() - thePntRef.X());
414 Standard_Real dvmin = Abs(thePnt.Y() - thePntRef.Y());
416 if((dumin < dumax) && (dvmin < dvmax))
417 return Standard_True;
423 cout << "--------Function IsDistanceIn2DTolerance(...)----------" << endl;
424 cout << "--- BRepCheck Wire: Not closed in 2D" << endl;
425 cout << "*****************************************************" << endl;
426 cout << "*dumin = " << dumin << "; dumax = " << dumax << endl;
427 cout << "* dvmin = " << dvmin << "; dvmax = " << dvmax << endl;
428 cout << "* (dumin > dumax) or (dvmin > dvmax)." << endl;
429 cout << "*****************************************************" << endl;
431 cout << "UFirst = " << aFaceSurface.FirstUParameter();
432 cout << "; ULast = " << aFaceSurface.LastUParameter() << endl;
433 cout << "VFirst = " << aFaceSurface.FirstVParameter();
434 cout << "; VLast = " << aFaceSurface.LastVParameter() << endl;
437 dumax = aFaceSurface.UResolution(aTol3d);
438 dvmax = aFaceSurface.VResolution(aTol3d);
442 cout << "aTol3d = " << aTol3d <<"; URes = " << dumax << "; VRes = " << dvmax << endl;
443 cout << "thePnt(" << thePnt.X() << "; " << thePnt.Y() << ")" << endl;
444 cout << "thePntRef(" << thePntRef.X() << "; " << thePntRef.Y() << ")" << endl;
448 dumax = aFaceSurface.UResolution(aTol3d);
449 dvmax = aFaceSurface.VResolution(aTol3d);
452 Standard_Real aTol2d = 2*Max( dumax, dvmax);
455 if((aTol2d <= 0.0) && (PrintWarnings))
457 cout<<"BRepCheck_Wire : UResolution and VResolution = 0.0 (Face too small ?)"<<endl;
462 //Standard_Real Dist = thePntRef.Distance(thePnt);
463 Standard_Real Dist = Max(dumin, dvmin);
466 return Standard_True;
472 cout << "--------Function IsDistanceIn2DTolerance(...)----------" << endl;
473 cout << "--- BRepCheck Wire: Not closed in 2d" << endl;
474 cout << "*****************************************************" << endl;
475 cout << "* Dist = " << Dist << " > Tol2d = " << aTol2d << endl;
476 cout << "*****************************************************" << endl;
477 cout << "aTol3d = " << aTol3d <<"; URes = " << dumax << "; VRes = " << dvmax << endl;
478 cout << "thePnt(" << thePnt.X() << "; " << thePnt.Y() << ")" << endl;
479 cout << "thePntRef(" << thePntRef.X() << "; " << thePntRef.Y() << ")" << endl;
483 return Standard_False;
486 //=======================================================================
487 //function : Closed2d
488 //purpose : for periodic faces
489 //=======================================================================
490 BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
491 const Standard_Boolean Update)
493 // 3d closure checked too
494 BRepCheck_Status aClosedStat = Closed();
495 if (aClosedStat != BRepCheck_NoError)
498 BRepCheck::Add(myMap(myShape),aClosedStat);
503 // 20/03/02 akm vvv : (OCC234) Hence this method will be used to check
504 // both periodic and non-periodic faces
505 // // this check is for periodic faces
506 BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
507 // if (!aFaceSurface.IsUPeriodic() && !aFaceSurface.IsVPeriodic())
510 // BRepCheck::Add(myMap(myShape),aClosedStat);
511 // return aClosedStat;
515 // count edges having FORWARD or REVERSED orientation
516 Standard_Integer aNbOrirntedEdges = 0;
517 TopExp_Explorer anEdgeExp(myShape,TopAbs_EDGE);
518 for (;anEdgeExp.More(); anEdgeExp.Next())
520 if (IsOriented(anEdgeExp.Current()))
524 if (aNbOrirntedEdges==0)
527 BRepCheck::Add(myMap(myShape),aClosedStat);
532 // all those edges must form a closed 2d contour and be found by WireExplorer
534 Standard_Integer aNbFoundEdges = 0;
535 BRepTools_WireExplorer aWireExp(TopoDS::Wire(myShape), theFace);
536 TopoDS_Edge aFirstEdge = aWireExp.Current();
537 TopoDS_Vertex aFirstVertex = aWireExp.CurrentVertex();
538 TopoDS_Edge aLastEdge;
540 for (;aWireExp.More(); aWireExp.Next())
543 aLastEdge = aWireExp.Current();
546 if (aNbFoundEdges != aNbOrirntedEdges)
548 aClosedStat = BRepCheck_NotClosed;
550 BRepCheck::Add(myMap(myShape),aClosedStat);
555 // Check distance between 2d ends of first and last edges
556 // Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 Begin
557 // First check if first and last edges are infinite:
560 Standard_Boolean isFirstInfinite = Standard_False;
561 Standard_Boolean isLastInfinite = Standard_False;
562 TopAbs_Orientation anOri;
564 anOri = aFirstEdge.Orientation();
565 BRep_Tool::Range(aFirstEdge, aF, aL);
566 if ((anOri == TopAbs_FORWARD && Precision::IsNegativeInfinite( aF )) ||
567 (anOri == TopAbs_REVERSED && Precision::IsPositiveInfinite( aL )))
568 isFirstInfinite = Standard_True;
570 anOri = aLastEdge.Orientation();
571 BRep_Tool::Range(aLastEdge, aF, aL);
573 if ((anOri == TopAbs_FORWARD && Precision::IsPositiveInfinite( aL )) ||
574 (anOri == TopAbs_REVERSED && Precision::IsNegativeInfinite( aF )))
575 isLastInfinite = Standard_True;
577 if (isFirstInfinite && isLastInfinite)
580 BRepCheck::Add(myMap(myShape),aClosedStat);
584 else if (aFirstVertex.IsNull())
586 aClosedStat = BRepCheck_NotClosed;
589 BRepCheck::Add(myMap(myShape),aClosedStat);
593 // Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 End
595 gp_Pnt2d aP_first, aP_last, aP_temp; // ends of prev edge, next edge, bidon
598 BRep_Tool::UVPoints(aLastEdge, theFace, aP_temp, aP_last);
599 if (aLastEdge.Orientation() == TopAbs_REVERSED)
602 // Modified by Sergey KHROMOV - Mon Apr 22 10:36:33 2002 Begin
603 // Standard_Real aTol, aUResol, aVResol;
604 // // find 2d tolerance
605 // aTol = BRep_Tool::Tolerance(aFirstVertex);
606 // aUResol = 2*aFaceSurface.UResolution(aTol);
607 // aVResol = 2*aFaceSurface.VResolution(aTol);
610 if (aFirstEdge.Orientation() == TopAbs_REVERSED)
611 BRep_Tool::UVPoints(aFirstEdge, theFace, aP_temp, aP_first);
613 BRep_Tool::UVPoints(aFirstEdge, theFace, aP_first, aP_temp);
615 // Modified by Sergey KHROMOV - Thu Jun 20 10:55:42 2002 OCC325 Begin
616 // Check 2d distance for periodic faces with seam edge
617 if (!IsClosed2dForPeriodicFace(theFace, aP_first, aP_last, aFirstVertex))
619 aClosedStat = BRepCheck_NotClosed;
621 BRepCheck::Add(myMap(myShape),aClosedStat);
625 // Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End
628 // Standard_Real dfUDist=Abs(p.X()-p1.X());
629 // Standard_Real dfVDist=Abs(p.Y()-p1.Y());
630 // if (dfUDist > aUResol || dfVDist > aVResol)
633 Standard_Real aTol3d = Max(BRep_Tool::Tolerance(aFirstVertex),BRep_Tool::Tolerance(aWireExp.CurrentVertex()));
635 gp_Pnt aPntRef = BRep_Tool::Pnt(aFirstVertex);
636 gp_Pnt aPnt = BRep_Tool::Pnt(aWireExp.CurrentVertex());
638 if (!(IsDistanceIn2DTolerance(aFaceSurface, aP_first, aP_last, aTol3d)))
639 aClosedStat = BRepCheck_NotClosed;
641 if(!IsDistanceIn3DTolerance(aPntRef, aPnt, aTol3d))
642 aClosedStat = BRepCheck_NotClosed;
645 BRepCheck::Add(myMap(myShape),aClosedStat);
649 //=======================================================================
650 //function : Orientation
652 //=======================================================================
653 BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
654 const Standard_Boolean Update)
656 BRepCheck_Status theOstat = Closed();
657 if (theOstat != BRepCheck_NotClosed && theOstat != BRepCheck_NoError) {
659 BRepCheck::Add(myMap(myShape),theOstat);
664 theOstat = BRepCheck_NoError;
667 TopAbs_Orientation orient, ortmp = TopAbs_FORWARD;
668 TopTools_ListOfShape ledge, ListOfPassedEdge;
669 TopExp_Explorer exp,vte;
670 TopTools_MapOfShape mapS;
671 TopoDS_Edge theEdge,theRef;
673 // Checks the orientation of the edges
674 for (exp.Init(myShape,TopAbs_EDGE); exp.More(); exp.Next()) {
675 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
676 orient = edg.Orientation();
677 if (IsOriented(edg)) {
681 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
682 TopAbs_Orientation vto = vte.Current().Orientation();
683 if (vto == TopAbs_FORWARD) {
684 VF = TopoDS::Vertex(vte.Current());
686 else if (vto == TopAbs_REVERSED) {
687 VL = TopoDS::Vertex(vte.Current());
689 if (!VF.IsNull() && !VL.IsNull()) {
693 if (VF.IsNull() && VL.IsNull())
694 theOstat = BRepCheck_InvalidDegeneratedFlag;
699 if (theOstat == BRepCheck_NoError) {
700 Standard_Integer Index = 1;
701 Standard_Integer nbOriNoDegen=myMapVE.Extent();
702 // Modified by Sergey KHROMOV - Tue May 21 17:12:45 2002 Begin
703 Standard_Boolean isGoFwd = Standard_True;
706 isGoFwd = Standard_False;
707 // Modified by Sergey KHROMOV - Tue May 21 17:12:45 2002 End
709 while (Index < nbOriNoDegen) {
711 ListOfPassedEdge.Clear();
712 // find edges that make a chain on VL if !VL.IsNull
715 Standard_Integer ind;
717 ind = myMapVE.FindIndex(VL);
719 else if (!VF.IsNull()) {
720 ind = myMapVE.FindIndex(VF);
723 theOstat = BRepCheck_InvalidDegeneratedFlag;
727 for (TopTools_ListIteratorOfListOfShape itls(myMapVE(ind));
728 itls.More(); itls.Next()) {
729 const TopoDS_Edge & edg = TopoDS::Edge(itls.Value());
731 orient = edg.Orientation();
732 if (mapS.Contains(edg)) ortmp = GetOrientation(mapS,edg);
734 //Add to list already passed outcoming edges
735 if (mapS.Contains(edg) && ortmp == orient && !edg.IsSame(theEdge))
736 for (vte.Init(edg,TopAbs_VERTEX); vte.More(); vte.Next())
738 TopAbs_Orientation vto = vte.Current().Orientation();
741 if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current()))
743 ListOfPassedEdge.Append(edg);
747 else // VF is not null
749 if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current()))
751 ListOfPassedEdge.Append(edg);
757 if (!mapS.Contains(edg) || ortmp != orient) {
758 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
759 TopAbs_Orientation vto = vte.Current().Orientation();
761 if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current())) {
762 // If the processing is in 2d (face not null) or
763 // if the edge is not degenerated it is added
764 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
769 else { // VF is not null
770 if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
771 // // If the processing is in 2d (face not null) or
772 // if the edge is not degenerated it is added
773 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
781 Standard_Integer nbconnex = ledge.Extent();
782 Standard_Boolean Changedesens = Standard_False;
784 if (myCstat == BRepCheck_NotClosed) {
787 BRepCheck::Add(myMap(myShape),theOstat);
789 return theOstat; // leave
792 Index--; // because after Index++ and if there is no chain,
793 VL.Nullify(); // chain on VF is forced
795 Changedesens = Standard_True;
799 theOstat = BRepCheck_BadOrientationOfSubshape;
801 BRepCheck::Add(myMap(myShape),theOstat);
807 // JAG 03/07 else if (nbconnex >= 2 && !F.IsNull()) // Try to see in 2d
808 else if (!F.IsNull()) { // Try to see in 2d
817 ChoixUV(pivot,theEdge,F,ledge);
818 nbconnex = ledge.Extent();
819 // 20/03/02 akm vvv : (OCC234) - The 2d exploration of wire with necessary
820 // checks is performed in Closed2d, here it's useless
821 // if (nbconnex == 1 && !CheckLoopOrientation( pivot, theEdge, TopoDS::Edge(ledge.First()), F, ListOfPassedEdge ))
823 // theOstat = BRepCheck_BadOrientationOfSubshape;
825 // BRepCheck::Add(myMap(myShape),theOstat);
832 theOstat = BRepCheck_BadOrientationOfSubshape;
834 BRepCheck::Add(myMap(myShape),theOstat);
838 else if (nbconnex == 1) {
840 for (vte.Init(ledge.First(),TopAbs_VERTEX);vte.More(); vte.Next()) {
841 TopAbs_Orientation vto = vte.Current().Orientation();
843 if (vto == TopAbs_REVERSED) {
844 VL = TopoDS::Vertex(vte.Current());
848 else { // VF is not null
849 if (vto == TopAbs_FORWARD) {
850 VF = TopoDS::Vertex(vte.Current());
855 mapS.Add(ledge.First());
856 theEdge = TopoDS::Edge(ledge.First());
866 else if (!Changedesens) { //nbconnex == 0
867 theOstat = BRepCheck_NotClosed;
869 BRepCheck::Add(myMap(myShape),theOstat);
874 // Check the closure of the wire in 2d (not done in Closed())
877 Standard_Boolean isCheckClose = Standard_False;
879 if (isGoFwd && !VF.IsNull()) {
881 isCheckClose = Standard_True;
882 } else if (!isGoFwd && !VL.IsNull()) {
884 isCheckClose = Standard_True;
887 // if (Index==1 && myCstat!=BRepCheck_NotClosed &&
888 // !VF.IsNull() && !F.IsNull()) {
889 if (Index==1 && myCstat!=BRepCheck_NotClosed &&
890 isCheckClose && !F.IsNull()) {
892 // ind = myMapVE.FindIndex(VF);
893 ind = myMapVE.FindIndex(aVRef);
894 for (TopTools_ListIteratorOfListOfShape itlsh(myMapVE(ind));
895 itlsh.More(); itlsh.Next()) {
896 const TopoDS_Edge & edg = TopoDS::Edge(itlsh.Value());
897 orient = edg.Orientation();
898 if (!theRef.IsSame(edg)) {
899 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
900 TopAbs_Orientation vto = vte.Current().Orientation();
901 // if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
902 if (vto == TopAbs_REVERSED && aVRef.IsSame(vte.Current())) {
909 // ChoixUV(VF, theRef, F, ledge);
910 ChoixUV(aVRef, theRef, F, ledge);
911 if (ledge.Extent()==0) {
912 theOstat = BRepCheck_NotClosed;
914 BRepCheck::Add(myMap(myShape),theOstat);
919 // End control closure 2d
925 BRepCheck::Add(myMap(myShape),theOstat);
929 //=======================================================================
930 //function : SelfIntersect
932 //=======================================================================
933 BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
936 const Standard_Boolean Update)
940 Standard_Integer i,j,Nbedges;
941 Standard_Real first1,last1,first2,last2, tolint;
942 gp_Pnt2d pfirst1,plast1,pfirst2,plast2;
944 Handle(BRepAdaptor_HSurface) HS;
945 Geom2dAdaptor_Curve C1, C2;
946 Geom2dInt_GInter Inter;
947 IntRes2d_Domain myDomain1;
948 TopTools_IndexedMapOfOrientedShape EMap;
949 TopTools_MapOfOrientedShape auxmape;
951 //-- check with proper tolerances if there is no
952 //-- point in the tolerance of a vertex.
954 HS = new BRepAdaptor_HSurface();
955 HS->ChangeSurface().Initialize(F,Standard_False);
957 for (TopoDS_Iterator Iter1(myShape);Iter1.More();Iter1.Next()) {
958 if (Iter1.Value().ShapeType() == TopAbs_EDGE) {
959 EMap.Add(Iter1.Value());
963 Nbedges=EMap.Extent();
966 BRepCheck::Add(myMap(myShape),BRepCheck_EmptyWire);
968 return(BRepCheck_EmptyWire);
971 IntRes2d_Domain *tabDom = new IntRes2d_Domain[Nbedges];
972 TColGeom2d_Array1OfCurve tabCur(1,Nbedges);
973 Bnd_Array1OfBox2d boxes(1,Nbedges);
975 for(i = 1; i <= Nbedges; i++) {
976 const TopoDS_Edge& E1 = TopoDS::Edge(EMap.FindKey(i));
978 Handle(Geom2d_Curve) pcu = BRep_Tool::CurveOnSurface(E1, F, first1, last1);
982 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
985 return(BRepCheck_SelfIntersectingWire);
989 // To avoid exeption in Segment if C1 is BSpline - IFV
990 if(!C1.IsPeriodic()) {
991 if(C1.FirstParameter() > first1) {
992 first1 = C1.FirstParameter();
994 if(C1.LastParameter() < last1 ){
995 last1 = C1.LastParameter();
999 BRep_Tool::UVPoints(E1, F, pfirst1, plast1);
1000 myDomain1.SetValues(pfirst1,first1,tolint, plast1,last1,tolint);
1002 BndLib_Add2dCurve::Add(C1, first1, last1, Precision::PConfusion(), boxes(i));
1006 myDomain1 = tabDom[i-1];
1009 // Self intersect of C1
1010 Inter.Perform(C1, myDomain1, tolint, tolint);
1012 if(Inter.IsDone()) {
1013 Standard_Integer nbp = Inter.NbPoints();
1014 //Standard_Integer nbs = Inter.NbSegments();
1016 for(Standard_Integer p=1;p<=nbp;p++) {
1017 const IntRes2d_IntersectionPoint& IP=Inter.Point(p);
1018 const IntRes2d_Transition& Tr1 = IP.TransitionOfFirst();
1019 const IntRes2d_Transition& Tr2 = IP.TransitionOfSecond();
1020 if( Tr1.PositionOnCurve() == IntRes2d_Middle
1021 || Tr2.PositionOnCurve() == IntRes2d_Middle) {
1022 //-- Checking of points with true tolerances (ie Tol in 3d)
1023 //-- If the point of intersection is within the tolearnce of a vertex
1024 //-- this intersection is considered correct (no error)
1025 Standard_Boolean localok = Standard_False;
1028 const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f,l);
1029 if(!ConS.IsNull()) {
1030 //-- try to test in 3d. (ParamOnSecond gives the same result)
1031 P3d = ConS->Value(IP.ParamOnFirst());
1032 P3d.Transform(L.Transformation());
1033 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1036 gp_Pnt2d aP2d = C1.Value(IP.ParamOnFirst());
1037 P3d = HS->Value(aP2d.X(), aP2d.Y());
1039 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1040 TopExp_Explorer ExplVtx;
1041 for(ExplVtx.Init(E1,TopAbs_VERTEX);
1042 localok==Standard_False && ExplVtx.More();
1045 Standard_Real tolvtt, p3dvttDistanceP3d;
1047 const TopoDS_Vertex& vtt = TopoDS::Vertex(ExplVtx.Current());
1048 p3dvtt = BRep_Tool::Pnt(vtt);
1049 tolvtt = BRep_Tool::Tolerance(vtt);
1050 tolvtt=tolvtt*tolvtt;
1051 p3dvttDistanceP3d=p3dvtt.SquareDistance(P3d);
1052 if(p3dvttDistanceP3d <= tolvtt) {
1053 localok=Standard_True;
1056 if(localok==Standard_False) {
1059 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1063 static Standard_Integer numpoint=0;
1064 cout<<"point p"<<++numpoint<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;cout.flush();
1066 return(BRepCheck_SelfIntersectingWire);
1070 }// if(Inter.IsDone()) {
1072 for(j=i+1; j<=Nbedges; j++) {
1073 const TopoDS_Edge& E2 = TopoDS::Edge(EMap.FindKey(j));
1075 tabCur(j) = BRep_Tool::CurveOnSurface(E2,F,first2,last2);
1076 if (!tabCur(j).IsNull() && last2 > first2) {
1078 // To avoid exeption in Segment if C2 is BSpline - IFV
1079 if(!C2.IsPeriodic()) {
1080 if(C2.FirstParameter() > first2) {
1081 first2 = C2.FirstParameter();
1083 if(C2.LastParameter() < last2 ) {
1084 last2 = C2.LastParameter();
1088 BRep_Tool::UVPoints(E2,F,pfirst2,plast2);
1089 tabDom[j-1].SetValues(pfirst2,first2,tolint,plast2,last2,tolint);
1091 BndLib_Add2dCurve::Add( C2, first2, last2, Precision::PConfusion(), boxes(j) );
1096 cout<<"BRepCheck_NoCurveOnSurface or BRepCheck_InvalidRange"<<endl;cout.flush();
1098 if(tabCur(j).IsNull()) {
1099 return(BRepCheck_NoCurveOnSurface);
1101 return (BRepCheck_InvalidRange);
1108 if (boxes(i).IsOut( boxes(j))) {
1111 //modified by NIZNHY-PKV Fri Oct 29 10:09:01 2010f
1112 if (E1.IsSame(E2)) {
1115 //modified by NIZNHY-PKV Fri Oct 29 10:09:02 2010t
1117 //-- ************************************************************
1118 //-- ******* I n t e r s e c t i o n C 1 and C 2 ********
1119 //-- ************************************************************
1120 Inter.Perform(C1,myDomain1,C2,tabDom[j-1],tolint,tolint);
1122 if(Inter.IsDone()) {
1123 Standard_Integer nbp, nbs;
1124 Standard_Real IP_ParamOnFirst, IP_ParamOnSecond;
1125 IntRes2d_Transition Tr1,Tr2;
1126 TopTools_ListOfShape CommonVertices;
1127 TopTools_ListIteratorOfListOfShape itl;
1128 TopTools_MapOfShape Vmap;
1130 TopoDS_Iterator it( E1 );
1131 for (; it.More(); it.Next()) {
1132 Vmap.Add( it.Value() );
1135 it.Initialize( E2 );
1136 for (; it.More(); it.Next()) {
1137 const TopoDS_Shape& V = it.Value();
1138 if (Vmap.Contains( V )) {
1139 CommonVertices.Append( V );
1143 nbp = Inter.NbPoints();
1144 nbs = Inter.NbSegments();
1145 IP_ParamOnFirst = 0.;
1146 IP_ParamOnSecond = 0.;
1148 //// **** Points of intersection **** ////
1149 for (Standard_Integer p = 1; p <= nbp; p++) {
1150 const IntRes2d_IntersectionPoint& IP = Inter.Point(p);
1151 IP_ParamOnFirst = IP.ParamOnFirst();
1152 IP_ParamOnSecond = IP.ParamOnSecond();
1153 Tr1 = IP.TransitionOfFirst();
1154 Tr2 = IP.TransitionOfSecond();
1155 if( Tr1.PositionOnCurve() == IntRes2d_Middle
1156 || Tr2.PositionOnCurve() == IntRes2d_Middle) {
1157 //-- Checking of points with true tolerances (ie Tol in 3d)
1158 //-- If the point of intersection is within the tolerance of a vertex
1159 //-- this intersection is considered correct (no error)
1160 Standard_Boolean localok = Standard_False;
1161 Standard_Real f1,l1, f2, l2;
1162 TopLoc_Location L, L2;
1164 const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f1,l1);
1165 const Handle(Geom_Curve) ConS2 = BRep_Tool::Curve(E2,L2,f2,l2);
1166 //gka protect against working out of edge range
1167 if ( f1-IP_ParamOnFirst > ::Precision::PConfusion() ||
1168 IP_ParamOnFirst-l1 > ::Precision::PConfusion() ||
1169 f2-IP_ParamOnSecond > ::Precision::PConfusion() ||
1170 IP_ParamOnSecond-l2 > ::Precision::PConfusion() )
1172 Standard_Real tolvtt = 0.;
1173 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1174 if (!ConS.IsNull()) {
1175 P3d = ConS->Value(IP_ParamOnFirst);
1176 P3d.Transform(L.Transformation());
1179 gp_Pnt2d aP2d = C1.Value(IP_ParamOnFirst);
1180 P3d = HS->Value(aP2d.X(), aP2d.Y());
1183 if (!ConS2.IsNull()) {
1184 P3d2 = ConS2->Value(IP_ParamOnSecond);
1185 P3d2.Transform(L2.Transformation());
1188 gp_Pnt2d aP2d = C2.Value(IP_ParamOnSecond);
1189 P3d2 = HS->Value(aP2d.X(), aP2d.Y());
1191 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1192 itl.Initialize( CommonVertices );
1193 for (; itl.More(); itl.Next()) {
1194 Standard_Real p3dvttDistanceP3d, p3dvttDistanceP3d2;
1197 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1198 p3dvtt = BRep_Tool::Pnt(vtt);
1199 tolvtt = BRep_Tool::Tolerance(vtt);
1201 tolvtt=tolvtt*tolvtt;
1202 p3dvttDistanceP3d = p3dvtt.SquareDistance(P3d);
1203 p3dvttDistanceP3d2 = p3dvtt.SquareDistance(P3d2);
1205 if (p3dvttDistanceP3d<=tolvtt && p3dvttDistanceP3d2<=tolvtt) {
1206 localok = Standard_True;
1211 //-- --------------------------------------------------------
1212 //-- Check maximum yawn between 2 edges
1214 //-- Check distance from edges to the curve joining
1215 //-- the point of intersection with vertex (if exists)
1216 if (localok == Standard_False && !CommonVertices.IsEmpty()) {
1218 cout << "\n------------------------------------------------------\n" <<endl;
1219 cout << "\n--- BRepCheck Wire: AutoIntersection Phase1 -> Erreur \n" <<endl;
1222 Standard_Real distauvtxleplusproche,VParaOnEdge1,VParaOnEdge2;
1223 gp_Pnt VertexLePlusProche;
1227 distauvtxleplusproche=RealLast();
1228 //Find the nearest common vertex
1229 itl.Initialize( CommonVertices );
1230 for (; itl.More(); itl.Next()) {
1231 Standard_Real disptvtx;
1234 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1235 p3dvtt = BRep_Tool::Pnt(vtt);
1236 disptvtx = P3d.Distance(p3dvtt);
1237 if (disptvtx < distauvtxleplusproche) {
1238 VertexLePlusProche = p3dvtt;
1239 distauvtxleplusproche = disptvtx;
1240 VParaOnEdge1 = BRep_Tool::Parameter(vtt,E1);
1241 VParaOnEdge2 = BRep_Tool::Parameter(vtt,E2);
1243 // eap: case of closed edge
1244 else if (IsEqual(distauvtxleplusproche, disptvtx)) {
1245 Standard_Real newVParaOnEdge1 = BRep_Tool::Parameter(vtt,E1);
1246 Standard_Real newVParaOnEdge2 = BRep_Tool::Parameter(vtt,E2);
1247 if (Abs(IP_ParamOnFirst - VParaOnEdge1) + Abs(IP_ParamOnSecond - VParaOnEdge2)
1249 Abs(IP_ParamOnFirst - newVParaOnEdge1) + Abs(IP_ParamOnSecond - newVParaOnEdge2)) {
1250 VertexLePlusProche = p3dvtt;
1251 VParaOnEdge1 = newVParaOnEdge1;
1252 VParaOnEdge2 = newVParaOnEdge2;
1256 //Patch: extraordinar situation (e.g. tolerance(v) == 0.)
1257 // Modified by skv - Wed Jul 23 12:28:11 2003 OCC1764 Begin
1258 // if (VertexLePlusProche.Distance( P3d ) <= gp::Resolution())
1259 if (VertexLePlusProche.Distance(P3d) <= gp::Resolution() ||
1260 VertexLePlusProche.Distance(P3d2) <= gp::Resolution()) {
1261 // Modified by skv - Wed Jul 23 12:28:12 2003 OCC1764 End
1262 localok = Standard_True;
1265 gp_Lin Lig( VertexLePlusProche, gp_Vec(VertexLePlusProche,P3d) );
1266 Standard_Real du1 = 0.1*(IP_ParamOnFirst -VParaOnEdge1);
1267 Standard_Real du2 = 0.1*(IP_ParamOnSecond-VParaOnEdge2);
1268 Standard_Real maxd1 = 0., maxd2 = 0.;
1271 localok = Standard_True;
1272 Standard_Real tole1 = BRep_Tool::Tolerance(E1);
1273 for (k = 2; localok && k < 9; k++) {
1274 Standard_Real u = VParaOnEdge1 + k*du1; // check if it works
1276 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1277 if (!ConS.IsNull()) {
1278 P1 = ConS->Value(u);
1279 P1.Transform(L.Transformation());
1282 gp_Pnt2d aP2d = C1.Value(u);
1283 P1 = HS->Value(aP2d.X(), aP2d.Y());
1285 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1286 Standard_Real d1 = Lig.Distance(P1);
1290 if (d1 > tole1*2.0){
1291 localok = Standard_False;
1295 // Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764 Begin
1296 gp_Dir aTmpDir(P3d2.XYZ().Subtracted(VertexLePlusProche.XYZ()));
1298 Lig.SetDirection(aTmpDir);
1299 // Modified by skv - Wed Jul 23 12:22:23 2003 OCC1764 End
1300 Standard_Real tole2 = BRep_Tool::Tolerance(E2);
1301 for (k = 2; localok && k < 9; k++) {
1302 Standard_Real u = VParaOnEdge2 + k*du2; // check if it works
1304 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1305 if (!ConS2.IsNull()) {
1306 P2 = ConS2->Value(u);
1307 P2.Transform(L2.Transformation());
1310 gp_Pnt2d aP2d = C2.Value(u);
1311 P2 = HS->Value(aP2d.X(), aP2d.Y());
1313 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1314 Standard_Real d2 = Lig.Distance(P2);
1318 if (d2 > tole2*2.0){
1319 localok = Standard_False;
1324 printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Bon \n");
1325 printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
1326 printf("--- Erreur Max sur E1 : %10.7g Tol_Edge:%10.7g\n",maxd1,tole1);
1327 printf("--- Erreur Max sur E2 : %10.7g Tol_Edge:%10.7g\n",maxd2,tole2);
1331 printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Erreur \n");
1332 printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
1333 printf("--- Erreur Max sur E1 : %10.7g Tol_Edge:%10.7g\n",maxd1,tole1);
1334 printf("--- Erreur Max sur E2 : %10.7g Tol_Edge:%10.7g\n",maxd2,tole2);
1338 } //end of else (construction of the line Lig)
1339 } //end of if (localok == Standard_False && !CommonVertices.IsEmpty())
1341 if(localok==Standard_False) {
1345 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1348 static Standard_Integer numpoint1=0;
1349 cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
1353 return(BRepCheck_SelfIntersectingWire);
1354 } //-- localok == False
1355 } //end of if(Tr1.PositionOnCurve() == IntRes2d_Middle || Tr2.PositionOnCurve() == IntRes2d_Middle)
1356 } //end of for (Standard_Integer p=1; p <= nbp; p++)
1358 //// **** Segments of intersection **** ////
1359 for (Standard_Integer s = 1; s <= nbs; ++s) {
1360 const IntRes2d_IntersectionSegment& Seg = Inter.Segment(s);
1361 if (Seg.HasFirstPoint() && Seg.HasLastPoint()) {
1362 Standard_Boolean localok;
1364 IntRes2d_IntersectionPoint PSeg [2];
1365 IntRes2d_Position aPCR1, aPCR2;
1367 localok = Standard_False;
1368 PSeg[0] = Seg.FirstPoint();
1369 PSeg[1] = Seg.LastPoint();
1370 // At least one of extremities of the segment must be inside
1371 // the tolerance of a common vertex
1372 for (k = 0; k < 2; ++k) {
1373 IP_ParamOnFirst = PSeg[k].ParamOnFirst();
1374 IP_ParamOnSecond = PSeg[k].ParamOnSecond();
1375 Tr1 = PSeg[k].TransitionOfFirst();
1376 Tr2 = PSeg[k].TransitionOfSecond();
1377 aPCR1=Tr1.PositionOnCurve();
1378 aPCR2=Tr2.PositionOnCurve();
1380 if(aPCR1!=IntRes2d_Middle && aPCR2!=IntRes2d_Middle) {
1381 GeomAbs_CurveType aCT1, aCT2;
1385 if (aCT1==GeomAbs_Line && aCT2==GeomAbs_Line) {
1386 // check for the two lines coincidence
1387 Standard_Real aPAR_T, aT11, aT12, aT21, aT22, aT1m, aT2m;
1388 Standard_Real aD2, aTolE1, aTolE2, aTol2, aDot;
1394 aTolE1=BRep_Tool::Tolerance(E1);
1395 aTolE2=BRep_Tool::Tolerance(E2);
1396 aTol2=aTolE1+aTolE2;
1402 aT11=PSeg[0].ParamOnFirst();
1403 aT12=PSeg[1].ParamOnFirst();
1404 aT21=PSeg[0].ParamOnSecond();
1405 aT22=PSeg[1].ParamOnSecond();
1407 aT1m=(1.-aPAR_T)*aT11 + aPAR_T*aT12;
1408 aP1m=C1.Value(aT1m);
1410 aD2=aL2.SquareDistance(aP1m);
1412 aT2m=ElCLib::Parameter(aL2, aP1m);
1413 if (aT2m>aT21 && aT2m<aT22) {
1414 const gp_Dir2d& aDir1=aL1.Direction();
1415 const gp_Dir2d& aDir2=aL2.Direction();
1421 if ((1.-aDot)<5.e-11){//0.00001 rad
1422 localok = Standard_False;
1423 break;// from for (k = 0; k < 2; ++k){...
1425 }//if (aT2m>aT21 && aT2m<aT22) {
1427 }//if (aCT1==GeomAbs_Line && aCT2==GeomAbs_Line) {
1429 localok = Standard_True;
1433 Standard_Real f,l, tolvtt;
1434 TopLoc_Location L, L2;
1435 const Handle(Geom_Curve)& ConS = BRep_Tool::Curve(E1,L,f,l);
1436 const Handle(Geom_Curve)& ConS2 = BRep_Tool::Curve(E2,L2,f,l);
1437 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1438 if (!ConS.IsNull()) {
1439 P3d = ConS->Value(IP_ParamOnFirst);
1440 P3d.Transform(L.Transformation());
1442 gp_Pnt2d aP2d = C1.Value(IP_ParamOnFirst);
1443 P3d = HS->Value(aP2d.X(), aP2d.Y());
1445 if (!ConS2.IsNull()) {
1446 P3d2 = ConS2->Value(IP_ParamOnSecond);
1447 P3d2.Transform(L2.Transformation());
1449 gp_Pnt2d aP2d = C2.Value(IP_ParamOnSecond);
1450 P3d2 = HS->Value(aP2d.X(), aP2d.Y());
1452 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1453 itl.Initialize( CommonVertices );
1454 for (; itl.More(); itl.Next()) {
1455 Standard_Real p3dvttDistanceP3d, p3dvttDistanceP3d2;
1458 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1459 p3dvtt = BRep_Tool::Pnt(vtt);
1460 tolvtt = BRep_Tool::Tolerance(vtt);
1462 tolvtt=tolvtt*tolvtt;
1463 p3dvttDistanceP3d = p3dvtt.SquareDistance(P3d);
1464 p3dvttDistanceP3d2 = p3dvtt.SquareDistance(P3d2);
1465 if (p3dvttDistanceP3d <= tolvtt && p3dvttDistanceP3d2 <= tolvtt) {
1466 localok = Standard_True;
1470 if (localok == Standard_True) {
1473 } //end of for (k = 0; k < 2; k++)
1475 if(localok==Standard_False) {
1479 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1482 static Standard_Integer numpoint1=0;
1483 cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
1487 return(BRepCheck_SelfIntersectingWire);
1488 } //-- localok == False
1489 } //end of if(Seg.HasFirstPoint() && Seg.HasLastPoint())
1490 } //end of for (Standard_Integer s = 1; s <= nbs; p++)
1491 } //-- Inter.IsDone()
1492 } //end of for( j = i+1; j<=Nbedges; j++)
1493 } //end of for(i = 1; i <= Nbedges; i++)
1497 BRepCheck::Add(myMap(myShape),BRepCheck_NoError);
1500 return (BRepCheck_NoError);
1503 //=======================================================================
1504 //function : SetStatus
1506 //=======================================================================
1508 void BRepCheck_Wire::SetStatus(const BRepCheck_Status theStatus)
1510 BRepCheck::Add(myMap(myShape),theStatus);
1513 //=======================================================================
1514 //function : GeometricControls
1516 //=======================================================================
1517 void BRepCheck_Wire::GeometricControls(const Standard_Boolean B)
1521 myCdone = Standard_False;
1526 //=======================================================================
1527 //function : GeometricControls
1529 //=======================================================================
1530 Standard_Boolean BRepCheck_Wire::GeometricControls() const
1535 //=======================================================================
1536 //function : Propagate
1537 //purpose : fill <mapE> with edges connected to <edg> through vertices
1538 // contained in <mapVE>
1539 //=======================================================================
1540 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape& mapVE,
1541 const TopoDS_Shape& edg,
1542 TopTools_MapOfShape& mapE)
1544 TopTools_ListOfShape currentEdges;
1545 currentEdges.Append(edg);
1549 TopTools_ListOfShape nextEdges;
1550 TopTools_ListIteratorOfListOfShape itrc(currentEdges);
1551 for (; itrc.More(); itrc.Next())
1553 const TopoDS_Shape& Edge = itrc.Value();
1554 if (!mapE.Contains(Edge))
1557 TopExp_Explorer ex(Edge, TopAbs_VERTEX);
1558 for (; ex.More(); ex.Next())
1560 const TopoDS_Vertex& vtx = TopoDS::Vertex(ex.Current());
1561 Standard_Integer indv = mapVE.FindIndex(vtx);
1564 const TopTools_ListOfShape& edges = mapVE(indv);
1566 TopTools_ListIteratorOfListOfShape itl(edges);
1567 for (; itl.More(); itl.Next())
1569 const TopoDS_Shape& E = itl.Value();
1570 if (!Edge.IsSame(E) && !mapE.Contains(E))
1573 nextEdges.Append(E);
1579 currentEdges = nextEdges;
1581 while (!currentEdges.IsEmpty());
1584 //=======================================================================
1585 //function : GetOrientation
1587 //=======================================================================
1589 static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape& mapE,
1590 const TopoDS_Edge& edg)
1592 TopTools_MapIteratorOfMapOfShape itm(mapE);
1593 for ( ; itm.More(); itm.Next()) {
1594 if (itm.Key().IsSame(edg)) {
1598 return itm.Key().Orientation();
1600 //=======================================================================
1601 //function : ChoixUV
1602 //purpose : For vertex theVertex given function find an edge along
1603 // that we should go further.
1604 //=======================================================================
1605 void ChoixUV(const TopoDS_Vertex& theVertex,
1606 const TopoDS_Edge& theEdge,
1607 const TopoDS_Face& theFace,
1608 TopTools_ListOfShape& theLOfShape)
1610 TopTools_ListIteratorOfListOfShape It( theLOfShape );
1613 if (theEdge.IsSame( It.Value() ))
1614 theLOfShape.Remove( It );
1619 Standard_Real aTol3d = BRep_Tool::Tolerance(theVertex);
1621 Standard_Integer anIndex = 0, anIndMin = 0;
1622 TopoDS_Edge anEFound;
1623 gp_Pnt2d aPntRef, aPnt;
1624 gp_Vec2d aDerRef, aDer;
1625 Standard_Real aMinAngle, aMaxAngle, anAngle;
1626 Standard_Real a_gpResolution=gp::Resolution();
1627 TopAbs_Orientation aVOrientation, anEdgOrientation;
1628 Standard_Real aParam = 0.0, aFirstParam = 0.0, aLastParam = 0.0, aParPiv = 0.0;
1629 BRepAdaptor_Surface aFaceSurface(theFace,Standard_False); // no restriction
1631 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(theEdge, theFace, aFirstParam, aLastParam);
1632 if (C2d.IsNull())// JAG 10.12.96
1635 aVOrientation = theVertex.Orientation();
1636 anEdgOrientation = theEdge.Orientation();
1638 aParPiv =(aVOrientation==anEdgOrientation) ? aFirstParam : aLastParam;
1639 aMinAngle = RealLast();
1640 aMaxAngle = RealFirst();
1642 CurveDirForParameter(C2d, aParPiv, aPntRef, aDerRef);
1644 if (aVOrientation != anEdgOrientation)
1647 It.Initialize(theLOfShape);
1649 for (; It.More(); It.Next())
1652 const TopoDS_Edge& anE=TopoDS::Edge(It.Value());
1653 C2d = BRep_Tool::CurveOnSurface(anE, theFace, aFirstParam, aLastParam);
1656 Geom2dAdaptor_Curve aCA(C2d);
1658 aParam =(aVOrientation != anE.Orientation()) ? aFirstParam : aLastParam;
1659 aPnt = aCA.Value(aParam);
1661 if(!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d, Standard_False))
1664 CurveDirForParameter(aCA, aParam, aPnt, aDer);
1666 if (aVOrientation == anE.Orientation())
1669 if ((aDerRef.Magnitude() <= a_gpResolution) ||
1670 (aDer.Magnitude() <= a_gpResolution))
1671 //Vector length is too small
1674 anAngle = -aDerRef.Angle( aDer );
1679 if ( theFace.Orientation() == TopAbs_FORWARD )
1681 if ( anAngle < aMinAngle )
1684 aMinAngle = anAngle;
1687 else //theFace.Orientation() != TopAbs_FORWARD
1689 if ( anAngle > aMaxAngle )
1692 aMaxAngle = anAngle;
1699 if (theLOfShape.Extent() == 1)
1701 Standard_Boolean IsFound = Standard_True; //all right
1702 anEFound = TopoDS::Edge(theLOfShape.First());
1704 if(anEFound.IsNull() || BRep_Tool::Degenerated(theEdge) ||
1705 BRep_Tool::Degenerated(anEFound))
1706 IsFound = Standard_False; //bad
1707 else if (!IsDistanceIn2DTolerance(aFaceSurface, aPnt, aPntRef, aTol3d))
1708 IsFound = Standard_False; //bad
1710 // clousureness in 3D
1712 //IsDistanceIn3DTolerance
1713 BRepAdaptor_Curve bcEdg(theEdge, theFace);
1714 BRepAdaptor_Curve bcEvois(anEFound, theFace);
1715 gp_Pnt pEdg = bcEdg.Value(aParPiv);
1716 gp_Pnt pEFound = bcEvois.Value(aParam);
1718 if(!IsDistanceIn3DTolerance(pEdg, pEFound, aTol3d))
1719 IsFound = Standard_False;
1721 //angle was not defined but points are close
1722 IsFound = Standard_True; //all right
1727 theLOfShape.Clear();
1729 }//if (theLOfShape.Extent() == 1)
1730 else //if (anIndMin == 0)
1732 theLOfShape.Clear();
1738 while (anIndex < anIndMin)
1740 theLOfShape.RemoveFirst();
1744 It.Initialize(theLOfShape);
1748 theLOfShape.Remove(It);
1753 //=======================================================================
1754 //function : CurveDirForParameter
1756 //=======================================================================
1757 void CurveDirForParameter(const Geom2dAdaptor_Curve& aC2d,
1758 const Standard_Real aPrm,
1762 Standard_Real aTol=gp::Resolution();
1765 aC2d.D1(aPrm, Pnt, aVec2d);
1767 if (aVec2d.Magnitude() <= aTol) {
1768 for (i = 2; i <= 100; i++){
1769 aVec2d = aC2d.DN(aPrm, i);
1770 if (aVec2d.Magnitude() > aTol) {
1777 // Modified by Sergey KHROMOV - Wed May 22 10:44:06 2002 OCC325 Begin
1778 //=======================================================================
1779 //function : GetPnts2d
1780 //purpose : this function returns the parametric points of theVertex on theFace.
1781 // If theVertex is a start and end vertex of theEdge hasSecondPnt
1782 // becomes Standard_True and aPnt2 returns the second parametric point.
1783 // Returns Standard_True if paraametric points are successfully found.
1784 //=======================================================================
1786 static Standard_Boolean GetPnt2d(const TopoDS_Vertex &theVertex,
1787 const TopoDS_Edge &theEdge,
1788 const TopoDS_Face &theFace,
1791 Handle(Geom2d_Curve) aPCurve;
1792 Standard_Real aFPar;
1793 Standard_Real aLPar;
1794 Standard_Real aParOnEdge;
1795 TopoDS_Vertex aFirstVtx;
1796 TopoDS_Vertex aLastVtx;
1798 TopExp::Vertices(theEdge, aFirstVtx, aLastVtx);
1800 if (!theVertex.IsSame(aFirstVtx) && !theVertex.IsSame(aLastVtx))
1801 return Standard_False;
1803 aPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFPar, aLPar);
1805 if (aPCurve.IsNull())
1806 return Standard_False;
1808 aParOnEdge = BRep_Tool::Parameter(theVertex, theEdge);
1809 aPnt = aPCurve->Value(aParOnEdge);
1811 return Standard_True;
1814 //=======================================================================
1815 //function : Closed2dForPeriodicFace
1816 //purpose : Checks the distance between first point of the first edge
1817 // and last point of the last edge in 2d for periodic face.
1818 //=======================================================================
1819 static Standard_Boolean IsClosed2dForPeriodicFace
1820 (const TopoDS_Face &theFace,
1821 const gp_Pnt2d &theP1,
1822 const gp_Pnt2d &theP2,
1823 const TopoDS_Vertex &theVertex)
1825 // Check 2d distance for periodic faces with seam edge.
1826 // Searching for seam edges
1827 TopTools_ListOfShape aSeamEdges;
1828 TopTools_MapOfShape NotSeams;
1829 TopTools_MapOfShape ClosedEdges;
1830 TopExp_Explorer anExp(theFace, TopAbs_EDGE);
1832 for (;anExp.More(); anExp.Next()) {
1833 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
1835 if (NotSeams.Contains(anEdge))
1838 if (!IsOriented(anEdge) ||
1839 !BRep_Tool::IsClosed(anEdge, theFace)) {
1840 NotSeams.Add(anEdge);
1844 if (!ClosedEdges.Add(anEdge))
1845 aSeamEdges.Append(anEdge);
1848 if (aSeamEdges.Extent() == 0)
1849 return Standard_True;
1851 // check if theVertex lies on one of the seam edges
1852 BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
1853 Standard_Real aTol = BRep_Tool::Tolerance(theVertex);
1854 Standard_Real aUResol = aFaceSurface.UResolution(aTol);
1855 Standard_Real aVResol = aFaceSurface.VResolution(aTol);
1856 Standard_Real aVicinity = Sqrt(aUResol*aUResol + aVResol*aVResol);
1857 Standard_Real aDistP1P2 = theP1.Distance(theP2);
1860 TopTools_ListIteratorOfListOfShape anIter(aSeamEdges);
1862 for (; anIter.More(); anIter.Next()) {
1863 TopoDS_Edge aSeamEdge = TopoDS::Edge(anIter.Value());
1865 anExp.Init(aSeamEdge, TopAbs_VERTEX);
1866 for (; anExp.More(); anExp.Next()) {
1867 const TopoDS_Shape &aVtx = anExp.Current();
1869 // We found an edge. Check the distance between two given points
1870 // to be lower than the computed tolerance.
1871 if (IsOriented(aVtx) && aVtx.IsSame(theVertex)) {
1874 Standard_Real a2dTol;
1876 if (!GetPnt2d(theVertex, aSeamEdge, theFace, aPnt1))
1879 aSeamEdge = TopoDS::Edge(aSeamEdge.Reversed());
1881 if (!GetPnt2d(theVertex, aSeamEdge, theFace, aPnt2))
1884 a2dTol = aPnt1.Distance(aPnt2)*1.e-2;
1885 a2dTol = Max(a2dTol, aVicinity);
1887 if (aDistP1P2 > a2dTol)
1888 return Standard_False;
1893 return Standard_True;
1895 // Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End