DGtal  1.5.beta
standardDigitalPolyhedronBuilder3D.cpp File Reference
#include <iostream>
#include <queue>
#include "DGtal/base/Common.h"
#include "DGtal/helpers/StdDefs.h"
#include "DGtal/io/viewers/Viewer3D.h"
#include "DGtal/shapes/Shapes.h"
#include "DGtal/shapes/SurfaceMesh.h"
#include "DGtal/io/readers/SurfaceMeshReader.h"
#include "DGtal/geometry/volumes/DigitalConvexity.h"
#include "ConfigExamples.h"
Include dependency graph for standardDigitalPolyhedronBuilder3D.cpp:

Go to the source code of this file.

Namespaces

 DGtal
 DGtal is the top-level namespace which contains all DGtal functions and types.
 

Typedefs

typedef Z3i::Space Space
 
typedef Z3i::Integer Integer
 
typedef Z3i::KSpace KSpace
 
typedef Z3i::Domain Domain
 
typedef Z3i::SCell SCell
 
typedef Space::Point Point
 
typedef Space::RealPoint RealPoint
 
typedef Space::RealVector RealVector
 
typedef Space::Vector Vector
 
typedef std::vector< PointPointRange
 
typedef MedianPlane< false, true > Plane
 

Functions

int main (int argc, char **argv)
 

Detailed Description

This program 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.

This program 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 General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Author
Jacques-Olivier Lachaud (jacqu.nosp@m.es-o.nosp@m.livie.nosp@m.r.la.nosp@m.chaud.nosp@m.@uni.nosp@m.v-sav.nosp@m.oie..nosp@m.fr ) Laboratory of Mathematics (CNRS, UMR 5127), University of Savoie, France
Date
2022/06/20

An example file named standardDigitalPolyhedronBuilder3D

This file is part of the DGtal library.

Definition in file standardDigitalPolyhedronBuilder3D.cpp.

Typedef Documentation

◆ Domain

Definition at line 82 of file standardDigitalPolyhedronBuilder3D.cpp.

◆ Integer

Definition at line 80 of file standardDigitalPolyhedronBuilder3D.cpp.

◆ KSpace

Definition at line 81 of file standardDigitalPolyhedronBuilder3D.cpp.

◆ Plane

typedef MedianPlane< false, true > Plane

◆ Point

Definition at line 84 of file standardDigitalPolyhedronBuilder3D.cpp.

◆ PointRange

typedef std::vector<Point> PointRange

Definition at line 88 of file standardDigitalPolyhedronBuilder3D.cpp.

◆ RealPoint

◆ RealVector

◆ SCell

typedef Z3i::SCell SCell

Definition at line 83 of file standardDigitalPolyhedronBuilder3D.cpp.

◆ Space

typedef Z3i::Space Space

Definition at line 79 of file standardDigitalPolyhedronBuilder3D.cpp.

◆ Vector

Definition at line 87 of file standardDigitalPolyhedronBuilder3D.cpp.

Function Documentation

◆ main()

int main ( int  argc,
char **  argv 
)

Definition at line 122 of file standardDigitalPolyhedronBuilder3D.cpp.

123 {
124  trace.info() << "Usage: " << argv[ 0 ] << " <input.obj> <h> <view>" << std::endl;
125  trace.info() << "\tComputes a digital polyhedron from an OBJ file" << std::endl;
126  trace.info() << "\t- input.obj: choose your favorite mesh" << std::endl;
127  trace.info() << "\t- h [==1]: the digitization gridstep" << std::endl;
128  trace.info() << "\t- view [==31]: display vertices(1), common edges(2), positive side f edges(4), negative side f edges (8), faces(16)" << std::endl;
129  string filename = examplesPath + "samples/lion.obj";
130  std::string fn = argc > 1 ? argv[ 1 ] : filename; //< vol filename
131  double h = argc > 2 ? atof( argv[ 2 ] ) : 1.0;
132  int view = argc > 3 ? atoi( argv[ 3 ] ) : 31;
133  // Read OBJ file
134  std::ifstream input( fn.c_str() );
137  if ( ! ok )
138  {
139  trace.error() << "Unable to read obj file : " << fn << std::endl;
140  return 1;
141  }
142 
143  QApplication application(argc,argv);
144  typedef Viewer3D<Space,KSpace> MViewer;
145  MViewer viewer;
146  viewer.setWindowTitle("standardDigitalPolyhedronBuilder3D");
147  viewer.show();
148 
149  Point lo(-500,-500,-500);
150  Point up(500,500,500);
151  DigitalConvexity< KSpace > dconv( lo, up );
153 
154  auto vertices = std::vector<Point>( surfmesh.nbVertices() );
155  for ( auto v : surfmesh )
156  {
157  RealPoint p = (1.0 / h) * surfmesh.position( v );
158  Point q ( (Integer) round( p[ 0 ] ),
159  (Integer) round( p[ 1 ] ),
160  (Integer) round( p[ 2 ] ) );
161  vertices[ v ] = q;
162  }
163  std::set< Point > faces_set, pos_edges_set, neg_edges_set;
164  auto faceVertices = surfmesh.allIncidentVertices();
165 
166  trace.beginBlock( "Checking face planarity" );
167  std::vector< Plane > face_planes;
168  face_planes.resize( surfmesh.nbFaces() );
169  bool planarity = true;
170  for ( int f = 0; f < surfmesh.nbFaces() && planarity; ++f )
171  {
172  PointRange X;
173  for ( auto v : faceVertices[ f ] )
174  X.push_back( vertices[ v ] );
175  face_planes[ f ] = Plane( X[ 0 ], X[ 1 ], X[ 2 ] );
176  for ( int v = 3; v < X.size(); v++ )
177  if ( ! face_planes[ f ]( X[ v ] ) )
178  {
179  trace.error() << "Face " << f << " is not planar." << std::endl;
180  planarity = false; break;
181  }
182  }
183  trace.endBlock();
184  if ( ! planarity ) return 1;
185  trace.beginBlock( "Computing polyhedron" );
186  for ( int f = 0; f < surfmesh.nbFaces(); ++f )
187  {
188  PointRange X;
189  for ( auto v : faceVertices[ f ] )
190  X.push_back( vertices[ v ] );
191  auto F = dconv.relativeEnvelope( X, face_planes[ f ], Algorithm::DIRECT );
192  faces_set.insert( F.cbegin(), F.cend() );
193  for ( int i = 0; i < X.size(); i++ )
194  {
195  PointRange Y { X[ i ], X[ (i+1)%X.size() ] };
196  if ( Y[ 1 ] < Y[ 0 ] ) std::swap( Y[ 0 ], Y[ 1 ] );
197  int idx1 = faceVertices[ f ][ i ];
198  int idx2 = faceVertices[ f ][ (i+1)%X.size() ];
199  // Variant (1): edges of both sides have many points in common
200  // auto A = dconv.relativeEnvelope( Y, face_planes[ f ], Algorithm::DIRECT );
201  // Variant (2): edges of both sides have much less points in common
202  auto A = dconv.relativeEnvelope( Y, F, Algorithm::DIRECT );
203  bool pos = idx1 < idx2;
204  (pos ? pos_edges_set : neg_edges_set).insert( A.cbegin(), A.cend() );
205  }
206  }
207  trace.endBlock();
208  std::vector< Point > face_points, common_edge_points, arc_points, final_arc_points ;
209  std::vector< Point > pos_edge_points, neg_edge_points, both_edge_points;
210  std::vector< Point > vertex_points = vertices;
211  std::sort( vertex_points.begin(), vertex_points.end() );
212  std::set_symmetric_difference( pos_edges_set.cbegin(), pos_edges_set.cend(),
213  neg_edges_set.cbegin(), neg_edges_set.cend(),
214  std::back_inserter( arc_points ) );
215  std::set_intersection( pos_edges_set.cbegin(), pos_edges_set.cend(),
216  neg_edges_set.cbegin(), neg_edges_set.cend(),
217  std::back_inserter( common_edge_points ) );
218  std::set_union( pos_edges_set.cbegin(), pos_edges_set.cend(),
219  neg_edges_set.cbegin(), neg_edges_set.cend(),
220  std::back_inserter( both_edge_points ) );
221  std::set_difference( faces_set.cbegin(), faces_set.cend(),
222  both_edge_points.cbegin(), both_edge_points.cend(),
223  std::back_inserter( face_points ) );
224  std::set_difference( pos_edges_set.cbegin(), pos_edges_set.cend(),
225  common_edge_points.cbegin(), common_edge_points.cend(),
226  std::back_inserter( pos_edge_points ) );
227  std::set_difference( neg_edges_set.cbegin(), neg_edges_set.cend(),
228  common_edge_points.cbegin(), common_edge_points.cend(),
229  std::back_inserter( neg_edge_points ) );
230  std::set_difference( common_edge_points.cbegin(), common_edge_points.cend(),
231  vertex_points.cbegin(), vertex_points.cend(),
232  std::back_inserter( final_arc_points ) );
233  auto total = vertex_points.size() + pos_edge_points.size()
234  + neg_edge_points.size()
235  + final_arc_points.size() + face_points.size();
236  trace.info() << "#vertex points=" << vertex_points.size() << std::endl;
237  trace.info() << "#pos edge points=" << pos_edge_points.size() << std::endl;
238  trace.info() << "#neg edge points=" << neg_edge_points.size() << std::endl;
239  trace.info() << "#arc points=" << final_arc_points.size() << std::endl;
240  trace.info() << "#face points=" << face_points.size() << std::endl;
241  trace.info() << "#total points=" << total << std::endl;
242 
243  // display everything
244  Color colors[] =
245  { Color::Black, Color::Blue, Color::Red,
246  Color::Magenta, Color( 200, 200, 200 ) };
247  if ( view & 0x1 )
248  {
249  viewer.setLineColor( colors[ 0 ] );
250  viewer.setFillColor( colors[ 0 ] );
251  for ( auto p : vertices ) viewer << p;
252  }
253  if ( view & 0x2 )
254  {
255  viewer.setLineColor( colors[ 3 ] );
256  viewer.setFillColor( colors[ 3 ] );
257  for ( auto p : final_arc_points ) viewer << p;
258  }
259  if ( view & 0x4 )
260  {
261  viewer.setLineColor( colors[ 1 ] );
262  viewer.setFillColor( colors[ 1 ] );
263  for ( auto p : pos_edge_points ) viewer << p;
264  }
265  if ( view & 0x8 )
266  {
267  viewer.setLineColor( colors[ 2 ] );
268  viewer.setFillColor( colors[ 2 ] );
269  for ( auto p : neg_edge_points ) viewer << p;
270  }
271  if ( view & 0x10 )
272  {
273  viewer.setLineColor( colors[ 4 ] );
274  viewer.setFillColor( colors[ 4 ] );
275  for ( auto p : face_points ) viewer << p;
276  }
277  viewer << MViewer::updateDisplay;
278  return application.exec();
279 
280 }
Structure representing an RGB triple with alpha component.
Definition: Color.h:68
PointRange relativeEnvelope(const PointRange &Z, const PointRange &Y, EnvelopeAlgorithm algo=EnvelopeAlgorithm::DIRECT) const
std::ostream & error()
void beginBlock(const std::string &keyword="")
std::ostream & info()
double endBlock()
virtual void show()
Overload QWidget method in order to add a call to updateList() method (to ensure that the lists are w...
SurfMesh surfmesh
std::vector< Point > PointRange
Trace trace
Definition: Common.h:153
std::pair< typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_iterator, typename graph_traits< DGtal::DigitalSurface< TDigitalSurfaceContainer > >::vertex_iterator > vertices(const DGtal::DigitalSurface< TDigitalSurfaceContainer > &digSurf)
MedianPlane< false, true > Plane
Aim: An helper class for reading mesh files (Wavefront OBJ at this point) and creating a SurfaceMesh.
Aim: Represents an embedded mesh as faces and a list of vertices. Vertices may be shared among faces ...
Definition: SurfaceMesh.h:92
RealPoint & position(Vertex v)
Definition: SurfaceMesh.h:647
Size nbFaces() const
Definition: SurfaceMesh.h:296
const std::vector< Vertices > & allIncidentVertices() const
Definition: SurfaceMesh.h:371
Size nbVertices() const
Definition: SurfaceMesh.h:288
MyPointD Point
Definition: testClone2.cpp:383
void insert(VContainer1 &c1, LContainer2 &c2, unsigned int idx, double v)

References DGtal::SurfaceMesh< TRealPoint, TRealVector >::allIncidentVertices(), DGtal::Trace::beginBlock(), DGtal::Trace::endBlock(), DGtal::Trace::error(), DGtal::Trace::info(), insert(), DGtal::SurfaceMesh< TRealPoint, TRealVector >::nbFaces(), DGtal::SurfaceMesh< TRealPoint, TRealVector >::nbVertices(), DGtal::SurfaceMesh< TRealPoint, TRealVector >::position(), DGtal::DigitalConvexity< TKSpace >::relativeEnvelope(), DGtal::Viewer3D< TSpace, TKSpace >::show(), surfmesh, and DGtal::trace.