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