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