Integration of OCCT 6.5.0 from SVN
[occt.git] / src / Contap / Contap_ContourGen_3.gxx
1 //-- Contap_ContourGen_3.gxx
2
3 #define Tolpetit 1.e-10  // pour dist au carre
4 #include <ElSLib.hxx>
5
6
7 #include <TColStd_SequenceOfInteger.hxx>
8
9 static Standard_Boolean FindLine(Contap_TheLine& Line,
10                                  const TheSurface& Surf,
11                                  const gp_Pnt2d& Pt2d,
12                                  gp_Pnt& Ptref,
13                                  Standard_Real& Paramin,
14                                  gp_Vec& Tgmin,
15                                  gp_Vec& Norm)
16 {
17 //  Standard_Integer i;
18   gp_Pnt pt,ptmin;
19   gp_Vec tg;
20   Standard_Real para,dist;
21   Standard_Real dismin = RealLast();
22
23   Contap_TheSurfProps::Normale(Surf,Pt2d.X(),Pt2d.Y(),Ptref,Norm);
24
25   if (Line.TypeContour() == Contap_Lin) {
26     gp_Lin lin(Line.Line());
27     para = ElCLib::Parameter(lin,Ptref);
28     ElCLib::D1(para,lin,pt,tg);
29     dist = pt.Distance(Ptref) + Abs(Norm.Dot(lin.Direction()));
30   }
31   else { // Contap__Circle
32     gp_Circ cir(Line.Circle());
33     para = ElCLib::Parameter(cir,Ptref);
34     ElCLib::D1(para,cir,pt,tg);
35     dist = pt.Distance(Ptref)+Abs(Norm.Dot(tg/cir.Radius()));
36   }
37   if (dist < dismin) {
38     dismin = dist;
39     Paramin = para;
40     ptmin = pt;
41     Tgmin = tg;
42   }
43   if (ptmin.SquareDistance(Ptref) <= Tolpetit) {
44     return Standard_True;
45   }
46   else {
47     return Standard_False;
48   }
49 }
50
51
52 static void PutPointsOnLine (const Contap_TheSearch& solrst,
53                              const TheSurface& Surf,
54                              Contap_TheSequenceOfLine& slin)
55
56 {
57   Standard_Integer i,l;//,index; 
58   Standard_Integer NbPoints = solrst.NbPoints();
59
60   Standard_Real theparam;
61
62   IntSurf_Transition TLine,TArc;
63   Standard_Boolean goon;
64   
65   gp_Pnt2d pt2d;
66   gp_Vec2d d2d;
67
68   gp_Pnt ptonsurf;
69   gp_Vec vectg,normale,tgtrst;
70   Standard_Real paramlin;
71
72   
73   Standard_Integer nbLin = slin.Length();
74   for(l=1;l<=nbLin;l++) { 
75     Contap_TheLine& Line=slin.ChangeValue(l);
76     for (i=1; i<= NbPoints; i++) {
77       
78       const Contap_ThePathPointOfTheSearch& PStart = solrst.Point(i);
79       const TheArc& thearc = PStart.Arc();
80       theparam = PStart.Parameter();
81       
82       TheArcTool::D1(thearc,theparam,pt2d,d2d);
83       goon = FindLine(Line,Surf,pt2d,ptonsurf,paramlin,vectg,normale);
84       
85       Contap_ThePoint PPoint;
86
87       if (goon) {
88         gp_Vec d1u,d1v;
89         gp_Pnt bidpt;
90         TheSurfaceTool::D1(Surf,pt2d.X(),pt2d.Y(),bidpt,d1u,d1v);
91         PPoint.SetValue(ptonsurf,pt2d.X(),pt2d.Y());
92         if (normale.Magnitude() < RealEpsilon()) {
93           TLine.SetValue();
94           TArc.SetValue();
95         }
96         else {
97           // Petit test qui devrait permettre de bien traiter les pointes
98           // des cones, et les sommets d`une sphere. Il faudrait peut-etre
99           // rajouter une methode dans SurfProps
100           
101           if (Abs(d2d.Y()) <= Precision::Confusion()) {
102             tgtrst = d1v.Crossed(normale);
103             if(d2d.X() < 0.0) 
104               tgtrst.Reverse();
105           }
106           else {
107             tgtrst.SetLinearForm(d2d.X(),d1u,d2d.Y(),d1v);
108           }
109           IntSurf::MakeTransition(vectg,tgtrst,normale,TLine,TArc);
110         }
111         
112         PPoint.SetArc(thearc,theparam, TLine, TArc);
113         PPoint.SetParameter(paramlin);
114         if (!PStart.IsNew()) {
115           PPoint.SetVertex(PStart.Vertex());
116         }
117         Line.Add(PPoint);
118       }
119     }
120   }
121 }
122
123
124 //----------------------------------------------------------------------------------
125 //-- Orientation des contours Apparents quand ceux-ci sont des lignes ou des cercles
126 //-- On prend un point de la ligne ou du cercle ---> P 
127 //-- On projete ce point sur la surface P ---> u,v
128 //-- et on evalue la transition au point u,v
129 //----------------------------------------------------------------------------------
130
131 IntSurf_TypeTrans ComputeTransitionOngpLine
132   (Contap_TheSurfFunction& SFunc,
133    const gp_Lin& L)
134
135   const TheSurface& Surf=SFunc.Surface();
136   GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(Surf);
137   gp_Pnt P;
138   gp_Vec T;
139   ElCLib::D1(0.0,L,P,T);
140   Standard_Real u,v;
141   switch (typS) {
142   case GeomAbs_Cylinder: {
143     ElSLib::Parameters(TheSurfaceTool::Cylinder(Surf),P,u,v);
144       break;
145     }
146   case GeomAbs_Cone: {
147     ElSLib::Parameters(TheSurfaceTool::Cone(Surf),P,u,v);
148       break;
149     }
150   case GeomAbs_Sphere: { 
151     ElSLib::Parameters(TheSurfaceTool::Sphere(Surf),P,u,v);
152       break;
153     }
154 #ifndef DEB
155   default:
156     break;
157 #endif
158   }
159   return(ComputeTransitionOnLine(SFunc,u,v,T));
160 }
161
162
163 IntSurf_TypeTrans ComputeTransitionOngpCircle
164   (Contap_TheSurfFunction& SFunc,
165    const gp_Circ& C)
166
167   const TheSurface& Surf=SFunc.Surface();
168   GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(Surf);
169   gp_Pnt P;
170   gp_Vec T;
171   ElCLib::D1(0.0,C,P,T);
172   Standard_Real u,v;
173   switch (typS) {
174   case GeomAbs_Cylinder: {
175     ElSLib::Parameters(TheSurfaceTool::Cylinder(Surf),P,u,v);
176       break;
177     }
178   case GeomAbs_Cone: {
179     ElSLib::Parameters(TheSurfaceTool::Cone(Surf),P,u,v);
180       break;
181     }
182   case GeomAbs_Sphere: { 
183     ElSLib::Parameters(TheSurfaceTool::Sphere(Surf),P,u,v);
184       break;
185     }
186 #ifndef DEB
187   default:
188     break;
189 #endif
190   }
191   return(ComputeTransitionOnLine(SFunc,u,v,T));
192   
193 }
194
195
196 void Contap_ContourGen::PerformAna(const Handle(TheTopolTool)& Domain)
197 {
198
199   done = Standard_False;
200   slin.Clear();
201
202   Standard_Real TolArc = 1.e-5;
203
204   Standard_Integer nbCont, nbPointRst, i;
205   //gp_Circ cirsol;
206   //gp_Lin linsol;
207   Contap_ContAna contana;
208   Contap_TheLine theline;
209   const TheSurface& Surf = mySFunc.Surface();
210   Contap_TFunction TypeFunc(mySFunc.FunctionType());
211   Standard_Boolean PerformSolRst = Standard_True;
212
213   GeomAbs_SurfaceType typS = TheSurfaceTool::GetType(Surf);
214
215   switch (typS) {
216   case GeomAbs_Plane: 
217     {
218       gp_Pln pl(TheSurfaceTool::Plane(Surf));
219       switch (TypeFunc) {
220       case Contap_ContourStd:
221         {
222           gp_Dir Dirpln(pl.Axis().Direction());
223           if (Abs(mySFunc.Direction().Dot(Dirpln)) > Precision::Angular()) {
224             // Aucun point du plan n`est solution, en particulier aucun point
225             // sur restriction.
226             PerformSolRst = Standard_False;
227           }
228         }
229         break;
230       case Contap_ContourPrs:
231         {
232           gp_Pnt Eye(mySFunc.Eye());
233           if (pl.Distance(Eye) > Precision::Confusion()) {
234             // Aucun point du plan n`est solution, en particulier aucun point
235             // sur restriction.
236             PerformSolRst = Standard_False;
237           }         
238         }
239         break;
240       case Contap_DraftStd:
241         {
242           gp_Dir Dirpln(pl.Axis().Direction());
243           Standard_Real Sina = Sin(mySFunc.Angle());
244           if (Abs(mySFunc.Direction().Dot(Dirpln)+ Sina) > //voir SurfFunction
245               Precision::Angular()) {
246           
247             PerformSolRst = Standard_False;
248           }
249         }
250         break;
251       case Contap_DraftPrs:
252       default:
253         {
254         }
255       }
256     }
257     break;
258
259   case GeomAbs_Sphere:
260     {
261       switch (TypeFunc) {
262       case Contap_ContourStd:
263         {
264           contana.Perform(TheSurfaceTool::Sphere(Surf),mySFunc.Direction());
265         }
266         break;
267       case Contap_ContourPrs:
268         {
269           contana.Perform(TheSurfaceTool::Sphere(Surf),mySFunc.Eye());
270         }
271         break;
272       case Contap_DraftStd:
273         {
274           contana.Perform(TheSurfaceTool::Sphere(Surf),
275                           mySFunc.Direction(),mySFunc.Angle());
276         }
277         break;
278       case Contap_DraftPrs:
279       default:
280         {
281         }
282       }
283     }
284     break;
285
286   case GeomAbs_Cylinder:
287     {
288       switch (TypeFunc) {
289       case Contap_ContourStd:
290         {
291           contana.Perform(TheSurfaceTool::Cylinder(Surf),mySFunc.Direction());
292         }
293         break;
294       case Contap_ContourPrs:
295         {
296           contana.Perform(TheSurfaceTool::Cylinder(Surf),mySFunc.Eye());
297         }
298         break;
299       case Contap_DraftStd:
300         {
301           contana.Perform(TheSurfaceTool::Cylinder(Surf),
302                           mySFunc.Direction(),mySFunc.Angle());
303         }
304         break;
305       case Contap_DraftPrs:
306       default:
307         {
308         }
309       }
310     }
311     break;
312
313   case GeomAbs_Cone:
314     {
315       switch (TypeFunc) {
316       case Contap_ContourStd:
317         {
318           contana.Perform(TheSurfaceTool::Cone(Surf),mySFunc.Direction());
319         }
320         break;
321       case Contap_ContourPrs:
322         {
323           contana.Perform(TheSurfaceTool::Cone(Surf),mySFunc.Eye());
324         }
325         break;
326       case Contap_DraftStd:
327         {
328           contana.Perform(TheSurfaceTool::Cone(Surf),
329                           mySFunc.Direction(),mySFunc.Angle());
330         }
331         break;
332       case Contap_DraftPrs:
333       default:
334         {
335         }
336       }
337 #ifndef DEB
338     default:
339       break;
340 #endif
341     }
342     break;
343   }
344   
345   if (typS != GeomAbs_Plane) {
346
347     if (!contana.IsDone()) {
348       return;
349     }
350
351     nbCont = contana.NbContours();
352
353     if (contana.NbContours() == 0) {
354       done = Standard_True;
355       return;
356     }
357
358     GeomAbs_CurveType typL = contana.TypeContour();
359     if (typL == GeomAbs_Circle) {
360       theline.SetValue(contana.Circle());
361       IntSurf_TypeTrans TransCircle;
362       TransCircle = ComputeTransitionOngpCircle(mySFunc,contana.Circle());
363       theline.SetTransitionOnS(TransCircle);
364       slin.Append(theline);
365     }
366     else if (typL == GeomAbs_Line) {
367       for (i=1; i<=nbCont; i++) {
368         theline.SetValue(contana.Line(i));
369         IntSurf_TypeTrans TransLine;
370         TransLine = ComputeTransitionOngpLine(mySFunc,contana.Line(i));
371         theline.SetTransitionOnS(TransLine);
372         slin.Append(theline);
373         theline.Clear();
374       }
375       
376 /*
377       if (typS == GeomAbs_Cone) {
378         Standard_Real u,v;
379         gp_Cone thecone(TheSurfaceTool::Cone(Surf));
380         ElSLib::Parameters(thecone,thecone.Apex(),u,v);
381         Contap_ThePoint vtxapex(thecone.Apex(),u,v);
382         vtxapex.SetInternal();
383         vtxapex.SetMultiple();
384         for (i=1; i<=nbCont i++) {
385           slin.ChangeValue(i).Add(vtxapex);
386         }
387       }
388 */
389     }
390   }
391
392   if(PerformSolRst) { 
393     
394     solrst.Perform(myAFunc,Domain,TolArc,TolArc);
395     if (!solrst.IsDone()) {
396       return;
397     }
398     nbPointRst = solrst.NbPoints();
399     
400     if (nbPointRst != 0) {
401       PutPointsOnLine(solrst,Surf,slin);
402     }
403     
404     if (solrst.NbSegments() !=0) {
405       ProcessSegments(solrst,slin,TolArc,mySFunc,Domain);
406     }
407     
408     
409     //-- lbr 
410     //Standard_Boolean oneremov;
411     Standard_Integer nblinto = slin.Length();
412     TColStd_SequenceOfInteger SeqToDestroy;
413     
414     //-- cout<<" Construct Contour_3   nblin = "<<nblinto<<endl;
415     for(i=1; i<= nblinto ; i++) { 
416       //-- cout<<" nbvtx : "<<slin.Value(i).NbVertex()<<endl;
417       //--if(slin.Value(i).NbVertex() > 1) { 
418       if(slin.Value(i).TypeContour() != Contap_Restriction) { 
419         LineConstructor(slin,Domain,slin.ChangeValue(i),Surf);
420         SeqToDestroy.Append(i);
421       }
422       //-- }
423     }
424     for(i=SeqToDestroy.Length(); i>=1; i--) { 
425       slin.Remove(SeqToDestroy.Value(i));
426     } 
427   }
428
429   done = Standard_True;
430 }
431
432
433
434
435