Commit a90d43ef authored by Matthias Möller's avatar Matthias Möller

some function and class change for better readability and multi ruler support




git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@16921 383ad7c9-94d9-4d36-a494-682f7c89f535
parent 36d96e77
#include "Ruler.hh"
//------------------------------------------------------------------------------
Ruler::Ruler(BaseObjectData* _obj,const QString &_pluginName, unsigned index)
:pluginName_(_pluginName),
lineNodeName_(QString("Ruler-Plugin LineNode%1").arg(index).toStdString()),
textNodeName_(QString("Ruler-Plugin TextNode%1").arg(index).toStdString()),
textTransformNodeName_(QString("Ruler-Plugin TransformNode%1").arg(index).toStdString()),
lineNode_(0),
textNode_(0),
textTransformNode_(0),
obj_(_obj)
{
points_[0] = points_[1] = ACG::Vec3d(0.0,0.0,0.0);
//create line, point, text and transformation nodes
if (!_obj->getAdditionalNode(lineNode_,_pluginName,lineNodeName_.c_str()))
{
lineNode_ = new ACG::SceneGraph::LineNode(ACG::SceneGraph::LineNode::LineSegmentsMode,
_obj->manipulatorNode(),lineNodeName_);
_obj->addAdditionalNode(lineNode_,_pluginName,lineNodeName_.c_str());
}
if (!_obj->getAdditionalNode(textTransformNode_,_pluginName,textTransformNodeName_.c_str()))
{
textTransformNode_ = new ACG::SceneGraph::TransformNode(lineNode_,textTransformNodeName_.c_str());
_obj->addAdditionalNode(textTransformNode_,_pluginName,textTransformNodeName_.c_str());
}
if (!_obj->getAdditionalNode(textNode_,_pluginName,textNodeName_.c_str()))
{
textNode_ = new ACG::SceneGraph::TextNode(textTransformNode_,textNodeName_,ACG::SceneGraph::TextNode::SCREEN_ALIGNED,true);
_obj->addAdditionalNode(textNode_,_pluginName,textNodeName_.c_str());
}
}
//------------------------------------------------------------------------------
Ruler::~Ruler()
{
if (obj_->getAdditionalNode(textNode_,pluginName_,textNodeName_.c_str()))
{
obj_->removeAdditionalNode(textNode_,pluginName_,textNodeName_.c_str());
}
if (obj_->getAdditionalNode(textTransformNode_,pluginName_,textTransformNodeName_.c_str()))
{
obj_->removeAdditionalNode(textTransformNode_,pluginName_,textTransformNodeName_.c_str());
}
if (obj_->getAdditionalNode(lineNode_,pluginName_,lineNodeName_.c_str()))
{
obj_->removeAdditionalNode(lineNode_,pluginName_,lineNodeName_.c_str());
}
}
//------------------------------------------------------------------------------
void Ruler::setPoints(const ACG::Vec3d &_start,const ACG::Vec3d &_end)
{
points_[0] = _start;
points_[1] = _end;
updateNodes();
}
void Ruler::setStartPoint(const ACG::Vec3d& _start)
{
points_[0] = _start;
updateNodes();
}
//------------------------------------------------------------------------------
void Ruler::setEndPoint(const ACG::Vec3d& _end)
{
points_[1] = _end;
updateNodes();
}
//------------------------------------------------------------------------------
void Ruler::updateNodes()
{
ACG::Vec3d Point1 = points_[0];
ACG::Vec3d Point2 = points_[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);
lineNode_->alwaysOnTop() = true;
//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(Point1);
ACG::Vec3d halfDist = distVec/2.f;
textTransformNode_->translate(-halfDist);
textTransformNode_->scale(distVec.length()*0.125);
emit updateView();
}
/*===========================================================================*\
* *
* OpenFlipper *
* Copyright (C) 2001-2011 by Computer Graphics Group, RWTH Aachen *
* www.openflipper.org *
* *
*--------------------------------------------------------------------------- *
* This file is part of OpenFlipper. *
* *
* OpenFlipper is free software: you can redistribute it and/or modify *
* it under the terms of the GNU Lesser General Public License as *
* published by the Free Software Foundation, either version 3 of *
* the License, or (at your option) any later version with the *
* following exceptions: *
* *
* If other files instantiate templates or use macros *
* or inline functions from this file, or you compile this file and *
* link it with other files to produce an executable, this file does *
* not by itself cause the resulting executable to be covered by the *
* GNU Lesser General Public License. This exception does not however *
* invalidate any other reasons why the executable file might be *
* covered by the GNU Lesser General Public License. *
* *
* OpenFlipper 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 Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU LesserGeneral Public *
* License along with OpenFlipper. If not, *
* see <http://www.gnu.org/licenses/>. *
* *
\*===========================================================================*/
/*===========================================================================*\
* *
* $Revision$ *
* $LastChangedBy$ *
* $Date$ *
* *
\*===========================================================================*/
#include <QObject>
#include <QString>
#include <ACG/Scenegraph/LineNode.hh>
#include <ACG/Scenegraph/TextNode.hh>
#include <OpenFlipper/common/BaseObjectData.hh>
class Ruler : public QObject
{
Q_OBJECT
signals:
void updateView();
public:
/**
* creates a new ruler on a given object
* @param _obj Object where additional nodes are added
* @param _pluginName name of the plugin
* @param _index the current index of the ruler. If you create multiple rulers, you can use this parameter to avoid identical nodenames
*/
Ruler(BaseObjectData *_obj,const QString &_pluginName, unsigned _index);
~Ruler();
void setPoints(const ACG::Vec3d& _start,const ACG::Vec3d& _end);
void setStartPoint(const ACG::Vec3d& _start);
void setEndPoint(const ACG::Vec3d& _end);
const ACG::Vec3d* points() const{return points_;}
const BaseObject* getBaseObj(){return obj_;}
private:
void updateNodes();
const QString pluginName_;
const std::string lineNodeName_;
const std::string textNodeName_;
const std::string textTransformNodeName_;
ACG::SceneGraph::LineNode* lineNode_;
ACG::SceneGraph::TextNode* textNode_;
ACG::SceneGraph::TransformNode* textTransformNode_;
ACG::Vec3d points_[2];
BaseObjectData* obj_;
};
......@@ -50,17 +50,8 @@ RulerPlugin::RulerPlugin()
:
buttonAction_(0),
pickModeName_("MeasureDistance"),
lineNodeName_("Ruler-Plugin LineNode"),
textNodeName_("Ruler-Plugin TextNode"),
textTransformNodeName_("Ruler-Plugin TransformNode"),
hitStage_(firstClick),
hitPoints_( ),
lineNode_(0),
textNode_(0),
textTransformNode_(0),
lineDrag_(-1),
dblClickCheck_(false)
{
}
......@@ -68,38 +59,8 @@ dblClickCheck_(false)
//------------------------------------------------------------------------------
RulerPlugin::~RulerPlugin()
{
}
//------------------------------------------------------------------------------
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);
lineNode_->alwaysOnTop() = true;
//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(Point1);
ACG::Vec3d halfDist = distVec/2.f;
textTransformNode_->translate(-halfDist);
textTransformNode_->scale(distVec.length()*0.125);
emit updateView();
reset();
}
//------------------------------------------------------------------------------
void RulerPlugin::initializePlugin()
{
......@@ -131,8 +92,8 @@ void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
if ( PluginFunctions::pickMode() != pickModeName_)
return;
//set one of the points, depending on the hit state (first, second or modifying)
//////create or change ruler/////////
//set one of the points, depending on the hit state (first, second or modifying)
if (_event->type() == QEvent::MouseButtonRelease )
{
unsigned int node_idx, target_idx;
......@@ -141,75 +102,41 @@ void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
// 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)
if (!currentRuler_)
{
//get or create the line
//create a new Ruler
BaseObjectData* object;
if ( PluginFunctions::getPickedObject(node_idx, object) )
{
currentRuler_.reset(new Ruler(object,name(),0));
connect(currentRuler_.get(),SIGNAL(updateView()),this,SIGNAL(updateView()));
currentRuler_->setPoints(hitPoint,hitPoint);
enableDragMode(1);
}
//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());
}
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,true);
object->addAdditionalNode(textNode_,name(),textNodeName_.c_str());
}
}//end creating nodes
hitPoints_[1] = hitPoints_[0] = hitPoint;
hitStage_ = secondClick;
enableDragMode(1);
showDistance();
}
else if (hitStage_ == secondClick)
{
disableDragMode();
//second position was clicked, so distance can be computed and displayed
hitPoints_[1] = hitPoint;
// show picked object
showDistance();
//after this stage, the points can be modified by a simple click
hitStage_ = modifyPoint;
}
else if (hitStage_ == modifyPoint)
else
{
//two modes:
//first: no point was dragged, so we can compute and change the position
//of the nearest one
if (lineDrag_ < 0)
//Ruler was created -> change position of a point
if (!dragModeActive())
{
float firstDist = (hitPoints_[0] - hitPoint).length();
float secondDist = (hitPoints_[1] - hitPoint).length();
if (firstDist < secondDist)
hitPoints_[0] = hitPoint;
//dragmode is disabled -> update position of nearest point
float distToStart = (currentRuler_->points()[0] - hitPoint).length();
float distToEnd = (currentRuler_->points()[1] - hitPoint).length();
if (distToStart < distToEnd)
currentRuler_->setStartPoint(hitPoint);
else
hitPoints_[1] = hitPoint;
currentRuler_->setEndPoint(hitPoint);
}
else
//second: drag mode is enabled so we can easily update the position
{
hitPoints_[lineDrag_] = hitPoint;
//second: drag mode is enabled so we can easily update the position
if (lineDrag_ == 0)
currentRuler_->setStartPoint(hitPoint);
else
currentRuler_->setEndPoint(hitPoint);
disableDragMode();
}
showDistance();
}
}
else // if nothing was picked
......@@ -217,10 +144,12 @@ void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
reset();
}
}
//////enable drag mode//////
else if (_event->type() == QEvent::MouseButtonPress)
{//enable drag mode
if (hitStage_ == modifyPoint)
if (currentRuler_)
{
//decides which point is the nearest one, so
//it can be dragged
......@@ -230,18 +159,20 @@ void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
// Get picked object's identifier by picking in scenegraph
if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
{
float firstDist = (hitPoints_[0] - hitPoint).length();
float secondDist = (hitPoints_[1] - hitPoint).length();
enableDragMode( (firstDist < secondDist)? 0 : 1);
showDistance();
float distToStart = (currentRuler_->points()[0] - hitPoint).length();
float distToEnd = (currentRuler_->points()[1] - hitPoint).length();
enableDragMode( (distToStart < distToEnd)? 0 : 1);
}
}
}
else if (_event->type() == QEvent::MouseMove && lineDrag_ >= 0)
////////modify ruler of drag mode was enabled/////////
else if (_event->type() == QEvent::MouseMove && dragModeActive())
{//mouse moved and drag mode is enabled
unsigned int node_idx, target_idx;
OpenMesh::Vec3d hitPoint;
ACG::Vec3d hitPoints[2];
std::copy(currentRuler_->points(),currentRuler_->points()+2,hitPoints);
// Get picked object's identifier by picking in scenegraph
if ( !PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
......@@ -250,12 +181,15 @@ void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
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] );
hitPoints[lineDrag_] = ACG::Vec3d(hitPoint.data()[0], hitPoint.data()[1], hitPoints[lineDrag_].data()[2] );
}
else
hitPoints_[lineDrag_] = hitPoint;
showDistance();
hitPoints[lineDrag_] = hitPoint;
currentRuler_->setPoints(hitPoints[0],hitPoints[1]);
}
else if (_event->type() == QEvent::MouseButtonDblClick)
{//reset
reset();
......@@ -268,12 +202,7 @@ void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
//------------------------------------------------------------------------------
void RulerPlugin::reset()
{
hitStage_ = firstClick;
lineDrag_ = -1;
if (lineNode_)
lineNode_->clear_points();
if (textNode_)
textNode_->setText("");
}
//------------------------------------------------------------------------------
void RulerPlugin::enableDragMode(const int _point)
......@@ -306,12 +235,20 @@ void RulerPlugin::slotPickModeChanged(const std::string& _mode)
//------------------------------------------------------------------------------
void RulerPlugin::slotAllCleared()
{
hitStage_ = firstClick;
lineDrag_ = -1;
disableDragMode();
}
void RulerPlugin::objectDeleted(int _id)
{
if (!currentRuler_)
return;
lineNode_ = 0;
textNode_ = 0;
textTransformNode_ = 0;
disableDragMode();
if (_id == currentRuler_->getBaseObj()->id())
{
disconnect(currentRuler_.get(),SIGNAL(updateView()),this,SIGNAL(updateView()));
currentRuler_.reset();
}
}
Q_EXPORT_PLUGIN2( rulerPlugin , RulerPlugin );
......@@ -46,25 +46,28 @@
#include <QObject>
#include <QString>
#include <ACG/Utils/SmartPointer.hh>
#include <OpenFlipper/BasePlugin/BaseInterface.hh>
#include <OpenFlipper/BasePlugin/MouseInterface.hh>
#include <OpenFlipper/BasePlugin/PickingInterface.hh>
#include <OpenFlipper/BasePlugin/ToolbarInterface.hh>
#include <OpenFlipper/BasePlugin/LoadSaveInterface.hh>
#include <OpenFlipper/common/Types.hh>
#include <ObjectTypes/PolyMesh/PolyMesh.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
#include <ACG/Scenegraph/LineNode.hh>
#include <ACG/Scenegraph/TextNode.hh>
#include "Ruler.hh"
class RulerPlugin : public QObject, BaseInterface, MouseInterface, PickingInterface, ToolbarInterface
class RulerPlugin : public QObject, BaseInterface, MouseInterface, PickingInterface, ToolbarInterface, LoadSaveInterface
{
Q_OBJECT
Q_INTERFACES(BaseInterface)
Q_INTERFACES(MouseInterface)
Q_INTERFACES(PickingInterface)
Q_INTERFACES(ToolbarInterface)
Q_INTERFACES(LoadSaveInterface)
signals:
void addToolbar(QToolBar *_toolbar);
......@@ -98,26 +101,11 @@ private:
void disableDragMode();
QAction *buttonAction_;
bool dragModeActive(){return lineDrag_ >= 0;}
QAction *buttonAction_;
const std::string pickModeName_;
const std::string lineNodeName_;
const std::string textNodeName_;
const std::string textTransformNodeName_;
enum HitStage
{
firstClick = 0,
secondClick,
modifyPoint
} hitStage_;
OpenMesh::Vec3d hitPoints_[2];
ACG::SceneGraph::LineNode* lineNode_;
ACG::SceneGraph::TextNode* textNode_;
ACG::SceneGraph::TransformNode* textTransformNode_;
//saves the index of the dragged point, if no point was dragged, it is -1
int lineDrag_;
......@@ -125,18 +113,19 @@ private:
//checks if a double click was provided for resetting
bool dblClickCheck_;
ptr::shared_ptr<Ruler> currentRuler_;
private slots:
void initializePlugin();
void pluginsInitialized();
void showDistance();
void slotChangePickMode();
void slotAllCleared();
void objectDeleted(int _id);
public slots:
QString version(){ return QString("1.0"); }
......
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