1 //#**************************************************************
2 //#
3 //# filename: drawsystem.cpp
4 //#
5 //# author: Gerstmayr Johannes
6 //#
7 //# generated: September 2010
8 //# description: Driver and model for timeintegration
9 //# Model of a rigid arm and a hydraulic zylinder
10 //# remarks:
11 //#
12 //# Copyright (c) 2003-2013 Johannes Gerstmayr, Linz Center of Mechatronics GmbH, Austrian
13 //# Center of Competence in Mechatronics GmbH, Institute of Technical Mechanics at the
14 //# Johannes Kepler Universitaet Linz, Austria. All rights reserved.
15 //#
16 //# This file is part of HotInt.
17 //# HotInt is free software: you can redistribute it and/or modify it under the terms of
18 //# the HOTINT license. See folder 'licenses' for more details.
19 //#
20 //# bug reports are welcome!!!
21 //# WWW: www.hotint.org
22 //# email: bug_reports@hotint.org or support@hotint.org
23 //#***************************************************************************************
24
25 #include "mbs.h"
26 #include "element.h"
27 #include "graphicsConstants.h"
28 #include "node.h"
29 #include "sensors.h"
30
DrawSystem()31 void MultiBodySystem::DrawSystem()
32 {
33 if (GetProhibitRedraw()) return;
34
35 GetRC()->PrintTextStruct(0,-1," HOTINT");
36
37 TMStartTimer(2);
38
39 GetRC()->SetBackgroundColor(1.,1.,1.);
40 const Vector& x = GetDrawVector();
41
42 GetRC()->SetTextColor(0.,0.,0.);
43
44 if (GetCenterObject() != 0)
45 {
46 Vector3D bodypos = GetElement(GetCenterObject()).GetRefPosD();
47 bodypos += GetCenterObjectOffset();
48 GetRC()->SetCenterOffset((float)bodypos.X(),(float)bodypos.Y(),(float)bodypos.Z());
49 }
50
51 char str[100];
52 sprintf(str," time=%4.4g s ", GetDrawTime());
53 //sprintf(str," time=%3.3g days ", GetDrawTime()/(24*3600));
54
55 //if (!GetIOption(116))
56 {
57 GetRC()->PrintTextStruct(3,-1,str);
58 }
59
60 if (GetIOption(106))
61 {
62 //Draw Origin ...
63 SetColor(colgrey3);
64 double s = GetDOption(103);
65 Vector3D v1(-0.3*s, 0,0);
66 Vector3D v2( s, 0,0);
67 Vector3D v3( 0,-0.3*s,0);
68 Vector3D v4( 0, s,0);
69 Vector3D v5( 0,0,-0.3*s);
70 Vector3D v6( 0,0, s);
71 double d = GetDOption(114); //global line thickness
72 MyDrawLine(v1,v2,d);
73 MyDrawLine(v3,v4,d);
74 MyDrawLine(v5,v6,d);
75
76 GetRC()->PrintText3D((float)v2.X(), (float)v2.Y(), (float)v2.Z(), "X0");
77 GetRC()->PrintText3D((float)v4.X(), (float)v4.Y(), (float)v4.Z(), "Y0");
78 GetRC()->PrintText3D((float)v6.X(), (float)v6.Y(), (float)v6.Z(), "Z0");
79 }
80
81 //!AD 2012-12-14 new scene background use the entries in the options used for option Grid...
82 if(GetIOption(126))
83 {
84 // UNDER CONSTRUCTION !
85 // 6 options for size of RECTANGLES
86 double refpos_x = GetDOption(107);
87 double refpos_y = GetDOption(108);
88 double refpos_z = GetDOption(109);
89 double size_of_plane_x = GetDOption(112);
90 double size_of_plane_y = GetDOption(113);
91 double size_of_plane_z = GetDOption(142);
92
93 // 5 options for GRID DISCRETIZATION
94 double size_of_grid_x = GetDOption(110);
95 double size_of_grid_y = GetDOption(111);
96 double size_of_grid_z = GetDOption(143);
97 int lines_crosses_dots = 1; // HARDCODED: ALWAYS LINES ( code for dots stays in )
98 int max_gridlines = 200; // HARDCODED ON DEMAND
99
100 // 10 options for COLOR
101 float color_p1r = (float) GetDOption(133); float color_p1g = (float) GetDOption(134); float color_p1b = (float) GetDOption(135);
102 float color_p2r = (float) GetDOption(136); float color_p2g = (float) GetDOption(137); float color_p2b = (float) GetDOption(138);
103 float color_p3r = (float) GetDOption(139); float color_p3g = (float) GetDOption(140); float color_p3b = (float) GetDOption(141);
104 float background_transparency_factor = GetDOption(144);
105
106 // IOption 126 must be nonzero to activate
107 double global_line_thickness = GetDOption(114);
108 double global_point_size = GetDOption(117);
109
110
111 // account for maximum number of grid lines
112 int nr_of_gridlines_x = (int) abs(size_of_plane_x/size_of_grid_x) +0.5; // excluding the 0-th line
113 if (nr_of_gridlines_x > max_gridlines) { nr_of_gridlines_x = max_gridlines; size_of_grid_x = abs(size_of_plane_x / max_gridlines); }
114 int nr_of_gridlines_y = (int) abs(size_of_plane_y/size_of_grid_y) +0.5; // excluding the 0-th line
115 if (nr_of_gridlines_y > max_gridlines) { nr_of_gridlines_y = max_gridlines; size_of_grid_y = abs(size_of_plane_y / max_gridlines); }
116 int nr_of_gridlines_z = (int) abs(size_of_plane_z/size_of_grid_z) +0.5; // excluding the 0-th line
117 if (nr_of_gridlines_z > max_gridlines) { nr_of_gridlines_z = max_gridlines; size_of_grid_z = abs(size_of_plane_z / max_gridlines); }
118
119
120 Vector3D p0(refpos_x, refpos_y, refpos_z); // intersection point of the planes
121 int active_flag = GetIOption(126);
122 // draw the planes
123 if(active_flag & 1)
124 {
125 pCurrentRC->glColor4f(color_p1r, color_p1g, color_p1b, background_transparency_factor);
126 TArray<Vector3D> ptsxy; ptsxy.Add(p0); ptsxy.Add(p0+Vector3D(size_of_plane_x,0.,0.)); ptsxy.Add(p0+Vector3D(size_of_plane_x,size_of_plane_y,0.)); ptsxy.Add(p0+Vector3D(0.,size_of_plane_y,0.));
127 DrawQuad( ptsxy(1), ptsxy(2), ptsxy(3), ptsxy(4) );
128 DrawPolygonOutline( ptsxy, global_line_thickness );
129 }
130 if(active_flag & 2)
131 {
132 pCurrentRC->glColor4f(color_p2r, color_p2g, color_p2b, background_transparency_factor);
133 TArray<Vector3D> ptsxz; ptsxz.Add(p0); ptsxz.Add(p0+Vector3D(size_of_plane_x,0.,0.)); ptsxz.Add(p0+Vector3D(size_of_plane_x,0.,size_of_plane_z)); ptsxz.Add(p0+Vector3D(0.,0.,size_of_plane_z));
134 DrawQuad( ptsxz(1), ptsxz(2), ptsxz(3), ptsxz(4) );
135 DrawPolygonOutline( ptsxz, global_line_thickness );
136 }
137 if(active_flag & 4)
138 {
139 pCurrentRC->glColor4f(color_p3r, color_p3g, color_p3b, background_transparency_factor);
140 TArray<Vector3D> ptsyz; ptsyz.Add(p0); ptsyz.Add(p0+Vector3D(0.,size_of_plane_y,0.)); ptsyz.Add(p0+Vector3D(0.,size_of_plane_y,size_of_plane_z)); ptsyz.Add(p0+Vector3D(0.,0.,size_of_plane_z));
141 DrawQuad( ptsyz(1), ptsyz(2), ptsyz(3), ptsyz(4) );
142 DrawPolygonOutline( ptsyz, global_line_thickness );
143 }
144
145 // account for negative size ( extends in negative axis direction )
146 Vector3D ex(1.,0.,0.); if(size_of_plane_x<0) ex.X() = -1.;
147 Vector3D ey(0.,1.,0.); if(size_of_plane_y<0) ey.Y() = -1.;
148 Vector3D ez(0.,0.,1.); if(size_of_plane_z<0) ez.Z() = -1.;
149
150 Vector3D old_color_line = colline;
151 colline = Vector3D(0.8,0.8,0.8);
152 if(lines_crosses_dots == 1) // GRID LINES
153 {
154 Vector3D p1,p2;
155 for(int ix=0; ix<=nr_of_gridlines_x; ix++)
156 {
157 p1 = p0 + ex*size_of_grid_x*ix;
158 p2 = p0 + ex*size_of_grid_x*ix + Vector3D(0.,size_of_plane_y,0.);
159 if (active_flag & 1)
160 MyDrawLine(p1, p2, global_line_thickness); // this is a line on the XY plane
161 p2 = p0 + ex*size_of_grid_x*ix + Vector3D(0.,0.,size_of_plane_z);
162 if (active_flag & 2)
163 MyDrawLine(p1, p2, global_line_thickness); // this is a line on the XZ plane
164 }
165 for(int iy=0; iy<=nr_of_gridlines_y; iy++)
166 {
167 p1 = p0 + ey*size_of_grid_y*iy;
168 p2 = p0 + ey*size_of_grid_y*iy + Vector3D(size_of_plane_x,0.,0.);
169 if (active_flag & 1)
170 MyDrawLine(p1, p2, global_line_thickness); // this is a line on the XY plane
171 p2 = p0 + ey*size_of_grid_y*iy + Vector3D(0.,0.,size_of_plane_z);
172 if (active_flag & 4)
173 MyDrawLine(p1, p2, global_line_thickness); // this is a line on the YZ plane
174 }
175 for(int iz=0; iz<=nr_of_gridlines_z; iz++)
176 {
177 p1 = p0 + ez*size_of_grid_z*iz;
178 p2 = p0 + ez*size_of_grid_z*iz + Vector3D(size_of_plane_x,0.,0.);
179 if (active_flag & 2)
180 MyDrawLine(p1, p2, global_line_thickness); // thie is a line on the XZ plane
181 p2 = p0 + ez*size_of_grid_z*iz + Vector3D(0.,size_of_plane_y,0.);
182 if (active_flag & 4)
183 MyDrawLine(p1, p2, global_line_thickness); // this is a line on the YZ plane
184 }
185 colline = old_color_line;
186 }
187 /* else if(lines_crosses_dots == 2) { ; } // crosses not implemented yet */
188 else // GRID DOTS
189 {
190 Vector3D p1;
191 ChooseColor((float)colline[0],(float)colline[1],(float)colline[2]);
192 GetRC()->ChoosePointSize((float)global_point_size);
193
194 GetRC()->glBeginPoints();
195 if (active_flag & 1)
196 {
197 for(int ix=0; ix<=nr_of_gridlines_x; ix++)
198 {
199 for(int iy=0; iy<=nr_of_gridlines_y; iy++)
200 {
201 p1 = p0 + ex*size_of_grid_x*ix + ey*size_of_grid_y*iy;
202 GetRC()->glVertex((float)p1.X(), (float)p1.Y(), (float)p1.Z());
203 }
204 }
205 }
206 if (active_flag & 2)
207 {
208 for(int ix=0; ix<=nr_of_gridlines_x; ix++)
209 {
210 for(int iz=0; iz<=nr_of_gridlines_z; iz++)
211 {
212 p1 = p0 + ex*size_of_grid_x*ix + ez*size_of_grid_z*iz;
213 GetRC()->glVertex((float)p1.X(), (float)p1.Y(), (float)p1.Z());
214 }
215 }
216 }
217 if (active_flag & 4)
218 {
219 for(int iy=0; iy<=nr_of_gridlines_y; iy++)
220 {
221 for(int iz=0; iz<=nr_of_gridlines_z; iz++)
222 {
223 p1 = p0 + ey*size_of_grid_y*iy + ez*size_of_grid_z*iz;
224 GetRC()->glVertex((float)p1.X(), (float)p1.Y(), (float)p1.Z());
225 }
226 }
227 }
228 GetRC()->glEnd();
229 }
230 }
231
232 int old_transp_mode = GetTransparency();
233 //+++++transparency is turned on here
234 SetTransparency(0);
235
236 //drawing preprocessing: for interpolation of stress, etc.
237
238 for (int i=1; i<=nodes.Length(); i++)
239 {
240 nodes(i)->SetDrawTemp(0);
241 nodes(i)->SetDrawTempCnt(0);
242 }
243
244 for (int i=1; i<=elements.Length(); i++)
245 {
246 if (GetElement(i).IsType(TCMSflag))
247 {
248 //UO() << "cms=" << i << ", nn=" << GetElement(i).NNodes() << "\n";
249 for (int j=1; j <= GetElement(i).NCMSNodes(); j++)
250 {
251 GetElement(i).GetNode(j).SetDrawTemp(0);
252 GetElement(i).GetNode(j).SetDrawTempCnt(0);
253 }
254 }
255 }
256
257 for (int i=1; i<=elements.Length(); i++)
258 {
259 GetElementPtr(i)->DrawElementPreProc();
260 }
261
262 for (int i=1; i<=auxelements.Length(); i++)
263 {
264 GetAuxElementPtr(i)->DrawElementPreProc();
265 }
266
267 //perform averaging of Finite element solution at nodes, using the number of values added to the node
268 for (int i=1; i<=nodes.Length(); i++)
269 {
270 double val = nodes(i)->GetDrawTempCnt();
271 if (val == 0) val = 1;
272
273 nodes(i)->GetDrawTemp() /= val;
274 }
275
276 for (int i=1; i<=elements.Length(); i++)
277 {
278 if (GetElement(i).IsType(TCMSflag))
279 {
280 Element& el = GetElement(i);
281 for (int j=1; j <= el.NCMSNodes(); j++)
282 {
283 double val = el.GetNode(j).GetDrawTempCnt();
284 if (val == 0) val = 1;
285
286 el.GetNode(j).GetDrawTemp() /= val;
287 }
288 }
289 }
290
291 //determine range of finite element contour colors
292 if (GetActualPostProcessingFieldVariable() != NULL)
293 {
294 SetFlagComputeMinMaxFECol(1);
295 if(GetIOption(102)) // auto adjust range
296 {
297 GetFEmincol() = 1e30;
298 GetFEmaxcol() = -1e30;
299 }
300 DrawBodies();
301 //global_uo << "aha, femincol = " << GetFEmincol() << ", max = " << GetFEmaxcol() << "\n";
302 SetFlagComputeMinMaxFECol(0);
303 }
304
305 //compute loads, nodes, sensors, constraints (different order depending if transparent or not)
306 if (GetIOption(142)) //draw loads
307 {
308 DrawLoads();
309 }
310
311 if (GetIOption(145)) //draw nodes
312 {
313 DrawNodes();
314 }
315
316 if (!GetIOption(130)) //sensors not transparent
317 {
318 DrawSensors();
319 }
320 if (!GetIOption(129)) //constraints not transparent
321 {
322 DrawConstraints();
323 }
324 if (!GetIOption(128)) //bodies not transparent
325 {
326 DrawBodies();
327 }
328 DrawElementAdd();
329 //++++ up to here transparency is set to global value
330
331 //++++ from here transparency is turned of
332 SetTransparency(1);
333 if (GetIOption(130)) //sensors transparent
334 {
335 DrawSensors();
336 }
337 if (GetIOption(129)) //constraints transparent
338 {
339 DrawConstraints();
340 }
341 if (GetIOption(128)) //bodies transparent
342 {
343 DrawBodies();
344 }
345 SetTransparency(0); //legend not transparent
346
347
348 if (GetActualPostProcessingFieldVariable() != NULL && !GetIOption(141))
349 {
350 sprintf(str," ");
351 int toff = 3;
352 int h2 = GetIOption(103);
353
354 //*YV: new version of printing the title of the legend is based on the names of the variables
355 bool flagMillimeter = GetIOption(143) == 1; // whether "mm" or "m" should be printed
356 char * dim_str = "";
357 switch(GetActualPostProcessingFieldVariable()->GetDimensionality())
358 {
359 case FieldVariableDescriptor::FVD_length: dim_str = flagMillimeter ? "mm" : "m"; break;
360 case FieldVariableDescriptor::FVD_velocity: dim_str = flagMillimeter ? "mm/s" : "m/s"; break;
361 case FieldVariableDescriptor::FVD_acceleration: dim_str = flagMillimeter ? "mm/s�" : "m/s�"; break;
362 case FieldVariableDescriptor::FVD_force: dim_str = "N"; break;
363 case FieldVariableDescriptor::FVD_force_per_length: dim_str = flagMillimeter ? "N/mm" : "N/m"; break;
364 case FieldVariableDescriptor::FVD_force_per_length_square: dim_str = flagMillimeter ? "N/mm�" : "N/m�"; break;
365 case FieldVariableDescriptor::FVD_force_length: dim_str = flagMillimeter ? "N*mm" : "N*m"; break;
366 case FieldVariableDescriptor::FVD_1_per_length: dim_str = flagMillimeter ? "1/mm" : "1/m"; break;
367 case FieldVariableDescriptor::FVD_density: dim_str = flagMillimeter ? "kg/mm�" : "kg/m�"; break;
368 case FieldVariableDescriptor::FVD_pressure: dim_str = flagMillimeter ? "N/mm�" : "N/m�"; break;
369 }
370 if(GetActualPostProcessingFieldVariable()->GetDimensionality() == FieldVariableDescriptor::FVD_none)
371 sprintf(str, " %s max", GetActualPostProcessingFieldVariable()->GetTextualIdentifier().c_str());
372 else
373 sprintf(str, " %s max, %s", GetActualPostProcessingFieldVariable()->GetTextualIdentifier().c_str(), dim_str);
374 pCurrentRC->PrintTextStruct(5+toff,-1,str);
375 if(GetActualPostProcessingFieldVariable()->GetDimensionality() == FieldVariableDescriptor::FVD_none)
376 sprintf(str, " %s min", GetActualPostProcessingFieldVariable()->GetTextualIdentifier().c_str());
377 else
378 sprintf(str, " %s min, %s", GetActualPostProcessingFieldVariable()->GetTextualIdentifier().c_str(), dim_str);
379 pCurrentRC->PrintTextStruct(7+h2+toff,-1,str); //18
380 //sprintf(str," %6.5gN/m� ", TImincol);
381 //pCurrentRC->PrintTextStruct(6+h2+toff,-1,str); //19
382 DrawLegend(6+toff);
383
384 for (double i=0.; i <= h2; i++)
385 {
386 double val = i/(double)h2;
387 if (GetIOption(108) && val >= 0 && val <= 1.)
388 {
389 //val = 1.-pow(1.-val,10.);
390 val = 1.-pow(1.-val,5);
391 }
392 val = (GetFEmincol()-GetFEmaxcol())*val+GetFEmaxcol();
393 //sprintf(str," %6.3e ", val);
394 sprintf_s(str," %6.*e ", GetIOption(160),val); //$ AD 2011-04-08: precision of legend adjustable
395
396 pCurrentRC->PrintTextStruct(6+toff+(int)i,-1,str);
397 }
398 }
399 SetTransparency(old_transp_mode);
400
401
402
403 TMStopTimer(2);
404
405 }
406
407 //AD
DrawSystem2D()408 void MultiBodySystem::DrawSystem2D()
409 {
410 p2DDrawWindow->Reset();
411 for (int i=1; i<=elements.Length(); i++)
412 {
413 if (elements(i)->IsType(TConstraint) && elements(i)->DrawElementFlag())
414 {
415 elements(i)->DrawElement2D();
416 }
417 }
418 }
419
DrawElementAdd()420 void MultiBodySystem::DrawElementAdd()
421 {
422 int use_cutting_planes = UseCuttingPlanes();
423
424 //draw only elements which do not belong to an element!
425 for (int i=1; i <= drawelements.Length(); i++)
426 {
427 if(
428 !drawelements(i)->GetElnum() &&
429 (!use_cutting_planes || !GetOptions()->ViewingOptions()->CuttingPlaneCutGround() || CuttingPlanesAllow(drawelements(i)->GetRefPosD()))
430 )
431 {
432 drawelements(i)->DrawYourself();
433 }
434 }
435 }
436
DrawBodies()437 void MultiBodySystem::DrawBodies()
438 {
439 //drawbodiescnt++;
440 //UO() << "cnt=" << drawbodiescnt << "\n";
441
442 int use_cutting_planes = UseCuttingPlanes();
443 int num_particles = 0.;
444
445 for (int i=1; i<=elements.Length(); i++)
446 {
447 if (elements(i)->DrawElementFlag())
448 {
449 if (!(elements(i)->IsType(TConstraint)))
450 {
451 if (!use_cutting_planes || elements(i)->GetAltShape() || !GetOptions()->ViewingOptions()->CuttingPlaneCutBodies() || CuttingPlanesAllow(elements(i)->GetRefPosD()))
452 {
453 // Draw body number if IOption(123) for all bodies
454 if ((elements(i)->IsType(TBody) && GetIOption(123)) && !IsFlagComputeMinMaxFECol())
455 {
456 //does work for 2D-bodies ?
457 Vector3D p = elements(i)->GetRefPosD();
458 //global_uo << "p" << i << "=" << p << "\n";
459 //Vector3D p = GetPosD(Vector3D(0));
460 char text[40];
461 sprintf(text,"element %d", i);
462
463 GetRC()->PrintText3D((float)p.X(),(float)p.Y(),(float)p.Z(),text);
464 }
465
466 // 125 = show local frame
467 if ((elements(i)->IsType(TBody) && GetIOption(125)) && !IsFlagComputeMinMaxFECol())
468 {
469 elements(i)->DrawElementLocalFrame();
470 }
471
472 // Draw element (also done in ComputeMinMaxFECol case for finite elements)
473 if (!elements(i)->GetAltShape())
474 {
475 if (!(IsFlagComputeMinMaxFECol() && elements(i)->IsRigid()))
476 {
477 int no_surfaceupdate = GetIOption(119);
478 if (use_cutting_planes && no_surfaceupdate==0 && elements(i)->IsFiniteElement() && elements(i)->Dim()==3) // probably it is Hex/Tet)
479 {
480 //$ YV 2012-12-11: treatment of outer faces in finite elements was placed to finite elements
481 /*
482 FiniteElement3D * fe = dynamic_cast<FiniteElement3D*>(elements(i));
483 char copyofouterfaces = fe->Outer_Face();
484
485 fe->SetOuterFacesCuttingPlane();
486 elements(i)->DrawElement();
487
488 fe->Outer_Face() = copyofouterfaces;
489 */
490 elements(i)->DrawElement();
491 }
492 else
493 {
494 if (GetOptions()->PostProcOptions()->BodiesShowVelocityVector())
495 {
496 Element* el = elements(i);
497 if (!GetOptions()->PostProcOptions()->BodiesVelocityVectorJustForParticles())
498 {
499 el->DrawElementVelocityVector();
500 }
501 }
502
503 elements(i)->DrawElement();
504 }
505 }
506 }
507 // draw AltShape elements
508 else if (!IsFlagComputeMinMaxFECol())
509 {
510 if (GetOptions()->PostProcOptions()->BodiesShowVelocityVector())
511 {
512 Element* el = elements(i);
513 if (!GetOptions()->PostProcOptions()->BodiesVelocityVectorJustForParticles())
514 {
515 el->DrawElementVelocityVector();
516 }
517 }
518
519 elements(i)->DrawElementAdd();
520 }
521 }
522 }
523 }
524 }
525 for (int i=1; i<=auxelements.Length(); i++)
526 {
527 //$ MaSch 2013-10-28: moved drawing of SPH particles from elements to auxelements
528 if (!auxelements(i)->IsType(TParticle) || GetIOption(155) <= 1 || ++num_particles % GetIOption(155) == 0) //GetIOption(155) corresponds to PostProcOptions.Bodies.Particles.draw_every_nth
529 {
530 if (!use_cutting_planes || CuttingPlanesAllow(auxelements(i)->GetRefPosD()))
531 {
532 // Draw auxelement body number if IOption(123) for all bodies
533 if ((auxelements(i)->IsType(TBody) && GetIOption(123)) && !IsFlagComputeMinMaxFECol())
534 {
535 //does work for 2D-bodies ?
536 Vector3D p = auxelements(i)->GetRefPosD();
537 //global_uo << "p" << i << "=" << p << "\n";
538 //Vector3D p = GetPosD(Vector3D(0));
539 char text[40];
540 sprintf(text,"aux-element %d", i);
541
542 GetRC()->PrintText3D((float)p.X(),(float)p.Y(),(float)p.Z(),text);
543 }
544 // Draw auxelement (also done in ComputeMinMaxFECol case for finite elements)
545 if (!auxelements(i)->GetAltShape())
546 {
547 if (!(IsFlagComputeMinMaxFECol() && auxelements(i)->IsRigid()))
548 {
549 if (GetOptions()->PostProcOptions()->BodiesShowVelocityVector() && auxelements(i)->IsType(TParticle))
550 {
551 auxelements(i)->DrawElementVelocityVector();
552 }
553 auxelements(i)->DrawElement();
554 }
555 }
556 // draw AltShape auxelements
557 else if (!IsFlagComputeMinMaxFECol())
558 {
559 if (GetOptions()->PostProcOptions()->BodiesShowVelocityVector() && auxelements(i)->IsType(TParticle))
560 {
561 auxelements(i)->DrawElementVelocityVector();
562 }
563 auxelements(i)->DrawElementAdd();
564 }
565 }
566 }
567 }
568 }
569
DrawConstraints()570 void MultiBodySystem::DrawConstraints()
571 {
572 int use_cutting_planes = UseCuttingPlanes();
573
574 if (GetIOption(121)) //do not draw constraints/joints
575 {
576 for (int i=1; i<=elements.Length(); i++)
577 {
578 if (elements(i)->IsType(TConstraint) && elements(i)->DrawElementFlag())
579 {
580 if (!use_cutting_planes || CuttingPlanesAllow(elements(i)->GetRefPosD()))
581 {
582 if ((elements(i)->IsType(TConstraint) && GetIOption(124)))
583 {
584 //does work for 2D-bodies ?
585 Vector3D p = elements(i)->GetRefPosD();
586 //Vector3D p = GetPosD(Vector3D(0));
587 char text[40];
588 sprintf(text,"element %d", i);
589
590 GetRC()->PrintText3D((float)p.X(),(float)p.Y(),(float)p.Z(),text);
591 }
592
593 if (!elements(i)->GetAltShape())
594 elements(i)->DrawElement();
595
596 elements(i)->DrawElementAdd();
597 }
598 }
599 }
600 }
601 }
602
DrawSensors()603 void MultiBodySystem::DrawSensors()
604 {
605 int use_cutting_planes = UseCuttingPlanes();
606 Vector3D pos;
607 int np;
608
609 if (GetIOption(127))
610 {
611 for (int i=1; i <= NSensors(); i++)
612 {
613 if(GetSensor(i).GetNumberOfDrawingPositions() > 0)
614 if (!use_cutting_planes || CuttingPlanesAllow(GetSensor(i).GetDrawPosition(1)))
615 {
616 mystr label = "S" + mystr(i);
617 GetSensor(i).Draw(label);
618 }
619 }
620 }
621 }
622
DrawLoads()623 void MultiBodySystem::DrawLoads()
624 {
625 int use_cutting_planes = UseCuttingPlanes();
626
627 for (int i=1; i<=elements.Length(); i++)
628 {
629 if (!use_cutting_planes || CuttingPlanesAllow(elements(i)->GetRefPosD()))
630 {
631 if ((elements(i)->IsType(TBody)))
632 {
633 for (int j = 1; j <= elements(i)->NLoads(); j++)
634 {
635 elements(i)->GetLoad(j).DrawLoad(this,elements(i));
636 }
637 }
638 }
639 }
640 }
641
DrawNodes()642 void MultiBodySystem::DrawNodes()
643 {
644 int use_cutting_planes = UseCuttingPlanes();
645
646 for (int i=1; i<=nodes.Length(); i++)
647 {
648 if (!use_cutting_planes || CuttingPlanesAllow(nodes(i)->GetPosD())) //$ AD 2011-07-28: Cutplane for Nodes
649 {
650 nodes(i)->DrawNode();
651 }
652 }
653 }
654
655
UseCuttingPlanes()656 int MultiBodySystem::UseCuttingPlanes()
657 {
658 int rv = 0;
659
660 //$ PG 2012-3-6:[ Cutting plane may now be optionally handled by OpenGL (if GetOptions()->ViewingOptions()->CuttingPlaneCutWholeSceneByOpenGl() (or GetIOption(157)) is true)
661 if (!GetOptions()->ViewingOptions()->CuttingPlaneCutWholeSceneByOpenGl())
662 {
663 int n_cutting_planes = 2;
664 ncut.SetLen(n_cutting_planes);
665 pcut.SetLen(n_cutting_planes);
666
667 use_cutting_plane(1) = GetIOption(149);
668 ncut(1) = Vector3D(GetDOption(125),GetDOption(126),GetDOption(127));
669 pcut(1) = ncut(1)*GetDOption(128); // multiply by distance of plane from origin
670
671 use_cutting_plane(2) = GetIOption(156);
672 ncut(2) = Vector3D(GetDOption(129),GetDOption(130),GetDOption(131));
673 pcut(2) = ncut(2)*GetDOption(132);
674
675 for (int j=1; j<=n_cutting_planes; j++) // multiply by distance of plane from origin
676 {
677 if (use_cutting_plane(j))
678 {
679 rv = 1;
680 }
681 }
682 }
683 //$ PG 2012-3-6:] Cutting plane may now be optionally handled by OpenGL
684
685 return rv;
686 }
687
CuttingPlanesAllow(const Vector3D & pos)688 int MultiBodySystem::CuttingPlanesAllow(const Vector3D& pos)
689 {
690 for (int j=1; j<=use_cutting_plane.Length(); j++)
691 {
692 if (use_cutting_plane(j) && (pos-pcut(j))*ncut(j) >= 0) //$ DR 2011-05-20: GetRefPos changed to GetRefPosD, now control element is drawn correctly
693 {
694 return 0; //cut_element = 1;
695 }
696 }
697
698 return 1;
699 }
700
GetActualPostProcessingFieldVariable()701 FieldVariableDescriptor * MultiBodySystem::GetActualPostProcessingFieldVariable()
702 {
703 if(indexOfActualPostProcessingFieldVariable == 0)
704 return NULL;
705 return &(availableFieldVariables(indexOfActualPostProcessingFieldVariable));
706 }
707
SetIndexOfActualPostProcessingFieldVariable(int index)708 void MultiBodySystem::SetIndexOfActualPostProcessingFieldVariable(int index)
709 {
710 assert(index <= availableFieldVariables.Length());
711
712 // piece of code, similar to that one from the old version of SetIOption() for the case "index == 102"
713 if (indexOfActualPostProcessingFieldVariable != index)
714 {
715 indexOfActualPostProcessingFieldVariable = index;
716
717 if (!GetIOption(100))
718 GetFEmaxcol() = -1e15;
719 else
720 GetFEmaxcol() = GetDOption(100);
721
722 if (!GetIOption(101))
723 GetFEmincol() = 1e15;
724 else
725 GetFEmincol() = GetDOption(101);
726 }
727
728 // we set the textual identifier of the present variable
729 if(index == 0)
730 SetTOption(107, "");
731 else
732 SetTOption(107, GetActualPostProcessingFieldVariable()->GetTextualIdentifier());
733 }