PoissonReconstructionPlugin.cc 12 KB
Newer Older
1
2
3
/*===========================================================================*\
*                                                                            *
*                              OpenFlipper                                   *
Jan Möbius's avatar
Jan Möbius committed
4
*      Copyright (C) 2001-2014 by Computer Graphics Group, RWTH Aachen       *
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
*                           www.openflipper.org                              *
*                                                                            *
*--------------------------------------------------------------------------- *
*  This file is part of OpenFlipper.                                         *
*                                                                            *
*  OpenFlipper is free software: you can redistribute it and/or modify       *
*  it under the terms of the GNU Lesser General Public License as            *
*  published by the Free Software Foundation, either version 3 of            *
*  the License, or (at your option) any later version with the               *
*  following exceptions:                                                     *
*                                                                            *
*  If other files instantiate templates or use macros                        *
*  or inline functions from this file, or you compile this file and          *
*  link it with other files to produce an executable, this file does         *
*  not by itself cause the resulting executable to be covered by the         *
*  GNU Lesser General Public License. This exception does not however        *
*  invalidate any other reasons why the executable file might be             *
*  covered by the GNU Lesser General Public License.                         *
*                                                                            *
*  OpenFlipper is distributed in the hope that it will be useful,            *
*  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
*  GNU Lesser General Public License for more details.                       *
*                                                                            *
*  You should have received a copy of the GNU LesserGeneral Public           *
*  License along with OpenFlipper. If not,                                   *
*  see <http://www.gnu.org/licenses/>.                                       *
*                                                                            *
\*===========================================================================*/

/*===========================================================================*\
*                                                                            *
*   $Revision: 13354 $                                                       *
*   $LastChangedBy: moebius $                                                *
*   $Date: 2012-01-12 13:39:10 +0100 (Do, 12 Jan 2012) $                     *
*                                                                            *
\*===========================================================================*/


#include <QtGui>

#include "PoissonReconstructionPlugin.hh"
#include <iostream>

Matthias Möller's avatar
Matthias Möller committed
49
#include <OpenFlipper/BasePlugin/PluginFunctions.hh>
50
51
#include <OpenFlipper/common/GlobalOptions.hh>
#include <ObjectTypes/TriangleMesh/TriangleMesh.hh>
52
#include <ObjectTypes/PolyMesh/PolyMesh.hh>
53
#include <ObjectTypes/SplatCloud/SplatCloud.hh>
54
55
56
57
58
59
60
61
62
63
64

#include "PoissonReconstructionT.hh"

PoissonPlugin::PoissonPlugin() :
        tool_(0),
        toolIcon_(0)
{

}

void PoissonPlugin::initializePlugin(){
Matthias Möller's avatar
Matthias Möller committed
65
66
67

  if ( ! OpenFlipper::Options::gui())
      return;
68
69
70
71
72
 
  tool_ = new PoissonToolBox();
  
  connect(tool_->reconstructButton, SIGNAL( clicked() ), this, SLOT( slotPoissonReconstruct() ) );

Matthias Möller's avatar
Matthias Möller committed
73
74
  toolIcon_ = new QIcon(OpenFlipper::Options::iconDirStr()+OpenFlipper::Options::dirSeparator()+"PoissonReconstruction.png");
  emit addToolbox( tr("Poisson Reconstruction") , tool_, toolIcon_);
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105

  QString info =
  "This plugin is based on the code published by Michael Kazhdan and Matthew Bolitho<br>   "
  "<br>                                                                                    "
  "The following license applies to their code: <br>                                       "
  "Copyright (c) 2006, Michael Kazhdan and Matthew Bolitho <br>                            "
  "All rights reserved. <br>                                                               "
  "<br>                                                                                    "
  "Redistribution and use in source and binary forms, with or without modification,        "
  "are permitted provided that the following conditions are met: <br>                      "
  "<br>                                                                                    "
  "Redistributions of source code must retain the above copyright notice, this list of     "
  "conditions and the following disclaimer. Redistributions in binary form must reproduce  "
  "the above copyright notice, this list of conditions and the following disclaimer        "
  "in the documentation and/or other materials provided with the distribution. <br>        "
  "<br>                                                                                    "
  "Neither the name of the Johns Hopkins University nor the names of its contributors      "
  "may be used to endorse or promote products derived from this software without specific  "
  "prior written permission.  <br>                                                         "
  "<br>                                                                                    "
  "THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY   "
  "EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO THE IMPLIED WARRANTIES     "
  "OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT     "
  "SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,           "
  "INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED    "
  "TO, PROCUREMENT OF SUBSTITUTE  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR     "
  "BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN        "
  "CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN      "
  "ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH     "
  "DAMAGE.                                                                                 ";

Matthias Möller's avatar
Matthias Möller committed
106
107
  emit addAboutInfo(info,"Poisson Reconstruction Plugin");

Matthias Möller's avatar
Matthias Möller committed
108
109
110
111
  WhatsThisGenerator whatGen("PoissonReconstruction");
  tool_->reconstructButton->setWhatsThis(tool_->reconstructButton->toolTip()+whatGen.generateLink());
  tool_->depthBox->setWhatsThis(tool_->depthBox->toolTip()+whatGen.generateLink("octree"));
  tool_->label->setWhatsThis(tool_->label->toolTip()+whatGen.generateLink("octree"));
112
113
114
}


115
116
void PoissonPlugin::pluginsInitialized()
{
Jan Möbius's avatar
Jan Möbius committed
117
118
119
120
121
122
  emit setSlotDescription("poissonReconstruct(int,int)",tr("Reconstruct a triangle mesh from the given object."),
      QStringList(tr("ObjectId;depth").split(';')),QStringList(tr("ObjectId of the object;octree depth").split(';')));
  emit setSlotDescription("poissonReconstruct(IdList,int)",tr("Reconstruct one triangle mesh from the given objects."),
      QStringList(tr("IdList;depth").split(';')),QStringList(tr("Id of the objects;octree depth").split(';')));

  emit setSlotDescription("poissonReconstruct(int)",tr("Reconstruct a triangle mesh from the given object. (Octree depth defaults to 7)"),
123
      QStringList(tr("ObjectId")),QStringList(tr("ObjectId of the object")));
Jan Möbius's avatar
Jan Möbius committed
124
  emit setSlotDescription("poissonReconstruct(IdList)",tr("Reconstruct one triangle mesh from the given objects. (Octree depth defaults to 7)"),
125
126
      QStringList(tr("IdList")),QStringList(tr("Id of the objects")));
}
127

Jan Möbius's avatar
Jan Möbius committed
128
void PoissonPlugin::poissonReconstruct(int _id, int _depth)
129
130
{
  IdList list(1,_id);
Jan Möbius's avatar
Jan Möbius committed
131
  poissonReconstruct(list, _depth);
132
}
133

Jan Möbius's avatar
Jan Möbius committed
134
void PoissonPlugin::poissonReconstruct(IdList _ids, int _depth)
135
{
136
137
  unsigned int n_points = 0;

Jan Möbius's avatar
Jan Möbius committed
138
139
  // Data container for the algorithm
  // holds two 3D vectors in 6 columns, first the position, followed by the normal of the point
140
  std::vector< Real > pt_data;
141

142
143
144
145
146
147
148
149
150
  //get data from objects
  for (IdList::iterator idIter = _ids.begin(); idIter != _ids.end(); ++idIter)
  {
    BaseObjectData* obj = 0;
    PluginFunctions::getObject(*idIter,obj);
    if ( obj == 0 ) {
      emit log(LOGERR , QString("Unable to get Object width id %1").arg(*idIter));
      continue;
    }
151

152
153
    //Triangle mesh
    if ( obj->dataType() == DATA_TRIANGLE_MESH) {
154
155

      // Get triangle mesh
156
      TriMesh* mesh = PluginFunctions::triMesh(obj);
157
158
159
160
161
162
163

      n_points += mesh->n_vertices();

      pt_data.reserve( n_points );
      TriMesh::VertexIter vit = mesh->vertices_begin();
      for ( ; vit != mesh->vertices_end(); ++vit )
      {
Jan Möbius's avatar
Jan Möbius committed
164
165
166
167
168
169
        pt_data.push_back( mesh->point( *vit )[0] );
        pt_data.push_back( mesh->point( *vit )[1] );
        pt_data.push_back( mesh->point( *vit )[2] );
        pt_data.push_back( mesh->normal( *vit )[0] );
        pt_data.push_back( mesh->normal( *vit )[1] );
        pt_data.push_back( mesh->normal( *vit )[2] );
170
171
      }
    }
172
173
174
175
    //Poly mesh
    else if ( obj->dataType() == DATA_POLY_MESH) {
      // Get poly mesh
      PolyMesh* mesh = PluginFunctions::polyMesh(obj);
176

177
      n_points += mesh->n_vertices();
178

179
180
181
182
      pt_data.reserve( n_points );
      PolyMesh::VertexIter vit = mesh->vertices_begin();
      for ( ; vit != mesh->vertices_end(); ++vit )
      {
Jan Möbius's avatar
Jan Möbius committed
183
184
185
186
187
188
        pt_data.push_back( mesh->point( *vit )[0] );
        pt_data.push_back( mesh->point( *vit )[1] );
        pt_data.push_back( mesh->point( *vit )[2] );
        pt_data.push_back( mesh->normal( *vit )[0] );
        pt_data.push_back( mesh->normal( *vit )[1] );
        pt_data.push_back( mesh->normal( *vit )[2] );
189
190
191
192
193
      }
    }
    //Splat cloud
    else if( obj->dataType() == DATA_SPLATCLOUD)
    {
Jan Möbius's avatar
Jan Möbius committed
194
195

      // Get splat cloud mesh
196
      SplatCloud* cloud = PluginFunctions::splatCloud(obj);
197

Jan Möbius's avatar
Jan Möbius committed
198
199
200
201
202
      if ( ! cloud->hasNormals() ) {
        emit log(LOGERR,"Splat cloud has no normals. Skipping it");
        continue;
      }

203
      n_points += cloud->numSplats();
204

205
206
207
208
209
210
211
212
213
214
215
216
217
      pt_data.reserve( n_points );
      for (unsigned i = 0 ; i < cloud->numSplats(); ++i )
      {
        pt_data.push_back( cloud->positions( i )[0] );
        pt_data.push_back( cloud->positions( i )[1] );
        pt_data.push_back( cloud->positions( i )[2] );
        pt_data.push_back( cloud->normals( i )[0] );
        pt_data.push_back( cloud->normals( i )[1] );
        pt_data.push_back( cloud->normals( i )[2] );
      }
    }
    else
      emit log(LOGERR,QString("ObjectType of Object with id %1 is unsupported").arg(*idIter));
218
219
220
  }


221
  //create and reconstruct mesh
222
223
  if ( !pt_data.empty() ) {

224
225
226
227
228
229
    // Add empty triangle mesh
    int meshId = -1;
    emit addEmptyObject ( DATA_TRIANGLE_MESH, meshId );

    TriMeshObject* finalObject = PluginFunctions::triMeshObject(meshId);

230
231
232
    // Get triangle mesh
    TriMesh* final_mesh = NULL;

233
234
    PluginFunctions::getMesh(meshId,final_mesh);

235
236
237
238
    //Reconstruct
    ACG::PoissonReconstructionT<TriMesh> pr;

    ACG::PoissonReconstructionT<TriMesh>::Parameter params;
Jan Möbius's avatar
Jan Möbius committed
239
    params.Depth = _depth;
240

241
242
243
    if ( pr.run( pt_data, *final_mesh, params ) ) {
      emit log(LOGINFO,"Reconstruction succeeded");
      emit updatedObject(meshId,UPDATE_ALL);
244
      finalObject->setName("Poisson Reconstruction.obj");
245
246
    } else {
      emit log(LOGERR,"Reconstruction failed");
247
      emit deleteObject( meshId );
248
249
250
    }

  }
251
252
253
254
255
}


void PoissonPlugin::slotPoissonReconstruct(){

Matthias Möller's avatar
Matthias Möller committed
256
257
258
  if ( ! OpenFlipper::Options::gui())
    return;

259
  IdList ids;
Jan Möbius's avatar
Jan Möbius committed
260
  for ( PluginFunctions::ObjectIterator o_it(PluginFunctions::TARGET_OBJECTS,(DATA_TRIANGLE_MESH | DATA_POLY_MESH | DATA_SPLATCLOUD )) ;o_it != PluginFunctions::objectsEnd(); ++o_it)
261
262
  {
    ids.push_back(o_it->id());
Jan Möbius's avatar
Jan Möbius committed
263
    std::cerr << "Added " << o_it->id() << std::endl;
264
  }
265

Jan Möbius's avatar
Jan Möbius committed
266
267
268
  const int depth = tool_->depthBox->value();

  poissonReconstruct(ids,depth);
269
270
271

}

Jan Möbius's avatar
Jan Möbius committed
272
#if QT_VERSION < 0x050000
273
Q_EXPORT_PLUGIN2( poissonplugin , PoissonPlugin );
Jan Möbius's avatar
Jan Möbius committed
274
#endif