1 /****************************************************************************
2 * MeshLab                                                           o o     *
3 * An extendible mesh processor                                    o     o   *
4 *                                                                _   O  _   *
5 * Copyright(C) 2005, 2009                                          \/)\/    *
6 * Visual Computing Lab                                            /\/|      *
7 * ISTI - Italian National Research Council                           |      *
8 *                                                                    \      *
9 * All rights reserved.                                                      *
10 *                                                                           *
11 * This program is free software; you can redistribute it and/or modify      *
12 * it under the terms of the GNU General Public License as published by      *
13 * the Free Software Foundation; either version 2 of the License, or         *
14 * (at your option) any later version.                                       *
15 *                                                                           *
16 * This program is distributed in the hope that it will be useful,           *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of            *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
19 * GNU General Public License (http://www.gnu.org/licenses/gpl.txt)          *
20 * for more details.                                                         *
21 *                                                                           *
22 ****************************************************************************/
23 
24 #include <QtGui>
25 #include <math.h>
26 #include <stdlib.h>
27 #include <meshlab/glarea.h>
28 #include "editslice.h"
29 #include <qstring.h>
30 #include <wrap/gl/pick.h>
31 
32 #include <vcg/complex/algorithms/create/platonic.h>
33 #include <vcg/space/index/grid_closest.h>
34 #include <vcg/complex/intersection.h>
35 #include <wrap/gl/space.h>
36 #include <wrap/gui/trackball.h>
37 #include <qfiledialog.h>
38 #include<limits>
39 #include <vcg/complex/edgemesh/update/bounding.h>
40 #include <wrap/io_trimesh/import.h>
41 
42 #include <vcg/complex/algorithms/update/position.h>
43 #include <vcg/complex/algorithms/update/bounding.h>
44 #include <vcg/complex/algorithms/update/normal.h>
45 
46 using namespace std;
47 using namespace vcg;
48 
49 
50 
51 
ExtraMeshSlidePlugin()52 ExtraMeshSlidePlugin::ExtraMeshSlidePlugin() {
53  dialogsliceobj=0;
54  isDragging=false;
55 
56  trackball_slice.center=Point3f(0, 0, 0);
57  trackball_slice.radius= 50;
58 }
59 
~ExtraMeshSlidePlugin()60 ExtraMeshSlidePlugin::~ExtraMeshSlidePlugin() {
61 if ( dialogsliceobj!=0) {
62 			delete  dialogsliceobj;
63 
64 			 dialogsliceobj=0;
65 			 }
66 
67 }
68 
QT2VCG(Qt::MouseButton qtbt,Qt::KeyboardModifiers modifiers)69 Trackball::Button QT2VCG(Qt::MouseButton qtbt,  Qt::KeyboardModifiers modifiers)
70 {
71 
72 	int vcgbt=Trackball::BUTTON_NONE;
73 	if(qtbt & Qt::LeftButton		) vcgbt |= Trackball::BUTTON_LEFT;
74 	if(qtbt & Qt::RightButton		) vcgbt |= Trackball::BUTTON_RIGHT;
75 	if(qtbt & Qt::MidButton			) vcgbt |= Trackball::BUTTON_MIDDLE;
76 	if(modifiers & Qt::ShiftModifier   ) vcgbt |= Trackball::KEY_SHIFT;
77 	if(modifiers & Qt::ControlModifier ) vcgbt |= Trackball::KEY_CTRL;
78 	if(modifiers & Qt::AltModifier     ) vcgbt |= Trackball::KEY_ALT;
79 
80 	return Trackball::Button(vcgbt);
81 }
82 
Info()83 const QString ExtraMeshSlidePlugin::Info()
84 {
85 	return tr("Interactive selection of plane intersec with mesh");
86 }
87 
mouseReleaseEvent(QMouseEvent * e,MeshModel &,GLArea * gla)88 void ExtraMeshSlidePlugin::mouseReleaseEvent(QMouseEvent * e, MeshModel &/*m*/, GLArea * gla)
89 {
90 	 trackball_slice.MouseUp(e->x(),gla->height()-e->y(),QT2VCG(e->button(), e->modifiers()));
91 }
92 
mousePressEvent(QMouseEvent * e,MeshModel & m,GLArea * gla)93 void ExtraMeshSlidePlugin::mousePressEvent(QMouseEvent * e, MeshModel &m, GLArea * gla)
94  {
95 	  if (  (e->button()==Qt::LeftButton)         &&
96 		  !(e->modifiers() & Qt::ShiftModifier) )
97 		  trackball_slice.MouseDown(e->x(),gla->height()-e->y(),QT2VCG(e->button(), e->modifiers()) );
98 	 gla->update();
99  }
100 
mouseMoveEvent(QMouseEvent * e,MeshModel &,GLArea * gla)101 void ExtraMeshSlidePlugin::mouseMoveEvent(QMouseEvent * e, MeshModel &/*m*/, GLArea * gla)
102  {
103   if( (e->buttons()| Qt::LeftButton) &&
104 	  !(e->modifiers() & Qt::ShiftModifier))
105 				trackball_slice.MouseMove(e->x(),gla->height()-e->y());
106 	gla->update();
107  }
108 
RestoreDefault()109 void ExtraMeshSlidePlugin::RestoreDefault(){
110 			trackball_slice.Reset();
111 			gla->trackball.Reset();
112 			gla->update();
113  }
SlotExportButton()114  void ExtraMeshSlidePlugin::SlotExportButton()
115  {
116 
117 	QFileDialog saveF;
118 	fileName = saveF.getSaveFileName(gla->window(), tr("Saving..."),"/",tr("Mesh (*.svg)"));
119 	if (fileName==0) return;
120     if (!(fileName.endsWith("svg")))
121 		fileName= fileName+".svg";
122 
123 	dialogsliceobj->hide();
124 	Matrix44f mat_trac_rotation ;
125 	trackball_slice.track.rot.ToMatrix( mat_trac_rotation ); //rotation Matrix of the plans' trackball
126         Invert(mat_trac_rotation);
127 	Point3f dir(1,0,0);   //the plans' normal vector init
128 	dir= mat_trac_rotation * dir; //rotation of the directions vector
129 	Point3f translation_plans=trackball_slice.track.tra;  //vettore di translazione dei piani
130 	bool EvportVector=false;           //variabile used after
131 	vector<n_EdgeMesh*> ev;
132 	ev.clear();
133 
134 	pr.projDir = dir;
135 	svgpro= new SVGPro(gla->window(), point_Vector.size(), dialogsliceobj->getExportOption());
136 	svgpro->Init(pr.sizeCm[0], pr.sizeCm[1],1, 1, pr.scale);
137 	if ( svgpro->exec() == QDialog::Accepted )
138 
139 	{
140 		UpdateVal(svgpro, &pr);
141 		if (!dialogsliceobj->getExportOption())
142 			pr.numCol=1;
143 		else
144 			pr.numCol=point_Vector.size();
145 		pr.numRow=1;
146 
147 		mesh_grid = new TriMeshGrid();
148 		mesh_grid->Set(m->cm.face.begin() ,m->cm.face.end());
149 		//pr.scale =  (pr.viewBox[0]/pr.numCol) /(edgeMax*(1.4142)) ;
150 		//pr.textDetails = svgpro->showText ;
151 		for(int i=0; i<point_Vector.size(); i++){
152 			Point3f rotationCenter=m->cm.bbox.Center(); //the point where the plans rotate
153 			Point3f po=point_Vector[i]-m->cm.bbox.Center();
154 			Plane3f p;
155 			p.SetDirection(dir);
156 				/*
157 				/ Equazione del piano ax+by+cz=distance
158 				/  a,b,c coordinata centro di rotazione del piano
159 			    /  x,y,z vettore di rotazione del pinao
160 			   */
161 
162 			Point3f off= mat_trac_rotation * Point3f(translation_plans+po); //translation vector
163 			p.SetOffset( rotationCenter.dot(dir) + off.dot(dir));
164 
165 			double avg_length;
166 			edge_mesh = new n_EdgeMesh();
167 			vcg::Intersection<n_Mesh, n_EdgeMesh, n_Mesh::ScalarType, TriMeshGrid>(p , *edge_mesh, avg_length, mesh_grid, intersected_cells);
168 			vcg::edg::UpdateBounding<n_EdgeMesh>::Box(*edge_mesh);
169 
170 
171 			if (!dialogsliceobj->getExportOption()){
172 			   QString index;
173 			   index.setNum(i);
174 			   fileN=fileName.left( fileName.length ()- 4 )+"_"+index+".svg";
175 			  // pr.setPosition(Point2d(0,0));
176 			   pr.numCol=1;
177 			   pr.numRow=1;
178 
179 			   vcg::edg::io::ExporterSVG<n_EdgeMesh>::Save(*edge_mesh, fileN.toLatin1().data(), pr);
180 
181 			}
182 			else{
183 
184 			 ev.push_back(edge_mesh);
185              EvportVector=true;
186             }
187 		}
188 
189 	if(EvportVector){
190 
191 		vcg::edg::io::ExporterSVG<n_EdgeMesh>::Save(ev, fileName.toLatin1().data(),pr);
192         //Free memory allocated
193 
194 		vector<n_EdgeMesh*>::iterator it;
195 		for(it=ev.begin(); it!=ev.end(); it++){
196 			delete *it;}
197 
198 		}
199    }
200  dialogsliceobj->show();
201  }
202 
UpdateVal(SVGPro * sv,SVGProperties * pr)203 void ExtraMeshSlidePlugin::UpdateVal(SVGPro* sv,  SVGProperties * pr)
204 {
205 	// pr->setDimension(sv->getImageWidth(),sv->getImageHeight());
206 	// pr->viewBox= Point2f(sv->getViewBoxWidth(), sv->getViewBoxHeight());
207 }
Decorate(MeshModel & m,GLArea * gla)208  void ExtraMeshSlidePlugin::Decorate(MeshModel &m, GLArea * gla)
209  {
210 
211 	 this->gla=gla;
212 	 this->m=&m;
213 	 if(!gla->isEnabled()){
214 	    dialogsliceobj->close();
215 	 }
216 	 DrawPlane(this->gla,*(this->m));
217 
218  }
EndEdit(MeshModel & m,GLArea * gla)219  void ExtraMeshSlidePlugin::EndEdit(MeshModel &m, GLArea *gla ){
220 	if ( dialogsliceobj!=0) {
221 			delete  dialogsliceobj;
222 
223 			 dialogsliceobj=0;
224 
225 	 }
226  }
StartEdit(MeshModel & m,GLArea * gla)227  bool ExtraMeshSlidePlugin::StartEdit(MeshModel &m, GLArea *gla ){
228 	 gla->update();
229 	 if(!dialogsliceobj){
230 		 dialogsliceobj=new dialogslice(gla->window());
231 		 dialogsliceobj->show();
232 		 dialogsliceobj->setAllowedAreas(Qt::NoDockWidgetArea);
233 		 this->m=&m;
234 		 QObject::connect(dialogsliceobj, SIGNAL(exportMesh()), this,SLOT(SlotExportButton()));
235          QObject::connect(dialogsliceobj, SIGNAL(Update_glArea()), this, SLOT(upGlA()));
236 	    QObject::connect(dialogsliceobj, SIGNAL(RestoreDefault()), this, SLOT(RestoreDefault()));
237 	 }
238 	 return true;
239 	 }
upGlA()240  void ExtraMeshSlidePlugin::upGlA(){
241 
242 	 gla->update();
243 
244  }
DrawPlane(GLArea * gla,MeshModel & m)245  void ExtraMeshSlidePlugin::DrawPlane(GLArea * gla, MeshModel &m){
246 
247 	b=m.cm.bbox; //Boundig Box
248 	Point3f mi=b.min;
249 	Point3f ma=b.max;
250 	Point3f centre=b.Center() ;
251 	edgeMax=0;
252     float LX= ma[0]-mi[0];
253 	float LY= ma[1]-mi[1];
254 	float LZ= ma[2]-mi[2];
255 	edgeMax= max(LX, LY);
256 	edgeMax=max(edgeMax, LZ); //edgeMax: the longest side of BBox
257 	dialogsliceobj->setDistanceRange(edgeMax);
258 	glPushMatrix();
259 	glPushAttrib(GL_COLOR_BUFFER_BIT|GL_LIGHTING_BIT);
260         trackball_slice.GetView();
261 		trackball_slice.Apply(true);
262 		trackball_slice.center=centre;
263 		trackball_slice.radius=edgeMax;
264         glColor4f(1.0,0.0,0.0,0.8);
265 	    int plane=1;  //number of planes, default=1
266 
267  if(dialogsliceobj!=0) plane=dialogsliceobj->getPlaneNumber();
268   glEnable(GL_BLEND);
269   glEnable(GL_COLOR_MATERIAL);
270   float layer=(float)LX /(float)(plane+1);
271   dialogsliceobj->setDefaultDistance(layer);
272   point_Vector.clear();
273   for(int i=1; i<=(plane); i++){
274 	  int in_ass;
275 	  if(dialogsliceobj->getdistanceDefault())in_ass=0;
276 		else in_ass=2;
277 
278 		glEnable(GL_CULL_FACE);
279 		glColor4f(0,1,0,0.5);
280 		glBegin(GL_QUADS);
281 			glNormal3f(1,0,0);
282 
283 			float assi_x[4];
284 			assi_x[0]=mi[0]+(layer*i);
285 			assi_x[1]=mi[0]+(layer*((plane+1)-i));
286 			assi_x[2]=centre[0]-((dialogsliceobj->getDistance()*(plane+1))/2)+(dialogsliceobj->getDistance()*i);
287 			assi_x[3]=centre[0]-((dialogsliceobj->getDistance()*(plane+1))/2)+(dialogsliceobj->getDistance()*((plane+1)-i));
288 
289 			this->point_Vector.push_back(Point3f(assi_x[in_ass], centre[1], centre[2]));
290 
291 			glVertex3f(assi_x[in_ass], centre[1]-edgeMax, centre[2]-edgeMax);
292 			glVertex3f(assi_x[in_ass], centre[1]+edgeMax, centre[2]-edgeMax);
293 			glVertex3f(assi_x[in_ass], centre[1]+edgeMax, centre[2]+edgeMax);
294 			glVertex3f(assi_x[in_ass], centre[1]-edgeMax, centre[2]+edgeMax);
295 		glEnd();
296 
297 		glColor4f(1,0,0,0.5);
298 		glBegin(GL_QUADS);
299         glNormal3f(-1,0,0);
300         glVertex3f(assi_x[in_ass+1], centre[1]-edgeMax, centre[2]-edgeMax);
301         glVertex3f(assi_x[in_ass+1], centre[1]-edgeMax, centre[2]+edgeMax);
302 		glVertex3f(assi_x[in_ass+1], centre[1]+edgeMax, centre[2]+edgeMax);
303 		glVertex3f(assi_x[in_ass+1], centre[1]+edgeMax, centre[2]-edgeMax);
304 		glEnd();
305 	    }
306       glPopAttrib();
307       glPopMatrix();
308  if(isDragging){
309 		 isDragging=false;
310 		 gla->update();}
311  }
312