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