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