1 /*********************************************************************/
2 /* File:   demoview.cpp                                              */
3 /* Author: Robert, Joachim                                           */
4 /* Date:   6. Mar. 2003                                              */
5 /*********************************************************************/
6 
7 
8 #include <mystdlib.h>
9 
10 
11 //#include <iostream.h>
12 #include <myadt.hpp>
13 #include <linalg.hpp>
14 #include <gprim.hpp>
15 #include <csg.hpp>
16 #include <geometry2d.hpp>
17 #include <stlgeom.hpp>
18 #include <meshing.hpp>
19 #include "inctcl.hpp"
20 #include <visual.hpp>
21 
22 namespace netgen {
23 #include "demoview.hpp"
24 
25 
26   /*
27     static demokwstruct defkw[] =
28     {
29     { TOK_TIME,     "t" },
30     { TOK_CAMPOS,   "camerapos" },
31     { TOK_CAMPOINT, "camerapointto" },
32     { TOK_CAMUP,    "cameraup" }
33     };
34   */
35 
36 
37   static demoview_kwstruct demoview_defkw[] =
38     {
39       { DTOK_TIME,     "t" },
40       { DTOK_CAMPOS,   "camerapos" },
41       { DTOK_CAMPOINT, "camerapointto" },
42       { DTOK_CAMUP,    "cameraup" }
43     };
44 
45 
DemoScanner(ifstream & ascanin)46   DemoScanner :: DemoScanner (ifstream & ascanin)
47   {
48     scanin = &ascanin;
49     token = DTOK_END;
50     num_value = 0;
51     linenum = 1;
52   }
53 
54 
55 
ReadNext()56   void DemoScanner :: ReadNext ()
57   {
58     char ch;
59 
60 
61     // whitespaces ueberspringen
62     do
63       {
64 	scanin->get(ch);
65 
66 	if (ch == '\n')
67 	  linenum++;
68 
69 	// end of file reached
70 	if (scanin->eof())
71 	  {
72 	    token = DTOK_END;
73 	    return;
74 	  }
75 
76 	// skip comment line
77 	if (ch == '#')
78 	  {
79 	    while (ch != '\n')
80 	      {
81 		scanin->get(ch);
82 		if (scanin->eof())
83 		  {
84 		    token = DTOK_END;
85 		    return;
86 		  }
87 	      }
88 	    linenum++;
89 	  }
90       }
91     while (isspace(ch));
92 
93     switch (ch)
94       {
95       case '(': case ')':
96       case '[': case ']':
97       case '-': case ':':
98       case '=': case ',':
99       case ';': case '+':
100 	{
101 	  token = DEMOVIEW_TOKEN_TYPE (ch);
102 	  break;
103 	}
104 
105       default:
106 	{
107 	  if (isdigit (ch) || ch == '.')
108 	    {
109 	      scanin->putback (ch);
110 	      (*scanin) >> num_value;
111 	      token = DTOK_NUM;
112 	      return;
113 	    }
114 
115 	  if (isalpha (ch))
116 	    {
117 	      string_value = string (1, ch);
118 	      scanin->get(ch);
119 	      while (isalnum(ch))
120 		{
121 		  string_value += ch;
122 		  scanin->get(ch);
123 		}
124 	      scanin->putback (ch);
125 	    }
126 
127 	  int nr = 0;
128 	  while (demoview_defkw[nr].kw)
129 	    {
130 	      if (string_value == demoview_defkw[nr].name)
131 		{
132 		  token = demoview_defkw[nr].kw;
133 		  return;
134 		}
135 	      nr++;
136 	    }
137 
138 	  token = DTOK_STRING;
139 	}
140       }
141   }
142 
143 
144 
Error(const string & err)145   void DemoScanner :: Error (const string & err)
146   {
147     stringstream errstr;
148     errstr << "Parsing error in line " << linenum << ": " << endl << err << endl;
149     throw string(errstr.str());
150   }
151 
152 
153 
ParseChar(DemoScanner & scan,char ch)154   void ParseChar (DemoScanner & scan, char ch)
155   {
156     char str[2];
157     str[0] = ch;
158     str[1] = 0;
159     if (scan.GetToken() != DEMOVIEW_TOKEN_TYPE(ch))
160       scan.Error (string ("token '") + string(str) + string("' expected"));
161     scan.ReadNext();
162   }
163 
164 
165 
ParseNumber(DemoScanner & scan)166   double ParseNumber(DemoScanner & scan)
167   {
168     if (scan.GetToken() == '-')
169       {
170 	scan.ReadNext();
171 	return -ParseNumber (scan);
172       }
173     if (scan.GetToken() != DTOK_NUM) scan.Error ("number expected");
174     double val = scan.GetNumValue();
175     scan.ReadNext();
176     return val;
177   }
178 
179 
ParseVector(DemoScanner & scan)180   Vec<3> ParseVector (DemoScanner & scan)
181   {
182     Vec<3> s;
183 
184     s(0) = ParseNumber (scan);
185     ParseChar (scan, ',');
186 
187     s(1) = ParseNumber (scan);
188     ParseChar (scan, ',');
189 
190     s(2) = ParseNumber (scan);
191 
192     return s;
193   }
194 
195 
ParseConstLineOrSpline(DemoScanner & scan,double * t,Vec<3> * s)196   void ParseConstLineOrSpline (DemoScanner & scan, double * t, Vec<3> * s)
197   {
198     int np = 1;
199 
200     scan.ReadNext();
201     ParseChar (scan, '(');
202 
203     t[0] = ParseNumber (scan)*1000;
204     ParseChar (scan, ':');
205 
206     s[0] = ParseVector (scan);
207 
208     if (scan.GetToken() != DTOK_RP &&
209 	scan.GetToken() != DTOK_SEMICOLON)
210       scan.Error (") or ; expected");
211 
212     if (scan.GetToken() == DTOK_SEMICOLON)
213       {
214 	np++;
215 
216 	scan.ReadNext();
217 
218 	t[1] = ParseNumber (scan)*1000;
219 	ParseChar (scan, ':');
220 
221 	s[1] = ParseVector (scan);
222 
223 	if (scan.GetToken() != DTOK_RP &&
224 	    scan.GetToken() != DTOK_SEMICOLON)
225 	  scan.Error (") or ; expected");
226 
227 	if (scan.GetToken() == DTOK_SEMICOLON)
228 	  {
229 	    np++;
230 
231 	    scan.ReadNext();
232 
233 	    t[2] = ParseNumber (scan)*1000;
234 	    ParseChar (scan, ':');
235 
236 	    s[2] = ParseVector (scan);
237 
238 	    ParseChar (scan, ')');
239 	    ParseChar (scan, ';');
240 	  }
241 	else if (scan.GetToken() == DTOK_RP)
242 	  {
243 	    scan.ReadNext();
244 	    ParseChar (scan, ';');
245 	  }
246       }
247     else if (scan.GetToken() == DTOK_RP)
248       {
249 	scan.ReadNext();
250 	ParseChar (scan, ';');
251       }
252 
253     if (np == 1) // constant spline
254       {
255 	t[1] = t[2] = t[0];
256 	s[1] = s[2] = s[0];
257       }
258     if (np == 2) // linear spline
259       {
260 	t[2] = t[1]; t[1] = 0.5*(t[0] + t[2]);
261 	s[2] = s[1]; s[1] = 0.5*(s[0] + s[2]);
262       }
263   }
264 
265 
266 
267 
268   template <class S>
AddSpline(double t1,double t2,double t3,S s1,S s2,S s3)269   void InterpolationSpline<S> :: AddSpline(double t1, double t2, double t3, S s1, S s2, S s3)
270   {
271     int pos, i, j;
272     // find pos to insert interpotation point
273     for (pos = 0; pos < ip.Size() && ip[pos][0].GetT() < t1; pos++) ;
274 
275     ip.SetSize( ip.Size()+1 );
276     for (i = ip.Size()-2; i >= pos; i--)
277       for (j = 0; j < 3; j++)
278 	ip[i+1][j] = ip[i][j];
279 
280     ip[pos][0].SetTS (t1, s1);
281     ip[pos][1].SetTS (t2, s2);
282     ip[pos][2].SetTS (t3, s3);
283   }
284 
285 
286 
287   template <class S>
Evaluate(double t)288   S InterpolationSpline<S> :: Evaluate (double t)
289   {
290     if (t < ip[0][0].GetT())
291       return (ip[0][0].GetS());
292 
293     if (t > ip[ip.Size()-1][2].GetT())
294       {
295 	finished = 1;
296 	return (ip[ip.Size()-1][2].GetS());
297       }
298 
299     int pos;
300     for (pos = 0; pos < ip.Size() && t >= ip[pos][0].GetT(); pos++) ;
301     pos--;
302 
303     if (t >= ip[pos][0].GetT() && t <= ip[pos][2].GetT())
304       {
305 	double t0 = ip[pos][0].GetT();
306 	double t1 = ip[pos][2].GetT();
307 
308 	double t01 = (t-t0)/(t1-t0);
309 
310 	double b1, b2, b3, w;
311 
312 	b1 = (1-t01)*(1-t01);
313 	b2 = sqrt(2.0) * t01 * (1-t01);
314 	b3 = t01 * t01;
315 	w = b1 + b2 + b3;
316 
317 	return ( (1/w) * (b1 * ip[pos][0].GetS() +
318 			  b2 * ip[pos][1].GetS() +
319 			  b3 * ip[pos][2].GetS()) );
320       }
321     else
322       return (ip[pos][2].GetS());
323   }
324 
325 
326 
DemoView(const char * filename)327   DemoView :: DemoView (const char * filename)
328     : campos( Vec<3>(5,0,0) ),
329       campoint ( Vec<3>(0,0,0) ),
330       camup ( Vec<3>(0,0,1) )
331   {
332     double time = 0;
333 
334     ifstream istr;
335     istr.open(filename);
336 
337     DemoScanner scan(istr);
338 
339     double t[3];
340     Vec<3> s[3];
341 
342     scan.ReadNext();
343 
344     try
345       {
346 	while (1)
347 	  {
348 	    if (scan.GetToken() == DTOK_END) break;
349 
350 	    if (scan.GetToken() == DTOK_CAMPOS)
351 	      {
352 		ParseConstLineOrSpline (scan, &t[0], &s[0]);
353 		campos.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]);
354 	      }
355 
356 	    else if (scan.GetToken() == DTOK_CAMUP)
357 	      {
358 		ParseConstLineOrSpline (scan, &t[0], &s[0]);
359 		camup.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]);
360 	      }
361 
362 	    else if (scan.GetToken() == DTOK_CAMPOINT)
363 	      {
364 		ParseConstLineOrSpline (scan, &t[0], &s[0]);
365 		campoint.AddSpline (time+t[0], time+t[1], time+t[2], s[0], s[1], s[2]);
366 	      }
367 
368 	    else if (scan.GetToken() == DTOK_TIME)
369 	      {
370 		scan.ReadNext();
371 
372 		if (scan.GetToken() != DTOK_EQU &&
373 		    scan.GetToken() != DTOK_PLUS)
374 		  scan.Error ("= or += expected");
375 
376 		if (scan.GetToken() == DTOK_EQU)
377 		  {
378 		    scan.ReadNext();
379 		    time = ParseNumber (scan)*1000;
380 		    ParseChar (scan, ';');
381 		  }
382 		else if (scan.GetToken() == DTOK_PLUS)
383 		  {
384 		    scan.ReadNext();
385 		    ParseChar (scan, '=');
386 		    time += ParseNumber (scan)*1000;
387 		    ParseChar (scan, ';');
388 		  }
389 	      }
390 
391 	    else
392 	      {
393 		cout << "read unidentified token " << scan.GetToken()
394 		     << " string = " << scan.GetStringValue() << endl;
395 		scan.ReadNext();
396 	      }
397 	  }
398       }
399     catch (string errstr)
400       {
401 	cout << "caught error " << errstr << endl;
402       }
403 
404 
405   }
406 
407 
~DemoView()408   DemoView :: ~DemoView ()
409   {
410     ;
411   }
412 
SetTime(double time)413   int DemoView :: SetTime (double time)
414   {
415     /*
416       cout << "time = " << time << endl;
417 
418       cout << "campos  : " << campos.Evaluate (time) << endl;
419       cout << "campoint: " << campoint.Evaluate (time) << endl;
420       cout << "camup   : " << camup.Evaluate (time) << endl;
421     */
422 
423 
424     visual_scene -> LookAt ( Point<3>(  campos.Evaluate (time)),
425 		   Point<3>(campoint.Evaluate (time)),
426 		   Point<3>(   camup.Evaluate (time)) );
427 
428     if (campos.IsFinished() &&
429 	campoint.IsFinished() &&
430 	camup.IsFinished())
431       {
432 	return -1;
433       }
434 
435     return 0;
436   }
437 
438 
439 }
440