Developer Documentation
TypeSplatCloud.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 // CLASS TypeSplatCloudPlugin - IMPLEMENTATION
47 //
48 //================================================================
49 
50 
51 //== INCLUDES ====================================================
52 
53 
54 #include "TypeSplatCloud.hh"
55 
56 #include <OpenFlipper/common/BackupData.hh>
58 #include "SplatCloudBackup.hh"
59 
60 
61 
62 //== CONSTANTS ===================================================
63 
64 
65 static const char SPLATCLOUD_OBJECT_ID_DATANAME[] = "SplatCloudObjectId";
66 
67 static const double MIN_CLUSTER_BRIGHTNESS = 0.25;
68 
69 
70 //== IMPLEMENTATION ==============================================
71 
72 TypeSplatCloudPlugin::TypeSplatCloudPlugin() {
73 }
74 
75 void TypeSplatCloudPlugin::slotViewChanged()
76 {
77  // if drawmodes don't exist we have no object of this type
78  if( splatsDrawMode_ == ACG::SceneGraph::DrawModes::NONE ||
79  dotsDrawMode_ == ACG::SceneGraph::DrawModes::NONE )
80  {
81  //emit log(LOGERR,tr("Shader DrawModes for SplatCloud not existent!"));
82  return;
83  }
84 
85  // get current glState
87 
88  // get viewport
89  int left, bottom, width, height;
90  glstate.get_viewport( left, bottom, width, height );
91 
92  float x = (float) left;
93  float y = (float) bottom;
94  float w = (float) width;
95  float h = (float) height;
96 
97  // get depthrange
98  // TODO: use glstate.get_depth_range when implemented
99  GLfloat depthRange[2];
100  glGetFloatv( GL_DEPTH_RANGE, depthRange );
101  float z = (float) depthRange[0];
102  float d = (float) depthRange[1] - z;
103 
104  // check if we are safe
105  if( w<=0.0f || h<=0.0f || d<=0.0f )
106  return;
107 
108  // calculate window-coordinates to normalized-device-coordinates scale
109  ACG::Vec4f invVPs;
110  invVPs[0] = 2.0f / w;
111  invVPs[1] = 2.0f / h;
112  invVPs[2] = 2.0f / d;
113  invVPs[3] = 0.0f;
114 
115  // calculate window-coordinates to normalized-device-coordinates transpose
116  ACG::Vec4f invVPt;
117  invVPt[0] = - ( x * invVPs[0] + 1.0f );
118  invVPt[1] = - ( y * invVPs[1] + 1.0f );
119  invVPt[2] = - ( z * invVPs[2] + 1.0f );
120  invVPt[3] = 1.0f;
121 
122  // calculate normalized-device-coordinates to window-coordinates scale and transpose
123  GLfloat VPs_z = 0.5f * d;
124  GLfloat VPt_z = z + VPs_z;
125 
126  // calculate scaling factor of modelview matrix
127  static const double RCP_3 = 1.0 / 3.0;
128  const ACG::GLMatrixd &mv = glstate.modelview();
129  double detMV = mv(0,0) * (mv(1,1)*mv(2,2) - mv(1,2)*mv(2,1))
130  + mv(0,1) * (mv(1,2)*mv(2,0) - mv(1,0)*mv(2,2))
131  + mv(0,2) * (mv(1,0)*mv(2,1) - mv(1,1)*mv(2,0));
132  GLfloat MVs = (GLfloat) pow( fabs( detMV ), RCP_3 );
133 
134  // calculate scale for pointsizes in eye-coordinates according to fovy and transformation to window-coordinates
135  GLfloat VPsFov_y = glstate.projection()(1,1) * (0.5f * h);
136 
137  // for all splatcloud-objects...
139  for( ; objIter != PluginFunctions::objectsEnd(); ++objIter )
140  {
141  // get scenegraph shader-node
142  ShaderNode *shaderNode = PluginFunctions::splatShaderNode( *objIter );
143 
144  // get standard shaders and picking shaders
145  GLSL::PtrProgram splatsShader = shaderNode->getShader( splatsDrawMode_, false );
146  GLSL::PtrProgram splatsPickShader = shaderNode->getShader( splatsDrawMode_, true );
147  GLSL::PtrProgram dotsShader = shaderNode->getShader( dotsDrawMode_, false );
148  GLSL::PtrProgram dotsPickShader = shaderNode->getShader( dotsDrawMode_, true );
149 
150  // update shader uniforms concerning viewport and depthrange
151 
152  if( splatsShader )
153  {
154  splatsShader->use();
155  splatsShader->setUniform( "invViewportScale", invVPs );
156  splatsShader->setUniform( "invViewportTransp", invVPt );
157  splatsShader->setUniform( "viewportScale_z", VPs_z );
158  splatsShader->setUniform( "viewportTransp_z", VPt_z );
159  splatsShader->setUniform( "modelviewScale", MVs );
160  splatsShader->setUniform( "viewportScaleFov_y", VPsFov_y );
161  splatsShader->disable();
162  }
163 
164  if( splatsPickShader )
165  {
166  splatsPickShader->use();
167  splatsPickShader->setUniform( "invViewportScale", invVPs );
168  splatsPickShader->setUniform( "invViewportTransp", invVPt );
169  splatsPickShader->setUniform( "viewportScale_z", VPs_z );
170  splatsPickShader->setUniform( "viewportTransp_z", VPt_z );
171  splatsPickShader->setUniform( "modelviewScale", MVs );
172  splatsPickShader->setUniform( "viewportScaleFov_y", VPsFov_y );
173  splatsPickShader->disable();
174  }
175 
176  if( dotsShader )
177  {
178  dotsShader->use();
179  dotsShader->setUniform( "modelviewScale", MVs );
180  dotsShader->setUniform( "viewportScaleFov_y", VPsFov_y );
181  dotsShader->disable();
182  }
183 
184  if( dotsPickShader )
185  {
186  dotsPickShader->use();
187  dotsPickShader->setUniform( "modelviewScale", MVs );
188  dotsPickShader->setUniform( "viewportScaleFov_y", VPsFov_y );
189  dotsPickShader->disable();
190  }
191  }
192 }
193 
194 
195 //----------------------------------------------------------------
196 
197 
198 void TypeSplatCloudPlugin::slotObjectPropertiesChanged( int _objectId )
199 {
200  // get splatcloud-object by id
202  if( PluginFunctions::getObject( _objectId, splatCloudObject ) )
203  {
204  // get parent and check if parent is a group
205  BaseObject *parent = splatCloudObject->parent();
206  if( (parent != 0) && parent->isGroup() )
207  {
208  // update name of group
209  parent->setName( splatCloudObject->name() );
210  }
211  }
212 }
213 
214 
215 //----------------------------------------------------------------
216 
217 
218 void TypeSplatCloudPlugin::slotObjectUpdated( int _objectId, const UpdateType &_updateType )
219 {
220  // get object by id
221  BaseObject *object = 0;
222  if( !PluginFunctions::getObject( _objectId, object ) )
223  return;
224 
225  // check if object is a splatcloud-object
226  SplatCloudObject *splatCloudObject = PluginFunctions::splatCloudObject( static_cast<BaseObjectData *>( object ) ); // TODO: remove cast
227  if( splatCloudObject != 0 )
228  {
229  // check update type
230  if( _updateType.contains( UPDATE_STATE ) )
231  {
232  // add objects
233  addCameraObjects ( splatCloudObject );
234  addClusterObjects( splatCloudObject );
235  }
236  }
237 }
238 
239 
240 //----------------------------------------------------------------
241 
242 
243 void TypeSplatCloudPlugin::objectDeleted( int _objectId )
244 {
245  // get object by id
246  BaseObject *object = 0;
247  if( !PluginFunctions::getObject( _objectId, object ) )
248  return;
249 
250  // check if object is a splatcloud-object
251  SplatCloudObject *splatCloudObject = PluginFunctions::splatCloudObject( static_cast<BaseObjectData *>( object ) ); // TODO: remove cast
252  if( splatCloudObject != 0 )
253  {
254  // free objects
255  freeCameraObjects ( splatCloudObject );
256  freeClusterObjects( splatCloudObject );
257  }
258 
259  // check if object is a camera-object
260  CameraObject *cameraObject = PluginFunctions::cameraObject( static_cast<BaseObjectData *>( object ) ); // TODO: remove cast
261  if( cameraObject != 0 )
262  {
263  // erase camera
264  eraseCamera( cameraObject );
265  }
266 }
267 
268 
269 //----------------------------------------------------------------
270 
271 
272 bool TypeSplatCloudPlugin::registerType()
273 {
274  addDataType( "SplatCloud", tr( "SplatCloud" ) );
275  setTypeIcon( "SplatCloud", "SplatCloudType.png" );
276  return true;
277 }
278 
279 
280 //----------------------------------------------------------------
281 
282 
284 {
285  // Add or get the current draw modes to make sure they exist now
286  splatsDrawMode_ = ACG::SceneGraph::DrawModes::addDrawMode("Splats");
287  dotsDrawMode_ = ACG::SceneGraph::DrawModes::addDrawMode("Dots");
288 
289  // new object data struct
290  SplatCloudObject *object = new SplatCloudObject();
291 
292  if( object == 0 )
293  return -1;
294 
295  if ( OpenFlipperSettings().value("Core/File/AllTarget",false).toBool() )
296  object->target(true);
297  else {
298 
299  // Only the first object in the scene will be target
300  if ( PluginFunctions::objectCount() == 1 )
301  object->target(true);
302 
303  // If no target is available, we set the new object as target
304  if (PluginFunctions::targetCount() == 0 )
305  object->target(true);
306  }
307 
308  QString name = QString(tr("New Splat Cloud %1.spl").arg( object->id() ));
309 
310  // call the local function to update names
311  QFileInfo f( name );
312  object->setName( f.fileName() );
313 
314  // set the default colors
315  const QColor color = OpenFlipper::Options::defaultColor();
316  const ACG::Vec4f default_color(color.redF(), color.greenF(), color.blueF(), color.alphaF());
317  object->materialNode()->set_color(default_color);
318 
319  object->update();
320 
321  object->show();
322 
323  emit emptyObjectAdded( object->id() );
324 
325  return object->id();
326 }
327 
328 
329 //----------------------------------------------------------------
330 
331 
332 void TypeSplatCloudPlugin::generateBackup( int _objectId, QString _name, UpdateType _type )
333 {
334  if( _objectId == -1 )
335  return;
336 
337  BaseObjectData *object = 0;
338  PluginFunctions::getObject( _objectId, object );
339 
340  SplatCloudObject *splatCloudObject = PluginFunctions::splatCloudObject( object );
341 
342  if( splatCloudObject )
343  {
344  // get backup object data
345  BackupData *backupData = 0;
346 
347  if( object->hasObjectData( OBJECT_BACKUPS ) )
348  {
349  backupData = dynamic_cast<BackupData *>( object->objectData( OBJECT_BACKUPS ) );
350  }
351  else
352  {
353  // add backup data
354  backupData = new BackupData( object );
355  object->setObjectData( OBJECT_BACKUPS, backupData );
356  }
357 
358  // store a new backup
359  SplatCloudBackup *backup = new SplatCloudBackup( splatCloudObject, _name, _type );
360 
361  backupData->storeBackup( backup );
362  }
363 }
364 
365 
366 //----------------------------------------------------------------
367 
368 
369 void TypeSplatCloudPlugin::ungroupGroupObject( GroupObject *_groupObject )
370 {
371  // get new parent
372  BaseObject *parent = _groupObject->parent();
373 
374  // iterate over all children
375  int i;
376  for( i = _groupObject->childCount() - 1; i >= 0; --i )
377  {
378  // get current child
379  BaseObject *child = _groupObject->child( i );
380 
381  // change child's parent
382  child->setParent( parent );
383  }
384 
385  // delete group-object
386  emit deleteObject( _groupObject->id() );
387 }
388 
389 
390 //----------------------------------------------------------------
391 
392 
393 GroupObject *TypeSplatCloudPlugin::getCamerasGroupObject( const SplatCloud_CameraManager &_cameraManager )
394 {
395  // iterate over all cameras
396  SplatCloud_Cameras::const_iterator cameraIter;
397  for( cameraIter = _cameraManager.cameras_.begin(); cameraIter != _cameraManager.cameras_.end(); ++cameraIter )
398  {
399  const SplatCloud_Camera &camera = *cameraIter;
400 
401  // get current camera-object by id
402  CameraObject *cameraObject = 0;
403  if( PluginFunctions::getObject( camera.objectId_, cameraObject ) )
404  {
405  // get parent
406  BaseObject *parent = cameraObject->parent();
407  if( (parent != 0) && parent->isGroup() && (parent->parent() != 0) ) // parent is valid, group and *not* root-node
408  {
409  // cast parent to group-object
410  GroupObject *groupObject = dynamic_cast<GroupObject *>( parent );
411  if( groupObject != 0 )
412  return groupObject;
413  }
414  }
415  }
416 
417  // return failure
418  return 0;
419 }
420 
421 
422 //----------------------------------------------------------------
423 
424 
425 GroupObject *TypeSplatCloudPlugin::getClustersGroupObject( const SplatCloud_ClusterManager &_clusterManager )
426 {
427  // there is no clusters group-object yet, so return 0
428  return 0;
429 }
430 
431 
432 //----------------------------------------------------------------
433 
434 
435 void TypeSplatCloudPlugin::ungroupCameraObjects( const SplatCloud_CameraManager &_cameraManager )
436 {
437  // get cameras group-object
438  GroupObject *groupObject = getCamerasGroupObject( _cameraManager );
439  if( groupObject != 0 )
440  {
441  // ungroup group-object
442  ungroupGroupObject( groupObject );
443  }
444 }
445 
446 
447 //----------------------------------------------------------------
448 
449 
450 void TypeSplatCloudPlugin::ungroupClusterObjects( const SplatCloud_ClusterManager &_clusterManager )
451 {
452  // get clusters group-object
453  GroupObject *groupObject = getClustersGroupObject( _clusterManager );
454  if( groupObject != 0 )
455  {
456  // ungroup group-object
457  ungroupGroupObject( groupObject );
458  }
459 }
460 
461 
462 //----------------------------------------------------------------
463 
464 
465 void TypeSplatCloudPlugin::groupCameraObjects( const SplatCloud_CameraManager &_cameraManager )
466 {
467  // ungroup cameras first
468  ungroupCameraObjects( _cameraManager );
469 
470  // group cameras
471  {
472  // create new, emtpy list of object IDs
473  IdList objectIDs;
474 
475  // reserve enough memory
476  objectIDs.reserve( _cameraManager.cameras_.size() );
477 
478  // iterate over all cameras
479  SplatCloud_Cameras::const_iterator cameraIter;
480  for( cameraIter = _cameraManager.cameras_.begin(); cameraIter != _cameraManager.cameras_.end(); ++cameraIter )
481  {
482  const SplatCloud_Camera &camera = *cameraIter;
483 
484  // check if object id is valid
485  if( camera.objectId_ != -1 )
486  {
487  // add object id to list
488  objectIDs.push_back( camera.objectId_ );
489  }
490  }
491 
492  // group objects in list
493  RPC::callFunction( "datacontrol", "groupObjects", objectIDs, QString( "Cameras" ) );
494  }
495 }
496 
497 
498 //----------------------------------------------------------------
499 
500 
501 void TypeSplatCloudPlugin::groupClusterObjects( const SplatCloud_ClusterManager &_clusterManager )
502 {
503  // ungroup clusters first
504  ungroupClusterObjects( _clusterManager );
505 }
506 
507 
508 //----------------------------------------------------------------
509 
510 
511 void TypeSplatCloudPlugin::addCameraObjects( SplatCloudObject *_splatCloudObject )
512 {
513  // get splatcloud
514  SplatCloud *splatCloud = PluginFunctions::splatCloud( _splatCloudObject );
515  if( splatCloud == 0 )
516  return;
517 
518  // get camera-manager property
519  SplatCloud_CameraManagerProperty *cameraManagerProp = splatCloud->getCloudProperty( SPLATCLOUD_CAMERAMANAGER_HANDLE );
520  if( cameraManagerProp == 0 )
521  return;
522 
523  // get camera-manager
524  SplatCloud_CameraManager &cameraManager = cameraManagerProp->data();
525 
526  // get cameras
527  SplatCloud_Cameras &cameras = cameraManager.cameras_;
528  if( cameras.empty() )
529  return;
530 
531  // get splatcloud-object id
532  int splatCloudObjectId = _splatCloudObject->id();
533 
534  // add object(s)
535  {
536  // disable update of scenegraph
537  OpenFlipper::Options::blockSceneGraphUpdates();
538 
539  // iterate over all cameras
540  SplatCloud_Cameras::iterator cameraIter;
541  for( cameraIter = cameras.begin(); cameraIter != cameras.end(); ++cameraIter )
542  {
543  SplatCloud_Camera &camera = *cameraIter;
544 
545  // create new, empty camera-object if not already present
546  if( camera.objectId_ == -1 )
547  emit addEmptyObject( DATA_CAMERA, camera.objectId_ );
548 
549  // check object id
550  if( camera.objectId_ != -1 )
551  {
552  // get camera-object by id
553  CameraObject *cameraObject = 0;
554  if( PluginFunctions::getObject( camera.objectId_, cameraObject ) )
555  {
556  // set name of camera-object
557  cameraObject->setName( camera.imagePath_.c_str() );
558 
559  // remember splatcloud-object id
560  cameraObject->setObjectData( SPLATCLOUD_OBJECT_ID_DATANAME, new IntPerObjectData( splatCloudObjectId ) );
561 
562  // get camera
563  CameraNode *cameraNode = cameraObject->cameraNode();
564  if( cameraNode != 0 )
565  {
566  // set resolution
567  unsigned int width = camera.imageWidth_;
568  unsigned int height = camera.imageHeight_;
569  if( (width == 0) || (height == 0) )
570  {
571  width = 1;
572  height = 1;
573  }
574 
575  // set matrix
576  ACG::GLMatrixd matrixView, matrixProj;
577  {
578  const SplatCloud_Projection &proj = camera.projection_;
579  matrixView(0,0) = proj.r_[0][0]; matrixView(0,1) = proj.r_[1][0]; matrixView(0,2) = proj.r_[2][0];
580  matrixView(1,0) = proj.r_[0][1]; matrixView(1,1) = proj.r_[1][1]; matrixView(1,2) = proj.r_[2][1];
581  matrixView(2,0) = proj.r_[0][2]; matrixView(2,1) = proj.r_[1][2]; matrixView(2,2) = proj.r_[2][2];
582  matrixView(0,3) = -(proj.r_[0][0]*proj.t_[0] + proj.r_[1][0]*proj.t_[1] + proj.r_[2][0]*proj.t_[2]);
583  matrixView(1,3) = -(proj.r_[0][1]*proj.t_[0] + proj.r_[1][1]*proj.t_[1] + proj.r_[2][1]*proj.t_[2]);
584  matrixView(2,3) = -(proj.r_[0][2]*proj.t_[0] + proj.r_[1][2]*proj.t_[1] + proj.r_[2][2]*proj.t_[2]);
585  matrixView(3,0) = 0.0; matrixView(3,1) = 0.0; matrixView(3,2) = 0.0; matrixView(3,3) = 1.0;
586 
587  matrixProj.identity();
588  matrixProj.perspective(proj.f_, double(width) / double(height), proj.k1_, proj.k2_);
589  }
590 
591  // set camera parameters
592  cameraNode->setModelView( matrixView );
593  cameraNode->setProjection( matrixProj );
594 
595  // emit signal that the camera-object has to be updated
596  emit updatedObject( camera.objectId_, UPDATE_ALL );
597 
598  // everything is okay, so continue with next camera
599  continue;
600  }
601 
602  // something went wrong
603  }
604 
605  // something went wrong, so delete camera-object
606  emit deleteObject( camera.objectId_ );
607  camera.objectId_ = -1;
608  }
609  }
610 
611  // enable update of scenegraph
612  OpenFlipper::Options::unblockSceneGraphUpdates();
613 
614  // group camera-objects
615  groupCameraObjects( cameraManager );
616  }
617 
618 }
619 
620 
621 //----------------------------------------------------------------
622 
623 
624 void TypeSplatCloudPlugin::addClusterObjects( SplatCloudObject *_splatCloudObject )
625 {
626  // get splatcloud
627  SplatCloud *splatCloud = PluginFunctions::splatCloud( _splatCloudObject );
628  if( splatCloud == 0 )
629  return;
630 
631  // get cluster-manager property
632  SplatCloud_ClusterManagerProperty *clusterManagerProp = splatCloud->getCloudProperty( SPLATCLOUD_CLUSTERMANAGER_HANDLE );
633  if( clusterManagerProp == 0 )
634  return;
635 
636  // get cluster-manager
637  SplatCloud_ClusterManager &clusterManager = clusterManagerProp->data();
638 
639  // get clusters
640  SplatCloud_Clusters &clusters = clusterManager.clusters_;
641  if( clusters.empty() )
642  return;
643 
644  // get splatcloud-object id
645  int splatCloudObjectId = _splatCloudObject->id();
646 
647  // add object(s)
648  {
649  // create new, empty (poly)mesh-object if not already present
650  if( clusterManager.objectId_ == -1 )
651  emit addEmptyObject( DATA_POLY_MESH, clusterManager.objectId_ );
652 
653  // check object id
654  if( clusterManager.objectId_ != -1 )
655  {
656  // get mesh-object by id
657  PolyMeshObject *meshObject = 0;
658  if( PluginFunctions::getObject( clusterManager.objectId_, meshObject ) )
659  {
660  // set name of mesh-object
661  meshObject->setName( "Clusters" );
662 
663  // remember splatcloud-object id
664  meshObject->setObjectData( SPLATCLOUD_OBJECT_ID_DATANAME, new IntPerObjectData( splatCloudObjectId ) );
665 
666  // get mesh
667  PolyMesh *mesh = meshObject->mesh();
668  if( mesh != 0 )
669  {
670  // request colors
671  mesh->request_vertex_colors();
672  mesh->request_face_colors();
673 
674  // reset seed of random-number-generator
675  srand( 0 );
676 
677  // add clusters to mesh
678  SplatCloud_Clusters::const_iterator clusterIter;
679  for( clusterIter = clusters.begin(); clusterIter != clusters.end(); ++clusterIter )
680  {
681  const SplatCloud_Cluster &cluster = *clusterIter;
682 
683  // choose random color
684  PolyMesh::Color color;
685  {
686  static const double MIN_SQR_BRIGHTNESS = MIN_CLUSTER_BRIGHTNESS * MIN_CLUSTER_BRIGHTNESS;
687  static const double RCP_RAND_MAX = 1.0 / (double) RAND_MAX;
688  static const double RCP_3 = 1.0 / 3.0;
689 
690  double r, g, b;
691  double sqrBrightness;
692  do
693  {
694  r = rand() * RCP_RAND_MAX;
695  g = rand() * RCP_RAND_MAX;
696  b = rand() * RCP_RAND_MAX;
697  sqrBrightness = RCP_3 * (r*r + g*g + b*b);
698  }
699  while( sqrBrightness < MIN_SQR_BRIGHTNESS );
700 
701  color = PolyMesh::Color( r, g, b, 1.f );
702  }
703 
704  // get quad vertices
705  const ACG::Vec3d &qv0 = cluster.quad_.vertices_[0];
706  const ACG::Vec3d &qv1 = cluster.quad_.vertices_[1];
707  const ACG::Vec3d &qv2 = cluster.quad_.vertices_[2];
708  const ACG::Vec3d &qv3 = cluster.quad_.vertices_[3];
709 
710  // add vertices to mesh
711  std::vector<PolyMesh::VertexHandle> vertexHandles( 4 );
712  vertexHandles[0] = mesh->add_vertex( PolyMesh::Point( qv0[0], qv0[1], qv0[2] ) );
713  vertexHandles[1] = mesh->add_vertex( PolyMesh::Point( qv1[0], qv1[1], qv1[2] ) );
714  vertexHandles[2] = mesh->add_vertex( PolyMesh::Point( qv2[0], qv2[1], qv2[2] ) );
715  vertexHandles[3] = mesh->add_vertex( PolyMesh::Point( qv3[0], qv3[1], qv3[2] ) );
716  mesh->set_color( vertexHandles[0], color );
717  mesh->set_color( vertexHandles[1], color );
718  mesh->set_color( vertexHandles[2], color );
719  mesh->set_color( vertexHandles[3], color );
720 
721  // add face to mesh
722  PolyMesh::FaceHandle faceHandle = mesh->add_face( vertexHandles );
723  mesh->set_color( faceHandle, color );
724  }
725 
726  // request and calculate normals
727  mesh->request_face_normals();
728  mesh->request_vertex_normals();
729  mesh->update_normals();
730 
731  // emit signal that the mesh-object has to be updated
732  emit updatedObject( clusterManager.objectId_, UPDATE_ALL );
733 
734  // group cluster-object(s)
735  groupClusterObjects( clusterManager );
736 
737  // everything is okay, so return
738  return;
739  }
740 
741  // something went wrong
742  }
743 
744  // something went wrong, so delete mesh-object
745  emit deleteObject( clusterManager.objectId_ );
746  clusterManager.objectId_ = -1;
747  }
748  }
749 
750 }
751 
752 
753 //----------------------------------------------------------------
754 
755 
756 void TypeSplatCloudPlugin::freeCameraObjects( SplatCloudObject *_splatCloudObject )
757 {
758  // get splatcloud
759  SplatCloud *splatCloud = PluginFunctions::splatCloud( _splatCloudObject );
760  if( splatCloud == 0 )
761  return;
762 
763  // get camera-manager property
764  SplatCloud_CameraManagerProperty *cameraManagerProp = splatCloud->getCloudProperty( SPLATCLOUD_CAMERAMANAGER_HANDLE );
765  if( cameraManagerProp == 0 )
766  return;
767 
768  // get camera-manager
769  SplatCloud_CameraManager &cameraManager = cameraManagerProp->data();
770 
771  // get cameras
772  SplatCloud_Cameras &cameras = cameraManager.cameras_;
773  if( cameras.empty() )
774  return;
775 
776  // remove splatcloud-reference from object(s)
777  {
778  // iterate over all cameras
779  SplatCloud_Cameras::const_iterator cameraIter;
780  for( cameraIter = cameras.begin(); cameraIter != cameras.end(); ++cameraIter )
781  {
782  // get camera-object by id
783  CameraObject *cameraObject = 0;
784  if( PluginFunctions::getObject( cameraIter->objectId_, cameraObject ) )
785  {
786  // delete per-object-data
787  cameraObject->clearObjectData( SPLATCLOUD_OBJECT_ID_DATANAME );
788  }
789  }
790  }
791 
792 }
793 
794 
795 //----------------------------------------------------------------
796 
797 
798 void TypeSplatCloudPlugin::freeClusterObjects( SplatCloudObject *_splatCloudObject )
799 {
800  // get splatcloud
801  SplatCloud *splatCloud = PluginFunctions::splatCloud( _splatCloudObject );
802  if( splatCloud == 0 )
803  return;
804 
805  // get cluster-manager property
806  SplatCloud_ClusterManagerProperty *clusterManagerProp = splatCloud->getCloudProperty( SPLATCLOUD_CLUSTERMANAGER_HANDLE );
807  if( clusterManagerProp == 0 )
808  return;
809 
810  // get cluster-manager
811  SplatCloud_ClusterManager &clusterManager = clusterManagerProp->data();
812 
813  // remove splatcloud-reference from object(s)
814  {
815  // get clusters mesh-object by id
816  PolyMeshObject *meshObject = 0;
817  if( PluginFunctions::getObject( clusterManager.objectId_, meshObject ) )
818  {
819  // delete per-object-data
820  meshObject->clearObjectData( SPLATCLOUD_OBJECT_ID_DATANAME );
821  }
822  }
823 
824 }
825 
826 
827 //----------------------------------------------------------------
828 
829 
830 void TypeSplatCloudPlugin::eraseCamera( CameraObject *_cameraObject )
831 {
832  // get per-object-data
833  IntPerObjectData *splatCloudObjectIdPOD = dynamic_cast<IntPerObjectData *>( _cameraObject->objectData( SPLATCLOUD_OBJECT_ID_DATANAME ) );
834  if( splatCloudObjectIdPOD == 0 )
835  return;
836 
837  // get splatcloud-object by id
838  SplatCloudObject *splatCloudObject = 0;
839  if( !PluginFunctions::getObject( splatCloudObjectIdPOD->data(), splatCloudObject ) )
840  return;
841 
842  // get splatcloud
843  SplatCloud *splatCloud = PluginFunctions::splatCloud( splatCloudObject );
844  if( splatCloud == 0 )
845  return;
846 
847  // get camera-object id
848  int cameraObjectId = _cameraObject->id();
849 
850  // delete camera from cameras
851  {
852  // get camera-manager property
853  SplatCloud_CameraManagerProperty *cameraManagerProp = splatCloud->getCloudProperty( SPLATCLOUD_CAMERAMANAGER_HANDLE );
854  if( cameraManagerProp != 0 )
855  {
856  // get camera-manager
857  SplatCloud_CameraManager &cameraManager = cameraManagerProp->data();
858 
859  // get cameras
860  SplatCloud_Cameras &cameras = cameraManager.cameras_;
861 
862  // iterate over all cameras
863  SplatCloud_Cameras::iterator cameraIter;
864  for( cameraIter = cameras.begin(); cameraIter != cameras.end(); ++cameraIter )
865  {
866  // check if camera should be deleted
867  if( cameraIter->objectId_ == cameraObjectId )
868  {
869  // delete current camera
870  cameras.erase( cameraIter );
871  break; // there is only one camera with this object id, so break
872  }
873  }
874  }
875  }
876 
877  // delete camera from viewlists
878  {
879  if( splatCloud->hasViewlists() )
880  {
881  // iterate over all splats
882  unsigned int splatIdx, numSplats = splatCloud->numSplats();
883  for( splatIdx = 0; splatIdx < numSplats; ++splatIdx )
884  {
885  // get viewlist
886  SplatCloud::Viewlist &viewlist = splatCloud->viewlists( splatIdx );
887 
888  // iterate over all views
889  SplatCloud::Viewlist::iterator viewIter;
890  for( viewIter = viewlist.begin(); viewIter != viewlist.end(); ++viewIter )
891  {
892  // check if view should be deleted
893  if( viewIter->cameraObjectId_ == cameraObjectId )
894  {
895  // delete current view
896  viewlist.erase( viewIter );
897  break; // there is only one view with this object id, so break
898  }
899  }
900  }
901  }
902  }
903 
904 }
905 
906 
907 //================================================================
void perspective(Scalar fovY, Scalar aspect, Scalar near_plane, Scalar far_plane)
multiply self with a perspective projection matrix
void clearObjectData(QString _dataName)
Clear the object data pointer ( this will not delete the object!! )
Definition: BaseObject.cc:787
BaseObject * child(int row)
return a child
Definition: BaseObject.cc:506
CameraObject * cameraObject(int _objectId)
Get a CameraObject from an object id if possible.
#define DATA_CAMERA
Definition: Camera.hh:67
const UpdateType UPDATE_STATE(UpdateTypeSet(1)<< 12)
State has changed.
#define DATA_POLY_MESH
Definition: PolyMesh.hh:59
int childCount() const
get the number of children
Definition: BaseObject.cc:511
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
void setObjectData(QString _dataName, PerObjectData *_data)
Definition: BaseObject.cc:781
unsigned int numSplats() const
Get the number of splats.
Definition: SplatCloud.hh:179
Kernel::Color Color
Color type.
Definition: PolyMeshT.hh:116
void use()
Enables the program object for using.
Definition: GLSLShader.cc:345
Type for a Meshobject containing a poly mesh.
Definition: PolyMesh.hh:65
QScriptValue callFunction(QString _plugin, QString _functionName, std::vector< QScriptValue > _parameters)
Call a function provided by a plugin getting multiple parameters.
Definition: RPCWrappers.cc:55
int objectCount()
Get the number of available objects.
Kernel::Point Point
Coordinate type.
Definition: PolyMeshT.hh:112
bool getObject(const int _identifier, BaseObject *&_object)
Get the object which has the given identifier.
ShaderNode * splatShaderNode(BaseObjectData *_object)
Get a ShaderNode from an object.
bool hasViewlists() const
Return the availability of the predefined property.
Definition: SplatCloud.hh:612
void storeBackup(BaseBackup *_backup)
store a backup
Definition: BackupData.cc:72
void get_viewport(int &_left, int &_bottom, int &_width, int &_height) const
get viewport
Definition: GLState.hh:816
void identity()
setup an identity matrix
const QStringList ALL_OBJECTS
Iterable object range.
#define DATA_SPLATCLOUD
Definition: SplatCloud.hh:59
CameraNode * cameraNode()
Get the scenegraph Node.
QString name()
Return a name for the plugin.
int id() const
Definition: BaseObject.cc:190
MeshT * mesh()
return a pointer to the mesh
DLLEXPORT DataType addDataType(QString _name, QString _readableName)
Adds a datatype and returns the id for the new type.
Definition: Types.cc:117
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:179
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
void setName(QString _name)
Set the name of the Object.
void setName(QString _name)
Set the name of the Object.
Add colors to mesh item (vertices/faces/edges)
Definition: Attributes.hh:83
Abstract class that is used to store backups.
Definition: BackupData.hh:57
GLSL program class.
Definition: GLSLShader.hh:211
SplatCloudObject * splatCloudObject(BaseObjectData *_object)
Cast an SplatCloudObject to a SplatCloudObject if possible.
BaseObject * parent()
Get the parent item ( 0 if rootitem )
Definition: BaseObject.cc:466
void setParent(BaseObject *_parent)
Set the parent pointer.
Definition: BaseObject.cc:477
virtual void setName(QString _name)
path to the file from which the object is loaded ( defaults to "." )
Definition: BaseObject.cc:723
DLLEXPORT void setTypeIcon(DataType _id, QString _icon)
Set an Icon for a given DataType.
Definition: Types.cc:223
Class that encapsulates a backup.
QString name() const
return the name of the object. The name defaults to NONAME if unset.
Definition: BaseObject.cc:730
void setUniform(const char *_name, GLint _value)
Set int uniform to specified value.
Definition: GLSLShader.cc:385
SplatCloud * splatCloud(BaseObjectData *_object)
Get a SplatCloud from an object.
int targetCount()
Get the number of target objects.
const DrawMode & addDrawMode(const std::string &_name, bool _propertyBased)
Add a custom DrawMode.
Definition: DrawModes.cc:765
void disable()
Resets to standard rendering pipeline.
Definition: GLSLShader.cc:355
DrawMode NONE
not a valid draw mode
Definition: DrawModes.cc:71
SmartVertexHandle add_vertex(const Point &_p)
Alias for new_vertex(const Point&).
Definition: PolyMeshT.hh:235
Update type class.
Definition: UpdateType.hh:60
void setModelView(ACG::GLMatrixd _modelView)
set model view matrix
Definition: CameraNode.hh:118
void generateBackup(int _objectId, QString _name, UpdateType _type)
This slot should be implemented in a TypePlugin to generate type specific backups.
void update_normals()
Compute normals for all primitives.
bool isGroup() const
Check if object is a group.
Definition: BaseObject.cc:619
CloudPropertyT< T > * getCloudProperty(const PropertyHandleT< T > &_handle)
Get a pointer to a property.
bool contains(const UpdateType &_type) const
Check if this update contains the given UpdateType.
Definition: UpdateType.cc:104
Viewlist & viewlists(int _idx)
Get a reference of the predefined property&#39;s value.
Definition: SplatCloud.hh:641
virtual void updatedObject(int _objectId)
An object has been changed or added by this plugin.
GLSL::PtrProgram getShader(DrawModes::DrawMode _drawmode, bool _pick=false)
Get the shader for the given drawMode.
Definition: ShaderNode.cc:222
PerObjectData * objectData(QString _dataName)
Returns the object data pointer.
Definition: BaseObject.cc:803
Viewer::ViewerProperties & viewerProperties(int _id)
Get the viewer properties Use this functions to get basic viewer properties such as backgroundcolor o...
const GLMatrixd & modelview() const
get modelview matrix
Definition: GLState.hh:791
bool hasObjectData(QString _dataName)
Checks if object data with given name is available.
Definition: BaseObject.cc:795
DLLEXPORT OpenFlipperQSettings & OpenFlipperSettings()
QSettings object containing all program settings of OpenFlipper.
const GLMatrixd & projection() const
get projection matrix
Definition: GLState.hh:786
Reference data()
Access the data as reference.
Definition: SplatCloud.hh:333
void setProjection(ACG::GLMatrixd _projection)
Set projection Matrix ( used to calculate frustum ... )
Definition: CameraNode.hh:124
int addEmpty()
Create an empty object.
ACG::GLState & glState()
Get the glState of the Viewer.