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
c8c4f882
Commit
c8c4f882
authored
Jul 03, 2018
by
Philip Trettner
Browse files
renamed PropT to AttrT, added copy from data for attributes
parent
9746ec6e
Changes
10
Hide whitespace changes
Inline
Side-by-side
Readme.md
View file @
c8c4f882
...
...
@@ -23,4 +23,5 @@ Best used with glm and glow.
*
make handle.
<primitives>
() contain only valid ones and provide an all_
<primitives>
() version
*
_copy versions of topological operations that copy attributes
*
vertex split?
*
half-edge collapse
\ No newline at end of file
*
half-edge collapse
*
normal, tangent, bitangent computation
\ No newline at end of file
src/polymesh/algorithms.hh
View file @
c8c4f882
...
...
@@ -19,6 +19,9 @@
// - intersections
#include "algorithms/operations.hh"
// Geodesics
#include "algorithms/geodesic_nnf.hh"
// TODO:
// - decimation
// - subdivision
...
...
src/polymesh/algorithms/geodesic_nnf.hh
0 → 100644
View file @
c8c4f882
#pragma once
#include "../Mesh.hh"
#include "../fields.hh"
namespace
polymesh
{
/**
* @brief Implements geodesic distances using the NNF algorithm
*
* Usage:
*
* auto nnf = make_geodesic_nnf(mesh, positions);
*/
template
<
class
Vec3
,
class
Scalar
=
typename
field_3d
<
Vec3
>
::
Scalar
>
struct
GeodesicNNF
{
public:
GeodesicNNF
(
Mesh
const
&
m
,
vertex_attribute
<
Vec3
>
const
&
position
);
private:
Mesh
const
&
mesh
;
vertex_attribute
<
Vec3
>
const
&
position
;
};
template
<
class
Vec3
,
class
Scalar
=
typename
field_3d
<
Vec3
>
::
Scalar
>
GeodesicNNF
<
Vec3
,
Scalar
>
make_geodesic_nnf
(
Mesh
const
&
m
,
vertex_attribute
<
Vec3
>
const
&
position
);
}
// Implementation
#include "geodesic_nnf.impl.hh"
src/polymesh/algorithms/geodesic_nnf.impl.hh
0 → 100644
View file @
c8c4f882
#pragma once
#include "geodesic_nnf.hh"
namespace
polymesh
{
template
<
class
Vec3
,
class
Scalar
>
GeodesicNNF
<
Vec3
,
Scalar
>
make_geodesic_nnf
(
Mesh
const
&
m
,
vertex_attribute
<
Vec3
>
const
&
position
)
{
return
{
m
,
position
};
}
template
<
class
Vec3
,
class
Scalar
>
GeodesicNNF
<
Vec3
,
Scalar
>::
GeodesicNNF
(
const
Mesh
&
m
,
const
vertex_attribute
<
Vec3
>&
position
)
:
mesh
(
m
),
position
(
position
)
{
}
}
src/polymesh/attribute_base.hh
View file @
c8c4f882
...
...
@@ -113,11 +113,13 @@ protected:
int
mDataSize
=
0
;
Mesh
const
*
mMesh
;
primitive_attribute_base
(
Mesh
const
*
mesh
)
:
mMesh
(
mesh
)
{}
// no registration, it's too early!
virtual
~
primitive_attribute_base
()
{
deregister_attr
();
}
virtual
void
on_resize
(
int
new_size
)
=
0
;
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
void
deregister_attr
();
friend
class
Mesh
;
public:
virtual
~
primitive_attribute_base
()
{
deregister_attr
();
}
};
}
src/polymesh/attribute_collection.hh
View file @
c8c4f882
#pragma once
#include <cassert>
#include <map>
#include <memory>
#include <string>
#include "attributes.hh"
namespace
polymesh
{
/// Collection of named attributes (requires RTTI)
/// Attributes are owned by the collection
///
/// Usage:
///
/// attribute_collection ac;
///
/// // insert attributes
/// // NOTE: copies the attribute!
/// // TODO: support std::move
/// ac["aPosition"] = m.vertices().make_attribute<glm::vec3>();
///
/// // access attributes (must exist)
/// auto aPos = ac["aPosition"].vertex<glm::vec3>();
struct
attribute_collection
{
struct
accessor
;
struct
const_accessor
;
/// returns access to a named attribute
accessor
operator
[](
std
::
string
const
&
name
)
{
return
{
name
,
*
this
};
}
const_accessor
operator
[](
std
::
string
const
&
name
)
const
{
return
{
name
,
*
this
};
}
public:
struct
accessor
{
std
::
string
name
;
attribute_collection
&
ref
;
template
<
class
AttrT
>
accessor
&
operator
=
(
vertex_attribute
<
AttrT
>
const
&
a
)
{
ref
.
mVertexAttrs
[
name
].
reset
(
new
vertex_attribute
<
AttrT
>
(
a
));
return
*
this
;
}
template
<
class
AttrT
>
accessor
&
operator
=
(
face_attribute
<
AttrT
>
const
&
a
)
{
ref
.
mFaceAttrs
[
name
].
reset
(
new
face_attribute
<
AttrT
>
(
a
));
return
*
this
;
}
template
<
class
AttrT
>
accessor
&
operator
=
(
edge_attribute
<
AttrT
>
const
&
a
)
{
ref
.
mEdgeAttrs
[
name
].
reset
(
new
edge_attribute
<
AttrT
>
(
a
));
return
*
this
;
}
template
<
class
AttrT
>
accessor
&
operator
=
(
halfedge_attribute
<
AttrT
>
const
&
a
)
{
ref
.
mHalfedgeAttrs
[
name
].
reset
(
new
halfedge_attribute
<
AttrT
>
(
a
));
return
*
this
;
}
template
<
class
AttrT
>
vertex_attribute
<
AttrT
>&
vertex
()
{
auto
pa
=
ref
.
mVertexAttrs
.
at
(
name
).
get
();
assert
(
pa
&&
"non-existent attribute"
);
return
*
dynamic_cast
<
vertex_attribute
<
AttrT
>*>
(
pa
);
}
template
<
class
AttrT
>
face_attribute
<
AttrT
>&
face
()
{
auto
pa
=
ref
.
mVertexAttrs
.
at
(
name
).
get
();
assert
(
pa
&&
"non-existent attribute"
);
return
*
dynamic_cast
<
face_attribute
<
AttrT
>*>
(
pa
);
}
template
<
class
AttrT
>
edge_attribute
<
AttrT
>&
edge
()
{
auto
pa
=
ref
.
mVertexAttrs
.
at
(
name
).
get
();
assert
(
pa
&&
"non-existent attribute"
);
return
*
dynamic_cast
<
edge_attribute
<
AttrT
>*>
(
pa
);
}
template
<
class
AttrT
>
halfedge_attribute
<
AttrT
>&
halfedge
()
{
auto
pa
=
ref
.
mVertexAttrs
.
at
(
name
).
get
();
assert
(
pa
&&
"non-existent attribute"
);
return
*
dynamic_cast
<
halfedge_attribute
<
AttrT
>*>
(
pa
);
}
};
struct
const_accessor
{
std
::
string
name
;
attribute_collection
const
&
ref
;
template
<
class
AttrT
>
vertex_attribute
<
AttrT
>&
vertex
()
{
auto
pa
=
ref
.
mVertexAttrs
.
at
(
name
).
get
();
assert
(
pa
&&
"non-existent attribute"
);
return
*
dynamic_cast
<
vertex_attribute
<
AttrT
>*>
(
pa
);
}
template
<
class
AttrT
>
face_attribute
<
AttrT
>&
face
()
{
auto
pa
=
ref
.
mVertexAttrs
.
at
(
name
).
get
();
assert
(
pa
&&
"non-existent attribute"
);
return
*
dynamic_cast
<
face_attribute
<
AttrT
>*>
(
pa
);
}
template
<
class
AttrT
>
edge_attribute
<
AttrT
>&
edge
()
{
auto
pa
=
ref
.
mVertexAttrs
.
at
(
name
).
get
();
assert
(
pa
&&
"non-existent attribute"
);
return
*
dynamic_cast
<
edge_attribute
<
AttrT
>*>
(
pa
);
}
template
<
class
AttrT
>
halfedge_attribute
<
AttrT
>&
halfedge
()
{
auto
pa
=
ref
.
mVertexAttrs
.
at
(
name
).
get
();
assert
(
pa
&&
"non-existent attribute"
);
return
*
dynamic_cast
<
halfedge_attribute
<
AttrT
>*>
(
pa
);
}
};
private:
std
::
map
<
std
::
string
,
primitive_attribute_base
<
vertex_tag
>>
mVertexAttrs
;
// TODO
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
primitive_attribute_base
<
vertex_tag
>>>
mVertexAttrs
;
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
primitive_attribute_base
<
face_tag
>>>
mFaceAttrs
;
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
primitive_attribute_base
<
edge_tag
>>>
mEdgeAttrs
;
std
::
map
<
std
::
string
,
std
::
unique_ptr
<
primitive_attribute_base
<
halfedge_tag
>>>
mHalfedgeAttrs
;
friend
accessor
;
friend
const_accessor
;
};
}
src/polymesh/attributes.hh
View file @
c8c4f882
...
...
@@ -59,6 +59,11 @@ public:
template
<
class
FuncT
>
void
apply
(
FuncT
&&
f
);
/// copies as much data as possible from the given vector
void
copy_from
(
std
::
vector
<
AttrT
>
const
&
data
);
/// copies as much data as possible from the given array
void
copy_from
(
AttrT
const
*
data
,
int
cnt
);
// data
protected:
attribute_data
<
AttrT
>
mData
;
...
...
@@ -112,64 +117,4 @@ struct halfedge_attribute : primitive_attribute<halfedge_tag, AttrT>
friend
struct
smart_collection
;
};
/// ======== IMPLEMENTATION ========
template
<
class
tag
,
class
AttrT
>
void
primitive_attribute
<
tag
,
AttrT
>::
apply_remapping
(
const
std
::
vector
<
int
>&
map
)
{
for
(
auto
i
=
0u
;
i
<
map
.
size
();
++
i
)
this
->
mData
[
i
]
=
this
->
mData
[
map
[
i
]];
}
template
<
class
tag
,
class
AttrT
>
primitive_attribute
<
tag
,
AttrT
>::
primitive_attribute
(
primitive_attribute
const
&
rhs
)
noexcept
:
primitive_attribute_base
<
tag
>
(
rhs
.
mMesh
)
// copy
{
this
->
mDefaultValue
=
rhs
.
mDefaultValue
;
this
->
mData
=
rhs
.
mData
;
this
->
mDataSize
=
rhs
.
mDataSize
;
this
->
register_attr
();
}
template
<
class
tag
,
class
AttrT
>
primitive_attribute
<
tag
,
AttrT
>::
primitive_attribute
(
primitive_attribute
&&
rhs
)
noexcept
:
primitive_attribute_base
<
tag
>
(
rhs
.
mMesh
)
// move
{
this
->
mDefaultValue
=
std
::
move
(
rhs
.
mDefaultValue
);
this
->
mData
=
std
::
move
(
rhs
.
mData
);
this
->
mDataSize
=
rhs
.
mDataSize
;
rhs
.
deregister_attr
();
this
->
register_attr
();
}
template
<
class
tag
,
class
AttrT
>
primitive_attribute
<
tag
,
AttrT
>&
primitive_attribute
<
tag
,
AttrT
>::
operator
=
(
primitive_attribute
const
&
rhs
)
noexcept
// copy
{
this
->
deregister_attr
();
this
->
mMesh
=
rhs
.
mMesh
;
this
->
mDefaultValue
=
rhs
.
mDefaultValue
;
this
->
mData
=
rhs
.
mData
;
this
->
mDataSize
=
rhs
.
mDataSize
;
this
->
register_attr
();
return
*
this
;
}
template
<
class
tag
,
class
AttrT
>
primitive_attribute
<
tag
,
AttrT
>&
primitive_attribute
<
tag
,
AttrT
>::
operator
=
(
primitive_attribute
&&
rhs
)
noexcept
// move
{
this
->
deregister_attr
();
this
->
mMesh
=
rhs
.
mMesh
;
this
->
mDefaultValue
=
std
::
move
(
rhs
.
mDefaultValue
);
this
->
mData
=
std
::
move
(
rhs
.
mData
);
this
->
mDataSize
=
rhs
.
mDataSize
;
rhs
.
deregister_attr
();
this
->
register_attr
();
return
*
this
;
}
}
src/polymesh/impl/impl_attributes.hh
View file @
c8c4f882
...
...
@@ -4,6 +4,81 @@
namespace
polymesh
{
template
<
class
tag
,
class
AttrT
>
void
primitive_attribute
<
tag
,
AttrT
>::
copy_from
(
const
std
::
vector
<
AttrT
>
&
data
)
{
auto
s
=
std
::
min
((
int
)
data
.
size
(),
this
->
mDataSize
);
for
(
auto
i
=
0
;
i
<
s
;
++
i
)
this
->
mData
[
i
]
=
data
[
i
];
}
template
<
class
tag
,
class
AttrT
>
void
primitive_attribute
<
tag
,
AttrT
>::
copy_from
(
const
AttrT
*
data
,
int
cnt
)
{
auto
s
=
std
::
min
(
cnt
,
this
->
mDataSize
);
for
(
auto
i
=
0
;
i
<
s
;
++
i
)
this
->
mData
[
i
]
=
data
[
i
];
}
template
<
class
tag
,
class
AttrT
>
void
primitive_attribute
<
tag
,
AttrT
>::
apply_remapping
(
const
std
::
vector
<
int
>
&
map
)
{
for
(
auto
i
=
0u
;
i
<
map
.
size
();
++
i
)
this
->
mData
[
i
]
=
this
->
mData
[
map
[
i
]];
}
template
<
class
tag
,
class
AttrT
>
primitive_attribute
<
tag
,
AttrT
>::
primitive_attribute
(
primitive_attribute
const
&
rhs
)
noexcept
:
primitive_attribute_base
<
tag
>
(
rhs
.
mMesh
)
// copy
{
this
->
mDefaultValue
=
rhs
.
mDefaultValue
;
this
->
mData
=
rhs
.
mData
;
this
->
mDataSize
=
rhs
.
mDataSize
;
this
->
register_attr
();
}
template
<
class
tag
,
class
AttrT
>
primitive_attribute
<
tag
,
AttrT
>::
primitive_attribute
(
primitive_attribute
&&
rhs
)
noexcept
:
primitive_attribute_base
<
tag
>
(
rhs
.
mMesh
)
// move
{
this
->
mDefaultValue
=
std
::
move
(
rhs
.
mDefaultValue
);
this
->
mData
=
std
::
move
(
rhs
.
mData
);
this
->
mDataSize
=
rhs
.
mDataSize
;
rhs
.
deregister_attr
();
this
->
register_attr
();
}
template
<
class
tag
,
class
AttrT
>
primitive_attribute
<
tag
,
AttrT
>
&
primitive_attribute
<
tag
,
AttrT
>::
operator
=
(
primitive_attribute
const
&
rhs
)
noexcept
// copy
{
this
->
deregister_attr
();
this
->
mMesh
=
rhs
.
mMesh
;
this
->
mDefaultValue
=
rhs
.
mDefaultValue
;
this
->
mData
=
rhs
.
mData
;
this
->
mDataSize
=
rhs
.
mDataSize
;
this
->
register_attr
();
return
*
this
;
}
template
<
class
tag
,
class
AttrT
>
primitive_attribute
<
tag
,
AttrT
>
&
primitive_attribute
<
tag
,
AttrT
>::
operator
=
(
primitive_attribute
&&
rhs
)
noexcept
// move
{
this
->
deregister_attr
();
this
->
mMesh
=
rhs
.
mMesh
;
this
->
mDefaultValue
=
std
::
move
(
rhs
.
mDefaultValue
);
this
->
mData
=
std
::
move
(
rhs
.
mData
);
this
->
mDataSize
=
rhs
.
mDataSize
;
rhs
.
deregister_attr
();
this
->
register_attr
();
return
*
this
;
}
inline
void
Mesh
::
register_attr
(
primitive_attribute_base
<
vertex_tag
>
*
attr
)
const
{
// insert in front
...
...
src/polymesh/impl/impl_ranges.hh
View file @
c8c4f882
...
...
@@ -279,23 +279,41 @@ void smart_collection<mesh_ptr, tag, iterator>::reserve(int capacity) const
}
template
<
class
mesh_ptr
,
class
tag
,
class
iterator
>
template
<
class
Prop
T
>
typename
primitive
<
tag
>::
template
attribute
<
Prop
T
>
smart_collection
<
mesh_ptr
,
tag
,
iterator
>::
make_attribute
()
const
template
<
class
Attr
T
>
typename
primitive
<
tag
>::
template
attribute
<
Attr
T
>
smart_collection
<
mesh_ptr
,
tag
,
iterator
>::
make_attribute
()
const
{
return
typename
primitive
<
tag
>::
template
attribute
<
Prop
T
>(
mesh
,
Prop
T
());
return
typename
primitive
<
tag
>::
template
attribute
<
Attr
T
>(
mesh
,
Attr
T
());
}
template
<
class
mesh_ptr
,
class
tag
,
class
iterator
>
template
<
class
Prop
T
>
typename
primitive
<
tag
>::
template
attribute
<
Prop
T
>
smart_collection
<
mesh_ptr
,
tag
,
iterator
>::
make_attribute_default
(
Prop
T
const
&
def_value
)
const
template
<
class
Attr
T
>
typename
primitive
<
tag
>::
template
attribute
<
Attr
T
>
smart_collection
<
mesh_ptr
,
tag
,
iterator
>::
make_attribute_
with_
default
(
Attr
T
const
&
def_value
)
const
{
return
typename
primitive
<
tag
>::
template
attribute
<
Prop
T
>(
mesh
,
def_value
);
return
typename
primitive
<
tag
>::
template
attribute
<
Attr
T
>(
mesh
,
def_value
);
}
template
<
class
mesh_ptr
,
class
tag
,
class
iterator
>
template
<
class
FuncT
,
class
Prop
T
>
typename
primitive
<
tag
>::
template
attribute
<
Prop
T
>
smart_collection
<
mesh_ptr
,
tag
,
iterator
>::
make_attribute
(
FuncT
&&
f
,
PropT
const
&
d
ef_value
)
const
template
<
class
Attr
T
>
typename
primitive
<
tag
>::
template
attribute
<
Attr
T
>
smart_collection
<
mesh_ptr
,
tag
,
iterator
>::
make_attribute
_from_data
(
std
::
vector
<
AttrT
>
const
&
d
ata
)
const
{
auto
attr
=
make_attribute_default
<
PropT
>
(
def_value
);
auto
attr
=
make_attribute
<
AttrT
>
();
attr
.
copy_from
(
data
);
return
attr
;
// copy elison
}
template
<
class
mesh_ptr
,
class
tag
,
class
iterator
>
template
<
class
AttrT
>
typename
primitive
<
tag
>::
template
attribute
<
AttrT
>
smart_collection
<
mesh_ptr
,
tag
,
iterator
>::
make_attribute_from_data
(
AttrT
const
*
data
,
int
cnt
)
const
{
auto
attr
=
make_attribute
<
AttrT
>
();
attr
.
copy_from
(
data
,
cnt
);
return
attr
;
// copy elison
}
template
<
class
mesh_ptr
,
class
tag
,
class
iterator
>
template
<
class
FuncT
,
class
AttrT
>
typename
primitive
<
tag
>::
template
attribute
<
AttrT
>
smart_collection
<
mesh_ptr
,
tag
,
iterator
>::
make_attribute
(
FuncT
&&
f
,
AttrT
const
&
def_value
)
const
{
auto
attr
=
make_attribute_with_default
<
AttrT
>
(
def_value
);
for
(
auto
h
:
*
this
)
attr
[
h
]
=
f
(
h
);
return
attr
;
// copy elison
...
...
@@ -564,7 +582,7 @@ void vertex_collection<iterator>::collapse(vertex_handle v) const
this
->
mesh
->
vertex_collapse
(
v
.
idx
);
}
template
<
class
iterator
>
template
<
class
iterator
>
void
halfedge_collection
<
iterator
>::
collapse
(
halfedge_handle
h
)
const
{
this
->
mesh
->
halfedge_collapse
(
h
.
idx
);
...
...
src/polymesh/ranges.hh
View file @
c8c4f882
...
...
@@ -125,14 +125,20 @@ struct smart_collection : smart_range<smart_collection<mesh_ptr, tag, iterator>,
void
reserve
(
int
capacity
)
const
;
/// Creates a new primitive attribute
template
<
class
Prop
T
>
attribute
<
Prop
T
>
make_attribute
()
const
;
template
<
class
Attr
T
>
attribute
<
Attr
T
>
make_attribute
()
const
;
/// Creates a new primitive attribute with a given default value
template
<
class
PropT
>
attribute
<
PropT
>
make_attribute_default
(
PropT
const
&
def_value
)
const
;
template
<
class
AttrT
>
attribute
<
AttrT
>
make_attribute_with_default
(
AttrT
const
&
def_value
)
const
;
/// Creates a new primitive attribute and copies the given data
template
<
class
AttrT
>
attribute
<
AttrT
>
make_attribute_from_data
(
std
::
vector
<
AttrT
>
const
&
data
)
const
;
/// Creates a new primitive attribute and copies the given data
template
<
class
AttrT
>
attribute
<
AttrT
>
make_attribute_from_data
(
AttrT
const
*
data
,
int
cnt
)
const
;
/// Creates a new primitive attribute and initializes it with f(h) for each handle h
template
<
class
FuncT
,
class
Prop
T
=
tmp
::
decayed_result_type_of
<
FuncT
,
handle
>
>
attribute
<
Prop
T
>
make_attribute
(
FuncT
&&
f
,
Prop
T
const
&
def_value
=
Prop
T
())
const
;
template
<
class
FuncT
,
class
Attr
T
=
tmp
::
decayed_result_type_of
<
FuncT
,
handle
>
>
attribute
<
Attr
T
>
make_attribute
(
FuncT
&&
f
,
Attr
T
const
&
def_value
=
Attr
T
())
const
;
// Iteration:
iterator
begin
()
const
;
...
...
@@ -445,5 +451,4 @@ struct halfedge_ring : halfedge_primitive_ring<halfedge_tag, halfedge_ring_circu
{
using
halfedge_primitive_ring
<
halfedge_tag
,
halfedge_ring_circulator
>::
halfedge_primitive_ring
;
};
}
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