Commit 11123e92 authored by Matthias Möller's avatar Matthias Möller
Browse files

- fix: drag mode can be enabled again

- fix: possible crash in drag mode
- fix: translation does not use bounding box information for the text depth
- fix: text scale factor

refs #741

git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@14715 383ad7c9-94d9-4d36-a494-682f7c89f535
parent ea557dec
......@@ -52,15 +52,16 @@ RulerPlugin::RulerPlugin()
:
buttonAction_(0),
pickModeName_("MeasureDistance"),
lineNodeName_("Ruler Line"),
textNodeName_("Ruler Text"),
textTransformNodeName_("Ruler Text Transform"),
lineNodeName_("Ruler-Plugin LineNode"),
textNodeName_("Ruler-Plugin TextNode"),
textTransformNodeName_("Ruler-Plugin TransformNode"),
hitStage_(firstClick),
hitPoints_( ),
lineNode_(0),
textNode_(0),
textTransformNode_(0),
lineDrag_(-1)
lineDrag_(-1),
dblClickCheck_(false)
{
......@@ -77,22 +78,25 @@ void RulerPlugin::showDistance()
ACG::Vec3d Point1 = hitPoints_[0];
ACG::Vec3d Point2 = hitPoints_[1];
//creates the line
lineNode_->clear_points();
lineNode_->set_color(OpenMesh::Vec4f(1.0f,0.0f,0.0f,1.0f));
lineNode_->set_line_width(3);
lineNode_->add_line(Point1,Point2);
//set params for the text
ACG::Vec3d distVec = Point1 - Point2;
QString distanceStr = QString().number((distVec).length());
textNode_->setText(distanceStr.toStdString());
textNode_->multipassNodeSetActive(8, true);
textNode_->setSize(1);
//translate and scale text
textTransformNode_->loadIdentity();
textTransformNode_->translate(ACG::Vec3d(Point2.data()[0],Point2.data()[1],bbmax_.data()[2]));
textTransformNode_->translate(Point1);
ACG::Vec3d halfDist = distVec/2.f;
textTransformNode_->translate(ACG::Vec3d(halfDist.data()[0], halfDist.data()[1], 0.0));
textTransformNode_->scale(std::max(distVec.length()*0.2, 1.0));
textTransformNode_->translate(-halfDist);
textTransformNode_->scale(distVec.length()*0.125);
emit updateView();
}
......@@ -124,157 +128,166 @@ void RulerPlugin::pluginsInitialized()
//------------------------------------------------------------------------------
void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
{
if ( PluginFunctions::pickMode() == pickModeName_)
{//set one of the points, depending on the hit state (first, second or modifying)
if ( PluginFunctions::pickMode() != pickModeName_)
return;
if (_event->type() == QEvent::MouseButtonPress )
{
unsigned int node_idx, target_idx;
OpenMesh::Vec3d hitPoint;
//set one of the points, depending on the hit state (first, second or modifying)
// Get picked object's identifier by picking in scenegraph
if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
{
if (hitStage_ == firstClick)
{
//get or create the line
BaseObjectData* object;
if ( PluginFunctions::getPickedObject(node_idx, object) )
{
if (_event->type() == QEvent::MouseButtonRelease )
{
unsigned int node_idx, target_idx;
OpenMesh::Vec3d hitPoint;
//create line, text and transformation nodes
if (!object->getAdditionalNode(lineNode_,name(),lineNodeName_.c_str()))
{
lineNode_ = new ACG::SceneGraph::LineNode(ACG::SceneGraph::LineNode::LineSegmentsMode,
object->manipulatorNode(),lineNodeName_);
object->addAdditionalNode(lineNode_,name(),lineNodeName_.c_str());
}
if (!object->getAdditionalNode(textTransformNode_,name(),textTransformNodeName_.c_str()))
{
textTransformNode_ = new ACG::SceneGraph::TransformNode(lineNode_,textTransformNodeName_.c_str());
object->addAdditionalNode(textTransformNode_,name(),textTransformNodeName_.c_str());
}
if (!object->getAdditionalNode(textNode_,name(),textNodeName_.c_str()))
{
textNode_ = new ACG::SceneGraph::TextNode(textTransformNode_,textNodeName_,ACG::SceneGraph::TextNode::SCREEN_ALIGNED);
object->addAdditionalNode(textNode_,name(),textNodeName_.c_str());
}
}//end creating nodes
hitPoints_[1] = hitPoints_[0] = hitPoint;
hitStage_ = secondClick;
ACG::Vec3d bbmin;
object->getBoundingBox(bbmin,bbmax_);
showDistance();
//enable mouse tracking for line drawing
lineDrag_ = 1;
emit setPickModeMouseTracking(pickModeName_,true);
}
else if (hitStage_ == secondClick)
// Get picked object's identifier by picking in scenegraph
if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) && !dblClickCheck_)
{
if (hitStage_ == firstClick)
{
//get or create the line
BaseObjectData* object;
if ( PluginFunctions::getPickedObject(node_idx, object) )
{
lineDrag_ = -1;
emit setPickModeMouseTracking(pickModeName_,false);
//second position was clicked, so distance can be computed and displayed
hitPoints_[1] = hitPoint;
// show picked object
showDistance();
//create line, point, text and transformation nodes
if (!object->getAdditionalNode(lineNode_,name(),lineNodeName_.c_str()))
{
lineNode_ = new ACG::SceneGraph::LineNode(ACG::SceneGraph::LineNode::LineSegmentsMode,
object->manipulatorNode(),lineNodeName_);
object->addAdditionalNode(lineNode_,name(),lineNodeName_.c_str());
}
//after this stage, the points can be modified by a simple click
hitStage_ = modifyPoint;
}
else if ((hitStage_ == modifyPoint))
{
//two modes:
//first: no point was dragged, so we can compute and change the position
//of the nearest one
if (lineDrag_ < 0)
if (!object->getAdditionalNode(textTransformNode_,name(),textTransformNodeName_.c_str()))
{
float firstDist = (hitPoints_[0] - hitPoint).length();
float secondDist = (hitPoints_[1] - hitPoint).length();
if (firstDist < secondDist)
hitPoints_[0] = hitPoint;
else
hitPoints_[1] = hitPoint;
textTransformNode_ = new ACG::SceneGraph::TransformNode(lineNode_,textTransformNodeName_.c_str());
object->addAdditionalNode(textTransformNode_,name(),textTransformNodeName_.c_str());
}
else
//second: drag mode is enabled so we know the point
if (!object->getAdditionalNode(textNode_,name(),textNodeName_.c_str()))
{
hitPoints_[lineDrag_] = hitPoint;
lineDrag_ = -1;
textNode_ = new ACG::SceneGraph::TextNode(textTransformNode_,textNodeName_,ACG::SceneGraph::TextNode::SCREEN_ALIGNED,true);
object->addAdditionalNode(textNode_,name(),textNodeName_.c_str());
}
showDistance();
}
}//end creating nodes
hitPoints_[1] = hitPoints_[0] = hitPoint;
hitStage_ = secondClick;
enableDragMode(1);
showDistance();
}
else // if nothing was picked
else if (hitStage_ == secondClick)
{
reset();
}
}
else if (_event->type() == QEvent::MouseButtonPress)
{//enable drag mode
disableDragMode();
//second position was clicked, so distance can be computed and displayed
hitPoints_[1] = hitPoint;
if (hitStage_ == modifyPoint)
{
//decides which point is the nearest one, so
//it can be dragged
unsigned int node_idx, target_idx;
OpenMesh::Vec3d hitPoint;
// show picked object
showDistance();
// Get picked object's identifier by picking in scenegraph
if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
//after this stage, the points can be modified by a simple click
hitStage_ = modifyPoint;
}
else if ((hitStage_ == modifyPoint))
{
//two modes:
//first: no point was dragged, so we can compute and change the position
//of the nearest one
if (lineDrag_ < 0)
{
float firstDist = (hitPoints_[0] - hitPoint).length();
float secondDist = (hitPoints_[1] - hitPoint).length();
if (firstDist < secondDist)
lineDrag_ = 0;
hitPoints_[0] = hitPoint;
else
lineDrag_ = 1;
showDistance();
hitPoints_[1] = hitPoint;
}
else
//second: drag mode is enabled so we can easily update the position
{
hitPoints_[lineDrag_] = hitPoint;
disableDragMode();
}
showDistance();
}
}
else if (_event->type() == QEvent::MouseMove && lineDrag_ >= 0)
{//mouse moved and drag mode is enabled
else // if nothing was picked
{
reset();
}
}
else if (_event->type() == QEvent::MouseButtonPress)
{//enable drag mode
if (hitStage_ == modifyPoint)
{
//decides which point is the nearest one, so
//it can be dragged
unsigned int node_idx, target_idx;
OpenMesh::Vec3d hitPoint;
// Get picked object's identifier by picking in scenegraph
if ( !PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
{
QPoint position = _event->pos();
ACG::Vec3d viewCoords = ACG::Vec3d(position.x(), PluginFunctions::viewerProperties().glState().context_height() - position.y(), 0.5);
hitPoint = PluginFunctions::viewerProperties().glState().unproject(viewCoords);
hitPoints_[lineDrag_] = ACG::Vec3d(hitPoint.data()[0], hitPoint.data()[1], hitPoints_[lineDrag_].data()[2] );
float firstDist = (hitPoints_[0] - hitPoint).length();
float secondDist = (hitPoints_[1] - hitPoint).length();
enableDragMode( (firstDist < secondDist)? 0 : 1);
showDistance();
}
else
hitPoints_[lineDrag_] = hitPoint;
showDistance();
}
else if (_event->type() == QEvent::MouseButtonDblClick)
{//reset
reset();
}
}
else if (_event->type() == QEvent::MouseMove && lineDrag_ >= 0)
{//mouse moved and drag mode is enabled
unsigned int node_idx, target_idx;
OpenMesh::Vec3d hitPoint;
// Get picked object's identifier by picking in scenegraph
if ( !PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
{
//if mouse is not over an object, get the unprojected coordinates and the last z-value
QPoint position = _event->pos();
ACG::Vec3d viewCoords = ACG::Vec3d(position.x(), PluginFunctions::viewerProperties().glState().context_height() - position.y(), 0.5);
hitPoint = PluginFunctions::viewerProperties().glState().unproject(viewCoords);
hitPoints_[lineDrag_] = ACG::Vec3d(hitPoint.data()[0], hitPoint.data()[1], hitPoints_[lineDrag_].data()[2] );
}
else
hitPoints_[lineDrag_] = hitPoint;
showDistance();
}
else if (_event->type() == QEvent::MouseButtonDblClick)
{//reset
reset();
dblClickCheck_ = true;
}
if (dblClickCheck_ && _event->type() == QEvent::MouseButtonRelease)
dblClickCheck_ = false;
}
//------------------------------------------------------------------------------
void RulerPlugin::reset()
{
hitStage_ = firstClick;
lineDrag_ = -1;
if (lineNode_)
lineNode_->clear_points();
if (textNode_)
textNode_->setText("");
}
//------------------------------------------------------------------------------
void RulerPlugin::enableDragMode(const int _point)
{
lineDrag_ = _point;
emit setPickModeMouseTracking(pickModeName_,true);
}
//------------------------------------------------------------------------------
void RulerPlugin::disableDragMode()
{
lineDrag_ = -1;
emit setPickModeMouseTracking(pickModeName_,false);
}
//------------------------------------------------------------------------------
void RulerPlugin::slotChangePickMode()
......
......@@ -92,10 +92,15 @@ public:
private:
QAction *buttonAction_;
void enableDragMode(const int _point);
void disableDragMode();
void reset();
QAction *buttonAction_;
const std::string pickModeName_;
const std::string lineNodeName_;
const std::string textNodeName_;
......@@ -117,7 +122,8 @@ private:
//saves the index of the dragged point, if no point was dragged, it is -1
int lineDrag_;
ACG::Vec3d bbmax_;
//checks if a double click was provided for resetting
bool dblClickCheck_;
private slots:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment