mirror of
https://github.com/lucaspalomodevelop/meshlab.git
synced 2026-03-15 09:04:36 +00:00
1448 lines
49 KiB
C++
1448 lines
49 KiB
C++
/****************************************************************************
|
|
* MeshLab o o *
|
|
* A versatile mesh processing toolbox o o *
|
|
* _ O _ *
|
|
* Copyright(C) 2008 \/)\/ *
|
|
* Visual Computing Lab /\/| *
|
|
* ISTI - Italian National Research Council | *
|
|
* \ *
|
|
* All rights reserved. *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License (http://www.gnu.org/licenses/gpl.txt) *
|
|
* for more details. *
|
|
* *
|
|
****************************************************************************/
|
|
|
|
#include <meshlab/glarea.h>
|
|
#include "edit_manipulators.h"
|
|
#include <wrap/qt/gl_label.h>
|
|
#include <wrap/gui/trackball.h>
|
|
|
|
|
|
using namespace vcg;
|
|
|
|
EditManipulatorsPlugin::EditManipulatorsPlugin()
|
|
{
|
|
current_manip = EditManipulatorsPlugin::ManNone;
|
|
current_manip_mode = EditManipulatorsPlugin::ModNone;
|
|
isMoving = false;
|
|
isSnapping = false;
|
|
aroundOrigin = true;
|
|
snapto = 1;
|
|
resetOffsets();
|
|
inputnumberstring= "";
|
|
inputnumbernegative = false;
|
|
inputnumber=0;
|
|
|
|
original_Transform = Matrix44m::Identity();
|
|
delta_Transform = Matrix44m::Identity();
|
|
}
|
|
|
|
const QString EditManipulatorsPlugin::info()
|
|
{
|
|
return tr("Provide tools for moving meshes around the space");
|
|
}
|
|
|
|
void EditManipulatorsPlugin::mousePressEvent(QMouseEvent *event, MeshModel &, GLArea * gla)
|
|
{
|
|
isMoving = true;
|
|
startdrag = Point2i(event->x(),event->y());
|
|
gla->update();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::mouseMoveEvent(QMouseEvent * event, MeshModel &model, GLArea * gla)
|
|
{
|
|
if(isMoving)
|
|
{
|
|
enddrag = Point2i(event->x(),event->y());
|
|
currScreenOffset_X = enddrag[0] - startdrag[0];
|
|
currScreenOffset_Y = enddrag[1] - startdrag[1];
|
|
UpdateMatrix(model, gla, false);
|
|
}
|
|
gla->update();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::mouseReleaseEvent(QMouseEvent * event, MeshModel &model, GLArea * gla)
|
|
{
|
|
if(isMoving)
|
|
{
|
|
isMoving = false;
|
|
enddrag = Point2i(event->x(),event->y());
|
|
currScreenOffset_X = enddrag[0] - startdrag[0];
|
|
currScreenOffset_Y = enddrag[1] - startdrag[1];
|
|
UpdateMatrix(model, gla, true);
|
|
}
|
|
gla->update();
|
|
}
|
|
|
|
// Apply movement
|
|
void EditManipulatorsPlugin::applyMotion(MeshModel &model, GLArea *gla)
|
|
{
|
|
// the current matrix already contains the motion... so, just keep it there
|
|
|
|
// reset filter data
|
|
current_manip = EditManipulatorsPlugin::ManNone;
|
|
current_manip_mode = EditManipulatorsPlugin::ModNone;
|
|
isMoving = false;
|
|
isSnapping = false;
|
|
aroundOrigin = true;
|
|
snapto = 1.0;
|
|
resetOffsets();
|
|
|
|
inputnumberstring= "";
|
|
inputnumbernegative = false;
|
|
inputnumber=0;
|
|
|
|
// storing start matrix
|
|
original_Transform = model.cm.Tr;
|
|
delta_Transform = Matrix44m::Identity();
|
|
|
|
gla->update();
|
|
}
|
|
|
|
// Cancel movement
|
|
void EditManipulatorsPlugin::cancelMotion(MeshModel &model, GLArea *gla)
|
|
{
|
|
//restoring old matrix
|
|
model.cm.Tr = original_Transform;
|
|
|
|
// reset filter data
|
|
current_manip = EditManipulatorsPlugin::ManNone;
|
|
current_manip_mode = EditManipulatorsPlugin::ModNone;
|
|
isMoving = false;
|
|
isSnapping = false;
|
|
aroundOrigin = true;
|
|
snapto=1.0;
|
|
resetOffsets();
|
|
|
|
inputnumberstring= "";
|
|
inputnumbernegative = false;
|
|
inputnumber=0;
|
|
|
|
// storing start matrix
|
|
original_Transform = model.cm.Tr;
|
|
delta_Transform = Matrix44m::Identity();
|
|
|
|
gla->update();
|
|
}
|
|
|
|
// keyboard press
|
|
void EditManipulatorsPlugin::keyPressEvent(QKeyEvent* e, MeshModel& /*model*/, GLArea* /*gla*/)
|
|
{
|
|
// shift pressed, entering snapping mode
|
|
if(e->key() == Qt::Key_Shift)
|
|
{
|
|
isSnapping = true;
|
|
}
|
|
}
|
|
|
|
// keyboard commands, just like Blender
|
|
void EditManipulatorsPlugin::keyReleaseEvent(QKeyEvent *e, MeshModel &model, GLArea *gla)
|
|
{
|
|
// enter will apply, backspace to cancel
|
|
if(current_manip != EditManipulatorsPlugin::ManNone)
|
|
{
|
|
if ((e->key() == Qt::Key_Enter) || (e->key() == Qt::Key_Return))
|
|
{
|
|
applyMotion(model, gla);
|
|
}
|
|
if (e->key() == Qt::Key_Backspace)
|
|
{
|
|
cancelMotion(model, gla);
|
|
}
|
|
}
|
|
|
|
// shift released, exit snapping mode
|
|
if(e->key() == Qt::Key_Shift)
|
|
{
|
|
isSnapping = false;
|
|
}
|
|
|
|
if((current_manip == EditManipulatorsPlugin::ManRotate) || (current_manip == EditManipulatorsPlugin::ManScale))
|
|
{
|
|
if ((e->key() == Qt::Key_Space) || (e->key() == Qt::Key_C))
|
|
{
|
|
aroundOrigin = !aroundOrigin;
|
|
}
|
|
}
|
|
|
|
if(current_manip == EditManipulatorsPlugin::ManNone) // if no active manipulator, listen to T R S to select one
|
|
{
|
|
if ((e->key() == Qt::Key_T) || (e->key() == Qt::Key_G)) // translate (I added also G to work like blender)
|
|
{
|
|
current_manip = EditManipulatorsPlugin::ManMove;
|
|
resetOffsets();
|
|
UpdateMatrix(model,gla,false);
|
|
}
|
|
if (e->key() == Qt::Key_R) // rotate
|
|
{
|
|
current_manip = EditManipulatorsPlugin::ManRotate;
|
|
resetOffsets();
|
|
UpdateMatrix(model,gla,false);
|
|
}
|
|
if (e->key() == Qt::Key_S) // scale
|
|
{
|
|
current_manip = EditManipulatorsPlugin::ManScale;
|
|
resetOffsets();
|
|
UpdateMatrix(model,gla,false);
|
|
}
|
|
}
|
|
|
|
if(current_manip != EditManipulatorsPlugin::ManNone) // if there is an active manipulator, listen to modifiers
|
|
{
|
|
if (e->key() == Qt::Key_X) // X axis
|
|
{
|
|
if(current_manip_mode == EditManipulatorsPlugin::ModX)
|
|
current_manip_mode = EditManipulatorsPlugin::ModXX;
|
|
else
|
|
current_manip_mode = EditManipulatorsPlugin::ModX;
|
|
|
|
resetOffsets();
|
|
|
|
UpdateMatrix(model,gla,false);
|
|
}
|
|
if (e->key() == Qt::Key_Y) // Y axis
|
|
{
|
|
if(current_manip_mode == EditManipulatorsPlugin::ModY)
|
|
current_manip_mode = EditManipulatorsPlugin::ModYY;
|
|
else
|
|
current_manip_mode = EditManipulatorsPlugin::ModY;
|
|
|
|
resetOffsets();
|
|
|
|
UpdateMatrix(model,gla,false);
|
|
}
|
|
if (e->key() == Qt::Key_Z) // Z axis
|
|
{
|
|
if(current_manip_mode == EditManipulatorsPlugin::ModZ)
|
|
current_manip_mode = EditManipulatorsPlugin::ModZZ;
|
|
else
|
|
current_manip_mode = EditManipulatorsPlugin::ModZ;
|
|
|
|
resetOffsets();
|
|
|
|
UpdateMatrix(model,gla,false);
|
|
}
|
|
}
|
|
|
|
// numerical input
|
|
if ((current_manip == EditManipulatorsPlugin::ManScale) || (current_manip == EditManipulatorsPlugin::ManRotate) || (current_manip_mode != EditManipulatorsPlugin::ModNone)) // transform on one axis only
|
|
{
|
|
bool hasNumberChanged = false;
|
|
|
|
if (e->key() == Qt::Key_1) { inputnumberstring += "1"; hasNumberChanged = true; }
|
|
if (e->key() == Qt::Key_2) { inputnumberstring += "2"; hasNumberChanged = true; }
|
|
if (e->key() == Qt::Key_3) { inputnumberstring += "3"; hasNumberChanged = true; }
|
|
if (e->key() == Qt::Key_4) { inputnumberstring += "4"; hasNumberChanged = true; }
|
|
if (e->key() == Qt::Key_5) { inputnumberstring += "5"; hasNumberChanged = true; }
|
|
if (e->key() == Qt::Key_6) { inputnumberstring += "6"; hasNumberChanged = true; }
|
|
if (e->key() == Qt::Key_7) { inputnumberstring += "7"; hasNumberChanged = true; }
|
|
if (e->key() == Qt::Key_8) { inputnumberstring += "8"; hasNumberChanged = true; }
|
|
if (e->key() == Qt::Key_9) { inputnumberstring += "9"; hasNumberChanged = true; }
|
|
|
|
if (e->key() == Qt::Key_0)
|
|
{
|
|
if(inputnumberstring.length() == 0)
|
|
inputnumberstring = "0.";
|
|
if((inputnumberstring.length() >= 2) || (inputnumberstring[0]!=0))
|
|
inputnumberstring += "0";
|
|
|
|
hasNumberChanged = true;
|
|
}
|
|
|
|
if (e->key() == Qt::Key_Period)
|
|
{
|
|
if(inputnumberstring.length() == 0)
|
|
inputnumberstring = "0.";
|
|
else if(!inputnumberstring.contains("."))
|
|
inputnumberstring += ".";
|
|
|
|
hasNumberChanged = true;
|
|
}
|
|
|
|
if (e->key() == Qt::Key_Minus)
|
|
{
|
|
inputnumbernegative = !inputnumbernegative;
|
|
hasNumberChanged = true;
|
|
}
|
|
|
|
if (!inputnumbernegative)
|
|
inputnumber = inputnumberstring.toFloat();
|
|
else
|
|
inputnumber = -inputnumberstring.toFloat();
|
|
|
|
if (hasNumberChanged)
|
|
UpdateMatrix(model, gla, false, true);
|
|
}
|
|
|
|
//else e->ignore();
|
|
gla->update();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::resetOffsets()
|
|
{
|
|
if(current_manip == EditManipulatorsPlugin::ManScale)
|
|
{
|
|
displayOffset = 1; // mouse offset value (single axis)
|
|
displayOffset_X = 1; // mouse X offset value
|
|
displayOffset_Y = 1; // mouse Y offset value
|
|
displayOffset_Z = 1; // mouse Z offset value
|
|
currOffset = 1; // combined offset value (single axis)
|
|
currOffset_X = 1; // X offset value
|
|
currOffset_Y = 1; // Y offset value
|
|
currOffset_Z = 1; // Z offset value
|
|
}
|
|
else
|
|
{
|
|
displayOffset = 0; // mouse offset value (single axis)
|
|
displayOffset_X = 0; // mouse X offset value
|
|
displayOffset_Y = 0; // mouse Y offset value
|
|
displayOffset_Z = 0; // mouse Z offset value
|
|
currOffset = 0; // combined offset value (single axis)
|
|
currOffset_X = 0; // X offset value
|
|
currOffset_Y = 0; // Y offset value
|
|
currOffset_Z = 0; // Z offset value
|
|
}
|
|
|
|
currScreenOffset_X = 0; // horizontal offset (screen space)
|
|
currScreenOffset_Y = 0; // vertical offset (screen space)
|
|
}
|
|
|
|
void EditManipulatorsPlugin::DrawMeshBox(MeshModel &model)
|
|
{
|
|
Box3m b;
|
|
b = model.cm.bbox;
|
|
Point3m mi=b.min;
|
|
Point3m ma=b.max;
|
|
Point3m d3=(b.max-b.min)/4.0;
|
|
Point3m zz(0,0,0);
|
|
|
|
// setup
|
|
glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT );
|
|
glDisable(GL_LIGHTING);
|
|
glDisable(GL_TEXTURE_2D);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_LINE_SMOOTH);
|
|
glLineWidth(1.0);
|
|
glColor(vcg::Color4b(Color4b::Cyan));
|
|
|
|
glPushMatrix();
|
|
glMultMatrix(original_Transform);
|
|
|
|
glBegin(GL_LINES);
|
|
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]);
|
|
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]);
|
|
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]);
|
|
|
|
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]);
|
|
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]);
|
|
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]);
|
|
|
|
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]);
|
|
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]);
|
|
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]);
|
|
|
|
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]);
|
|
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]);
|
|
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]);
|
|
|
|
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]);
|
|
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]);
|
|
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]);
|
|
|
|
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]);
|
|
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]);
|
|
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]);
|
|
|
|
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]);
|
|
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]);
|
|
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]);
|
|
|
|
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]);
|
|
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]);
|
|
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]);
|
|
glEnd();
|
|
|
|
|
|
//drawing mesh origin
|
|
glBegin(GL_LINES);
|
|
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);
|
|
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);
|
|
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]);
|
|
glEnd();
|
|
|
|
// restore
|
|
glPopMatrix();
|
|
glPopAttrib();
|
|
}
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
void EditManipulatorsPlugin::DrawCubes(float r, float g, float b)
|
|
{
|
|
glColor4f(r,g,b,1.0f);
|
|
glBegin (GL_LINES);
|
|
// mid line
|
|
glVertex3f( 0.0f, 0.0f, -1.0f);
|
|
glVertex3f( 0.0f, 0.0f, 1.0f);
|
|
glEnd ();
|
|
|
|
glBegin (GL_LINES);
|
|
// right cube
|
|
glVertex3f( 0.0f, 0.0f, 1.0f);
|
|
glVertex3f( 0.1f, 0.0f, 1.1f);
|
|
glVertex3f( 0.0f, 0.0f, 1.0f);
|
|
glVertex3f( -0.1f, 0.0f, 1.1f);
|
|
glVertex3f( 0.0f, 0.0f, 1.0f);
|
|
glVertex3f( 0.0f, -0.1f, 1.1f);
|
|
glVertex3f( 0.0f, 0.0f, 1.0f);
|
|
glVertex3f( 0.0f, 0.1f, 1.1f);
|
|
glVertex3f( 0.0f, 0.0f, 1.2f);
|
|
glVertex3f( 0.1f, 0.0f, 1.1f);
|
|
glVertex3f( 0.0f, 0.0f, 1.2f);
|
|
glVertex3f( -0.1f, 0.0f, 1.1f);
|
|
glVertex3f( 0.0f, 0.0f, 1.2f);
|
|
glVertex3f( 0.0f, -0.1f, 1.1f);
|
|
glVertex3f( 0.0f, 0.0f, 1.2f);
|
|
glVertex3f( 0.0f, 0.1f, 1.1f);
|
|
glEnd ();
|
|
|
|
glBegin (GL_LINES);
|
|
// left cube
|
|
glVertex3f( 0.0f, 0.0f, -1.0f);
|
|
glVertex3f( 0.1f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, 0.0f, -1.0f);
|
|
glVertex3f( -0.1f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, 0.0f, -1.0f);
|
|
glVertex3f( 0.0f, -0.1f, -1.1f);
|
|
glVertex3f( 0.0f, 0.0f, -1.0f);
|
|
glVertex3f( 0.0f, 0.1f, -1.1f);
|
|
glVertex3f( 0.0f, 0.0f, -1.2f);
|
|
glVertex3f( 0.1f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, 0.0f, -1.2f);
|
|
glVertex3f( -0.1f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, 0.0f, -1.2f);
|
|
glVertex3f( 0.0f, -0.1f, -1.1f);
|
|
glVertex3f( 0.0f, 0.0f, -1.2f);
|
|
glVertex3f( 0.0f, 0.1f, -1.1f);
|
|
glEnd ();
|
|
|
|
|
|
// right cube
|
|
glColor4f(std::min(1.0f,r+0.2f), std::min(1.0f,g+0.2f), std::min(1.0f,b+0.2f),0.5f);
|
|
glBegin (GL_TRIANGLE_FAN);
|
|
glVertex3f( 0.0f, 0.0f, 1.2f);
|
|
glVertex3f( 0.0f, 0.1f, 1.1f);
|
|
glVertex3f( -0.1f, 0.0f, 1.1f);
|
|
glVertex3f( 0.0f, -0.1f, 1.1f);
|
|
glVertex3f( 0.1f, 0.0f, 1.1f);
|
|
glVertex3f( 0.0f, 0.1f, 1.1f);
|
|
glEnd();
|
|
glBegin (GL_TRIANGLE_FAN);
|
|
glVertex3f( 0.0f, 0.0f, 1.0f);
|
|
glVertex3f( 0.0f, 0.1f, 1.1f);
|
|
glVertex3f( -0.1f, 0.0f, 1.1f);
|
|
glVertex3f( 0.0f, -0.1f, 1.1f);
|
|
glVertex3f( 0.1f, 0.0f, 1.1f);
|
|
glVertex3f( 0.0f, 0.1f, 1.1f);
|
|
glEnd();
|
|
|
|
// left cube
|
|
glBegin (GL_TRIANGLE_FAN);
|
|
glVertex3f( 0.0f, 0.0f, -1.2f);
|
|
glVertex3f( 0.0f, 0.1f, -1.1f);
|
|
glVertex3f( -0.1f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, -0.1f, -1.1f);
|
|
glVertex3f( 0.1f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, 0.1f, -1.1f);
|
|
glEnd();
|
|
glBegin (GL_TRIANGLE_FAN);
|
|
glVertex3f( 0.0f, 0.0f, -1.0f);
|
|
glVertex3f( 0.0f, 0.1f, -1.1f);
|
|
glVertex3f( -0.1f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, -0.1f, -1.1f);
|
|
glVertex3f( 0.1f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, 0.1f, -1.1f);
|
|
glEnd();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::DrawArrows(float r, float g, float b)
|
|
{
|
|
glColor4f(r,g,b,1.0f);
|
|
glBegin (GL_LINES);
|
|
// mid line
|
|
glVertex3f( 0.0f, 0.0f, -1.1f);
|
|
glVertex3f( 0.0f, 0.0f, 1.1f);
|
|
|
|
// right arrow
|
|
glVertex3f( 0.0f, 0.0f, 1.1f);
|
|
glVertex3f( 0.1f, 0.1f, 0.9f);
|
|
glVertex3f( 0.0f, 0.0f, 1.1f);
|
|
glVertex3f( -0.1f, 0.1f, 0.9f);
|
|
glVertex3f( 0.0f, 0.0f, 1.1f);
|
|
glVertex3f( 0.1f, -0.1f, 0.9f);
|
|
glVertex3f( 0.0f, 0.0f, 1.1f);
|
|
glVertex3f( -0.1f, -0.1f, 0.9f);
|
|
|
|
// left arrow
|
|
glVertex3f( 0.0f, 0.0f, -1.1f);
|
|
glVertex3f( 0.1f, 0.1f, -0.9f);
|
|
glVertex3f( 0.0f, 0.0f, -1.1f);
|
|
glVertex3f( -0.1f, 0.1f, -0.9f);
|
|
glVertex3f( 0.0f, 0.0f, -1.1f);
|
|
glVertex3f( 0.1f, -0.1f, -0.9f);
|
|
glVertex3f( 0.0f, 0.0f, -1.1f);
|
|
glVertex3f( -0.1f, -0.1f, -0.9f);
|
|
glEnd ();
|
|
|
|
// right arrow
|
|
glColor4f(std::min(1.0f,r+0.2f), std::min(1.0f,g+0.2f), std::min(1.0f,b+0.2f), 0.5f);
|
|
glBegin (GL_TRIANGLE_FAN);
|
|
glVertex3f( 0.0f, 0.0f, 1.1f);
|
|
glVertex3f( 0.1f, 0.1f, 0.9f);
|
|
glVertex3f( -0.1f, 0.1f, 0.9f);
|
|
glVertex3f( -0.1f, -0.1f, 0.9f);
|
|
glVertex3f( 0.1f, -0.1f, 0.9f);
|
|
glVertex3f( 0.1f, 0.1f, 0.9f);
|
|
glEnd();
|
|
// left arrow
|
|
glBegin (GL_TRIANGLE_FAN);
|
|
glVertex3f( 0.0f, 0.0f, -1.1f);
|
|
glVertex3f( 0.1f, 0.1f, -0.9f);
|
|
glVertex3f( -0.1f, 0.1f, -0.9f);
|
|
glVertex3f( -0.1f, -0.1f, -0.9f);
|
|
glVertex3f( 0.1f, -0.1f, -0.9f);
|
|
glVertex3f( 0.1f, 0.1f, -0.9f);
|
|
glEnd();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::DrawCircle(float r, float g, float b)
|
|
{
|
|
int nside =32;
|
|
const double pi2 = 3.14159265 * 2.0;
|
|
|
|
glColor4f(r,g,b,1.0);
|
|
glBegin (GL_LINE_LOOP);
|
|
for (double i = 0; i < nside; i++) {
|
|
glNormal3d (cos (i * pi2 / nside), sin (i * pi2 / nside), 0.0);
|
|
glVertex3d (cos (i * pi2 / nside), sin (i * pi2 / nside), 0.0);
|
|
}
|
|
glEnd();
|
|
glColor4f(std::min(1.0f,r+0.2f), std::min(1.0f,g+0.2f), std::min(1.0f,b+0.2f), 0.5f);
|
|
glBegin (GL_TRIANGLE_FAN);
|
|
glVertex3d (0.0, 0.0, 0.0);
|
|
int renderangle;
|
|
if (displayOffset>=0)
|
|
renderangle = int(displayOffset)%360;
|
|
else
|
|
renderangle = 360 - (int(-displayOffset)%360);
|
|
|
|
for (double i = 0; i<=renderangle; i++)
|
|
{
|
|
glVertex3d (cos (i * pi2 / 360.0), sin (i * pi2 / 360.0), 0.0);
|
|
}
|
|
glEnd();
|
|
|
|
|
|
}
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
void EditManipulatorsPlugin::DrawTranslateManipulators(MeshModel &model, GLArea *gla)
|
|
{
|
|
glPushMatrix();
|
|
|
|
Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis, new_mesh_origin;
|
|
mesh_boxcenter = original_Transform * model.cm.bbox.Center();
|
|
mesh_origin = original_Transform.GetColumn3(3);
|
|
new_mesh_origin = model.cm.Tr.GetColumn3(3);
|
|
mesh_xaxis = original_Transform.GetColumn3(0);
|
|
mesh_yaxis = original_Transform.GetColumn3(1);
|
|
mesh_zaxis = original_Transform.GetColumn3(2);
|
|
float manipsize = model.cm.bbox.Diag() / 2.0;
|
|
Matrix44f track_rotation;
|
|
gla->trackball.track.rot.ToMatrix(track_rotation);
|
|
|
|
glLineWidth(2.0);
|
|
|
|
switch(current_manip_mode)
|
|
{
|
|
case EditManipulatorsPlugin::ModNone:
|
|
glTranslate(new_mesh_origin);
|
|
glScale(manipsize);
|
|
glMultMatrix(Inverse(track_rotation));
|
|
glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
|
|
DrawArrows(1.0f,0.8f,0.5f);
|
|
glRotatef (90.0f, 1.0f, 0.0f, 0.0f);
|
|
DrawArrows(1.0f,0.8f,0.5f);
|
|
break;
|
|
case EditManipulatorsPlugin::ModX:
|
|
glTranslate(new_mesh_origin);
|
|
glScale(manipsize);
|
|
glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
|
|
DrawArrows(1.0f,0.0f,0.0f);
|
|
break;
|
|
case EditManipulatorsPlugin::ModY:
|
|
glTranslate(new_mesh_origin);
|
|
glScale(manipsize);
|
|
glRotatef (90, 1, 0, 0);
|
|
DrawArrows(0,1.0,0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModZ:
|
|
glTranslate(new_mesh_origin);
|
|
glScale(manipsize);
|
|
DrawArrows(0,0,1.0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModXX:
|
|
glMultMatrix(model.cm.Tr);
|
|
glScale(manipsize);
|
|
glRotatef (90, 0, 1, 0);
|
|
DrawArrows(1.0,0.5,0.5);
|
|
break;
|
|
case EditManipulatorsPlugin::ModYY:
|
|
glMultMatrix(model.cm.Tr);
|
|
glScale(manipsize);
|
|
glRotatef (90, 1, 0, 0);
|
|
DrawArrows(0.5,1.0,0.5);
|
|
break;
|
|
case EditManipulatorsPlugin::ModZZ:
|
|
glMultMatrix(model.cm.Tr);
|
|
glScale(manipsize);
|
|
DrawArrows(0.5,0.5,1.0);
|
|
break;
|
|
default: ;
|
|
}
|
|
|
|
glLineWidth(1.0);
|
|
glPopMatrix();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::DrawScaleManipulators(MeshModel &model, GLArea *gla)
|
|
{
|
|
glPushMatrix();
|
|
|
|
Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis;
|
|
mesh_boxcenter = original_Transform * model.cm.bbox.Center();
|
|
mesh_origin = original_Transform.GetColumn3(3);
|
|
mesh_xaxis = original_Transform.GetColumn3(0);
|
|
mesh_yaxis = original_Transform.GetColumn3(1);
|
|
mesh_zaxis = original_Transform.GetColumn3(2);
|
|
float manipsize(model.cm.bbox.Diag() / 2.0);
|
|
Matrix44m original_rot = original_Transform;
|
|
original_rot.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
|
|
Matrix44f track_rotation;
|
|
gla->trackball.track.rot.ToMatrix(track_rotation);
|
|
|
|
glLineWidth(2.0);
|
|
|
|
switch(current_manip_mode)
|
|
{
|
|
case EditManipulatorsPlugin::ModNone:
|
|
if(!aroundOrigin)
|
|
glTranslate(mesh_boxcenter);
|
|
else
|
|
glTranslate(mesh_origin);
|
|
glScale(manipsize);
|
|
glMultMatrix(Inverse(track_rotation));
|
|
glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
|
|
DrawCubes(1.0f,0.8f,0.5f);
|
|
glRotatef (90.0f, 1.0f, 0.0f, 0.0f);
|
|
DrawCubes(1.0f,0.8f,0.5f);
|
|
break;
|
|
case EditManipulatorsPlugin::ModX:
|
|
if(!aroundOrigin)
|
|
glTranslate(mesh_boxcenter);
|
|
else
|
|
glTranslate(mesh_origin);
|
|
glScale(manipsize);
|
|
glRotatef (90.0f, 0.0f, 1.0f, 0.0f);
|
|
DrawCubes(1.0f,0.0f,0.0f);
|
|
break;
|
|
case EditManipulatorsPlugin::ModY:
|
|
if(!aroundOrigin)
|
|
glTranslate(mesh_boxcenter);
|
|
else
|
|
glTranslate(mesh_origin);
|
|
glScale(manipsize);
|
|
glRotatef (90.0f, 1.0f, 0.0f, 0.0f);
|
|
DrawCubes(0.0f,1.0f,0.0f);
|
|
break;
|
|
case EditManipulatorsPlugin::ModZ:
|
|
if(!aroundOrigin)
|
|
glTranslate(mesh_boxcenter);
|
|
else
|
|
glTranslate(mesh_origin);
|
|
glScale(manipsize);
|
|
DrawCubes(0,0,1.0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModXX:
|
|
if (!aroundOrigin)
|
|
{
|
|
glTranslate(mesh_boxcenter);
|
|
glMultMatrix(original_rot);
|
|
}
|
|
else
|
|
glMultMatrix(original_Transform);
|
|
glScale(manipsize);
|
|
glRotatef (90, 0, 1, 0);
|
|
DrawCubes(1.0,0.5,0.5);
|
|
break;
|
|
case EditManipulatorsPlugin::ModYY:
|
|
if (!aroundOrigin)
|
|
{
|
|
glTranslate(mesh_boxcenter);
|
|
glMultMatrix(original_rot);
|
|
}
|
|
else
|
|
glMultMatrix(original_Transform);
|
|
glScale(manipsize);
|
|
glRotatef (90, 1, 0, 0);
|
|
DrawCubes(0.5,1.0,0.5);
|
|
break;
|
|
case EditManipulatorsPlugin::ModZZ:
|
|
if (!aroundOrigin)
|
|
{
|
|
glTranslate(mesh_boxcenter);
|
|
glMultMatrix(original_rot);
|
|
}
|
|
else
|
|
glMultMatrix(original_Transform);
|
|
glScale(manipsize);
|
|
DrawCubes(0.5,0.5,1.0);
|
|
break;
|
|
default: ;
|
|
}
|
|
|
|
glLineWidth(1.0);
|
|
glPopMatrix ();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::DrawRotateManipulators(MeshModel &model, GLArea *gla)
|
|
{
|
|
glPushMatrix();
|
|
|
|
Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis, new_mesh_origin;
|
|
mesh_boxcenter = original_Transform * model.cm.bbox.Center();
|
|
mesh_origin = original_Transform.GetColumn3(3);
|
|
new_mesh_origin = model.cm.Tr.GetColumn3(3);
|
|
mesh_xaxis = original_Transform.GetColumn3(0);
|
|
mesh_yaxis = original_Transform.GetColumn3(1);
|
|
mesh_zaxis = original_Transform.GetColumn3(2);
|
|
float manipsize = model.cm.bbox.Diag() / 2.0;
|
|
Matrix44m original_rot = original_Transform;
|
|
original_rot.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
|
|
Matrix44f track_rotation;
|
|
gla->trackball.track.rot.ToMatrix(track_rotation);
|
|
|
|
glLineWidth(2.0);
|
|
|
|
switch(current_manip_mode)
|
|
{
|
|
case EditManipulatorsPlugin::ModNone:
|
|
if(!aroundOrigin)
|
|
glTranslate(mesh_boxcenter);
|
|
else
|
|
glTranslate(mesh_origin);
|
|
glScale(manipsize);
|
|
glMultMatrix(Inverse(track_rotation));
|
|
DrawCircle(1.0f,0.8f,0.5f);
|
|
break;
|
|
case EditManipulatorsPlugin::ModX:
|
|
if(!aroundOrigin)
|
|
glTranslate(mesh_boxcenter);
|
|
else
|
|
glTranslate(mesh_origin);
|
|
glScale(manipsize);
|
|
glRotatef (90, 0, 1, 0);
|
|
DrawCircle(1.0,0,0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModY:
|
|
if(!aroundOrigin)
|
|
glTranslate(mesh_boxcenter);
|
|
else
|
|
glTranslate(mesh_origin);
|
|
glScale(manipsize);
|
|
glRotatef (-90, 1, 0, 0);
|
|
DrawCircle(0,1.0,0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModZ:
|
|
if(!aroundOrigin)
|
|
glTranslate(mesh_boxcenter);
|
|
else
|
|
glTranslate(mesh_origin);
|
|
glScale(manipsize);
|
|
DrawCircle(0,0,1.0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModXX:
|
|
if(!aroundOrigin)
|
|
{
|
|
glTranslate(mesh_boxcenter);
|
|
glMultMatrix(original_rot);
|
|
}
|
|
else
|
|
glMultMatrix(original_Transform);
|
|
glScale(manipsize);
|
|
glRotatef (90, 0, 1, 0);
|
|
DrawCircle(1.0,0.5,0.5);
|
|
break;
|
|
case EditManipulatorsPlugin::ModYY:
|
|
if(!aroundOrigin)
|
|
{
|
|
glTranslate(mesh_boxcenter);
|
|
glMultMatrix(original_rot);
|
|
}
|
|
else
|
|
glMultMatrix(original_Transform);
|
|
glScale(manipsize);
|
|
glRotatef (-90, 1, 0, 0);
|
|
DrawCircle(0.5,1.0,0.5);
|
|
break;
|
|
case EditManipulatorsPlugin::ModZZ:
|
|
if (!aroundOrigin)
|
|
{
|
|
glTranslate(mesh_boxcenter);
|
|
glMultMatrix(original_rot);
|
|
}
|
|
else
|
|
glMultMatrix(original_Transform);
|
|
glScale(manipsize);
|
|
DrawCircle(0.5,0.5,1.0);
|
|
break;
|
|
default: ;
|
|
}
|
|
|
|
glLineWidth(1.0);
|
|
glPopMatrix();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::DrawManipulators(MeshModel &model, GLArea *gla, bool /*onlyActive*/)
|
|
{
|
|
Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis;
|
|
mesh_boxcenter = original_Transform * model.cm.bbox.Center();
|
|
mesh_origin = original_Transform.GetColumn3(3);
|
|
mesh_xaxis = original_Transform.GetColumn3(0);
|
|
mesh_yaxis = original_Transform.GetColumn3(1);
|
|
mesh_zaxis = original_Transform.GetColumn3(2);
|
|
|
|
// setup
|
|
glPushAttrib(GL_ENABLE_BIT | GL_LINE_BIT | GL_POINT_BIT | GL_CURRENT_BIT | GL_LIGHTING_BIT | GL_COLOR_BUFFER_BIT );
|
|
glDisable(GL_LIGHTING);
|
|
glEnable(GL_BLEND);
|
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
|
glEnable(GL_LINE_SMOOTH);
|
|
|
|
switch(current_manip)
|
|
{
|
|
case EditManipulatorsPlugin::ManMove:
|
|
DrawTranslateManipulators(model, gla);
|
|
break;
|
|
case EditManipulatorsPlugin::ManRotate:
|
|
DrawRotateManipulators(model, gla);
|
|
break;
|
|
case EditManipulatorsPlugin::ManScale:
|
|
DrawScaleManipulators(model, gla);
|
|
break;
|
|
default: ;
|
|
}
|
|
|
|
if(current_manip_mode != EditManipulatorsPlugin::ModNone)
|
|
{
|
|
glBegin(GL_LINES);
|
|
|
|
switch(current_manip_mode)
|
|
{
|
|
case EditManipulatorsPlugin::ModX:
|
|
glColor3f(1.0,0,0);
|
|
if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
|
|
{
|
|
glVertex(mesh_origin + Point3m(Scalarm(-10.0),Scalarm(0.0),Scalarm(0.0)));
|
|
glVertex(mesh_origin + Point3m(Scalarm(10.0), Scalarm(0.0),Scalarm(0.0)));
|
|
}
|
|
else
|
|
{
|
|
glVertex(mesh_boxcenter + Point3m(Scalarm(-10.0),Scalarm(0.0),Scalarm(0.0)));
|
|
glVertex(mesh_boxcenter + Point3m(Scalarm(10.0),Scalarm(0.0),Scalarm(0.0)));
|
|
}
|
|
break;
|
|
case EditManipulatorsPlugin::ModY:
|
|
glColor3f(0,1.0,0);
|
|
if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
|
|
{
|
|
glVertex(mesh_origin + Point3m(Scalarm(0.0),Scalarm(-10.0),Scalarm(0.0)));
|
|
glVertex(mesh_origin + Point3m(Scalarm(0.0),Scalarm(10.0),Scalarm(0.0)));
|
|
}
|
|
else
|
|
{
|
|
glVertex(mesh_boxcenter + Point3m(Scalarm(0.0), Scalarm(-10.0),Scalarm(0.0)));
|
|
glVertex(mesh_boxcenter + Point3m(Scalarm(0.0), Scalarm(10.0), Scalarm(0.0)));
|
|
}
|
|
break;
|
|
case EditManipulatorsPlugin::ModZ:
|
|
glColor3f(0,0,1.0);
|
|
if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
|
|
{
|
|
glVertex(mesh_origin + Point3m(Scalarm(0.0),Scalarm(0.0),Scalarm(-10.0)));
|
|
glVertex(mesh_origin + Point3m(Scalarm(0.0),Scalarm(0.0),Scalarm(10.0)));
|
|
}
|
|
else
|
|
{
|
|
glVertex(mesh_boxcenter + Point3m(Scalarm(0.0),Scalarm(0.0), Scalarm(-10.0)));
|
|
glVertex(mesh_boxcenter + Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(10.0)));
|
|
}
|
|
break;
|
|
case EditManipulatorsPlugin::ModXX:
|
|
glColor3f(1.0f,0.5f,0.5f);
|
|
if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
|
|
{
|
|
glVertex(mesh_origin + (mesh_xaxis * Scalarm(-10.0)));
|
|
glVertex(mesh_origin + (mesh_xaxis * Scalarm(10.0)));
|
|
}
|
|
else
|
|
{
|
|
glVertex(mesh_boxcenter + (mesh_xaxis * Scalarm(-10.0)));
|
|
glVertex(mesh_boxcenter + (mesh_xaxis * Scalarm(10.0)));
|
|
}
|
|
break;
|
|
case EditManipulatorsPlugin::ModYY:
|
|
glColor3f(0.5,1.0,0.5);
|
|
if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
|
|
{
|
|
glVertex(mesh_origin + (mesh_yaxis * Scalarm(-10.0)));
|
|
glVertex(mesh_origin + (mesh_yaxis * Scalarm(10.0)));
|
|
}
|
|
else
|
|
{
|
|
glVertex(mesh_boxcenter + (mesh_yaxis * Scalarm(-10.0)));
|
|
glVertex(mesh_boxcenter + (mesh_yaxis * Scalarm(10.0)));
|
|
}
|
|
break;
|
|
case EditManipulatorsPlugin::ModZZ:
|
|
glColor3f(0.5,0.5,1.0);
|
|
if(aroundOrigin || (current_manip == EditManipulatorsPlugin::ManMove))
|
|
{
|
|
glVertex(mesh_origin + (mesh_zaxis * Scalarm(-10.0)));
|
|
glVertex(mesh_origin + (mesh_zaxis * Scalarm(10.0)));
|
|
}
|
|
else
|
|
{
|
|
glVertex(mesh_boxcenter + (mesh_zaxis * Scalarm(-10.0)));
|
|
glVertex(mesh_boxcenter + (mesh_zaxis * Scalarm(10.0)));
|
|
}
|
|
break;
|
|
default: ;
|
|
}
|
|
|
|
glEnd();
|
|
}
|
|
|
|
// restore
|
|
glPopAttrib();
|
|
}
|
|
|
|
void EditManipulatorsPlugin::decorate(MeshModel &model, GLArea *gla, QPainter* /*painter*/)
|
|
{
|
|
//
|
|
Point3m center, right, top, front;
|
|
|
|
MyPick(gla->width()*0.5f, gla->height()*0.5f, center, 0.5f);
|
|
MyPick(gla->width()*0.99f, gla->height()*0.5f, right, 0.5f);
|
|
MyPick(gla->width()*0.5f, gla->height()*0.01f, top, 0.5f);
|
|
MyPick(gla->width()*0.5f, gla->height()*0.5f, front, 0.01f);
|
|
|
|
screen_xaxis = (right - center) * Scalarm(2.0);
|
|
screen_yaxis = (top - center) * Scalarm(2.0);
|
|
screen_zaxis = (front - center) * Scalarm(2.0);
|
|
|
|
float diag = sqrt(screen_xaxis.Norm()*screen_xaxis.Norm() + screen_yaxis.Norm()*screen_yaxis.Norm());
|
|
|
|
// calculate snapping factor
|
|
if(current_manip != EditManipulatorsPlugin::ManNone)
|
|
{
|
|
switch(current_manip)
|
|
{
|
|
case EditManipulatorsPlugin::ManMove:
|
|
snapto = Scalarm(powf(10.f, ceil(log10(diag)) - 2));
|
|
break;
|
|
case EditManipulatorsPlugin::ManRotate:
|
|
snapto = Scalarm(1.0);
|
|
break;
|
|
case EditManipulatorsPlugin::ManScale:
|
|
snapto = Scalarm(0.1);
|
|
break;
|
|
default:;
|
|
}
|
|
}
|
|
|
|
// write manipulator data
|
|
QString StatusString1 = "";
|
|
QString StatusString2 = "";
|
|
QString HelpString1 = "";
|
|
QString HelpString2 = "";
|
|
QString HelpString3 = "";
|
|
|
|
if(current_manip == EditManipulatorsPlugin::ManNone)
|
|
{
|
|
StatusString1 += " NONE ";
|
|
}
|
|
else
|
|
{
|
|
switch(current_manip)
|
|
{
|
|
case EditManipulatorsPlugin::ManMove:
|
|
StatusString1 += " Translate";
|
|
break;
|
|
case EditManipulatorsPlugin::ManRotate:
|
|
if(aroundOrigin) StatusString1 += "Rotate around Mesh Origin";
|
|
else StatusString1 += "Rotate around BBox center";
|
|
break;
|
|
case EditManipulatorsPlugin::ManScale:
|
|
if(aroundOrigin) StatusString1 += "Scale around Mesh Origin";
|
|
else StatusString1 += "Scale around BBox center";
|
|
break;
|
|
default: ;
|
|
}
|
|
StatusString2="<br>";
|
|
switch(current_manip_mode)
|
|
{
|
|
case EditManipulatorsPlugin::ModX: StatusString2 += "X global"; break;
|
|
case EditManipulatorsPlugin::ModY: StatusString2 += "Y global"; break;
|
|
case EditManipulatorsPlugin::ModZ: StatusString2 += "Z global"; break;
|
|
case EditManipulatorsPlugin::ModXX: StatusString2 += "X local"; break;
|
|
case EditManipulatorsPlugin::ModYY: StatusString2 += "Y local"; break;
|
|
case EditManipulatorsPlugin::ModZZ: StatusString2 += "Z local"; break;
|
|
default:
|
|
if((current_manip == EditManipulatorsPlugin::ManMove) || (current_manip == EditManipulatorsPlugin::ManRotate))
|
|
StatusString2 += "viewport";
|
|
else if(current_manip == EditManipulatorsPlugin::ManScale)
|
|
StatusString2 += "uniform";
|
|
break;
|
|
}
|
|
|
|
// display offset factor in single axis
|
|
if(current_manip_mode != EditManipulatorsPlugin::ModNone)
|
|
{
|
|
StatusString2 += QString(" :: %1").arg(displayOffset);
|
|
}
|
|
|
|
// viewport translation, display the XYZ offsets
|
|
if((current_manip_mode == EditManipulatorsPlugin::ModNone) && (current_manip == EditManipulatorsPlugin::ManMove))
|
|
{
|
|
StatusString2 += QString(" - %1 %2 %3").arg(displayOffset_X).arg(displayOffset_Y).arg(displayOffset_Z);
|
|
}
|
|
|
|
// viewport rotation, display rotation angle
|
|
if((current_manip_mode == EditManipulatorsPlugin::ModNone) && (current_manip == EditManipulatorsPlugin::ManRotate))
|
|
{
|
|
StatusString2 += QString(" - %1").arg(displayOffset);
|
|
}
|
|
|
|
// uniform scale, display scale factor
|
|
if((current_manip_mode == EditManipulatorsPlugin::ModNone) && (current_manip == EditManipulatorsPlugin::ManScale))
|
|
{
|
|
StatusString2 += QString(" - %1").arg(displayOffset);
|
|
}
|
|
|
|
if(isSnapping)
|
|
{
|
|
StatusString2 += QString(" - Snapping: %1").arg(snapto);
|
|
}
|
|
}
|
|
|
|
if(current_manip == EditManipulatorsPlugin::ManNone)
|
|
{
|
|
HelpString1 = "<br><i> press T to translate, R to rotate, S to scale</i>";
|
|
}
|
|
else
|
|
{
|
|
switch(current_manip)
|
|
{
|
|
case EditManipulatorsPlugin::ManMove : HelpString1 = "<br> LEFT CLICK and DRAG to move"; break;
|
|
case EditManipulatorsPlugin::ManRotate : HelpString1 = "<br> LEFT CLICK and DRAG to rotate"; break;
|
|
case EditManipulatorsPlugin::ManScale : HelpString1 = "<br> LEFT CLICK and DRAG to scale"; break;
|
|
case EditManipulatorsPlugin::ManNone : break;
|
|
}
|
|
|
|
if((current_manip != EditManipulatorsPlugin::ManMove) || (current_manip_mode != EditManipulatorsPlugin::ModNone))
|
|
HelpString1 += " - hold SHIFT to snap";
|
|
|
|
HelpString2="<br>";
|
|
switch(current_manip_mode)
|
|
{
|
|
case EditManipulatorsPlugin::ModX: HelpString2 = "<br> press X to switch to X local"; break;
|
|
case EditManipulatorsPlugin::ModY: HelpString2 = "<br> press Y to switch to Y local"; break;
|
|
case EditManipulatorsPlugin::ModZ: HelpString2 = "<br> press Z to switch to Z local"; break;
|
|
case EditManipulatorsPlugin::ModXX: HelpString2 = "<br> press X to switch to X global"; break;
|
|
case EditManipulatorsPlugin::ModYY: HelpString2 = "<br> press Y to switch to Y global"; break;
|
|
case EditManipulatorsPlugin::ModZZ: HelpString2 = "<br> press Z to switch to Z global"; break;
|
|
default: HelpString2 = "<br> press X Y Z to select an axis"; break;
|
|
}
|
|
|
|
if((current_manip == EditManipulatorsPlugin::ManRotate) || (current_manip == EditManipulatorsPlugin::ManScale))
|
|
{
|
|
if(aroundOrigin) HelpString2 += " - press SPACE or C to pivot on BBox center";
|
|
else HelpString2 += " - press SPACE or C to pivot on Mesh Origin";
|
|
}
|
|
|
|
HelpString3 = "<br>press RETURN to apply, BACKSPACE to cancel";
|
|
}
|
|
|
|
this->realTimeLog("Manipulator","",qUtf8Printable("<b>"+StatusString1+"</b>"+StatusString2+HelpString1+HelpString2+HelpString3));
|
|
|
|
// render original mesh BBox
|
|
DrawMeshBox(model);
|
|
|
|
// render active manipulator
|
|
DrawManipulators(model, gla, true);
|
|
|
|
assert(!glGetError());
|
|
}
|
|
|
|
void EditManipulatorsPlugin::UpdateMatrix(MeshModel &model, GLArea * gla, bool applymouseoffset, bool useinputnumber)
|
|
{
|
|
Matrix44m newmatrix;
|
|
|
|
Matrix44m old_rotation;
|
|
Matrix44m old_translation;
|
|
Matrix44m old_meshcenter;
|
|
Matrix44m old_meshuncenter;
|
|
Matrix44m old_meshcenter_untr;
|
|
Matrix44m old_meshuncenter_untr;
|
|
|
|
Point3m new_scale;
|
|
Point3m axis;
|
|
Scalarm mouseXoff;
|
|
Scalarm mouseYoff;
|
|
|
|
Point3m mesh_boxcenter, mesh_origin, mesh_xaxis, mesh_yaxis, mesh_zaxis;
|
|
mesh_boxcenter = model.cm.bbox.Center();
|
|
mesh_origin = original_Transform.GetColumn3(3);
|
|
mesh_xaxis = original_Transform.GetColumn3(0);
|
|
mesh_yaxis = original_Transform.GetColumn3(1);
|
|
mesh_zaxis = original_Transform.GetColumn3(2);
|
|
vcg::Normalize(mesh_xaxis);
|
|
vcg::Normalize(mesh_yaxis);
|
|
vcg::Normalize(mesh_zaxis);
|
|
|
|
delta_Transform.SetIdentity();
|
|
newmatrix.SetIdentity();
|
|
|
|
if(current_manip == EditManipulatorsPlugin::ManNone)
|
|
{
|
|
model.cm.Tr = original_Transform;
|
|
}
|
|
else
|
|
{
|
|
|
|
if(current_manip_mode != EditManipulatorsPlugin::ModNone) // transform on one axis only
|
|
{
|
|
|
|
switch(current_manip_mode) // which axis is active
|
|
{
|
|
case EditManipulatorsPlugin::ModX:
|
|
axis = Point3m(1.0, 0.0, 0.0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModY:
|
|
axis = Point3m(0.0, 1.0, 0.0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModZ:
|
|
axis = Point3m(0.0, 0.0, 1.0);
|
|
break;
|
|
case EditManipulatorsPlugin::ModXX:
|
|
axis = mesh_xaxis;
|
|
break;
|
|
case EditManipulatorsPlugin::ModYY:
|
|
axis = mesh_yaxis;
|
|
break;
|
|
case EditManipulatorsPlugin::ModZZ:
|
|
axis = mesh_zaxis;
|
|
break;
|
|
default: axis = Point3m(1.0, 1.0, 1.0); // it should never arrive here, anyway
|
|
}
|
|
|
|
if(current_manip == EditManipulatorsPlugin::ManMove)
|
|
{
|
|
// mouse offset -> single axis translation
|
|
float xsign = ((screen_xaxis*axis)>0.0)?1.0:-1.0;
|
|
float ysign = ((screen_yaxis*axis)>0.0)?1.0:-1.0;
|
|
mouseXoff = xsign * screen_xaxis.Norm() * (currScreenOffset_X/float(gla->width()));
|
|
mouseYoff = ysign * screen_yaxis.Norm() * (currScreenOffset_Y/float(gla->height()));
|
|
displayOffset = currOffset + mouseXoff + mouseYoff;
|
|
|
|
// snapping
|
|
if(isSnapping)
|
|
{
|
|
displayOffset /= snapto;
|
|
displayOffset = floor(displayOffset+0.5);
|
|
displayOffset *= snapto;
|
|
}
|
|
|
|
if (useinputnumber)
|
|
displayOffset = inputnumber;
|
|
|
|
delta_Transform.SetTranslate(axis * displayOffset);
|
|
newmatrix = delta_Transform * original_Transform;
|
|
}
|
|
else if(current_manip == EditManipulatorsPlugin::ManRotate)
|
|
{
|
|
// mouse offset -> single axis rotation
|
|
mouseXoff = (currScreenOffset_X/float(gla->width()));
|
|
mouseYoff = (currScreenOffset_Y/float(gla->height()));
|
|
displayOffset = currOffset + (360.0 * (mouseXoff + mouseYoff));
|
|
if((displayOffset > 360.0) || (displayOffset < -360.0))
|
|
displayOffset = 360.0;
|
|
|
|
// snapping
|
|
if(isSnapping)
|
|
{
|
|
displayOffset = floor(displayOffset+0.5);
|
|
}
|
|
|
|
if(useinputnumber)
|
|
displayOffset = inputnumber;
|
|
|
|
delta_Transform.SetRotateDeg(displayOffset, axis);
|
|
|
|
old_rotation = original_Transform;
|
|
old_rotation.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
|
|
old_translation.SetTranslate(original_Transform.GetColumn3(3));
|
|
old_meshcenter.SetTranslate(old_rotation * (-mesh_boxcenter));
|
|
old_meshuncenter.SetTranslate(old_rotation * mesh_boxcenter);
|
|
|
|
if(aroundOrigin)
|
|
newmatrix = old_translation * delta_Transform * old_rotation;
|
|
else
|
|
newmatrix = old_translation * old_meshuncenter * delta_Transform * old_meshcenter * old_rotation;
|
|
}
|
|
else if(current_manip == EditManipulatorsPlugin::ManScale)
|
|
{
|
|
// mouse offset -> single axis scaling
|
|
mouseXoff = (currScreenOffset_X/float(gla->width()));
|
|
mouseYoff = (currScreenOffset_Y/float(gla->height()));
|
|
displayOffset = currOffset + (2.0 * (mouseXoff + mouseYoff));
|
|
|
|
// snapping
|
|
if(isSnapping)
|
|
{
|
|
displayOffset /= snapto;
|
|
displayOffset = floor(displayOffset+0.5);
|
|
displayOffset *= snapto;
|
|
}
|
|
|
|
if(useinputnumber)
|
|
displayOffset = inputnumber;
|
|
|
|
if ((current_manip_mode == EditManipulatorsPlugin::ModX) || (current_manip_mode == EditManipulatorsPlugin::ModXX))
|
|
{
|
|
delta_Transform.SetScale(Point3m(displayOffset, Scalarm(1.0), Scalarm(1.0)));
|
|
}
|
|
if ((current_manip_mode == EditManipulatorsPlugin::ModY) || (current_manip_mode == EditManipulatorsPlugin::ModYY))
|
|
{
|
|
delta_Transform.SetScale(Point3m(Scalarm(1.0), displayOffset, Scalarm(1.0)));
|
|
}
|
|
if ((current_manip_mode == EditManipulatorsPlugin::ModZ) || (current_manip_mode == EditManipulatorsPlugin::ModZZ))
|
|
{
|
|
delta_Transform.SetScale(Point3m(Scalarm(1.0), Scalarm(1.0), displayOffset));
|
|
}
|
|
|
|
old_rotation = original_Transform;
|
|
old_rotation.SetColumn(3, Point3m(Scalarm(0.0),Scalarm(0.0),Scalarm(0.0)));
|
|
old_translation.SetTranslate(original_Transform.GetColumn3(3));
|
|
old_meshcenter.SetTranslate(old_rotation * (-mesh_boxcenter));
|
|
old_meshuncenter.SetTranslate(old_rotation * mesh_boxcenter);
|
|
old_meshcenter_untr.SetTranslate(-mesh_boxcenter);
|
|
old_meshuncenter_untr.SetTranslate(mesh_boxcenter);
|
|
|
|
if ((current_manip_mode == EditManipulatorsPlugin::ModX) || (current_manip_mode == EditManipulatorsPlugin::ModY) || (current_manip_mode == EditManipulatorsPlugin::ModZ))
|
|
{
|
|
if (aroundOrigin)
|
|
newmatrix = old_translation * delta_Transform * old_rotation;
|
|
else
|
|
newmatrix = old_translation * old_meshuncenter * delta_Transform * old_meshcenter * old_rotation;
|
|
}
|
|
else // local axis
|
|
{
|
|
if (aroundOrigin)
|
|
newmatrix = old_translation * old_rotation * delta_Transform;
|
|
else
|
|
newmatrix = old_translation * old_rotation * old_meshuncenter_untr * delta_Transform * old_meshcenter_untr;
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
newmatrix = original_Transform; // it should never arrive here, anyway
|
|
|
|
}
|
|
else // transform on full space ? on view space ?
|
|
{
|
|
|
|
|
|
if(current_manip == EditManipulatorsPlugin::ManMove)
|
|
{
|
|
// mouse offset -> viewport translation
|
|
mouseXoff = (currScreenOffset_X/float(gla->width()));
|
|
mouseYoff = (currScreenOffset_Y/float(gla->height()));
|
|
|
|
displayOffset_X = currOffset_X + (screen_xaxis[0] * mouseXoff) + (screen_yaxis[0] * mouseYoff);
|
|
displayOffset_Y = currOffset_Y + (screen_xaxis[1] * mouseXoff) + (screen_yaxis[1] * mouseYoff);
|
|
displayOffset_Z = currOffset_Z + (screen_xaxis[2] * mouseXoff) + (screen_yaxis[2] * mouseYoff);
|
|
|
|
// snapping
|
|
if(isSnapping)
|
|
{
|
|
displayOffset_X /= snapto;
|
|
displayOffset_X = floor(displayOffset_X+0.5);
|
|
displayOffset_X *= snapto;
|
|
displayOffset_Y /= snapto;
|
|
displayOffset_Y = floor(displayOffset_Y+0.5);
|
|
displayOffset_Y *= snapto;
|
|
displayOffset_Z /= snapto;
|
|
displayOffset_Z = floor(displayOffset_Z+0.5);
|
|
displayOffset_Z *= snapto;
|
|
}
|
|
|
|
delta_Transform.SetTranslate(Point3m(displayOffset_X,displayOffset_Y,displayOffset_Z));
|
|
newmatrix = delta_Transform * original_Transform;
|
|
}
|
|
|
|
if(current_manip == EditManipulatorsPlugin::ManRotate)
|
|
{
|
|
// mouse offset -> viewport rotation
|
|
mouseXoff = (currScreenOffset_X/float(gla->width()));
|
|
mouseYoff = (currScreenOffset_Y/float(gla->height()));
|
|
displayOffset = currOffset + (360.0 * (mouseXoff + mouseYoff));
|
|
if((displayOffset > 360.0) || (displayOffset < -360.0))
|
|
displayOffset = 360.0;
|
|
|
|
// snapping
|
|
if(isSnapping)
|
|
{
|
|
displayOffset = floor(displayOffset+0.5);
|
|
}
|
|
|
|
if(useinputnumber)
|
|
displayOffset = inputnumber;
|
|
|
|
delta_Transform.SetRotateDeg(displayOffset, screen_zaxis);
|
|
|
|
old_rotation = original_Transform;
|
|
old_rotation.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
|
|
old_translation.SetTranslate(original_Transform.GetColumn3(3));
|
|
old_meshcenter.SetTranslate(old_rotation * (-mesh_boxcenter));
|
|
old_meshuncenter.SetTranslate(old_rotation * mesh_boxcenter);
|
|
|
|
if(aroundOrigin)
|
|
newmatrix = old_translation * delta_Transform * old_rotation;
|
|
else
|
|
newmatrix = old_translation * old_meshuncenter * delta_Transform * old_meshcenter * old_rotation;
|
|
}
|
|
|
|
if(current_manip == EditManipulatorsPlugin::ManScale)
|
|
{
|
|
// mouse offset -> uniform scaling
|
|
mouseXoff = (currScreenOffset_X/float(gla->width()));
|
|
mouseYoff = (-currScreenOffset_Y/float(gla->height()));
|
|
displayOffset = currOffset + (2.0 * (mouseXoff + mouseYoff));
|
|
|
|
// snapping
|
|
if(isSnapping)
|
|
{
|
|
displayOffset /= snapto;
|
|
displayOffset = floor(displayOffset+0.5);
|
|
displayOffset *= snapto;
|
|
}
|
|
|
|
if(useinputnumber)
|
|
displayOffset = inputnumber;
|
|
|
|
new_scale[0] = displayOffset;
|
|
new_scale[1] = displayOffset;
|
|
new_scale[2] = displayOffset;
|
|
|
|
delta_Transform.SetScale(new_scale);
|
|
|
|
old_rotation = original_Transform;
|
|
old_rotation.SetColumn(3, Point3m(Scalarm(0.0), Scalarm(0.0), Scalarm(0.0)));
|
|
old_translation.SetTranslate(original_Transform.GetColumn3(3));
|
|
old_meshcenter.SetTranslate(-mesh_boxcenter);
|
|
old_meshuncenter.SetTranslate(mesh_boxcenter);
|
|
old_meshcenter_untr.SetTranslate(-mesh_boxcenter);
|
|
old_meshuncenter_untr.SetTranslate(mesh_boxcenter);
|
|
|
|
if(aroundOrigin)
|
|
newmatrix = old_translation * old_rotation * delta_Transform;
|
|
else
|
|
newmatrix = old_translation * old_rotation * old_meshuncenter_untr * delta_Transform * old_meshcenter_untr;
|
|
}
|
|
|
|
}
|
|
model.cm.Tr = newmatrix;
|
|
}
|
|
|
|
if(applymouseoffset)
|
|
{
|
|
// user finished dragging... accumulation of mouse offset into current offset
|
|
currOffset = displayOffset;
|
|
currOffset_X = displayOffset_X;
|
|
currOffset_Y = displayOffset_Y;
|
|
currOffset_Z = displayOffset_Z;
|
|
}
|
|
}
|
|
|
|
|
|
bool EditManipulatorsPlugin::MyPick(const int &x, const int &y, Point3m &pp, float mydepth)
|
|
{
|
|
double res[3];
|
|
GLdouble mm[16],pm[16]; GLint vp[4];
|
|
glGetDoublev(GL_MODELVIEW_MATRIX,mm);
|
|
glGetDoublev(GL_PROJECTION_MATRIX,pm);
|
|
glGetIntegerv(GL_VIEWPORT,vp);
|
|
|
|
gluUnProject(x,y,mydepth,mm,pm,vp,&res[0],&res[1],&res[2]);
|
|
pp=Point3m(Scalarm(res[0]),Scalarm(res[1]),Scalarm(res[2]));
|
|
return true;
|
|
}
|
|
|
|
bool EditManipulatorsPlugin::startEdit(MeshModel & model, GLArea * gla, MLSceneGLSharedDataContext* /*cont*/)
|
|
{
|
|
gla->setCursor(QCursor(QPixmap(":/images/cur_manipulators.png"),15,15));
|
|
connect(this, SIGNAL(suspendEditToggle()),gla,SLOT(suspendEditToggle()) );
|
|
|
|
// reset filter data
|
|
current_manip = EditManipulatorsPlugin::ManNone;
|
|
current_manip_mode = EditManipulatorsPlugin::ModNone;
|
|
isMoving = false;
|
|
isSnapping = false;
|
|
aroundOrigin = true;
|
|
snapto = 1.0;
|
|
resetOffsets();
|
|
|
|
inputnumberstring= "";
|
|
inputnumbernegative = false;
|
|
inputnumber=0;
|
|
|
|
// storing start matrix
|
|
original_Transform = model.cm.Tr;
|
|
delta_Transform = Matrix44m::Identity();
|
|
|
|
gla->update();
|
|
return true;
|
|
}
|
|
|
|
void EditManipulatorsPlugin::endEdit(MeshModel & model, GLArea * gla, MLSceneGLSharedDataContext* /*cont*/)
|
|
{
|
|
cancelMotion(model, gla); // something interrupted the filter... canceling
|
|
}
|
|
|
|
|