Developer Documentation

RulerPlugin.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39 * *
40 \*===========================================================================*/
41
42 #include "RulerPlugin.hh"
43
44 #include <OpenFlipper/BasePlugin/PluginFunctions.hh>
45 #include <OpenFlipper/BasePlugin/WhatsThisGenerator.hh>
46 #include <OpenFlipper/common/GlobalOptions.hh>
47
48 //------------------------------------------------------------------------------
49 RulerPlugin::RulerPlugin()
50 :
51 buttonAction_(0),
52 pickModeName_("MeasureDistance"),
53 lineDrag_(-1),
54 dblClickCheck_(false),
55 optionsWidget_(0),
56 textSizeSettingName_(name()+QString("/TextSize"))
57 {
58
59 }
60
61 //------------------------------------------------------------------------------
62 RulerPlugin::~RulerPlugin()
63 {
64 reset();
65 }
66 //------------------------------------------------------------------------------
67 void RulerPlugin::initializePlugin()
68 {
69 QToolBar *button = new QToolBar("Ruler");
70
71 buttonAction_ = new QAction(tr("<B>Ruler</B><br> Display the distance between two points."),this);
72
73 button->addAction(buttonAction_);
74 buttonAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"ruler.png"));
75 buttonAction_->setCheckable(true);
76 WhatsThisGenerator whatsThisGen("Ruler");
77 whatsThisGen.setWhatsThis(buttonAction_,tr("Measures the distance between two points.<br><b>LeftClick</b>: define/change the position.<br><b>DoubleClick</b>: reset the ruler.<br>"));
78
79 buttonAction_->setChecked(false);
80
81 connect(buttonAction_,SIGNAL(triggered()), this , SLOT(slotChangePickMode()) );
82 emit addToolbar(button);
83 }
84
85 //------------------------------------------------------------------------------
86 void RulerPlugin::pluginsInitialized()
87 {
88 emit addPickMode(pickModeName_);
89 }
90
91 //------------------------------------------------------------------------------
92 void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
93 {
94 if ( PluginFunctions::pickMode() != pickModeName_)
95 return;
96
98 //set one of the points, depending on the hit state (first, second or modifying)
99 if (_event->type() == QEvent::MouseButtonRelease )
100 {
101 size_t node_idx, target_idx;
102 OpenMesh::Vec3d hitPoint;
103
104 // Get picked object's identifier by picking in scenegraph
105 if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) && !dblClickCheck_)
106 {
107 if (!currentRuler_)
108 {
109 //create a new Ruler
110 BaseObjectData* object;
111 if ( PluginFunctions::getPickedObject(node_idx, object) )
112 {
113 currentRuler_.reset(new Ruler(object,name(),0));
114 connect(currentRuler_.get(),SIGNAL(updateView()),this,SIGNAL(updateView()));
115 unsigned textSize = OpenFlipperSettings().value(textSizeSettingName_,16).toUInt();
116 currentRuler_->setTextSize(textSize);
117 currentRuler_->setPoints(hitPoint,hitPoint);
118 enableDragMode(1);
119 }
120
121 }
122 else
123 {
124 //Ruler was created -> change position of a point
125 if (!dragModeActive())
126 {
127 //dragmode is disabled -> update position of nearest point
128 float distToStart = (currentRuler_->points()[0] - hitPoint).length();
129 float distToEnd = (currentRuler_->points()[1] - hitPoint).length();
130 if (distToStart < distToEnd)
131 currentRuler_->setStartPoint(hitPoint);
132 else
133 currentRuler_->setEndPoint(hitPoint);
134 }
135 else
136 {
137 //second: drag mode is enabled so we can easily update the position
138 if (lineDrag_ == 0)
139 currentRuler_->setStartPoint(hitPoint);
140 else
141 currentRuler_->setEndPoint(hitPoint);
142 disableDragMode();
143 }
144 }
145 }
146 else // if nothing was picked
147 {
148 reset();
149 }
150 }
151
153 else if (_event->type() == QEvent::MouseButtonPress)
154 {//enable drag mode
155
156 if (currentRuler_)
157 {
158 //decides which point is the nearest one, so
159 //it can be dragged
160 size_t node_idx, target_idx;
161 OpenMesh::Vec3d hitPoint;
162
163 // Get picked object's identifier by picking in scenegraph
164 if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
165 {
166 float distToStart = (currentRuler_->points()[0] - hitPoint).length();
167 float distToEnd = (currentRuler_->points()[1] - hitPoint).length();
168 enableDragMode( (distToStart < distToEnd)? 0 : 1);
169 }
170 }
171 }
173 else if (_event->type() == QEvent::MouseMove && dragModeActive())
174 {//mouse moved and drag mode is enabled
175
176 size_t node_idx, target_idx;
177 OpenMesh::Vec3d hitPoint;
178 ACG::Vec3d hitPoints[2];
179 std::copy(currentRuler_->points(),currentRuler_->points()+2,hitPoints);
180
181 // Get picked object's identifier by picking in scenegraph
182 if ( !PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
183 {
184 //if mouse is not over an object, get the unprojected coordinates and the last z-value
185 QPoint position = _event->pos();
186 ACG::Vec3d viewCoords = ACG::Vec3d(position.x(), PluginFunctions::viewerProperties().glState().context_height() - position.y(), 0.5);
187 hitPoint = PluginFunctions::viewerProperties().glState().unproject(viewCoords);
188 hitPoints[lineDrag_] = ACG::Vec3d(hitPoint.data()[0], hitPoint.data()[1], hitPoints[lineDrag_].data()[2] );
189 }
190 else
191 hitPoints[lineDrag_] = hitPoint;
192
193 currentRuler_->setPoints(hitPoints[0],hitPoints[1]);
194 }
195
197 else if (_event->type() == QEvent::MouseButtonDblClick)
198 {//reset
199 reset();
200 dblClickCheck_ = true;
201 }
202 if (dblClickCheck_ && _event->type() == QEvent::MouseButtonRelease)
203 dblClickCheck_ = false;
204 }
205
206 //------------------------------------------------------------------------------
207 void RulerPlugin::reset()
208 {
209 currentRuler_.reset();
210 lineDrag_ = -1;
211 }
212 //------------------------------------------------------------------------------
213 void RulerPlugin::enableDragMode(const int _point)
214 {
215 lineDrag_ = _point;
216 emit setPickModeMouseTracking(pickModeName_,true);
217 }
218
219 //------------------------------------------------------------------------------
220 void RulerPlugin::disableDragMode()
221 {
222 lineDrag_ = -1;
223 emit setPickModeMouseTracking(pickModeName_,false);
224 }
225
226 //------------------------------------------------------------------------------
227 void RulerPlugin::slotChangePickMode()
228 {
229 PluginFunctions::actionMode( Viewer::PickingMode );
230 PluginFunctions::pickMode(pickModeName_);
231
232 }
233
234 //------------------------------------------------------------------------------
235 void RulerPlugin::slotPickModeChanged(const std::string& _mode)
236 {
237 buttonAction_->setChecked(_mode == pickModeName_);
238 }
239
240 //------------------------------------------------------------------------------
241 void RulerPlugin::slotAllCleared()
242 {
243 disableDragMode();
244 }
245
246 void RulerPlugin::objectDeleted(int _id)
247 {
248 if (!currentRuler_)
249 return;
250
251 disableDragMode();
252 if (_id == currentRuler_->getBaseObj()->id())
253 {
254 disconnect(currentRuler_.get(),SIGNAL(updateView()),this,SIGNAL(updateView()));
255 currentRuler_.reset();
256 }
257 }
258 //------------------------------------------------------------------------------
259 bool RulerPlugin::initializeOptionsWidget(QWidget*& _widget)
260 {
261 if (!optionsWidget_)
262 {
263 optionsWidget_ = new RulerOptions();
264 }
265
266 unsigned textSize = OpenFlipperSettings().value(textSizeSettingName_,16).toUInt();
267 optionsWidget_->textSizeSpinBox->setValue(textSize);
268 _widget = optionsWidget_;
269 return true;
270 }
271 //------------------------------------------------------------------------------
272 void RulerPlugin::applyOptions()
273 {
274 int textSize = optionsWidget_->textSizeSpinBox->value();
275 if (currentRuler_)
276 currentRuler_->setTextSize(textSize);
277 OpenFlipperSettings().setValue(textSizeSettingName_,textSize);
278 }
279 //------------------------------------------------------------------------------
280 void RulerPlugin::slotViewChanged()
281 {
282
283 if (!currentRuler_)
284 return;
285
286 //compute line direction
287 ACG::Vec3d lineVector = currentRuler_->points()[0] - currentRuler_->points()[1];
288 ACG::Vec3d rightVec = (PluginFunctions::viewingDirection() % -PluginFunctions::upVector()).normalize();
289
290 float cosAngleLineRight = lineVector.normalize() | rightVec;
291 float cosAngleUpLine = PluginFunctions::upVector().normalized() | lineVector.normalized() ;
292
293
294 rightVec *= -0.5f*currentRuler_->textScale();
295 ACG::Vec3d updownVec = PluginFunctions::upVector()*currentRuler_->textScale();
296
297 //compute up/down offset
298 if (cosAngleLineRight > 0.f)
299 {
300 updownVec *= (cosAngleUpLine < 0.f) ? -2.f : 0.5f;
301 }
302 else
303 {
304 updownVec *= (cosAngleUpLine < 0.f) ? 0.5f : -2.0f;
305 }
306
307 // small offset to the right and big offset up/down depending on the line
308 currentRuler_->setTextOffset(rightVec+updownVec);
309
310
311 }
312
313
PluginFunctions::scenegraphPick
bool scenegraphPick(ACG::SceneGraph::PickTarget _pickTarget, const QPoint &_mousePos, size_t &_nodeIdx, size_t &_targetIdx, ACG::Vec3d *_hitPointPtr=0)
Execute picking operation on scenegraph.
Definition: PluginFunctions.cc:480
WhatsThisGenerator
a class which provides an link generator for WhatsThisMessages linking to the user doc If you have an...
Definition: WhatsThisGenerator.hh:65
PluginFunctions::viewingDirection
void viewingDirection(const ACG::Vec3d &_dir, const ACG::Vec3d &_up, int _viewer)
Set the viewing direction.
Definition: PluginFunctions.cc:689
PluginFunctions::upVector
ACG::Vec3d upVector(int _viewer)
Get the current up vector.
Definition: PluginFunctions.cc:913
GlobalOptions.hh
OpenMesh::VectorT::normalized
auto normalized() const -> decltype(*this/std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:445
OpenMesh::VectorT
Definition: Vector11T.hh:83
PluginFunctions.hh
OpenMesh::VectorT::data
Scalar * data()
access to Scalar array
Definition: Vector11T.hh:200
ACG::GLState::unproject
Vec3d unproject(const Vec3d &_winPoint) const
unproject point in window coordinates _winPoint to world coordinates
Definition: GLState.cc:651
PluginFunctions::actionMode
Viewer::ActionMode actionMode()
Get the current Action mode.
Definition: PluginFunctions.cc:588
OpenFlipperQSettings::value
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
Definition: OpenFlipperQSettings.cc:46
ACG::SceneGraph::PICK_ANYTHING
pick any of the prior targets (should be implemented for all nodes)
Definition: PickTarget.hh:84
Ruler
Definition: Ruler.hh:52
BaseObjectData
Definition: BaseObjectData.hh:102
PluginFunctions::pickMode
const std::string pickMode()
Get the current Picking mode.
Definition: PluginFunctions.cc:577
RulerOptions
Definition: RulerOptions.hh:51
PluginFunctions::viewerProperties
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
Definition: PluginFunctions.cc:611
OpenFlipperQSettings::setValue
void setValue(const QString &key, const QVariant &value)
Wrapper function which makes it possible to enable Debugging output with -DOPENFLIPPER_SETTINGS_DEBUG...
Definition: OpenFlipperQSettings.cc:61
ACG::GLState::context_height
int context_height() const
get gl context height
Definition: GLState.hh:830
OpenFlipperSettings
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
Definition: GlobalOptions.cc:1038
PluginFunctions::getPickedObject
bool getPickedObject(const size_t _node_idx, BaseObjectData *&_object)
Get the picked mesh.
Definition: PluginFunctions.cc:261
OpenMesh::VectorT::normalize
auto normalize() -> decltype(*this/=std::declval< VectorT< S, DIM >>().norm())
Definition: Vector11T.hh:434
ACG::Vec3d
VectorT< double, 3 > Vec3d
Definition: VectorT.hh:121
RulerPlugin::initializeOptionsWidget
bool initializeOptionsWidget(QWidget *&_widget)
Initialize the Options Widget.
Definition: RulerPlugin.cc:259
Viewer::ViewerProperties::glState
ACG::GLState & glState()
Get the glState of the Viewer.
Definition: ViewerProperties.cc:318