local.md 3.87 KB
Newer Older
TheNumbat's avatar
TheNumbat committed
1
2
---
layout: default
allai5's avatar
allai5 committed
3
title: Local Operations
TheNumbat's avatar
TheNumbat committed
4
permalink: /meshedit/local/
allai5's avatar
allai5 committed
5
6
7
8
parent: "A2: MeshEdit"
has_children: true
has_toc: false
nav_order: 1
TheNumbat's avatar
TheNumbat committed
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
---

# Local Mesh Operations

Many of the actions that need to be implemented in the MeshEdit mode are local mesh operations (like edge collapse, face bevel, etc.).

A good recipe for ensuring that all pointers are still valid after a local remeshing operation is:

1.  Draw a picture of all the elements (vertices, edges, faces, halfedges) that will be needed from the original mesh, and all the elements that should appear in the modified mesh.
2.  Allocate any new elements that are needed in the modified mesh, but do not appear in the original mesh.
3.  For every element in the "modified" picture, set **all** of its pointers -- even if they didn't change. For instance, for each halfedge, make sure to set `next`, `twin`, `vertex`, `edge`, and `face` to the correct values in the new (modified) picture. For each vertex, make sure to set its `halfedge` pointer. Etc. A convenience method `Halfedge::set_neighbors()` has been created for this purpose.
4.  Deallocate any elements that are no longer used in the modified mesh, which can be done by calling `Halfedge_Mesh::erase()`.

The reason for setting all the pointers (and not just the ones that changed) is that it is very easy to miss a pointer, causing your code to crash.

allai5's avatar
allai5 committed
24
### Interface with global mesh operations
TheNumbat's avatar
TheNumbat committed
25

allai5's avatar
allai5 committed
26
To facilitate user interaction, as well as global mesh processing operations (described below), local mesh operations should return the following values when possible. However, should it happen that the specified values are not available, or that the operation should not work on the given input, we need a way to signify the failure case. To do so, each local operation actually returns a ``std::optional`` value parameterized on the type of element it returns. For example, ``Halfedge_Mesh::erase_vertex`` returns a ``std::optional<Halfedge_Mesh::Face>``.  An ``optional`` can hold a value of the specified type, or, similarly to a pointer, a null value (``std::nullopt``). See ``student/meshedit.cpp`` for specific examples.
TheNumbat's avatar
TheNumbat committed
27

allai5's avatar
allai5 committed
28
Also, remember that in any case, _the program should not crash!_ So for instance, you should never return a pointer to an element that was deleted.
TheNumbat's avatar
TheNumbat committed
29

Hui Wang's avatar
Hui Wang committed
30
See the [User Guide](../guide/model) for demonstrations of each local operation.
TheNumbat's avatar
TheNumbat committed
31

TheNumbat's avatar
TheNumbat committed
32
33
*   `Halfedge_Mesh::flip_edge` - should return the edge that was flipped

Hui Wang's avatar
Hui Wang committed
34
![](local/flip_edge.svg)
TheNumbat's avatar
TheNumbat committed
35
36
37

*   `Halfedge_Mesh::split_edge` - should return the inserted vertex

Hui Wang's avatar
Hui Wang committed
38
![](local/split_edge.svg)
TheNumbat's avatar
TheNumbat committed
39

Sanjay Salem's avatar
Sanjay Salem committed
40
41
*   `Halfedge_Mesh::bisect_edge` - should bisect the edge and return the inserted vertex

Hui Wang's avatar
Hui Wang committed
42
![](local/bisect_edge.svg)
Sanjay Salem's avatar
Sanjay Salem committed
43

TheNumbat's avatar
TheNumbat committed
44
45
*   `Halfedge_Mesh::collapse_edge` - should return the new vertex, corresponding to the collapsed edge

Hui Wang's avatar
Hui Wang committed
46
![](local/collapse_edge.svg)
TheNumbat's avatar
TheNumbat committed
47
48
49

*   `Halfedge_Mesh::collapse_face` - should return the new vertex, corresponding to the collapsed face

Hui Wang's avatar
Hui Wang committed
50
![](local/collapse_face.svg)
TheNumbat's avatar
TheNumbat committed
51

Sanjay Salem's avatar
Sanjay Salem committed
52
53
*   `Halfedge_Mesh::inset_vertex` - should return the newly inserted vertex

Hui Wang's avatar
Hui Wang committed
54
![](local/inset_vertex.svg)
Sanjay Salem's avatar
Sanjay Salem committed
55

TheNumbat's avatar
TheNumbat committed
56
57
*   `Halfedge_Mesh::erase_vertex` - should return the new face, corresponding to the faces originally containing the vertex

Hui Wang's avatar
Hui Wang committed
58
![](local/erase_vertex.svg)
TheNumbat's avatar
TheNumbat committed
59
60
61

*   `Halfedge_Mesh::erase_edge` - should return the new face, corresponding to the faces originally containing the edge

Hui Wang's avatar
Hui Wang committed
62
![](local/erase_edge.svg)
TheNumbat's avatar
TheNumbat committed
63
64
65

*   `Halfedge_Mesh::bevel_vertex` - should return the new face, corresponding to the beveled vertex

Hui Wang's avatar
Hui Wang committed
66
![](local/bevel_vertex.svg)
TheNumbat's avatar
TheNumbat committed
67
68
69

*   `Halfedge_Mesh::bevel_edge` - should return the new face, corresponding to the beveled edge

Hui Wang's avatar
Hui Wang committed
70
![](local/bevel_edge.svg)
TheNumbat's avatar
TheNumbat committed
71

Sanjay Salem's avatar
Sanjay Salem committed
72
*   `Halfedge_Mesh::bevel_face` / `Halfedge_Mesh::extrude_face` / `Halfedge_Mesh::inset_face` - should return the new, inset face
TheNumbat's avatar
TheNumbat committed
73

Hui Wang's avatar
Hui Wang committed
74
![](local/bevel_face.svg)
TheNumbat's avatar
TheNumbat committed
75

Sanjay Salem's avatar
Sanjay Salem committed
76
77
*   `Halfedge_Mesh::extrude_vertex` - should return the new vertex

Hui Wang's avatar
Hui Wang committed
78
![](local/extrude_vertex.svg)