1 // Created on: 1995-12-12
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
21 // Modified by dpf, Fri Dec 19 15:31:03 1997
22 // Processing of closing in 2d.
23 // modified by eap Tue Dec 18 14:14:25 2001 (bug OCC23)
24 // Check self-intersection in case of closed edge
25 // modified by eap Fri Dec 21 17:36:55 2001 (bug OCC35)
28 // Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764
30 #include <BRepCheck_Wire.ixx>
31 #include <BRepCheck_ListOfStatus.hxx>
32 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
33 #include <TopTools_MapOfShape.hxx>
34 #include <TopTools_MapIteratorOfMapOfShape.hxx>
35 #include <TopTools_IndexedMapOfShape.hxx>
36 #include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
37 #include <TopTools_DataMapOfShapeListOfShape.hxx>
38 #include <TopTools_DataMapIteratorOfDataMapOfShapeListOfShape.hxx>
39 #include <TopTools_ListOfShape.hxx>
40 #include <TopTools_ListIteratorOfListOfShape.hxx>
41 #include <TopExp_Explorer.hxx>
42 #include <TopoDS_Iterator.hxx>
43 #include <TopLoc_Location.hxx>
44 #include <TColGeom2d_Array1OfCurve.hxx>
45 #include <IntRes2d_Intersection.hxx>
46 #include <IntRes2d_IntersectionPoint.hxx>
47 #include <IntRes2d_IntersectionSegment.hxx>
48 #include <IntRes2d_Transition.hxx>
49 #include <IntRes2d_Domain.hxx>
50 #include <Geom2dInt_GInter.hxx>
51 #include <gp_Pnt2d.hxx>
54 #include <Geom2d_Curve.hxx>
55 #include <Geom_Curve.hxx>
56 #include <Geom2dAdaptor_Curve.hxx>
57 #include <Geom2dAdaptor_HCurve.hxx>
58 #include <BRep_Tool.hxx>
59 #include <BRepAdaptor_Curve.hxx>
60 #include <BRepAdaptor_Surface.hxx>
61 #include <BRepAdaptor_HSurface.hxx>
62 #include <BRepCheck.hxx>
64 #include <TopoDS_Vertex.hxx>
65 #include <TopTools_MapOfOrientedShape.hxx>
66 #include <TopTools_HArray1OfShape.hxx>
67 #include <TopTools_MapIteratorOfMapOfOrientedShape.hxx>
70 #include <Precision.hxx>
71 #include <Bnd_Array1OfBox2d.hxx>
72 #include <BndLib_Add2dCurve.hxx>
76 #include <BRepTools_WireExplorer.hxx>
80 #include <TopTools_IndexedMapOfOrientedShape.hxx>
84 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape&,
85 const TopoDS_Shape&, // edge
86 TopTools_MapOfShape&); // mapofedge
89 static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape&,
94 void ChoixUV(const TopoDS_Vertex&,
97 TopTools_ListOfShape&);
99 // 20/03/02 akm vvv (OCC234)
101 // Standard_Boolean CheckLoopOrientation( const TopoDS_Vertex&,
102 // const TopoDS_Edge&,
103 // const TopoDS_Edge&,
104 // const TopoDS_Face&,
105 // TopTools_ListOfShape&);
108 inline Standard_Boolean IsOriented(const TopoDS_Shape& S)
110 return (S.Orientation() == TopAbs_FORWARD ||
111 S.Orientation() == TopAbs_REVERSED);
115 void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
116 const Standard_Real aPrm,
120 // Modified by Sergey KHROMOV - Thu Jun 20 11:21:51 2002 OCC325 Begin
121 static Standard_Boolean IsClosed2dForPeriodicFace
122 (const TopoDS_Face &theFace,
123 const gp_Pnt2d &theP1,
124 const gp_Pnt2d &theP2,
125 const TopoDS_Vertex &theVertex);
127 static Standard_Boolean GetPnt2d(const TopoDS_Vertex &theVertex,
128 const TopoDS_Edge &theEdge,
129 const TopoDS_Face &theFace,
131 // Modified by Sergey KHROMOV - Wed May 22 10:44:08 2002 End
133 //=======================================================================
134 //function : BRepCheck_Wire
136 //=======================================================================
137 BRepCheck_Wire::BRepCheck_Wire(const TopoDS_Wire& W)
141 //=======================================================================
144 //=======================================================================
145 void BRepCheck_Wire::Minimum()
147 myCdone = Standard_False;
148 myGctrl = Standard_True;
150 BRepCheck_ListOfStatus thelist;
151 myMap.Bind(myShape, thelist);
152 BRepCheck_ListOfStatus& lst = myMap(myShape);
154 // check that the wire is "connex"
155 TopExp_Explorer exp(myShape,TopAbs_EDGE);
156 Standard_Integer nbedge = 0;
159 for (; exp.More(); exp.Next()) {
161 TopExp_Explorer expv;
162 for (expv.Init(exp.Current(),TopAbs_VERTEX);
163 expv.More(); expv.Next()) {
164 const TopoDS_Shape& vtx = expv.Current();
165 Standard_Integer index = myMapVE.FindIndex(vtx);
167 TopTools_ListOfShape theListOfShape;
168 index = myMapVE.Add(vtx, theListOfShape);
170 myMapVE(index).Append(exp.Current());
173 // wire must have at least one edge
175 BRepCheck::Add(lst,BRepCheck_EmptyWire);
177 // check if all edges are connected through vertices
178 else if (nbedge >= 2) {
179 TopTools_MapOfShape mapE;
181 Propagate(myMapVE,exp.Current(),mapE);
182 for (exp.ReInit(); exp.More(); exp.Next()) {
183 if (!mapE.Contains(exp.Current())) {
184 BRepCheck::Add(lst,BRepCheck_NotConnected);
190 lst.Append(BRepCheck_NoError);
193 myMin = Standard_True;
196 //=======================================================================
197 //function : InContext
199 //=======================================================================
200 void BRepCheck_Wire::InContext(const TopoDS_Shape& S)
203 if (myMap.IsBound(S)) {
206 BRepCheck_ListOfStatus thelist;
207 myMap.Bind(S, thelist);
209 BRepCheck_ListOfStatus& lst = myMap(S);
211 // check if my wire is in <S>
212 TopExp_Explorer exp(S,TopAbs_WIRE);
213 for ( ; exp.More(); exp.Next()) {
214 if (exp.Current().IsSame(myShape)) {
219 BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
223 BRepCheck_Status st = BRepCheck_NoError;
224 TopAbs_ShapeEnum styp = S.ShapeType();
231 st = SelfIntersect(TopoDS::Face(S),ed1,ed2,Standard_True);
232 if (st != BRepCheck_NoError) break;
234 if (st != BRepCheck_NoError) break;
235 st = Orientation(TopoDS::Face(S));
236 if (st != BRepCheck_NoError) break;
237 st = Closed2d(TopoDS::Face(S));
244 if (st != BRepCheck_NoError)
245 BRepCheck::Add(lst,st);
248 lst.Append(BRepCheck_NoError);
250 //=======================================================================
253 //=======================================================================
254 void BRepCheck_Wire::Blind()
257 // nothing more that the minimum
258 myBlind = Standard_True;
261 //=======================================================================
264 //=======================================================================
265 BRepCheck_Status BRepCheck_Wire::Closed(const Standard_Boolean Update)
270 BRepCheck::Add(myMap(myShape),myCstat);
275 myCdone = Standard_True;
277 BRepCheck_ListIteratorOfListOfStatus itl(myMap(myShape));
278 if (itl.Value() != BRepCheck_NoError) {
279 myCstat = itl.Value();
280 return myCstat; // already saved
283 myCstat = BRepCheck_NoError;
285 TopExp_Explorer exp,expv;
286 TopTools_MapOfShape mapS;
287 TopTools_DataMapOfShapeListOfShape Cradoc;
289 // Checks if the oriented edges of the wire give a "closed" wire,
290 // i-e if each oriented vertex on oriented edges is found 2 times...
292 for (exp.Init(myShape,TopAbs_EDGE);exp.More(); exp.Next()) {
293 if (IsOriented(exp.Current())) {
295 if (!Cradoc.IsBound(exp.Current())) {
296 TopTools_ListOfShape theListOfShape;
297 Cradoc.Bind(exp.Current(), theListOfShape);
299 Cradoc(exp.Current()).Append(exp.Current());
301 mapS.Add(exp.Current());
302 for (expv.Init(exp.Current(),TopAbs_VERTEX); expv.More(); expv.Next()) {
303 if (IsOriented(expv.Current())) {
304 Standard_Integer index = myMapVE.FindIndex(expv.Current());
306 TopTools_ListOfShape theListOfShape1;
307 index = myMapVE.Add(expv.Current(), theListOfShape1);
309 myMapVE(index).Append(exp.Current());
315 Standard_Integer theNbori = mapS.Extent();
318 for (exp.ReInit(); exp.More(); exp.Next()) {
319 if (IsOriented(exp.Current())) {
323 Propagate(myMapVE,exp.Current(),mapS);
325 if (theNbori != mapS.Extent()) {
326 myCstat = BRepCheck_NotConnected;
328 BRepCheck::Add(myMap(myShape),myCstat);
333 // Checks the number of occurence of an edge : maximum 2, and in this
334 // case, one time FORWARD and one time REVERSED
336 Standard_Boolean yabug = Standard_False;
337 for (TopTools_DataMapIteratorOfDataMapOfShapeListOfShape itdm(Cradoc);
338 itdm.More(); itdm.Next()) {
339 if (itdm.Value().Extent() >= 3) {
340 yabug = Standard_True;
342 else if (itdm.Value().Extent() == 2) {
343 if (itdm.Value().First().Orientation() ==
344 itdm.Value().Last().Orientation()) {
345 yabug = Standard_True;
349 myCstat = BRepCheck_RedundantEdge;
351 BRepCheck::Add(myMap(myShape),myCstat);
357 for (Standard_Integer i = 1; i<= myMapVE.Extent(); i++) {
358 if (myMapVE(i).Extent()%2 != 0) {
359 myCstat=BRepCheck_NotClosed;
361 BRepCheck::Add(myMap(myShape),myCstat);
368 BRepCheck::Add(myMap(myShape),myCstat);
372 //=======================================================================
373 //function : Closed2d
374 //purpose : for periodic faces
375 //=======================================================================
376 BRepCheck_Status BRepCheck_Wire::Closed2d(const TopoDS_Face& theFace,
377 const Standard_Boolean Update)
380 // 3d closure checked?
381 BRepCheck_Status aClosedStat = Closed();
382 if (aClosedStat != BRepCheck_NoError) {
384 BRepCheck::Add(myMap(myShape),aClosedStat);
388 // 20/03/02 akm vvv : (OCC234) Hence this method will be used to check
389 // both periodic and non-periodic faces
390 // // this check is for periodic faces
391 BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
392 // if (!aFaceSurface.IsUPeriodic() && !aFaceSurface.IsVPeriodic())
395 // BRepCheck::Add(myMap(myShape),aClosedStat);
396 // return aClosedStat;
400 // count edges having FORWARD or REVERSED orientation
401 Standard_Integer aNbOrirntedEdges = 0;
402 TopExp_Explorer anEdgeExp(myShape,TopAbs_EDGE);
403 for (;anEdgeExp.More(); anEdgeExp.Next()) {
404 if (IsOriented(anEdgeExp.Current()))
407 if (aNbOrirntedEdges==0)
410 BRepCheck::Add(myMap(myShape),aClosedStat);
414 // all those edges must form a closed 2d contour and be found by WireExplorer
416 Standard_Integer aNbFoundEdges = 0;
418 BRepTools_WireExplorer aWireExp(TopoDS::Wire(myShape), theFace);
419 TopoDS_Edge aFirstEdge = aWireExp.Current();
420 TopoDS_Vertex aFirstVertex = aWireExp.CurrentVertex();
421 TopoDS_Edge aLastEdge;
422 for (;aWireExp.More(); aWireExp.Next())
425 aLastEdge = aWireExp.Current();
428 if (aNbFoundEdges != aNbOrirntedEdges)
430 aClosedStat = BRepCheck_NotClosed;
432 BRepCheck::Add(myMap(myShape),aClosedStat);
436 // Check distance between 2d ends of first and last edges
437 // Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 Begin
438 // First check if first and last edges are infinite:
441 Standard_Boolean isFirstInfinite = Standard_False;
442 Standard_Boolean isLastInfinite = Standard_False;
443 TopAbs_Orientation anOri;
445 anOri = aFirstEdge.Orientation();
446 BRep_Tool::Range(aFirstEdge, aF, aL);
447 if ((anOri == TopAbs_FORWARD && aF == -Precision::Infinite()) ||
448 (anOri == TopAbs_REVERSED && aL == Precision::Infinite()))
449 isFirstInfinite = Standard_True;
451 anOri = aLastEdge.Orientation();
452 BRep_Tool::Range(aLastEdge, aF, aL);
453 if ((anOri == TopAbs_FORWARD && aL == Precision::Infinite()) ||
454 (anOri == TopAbs_REVERSED && aF == -Precision::Infinite()))
455 isLastInfinite = Standard_True;
457 if (isFirstInfinite && isLastInfinite) {
459 BRepCheck::Add(myMap(myShape),aClosedStat);
461 } else if (aFirstVertex.IsNull()) {
462 aClosedStat = BRepCheck_NotClosed;
464 BRepCheck::Add(myMap(myShape),aClosedStat);
467 // Modified by Sergey KHROMOV - Mon May 13 12:42:10 2002 End
469 gp_Pnt2d p, p1, p2; // ends of prev edge, next edge, bidon
472 BRep_Tool::UVPoints(aLastEdge, theFace, p2, p);
473 if (aLastEdge.Orientation() == TopAbs_REVERSED) p = p2;
475 // Modified by Sergey KHROMOV - Mon Apr 22 10:36:33 2002 Begin
476 // Standard_Real aTol, aUResol, aVResol;
478 // // find 2d tolerance
479 // aTol = BRep_Tool::Tolerance(aFirstVertex);
480 // aUResol = 2*aFaceSurface.UResolution(aTol);
481 // aVResol = 2*aFaceSurface.VResolution(aTol);
484 if (aFirstEdge.Orientation() == TopAbs_REVERSED)
485 BRep_Tool::UVPoints(aFirstEdge, theFace, p2, p1);
487 BRep_Tool::UVPoints(aFirstEdge, theFace, p1, p2);
489 // Modified by Sergey KHROMOV - Thu Jun 20 10:55:42 2002 OCC325 Begin
490 // Check 2d distance for periodic faces with seam edge
491 if (!IsClosed2dForPeriodicFace(theFace, p, p1, aFirstVertex)) {
492 aClosedStat = BRepCheck_NotClosed;
494 BRepCheck::Add(myMap(myShape),aClosedStat);
497 // Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End
500 // Standard_Real dfUDist=Abs(p.X()-p1.X());
501 // Standard_Real dfVDist=Abs(p.Y()-p1.Y());
502 // if (dfUDist > aUResol || dfVDist > aVResol)
504 Standard_Real aTol3d = BRep_Tool::Tolerance(aFirstVertex);
505 gp_Pnt aPRef = BRep_Tool::Pnt(aFirstVertex);
506 gp_Pnt aP1 = aFaceSurface.Value(p.X(), p.Y());
507 gp_Pnt aP2 = aFaceSurface.Value(p1.X(), p1.Y());
508 Standard_Real Dist1 = aPRef.Distance(aP1);
509 Standard_Real Dist2 = aPRef.Distance(aP2);
511 if (Dist1 > aTol3d || Dist2 > aTol3d) {
512 // Modified by Sergey KHROMOV - Mon Apr 22 10:36:44 2002 End
515 cout << "------------------------------------------------------" <<endl;
516 cout << "--- BRepCheck Wire: Closed2d -> Erreur" <<endl;
518 cout << "--- Dist1 (" << Dist1 << ") > Tol3d (" << aTol3d << ")" <<endl;
520 cout << "--- Dist2 (" << Dist2 << ") > Tol3d (" << aTol3d << ")" <<endl;
521 cout << "------------------------------------------------------" <<endl;
523 aClosedStat = BRepCheck_NotClosed;
525 BRepCheck::Add(myMap(myShape),aClosedStat);
530 BRepCheck::Add(myMap(myShape),aClosedStat);
533 //=======================================================================
534 //function : Orientation
536 //=======================================================================
537 BRepCheck_Status BRepCheck_Wire::Orientation(const TopoDS_Face& F,
538 const Standard_Boolean Update)
540 BRepCheck_Status theOstat = Closed();
541 if (theOstat != BRepCheck_NotClosed && theOstat != BRepCheck_NoError) {
543 BRepCheck::Add(myMap(myShape),theOstat);
548 theOstat = BRepCheck_NoError;
552 TopAbs_Orientation orient, ortmp = TopAbs_FORWARD;
554 TopAbs_Orientation orient, ortmp;
556 TopTools_ListOfShape ledge, ListOfPassedEdge;
557 TopExp_Explorer exp,vte;
558 TopTools_MapOfShape mapS;
559 TopoDS_Edge theEdge,theRef;
561 // Checks the orientation of the edges
562 for (exp.Init(myShape,TopAbs_EDGE); exp.More(); exp.Next()) {
563 const TopoDS_Edge& edg = TopoDS::Edge(exp.Current());
564 orient = edg.Orientation();
565 if (IsOriented(edg)) {
569 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
570 TopAbs_Orientation vto = vte.Current().Orientation();
571 if (vto == TopAbs_FORWARD) {
572 VF = TopoDS::Vertex(vte.Current());
574 else if (vto == TopAbs_REVERSED) {
575 VL = TopoDS::Vertex(vte.Current());
577 if (!VF.IsNull() && !VL.IsNull()) {
581 if (VF.IsNull() && VL.IsNull())
582 theOstat = BRepCheck_InvalidDegeneratedFlag;
587 if (theOstat == BRepCheck_NoError) {
588 Standard_Integer Index = 1;
589 Standard_Integer nbOriNoDegen=myMapVE.Extent();
590 // Modified by Sergey KHROMOV - Tue May 21 17:12:45 2002 Begin
591 Standard_Boolean isGoFwd = Standard_True;
594 isGoFwd = Standard_False;
595 // Modified by Sergey KHROMOV - Tue May 21 17:12:45 2002 End
597 while (Index < nbOriNoDegen) {
599 ListOfPassedEdge.Clear();
600 // find edges that make a chain on VL if !VL.IsNull
603 Standard_Integer ind;
605 ind = myMapVE.FindIndex(VL);
607 else if (!VF.IsNull()) {
608 ind = myMapVE.FindIndex(VF);
611 theOstat = BRepCheck_InvalidDegeneratedFlag;
615 for (TopTools_ListIteratorOfListOfShape itls(myMapVE(ind));
616 itls.More(); itls.Next()) {
617 const TopoDS_Edge & edg = TopoDS::Edge(itls.Value());
619 orient = edg.Orientation();
620 if (mapS.Contains(edg)) ortmp = GetOrientation(mapS,edg);
622 //Add to list already passed outcoming edges
623 if (mapS.Contains(edg) && ortmp == orient && !edg.IsSame(theEdge))
624 for (vte.Init(edg,TopAbs_VERTEX); vte.More(); vte.Next())
626 TopAbs_Orientation vto = vte.Current().Orientation();
629 if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current()))
631 ListOfPassedEdge.Append(edg);
635 else // VF is not null
637 if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current()))
639 ListOfPassedEdge.Append(edg);
645 if (!mapS.Contains(edg) || ortmp != orient) {
646 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
647 TopAbs_Orientation vto = vte.Current().Orientation();
649 if (vto == TopAbs_FORWARD && VL.IsSame(vte.Current())) {
650 // If the processing is in 2d (face not null) or
651 // if the edge is not degenerated it is added
652 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
657 else { // VF is not null
658 if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
659 // // If the processing is in 2d (face not null) or
660 // if the edge is not degenerated it is added
661 if (!F.IsNull() || !BRep_Tool::Degenerated(edg))
669 Standard_Integer nbconnex = ledge.Extent();
670 Standard_Boolean Changedesens = Standard_False;
672 if (myCstat == BRepCheck_NotClosed) {
675 BRepCheck::Add(myMap(myShape),theOstat);
677 return theOstat; // leave
680 Index--; // because after Index++ and if there is no chain,
681 VL.Nullify(); // chain on VF is forced
683 Changedesens = Standard_True;
687 theOstat = BRepCheck_BadOrientationOfSubshape;
689 BRepCheck::Add(myMap(myShape),theOstat);
695 // JAG 03/07 else if (nbconnex >= 2 && !F.IsNull()) // Try to see in 2d
696 else if (!F.IsNull()) { // Try to see in 2d
705 ChoixUV(pivot,theEdge,F,ledge);
706 nbconnex = ledge.Extent();
707 // 20/03/02 akm vvv : (OCC234) - The 2d exploration of wire with necessary
708 // checks is performed in Closed2d, here it's useless
709 // if (nbconnex == 1 && !CheckLoopOrientation( pivot, theEdge, TopoDS::Edge(ledge.First()), F, ListOfPassedEdge ))
711 // theOstat = BRepCheck_BadOrientationOfSubshape;
713 // BRepCheck::Add(myMap(myShape),theOstat);
720 theOstat = BRepCheck_BadOrientationOfSubshape;
722 BRepCheck::Add(myMap(myShape),theOstat);
726 else if (nbconnex == 1) {
728 for (vte.Init(ledge.First(),TopAbs_VERTEX);vte.More(); vte.Next()) {
729 TopAbs_Orientation vto = vte.Current().Orientation();
731 if (vto == TopAbs_REVERSED) {
732 VL = TopoDS::Vertex(vte.Current());
736 else { // VF is not null
737 if (vto == TopAbs_FORWARD) {
738 VF = TopoDS::Vertex(vte.Current());
743 mapS.Add(ledge.First());
744 theEdge = TopoDS::Edge(ledge.First());
754 else if (!Changedesens) { //nbconnex == 0
755 theOstat = BRepCheck_NotClosed;
757 BRepCheck::Add(myMap(myShape),theOstat);
762 // Check the closure of the wire in 2d (not done in Closed())
765 Standard_Boolean isCheckClose = Standard_False;
767 if (isGoFwd && !VF.IsNull()) {
769 isCheckClose = Standard_True;
770 } else if (!isGoFwd && !VL.IsNull()) {
772 isCheckClose = Standard_True;
775 // if (Index==1 && myCstat!=BRepCheck_NotClosed &&
776 // !VF.IsNull() && !F.IsNull()) {
777 if (Index==1 && myCstat!=BRepCheck_NotClosed &&
778 isCheckClose && !F.IsNull()) {
780 // ind = myMapVE.FindIndex(VF);
781 ind = myMapVE.FindIndex(aVRef);
782 for (TopTools_ListIteratorOfListOfShape itlsh(myMapVE(ind));
783 itlsh.More(); itlsh.Next()) {
784 const TopoDS_Edge & edg = TopoDS::Edge(itlsh.Value());
785 orient = edg.Orientation();
786 if (!theRef.IsSame(edg)) {
787 for (vte.Init(edg,TopAbs_VERTEX);vte.More(); vte.Next()) {
788 TopAbs_Orientation vto = vte.Current().Orientation();
789 // if (vto == TopAbs_REVERSED && VF.IsSame(vte.Current())) {
790 if (vto == TopAbs_REVERSED && aVRef.IsSame(vte.Current())) {
797 // ChoixUV(VF, theRef, F, ledge);
798 ChoixUV(aVRef, theRef, F, ledge);
799 if (ledge.Extent()==0) {
800 theOstat = BRepCheck_NotClosed;
802 BRepCheck::Add(myMap(myShape),theOstat);
807 // End control closure 2d
813 BRepCheck::Add(myMap(myShape),theOstat);
817 //=======================================================================
818 //function : SelfIntersect
820 //=======================================================================
821 BRepCheck_Status BRepCheck_Wire::SelfIntersect(const TopoDS_Face& F,
824 const Standard_Boolean Update)
829 Standard_Integer i,j,Nbedges;
830 Standard_Real first1,last1,first2,last2, tolint;
831 gp_Pnt2d pfirst1,plast1,pfirst2,plast2;
833 Handle(BRepAdaptor_HSurface) HS;
834 Geom2dAdaptor_Curve C1, C2;
835 Geom2dInt_GInter Inter;
836 IntRes2d_Domain myDomain1;
837 TopTools_IndexedMapOfOrientedShape EMap;
838 TopTools_MapOfOrientedShape auxmape;
841 //-- check with proper tolerances if there is no
842 //-- point in the tolerance of a vertex.
844 HS = new BRepAdaptor_HSurface();
845 HS->ChangeSurface().Initialize(F,Standard_False);
847 for (TopoDS_Iterator Iter1(myShape);Iter1.More();Iter1.Next()) {
848 if (Iter1.Value().ShapeType() == TopAbs_EDGE) {
849 EMap.Add(Iter1.Value());
853 Nbedges=EMap.Extent();
856 BRepCheck::Add(myMap(myShape),BRepCheck_EmptyWire);
858 return(BRepCheck_EmptyWire);
861 IntRes2d_Domain *tabDom = new IntRes2d_Domain[Nbedges];
862 TColGeom2d_Array1OfCurve tabCur(1,Nbedges);
863 Bnd_Array1OfBox2d boxes(1,Nbedges);
865 for(i = 1; i <= Nbedges; i++) {
866 const TopoDS_Edge& E1 = TopoDS::Edge(EMap.FindKey(i));
868 Handle(Geom2d_Curve) pcu = BRep_Tool::CurveOnSurface(E1, F, first1, last1);
872 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
875 return(BRepCheck_SelfIntersectingWire);
879 // To avoid exeption in Segment if C1 is BSpline - IFV
880 if(!C1.IsPeriodic()) {
881 if(C1.FirstParameter() > first1) {
882 first1 = C1.FirstParameter();
884 if(C1.LastParameter() < last1 ){
885 last1 = C1.LastParameter();
889 BRep_Tool::UVPoints(E1, F, pfirst1, plast1);
890 myDomain1.SetValues(pfirst1,first1,tolint, plast1,last1,tolint);
892 BndLib_Add2dCurve::Add(C1, first1, last1, Precision::PConfusion(), boxes(i));
896 myDomain1 = tabDom[i-1];
899 // Self intersect of C1
900 Inter.Perform(C1, myDomain1, tolint, tolint);
903 Standard_Integer nbp = Inter.NbPoints();
904 //Standard_Integer nbs = Inter.NbSegments();
906 for(Standard_Integer p=1;p<=nbp;p++) {
907 const IntRes2d_IntersectionPoint& IP=Inter.Point(p);
908 const IntRes2d_Transition& Tr1 = IP.TransitionOfFirst();
909 const IntRes2d_Transition& Tr2 = IP.TransitionOfSecond();
910 if( Tr1.PositionOnCurve() == IntRes2d_Middle
911 || Tr2.PositionOnCurve() == IntRes2d_Middle) {
912 //-- Checking of points with true tolerances (ie Tol in 3d)
913 //-- If the point of intersection is within the tolearnce of a vertex
914 //-- this intersection is considered correct (no error)
915 Standard_Boolean localok = Standard_False;
918 const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f,l);
920 //-- try to test in 3d. (ParamOnSecond gives the same result)
921 P3d = ConS->Value(IP.ParamOnFirst());
922 P3d.Transform(L.Transformation());
923 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
926 gp_Pnt2d aP2d = C1.Value(IP.ParamOnFirst());
927 P3d = HS->Value(aP2d.X(), aP2d.Y());
929 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
930 TopExp_Explorer ExplVtx;
931 for(ExplVtx.Init(E1,TopAbs_VERTEX);
932 localok==Standard_False && ExplVtx.More();
935 Standard_Real tolvtt, p3dvttDistanceP3d;
937 const TopoDS_Vertex& vtt = TopoDS::Vertex(ExplVtx.Current());
938 p3dvtt = BRep_Tool::Pnt(vtt);
939 tolvtt = BRep_Tool::Tolerance(vtt);
940 tolvtt=tolvtt*tolvtt;
941 p3dvttDistanceP3d=p3dvtt.SquareDistance(P3d);
942 if(p3dvttDistanceP3d <= tolvtt) {
943 localok=Standard_True;
946 if(localok==Standard_False) {
950 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
954 static Standard_Integer numpoint=0;
955 cout<<"point p"<<++numpoint<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;cout.flush();
957 return(BRepCheck_SelfIntersectingWire);
961 }// if(Inter.IsDone()) {
963 for(j=i+1; j<=Nbedges; j++) {
964 const TopoDS_Edge& E2 = TopoDS::Edge(EMap.FindKey(j));
966 tabCur(j) = BRep_Tool::CurveOnSurface(E2,F,first2,last2);
967 if (!tabCur(j).IsNull() && last2 > first2) {
969 // To avoid exeption in Segment if C2 is BSpline - IFV
970 if(!C2.IsPeriodic()) {
971 if(C2.FirstParameter() > first2) {
972 first2 = C2.FirstParameter();
974 if(C2.LastParameter() < last2 ) {
975 last2 = C2.LastParameter();
979 BRep_Tool::UVPoints(E2,F,pfirst2,plast2);
980 tabDom[j-1].SetValues(pfirst2,first2,tolint,plast2,last2,tolint);
982 BndLib_Add2dCurve::Add( C2, first2, last2, Precision::PConfusion(), boxes(j) );
987 cout<<"BRepCheck_NoCurveOnSurface or BRepCheck_InvalidRange"<<endl;cout.flush();
989 if(tabCur(j).IsNull()) {
990 return(BRepCheck_NoCurveOnSurface);
992 return (BRepCheck_InvalidRange);
999 if (boxes(i).IsOut( boxes(j))) {
1002 //modified by NIZNHY-PKV Fri Oct 29 10:09:01 2010f
1003 if (E1.IsSame(E2)) {
1006 //modified by NIZNHY-PKV Fri Oct 29 10:09:02 2010t
1008 //-- ************************************************************
1009 //-- ******* I n t e r s e c t i o n C 1 and C 2 ********
1010 //-- ************************************************************
1011 Inter.Perform(C1,myDomain1,C2,tabDom[j-1],tolint,tolint);
1013 if(Inter.IsDone()) {
1014 Standard_Integer nbp, nbs;
1015 Standard_Real IP_ParamOnFirst, IP_ParamOnSecond;
1016 IntRes2d_Transition Tr1,Tr2;
1017 TopTools_ListOfShape CommonVertices;
1018 TopTools_ListIteratorOfListOfShape itl;
1019 TopTools_MapOfShape Vmap;
1021 TopoDS_Iterator it( E1 );
1022 for (; it.More(); it.Next()) {
1023 Vmap.Add( it.Value() );
1026 it.Initialize( E2 );
1027 for (; it.More(); it.Next()) {
1028 const TopoDS_Shape& V = it.Value();
1029 if (Vmap.Contains( V )) {
1030 CommonVertices.Append( V );
1034 nbp = Inter.NbPoints();
1035 nbs = Inter.NbSegments();
1036 IP_ParamOnFirst = 0.;
1037 IP_ParamOnSecond = 0.;
1039 //// **** Points of intersection **** ////
1040 for (Standard_Integer p = 1; p <= nbp; p++) {
1041 const IntRes2d_IntersectionPoint& IP = Inter.Point(p);
1042 IP_ParamOnFirst = IP.ParamOnFirst();
1043 IP_ParamOnSecond = IP.ParamOnSecond();
1044 Tr1 = IP.TransitionOfFirst();
1045 Tr2 = IP.TransitionOfSecond();
1046 if( Tr1.PositionOnCurve() == IntRes2d_Middle
1047 || Tr2.PositionOnCurve() == IntRes2d_Middle) {
1048 //-- Checking of points with true tolerances (ie Tol in 3d)
1049 //-- If the point of intersection is within the tolerance of a vertex
1050 //-- this intersection is considered correct (no error)
1051 Standard_Boolean localok = Standard_False;
1052 Standard_Real f1,l1, f2, l2;
1053 TopLoc_Location L, L2;
1055 const Handle(Geom_Curve) ConS = BRep_Tool::Curve(E1,L,f1,l1);
1056 const Handle(Geom_Curve) ConS2 = BRep_Tool::Curve(E2,L2,f2,l2);
1057 //gka protect against working out of edge range
1058 if ( f1-IP_ParamOnFirst > ::Precision::PConfusion() ||
1059 IP_ParamOnFirst-l1 > ::Precision::PConfusion() ||
1060 f2-IP_ParamOnSecond > ::Precision::PConfusion() ||
1061 IP_ParamOnSecond-l2 > ::Precision::PConfusion() )
1063 Standard_Real tolvtt;
1064 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1065 if (!ConS.IsNull()) {
1066 P3d = ConS->Value(IP_ParamOnFirst);
1067 P3d.Transform(L.Transformation());
1070 gp_Pnt2d aP2d = C1.Value(IP_ParamOnFirst);
1071 P3d = HS->Value(aP2d.X(), aP2d.Y());
1074 if (!ConS2.IsNull()) {
1075 P3d2 = ConS2->Value(IP_ParamOnSecond);
1076 P3d2.Transform(L2.Transformation());
1079 gp_Pnt2d aP2d = C2.Value(IP_ParamOnSecond);
1080 P3d2 = HS->Value(aP2d.X(), aP2d.Y());
1082 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1083 itl.Initialize( CommonVertices );
1084 for (; itl.More(); itl.Next()) {
1085 Standard_Real p3dvttDistanceP3d, p3dvttDistanceP3d2;
1088 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1089 p3dvtt = BRep_Tool::Pnt(vtt);
1090 tolvtt = BRep_Tool::Tolerance(vtt);
1092 tolvtt=tolvtt*tolvtt;
1093 p3dvttDistanceP3d = p3dvtt.SquareDistance(P3d);
1094 p3dvttDistanceP3d2 = p3dvtt.SquareDistance(P3d2);
1096 if (p3dvttDistanceP3d<=tolvtt && p3dvttDistanceP3d2<=tolvtt) {
1097 localok = Standard_True;
1102 //-- --------------------------------------------------------
1103 //-- Check maximum yawn between 2 edges
1105 //-- Check distance from edges to the curve joining
1106 //-- the point of intersection with vertex (if exists)
1107 if (localok == Standard_False && !CommonVertices.IsEmpty()) {
1109 cout << "\n------------------------------------------------------\n" <<endl;
1110 cout << "\n--- BRepCheck Wire: AutoIntersection Phase1 -> Erreur \n" <<endl;
1113 Standard_Boolean yaunvtxproche;
1114 Standard_Real distauvtxleplusproche,VParaOnEdge1,VParaOnEdge2;
1115 gp_Pnt VertexLePlusProche;
1117 yaunvtxproche=Standard_False;
1120 distauvtxleplusproche=RealLast();
1121 //Find the nearest common vertex
1122 itl.Initialize( CommonVertices );
1123 for (; itl.More(); itl.Next()) {
1124 Standard_Real tolvtt, disptvtx;
1127 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1128 p3dvtt = BRep_Tool::Pnt(vtt);
1129 tolvtt = BRep_Tool::Tolerance(vtt);
1130 disptvtx = P3d.Distance(p3dvtt);
1131 if (disptvtx < distauvtxleplusproche) {
1132 VertexLePlusProche = p3dvtt;
1133 distauvtxleplusproche = disptvtx;
1134 VParaOnEdge1 = BRep_Tool::Parameter(vtt,E1);
1135 VParaOnEdge2 = BRep_Tool::Parameter(vtt,E2);
1137 // eap: case of closed edge
1138 else if (IsEqual(distauvtxleplusproche, disptvtx)) {
1139 Standard_Real newVParaOnEdge1 = BRep_Tool::Parameter(vtt,E1);
1140 Standard_Real newVParaOnEdge2 = BRep_Tool::Parameter(vtt,E2);
1141 if (Abs(IP_ParamOnFirst - VParaOnEdge1) + Abs(IP_ParamOnSecond - VParaOnEdge2)
1143 Abs(IP_ParamOnFirst - newVParaOnEdge1) + Abs(IP_ParamOnSecond - newVParaOnEdge2)) {
1144 VertexLePlusProche = p3dvtt;
1145 VParaOnEdge1 = newVParaOnEdge1;
1146 VParaOnEdge2 = newVParaOnEdge2;
1150 //Patch: extraordinar situation (e.g. tolerance(v) == 0.)
1151 // Modified by skv - Wed Jul 23 12:28:11 2003 OCC1764 Begin
1152 // if (VertexLePlusProche.Distance( P3d ) <= gp::Resolution())
1153 if (VertexLePlusProche.Distance(P3d) <= gp::Resolution() ||
1154 VertexLePlusProche.Distance(P3d2) <= gp::Resolution()) {
1155 // Modified by skv - Wed Jul 23 12:28:12 2003 OCC1764 End
1156 localok = Standard_True;
1159 gp_Lin Lig( VertexLePlusProche, gp_Vec(VertexLePlusProche,P3d) );
1160 Standard_Real du1 = 0.1*(IP_ParamOnFirst -VParaOnEdge1);
1161 Standard_Real du2 = 0.1*(IP_ParamOnSecond-VParaOnEdge2);
1162 Standard_Real maxd1 = 0., maxd2 = 0.;
1165 localok = Standard_True;
1166 Standard_Real tole1 = BRep_Tool::Tolerance(E1);
1167 for (k = 2; localok && k < 9; k++) {
1168 Standard_Real u = VParaOnEdge1 + k*du1; // check if it works
1170 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1171 if (!ConS.IsNull()) {
1172 P1 = ConS->Value(u);
1173 P1.Transform(L.Transformation());
1176 gp_Pnt2d aP2d = C1.Value(u);
1177 P1 = HS->Value(aP2d.X(), aP2d.Y());
1179 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1180 Standard_Real d1 = Lig.Distance(P1);
1184 if (d1 > tole1*2.0){
1185 localok = Standard_False;
1189 // Modified by skv - Wed Jul 23 12:22:20 2003 OCC1764 Begin
1190 gp_Dir aTmpDir(P3d2.XYZ().Subtracted(VertexLePlusProche.XYZ()));
1192 Lig.SetDirection(aTmpDir);
1193 // Modified by skv - Wed Jul 23 12:22:23 2003 OCC1764 End
1194 Standard_Real tole2 = BRep_Tool::Tolerance(E2);
1195 for (k = 2; localok && k < 9; k++) {
1196 Standard_Real u = VParaOnEdge2 + k*du2; // check if it works
1198 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1199 if (!ConS2.IsNull()) {
1200 P2 = ConS2->Value(u);
1201 P2.Transform(L2.Transformation());
1204 gp_Pnt2d aP2d = C2.Value(u);
1205 P2 = HS->Value(aP2d.X(), aP2d.Y());
1207 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1208 Standard_Real d2 = Lig.Distance(P2);
1212 if (d2 > tole2*2.0){
1213 localok = Standard_False;
1218 printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Bon \n");
1219 printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
1220 printf("--- Erreur Max sur E1 : %10.7g Tol_Edge:%10.7g\n",maxd1,tole1);
1221 printf("--- Erreur Max sur E2 : %10.7g Tol_Edge:%10.7g\n",maxd2,tole2);
1225 printf("--- BRepCheck Wire: AutoIntersection Phase2 -> Erreur \n");
1226 printf("--- distance Point Vertex : %10.7g (tol %10.7g)\n",distauvtxleplusproche,tolvtt);
1227 printf("--- Erreur Max sur E1 : %10.7g Tol_Edge:%10.7g\n",maxd1,tole1);
1228 printf("--- Erreur Max sur E2 : %10.7g Tol_Edge:%10.7g\n",maxd2,tole2);
1232 } //end of else (construction of the line Lig)
1233 } //end of if (localok == Standard_False && !CommonVertices.IsEmpty())
1235 if(localok==Standard_False) {
1240 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1243 static Standard_Integer numpoint1=0;
1244 cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
1248 return(BRepCheck_SelfIntersectingWire);
1249 } //-- localok == False
1250 } //end of if(Tr1.PositionOnCurve() == IntRes2d_Middle || Tr2.PositionOnCurve() == IntRes2d_Middle)
1251 } //end of for (Standard_Integer p=1; p <= nbp; p++)
1253 //// **** Segments of intersection **** ////
1254 for (Standard_Integer s = 1; s <= nbs; ++s) {
1255 const IntRes2d_IntersectionSegment& Seg = Inter.Segment(s);
1256 if (Seg.HasFirstPoint() && Seg.HasLastPoint()) {
1257 Standard_Boolean localok;
1259 IntRes2d_IntersectionPoint PSeg [2];
1260 IntRes2d_Position aPCR1, aPCR2;
1262 localok = Standard_False;
1263 PSeg[0] = Seg.FirstPoint();
1264 PSeg[1] = Seg.LastPoint();
1265 // At least one of extremities of the segment must be inside
1266 // the tolerance of a common vertex
1267 for (k = 0; k < 2; ++k) {
1268 IP_ParamOnFirst = PSeg[k].ParamOnFirst();
1269 IP_ParamOnSecond = PSeg[k].ParamOnSecond();
1270 Tr1 = PSeg[k].TransitionOfFirst();
1271 Tr2 = PSeg[k].TransitionOfSecond();
1272 aPCR1=Tr1.PositionOnCurve();
1273 aPCR2=Tr2.PositionOnCurve();
1275 if(aPCR1!=IntRes2d_Middle && aPCR2!=IntRes2d_Middle) {
1276 GeomAbs_CurveType aCT1, aCT2;
1280 if (aCT1==GeomAbs_Line && aCT2==GeomAbs_Line) {
1281 // check for the two lines coincidence
1282 Standard_Real aPAR_T, aT11, aT12, aT21, aT22, aT1m, aT2m;
1283 Standard_Real aD2, aTolE1, aTolE2, aTol2, aDot;
1289 aTolE1=BRep_Tool::Tolerance(E1);
1290 aTolE2=BRep_Tool::Tolerance(E2);
1291 aTol2=aTolE1+aTolE2;
1297 aT11=PSeg[0].ParamOnFirst();
1298 aT12=PSeg[1].ParamOnFirst();
1299 aT21=PSeg[0].ParamOnSecond();
1300 aT22=PSeg[1].ParamOnSecond();
1302 aT1m=(1.-aPAR_T)*aT11 + aPAR_T*aT12;
1303 aP1m=C1.Value(aT1m);
1305 aD2=aL2.SquareDistance(aP1m);
1307 aT2m=ElCLib::Parameter(aL2, aP1m);
1308 if (aT2m>aT21 && aT2m<aT22) {
1309 const gp_Dir2d& aDir1=aL1.Direction();
1310 const gp_Dir2d& aDir2=aL2.Direction();
1316 if ((1.-aDot)<5.e-11){//0.00001 rad
1317 localok = Standard_False;
1318 break;// from for (k = 0; k < 2; ++k){...
1320 }//if (aT2m>aT21 && aT2m<aT22) {
1322 }//if (aCT1==GeomAbs_Line && aCT2==GeomAbs_Line) {
1324 localok = Standard_True;
1328 Standard_Real f,l, tolvtt;
1329 TopLoc_Location L, L2;
1330 const Handle(Geom_Curve)& ConS = BRep_Tool::Curve(E1,L,f,l);
1331 const Handle(Geom_Curve)& ConS2 = BRep_Tool::Curve(E2,L2,f,l);
1332 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 Begin
1333 if (!ConS.IsNull()) {
1334 P3d = ConS->Value(IP_ParamOnFirst);
1335 P3d.Transform(L.Transformation());
1337 gp_Pnt2d aP2d = C1.Value(IP_ParamOnFirst);
1338 P3d = HS->Value(aP2d.X(), aP2d.Y());
1340 if (!ConS2.IsNull()) {
1341 P3d2 = ConS2->Value(IP_ParamOnSecond);
1342 P3d2.Transform(L2.Transformation());
1344 gp_Pnt2d aP2d = C2.Value(IP_ParamOnSecond);
1345 P3d2 = HS->Value(aP2d.X(), aP2d.Y());
1347 // Modified by Sergey KHROMOV - Mon Apr 15 12:34:22 2002 End
1348 itl.Initialize( CommonVertices );
1349 for (; itl.More(); itl.Next()) {
1350 Standard_Real p3dvttDistanceP3d, p3dvttDistanceP3d2;
1353 const TopoDS_Vertex& vtt = TopoDS::Vertex(itl.Value());
1354 p3dvtt = BRep_Tool::Pnt(vtt);
1355 tolvtt = BRep_Tool::Tolerance(vtt);
1357 tolvtt=tolvtt*tolvtt;
1358 p3dvttDistanceP3d = p3dvtt.SquareDistance(P3d);
1359 p3dvttDistanceP3d2 = p3dvtt.SquareDistance(P3d2);
1360 if (p3dvttDistanceP3d <= tolvtt && p3dvttDistanceP3d2 <= tolvtt) {
1361 localok = Standard_True;
1365 if (localok == Standard_True) {
1368 } //end of for (k = 0; k < 2; k++)
1370 if(localok==Standard_False) {
1375 BRepCheck::Add(myMap(myShape),BRepCheck_SelfIntersectingWire);
1378 static Standard_Integer numpoint1=0;
1379 cout<<"point p"<<++numpoint1<<" "<<P3d.X()<<" "<<P3d.Y()<<" "<<P3d.Z()<<endl;
1383 return(BRepCheck_SelfIntersectingWire);
1384 } //-- localok == False
1385 } //end of if(Seg.HasFirstPoint() && Seg.HasLastPoint())
1386 } //end of for (Standard_Integer s = 1; s <= nbs; p++)
1387 } //-- Inter.IsDone()
1388 } //end of for( j = i+1; j<=Nbedges; j++)
1389 } //end of for(i = 1; i <= Nbedges; i++)
1393 BRepCheck::Add(myMap(myShape),BRepCheck_NoError);
1396 return (BRepCheck_NoError);
1398 //=======================================================================
1399 //function : GeometricControls
1401 //=======================================================================
1402 void BRepCheck_Wire::GeometricControls(const Standard_Boolean B)
1406 myCdone = Standard_False;
1411 //=======================================================================
1412 //function : GeometricControls
1414 //=======================================================================
1415 Standard_Boolean BRepCheck_Wire::GeometricControls() const
1421 //=======================================================================
1422 //function : Propagate
1423 //purpose : fill <mapE> with edges connected to <edg> through vertices
1424 // contained in <mapVE>
1425 //=======================================================================
1426 static void Propagate(const TopTools_IndexedDataMapOfShapeListOfShape& mapVE,
1427 const TopoDS_Shape& edg,
1428 TopTools_MapOfShape& mapE)
1430 if (mapE.Contains(edg)) {
1433 mapE.Add(edg); // attention, if oriented == Standard_True, edge should
1434 // be FORWARD or REVERSED. It is not checked.
1436 // attention, if oriented == Standard_True, <edg> must
1437 // be FORWARD or REVERSED. That is not checked.
1440 for (ex.Init(edg,TopAbs_VERTEX); ex.More(); ex.Next()) {
1441 const TopoDS_Vertex& vtx = TopoDS::Vertex(ex.Current());
1443 Standard_Integer indv = mapVE.FindIndex(vtx);
1445 for (TopTools_ListIteratorOfListOfShape itl(mapVE(indv)); itl.More(); itl.Next()) {
1446 if (!itl.Value().IsSame(edg) &&
1447 !mapE.Contains(itl.Value())) {
1448 Propagate(mapVE,itl.Value(),mapE);
1454 //=======================================================================
1455 //function : GetOrientation
1457 //=======================================================================
1459 static TopAbs_Orientation GetOrientation(const TopTools_MapOfShape& mapE,
1460 const TopoDS_Edge& edg)
1462 TopTools_MapIteratorOfMapOfShape itm(mapE);
1463 for ( ; itm.More(); itm.Next()) {
1464 if (itm.Key().IsSame(edg)) {
1468 return itm.Key().Orientation();
1470 //=======================================================================
1471 //function : ChoixUV
1473 //=======================================================================
1474 void ChoixUV(const TopoDS_Vertex& V,
1475 const TopoDS_Edge& Edg,
1476 const TopoDS_Face& F,
1477 TopTools_ListOfShape& L)
1479 TopTools_ListIteratorOfListOfShape It( L );
1482 if (Edg.IsSame( It.Value() ))
1488 Standard_Integer index = 0, imin = 0;
1490 gp_Pnt2d PntRef, Pnt;
1491 gp_Vec2d DerRef, Der;
1492 Standard_Real MinAngle, MaxAngle, angle;
1493 Standard_Real gpResolution=gp::Resolution();
1494 TopAbs_Orientation aVOrientation, aEdgOrientation;
1496 Standard_Real dist2d = 0, p = 0;
1498 Standard_Real dist2d, p;
1500 Standard_Real f, l, parpiv;
1501 Standard_Real tolv = BRep_Tool::Tolerance(V);
1502 BRepAdaptor_Surface Ads(F,Standard_False); // no restriction
1503 Standard_Real ures = Ads.UResolution(tolv);
1504 Standard_Real vres = Ads.VResolution(tolv);
1505 Standard_Real tol = Max(ures,vres);
1509 cout<<"BRepCheck_Wire : UResolution and VResolution = 0.0 (Face too small ?)"<<endl;cout.flush();
1516 Handle(Geom2d_Curve) C2d = BRep_Tool::CurveOnSurface(Edg, F, f, l);
1517 if (C2d.IsNull()) {// JAG 10.12.96
1521 aVOrientation=V.Orientation();
1522 aEdgOrientation=Edg.Orientation();
1524 parpiv =(aVOrientation==aEdgOrientation) ? f : l;
1526 MinAngle = RealLast();
1527 MaxAngle = RealFirst();
1529 CurveDirForParameter(C2d, parpiv, PntRef, DerRef);
1531 if (aVOrientation != aEdgOrientation){
1536 for (; It.More(); It.Next()) {
1538 const TopoDS_Edge& aE=TopoDS::Edge(It.Value());
1539 C2d = BRep_Tool::CurveOnSurface(aE, F, f, l);
1544 p =(aVOrientation != aE.Orientation()) ? f : l;
1546 Pnt = C2d->Value(p);
1547 dist2d = Pnt.Distance( PntRef );
1552 CurveDirForParameter(C2d, p, Pnt, Der);
1554 if (aVOrientation == aE.Orientation()){
1558 if (DerRef.Magnitude() <= gpResolution ||
1559 Der.Magnitude() <= gpResolution){
1563 angle = DerRef.Angle( Der );
1568 if (F.Orientation() == TopAbs_FORWARD) {
1569 if (angle < MinAngle) {
1574 else { //F.Orientation() != TopAbs_FORWARD
1575 if (angle > MaxAngle){
1584 if (L.Extent() == 1) {
1585 Standard_Boolean onjette = 0; //all right
1586 Evois = TopoDS::Edge(L.First());
1589 cout<<"BRepCheckWire : control closure in 2d --> false"<<endl;cout.flush();
1591 if(Evois.IsNull() || BRep_Tool::Degenerated(Edg) ||
1592 BRep_Tool::Degenerated(Evois)){
1597 Standard_Real dumax = 0.01 * (Ads.LastUParameter() - Ads.FirstUParameter());
1598 Standard_Real dvmax = 0.01 * (Ads.LastVParameter() - Ads.FirstVParameter());
1599 Standard_Real dumin = Abs(Pnt.X() - PntRef.X());
1600 Standard_Real dvmin = Abs(Pnt.Y() - PntRef.Y());
1601 if(dumin > dumax || dvmin > dvmax){
1605 BRepAdaptor_Curve bcEdg(Edg,F);
1606 BRepAdaptor_Curve bcEvois(Evois,F);
1607 gp_Pnt pEdg = bcEdg.Value(parpiv);
1608 gp_Pnt pEvois = bcEvois.Value(p);
1609 Standard_Real d3d = pEvois.Distance(pEdg);
1611 cout<<"point P "<<pEdg.X()<<" "<<pEdg.Y()<<" "<<pEdg.Z()<<endl;
1612 cout<<"distance 3d : "<<d3d<<endl;
1613 cout<<"tolerance vertex : "<<tolv<<endl;
1622 cout<<"control closure in 3d --> ok"<<endl;cout.flush();
1626 } //if (dist2d > tol)
1627 else {//angle was not defined but points are close
1632 cout<<"control closure in 3d --> false"<<endl;cout.flush();
1642 while (index < imin) {
1652 //=======================================================================
1653 //function : CurveDirForParameter
1655 //=======================================================================
1656 void CurveDirForParameter(const Handle(Geom2d_Curve)& aC2d,
1657 const Standard_Real aPrm,
1661 Standard_Real aTol=gp::Resolution();
1664 aC2d->D1(aPrm, Pnt, aVec2d);
1666 if (aVec2d.Magnitude() <= aTol) {
1667 for (i = 2; i <= 100; i++){
1668 aVec2d = aC2d->DN(aPrm, i);
1669 if (aVec2d.Magnitude() > aTol) {
1676 // Modified by Sergey KHROMOV - Wed May 22 10:44:06 2002 OCC325 Begin
1677 //=======================================================================
1678 //function : GetPnts2d
1679 //purpose : this function returns the parametric points of theVertex on theFace.
1680 // If theVertex is a start and end vertex of theEdge hasSecondPnt
1681 // becomes Standard_True and aPnt2 returns the second parametric point.
1682 // Returns Standard_True if paraametric points are successfully found.
1683 //=======================================================================
1685 static Standard_Boolean GetPnt2d(const TopoDS_Vertex &theVertex,
1686 const TopoDS_Edge &theEdge,
1687 const TopoDS_Face &theFace,
1690 Handle(Geom2d_Curve) aPCurve;
1691 Standard_Real aFPar;
1692 Standard_Real aLPar;
1693 Standard_Real aParOnEdge;
1694 TopoDS_Vertex aFirstVtx;
1695 TopoDS_Vertex aLastVtx;
1697 TopExp::Vertices(theEdge, aFirstVtx, aLastVtx);
1699 if (!theVertex.IsSame(aFirstVtx) && !theVertex.IsSame(aLastVtx))
1700 return Standard_False;
1702 aPCurve = BRep_Tool::CurveOnSurface(theEdge, theFace, aFPar, aLPar);
1704 if (aPCurve.IsNull())
1705 return Standard_False;
1707 aParOnEdge = BRep_Tool::Parameter(theVertex, theEdge);
1708 aPnt = aPCurve->Value(aParOnEdge);
1710 return Standard_True;
1713 //=======================================================================
1714 //function : Closed2dForPeriodicFace
1715 //purpose : Checks the distance between first point of the first edge
1716 // and last point of the last edge in 2d for periodic face.
1717 //=======================================================================
1718 static Standard_Boolean IsClosed2dForPeriodicFace
1719 (const TopoDS_Face &theFace,
1720 const gp_Pnt2d &theP1,
1721 const gp_Pnt2d &theP2,
1722 const TopoDS_Vertex &theVertex)
1724 // Check 2d distance for periodic faces with seam edge.
1725 // Searching for seam edges
1726 TopTools_ListOfShape aSeamEdges;
1727 TopTools_MapOfShape NotSeams;
1728 TopTools_MapOfShape ClosedEdges;
1729 TopExp_Explorer anExp(theFace, TopAbs_EDGE);
1731 for (;anExp.More(); anExp.Next()) {
1732 TopoDS_Edge anEdge = TopoDS::Edge(anExp.Current());
1734 if (NotSeams.Contains(anEdge))
1737 if (!IsOriented(anEdge) ||
1738 !BRep_Tool::IsClosed(anEdge, theFace)) {
1739 NotSeams.Add(anEdge);
1743 if (!ClosedEdges.Add(anEdge))
1744 aSeamEdges.Append(anEdge);
1747 if (aSeamEdges.Extent() == 0)
1748 return Standard_True;
1750 // check if theVertex lies on one of the seam edges
1751 BRepAdaptor_Surface aFaceSurface (theFace, Standard_False);
1752 Standard_Real aTol = BRep_Tool::Tolerance(theVertex);
1753 Standard_Real aUResol = aFaceSurface.UResolution(aTol);
1754 Standard_Real aVResol = aFaceSurface.VResolution(aTol);
1755 Standard_Real aVicinity = Sqrt(aUResol*aUResol + aVResol*aVResol);
1756 Standard_Real aDistP1P2 = theP1.Distance(theP2);
1759 TopTools_ListIteratorOfListOfShape anIter(aSeamEdges);
1761 for (; anIter.More(); anIter.Next()) {
1762 TopoDS_Edge aSeamEdge = TopoDS::Edge(anIter.Value());
1764 anExp.Init(aSeamEdge, TopAbs_VERTEX);
1765 for (; anExp.More(); anExp.Next()) {
1766 const TopoDS_Shape &aVtx = anExp.Current();
1768 // We found an edge. Check the distance between two given points
1769 // to be lower than the computed tolerance.
1770 if (IsOriented(aVtx) && aVtx.IsSame(theVertex)) {
1773 Standard_Real a2dTol;
1775 if (!GetPnt2d(theVertex, aSeamEdge, theFace, aPnt1))
1778 aSeamEdge = TopoDS::Edge(aSeamEdge.Reversed());
1780 if (!GetPnt2d(theVertex, aSeamEdge, theFace, aPnt2))
1783 a2dTol = aPnt1.Distance(aPnt2)*1.e-2;
1784 a2dTol = Max(a2dTol, aVicinity);
1786 if (aDistP1P2 > a2dTol)
1787 return Standard_False;
1792 return Standard_True;
1794 // Modified by Sergey KHROMOV - Thu Jun 20 10:58:05 2002 End