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