BaseObjectData.cc 11.7 KB
Newer Older
1
/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
2 3
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen       *
Jan Möbius's avatar
Jan Möbius committed
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
*                           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/>.                                       *
*                                                                            *
33 34 35
\*===========================================================================*/

/*===========================================================================*\
Jan Möbius's avatar
Jan Möbius committed
36 37 38 39 40
*                                                                            *
*   $Revision$                                                       *
*   $LastChangedBy$                                                *
*   $Date$                     *
*                                                                            *
41
\*===========================================================================*/
Jan Möbius's avatar
 
Jan Möbius committed
42 43 44 45 46 47 48 49 50 51 52 53 54




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

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

#include "Types.hh"
55
#include <ACG/Scenegraph/SceneGraph.hh>
56
#include <OpenFlipper/common/BaseObjectCore.hh>
57
#include <OpenFlipper/common/GlobalOptions.hh>
58 59 60 61
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
#include <QDir>


Jan Möbius's avatar
 
Jan Möbius committed
62 63 64 65

//== TYPEDEFS =================================================================

//== CLASS DEFINITION =========================================================
66

67 68
BaseObjectData::BaseObjectData(const BaseObjectData& _object)
  : BaseObject(_object),
69
    manipPlaced_(false),
70 71 72
    rootNode_(_object.rootNode_),
    separatorNode_(0),
    manipulatorNode_(0),
73
    materialNode_(0),
74 75
    boundingBoxNode_(0),
    stencilRefNode_(0)
76
{
77 78
  /// We have to create our own visualization nodes as we are a new object
  initializeScenegraphNodes();
79 80
}

81
BaseObjectData::BaseObjectData() :
Jan Möbius's avatar
 
Jan Möbius committed
82
  BaseObject(),
83
  manipPlaced_(false),
84
  rootNode_( dynamic_cast< ACG::SceneGraph::SeparatorNode* > (PluginFunctions::getRootNode()) ),
Jan Möbius's avatar
 
Jan Möbius committed
85 86
  separatorNode_(0),
  manipulatorNode_(0),
87
  materialNode_(0),
88 89
  boundingBoxNode_(0),
  stencilRefNode_(0)
Jan Möbius's avatar
 
Jan Möbius committed
90
{
91
  initializeScenegraphNodes();
Jan Möbius's avatar
 
Jan Möbius committed
92 93 94 95 96 97
}

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

Jan Möbius's avatar
 
Jan Möbius committed
99 100 101
}

void BaseObjectData::cleanup() {
102

Jan Möbius's avatar
 
Jan Möbius committed
103 104 105 106 107 108 109 110
  // 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;
111
    boundingBoxNode_ = 0;
Jan Möbius's avatar
 
Jan Möbius committed
112 113
    additionalNodes_.clear();
  }
114

Jan Möbius's avatar
 
Jan Möbius committed
115
  BaseObject::cleanup();
116

117
  initializeScenegraphNodes();
Jan Möbius's avatar
 
Jan Möbius committed
118 119
}

120
void BaseObjectData::initializeScenegraphNodes() {
Jan Möbius's avatar
 
Jan Möbius committed
121 122 123
  // Create seperatorNode for Object only if it does not exist.
  if ( separatorNode_ == 0 )
    separatorNode_       = new SeparatorNode((BaseNode*)rootNode_,"NEW Object");
124
  else
Jan Möbius's avatar
 
Jan Möbius committed
125
    std::cerr << "Separator Node already exists. this should not happen!" << std::endl;
126

Jan Möbius's avatar
 
Jan Möbius committed
127
  if ( manipulatorNode_ == 0 ) {
128
    manipulatorNode_      = new QtTranslationManipulatorNode(baseNode(),"NEW ManipulatorNode");
129 130 131

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

153 154 155 156 157 158 159 160 161 162 163 164
      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{
165
      color = OpenFlipper::Options::defaultColor();
166 167 168 169 170 171 172 173 174 175 176
    }
    
    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);
    
177 178
    // We take the brightest color component for overlays to get best contrast
    materialNode_->set_overlay_color(materialNode_->specular_color());
179
  }
Jan Möbius's avatar
 
Jan Möbius committed
180 181 182 183 184 185 186 187
}


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

void BaseObjectData::show() {
188 189 190 191 192 193
  if ( !visible_ ) {
    separatorNode_->set_status( ACG::SceneGraph::BaseNode::Active  );
    visible_ = true;
    
    emit visibilityChanged( id() );
  }
Jan Möbius's avatar
 
Jan Möbius committed
194 195 196
}

void BaseObjectData::hide() {
197 198 199 200 201 202
  if ( visible_ ) {
    separatorNode_->set_status( ACG::SceneGraph::BaseNode::HideSubtree );
    visible_ = false;
    
    emit visibilityChanged( id() );
  }
Jan Möbius's avatar
 
Jan Möbius committed
203 204
}

205 206 207 208 209 210
bool BaseObjectData::visible(){
  return visible_;
}

void BaseObjectData::visible(bool _visible) {

211 212 213 214 215 216
  if ( visible_ != _visible ) {
    
    if (_visible)
      separatorNode_->set_status( ACG::SceneGraph::BaseNode::Active  );
    else
      separatorNode_->set_status( ACG::SceneGraph::BaseNode::HideSubtree );
217

218 219 220 221
    visible_ = _visible;
    
    emit visibilityChanged( id() );
  }
222 223
}

Jan Möbius's avatar
 
Jan Möbius committed
224
SeparatorNode* BaseObjectData::baseNode() {
225
  return separatorNode_;
Jan Möbius's avatar
 
Jan Möbius committed
226 227
}

228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
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
250 251 252 253
BaseNode* BaseObjectData::primaryNode() {
  return separatorNode_;
}

254
QtTranslationManipulatorNode* BaseObjectData::manipulatorNode() {
255 256 257 258 259
  return manipulatorNode_;
}

ACG::SceneGraph::ShaderNode* BaseObjectData::shaderNode() {
  return 0;
Jan Möbius's avatar
 
Jan Möbius committed
260 261 262
}

MaterialNode* BaseObjectData::materialNode() {
263
  return materialNode_;
Jan Möbius's avatar
 
Jan Möbius committed
264 265
}

266 267 268 269
BoundingBoxNode* BaseObjectData::boundingBoxNode() {
  return boundingBoxNode_;
}

270 271 272 273
StencilRefNode* BaseObjectData::stencilRefNode() {
  return stencilRefNode_;
}

Jan Möbius's avatar
 
Jan Möbius committed
274 275 276 277 278 279 280 281
bool BaseObjectData::manipPlaced() {
  return manipPlaced_;
}

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

282 283
void BaseObjectData::getBoundingBox(ACG::Vec3d& bbmin, ACG::Vec3d& bbmax){

284
  // Single pass action, as the bounding box is not influenced by multipass traversal
285 286 287 288 289 290 291 292
  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
293
void BaseObjectData::setObjectDrawMode(const ACG::SceneGraph::DrawModes::DrawMode& _mode, const bool& _force) {
294 295
    
  // Set draw mode for this object
296
  ACG::SceneGraph::SetDrawModesAction actionActive(_mode, _force);
297 298 299 300 301
  
  // Traverse scenegraph in order to set new draw mode
  ACG::SceneGraph::traverse(primaryNode(), actionActive);
}

Jan Möbius's avatar
 
Jan Möbius committed
302
// ===============================================================================
303
// Picking
Jan Möbius's avatar
 
Jan Möbius committed
304 305 306
// ===============================================================================

bool BaseObjectData::picked( uint /* _node_idx */ ) {
307
 return false;
Jan Möbius's avatar
 
Jan Möbius committed
308 309
}

310 311 312 313 314 315 316
void BaseObjectData::enablePicking( bool /*_enable*/ ) {
}

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

Jan Möbius's avatar
 
Jan Möbius committed
317 318 319
// ===============================================================================
// Content Nodes
// ===============================================================================
320
void BaseObjectData::update(UpdateType _type )
Jan Möbius's avatar
 
Jan Möbius committed
321 322 323 324 325 326 327 328 329 330 331 332 333
{

}

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

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

Jan Möbius's avatar
 
Jan Möbius committed
335 336 337 338
  for ( uint i =0 ; i < additionalNodes_.size() ; ++i ) {
    if (additionalNodes_[i].second == searchname )
      return true;
  }
339

Jan Möbius's avatar
 
Jan Möbius committed
340 341 342
  return false;
}

343

Jan Möbius's avatar
 
Jan Möbius committed
344
//=============================================================================
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364

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