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