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