DGtal 1.4.0
Loading...
Searching...
No Matches
windingNumbersShape.cpp
1
25#include <iostream>
26#include <string>
27#include <algorithm>
28#include <fstream> // std::ofstream
29
30#include <DGtal/base/Common.h>
31#include <DGtal/helpers/StdDefs.h>
32#include <DGtal/helpers/Shortcuts.h>
33#include <DGtal/helpers/ShortcutsGeometry.h>
34#include <polyscope/polyscope.h>
35#include <polyscope/surface_mesh.h>
36#include <polyscope/point_cloud.h>
37
38#include <DGtal/shapes/WindingNumbersShape.h>
39#include <DGtal/shapes/GaussDigitizer.h>
40
41#include "ConfigExamples.h"
42
43using namespace DGtal;
44using namespace Z3i;
45
46// Using standard 3D digital space.
49// The following typedefs are useful
51
52int main()
53{
55 params("surfaceComponents", "All")( "gridstep", 1. )("r-radius" , 4.0);
56
57 std::string filename = examplesPath + std::string("/samples/bunny-32.vol");
58 auto binary_image = SH3::makeBinaryImage(filename, params );
59 auto K = SH3::getKSpace( binary_image, params );
62 auto primalSurface = SH3::makePrimalSurfaceMesh(surface);
63 auto surfels = SH3::getSurfelRange( surface, params);
64 auto embedder = SH3::getSCellEmbedder( K );
65
66
67 //Need to convert the faces
68 std::vector<std::vector<SH3::SurfaceMesh::Vertex>> faces;
69 std::vector<RealPoint> positions;
70 for(auto face= 0 ; face < primalSurface->nbFaces(); ++face)
71 faces.push_back(primalSurface->incidentVertices( face ));
72 //Recasting to vector of vertices
73 positions = primalSurface->positions();
74
75 auto surfmesh = SurfMesh(positions.begin(),
76 positions.end(),
77 faces.begin(),
78 faces.end());
79
80
81 trace.info()<<"Got "<<surfels.size()<<" surfels."<<std::endl;
82
83 // Initialize polyscope
84 polyscope::init();
85
86 auto iinormals = SHG3::getIINormalVectors(binary_image, surfels, params);
87 auto psMesh = polyscope::registerSurfaceMesh("input digital surface", positions, faces);
88 psMesh->addFaceVectorQuantity("normals", iinormals);
89
90 Eigen::MatrixXd points(surfels.size(),3);
91 Eigen::MatrixXd normals(surfels.size(),3);
92 std::ofstream ofs ("bunny.pts", std::ofstream::out);
93 for(auto i=0; i< surfels.size(); ++i)
94 {
95 auto p = embedder(surfels[i]);
96 auto n = iinormals[i];
97 points(i,0) = p(0);
98 points(i,1) = p(1);
99 points(i,2) = p(2);
100 normals(i,0) = n(0);
101 normals(i,1) = n(1);
102 normals(i,2) = n(2);
103
104 ofs<<p(0)<<" "<<p(1)<<" "<<p(2)<<" "<<n(0)<<" "<< n(1)<<" "<<n(2)<<std::endl;
105 }
106 ofs.close();
107 auto pc= polyscope::registerPointCloud("input boundary points", points);
108 pc->addVectorQuantity("normals", normals);
109
110 //Winding number shape
111 WindingNumbersShape<Z3i::Space> wnshape(points,normals);
112
113
114 auto lower = binary_image->domain().lowerBound();
115 auto upper = binary_image->domain().upperBound();
116
117 auto resample_h = [&](double h){
118
120 pointEmbedder.init( h );
121 Z3i::Point lowerPoint = pointEmbedder.floor( lower );
122 Z3i::Point upperPoint = pointEmbedder.ceil( upper );
123 Z3i::Domain domain(lowerPoint,upperPoint);
124 trace.info() <<"Digital domain = "<<domain.size()<<" " <<domain<<std::endl;
125
126 //Winding (batched)
127 size_t size = domain.size();
128 Eigen::MatrixXd queries(size,3);
129 auto cpt=0;
130 for(const auto &vox: domain)
131 {
132 Eigen::RowVector3<double> p(vox[0],vox[1],vox[2]);
133 p *= h;
134 queries.row(cpt) = p;
135 ++cpt;
136 }
137 trace.info()<<"Cpt= "<<cpt<<" size= "<<size<<std::endl;
138 auto orientations = wnshape.orientationBatch(queries);
139
140 //Binary Predicate
141 Z3i::DigitalSet voxels(domain);
142 cpt=0;
143 for(const auto &voxel: domain)
144 {
145 if (orientations[cpt]==INSIDE)
146 voxels.insertNew(voxel);
147 ++cpt;
148 }
149 trace.info() <<"Number of voxels = "<<voxels.size()<<std::endl;
150
151 //Digital surface
152 Z3i::KSpace kspace;
153 kspace.init(lowerPoint, upperPoint, true);
155 typedef SetOfSurfels< KSpace, SurfelSet > MySetOfSurfels;
157 typedef SurfelAdjacency<KSpace::dimension> MySurfelAdjacency;
158
159 MySurfelAdjacency surfAdj( true ); // interior in all directions.
160 MySetOfSurfels theSetOfSurfels( kspace, surfAdj );
161 Surfaces<KSpace>::sMakeBoundary(theSetOfSurfels.surfelSet(),
162 kspace,
163 voxels,
164 lowerPoint,
165 upperPoint);
166 trace.info()<<"Surfel set size= "<<theSetOfSurfels.surfelSet().size()<<std::endl;
167
168 //Polyscope visualization
169 auto surfPtr = CountedPtr<DigitalSurface< MySetOfSurfels >>(new MyDigitalSurface(theSetOfSurfels));
170 auto primalSurfaceReco = SH3::makePrimalSurfaceMesh(surfPtr);
171
172 std::vector<RealPoint> positionsReco = primalSurfaceReco->positions();
173 //Fixing the embedding
174 std::for_each(std::begin(positionsReco), std::end(positionsReco), [&](RealPoint &p){p=p*h;});
175
176 std::vector<std::vector<SH3::SurfaceMesh::Vertex>> facesReco;
177 for(auto face= 0 ; face < primalSurfaceReco->nbFaces(); ++face)
178 facesReco.push_back(primalSurfaceReco->incidentVertices( face ));
179 auto psMesh = polyscope::registerSurfaceMesh("Reconstruction "+std::to_string(h), positionsReco, facesReco);
180 };
181
182 resample_h(1.0);
183 resample_h(2.0); //downscaling
184 resample_h(0.5); //upscaling
185#if defined(NDEBUG)
186 resample_h(0.2); //upscaling
187 resample_h(0.2); //upscaling
188#else
189 trace.warning() << "CMake Debug mode detected, limiting upscaling to 0.5.";
190#endif
191 //resample_h(0.07); //extreme upscaling, 2M vertices
192
193 // Set the callback function
194 polyscope::show();
195 return EXIT_SUCCESS;
196}
Aim: Smart pointer based on reference counts.
Definition CountedPtr.h:80
Aim: A wrapper class around a STL associative container for storing sets of digital points within som...
Aim: Represents a set of n-1-cells in a nD space, together with adjacency relation between these cell...
Aim: This class is a model of CCellularGridSpaceND. It represents the cubical grid as a cell complex,...
std::set< SCell > SurfelSet
Preferred type for defining a set of surfels (always signed cells).
bool init(const Point &lower, const Point &upper, bool isClosed)
Specifies the upper and lower bounds for the maximal cells in this space.
Aim: A simple point embedder where grid steps are given for each axis. Note that the real point (0,...
Point floor(const RealPoint &p) const
Point ceil(const RealPoint &p) const
void init(typename RealVector::Component gridStep)
Aim: A model of CDigitalSurfaceContainer which defines the digital surface as connected surfels....
Aim: This class is used to simplify shape and surface creation. With it, you can create new shapes an...
static Parameters parametersGeometryEstimation()
static RealVectors getIINormalVectors(CountedPtr< BinaryImage > bimage, const SurfelRange &surfels, const Parameters &params=parametersGeometryEstimation()|parametersKSpace())
static Parameters defaultParameters()
Aim: This class is used to simplify shape and surface creation. With it, you can create new shapes an...
Definition Shortcuts.h:105
static KSpace getKSpace(const Point &low, const Point &up, Parameters params=parametersKSpace())
Definition Shortcuts.h:332
std::map< Cell, IdxVertex > Cell2Index
Definition Shortcuts.h:189
static SurfelRange getSurfelRange(CountedPtr< ::DGtal::DigitalSurface< TDigitalSurfaceContainer > > surface, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1547
static CanonicSCellEmbedder< KSpace > getSCellEmbedder(const KSpace &K)
Definition Shortcuts.h:446
static CountedPtr< DigitalSurface > makeDigitalSurface(CountedPtr< TPointPredicate > bimage, const KSpace &K, const Parameters &params=parametersDigitalSurface())
Definition Shortcuts.h:1209
static Parameters defaultParameters()
Definition Shortcuts.h:203
static CountedPtr< SurfaceMesh > makePrimalSurfaceMesh(Cell2Index &c2i, CountedPtr< ::DGtal::DigitalSurface< TContainer > > aSurface)
Definition Shortcuts.h:2372
static CountedPtr< BinaryImage > makeBinaryImage(Domain shapeDomain)
Definition Shortcuts.h:561
static void sMakeBoundary(SCellSet &aBoundary, const KSpace &aKSpace, const PointPredicate &pp, const Point &aLowerBound, const Point &aUpperBound)
Aim: Represent adjacencies between surfel elements, telling if it follows an interior to exterior ord...
std::ostream & warning()
std::ostream & info()
polyscope::SurfaceMesh * psMesh
SurfMesh surfmesh
CountedPtr< SH3::DigitalSurface > surface
CountedPtr< SH3::BinaryImage > binary_image
SHG3::RealVectors iinormals
DigitalSurface< MyDigitalSurfaceContainer > MyDigitalSurface
MyDigitalSurface::SurfelSet SurfelSet
DGtal is the top-level namespace which contains all DGtal functions and types.
Trace trace
Definition Common.h:153
@ INSIDE
Definition Common.h:141
Aim: Represents an embedded mesh as faces and a list of vertices. Vertices may be shared among faces ...
Definition SurfaceMesh.h:92
Aim: model of a CEuclideanOrientedShape from an implicit function from an oriented point cloud....
int main(int argc, char **argv)
KSpace K
Domain domain
Vector lower(const Vector &z, unsigned int k)
Vector upper(const Vector &z, unsigned int k)