RulerPlugin.cc 11.8 KB
Newer Older
Matthias Möller's avatar
Matthias Möller committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/*===========================================================================*\
*                                                                            *
*                              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/>.                                       *
*                                                                            *
\*===========================================================================*/

/*===========================================================================*\
*                                                                            *
Matthias Möller's avatar
Matthias Möller committed
37 38 39
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
Matthias Möller's avatar
Matthias Möller committed
40 41 42 43 44 45 46
*                                                                            *
\*===========================================================================*/


#include "RulerPlugin.hh"

#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
Matthias Möller's avatar
Matthias Möller committed
47
#include <OpenFlipper/common/GlobalOptions.hh>
Matthias Möller's avatar
Matthias Möller committed
48 49 50 51 52 53

//------------------------------------------------------------------------------
RulerPlugin::RulerPlugin()
:
buttonAction_(0),
pickModeName_("MeasureDistance"),
54
lineDrag_(-1),
Matthias Möller's avatar
Matthias Möller committed
55
dblClickCheck_(false),
56
viewupdated_(false),
Matthias Möller's avatar
Matthias Möller committed
57 58
optionsWidget_(0),
textSizeSettingName_(name()+QString("/TextSize"))
Matthias Möller's avatar
Matthias Möller committed
59 60 61 62 63 64 65
{

}

//------------------------------------------------------------------------------
RulerPlugin::~RulerPlugin()
{
66
  reset();
Matthias Möller's avatar
Matthias Möller committed
67 68 69 70
}
//------------------------------------------------------------------------------
void RulerPlugin::initializePlugin()
{
71
  QToolBar *button = new QToolBar("Ruler");
Matthias Möller's avatar
Matthias Möller committed
72 73 74 75 76 77

  buttonAction_ = new QAction(tr("<B>Ruler</B><br> Display the distance between two points."),this);

  button->addAction(buttonAction_);
  buttonAction_->setIcon(QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"ruler.png"));
  buttonAction_->setCheckable(true);
Matthias Möller's avatar
Matthias Möller committed
78 79
  WhatsThisGenerator whatsThisGen("Ruler");
  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>"));
Matthias Möller's avatar
Matthias Möller committed
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95

  buttonAction_->setChecked(false);

  connect(buttonAction_,SIGNAL(triggered()), this , SLOT(slotChangePickMode()) );
  emit addToolbar(button);
}

//------------------------------------------------------------------------------
void RulerPlugin::pluginsInitialized()
{
  emit addPickMode(pickModeName_);
}

//------------------------------------------------------------------------------
void RulerPlugin::slotMouseEvent(QMouseEvent* _event)
{
96 97
  if ( PluginFunctions::pickMode() != pickModeName_)
    return;
Matthias Möller's avatar
doc  
Matthias Möller committed
98

99 100
//////create or change ruler/////////
//set one of the points, depending on the hit state (first, second or modifying)
101 102 103 104
  if (_event->type() == QEvent::MouseButtonRelease )
  {
    unsigned int node_idx, target_idx;
    OpenMesh::Vec3d hitPoint;
Matthias Möller's avatar
Matthias Möller committed
105

106 107 108
    // Get picked object's identifier by picking in scenegraph
    if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) && !dblClickCheck_)
    {
109
      if (!currentRuler_)
110
      {
111
        //create a new Ruler
112 113
        BaseObjectData* object;
        if ( PluginFunctions::getPickedObject(node_idx, object) )
Matthias Möller's avatar
Matthias Möller committed
114
        {
115 116
          currentRuler_.reset(new Ruler(object,name(),0));
          connect(currentRuler_.get(),SIGNAL(updateView()),this,SIGNAL(updateView()));
117
          unsigned textSize = OpenFlipperSettings().value(textSizeSettingName_,16).toUInt();
Matthias Möller's avatar
Matthias Möller committed
118
          currentRuler_->setTextSize(textSize);
119 120 121
          currentRuler_->setPoints(hitPoint,hitPoint);
          enableDragMode(1);
        }
Matthias Möller's avatar
Matthias Möller committed
122

123
      }
124
      else
125
      {
126 127
        //Ruler was created -> change position of a point
        if (!dragModeActive())
Matthias Möller's avatar
Matthias Möller committed
128
        {
129 130 131 132 133
          //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);
Matthias Möller's avatar
Matthias Möller committed
134
          else
135
            currentRuler_->setEndPoint(hitPoint);
Matthias Möller's avatar
Matthias Möller committed
136
        }
137 138
        else
        {
139 140 141 142 143
          //second: drag mode is enabled so we can easily update the position
          if (lineDrag_ == 0)
            currentRuler_->setStartPoint(hitPoint);
          else
            currentRuler_->setEndPoint(hitPoint);
144 145
          disableDragMode();
        }
Matthias Möller's avatar
Matthias Möller committed
146 147
      }
    }
148 149 150 151 152
    else // if nothing was picked
    {
      reset();
    }
  }
153 154

//////enable drag mode//////
155 156
  else if (_event->type() == QEvent::MouseButtonPress)
  {//enable drag mode
Matthias Möller's avatar
doc  
Matthias Möller committed
157

158
    if (currentRuler_)
159 160 161
    {
      //decides which point is the nearest one, so
      //it can be dragged
Matthias Möller's avatar
Matthias Möller committed
162 163 164 165
      unsigned int node_idx, target_idx;
      OpenMesh::Vec3d hitPoint;

      // Get picked object's identifier by picking in scenegraph
166
      if ( PluginFunctions::scenegraphPick(ACG::SceneGraph::PICK_ANYTHING ,_event->pos(), node_idx, target_idx, &hitPoint) )
Matthias Möller's avatar
Matthias Möller committed
167
      {
168 169 170
        float distToStart = (currentRuler_->points()[0] - hitPoint).length();
        float distToEnd = (currentRuler_->points()[1] - hitPoint).length();
        enableDragMode( (distToStart < distToEnd)? 0 : 1);
Matthias Möller's avatar
Matthias Möller committed
171 172
      }
    }
173
  }
174 175
////////modify ruler of drag mode was enabled/////////
  else if (_event->type() == QEvent::MouseMove && dragModeActive())
176 177 178 179
  {//mouse moved and drag mode is enabled

    unsigned int node_idx, target_idx;
    OpenMesh::Vec3d hitPoint;
180 181
    ACG::Vec3d hitPoints[2];
    std::copy(currentRuler_->points(),currentRuler_->points()+2,hitPoints);
Matthias Möller's avatar
Matthias Möller committed
182

183 184 185 186 187 188 189
    // 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);
190
      hitPoints[lineDrag_] = ACG::Vec3d(hitPoint.data()[0], hitPoint.data()[1], hitPoints[lineDrag_].data()[2] );
191 192
    }
    else
193 194 195
      hitPoints[lineDrag_] = hitPoint;

    currentRuler_->setPoints(hitPoints[0],hitPoints[1]);
196
  }
197

198
///////////////////////Reset/////////////////////////////////
199 200 201 202
  else if (_event->type() == QEvent::MouseButtonDblClick)
  {//reset
    reset();
    dblClickCheck_ = true;
Matthias Möller's avatar
Matthias Möller committed
203
  }
204 205
  if (dblClickCheck_ && _event->type() == QEvent::MouseButtonRelease)
    dblClickCheck_ = false;
Matthias Möller's avatar
Matthias Möller committed
206 207 208 209 210
}

//------------------------------------------------------------------------------
void RulerPlugin::reset()
{
211
  currentRuler_.reset();
212
  lineDrag_ = -1;
Matthias Möller's avatar
Matthias Möller committed
213
}
214 215 216 217 218 219 220 221 222 223 224 225 226
//------------------------------------------------------------------------------
void RulerPlugin::enableDragMode(const int _point)
{
  lineDrag_ = _point;
  emit setPickModeMouseTracking(pickModeName_,true);
}

//------------------------------------------------------------------------------
void RulerPlugin::disableDragMode()
{
  lineDrag_ = -1;
  emit setPickModeMouseTracking(pickModeName_,false);
}
Matthias Möller's avatar
Matthias Möller committed
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241

//------------------------------------------------------------------------------
void RulerPlugin::slotChangePickMode()
{
  PluginFunctions::actionMode( Viewer::PickingMode );
  PluginFunctions::pickMode(pickModeName_);

}

//------------------------------------------------------------------------------
void RulerPlugin::slotPickModeChanged(const std::string& _mode)
{
  buttonAction_->setChecked(_mode == pickModeName_);
}

242 243 244
//------------------------------------------------------------------------------
void RulerPlugin::slotAllCleared()
{
245 246 247 248 249 250 251
  disableDragMode();
}

void RulerPlugin::objectDeleted(int _id)
{
  if (!currentRuler_)
    return;
252

253 254 255 256 257 258
  disableDragMode();
  if (_id == currentRuler_->getBaseObj()->id())
  {
    disconnect(currentRuler_.get(),SIGNAL(updateView()),this,SIGNAL(updateView()));
    currentRuler_.reset();
  }
259
}
Matthias Möller's avatar
Matthias Möller committed
260 261 262 263 264 265 266 267
//------------------------------------------------------------------------------
bool RulerPlugin::initializeOptionsWidget(QWidget*& _widget)
{
  if (!optionsWidget_)
  {
    optionsWidget_ = new RulerOptions();
  }

268
  unsigned textSize = OpenFlipperSettings().value(textSizeSettingName_,16).toUInt();
Matthias Möller's avatar
Matthias Möller committed
269 270 271 272 273 274 275 276 277 278 279 280
  optionsWidget_->textSizeSpinBox->setValue(textSize);
  _widget = optionsWidget_;
  return true;
}
//------------------------------------------------------------------------------
void RulerPlugin::applyOptions()
{
  int textSize = optionsWidget_->textSizeSpinBox->value();
  if (currentRuler_)
    currentRuler_->setTextSize(textSize);
  OpenFlipperSettings().setValue(textSizeSettingName_,textSize);
}
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313
//------------------------------------------------------------------------------
void RulerPlugin::slotViewChanged()
{

  if (!currentRuler_)
    return;

  //compute line direction
  ACG::Vec3d lineVector = currentRuler_->points()[0] - currentRuler_->points()[1];
  ACG::Vec3d rightVec = (PluginFunctions::viewingDirection() % -PluginFunctions::upVector()).normalize();

  float cosAngleLineRight = lineVector.normalize() | rightVec;
  float cosAngleUpLine = PluginFunctions::upVector().normalized() | lineVector.normalized() ;


  rightVec *= -0.5f*currentRuler_->textScale();
  ACG::Vec3d updownVec = PluginFunctions::upVector()*currentRuler_->textScale();

  //compute up/down offset
  if (cosAngleLineRight > 0.f)
  {
    updownVec *= (cosAngleUpLine < 0.f) ? -2.f : 0.5f;
  }
  else
  {
    updownVec *= (cosAngleUpLine < 0.f) ? 0.5f : -2.0f;
  }

  // small offset to the right and big offset up/down depending on the line
  currentRuler_->setTextOffset(rightVec+updownVec);


}
314

Matthias Möller's avatar
Matthias Möller committed
315 316 317 318
#if QT_VERSION < 0x050000
  Q_EXPORT_PLUGIN2( rulerPlugin , RulerPlugin );
#endif