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