Closed psarahdactyl closed 5 years ago
@psarahdactyl If you want to write the border points in cases like in one from the example you refer to then you can use something like this
#include <iostream>
#include "DGtal/base/Common.h"
#include "DGtal/io/readers/VolReader.h"
#include "DGtal/io/Color.h"
#include "DGtal/images/ImageSelector.h"
#include "DGtal/helpers/StdDefs.h"
#include "ConfigExamples.h"
#include "DGtal/io/boards/Board3D.h"
///////////////////////////////////////////////////////////////////////////////
using namespace std;
using namespace DGtal;
///////////////////////////////////////////////////////////////////////////////
int main( int argc, char** argv )
{
typedef SpaceND< 3,int > Z3;
typedef MetricAdjacency< Z3, 1 > Adj6;
typedef MetricAdjacency< Z3, 2 > Adj18;
typedef DigitalTopology< Adj6, Adj18 > DT6_18;
Adj6 adj6;
Adj18 adj18;
DT6_18 dt6_18( adj6, adj18, JORDAN_DT );
typedef Z3::Point Point;
typedef HyperRectDomain< Z3 > Domain;
typedef Domain::ConstIterator DomainConstIterator;
typedef DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet;
typedef Object<DT6_18, DigitalSet> ObjectType;
Point p1( -50, -50, -50 );
Point p2( 50, 50, 50 );
Domain domain( p1, p2 );
Point c( 0, 0 );
// diamond of radius 30
DigitalSet diamond_set( domain );
for ( DomainConstIterator it = domain.begin(); it != domain.end(); ++it )
{
if ( (*it - c ).norm1() <= 30 ) diamond_set.insertNew( *it );
}
ObjectType diamond( dt6_18, diamond_set );
// The following line takes almost no time.
ObjectType diamond_clone( diamond );
// Since one of the objects is modified, the set is duplicated at the following line
diamond_clone.pointSet().erase( c );
ObjectType bdiamond = diamond.border(); // one component
ObjectType bdiamond_clone = diamond_clone.border(); // two components
Board3D<> board;
board << SetMode3D(domain.className(), "Paving");
board << CustomColors3D(Color(250, 0,0),Color(250, 0,0));
for(auto it : bdiamond_clone.pointSet())
board << it;
board.saveOBJ("/home/kacper/dgtalBoard3D-1bis-points.obj");
return 0;
}
It is basically the example with some lines changed at the very end.
thank you so much! I wasn't quite sure how to use the Board class.
@psarahdactyl Great! Could you please close the issue if the solution helped you out.
@psarahdactyl By the way, you do not need the loop over points. You can send the object directly, i.e., replace
for(auto it : bdiamond_clone.pointSet())
board << it;
with board << bdiamond_clone;
Board3D more or less works like Viewer3D – you can send an object to it and control its appearance by modifiers: modes like Paving
or colors, etc. I am not the best person to explain this stuff but I am sure that we can help you with your further questions. So do not hesitate to ask. Also, examples are a good starting point. Good luck!
Sorry to ask so many questions, but say now I want to get the vertices and faces of the voxel geometry. I have been looking around the documentation and the inline header files for Display3D and Board3D and see that there is an addCube function which seems to deal with the actual geometry. Is there an easier way exposed to the user where I can access this? Maybe through the PointSet?
You should have a look to the brand new Shortcuts https://dgtal.org/doc/stable/moduleShortcuts.html
There are direct methods to export a digital surface to OBJ (either primal or dual surface) or to obtain easy vertices/faces accessors.
Like getSurfelRange or getPointelRange
Do I first need to make the DigitalTopology into a DigitalSurface?
typedef DigitalSetSelector< Domain, BIG_DS+HIGH_BEL_DS >::Type DigitalSet;
typedef MetricAdjacency< Z3, 2 > Adj18;
typedef DigitalTopology< Adj6, Adj18 > DT6_18;
Adj6 adj6;
Adj18 adj18;
DT6_18 dt6_18( adj6, adj18, JORDAN_DT );
typedef Object<DT6_18, DigitalSet> ObjectType;
typedef DigitalSetBoundary< Z3i::KSpace, DigitalSet > Boundary;
ObjectType b_scene = sc.border();
DigitalSet border = b_scene.pointSet();
Boundary boundary(Z3, border, Adj18);
I was trying to make a DigitalSetBoundary because it has a surfel iterator but I can't figure out how to use the constructor on line 192 of DigitalSetBoundary.h https://dgtal.org/doc/stable/classDGtal_1_1DigitalSetBoundary.html#aa8c18e7161085386f2aa9328a8382f11
I'm having trouble understanding what aKSpace
is. in the documentation it says it's a cellular grid space. Is this the same this as a Khalimsky space typedef KhalimskySpaceND<3,int> KSpace;
?
DigitalSetBoundary( ConstAlias<KSpace> aKSpace,
const DigitalSet & aSet,
const Adjacency & adj = Adjacency( true ) );
Yes it is.
If you want to construct a digital surface from a set, a binary image, or a point predicate (all these objects are really close), the makeLightDigitalSurface
or makeDigitalSurface
in the Shortcuts doc would do the job.
In most situations, no need to manually construct the KSpace, it is usually given by the container.
Thank you!
Yes it is. If you want to construct a digital surface from a set, a binary image, or a point predicate (all these objects are really close), the
makeLightDigitalSurface
ormakeDigitalSurface
in the Shortcuts doc would do the job.In most situations, no need to manually construct the KSpace, it is usually given by the container.
Hi @dcoeurjo,
I had a short follow-up question to this: it appears that makeDigitalSurface
as documented here can accept either an "indexed digital surface" or a "binary image" as input types. It's still not clear to me how I can use these functions with the "digital set" type as input.
Wonder if you're able to clarify (i.e. how can I obtain a digital surface given a digital set)? I am basically trying to import a triangle mesh from an OBJ file, voxelize it, obtain its digital surface (boundary), and save the result back as a quadrilateral mesh OBJ file.
Thank you very much.
Hello If you wish to construct the digital surface that is the boundary of a digital set, you can have a look at this doc https://dgtal-team.github.io/doc-pr/pr1736/moduleDigitalSurfaces.html#dgtal_digsurf_sec1_1 A DigitalSetBoundary class correspond to your purpose.
Otherwise there are helper functions that simply builds the set of cells forming the boundary (2-cells in 3D). This can be done by scanning the whole image as:
KSpace::SCellSet boundary;
Surfaces<KSpace>::sMakeBoundary( boundary, ks, set3d,
image.domain().lowerBound(),
image.domain().upperBound() );
where ks is your KSpace
and set3d is a DigitalSet.
Alternatively, you can use the mesh2vol
, volFillInterior
and volBoundary2obj
tools from https://github.com/DGtal-team/DGtalTools if you want to from the command line.
I want to avoid marching cube type artifacts in my obj files, where some of the surface is missing on the boundaries of the voxel grid. I get these when I make a DigitalSurface or a TrianglulatedSurface from a BinaryImage of my DigitalSet.
In this example, which I've gotten running on my own DigitalSet, I want to write out just the border voxels to an OBJ. Is there a way to do this?