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