Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Philip Trettner
polymesh
Commits
913e7b51
Commit
913e7b51
authored
Jul 04, 2018
by
Philip Trettner
Browse files
added components algorithm and stats
parent
3499cd38
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/polymesh/algorithms.hh
View file @
913e7b51
...
...
@@ -19,8 +19,13 @@
// - intersections
#include "algorithms/operations.hh"
// Mesh statistics
#include "algorithms/components.hh"
// WIP: #include "algorithms/stats.hh"
// Geodesics
#include "algorithms/geodesic_nnf.hh"
// WIP: #include "algorithms/geodesic_fast_marching.hh"
// WIP: #include "algorithms/geodesic_nnf.hh"
// TODO:
// - decimation
...
...
src/polymesh/algorithms/components.hh
0 → 100644
View file @
913e7b51
#pragma once
#include "../Mesh.hh"
#include <queue>
namespace
polymesh
{
/// Calculates the number of connected components based on vertex connectivity
/// (reports wiremeshes as connected)
/// Returns a vertex attribute for 0-based per-vertex component
/// Optionally returns the total number of components in `comps`
vertex_attribute
<
int
>
vertex_components
(
Mesh
const
&
m
,
int
*
comps
=
nullptr
);
/// Calculates the number of connected components based on face connectivity
/// (only counts face-edge-face as connected)
/// Returns a face attribute for 0-based per-face component
/// Optionally returns the total number of components in `comps`
face_attribute
<
int
>
face_components
(
Mesh
const
&
m
,
int
*
comps
=
nullptr
);
/// ======== IMPLEMENTATION ========
inline
vertex_attribute
<
int
>
vertex_components
(
Mesh
const
&
m
,
int
*
comps
)
{
auto
comp
=
m
.
vertices
().
make_attribute_with_default
(
-
1
);
auto
c_cnt
=
0
;
for
(
auto
seed
:
m
.
vertices
())
if
(
comp
[
seed
]
==
-
1
)
{
std
::
queue
<
vertex_handle
>
q
;
q
.
push
(
seed
);
seed
[
comp
]
=
c_cnt
;
while
(
!
q
.
empty
())
{
auto
v
=
q
.
front
();
q
.
pop
();
for
(
auto
vv
:
v
.
adjacent_vertices
())
if
(
vv
[
comp
]
!=
c_cnt
)
{
vv
[
comp
]
=
c_cnt
;
q
.
push
(
vv
);
}
}
++
c_cnt
;
}
if
(
comps
)
*
comps
=
c_cnt
;
return
comp
;
}
inline
face_attribute
<
int
>
face_components
(
Mesh
const
&
m
,
int
*
comps
)
{
auto
comp
=
m
.
faces
().
make_attribute_with_default
(
-
1
);
auto
c_cnt
=
0
;
for
(
auto
seed
:
m
.
faces
())
if
(
comp
[
seed
]
==
-
1
)
{
std
::
queue
<
face_handle
>
q
;
q
.
push
(
seed
);
seed
[
comp
]
=
c_cnt
;
while
(
!
q
.
empty
())
{
auto
f
=
q
.
front
();
q
.
pop
();
for
(
auto
ff
:
f
.
adjacent_faces
())
if
(
ff
[
comp
]
!=
c_cnt
)
{
ff
[
comp
]
=
c_cnt
;
q
.
push
(
ff
);
}
}
++
c_cnt
;
}
if
(
comps
)
*
comps
=
c_cnt
;
return
comp
;
}
}
src/polymesh/algorithms/stats.hh
0 → 100644
View file @
913e7b51
#pragma once
#include <iostream>
#include "../Mesh.hh"
#include "../fields.hh"
#include "components.hh"
namespace
polymesh
{
/// Prints statistics for the given mesh, including:
/// - number of primitives
/// - components
/// - aabb
template
<
class
Vec3
=
void
>
void
print_stats
(
std
::
ostream
&
out
,
Mesh
const
&
m
,
vertex_attribute
<
Vec3
>
const
*
position
=
nullptr
);
/// ======== IMPLEMENTATION ========
template
<
class
Vec3
>
void
print_stats
(
std
::
ostream
&
out
,
Mesh
const
&
m
,
vertex_attribute
<
Vec3
>
const
*
position
)
{
auto
ln
=
"
\n
"
;
out
<<
"[Mesh]:"
<<
ln
;
// # verts, faces, edges, hedges
out
<<
" Vertices: "
<<
m
.
vertices
().
size
();
if
(
m
.
vertices
().
size
()
!=
m
.
all_vertices
().
size
())
out
<<
" ("
<<
m
.
all_vertices
().
size
()
-
m
.
vertices
().
size
()
<<
" removed)"
;
out
<<
ln
;
out
<<
" Faces: "
<<
m
.
faces
().
size
();
if
(
m
.
faces
().
size
()
!=
m
.
all_faces
().
size
())
out
<<
" ("
<<
m
.
all_faces
().
size
()
-
m
.
faces
().
size
()
<<
" removed)"
;
out
<<
ln
;
out
<<
" Edges: "
<<
m
.
edges
().
size
();
if
(
m
.
edges
().
size
()
!=
m
.
all_edges
().
size
())
out
<<
" ("
<<
m
.
all_edges
().
size
()
-
m
.
edges
().
size
()
<<
" removed)"
;
out
<<
ln
;
out
<<
" Half-edges: "
<<
m
.
halfedges
().
size
();
if
(
m
.
halfedges
().
size
()
!=
m
.
all_halfedges
().
size
())
out
<<
" ("
<<
m
.
all_halfedges
().
size
()
-
m
.
halfedges
().
size
()
<<
" removed)"
;
out
<<
ln
;
if
(
m
.
vertices
().
empty
())
return
;
// no vertices, no further stats
out
<<
ln
;
// # isolated, components, boundaries, genus
int
face_comps
;
int
vertex_comps
;
vertex_components
(
m
,
&
vertex_comps
);
face_components
(
m
,
&
face_comps
);
out
<<
" Vertex Components: "
<<
vertex_comps
<<
ln
;
out
<<
" Face Components: "
<<
face_comps
<<
ln
;
// TODO: genus
// TODO: boundaries
// TODO: isolated verts, edges
if
(
position
)
{
out
<<
ln
;
auto
const
&
pos
=
*
position
;
auto
aabb
=
m
.
vertices
().
aabb
(
pos
);
auto
min
=
aabb
.
min
;
auto
max
=
aabb
.
max
;
out
<<
" AABB Min: "
<<
field_3d
<
Vec3
>::
to_string
(
min
)
<<
ln
;
out
<<
" AABB Max: "
<<
field_3d
<
Vec3
>::
to_string
(
max
)
<<
ln
;
out
<<
" AABB Size: "
<<
field_3d
<
Vec3
>::
to_string
(
max
-
min
)
<<
ln
;
auto
avg
=
m
.
vertices
().
avg
(
pos
);
out
<<
" Vertex Centroid: "
<<
field_3d
<
Vec3
>::
to_string
(
avg
)
<<
ln
;
}
}
}
src/polymesh/fields.hh
View file @
913e7b51
...
...
@@ -2,6 +2,8 @@
#include <cmath>
#include <cstddef>
#include <sstream>
#include <string>
#include <utility>
namespace
polymesh
...
...
@@ -37,5 +39,12 @@ struct field_3d
{
return
static_cast
<
Scalar
>
(
t
);
}
static
std
::
string
to_string
(
Vec3
const
&
v
)
{
std
::
stringstream
ss
;
ss
<<
"("
<<
v
[
0
]
<<
", "
<<
v
[
1
]
<<
", "
<<
v
[
2
]
<<
")"
;
return
ss
.
str
();
}
};
}
src/polymesh/impl/impl_ranges.hh
View file @
913e7b51
...
...
@@ -39,12 +39,13 @@ ElementT smart_range<this_t, ElementT>::last() const
template
<
class
this_t
,
class
ElementT
>
bool
smart_range
<
this_t
,
ElementT
>::
any
()
const
{
for
(
auto
h
:
*
static_cast
<
this_t
const
*>
(
this
))
{
(
void
)
h
;
// unused
return
true
;
}
return
false
;
return
static_cast
<
this_t
const
*>
(
this
)
->
begin
()
!=
static_cast
<
this_t
const
*>
(
this
)
->
end
();
}
template
<
class
this_t
,
class
ElementT
>
bool
smart_range
<
this_t
,
ElementT
>::
empty
()
const
{
return
static_cast
<
this_t
const
*>
(
this
)
->
begin
()
==
static_cast
<
this_t
const
*>
(
this
)
->
end
();
}
template
<
class
this_t
,
class
ElementT
>
...
...
src/polymesh/ranges.hh
View file @
913e7b51
...
...
@@ -34,6 +34,8 @@ struct smart_range
/// TODO: how to make this O(1)
ElementT
last
()
const
;
/// returns true if the range is empty
bool
empty
()
const
;
/// returns true if the range is non-empty
bool
any
()
const
;
/// returns true if any value fulfils p(v)
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment