23 #include "DGtal/io/readers/VolReader.h"
24 #include "DGtal/io/viewers/Viewer3D.h"
25 #include "DGtal/topology/SurfelAdjacency.h"
26 #include "DGtal/topology/LightImplicitDigitalSurface.h"
27 #include "DGtal/topology/DigitalSurface.h"
28 #include "DGtal/math/linalg/EigenSupport.h"
29 #include "DGtal/dec/DiscreteExteriorCalculus.h"
30 #include "DGtal/dec/DiscreteExteriorCalculusSolver.h"
31 #include "DGtal/dec/DiscreteExteriorCalculusFactory.h"
33 #include "ConfigExamples.h"
38 template <
typename Predicate,
typename Domain>
39 struct FalseOutsideDomain
47 myPredicate(&predicate), myDomain(&adomain)
52 operator()(
const Point& point)
const
54 if (!myDomain->isInside(point))
return false;
55 return (*myPredicate)(point);
58 const Predicate* myPredicate;
70 const std::string filename = examplesPath +
"samples/Al.100.vol";
82 typedef FalseOutsideDomain<Image, DGtal::Z3i::Domain> ImageExtended;
83 const ImageExtended image_extended(image,
domain);
91 const SurfelAdjacency surfel_adjacency(
true);
94 const DigitalSurfaceContainer digital_surface_container(kspace, image_extended, surfel_adjacency, cell_bel);
97 const DigitalSurface digital_surface(digital_surface_container);
100 trace.
info() <<
"digital_surface_size=" << digital_surface.size() << endl;
105 viewer->setWindowTitle(
"alcapone surface");
121 const Calculus calculus = CalculusFactory::createFromNSCells<2>(digital_surface.begin(), digital_surface.end(),
false);
123 trace.
info() <<
"calculus=" << calculus << endl;
128 viewer->setWindowTitle(
"alcapone calculus");
141 Calculus::DualForm0 rho(calculus);
142 for (
int index=0; index<rho.length(); index++)
144 const Calculus::SCell cell = rho.getSCell(index);
146 if (point[2]>1)
continue;
147 rho.myContainer(index) = point[1]>100 ? 1 : -1;
149 trace.
info() <<
"rho_range=" << rho.myContainer.minCoeff() <<
"/" << rho.myContainer.maxCoeff() << endl;
155 viewer->setWindowTitle(
"alcapone poisson rho");
161 const Calculus::DualIdentity0 laplace = calculus.laplace<
DUAL>();
165 PoissonSolver solver;
167 const Calculus::DualForm0 phi = solver.
solve(rho);
168 trace.
info() <<
"phi_range=" << phi.myContainer.minCoeff() <<
"/" << phi.myContainer.maxCoeff() << endl;
174 viewer->setWindowTitle(
"alcapone poisson phi");
195 trace.
info() <<
"input_domain=" << input_domain << endl;
198 kspace.
init(input_domain.lowerBound(), input_domain.upperBound(),
true);
208 trace.
info() <<
"input_set_size=" << input_set.size() << endl;
213 viewer->setWindowTitle(
"input set");
214 (*viewer) << input_set;
222 const SurfelAdjacency surfel_adjacency(
true);
225 const DigitalSurfaceContainer digital_surface_container(kspace, input_set, surfel_adjacency, cell_bel);
228 const DigitalSurface digital_surface(digital_surface_container);
231 trace.
info() <<
"surfel_adjacency=" << endl;
232 for (
int ii=0; ii<3; ii++)
234 std::stringstream ss;
235 for (
int jj=0; jj<3; jj++)
236 ss << surfel_adjacency.getAdjacency(ii, jj) <<
" ";
240 trace.
info() <<
"digital_surface_container=" << digital_surface_container << endl;
242 trace.
info() <<
"digital_surface_size=" << digital_surface.size() << endl;
247 viewer->setWindowTitle(
"digital surface");
263 const Calculus calculus = CalculusFactory::createFromNSCells<2>(digital_surface.begin(), digital_surface.end());
265 trace.
info() <<
"calculus=" << calculus << endl;
270 viewer->setWindowTitle(
"discrete exterior calculus");
278 const Calculus::PrimalForm2 primal_surfel_area = calculus.hodge<0,
DUAL>() *
279 Calculus::DualForm0(calculus, Eigen::VectorXd::Ones(calculus.kFormLength(0, DUAL)));
281 const Calculus::DualForm2 dual_surfel_area = calculus.hodge<0,
PRIMAL>() *
282 Calculus::PrimalForm0(calculus, Eigen::VectorXd::Ones(calculus.kFormLength(0, PRIMAL)));
284 const double area_th = calculus.kFormLength(2, PRIMAL);
285 const double area_primal = dual_surfel_area.myContainer.sum();
286 const double area_dual = primal_surfel_area.myContainer.sum();
287 trace.
info() <<
"area_th=" << area_th << endl;
288 trace.
info() <<
"area_primal=" << area_primal << endl;
289 trace.
info() <<
"area_dual=" << area_dual << endl;
290 FATAL_ERROR( area_th == area_primal );
291 FATAL_ERROR( area_th == area_dual );
293 const Calculus::DualForm1 dual_edge_length = calculus.hodge<1,
PRIMAL>() *
294 Calculus::PrimalForm1(calculus, Eigen::VectorXd::Ones(calculus.kFormLength(1, PRIMAL)));
296 const bool dual_edge_length_match = dual_edge_length.myContainer == Eigen::VectorXd::Ones(calculus.kFormLength(1, DUAL)) ;
297 trace.
info() <<
"dual_edge_length_match=" << dual_edge_length_match << endl;
298 FATAL_ERROR( dual_edge_length_match );
302 for (Calculus::Index index=0; index<dual_surfel_area.length(); index++)
304 const Calculus::SCell cell = dual_surfel_area.getSCell(index);
305 const Calculus::Scalar area = dual_surfel_area.myContainer(index);
306 trace.
info() << index <<
" " << cell <<
" " << area << endl;
316 int main(
int argc,
char* argv[])
318 QApplication app(argc, argv);