Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Courses
Scotty3D
Commits
01f62985
Commit
01f62985
authored
Oct 07, 2020
by
TheNumbat
Browse files
upstream changes
parent
750af030
Changes
6
Hide whitespace changes
Inline
Side-by-side
src/geometry/halfedge.cpp
View file @
01f62985
...
@@ -35,6 +35,9 @@ void Halfedge_Mesh::copy_to(Halfedge_Mesh &mesh) { copy_to(mesh, 0); }
...
@@ -35,6 +35,9 @@ void Halfedge_Mesh::copy_to(Halfedge_Mesh &mesh) { copy_to(mesh, 0); }
Halfedge_Mesh
::
ElementRef
Halfedge_Mesh
::
copy_to
(
Halfedge_Mesh
&
mesh
,
unsigned
int
eid
)
{
Halfedge_Mesh
::
ElementRef
Halfedge_Mesh
::
copy_to
(
Halfedge_Mesh
&
mesh
,
unsigned
int
eid
)
{
// Erase erase lists
do_erase
();
// Clear any existing elements.
// Clear any existing elements.
mesh
.
clear
();
mesh
.
clear
();
ElementRef
ret
=
vertices_begin
();
ElementRef
ret
=
vertices_begin
();
...
@@ -329,89 +332,156 @@ void Halfedge_Mesh::to_mesh(GL::Mesh &mesh, bool split_faces) const {
...
@@ -329,89 +332,156 @@ void Halfedge_Mesh::to_mesh(GL::Mesh &mesh, bool split_faces) const {
void
Halfedge_Mesh
::
mark_dirty
()
{
render_dirty_flag
=
true
;
}
void
Halfedge_Mesh
::
mark_dirty
()
{
render_dirty_flag
=
true
;
}
std
::
string
Halfedge_Mesh
::
validate
()
const
{
std
::
string
Halfedge_Mesh
::
validate
()
{
if
(
!
check_finite
())
if
(
!
check_finite
())
return
"A vertex position was set to a non-finite value."
;
return
"A vertex position was set to a non-finite value."
;
std
::
set
<
Halfedge
C
Ref
>
permutation
;
std
::
set
<
HalfedgeRef
>
permutation
;
// Check valid halfedge permutation
// Check valid halfedge permutation
for
(
HalfedgeCRef
h
=
halfedges_begin
();
h
!=
halfedges_end
();
h
++
)
{
for
(
HalfedgeRef
h
=
halfedges_begin
();
h
!=
halfedges_end
();
h
++
)
{
if
(
herased
.
find
(
h
)
!=
herased
.
end
())
continue
;
if
(
herased
.
find
(
h
->
next
())
!=
herased
.
end
())
{
return
"A halfedge's next is erased!"
;
}
if
(
herased
.
find
(
h
->
twin
())
!=
herased
.
end
())
{
return
"A halfedge's twin is erased!"
;
}
if
(
verased
.
find
(
h
->
vertex
())
!=
verased
.
end
())
{
return
"A halfedge's vertex is erased!"
;
}
if
(
ferased
.
find
(
h
->
face
())
!=
ferased
.
end
())
{
return
"A halfedge's face is erased!"
;
}
if
(
eerased
.
find
(
h
->
edge
())
!=
eerased
.
end
())
{
return
"A halfedge's edge is erased!"
;
}
// Check whether each halfedge's next points to a unique halfedge
// Check whether each halfedge's next points to a unique halfedge
if
(
permutation
.
find
(
h
->
next
())
==
permutation
.
end
())
{
if
(
permutation
.
find
(
h
->
next
())
==
permutation
.
end
())
{
permutation
.
insert
(
h
->
next
());
permutation
.
insert
(
h
->
next
());
}
else
{
}
else
{
return
"A halfedge is the next of m
ore than on
e halfedge!"
;
return
"A halfedge is the next of m
ultipl
e halfedge!"
;
}
}
}
}
for
(
HalfedgeCRef
h
=
halfedges_begin
();
h
!=
halfedges_end
();
h
++
)
{
for
(
HalfedgeRef
h
=
halfedges_begin
();
h
!=
halfedges_end
();
h
++
)
{
if
(
herased
.
find
(
h
)
!=
herased
.
end
())
continue
;
// Check whether each halfedge was pointed to by a halfedge
// Check whether each halfedge was pointed to by a halfedge
if
(
permutation
.
find
(
h
)
==
permutation
.
end
())
{
if
(
permutation
.
find
(
h
)
==
permutation
.
end
())
{
return
"A halfedge is the next of zero halfedges!"
;
return
"A halfedge is the next of zero halfedges!"
;
}
}
}
// Check twin relationships
for
(
HalfedgeCRef
h
=
halfedges_begin
();
h
!=
halfedges_end
();
h
++
)
{
// Check twin relationships
if
(
h
->
twin
()
==
h
)
{
if
(
h
->
twin
()
==
h
)
{
return
"A halfedge's twin
points to
itself!"
;
return
"A halfedge's twin
is
itself!"
;
}
}
if
(
h
->
twin
()
->
twin
()
!=
h
)
{
if
(
h
->
twin
()
->
twin
()
!=
h
)
{
return
"A halfedge's twin's twin
doe
s not
point to
itself!"
;
return
"A halfedge's twin's twin
i
s not itself!"
;
}
}
}
}
// Check whether each halfedge incident on a vertex points to that vertex
// Check whether each halfedge incident on a vertex points to that vertex
for
(
VertexCRef
v
=
vertices_begin
();
v
!=
vertices_end
();
v
++
)
{
for
(
VertexRef
v
=
vertices_begin
();
v
!=
vertices_end
();
v
++
)
{
HalfedgeCRef
h
=
v
->
halfedge
();
if
(
verased
.
find
(
v
)
!=
verased
.
end
())
continue
;
HalfedgeRef
h
=
v
->
halfedge
();
if
(
herased
.
find
(
h
)
!=
herased
.
end
())
{
return
"A vertex's halfedge is erased!"
;
}
do
{
do
{
if
(
h
->
vertex
()
!=
v
)
{
if
(
h
->
vertex
()
!=
v
)
{
return
"A halfedge does not point to
its
vertex!"
;
return
"A
vertex's
halfedge does not point to
that
vertex!"
;
}
}
h
=
h
->
twin
()
->
next
();
h
=
h
->
twin
()
->
next
();
}
while
(
h
!=
v
->
halfedge
());
}
while
(
h
!=
v
->
halfedge
());
}
}
// Check whether each halfedge incident on an edge points to that edge
// Check whether each halfedge incident on an edge points to that edge
for
(
EdgeCRef
e
=
edges_begin
();
e
!=
edges_end
();
e
++
)
{
for
(
EdgeRef
e
=
edges_begin
();
e
!=
edges_end
();
e
++
)
{
HalfedgeCRef
h
=
e
->
halfedge
();
if
(
eerased
.
find
(
e
)
!=
eerased
.
end
())
continue
;
HalfedgeRef
h
=
e
->
halfedge
();
if
(
herased
.
find
(
h
)
!=
herased
.
end
())
{
return
"An edge's halfedge is erased!"
;
}
do
{
do
{
if
(
h
->
edge
()
!=
e
)
{
if
(
h
->
edge
()
!=
e
)
{
return
"A halfedge does not point to
its
edge!"
;
return
"A
n edge's
halfedge does not point to
that
edge!"
;
}
}
h
=
h
->
twin
();
h
=
h
->
twin
();
}
while
(
h
!=
e
->
halfedge
());
}
while
(
h
!=
e
->
halfedge
());
}
}
// Check whether each halfedge incident on a face points to that face
// Check whether each halfedge incident on a face points to that face
for
(
FaceCRef
f
=
faces_begin
();
f
!=
faces_end
();
f
++
)
{
for
(
FaceRef
f
=
faces_begin
();
f
!=
faces_end
();
f
++
)
{
HalfedgeCRef
h
=
f
->
halfedge
();
if
(
ferased
.
find
(
f
)
!=
ferased
.
end
())
continue
;
HalfedgeRef
h
=
f
->
halfedge
();
if
(
herased
.
find
(
h
)
!=
herased
.
end
())
{
return
"A face's halfedge is erased!"
;
}
do
{
do
{
if
(
h
->
face
()
!=
f
)
{
if
(
h
->
face
()
!=
f
)
{
return
"A halfedge does not point to
its
face!"
;
return
"A
face's
halfedge does not point to
that
face!"
;
}
}
h
=
h
->
next
();
h
=
h
->
next
();
}
while
(
h
!=
f
->
halfedge
());
}
while
(
h
!=
f
->
halfedge
());
}
}
// Check whether each halfedge incident on a boundary loop points to that boundary loop
// Check whether each halfedge incident on a boundary loop points to that boundary loop
for
(
FaceCRef
b
=
boundaries_begin
();
b
!=
boundaries_end
();
b
++
)
{
for
(
FaceRef
b
=
boundaries_begin
();
b
!=
boundaries_end
();
b
++
)
{
HalfedgeCRef
h
=
b
->
halfedge
();
if
(
ferased
.
find
(
b
)
!=
ferased
.
end
())
continue
;
HalfedgeRef
h
=
b
->
halfedge
();
if
(
herased
.
find
(
h
)
!=
herased
.
end
())
{
return
"A boundary's halfedge is erased!"
;
}
do
{
do
{
if
(
h
->
face
()
!=
b
)
{
if
(
h
->
face
()
!=
b
)
{
return
"A halfedge does not point to its boundary loop!"
;
return
"A
boundary
halfedge does not point to its boundary loop!"
;
}
}
h
=
h
->
next
();
h
=
h
->
next
();
}
while
(
h
!=
b
->
halfedge
());
}
while
(
h
!=
b
->
halfedge
());
}
}
do_erase
();
return
{};
return
{};
}
}
void
Halfedge_Mesh
::
do_erase
()
{
for
(
auto
&
v
:
verased
)
{
vertices
.
erase
(
v
);
}
for
(
auto
&
e
:
eerased
)
{
edges
.
erase
(
e
);
}
for
(
auto
&
f
:
ferased
)
{
if
(
f
->
is_boundary
())
boundaries
.
erase
(
f
);
else
faces
.
erase
(
f
);
}
for
(
auto
&
h
:
herased
)
{
halfedges
.
erase
(
h
);
}
verased
.
clear
();
eerased
.
clear
();
ferased
.
clear
();
herased
.
clear
();
}
std
::
string
Halfedge_Mesh
::
from_mesh
(
const
GL
::
Mesh
&
mesh
)
{
std
::
string
Halfedge_Mesh
::
from_mesh
(
const
GL
::
Mesh
&
mesh
)
{
auto
idx
=
mesh
.
indices
();
auto
idx
=
mesh
.
indices
();
...
...
src/geometry/halfedge.h
View file @
01f62985
...
@@ -132,6 +132,7 @@
...
@@ -132,6 +132,7 @@
#include <list>
#include <list>
#include <optional>
#include <optional>
#include <string>
#include <string>
#include <set>
#include <variant>
#include <variant>
#include <vector>
#include <vector>
...
@@ -447,12 +448,14 @@ public:
...
@@ -447,12 +448,14 @@ public:
iterating over a linked list, and want to delete some of the elements as you go. How do you
iterating over a linked list, and want to delete some of the elements as you go. How do you
do this without causing any problems? For instance, if you delete the current element, will
do this without causing any problems? For instance, if you delete the current element, will
you be able to iterate to the next element? Etc.
you be able to iterate to the next element? Etc.
Note: the elements are not actually deleted until validate() is called in order to facilitate
checking for dangling references.
*/
*/
void
erase
(
HalfedgeRef
h
)
{
halfedges
.
erase
(
h
);
}
void
erase
(
VertexRef
v
)
{
verased
.
insert
(
v
);
}
void
erase
(
VertexRef
v
)
{
vertices
.
erase
(
v
);
}
void
erase
(
EdgeRef
e
)
{
eerased
.
insert
(
e
);
}
void
erase
(
EdgeRef
e
)
{
edges
.
erase
(
e
);
}
void
erase
(
FaceRef
f
)
{
ferased
.
insert
(
f
);
}
void
erase
(
FaceRef
f
)
{
faces
.
erase
(
f
);
}
void
erase
(
HalfedgeRef
h
)
{
herased
.
insert
(
h
);
}
void
erase_boundary
(
FaceRef
f
)
{
boundaries
.
erase
(
f
);
}
/*
/*
These methods allocate new mesh elements, returning a pointer (i.e., iterator) to the
These methods allocate new mesh elements, returning a pointer (i.e., iterator) to the
...
@@ -512,7 +515,7 @@ public:
...
@@ -512,7 +515,7 @@ public:
Size
n_halfedges
()
const
{
return
halfedges
.
size
();
};
Size
n_halfedges
()
const
{
return
halfedges
.
size
();
};
/// Check if half-edge mesh is valid
/// Check if half-edge mesh is valid
std
::
string
validate
()
const
;
std
::
string
validate
();
//////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////
// End methods students should use, begin internal methods - you don't need to use these
// End methods students should use, begin internal methods - you don't need to use these
...
@@ -545,11 +548,14 @@ public:
...
@@ -545,11 +548,14 @@ public:
/// vertices)
/// vertices)
std
::
string
from_mesh
(
const
GL
::
Mesh
&
mesh
);
std
::
string
from_mesh
(
const
GL
::
Mesh
&
mesh
);
/// For rendering
/// WARNING: erased elements stay in the element lists until do_erase()
bool
render_dirty_flag
=
false
;
/// or validate() are called
void
do_erase
();
void
mark_dirty
();
void
mark_dirty
();
bool
flipped
()
const
{
return
flip_orientation
;
}
bool
flipped
()
const
{
return
flip_orientation
;
}
void
flip
()
{
flip_orientation
=
!
flip_orientation
;
};
void
flip
()
{
flip_orientation
=
!
flip_orientation
;
};
bool
render_dirty_flag
=
false
;
Vec3
normal_of
(
ElementRef
elem
);
Vec3
normal_of
(
ElementRef
elem
);
static
Vec3
center_of
(
ElementRef
elem
);
static
Vec3
center_of
(
ElementRef
elem
);
...
@@ -560,9 +566,15 @@ private:
...
@@ -560,9 +566,15 @@ private:
std
::
list
<
Edge
>
edges
;
std
::
list
<
Edge
>
edges
;
std
::
list
<
Face
>
faces
,
boundaries
;
std
::
list
<
Face
>
faces
,
boundaries
;
std
::
list
<
Halfedge
>
halfedges
;
std
::
list
<
Halfedge
>
halfedges
;
bool
check_finite
()
const
;
unsigned
int
next_id
;
unsigned
int
next_id
;
bool
flip_orientation
=
false
;
bool
flip_orientation
=
false
;
bool
check_finite
()
const
;
std
::
set
<
VertexRef
>
verased
;
std
::
set
<
EdgeRef
>
eerased
;
std
::
set
<
FaceRef
>
ferased
;
std
::
set
<
HalfedgeRef
>
herased
;
};
};
/*
/*
...
...
src/gui/manager.cpp
View file @
01f62985
...
@@ -53,7 +53,9 @@ bool Manager::keydown(Undo &undo, SDL_Keysym key, Scene &scene, Camera &cam) {
...
@@ -53,7 +53,9 @@ bool Manager::keydown(Undo &undo, SDL_Keysym key, Scene &scene, Camera &cam) {
Uint16
mod
=
KMOD_CTRL
;
Uint16
mod
=
KMOD_CTRL
;
if
(
key
.
sym
==
SDLK_DELETE
&&
layout
.
selected
())
{
if
(
key
.
sym
==
SDLK_DELETE
&&
layout
.
selected
())
{
#endif
#endif
if
(
mode
!=
Mode
::
model
&&
mode
!=
Mode
::
rig
&&
mode
!=
Mode
::
animate
)
{
if
(
mode
==
Mode
::
model
)
{
model
.
erase_selected
(
undo
,
scene
.
get
(
layout
.
selected
()));
}
else
if
(
mode
!=
Mode
::
rig
&&
mode
!=
Mode
::
animate
)
{
undo
.
del_obj
(
layout
.
selected
());
undo
.
del_obj
(
layout
.
selected
());
return
true
;
return
true
;
}
}
...
@@ -90,7 +92,7 @@ bool Manager::keydown(Undo &undo, SDL_Keysym key, Scene &scene, Camera &cam) {
...
@@ -90,7 +92,7 @@ bool Manager::keydown(Undo &undo, SDL_Keysym key, Scene &scene, Camera &cam) {
if
(
mode
==
Mode
::
rig
)
{
if
(
mode
==
Mode
::
rig
)
{
cam
.
look_at
(
Vec3
{},
-
cam
.
front
()
*
cam
.
dist
());
cam
.
look_at
(
Vec3
{},
-
cam
.
front
()
*
cam
.
dist
());
return
true
;
return
true
;
}
else
if
(
layout
.
selected
())
{
}
else
if
(
mode
!=
Mode
::
model
&&
layout
.
selected
())
{
frame
(
scene
,
cam
);
frame
(
scene
,
cam
);
return
true
;
return
true
;
}
}
...
@@ -463,10 +465,9 @@ void Manager::UIsidebar(Scene &scene, Undo &undo, float menu_height, Camera &cam
...
@@ -463,10 +465,9 @@ void Manager::UIsidebar(Scene &scene, Undo &undo, float menu_height, Camera &cam
new_light_focus
=
true
;
new_light_focus
=
true
;
}
}
}
}
if
(
!
scene
.
empty
())
{
ImGui
::
Separator
();
ImGui
::
Separator
();
ImGui
::
Text
(
"Select an Object"
);
ImGui
::
Text
(
"Select an Object"
);
}
scene
.
for_items
([
&
](
Scene_Item
&
obj
)
{
scene
.
for_items
([
&
](
Scene_Item
&
obj
)
{
if
((
mode
==
Mode
::
model
||
mode
==
Mode
::
rig
)
&&
if
((
mode
==
Mode
::
model
||
mode
==
Mode
::
rig
)
&&
...
...
src/gui/model.cpp
View file @
01f62985
...
@@ -572,30 +572,39 @@ void Model::zoom_to(Halfedge_Mesh::ElementRef ref, Camera &cam) {
...
@@ -572,30 +572,39 @@ void Model::zoom_to(Halfedge_Mesh::ElementRef ref, Camera &cam) {
cam
.
look_at
(
center
,
pos
);
cam
.
look_at
(
center
,
pos
);
}
}
std
::
string
Model
::
UIsidebar
(
Undo
&
undo
,
Widgets
&
widgets
,
Scene_Maybe
obj_opt
,
Camera
&
camera
)
{
std
::
optional
<
std
::
reference_wrapper
<
Scene_Object
>>
Model
::
is_my_obj
(
Scene_Maybe
obj_opt
)
{
if
(
ImGui
::
CollapsingHeader
(
"Edit Colors"
))
{
ImGui
::
ColorEdit3
(
"Face"
,
f_col
.
data
);
ImGui
::
ColorEdit3
(
"Vertex"
,
v_col
.
data
);
ImGui
::
ColorEdit3
(
"Edge"
,
e_col
.
data
);
ImGui
::
ColorEdit3
(
"Halfedge"
,
he_col
.
data
);
}
ImGui
::
Separator
();
if
(
!
obj_opt
.
has_value
())
if
(
!
obj_opt
.
has_value
())
return
{}
;
return
std
::
nullopt
;
Scene_Item
&
item
=
obj_opt
.
value
();
Scene_Item
&
item
=
obj_opt
.
value
();
if
(
!
item
.
is
<
Scene_Object
>
())
if
(
!
item
.
is
<
Scene_Object
>
())
return
{}
;
return
std
::
nullopt
;
Scene_Object
&
obj
=
item
.
get
<
Scene_Object
>
();
Scene_Object
&
obj
=
item
.
get
<
Scene_Object
>
();
if
(
obj
.
opt
.
shape_type
!=
PT
::
Shape_Type
::
none
)
if
(
obj
.
opt
.
shape_type
!=
PT
::
Shape_Type
::
none
)
return
{}
;
return
std
::
nullopt
;
if
(
!
my_mesh
||
!
obj
.
is_editable
())
if
(
!
my_mesh
||
!
obj
.
is_editable
())
return
{};
return
std
::
nullopt
;
assert
(
my_mesh
==
&
obj
.
get_mesh
());
assert
(
my_mesh
==
&
obj
.
get_mesh
());
return
obj
;
}
std
::
string
Model
::
UIsidebar
(
Undo
&
undo
,
Widgets
&
widgets
,
Scene_Maybe
obj_opt
,
Camera
&
camera
)
{
if
(
ImGui
::
CollapsingHeader
(
"Edit Colors"
))
{
ImGui
::
ColorEdit3
(
"Face"
,
f_col
.
data
);
ImGui
::
ColorEdit3
(
"Vertex"
,
v_col
.
data
);
ImGui
::
ColorEdit3
(
"Edge"
,
e_col
.
data
);
ImGui
::
ColorEdit3
(
"Halfedge"
,
he_col
.
data
);
}
ImGui
::
Separator
();
auto
opt
=
is_my_obj
(
obj_opt
);
if
(
!
opt
.
has_value
())
return
{};
Scene_Object
&
obj
=
opt
.
value
();
Halfedge_Mesh
&
mesh
=
*
my_mesh
;
Halfedge_Mesh
&
mesh
=
*
my_mesh
;
Halfedge_Mesh
before
;
Halfedge_Mesh
before
;
...
@@ -648,7 +657,7 @@ std::string Model::UIsidebar(Undo &undo, Widgets &widgets, Scene_Maybe obj_opt,
...
@@ -648,7 +657,7 @@ std::string Model::UIsidebar(Undo &undo, Widgets &widgets, Scene_Maybe obj_opt,
std
::
string
err
=
std
::
visit
(
std
::
string
err
=
std
::
visit
(
overloaded
{
overloaded
{
[
&
](
Halfedge_Mesh
::
VertexRef
vert
)
->
std
::
string
{
[
&
](
Halfedge_Mesh
::
VertexRef
vert
)
->
std
::
string
{
if
(
ImGui
::
Button
(
"Erase"
))
{
if
(
ImGui
::
Button
(
"Erase
[del]
"
))
{
mesh
.
copy_to
(
before
);
mesh
.
copy_to
(
before
);
return
update_mesh
(
undo
,
obj
,
std
::
move
(
before
),
vert
,
return
update_mesh
(
undo
,
obj
,
std
::
move
(
before
),
vert
,
[](
Halfedge_Mesh
&
m
,
Halfedge_Mesh
::
ElementRef
vert
)
{
[](
Halfedge_Mesh
&
m
,
Halfedge_Mesh
::
ElementRef
vert
)
{
...
@@ -659,7 +668,7 @@ std::string Model::UIsidebar(Undo &undo, Widgets &widgets, Scene_Maybe obj_opt,
...
@@ -659,7 +668,7 @@ std::string Model::UIsidebar(Undo &undo, Widgets &widgets, Scene_Maybe obj_opt,
return
{};
return
{};
},
},
[
&
](
Halfedge_Mesh
::
EdgeRef
edge
)
->
std
::
string
{
[
&
](
Halfedge_Mesh
::
EdgeRef
edge
)
->
std
::
string
{
if
(
ImGui
::
Button
(
"Erase"
))
{
if
(
ImGui
::
Button
(
"Erase
[del]
"
))
{
mesh
.
copy_to
(
before
);
mesh
.
copy_to
(
before
);
return
update_mesh
(
undo
,
obj
,
std
::
move
(
before
),
edge
,
return
update_mesh
(
undo
,
obj
,
std
::
move
(
before
),
edge
,
[](
Halfedge_Mesh
&
m
,
Halfedge_Mesh
::
ElementRef
edge
)
{
[](
Halfedge_Mesh
&
m
,
Halfedge_Mesh
::
ElementRef
edge
)
{
...
@@ -754,6 +763,40 @@ std::string Model::UIsidebar(Undo &undo, Widgets &widgets, Scene_Maybe obj_opt,
...
@@ -754,6 +763,40 @@ std::string Model::UIsidebar(Undo &undo, Widgets &widgets, Scene_Maybe obj_opt,
return
{};
return
{};
}
}
void
Model
::
erase_selected
(
Undo
&
undo
,
Scene_Maybe
obj_opt
)
{
auto
opt
=
is_my_obj
(
obj_opt
);
if
(
!
opt
.
has_value
())
return
;
Scene_Object
&
obj
=
opt
.
value
();
auto
sel_
=
selected_element
();
if
(
!
sel_
.
has_value
())
return
;
Halfedge_Mesh
::
ElementRef
sel
=
sel_
.
value
();
Halfedge_Mesh
&
mesh
=
*
my_mesh
;
Halfedge_Mesh
before
;
mesh
.
copy_to
(
before
);
std
::
visit
(
overloaded
{
[
&
](
Halfedge_Mesh
::
VertexRef
vert
)
{
return
update_mesh
(
undo
,
obj
,
std
::
move
(
before
),
vert
,
[](
Halfedge_Mesh
&
m
,
Halfedge_Mesh
::
ElementRef
vert
)
{
return
m
.
erase_vertex
(
std
::
get
<
Halfedge_Mesh
::
VertexRef
>
(
vert
));
});
},
[
&
](
Halfedge_Mesh
::
EdgeRef
edge
)
{
return
update_mesh
(
undo
,
obj
,
std
::
move
(
before
),
edge
,
[](
Halfedge_Mesh
&
m
,
Halfedge_Mesh
::
ElementRef
edge
)
{
return
m
.
erase_edge
(
std
::
get
<
Halfedge_Mesh
::
EdgeRef
>
(
edge
));
});
},
[](
auto
)
{
return
std
::
string
{};
}
},
sel
);
}
void
Model
::
clear_select
()
{
selected_elem_id
=
0
;
}
void
Model
::
clear_select
()
{
selected_elem_id
=
0
;
}
void
Model
::
render
(
Scene_Maybe
obj_opt
,
Widgets
&
widgets
,
Camera
&
cam
)
{
void
Model
::
render
(
Scene_Maybe
obj_opt
,
Widgets
&
widgets
,
Camera
&
cam
)
{
...
...
src/gui/model.h
View file @
01f62985
...
@@ -27,6 +27,7 @@ public:
...
@@ -27,6 +27,7 @@ public:
Vec3
selected_pos
();
Vec3
selected_pos
();
void
clear_select
();
void
clear_select
();
void
erase_selected
(
Undo
&
undo
,
Scene_Maybe
obj_opt
);
std
::
string
end_transform
(
Widgets
&
widgets
,
Undo
&
undo
,
Scene_Object
&
obj
);
std
::
string
end_transform
(
Widgets
&
widgets
,
Undo
&
undo
,
Scene_Object
&
obj
);
void
apply_transform
(
Widgets
&
widgets
);
void
apply_transform
(
Widgets
&
widgets
);
std
::
string
select
(
Widgets
&
widgets
,
Scene_ID
click
,
Vec3
cam
,
Vec2
spos
,
Vec3
dir
);
std
::
string
select
(
Widgets
&
widgets
,
Scene_ID
click
,
Vec3
cam
,
Vec2
spos
,
Vec3
dir
);
...
@@ -48,6 +49,7 @@ private:
...
@@ -48,6 +49,7 @@ private:
void
begin_transform
();
void
begin_transform
();
bool
begin_bevel
(
std
::
string
&
err
);
bool
begin_bevel
(
std
::
string
&
err
);
void
set_selected
(
Halfedge_Mesh
::
ElementRef
elem
);
void
set_selected
(
Halfedge_Mesh
::
ElementRef
elem
);
std
::
optional
<
std
::
reference_wrapper
<
Scene_Object
>>
is_my_obj
(
Scene_Maybe
obj_opt
);
std
::
optional
<
Halfedge_Mesh
::
ElementRef
>
selected_element
();
std
::
optional
<
Halfedge_Mesh
::
ElementRef
>
selected_element
();
void
rebuild
();
void
rebuild
();
...
...
src/scene/undo.h
View file @
01f62985
...
@@ -22,7 +22,8 @@ public:
...
@@ -22,7 +22,8 @@ public:
virtual
~
Action_Base
()
=
default
;
virtual
~
Action_Base
()
=
default
;
};
};
template
<
typename
T
>
class
MeshOp
:
public
Action_Base
{
template
<
typename
T
>
class
MeshOp
:
public
Action_Base
{
void
undo
()
{
void
undo
()
{
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
obj
.
set_mesh
(
mesh
);
obj
.
set_mesh
(
mesh
);
...
@@ -31,6 +32,7 @@ template <typename T> class MeshOp : public Action_Base {
...
@@ -31,6 +32,7 @@ template <typename T> class MeshOp : public Action_Base {
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
Scene_Object
&
obj
=
scene
.
get_obj
(
id
);
auto
sel
=
obj
.
set_mesh
(
mesh
,
eid
);
auto
sel
=
obj
.
set_mesh
(
mesh
,
eid
);
op
(
obj
.
get_mesh
(),
sel
);
op
(
obj
.
get_mesh
(),
sel
);
obj
.
get_mesh
().
do_erase
();
}
}
Scene
&
scene
;
Scene
&
scene
;
Scene_ID
id
;
Scene_ID
id
;
...
...
Write
Preview
Markdown
is supported
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