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