0028316: Coding Rules - Elimilate confusing aliases of Standard_Real type in V3d_View
[occt.git] / samples / mfc / occtdemo / Interpol / Interpol_Presentation.cpp
1 // Interpol_Presentation.cpp: implementation of the Interpol_Presentation class.
2 //
3 //////////////////////////////////////////////////////////////////////
4
5 #include "stdafx.h"
6 #include "Interpol_Presentation.h"
7
8 #include <gp_Pnt.hxx>
9 #include <TColgp_HArray1OfPnt.hxx>
10 #include <Precision.hxx>
11 #include <GeomAPI_Interpolate.hxx>
12 #include <Geom_BSplineCurve.hxx>
13 #include <gp_Vec.hxx>
14 #include <TColStd_HArray1OfBoolean.hxx>
15 #include <TColgp_Array1OfVec.hxx>
16 #include <TColStd_Array1OfInteger.hxx>
17 #include <TColStd_Array1OfReal.hxx>
18 #include <GeomLProp_CLProps.hxx>
19 #include <GeomAPI_ProjectPointOnCurve.hxx>
20
21 #ifdef WNT
22  #define EOL "\r\n"
23 #else
24  #define EOL "\n"
25 #endif
26
27 // Initialization of global variable with an instance of this class
28 OCCDemo_Presentation* OCCDemo_Presentation::Current = new Interpol_Presentation;
29
30 // Initialization of array of samples
31 const Interpol_Presentation::PSampleFuncType Interpol_Presentation::SampleFuncs[] =
32 {
33   &Interpol_Presentation::sample1,
34   &Interpol_Presentation::sample2,
35   &Interpol_Presentation::sample3,
36 };
37
38 //////////////////////////////////////////////////////////////////////
39 // Construction/Destruction
40 //////////////////////////////////////////////////////////////////////
41
42 Interpol_Presentation::Interpol_Presentation()
43 {
44   myIndex = 0;
45   myNbSamples = sizeof(SampleFuncs)/sizeof(PSampleFuncType);
46   setName ("Interpolation of a set of points to form a curve");
47 }
48
49 //////////////////////////////////////////////////////////////////////
50 // Sample execution
51 //////////////////////////////////////////////////////////////////////
52
53 void Interpol_Presentation::DoSample()
54 {
55   setResultTitle("Interpolation");
56   getAISContext()->EraseAll();
57
58   if (myIndex >=0 && myIndex < myNbSamples)
59     (this->*SampleFuncs[myIndex])();
60 }
61
62
63 //================================================================
64 // Function : calculateNewTangent
65 // Purpose  : finds a tangent at the given point on the given curve,
66 //  rotate it by <angle> in the plane of the tangent and normal to
67 //  the curve in this point.
68 // Output   : vectors theTan, theNewTan.
69 // Returns  : false if failed, true if ok.
70 //================================================================
71 static Standard_Boolean calculateNewTangent(const Handle(Geom_BSplineCurve)& anInterpolationCurve, 
72                                             gp_Pnt aPointOnCurve, gp_Vec& theTan, gp_Vec& theNewTan,
73                                             Standard_Real angle)
74 {
75   GeomLProp_CLProps aLProps (anInterpolationCurve, 2, Precision::Confusion());
76   GeomAPI_ProjectPointOnCurve aProjector(aPointOnCurve, anInterpolationCurve);
77   aLProps.SetParameter (aProjector.LowerDistanceParameter());
78   gp_Dir aTangent, aNormal;
79   // the tangent and must be defined to compute the normal
80   if (aLProps.IsTangentDefined())
81   {
82     aLProps.Tangent (aTangent);
83     Standard_Real aCurvature = aLProps.Curvature();
84     // the curvature must be non-null and finite to compute the normal
85     if (aCurvature > Precision::Confusion() && !Precision::IsInfinite(aCurvature))
86       aLProps.Normal (aNormal);
87     else return Standard_False;
88   }
89   else return Standard_False;
90
91   gp_Dir aPlaneNormal(aTangent.XYZ() ^ aNormal.XYZ());
92   gp_Ax1 anAx(aPointOnCurve, aPlaneNormal);
93   theTan = aTangent; 
94   theNewTan = theTan.Rotated(anAx, angle);
95
96   return Standard_True;
97 }
98
99
100 //================================================================
101 // Function : interpolate
102 // Purpose  : builds interpolation curve using given Pnts 
103 //================================================================
104 void Interpol_Presentation::interpolate (Standard_Real aCoords[][3],
105                                          Standard_Integer nPnts,
106                                          TCollection_AsciiString& theText,
107                                          const TColStd_Array1OfInteger& indexes,
108                                          const TColStd_Array1OfReal& angles)
109 {
110   theText += EOL
111     "  Standard_Integer nPnts = sizeof(aCoords)/(sizeof(Standard_Real)*3);" EOL
112     "  Handle(TColgp_HArray1OfPnt) aPnts = new TColgp_HArray1OfPnt(1, nPnts);" EOL
113     "  for (Standard_Integer i=0; i < nPnts; i++)" EOL
114     "  {" EOL
115     "    gp_Pnt aPnt(aCoords[i][0]*75-400, aCoords[i][1]*75-400, aCoords[i][2]*75-400);" EOL
116     "    aPnts->SetValue(i+1, aPnt);" EOL
117     "    drawPoint(aPnt);" EOL
118     "    if (WaitForInput(250)) return;" EOL
119     "  }" EOL EOL
120
121     "  //=====================================" EOL
122     "  // Creating a non periodic interpolation curve without constraints " EOL
123     "  // (type of resulting curve is BSpline)" EOL
124     "  Standard_Boolean isPeriodic = Standard_False;" EOL
125     "  GeomAPI_Interpolate aNoPeriodInterpolate(aPnts, isPeriodic, Precision::Confusion());" EOL
126     "  aNoPeriodInterpolate.Perform();" EOL
127     "  // check results" EOL
128     "  if (!aNoPeriodInterpolate.IsDone()) return;" EOL
129     "  Handle(Geom_BSplineCurve) anInterpolationCurve = aNoPeriodInterpolate.Curve();" EOL EOL
130
131     "  //===================================" EOL
132     "  // Creating a constrained interpolation curve" EOL
133     "  TColgp_Array1OfVec aConstraints(1, nPnts);" EOL
134     "  Handle(TColStd_HArray1OfBoolean) aFlags = new TColStd_HArray1OfBoolean(1, nPnts);" EOL
135     "  Handle(TColStd_HArray1OfBoolean) aCopyFlags = new TColStd_HArray1OfBoolean(1, nPnts);" EOL
136     "  Standard_Boolean toScale = Standard_False;" EOL EOL
137
138     "  // some code initializing arrays aConstraints and aCopyFlags" EOL
139     "  aCopyFlags->Init(Standard_False);" EOL
140     "  aCopyFlags->SetValue(1, Standard_True);" EOL
141     "  aConstraints(1) = aTanVec;" EOL
142     "  // ..." EOL
143     "  //" EOL EOL
144
145     "  // Loading constraints and perform" EOL
146     "  aFlags->ChangeArray1() = aCopyFlags->Array1();" EOL
147     "  aNoPeriodInterpolate.Load(aConstraints, aFlags, toScale);" EOL
148     "  aNoPeriodInterpolate.Perform();" EOL
149     "  // check results" EOL
150     "  if (!aNoPeriodInterpolate.IsDone()) return;" EOL
151     "  anInterpolationCurve = aNoPeriodInterpolate.Curve();" EOL EOL
152
153     "  //==================================================" EOL
154     "  // Creating a periodic interpolation curve" EOL
155     "  isPeriodic = Standard_True;" EOL
156     "  GeomAPI_Interpolate aPeriodInterpolate(aPnts, isPeriodic, Precision::Confusion());" EOL
157     "  // Loading constraints and perform" EOL
158     "  aFlags->ChangeArray1() = aCopyFlags->Array1();" EOL
159     "  aPeriodInterpolate.Load(aConstraints, aFlags, toScale);" EOL
160     "  aPeriodInterpolate.Perform();" EOL
161     "  // check results" EOL
162     "  if (!aPeriodInterpolate.IsDone()) return;" EOL
163     "  anInterpolationCurve = aPeriodInterpolate.Curve();" EOL;
164
165   setResultText(theText.ToCString());
166
167   Handle(TColgp_HArray1OfPnt) aPnts = new TColgp_HArray1OfPnt(1, nPnts);
168   for (Standard_Integer i=0; i < nPnts; i++)
169   {
170     gp_Pnt aPnt(aCoords[i][0]*75-400, aCoords[i][1]*75-400, aCoords[i][2]*75-400);
171     aPnts->SetValue(i+1, aPnt);
172     drawPoint(aPnt);
173     if (WaitForInput(250)) return;
174   }
175   
176   //=====================================
177   // Creating a non periodic interpolation curve without constraints 
178   // (type of resulting curve is BSpline)
179   Standard_Boolean isPeriodic = Standard_False;
180   GeomAPI_Interpolate aNoPeriodInterpolate(aPnts, isPeriodic, Precision::Confusion());
181   aNoPeriodInterpolate.Perform();
182   // check results
183   if (!aNoPeriodInterpolate.IsDone()) return;
184   Handle(Geom_BSplineCurve) anInterpolationCurve = aNoPeriodInterpolate.Curve();
185
186   Handle(AIS_InteractiveObject) aShowCurve = drawCurve(anInterpolationCurve);
187   if (WAIT_A_SECOND) return;
188      
189   //===================================
190   // Creating several constrained interpolation curves
191   TColgp_Array1OfVec aConstraints(1, nPnts);
192   Handle(TColStd_HArray1OfBoolean) aFlags = new TColStd_HArray1OfBoolean(1, nPnts);
193   Handle(TColStd_HArray1OfBoolean) aCopyFlags = new TColStd_HArray1OfBoolean(1, nPnts);
194   Standard_Boolean toScale = Standard_False;
195   Standard_Real scaleVec = 1;
196   aCopyFlags->Init(Standard_False);
197
198   Handle(AIS_InteractiveObject) aShowTan;
199   for (i = indexes.Lower(); i <= indexes.Upper(); i++)
200   {
201     gp_Pnt aPoint = aPnts->Value(indexes(i));
202     Standard_Real anAngle = angles(i);
203
204     gp_Vec aTan, aNewTan;
205     if (!calculateNewTangent(anInterpolationCurve, aPoint, aTan, aNewTan, anAngle))
206       return;
207
208     if (!aShowTan.IsNull()) getAISContext()->Erase(aShowTan);
209     aShowTan = drawVector(aPoint, aTan.Scaled(300));
210     if (WAIT_A_LITTLE) return;
211
212     aCopyFlags->SetValue(indexes(i), Standard_True);
213     aConstraints(indexes(i)) = aNewTan * scaleVec;
214
215     aFlags->ChangeArray1() = aCopyFlags->Array1();
216     aNoPeriodInterpolate.Load(aConstraints, aFlags, toScale);
217     aNoPeriodInterpolate.Perform();
218
219     if (!aNoPeriodInterpolate.IsDone()) return;
220
221     // replacing the curve with a new one, so calculation of the next tagent
222     // on the next point from indexes will be done using the new curve
223     anInterpolationCurve = aNoPeriodInterpolate.Curve();
224
225     // display a new curve and new vector
226     getAISContext()->Erase(aShowTan);
227     getAISContext()->Erase(aShowCurve);
228     aShowCurve = drawCurve(anInterpolationCurve);
229     aShowTan = drawVector(aPoint, aNewTan.Scaled(300));
230
231     if (WAIT_A_SECOND) return;
232   }
233
234   //==================================================
235   // Creating a periodic interpolation curve
236   isPeriodic = Standard_True;
237   GeomAPI_Interpolate aPeriodInterpolate(aPnts, isPeriodic, Precision::Confusion());
238
239   aFlags->ChangeArray1() = aCopyFlags->Array1();
240   aPeriodInterpolate.Load(aConstraints, aFlags, toScale);
241   aPeriodInterpolate.Perform();
242
243   // the interpolation can not be computed
244   if (!aPeriodInterpolate.IsDone()) return;
245
246   anInterpolationCurve = aPeriodInterpolate.Curve();
247
248   getAISContext()->Erase(aShowTan);
249   getAISContext()->Erase(aShowCurve);
250   drawCurve(anInterpolationCurve);
251 }
252
253 //////////////////////////////////////////////////////////////////////
254 // Sample functions
255 //////////////////////////////////////////////////////////////////////
256 //================================================================
257 // Function : Interpol_Presentation::sample1
258 // Purpose  : 
259 //================================================================
260 void Interpol_Presentation::sample1()
261 {
262   ResetView();
263   SetViewCenter(-43,-333);
264   SetViewScale(1.4210);
265   
266   TCollection_AsciiString aText(
267     "  // initializing array of points to interpolate" EOL
268     "  Standard_Real aCoords[][3] = {{0,0,0},{3,5,0},{4,7,0},{10,10,0}};" EOL
269   );
270
271   // initializing array of interpolation curve Pnts
272   Standard_Real aCoords[][3] = {{0,0,0},{3,5,0},{4,7,0},{10,10,0}};
273
274   // initializing array of indexes of points where the constraints will be applied
275   TColStd_Array1OfInteger indexes(1,2);
276   indexes(1) = 1; 
277   indexes(2) = 2;
278
279   // initializing array of angles of tagent rotation in the points
280   // with indexes from the array defined above.
281   TColStd_Array1OfReal aAngles(1,2);
282   aAngles(1) = PI/2; 
283   aAngles(2) = -PI/4;
284   
285   interpolate(aCoords, sizeof(aCoords)/(sizeof(Standard_Real)*3), 
286     aText, indexes, aAngles);
287 }
288
289
290 //================================================================
291 // Function : Interpol_Presentation::sample2
292 // Purpose  : 
293 //================================================================
294 void Interpol_Presentation::sample2()
295 {
296   ResetView();
297   SetViewCenter(-148.74,-603.06);
298   SetViewScale(1.09);
299
300   TCollection_AsciiString aText(
301     "  // initializing array of points to interpolate" EOL
302     "  Standard_Real aCoords[][3] = {{0,-1,0},{1,1,0},{4,5,0},{9,0,0},{13,3,0},{16,-5,0}};" EOL
303   );
304
305   // initializing array of interpolation curve Pnts
306   Standard_Real aCoords[][3] = {{0,-1,0},{1,1,0},{4,5,0},{9,0,0},{13,3,0},{16,-5,0}};
307
308   // initializing array of indexes of points where the constraints will be applied
309   TColStd_Array1OfInteger indexes(1,3);
310   indexes(1) = 1; 
311   indexes(2) = 2; 
312   indexes(3) = 6;
313
314   // initializing array of angles of tagent rotation in the points
315   // with indexes from the array defined above.
316   TColStd_Array1OfReal aAngles(1,3);
317   aAngles(1) = -PI/4; 
318   aAngles(2) = -PI/3; 
319   aAngles(3) = +PI/3;
320   
321   interpolate(aCoords, sizeof(aCoords)/(sizeof(Standard_Real)*3), 
322     aText, indexes, aAngles);
323 }
324
325
326 //================================================================
327 // Function : Interpol_Presentation::sample3
328 // Purpose  : 
329 //================================================================
330 void Interpol_Presentation::sample3()
331 {
332   ResetView();
333   SetViewCenter(374.27539,185.40618);
334   SetViewScale(0.87185);
335
336
337         TCollection_AsciiString aText(
338     "  // initializing array of points to interpolate" EOL
339     "  Standard_Real aCoords[][3] = {{10,0,11},{13,15,10},{7,13,12},{10,0,5}};" EOL
340   );
341
342   // initializing array of interpolation curve Pnts
343   Standard_Real aCoords[][3] = {{10,0,11},{13,15,10},{7,13,12},{5,5,9}};
344   TColStd_Array1OfInteger indexes(1,2);
345   indexes(1) = 2; indexes(2) = 4;
346   TColStd_Array1OfReal aAngles(1,2);
347   aAngles(1) = PI/4; aAngles(2) = -PI/3;
348   
349   interpolate(aCoords, sizeof(aCoords)/(sizeof(Standard_Real)*3), 
350     aText, indexes, aAngles);
351 }