Developer Documentation
SplatCloudObject.cc
1/*===========================================================================*\
2* *
3* OpenFlipper *
4 * Copyright (c) 2001-2015, RWTH-Aachen University *
5 * Department of Computer Graphics and Multimedia *
6 * All rights reserved. *
7 * www.openflipper.org *
8 * *
9 *---------------------------------------------------------------------------*
10 * This file is part of OpenFlipper. *
11 *---------------------------------------------------------------------------*
12 * *
13 * Redistribution and use in source and binary forms, with or without *
14 * modification, are permitted provided that the following conditions *
15 * are met: *
16 * *
17 * 1. Redistributions of source code must retain the above copyright notice, *
18 * this list of conditions and the following disclaimer. *
19 * *
20 * 2. Redistributions in binary form must reproduce the above copyright *
21 * notice, this list of conditions and the following disclaimer in the *
22 * documentation and/or other materials provided with the distribution. *
23 * *
24 * 3. Neither the name of the copyright holder nor the names of its *
25 * contributors may be used to endorse or promote products derived from *
26 * this software without specific prior written permission. *
27 * *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS *
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
30 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
31 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER *
32 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
33 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, *
34 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR *
35 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF *
36 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING *
37 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS *
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
39* *
40\*===========================================================================*/
41
42
43
44//================================================================
45//
46// SplatCloudObject
47//
48//================================================================
49
50
51#define SPLATCLOUDOBJECT_C
52
53
54//== INCLUDES ====================================================
55
56
57#include "SplatCloud.hh"
60
61#include <ACG/Scenegraph/ShaderNode.hh>
62#include <ACG/Scenegraph/MaterialNode.hh>
63
64//== DEFINES =====================================================
65
66
67//#define REPORT_UPDATE_TYPE
68
69
70//== IMPLEMENTATION ==============================================
71
72
81backfaceCullingEnabled_( false ),
82pointsizeScale_ ( 1.0f ),
83shaderNode_ ( 0 ),
84splatCloudNode_ ( 0 )
85{
86 // allocate memory for splat cloud
88 if( !splatCloud_ )
89 {
90 std::cerr << "SplatCloudObject::SplatCloudObject() : Out of memory." << std::endl;
91 }
92
94 setTypeIcon( DATA_SPLATCLOUD, "SplatCloudType.png" );
95 init();
96}
97
98
99//----------------------------------------------------------------
100
101
106{
107 init( _object.splatCloud_ );
108 setName( name() );
109}
110
111
112//----------------------------------------------------------------
113
114
119{
120 // Delete the data attached to this object ( this will remove all perObject data)
121 // Not the best way to do it but it will work.
122 // This is only necessary if people use references to the SplatCloud below and
123 // they do something with the SplatCloud in the destructor of their
124 // perObjectData.
125 deleteData();
126
127 // No need to delete the scenegraph Nodes as this will be managed by baseplugin
128 shaderNode_ = 0;
129 splatCloudNode_ = 0;
130
131 // free memory of splat cloud
132 delete splatCloud_;
133 splatCloud_ = 0;
134}
135
136
137//----------------------------------------------------------------
138
139
144{
146
147 shaderNode_ = 0;
148 splatCloudNode_ = 0;
149
150 init();
151}
152
153
154//----------------------------------------------------------------
155
156
161{
162 SplatCloudObject *object = new SplatCloudObject( *this );
163 return dynamic_cast<BaseObject *>( object );
164}
165
166
167//----------------------------------------------------------------
168
169
174{
175 // standard shader filenames
176 static const char SPLATS_VERTEXSHADER_FILENAME[] = "SplatCloud_Splats/Vertex.glsl";
177 static const char SPLATS_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Splats/Fragment.glsl";
178 static const char DOTS_VERTEXSHADER_FILENAME[] = "SplatCloud_Dots/Vertex.glsl";
179 static const char DOTS_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Dots/Fragment.glsl";
180 static const char POINTS_VERTEXSHADER_FILENAME[] = "SplatCloud_Points/Vertex.glsl";
181 static const char POINTS_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Points/Fragment.glsl";
182
183 // picking shader filenames
184 static const char SPLATS_PICK_VERTEXSHADER_FILENAME[] = "SplatCloud_Splats/PickVertex.glsl";
185 static const char SPLATS_PICK_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Splats/Fragment.glsl";
186 static const char DOTS_PICK_VERTEXSHADER_FILENAME[] = "SplatCloud_Dots/PickVertex.glsl";
187 static const char DOTS_PICK_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Dots/Fragment.glsl";
188 static const char POINTS_PICK_VERTEXSHADER_FILENAME[] = "SplatCloud_Points/PickVertex.glsl";
189 static const char POINTS_PICK_FRAGMENTSHADER_FILENAME[] = "SplatCloud_Points/Fragment.glsl";
190
191 // get drawmodes
195
196 // if drawmodes don't exist something went wrong
197 if( splatsDrawMode == ACG::SceneGraph::DrawModes::NONE ||
198 dotsDrawMode == ACG::SceneGraph::DrawModes::NONE ||
199 pointsDrawMode == ACG::SceneGraph::DrawModes::NONE )
200 {
201 std::cerr << "Shader DrawModes for SplatCloud not existent!" << std::endl;
202 return;
203 }
204
205 // get shader directory
206 QString shaderDir = OpenFlipper::Options::shaderDirStr() + OpenFlipper::Options::dirSeparator();
207 std::string shaderDirectory = std::string( shaderDir.toUtf8() );
208
209 // set shader directory
210 shaderNode_->setShaderDir( shaderDirectory );
211
212 // load shaders
213
214 if( QFile( shaderDir + SPLATS_VERTEXSHADER_FILENAME ).exists() &&
215 QFile( shaderDir + SPLATS_PICK_VERTEXSHADER_FILENAME ).exists() &&
216 QFile( shaderDir + SPLATS_FRAGMENTSHADER_FILENAME ).exists() &&
217 QFile( shaderDir + SPLATS_PICK_FRAGMENTSHADER_FILENAME ).exists() )
218 {
219 shaderNode_->setShader( splatsDrawMode,
220 SPLATS_VERTEXSHADER_FILENAME, SPLATS_FRAGMENTSHADER_FILENAME,
221 SPLATS_PICK_VERTEXSHADER_FILENAME, SPLATS_PICK_FRAGMENTSHADER_FILENAME );
222 }
223 else
224 {
225 std::cerr << "Shader Files for SplatCloud/Splats not found!" << std::endl;
226 }
227
228 if( QFile( shaderDir + DOTS_VERTEXSHADER_FILENAME ).exists() &&
229 QFile( shaderDir + DOTS_PICK_VERTEXSHADER_FILENAME ).exists() &&
230 QFile( shaderDir + DOTS_FRAGMENTSHADER_FILENAME ).exists() &&
231 QFile( shaderDir + DOTS_PICK_FRAGMENTSHADER_FILENAME ).exists() )
232 {
233 shaderNode_->setShader( dotsDrawMode,
234 DOTS_VERTEXSHADER_FILENAME, DOTS_FRAGMENTSHADER_FILENAME,
235 DOTS_PICK_VERTEXSHADER_FILENAME, DOTS_PICK_FRAGMENTSHADER_FILENAME );
236 }
237 else
238 {
239 std::cerr << "Shader Files for SplatCloud/Dots not found!" << std::endl;
240 }
241
242 if( QFile( shaderDir + POINTS_VERTEXSHADER_FILENAME ).exists() &&
243 QFile( shaderDir + POINTS_PICK_VERTEXSHADER_FILENAME ).exists() &&
244 QFile( shaderDir + POINTS_FRAGMENTSHADER_FILENAME ).exists() &&
245 QFile( shaderDir + POINTS_PICK_FRAGMENTSHADER_FILENAME ).exists() )
246 {
247 shaderNode_->setShader( pointsDrawMode,
248 POINTS_VERTEXSHADER_FILENAME, POINTS_FRAGMENTSHADER_FILENAME,
249 POINTS_PICK_VERTEXSHADER_FILENAME, POINTS_PICK_FRAGMENTSHADER_FILENAME );
250 }
251 else
252 {
253 std::cerr << "Shader Files for SplatCloud/Points not found!" << std::endl;
254 }
255}
256
257
258//----------------------------------------------------------------
259
260
265{
266 splatCloudNode_->setBackfaceCulling(_enable);
267
268 // get drawmodes
272
273 // if drawmodes don't exist something went wrong
274 if( splatsDrawMode == ACG::SceneGraph::DrawModes::NONE ||
275 dotsDrawMode == ACG::SceneGraph::DrawModes::NONE ||
276 pointsDrawMode == ACG::SceneGraph::DrawModes::NONE )
277 {
278 std::cerr << "Shader DrawModes for SplatCloud not existent!" << std::endl;
279 return;
280 }
281
282 // get standard and picking shaders
283 GLSL::PtrProgram splatsShader = shaderNode_->getShader( splatsDrawMode, false );
284 GLSL::PtrProgram splatsPickShader = shaderNode_->getShader( splatsDrawMode, true );
285 GLSL::PtrProgram dotsShader = shaderNode_->getShader( dotsDrawMode, false );
286 GLSL::PtrProgram dotsPickShader = shaderNode_->getShader( dotsDrawMode, true );
287 GLSL::PtrProgram pointsShader = shaderNode_->getShader( pointsDrawMode, false );
288 GLSL::PtrProgram pointsPickShader = shaderNode_->getShader( pointsDrawMode, true );
289
290 // update backface-culling uniform of shaders
291
292 backfaceCullingEnabled_ = _enable;
293 GLint backfaceCulling = (GLint) _enable;
294
295 if( splatsShader )
296 {
297 splatsShader->use();
298 splatsShader->setUniform( "backfaceCulling", backfaceCulling );
299 splatsShader->disable();
300 }
301
302 if( splatsPickShader )
303 {
304 splatsPickShader->use();
305 splatsPickShader->setUniform( "backfaceCulling", backfaceCulling );
306 splatsPickShader->disable();
307 }
308
309 if( dotsShader )
310 {
311 dotsShader->use();
312 dotsShader->setUniform( "backfaceCulling", backfaceCulling );
313 dotsShader->disable();
314 }
315
316 if( dotsPickShader )
317 {
318 dotsPickShader->use();
319 dotsPickShader->setUniform( "backfaceCulling", backfaceCulling );
320 dotsPickShader->disable();
321 }
322
323 if( pointsShader )
324 {
325 pointsShader->use();
326 pointsShader->setUniform( "backfaceCulling", backfaceCulling );
327 pointsShader->disable();
328 }
329
330 if( pointsPickShader )
331 {
332 pointsPickShader->use();
333 pointsPickShader->setUniform( "backfaceCulling", backfaceCulling );
334 pointsPickShader->disable();
335 }
336}
337
338
339//----------------------------------------------------------------
340
346{
347 splatCloudNode_->setGeometryShaderQuads(_enable);
348}
349
350
351//----------------------------------------------------------------
352
353
358{
359 splatCloudNode_->setPointsizeScale(_scale);
360
361 // get drawmodes
364
365 // if drawmodes don't exist something went wrong
366 if( splatsDrawMode == ACG::SceneGraph::DrawModes::NONE ||
367 dotsDrawMode == ACG::SceneGraph::DrawModes::NONE )
368 {
369 std::cerr << "Shader DrawModes for SplatCloud not existent!" << std::endl;
370 return;
371 }
372
373 // get standard and picking shaders
374 GLSL::PtrProgram splatsShader = shaderNode_->getShader( splatsDrawMode, false );
375 GLSL::PtrProgram splatsPickShader = shaderNode_->getShader( splatsDrawMode, true );
376 GLSL::PtrProgram dotsShader = shaderNode_->getShader( dotsDrawMode, false );
377 GLSL::PtrProgram dotsPickShader = shaderNode_->getShader( dotsDrawMode, true );
378
379 // update pointsize-scale uniform of shaders
380
381 pointsizeScale_ = _scale;
382 GLfloat pointsizeScale = (GLfloat) _scale;
383
384 if( splatsShader )
385 {
386 splatsShader->use();
387 splatsShader->setUniform( "pointsizeScale", pointsizeScale );
388 splatsShader->disable();
389 }
390
391 if( splatsPickShader )
392 {
393 splatsPickShader->use();
394 splatsPickShader->setUniform( "pointsizeScale", pointsizeScale );
395 splatsPickShader->disable();
396 }
397
398 if( dotsShader )
399 {
400 dotsShader->use();
401 dotsShader->setUniform( "pointsizeScale", pointsizeScale );
402 dotsShader->disable();
403 }
404
405 if( dotsPickShader )
406 {
407 dotsPickShader->use();
408 dotsPickShader->setUniform( "pointsizeScale", pointsizeScale );
409 dotsPickShader->disable();
410 }
411}
412
413
414//----------------------------------------------------------------
415
416
419void SplatCloudObject::init( const SplatCloud *_splatCloud )
420{
421 if( materialNode() == NULL )
422 std::cerr << "Error when creating SplatCloud Object! materialNode is NULL!" << std::endl;
423
424 // if _splatCloud is *not* 0, copy it's contents
425 if( _splatCloud )
426 {
427 delete splatCloud_;
428
429 splatCloud_ = new SplatCloud( *_splatCloud );
430 if( !splatCloud_ )
431 {
432 std::cerr << "SplatCloudObject::init() : Out of memory." << std::endl;
433 }
434 }
435
436 // if something went wrong during initialization, abort
437 if( !splatCloud_ )
438 {
439 shaderNode_ = 0;
440 splatCloudNode_ = 0;
441 return;
442 }
443
444 // create new scenegraph nodes
445 shaderNode_ = new ShaderNode ( materialNode(), "NEW ShaderNode for" );
446 splatCloudNode_ = new SplatCloudNode( *splatCloud_, shaderNode_, "NEW SplatCloudNode" );
447
448 // load shaders
450}
451
452
453//----------------------------------------------------------------
454
455
460{
461 if( _type == UPDATE_ALL )
462 {
463# ifdef REPORT_UPDATE_TYPE
464 std::cout << "SplatCloudObject::update() : UPDATE_ALL" << std::endl;
465 std::cout << std::endl;
466# endif
467
468 if( splatCloudNode_ )
469 splatCloudNode_->modifiedAll();
470 return;
471 }
472
473 if( _type.contains( UPDATE_GEOMETRY ) )
474 {
475# ifdef REPORT_UPDATE_TYPE
476 std::cout << "SplatCloudObject::update() : UPDATE_GEOMETRY" << std::endl;
477# endif
478
479 if( splatCloudNode_ )
480 splatCloudNode_->modifiedPositions();
481 }
482
483 if( _type.contains( UPDATE_COLOR ) )
484 {
485# ifdef REPORT_UPDATE_TYPE
486 std::cout << "SplatCloudObject::update() : UPDATE_COLOR" << std::endl;
487# endif
488
489 if( splatCloudNode_ )
490 splatCloudNode_->modifiedColors();
491 }
492
493 if( _type.contains( updateType("Normals") ) )
494 {
495# ifdef REPORT_UPDATE_TYPE
496 std::cout << "SplatCloudObject::update() : UPDATE_Normals" << std::endl;
497# endif
498
499 if( splatCloudNode_ )
500 splatCloudNode_->modifiedNormals();
501 }
502
503 if( _type.contains( updateType("Pointsizes") ) )
504 {
505# ifdef REPORT_UPDATE_TYPE
506 std::cout << "SplatCloudObject::update() : UPDATE_Pointsizes" << std::endl;
507# endif
508
509 if( splatCloudNode_ )
510 splatCloudNode_->modifiedPointsizes();
511 }
512
513 if( _type.contains( updateType("Indices") ) )
514 {
515# ifdef REPORT_UPDATE_TYPE
516 std::cout << "SplatCloudObject::update() : UPDATE_Indices" << std::endl;
517# endif
518 }
519
520 if( _type.contains( UPDATE_SELECTION ) )
521 {
522# ifdef REPORT_UPDATE_TYPE
523 std::cout << "SplatCloudObject::update() : UPDATE_SELECTION" << std::endl;
524# endif
525
526 if( splatCloudNode_ )
527 splatCloudNode_->modifiedSelections();
528 }
529
530# ifdef REPORT_UPDATE_TYPE
531 std::cout << std::endl;
532# endif
533}
534
535
536//----------------------------------------------------------------
537// Name/Path Handling
538//----------------------------------------------------------------
539
540
544void SplatCloudObject::setName( QString _name )
545{
547
548 std::string nodename;
549
550 nodename = std::string( "ShaderNode for SplatCloud " + _name.toUtf8() );
551 shaderNode_->name( nodename );
552
553 nodename = std::string( "SplatCloudNode for SplatCloud " + _name.toUtf8() );
554 splatCloudNode_->name( nodename );
555}
556
557
558//----------------------------------------------------------------
559// Object information
560//----------------------------------------------------------------
561
562
569{
570 QString output;
571
572 output += "========================================================================\n";
574
576 {
577 output += "Object Contains SplatCloud: ";
578
579 if( splatCloud_ )
580 {
581 output += " #Splats: " + QString::number( splatCloud_->numSplats() );
582
583 output += "; Splat-Properties: ";
584 if( splatCloud_->splatProperties().empty() )
585 {
586 output += "-none-";
587 }
588 else
589 {
590 SplatCloud::SplatPropertyMap::const_iterator splatPropertyIter = splatCloud_->splatProperties().begin();
591 while( true )
592 {
593 output += splatPropertyIter->first.c_str();
594
595 if( ++splatPropertyIter == splatCloud_->splatProperties().end() )
596 break;
597
598 output += ", ";
599 }
600 }
601
602 output += "; Cloud-Properties: ";
603 if( splatCloud_->cloudProperties().empty() )
604 {
605 output += "-none-";
606 }
607 else
608 {
609 SplatCloud::CloudPropertyMap::const_iterator cloudPropertyIter = splatCloud_->cloudProperties().begin();
610 while( true )
611 {
612 output += cloudPropertyIter->first.c_str();
613
614 if( ++cloudPropertyIter == splatCloud_->cloudProperties().end() )
615 break;
616
617 output += ", ";
618 }
619 }
620 }
621
622 output += "\n";
623 }
624
625 output += "========================================================================\n";
626 return output;
627}
628
629
630//----------------------------------------------------------------
631// Picking
632//----------------------------------------------------------------
633
634
641bool SplatCloudObject::picked( uint _node_idx )
642{
643 return ( _node_idx == splatCloudNode_->id() );
644}
645
646
647//----------------------------------------------------------------
648
649
651{
652 splatCloudNode_->enablePicking( _enable );
653 shaderNode_->enablePicking( _enable );
654}
655
656
657//----------------------------------------------------------------
658
659
661{
663}
DLLEXPORT void setTypeIcon(DataType _id, const QString &_icon)
Set an Icon for a given DataType.
Definition: Types.cc:223
ACG::SceneGraph::SplatCloudNode SplatCloudNode
Simple Name for SplatCloudNode.
ACG::SceneGraph::ShaderNode ShaderNode
Simple Name for ShaderNode.
#define DATA_SPLATCLOUD
Definition: SplatCloud.hh:59
void enablePicking(bool _enable)
Definition: BaseNode.hh:265
unsigned int id() const
Definition: BaseNode.hh:423
std::string name() const
Returns: name of node (needs not be unique)
Definition: BaseNode.hh:415
void setShaderDir(std::string _shaderDir)
Sets the shader dir.
Definition: ShaderNode.cc:392
GLSL::PtrProgram getShader(DrawModes::DrawMode _drawmode, bool _pick=false)
Get the shader for the given drawMode.
Definition: ShaderNode.cc:222
void setShader(DrawModes::DrawMode _drawmode, const std::string &_vertexShader, const std::string &_fragmentShader, std::string _pickVertexShader="", std::string _pickFragmentShader="")
Definition: ShaderNode.cc:291
virtual void setName(QString _name) override
path to the file from which the object is loaded ( defaults to "." )
MaterialNode * materialNode()
get a pointer to the materialnode
virtual void cleanup() override
virtual QString getObjectinfo()
Get all Info for the Object as a string.
Definition: BaseObject.cc:242
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:728
void setDataType(DataType _type)
Definition: BaseObject.cc:231
void deleteData()
Delete all data attached to this object ( calls delete on each object )
Definition: BaseObject.cc:810
DataType dataType() const
Definition: BaseObject.cc:227
GLSL program class.
Definition: GLSLShader.hh:211
void disable()
Resets to standard rendering pipeline.
Definition: GLSLShader.cc:355
void use()
Enables the program object for using.
Definition: GLSLShader.cc:345
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: GLSLShader.cc:385
virtual ~SplatCloudObject()
Destructor.
void enableGeometryShaderQuads(bool _enable)
Enable or disable quad extrusion in geometry shader (shader pipeline)
void setName(QString _name)
Set the name of the Object.
ShaderNode * shaderNode_
Get Shader's scenegraph Node.
SplatCloudObject()
Constructor.
void enableBackfaceCulling(bool _enable)
Enable or disable backface culling for all Shaders.
void setPointsizeScale(float _scale)
Set the scaling factor for pointsizes for all Shaders.
bool picked(uint _node_idx)
Detect if the node has been picked.
virtual void init(const SplatCloud *_splatCloud=0)
Initialise current Object, including all related Nodes.
BaseObject * copy()
QString getObjectinfo()
Get all Info for the Object as a string.
SplatCloudNode * splatCloudNode_
Get Shader's scenegraph Node.
bool pickingEnabled()
Check if picking is enabled for this Object.
virtual void cleanup()
Reset current Object, including all related Nodes.
void enablePicking(bool _enable)
Enable or disable picking for this Object.
SplatCloud * splatCloud_
Get SplatCloud.
void reloadShaders()
Reload standard and picking Shaders from file.
void update(UpdateType _type=UPDATE_ALL)
Called by the core if the object has to be updated.
const CloudPropertyMap & cloudProperties() const
Get all cloud-properties.
Definition: SplatCloud.hh:457
unsigned int numSplats() const
Get the number of splats.
Definition: SplatCloud.hh:179
const SplatPropertyMap & splatProperties() const
Get all splat-properties.
Definition: SplatCloud.hh:447
Update type class.
Definition: UpdateType.hh:59
bool contains(const UpdateType &_type) const
Check if this update contains the given UpdateType.
Definition: UpdateType.cc:99
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
const UpdateType UPDATE_GEOMETRY(UpdateTypeSet(4))
Geometry updated.
const UpdateType UPDATE_COLOR(UpdateTypeSet(1024))
Colors have changed.
const UpdateType UPDATE_SELECTION(UpdateTypeSet(16))
Selection updated.
UpdateType updateType(QString _name)
Get the id of a type with given name.
Definition: UpdateType.cc:255
const DrawMode & getDrawMode(const std::string &_name)
Get a custom DrawMode.
Definition: DrawModes.cc:797
DrawMode NONE
not a valid draw mode
Definition: DrawModes.cc:71