0028053: Regressions in HLR when FPE signals are enabled
[occt.git] / src / Contap / Contap_Contour.cxx
1 // Created on: 1993-02-05
2 // Created by: Jacques GOUSSARD
3 // Copyright (c) 1993-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_HSurface.hxx>
19 #include <Adaptor3d_HSurfaceTool.hxx>
20 #include <Adaptor3d_TopolTool.hxx>
21 #include <Bnd_Box.hxx>
22 #include <BndLib_AddSurface.hxx>
23 #include <Contap_ContAna.hxx>
24 #include <Contap_Contour.hxx>
25 #include <Contap_HContTool.hxx>
26 #include <Contap_HCurve2dTool.hxx>
27 #include <Contap_Line.hxx>
28 #include <Contap_SurfFunction.hxx>
29 #include <Contap_SurfProps.hxx>
30 #include <Contap_TheIWalking.hxx>
31 #include <Contap_ThePathPointOfTheSearch.hxx>
32 #include <Contap_TheSegmentOfTheSearch.hxx>
33 #include <ElCLib.hxx>
34 #include <ElSLib.hxx>
35 #include <gp_Pnt.hxx>
36 #include <gp_Vec.hxx>
37 #include <IntSurf.hxx>
38 #include <IntSurf_InteriorPoint.hxx>
39 #include <IntSurf_SequenceOfPathPoint.hxx>
40 #include <math_FunctionSetRoot.hxx>
41 #include <Standard_ConstructionError.hxx>
42 #include <Standard_OutOfRange.hxx>
43 #include <StdFail_NotDone.hxx>
44 #include <TColStd_Array1OfInteger.hxx>
45 #include <TopTrans_CurveTransition.hxx>
46
47 static const Standard_Real Tolpetit = 1.e-10; // pour dist au carre
48
49 static const Standard_Real tole = 5.e-6;
50
51 Contap_Contour::Contap_Contour () : 
52 done(Standard_False),modeset(Standard_False)
53 {}
54
55 Contap_Contour::Contap_Contour (const gp_Vec& Direction) :
56
57 done(Standard_False),modeset(Standard_True)
58 {
59   mySFunc.Set(Direction);
60   myAFunc.Set(Direction);
61 }
62
63
64 Contap_Contour::Contap_Contour (const gp_Vec& Direction,
65                                 const Standard_Real Angle) :
66
67 done(Standard_False),modeset(Standard_True)
68 {
69   mySFunc.Set(Direction,Angle);
70   myAFunc.Set(Direction,Angle);
71 }
72
73 Contap_Contour::Contap_Contour (const gp_Pnt& Eye) :
74
75 done(Standard_False),modeset(Standard_True)
76 {
77   mySFunc.Set(Eye);
78   myAFunc.Set(Eye);
79 }
80
81
82 Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
83                                 const Handle(Adaptor3d_TopolTool)& Domain,
84                                 const gp_Vec& Direction) :
85
86 done(Standard_False),modeset(Standard_True)
87 {
88   Perform(Surf,Domain,Direction);
89 }
90
91
92 Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
93                                 const Handle(Adaptor3d_TopolTool)& Domain,
94                                 const gp_Vec& Direction,
95                                 const Standard_Real Angle) :
96
97 done(Standard_False),modeset(Standard_True)
98 {
99   Perform(Surf,Domain,Direction,Angle);
100 }
101
102
103 Contap_Contour::Contap_Contour (const Handle(Adaptor3d_HSurface)& Surf,
104                                 const Handle(Adaptor3d_TopolTool)& Domain,
105                                 const gp_Pnt& Eye) :
106
107 done(Standard_False),modeset(Standard_True)
108 {
109   Perform(Surf,Domain,Eye);
110 }
111
112
113 void Contap_Contour::Init (const gp_Vec& Direction)
114
115 {
116   done = Standard_False;
117   modeset = Standard_True;
118   mySFunc.Set(Direction);
119   myAFunc.Set(Direction);
120 }
121
122
123 void Contap_Contour::Init(const gp_Vec& Direction,
124                           const Standard_Real Angle)
125 {
126   done = Standard_False;
127   modeset = Standard_True;
128   mySFunc.Set(Direction,Angle);
129   myAFunc.Set(Direction,Angle);
130 }
131
132 void Contap_Contour::Init (const gp_Pnt& Eye)
133 {
134   done = Standard_False;
135   modeset = Standard_True;
136   mySFunc.Set(Eye);
137   myAFunc.Set(Eye);
138 }
139
140
141 void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
142                               const Handle(Adaptor3d_TopolTool)& Domain)
143 {
144   if (!modeset) {Standard_ConstructionError::Raise();}
145   mySFunc.Set(Surf);
146   myAFunc.Set(Surf);
147
148   GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
149   switch (typS) {
150   case GeomAbs_Plane:
151   case GeomAbs_Sphere:
152   case GeomAbs_Cylinder:
153   case GeomAbs_Cone:
154     {
155       PerformAna(Domain); //Surf,Domain,Direction,0.,gp_Pnt(0.,0.,0.),1);
156     }
157     break;
158
159   default:
160     {
161       Perform(Domain); //Surf,Domain,Direction,0.,gp_Pnt(0.,0.,0.),1);
162     }
163     break;
164   }
165
166 }
167
168
169 void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
170                               const Handle(Adaptor3d_TopolTool)& Domain,
171                               const gp_Vec& Direction)
172
173 {
174   Init(Direction);
175   Perform(Surf,Domain);
176 }
177
178 void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
179                               const Handle(Adaptor3d_TopolTool)& Domain,
180                               const gp_Vec& Direction,
181                               const Standard_Real Angle)
182
183 {
184   Init(Direction,Angle);
185   Perform(Surf,Domain);
186 }
187
188
189 void Contap_Contour::Perform (const Handle(Adaptor3d_HSurface)& Surf,
190                               const Handle(Adaptor3d_TopolTool)& Domain,
191                               const gp_Pnt& Eye)
192
193 {
194   Init(Eye);
195   Perform(Surf,Domain);
196 }
197
198 static  IntSurf_TypeTrans ComputeTransitionOnLine
199 (Contap_SurfFunction&,
200  const Standard_Real,
201  const Standard_Real,
202  const gp_Vec&);
203
204
205 static IntSurf_TypeTrans ComputeTransitionOngpCircle
206 (Contap_SurfFunction&,
207  const gp_Circ&);
208
209
210 static IntSurf_TypeTrans ComputeTransitionOngpLine
211 (Contap_SurfFunction&,
212  const gp_Lin&);
213
214
215 static void ComputeInternalPoints
216 (Contap_Line& Line,
217  Contap_SurfFunction&,
218  const Standard_Real ureso,
219  const Standard_Real vreso);
220
221
222 static void ComputeInternalPointsOnRstr
223 (Contap_Line&,
224  const Standard_Real,
225  const Standard_Real,
226  Contap_SurfFunction&);
227
228 static void ProcessSegments (const Contap_TheSearch&,
229                              Contap_TheSequenceOfLine&,
230                              const Standard_Real,
231                              Contap_SurfFunction&,
232                              const Handle(Adaptor3d_TopolTool)&);
233
234 //-- --------------------------------------------------------------------------------
235 //-- Recherche des portions utiles sur les lignes 
236
237
238 static void Recadre(const Handle(Adaptor3d_HSurface)& myHS1,
239                     Standard_Real& u1,
240                     Standard_Real& v1) { 
241                       Standard_Real f,l,lmf;
242                       GeomAbs_SurfaceType typs1 = myHS1->GetType();
243
244                       Standard_Boolean myHS1IsUPeriodic,myHS1IsVPeriodic;
245                       switch (typs1) { 
246   case GeomAbs_Cylinder:
247   case GeomAbs_Cone:
248   case GeomAbs_Sphere: 
249     { 
250       myHS1IsUPeriodic = Standard_True;
251       myHS1IsVPeriodic = Standard_False;
252       break;
253     }
254   case GeomAbs_Torus:
255     {
256       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_True;
257       break;
258     }
259   default:
260     {
261       myHS1IsUPeriodic = myHS1IsVPeriodic = Standard_False;
262       break;
263     }
264                       }
265                       if(myHS1IsUPeriodic) {
266                         lmf = M_PI+M_PI; //-- myHS1->UPeriod();
267                         f = myHS1->FirstUParameter();
268                         l = myHS1->LastUParameter();
269                         while(u1 < f) { u1+=lmf; } 
270                         while(u1 > l) { u1-=lmf; }
271                       }
272                       if(myHS1IsVPeriodic) {
273                         lmf = M_PI+M_PI; //-- myHS1->VPeriod(); 
274                         f = myHS1->FirstVParameter();
275                         l = myHS1->LastVParameter();
276                         while(v1 < f) { v1+=lmf; } 
277                         while(v1 > l) { v1-=lmf; }
278                       }
279 }
280
281
282 static void LineConstructor(Contap_TheSequenceOfLine& slin,
283                             const Handle(Adaptor3d_TopolTool)& Domain,
284                             Contap_Line& L,
285                             const Handle(Adaptor3d_HSurface)& Surf) { 
286
287                               //-- ------------------------------------------------------------
288                               //-- on decoupe la ligne en portions  entre 2 vertex 
289                               Standard_Real Tol = Precision::PConfusion();
290                               Contap_IType typl = L.TypeContour();
291                               //-- cout<<"\n ----------- Ligne Constructor "<<endl;
292                               if(typl == Contap_Walking) { 
293                                 Standard_Real u1,v1,u2,v2;
294                                 Standard_Integer nbvtx = L.NbVertex();
295                                 //-- cout<<" WLine -> "<<nbvtx<<" vtx"<<endl;
296                                 for(Standard_Integer i=1;i<nbvtx;i++) { 
297                                   Standard_Integer firstp = (Standard_Integer) L.Vertex(i).ParameterOnLine();
298                                   Standard_Integer lastp =  (Standard_Integer) L.Vertex(i+1).ParameterOnLine();
299                                   if(firstp!=lastp) {  
300                                     Standard_Integer pmid = (firstp+lastp)/2; //-- entiers
301                                     const IntSurf_PntOn2S& Pmid = L.Point(pmid);
302                                     Pmid.Parameters(u1,v1,u2,v2);
303                                     Recadre(Surf,u2,v2);
304                                     TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
305                                     if(in2 == TopAbs_OUT) { 
306                                     }
307                                     else { 
308                                       //-- cout<<"ContapWLine      : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
309                                       Handle(IntSurf_LineOn2S) LineOn2S = new IntSurf_LineOn2S();
310                                       Contap_Line Line;
311                                       Standard_Real aLen = 0.;
312                                       for(Standard_Integer j=firstp; j<=lastp; j++) { 
313                                         LineOn2S->Add(L.Point(j));
314                                         if (j > firstp)
315                                           aLen += L.Point(j).Value().Distance(L.Point(j - 1).Value());
316                                       }
317                                       if (aLen < Precision::Confusion())
318                                         continue;
319                                       Line.SetLineOn2S(LineOn2S);
320                                       Contap_Point pvtx = L.Vertex(i);
321                                       pvtx.SetParameter(1);
322                                       Line.Add(pvtx);
323
324                                       pvtx = L.Vertex(i+1);
325                                       pvtx.SetParameter(lastp-firstp+1);
326                                       Line.Add(pvtx);
327                                       Line.SetTransitionOnS(L.TransitionOnS());
328                                       slin.Append(Line);
329                                     }
330                                   }
331                                 }
332                               }
333                               else if(typl==Contap_Lin) { 
334                                 Standard_Real u2,v2;// u1,v1;
335                                 Standard_Integer nbvtx = L.NbVertex();
336                                 //-- cout<<" Lin -> "<<nbvtx<<" vtx"<<endl;
337                                 for(Standard_Integer i=1;i<nbvtx;i++) { 
338                                   Standard_Real firstp = L.Vertex(i).ParameterOnLine();
339                                   Standard_Real lastp =  L.Vertex(i+1).ParameterOnLine();
340                                   if(firstp!=lastp) {  
341                                     Standard_Real pmid = (firstp+lastp)*0.5;
342                                     gp_Pnt Pmid =  ElCLib::Value(pmid,L.Line());
343                                     if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) { 
344                                       ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
345                                     }
346                                     else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) { 
347                                       ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
348                                     }
349                                     else { 
350                                       //-- cout<<" Pb ds Contap_ContourGen_2.gxx (type)"<<endl;
351                                     }
352
353                                     Recadre(Surf,u2,v2);
354                                     TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
355                                     if(in2 == TopAbs_OUT) { 
356                                     }
357                                     else { 
358                                       //-- cout<<"Contap Lin      : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
359                                       Contap_Line Line;
360                                       Line.SetValue(L.Line());
361                                       Contap_Point pvtx = L.Vertex(i);
362                                       Line.Add(pvtx);
363
364                                       pvtx = L.Vertex(i+1);
365                                       Line.Add(pvtx);
366                                       Line.SetTransitionOnS(L.TransitionOnS());
367                                       slin.Append(Line);
368                                     }
369                                   }
370                                 }
371                               }
372                               else if(typl==Contap_Circle) { 
373                                 Standard_Real u2,v2; //u1,v1,
374                                 Standard_Integer nbvtx = L.NbVertex();
375                                 //-- cout<<" Circ -> "<<nbvtx<<" vtx"<<endl;
376                                 Standard_Boolean novtx = Standard_True;
377                                 if(nbvtx) novtx=Standard_False;
378                                 for(Standard_Integer i=1;i<nbvtx  || novtx;i++) { 
379                                   Standard_Real firstp=0,lastp=M_PI+M_PI;
380                                   if(novtx == Standard_False) { 
381                                     firstp = L.Vertex(i).ParameterOnLine();
382                                     lastp =  L.Vertex(i+1).ParameterOnLine();
383                                   }
384                                   if(Abs(firstp-lastp)>0.000000001) {  
385                                     Standard_Real pmid = (firstp+lastp)*0.5;
386                                     gp_Pnt Pmid =  ElCLib::Value(pmid,L.Circle());
387                                     if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) { 
388                                       ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
389                                     }
390                                     else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) { 
391                                       ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
392                                     }
393                                     else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Sphere) { 
394                                       ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),Pmid,u2,v2);
395                                     }
396                                     else { 
397                                       //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
398                                     }
399
400                                     Recadre(Surf,u2,v2);
401                                     TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
402                                     if(in2 == TopAbs_OUT) { 
403                                     }
404                                     else { 
405                                       //-- cout<<"Contap Circle     : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
406                                       Contap_Line Line;
407                                       Line.SetValue(L.Circle());
408                                       if(novtx == Standard_False) { 
409                                         Contap_Point pvtx = L.Vertex(i);
410                                         Line.Add(pvtx);
411                                         pvtx = L.Vertex(i+1);
412                                         Line.Add(pvtx);
413                                       }
414                                       Line.SetTransitionOnS(L.TransitionOnS());
415                                       slin.Append(Line);
416                                     }
417                                   }
418                                   novtx = Standard_False;
419                                 }
420                                 if(nbvtx)  {
421                                   Standard_Real firstp = L.Vertex(nbvtx).ParameterOnLine();
422                                   Standard_Real lastp =  L.Vertex(1).ParameterOnLine() + M_PI+M_PI;
423                                   if(Abs(firstp-lastp)>0.0000000001) {  
424                                     Standard_Real pmid = (firstp+lastp)*0.5;
425                                     gp_Pnt Pmid =  ElCLib::Value(pmid,L.Circle());
426                                     if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cylinder) { 
427                                       ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),Pmid,u2,v2);
428                                     }
429                                     else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Cone) { 
430                                       ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),Pmid,u2,v2);
431                                     }
432                                     else if(Adaptor3d_HSurfaceTool::GetType(Surf)==GeomAbs_Sphere) { 
433                                       ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),Pmid,u2,v2);
434                                     }
435                                     else { 
436                                       //-- cout<<" Pb ds Contap_ContourGen_2.gxx (typep)"<<endl;
437                                     }
438
439                                     Recadre(Surf,u2,v2);
440                                     TopAbs_State in2 = Domain->Classify(gp_Pnt2d(u2,v2),Tol);
441                                     if(in2 == TopAbs_OUT) { 
442                                     }
443                                     else { 
444                                       //-- cout<<"Contap Circle  *Compl* : firtsp="<<firstp<<" lastp="<<lastp<<" Vtx:"<<i<<","<<i+1<<endl;
445                                       Contap_Line Line;
446                                       Line.SetValue(L.Circle());
447                                       Contap_Point pvtx = L.Vertex(nbvtx);
448                                       Line.Add(pvtx);
449
450                                       pvtx = L.Vertex(1);  pvtx.SetParameter(pvtx.ParameterOnLine()+M_PI+M_PI);
451                                       Line.Add(pvtx);
452                                       Line.SetTransitionOnS(L.TransitionOnS());
453                                       slin.Append(Line);
454                                     }
455                                   }      
456                                 }
457                               }
458                               else { 
459                                 //-- cout<<" ni WLine ni Lin ni Circ "<<endl;
460                                 slin.Append(L);
461                               }
462                               //-- 
463 }
464
465 //-- --------------------------------------------------------------------------------
466
467
468
469 static void KeepInsidePoints(const Contap_TheSearchInside& solins,
470                              const Contap_TheSearch& solrst,
471                              Contap_SurfFunction& Func,
472                              IntSurf_SequenceOfInteriorPoint& seqpins)
473
474 {
475   Standard_Integer Nba = solrst.NbSegments();
476   Standard_Integer Nbp,indp,inda;
477   Standard_Real U,V,paramproj;
478   gp_Pnt2d toproj,Ptproj;
479   Standard_Boolean projok,tokeep;
480   const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
481
482   Nbp = solins.NbPoints();
483   for (indp=1; indp <= Nbp; indp++) {
484     tokeep = Standard_True;
485     const IntSurf_InteriorPoint& pti = solins.Value(indp);
486     pti.Parameters(U,V);
487     toproj = gp_Pnt2d(U,V);
488     for (inda = 1; inda <= Nba; inda++) {
489       const Handle(Adaptor2d_HCurve2d)& thearc = solrst.Segment(inda).Curve();
490       projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
491       if (projok) {
492         gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptproj.X(),Ptproj.Y());
493         if (pti.Value().Distance(pprojete) <= Precision::Confusion()) {
494           tokeep = Standard_False;
495           break;
496         }
497       }
498     }
499     if (tokeep) {
500       seqpins.Append(pti);
501     }
502   }
503 }
504
505
506 static void ComputeTangency (const Contap_TheSearch& solrst,
507                              const Handle(Adaptor3d_TopolTool)& Domain,
508                              Contap_SurfFunction& Func,
509                              IntSurf_SequenceOfPathPoint& seqpdep,
510                              TColStd_Array1OfInteger& Destination)
511 {
512
513   Standard_Integer i,k;
514   Standard_Integer NbPoints = solrst.NbPoints();
515   Standard_Integer seqlength = 0;
516
517   Standard_Real theparam,test;
518   Standard_Boolean fairpt;
519   TopAbs_Orientation arcorien,vtxorien;
520   Standard_Boolean ispassing;
521
522   math_Vector X(1, 2);
523   math_Vector F(1, 1);
524   math_Matrix D(1, 1, 1, 2); 
525
526   gp_Vec   normale, vectg, tg3drst,v1,v2;
527   gp_Dir2d dirtg;
528   gp_Vec2d tg2drst;
529   gp_Pnt2d pt2d;
530
531   IntSurf_PathPoint PPoint;
532   const Handle(Adaptor3d_HSurface)& Surf = Func.Surface();
533
534   for (i=1; i<= NbPoints; i++) {
535
536     if (Destination(i) == 0) {
537
538       const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
539       const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
540       theparam = PStart.Parameter();
541       gp_Pnt2d Ptoproj=Contap_HCurve2dTool::Value(thearc,theparam);
542       //-- lbr le 15 mai 97 
543       //-- On elimine les points qui sont egalement present sur une restriction solution
544       Standard_Boolean SurUneRestrictionSolution = Standard_False;
545       for(Standard_Integer restriction=1;
546         SurUneRestrictionSolution==Standard_False && restriction<=solrst.NbSegments(); 
547         restriction++) { 
548           const Handle(Adaptor2d_HCurve2d)& thearcsol = solrst.Segment(restriction).Curve();
549           Standard_Real  paramproj;
550           gp_Pnt2d       pproj;
551           Standard_Boolean projok = Contap_HContTool::Project(thearcsol,Ptoproj,paramproj,pproj);
552           if(projok) { 
553             //gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,Ptoproj.X(),Ptoproj.Y());
554             //IFV - begin
555             gp_Pnt pprojete = Adaptor3d_HSurfaceTool::Value(Surf,pproj.X(),pproj.Y());
556             //IFV - end
557             if ((PStart.Value()).Distance(pprojete) <= Precision::Confusion()) {
558               SurUneRestrictionSolution = Standard_True;
559             }
560           }
561       }
562       if(SurUneRestrictionSolution == Standard_False) { 
563         arcorien = Domain->Orientation(thearc);
564         ispassing = (arcorien == TopAbs_INTERNAL ||
565           arcorien == TopAbs_EXTERNAL);
566
567         Contap_HCurve2dTool::D1(thearc,theparam,pt2d,tg2drst);
568         X(1) = pt2d.X();
569         X(2) = pt2d.Y();
570         PPoint.SetValue(PStart.Value(),X(1),X(2));
571
572         Func.Values(X,F,D);
573         if (Func.IsTangent()) {
574           PPoint.SetTangency(Standard_True);
575           Destination(i) = seqlength+1;
576           if (!PStart.IsNew()) {
577             const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
578             for (k=i+1; k<=NbPoints; k++) {
579               if (Destination(k) ==0) {
580                 const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
581                 if (!PStart2.IsNew()) {
582                   const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
583                   if (Domain->Identical(vtx,vtx2)) {
584                     const Handle(Adaptor2d_HCurve2d)& thearc2   = PStart2.Arc();
585                     theparam = PStart2.Parameter();
586                     arcorien = Domain->Orientation(thearc2);
587                     ispassing = ispassing && (arcorien == TopAbs_INTERNAL ||
588                       arcorien == TopAbs_EXTERNAL);
589
590                     pt2d = Contap_HCurve2dTool::Value(thearc2,theparam);
591                     X(1) = pt2d.X();
592                     X(2) = pt2d.Y();
593                     PPoint.AddUV(X(1),X(2));
594                     Destination(k) = seqlength+1;
595                   }
596                 }
597               }
598             }
599           }
600           PPoint.SetPassing(ispassing);
601           seqpdep.Append(PPoint);
602           seqlength++;
603         }
604         else { // on a un point de depart potentiel
605
606           vectg = Func.Direction3d();
607           dirtg = Func.Direction2d();
608
609           gp_Pnt ptbid;
610           //    Adaptor3d_HSurfaceTool::D1(Surf,X(1),X(2),ptbid,v1,v2);
611           Contap_SurfProps::DerivAndNorm(Surf,X(1),X(2),ptbid,v1,v2,normale);
612           tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
613           //    normale = v1.Crossed(v2);
614           if(normale.SquareMagnitude() < RealEpsilon()) { 
615             //-- cout<<"\n*** Contap_ContourGen_2.gxx  Normale Nulle en U:"<<X(1)<<" V:"<<X(2)<<endl;
616           }
617           else { 
618             test = vectg.Dot(normale.Crossed(tg3drst));
619
620             if (PStart.IsNew()) {
621               Standard_Real tbis = vectg.Normalized().Dot(tg3drst.Normalized());
622               if (Abs(tbis) < 1.-tole) {
623
624                 if ((test < 0. && arcorien == TopAbs_FORWARD) ||
625                   (test > 0. && arcorien == TopAbs_REVERSED)) {
626                     vectg.Reverse();
627                     dirtg.Reverse();
628                 }
629                 PPoint.SetDirections(vectg,dirtg);
630               }
631               else { // on garde le point comme point d`arret (tangent)
632                 PPoint.SetTangency(Standard_True);
633               }
634               PPoint.SetPassing(ispassing);
635               Destination(i) = seqlength+1;
636               seqpdep.Append(PPoint);
637               seqlength++;
638             }
639             else { // traiter la transition complexe
640               gp_Dir bidnorm(1.,1.,1.);
641
642               Standard_Boolean tobeverified = Standard_False;
643               TopAbs_Orientation LocTrans;
644               TopTrans_CurveTransition comptrans;
645               comptrans.Reset(vectg,bidnorm,0.);
646               if (arcorien != TopAbs_INTERNAL &&
647                 arcorien != TopAbs_EXTERNAL) {
648                   // pour essai
649                   const Handle(Adaptor3d_HVertex)& vtx = PStart.Vertex();
650                   vtxorien = Domain->Orientation(vtx);
651                   test = test/(vectg.Magnitude());
652                   test = test/((normale.Crossed(tg3drst)).Magnitude());
653
654                   if (Abs(test) <= tole) {
655                     tobeverified = Standard_True;
656                     LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
657                   }
658                   else {
659                     if ((test > 0. && arcorien == TopAbs_FORWARD) ||
660                       (test < 0. && arcorien == TopAbs_REVERSED)){
661                         LocTrans = TopAbs_FORWARD;
662                     }
663                     else {
664                       LocTrans = TopAbs_REVERSED;
665                     }
666                     if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} // pas deja fait ???
667                   }
668
669                   comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
670               }
671               Destination(i) = seqlength+1;
672               for (k= i+1; k<=NbPoints; k++) {
673                 if (Destination(k) == 0) {
674                   const Contap_ThePathPointOfTheSearch& PStart2 = solrst.Point(k);
675                   if (!PStart2.IsNew()) {
676                     const Handle(Adaptor3d_HVertex)& vtx2 = PStart2.Vertex();
677                     if (Domain->Identical(PStart.Vertex(),vtx2)) {
678                       const Handle(Adaptor2d_HCurve2d)& thearc2 = PStart2.Arc();
679                       theparam = PStart2.Parameter();
680                       arcorien = Domain->Orientation(thearc2);
681
682                       Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
683                       X(1) = pt2d.X();
684                       X(2) = pt2d.Y();
685                       PPoint.AddUV(X(1),X(2));
686
687                       if (arcorien != TopAbs_INTERNAL &&
688                         arcorien != TopAbs_EXTERNAL) {
689                           ispassing = Standard_False;
690                           tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
691                           test = vectg.Dot(normale.Crossed(tg3drst));
692                           test = test/(vectg.Magnitude());
693                           test = test /((normale.Crossed(tg3drst)).Magnitude());
694
695                           vtxorien = Domain->Orientation(vtx2);
696                           if (Abs(test) <= tole) {
697                             tobeverified = Standard_True;
698                             LocTrans = TopAbs_EXTERNAL; // et pourquoi pas INTERNAL
699                           }
700                           else {
701                             if ((test > 0. && arcorien == TopAbs_FORWARD) ||
702                               (test < 0. && arcorien == TopAbs_REVERSED)){
703                                 LocTrans = TopAbs_FORWARD;
704                             }
705                             else {
706                               LocTrans = TopAbs_REVERSED;
707                             }
708                             if (arcorien == TopAbs_REVERSED) {tg3drst.Reverse();} //deja fait????
709                           }
710
711                           comptrans.Compare(tole,tg3drst,bidnorm,0.,LocTrans,vtxorien);
712                       }
713                       Destination(k) = seqlength+1;
714                     }
715                   }
716                 }
717               }
718               fairpt = Standard_True;
719               if (!ispassing) {
720                 TopAbs_State Before = comptrans.StateBefore();
721                 TopAbs_State After  = comptrans.StateAfter();
722                 if ((Before == TopAbs_UNKNOWN)||(After == TopAbs_UNKNOWN)) {
723                   fairpt = Standard_False;
724                 }
725                 else if (Before == TopAbs_IN) {
726                   if (After == TopAbs_IN) {
727                     ispassing = Standard_True;
728                   }
729                   else {
730                     vectg.Reverse();
731                     dirtg.Reverse();
732                   }
733                 }
734                 else {
735                   if (After !=TopAbs_IN) {
736                     fairpt = Standard_False;
737                   }
738                 }
739               }
740
741               // evite de partir le long d une restriction solution
742
743               if (fairpt && tobeverified) {
744                 for (k=i; k <=NbPoints ; k++) {
745                   if (Destination(k)==seqlength + 1) {
746                     theparam = solrst.Point(k).Parameter();
747                     const Handle(Adaptor2d_HCurve2d)& thearc2 = solrst.Point(k).Arc();
748                     arcorien = Domain->Orientation(thearc2);
749
750                     if (arcorien == TopAbs_FORWARD ||
751                       arcorien == TopAbs_REVERSED) {
752                         Contap_HCurve2dTool::D1(thearc2,theparam,pt2d,tg2drst);
753                         tg3drst = tg2drst.X()*v1 + tg2drst.Y()*v2;
754                         vtxorien = Domain->Orientation(solrst.Point(k).Vertex());
755                         if ((arcorien == TopAbs_FORWARD && 
756                           vtxorien == TopAbs_REVERSED)    ||
757                           (arcorien == TopAbs_REVERSED &&
758                           vtxorien == TopAbs_FORWARD)) {
759                             tg3drst.Reverse();
760                         }
761                         test = vectg.Normalized().Dot(tg3drst.Normalized());
762                         if (test >= 1. - tole) {
763                           fairpt = Standard_False;
764                           break;
765                         }
766                     }
767                   }
768                 }
769               }
770
771               if (fairpt) {
772                 PPoint.SetDirections(vectg,dirtg);
773                 PPoint.SetPassing(ispassing);
774                 seqpdep.Append(PPoint);
775                 seqlength++;
776               }
777               else { // il faut remettre en "ordre" si on ne garde pas le point.
778                 for (k=i; k <=NbPoints ; k++) {
779                   if (Destination(k)==seqlength + 1) {
780                     Destination(k) = -Destination(k);
781                   }
782                 }
783               }
784             }
785           }
786         }
787       }
788     }
789   }
790 }
791
792
793 IntSurf_TypeTrans ComputeTransitionOnLine(Contap_SurfFunction& SFunc,
794                                           const Standard_Real u,
795                                           const Standard_Real v,
796                                           const gp_Vec& tgline)
797 {
798   gp_Vec d1u,d1v;
799   gp_Pnt pntbid;
800   //gp_Vec tglineuv;
801
802   Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),u,v,pntbid,d1u,d1v);
803
804   //------------------------------------------------------
805   //--   Calcul de la tangente dans l espace uv        ---
806   //------------------------------------------------------
807
808   Standard_Real det,d1uT,d1vT,normu2,normv2,d1ud1v,alpha,beta;
809   d1uT = d1u.Dot(tgline);
810   d1vT = d1v.Dot(tgline);
811   normu2 = d1u.Dot(d1u);
812   normv2 = d1v.Dot(d1v);
813   d1ud1v = d1u.Dot(d1v);
814   det = normu2 * normv2 - d1ud1v * d1ud1v;
815   if(det<RealEpsilon()) { 
816     //-- On ne doit pas passer ici !!
817     //-- cout<<" Probleme !!!"<<endl ;
818     return IntSurf_Undecided;
819   }
820
821   alpha = (d1uT * normv2 - d1vT * d1ud1v)/det;
822   beta  = (normu2 * d1vT - d1ud1v * d1uT)/det;
823   //-----------------------------------------------------
824   //--  Calcul du Gradient de la fonction Utilisee     --
825   //--  pour le contour apparent                       --
826   //-----------------------------------------------------
827
828   Standard_Real v1,v2;
829   math_Vector X(1,2);
830   math_Matrix Df(1,1,1,2);
831   X(1) = u;
832   X(2) = v;
833   SFunc.Derivatives(X,Df);
834   v1 = Df(1,1);
835   v2 = Df(1,2);
836
837   //-----------------------------------------------------
838   //-- On calcule si la fonction                       --
839   //--        F(.) = Normale . Dir_Regard              --
840   //-- Croit Losrque l on se deplace sur la Gauche     --
841   //--  de la direction de deplacement sur la ligne.   --
842   //-----------------------------------------------------
843
844   det = -v1*beta + v2*alpha;
845
846   if(det<RealEpsilon()) { // revoir le test jag 940620
847     return IntSurf_Undecided;
848   }
849   if(det>0.0) { 
850     return(IntSurf_Out);
851   }
852   return(IntSurf_In);
853 }
854
855
856 void ProcessSegments (const Contap_TheSearch& solrst,
857                       Contap_TheSequenceOfLine& slin,
858                       const Standard_Real TolArc,
859                       Contap_SurfFunction& SFunc,
860                       const Handle(Adaptor3d_TopolTool)& Domain)
861
862 {     
863   Standard_Integer i,j,k;
864   Standard_Integer nbedg = solrst.NbSegments();
865   Standard_Integer Nblines,Nbpts;
866
867   Handle(Adaptor2d_HCurve2d) arcRef;
868   Contap_Point ptvtx;
869
870   Contap_ThePathPointOfTheSearch PStartf,PStartl;
871
872   Standard_Boolean dofirst,dolast,procf,procl;
873   Standard_Real paramf =0.,paraml =0.,U;
874   Contap_Line theline;
875
876   gp_Vec tgline;//,norm1,norm2;
877   gp_Pnt valpt;
878
879   gp_Vec d1u,d1v;
880   gp_Pnt2d p2d;
881   gp_Vec2d d2d;
882
883
884   for (i = 1; i <= nbedg; i++) {
885
886     const Contap_TheSegmentOfTheSearch& thesegsol = solrst.Segment(i);
887     theline.SetValue(thesegsol.Curve());
888
889     // Traitement des points debut/fin du segment solution.
890
891     dofirst = Standard_False;
892     dolast  = Standard_False;
893     procf = Standard_False;
894     procl = Standard_False;
895
896     if (thesegsol.HasFirstPoint()) {
897       dofirst = Standard_True;
898       PStartf = thesegsol.FirstPoint();
899       paramf = PStartf.Parameter();
900     }
901     if (thesegsol.HasLastPoint()) {
902       dolast = Standard_True;
903       PStartl = thesegsol.LastPoint();
904       paraml = PStartl.Parameter();
905     }
906
907     // determination de la transition
908     if (dofirst && dolast) {
909       U = (paramf+paraml)/2.;
910     }
911     else if (dofirst) {
912       U = paramf + 1.0;
913     }
914     else if (dolast) {
915       U = paraml - 1.0;
916     }
917     else {
918       U = 0.0;
919     }
920
921     Contap_HCurve2dTool::D1(thesegsol.Curve(),U,p2d,d2d);
922     Adaptor3d_HSurfaceTool::D1(SFunc.Surface(),p2d.X(),p2d.Y(),valpt,d1u,d1v);
923     tgline.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
924     IntSurf_TypeTrans  tral = 
925       ComputeTransitionOnLine(SFunc,p2d.X(),p2d.Y(),tgline);
926
927     theline.SetTransitionOnS(tral);
928
929
930     if (dofirst || dolast) {
931       Nblines = slin.Length();
932       for (j=1; j<=Nblines; j++) {
933         Nbpts = slin(j).NbVertex();
934         for (k=1; k<=Nbpts;k++) {
935           ptvtx = slin(j).Vertex(k);
936           if (dofirst) {
937             if (ptvtx.Value().Distance(PStartf.Value()) <=TolArc) {
938               slin(j).Vertex(k).SetMultiple();
939               ptvtx.SetMultiple();
940               ptvtx.SetParameter(paramf);
941               theline.Add(ptvtx);
942               procf=Standard_True;
943             }
944           }
945           if (dolast) {
946             if (ptvtx.Value().Distance(PStartl.Value()) <=TolArc) {
947               slin(j).Vertex(k).SetMultiple();
948               ptvtx.SetMultiple();
949               ptvtx.SetParameter(paraml);
950               theline.Add(ptvtx);
951               procl=Standard_True;
952             }
953           }
954         }
955         // Si on a traite le pt debut et/ou fin, on ne doit pas recommencer si
956         // il (ils) correspond(ent) a un point multiple.
957
958         if (procf) {
959           dofirst = Standard_False;
960         }
961         if (procl) {
962           dolast  = Standard_False;
963         }
964       }
965     }
966
967     // Si on n a pas trouve le point debut et./ou fin sur une des lignes
968     // d intersection, il faut quand-meme le placer sur la restriction solution
969
970     if (dofirst) {
971
972       p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paramf);
973       ptvtx.SetValue(PStartf.Value(),p2d.X(),p2d.Y());
974       ptvtx.SetParameter(paramf);
975       if (! PStartf.IsNew()) {
976         ptvtx.SetVertex(PStartf.Vertex());
977       }
978       theline.Add(ptvtx);
979     }
980     if (dolast) {
981       p2d = Contap_HCurve2dTool::Value(thesegsol.Curve(),paraml);
982       ptvtx.SetValue(PStartl.Value(),p2d.X(),p2d.Y());
983       ptvtx.SetParameter(paraml);
984       if (! PStartl.IsNew()) {
985         ptvtx.SetVertex(PStartl.Vertex());
986       }
987       theline.Add(ptvtx);
988     }
989
990     // il faut chercher le points internal sur les restrictions solutions.
991     if (thesegsol.HasFirstPoint() && thesegsol.HasLastPoint()) {
992       ComputeInternalPointsOnRstr(theline,paramf,paraml,SFunc);
993     }
994     LineConstructor(slin,Domain,theline,SFunc.Surface()); //-- lbr 
995     //-- slin.Append(theline);
996     theline.Clear();
997   }
998 }
999
1000 void ComputeInternalPointsOnRstr
1001 (Contap_Line& Line,
1002  const Standard_Real Paramf,
1003  const Standard_Real Paraml,
1004  Contap_SurfFunction& SFunc)
1005 {
1006   // On recherche les points ou la tangente a la ligne de contour et
1007   // la direction sont alignees.
1008   // 1ere etape : recherche de changement de signe.
1009   // 2eme etape : localisation de la solution par dichotomie
1010
1011
1012   Standard_Integer indexinf,indexsup,i;
1013   gp_Vec tgt, vecref, vectest, vtestb, vecregard,d1u,d1v;
1014   gp_Pnt pcour;
1015   gp_Pnt2d p2d;
1016   gp_Vec2d d2d;
1017   Standard_Boolean found,ok = Standard_False,toutvu,solution;
1018   Standard_Real paramp = 0.,paraminf,paramsup,toler;
1019
1020   if (Line.TypeContour() != Contap_Restriction) {
1021     return;
1022   }
1023
1024   const Handle(Adaptor2d_HCurve2d)& thearc = Line.Arc();
1025
1026   const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1027   Contap_TFunction TypeFunc(SFunc.FunctionType());
1028
1029   Standard_Integer Nbpnts = Contap_HContTool::NbSamplesOnArc(thearc);
1030   indexinf = 1;
1031   vecregard = SFunc.Direction();
1032   toler = Contap_HCurve2dTool::Resolution(thearc,Precision::Confusion());
1033   found = Standard_False;
1034
1035   do {
1036     paraminf = ((Nbpnts-indexinf)*Paramf + (indexinf-1)*Paraml)/(Nbpnts-1);
1037     Contap_HCurve2dTool::D1(thearc,paraminf,p2d,d2d);
1038     Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1039     tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1040
1041     if (tgt.Magnitude() > gp::Resolution()) {
1042       if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1043         vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1044       }
1045       vecref = vecregard.Crossed(tgt);
1046
1047       if (vecref.Magnitude() <= gp::Resolution()) {
1048         indexinf++;
1049       }
1050       else {
1051         found = Standard_True;
1052       }
1053     }
1054     else {
1055       indexinf++;
1056     }
1057   } while ((indexinf <= Nbpnts) && (!found));
1058
1059
1060   indexsup = indexinf +1;
1061   toutvu = (indexsup > Nbpnts);
1062   while (!toutvu) {
1063     paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1064     Contap_HCurve2dTool::D1(thearc,paramsup,p2d,d2d);
1065     Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1066     tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1067
1068     if (tgt.Magnitude() > gp::Resolution()) {
1069       if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1070         vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1071       }
1072       vectest = vecregard.Crossed(tgt);
1073     }
1074     else {
1075       vectest = gp_Vec(0.,0.,0.);
1076     }
1077     if (vectest.Magnitude() <= gp::Resolution()) {
1078       // On cherche un vrai changement de signe
1079       indexsup++;
1080     }
1081     else {
1082       if (vectest.Dot(vecref) < 0.) {
1083         // Essayer de converger
1084         // cout << "Changement de signe detecte" << endl;
1085         solution = Standard_False;
1086         while (!solution) {
1087           paramp = (paraminf+paramsup)/2.;
1088           Contap_HCurve2dTool::D1(thearc,paramp,p2d,d2d);
1089           Adaptor3d_HSurfaceTool::D1(Surf,p2d.X(),p2d.Y(),pcour,d1u,d1v);
1090           tgt.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1091
1092           if (tgt.Magnitude() > gp::Resolution()) {
1093             if (TypeFunc == Contap_ContourPrs || TypeFunc==Contap_DraftPrs) {
1094               vecregard.SetXYZ(pcour.XYZ()-SFunc.Eye().XYZ());
1095             }
1096             vtestb = vecregard.Crossed(tgt);
1097           }
1098           else {
1099             vtestb = gp_Vec(0.,0.,0.);
1100           }
1101
1102           if ((vtestb.Magnitude() <= gp::Resolution())||
1103             (Abs(paramp-paraminf) <= toler) ||
1104             (Abs(paramp-paramsup) <= toler)) {
1105               // on est a la solution
1106               solution = Standard_True;
1107               ok = Standard_True;
1108           }
1109           else if (vtestb.Dot(vecref) < 0.) {
1110             paramsup = paramp;
1111           }
1112           else {
1113             paraminf = paramp;
1114           }
1115
1116         }
1117
1118         if (ok) {
1119           // On verifie que le point trouve ne correspond pas a un ou des
1120           // vertex deja existant(s). On teste sur le parametre paramp.
1121           for (i=1; i<=Line.NbVertex(); i++) {
1122             Contap_Point& thevtx = Line.Vertex(i);
1123             if (Abs(thevtx.ParameterOnLine()-paramp) <= toler) {
1124               thevtx.SetInternal();
1125               ok = Standard_False; // on a correspondance
1126             }
1127           }
1128           if (ok) { // il faut alors rajouter le point
1129             Contap_Point internalp(pcour,p2d.X(),p2d.Y());
1130             internalp.SetParameter(paramp);
1131             internalp.SetInternal();
1132             Line.Add(internalp);
1133           }
1134         }
1135         paramsup = ((Nbpnts-indexsup)*Paramf + (indexsup-1)*Paraml)/(Nbpnts-1);
1136       }
1137       vecref = vectest;
1138       indexinf = indexsup;
1139       indexsup++;
1140       paraminf = paramsup;
1141     }
1142     toutvu = (indexsup > Nbpnts);
1143   }
1144 }
1145
1146
1147 void ComputeInternalPoints
1148 (Contap_Line& Line,
1149  Contap_SurfFunction& SFunc,
1150  const Standard_Real ureso,
1151  const Standard_Real vreso)
1152
1153 {
1154   // On recherche les points ou la tangente a la ligne de contour et
1155   // la direction sont alignees.
1156   // 1ere etape : recheche de changement de signe.
1157   // 2eme etape : localisation de la solution par simili dichotomie
1158
1159
1160   Standard_Integer indexinf,indexsup,index;
1161   gp_Vec tgt, vecref, vectest, vtestb, vecregard;
1162   //gp_Pnt pprec,pcour;
1163   Standard_Boolean found,ok = Standard_False,toutvu,solution;
1164   Standard_Real paramp = 0.,U,V;
1165
1166   math_Vector XInf(1,2),XSup(1,2),X(1,2),F(1,1);
1167   math_Matrix DF(1,1,1,2);
1168   math_Vector toler(1,2),infb(1,2),supb(1,2);
1169
1170   if (Line.TypeContour() != Contap_Walking) {
1171     return;
1172   }
1173
1174   Standard_Integer Nbpnts = Line.NbPnts();
1175   const Handle(Adaptor3d_HSurface)& Surf = SFunc.Surface();
1176   Contap_TFunction TypeFunc(SFunc.FunctionType());
1177
1178   toler(1) = ureso; //-- Trop long !!! Adaptor3d_HSurfaceTool::UResolution(Surf,SFunc.Tolerance());
1179   toler(2) = vreso; //---Beaucoup trop long !!! Adaptor3d_HSurfaceTool::VResolution(Surf,SFunc.Tolerance());
1180   infb(1) = Adaptor3d_HSurfaceTool::FirstUParameter(Surf);
1181   infb(2) = Adaptor3d_HSurfaceTool::FirstVParameter(Surf);
1182   supb(1) = Adaptor3d_HSurfaceTool::LastUParameter(Surf);
1183   supb(2) = Adaptor3d_HSurfaceTool::LastVParameter(Surf);
1184
1185   math_FunctionSetRoot rsnld(SFunc,toler,30);
1186
1187   indexinf = 1;
1188   vecregard = SFunc.Direction();
1189
1190   found = Standard_False;
1191   do {
1192     Line.Point(indexinf).ParametersOnS2(XInf(1),XInf(2));
1193     SFunc.Values(XInf,F,DF);
1194     if (!SFunc.IsTangent()) {
1195       tgt = SFunc.Direction3d();
1196       if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1197         vecregard.SetXYZ(Line.Point(indexinf).Value().XYZ()-SFunc.Eye().XYZ());
1198       }
1199       vecref = vecregard.Crossed(tgt);
1200
1201       if (vecref.Magnitude() <= gp::Resolution()) {
1202         indexinf++;
1203       }
1204       else {
1205         found = Standard_True;
1206       }
1207     }
1208     else {
1209       indexinf++;
1210     }
1211   } while ((indexinf <= Nbpnts) && (!found));
1212
1213
1214   indexsup = indexinf +1;
1215   toutvu = (indexsup > Nbpnts);
1216   while (!toutvu) {
1217     Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1218     SFunc.Values(XSup,F,DF);
1219     if (!SFunc.IsTangent()) {
1220       tgt = SFunc.Direction3d();
1221
1222       if (TypeFunc == Contap_ContourPrs || TypeFunc == Contap_DraftPrs) {
1223         vecregard.SetXYZ(Line.Point(indexsup).Value().XYZ()-SFunc.Eye().XYZ());
1224       }
1225       vectest = vecregard.Crossed(tgt);
1226     }
1227     else {
1228       vectest = gp_Vec(0.,0.,0.);
1229     }
1230     if (vectest.Magnitude() <= gp::Resolution()) {
1231       // On cherche un vrai changement de signe
1232       indexsup++;
1233     }
1234     else {
1235       if (vectest.Dot(vecref) < 0.) {
1236         // Essayer de converger
1237         // cout << "Changement de signe detecte" << endl;
1238         solution = Standard_False;
1239         while (!solution) {
1240           X(1) = (XInf(1) + XSup(1)) /2.;
1241           X(2) = (XInf(2) + XSup(2)) /2.;
1242           rsnld.Perform(SFunc,X,infb,supb);
1243
1244           if (!rsnld.IsDone()) {
1245             cout << "Echec recherche internal points" << endl;
1246             solution = Standard_True;
1247             ok = Standard_False;
1248           }
1249           else {
1250
1251             rsnld.Root(X);
1252             SFunc.Values(X,F,DF);
1253             if (Abs(F(1)) <= SFunc.Tolerance()) {
1254
1255               if (!SFunc.IsTangent()) {
1256                 tgt = SFunc.Direction3d();
1257                 if (TypeFunc == Contap_ContourPrs || 
1258                   TypeFunc == Contap_DraftPrs) {
1259                     vecregard.SetXYZ(SFunc.Point().XYZ()-SFunc.Eye().XYZ());
1260                 }
1261                 vtestb = vecregard.Crossed(tgt);
1262               }
1263               else {
1264                 vtestb = gp_Vec(0.,0.,0.);
1265               }
1266               if ((vtestb.Magnitude() <= gp::Resolution())||
1267                 (Abs(X(1)-XInf(1)) <= toler(1) 
1268                 && Abs(X(2)-XInf(2)) <= toler(2)) ||
1269                 (Abs(X(1)-XSup(1)) <= toler(1)
1270                 && Abs(X(2)-XSup(2)) <= toler(2))) {
1271                   // on est a la solution
1272                   solution = Standard_True;
1273                   ok = Standard_True;
1274               }
1275               else if (vtestb.Dot(vecref) < 0.) {
1276                 XSup = X;
1277               }
1278               else {
1279                 XInf = X;
1280               }
1281             }
1282             else { // on n est pas sur une solution
1283               cout << "Echec recherche internal points" << endl;
1284               solution = Standard_True;
1285               ok = Standard_False;
1286             }
1287           }
1288         }
1289
1290         if (ok) {
1291           Standard_Boolean newpoint = Standard_False;
1292           Line.Point(indexinf).ParametersOnS2(U,V);
1293           gp_Vec2d vinf(X(1)-U,X(2)-V);
1294           if (Abs(vinf.X()) <= toler(1) && Abs(vinf.Y()) <= toler(2)) {
1295             paramp = indexinf;
1296           }
1297           else {
1298             for (index = indexinf+1; index <= indexsup; index++) {
1299               Line.Point(index).ParametersOnS2(U,V);
1300               gp_Vec2d vsup(X(1)-U,X(2)-V);
1301               if (Abs(vsup.X()) <= toler(1) && Abs(vsup.Y()) <= toler(2)) {
1302                 paramp = index;
1303                 break;
1304               }
1305               else if (vinf.Dot(vsup) < 0.) {
1306                 // on est entre les 2 points
1307                 paramp = index;
1308                 IntSurf_PntOn2S pt2s;
1309                 pt2s.SetValue(SFunc.Point(),Standard_False,X(1),X(2));
1310                 Line.LineOn2S()->InsertBefore(index,pt2s);
1311
1312                 //-- Il faut decaler les parametres des vertex situes entre 
1313                 //-- index et NbPnts ###################################
1314                 for(Standard_Integer v=1; v<=Line.NbVertex(); v++) { 
1315                   Contap_Point& Vertex = Line.Vertex(v);
1316                   if(Vertex.ParameterOnLine() >= index) { 
1317                     Vertex.SetParameter(Vertex.ParameterOnLine()+1); 
1318                   }
1319                 }
1320
1321                 Nbpnts = Nbpnts+1;
1322                 indexsup = indexsup+1;
1323                 newpoint = Standard_True;
1324                 break;
1325               }
1326               else {
1327                 vinf = vsup;
1328               }
1329             }
1330           }
1331
1332           Standard_Integer v;
1333           if (!newpoint) {
1334             // on est sur un point de cheminement. On regarde alors
1335             // la correspondance avec un vertex existant.
1336             newpoint = Standard_True;
1337             for (v=1; v<= Line.NbVertex(); v++) {
1338               Contap_Point& Vertex = Line.Vertex(v);
1339               if(Vertex.ParameterOnLine() == paramp) {
1340                 Vertex.SetInternal();
1341                 newpoint = Standard_False;
1342               }
1343             }
1344           }
1345
1346           if (newpoint && paramp >1. && paramp < Nbpnts) {
1347             // on doit creer un nouveau vertex.
1348             Contap_Point internalp(SFunc.Point(),X(1),X(2));
1349             internalp.SetParameter(paramp);
1350             internalp.SetInternal();
1351             Line.Add(internalp);
1352           }
1353         }
1354         Line.Point(indexsup).ParametersOnS2(XSup(1),XSup(2));
1355       }
1356       vecref = vectest;
1357       indexinf = indexsup;
1358       indexsup++;
1359       XInf = XSup;
1360     }
1361     toutvu = (indexsup > Nbpnts);
1362   }
1363 }
1364
1365
1366 void Contap_Contour::Perform 
1367 (const Handle(Adaptor3d_TopolTool)& Domain) {
1368
1369   done = Standard_False;
1370   slin.Clear();
1371
1372   Standard_Integer i,j,k,Nbvt1,Nbvt2,ivt1,ivt2;
1373   Standard_Integer NbPointRst,NbPointIns;
1374   Standard_Integer Nblines, Nbpts, indfirst, indlast;
1375   Standard_Real U,V;
1376   gp_Pnt2d pt2d;
1377   gp_Vec2d d2d;
1378   gp_Pnt ptonsurf;
1379   gp_Vec d1u,d1v,normale,tgtrst,tgline;
1380   Standard_Real currentparam;
1381   IntSurf_Transition TLine,TArc;
1382
1383   Contap_Line theline;
1384   Contap_Point ptdeb,ptfin;
1385   Contap_ThePathPointOfTheSearch PStartf,PStartl;
1386
1387   //  Standard_Real TolArc = 1.e-5;
1388   Standard_Real TolArc = Precision::Confusion();
1389
1390   const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1391
1392   Standard_Real EpsU = Adaptor3d_HSurfaceTool::UResolution(Surf,Precision::Confusion());
1393   Standard_Real EpsV = Adaptor3d_HSurfaceTool::VResolution(Surf,Precision::Confusion());
1394   Standard_Real Preci  = Min(EpsU,EpsV);
1395   //  Standard_Real Fleche = 5.e-1;
1396   //  Standard_Real Pas    = 5.e-2;
1397   Standard_Real Fleche = 0.01;
1398   Standard_Real Pas    = 0.005; 
1399   //   lbr: Il y avait Pas 0.2 -> Manque des Inters sur restr ; devrait faire un mini de 5 pts par lignes
1400   //-- le 23 janvier 98 0.05 -> 0.01
1401
1402
1403   //-- ******************************************************************************** Janvier 98
1404   Bnd_Box B1; Standard_Boolean Box1OK = Standard_True;
1405
1406   Standard_Real Uinf = Surf->FirstUParameter(); 
1407   Standard_Real Vinf = Surf->FirstVParameter();
1408   Standard_Real Usup = Surf->LastUParameter();
1409   Standard_Real Vsup = Surf->LastVParameter();
1410
1411   Standard_Boolean Uinfinfinite = Precision::IsNegativeInfinite(Uinf);
1412   Standard_Boolean Usupinfinite = Precision::IsPositiveInfinite(Usup);
1413   Standard_Boolean Vinfinfinite = Precision::IsNegativeInfinite(Vinf);
1414   Standard_Boolean Vsupinfinite = Precision::IsPositiveInfinite(Vsup);
1415
1416   if( Uinfinfinite || Usupinfinite || Vinfinfinite || Vsupinfinite) { 
1417     Box1OK = Standard_False;
1418   }
1419   else { 
1420     BndLib_AddSurface::Add(Surf->Surface(),1e-8,B1);
1421   }
1422   Standard_Real x0,y0,z0,x1,y1,z1,dx,dy,dz;
1423   if(Box1OK) { 
1424     B1.Get(x0,y0,z0,x1,y1,z1);
1425     dx=x1-x0;
1426     dy=y1-y0;
1427     dz=z1-z0;
1428   } 
1429   else { 
1430     dx=dy=dz=1.0;
1431   }
1432   if(dx<dy) dx=dy;
1433   if(dx<dz) dx=dz;
1434   if(dx>10000.0) dx=10000.0;
1435   Fleche*=dx;
1436   TolArc*=dx;
1437   //-- ********************************************************************************
1438
1439
1440   //gp_Pnt valpt;
1441
1442   //jag 940616  SFunc.Set(1.e-8); // tolerance sur la fonction
1443   mySFunc.Set(Precision::Confusion()); // tolerance sur la fonction
1444
1445   Standard_Boolean RecheckOnRegularity = Standard_True;
1446   solrst.Perform(myAFunc,Domain,TolArc,TolArc,RecheckOnRegularity);
1447
1448   if (!solrst.IsDone()) {
1449     return;
1450   }
1451
1452   NbPointRst = solrst.NbPoints();
1453   IntSurf_SequenceOfPathPoint seqpdep;
1454   TColStd_Array1OfInteger Destination(1,NbPointRst+1);
1455   Destination.Init(0);
1456   if (NbPointRst != 0) {
1457     ComputeTangency(solrst,Domain,mySFunc,seqpdep,Destination);
1458   }
1459
1460   //jag 940616  solins.Perform(SFunc,Surf,Domain,1.e-6); // 1.e-6 : tolerance dans l espace.
1461   solins.Perform(mySFunc,Surf,Domain,Precision::Confusion());
1462
1463   NbPointIns = solins.NbPoints();
1464   IntSurf_SequenceOfInteriorPoint seqpins;
1465
1466   if (NbPointIns != 0) {
1467     Standard_Boolean bKeepAllPoints = Standard_False;
1468     //IFV begin
1469     if(solrst.NbSegments() <= 0) {
1470       if(mySFunc.FunctionType() == Contap_ContourStd) {
1471         const Handle(Adaptor3d_HSurface)& SurfToCheck = mySFunc.Surface();
1472         if(Adaptor3d_HSurfaceTool::GetType(SurfToCheck) == GeomAbs_Torus) {
1473           gp_Torus aTor = Adaptor3d_HSurfaceTool::Torus(SurfToCheck);
1474           gp_Dir aTorDir = aTor.Axis().Direction();
1475           gp_Dir aProjDir = mySFunc.Direction();
1476
1477           if(aTorDir.Dot(aProjDir) < Precision::Confusion()) {
1478             bKeepAllPoints = Standard_True;
1479           }
1480         }
1481       }
1482     }
1483
1484     if(bKeepAllPoints) {
1485       Standard_Integer Nbp = solins.NbPoints(), indp;
1486       for (indp=1; indp <= Nbp; indp++) {
1487         const IntSurf_InteriorPoint& pti = solins.Value(indp);
1488         seqpins.Append(pti);
1489       }
1490     }
1491     //IFV - end
1492     else {
1493       KeepInsidePoints(solins,solrst,mySFunc,seqpins);
1494     }
1495   }
1496
1497   if (seqpdep.Length() != 0 || seqpins.Length() != 0) {
1498
1499     Standard_Boolean theToFillHoles = Standard_True;
1500     Contap_TheIWalking iwalk(Preci,Fleche,Pas,theToFillHoles);
1501     iwalk.Perform(seqpdep,seqpins,mySFunc ,Surf);
1502     if(!iwalk.IsDone()) {
1503       return;
1504     }
1505
1506     Nblines = iwalk.NbLines();
1507     for (j=1; j<=Nblines; j++) {
1508       IntSurf_TypeTrans TypeTransOnS = IntSurf_Undecided;
1509       const Handle(Contap_TheIWLineOfTheIWalking)& iwline = iwalk.Value(j);
1510       Nbpts = iwline->NbPoints();
1511       theline.SetLineOn2S(iwline->Line());
1512
1513       // jag 941018 On calcule une seule fois la transition
1514
1515       tgline = iwline->TangentVector(k);
1516       iwline->Line()->Value(k).ParametersOnS2(U,V); 
1517       TypeTransOnS = ComputeTransitionOnLine(mySFunc,U,V,tgline);
1518       theline.SetTransitionOnS(TypeTransOnS);
1519
1520       //---------------------------------------------------------------------
1521       //-- On ajoute a la liste des vertex les 1er et dernier points de la  -
1522       //-- ligne de cheminement si ceux-ci ne sont pas presents             -
1523       //---------------------------------------------------------------------
1524
1525       if (iwline->HasFirstPoint()) {
1526         indfirst = iwline->FirstPointIndex();
1527         const IntSurf_PathPoint& PPoint = seqpdep(indfirst);
1528         Standard_Integer themult = PPoint.Multiplicity();
1529         for (i=NbPointRst; i>=1; i--) {
1530           if (Destination(i) == indfirst) {
1531             PPoint.Parameters(themult,U,V);
1532             ptdeb.SetValue(PPoint.Value(),U,V);
1533             ptdeb.SetParameter(1.0);
1534
1535             const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1536             const Handle(Adaptor2d_HCurve2d)& currentarc = PStart.Arc();
1537             currentparam = PStart.Parameter();
1538             if (!iwline->IsTangentAtBegining()) {
1539
1540               Contap_HCurve2dTool::D1(currentarc,currentparam,pt2d,d2d);
1541               Contap_SurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1542                 ptonsurf,d1u,d1v,normale);
1543               tgtrst = d2d.X()*d1u;
1544               tgtrst.Add(d2d.Y()*d1v);
1545
1546               IntSurf::MakeTransition(PPoint.Direction3d(),tgtrst,normale,
1547                 TLine,TArc);
1548
1549             }
1550             else {// a voir. En effet, on a cheminer. Si on est sur un point 
1551               // debut, on sait qu'on rentre dans la matiere
1552               TLine.SetValue();
1553               TArc.SetValue();
1554             }
1555
1556             ptdeb.SetArc(currentarc,currentparam,TLine,TArc);
1557
1558             if (!solrst.Point(i).IsNew()) {
1559               ptdeb.SetVertex(PStart.Vertex());
1560             }
1561             theline.Add(ptdeb);
1562             themult--;
1563           }
1564         }
1565       }
1566       else { 
1567         iwline->Value(1).ParametersOnS2(U,V);
1568         ptdeb.SetValue(theline.Point(1).Value(),U,V);
1569         ptdeb.SetParameter(1.0);
1570         theline.Add(ptdeb);
1571       }
1572
1573       if (iwline->HasLastPoint()) {
1574         indlast = iwline->LastPointIndex();
1575         const IntSurf_PathPoint& PPoint = seqpdep(indlast);
1576         Standard_Integer themult = PPoint.Multiplicity();
1577         for (i=NbPointRst; i>=1; i--) {
1578           if (Destination(i) == indlast) {
1579             PPoint.Parameters(themult,U,V);
1580             ptfin.SetValue(PPoint.Value(),U,V);
1581             ptfin.SetParameter((Standard_Real)(Nbpts));
1582             const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1583             const Handle(Adaptor2d_HCurve2d)& currentarc = PStart.Arc();
1584             currentparam = PStart.Parameter();
1585
1586             if (!iwline->IsTangentAtEnd()) {
1587
1588               Contap_HCurve2dTool::D1(currentarc,currentparam,pt2d,d2d);
1589
1590               Contap_SurfProps::DerivAndNorm(Surf,pt2d.X(),pt2d.Y(),
1591                 ptonsurf,d1u,d1v,normale);
1592               tgtrst = d2d.X()*d1u;
1593               tgtrst.Add(d2d.Y()*d1v);
1594               IntSurf::MakeTransition(PPoint.Direction3d().Reversed(),
1595                 tgtrst,normale,TLine,TArc);
1596             }
1597             else {
1598               TLine.SetValue();
1599               TArc.SetValue();
1600             }
1601
1602             ptfin.SetArc(currentarc,currentparam,TLine,TArc);
1603
1604             if (!solrst.Point(i).IsNew()) {
1605               ptfin.SetVertex(PStart.Vertex());
1606             }
1607             theline.Add(ptfin);
1608             themult--;
1609           }
1610         }
1611       }
1612       else { 
1613         iwline->Value(Nbpts).ParametersOnS2(U,V);
1614         ptfin.SetValue(theline.Point(Nbpts).Value(),U,V);
1615         ptfin.SetParameter((Standard_Real)(Nbpts));
1616         theline.Add(ptfin);
1617       }
1618
1619       ComputeInternalPoints(theline,mySFunc,EpsU,EpsV);
1620       LineConstructor(slin,Domain,theline,Surf); //-- lbr
1621       //-- slin.Append(theline);
1622       theline.ResetSeqOfVertex();
1623     }
1624
1625
1626     Nblines = slin.Length();
1627     for (j=1; j<=Nblines-1; j++) {
1628       const Contap_Line& theli = slin(j);
1629       Nbvt1 = theli.NbVertex();
1630       for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1631         if (!theli.Vertex(ivt1).IsOnArc()) {
1632           const gp_Pnt& pttg1 = theli.Vertex(ivt1).Value();
1633
1634           for (k=j+1; k<=Nblines;k++) {
1635             const Contap_Line& theli2 = slin(k);
1636             Nbvt2 = theli2.NbVertex();
1637             for (ivt2=1; ivt2<=Nbvt2; ivt2++) {
1638               if (!theli2.Vertex(ivt2).IsOnArc()) {
1639                 const gp_Pnt& pttg2 = theli2.Vertex(ivt2).Value();
1640
1641                 if (pttg1.Distance(pttg2) <= TolArc) {
1642                   theli.Vertex(ivt1).SetMultiple();
1643                   theli2.Vertex(ivt2).SetMultiple();
1644                 }
1645               }
1646             }
1647           }
1648         }
1649       }
1650     }
1651   }
1652
1653   // jag 940620 On ajoute le traitement des restrictions solutions.
1654
1655   if (solrst.NbSegments() !=0) {
1656     ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
1657   }
1658
1659
1660   // Ajout crad pour depanner CMA en attendant mieux
1661   if (solrst.NbSegments() !=0) {
1662
1663     Nblines = slin.Length();
1664     for (j=1; j<=Nblines; j++) {
1665       const Contap_Line& theli = slin(j);
1666       if (theli.TypeContour() == Contap_Walking) {
1667         Nbvt1 = theli.NbVertex();
1668         for (ivt1=1; ivt1<=Nbvt1; ivt1++) {
1669           Contap_Point& ptvt = theli.Vertex(ivt1);
1670           if (!ptvt.IsOnArc() && !ptvt.IsMultiple()) {
1671             Standard_Real Up,Vp;
1672             ptvt.Parameters(Up,Vp);
1673             gp_Pnt2d toproj(Up,Vp);
1674             Standard_Boolean projok;
1675             for (k=1; k<=Nblines;k++) {
1676               if (slin(k).TypeContour() == Contap_Restriction) {
1677                 const Handle(Adaptor2d_HCurve2d)& thearc = slin(k).Arc();
1678                 Standard_Real paramproj;
1679                 gp_Pnt2d Ptproj;
1680                 projok = Contap_HContTool::Project(thearc,toproj,paramproj,Ptproj);
1681
1682                 if (projok) {
1683                   Standard_Real dist = Ptproj.Distance(gp_Pnt2d(Up,Vp));
1684                   if (dist <= Preci) {
1685                     // Calcul de la transition
1686
1687                     Contap_HCurve2dTool::D1(thearc,paramproj,Ptproj,d2d);
1688                     //              Adaptor3d_HSurfaceTool::D1(Surf,Ptproj.X(),Ptproj.Y(),
1689                     //                                 ptonsurf,d1u,d1v);
1690                     //              normale = d1u.Crossed(d1v);
1691
1692                     Contap_SurfProps::DerivAndNorm
1693                       (Surf,Ptproj.X(),Ptproj.Y(),ptonsurf,d1u,d1v,normale);
1694
1695                     tgtrst = d2d.X()*d1u;
1696                     tgtrst.Add(d2d.Y()*d1v);
1697                     Standard_Integer Paraml =
1698                       (Standard_Integer) ptvt.ParameterOnLine();
1699
1700                     if (Paraml == theli.NbPnts()) {
1701                       tgline = gp_Vec(theli.Point(Paraml-1).Value(),
1702                         ptvt.Value());
1703                     }
1704                     else {
1705                       tgline = gp_Vec(ptvt.Value(),
1706                         theli.Point(Paraml+1).Value());
1707                     }
1708                     IntSurf::MakeTransition(tgline,tgtrst,normale,
1709                       TLine,TArc);
1710                     ptvt.SetArc(thearc,paramproj,TLine,TArc);
1711                     ptvt.SetMultiple();
1712                     ptdeb.SetValue(ptonsurf,Ptproj.X(),Ptproj.Y());
1713                     ptdeb.SetParameter(paramproj);
1714                     ptdeb.SetMultiple();
1715                     slin(k).Add(ptdeb);
1716                     break;
1717                   }
1718                   else {
1719                     projok = Standard_False;
1720                   }
1721                 }
1722               }
1723               else {
1724                 projok = Standard_False;
1725               }
1726               if (projok) {
1727                 break;
1728               }
1729             }
1730           }
1731         }
1732       }
1733     }
1734   }
1735   done = Standard_True;
1736 }
1737
1738 static Standard_Boolean FindLine(Contap_Line& Line,
1739                                  const Handle(Adaptor3d_HSurface)& Surf,
1740                                  const gp_Pnt2d& Pt2d,
1741                                  gp_Pnt& Ptref,
1742                                  Standard_Real& Paramin,
1743                                  gp_Vec& Tgmin,
1744                                  gp_Vec& Norm)
1745 {
1746   //  Standard_Integer i;
1747   gp_Pnt pt,ptmin;
1748   gp_Vec tg;
1749   Standard_Real para,dist;
1750   Standard_Real dismin = RealLast();
1751
1752   Contap_SurfProps::Normale(Surf,Pt2d.X(),Pt2d.Y(),Ptref,Norm);
1753
1754   if (Line.TypeContour() == Contap_Lin) {
1755     gp_Lin lin(Line.Line());
1756     para = ElCLib::Parameter(lin,Ptref);
1757     ElCLib::D1(para,lin,pt,tg);
1758     dist = pt.Distance(Ptref) + Abs(Norm.Dot(lin.Direction()));
1759   }
1760   else { // Contap__Circle
1761     gp_Circ cir(Line.Circle());
1762     para = ElCLib::Parameter(cir,Ptref);
1763     ElCLib::D1(para,cir,pt,tg);
1764     dist = pt.Distance(Ptref)+Abs(Norm.Dot(tg/cir.Radius()));
1765   }
1766   if (dist < dismin) {
1767     dismin = dist;
1768     Paramin = para;
1769     ptmin = pt;
1770     Tgmin = tg;
1771   }
1772   if (ptmin.SquareDistance(Ptref) <= Tolpetit) {
1773     return Standard_True;
1774   }
1775   else {
1776     return Standard_False;
1777   }
1778 }
1779
1780
1781 static void PutPointsOnLine (const Contap_TheSearch& solrst,
1782                              const Handle(Adaptor3d_HSurface)& Surf,
1783                              Contap_TheSequenceOfLine& slin)
1784
1785 {
1786   Standard_Integer i,l;//,index; 
1787   Standard_Integer NbPoints = solrst.NbPoints();
1788
1789   Standard_Real theparam;
1790
1791   IntSurf_Transition TLine,TArc;
1792   Standard_Boolean goon;
1793
1794   gp_Pnt2d pt2d;
1795   gp_Vec2d d2d;
1796
1797   gp_Pnt ptonsurf;
1798   gp_Vec vectg,normale,tgtrst;
1799   Standard_Real paramlin = 0.0;
1800
1801
1802   Standard_Integer nbLin = slin.Length();
1803   for(l=1;l<=nbLin;l++) { 
1804     Contap_Line& Line=slin.ChangeValue(l);
1805     for (i=1; i<= NbPoints; i++) {
1806
1807       const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
1808       const Handle(Adaptor2d_HCurve2d)& thearc = PStart.Arc();
1809       theparam = PStart.Parameter();
1810
1811       Contap_HCurve2dTool::D1(thearc,theparam,pt2d,d2d);
1812       goon = FindLine(Line,Surf,pt2d,ptonsurf,paramlin,vectg,normale);
1813
1814       Contap_Point PPoint;
1815
1816       if (goon) {
1817         gp_Vec d1u,d1v;
1818         gp_Pnt bidpt;
1819         Adaptor3d_HSurfaceTool::D1(Surf,pt2d.X(),pt2d.Y(),bidpt,d1u,d1v);
1820         PPoint.SetValue(ptonsurf,pt2d.X(),pt2d.Y());
1821         if (normale.Magnitude() < RealEpsilon()) {
1822           TLine.SetValue();
1823           TArc.SetValue();
1824         }
1825         else {
1826           // Petit test qui devrait permettre de bien traiter les pointes
1827           // des cones, et les sommets d`une sphere. Il faudrait peut-etre
1828           // rajouter une methode dans SurfProps
1829
1830           if (Abs(d2d.Y()) <= Precision::Confusion()) {
1831             tgtrst = d1v.Crossed(normale);
1832             if(d2d.X() < 0.0) 
1833               tgtrst.Reverse();
1834           }
1835           else {
1836             tgtrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
1837           }
1838           IntSurf::MakeTransition(vectg,tgtrst,normale,TLine,TArc);
1839         }
1840
1841         PPoint.SetArc(thearc,theparam, TLine, TArc);
1842         PPoint.SetParameter(paramlin);
1843         if (!PStart.IsNew()) {
1844           PPoint.SetVertex(PStart.Vertex());
1845         }
1846         Line.Add(PPoint);
1847       }
1848     }
1849   }
1850 }
1851
1852
1853 //----------------------------------------------------------------------------------
1854 //-- Orientation des contours Apparents quand ceux-ci sont des lignes ou des cercles
1855 //-- On prend un point de la ligne ou du cercle ---> P 
1856 //-- On projete ce point sur la surface P ---> u,v
1857 //-- et on evalue la transition au point u,v
1858 //----------------------------------------------------------------------------------
1859
1860 IntSurf_TypeTrans ComputeTransitionOngpLine
1861 (Contap_SurfFunction& SFunc,
1862  const gp_Lin& L)
1863
1864   const Handle(Adaptor3d_HSurface)& Surf=SFunc.Surface();
1865   GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1866   gp_Pnt P;
1867   gp_Vec T;
1868   ElCLib::D1(0.0,L,P,T);
1869   Standard_Real u = 0.,v = 0.;
1870   switch (typS) {
1871   case GeomAbs_Cylinder: {
1872     ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),P,u,v);
1873     break;
1874                          }
1875   case GeomAbs_Cone: {
1876     ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),P,u,v);
1877     break;
1878                      }
1879   case GeomAbs_Sphere: { 
1880     ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),P,u,v);
1881     break;
1882                        }
1883   default:
1884     break;
1885   }
1886   return(ComputeTransitionOnLine(SFunc,u,v,T));
1887 }
1888
1889
1890 IntSurf_TypeTrans ComputeTransitionOngpCircle
1891 (Contap_SurfFunction& SFunc,
1892  const gp_Circ& C)
1893
1894   const Handle(Adaptor3d_HSurface)& Surf=SFunc.Surface();
1895   GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1896   gp_Pnt P;
1897   gp_Vec T;
1898   ElCLib::D1(0.0,C,P,T);
1899   Standard_Real u = 0.,v = 0.;
1900   switch (typS) {
1901   case GeomAbs_Cylinder: {
1902     ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cylinder(Surf),P,u,v);
1903     break;
1904                          }
1905   case GeomAbs_Cone: {
1906     ElSLib::Parameters(Adaptor3d_HSurfaceTool::Cone(Surf),P,u,v);
1907     break;
1908                      }
1909   case GeomAbs_Sphere: { 
1910     ElSLib::Parameters(Adaptor3d_HSurfaceTool::Sphere(Surf),P,u,v);
1911     break;
1912                        }
1913   default:
1914     break;
1915   }
1916   return(ComputeTransitionOnLine(SFunc,u,v,T));
1917 }
1918
1919
1920 void Contap_Contour::PerformAna(const Handle(Adaptor3d_TopolTool)& Domain)
1921 {
1922
1923   done = Standard_False;
1924   slin.Clear();
1925
1926   Standard_Real TolArc = 1.e-5;
1927
1928   Standard_Integer nbCont, nbPointRst, i;
1929   //gp_Circ cirsol;
1930   //gp_Lin linsol;
1931   Contap_ContAna contana;
1932   Contap_Line theline;
1933   const Handle(Adaptor3d_HSurface)& Surf = mySFunc.Surface();
1934   Contap_TFunction TypeFunc(mySFunc.FunctionType());
1935   Standard_Boolean PerformSolRst = Standard_True;
1936
1937   GeomAbs_SurfaceType typS = Adaptor3d_HSurfaceTool::GetType(Surf);
1938
1939   switch (typS) {
1940   case GeomAbs_Plane: 
1941     {
1942       gp_Pln pl(Adaptor3d_HSurfaceTool::Plane(Surf));
1943       switch (TypeFunc) {
1944   case Contap_ContourStd:
1945     {
1946       gp_Dir Dirpln(pl.Axis().Direction());
1947       if (Abs(mySFunc.Direction().Dot(Dirpln)) > Precision::Angular()) {
1948         // Aucun point du plan n`est solution, en particulier aucun point
1949         // sur restriction.
1950         PerformSolRst = Standard_False;
1951       }
1952     }
1953     break;
1954   case Contap_ContourPrs:
1955     {
1956       gp_Pnt Eye(mySFunc.Eye());
1957       if (pl.Distance(Eye) > Precision::Confusion()) {
1958         // Aucun point du plan n`est solution, en particulier aucun point
1959         // sur restriction.
1960         PerformSolRst = Standard_False;
1961       }     
1962     }
1963     break;
1964   case Contap_DraftStd:
1965     {
1966       gp_Dir Dirpln(pl.Axis().Direction());
1967       Standard_Real Sina = Sin(mySFunc.Angle());
1968       if (Abs(mySFunc.Direction().Dot(Dirpln)+ Sina) > //voir SurfFunction
1969         Precision::Angular()) {
1970
1971           PerformSolRst = Standard_False;
1972       }
1973     }
1974     break;
1975   case Contap_DraftPrs:
1976   default:
1977     {
1978     }
1979       }
1980     }
1981     break;
1982
1983   case GeomAbs_Sphere:
1984     {
1985       switch (TypeFunc) {
1986   case Contap_ContourStd:
1987     {
1988       contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),mySFunc.Direction());
1989     }
1990     break;
1991   case Contap_ContourPrs:
1992     {
1993       contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),mySFunc.Eye());
1994     }
1995     break;
1996   case Contap_DraftStd:
1997     {
1998       contana.Perform(Adaptor3d_HSurfaceTool::Sphere(Surf),
1999         mySFunc.Direction(),mySFunc.Angle());
2000     }
2001     break;
2002   case Contap_DraftPrs:
2003   default:
2004     {
2005     }
2006       }
2007     }
2008     break;
2009
2010   case GeomAbs_Cylinder:
2011     {
2012       switch (TypeFunc) {
2013   case Contap_ContourStd:
2014     {
2015       contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),mySFunc.Direction());
2016     }
2017     break;
2018   case Contap_ContourPrs:
2019     {
2020       contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),mySFunc.Eye());
2021     }
2022     break;
2023   case Contap_DraftStd:
2024     {
2025       contana.Perform(Adaptor3d_HSurfaceTool::Cylinder(Surf),
2026         mySFunc.Direction(),mySFunc.Angle());
2027     }
2028     break;
2029   case Contap_DraftPrs:
2030   default:
2031     {
2032     }
2033       }
2034     }
2035     break;
2036
2037   case GeomAbs_Cone:
2038     {
2039       switch (TypeFunc) {
2040   case Contap_ContourStd:
2041     {
2042       contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),mySFunc.Direction());
2043     }
2044     break;
2045   case Contap_ContourPrs:
2046     {
2047       contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),mySFunc.Eye());
2048     }
2049     break;
2050   case Contap_DraftStd:
2051     {
2052       contana.Perform(Adaptor3d_HSurfaceTool::Cone(Surf),
2053         mySFunc.Direction(),mySFunc.Angle());
2054     }
2055     break;
2056   case Contap_DraftPrs:
2057   default:
2058     {
2059     }
2060       }
2061   default:
2062     break;
2063     }
2064     break;
2065   }
2066
2067   if (typS != GeomAbs_Plane) {
2068
2069     if (!contana.IsDone()) {
2070       return;
2071     }
2072
2073     nbCont = contana.NbContours();
2074
2075     if (contana.NbContours() == 0) {
2076       done = Standard_True;
2077       return;
2078     }
2079
2080     GeomAbs_CurveType typL = contana.TypeContour();
2081     if (typL == GeomAbs_Circle) {
2082       theline.SetValue(contana.Circle());
2083       IntSurf_TypeTrans TransCircle;
2084       TransCircle = ComputeTransitionOngpCircle(mySFunc,contana.Circle());
2085       theline.SetTransitionOnS(TransCircle);
2086       slin.Append(theline);
2087     }
2088     else if (typL == GeomAbs_Line) {
2089       for (i=1; i<=nbCont; i++) {
2090         theline.SetValue(contana.Line(i));
2091         IntSurf_TypeTrans TransLine;
2092         TransLine = ComputeTransitionOngpLine(mySFunc,contana.Line(i));
2093         theline.SetTransitionOnS(TransLine);
2094         slin.Append(theline);
2095         theline.Clear();
2096       }
2097
2098       /*
2099       if (typS == GeomAbs_Cone) {
2100       Standard_Real u,v;
2101       gp_Cone thecone(Adaptor3d_HSurfaceTool::Cone(Surf));
2102       ElSLib::Parameters(thecone,thecone.Apex(),u,v);
2103       Contap_Point vtxapex(thecone.Apex(),u,v);
2104       vtxapex.SetInternal();
2105       vtxapex.SetMultiple();
2106       for (i=1; i<=nbCont i++) {
2107       slin.ChangeValue(i).Add(vtxapex);
2108       }
2109       }
2110       */
2111     }
2112   }
2113
2114   if(PerformSolRst) { 
2115
2116     solrst.Perform(myAFunc,Domain,TolArc,TolArc);
2117     if (!solrst.IsDone()) {
2118       return;
2119     }
2120     nbPointRst = solrst.NbPoints();
2121
2122     if (nbPointRst != 0) {
2123       PutPointsOnLine(solrst,Surf,slin);
2124     }
2125
2126     if (solrst.NbSegments() !=0) {
2127       ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
2128     }
2129
2130
2131     //-- lbr 
2132     //Standard_Boolean oneremov;
2133     Standard_Integer nblinto = slin.Length();
2134     TColStd_SequenceOfInteger SeqToDestroy;
2135
2136     //-- cout<<" Construct Contour_3   nblin = "<<nblinto<<endl;
2137     for(i=1; i<= nblinto ; i++) { 
2138       //-- cout<<" nbvtx : "<<slin.Value(i).NbVertex()<<endl;
2139       //--if(slin.Value(i).NbVertex() > 1) { 
2140       if(slin.Value(i).TypeContour() != Contap_Restriction) { 
2141         LineConstructor(slin,Domain,slin.ChangeValue(i),Surf);
2142         SeqToDestroy.Append(i);
2143       }
2144       //-- }
2145     }
2146     for(i=SeqToDestroy.Length(); i>=1; i--) { 
2147       slin.Remove(SeqToDestroy.Value(i));
2148     } 
2149   }
2150
2151   done = Standard_True;
2152 }
2153