0032133: Modeling Data - Restriction of access to internal arrays for Poly_Triangulat...
[occt.git] / src / BRepCheck / BRepCheck_Edge.cxx
CommitLineData
b311480e 1// Created on: 1995-12-11
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//
d5f74e42 8// This library is free software; you can redistribute it and/or modify it under
9// the terms of the GNU Lesser General Public License version 2.1 as published
973c2be1 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.
7fd59977 16
52d45841 17
42cf5bc1 18#include <Adaptor3d_CurveOnSurface.hxx>
c22b52d6 19#include <Adaptor3d_Curve.hxx>
20#include <Adaptor3d_CurveOnSurface.hxx>
52d45841 21#include <Bnd_Box.hxx>
42cf5bc1 22#include <BRep_CurveOnSurface.hxx>
7fd59977 23#include <BRep_CurveRepresentation.hxx>
7fd59977 24#include <BRep_GCurve.hxx>
42cf5bc1 25#include <BRep_ListIteratorOfListOfCurveRepresentation.hxx>
26#include <BRep_ListOfCurveRepresentation.hxx>
52d45841 27#include <BRep_PolygonOnTriangulation.hxx>
42cf5bc1 28#include <BRep_TEdge.hxx>
29#include <BRep_TFace.hxx>
7fd59977 30#include <BRep_Tool.hxx>
42cf5bc1 31#include <BRepAdaptor_Curve.hxx>
32#include <BRepCheck.hxx>
33#include <BRepCheck_Edge.hxx>
34#include <BRepCheck_ListIteratorOfListOfStatus.hxx>
35#include <BRepCheck_ListOfStatus.hxx>
36#include <Extrema_LocateExtPC.hxx>
7fd59977 37#include <Geom2d_Curve.hxx>
42cf5bc1 38#include <Geom2dAdaptor.hxx>
c22b52d6 39#include <Geom2dAdaptor_Curve.hxx>
42cf5bc1 40#include <Geom_Curve.hxx>
41#include <Geom_Plane.hxx>
42#include <Geom_RectangularTrimmedSurface.hxx>
43#include <Geom_Surface.hxx>
44#include <Geom_TrimmedCurve.hxx>
4e882c71 45#include <Geom2d_TrimmedCurve.hxx>
7fd59977 46#include <GeomAdaptor_Curve.hxx>
c22b52d6 47#include <GeomAdaptor_Curve.hxx>
48#include <GeomAdaptor_Surface.hxx>
7fd59977 49#include <GeomProjLib.hxx>
52d45841 50#include <Poly_PolygonOnTriangulation.hxx>
51#include <Poly_Triangulation.hxx>
42cf5bc1 52#include <Precision.hxx>
53#include <ProjLib_ProjectedCurve.hxx>
54#include <Standard_Type.hxx>
55#include <TColStd_Array1OfTransient.hxx>
56#include <TColStd_HArray1OfReal.hxx>
57#include <TopAbs_ShapeEnum.hxx>
58#include <TopExp_Explorer.hxx>
59#include <TopoDS.hxx>
60#include <TopoDS_Edge.hxx>
61#include <TopoDS_Face.hxx>
62#include <TopoDS_Shape.hxx>
7fd59977 63
92efcf78 64IMPLEMENT_STANDARD_RTTIEXT(BRepCheck_Edge,BRepCheck_Result)
65
171d8cd9
P
66//modified by NIZNHY-PKV Thu May 05 09:01:57 2011f
67static
68 Standard_Boolean Validate(const Adaptor3d_Curve&,
b7723347 69 const Adaptor3d_CurveOnSurface&,
70 const Standard_Real,
71 const Standard_Boolean);
171d8cd9
P
72static
73 void PrintProblematicPoint(const gp_Pnt&,
b7723347 74 const Standard_Real,
75 const Standard_Real);
171d8cd9
P
76
77static
78 Standard_Real Prec(const Adaptor3d_Curve& aAC3D,
b7723347 79 const Adaptor3d_CurveOnSurface& aACS);
171d8cd9
P
80
81//static Standard_Boolean Validate(const Adaptor3d_Curve&,
82// const Adaptor3d_Curve&,
83// const Standard_Real,
84// const Standard_Boolean);
85//modified by NIZNHY-PKV Thu May 05 09:02:01 2011t
7fd59977 86
52d45841 87static const Standard_Integer NCONTROL=23;
7fd59977 88
89//=======================================================================
90//function : BRepCheck_Edge
91//purpose :
92//=======================================================================
93
94BRepCheck_Edge::BRepCheck_Edge(const TopoDS_Edge& E)
95{
96 Init(E);
97 myGctrl = Standard_True;
98}
99
100//=======================================================================
101//function : Minimum
102//purpose :
103//=======================================================================
104
105void BRepCheck_Edge::Minimum()
106{
107
108 if (!myMin) {
109 BRepCheck_ListOfStatus thelist;
110 myMap.Bind(myShape, thelist);
111 BRepCheck_ListOfStatus& lst = myMap(myShape);
112 myCref.Nullify();
113
114 // Existence et unicite d`une representation 3D
115 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
116 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
117 Standard_Boolean exist = Standard_False;
118 Standard_Boolean unique = Standard_True;
119 // Search for a 3D reference. If no existent one, creates it with the
120 // first encountered CurveOnSurf; if multiple, chooses the first one...
b7723347 121
7fd59977 122 Standard_Boolean Degenerated = TE->Degenerated();
123 Standard_Boolean SameParameter = TE->SameParameter();
124 Standard_Boolean SameRange = TE->SameRange();
125 if (!SameRange && SameParameter) {
126 BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
127 }
b7723347 128 // Handle(Geom_Curve) C3d;
7fd59977 129
130 while (itcr.More()) {
131 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
132 if (cr->IsCurve3D()) {
b7723347 133 if (!exist) {
134 exist = Standard_True;
135 }
136 else {
137 unique = Standard_False;
138 }
139 if (myCref.IsNull() && !cr->Curve3D().IsNull()) {
140 myCref = cr;
141 }
7fd59977 142 }
143 itcr.Next();
144 }
145
146 if (!exist) {
147 BRepCheck::Add(lst,BRepCheck_No3DCurve);
148 // myCref est nulle
149 }
150 else if (!unique) {
151 BRepCheck::Add(lst,BRepCheck_Multiple3DCurve);
152 }
153
154 if (myCref.IsNull() && !Degenerated) {
155 itcr.Initialize(TE->Curves());
156 while (itcr.More()) {
b7723347 157 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
158 if (cr->IsCurveOnSurface()) {
159 myCref = cr;
160 break;
161 }
162 itcr.Next();
7fd59977 163 }
164 }
165 else if (!myCref.IsNull() && Degenerated){
166 BRepCheck::Add(lst,BRepCheck_InvalidDegeneratedFlag);
167 }
168
169 if (!myCref.IsNull()) {
c5f3a425 170 Handle(BRep_GCurve) GCref (Handle(BRep_GCurve)::DownCast (myCref));
4e882c71 171 Standard_Real eps = Precision::PConfusion();
7fd59977 172 Standard_Real First,Last;
173 GCref->Range(First,Last);
174 if (Last<=First) {
b7723347 175 myCref.Nullify();
176 BRepCheck::Add(lst,BRepCheck_InvalidRange);
7fd59977 177 }
178 else {
b7723347 179 if (myCref->IsCurve3D()) {
7fd59977 180 // eap 6 Jun 2002 occ332
181 // better transform C3d instead of transforming Surf upto C3d initial location,
182 // on transformed BSpline surface 'same parameter' may seem wrong
183 TopLoc_Location L = myShape.Location() * myCref->Location();
b7723347 184 Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast
185 (myCref->Curve3D()->Transformed
186 (/*myCref->Location()*/L.Transformation()));
4e882c71 187 Standard_Boolean IsPeriodic = C3d->IsPeriodic();
188 Standard_Real aPeriod = RealLast();
189 if(IsPeriodic)
190 {
191 aPeriod = C3d->Period();
192 }
193 Standard_Real f = C3d->FirstParameter(), l = C3d->LastParameter();
194 if (C3d->DynamicType() == STANDARD_TYPE(Geom_TrimmedCurve))
195 {
196 const Handle(Geom_Curve)& aC = Handle(Geom_TrimmedCurve)::DownCast (C3d)->BasisCurve();
197 f = aC->FirstParameter();
198 l = aC->LastParameter();
199 IsPeriodic = aC->IsPeriodic();
200 if(IsPeriodic)
201 {
202 aPeriod = aC->Period();
203 }
204 }
205 if(IsPeriodic && (Last - First > aPeriod + eps))
206 {
207 myCref.Nullify();
208 BRepCheck::Add(lst,BRepCheck_InvalidRange);
209 }
210 else if(!IsPeriodic && (First < f - eps || Last > l + eps))
211 {
212 myCref.Nullify();
213 BRepCheck::Add(lst,BRepCheck_InvalidRange);
214 }
215 else
216 {
217 GeomAdaptor_Curve GAC3d(C3d, C3d->TransformedParameter(First, L.Transformation()),
b7723347 218 C3d->TransformedParameter(Last, L.Transformation()));
c22b52d6 219 myHCurve = new GeomAdaptor_Curve(GAC3d);
4e882c71 220 }
b7723347 221 }
222 else { // curve on surface
223 Handle(Geom_Surface) Sref = myCref->Surface();
224 Sref = Handle(Geom_Surface)::DownCast
225 (Sref->Transformed(myCref->Location().Transformation()));
226 const Handle(Geom2d_Curve)& PCref = myCref->PCurve();
4e882c71 227 Standard_Boolean IsPeriodic = PCref->IsPeriodic();
228 Standard_Real aPeriod = RealLast();
229 if(IsPeriodic)
230 {
231 aPeriod = PCref->Period();
232 }
233 Standard_Real f = PCref->FirstParameter(), l = PCref->LastParameter();
234 if (PCref->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
235 {
236 const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (PCref)->BasisCurve();
237 f = aC->FirstParameter();
238 l = aC->LastParameter();
239 IsPeriodic = aC->IsPeriodic();
240 if(IsPeriodic)
241 {
242 aPeriod = aC->Period();
243 }
244 }
245 if(IsPeriodic && (Last - First > aPeriod + eps))
246 {
247 myCref.Nullify();
248 BRepCheck::Add(lst,BRepCheck_InvalidRange);
249 }
250 else if(!IsPeriodic && (First < f - eps || Last > l + eps))
251 {
252 myCref.Nullify();
253 BRepCheck::Add(lst,BRepCheck_InvalidRange);
254 }
255 else
256 {
c22b52d6 257 Handle(GeomAdaptor_Surface) GAHSref = new GeomAdaptor_Surface(Sref);
258 Handle(Geom2dAdaptor_Curve) GHPCref =
259 new Geom2dAdaptor_Curve(PCref,First,Last);
4e882c71 260 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
c22b52d6 261 myHCurve = new Adaptor3d_CurveOnSurface(ACSref);
4e882c71 262 }
b7723347 263 }
7fd59977 264 }
265 }
266 if (lst.IsEmpty()) {
267 lst.Append(BRepCheck_NoError);
268 }
269 myMin = Standard_True;
270 }
271}
272
273
274//=======================================================================
275//function : InContext
276//purpose :
277//=======================================================================
278
279void BRepCheck_Edge::InContext(const TopoDS_Shape& S)
280{
281 if (myMap.IsBound(S)) {
282 return;
283 }
284 BRepCheck_ListOfStatus thelist;
285 myMap.Bind(S, thelist);
286 BRepCheck_ListOfStatus& lst = myMap(S);
287
288 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
289 Standard_Real Tol = BRep_Tool::Tolerance(TopoDS::Edge(myShape));
290
291 TopAbs_ShapeEnum styp = S.ShapeType();
b7723347 292 // for (TopExp_Explorer exp(S,TopAbs_EDGE); exp.More(); exp.Next()) {
7fd59977 293 TopExp_Explorer exp(S,TopAbs_EDGE) ;
294 for ( ; exp.More(); exp.Next()) {
295 if (exp.Current().IsSame(myShape)) {
296 break;
297 }
298 }
299 if (!exp.More()) {
300 BRepCheck::Add(lst,BRepCheck_SubshapeNotInShape);
301 return;
302 }
b7723347 303
52d45841 304 switch (styp)
305 {
306 case TopAbs_WIRE:
307 {
308 }
309 break;
310
7fd59977 311 case TopAbs_FACE:
312 if (!myCref.IsNull()) {
b7723347 313
7fd59977 314 Standard_Boolean SameParameter = TE->SameParameter();
315 Standard_Boolean SameRange = TE->SameRange();
b7723347 316 // Modified by skv - Tue Apr 27 11:48:13 2004 Begin
7fd59977 317 if (!SameParameter || !SameRange) {
b7723347 318 if (!SameParameter)
319 BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
320 if (!SameRange)
321 BRepCheck::Add(lst,BRepCheck_InvalidSameRangeFlag);
7fd59977 322
b7723347 323 return;
7fd59977 324 }
b7723347 325 // Modified by skv - Tue Apr 27 11:48:14 2004 End
7fd59977 326 Standard_Real First = myHCurve->FirstParameter();
327 Standard_Real Last = myHCurve->LastParameter();
328
329 Handle(BRep_TFace)& TF = *((Handle(BRep_TFace)*) &S.TShape());
330 const TopLoc_Location& Floc = S.Location();
331 const TopLoc_Location& TFloc = TF->Location();
332 const Handle(Geom_Surface)& Su = TF->Surface();
333 TopLoc_Location L = (Floc * TFloc).Predivided(myShape.Location());
b7723347 334 TopLoc_Location LE = myShape.Location() * myCref->Location();
335 const gp_Trsf& Etrsf = LE.Transformation();
7fd59977 336 Standard_Boolean pcurvefound = Standard_False;
337
338 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
4e882c71 339 Standard_Real eps = Precision::PConfusion();
7fd59977 340 while (itcr.More()) {
b7723347 341 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
342 if (cr != myCref && cr->IsCurveOnSurface(Su,L)) {
343 pcurvefound = Standard_True;
c5f3a425 344 Handle(BRep_GCurve) GC (Handle(BRep_GCurve)::DownCast (cr));
b7723347 345 Standard_Real f,l;
346 GC->Range(f,l);
347 Standard_Real ff = f, ll = l;
348 if(myCref->IsCurve3D())
349 {
350 ff = myCref->Curve3D()->TransformedParameter(f, Etrsf);
351 ll = myCref->Curve3D()->TransformedParameter(l, Etrsf);
352 }
7fd59977 353 // gka OCC
b7723347 354 // Modified by skv - Tue Apr 27 11:50:35 2004 Begin
4e882c71 355 if (Abs(ff-First) > eps ||
356 Abs(ll-Last) > eps) {
b7723347 357 BRepCheck::Add(lst,BRepCheck_InvalidSameRangeFlag);
358 BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
359 }
360 // Modified by skv - Tue Apr 27 11:50:37 2004 End
4e882c71 361 //
362 const Handle(Geom2d_Curve)& pc = cr->PCurve();
363 Standard_Boolean IsPeriodic = pc->IsPeriodic();
364 Standard_Real aPeriod = RealLast();
365 if(IsPeriodic)
366 {
367 aPeriod = pc->Period();
368 }
369 Standard_Real fp = pc->FirstParameter(), lp = pc->LastParameter();
370 if (pc->DynamicType() == STANDARD_TYPE(Geom2d_TrimmedCurve))
371 {
372 const Handle(Geom2d_Curve)& aC = Handle(Geom2d_TrimmedCurve)::DownCast (pc)->BasisCurve();
373 fp = aC->FirstParameter();
374 lp = aC->LastParameter();
375 IsPeriodic = aC->IsPeriodic();
376 if(IsPeriodic)
377 {
378 aPeriod = aC->Period();
379 }
380 }
381 if(IsPeriodic && (l - f > aPeriod + eps))
382 {
383 BRepCheck::Add(lst,BRepCheck_InvalidRange);
384 return;
385 }
386 else if(!IsPeriodic && (f < fp - eps || l > lp + eps))
387 {
388 BRepCheck::Add(lst,BRepCheck_InvalidRange);
389 return;
390 }
391
b7723347 392 if (myGctrl) {
393 Handle(Geom_Surface) Sb = cr->Surface();
394 Sb = Handle(Geom_Surface)::DownCast
395 // (Su->Transformed(L.Transformation()));
396 (Su->Transformed(/*L*/(Floc * TFloc).Transformation()));
397 Handle(Geom2d_Curve) PC = cr->PCurve();
c22b52d6 398 Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(Sb);
399 Handle(Geom2dAdaptor_Curve) GHPC = new Geom2dAdaptor_Curve(PC,f,l);
b7723347 400 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
c22b52d6 401 Standard_Boolean ok = Validate (*myHCurve, ACS, Tol, SameParameter);
b7723347 402 if (!ok) {
403 if (cr->IsCurveOnClosedSurface()) {
404 BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
405 }
406 else {
407 BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
408 }
409 // Modified by skv - Tue Apr 27 11:53:00 2004 Begin
410 BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
411 // if (SameParameter) {
412 // BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
413 // }
414 // Modified by skv - Tue Apr 27 11:53:01 2004 End
415 }
416 if (cr->IsCurveOnClosedSurface()) {
c22b52d6 417 GHPC->Load(cr->PCurve2(),f,l); // same bounds
543a9964 418 ACS.Load(GHPC, GAHS); // sans doute inutile
c22b52d6 419 ok = Validate(*myHCurve,ACS,Tol,SameParameter);
b7723347 420 if (!ok) {
421 BRepCheck::Add(lst,BRepCheck_InvalidCurveOnClosedSurface);
422 // Modified by skv - Tue Apr 27 11:53:20 2004 Begin
423 if (SameParameter) {
424 BRepCheck::Add(lst,BRepCheck_InvalidSameParameterFlag);
425 }
426 // Modified by skv - Tue Apr 27 11:53:23 2004 End
427 }
428 }
429 }
430 }
431 itcr.Next();
7fd59977 432 }
433
434 if (!pcurvefound) {
b7723347 435 Handle(Geom_Plane) P;
436 Handle(Standard_Type) dtyp = Su->DynamicType();
437 if (dtyp == STANDARD_TYPE(Geom_RectangularTrimmedSurface)) {
438 P = Handle(Geom_Plane)::DownCast
439 (Handle(Geom_RectangularTrimmedSurface)::
440 DownCast(Su)->BasisSurface());
441 }
442 else {
443 P = Handle(Geom_Plane)::DownCast(Su);
444 }
445 if (P.IsNull()) { // not a plane
446 BRepCheck::Add(lst,BRepCheck_NoCurveOnSurface);
447 }
448 else { // on fait la projection a la volee, comme BRep_Tool
449 // plan en position
450 if (myGctrl) {
451 P = Handle(Geom_Plane)::
452 DownCast(P->Transformed(/*L*/(Floc * TFloc).Transformation()));// eap occ332
453 //on projette Cref sur ce plan
c22b52d6 454 Handle(GeomAdaptor_Surface) GAHS = new GeomAdaptor_Surface(P);
b7723347 455
c22b52d6 456 // Dub - Normalement myHCurve est une GeomAdaptor_Curve
457 Handle(GeomAdaptor_Curve) Gac = Handle(GeomAdaptor_Curve)::DownCast(myHCurve);
458 Handle(Geom_Curve) C3d = Gac->Curve();
b7723347 459 Handle(Geom_Curve) ProjOnPlane =
460 GeomProjLib::ProjectOnPlane(new Geom_TrimmedCurve(C3d,First,Last),
461 P, P->Position().Direction(),
462 Standard_True);
c22b52d6 463 Handle(GeomAdaptor_Curve) aHCurve =
464 new GeomAdaptor_Curve(ProjOnPlane);
b7723347 465
466 ProjLib_ProjectedCurve proj(GAHS,aHCurve);
467 Handle(Geom2d_Curve) PC = Geom2dAdaptor::MakeCurve(proj);
c22b52d6 468 Handle(Geom2dAdaptor_Curve) GHPC =
469 new Geom2dAdaptor_Curve(PC,
b7723347 470 myHCurve->FirstParameter(),
471 myHCurve->LastParameter());
472
473 Adaptor3d_CurveOnSurface ACS(GHPC,GAHS);
474
c22b52d6 475 Standard_Boolean ok = Validate (*myHCurve, ACS, Tol,Standard_True); // voir dub...
b7723347 476 if (!ok) {
477 BRepCheck::Add(lst,BRepCheck_InvalidCurveOnSurface);
478 }
479 }
480 }
7fd59977 481 }
482 }
483 break;
484 case TopAbs_SOLID:
485 {
486 // on verifie que l`edge est bien connectee 2 fois (pas de bord libre)
487 Standard_Integer nbconnection = 0;
488 //TopExp_Explorer exp;
489 for (exp.Init(S,TopAbs_FACE); exp.More(); exp.Next()) {
b7723347 490 const TopoDS_Face& fac = TopoDS::Face(exp.Current());
491 TopExp_Explorer exp2;
492 for (exp2.Init(fac,TopAbs_EDGE); exp2.More(); exp2.Next()) {
493 if (exp2.Current().IsSame(myShape)) {
494 nbconnection++;
495 }
496 }
7fd59977 497 }
498 if (nbconnection < 2 && !TE->Degenerated()) {
b7723347 499 BRepCheck::Add(myMap(S),BRepCheck_FreeEdge);
7fd59977 500 }
501 else if (nbconnection > 2) {
b7723347 502 BRepCheck::Add(myMap(S),BRepCheck_InvalidMultiConnexity);
7fd59977 503 }
504 else {
b7723347 505 BRepCheck::Add(myMap(S),BRepCheck_NoError);
7fd59977 506 }
507 }
508 break;
509 default:
510 break;
511 }
512 if (myMap(S).IsEmpty()) {
513 myMap(S).Append(BRepCheck_NoError);
514 }
515}
516
517
518//=======================================================================
519//function : Blind
520//purpose :
521//=======================================================================
522
523void BRepCheck_Edge::Blind()
524{
b7723347 525 // Modified by skv - Tue Apr 27 11:36:01 2004 Begin
526 // The body of this function is removed because of its useless.
7fd59977 527 if (!myBlind) {
528 myBlind = Standard_True;
529 }
b7723347 530 // Modified by skv - Tue Apr 27 11:36:02 2004 End
7fd59977 531}
532
533
534//=======================================================================
535//function : GeometricControls
536//purpose :
537//=======================================================================
538
539void BRepCheck_Edge::GeometricControls(const Standard_Boolean B)
540{
541 myGctrl = B;
542}
543
544
545//=======================================================================
546//function : GeometricControls
547//purpose :
548//=======================================================================
549
550Standard_Boolean BRepCheck_Edge::GeometricControls() const
551{
552 return myGctrl;
553}
554
52d45841 555//=======================================================================
556//function : SetStatus
557//purpose :
558//=======================================================================
559void BRepCheck_Edge::SetStatus(const BRepCheck_Status theStatus)
560{
b7723347 561 BRepCheck::Add(myMap(myShape),theStatus);
52d45841 562}
7fd59977 563
564
565//=======================================================================
566//function : Tolerance
567//purpose :
568//=======================================================================
569
570Standard_Real BRepCheck_Edge::Tolerance()
571{
572 Handle(BRep_TEdge)& TE = *((Handle(BRep_TEdge)*)&myShape.TShape());
573 Standard_Integer it, iRep=1, nbRep=(TE->Curves()).Extent();
574 if (nbRep<=1) {
575 return Precision::Confusion();
576 }
577 TColStd_Array1OfTransient theRep(1, nbRep*2);
578 Standard_Real First, Last;
579 if (!myHCurve.IsNull()) {
580 First = myHCurve->FirstParameter();
581 Last= myHCurve->LastParameter();
582 }
583 else {
584 BRep_Tool::Range(TopoDS::Edge(myShape), First, Last);
585 }
586
587 BRep_ListIteratorOfListOfCurveRepresentation itcr(TE->Curves());
588 for (; itcr.More(); itcr.Next()) {
589 const Handle(BRep_CurveRepresentation)& cr = itcr.Value();
590 if (cr->IsCurve3D() && !TE->Degenerated()) {
591 //// modified by jgv, 20.03.03 ////
592 TopLoc_Location Loc = myShape.Location() * cr->Location();
593 Handle(Geom_Curve) C3d = Handle(Geom_Curve)::DownCast
b7723347 594 (cr->Curve3D()->Transformed( Loc.Transformation() ));
7fd59977 595 ///////////////////////////////////
596 GeomAdaptor_Curve GAC3d(C3d,First,Last);
597 it=iRep;
598 if (iRep>1) {
b7723347 599 theRep(iRep)=theRep(1);
600 it=1;
7fd59977 601 }
c22b52d6 602 theRep(it) = new GeomAdaptor_Curve(GAC3d);
7fd59977 603 iRep++;
604 }
605 else if (cr->IsCurveOnSurface()) {
606 {
607 Handle(Geom_Surface) Sref = cr->Surface();
b7723347 608 //// modified by jgv, 20.03.03 ////
609 TopLoc_Location Loc = myShape.Location() * cr->Location();
7fd59977 610 Sref = Handle(Geom_Surface)::DownCast
611 (Sref->Transformed( Loc.Transformation() ));
b7723347 612 ///////////////////////////////////
7fd59977 613 const Handle(Geom2d_Curve)& PCref = cr->PCurve();
c22b52d6 614 Handle(GeomAdaptor_Surface) GAHSref = new GeomAdaptor_Surface(Sref);
615 Handle(Geom2dAdaptor_Curve) GHPCref =
616 new Geom2dAdaptor_Curve(PCref,First,Last);
7fd59977 617 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
c22b52d6 618 theRep(iRep) = new Adaptor3d_CurveOnSurface(ACSref);
7fd59977 619 iRep++;
620 }
621 if (cr->IsCurveOnClosedSurface()) {
b7723347 622 Handle(Geom_Surface) Sref = cr->Surface();
623 Sref = Handle(Geom_Surface)::DownCast
624 (Sref->Transformed(cr->Location().Transformation()));
625 const Handle(Geom2d_Curve)& PCref = cr->PCurve2();
c22b52d6 626 Handle(GeomAdaptor_Surface) GAHSref = new GeomAdaptor_Surface(Sref);
627 Handle(Geom2dAdaptor_Curve) GHPCref =
628 new Geom2dAdaptor_Curve(PCref,First,Last);
b7723347 629 Adaptor3d_CurveOnSurface ACSref(GHPCref,GAHSref);
c22b52d6 630 theRep(iRep) = new Adaptor3d_CurveOnSurface(ACSref);
b7723347 631 iRep++;
632 nbRep++;
7fd59977 633 }
634 }
635 else {
636 nbRep--;
637 }
638 }
639
640 Standard_Real dist2, tol2, tolCal=0., prm;
641 gp_Pnt center, othP;
96a95605 642 Standard_Integer i;
7fd59977 643 for (i= 0; i< NCONTROL; i++) {
644 prm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1);
645 tol2=dist2=0.;
c22b52d6 646 center=(*(Handle(Adaptor3d_Curve)*)&theRep(1))->Value(prm);
f4dee9bb 647 if(Precision::IsInfinite(center.X()) || Precision::IsInfinite(center.Y())
648 || Precision::IsInfinite(center.Z()))
649 {
650 return Precision::Infinite();
651 }
7fd59977 652 for (iRep=2; iRep<=nbRep; iRep++) {
c22b52d6 653 othP=(*(Handle(Adaptor3d_Curve)*)&theRep(iRep))->Value(prm);
f4dee9bb 654 if(Precision::IsInfinite(othP.X()) || Precision::IsInfinite(othP.Y())
655 || Precision::IsInfinite(othP.Z()))
656 {
657 return Precision::Infinite();
658 }
7fd59977 659 dist2=center.SquareDistance(othP);
660 if (dist2>tolCal) tolCal=dist2;
661 }
662 if (tol2>tolCal) {
663 tolCal=tol2;
7fd59977 664 }
665 }
666 // On prend 5% de marge car au dessus on crontrole severement
667 return sqrt(tolCal)*1.05;
668}
171d8cd9 669
52d45841 670
671//=======================================================================
672//function : CheckPolygonOnTriangulation
673//purpose :
674//=======================================================================
675BRepCheck_Status BRepCheck_Edge::
b7723347 676 CheckPolygonOnTriangulation(const TopoDS_Edge& theEdge)
52d45841 677{
678 BRep_ListOfCurveRepresentation& aListOfCR =
b7723347 679 (*((Handle(BRep_TEdge)*) &theEdge.TShape()))->ChangeCurves();
52d45841 680 BRep_ListIteratorOfListOfCurveRepresentation anITCR(aListOfCR);
681
682 BRepAdaptor_Curve aBC;
683 aBC.Initialize(theEdge);
684
685 if(!aBC.Is3DCurve())
686 return BRepCheck_NoError;
687
688 while (anITCR.More())
689 {
690 if(!anITCR.Value()->IsPolygonOnTriangulation())
691 {
692 anITCR.Next();
693 continue;
694 }
695
696 const Handle(BRep_CurveRepresentation) aCR = anITCR.Value();
c5f3a425 697 Handle(BRep_PolygonOnTriangulation) aPT (Handle(BRep_PolygonOnTriangulation)::DownCast(aCR));
52d45841 698
699 const TopLoc_Location aLL = theEdge.Location() * aPT->Location();
a8b605eb 700 const gp_Trsf aTrsf = aLL;
52d45841 701
702 const Handle(Poly_Triangulation) aTriang = aCR->Triangulation();
703 const Handle(Poly_PolygonOnTriangulation) aPOnTriag =
b7723347 704 aCR->IsPolygonOnClosedTriangulation() ?
705 aCR->PolygonOnTriangulation2() :
706 aCR->PolygonOnTriangulation();
52d45841 707 const TColStd_Array1OfInteger& anIndices = aPOnTriag->Nodes();
52d45841 708 const Standard_Integer aNbNodes = anIndices.Length();
709
710 const Standard_Real aTol = aPOnTriag->Deflection() +
b7723347 711 BRep_Tool::Tolerance(theEdge);
52d45841 712
713 if(aPOnTriag->HasParameters())
714 {
715 for(Standard_Integer i = aPOnTriag->Parameters()->Lower();
b7723347 716 i <= aPOnTriag->Parameters()->Upper(); i++)
52d45841 717 {
718 const Standard_Real aParam = aPOnTriag->Parameters()->Value(i);
a8b605eb 719 const gp_Pnt aPE (aBC.Value (aParam));
720 const gp_Pnt aPnt (aTriang->Node (anIndices (i)).Transformed (aTrsf));
52d45841 721
51740958 722 const Standard_Real aSQDist = aPE.SquareDistance(aPnt);
52d45841 723 if(aSQDist > aTol*aTol)
724 {
725 return BRepCheck_InvalidPolygonOnTriangulation;
726 }
727 }
728 }
729 else
730 {
731 //If aPOnTriag does not have any parameters we will check if it
732 //inscribes into Bounding box, which is built on the edge triangulation.
733
734 Bnd_Box aB;
735
736 for (Standard_Integer i = 1; i <= aNbNodes; i++)
737 {
a8b605eb 738 if (aTrsf.Form() == gp_Identity)
739 {
740 aB.Add (aTriang->Node (anIndices(i)));
741 }
52d45841 742 else
a8b605eb 743 {
744 aB.Add (aTriang->Node (anIndices(i)).Transformed(aTrsf));
745 }
52d45841 746 }
747
748 aB.Enlarge(aTol);
749
750 Standard_Real aFP = aBC.FirstParameter();
751 Standard_Real aLP = aBC.LastParameter();
752
753 const Standard_Real aStep = (aLP - aFP)/IntToReal(NCONTROL);
754 gp_Pnt aP;
755 Standard_Real aPar = aFP;
756
757 for(Standard_Integer i = 1; i < NCONTROL; i ++)
758 {
759 aBC.D0(aPar, aP);
760 if(aB.IsOut(aP))
761 {
762 return BRepCheck_InvalidPolygonOnTriangulation;
763 }
764
765 aPar += aStep;
766 }
767
768 aBC.D0(aLP, aP);
769 if(aB.IsOut(aP))
770 {
771 return BRepCheck_InvalidPolygonOnTriangulation;
772 }
773 }
774
775 anITCR.Next();
776 }
777
778 return BRepCheck_NoError;
779}
780
171d8cd9
P
781//=======================================================================
782//function : Validate
783//purpose :
784//=======================================================================
785Standard_Boolean Validate(const Adaptor3d_Curve& CRef,
b7723347 786 const Adaptor3d_CurveOnSurface& Other,
787 const Standard_Real Tol,
788 const Standard_Boolean SameParameter)
171d8cd9
P
789{
790 Standard_Boolean Status, proj;
791 Standard_Real aPC, First, Last, Error;
792 gp_Pnt problematic_point ;
793 //
794 Status = Standard_True;
795 Error = 0.;
796 First = CRef.FirstParameter();
797 Last = CRef.LastParameter();
b7723347 798
171d8cd9
P
799 aPC=Precision::PConfusion();
800 proj = (!SameParameter ||
b7723347 801 Abs(Other.FirstParameter()-First) > aPC ||
802 Abs( Other.LastParameter()-Last) > aPC);
52d45841 803 if (!proj)
804 {
171d8cd9 805 Standard_Integer i;
6e6cd5d9 806 Standard_Real Tol2, prm, dD;
171d8cd9
P
807 gp_Pnt pref, pother;
808 //modified by NIZNHY-PKV Thu May 05 09:06:41 2011f
809 //OCC22428
810 dD=Prec(CRef, Other);//3.e-15;
811 Tol2=Tol+dD;
812 Tol2=Tol2*Tol2;
813 //Tol2=Tol*Tol;
814 //modified by NIZNHY-PKV Thu May 05 09:06:47 2011t
b7723347 815
52d45841 816 for (i = 0; i < NCONTROL; ++i) {
171d8cd9
P
817 prm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1);
818 pref = CRef.Value(prm);
819 pother = Other.Value(prm);
820 if (pref.SquareDistance(pother) > Tol2) {
b7723347 821 problematic_point = pref ;
822 Status = Standard_False;
823 Error = pref.Distance(pother);
824 PrintProblematicPoint(problematic_point, Error, Tol);
825 return Status;
171d8cd9
P
826 //goto FINISH ;
827 }
828 }
829 }
830 else {
831 Extrema_LocateExtPC refd,otherd;
832 Standard_Real OFirst = Other.FirstParameter();
833 Standard_Real OLast = Other.LastParameter();
834 gp_Pnt pd = CRef.Value(First);
835 gp_Pnt pdo = Other.Value(OFirst);
836 Standard_Real distt = pd.SquareDistance(pdo);
837 if (distt > Tol*Tol) {
838 problematic_point = pd ;
839 Status = Standard_False ;
840 Error = Sqrt(distt);
841 PrintProblematicPoint(problematic_point, Error, Tol);
842 return Status;
843 //goto FINISH ;
844 }
845 pd = CRef.Value(Last);
846 pdo = Other.Value(OLast);
847 distt = pd.SquareDistance(pdo);
848 if (distt > Tol*Tol) {
849 problematic_point = pd ;
850 Status = Standard_False ;
851 Error = Sqrt(distt);
852 PrintProblematicPoint(problematic_point, Error, Tol);
853 return Status;
854 //goto FINISH ;
855 }
856
857 refd.Initialize(CRef,First,Last,CRef.Resolution(Tol));
858 otherd.Initialize(Other,OFirst,OLast,Other.Resolution(Tol));
859 for (Standard_Integer i = 2; i< NCONTROL-1; i++) {
860 Standard_Real rprm = ((NCONTROL-1-i)*First + i*Last)/(NCONTROL-1);
861 gp_Pnt pref = CRef.Value(rprm);
862 Standard_Real oprm = ((NCONTROL-1-i)*OFirst + i*OLast)/(NCONTROL-1);
863 gp_Pnt pother = Other.Value(oprm);
864 refd.Perform(pother,rprm);
865 if (!refd.IsDone() || refd.SquareDistance() > Tol * Tol) {
b7723347 866 problematic_point = pref ;
867 Status = Standard_False ;
868 if (refd.IsDone()) {
869 Error = sqrt (refd.SquareDistance());
870 }
871 else {
872 Error = RealLast();
873 }
874 PrintProblematicPoint(problematic_point, Error, Tol);
875 return Status;
171d8cd9
P
876 //goto FINISH ;
877 }
878 otherd.Perform(pref,oprm);
879 if (!otherd.IsDone() || otherd.SquareDistance() > Tol * Tol) {
b7723347 880 problematic_point = pref ;
881 Status = Standard_False ;
882 if (otherd.IsDone()) {
883 Error = sqrt (otherd.SquareDistance());
884 }
885 else {
886 Error = RealLast();
887 }
888 PrintProblematicPoint(problematic_point, Error, Tol);
889 return Status;
890 //goto FINISH ;
171d8cd9
P
891 }
892 }
893 }
171d8cd9
P
894
895 return Status ;
b7723347 896
171d8cd9 897}
e9c073b8 898
171d8cd9
P
899//=======================================================================
900//function : Prec
901//purpose :
902//=======================================================================
903Standard_Real Prec(const Adaptor3d_Curve& aAC3D,
e9c073b8 904 const Adaptor3d_CurveOnSurface& aACS)
171d8cd9
P
905{
906 Standard_Real aXEmax, aXC, aXS;
c22b52d6 907 const Handle(Adaptor3d_Surface)& aAHS = aACS.GetSurface();
171d8cd9 908 //
e9c073b8 909 aXC = BRepCheck::PrecCurve(aAC3D);
910 aXS = BRepCheck::PrecSurface(aAHS);
911 aXEmax = (aXC>aXS) ? aXC: aXS;
171d8cd9
P
912 return aXEmax;
913}
e9c073b8 914
171d8cd9
P
915//=======================================================================
916//function : PrintProblematicPoint
917//purpose :
918//=======================================================================
0797d9d3 919#ifdef OCCT_DEBUG
171d8cd9 920void PrintProblematicPoint(const gp_Pnt& problematic_point,
b7723347 921 const Standard_Real Error,
922 const Standard_Real Tol)
171d8cd9 923{
04232180 924 std::cout << " **** probleme de SameParameter au point :" << std::endl;
925 std::cout << " " << problematic_point.Coord(1) << " "
926 << problematic_point.Coord(2) << " " << problematic_point.Coord(3) << std::endl ;
927 std::cout << " Erreur detectee :" << Error << " Tolerance :" << Tol << std::endl;
171d8cd9
P
928}
929#else
930void PrintProblematicPoint(const gp_Pnt&,
b7723347 931 const Standard_Real,
932 const Standard_Real)
171d8cd9
P
933{
934}
935#endif