Integration of OCCT 6.5.0 from SVN
[occt.git] / samples / mfc / occtdemo / Projection / Projection_Presentation.cpp
1 // Projection_Presentation.cpp: implementation of the Projection_Presentation class.
2 // Projection of points on curves and curves on surfaces
3 //////////////////////////////////////////////////////////////////////
4
5 #include "stdafx.h"
6 #include "Projection_Presentation.h"
7
8 #include <GeomAPI_ProjectPointOnCurve.hxx>
9 #include <GeomAPI_ProjectPointOnSurf.hxx>
10 #include <Geom_BSplineCurve.hxx>
11 #include <Geom_Curve.hxx>
12 #include <Geom_Plane.hxx>
13
14 #include <Geom_Line.hxx>
15 #include <GeomProjLib.hxx>
16 #include <Geom_TrimmedCurve.hxx>
17 #include <Geom_CylindricalSurface.hxx>
18 #include <Geom_RectangularTrimmedSurface.hxx>
19 #include <GeomAPI_PointsToBSpline.hxx>
20 #include <GeomAPI_PointsToBSplineSurface.hxx>
21 #include <Precision.hxx>
22 #include <OCCDemo_Presentation.h>
23
24 #include <TColgp_Array1OfPnt.hxx>
25 #include <TColgp_Array2OfPnt.hxx>
26
27 #include <gce_MakeLin.hxx>
28
29 #include <gp_Pnt.hxx>
30 #include <gp_Dir.hxx>
31 #include <GeomAdaptor_HSurface.hxx>
32 #include <GeomAdaptor_HCurve.hxx>
33 #include <Adaptor2d_HCurve2d.hxx>
34 #include <Approx_CurveOnSurface.hxx>
35 #include <ProjLib_CompProjectedCurve.hxx>
36 #include <TColGeom_SequenceOfCurve.hxx>
37
38 #ifdef WNT
39  #define EOL "\r\n"
40 #else
41  #define EOL "\n"
42 #endif
43
44 // Initialization of global variable with an instance of this class
45 OCCDemo_Presentation* OCCDemo_Presentation::Current = new Projection_Presentation;
46
47 // Initialization of array of samples
48 const Projection_Presentation::PSampleFuncType Projection_Presentation::SampleFuncs[] =
49 {
50   &Projection_Presentation::sample1,
51   &Projection_Presentation::sample2,
52   &Projection_Presentation::sample3,
53   &Projection_Presentation::sample4,
54 };
55
56 //////////////////////////////////////////////////////////////////////
57 // Construction/Destruction
58 //////////////////////////////////////////////////////////////////////
59
60 Projection_Presentation::Projection_Presentation()
61 {
62   FitMode=false;
63   myIndex = 0;
64   myNbSamples = sizeof(SampleFuncs)/sizeof(PSampleFuncType);
65   setName ("Projection of points onto curve and surface, and curve onto surface");
66 }
67
68 //////////////////////////////////////////////////////////////////////
69 // Create bspline curve
70 //////////////////////////////////////////////////////////////////////
71
72 //================================================================
73 // Function : createCurve
74 // Purpose  : returns a BSpline curve with 10 poles
75 //================================================================
76 static Handle_Geom_BSplineCurve createCurve()
77 {
78   Standard_Real aCoords[][3] = {{-6,3,0},{-5,1,0},{-4,0,0},{-2,1,0},{-1,-1,0},
79                                 {0,-1,0},{1,0,0},{2,2,0},{3,1,0},{4,0,0}};
80
81   Standard_Integer nPoles = sizeof(aCoords)/(sizeof(Standard_Real)*3);
82   TColgp_Array1OfPnt aCurvePoint (1, nPoles);
83
84   for (Standard_Integer i=0; i < nPoles; i++)
85     aCurvePoint(i+1) = gp_Pnt (aCoords[i][0]*100, aCoords[i][1]*100, aCoords[i][2]*100);
86
87   Standard_Integer MinDegree = 3;
88   Standard_Integer MaxDegree = 8;
89   
90   return GeomAPI_PointsToBSpline(aCurvePoint, MinDegree,
91     MaxDegree, GeomAbs_C2, Precision::Confusion());
92 }
93
94 //================================================================
95 // Function : createSurface
96 // Purpose  : returns a BSpline Surface with 8 poles
97 //================================================================
98 static Handle_Geom_BSplineSurface createSurface()
99 {
100   // define points array
101   TColgp_Array2OfPnt aPoints (1,2,1,4);
102
103   // initializing array of points
104   aPoints(1,1) = gp_Pnt(-4,4.5,-3); aPoints(1,2) = gp_Pnt(-2.2,5,-2);
105   aPoints(1,3) = gp_Pnt(1,2,-2);    aPoints(1,4) = gp_Pnt(3.5,4.5,-2);
106   aPoints(2,1) = gp_Pnt(-4,-3,-3);  aPoints(2,2) = gp_Pnt(-1.5,-0.5,-4);
107   aPoints(2,3) = gp_Pnt(2,-1,-3);   aPoints(2,4) = gp_Pnt(5,-3,-2);
108
109   for (Standard_Integer i=1; i <= aPoints.ColLength(); i++)
110     for (Standard_Integer j=1; j <= aPoints.RowLength(); j++)
111         aPoints(i,j).ChangeCoord() = aPoints(i,j).Coord() * 100 + gp_XYZ(0,0,300);
112
113   Standard_Integer MinDegree = 3;
114   Standard_Integer MaxDegree = 8;
115   
116   return GeomAPI_PointsToBSplineSurface (
117     aPoints, MinDegree, MaxDegree, GeomAbs_C2, Precision::Confusion());
118 }
119
120
121 //=========================================================================================
122 // Sample execution
123 //=========================================================================================
124
125 void Projection_Presentation::DoSample()
126 {
127   getAISContext()->EraseAll();
128   if (myIndex >=0 && myIndex < myNbSamples)
129     (this->*SampleFuncs[myIndex])();
130 }
131
132 //////////////////////////////////////////////////////////////////////
133 // Sample functions
134 //////////////////////////////////////////////////////////////////////
135
136
137 //==========================================================================================
138 // Function : Projection_Presentation::sample1
139 // Purpose  : 
140 //==========================================================================================
141
142 void Projection_Presentation::sample1()
143 {
144   setResultTitle("Projection of a Point onto a Curve");
145   TCollection_AsciiString aText(
146     "  // define a BSpline curve" EOL
147     "  Handle(Geom_BSplineCurve) aCurve = createCurve();" EOL
148     "" EOL
149     "  // define initial point for projection" EOL
150     "  gp_Pnt aPoint(0,-70,150);" EOL
151     "" EOL
152     "  // projection of a point onto a curve" EOL
153     "  GeomAPI_ProjectPointOnCurve aPPC(aPoint,aCurve);" EOL
154     "" EOL
155     "  // evaluate solutions" EOL
156     "  Standard_Integer aNumSolutions = aPPC.NbPoints();" EOL
157     "  TColgp_Array1OfPnt aPoints(1, Max(aNumSolutions, 1));" EOL
158     "  Standard_Real aDistance;" EOL
159     "  gp_Pnt aNearestPoint;" EOL
160     "  Standard_Real aNearestParam;" EOL
161     "" EOL
162     "  if (aNumSolutions > 0)" EOL
163     "  {" EOL
164     "    for(Standard_Integer i = 1; i <= aNumSolutions; i++)" EOL
165     "      aPoints(i) = aPPC.Point(i);" EOL
166     "" EOL
167     "    // The nearest solution" EOL
168     "    aNearestParam = aPPC.LowerDistanceParameter();" EOL
169     "    aNearestPoint = aPPC.NearestPoint();" EOL
170     "    aDistance = aPPC.LowerDistance();" EOL
171     "  }" EOL EOL);
172   setResultText(aText.ToCString());
173
174   // define a BSpline curve
175   Handle(Geom_BSplineCurve) aCurve = createCurve();
176
177   // define initial point for projection
178   gp_Pnt aPoint(0,-70,150);
179
180   // projection of a point onto a curve
181   GeomAPI_ProjectPointOnCurve aPPC(aPoint,aCurve);
182
183   // evaluate solutions
184   Standard_Integer aNumSolutions = aPPC.NbPoints();
185   TColgp_Array1OfPnt aPoints(1, Max(aNumSolutions, 1));
186   Standard_Real aDistance;
187   gp_Pnt aNearestPoint;
188   Standard_Real aNearestParam;
189
190   if (aNumSolutions > 0)
191   {
192     for(Standard_Integer i = 1; i <= aNumSolutions; i++)
193       aPoints(i) = aPPC.Point(i);
194
195     // The nearest solution
196     aNearestParam = aPPC.LowerDistanceParameter();
197     aNearestPoint = aPPC.NearestPoint();
198     aDistance = aPPC.LowerDistance();
199
200     aText = aText +
201       "  //=================================================" EOL EOL
202
203       "  Lower distance parameter = " + TCollection_AsciiString(aNearestParam) + EOL
204       "  Nearest distance = " + TCollection_AsciiString(aDistance) + EOL;
205     setResultText(aText.ToCString());
206   }
207   
208   // output initial point
209   drawPoint(aPoint,Quantity_Color(Quantity_NOC_YELLOW));
210   if(WAIT_A_LITTLE) return;
211
212   // output Bspline curve
213   drawCurve(aCurve);
214
215   // output solutions
216   if (aNumSolutions > 0)
217   {
218     if(WAIT_A_SECOND) return;
219
220     for(int i = 1; i <= aNumSolutions; i++)
221       drawPoint(aPoints(i));
222
223     // output line between nearest points
224     Handle(Geom_Line) aLine = new Geom_Line(gce_MakeLin(aPoint, aNearestPoint));
225     Handle(Geom_TrimmedCurve) aTrimmedCurve = new Geom_TrimmedCurve(aLine,0,aDistance);
226     drawCurve(aTrimmedCurve,Quantity_Color(Quantity_NOC_WHITE));
227   }
228 }
229
230 //==========================================================================================
231 // Function : Projection_Presentation::sample2
232 // Purpose  : 
233 //==========================================================================================
234
235 void Projection_Presentation::sample2()
236 {
237   setResultTitle("Projection of a Point onto a Surface");
238   TCollection_AsciiString aText(
239     "  // define initial point" EOL
240     "  gp_Pnt aPoint(-380,-370,150);" EOL
241     "  " EOL
242     "  // define a cylindrical surface" EOL
243     "  gp_Pnt aCenterPoint(50,-20,-30);" EOL
244     "  gp_Dir aDir(0,0,1);" EOL
245     "  gp_Ax3 anAx3(aCenterPoint, aDir);" EOL
246     "  Standard_Real Radius = 300;" EOL
247     "  Handle_Geom_CylindricalSurface aCylSurface =" EOL
248     "    new Geom_CylindricalSurface(anAx3, Radius);" EOL
249     "" EOL
250     "  // projection of a point onto a surface" EOL
251     "  GeomAPI_ProjectPointOnSurf aPPS(aPoint,aCylSurface);" EOL
252     "" EOL
253     "  // evaluate solutions" EOL
254     "  Standard_Integer aNumSolutions = aPPS.NbPoints();" EOL
255     "  TColgp_Array1OfPnt aPoints(1, Max(aNumSolutions, 1));" EOL
256     "  Standard_Real aDistance;" EOL
257     "  gp_Pnt aNearestPoint;" EOL
258     "  Standard_Real aNearestU, aNearestV;" EOL
259     "" EOL
260     "  if (aNumSolutions > 0)" EOL
261     "  {" EOL
262     "    for(Standard_Integer i = 1; i <= aNumSolutions; i++)" EOL
263     "      aPoints(i) = aPPS.Point(i);" EOL
264     "" EOL
265     "    // The nearest solution" EOL
266     "    aPPS.LowerDistanceParameters(aNearestU, aNearestV);" EOL
267     "    aNearestPoint = aPPS.NearestPoint();" EOL
268     "    aDistance = aPPS.LowerDistance();" EOL
269     "  }" EOL EOL);
270   setResultText(aText.ToCString());
271
272   // define initial point
273   gp_Pnt aPoint(-380,-370,150);
274   
275   // define a cylindrical surface
276   gp_Pnt aCenterPoint(50,-20,-30);
277   gp_Dir aDir(0,0,1);
278   gp_Ax3 anAx3(aCenterPoint, aDir);
279   Standard_Real Radius = 300;
280   Handle_Geom_CylindricalSurface aCylSurface =
281     new Geom_CylindricalSurface(anAx3, Radius);
282
283   // projection of a point onto a surface
284   GeomAPI_ProjectPointOnSurf aPPS(aPoint,aCylSurface);
285
286   // evaluate solutions
287   Standard_Integer aNumSolutions = aPPS.NbPoints();
288   TColgp_Array1OfPnt aPoints(1, Max(aNumSolutions, 1));
289   Standard_Real aDistance;
290   gp_Pnt aNearestPoint;
291   Standard_Real aNearestU, aNearestV;
292
293   if (aNumSolutions > 0)
294   {
295     for(Standard_Integer i = 1; i <= aNumSolutions; i++)
296       aPoints(i) = aPPS.Point(i);
297
298     // The nearest solution
299     aPPS.LowerDistanceParameters(aNearestU, aNearestV);
300     aNearestPoint = aPPS.NearestPoint();
301     aDistance = aPPS.LowerDistance();
302
303     aText = aText +
304       "  //=================================================" EOL EOL
305
306       "  Lower distance parameters:  U = " + TCollection_AsciiString(aNearestU) +
307       ", V = "+ TCollection_AsciiString(aNearestV) + EOL
308       "  Nearest distance = " + TCollection_AsciiString(aDistance) + EOL;
309     setResultText(aText.ToCString());
310   }
311
312   // output initial point
313   drawPoint(aPoint);
314   if(WAIT_A_LITTLE) return;
315
316   // output cylindrical surface
317   Handle_Geom_RectangularTrimmedSurface aCylTrimmed = 
318     new Geom_RectangularTrimmedSurface(aCylSurface,0,2*PI,-200,300,Standard_True,Standard_True);
319   
320   drawSurface(aCylTrimmed);
321
322   // output solutions
323   if (aNumSolutions > 0)
324   {
325     if(WAIT_A_SECOND) return;
326
327     for(int i = 1; i <= aNumSolutions; i++)
328       drawPoint(aPoints(i));
329
330     // output line between nearest points
331     Handle(Geom_Line) aLine = new Geom_Line(gce_MakeLin(aPoint, aNearestPoint));
332     Handle(Geom_TrimmedCurve) aTrimmedCurve = new Geom_TrimmedCurve(aLine,0,aDistance);
333     drawCurve(aTrimmedCurve,Quantity_Color(Quantity_NOC_WHITE));
334   }
335 }
336
337 //==========================================================================================
338 // Function : Projection_Presentation::sample3
339 // Purpose  : 
340 //==========================================================================================
341
342 void Projection_Presentation::sample3()
343 {
344   setResultTitle("Projection of a Curve onto a Surface");
345   setResultText(
346     "  // create BSpline curve" EOL
347     "  Handle(Geom_BSplineCurve) aCurve = createCurve();" EOL
348     "" EOL
349     "  // define initial point" EOL
350     "  gp_Pnt aPoint(0,0,0);" EOL
351     "  " EOL
352     "  // define a planar surface" EOL
353     "  gp_Pnt aPlanePnt(0,0,-100);" EOL
354     "  gp_Dir aPlaneDir(0,0,1);" EOL
355     "  Handle_Geom_Plane aPlane = new Geom_Plane(aPlanePnt, aPlaneDir);" EOL
356     "" EOL
357     "  // create a cylindrical surface" EOL
358     "  gp_Pnt aCylPnt(-100,0,550);" EOL
359     "  gp_Dir aCylDir(0,1,0);" EOL
360     "  gp_Ax3 anAx3(aCylPnt, aCylDir);" EOL
361     "  Standard_Real aRadius = 800;" EOL
362     "  Handle_Geom_CylindricalSurface aCylSurface = " EOL
363     "    new Geom_CylindricalSurface(anAx3, aRadius);" EOL
364     "" EOL
365     "  // Projection of a curve onto a planar surface" EOL
366     "  Handle_Geom_Curve aPlaneProjCurve = GeomProjLib::Project(aCurve, aPlane);" EOL
367     "" EOL
368     "  // Projection of a curve onto a cylindrical surface" EOL
369     "  Handle_Geom_Curve aCylProjCurve = GeomProjLib::Project(aCurve, aCylSurface);" EOL
370   );
371   
372   // create BSpline curve
373   Handle(Geom_BSplineCurve) aCurve = createCurve();
374
375   // define initial point
376   gp_Pnt aPoint(0,0,0);
377   
378   // define a planar surface
379   gp_Pnt aPlanePnt(0,0,-100);
380   gp_Dir aPlaneDir(0,0,1);
381   Handle_Geom_Plane aPlane = new Geom_Plane(aPlanePnt, aPlaneDir);
382
383   // create a cylindrical surface
384   gp_Pnt aCylPnt(-100,0,550);
385   gp_Dir aCylDir(0,1,0);
386   gp_Ax3 anAx3(aCylPnt, aCylDir);
387   Standard_Real aRadius = 800;
388   Handle_Geom_CylindricalSurface aCylSurface = 
389     new Geom_CylindricalSurface(anAx3, aRadius);
390
391   // Projection of a curve onto a planar surface
392   Handle_Geom_Curve aPlaneProjCurve = GeomProjLib::Project(aCurve, aPlane);
393
394   // Projection of a curve onto a cylindrical surface
395   Handle_Geom_Curve aCylProjCurve = GeomProjLib::Project(aCurve, aCylSurface);
396
397   // ===== output ===========
398   // output original curve
399   drawCurve(aCurve);
400   if(WAIT_A_LITTLE) return;
401
402   // output the first surface - plane
403   Handle(AIS_InteractiveObject) aPlaneIO = drawSurface(
404     aPlane, Quantity_Color(Quantity_NOC_YELLOW), Standard_False);
405   getAISContext()->SetTransparency(aPlaneIO, 0.4, Standard_False);
406   getAISContext()->Display(aPlaneIO);
407
408   if(WAIT_A_SECOND) return; // wait longer.  "Projecting... Please wait..."
409
410   // output projected curve  
411   Handle(AIS_InteractiveObject) aProjCurveIO = drawCurve(aPlaneProjCurve, Quantity_Color(Quantity_NOC_GREEN));
412   if(WAIT_A_SECOND) return;
413
414   // Erasing the first surface and projected curve and 
415   // showing the second case of projection
416   getAISContext()->Erase(aPlaneIO, Standard_False);
417   getAISContext()->Erase(aProjCurveIO, Standard_False);
418
419   // output the second surface - cylindrical surface
420   Handle_Geom_RectangularTrimmedSurface aCylTrimmed = 
421    new Geom_RectangularTrimmedSurface(aCylSurface,PI/2,-PI/2,-450,550,Standard_True,Standard_True);
422   Handle(AIS_InteractiveObject) aCylIO = drawSurface(
423     aCylTrimmed, Quantity_Color(Quantity_NOC_YELLOW), Standard_False);
424   getAISContext()->SetTransparency(aCylIO, 0.4, Standard_False);
425   getAISContext()->Display(aCylIO);
426
427   if(WAIT_A_SECOND) return; // wait longer.  "Projecting... Please wait..."
428
429   // output projection curve
430   drawCurve(aCylProjCurve,Quantity_Color(Quantity_NOC_GREEN));
431 }
432
433 //==========================================================================================
434 // Function : Projection_Presentation::sample4
435 // Purpose  : 
436 //==========================================================================================
437 void Projection_Presentation::sample4()
438 {
439   setResultTitle("Projection of Curve onto a BSpline Surface");
440   setResultText(
441     "  // create a BSpline curve" EOL
442     "  Handle(Geom_BSplineCurve) aCurve = createCurve();" EOL
443     "" EOL
444     "  // create a BSpline surface" EOL
445     "  Handle(Geom_BSplineSurface) aSurface = createSurface();" EOL
446     "" EOL
447     "  // projecting a curve onto a bspline surface" EOL
448     "  Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(aSurface);" EOL
449     "  Handle(GeomAdaptor_HCurve)   HC = new GeomAdaptor_HCurve(aCurve);" EOL
450     "  Standard_Real Tol  = 0.0001;" EOL
451     "  Standard_Real TolU = 0.00001;" EOL
452     "  Standard_Real TolV = 0.00001;" EOL
453     "  ProjLib_CompProjectedCurve Proj(HS,HC,TolU,TolV);" EOL
454     "  " EOL
455     "  // sequence of projected curves" EOL
456     "  TColGeom_SequenceOfCurve aSolutionCurves;" EOL
457     "  " EOL
458     "  Standard_Integer ProjMaxDegree = 8;" EOL
459     "  Standard_Integer ProjMaxSegments = 30;" EOL
460     "  Standard_Real f,l;" EOL
461     "  Standard_Integer aNumSolutions = Proj.NbCurves();" EOL
462     "  for (Standard_Integer i = 1; i <= aNumSolutions; i++)" EOL
463     "  {" EOL
464     "    Proj.Bounds(i,f,l);" EOL
465     "    Handle(Adaptor2d_HCurve2d) HC2d = Proj.Trim(f,l,TolU);" EOL
466     "    Standard_Boolean aOnly3d = Standard_True;" EOL
467     "    Approx_CurveOnSurface Approx(" EOL
468     "      HC2d, HS, f, l, Tol,GeomAbs_C2,ProjMaxDegree,ProjMaxSegments,aOnly3d);" EOL
469     "    " EOL
470     "    if (Approx.IsDone() && Approx.HasResult())" EOL
471     "      aSolutionCurves.Append(Approx.Curve3d());" EOL
472     "  }" EOL
473   );
474   
475   // create a BSpline curve
476   Handle(Geom_BSplineCurve) aCurve = createCurve();
477
478   // create a BSpline surface
479   Handle(Geom_BSplineSurface) aSurface = createSurface();
480
481   // projecting a curve onto a bspline surface
482   Handle(GeomAdaptor_HSurface) HS = new GeomAdaptor_HSurface(aSurface);
483   Handle(GeomAdaptor_HCurve)   HC = new GeomAdaptor_HCurve(aCurve);
484   Standard_Real Tol  = 0.0001;
485   Standard_Real TolU = 0.00001;
486   Standard_Real TolV = 0.00001;
487   ProjLib_CompProjectedCurve Proj(HS,HC,TolU,TolV);
488
489   // sequence of projected curves
490   TColGeom_SequenceOfCurve aSolutionCurves;
491
492   Standard_Integer ProjMaxDegree = 8;
493   Standard_Integer ProjMaxSegments = 30;
494   Standard_Real f,l;
495   Standard_Integer aNumSolutions = Proj.NbCurves();
496   for (Standard_Integer i = 1; i <= aNumSolutions; i++)
497   {
498     Proj.Bounds(i,f,l);
499     Handle(Adaptor2d_HCurve2d) HC2d = Proj.Trim(f,l,TolU);
500     Standard_Boolean aOnly3d = Standard_True;
501     Approx_CurveOnSurface Approx(
502       HC2d, HS, f, l, Tol,GeomAbs_C2,ProjMaxDegree,ProjMaxSegments,aOnly3d);
503     
504     if (Approx.IsDone() && Approx.HasResult())
505       aSolutionCurves.Append(Approx.Curve3d());
506   }
507
508   // output bspline curve
509   drawCurve(aCurve);
510   if(WAIT_A_LITTLE) return;
511
512   // output bspline surface
513   Handle(AIS_InteractiveObject) aCylIO = drawSurface(
514     aSurface, Quantity_Color(Quantity_NOC_YELLOW), Standard_False);
515   getAISContext()->SetTransparency(aCylIO, 0.4, Standard_False);
516   getAISContext()->Display(aCylIO);
517
518   if(WAIT_A_SECOND) return; // wait longer.  "Projecting... Please wait..."
519
520   // output projected curves
521   for (i = 1; i <= aNumSolutions; i++)
522     drawCurve(aSolutionCurves(i), Quantity_Color(Quantity_NOC_GREEN));
523 }
524