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 }