tutorial_03.docu 5.25 KB
Newer Older
Jan Möbius's avatar
Jan Möbius committed
1
2
3
/** \page tutorial_03 Using (custom) properties

This examples shows:
4
- How to add and remove custom properties
Jan Möbius's avatar
Jan Möbius committed
5
6
7
8
9
10
11
12
13
- How to get and set the value of a custom property

In the last example we computed the barycenter of each vertex'
neighborhood and stored it in an array. It would be more convenient
and less error-prone if we could store this data in the mesh and
let %OpenMesh manage the data.
It would be even more helpful if we could attach such properties
dynamically to the mesh.

14
15
16
17
Custom properties can be conveniently created and attached to meshes with the following functions:
- makeTemporaryProperty() creates a property that is temporary to the current scope.
- getOrMakeProperty() is used for creating and accessing permanent named properties on a mesh.
- getProperty() is used for accessing an existing permanent named property on a mesh.
Jan Möbius's avatar
Jan Möbius committed
18

19
All three functions take two template arguments:
20
- First, the type of the mesh element that the property is attached to (i.e. OpenMesh::VertexHandle, OpenMesh::HalfedgeHandle, OpenMesh::EdgeHandle, or OpenMesh::FaceHandle). <em>Mesh properties</em> (i.e. singleton properties that are attached to an entire mesh instead of individual elements) are accessed by passing \c void instead of a handle type.
21
22
- Second, the type of the property value that is attached to each element (e.g., \p int, \p double, etc.).

23
All three functions return a handle object (of type OpenMesh::PropertyManager) that manages the lifetime of the property and provides read / write access to its values.
24

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
Here are a few examples of how to create and access mesh properties:

\code
// Add a temporary mesh property that stores a double value for every vertex
auto temperature = OpenMesh::getOrMakeProperty<OpenMesh::VertexHandle, double>(mesh, "temperature");
OpenMesh::VertexHandle vh = ...;
temperature[vh] = 1.0;
// The temperature property will be removed from the mesh when the handle reaches the end of the scope.

// Obtain an existing mesh property that stores a 2D vector for every halfedge
// (Beware: the next line might throw if the expected property doesn't exist.)
auto uv = OpenMesh::getProperty<OpenMesh::HalfedgeHandle, OpenMesh::Vec2d>(mesh, "uv");
OpenMesh::VertexHandle heh = ...;
std::cout << temperature[heh][0] << " " << temperature[heh][1] << std::endl;

// Add a permanent mesh property containing a description string
auto desc = OpenMesh::getOrMakeProperty<void, std::string>(mesh, "desc");
*desc = "This is a very nice mesh.";
\endcode

---

## Code Example

49
50
In this example, we will store the \c cog value (see previous example) in a vertex property instead of keeping it in a separate array.
To do so, we first add a (temporary) property of the desired element type (OpenMesh::VertexHandle) and value type (\c %MyMesh::Point) to the mesh:
Jan Möbius's avatar
Jan Möbius committed
51
52

\dontinclude 03-properties/smooth.cc
53
\skipline makeTemporaryProperty
Jan Möbius's avatar
Jan Möbius committed
54

55
56
Enough memory is allocated to hold as many values of \c %MyMesh::Point as there are vertices.
All insert and delete operations on the mesh are synchronized with the attached properties.
Jan Möbius's avatar
Jan Möbius committed
57

58
Once the property is created, we can use it to compute the centers of the neighborhood of each vertex:
Jan Möbius's avatar
Jan Möbius committed
59

60
\skipline mesh.vertices
61
\until cog[vh] /= valence
Jan Möbius's avatar
Jan Möbius committed
62
63
\until }

64
Finally, we set the new position for each vertex:
Jan Möbius's avatar
Jan Möbius committed
65

66
67
68
69
\skipline mesh.vertices
\until mesh.point
\until }

70
71
72
73
Below is the complete source code:

\include 03-properties/smooth.cc

74
75
---

76
77
78
## Property Lifetime

In the above example, we chose to use makeTemporaryProperty(). This causes the created property to automatically be removed from the mesh as soon as we leave the scope of the associated handle variable \c cog.
79
80
81
82

If, instead, a property is desired to survive its local scope, it should be created with using getOrMakeProperty(). In that case, the property must be given a name that can later be used to retrieve the property. For example:

\code
83
    auto face_area = OpenMesh::makeTemporaryProperty<OpenMesh::FaceHandle, double>(mesh, "face_area");
84
85
86
87
88
\endcode

At a later time, we can use the getProperty() function to obtain a handle to a property that was previously created by refering to its name:
\code
    try {
89
        auto face_area = OpenMesh::getProperty<OpenMesh::FaceHandle, double>(mesh, "face_area");
90
91
92
93
94
95
96
        // Use the face_area property.
    }
    catch (const std::runtime_error& e) {
        // Property not found. Handle the error here.
    }
\endcode

97
98
99
100
101
102
103
104
105
106
107
Using hasProperty(), we can test whether a mesh has a certain property:
\code
    if (OpenMesh::hasProperty<OpenMesh::EdgeHandle, bool>(mesh, "is_valley")) {
        // Property exists. Do something with it.
        auto valley = OpenMesh::getProperty<OpenMesh::EdgeHandle, bool>(mesh, "is_valley");
    }
    else {
        // Property does not exist. Do something else.
    }
\endcode

108
109
---

110
111
## Low-Level Property API

112
113
114
115
116
The functions makeTemporaryProperty(), getOrMakeProperty(), and getProperty() are the convenient high-level interface for creating and accessing mesh properties.

Beneath these convenience functions, there is also a low-level property interface where handle and property lifetime must be managed manually. This interface is accessed through a mesh's add_property(), remove_property(), and property() functions and several property handle classes (OpenMesh::VPropHandleT, OpenMesh::HPropHandleT, OpenMesh::EPropHandleT, OpenMesh::FPropHandleT, OpenMesh::MPropHandleT).

---
Jan Möbius's avatar
Jan Möbius committed
117
118
119



120
*/