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