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
9c3d267c
Commit
9c3d267c
authored
Jun 28, 2018
by
Philip Trettner
Browse files
better attributes
parent
23da7387
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/polymesh/Mesh.cc
View file @
9c3d267c
...
...
@@ -10,9 +10,6 @@ using namespace polymesh;
void
Mesh
::
assert_consistency
()
const
{
/// TODO
/// check compact!
// check sizes
assert
(
mHalfedges
.
size
()
%
2
==
0
);
///< even number of halfedges
...
...
src/polymesh/Mesh.hh
View file @
9c3d267c
...
...
@@ -104,10 +104,10 @@ public:
// internal helper
private:
// reserves a certain number of primitives
void
reserve_faces
(
size_t
capacity
)
{
mFaces
.
reserve
(
capacity
);
}
void
reserve_vertices
(
size_t
capacity
)
{
mVertices
.
reserve
(
capacity
);
}
void
reserve_edges
(
size_t
capacity
)
{
mHalfedges
.
reserve
(
capacity
*
2
);
}
void
reserve_halfedges
(
size_t
capacity
)
{
mHalfedges
.
reserve
(
capacity
);
}
void
reserve_faces
(
size_t
capacity
)
;
void
reserve_vertices
(
size_t
capacity
)
;
void
reserve_edges
(
size_t
capacity
)
;
void
reserve_halfedges
(
size_t
capacity
)
;
int
size_faces
()
const
{
return
(
int
)
mFaces
.
size
();
}
int
size_vertices
()
const
{
return
(
int
)
mVertices
.
size
();
}
...
...
@@ -384,7 +384,7 @@ inline vertex_index Mesh::add_vertex()
// notify attributes
auto
vCnt
=
mVertices
.
size
();
for
(
auto
p
=
mVertexAttrs
;
p
;
p
=
p
->
mNextAttribute
)
p
->
resize
(
vCnt
);
p
->
resize
(
vCnt
,
false
);
return
idx
;
}
...
...
@@ -463,7 +463,7 @@ inline face_index Mesh::add_face(const halfedge_index *half_loop, size_t vcnt)
// notify attributes
auto
fCnt
=
mFaces
.
size
();
for
(
auto
p
=
mFaceAttrs
;
p
;
p
=
p
->
mNextAttribute
)
p
->
resize
(
fCnt
);
p
->
resize
(
fCnt
,
false
);
return
fidx
;
}
...
...
@@ -538,9 +538,9 @@ inline edge_index Mesh::add_or_get_edge(vertex_index v_from, vertex_index v_to)
auto
hCnt
=
mHalfedges
.
size
();
auto
eCnt
=
hCnt
>>
1
;
for
(
auto
p
=
mHalfedgeAttrs
;
p
;
p
=
p
->
mNextAttribute
)
p
->
resize
(
hCnt
);
p
->
resize
(
hCnt
,
false
);
for
(
auto
p
=
mEdgeAttrs
;
p
;
p
=
p
->
mNextAttribute
)
p
->
resize
(
eCnt
);
p
->
resize
(
eCnt
,
false
);
return
eidx
;
}
...
...
@@ -1355,12 +1355,62 @@ inline void Mesh::compactify()
for
(
auto
a
=
mHalfedgeAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
apply_remapping
(
h_new_to_old
);
// shrink to fit
mVertices
.
shrink_to_fit
();
mFaces
.
shrink_to_fit
();
mHalfedges
.
shrink_to_fit
();
for
(
auto
a
=
mVertexAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
size_vertices
(),
true
);
for
(
auto
a
=
mFaceAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
size_faces
(),
true
);
for
(
auto
a
=
mEdgeAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
size_edges
(),
true
);
for
(
auto
a
=
mHalfedgeAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
size_halfedges
(),
true
);
mRemovedFaces
=
0
;
mRemovedHalfedges
=
0
;
mRemovedVertices
=
0
;
mCompact
=
true
;
}
inline
void
Mesh
::
reserve_faces
(
size_t
capacity
)
{
for
(
auto
a
=
mFaceAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
capacity
,
false
);
mFaces
.
reserve
(
capacity
);
}
inline
void
Mesh
::
reserve_vertices
(
size_t
capacity
)
{
for
(
auto
a
=
mVertexAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
capacity
,
false
);
mVertices
.
reserve
(
capacity
);
}
inline
void
Mesh
::
reserve_edges
(
size_t
capacity
)
{
for
(
auto
a
=
mEdgeAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
capacity
,
false
);
for
(
auto
a
=
mHalfedgeAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
capacity
<<
1
,
false
);
mHalfedges
.
reserve
(
capacity
*
2
);
}
inline
void
Mesh
::
reserve_halfedges
(
size_t
capacity
)
{
for
(
auto
a
=
mHalfedgeAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
capacity
,
false
);
for
(
auto
a
=
mEdgeAttrs
;
a
;
a
=
a
->
mNextAttribute
)
a
->
resize
(
capacity
>>
1
,
false
);
mHalfedges
.
reserve
(
capacity
);
}
/// ======== HANDLES IMPLEMENTATION ========
inline
bool
vertex_handle
::
is_removed
()
const
...
...
@@ -1632,7 +1682,7 @@ inline void Mesh::register_attr(vertex_attribute_base *attr) const
nextAttrs
->
mPrevAttribute
=
attr
;
// resize attr
attr
->
resize
(
vertices
().
size
());
attr
->
resize
(
vertices
().
size
()
,
false
);
}
inline
void
Mesh
::
deregister_attr
(
vertex_attribute_base
*
attr
)
const
...
...
@@ -1641,10 +1691,13 @@ inline void Mesh::deregister_attr(vertex_attribute_base *attr) const
attr
->
mPrevAttribute
->
mNextAttribute
=
attr
->
mNextAttribute
;
if
(
attr
->
mNextAttribute
)
attr
->
mNextAttribute
=
attr
->
mPrevAttribute
;
attr
->
mNextAttribute
->
mPrevAttribute
=
attr
->
mPrevAttribute
;
if
(
mVertexAttrs
==
attr
)
mVertexAttrs
=
attr
->
mNextAttribute
;
attr
->
mNextAttribute
=
nullptr
;
attr
->
mPrevAttribute
=
nullptr
;
}
inline
void
Mesh
::
register_attr
(
face_attribute_base
*
attr
)
const
...
...
@@ -1657,7 +1710,7 @@ inline void Mesh::register_attr(face_attribute_base *attr) const
nextAttrs
->
mPrevAttribute
=
attr
;
// resize attr
attr
->
resize
(
faces
().
size
());
attr
->
resize
(
faces
().
size
()
,
false
);
}
inline
void
Mesh
::
deregister_attr
(
face_attribute_base
*
attr
)
const
...
...
@@ -1666,10 +1719,13 @@ inline void Mesh::deregister_attr(face_attribute_base *attr) const
attr
->
mPrevAttribute
->
mNextAttribute
=
attr
->
mNextAttribute
;
if
(
attr
->
mNextAttribute
)
attr
->
mNextAttribute
=
attr
->
mPrevAttribute
;
attr
->
mNextAttribute
->
mPrevAttribute
=
attr
->
mPrevAttribute
;
if
(
mFaceAttrs
==
attr
)
mFaceAttrs
=
attr
->
mNextAttribute
;
attr
->
mNextAttribute
=
nullptr
;
attr
->
mPrevAttribute
=
nullptr
;
}
inline
void
Mesh
::
register_attr
(
edge_attribute_base
*
attr
)
const
...
...
@@ -1682,7 +1738,7 @@ inline void Mesh::register_attr(edge_attribute_base *attr) const
nextAttrs
->
mPrevAttribute
=
attr
;
// resize attr
attr
->
resize
(
edges
().
size
());
attr
->
resize
(
edges
().
size
()
,
false
);
}
inline
void
Mesh
::
deregister_attr
(
edge_attribute_base
*
attr
)
const
...
...
@@ -1691,10 +1747,13 @@ inline void Mesh::deregister_attr(edge_attribute_base *attr) const
attr
->
mPrevAttribute
->
mNextAttribute
=
attr
->
mNextAttribute
;
if
(
attr
->
mNextAttribute
)
attr
->
mNextAttribute
=
attr
->
mPrevAttribute
;
attr
->
mNextAttribute
->
mPrevAttribute
=
attr
->
mPrevAttribute
;
if
(
mEdgeAttrs
==
attr
)
mEdgeAttrs
=
attr
->
mNextAttribute
;
attr
->
mNextAttribute
=
nullptr
;
attr
->
mPrevAttribute
=
nullptr
;
}
inline
void
Mesh
::
register_attr
(
halfedge_attribute_base
*
attr
)
const
...
...
@@ -1707,7 +1766,7 @@ inline void Mesh::register_attr(halfedge_attribute_base *attr) const
nextAttrs
->
mPrevAttribute
=
attr
;
// resize attr
attr
->
resize
(
halfedges
().
size
());
attr
->
resize
(
halfedges
().
size
()
,
false
);
}
inline
void
Mesh
::
deregister_attr
(
halfedge_attribute_base
*
attr
)
const
...
...
@@ -1716,10 +1775,13 @@ inline void Mesh::deregister_attr(halfedge_attribute_base *attr) const
attr
->
mPrevAttribute
->
mNextAttribute
=
attr
->
mNextAttribute
;
if
(
attr
->
mNextAttribute
)
attr
->
mNextAttribute
=
attr
->
mPrevAttribute
;
attr
->
mNextAttribute
->
mPrevAttribute
=
attr
->
mPrevAttribute
;
if
(
mHalfedgeAttrs
==
attr
)
mHalfedgeAttrs
=
attr
->
mNextAttribute
;
attr
->
mNextAttribute
=
nullptr
;
attr
->
mPrevAttribute
=
nullptr
;
}
inline
vertex_attribute_base
::
vertex_attribute_base
(
const
Mesh
*
mesh
)
:
mMesh
(
mesh
)
...
...
@@ -1742,24 +1804,40 @@ inline halfedge_attribute_base::halfedge_attribute_base(const Mesh *mesh) : mMes
// mMesh->register_attr(this); TOO EARLY!
}
inline
vertex_attribute_base
::
~
ver
te
x
_attr
ibute_base
()
inline
void
vertex_attribute_base
::
deregis
te
r
_attr
()
{
mMesh
->
deregister_attr
(
this
);
if
(
mMesh
)
{
mMesh
->
deregister_attr
(
this
);
mMesh
=
nullptr
;
}
}
inline
face_attribute_base
::
~
face_attribute_base
()
inline
void
face_attribute_base
::
deregister_attr
()
{
mMesh
->
deregister_attr
(
this
);
if
(
mMesh
)
{
mMesh
->
deregister_attr
(
this
);
mMesh
=
nullptr
;
}
}
inline
edge_attribute_base
::
~
edge_attribute_base
()
inline
void
edge_attribute_base
::
deregister_attr
()
{
mMesh
->
deregister_attr
(
this
);
if
(
mMesh
)
{
mMesh
->
deregister_attr
(
this
);
mMesh
=
nullptr
;
}
}
inline
halfedge_attribute_base
::
~
halfedge_attribute_base
()
inline
void
halfedge_attribute_base
::
deregister_attr
()
{
mMesh
->
deregister_attr
(
this
);
if
(
mMesh
)
{
mMesh
->
deregister_attr
(
this
);
mMesh
=
nullptr
;
}
}
inline
void
vertex_attribute_base
::
register_attr
()
...
...
src/polymesh/algorithms/operations.hh
View file @
9c3d267c
...
...
@@ -13,9 +13,9 @@
namespace
polymesh
{
vertex_handle
split
(
edge_handle
e
)
{
// TODO
}
//
vertex_handle split(edge_handle e)
//
{
//
// TODO
//
}
}
\ No newline at end of file
}
src/polymesh/attribute_base.hh
View file @
9c3d267c
#pragma once
#include <vector>
#include <cstddef>
#include <vector>
// Helper for mesh-based attribute bookkeeping
...
...
@@ -9,29 +9,113 @@ namespace polymesh
{
class
Mesh
;
template
<
typename
DataT
>
struct
attribute_data
{
size_t
size
=
0
;
DataT
*
data
=
nullptr
;
DataT
&
operator
[](
int
i
)
{
return
data
[
i
];
}
DataT
const
&
operator
[](
int
i
)
const
{
return
data
[
i
];
}
attribute_data
()
=
default
;
attribute_data
(
attribute_data
<
DataT
>
const
&
rhs
)
// copy
{
size
=
rhs
.
size
;
data
=
new
DataT
[
size
];
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
data
[
i
]
=
rhs
.
data
[
i
];
}
attribute_data
(
attribute_data
<
DataT
>&&
rhs
)
// move
{
size
=
rhs
.
size
;
data
=
rhs
.
data
;
rhs
.
size
=
0
;
rhs
.
data
=
nullptr
;
}
attribute_data
<
DataT
>&
operator
=
(
attribute_data
<
DataT
>
const
&
rhs
)
// copy
{
delete
[]
data
;
size
=
rhs
.
size
;
data
=
new
DataT
[
size
];
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
data
[
i
]
=
rhs
.
data
[
i
];
return
*
this
;
}
attribute_data
<
DataT
>&
operator
=
(
attribute_data
<
DataT
>&&
rhs
)
// move
{
delete
[]
data
;
size
=
rhs
.
size
;
data
=
rhs
.
data
;
rhs
.
size
=
0
;
rhs
.
data
=
nullptr
;
return
*
this
;
}
~
attribute_data
()
{
delete
[]
data
;
}
void
resize
(
size_t
new_size
,
DataT
const
&
default_value
)
{
auto
new_data
=
new
DataT
[
new_size
];
if
(
new_size
<
size
)
{
for
(
size_t
i
=
0
;
i
<
new_size
;
++
i
)
new_data
[
i
]
=
data
[
i
];
}
else
{
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
new_data
[
i
]
=
data
[
i
];
for
(
size_t
i
=
size
;
i
<
new_size
;
++
i
)
new_data
[
i
]
=
default_value
;
}
delete
[]
data
;
data
=
new_data
;
size
=
new_size
;
}
};
struct
vertex_attribute_base
{
private:
vertex_attribute_base
*
mNextAttribute
=
nullptr
;
vertex_attribute_base
*
mPrevAttribute
=
nullptr
;
size_t
mDataSize
=
0
;
void
resize
(
size_t
newSize
)
void
resize
(
size_t
newSize
,
bool
force
)
{
if
(
force
)
{
mDataSize
=
newSize
;
on_resize
(
mDataSize
);
return
;
}
if
(
mDataSize
<
newSize
)
{
mDataSize
=
1
+
new
Size
+
(
new
Size
>>
1
);
// 1 + s * 1.5
mDataSize
=
std
::
max
(
newSize
,
1
+
mData
Size
+
(
mData
Size
>>
1
)
)
;
// 1 + s * 1.5
on_resize
(
mDataSize
);
}
}
protected:
size_t
mDataSize
=
0
;
Mesh
const
*
mMesh
;
vertex_attribute_base
(
Mesh
const
*
mesh
);
virtual
~
vertex_attribute_base
()
;
virtual
~
vertex_attribute_base
()
{
deregister_attr
();
}
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
void
deregister_attr
();
friend
class
Mesh
;
};
...
...
@@ -40,24 +124,32 @@ struct face_attribute_base
private:
face_attribute_base
*
mNextAttribute
=
nullptr
;
face_attribute_base
*
mPrevAttribute
=
nullptr
;
size_t
mDataSize
=
0
;
void
resize
(
size_t
newSize
)
void
resize
(
size_t
newSize
,
bool
force
)
{
if
(
force
)
{
mDataSize
=
newSize
;
on_resize
(
mDataSize
);
return
;
}
if
(
mDataSize
<
newSize
)
{
mDataSize
=
1
+
new
Size
+
(
new
Size
>>
1
);
// 1 + s * 1.5
mDataSize
=
std
::
max
(
newSize
,
1
+
mData
Size
+
(
mData
Size
>>
1
)
)
;
// 1 + s * 1.5
on_resize
(
mDataSize
);
}
}
protected:
size_t
mDataSize
=
0
;
Mesh
const
*
mMesh
;
face_attribute_base
(
Mesh
const
*
mesh
);
virtual
~
face_attribute_base
()
;
virtual
~
face_attribute_base
()
{
deregister_attr
();
}
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
void
deregister_attr
();
friend
class
Mesh
;
};
...
...
@@ -66,24 +158,32 @@ struct edge_attribute_base
private:
edge_attribute_base
*
mNextAttribute
=
nullptr
;
edge_attribute_base
*
mPrevAttribute
=
nullptr
;
size_t
mDataSize
=
0
;
void
resize
(
size_t
newSize
)
void
resize
(
size_t
newSize
,
bool
force
)
{
if
(
force
)
{
mDataSize
=
newSize
;
on_resize
(
mDataSize
);
return
;
}
if
(
mDataSize
<
newSize
)
{
mDataSize
=
1
+
new
Size
+
(
new
Size
>>
1
);
// 1 + s * 1.5
mDataSize
=
std
::
max
(
newSize
,
1
+
mData
Size
+
(
mData
Size
>>
1
)
)
;
// 1 + s * 1.5
on_resize
(
mDataSize
);
}
}
protected:
size_t
mDataSize
=
0
;
Mesh
const
*
mMesh
;
edge_attribute_base
(
Mesh
const
*
mesh
);
virtual
~
edge_attribute_base
()
;
virtual
~
edge_attribute_base
()
{
deregister_attr
();
}
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
void
deregister_attr
();
friend
class
Mesh
;
};
...
...
@@ -92,24 +192,32 @@ struct halfedge_attribute_base
private:
halfedge_attribute_base
*
mNextAttribute
=
nullptr
;
halfedge_attribute_base
*
mPrevAttribute
=
nullptr
;
size_t
mDataSize
=
0
;
void
resize
(
size_t
newSize
)
void
resize
(
size_t
newSize
,
bool
force
)
{
if
(
force
)
{
mDataSize
=
newSize
;
on_resize
(
mDataSize
);
return
;
}
if
(
mDataSize
<
newSize
)
{
mDataSize
=
1
+
new
Size
+
(
new
Size
>>
1
);
// 1 + s * 1.5
mDataSize
=
std
::
max
(
newSize
,
1
+
mData
Size
+
(
mData
Size
>>
1
)
)
;
// 1 + s * 1.5
on_resize
(
mDataSize
);
}
}
protected:
size_t
mDataSize
=
0
;
Mesh
const
*
mMesh
;
halfedge_attribute_base
(
Mesh
const
*
mesh
);
virtual
~
halfedge_attribute_base
()
;
virtual
~
halfedge_attribute_base
()
{
deregister_attr
();
}
virtual
void
on_resize
(
size_t
newSize
)
=
0
;
virtual
void
apply_remapping
(
std
::
vector
<
int
>
const
&
map
)
=
0
;
void
register_attr
();
void
deregister_attr
();
friend
class
Mesh
;
};
}
src/polymesh/attributes.hh
View file @
9c3d267c
...
...
@@ -3,10 +3,10 @@
#include <cstddef>
#include <vector>
#include "cursors.hh"
#include "attribute_base.hh"
#include "cursors.hh"
/** Attr
erti
es
/** Attr
ibut
es
*
* Golden rule:
* - the Mesh must always outlive the attribute!
...
...
@@ -18,8 +18,6 @@
* vertex_handle v; // or _index
* v[myAttr] = 7;
* myAttr[v] = 7;
*
* TODO: correct copy and move ctors/assignments
*/
namespace
polymesh
...
...
@@ -34,8 +32,8 @@ public:
AttrT
&
operator
[](
vertex_index
v
)
{
return
mData
[
v
.
value
];
}
AttrT
const
&
operator
[](
vertex_index
v
)
const
{
return
mData
[
v
.
value
];
}
AttrT
*
data
()
{
return
mData
.
data
()
;
}
AttrT
const
*
data
()
const
{
return
mData
.
data
()
;
}
AttrT
*
data
()
{
return
mData
;
}
AttrT
const
*
data
()
const
{
return
mData
;
}
size_t
size
()
const
;
// methods
...
...
@@ -45,7 +43,7 @@ public:
// data
private:
std
::
vector
<
AttrT
>
mData
;
attribute_data
<
AttrT
>
mData
;
AttrT
mDefaultValue
;
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
...
...
@@ -55,6 +53,13 @@ private:
private:
vertex_attribute
(
Mesh
const
*
mesh
,
AttrT
const
&
def_value
);
friend
struct
vertex_collection
;
// move & copy
public:
vertex_attribute
(
vertex_attribute
const
&
);
vertex_attribute
(
vertex_attribute
&&
);
vertex_attribute
&
operator
=
(
vertex_attribute
const
&
);
vertex_attribute
&
operator
=
(
vertex_attribute
&&
);
};
template
<
typename
AttrT
>
...
...
@@ -78,7 +83,7 @@ public:
// data
private:
std
::
vector
<
AttrT
>
mData
;
attribute_data
<
AttrT
>
mData
;
AttrT
mDefaultValue
;
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
...
...
@@ -88,6 +93,13 @@ private:
private:
face_attribute
(
Mesh
const
*
mesh
,
AttrT
const
&
def_value
);
friend
struct
face_collection
;
// move & copy
public:
face_attribute
(
face_attribute
const
&
);
face_attribute
(
face_attribute
&&
);
face_attribute
&
operator
=
(
face_attribute
const
&
);
face_attribute
&
operator
=
(
face_attribute
&&
);
};
template
<
typename
AttrT
>
...
...
@@ -111,7 +123,7 @@ public:
// data
private:
std
::
vector
<
AttrT
>
mData
;
attribute_data
<
AttrT
>
mData
;
AttrT
mDefaultValue
;
void
on_resize
(
size_t
newSize
)
override
{
mData
.
resize
(
newSize
,
mDefaultValue
);
}
...
...
@@ -121,6 +133,13 @@ private:
private:
edge_attribute
(
Mesh
const
*
mesh
,
AttrT
const
&
def_value
);
friend
struct
edge_collection
;
// move & copy
public:
edge_attribute
(
edge_attribute
const
&
);
edge_attribute
(
edge_attribute
&&
);
edge_attribute
&
operator
=
(
edge_attribute
const
&
);
edge_attribute
&
operator
=
(
edge_attribute
&&
);
};
template
<
typename
AttrT
>
...
...
@@ -147,42 +166,242 @@ public:
// data
private:
std
::
vector
<
AttrT
>
mData
;
attribute_data
<
AttrT
>
mData
;
AttrT
mDefaultValue
;
// ctor
private:
halfedge_attribute
(
Mesh
const
*
mesh
,
AttrT
const
&
def_value
);