BaseObjectData.cc 12.8 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
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 37 38
 *           Copyright (c) 2001-2015, RWTH-Aachen University                 *
 *           Department of Computer Graphics and Multimedia                  *
 *                          All rights reserved.                             *
 *                            www.openflipper.org                            *
 *                                                                           *
 *---------------------------------------------------------------------------*
 * This file is part of OpenFlipper.                                         *
 *---------------------------------------------------------------------------*
 *                                                                           *
 * Redistribution and use in source and binary forms, with or without        *
 * modification, are permitted provided that the following conditions        *
 * are met:                                                                  *
 *                                                                           *
 * 1. Redistributions of source code must retain the above copyright notice, *
 *    this list of conditions and the following disclaimer.                  *
 *                                                                           *
 * 2. Redistributions in binary form must reproduce the above copyright      *
 *    notice, this list of conditions and the following disclaimer in the    *
 *    documentation and/or other materials provided with the distribution.   *
 *                                                                           *
 * 3. Neither the name of the copyright holder nor the names of its          *
 *    contributors may be used to endorse or promote products derived from   *
 *    this software without specific prior written permission.               *
 *                                                                           *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       *
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A           *
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  *
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,       *
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR        *
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    *
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING      *
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS        *
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.              *
Jan Möbius's avatar
Jan Möbius committed
39
*                                                                            *
40 41 42
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
43 44 45 46 47
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
48
\*===========================================================================*/
49 50 51 52 53 54 55 56 57 58 59 60




//=============================================================================
//
//  MyTypes
//
//=============================================================================

//== INCLUDES =================================================================

61
#include "BaseObjectData.hh"
62
#include "Types.hh"
63
#include <ACG/Scenegraph/SceneGraph.hh>
64
#include <OpenFlipper/common/GlobalOptions.hh>
65 66 67
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>


68 69 70 71 72
#include <ACG/Scenegraph/SeparatorNode.hh>
#include <ACG/QtScenegraph/QtTranslationManipulatorNode.hh>
#include <ACG/Scenegraph/BoundingBoxNode.hh>
#include <ACG/Scenegraph/StencilRefNode.hh>
#include <ACG/Scenegraph/StatusNodesT.hh>
73

74 75 76
//== TYPEDEFS =================================================================

//== CLASS DEFINITION =========================================================
77

78 79
BaseObjectData::BaseObjectData(const BaseObjectData& _object)
  : BaseObject(_object),
80
    manipPlaced_(false),
81 82 83
    rootNode_(_object.rootNode_),
    separatorNode_(0),
    manipulatorNode_(0),
84
    materialNode_(0),
85 86
    boundingBoxNode_(0),
    stencilRefNode_(0)
87
{
88 89
  /// We have to create our own visualization nodes as we are a new object
  initializeScenegraphNodes();
90 91
}

92
BaseObjectData::BaseObjectData() :
93
  BaseObject(),
94
  manipPlaced_(false),
95
  rootNode_( dynamic_cast< ACG::SceneGraph::SeparatorNode* > (PluginFunctions::getRootNode()) ),
96 97
  separatorNode_(0),
  manipulatorNode_(0),
98
  materialNode_(0),
99 100
  boundingBoxNode_(0),
  stencilRefNode_(0)
101
{
102
  initializeScenegraphNodes();
103 104 105 106 107 108
}

BaseObjectData::~BaseObjectData() {
  if ( separatorNode_ != 0 ) {
    separatorNode_->delete_subtree();
  }
109

110 111 112
}

void BaseObjectData::cleanup() {
113

114 115 116 117 118 119 120 121
  // Delete everything below the seperator node on top of the object. This will remove the complete subtree.
  if ( separatorNode_ == 0 )
    std::cerr << "cleanup : separatorNode_ is already 0" << std::endl;
  else {
    separatorNode_->delete_subtree();
    separatorNode_   = 0;
    manipulatorNode_ = 0;
    materialNode_    = 0;
122
    boundingBoxNode_ = 0;
123 124
    additionalNodes_.clear();
  }
125

126
  BaseObject::cleanup();
127

128
  initializeScenegraphNodes();
129 130
}

131
void BaseObjectData::initializeScenegraphNodes() {
132 133 134
  // Create seperatorNode for Object only if it does not exist.
  if ( separatorNode_ == 0 )
    separatorNode_       = new SeparatorNode((BaseNode*)rootNode_,"NEW Object");
135
  else
136
    std::cerr << "Separator Node already exists. this should not happen!" << std::endl;
137

138
  if ( manipulatorNode_ == 0 ) {
139
    manipulatorNode_      = new QtTranslationManipulatorNode(baseNode(),"NEW ManipulatorNode");
140 141 142

    // Bind this manipulator to the current object
    manipulatorNode_->setIdentifier(id());
143
    manipulatorNode_->set_status( ACG::SceneGraph::TranslationManipulatorNode::Active );
144
  }
145
  else
146
    std::cerr << "Manipulator Node already exists. this should not happen!" << std::endl;
147 148 149 150 151
  if ( boundingBoxNode_ == 0)
  {
    boundingBoxNode_      = new BoundingBoxNode(manipulatorNode(),  "New Bounding Box");
    boundingBoxNode_->set_status( ACG::SceneGraph::BaseNode::HideNode );
  }
152 153
  if ( stencilRefNode_ == 0 )
  {
154
    stencilRefNode_       = new StencilRefNode(boundingBoxNode(),  "New Stencil Reference");
155 156
    stencilRefNode_->set_status( ACG::SceneGraph::BaseNode::HideNode );
  }
157
  if ( materialNode_ == 0 ) {
158
    materialNode_         = new MaterialNode(stencilRefNode(),  "New Material");
159 160 161
    
    QColor color;
    
162
    if ( OpenFlipper::Options::randomDefaultColor() ){
Jan Möbius's avatar
Jan Möbius committed
163

164 165 166 167 168 169 170 171 172 173 174 175
      QColor bckgrnd = OpenFlipperSettings().value("Core/Gui/glViewer/defaultBackgroundColor").value<QColor>();
      int diff;
      
      do{
        color.setRgb(rand()%255, rand()%255, rand()%255);
        
        diff = (bckgrnd.red()   - color.red())  *(bckgrnd.red()   - color.red())
              +(bckgrnd.green() - color.green())*(bckgrnd.green() - color.green())
              +(bckgrnd.blue()  - color.blue()) *(bckgrnd.blue()  - color.blue());
      } while (diff < 70000);
    }
    else{
176
      color = OpenFlipper::Options::defaultColor();
177 178 179 180 181 182 183 184 185 186 187
    }
    
    ACG::Vec4f colorV;
    colorV[0] = color.redF();
    colorV[1] = color.greenF();
    colorV[2] = color.blueF();
    colorV[3] = color.alphaF();
    
    materialNode_->set_base_color(colorV);
    materialNode_->set_color(colorV);
    
188 189
    // We take the brightest color component for overlays to get best contrast
    materialNode_->set_overlay_color(materialNode_->specular_color());
190
  }
191 192 193 194 195 196 197 198
}


// ===============================================================================
// Object visualization
// ===============================================================================

void BaseObjectData::show() {
199 200 201 202 203 204
  if ( !visible_ ) {
    separatorNode_->set_status( ACG::SceneGraph::BaseNode::Active  );
    visible_ = true;
    
    emit visibilityChanged( id() );
  }
205 206 207
}

void BaseObjectData::hide() {
208 209 210 211 212 213
  if ( visible_ ) {
    separatorNode_->set_status( ACG::SceneGraph::BaseNode::HideSubtree );
    visible_ = false;
    
    emit visibilityChanged( id() );
  }
214 215
}

216 217 218 219 220 221
bool BaseObjectData::visible(){
  return visible_;
}

void BaseObjectData::visible(bool _visible) {

222 223 224 225 226 227
  if ( visible_ != _visible ) {
    
    if (_visible)
      separatorNode_->set_status( ACG::SceneGraph::BaseNode::Active  );
    else
      separatorNode_->set_status( ACG::SceneGraph::BaseNode::HideSubtree );
228

229 230 231 232
    visible_ = _visible;
    
    emit visibilityChanged( id() );
  }
233 234
}

235
SeparatorNode* BaseObjectData::baseNode() {
236
  return separatorNode_;
237 238
}

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260
bool BaseObjectData::hasNode(BaseNode* _node) {

  QList< BaseNode* > list;
  list.push_back(separatorNode_);
  
  BaseNode* currentNode;
  while (!list.empty()) {
    currentNode = list.front();
    
    if ( currentNode->find(_node) == currentNode->childrenEnd() ) {
      for ( BaseNode::ChildIter child = currentNode->childrenBegin() ; child != currentNode->childrenEnd(); ++child )
        list.push_back(*child);
    } else 
      return true;
      
    list.pop_front();
  }
  
  return false;
  
}

Dirk Wilden's avatar
Dirk Wilden committed
261 262 263 264
BaseNode* BaseObjectData::primaryNode() {
  return separatorNode_;
}

265
QtTranslationManipulatorNode* BaseObjectData::manipulatorNode() {
266 267 268 269 270
  return manipulatorNode_;
}

ACG::SceneGraph::ShaderNode* BaseObjectData::shaderNode() {
  return 0;
271 272 273
}

MaterialNode* BaseObjectData::materialNode() {
274
  return materialNode_;
Heng Liu's avatar
Heng Liu committed
275 276 277 278
}

const MaterialNode* BaseObjectData::materialNode() const {
    return materialNode_;
279 280
}

281 282 283 284
BoundingBoxNode* BaseObjectData::boundingBoxNode() {
  return boundingBoxNode_;
}

285 286 287 288
StencilRefNode* BaseObjectData::stencilRefNode() {
  return stencilRefNode_;
}

289 290 291 292 293 294 295 296
bool BaseObjectData::manipPlaced() {
  return manipPlaced_;
}

void BaseObjectData::manipPlaced( bool _placed ) {
  manipPlaced_ = _placed;
}

297 298
void BaseObjectData::getBoundingBox(ACG::Vec3d& bbmin, ACG::Vec3d& bbmax){

299
  // Single pass action, as the bounding box is not influenced by multipass traversal
300 301 302 303 304 305 306 307
  ACG::SceneGraph::BoundingBoxAction act;
  ACG::SceneGraph::traverse(separatorNode_, act);


  bbmin = (ACG::Vec3d) act.bbMin();
  bbmax = (ACG::Vec3d) act.bbMax();
}

Jan Möbius's avatar
Jan Möbius committed
308
void BaseObjectData::setObjectDrawMode(const ACG::SceneGraph::DrawModes::DrawMode& _mode, const bool& _force) {
309 310
    
  // Set draw mode for this object
311
  ACG::SceneGraph::SetDrawModesAction actionActive(_mode, _force);
312 313 314 315 316
  
  // Traverse scenegraph in order to set new draw mode
  ACG::SceneGraph::traverse(primaryNode(), actionActive);
}

317
// ===============================================================================
318
// Picking
319 320 321
// ===============================================================================

bool BaseObjectData::picked( uint /* _node_idx */ ) {
322
 return false;
323 324
}

325 326 327 328 329 330 331
void BaseObjectData::enablePicking( bool /*_enable*/ ) {
}

bool BaseObjectData::pickingEnabled() {
  return true;
}

332 333 334 335
ACG::Vec3d BaseObjectData::refinePick(const ACG::SceneGraph::PickTarget _pickTarget, const ACG::Vec3d _hitPoint, const ACG::Vec3d _start , const ACG::Vec3d _dir,  const unsigned int _targetIdx  ) {
  return _hitPoint;
}

336 337 338
// ===============================================================================
// Content Nodes
// ===============================================================================
339
void BaseObjectData::update(UpdateType _type )
340 341 342 343 344 345 346 347 348 349 350 351 352
{

}

// ===============================================================================
// Additional Nodes
// ===============================================================================

bool BaseObjectData::hasAdditionalNode(QString _pluginName, QString _nodeName , int _id )
{
  QString index;
  index.setNum(_id);
  QString searchname = _pluginName+"#"+_nodeName+"#"+index;
353

354 355 356 357
  for ( uint i =0 ; i < additionalNodes_.size() ; ++i ) {
    if (additionalNodes_[i].second == searchname )
      return true;
  }
358

359 360 361
  return false;
}

362

363
//=============================================================================
364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383

void BaseObjectData::setName(QString _name ) {
  BaseObject::setName(_name);

  std::string nodename = std::string("SeparatorNode for object " + _name.toUtf8());
  separatorNode_->name( nodename );

  nodename = std::string("ManipulatorNode for object " + _name.toUtf8());
  manipulatorNode_->name( nodename );

  nodename = std::string("BoundingBoxNode for object " + _name.toUtf8());
  boundingBoxNode_->name( nodename );

  nodename = std::string(_name.toUtf8() + "'s Material" );
  materialNode_->name( nodename );

  nodename = std::string("StencilRefNode for object " + _name.toUtf8());
  stencilRefNode_->name( nodename );
}