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