1 /*
2 *	Copyright (C) 2008,2009,2010 Thorsten Liebig (Thorsten.Liebig@gmx.de)
3 *
4 *	This program is free software: you can redistribute it and/or modify
5 *	it under the terms of the GNU Lesser General Public License as published
6 *	by the Free Software Foundation, either version 3 of the License, or
7 *	(at your option) any later version.
8 *
9 *	This program is distributed in the hope that it will be useful,
10 *	but WITHOUT ANY WARRANTY; without even the implied warranty of
11 *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 *	GNU Lesser General Public License for more details.
13 *
14 *	You should have received a copy of the GNU Lesser General Public License
15 *	along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include <QFileDialog>
19 
20 #include "QVTKStructure.h"
21 
22 #include "vtkCommand.h"
23 #if VTK_MAJOR_VERSION>=8
24   #include "QVTKOpenGLWidget.h"
25   #include "vtkGenericOpenGLRenderWindow.h"
26 #else
27   #include "QVTKWidget.h"
28 
29 #endif
30 #include "vtkRenderWindow.h"
31 #include "vtkRenderWindowInteractor.h"
32 #include "vtkRenderer.h"
33 #include "vtkAxesActor.h"
34 #include "vtkActor.h"
35 #include "ContinuousStructure.h"
36 #include "ParameterCoord.h"
37 #include "VTKPrimitives.h"
38 #include "vtkCubeSource.h"
39 #include "vtkPolyDataMapper.h"
40 #include "vtkCellArray.h"
41 #include "vtkActor.h"
42 #include "vtkLODActor.h"
43 #include "vtkFollower.h"
44 #include "vtkAxes.h"
45 #include "vtkVectorText.h"
46 #include "vtkFollower.h"
47 #include "vtkTextProperty.h"
48 #include "vtkTextActor.h"
49 #include "vtkCamera.h"
50 #include "vtkProperty.h"
51 #include "vtkOrientationMarkerWidget.h"
52 #include "vtkPropAssembly.h"
53 #include "vtkTextProperty.h"
54 #include "vtkCaptionActor2D.h"
55 #include "vtkRectilinearGrid.h"
56 #include "vtkRectilinearGridGeometryFilter.h"
57 #include "vtkDoubleArray.h"
58 #include "vtkActorCollection.h"
59 #include "vtkInteractorStyle.h"
60 #include "vtkCallbackCommand.h"
61 #include "vtkWindowToImageFilter.h"
62 #include "vtkPNGWriter.h"
63 #include <vtkStructuredGrid.h>
64 #include <vtkStructuredGridGeometryFilter.h>
65 #include <vtkCamera.h>
66 #include <vtkInteractorStyleTrackballCamera.h>
67 #include "vtkInteractorStyleRubberBand2DPlane.h"
68 #include <vtkInteractorStyleRubberBand2D.h>
69 
70 #include "CSPrimPoint.h"
71 #include "CSPrimBox.h"
72 #include "CSPrimMultiBox.h"
73 #include "CSPrimSphere.h"
74 #include "CSPrimSphericalShell.h"
75 #include "CSPrimCylinder.h"
76 #include "CSPrimCylindricalShell.h"
77 #include "CSPrimPolygon.h"
78 #include "CSPrimLinPoly.h"
79 #include "CSPrimRotPoly.h"
80 #include "CSPrimPolyhedron.h"
81 #include "CSPrimCurve.h"
82 #include "CSPrimWire.h"
83 #include "CSPrimUserDefined.h"
84 
85 #include "CSPropDiscMaterial.h"
86 
87 #include "CSTransform.h"
88 
QVTKStructure()89 QVTKStructure::QVTKStructure()
90 {
91 	clCS=NULL;
92 	ActorGridPlane[0]=NULL;
93 	ActorGridPlane[1]=NULL;
94 	ActorGridPlane[2]=NULL;
95 	m_Rect_Grid = NULL;
96 	m_Struct_Grid = NULL;
97 	m_CamData = NULL;
98 
99 	iResolution=32;
100 	AllowUpdate=true;
101 
102 #if VTK_MAJOR_VERSION>=8
103 	VTKWidget = new QVTKOpenGLWidget();
104 	VTKWidget->SetRenderWindow(vtkGenericOpenGLRenderWindow::New());
105 #else
106 	VTKWidget= new QVTKWidget();
107 #endif
108 
109 	ren = vtkRenderer::New();
110 	VTKWidget->GetRenderWindow()->AddRenderer(ren);
111 
112 	AddAxes();
113 	SetBackgroundColor(255,255,255);
114 
115 	SetCallback(VTKWidget->GetRenderWindow()->GetInteractor());
116 }
117 
~QVTKStructure()118 QVTKStructure::~QVTKStructure()
119 {
120 	clear();
121 }
122 
AddAxes()123 void QVTKStructure::AddAxes()
124 {
125 	Axes = vtkAxesActor::New();
126 	Axes->SetTotalLength(4,4,4);
127 	vtkOrientationMarkerWidget* marker = vtkOrientationMarkerWidget::New();
128 	vtkPropAssembly* assembly = vtkPropAssembly::New();
129 	assembly->AddPart(Axes);
130 
131 	marker->SetOrientationMarker(assembly);
132 	marker->SetViewport(0.0,0.0,0.25,0.25);
133 
134 	marker->SetInteractor(VTKWidget->GetRenderWindow()->GetInteractor());
135 	marker->SetEnabled(1);
136 	marker->InteractiveOff();
137 
138 	//assembly->Delete();
139 	//marker->Delete();
140 }
141 
SetBackgroundColor(int r,int g,int b)142 void QVTKStructure::SetBackgroundColor(int r, int g, int b)
143 {
144 	double rgb[3]={(double)r/255.0,(double)g/255.0,(double)b/255.0};
145 	double irgb[3]={1-rgb[0],1-rgb[1],1-rgb[2]};
146 	ren->SetBackground(rgb);
147 
148 	Axes->GetXAxisCaptionActor2D()->GetCaptionTextProperty()->SetColor(irgb);
149 	Axes->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->SetColor(irgb);
150 	Axes->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->SetColor(irgb);
151 
152 	for (int i=0;i<3;++i)
153 	{
154 		if (ActorGridPlane[i]!=NULL) ActorGridPlane[i]->GetProperty()->SetColor(irgb);
155 	}
156     VTKWidget->GetRenderWindow()->GetInteractor()->Render();
157 }
158 
SetGeometry(ContinuousStructure * CS)159 void QVTKStructure::SetGeometry(ContinuousStructure *CS)
160 {
161 	clear();
162 	clCS=CS;
163 }
164 
clear()165 void QVTKStructure::clear()
166 {
167 	for (int i=0;i<LayerPrimitives.size();++i)
168 	{
169 		delete LayerPrimitives.at(i).VTKProp;
170 	}
171 	LayerPrimitives.clear();
172 
173 	for (int i=0;i<m_DiscMatModels.size();++i)
174 	{
175 		delete m_DiscMatModels.at(i).vtk_model;
176 	}
177 	m_DiscMatModels.clear();
178 
179 	for (int i=0; i<3; i++)
180 	{
181 		if (ActorGridPlane[i]!=NULL)
182 		{
183 			ren->RemoveActor(ActorGridPlane[i]);
184 			ActorGridPlane[i]->Delete();
185 			ActorGridPlane[i]=NULL;
186 		}
187 	}
188 	if (m_Rect_Grid)
189 		m_Rect_Grid->Delete();
190 	m_Rect_Grid=NULL;
191 	if (m_Struct_Grid)
192 		m_Struct_Grid->Delete();
193 	m_Struct_Grid=NULL;
194 }
195 
196 
RenderGrid()197 void QVTKStructure::RenderGrid()
198 {
199 	if (clCS==NULL) return;
200 	CSRectGrid* CSGrid = clCS->GetGrid();
201 	if (CSGrid->isValid()==false)
202 		return;
203 
204 	if (CSGrid->GetMeshType()==CARTESIAN)
205 	{
206 		if (m_Rect_Grid)
207 			m_Rect_Grid->Delete();
208 		m_Rect_Grid = vtkRectilinearGrid::New();
209 		vtkDoubleArray *Coords[3];
210 		int iQty[3];
211 
212 		for (int n=0;n<3;++n)
213 		{
214 			iQty[n]=CSGrid->GetQtyLines(n);
215 			Coords[n]=vtkDoubleArray::New();
216 			for (int m=0;m<iQty[n];++m) Coords[n]->InsertNextValue(CSGrid->GetLine(n,m));
217 		}
218 		if (iQty[0]*iQty[1]*iQty[2]==0)
219 		{
220 			for (int n=0;n<3;++n) Coords[n]->Delete();
221 			return;
222 		}
223 		m_Rect_Grid->SetDimensions(iQty[0],iQty[1],iQty[2]);
224 		m_Rect_Grid->SetXCoordinates(Coords[0]);
225 		m_Rect_Grid->SetYCoordinates(Coords[1]);
226 		m_Rect_Grid->SetZCoordinates(Coords[2]);
227 		for (int n=0;n<3;++n)
228 			Coords[n]->Delete();
229 	}
230 	else if (CSGrid->GetMeshType()==CYLINDRICAL)
231 	{
232 		if (m_Struct_Grid)
233 			m_Struct_Grid->Delete();
234 		m_Struct_Grid = vtkStructuredGrid::New();
235 
236 		unsigned int uiQty[3];
237 		double* lines[3]={NULL,NULL,NULL};
238 		for (unsigned int n=0;n<3;++n)
239 			lines[n] = CSGrid->GetLines(n,lines[n],uiQty[n]);
240 
241 		m_Struct_Grid->SetDimensions(uiQty[0],uiQty[1],uiQty[2]);
242 		vtkPoints *points = vtkPoints::New();
243 		points->SetNumberOfPoints(uiQty[0]*uiQty[1]*uiQty[2]);
244 		double r[3];
245 		int id=0;
246 		for (unsigned int k=0; k<uiQty[2]; ++k)
247 			for (unsigned int j=0; j<uiQty[1]; ++j)
248 				for (unsigned int i=0; i<uiQty[0]; ++i)
249 				{
250 					r[0] = lines[0][i] * cos(lines[1][j]);
251 					r[1] = lines[0][i] * sin(lines[1][j]);
252 					r[2] = lines[2][k];
253 					points->SetPoint(id++,r);
254 				}
255 		m_Struct_Grid->SetPoints(points);
256 		points->Delete();
257 		for (unsigned int n=0;n<3;++n)
258 		{
259 			delete[] lines[n];
260 			lines[n] = NULL;
261 		}
262 	}
263 	else
264 		cerr << "QVTKStructure::RenderGrid(): Error, unknown grid type!" << endl;
265 
266 	RenderGridDir(0,0);
267 	RenderGridDir(1,0);
268 	RenderGridDir(2,0);
269 }
270 
RenderGridX(int plane_pos)271 void QVTKStructure::RenderGridX(int plane_pos)
272 {
273 	RenderGridDir(0,plane_pos);
274 	VTKWidget->GetRenderWindow()->GetInteractor()->Render();
275 }
276 
RenderGridY(int plane_pos)277 void QVTKStructure::RenderGridY(int plane_pos)
278 {
279 	RenderGridDir(1,plane_pos);
280 	VTKWidget->GetRenderWindow()->GetInteractor()->Render();
281 
282 }
283 
RenderGridZ(int plane_pos)284 void QVTKStructure::RenderGridZ(int plane_pos)
285 {
286 	RenderGridDir(2,plane_pos);
287 	VTKWidget->GetRenderWindow()->GetInteractor()->Render();
288 }
289 
RenderGridDir(int dir,unsigned int plane_pos)290 void QVTKStructure::RenderGridDir(int dir, unsigned int plane_pos)
291 {
292 	if (ActorGridPlane[dir]!=NULL)
293 	{
294 		ren->RemoveActor(ActorGridPlane[dir]);
295 		ActorGridPlane[dir]->Delete();
296 	}
297 
298 	ActorGridPlane[dir] = vtkLODActor::New();
299 	vtkPolyDataMapper *gridMapper = vtkPolyDataMapper::New();
300 	vtkPolyDataAlgorithm *plane = NULL;
301 
302 	CSRectGrid* CSGrid = clCS->GetGrid();
303 	int uiQty[3];
304 
305 	for (int n=0;n<3;++n)
306 		uiQty[n]=CSGrid->GetQtyLines(n);
307 	if ((int)plane_pos>=uiQty[dir])
308 	{
309 		cerr << "QVTKStructure::RenderGridDir: requested plane postion is out of range, resetting to max value!" << endl;
310 		plane_pos = uiQty[dir]-1;
311 	}
312 
313 	if (CSGrid->GetMeshType()==CARTESIAN)
314 	{
315 		if (m_Rect_Grid==NULL)
316 		{
317 			ActorGridPlane[dir]->Delete();
318 			gridMapper->Delete();
319 			ActorGridPlane[dir]=NULL;
320 			cerr << "QVTKStructure::RenderGridDir: Error, rect grid mesh was not created, skipping drawing..." << endl;
321 			return;
322 		}
323 		vtkRectilinearGridGeometryFilter *grid_plane = vtkRectilinearGridGeometryFilter::New();
324 		plane = grid_plane;
325 #if VTK_MAJOR_VERSION>=6
326 		grid_plane->SetInputData(m_Rect_Grid);
327 #else
328 		grid_plane->SetInput(m_Rect_Grid);
329 #endif
330 		switch (dir)
331 		{
332 		case 2:
333 		{
334 			grid_plane->SetExtent(0,uiQty[0]-1, 0,uiQty[1]-1, plane_pos,plane_pos);
335 			break;
336 		}
337 		case 1:
338 		{
339 			grid_plane->SetExtent(0,uiQty[0]-1, plane_pos,plane_pos, 0,uiQty[2]-1);
340 			break;
341 		}
342 		case 0:
343 		{
344 			grid_plane->SetExtent(plane_pos,plane_pos, 0,uiQty[1]-1, 0,uiQty[2]-1);
345 			break;
346 		}
347 		}
348 	}
349 	else if (CSGrid->GetMeshType()==CYLINDRICAL)
350 	{
351 		if (m_Struct_Grid==NULL)
352 		{
353 			ActorGridPlane[dir]->Delete();
354 			gridMapper->Delete();
355 			ActorGridPlane[dir]=NULL;
356 			cerr << "QVTKStructure::RenderGridDir: Error, structured grid mesh was not created, skipping drawing..." << endl;
357 			return;
358 		}
359 
360 		vtkStructuredGridGeometryFilter *grid_plane = vtkStructuredGridGeometryFilter::New();
361 		plane = grid_plane;
362 #if VTK_MAJOR_VERSION>=6
363 		grid_plane->SetInputData(m_Struct_Grid);
364 #else
365 		grid_plane->SetInput(m_Struct_Grid);
366 #endif
367 		switch (dir)
368 		{
369 		case 2:
370 		{
371 			grid_plane->SetExtent(0,uiQty[0]-1, 0,uiQty[1]-1, plane_pos,plane_pos);
372 			break;
373 		}
374 		case 1:
375 		{
376 			grid_plane->SetExtent(0,uiQty[0]-1, plane_pos,plane_pos, 0,uiQty[2]-1);
377 			break;
378 		}
379 		case 0:
380 		{
381 			grid_plane->SetExtent(plane_pos,plane_pos, 0,uiQty[1]-1, 0,uiQty[2]-1);
382 			break;
383 		}
384 		}
385 	}
386 	else
387 		cerr << "QVTKStructure::RenderGrid(): Error, unknown grid type!" << endl;
388 
389 	gridMapper->SetInputConnection(plane->GetOutputPort());
390 	ActorGridPlane[dir]->SetMapper(gridMapper);
391 	ActorGridPlane[dir]->GetProperty()->SetColor(0,0,0);
392 	ActorGridPlane[dir]->GetProperty()->SetDiffuse(0);
393 	ActorGridPlane[dir]->GetProperty()->SetAmbient(1);
394 	ActorGridPlane[dir]->GetProperty()->SetRepresentationToWireframe();
395 	ActorGridPlane[dir]->GetProperty()->SetOpacity((double)GridOpacity/255.0);
396 	ren->AddActor(ActorGridPlane[dir]);
397 	gridMapper->Delete();
398 	plane->Delete();
399 
400 }
401 
SetGridOpacity(int val)402 void QVTKStructure::SetGridOpacity(int val)
403 {
404 	GridOpacity = val;
405 	if (AllowUpdate==false) return;
406 	for (int i=0;i<3;++i)
407 	{
408 		if (ActorGridPlane[i]!=NULL) ActorGridPlane[i]->GetProperty()->SetOpacity((double)val/255.0);
409 	}
410 	VTKWidget->GetRenderWindow()->GetInteractor()->Render();
411 }
412 
ResetView()413 void QVTKStructure::ResetView()
414 {
415 	ren->ResetCamera();
416     VTKWidget->GetRenderWindow()->GetInteractor()->Render();
417 }
418 
setXY()419 void QVTKStructure::setXY()
420 {
421 	vtkCamera* cam=ren->GetActiveCamera();
422 	ren->ResetCamera();
423 	double fp[3];
424 	cam->SetViewUp(0.5,0.5,0.5);
425 	cam->GetFocalPoint(fp);
426 	fp[2]+=1;
427 	cam->SetPosition(fp);
428 	cam->SetRoll(0);
429 	ResetView();
430 }
431 
setYZ()432 void QVTKStructure::setYZ()
433 {
434 	vtkCamera* cam=ren->GetActiveCamera();
435 	ren->ResetCamera();
436 	double fp[3];
437 	cam->SetViewUp(0.5,0.5,0.5);
438 	cam->GetFocalPoint(fp);
439 	fp[0]+=1;
440 	cam->SetPosition(fp);
441 
442 	cam->SetRoll(-90);
443 	ResetView();
444 }
445 
446 
setZX()447 void QVTKStructure::setZX()
448 {
449 	vtkCamera* cam=ren->GetActiveCamera();
450 	ren->ResetCamera();
451 	double fp[3];
452 	cam->SetViewUp(0.5,0.5,0.5);
453 	cam->GetFocalPoint(fp);
454 	fp[1]+=1;
455 	cam->SetPosition(fp);
456 	cam->SetRoll(90);
457 	ResetView();
458 }
459 
SetPropOpacity(unsigned int uiID,int val)460 void QVTKStructure::SetPropOpacity(unsigned int uiID, int val)
461 {
462 	for (int i=0;i<LayerPrimitives.size();++i)
463 	{
464 		if (LayerPrimitives.at(i).uID==uiID)
465 		{
466 			if (LayerPrimitives.at(i).VTKProp!=NULL) LayerPrimitives.at(i).VTKProp->SetOpacity2All((double)val/255.0);
467 		}
468 	}
469 	VTKWidget->GetRenderWindow()->GetInteractor()->Render();
470 }
471 
RenderGeometry()472 void QVTKStructure::RenderGeometry()
473 {
474 	for (int i=0;i<LayerPrimitives.size();++i)
475 	{
476 		delete LayerPrimitives.at(i).VTKProp;
477 	}
478 	LayerPrimitives.clear();
479 	if (clCS==NULL) return;
480 	int QtyProp=clCS->GetQtyProperties();
481 	for (int i=0;i<QtyProp;++i)
482 	{
483 		CSProperties* prop = clCS->GetProperty(i);
484 		if (prop==NULL) return;
485 		int QtyPrim=prop->GetQtyPrimitives();
486 		if (QtyPrim>0)
487 		{
488 			VTKLayerStruct layStruct;
489 			VTKPrimitives* vtkPrims= new VTKPrimitives(ren);
490 			layStruct.VTKProp=vtkPrims;
491 			layStruct.uID=prop->GetUniqueID();
492 			LayerPrimitives.append(layStruct);
493 			RGBa col=prop->GetFillColor();
494 			if (prop->GetVisibility()==false) col.a=0;
495 			double rgb[3]={(double)col.R/255.0,(double)col.G/255.0,(double)col.B/255.0};
496 			for (int n=0;n<QtyPrim;++n)
497 			{
498 				CSPrimitives* prim = prop->GetPrimitive(n);
499 				if (prim==NULL) return;
500 				CoordinateSystem primCS = prim->GetCoordinateSystem();
501 				CSTransform* transform = prim->GetTransform();
502 				double* transform_matrix = NULL;
503 				if (transform)
504 					transform_matrix = transform->GetMatrix();
505 				if (primCS==UNDEFINED_CS)
506 					primCS=clCS->GetCoordInputType();
507 				switch (prim->GetType())
508 				{
509 				case CSPrimitives::BOX:
510 				{
511 					CSPrimBox* box = prim->ToBox();
512 					if (primCS==CARTESIAN)
513 						vtkPrims->AddCube(box->GetStartCoord()->GetCartesianCoords(),box->GetStopCoord()->GetCartesianCoords(),rgb,(double)col.a/255.0,transform_matrix);
514 					else if (primCS==CYLINDRICAL)
515 						vtkPrims->AddCylindricalCube(box->GetStartCoord()->GetCylindricalCoords(),box->GetStopCoord()->GetCylindricalCoords(),rgb,(double)col.a/255.0,transform_matrix);
516 					break;
517 				}
518 				case CSPrimitives::MULTIBOX:
519 				{
520 					CSPrimMultiBox* multibox = prim->ToMultiBox();
521 					int qtyPts=multibox->GetQtyBoxes()*2;
522 					double *coords = new double[qtyPts*3];
523 					for (int a=0;a<qtyPts;a=a+2)
524 					{
525 						coords[a]=multibox->GetCoord(3*a);
526 						coords[a+1]=multibox->GetCoord(3*a+1);
527 						coords[qtyPts+a]=multibox->GetCoord(3*a+2);
528 						coords[qtyPts+a+1]=multibox->GetCoord(3*a+3);
529 						coords[2*qtyPts+a]=multibox->GetCoord(3*a+4);
530 						coords[2*qtyPts+a+1]=multibox->GetCoord(3*a+5);
531 					}
532 					vtkPrims->AddDisc(coords,qtyPts,rgb,(double)col.a/255.0,transform_matrix);
533 					delete[] coords;
534 					break;
535 				}
536 				case CSPrimitives::SPHERE:
537 				{
538 					CSPrimSphere* sphere = prim->ToSphere();
539 					vtkPrims->AddSphere(sphere->GetCenter()->GetCartesianCoords(),sphere->GetRadius(),rgb,(double)col.a/255.0,iResolution,transform_matrix);
540 					break;
541 				}
542 				case CSPrimitives::SPHERICALSHELL:
543 				{
544 					CSPrimSphericalShell* sphereshell = prim->ToSphericalShell();
545 					const double* center = sphereshell->GetCenter()->GetCartesianCoords();
546 					const double radius = sphereshell->GetRadius();
547 					const double shellWidth = sphereshell->GetShellWidth();
548 					vtkPrims->AddSphericalShell(center, radius-shellWidth/2, radius+shellWidth/2, rgb, (double)col.a/255.0, iResolution, transform_matrix);
549 					break;
550 				}
551 				case CSPrimitives::CYLINDER:
552 				{
553 					CSPrimCylinder* cylinder = prim->ToCylinder();
554 					vtkPrims->AddCylinder2(cylinder->GetAxisStartCoord()->GetCartesianCoords(),cylinder->GetAxisStopCoord()->GetCartesianCoords(),cylinder->GetRadius(),rgb,(double)col.a/255.0,iResolution,transform_matrix);
555 					break;
556 				}
557 				case CSPrimitives::CYLINDRICALSHELL:
558 				{
559 					CSPrimCylindricalShell* cylinder = prim->ToCylindricalShell();
560 					const double* start = cylinder->GetAxisStartCoord()->GetCartesianCoords();
561 					const double* stop  = cylinder->GetAxisStopCoord()->GetCartesianCoords();
562 					const double radius = cylinder->GetRadius();
563 					const double shellWidth = cylinder->GetShellWidth();
564 					vtkPrims->AddCylindricalShell( start, stop, radius-shellWidth/2, radius+shellWidth/2, rgb, (double)col.a/255.0, iResolution, transform_matrix );
565 					break;
566 				}
567 				case CSPrimitives::POLYGON:
568 				case CSPrimitives::LINPOLY:
569 				case CSPrimitives::ROTPOLY:
570 				{
571 					CSPrimPolygon* poly = NULL;
572 					if (prim->GetType()==CSPrimitives::POLYGON)
573 						poly = prim->ToPolygon();
574 					else if (prim->GetType()==CSPrimitives::LINPOLY)
575 						poly = prim->ToLinPoly();
576 					else if (prim->GetType()==CSPrimitives::ROTPOLY)
577 						poly = prim->ToRotPoly();
578 					int normDir = poly->GetNormDir();
579 					double elev = poly->GetElevation();
580 					int nP = (normDir+1)%3;
581 					int nPP = (normDir+2)%3;
582 					int nrPts = poly->GetQtyCoords();
583 					double* dCoords = new double[3*nrPts];
584 					for (int n=0;n<nrPts;++n)
585 					{
586 						dCoords[normDir*nrPts + n] = elev;
587 						dCoords[nP*nrPts + n] = poly->GetCoord(2*n);
588 						dCoords[nPP*nrPts + n] = poly->GetCoord(2*n+1);
589 					}
590 					double dVector[6] = {0,0,0,0,0,0};
591 					if (prim->GetType()==CSPrimitives::POLYGON)
592 						vtkPrims->AddClosedPoly(dCoords,nrPts,dVector,rgb,(double)col.a/255.0,transform_matrix);
593 					if (prim->GetType()==CSPrimitives::LINPOLY)
594 					{
595 						dVector[normDir] = prim->ToLinPoly()->GetLength();
596 						vtkPrims->AddClosedPoly(dCoords,nrPts,dVector,rgb,(double)col.a/255.0,transform_matrix);
597 					}
598 					if (prim->GetType()==CSPrimitives::ROTPOLY)
599 					{
600 						dVector[2*prim->ToRotPoly()->GetRotAxisDir()+1]=1;
601 						double angles[2] = {prim->ToRotPoly()->GetAngle(0)*180/PI,prim->ToRotPoly()->GetAngle(1)*180/PI};
602 						vtkPrims->AddRotationalPoly(dCoords,nrPts,dVector,angles,rgb,(double)col.a/255.0,32,transform_matrix);
603 					}
604 					delete[] dCoords; dCoords=NULL;
605 					break;
606 				}
607 				case CSPrimitives::POLYHEDRONREADER:
608 				case CSPrimitives::POLYHEDRON:
609 				{
610 					CSPrimPolyhedron* polyhedron = dynamic_cast<CSPrimPolyhedron*>(prim);
611 					vtkCellArray *poly = vtkCellArray::New();
612 					vtkPolyData* polydata=vtkPolyData::New();
613 					vtkPoints *points = vtkPoints::New();
614 					for (unsigned int i=0; i<polyhedron->GetNumVertices();i++)
615 						points->InsertPoint(i,polyhedron->GetVertex(i));
616 					unsigned int numVertex;
617 					int* vertices;
618 					for (unsigned int i=0; i<polyhedron->GetNumFaces();++i)
619 					{
620 						if (polyhedron->GetFaceValid(i)==false)
621 							continue;
622 						vertices=polyhedron->GetFace(i,numVertex);
623 						poly->InsertNextCell(numVertex);
624 						for (unsigned int p=0; p<numVertex;++p)
625 							poly->InsertCellPoint(vertices[p]);
626 					}
627 					polydata->SetPoints(points);
628 					polydata->SetPolys(poly);
629 					vtkPrims->AddPolyData(polydata,rgb,(double)col.a/255.0,transform_matrix);
630 					poly->Delete();
631 					points->Delete();
632 					polydata->Delete();
633 					break;
634 				}
635 //				case CSPrimitives::POLYHEDRONREADER:
636 //				{
637 //					CSPrimPolyhedronReader* reader = prim->ToPolyhedronReader();
638 //					double center[]={0,0,0};
639 //					vtkPrims->AddSTLObject(reader->GetFilename().c_str(),center,rgb,(double)col.a/255.0,transform_matrix);
640 //					break;
641 //				}
642 				case CSPrimitives::CURVE:
643 				case CSPrimitives::WIRE:
644 				{
645 					CSPrimCurve* curve = NULL;
646 					if (prim->GetType()==CSPrimitives::CURVE)
647 						curve = prim->ToCurve();
648 					else
649 						curve = prim->ToWire();
650 
651 					unsigned int nrP = (unsigned int)curve->GetNumberOfPoints();
652 					double* dCoords = new double[3*nrP];
653 					double xyz[3];
654 					bool isCurve = (prim->GetType()==CSPrimitives::CURVE);
655 					for (unsigned int n=0;n<nrP;++n)
656 					{
657 						curve->GetPoint(n,xyz,CARTESIAN,isCurve);
658 						dCoords[0*nrP+n] = xyz[0];
659 						dCoords[1*nrP+n] = xyz[1];
660 						dCoords[2*nrP+n] = xyz[2];
661 					}
662 					if (isCurve)
663 						vtkPrims->AddLinePoly(dCoords,nrP,1,rgb,(double)col.a/255.0);
664 					else
665 					{
666 						CSPrimWire* wire = prim->ToWire();
667 						vtkPrims->AddTubePoly(dCoords,nrP,wire->GetWireRadius(),rgb,(double)col.a/255.0,8,transform_matrix);
668 					}
669 					delete[] dCoords; dCoords=NULL;
670 					break;
671 				}
672 				}
673 			}
674 		}
675 	}
676 	VTKWidget->GetRenderWindow()->GetInteractor()->Render();
677 }
678 
RenderDiscMaterialModel()679 void QVTKStructure::RenderDiscMaterialModel()
680 {
681 	for (int i=0;i<m_DiscMatModels.size();++i)
682 	{
683 		delete m_DiscMatModels.at(i).vtk_model;
684 	}
685 	m_DiscMatModels.clear();
686 
687 	if (clCS==NULL) return;
688 
689 	for (unsigned int i=0;i<clCS->GetQtyProperties();++i)
690 	{
691 		CSProperties* prop = clCS->GetProperty(i);
692 		CSPropDiscMaterial* dm_prop = prop->ToDiscMaterial();
693 		if (dm_prop)
694 		{
695 			VTKDiscModel model;
696 			VTKPrimitives* vtkPrims= new VTKPrimitives(ren);
697 			model.vtk_model = vtkPrims;
698 			model.uID = dm_prop->GetUniqueID();
699 			m_DiscMatModels.append(model);
700 			vtkPolyData* polydata = dm_prop->CreatePolyDataModel();
701 
702 			double rgb[3] = {1,1,1};
703 			CSTransform* transform = new CSTransform(dm_prop->GetTransform());
704 			transform->SetPreMultiply();
705 			transform->Scale(dm_prop->GetScale());
706 			double* transform_matrix = NULL;
707 			if (transform)
708 				transform_matrix = transform->GetMatrix();
709 			vtkPrims->AddPolyData(polydata,rgb,1.0,transform_matrix);
710 			delete transform;
711 		}
712 	}
713 	VTKWidget->GetRenderWindow()->GetInteractor()->Render();
714 }
715 
SetParallelProjection(bool val,bool render)716 void QVTKStructure::SetParallelProjection(bool val, bool render)
717 {
718 	vtkCamera* cam = ren->GetActiveCamera();
719 	cam->SetParallelProjection(val);
720 
721 	if (render)
722 		VTKWidget->GetRenderWindow()->GetInteractor()->Render();
723 }
724 
Set2DInteractionStyle(bool val,bool render)725 void QVTKStructure::Set2DInteractionStyle(bool val, bool render)
726 {
727 	if (val)
728 		VTKWidget->GetRenderWindow()->GetInteractor()->SetInteractorStyle(vtkInteractorStyleRubberBand2DPlane::New());
729 	else
730 		VTKWidget->GetRenderWindow()->GetInteractor()->SetInteractorStyle(vtkInteractorStyleTrackballCamera::New());
731 
732 	if (render)
733 		VTKWidget->GetRenderWindow()->GetInteractor()->Render();
734 }
735 
SaveCamData()736 void QVTKStructure::SaveCamData()
737 {
738 	if (m_CamData==NULL)
739 		m_CamData = new CamData;
740 
741 	vtkCamera *Camera = ren->GetActiveCamera();
742 
743 	Camera->GetPosition(m_CamData->pos);
744 	Camera->GetFocalPoint(m_CamData->focalPoint);
745 	Camera->GetViewUp(m_CamData->viewUp);
746 	m_CamData->viewAngle = Camera->GetViewAngle();
747 }
748 
RestoreCamData(bool render)749 void QVTKStructure::RestoreCamData(bool render)
750 {
751 	if (m_CamData==NULL)
752 		return;
753 
754 	vtkCamera *Camera = ren->GetActiveCamera();
755 	Camera->SetPosition( m_CamData->pos );
756 	Camera->SetFocalPoint( m_CamData->focalPoint );
757 	Camera->SetViewUp( m_CamData->viewUp );
758 	Camera->SetViewAngle( m_CamData->viewAngle );
759 	Camera->Modified();
760 
761 	if (render)
762 		VTKWidget->GetRenderWindow()->GetInteractor()->Render();
763 }
764 
765 
ExportView2Image()766 void QVTKStructure::ExportView2Image()
767 {
768 	QString filename = QFileDialog::getSaveFileName(VTKWidget, tr("Choose file to save image"), QString(), tr("Images (*.png)"));
769 
770 	if (filename.isEmpty())
771 		return;
772 
773 	vtkWindowToImageFilter* filter = vtkWindowToImageFilter::New();
774 	filter->SetInput(VTKWidget->GetRenderWindow());
775 
776 	vtkPNGWriter* png_writer= vtkPNGWriter::New();
777 	png_writer->SetInputConnection(filter->GetOutputPort());
778 	//png_writer->SetQuality(100);
779 	png_writer->SetFileName(filename.toStdString().c_str());
780 	png_writer->Write();
781 }
782 
ExportProperty2PolyDataVTK(unsigned int uiID,QString filename,double scale)783 void QVTKStructure::ExportProperty2PolyDataVTK(unsigned int uiID, QString filename, double scale)
784 {
785 	for (int i=0;i<LayerPrimitives.size();++i)
786 	{
787 		if (LayerPrimitives.at(i).uID==uiID)
788 		{
789 			if (LayerPrimitives.at(i).VTKProp!=NULL)
790 			{
791 				QString name = filename + ".vtp";
792 				LayerPrimitives.at(i).VTKProp->WritePolyData2File(name.toStdString().c_str(), scale);
793 			}
794 		}
795 	}
796 
797 	for (int i=0;i<m_DiscMatModels.size();++i)
798 	{
799 		if (m_DiscMatModels.at(i).uID==uiID)
800 		{
801 			if (m_DiscMatModels.at(i).vtk_model!=NULL)
802 			{
803 				QString name = filename + "_DiscMaterial" + ".vtp";
804 				m_DiscMatModels.at(i).vtk_model->WritePolyData2File(name.toStdString().c_str(), scale);
805 			}
806 		}
807 	}
808 }
809 
ExportProperty2STL(unsigned int uiID,QString filename,double scale)810 void QVTKStructure::ExportProperty2STL(unsigned int uiID, QString filename, double scale)
811 {
812 	for (int i=0;i<LayerPrimitives.size();++i)
813 	{
814 		if (LayerPrimitives.at(i).uID==uiID)
815 		{
816 			if (LayerPrimitives.at(i).VTKProp!=NULL)
817 			{
818 				QString name = filename + ".stl";
819 				LayerPrimitives.at(i).VTKProp->WritePolyData2STL(name.toStdString().c_str(), scale);
820 			}
821 		}
822 	}
823 }
824 
ExportProperty2PLY(unsigned int uiID,QString filename,double scale)825 void QVTKStructure::ExportProperty2PLY(unsigned int uiID, QString filename, double scale)
826 {
827 	for (int i=0;i<LayerPrimitives.size();++i)
828 	{
829 		if (LayerPrimitives.at(i).uID==uiID)
830 		{
831 			if (LayerPrimitives.at(i).VTKProp!=NULL)
832 			{
833 				QString name = filename + ".ply";
834 				LayerPrimitives.at(i).VTKProp->WritePolyData2PLY(name.toStdString().c_str(), scale);
835 			}
836 		}
837 	}
838 }
839 
KeyPress(vtkObject * caller,unsigned long eid,void * clientdata,void * calldata)840 void QVTKStructure::KeyPress(vtkObject *caller, unsigned long eid, void *clientdata, void *calldata)
841 {
842 	UNUSED(caller);
843 	UNUSED(eid);
844 	UNUSED(calldata);
845 
846 	//vtkInteractorStyle * istyle = (vtkInteractorStyle *) caller;
847   	vtkRenderWindowInteractor * iren = ((KeyPressData *)clientdata)->iren;
848 	//vtkRenderWindow *renWin = iren->GetRenderWindow();
849 	vtkActor **GridPlanes = ((KeyPressData *)clientdata)->GridPlanes;
850 	//vtkRenderer *ren = ((KeyPressData *)clientdata)->ren;
851 	int key;
852 	key=iren->GetKeyCode();
853 	//	fprintf(stderr,"Event... EiD: %d Key: %d OpenGL?: %d\n",eid,key,renWin->SupportsOpenGL());
854 	switch(key)
855 	{
856 	case 's':
857 	{
858 		for (int n=0;n<3;++n)
859 		{
860 			if (GridPlanes[n])
861 				GridPlanes[n]->GetProperty()->SetRepresentationToWireframe();
862 		}
863 		iren->Render();
864 		break;
865 	}
866 	}
867 }
868 
SetCallback(vtkRenderWindowInteractor * iren)869 void QVTKStructure::SetCallback(vtkRenderWindowInteractor *iren)
870 {
871 	ren->GetActiveCamera()->SetFocalPoint(0,0,0);
872 	//Callback
873 	KeyPressData *cbData = new KeyPressData;
874 	cbData->GridPlanes=ActorGridPlane;
875 	cbData->ren=ren;
876 	cbData->iren=iren;
877 
878 	vtkCallbackCommand *cb = vtkCallbackCommand::New();
879 	cb->SetCallback(KeyPress);
880 	cb->SetClientData((void *)cbData);
881 	iren->AddObserver(vtkCommand::KeyReleaseEvent, cb);
882 	//VTKWidget->GetRenderWindow()->GetInteractor()->AddObserver(vtkCommand::KeyReleaseEvent, cb);
883 
884 	cb->Delete();
885 	//	free(cbData);
886 }
887