/*===========================================================================*\ * * * 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 . * * * \*===========================================================================*/ /*===========================================================================*\ * * * $Revision$ * * $LastChangedBy$ * * $Date$ * * * \*===========================================================================*/ //================================================================ // // SplatCloudObject // //================================================================ #define SPLATCLOUDOBJECT_C //== INCLUDES ==================================================== #include "SplatCloud.hh" #include #include #include #include #include //== DEFINES ===================================================== //#define REPORT_UPDATE_TYPE //== IMPLEMENTATION ============================================== /** Constructor for SplatCloud Objects. This object class gets a Separator Node giving * the root node to which it should be connected. The SplatCloud is generated internally * and all nodes for visualization will be added below the scenegraph node.\n * You dont need to create an object of this type manually. Use * PluginFunctions::addSplatCloud instead. ( see Types.hh::DataType ) */ SplatCloudObject::SplatCloudObject() : BaseObjectData ( ), backfaceCullingEnabled_( false ), pointsizeScale_ ( 1.0f ), shaderNode_ ( 0 ), splatCloudNode_ ( 0 ) { // allocate memory for splat cloud splatCloud_ = new SplatCloud; if( !splatCloud_ ) { std::cerr << "SplatCloudObject::SplatCloudObject() : Out of memory." << std::endl; } setDataType( DATA_SPLATCLOUD ); setTypeIcon( DATA_SPLATCLOUD, "SplatCloudType.png" ); init(); } //---------------------------------------------------------------- /** * Copy Constructor - generates a copy of the given object */ SplatCloudObject::SplatCloudObject( const SplatCloudObject &_object ) : BaseObjectData( _object ) { init( _object.splatCloud_ ); setName( name() ); } //---------------------------------------------------------------- /** Destructor for SplatCloud Objects. The destructor deletes the Line and all * Scenegraph nodes associated with the SplatCloud or the object. */ SplatCloudObject::~SplatCloudObject() { // Delete the data attached to this object ( this will remove all perObject data) // Not the best way to do it but it will work. // This is only necessary if people use references to the SplatCloud below and // they do something with the SplatCloud in the destructor of their // perObjectData. deleteData(); // No need to delete the scenegraph Nodes as this will be managed by baseplugin shaderNode_ = 0; splatCloudNode_ = 0; // free memory of splat cloud delete splatCloud_; splatCloud_ = 0; } //---------------------------------------------------------------- /** Cleanup Function for SplatCloud Objects. Deletes the contents of the whole object and * calls SplatCloudObject::init afterwards. */ void SplatCloudObject::cleanup() { BaseObjectData::cleanup(); shaderNode_ = 0; splatCloudNode_ = 0; init(); } //---------------------------------------------------------------- /** * Generate a copy */ BaseObject *SplatCloudObject::copy() { SplatCloudObject *object = new SplatCloudObject( *this ); return dynamic_cast( object ); } //---------------------------------------------------------------- /** * Reload shaders from file */ void SplatCloudObject::reloadShaders() { // standard shader filenames static const char SPLATS_VERTEXSHADER_FILENAME[] = "SplatCloud_Splats/Vertex.glsl"; static const char SPLATS_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Splats/Fragment.glsl"; static const char DOTS_VERTEXSHADER_FILENAME[] = "SplatCloud_Dots/Vertex.glsl"; static const char DOTS_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Dots/Fragment.glsl"; static const char POINTS_VERTEXSHADER_FILENAME[] = "SplatCloud_Points/Vertex.glsl"; static const char POINTS_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Points/Fragment.glsl"; // picking shader filenames static const char SPLATS_PICK_VERTEXSHADER_FILENAME[] = "SplatCloud_Splats/PickVertex.glsl"; static const char SPLATS_PICK_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Splats/Fragment.glsl"; static const char DOTS_PICK_VERTEXSHADER_FILENAME[] = "SplatCloud_Dots/PickVertex.glsl"; static const char DOTS_PICK_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Dots/Fragment.glsl"; static const char POINTS_PICK_VERTEXSHADER_FILENAME[] = "SplatCloud_Points/PickVertex.glsl"; static const char POINTS_PICK_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Points/Fragment.glsl"; // get drawmodes ACG::SceneGraph::DrawModes::DrawMode splatsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Splats" ); ACG::SceneGraph::DrawModes::DrawMode dotsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Dots" ); ACG::SceneGraph::DrawModes::DrawMode pointsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Points" ); // if drawmodes don't exist something went wrong if( splatsDrawMode == ACG::SceneGraph::DrawModes::NONE || dotsDrawMode == ACG::SceneGraph::DrawModes::NONE || pointsDrawMode == ACG::SceneGraph::DrawModes::NONE ) { std::cerr << "Shader DrawModes for SplatCloud not existent!" << std::endl; return; } // get shader directory QString shaderDir = OpenFlipper::Options::shaderDirStr() + OpenFlipper::Options::dirSeparator(); std::string shaderDirectory = std::string( shaderDir.toUtf8() ); // set shader directory shaderNode_->setShaderDir( shaderDirectory ); // load shaders if( QFile( shaderDir + SPLATS_VERTEXSHADER_FILENAME ).exists() && QFile( shaderDir + SPLATS_PICK_VERTEXSHADER_FILENAME ).exists() && QFile( shaderDir + SPLATS_FRAGMENTSHADER_FILENAME ).exists() && QFile( shaderDir + SPLATS_PICK_FRAGMENTSHADER_FILENAME ).exists() ) { shaderNode_->setShader( splatsDrawMode, SPLATS_VERTEXSHADER_FILENAME, SPLATS_FRAGMENTSHADER_FILENAME, SPLATS_PICK_VERTEXSHADER_FILENAME, SPLATS_PICK_FRAGMENTSHADER_FILENAME ); } else { std::cerr << "Shader Files for SplatCloud/Splats not found!" << std::endl; } if( QFile( shaderDir + DOTS_VERTEXSHADER_FILENAME ).exists() && QFile( shaderDir + DOTS_PICK_VERTEXSHADER_FILENAME ).exists() && QFile( shaderDir + DOTS_FRAGMENTSHADER_FILENAME ).exists() && QFile( shaderDir + DOTS_PICK_FRAGMENTSHADER_FILENAME ).exists() ) { shaderNode_->setShader( dotsDrawMode, DOTS_VERTEXSHADER_FILENAME, DOTS_FRAGMENTSHADER_FILENAME, DOTS_PICK_VERTEXSHADER_FILENAME, DOTS_PICK_FRAGMENTSHADER_FILENAME ); } else { std::cerr << "Shader Files for SplatCloud/Dots not found!" << std::endl; } if( QFile( shaderDir + POINTS_VERTEXSHADER_FILENAME ).exists() && QFile( shaderDir + POINTS_PICK_VERTEXSHADER_FILENAME ).exists() && QFile( shaderDir + POINTS_FRAGMENTSHADER_FILENAME ).exists() && QFile( shaderDir + POINTS_PICK_FRAGMENTSHADER_FILENAME ).exists() ) { shaderNode_->setShader( pointsDrawMode, POINTS_VERTEXSHADER_FILENAME, POINTS_FRAGMENTSHADER_FILENAME, POINTS_PICK_VERTEXSHADER_FILENAME, POINTS_PICK_FRAGMENTSHADER_FILENAME ); } else { std::cerr << "Shader Files for SplatCloud/Points not found!" << std::endl; } } //---------------------------------------------------------------- /** * Enable or disable backface culling */ void SplatCloudObject::enableBackfaceCulling( bool _enable ) { // get drawmodes ACG::SceneGraph::DrawModes::DrawMode splatsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Splats" ); ACG::SceneGraph::DrawModes::DrawMode dotsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Dots" ); ACG::SceneGraph::DrawModes::DrawMode pointsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Points" ); // if drawmodes don't exist something went wrong if( splatsDrawMode == ACG::SceneGraph::DrawModes::NONE || dotsDrawMode == ACG::SceneGraph::DrawModes::NONE || pointsDrawMode == ACG::SceneGraph::DrawModes::NONE ) { std::cerr << "Shader DrawModes for SplatCloud not existent!" << std::endl; return; } // get standard and picking shaders GLSL::PtrProgram splatsShader = shaderNode_->getShader( splatsDrawMode, false ); GLSL::PtrProgram splatsPickShader = shaderNode_->getShader( splatsDrawMode, true ); GLSL::PtrProgram dotsShader = shaderNode_->getShader( dotsDrawMode, false ); GLSL::PtrProgram dotsPickShader = shaderNode_->getShader( dotsDrawMode, true ); GLSL::PtrProgram pointsShader = shaderNode_->getShader( pointsDrawMode, false ); GLSL::PtrProgram pointsPickShader = shaderNode_->getShader( pointsDrawMode, true ); // update backface-culling uniform of shaders backfaceCullingEnabled_ = _enable; GLint backfaceCulling = (GLint) _enable; if( splatsShader ) { splatsShader->use(); splatsShader->setUniform( "backfaceCulling", backfaceCulling ); splatsShader->disable(); } if( splatsPickShader ) { splatsPickShader->use(); splatsPickShader->setUniform( "backfaceCulling", backfaceCulling ); splatsPickShader->disable(); } if( dotsShader ) { dotsShader->use(); dotsShader->setUniform( "backfaceCulling", backfaceCulling ); dotsShader->disable(); } if( dotsPickShader ) { dotsPickShader->use(); dotsPickShader->setUniform( "backfaceCulling", backfaceCulling ); dotsPickShader->disable(); } if( pointsShader ) { pointsShader->use(); pointsShader->setUniform( "backfaceCulling", backfaceCulling ); pointsShader->disable(); } if( pointsPickShader ) { pointsPickShader->use(); pointsPickShader->setUniform( "backfaceCulling", backfaceCulling ); pointsPickShader->disable(); } } //---------------------------------------------------------------- /** * Set scale for point sizes */ void SplatCloudObject::setPointsizeScale( float _scale ) { // get drawmodes ACG::SceneGraph::DrawModes::DrawMode splatsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Splats" ); ACG::SceneGraph::DrawModes::DrawMode dotsDrawMode = ACG::SceneGraph::DrawModes::getDrawMode( "Dots" ); // if drawmodes don't exist something went wrong if( splatsDrawMode == ACG::SceneGraph::DrawModes::NONE || dotsDrawMode == ACG::SceneGraph::DrawModes::NONE ) { std::cerr << "Shader DrawModes for SplatCloud not existent!" << std::endl; return; } // get standard and picking shaders GLSL::PtrProgram splatsShader = shaderNode_->getShader( splatsDrawMode, false ); GLSL::PtrProgram splatsPickShader = shaderNode_->getShader( splatsDrawMode, true ); GLSL::PtrProgram dotsShader = shaderNode_->getShader( dotsDrawMode, false ); GLSL::PtrProgram dotsPickShader = shaderNode_->getShader( dotsDrawMode, true ); // update pointsize-scale uniform of shaders pointsizeScale_ = _scale; GLfloat pointsizeScale = (GLfloat) _scale; if( splatsShader ) { splatsShader->use(); splatsShader->setUniform( "pointsizeScale", pointsizeScale ); splatsShader->disable(); } if( splatsPickShader ) { splatsPickShader->use(); splatsPickShader->setUniform( "pointsizeScale", pointsizeScale ); splatsPickShader->disable(); } if( dotsShader ) { dotsShader->use(); dotsShader->setUniform( "pointsizeScale", pointsizeScale ); dotsShader->disable(); } if( dotsPickShader ) { dotsPickShader->use(); dotsPickShader->setUniform( "pointsizeScale", pointsizeScale ); dotsPickShader->disable(); } } //---------------------------------------------------------------- /** This function initalizes the SplatCloud object. It creates the scenegraph nodes. */ void SplatCloudObject::init( const SplatCloud *_splatCloud ) { if( materialNode() == NULL ) std::cerr << "Error when creating SplatCloud Object! materialNode is NULL!" << std::endl; // if _splatCloud is *not* 0, copy it's contents if( _splatCloud ) { delete splatCloud_; splatCloud_ = new SplatCloud( *_splatCloud ); if( !splatCloud_ ) { std::cerr << "SplatCloudObject::init() : Out of memory." << std::endl; } } // if something went wrong during initialization, abort if( !splatCloud_ ) { shaderNode_ = 0; splatCloudNode_ = 0; return; } // create new scenegraph nodes shaderNode_ = new ShaderNode ( materialNode(), "NEW ShaderNode for" ); splatCloudNode_ = new SplatCloudNode( *splatCloud_, shaderNode_, "NEW SplatCloudNode" ); // load shaders reloadShaders(); } //---------------------------------------------------------------- /** * Update object and scenegraph nodes */ void SplatCloudObject::update( UpdateType _type ) { if( _type == UPDATE_ALL ) { # ifdef REPORT_UPDATE_TYPE std::cout << "SplatCloudObject::update() : UPDATE_ALL" << std::endl; std::cout << std::endl; # endif if( splatCloudNode_ ) splatCloudNode_->modifiedAll(); return; } if( _type.contains( UPDATE_GEOMETRY ) ) { # ifdef REPORT_UPDATE_TYPE std::cout << "SplatCloudObject::update() : UPDATE_GEOMETRY" << std::endl; # endif if( splatCloudNode_ ) splatCloudNode_->modifiedPoints(); } if( _type.contains( updateType("Normals") ) ) { # ifdef REPORT_UPDATE_TYPE std::cout << "SplatCloudObject::update() : UPDATE_Normals" << std::endl; # endif if( splatCloudNode_ ) splatCloudNode_->modifiedNormals(); } if( _type.contains( updateType("Pointsizes") ) ) { # ifdef REPORT_UPDATE_TYPE std::cout << "SplatCloudObject::update() : UPDATE_Pointsizes" << std::endl; # endif if( splatCloudNode_ ) splatCloudNode_->modifiedPointsizes(); } if( _type.contains( UPDATE_COLOR ) ) { # ifdef REPORT_UPDATE_TYPE std::cout << "SplatCloudObject::update() : UPDATE_COLOR" << std::endl; # endif if( splatCloudNode_ ) splatCloudNode_->modifiedColors(); } if( _type.contains( UPDATE_SELECTION ) ) { # ifdef REPORT_UPDATE_TYPE std::cout << "SplatCloudObject::update() : UPDATE_SELECTION" << std::endl; # endif if( splatCloudNode_ ) splatCloudNode_->modifiedSelections(); } # ifdef REPORT_UPDATE_TYPE std::cout << std::endl; # endif } //---------------------------------------------------------------- // Name/Path Handling //---------------------------------------------------------------- /** Set the name of an object. All Scenegraph nodes are renamed too. It also calls * BaseObjectData::setName. */ void SplatCloudObject::setName( QString _name ) { BaseObjectData::setName( _name ); std::string nodename; nodename = std::string( "ShaderNode for SplatCloud " + _name.toUtf8() ); shaderNode_->name( nodename ); nodename = std::string( "SplatCloudNode for SplatCloud " + _name.toUtf8() ); splatCloudNode_->name( nodename ); } //---------------------------------------------------------------- // Object information //---------------------------------------------------------------- /** Returns a string containing all information about the current object. This also * includes the information provided by BaseObjectData::getObjectinfo * * @return String containing the object information */ QString SplatCloudObject::getObjectinfo() { QString output; output += "========================================================================\n"; output += BaseObjectData::getObjectinfo(); if( dataType( DATA_SPLATCLOUD ) ) { output += "Object Contains SplatCloud : "; if( splatCloud_ ) { output += " # points: " + QString::number( splatCloud_->numPoints() ); output += ", normals used: "; output += splatCloud_->hasNormals() ? "true" : "false"; output += ", pointsizes used: "; output += splatCloud_->hasPointsizes() ? "true" : "false"; output += ", colors used: "; output += splatCloud_->hasColors() ? "true" : "false"; } output += "\n"; } output += "========================================================================\n"; return output; } //---------------------------------------------------------------- // Picking //---------------------------------------------------------------- /** Given an node index from PluginFunctions::scenegraphPick this function can be used to * check if the splatCloudNode of the object has been picked. * * @param _node_idx Index of the picked splatcloud node * @return bool if the splatCloudNode of this object is the picking target. */ bool SplatCloudObject::picked( uint _node_idx ) { return ( _node_idx == splatCloudNode_->id() ); } //---------------------------------------------------------------- void SplatCloudObject::enablePicking( bool _enable ) { splatCloudNode_->enablePicking( _enable ); shaderNode_->enablePicking( _enable ); } //---------------------------------------------------------------- bool SplatCloudObject::pickingEnabled() { return splatCloudNode_->pickingEnabled(); }