BaseObjectData.cc 12.6 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
//== TYPEDEFS =================================================================

//== CLASS DEFINITION =========================================================
73

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

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

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

106 107 108
}

void BaseObjectData::cleanup() {
109

110 111 112 113 114 115 116 117
  // 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;
118
    boundingBoxNode_ = 0;
119 120
    additionalNodes_.clear();
  }
121

122
  BaseObject::cleanup();
123

124
  initializeScenegraphNodes();
125 126
}

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

134
  if ( manipulatorNode_ == 0 ) {
135
    manipulatorNode_      = new QtTranslationManipulatorNode(baseNode(),"NEW ManipulatorNode");
136 137 138

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

160 161 162 163 164 165 166 167 168 169 170 171
      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{
172
      color = OpenFlipper::Options::defaultColor();
173 174 175 176 177 178 179 180 181 182 183
    }
    
    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);
    
184 185
    // We take the brightest color component for overlays to get best contrast
    materialNode_->set_overlay_color(materialNode_->specular_color());
186
  }
187 188 189 190 191 192 193 194
}


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

void BaseObjectData::show() {
195 196 197 198 199 200
  if ( !visible_ ) {
    separatorNode_->set_status( ACG::SceneGraph::BaseNode::Active  );
    visible_ = true;
    
    emit visibilityChanged( id() );
  }
201 202 203
}

void BaseObjectData::hide() {
204 205 206 207 208 209
  if ( visible_ ) {
    separatorNode_->set_status( ACG::SceneGraph::BaseNode::HideSubtree );
    visible_ = false;
    
    emit visibilityChanged( id() );
  }
210 211
}

212 213 214 215 216 217
bool BaseObjectData::visible(){
  return visible_;
}

void BaseObjectData::visible(bool _visible) {

218 219 220 221 222 223
  if ( visible_ != _visible ) {
    
    if (_visible)
      separatorNode_->set_status( ACG::SceneGraph::BaseNode::Active  );
    else
      separatorNode_->set_status( ACG::SceneGraph::BaseNode::HideSubtree );
224

225 226 227 228
    visible_ = _visible;
    
    emit visibilityChanged( id() );
  }
229 230
}

231
SeparatorNode* BaseObjectData::baseNode() {
232
  return separatorNode_;
233 234
}

235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
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
257 258 259 260
BaseNode* BaseObjectData::primaryNode() {
  return separatorNode_;
}

261
QtTranslationManipulatorNode* BaseObjectData::manipulatorNode() {
262 263 264 265 266
  return manipulatorNode_;
}

ACG::SceneGraph::ShaderNode* BaseObjectData::shaderNode() {
  return 0;
267 268 269
}

MaterialNode* BaseObjectData::materialNode() {
270
  return materialNode_;
Heng Liu's avatar
Heng Liu committed
271 272 273 274
}

const MaterialNode* BaseObjectData::materialNode() const {
    return materialNode_;
275 276
}

277 278 279 280
BoundingBoxNode* BaseObjectData::boundingBoxNode() {
  return boundingBoxNode_;
}

281 282 283 284
StencilRefNode* BaseObjectData::stencilRefNode() {
  return stencilRefNode_;
}

285 286 287 288 289 290 291 292
bool BaseObjectData::manipPlaced() {
  return manipPlaced_;
}

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

293 294
void BaseObjectData::getBoundingBox(ACG::Vec3d& bbmin, ACG::Vec3d& bbmax){

295
  // Single pass action, as the bounding box is not influenced by multipass traversal
296 297 298 299 300 301 302 303
  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
304
void BaseObjectData::setObjectDrawMode(const ACG::SceneGraph::DrawModes::DrawMode& _mode, const bool& _force) {
305 306
    
  // Set draw mode for this object
307
  ACG::SceneGraph::SetDrawModesAction actionActive(_mode, _force);
308 309 310 311 312
  
  // Traverse scenegraph in order to set new draw mode
  ACG::SceneGraph::traverse(primaryNode(), actionActive);
}

313
// ===============================================================================
314
// Picking
315 316 317
// ===============================================================================

bool BaseObjectData::picked( uint /* _node_idx */ ) {
318
 return false;
319 320
}

321 322 323 324 325 326 327
void BaseObjectData::enablePicking( bool /*_enable*/ ) {
}

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

328 329 330 331
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;
}

332 333 334
// ===============================================================================
// Content Nodes
// ===============================================================================
335
void BaseObjectData::update(UpdateType _type )
336 337 338 339 340 341 342 343 344 345 346 347 348
{

}

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

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

350 351 352 353
  for ( uint i =0 ; i < additionalNodes_.size() ; ++i ) {
    if (additionalNodes_[i].second == searchname )
      return true;
  }
354

355 356 357
  return false;
}

358

359
//=============================================================================
360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379

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 );
}