Developer Documentation
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
PoissonReconstructionPlugin.cc
1 /*===========================================================================*\
2 * *
3 * OpenFlipper *
4 * Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen *
5 * www.openflipper.org *
6 * *
7 *--------------------------------------------------------------------------- *
8 * This file is part of OpenFlipper. *
9 * *
10 * OpenFlipper is free software: you can redistribute it and/or modify *
11 * it under the terms of the GNU Lesser General Public License as *
12 * published by the Free Software Foundation, either version 3 of *
13 * the License, or (at your option) any later version with the *
14 * following exceptions: *
15 * *
16 * If other files instantiate templates or use macros *
17 * or inline functions from this file, or you compile this file and *
18 * link it with other files to produce an executable, this file does *
19 * not by itself cause the resulting executable to be covered by the *
20 * GNU Lesser General Public License. This exception does not however *
21 * invalidate any other reasons why the executable file might be *
22 * covered by the GNU Lesser General Public License. *
23 * *
24 * OpenFlipper is distributed in the hope that it will be useful, *
25 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
26 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
27 * GNU Lesser General Public License for more details. *
28 * *
29 * You should have received a copy of the GNU LesserGeneral Public *
30 * License along with OpenFlipper. If not, *
31 * see <http://www.gnu.org/licenses/>. *
32 * *
33 \*===========================================================================*/
34 
35 /*===========================================================================*\
36 * *
37 * $Revision: 13354 $ *
38 * $LastChangedBy: moebius $ *
39 * $Date: 2012-01-12 13:39:10 +0100 (Do, 12 Jan 2012) $ *
40 * *
41 \*===========================================================================*/
42 
43 #ifdef ENABLE_SPLATCLOUD_SUPPORT
45 #endif
46 
47 #include <QtGui>
48 
49 #include "PoissonReconstructionPlugin.hh"
50 #include <iostream>
51 
56 
57 
58 
59 #include "PoissonReconstructionT.hh"
60 
61 PoissonPlugin::PoissonPlugin() :
62  tool_(0),
63  toolIcon_(0)
64 {
65 
66 }
67 
68 void PoissonPlugin::initializePlugin(){
69 
70  if ( ! OpenFlipper::Options::gui())
71  return;
72 
73  tool_ = new PoissonToolBox();
74 
75  connect(tool_->reconstructButton, SIGNAL( clicked() ), this, SLOT( slotPoissonReconstruct() ) );
76 
77  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"PoissonReconstruction.png");
78  emit addToolbox( tr("Poisson Reconstruction") , tool_, toolIcon_);
79 
80  QString info =
81  "This plugin is based on the code published by Michael Kazhdan and Matthew Bolitho<br> "
82  "<br> "
83  "The following license applies to their code: <br> "
84  "Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho <br> "
85  "All rights reserved. <br> "
86  "<br> "
87  "Redistribution and use in source and binary forms, with or without modification, "
88  "are permitted provided that the following conditions are met: <br> "
89  "<br> "
90  "Redistributions of source code must retain the above copyright notice, this list of "
91  "conditions and the following disclaimer. Redistributions in binary form must reproduce "
92  "the above copyright notice, this list of conditions and the following disclaimer "
93  "in the documentation and/or other materials provided with the distribution. <br> "
94  "<br> "
95  "Neither the name of the Johns Hopkins University nor the names of its contributors "
96  "may be used to endorse or promote products derived from this software without specific "
97  "prior written permission. <br> "
98  "<br> "
99  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY "
100  "EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES "
101  "OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT "
102  "SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, "
103  "INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED "
104  "TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR "
105  "BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN "
106  "CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN "
107  "ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH "
108  "DAMAGE. ";
109 
110  emit addAboutInfo(info,"Poisson Reconstruction Plugin");
111 
112  WhatsThisGenerator whatGen("PoissonReconstruction");
113  tool_->reconstructButton->setWhatsThis(tool_->reconstructButton->toolTip()+whatGen.generateLink());
114  tool_->depthBox->setWhatsThis(tool_->depthBox->toolTip()+whatGen.generateLink("octree"));
115  tool_->label->setWhatsThis(tool_->label->toolTip()+whatGen.generateLink("octree"));
116 }
117 
118 
119 void PoissonPlugin::pluginsInitialized()
120 {
121  emit setSlotDescription("poissonReconstruct(int,int)",tr("Reconstruct a triangle mesh from the given object. Returns the id of the new object or -1 if it failed."),
122  QStringList(tr("ObjectId;depth").split(';')),QStringList(tr("ObjectId of the object;octree depth").split(';')));
123  emit setSlotDescription("poissonReconstruct(IdList,int)",tr("Reconstruct one triangle mesh from the given objects. Returns the id of the new object or -1 if it failed."),
124  QStringList(tr("IdList;depth").split(';')),QStringList(tr("Id of the objects;octree depth").split(';')));
125 
126  emit setSlotDescription("poissonReconstruct(int)",tr("Reconstruct a triangle mesh from the given object. (Octree depth defaults to 7). Returns the id of the new object or -1 if it failed."),
127  QStringList(tr("ObjectId")),QStringList(tr("ObjectId of the object")));
128  emit setSlotDescription("poissonReconstruct(IdList)",tr("Reconstruct one triangle mesh from the given objects. (Octree depth defaults to 7). Returns the id of the new object or -1 if it failed."),
129  QStringList(tr("IdList")),QStringList(tr("Id of the objects")));
130 }
131 
132 int PoissonPlugin::poissonReconstruct(int _id, int _depth)
133 {
134  IdList list(1,_id);
135  return poissonReconstruct(list, _depth);
136 }
137 
138 int PoissonPlugin::poissonReconstruct(IdList _ids, int _depth)
139 {
140  IdList generatedMeshes;
141 
142  unsigned int n_points = 0;
143 
144  // Data container for the algorithm
145  // holds two 3D vectors in 6 columns, first the position, followed by the normal of the point
146  std::vector< Real > pt_data;
147 
148  //get data from objects
149  for (IdList::iterator idIter = _ids.begin(); idIter != _ids.end(); ++idIter)
150  {
151  BaseObjectData* obj = 0;
152  PluginFunctions::getObject(*idIter,obj);
153  if ( obj == 0 ) {
154  emit log(LOGERR , QString("Unable to get Object width id %1").arg(*idIter));
155  continue;
156  }
157 
158  //Triangle mesh
159  if ( obj->dataType() == DATA_TRIANGLE_MESH) {
160 
161  // Get triangle mesh
162  TriMesh* mesh = PluginFunctions::triMesh(obj);
163 
164  n_points += mesh->n_vertices();
165 
166  emit log(LOGINFO,QString("Adding %1 points from Object %2").arg(mesh->n_vertices()).arg(*idIter) );
167 
168  pt_data.reserve( n_points * 6 );
169  TriMesh::VertexIter vit = mesh->vertices_begin();
170  for ( ; vit != mesh->vertices_end(); ++vit )
171  {
172  pt_data.push_back( mesh->point( *vit )[0] );
173  pt_data.push_back( mesh->point( *vit )[1] );
174  pt_data.push_back( mesh->point( *vit )[2] );
175  pt_data.push_back( mesh->normal( *vit )[0] );
176  pt_data.push_back( mesh->normal( *vit )[1] );
177  pt_data.push_back( mesh->normal( *vit )[2] );
178  }
179  }
180  //Poly mesh
181  else if ( obj->dataType() == DATA_POLY_MESH) {
182  // Get poly mesh
183  PolyMesh* mesh = PluginFunctions::polyMesh(obj);
184 
185  n_points += mesh->n_vertices();
186 
187  emit log(LOGINFO,QString("Adding %1 points from Object %2").arg(mesh->n_vertices()).arg(*idIter) );
188 
189  pt_data.reserve( n_points * 6 );
190  PolyMesh::VertexIter vit = mesh->vertices_begin();
191  for ( ; vit != mesh->vertices_end(); ++vit )
192  {
193  pt_data.push_back( mesh->point( *vit )[0] );
194  pt_data.push_back( mesh->point( *vit )[1] );
195  pt_data.push_back( mesh->point( *vit )[2] );
196  pt_data.push_back( mesh->normal( *vit )[0] );
197  pt_data.push_back( mesh->normal( *vit )[1] );
198  pt_data.push_back( mesh->normal( *vit )[2] );
199  }
200  }
201  //Splat cloud
202  #ifdef ENABLE_SPLATCLOUD_SUPPORT
203  else if( obj->dataType() == DATA_SPLATCLOUD)
204  {
205 
206  // Get splat cloud mesh
208 
209  if ( ! cloud->hasNormals() ) {
210  emit log(LOGERR,"Splat cloud has no normals. Skipping it");
211  continue;
212  }
213 
214  n_points += cloud->numSplats();
215 
216  emit log(LOGINFO,QString("Adding %1 points from Object %2").arg(cloud->numSplats()).arg(*idIter) );
217 
218  pt_data.reserve( n_points * 6 );
219  for (unsigned i = 0 ; i < cloud->numSplats(); ++i )
220  {
221  pt_data.push_back( cloud->positions( i )[0] );
222  pt_data.push_back( cloud->positions( i )[1] );
223  pt_data.push_back( cloud->positions( i )[2] );
224  pt_data.push_back( cloud->normals( i )[0] );
225  pt_data.push_back( cloud->normals( i )[1] );
226  pt_data.push_back( cloud->normals( i )[2] );
227  }
228  }
229 #endif
230  else
231  emit log(LOGERR,QString("ObjectType of Object with id %1 is unsupported").arg(*idIter));
232  }
233 
234 
235  int meshId = -1;
236 
237  //create and reconstruct mesh
238  if ( !pt_data.empty() ) {
239 
240  emit log(LOGINFO,"Creating Object");
241 
242  // Add empty triangle mesh
243 
244  emit addEmptyObject ( DATA_TRIANGLE_MESH, meshId );
245 
246  TriMeshObject* finalObject = PluginFunctions::triMeshObject(meshId);
247 
248  // Get triangle mesh
249  TriMesh* final_mesh = NULL;
250 
251  PluginFunctions::getMesh(meshId,final_mesh);
252 
253  //Reconstruct
255 
257  params.Depth = _depth;
258 
259  emit log(LOGINFO,"Starting reconstruction");
260 
261  if ( pr.run( pt_data, *final_mesh, params ) ) {
262  emit log(LOGINFO,"Reconstruction succeeded");
263  emit updatedObject(meshId,UPDATE_ALL);
264  finalObject->setName("Poisson Reconstruction.obj");
265  } else {
266  emit log(LOGERR,"Reconstruction failed");
267  emit deleteObject( meshId );
268  meshId = -1;
269  }
270  }
271 
272  return meshId;
273 
274 }
275 
276 
278 
279  if ( ! OpenFlipper::Options::gui())
280  return;
281 
282  IdList ids;
283 
284  DataType restriction = (DATA_TRIANGLE_MESH | DATA_POLY_MESH);
285 
286  #ifdef ENABLE_SPLATCLOUD_SUPPORT
287  restriction |= DATA_SPLATCLOUD;
288  #endif
289 
291  {
292  ids.push_back(o_it->id());
293  std::cerr << "Added " << o_it->id() << std::endl;
294  }
295 
296  const int depth = tool_->depthBox->value();
297 
298  poissonReconstruct(ids,depth);
299 
300 }
301 
302 #if QT_VERSION < 0x050000
303 Q_EXPORT_PLUGIN2( poissonplugin , PoissonPlugin );
304 #endif
std::vector< int > IdList
Standard Type for id Lists used for scripting.
Definition: DataTypes.hh:192
bool dataType(DataType _type) const
Definition: BaseObject.cc:232
bool getMesh(int _identifier, PolyMesh *&_mesh)
Get the Poly Mesh which has the given identifier.
TriMesh * triMesh(BaseObjectData *_object)
Get a triangle mesh from an object.
void setName(QString _name)
Set the name of the Object.
Definition: MeshObjectT.cc:311
bool getObject(int _identifier, BSplineCurveObject *&_object)
PolyMesh * polyMesh(BaseObjectData *_object)
Get a poly mesh from an object.
Type for a MeshObject containing a triangle mesh.
Definition: TriangleMesh.hh:73
Normal & normals(int _idx)
Get a reference of the predefined property's value.
Definition: SplatCloud.hh:641
#define DATA_POLY_MESH
Definition: PolyMesh.hh:65
void slotPoissonReconstruct()
Button slot iterating over all targets and passing them to the correct functions. ...
virtual void updatedObject(int _objectId)
An object has been changed or added by this plugin.
#define DATA_TRIANGLE_MESH
Definition: TriangleMesh.hh:66
TriMeshObject * triMeshObject(BaseObjectData *_object)
Cast an BaseObject to a TriMeshObject if possible.
Predefined datatypes.
Definition: DataTypes.hh:96
bool hasNormals() const
Return the availability of the predefined property.
Definition: SplatCloud.hh:615
unsigned int numSplats() const
Get the number of splats.
Definition: SplatCloud.hh:185
const UpdateType UPDATE_ALL(UpdateTypeSet(1))
Identifier for all updates.
Position & positions(int _idx)
Get a reference of the predefined property's value.
Definition: SplatCloud.hh:637
DLLEXPORT ObjectIterator objectsEnd()
Return Iterator to Object End.
a class which provides an link generator for WhatsThisMessages linking to the user doc If you have an...
#define DATA_SPLATCLOUD
Definition: SplatCloud.hh:65
const QStringList TARGET_OBJECTS("target")
Iterable object range.
SplatCloud * splatCloud(BaseObjectData *_object)
Get a SplatCloud from an object.