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