1 /****************************************************************************
2  * MeshLab                                                           o o     *
3  * A versatile mesh processing toolbox                             o     o   *
4  *                                                                _   O  _   *
5  * Copyright(C) 2008                                                \/)\/    *
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 <meshlab/glarea.h>
25 #include "edit_manipulators.h"
26 #include <wrap/qt/gl_label.h>
27 #include <wrap/gui/trackball.h>
28 
29 
30 using namespace vcg;
31 
EditManipulatorsPlugin()32 EditManipulatorsPlugin::EditManipulatorsPlugin()
33 {
34   current_manip = EditManipulatorsPlugin::ManNone;
35   current_manip_mode = EditManipulatorsPlugin::ModNone;
36   isMoving = false;
37   isSnapping = false;
38   aroundOrigin = true;
39   snapto = 1;
40   resetOffsets();
41   inputnumberstring= "";
42   inputnumbernegative = false;
43   inputnumber=0;
44 
45   original_Transform = Matrix44m::Identity();
46   delta_Transform = Matrix44m::Identity();
47 }
48 
Info()49 const QString EditManipulatorsPlugin::Info()
50 {
51 	return tr("Provide tools for moving meshes around the space");
52 }
53 
mousePressEvent(QMouseEvent * event,MeshModel &,GLArea * gla)54 void EditManipulatorsPlugin::mousePressEvent(QMouseEvent *event, MeshModel &, GLArea * gla)
55 {
56   isMoving = true;
57   startdrag = Point2i(event->x(),event->y());
58   gla->update();
59 }
60 
mouseMoveEvent(QMouseEvent * event,MeshModel & model,GLArea * gla)61 void EditManipulatorsPlugin::mouseMoveEvent(QMouseEvent * event, MeshModel &model, GLArea * gla)
62 {
63   if(isMoving)
64   {
65     enddrag = Point2i(event->x(),event->y());
66     currScreenOffset_X = enddrag[0] - startdrag[0];
67     currScreenOffset_Y = enddrag[1] - startdrag[1];
68     UpdateMatrix(model, gla, false);
69   }
70   gla->update();
71 }
72 
mouseReleaseEvent(QMouseEvent * event,MeshModel & model,GLArea * gla)73 void EditManipulatorsPlugin::mouseReleaseEvent(QMouseEvent * event, MeshModel &model, GLArea * gla)
74 {
75   if(isMoving)
76   {
77     isMoving = false;
78     enddrag = Point2i(event->x(),event->y());
79     currScreenOffset_X = enddrag[0] - startdrag[0];
80     currScreenOffset_Y = enddrag[1] - startdrag[1];
81     UpdateMatrix(model, gla, true);
82   }
83   gla->update();
84 }
85 
86 // Apply movement
applyMotion(MeshModel & model,GLArea * gla)87 void EditManipulatorsPlugin::applyMotion(MeshModel &model, GLArea *gla)
88 {
89   // the current matrix already contains the motion... so, just keep it there
90 
91   // reset filter data
92   current_manip = EditManipulatorsPlugin::ManNone;
93   current_manip_mode = EditManipulatorsPlugin::ModNone;
94   isMoving = false;
95   isSnapping = false;
96   aroundOrigin = true;
97   snapto = 1.0;
98   resetOffsets();
99 
100   inputnumberstring= "";
101   inputnumbernegative = false;
102   inputnumber=0;
103 
104   // storing start matrix
105   original_Transform = model.cm.Tr;
106   delta_Transform = Matrix44m::Identity();
107 
108   gla->update();
109 }
110 
111 // Cancel movement
cancelMotion(MeshModel & model,GLArea * gla)112 void EditManipulatorsPlugin::cancelMotion(MeshModel &model, GLArea *gla)
113 {
114   //restoring old matrix
115   model.cm.Tr = original_Transform;
116 
117   // reset filter data
118   current_manip = EditManipulatorsPlugin::ManNone;
119   current_manip_mode = EditManipulatorsPlugin::ModNone;
120   isMoving = false;
121   isSnapping = false;
122   aroundOrigin = true;
123   snapto=1.0;
124   resetOffsets();
125 
126   inputnumberstring= "";
127   inputnumbernegative = false;
128   inputnumber=0;
129 
130   // storing start matrix
131   original_Transform = model.cm.Tr;
132   delta_Transform = Matrix44m::Identity();
133 
134   gla->update();
135 }
136 
137 // keyboard press
keyPressEvent(QKeyEvent * e,MeshModel &,GLArea *)138 void EditManipulatorsPlugin::keyPressEvent(QKeyEvent* e, MeshModel& /*model*/, GLArea* /*gla*/)
139 {
140   // shift pressed, entering snapping mode
141   if(e->key() == Qt::Key_Shift)
142   {
143     isSnapping = true;
144   }
145 }
146 
147 // keyboard commands, just like Blender
keyReleaseEvent(QKeyEvent * e,MeshModel & model,GLArea * gla)148 void EditManipulatorsPlugin::keyReleaseEvent(QKeyEvent *e, MeshModel &model, GLArea *gla)
149 {
150   // enter will apply, backspace to cancel
151   if(current_manip != EditManipulatorsPlugin::ManNone)
152   {
153 	if ((e->key() == Qt::Key_Enter) || (e->key() == Qt::Key_Return))
154     {
155       applyMotion(model, gla);
156     }
157 	if (e->key() == Qt::Key_Backspace)
158     {
159       cancelMotion(model, gla);
160     }
161   }
162 
163   // shift released, exit snapping mode
164   if(e->key() == Qt::Key_Shift)
165   {
166     isSnapping = false;
167   }
168 
169   if((current_manip == EditManipulatorsPlugin::ManRotate) || (current_manip == EditManipulatorsPlugin::ManScale))
170   {
171     if ((e->key() == Qt::Key_Space) || (e->key() == Qt::Key_C))
172     {
173       aroundOrigin = !aroundOrigin;
174     }
175   }
176 
177   if(current_manip == EditManipulatorsPlugin::ManNone)   // if no active manipulator, listen to T R S to select one
178   {
179 	  if ((e->key() == Qt::Key_T) || (e->key() == Qt::Key_G)) // translate (I added also G to work like blender)
180     {
181       current_manip = EditManipulatorsPlugin::ManMove;
182       resetOffsets();
183       UpdateMatrix(model,gla,false);
184     }
185 	  if (e->key() == Qt::Key_R) // rotate
186     {
187       current_manip = EditManipulatorsPlugin::ManRotate;
188       resetOffsets();
189       UpdateMatrix(model,gla,false);
190     }
191     if (e->key() == Qt::Key_S) // scale
192     {
193       current_manip = EditManipulatorsPlugin::ManScale;
194       resetOffsets();
195       UpdateMatrix(model,gla,false);
196     }
197   }
198 
199   if(current_manip != EditManipulatorsPlugin::ManNone)   // if there is an active manipulator, listen to modifiers
200   {
201 	  if (e->key() == Qt::Key_X) // X axis
202     {
203       if(current_manip_mode == EditManipulatorsPlugin::ModX)
204         current_manip_mode = EditManipulatorsPlugin::ModXX;
205       else
206         current_manip_mode = EditManipulatorsPlugin::ModX;
207 
208       resetOffsets();
209 
210       UpdateMatrix(model,gla,false);
211     }
212 	  if (e->key() == Qt::Key_Y) // Y axis
213     {
214       if(current_manip_mode == EditManipulatorsPlugin::ModY)
215         current_manip_mode = EditManipulatorsPlugin::ModYY;
216       else
217         current_manip_mode = EditManipulatorsPlugin::ModY;
218 
219       resetOffsets();
220 
221       UpdateMatrix(model,gla,false);
222     }
223 	  if (e->key() == Qt::Key_Z) // Z axis
224     {
225       if(current_manip_mode == EditManipulatorsPlugin::ModZ)
226         current_manip_mode = EditManipulatorsPlugin::ModZZ;
227       else
228         current_manip_mode = EditManipulatorsPlugin::ModZ;
229 
230       resetOffsets();
231 
232       UpdateMatrix(model,gla,false);
233     }
234   }
235 
236   // numerical input
237   if ((current_manip == EditManipulatorsPlugin::ManScale) || (current_manip == EditManipulatorsPlugin::ManRotate) || (current_manip_mode != EditManipulatorsPlugin::ModNone))  // transform on one axis only
238   {
239 	bool hasNumberChanged = false;
240 
241 	if (e->key() == Qt::Key_1) { inputnumberstring += "1"; hasNumberChanged = true; }
242 	if (e->key() == Qt::Key_2) { inputnumberstring += "2"; hasNumberChanged = true; }
243 	if (e->key() == Qt::Key_3) { inputnumberstring += "3"; hasNumberChanged = true; }
244 	if (e->key() == Qt::Key_4) { inputnumberstring += "4"; hasNumberChanged = true; }
245 	if (e->key() == Qt::Key_5) { inputnumberstring += "5"; hasNumberChanged = true; }
246 	if (e->key() == Qt::Key_6) { inputnumberstring += "6"; hasNumberChanged = true; }
247 	if (e->key() == Qt::Key_7) { inputnumberstring += "7"; hasNumberChanged = true; }
248 	if (e->key() == Qt::Key_8) { inputnumberstring += "8"; hasNumberChanged = true; }
249 	if (e->key() == Qt::Key_9) { inputnumberstring += "9"; hasNumberChanged = true; }
250 
251     if (e->key() == Qt::Key_0)
252     {
253       if(inputnumberstring.length() == 0)
254         inputnumberstring = "0.";
255       if((inputnumberstring.length() >= 2) || (inputnumberstring[0]!=0))
256         inputnumberstring += "0";
257 
258 	  hasNumberChanged = true;
259     }
260 
261     if (e->key() == Qt::Key_Period)
262     {
263       if(inputnumberstring.length() == 0)
264         inputnumberstring = "0.";
265       else if(!inputnumberstring.contains("."))
266         inputnumberstring += ".";
267 
268 	  hasNumberChanged = true;
269     }
270 
271 	if (e->key() == Qt::Key_Minus)
272     {
273 		inputnumbernegative = !inputnumbernegative;
274 		hasNumberChanged = true;
275 	}
276 
277 	if (!inputnumbernegative)
278       inputnumber = inputnumberstring.toFloat();
279 	else
280       inputnumber = -inputnumberstring.toFloat();
281 
282 	if (hasNumberChanged)
283 		UpdateMatrix(model, gla, false, true);
284   }
285 
286   //else e->ignore();
287   gla->update();
288 }
289 
resetOffsets()290 void EditManipulatorsPlugin::resetOffsets()
291 {
292   if(current_manip == EditManipulatorsPlugin::ManScale)
293   {
294     displayOffset = 1;        // mouse offset value (single axis)
295     displayOffset_X = 1;      // mouse X offset value
296     displayOffset_Y = 1;      // mouse Y offset value
297     displayOffset_Z = 1;      // mouse Z offset value
298     currOffset = 1;           // combined offset value (single axis)
299     currOffset_X = 1;         // X offset value
300     currOffset_Y = 1;         // Y offset value
301     currOffset_Z = 1;         // Z offset value
302   }
303   else
304   {
305     displayOffset = 0;        // mouse offset value (single axis)
306     displayOffset_X = 0;      // mouse X offset value
307     displayOffset_Y = 0;      // mouse Y offset value
308     displayOffset_Z = 0;      // mouse Z offset value
309     currOffset = 0;           // combined offset value (single axis)
310     currOffset_X = 0;         // X offset value
311     currOffset_Y = 0;         // Y offset value
312     currOffset_Z = 0;         // Z offset value
313   }
314 
315   currScreenOffset_X = 0;   // horizontal offset (screen space)
316   currScreenOffset_Y = 0;   // vertical offset (screen space)
317 }
318 
DrawMeshBox(MeshModel & model)319 void EditManipulatorsPlugin::DrawMeshBox(MeshModel &model)
320 {
321     Box3m b;
322 	b = model.cm.bbox;
323 	Point3m mi=b.min;
324 	Point3m ma=b.max;
325 	Point3m d3=(b.max-b.min)/4.0;
326 	Point3m zz(0,0,0);
327 
328   // setup
329     glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT );
330     glDisable(GL_LIGHTING);
331     glDisable(GL_TEXTURE_2D);
332     glEnable(GL_BLEND);
333     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
334     glEnable(GL_LINE_SMOOTH);
335     glLineWidth(1.0);
336     glColor(vcg::Color4b(Color4b::Cyan));
337 
338     glPushMatrix();
339     glMultMatrix(original_Transform);
340 
341 	glBegin(GL_LINES);
342 	glColor3f(1.0, 0.5, 0.5); glVertex3f(mi[0],mi[1],mi[2]); glVertex3f(mi[0]+d3[0],mi[1]+zz[1],mi[2]+zz[2]);
343 	glColor3f(0.5, 1.0, 0.5); glVertex3f(mi[0],mi[1],mi[2]); glVertex3f(mi[0]+zz[0],mi[1]+d3[1],mi[2]+zz[2]);
344 	glColor3f(0.5, 0.5, 1.0); glVertex3f(mi[0],mi[1],mi[2]); glVertex3f(mi[0]+zz[0],mi[1]+zz[1],mi[2]+d3[2]);
345 
346 	glColor3f(1.0, 0.5, 0.5); glVertex3f(ma[0],mi[1],mi[2]); glVertex3f(ma[0]-d3[0],mi[1]+zz[1],mi[2]+zz[2]);
347 	glColor3f(0.5, 1.0, 0.5); glVertex3f(ma[0],mi[1],mi[2]); glVertex3f(ma[0]+zz[0],mi[1]+d3[1],mi[2]+zz[2]);
348 	glColor3f(0.5, 0.5, 1.0); glVertex3f(ma[0],mi[1],mi[2]); glVertex3f(ma[0]+zz[0],mi[1]+zz[1],mi[2]+d3[2]);
349 
350 	glColor3f(1.0, 0.5, 0.5); glVertex3f(mi[0],ma[1],mi[2]); glVertex3f(mi[0]+d3[0],ma[1]+zz[1],mi[2]+zz[2]);
351 	glColor3f(0.5, 1.0, 0.5); glVertex3f(mi[0],ma[1],mi[2]); glVertex3f(mi[0]+zz[0],ma[1]-d3[1],mi[2]+zz[2]);
352 	glColor3f(0.5, 0.5, 1.0); glVertex3f(mi[0],ma[1],mi[2]); glVertex3f(mi[0]+zz[0],ma[1]+zz[1],mi[2]+d3[2]);
353 
354 	glColor3f(1.0, 0.5, 0.5); glVertex3f(ma[0],ma[1],mi[2]); glVertex3f(ma[0]-d3[0],ma[1]+zz[1],mi[2]+zz[2]);
355 	glColor3f(0.5, 1.0, 0.5); glVertex3f(ma[0],ma[1],mi[2]); glVertex3f(ma[0]+zz[0],ma[1]-d3[1],mi[2]+zz[2]);
356 	glColor3f(0.5, 0.5, 1.0); glVertex3f(ma[0],ma[1],mi[2]); glVertex3f(ma[0]+zz[0],ma[1]+zz[1],mi[2]+d3[2]);
357 
358 	glColor3f(1.0, 0.5, 0.5); glVertex3f(mi[0],mi[1],ma[2]); glVertex3f(mi[0]+d3[0],mi[1]+zz[1],ma[2]+zz[2]);
359 	glColor3f(0.5, 1.0, 0.5); glVertex3f(mi[0],mi[1],ma[2]); glVertex3f(mi[0]+zz[0],mi[1]+d3[1],ma[2]+zz[2]);
360 	glColor3f(0.5, 0.5, 1.0); glVertex3f(mi[0],mi[1],ma[2]); glVertex3f(mi[0]+zz[0],mi[1]+zz[1],ma[2]-d3[2]);
361 
362 	glColor3f(1.0, 0.5, 0.5); glVertex3f(ma[0],mi[1],ma[2]); glVertex3f(ma[0]-d3[0],mi[1]+zz[1],ma[2]+zz[2]);
363 	glColor3f(0.5, 1.0, 0.5); glVertex3f(ma[0],mi[1],ma[2]); glVertex3f(ma[0]+zz[0],mi[1]+d3[1],ma[2]+zz[2]);
364 	glColor3f(0.5, 0.5, 1.0); glVertex3f(ma[0],mi[1],ma[2]); glVertex3f(ma[0]+zz[0],mi[1]+zz[1],ma[2]-d3[2]);
365 
366 	glColor3f(1.0, 0.5, 0.5); glVertex3f(mi[0],ma[1],ma[2]); glVertex3f(mi[0]+d3[0],ma[1]+zz[1],ma[2]+zz[2]);
367 	glColor3f(0.5, 1.0, 0.5); glVertex3f(mi[0],ma[1],ma[2]); glVertex3f(mi[0]+zz[0],ma[1]-d3[1],ma[2]+zz[2]);
368 	glColor3f(0.5, 0.5, 1.0); glVertex3f(mi[0],ma[1],ma[2]); glVertex3f(mi[0]+zz[0],ma[1]+zz[1],ma[2]-d3[2]);
369 
370 	glColor3f(1.0, 0.5, 0.5); glVertex3f(ma[0],ma[1],ma[2]); glVertex3f(ma[0]-d3[0],ma[1]+zz[1],ma[2]+zz[2]);
371 	glColor3f(0.5, 1.0, 0.5); glVertex3f(ma[0],ma[1],ma[2]); glVertex3f(ma[0]+zz[0],ma[1]-d3[1],ma[2]+zz[2]);
372 	glColor3f(0.5, 0.5, 1.0); glVertex3f(ma[0],ma[1],ma[2]); glVertex3f(ma[0]+zz[0],ma[1]+zz[1],ma[2]-d3[2]);
373 	glEnd();
374 
375 
376   //drawing mesh origin
377     glBegin(GL_LINES);
378     glColor3f(1.0, 0.5, 0.5); glVertex3f(-2.0*d3[0], 0.0, 0.0); glVertex3f(2.0*d3[0],0.0,0.0);
379 	glColor3f(0.5, 1.0, 0.5); glVertex3f(0.0, -2.0*d3[1], 0.0); glVertex3f(0.0, 2.0*d3[1], 0.0);
380 	glColor3f(0.5, 0.5, 1.0); glVertex3f(0.0, 0.0, -2.0*d3[2]); glVertex3f(0.0, 0.0, 2.0*d3[2]);
381 	glEnd();
382 
383   // restore
384   glPopMatrix();
385   glPopAttrib();
386 }
387 
388 
389 //----------------------------------------------------------------------------------
390 
DrawCubes(float r,float g,float b)391 void EditManipulatorsPlugin::DrawCubes(float r, float g, float b)
392 {
393   glColor4f(r,g,b,1.0f);
394   glBegin (GL_LINES);
395       // mid line
396     glVertex3f( 0.0f,  0.0f, -1.0f);
397     glVertex3f( 0.0f,  0.0f,  1.0f);
398   glEnd ();
399 
400   glBegin (GL_LINES);
401       // right cube
402     glVertex3f(  0.0f,  0.0f,  1.0f);
403     glVertex3f(  0.1f,  0.0f,  1.1f);
404     glVertex3f(  0.0f,  0.0f,  1.0f);
405     glVertex3f( -0.1f,  0.0f,  1.1f);
406     glVertex3f(  0.0f,  0.0f,  1.0f);
407     glVertex3f(  0.0f, -0.1f,  1.1f);
408     glVertex3f(  0.0f,  0.0f,  1.0f);
409     glVertex3f(  0.0f,  0.1f,  1.1f);
410     glVertex3f(  0.0f,  0.0f,  1.2f);
411     glVertex3f(  0.1f,  0.0f,  1.1f);
412     glVertex3f(  0.0f,  0.0f,  1.2f);
413     glVertex3f( -0.1f,  0.0f,  1.1f);
414     glVertex3f(  0.0f,  0.0f,  1.2f);
415     glVertex3f(  0.0f, -0.1f,  1.1f);
416     glVertex3f(  0.0f,  0.0f,  1.2f);
417     glVertex3f(  0.0f,  0.1f,  1.1f);
418   glEnd ();
419 
420   glBegin (GL_LINES);
421       // left cube
422     glVertex3f(  0.0f,  0.0f, -1.0f);
423     glVertex3f(  0.1f,  0.0f, -1.1f);
424     glVertex3f(  0.0f,  0.0f, -1.0f);
425     glVertex3f( -0.1f,  0.0f, -1.1f);
426     glVertex3f(  0.0f,  0.0f, -1.0f);
427     glVertex3f(  0.0f, -0.1f, -1.1f);
428     glVertex3f(  0.0f,  0.0f, -1.0f);
429     glVertex3f(  0.0f,  0.1f, -1.1f);
430     glVertex3f(  0.0f,  0.0f, -1.2f);
431     glVertex3f(  0.1f,  0.0f, -1.1f);
432     glVertex3f(  0.0f,  0.0f, -1.2f);
433     glVertex3f( -0.1f,  0.0f, -1.1f);
434     glVertex3f(  0.0f,  0.0f, -1.2f);
435     glVertex3f(  0.0f, -0.1f, -1.1f);
436     glVertex3f(  0.0f,  0.0f, -1.2f);
437     glVertex3f(  0.0f,  0.1f, -1.1f);
438   glEnd ();
439 
440 
441     // right cube
442   glColor4f(std::min(1.0f,r+0.2f), std::min(1.0f,g+0.2f), std::min(1.0f,b+0.2f),0.5f);
443   glBegin (GL_TRIANGLE_FAN);
444     glVertex3f(  0.0f,  0.0f,  1.2f);
445     glVertex3f(  0.0f,  0.1f,  1.1f);
446     glVertex3f( -0.1f,  0.0f,  1.1f);
447     glVertex3f(  0.0f, -0.1f,  1.1f);
448     glVertex3f(  0.1f,  0.0f,  1.1f);
449     glVertex3f(  0.0f,  0.1f,  1.1f);
450   glEnd();
451   glBegin (GL_TRIANGLE_FAN);
452     glVertex3f(  0.0f,  0.0f,  1.0f);
453     glVertex3f(  0.0f,  0.1f,  1.1f);
454     glVertex3f( -0.1f,  0.0f,  1.1f);
455     glVertex3f(  0.0f, -0.1f,  1.1f);
456     glVertex3f(  0.1f,  0.0f,  1.1f);
457     glVertex3f(  0.0f,  0.1f,  1.1f);
458   glEnd();
459 
460       // left cube
461   glBegin (GL_TRIANGLE_FAN);
462     glVertex3f(  0.0f,  0.0f, -1.2f);
463     glVertex3f(  0.0f,  0.1f, -1.1f);
464     glVertex3f( -0.1f,  0.0f, -1.1f);
465     glVertex3f(  0.0f, -0.1f, -1.1f);
466     glVertex3f(  0.1f,  0.0f, -1.1f);
467     glVertex3f(  0.0f,  0.1f, -1.1f);
468   glEnd();
469   glBegin (GL_TRIANGLE_FAN);
470     glVertex3f(  0.0f,  0.0f, -1.0f);
471     glVertex3f(  0.0f,  0.1f, -1.1f);
472     glVertex3f( -0.1f,  0.0f, -1.1f);
473     glVertex3f(  0.0f, -0.1f, -1.1f);
474     glVertex3f(  0.1f,  0.0f, -1.1f);
475     glVertex3f(  0.0f,  0.1f, -1.1f);
476   glEnd();
477 }
478 
DrawArrows(float r,float g,float b)479 void EditManipulatorsPlugin::DrawArrows(float r, float g, float b)
480 {
481   glColor4f(r,g,b,1.0f);
482   glBegin (GL_LINES);
483       // mid line
484     glVertex3f( 0.0f,  0.0f, -1.1f);
485     glVertex3f( 0.0f,  0.0f,  1.1f);
486 
487       // right arrow
488     glVertex3f(  0.0f,  0.0f,  1.1f);
489     glVertex3f(  0.1f,  0.1f,  0.9f);
490     glVertex3f(  0.0f,  0.0f,  1.1f);
491     glVertex3f( -0.1f,  0.1f,  0.9f);
492     glVertex3f(  0.0f,  0.0f,  1.1f);
493     glVertex3f(  0.1f, -0.1f,  0.9f);
494     glVertex3f(  0.0f,  0.0f,  1.1f);
495     glVertex3f( -0.1f, -0.1f,  0.9f);
496 
497       // left arrow
498     glVertex3f(  0.0f,  0.0f, -1.1f);
499     glVertex3f(  0.1f,  0.1f, -0.9f);
500     glVertex3f(  0.0f,  0.0f, -1.1f);
501     glVertex3f( -0.1f,  0.1f, -0.9f);
502     glVertex3f(  0.0f,  0.0f, -1.1f);
503     glVertex3f(  0.1f, -0.1f, -0.9f);
504     glVertex3f(  0.0f,  0.0f, -1.1f);
505     glVertex3f( -0.1f, -0.1f, -0.9f);
506   glEnd ();
507 
508     // right arrow
509   glColor4f(std::min(1.0f,r+0.2f), std::min(1.0f,g+0.2f), std::min(1.0f,b+0.2f), 0.5f);
510   glBegin (GL_TRIANGLE_FAN);
511     glVertex3f(  0.0f,  0.0f,  1.1f);
512     glVertex3f(  0.1f,  0.1f,  0.9f);
513     glVertex3f( -0.1f,  0.1f,  0.9f);
514     glVertex3f( -0.1f, -0.1f,  0.9f);
515     glVertex3f(  0.1f, -0.1f,  0.9f);
516     glVertex3f(  0.1f,  0.1f,  0.9f);
517   glEnd();
518       // left arrow
519   glBegin (GL_TRIANGLE_FAN);
520     glVertex3f(  0.0f,  0.0f, -1.1f);
521     glVertex3f(  0.1f,  0.1f, -0.9f);
522     glVertex3f( -0.1f,  0.1f, -0.9f);
523     glVertex3f( -0.1f, -0.1f, -0.9f);
524     glVertex3f(  0.1f, -0.1f, -0.9f);
525     glVertex3f(  0.1f,  0.1f, -0.9f);
526   glEnd();
527 }
528 
DrawCircle(float r,float g,float b)529 void EditManipulatorsPlugin::DrawCircle(float r, float g, float b)
530 {
531   int nside =32;
532   const double pi2 = 3.14159265 * 2.0;
533 
534   glColor4f(r,g,b,1.0);
535   glBegin (GL_LINE_LOOP);
536   for (double i = 0; i < nside; i++) {
537     glNormal3d (cos (i * pi2 / nside), sin (i * pi2 / nside), 0.0);
538     glVertex3d (cos (i * pi2 / nside), sin (i * pi2 / nside), 0.0);
539   }
540   glEnd();
541   glColor4f(std::min(1.0f,r+0.2f), std::min(1.0f,g+0.2f), std::min(1.0f,b+0.2f), 0.5f);
542   glBegin (GL_TRIANGLE_FAN);
543   glVertex3d (0.0, 0.0, 0.0);
544   int renderangle;
545   if (displayOffset>=0)
546    renderangle = int(displayOffset)%360;
547   else
548    renderangle = 360 - (int(-displayOffset)%360);
549 
550   for (double i = 0; i<=renderangle; i++)
551   {
552     glVertex3d (cos (i * pi2 / 360.0), sin (i * pi2 / 360.0), 0.0);
553   }
554   glEnd();
555 
556 
557 }
558 
559 //----------------------------------------------------------------------------------
560 
DrawTranslateManipulators(MeshModel & model,GLArea * gla)561 void  EditManipulatorsPlugin::DrawTranslateManipulators(MeshModel &model, GLArea *gla)
562 {
563   glPushMatrix();
564 
565   Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis, new_mesh_origin;
566   mesh_boxcenter = original_Transform * model.cm.bbox.Center();
567   mesh_origin = original_Transform.GetColumn3(3);
568   new_mesh_origin = model.cm.Tr.GetColumn3(3);
569   mesh_xaxis = original_Transform.GetColumn3(0);
570   mesh_yaxis = original_Transform.GetColumn3(1);
571   mesh_zaxis = original_Transform.GetColumn3(2);
572   float manipsize = model.cm.bbox.Diag() / 2.0;
573   Matrix44f track_rotation;
574   gla->trackball.track.rot.ToMatrix(track_rotation);
575 
576   glLineWidth(2.0);
577 
578   switch(current_manip_mode)
579   {
580     case EditManipulatorsPlugin::ModNone:
581       glTranslate(new_mesh_origin);
582       glScale(manipsize);
583       glMultMatrix(Inverse(track_rotation));
584 	    glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
585 	    DrawArrows(1.0f,0.8f,0.5f);
586 	    glRotatef (90.0f, 1.0f, 0.0f, 0.0f);
587 	    DrawArrows(1.0f,0.8f,0.5f);
588       break;
589     case EditManipulatorsPlugin::ModX:
590       glTranslate(new_mesh_origin);
591       glScale(manipsize);
592 	    glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
593 	    DrawArrows(1.0f,0.0f,0.0f);
594       break;
595     case EditManipulatorsPlugin::ModY:
596       glTranslate(new_mesh_origin);
597       glScale(manipsize);
598 	    glRotatef (90, 1, 0, 0);
599 	    DrawArrows(0,1.0,0);
600       break;
601     case EditManipulatorsPlugin::ModZ:
602       glTranslate(new_mesh_origin);
603       glScale(manipsize);
604 	    DrawArrows(0,0,1.0);
605       break;
606     case EditManipulatorsPlugin::ModXX:
607       glMultMatrix(model.cm.Tr);
608       glScale(manipsize);
609 	    glRotatef (90, 0, 1, 0);
610 	    DrawArrows(1.0,0.5,0.5);
611       break;
612     case EditManipulatorsPlugin::ModYY:
613       glMultMatrix(model.cm.Tr);
614       glScale(manipsize);
615 	    glRotatef (90, 1, 0, 0);
616 	    DrawArrows(0.5,1.0,0.5);
617       break;
618     case EditManipulatorsPlugin::ModZZ:
619       glMultMatrix(model.cm.Tr);
620       glScale(manipsize);
621 	    DrawArrows(0.5,0.5,1.0);
622       break;
623     default: ;
624   }
625 
626   glLineWidth(1.0);
627 	glPopMatrix();
628 }
629 
DrawScaleManipulators(MeshModel & model,GLArea * gla)630 void  EditManipulatorsPlugin::DrawScaleManipulators(MeshModel &model, GLArea *gla)
631 {
632   glPushMatrix();
633 
634   Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis;
635   mesh_boxcenter = original_Transform * model.cm.bbox.Center();
636   mesh_origin = original_Transform.GetColumn3(3);
637   mesh_xaxis = original_Transform.GetColumn3(0);
638   mesh_yaxis = original_Transform.GetColumn3(1);
639   mesh_zaxis = original_Transform.GetColumn3(2);
640   float manipsize(model.cm.bbox.Diag() / 2.0);
641   Matrix44f original_rot = original_Transform;
642   original_rot.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
643   Matrix44f track_rotation;
644   gla->trackball.track.rot.ToMatrix(track_rotation);
645 
646   glLineWidth(2.0);
647 
648   switch(current_manip_mode)
649   {
650     case EditManipulatorsPlugin::ModNone:
651       if(!aroundOrigin)
652         glTranslate(mesh_boxcenter);
653       else
654         glTranslate(mesh_origin);
655       glScale(manipsize);
656       glMultMatrix(Inverse(track_rotation));
657 	    glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
658 	    DrawCubes(1.0f,0.8f,0.5f);
659       glRotatef (90.0f, 1.0f, 0.0f, 0.0f);
660 	    DrawCubes(1.0f,0.8f,0.5f);
661       break;
662     case EditManipulatorsPlugin::ModX:
663       if(!aroundOrigin)
664         glTranslate(mesh_boxcenter);
665       else
666         glTranslate(mesh_origin);
667       glScale(manipsize);
668 	    glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
669 	    DrawCubes(1.0f,0.0f,0.0f);
670       break;
671     case EditManipulatorsPlugin::ModY:
672       if(!aroundOrigin)
673         glTranslate(mesh_boxcenter);
674       else
675         glTranslate(mesh_origin);
676       glScale(manipsize);
677 	    glRotatef (90.0f, 1.0f, 0.0f, 0.0f);
678 	    DrawCubes(0.0f,1.0f,0.0f);
679       break;
680     case EditManipulatorsPlugin::ModZ:
681       if(!aroundOrigin)
682         glTranslate(mesh_boxcenter);
683       else
684         glTranslate(mesh_origin);
685       glScale(manipsize);
686 	    DrawCubes(0,0,1.0);
687       break;
688     case EditManipulatorsPlugin::ModXX:
689 		if (!aroundOrigin)
690 		{
691 			glTranslate(mesh_boxcenter);
692 			glMultMatrix(original_rot);
693 		}
694 		else
695 			glMultMatrix(original_Transform);
696 		glScale(manipsize);
697 		glRotatef (90, 0, 1, 0);
698 		DrawCubes(1.0,0.5,0.5);
699       break;
700     case EditManipulatorsPlugin::ModYY:
701 		if (!aroundOrigin)
702 		{
703 			glTranslate(mesh_boxcenter);
704 			glMultMatrix(original_rot);
705 		}
706 		else
707 			glMultMatrix(original_Transform);
708 		glScale(manipsize);
709 		glRotatef (90, 1, 0, 0);
710 		DrawCubes(0.5,1.0,0.5);
711       break;
712     case EditManipulatorsPlugin::ModZZ:
713 		if (!aroundOrigin)
714 		{
715 			glTranslate(mesh_boxcenter);
716 			glMultMatrix(original_rot);
717 		}
718 		else
719 			glMultMatrix(original_Transform);
720 		glScale(manipsize);
721 		DrawCubes(0.5,0.5,1.0);
722       break;
723     default: ;
724   }
725 
726   glLineWidth(1.0);
727 	glPopMatrix ();
728 }
729 
DrawRotateManipulators(MeshModel & model,GLArea * gla)730 void  EditManipulatorsPlugin::DrawRotateManipulators(MeshModel &model, GLArea *gla)
731 {
732   glPushMatrix();
733 
734   Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis, new_mesh_origin;
735   mesh_boxcenter = original_Transform * model.cm.bbox.Center();
736   mesh_origin = original_Transform.GetColumn3(3);
737   new_mesh_origin = model.cm.Tr.GetColumn3(3);
738   mesh_xaxis = original_Transform.GetColumn3(0);
739   mesh_yaxis = original_Transform.GetColumn3(1);
740   mesh_zaxis = original_Transform.GetColumn3(2);
741   float manipsize = model.cm.bbox.Diag() / 2.0;
742   Matrix44f original_rot = original_Transform;
743   original_rot.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
744   Matrix44f track_rotation;
745   gla->trackball.track.rot.ToMatrix(track_rotation);
746 
747   glLineWidth(2.0);
748 
749   switch(current_manip_mode)
750   {
751     case EditManipulatorsPlugin::ModNone:
752       if(!aroundOrigin)
753         glTranslate(mesh_boxcenter);
754       else
755         glTranslate(mesh_origin);
756       glScale(manipsize);
757       glMultMatrix(Inverse(track_rotation));
758 	    DrawCircle(1.0f,0.8f,0.5f);
759       break;
760     case EditManipulatorsPlugin::ModX:
761        if(!aroundOrigin)
762         glTranslate(mesh_boxcenter);
763       else
764         glTranslate(mesh_origin);
765       glScale(manipsize);
766 	    glRotatef (90, 0, 1, 0);
767 	    DrawCircle(1.0,0,0);
768       break;
769     case EditManipulatorsPlugin::ModY:
770        if(!aroundOrigin)
771         glTranslate(mesh_boxcenter);
772       else
773         glTranslate(mesh_origin);
774       glScale(manipsize);
775 	    glRotatef (-90, 1, 0, 0);
776 	    DrawCircle(0,1.0,0);
777       break;
778     case EditManipulatorsPlugin::ModZ:
779       if(!aroundOrigin)
780         glTranslate(mesh_boxcenter);
781       else
782         glTranslate(mesh_origin);
783       glScale(manipsize);
784 	    DrawCircle(0,0,1.0);
785       break;
786     case EditManipulatorsPlugin::ModXX:
787 		if(!aroundOrigin)
788 		{
789 			glTranslate(mesh_boxcenter);
790 			glMultMatrix(original_rot);
791 		}
792 		else
793 			glMultMatrix(original_Transform);
794 		glScale(manipsize);
795 		glRotatef (90, 0, 1, 0);
796 		DrawCircle(1.0,0.5,0.5);
797 		break;
798     case EditManipulatorsPlugin::ModYY:
799 		if(!aroundOrigin)
800 		{
801 			glTranslate(mesh_boxcenter);
802 			glMultMatrix(original_rot);
803 		}
804 		else
805 			glMultMatrix(original_Transform);
806 		glScale(manipsize);
807 		glRotatef (-90, 1, 0, 0);
808 		DrawCircle(0.5,1.0,0.5);
809 		break;
810     case EditManipulatorsPlugin::ModZZ:
811 		if (!aroundOrigin)
812 		{
813 			glTranslate(mesh_boxcenter);
814 			glMultMatrix(original_rot);
815 		}
816 		else
817 			glMultMatrix(original_Transform);
818 		glScale(manipsize);
819 		DrawCircle(0.5,0.5,1.0);
820 		break;
821     default: ;
822   }
823 
824   glLineWidth(1.0);
825 	glPopMatrix();
826 }
827 
DrawManipulators(MeshModel & model,GLArea * gla,bool)828 void EditManipulatorsPlugin::DrawManipulators(MeshModel &model, GLArea *gla, bool /*onlyActive*/)
829 {
830   Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis;
831   mesh_boxcenter = original_Transform * model.cm.bbox.Center();
832   mesh_origin = original_Transform.GetColumn3(3);
833   mesh_xaxis = original_Transform.GetColumn3(0);
834   mesh_yaxis = original_Transform.GetColumn3(1);
835   mesh_zaxis = original_Transform.GetColumn3(2);
836 
837   // setup
838 	glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT );
839 	glDisable(GL_LIGHTING);
840 	glEnable(GL_BLEND);
841 	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
842 	glEnable(GL_LINE_SMOOTH);
843 
844   switch(current_manip)
845   {
846     case EditManipulatorsPlugin::ManMove:
847       DrawTranslateManipulators(model, gla);
848       break;
849     case EditManipulatorsPlugin::ManRotate:
850       DrawRotateManipulators(model, gla);
851       break;
852     case EditManipulatorsPlugin::ManScale:
853       DrawScaleManipulators(model, gla);
854       break;
855     default: ;
856   }
857 
858   if(current_manip_mode != EditManipulatorsPlugin::ModNone)
859   {
860     glBegin(GL_LINES);
861 
862     switch(current_manip_mode)
863     {
864       case EditManipulatorsPlugin::ModX:
865         glColor3f(1.0,0,0);
866         if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
867         {
868           glVertex(mesh_origin + Point3m(Scalarm(-10.0),Scalarm(0.0),Scalarm(0.0)));
869           glVertex(mesh_origin + Point3m(Scalarm(10.0), Scalarm(0.0),Scalarm(0.0)));
870         }
871         else
872         {
873           glVertex(mesh_boxcenter + Point3m(Scalarm(-10.0),Scalarm(0.0),Scalarm(0.0)));
874           glVertex(mesh_boxcenter + Point3m(Scalarm(10.0),Scalarm(0.0),Scalarm(0.0)));
875         }
876         break;
877       case EditManipulatorsPlugin::ModY:
878         glColor3f(0,1.0,0);
879         if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
880         {
881           glVertex(mesh_origin + Point3m(Scalarm(0.0),Scalarm(-10.0),Scalarm(0.0)));
882           glVertex(mesh_origin + Point3m(Scalarm(0.0),Scalarm(10.0),Scalarm(0.0)));
883         }
884         else
885         {
886           glVertex(mesh_boxcenter + Point3m(Scalarm(0.0), Scalarm(-10.0),Scalarm(0.0)));
887           glVertex(mesh_boxcenter + Point3m(Scalarm(0.0), Scalarm(10.0), Scalarm(0.0)));
888         }
889         break;
890       case EditManipulatorsPlugin::ModZ:
891         glColor3f(0,0,1.0);
892         if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
893         {
894           glVertex(mesh_origin + Point3m(Scalarm(0.0),Scalarm(0.0),Scalarm(-10.0)));
895           glVertex(mesh_origin + Point3m(Scalarm(0.0),Scalarm(0.0),Scalarm(10.0)));
896         }
897         else
898         {
899           glVertex(mesh_boxcenter + Point3m(Scalarm(0.0),Scalarm(0.0), Scalarm(-10.0)));
900           glVertex(mesh_boxcenter + Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(10.0)));
901         }
902         break;
903       case EditManipulatorsPlugin::ModXX:
904         glColor3f(1.0f,0.5f,0.5f);
905         if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
906         {
907           glVertex(mesh_origin + (mesh_xaxis * Scalarm(-10.0)));
908           glVertex(mesh_origin + (mesh_xaxis * Scalarm(10.0)));
909         }
910         else
911         {
912           glVertex(mesh_boxcenter + (mesh_xaxis * Scalarm(-10.0)));
913           glVertex(mesh_boxcenter + (mesh_xaxis * Scalarm(10.0)));
914         }
915         break;
916       case EditManipulatorsPlugin::ModYY:
917         glColor3f(0.5,1.0,0.5);
918         if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
919         {
920           glVertex(mesh_origin + (mesh_yaxis * Scalarm(-10.0)));
921           glVertex(mesh_origin + (mesh_yaxis * Scalarm(10.0)));
922         }
923         else
924         {
925           glVertex(mesh_boxcenter + (mesh_yaxis * Scalarm(-10.0)));
926           glVertex(mesh_boxcenter + (mesh_yaxis * Scalarm(10.0)));
927         }
928         break;
929       case EditManipulatorsPlugin::ModZZ:
930         glColor3f(0.5,0.5,1.0);
931         if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
932         {
933           glVertex(mesh_origin + (mesh_zaxis * Scalarm(-10.0)));
934           glVertex(mesh_origin + (mesh_zaxis * Scalarm(10.0)));
935         }
936         else
937         {
938           glVertex(mesh_boxcenter + (mesh_zaxis * Scalarm(-10.0)));
939           glVertex(mesh_boxcenter + (mesh_zaxis * Scalarm(10.0)));
940         }
941         break;
942       default: ;
943     }
944 
945     glEnd();
946   }
947 
948   // restore
949   glPopAttrib();
950 }
951 
Decorate(MeshModel & model,GLArea * gla,QPainter *)952 void EditManipulatorsPlugin::Decorate(MeshModel &model, GLArea *gla, QPainter* /*painter*/)
953 {
954   //
955   Point3m center, right, top, front;
956 
957   MyPick(gla->width()*0.5f, gla->height()*0.5f, center, 0.5f);
958   MyPick(gla->width()*0.99f, gla->height()*0.5f, right, 0.5f);
959   MyPick(gla->width()*0.5f, gla->height()*0.01f, top, 0.5f);
960   MyPick(gla->width()*0.5f, gla->height()*0.5f, front, 0.01f);
961 
962   screen_xaxis = (right - center) * Scalarm(2.0);
963   screen_yaxis = (top - center)   * Scalarm(2.0);
964   screen_zaxis = (front - center) * Scalarm(2.0);
965 
966   float diag = sqrt(screen_xaxis.Norm()*screen_xaxis.Norm() + screen_yaxis.Norm()*screen_yaxis.Norm());
967 
968   // calculate snapping factor
969   if(current_manip != EditManipulatorsPlugin::ManNone)
970   {
971     switch(current_manip)
972     {
973 	case EditManipulatorsPlugin::ManMove:
974 		snapto = Scalarm(powf(10.f, ceil(log10(diag)) - 2));
975 		break;
976 	case EditManipulatorsPlugin::ManRotate:
977 		snapto = Scalarm(1.0);
978 		break;
979 	case EditManipulatorsPlugin::ManScale:
980 		snapto = Scalarm(0.1);
981 		break;
982 	default:;
983     }
984   }
985 
986   // write manipulator data
987   QString StatusString1 = "";
988   QString StatusString2 = "";
989   QString HelpString1   = "";
990   QString HelpString2   = "";
991   QString HelpString3   = "";
992 
993   if(current_manip == EditManipulatorsPlugin::ManNone)
994   {
995     StatusString1 += "  NONE ";
996   }
997   else
998   {
999     switch(current_manip)
1000     {
1001       case EditManipulatorsPlugin::ManMove:
1002         StatusString1 += "  Translate";
1003         break;
1004       case EditManipulatorsPlugin::ManRotate:
1005         if(aroundOrigin) StatusString1 += "Rotate around Mesh Origin";
1006                     else StatusString1 += "Rotate around BBox center";
1007         break;
1008       case EditManipulatorsPlugin::ManScale:
1009         if(aroundOrigin) StatusString1 += "Scale around Mesh Origin";
1010                     else StatusString1 += "Scale around BBox center";
1011         break;
1012       default: ;
1013     }
1014     StatusString2="<br>";
1015     switch(current_manip_mode)
1016     {
1017       case EditManipulatorsPlugin::ModX: StatusString2 += "X global"; break;
1018       case EditManipulatorsPlugin::ModY: StatusString2 += "Y global"; break;
1019       case EditManipulatorsPlugin::ModZ: StatusString2 += "Z global"; break;
1020       case EditManipulatorsPlugin::ModXX: StatusString2 += "X local"; break;
1021       case EditManipulatorsPlugin::ModYY: StatusString2 += "Y local"; break;
1022       case EditManipulatorsPlugin::ModZZ: StatusString2 += "Z local"; break;
1023       default:
1024         if((current_manip == EditManipulatorsPlugin::ManMove) || (current_manip == EditManipulatorsPlugin::ManRotate))
1025           StatusString2 += "viewport";
1026         else if(current_manip == EditManipulatorsPlugin::ManScale)
1027           StatusString2 += "uniform";
1028         break;
1029     }
1030 
1031     // display offset factor in single axis
1032     if(current_manip_mode != EditManipulatorsPlugin::ModNone)
1033     {
1034       StatusString2 += QString("   ::   %1").arg(displayOffset);
1035     }
1036 
1037     // viewport translation, display the XYZ offsets
1038     if((current_manip_mode == EditManipulatorsPlugin::ModNone) && (current_manip == EditManipulatorsPlugin::ManMove))
1039     {
1040       StatusString2 += QString("  -  %1  %2  %3").arg(displayOffset_X).arg(displayOffset_Y).arg(displayOffset_Z);
1041     }
1042 
1043     // viewport rotation, display rotation angle
1044     if((current_manip_mode == EditManipulatorsPlugin::ModNone) && (current_manip == EditManipulatorsPlugin::ManRotate))
1045     {
1046       StatusString2 += QString("  -  %1").arg(displayOffset);
1047     }
1048 
1049     // uniform scale, display scale factor
1050     if((current_manip_mode == EditManipulatorsPlugin::ModNone) && (current_manip == EditManipulatorsPlugin::ManScale))
1051     {
1052       StatusString2 += QString("  -  %1").arg(displayOffset);
1053     }
1054 
1055     if(isSnapping)
1056     {
1057       StatusString2 += QString("  -  Snapping: %1").arg(snapto);
1058     }
1059   }
1060 
1061   if(current_manip == EditManipulatorsPlugin::ManNone)
1062   {
1063     HelpString1 = "<br><i> press T to translate, R to rotate, S to scale</i>";
1064   }
1065   else
1066   {
1067     switch(current_manip)
1068     {
1069     case EditManipulatorsPlugin::ManMove   : HelpString1 = "<br> LEFT CLICK and DRAG to move"; break;
1070     case EditManipulatorsPlugin::ManRotate : HelpString1 = "<br> LEFT CLICK and DRAG to rotate"; break;
1071     case EditManipulatorsPlugin::ManScale  : HelpString1 = "<br> LEFT CLICK and DRAG to scale"; break;
1072     case EditManipulatorsPlugin::ManNone   : break;
1073     }
1074 
1075     if((current_manip != EditManipulatorsPlugin::ManMove) || (current_manip_mode != EditManipulatorsPlugin::ModNone))
1076       HelpString1 += "  -  hold SHIFT to snap";
1077 
1078     HelpString2="<br>";
1079     switch(current_manip_mode)
1080     {
1081       case EditManipulatorsPlugin::ModX:  HelpString2 = "<br> press X to switch to X local"; break;
1082       case EditManipulatorsPlugin::ModY:  HelpString2 = "<br> press Y to switch to Y local"; break;
1083       case EditManipulatorsPlugin::ModZ:  HelpString2 = "<br> press Z to switch to Z local"; break;
1084       case EditManipulatorsPlugin::ModXX: HelpString2 = "<br> press X to switch to X global"; break;
1085       case EditManipulatorsPlugin::ModYY: HelpString2 = "<br> press Y to switch to Y global"; break;
1086       case EditManipulatorsPlugin::ModZZ: HelpString2 = "<br> press Z to switch to Z global"; break;
1087       default:   HelpString2 = "<br> press X Y Z to select an axis";    break;
1088     }
1089 
1090     if((current_manip == EditManipulatorsPlugin::ManRotate) || (current_manip == EditManipulatorsPlugin::ManScale))
1091     {
1092       if(aroundOrigin)  HelpString2 += "  -  press SPACE or C to pivot on BBox center";
1093                   else  HelpString2 += "  -  press SPACE or C to pivot on Mesh Origin";
1094     }
1095 
1096     HelpString3 = "<br>press RETURN to apply, BACKSPACE to cancel";
1097   }
1098 
1099   this->RealTimeLog("Manipulator","",qUtf8Printable("<b>"+StatusString1+"</b>"+StatusString2+HelpString1+HelpString2+HelpString3));
1100 
1101   // render original mesh BBox
1102   DrawMeshBox(model);
1103 
1104   // render active manipulator
1105   DrawManipulators(model, gla, true);
1106 
1107   assert(!glGetError());
1108 }
1109 
UpdateMatrix(MeshModel & model,GLArea * gla,bool applymouseoffset,bool useinputnumber)1110 void EditManipulatorsPlugin::UpdateMatrix(MeshModel &model, GLArea * gla, bool applymouseoffset, bool useinputnumber)
1111 {
1112   Matrix44m newmatrix;
1113 
1114   Matrix44m old_rotation;
1115   Matrix44m old_translation;
1116   Matrix44m old_meshcenter;
1117   Matrix44m old_meshuncenter;
1118   Matrix44m old_meshcenter_untr;
1119   Matrix44m old_meshuncenter_untr;
1120 
1121   Point3m new_scale;
1122   Point3m axis;
1123   Scalarm mouseXoff;
1124   Scalarm mouseYoff;
1125 
1126   Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis;
1127   mesh_boxcenter = model.cm.bbox.Center();
1128   mesh_origin = original_Transform.GetColumn3(3);
1129   mesh_xaxis = original_Transform.GetColumn3(0);
1130   mesh_yaxis = original_Transform.GetColumn3(1);
1131   mesh_zaxis = original_Transform.GetColumn3(2);
1132   vcg::Normalize(mesh_xaxis);
1133   vcg::Normalize(mesh_yaxis);
1134   vcg::Normalize(mesh_zaxis);
1135 
1136   delta_Transform.SetIdentity();
1137   newmatrix.SetIdentity();
1138 
1139   if(current_manip == EditManipulatorsPlugin::ManNone)
1140   {
1141     model.cm.Tr = original_Transform;
1142   }
1143   else
1144   {
1145 
1146     if(current_manip_mode != EditManipulatorsPlugin::ModNone)  // transform on one axis only
1147     {
1148 
1149       switch(current_manip_mode)          // which axis is active
1150       {
1151         case EditManipulatorsPlugin::ModX:
1152           axis = Point3m(1.0, 0.0, 0.0);
1153           break;
1154         case EditManipulatorsPlugin::ModY:
1155           axis = Point3m(0.0, 1.0, 0.0);
1156           break;
1157         case EditManipulatorsPlugin::ModZ:
1158           axis = Point3m(0.0, 0.0, 1.0);
1159           break;
1160         case EditManipulatorsPlugin::ModXX:
1161           axis = mesh_xaxis;
1162           break;
1163         case EditManipulatorsPlugin::ModYY:
1164           axis = mesh_yaxis;
1165           break;
1166         case EditManipulatorsPlugin::ModZZ:
1167           axis = mesh_zaxis;
1168           break;
1169         default: axis = Point3m(1.0, 1.0, 1.0); // it should never arrive here, anyway
1170       }
1171 
1172       if(current_manip == EditManipulatorsPlugin::ManMove)
1173       {
1174         // mouse offset -> single axis translation
1175         float xsign = ((screen_xaxis*axis)>0.0)?1.0:-1.0;
1176         float ysign = ((screen_yaxis*axis)>0.0)?1.0:-1.0;
1177         mouseXoff = xsign * screen_xaxis.Norm() * (currScreenOffset_X/float(gla->width()));
1178         mouseYoff = ysign * screen_yaxis.Norm() * (currScreenOffset_Y/float(gla->height()));
1179         displayOffset = currOffset + mouseXoff + mouseYoff;
1180 
1181         // snapping
1182         if(isSnapping)
1183         {
1184           displayOffset /= snapto;
1185           displayOffset = floor(displayOffset+0.5);
1186           displayOffset *= snapto;
1187         }
1188 
1189 		if (useinputnumber)
1190 			displayOffset = inputnumber;
1191 
1192         delta_Transform.SetTranslate(axis * displayOffset);
1193         newmatrix = delta_Transform * original_Transform;
1194       }
1195       else if(current_manip == EditManipulatorsPlugin::ManRotate)
1196       {
1197         // mouse offset -> single axis rotation
1198         mouseXoff = (currScreenOffset_X/float(gla->width()));
1199         mouseYoff = (currScreenOffset_Y/float(gla->height()));
1200         displayOffset = currOffset + (360.0 * (mouseXoff + mouseYoff));
1201         if((displayOffset > 360.0) || (displayOffset < -360.0))
1202           displayOffset = 360.0;
1203 
1204         // snapping
1205         if(isSnapping)
1206         {
1207           displayOffset = floor(displayOffset+0.5);
1208         }
1209 
1210         if(useinputnumber)
1211 			displayOffset = inputnumber;
1212 
1213         delta_Transform.SetRotateDeg(displayOffset, axis);
1214 
1215         old_rotation = original_Transform;
1216         old_rotation.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
1217         old_translation.SetTranslate(original_Transform.GetColumn3(3));
1218         old_meshcenter.SetTranslate(old_rotation * (-mesh_boxcenter));
1219         old_meshuncenter.SetTranslate(old_rotation * mesh_boxcenter);
1220 
1221         if(aroundOrigin)
1222           newmatrix = old_translation * delta_Transform * old_rotation;
1223         else
1224           newmatrix = old_translation * old_meshuncenter * delta_Transform * old_meshcenter * old_rotation;
1225       }
1226       else if(current_manip == EditManipulatorsPlugin::ManScale)
1227       {
1228         // mouse offset -> single axis scaling
1229         mouseXoff = (currScreenOffset_X/float(gla->width()));
1230         mouseYoff = (currScreenOffset_Y/float(gla->height()));
1231         displayOffset = currOffset + (2.0 * (mouseXoff + mouseYoff));
1232 
1233         // snapping
1234         if(isSnapping)
1235         {
1236           displayOffset /= snapto;
1237           displayOffset = floor(displayOffset+0.5);
1238           displayOffset *= snapto;
1239         }
1240 
1241         if(useinputnumber)
1242           displayOffset = inputnumber;
1243 
1244 		if ((current_manip_mode == EditManipulatorsPlugin::ModX) || (current_manip_mode == EditManipulatorsPlugin::ModXX))
1245 		{
1246 			delta_Transform.SetScale(Point3m(displayOffset, Scalarm(1.0), Scalarm(1.0)));
1247 		}
1248 		if ((current_manip_mode == EditManipulatorsPlugin::ModY) || (current_manip_mode == EditManipulatorsPlugin::ModYY))
1249 		{
1250 			delta_Transform.SetScale(Point3m(Scalarm(1.0), displayOffset, Scalarm(1.0)));
1251 		}
1252 		if ((current_manip_mode == EditManipulatorsPlugin::ModZ) || (current_manip_mode == EditManipulatorsPlugin::ModZZ))
1253 		{
1254 			delta_Transform.SetScale(Point3m(Scalarm(1.0), Scalarm(1.0), displayOffset));
1255 		}
1256 
1257         old_rotation = original_Transform;
1258         old_rotation.SetColumn(3, Point3m(Scalarm(0.0),Scalarm(0.0),Scalarm(0.0)));
1259         old_translation.SetTranslate(original_Transform.GetColumn3(3));
1260 		old_meshcenter.SetTranslate(old_rotation * (-mesh_boxcenter));
1261 		old_meshuncenter.SetTranslate(old_rotation * mesh_boxcenter);
1262 		old_meshcenter_untr.SetTranslate(-mesh_boxcenter);
1263 		old_meshuncenter_untr.SetTranslate(mesh_boxcenter);
1264 
1265 		if ((current_manip_mode == EditManipulatorsPlugin::ModX) || (current_manip_mode == EditManipulatorsPlugin::ModY) || (current_manip_mode == EditManipulatorsPlugin::ModZ))
1266 		{
1267 			if (aroundOrigin)
1268 				newmatrix = old_translation * delta_Transform * old_rotation;
1269 			else
1270 				newmatrix = old_translation * old_meshuncenter * delta_Transform * old_meshcenter * old_rotation;
1271 		}
1272 		else // local axis
1273 		{
1274 			if (aroundOrigin)
1275 				newmatrix = old_translation * old_rotation * delta_Transform;
1276 			else
1277 				newmatrix = old_translation * old_rotation * old_meshuncenter_untr * delta_Transform * old_meshcenter_untr;
1278 		}
1279 
1280 
1281       }
1282       else
1283         newmatrix = original_Transform;  // it should never arrive here, anyway
1284 
1285     }
1286     else   // transform on full space ? on view space ?
1287     {
1288 
1289 
1290       if(current_manip == EditManipulatorsPlugin::ManMove)
1291       {
1292         // mouse offset -> viewport translation
1293         mouseXoff = (currScreenOffset_X/float(gla->width()));
1294         mouseYoff = (currScreenOffset_Y/float(gla->height()));
1295 
1296         displayOffset_X = currOffset_X + (screen_xaxis[0] * mouseXoff) + (screen_yaxis[0] * mouseYoff);
1297         displayOffset_Y = currOffset_Y + (screen_xaxis[1] * mouseXoff) + (screen_yaxis[1] * mouseYoff);
1298         displayOffset_Z = currOffset_Z + (screen_xaxis[2] * mouseXoff) + (screen_yaxis[2] * mouseYoff);
1299 
1300         // snapping
1301         if(isSnapping)
1302         {
1303           displayOffset_X /= snapto;
1304           displayOffset_X = floor(displayOffset_X+0.5);
1305           displayOffset_X *= snapto;
1306           displayOffset_Y /= snapto;
1307           displayOffset_Y = floor(displayOffset_Y+0.5);
1308           displayOffset_Y *= snapto;
1309           displayOffset_Z /= snapto;
1310           displayOffset_Z = floor(displayOffset_Z+0.5);
1311           displayOffset_Z *= snapto;
1312         }
1313 
1314         delta_Transform.SetTranslate(Point3m(displayOffset_X,displayOffset_Y,displayOffset_Z));
1315         newmatrix = delta_Transform * original_Transform;
1316       }
1317 
1318       if(current_manip == EditManipulatorsPlugin::ManRotate)
1319       {
1320         // mouse offset -> viewport rotation
1321         mouseXoff = (currScreenOffset_X/float(gla->width()));
1322         mouseYoff = (currScreenOffset_Y/float(gla->height()));
1323         displayOffset = currOffset + (360.0 * (mouseXoff + mouseYoff));
1324         if((displayOffset > 360.0) || (displayOffset < -360.0))
1325           displayOffset = 360.0;
1326 
1327         // snapping
1328         if(isSnapping)
1329         {
1330           displayOffset = floor(displayOffset+0.5);
1331         }
1332 
1333         if(useinputnumber)
1334           displayOffset = inputnumber;
1335 
1336         delta_Transform.SetRotateDeg(displayOffset, screen_zaxis);
1337 
1338         old_rotation = original_Transform;
1339         old_rotation.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
1340         old_translation.SetTranslate(original_Transform.GetColumn3(3));
1341 		old_meshcenter.SetTranslate(old_rotation * (-mesh_boxcenter));
1342 		old_meshuncenter.SetTranslate(old_rotation * mesh_boxcenter);
1343 
1344         if(aroundOrigin)
1345           newmatrix = old_translation * delta_Transform * old_rotation;
1346         else
1347           newmatrix = old_translation * old_meshuncenter * delta_Transform * old_meshcenter * old_rotation;
1348       }
1349 
1350       if(current_manip == EditManipulatorsPlugin::ManScale)
1351       {
1352         // mouse offset -> uniform scaling
1353         mouseXoff = (currScreenOffset_X/float(gla->width()));
1354         mouseYoff = (-currScreenOffset_Y/float(gla->height()));
1355         displayOffset = currOffset + (2.0 * (mouseXoff + mouseYoff));
1356 
1357         // snapping
1358         if(isSnapping)
1359         {
1360           displayOffset /= snapto;
1361           displayOffset = floor(displayOffset+0.5);
1362           displayOffset *= snapto;
1363         }
1364 
1365         if(useinputnumber)
1366           displayOffset = inputnumber;
1367 
1368         new_scale[0] = displayOffset;
1369         new_scale[1] = displayOffset;
1370         new_scale[2] = displayOffset;
1371 
1372         delta_Transform.SetScale(new_scale);
1373 
1374         old_rotation = original_Transform;
1375         old_rotation.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
1376         old_translation.SetTranslate(original_Transform.GetColumn3(3));
1377         old_meshcenter.SetTranslate(-mesh_boxcenter);
1378         old_meshuncenter.SetTranslate(mesh_boxcenter);
1379 		old_meshcenter_untr.SetTranslate(-mesh_boxcenter);
1380 		old_meshuncenter_untr.SetTranslate(mesh_boxcenter);
1381 
1382         if(aroundOrigin)
1383 			newmatrix = old_translation * old_rotation * delta_Transform;
1384         else
1385 			newmatrix = old_translation * old_rotation * old_meshuncenter_untr * delta_Transform * old_meshcenter_untr;
1386       }
1387 
1388     }
1389     model.cm.Tr = newmatrix;
1390   }
1391 
1392   if(applymouseoffset)
1393   {
1394     // user finished dragging... accumulation of mouse offset into current offset
1395     currOffset = displayOffset;
1396     currOffset_X = displayOffset_X;
1397     currOffset_Y = displayOffset_Y;
1398     currOffset_Z = displayOffset_Z;
1399   }
1400 }
1401 
1402 
MyPick(const int & x,const int & y,Point3m & pp,float mydepth)1403 bool EditManipulatorsPlugin::MyPick(const int &x, const int &y, Point3m &pp, float mydepth)
1404 {
1405 	double res[3];
1406 	GLdouble mm[16],pm[16]; GLint vp[4];
1407 	glGetDoublev(GL_MODELVIEW_MATRIX,mm);
1408 	glGetDoublev(GL_PROJECTION_MATRIX,pm);
1409 	glGetIntegerv(GL_VIEWPORT,vp);
1410 
1411 	gluUnProject(x,y,mydepth,mm,pm,vp,&res[0],&res[1],&res[2]);
1412 	pp=Point3m(Scalarm(res[0]),Scalarm(res[1]),Scalarm(res[2]));
1413     return true;
1414 }
1415 
StartEdit(MeshModel & model,GLArea * gla,MLSceneGLSharedDataContext *)1416 bool EditManipulatorsPlugin::StartEdit(MeshModel & model, GLArea * gla, MLSceneGLSharedDataContext* /*cont*/)
1417 {
1418   gla->setCursor(QCursor(QPixmap(":/images/cur_manipulators.png"),15,15));
1419   connect(this, SIGNAL(suspendEditToggle()),gla,SLOT(suspendEditToggle()) );
1420 
1421   // reset filter data
1422   current_manip = EditManipulatorsPlugin::ManNone;
1423   current_manip_mode = EditManipulatorsPlugin::ModNone;
1424   isMoving = false;
1425   isSnapping = false;
1426   aroundOrigin = true;
1427   snapto = 1.0;
1428   resetOffsets();
1429 
1430   inputnumberstring= "";
1431   inputnumbernegative = false;
1432   inputnumber=0;
1433 
1434   // storing start matrix
1435   original_Transform = model.cm.Tr;
1436   delta_Transform = Matrix44m::Identity();
1437 
1438   gla->update();
1439 	return true;
1440 }
1441 
EndEdit(MeshModel & model,GLArea * gla,MLSceneGLSharedDataContext *)1442 void EditManipulatorsPlugin::EndEdit(MeshModel & model, GLArea * gla, MLSceneGLSharedDataContext* /*cont*/)
1443 {
1444   cancelMotion(model, gla);     // something interrupted the filter... canceling
1445 }
1446 
1447 
1448