[Bf-blender-cvs] [d22cfad9604] bevelv2: Initial hook up of face bevel to geometry nodes.
Howard Trickey
noreply at git.blender.org
Sun Sep 11 15:53:51 CEST 2022
Commit: d22cfad9604b738a734e0566cb10a6633134dc3c
Author: Howard Trickey
Date: Sun Sep 11 09:52:22 2022 -0400
Branches: bevelv2
https://developer.blender.org/rBd22cfad9604b738a734e0566cb10a6633134dc3c
Initial hook up of face bevel to geometry nodes.
Only works for individual face insets (bevels) so far,
and doesn't preserve attributes yet.
===================================================================
M source/blender/blenlib/intern/mesh_inset.cc
M source/blender/nodes/geometry/nodes/node_geo_bevel_mesh.cc
===================================================================
diff --git a/source/blender/blenlib/intern/mesh_inset.cc b/source/blender/blenlib/intern/mesh_inset.cc
index 69bddbb8035..ceb8d26060f 100644
--- a/source/blender/blenlib/intern/mesh_inset.cc
+++ b/source/blender/blenlib/intern/mesh_inset.cc
@@ -2964,10 +2964,14 @@ static MeshInset_Result trimesh_to_output(const TriangleMesh &trimesh,
}
}
result.vert = Array<float3>(totv);
+ result.orig_vert = Array<int>(totv, -1);
int out_v_index = 0;
for (int i : IndexRange(tot_all_verts)) {
const Vert *v = trimesh.get_vert_by_index(i);
if (!v->is_deleted()) {
+ if (i < input.vert.size()) {
+ result.orig_vert[out_v_index] = i;
+ }
result.vert[out_v_index++] = v->co;
}
}
@@ -3031,6 +3035,23 @@ static MeshInset_Result trimesh_to_output(const TriangleMesh &trimesh,
for (int fi : out_faces.index_range()) {
result.face[fi] = out_faces[fi];
}
+ if (dbg_level > 0) {
+ std::cout << "result:\n";
+ for (int i : result.vert.index_range()) {
+ std::cout << "vert[" << i << "] = " << result.vert[i] << "\n";
+ }
+ for (int i : result.face.index_range()) {
+ const Vector<int> &f = result.face[i];
+ std::cout << "face[" << i << "] =";
+ for (int j : f.index_range()) {
+ std::cout << " " << f[j];
+ }
+ std::cout << "\n";
+ }
+ for (int i : result.orig_vert.index_range()) {
+ std::cout << "orig_vert[" << i << "] = " << result.orig_vert[i] << "\n";
+ }
+ }
return result;
}
@@ -3038,7 +3059,29 @@ MeshInset_Result mesh_inset_calc(const MeshInset_Input &input)
{
constexpr int dbg_level = 0;
if (dbg_level > 0) {
- std::cout << "mesh_inset_calc, input has " << input.face.size() << " faces\n";
+ std::cout << "mesh_inset_calc\n";
+ if (dbg_level > 1) {
+ std::cout << "input\n";
+ for (int i : input.vert.index_range()) {
+ std::cout << "vert[" << i << "] = " << input.vert[i] << "\n";
+ }
+ for (int i : input.face.index_range()) {
+ std::cout << "face[" << i << "] =";
+ const Vector<int> &f = input.face[i];
+ for (int j : f.index_range()) {
+ std::cout << " " << f[j];
+ }
+ std::cout << "\n";
+ }
+ for (int i : input.contour.index_range()) {
+ std::cout << "contour[" << i << "] =";
+ const Vector<int> &c = input.contour[i];
+ for (int j : c.index_range()) {
+ std::cout << " " << c[j];
+ }
+ std::cout << "\n";
+ }
+ }
}
TriangleMesh trimesh = triangulate_input(input);
StraightSkeleton ss(trimesh, input.contour, input.inset_amount);
diff --git a/source/blender/nodes/geometry/nodes/node_geo_bevel_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_bevel_mesh.cc
index eb5c2584300..a0c1c2b2205 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_bevel_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_bevel_mesh.cc
@@ -11,6 +11,7 @@
#include "BLI_array.hh"
#include "BLI_math_vec_types.hh"
#include "BLI_math_vector.hh"
+#include "BLI_mesh_inset.hh"
#include "BLI_set.hh"
#include "BLI_sort.hh"
#include "BLI_task.hh"
@@ -781,6 +782,7 @@ class IndexAlloc {
*/
class MeshDelta {
const Mesh &mesh_;
+ const MeshTopology &topo_;
IndexAlloc vert_alloc_;
IndexAlloc edge_alloc_;
IndexAlloc poly_alloc_;
@@ -799,13 +801,15 @@ class MeshDelta {
Vector<int> new_loop_rep_;
public:
- MeshDelta(const Mesh &mesh);
+ MeshDelta(const Mesh &mesh, const MeshTopology &topo);
/* In the following, `rep` is the index of the old mesh element to base attributes on. */
int new_vert(const float3 &co, int rep);
int new_edge(int v1, int v2, int rep);
int new_loop(int v, int e, int rep);
int new_face(int loopstart, int totloop, int rep);
+ /* Find the edge either in mesh or new_edges_, or make a new one if not there. */
+ int find_or_add_edge(int v1, int v2, int rep);
void delete_vert(int v)
{
@@ -830,8 +834,9 @@ class MeshDelta {
void print(const std::string &label) const;
};
-MeshDelta::MeshDelta(const Mesh &mesh)
+MeshDelta::MeshDelta(const Mesh &mesh, const MeshTopology &topo)
: mesh_(mesh),
+ topo_(topo),
vert_alloc_(mesh_.totvert),
edge_alloc_(mesh_.totedge),
poly_alloc_(mesh_.totpoly),
@@ -865,6 +870,26 @@ int MeshDelta::new_edge(int v1, int v2, int rep)
return e;
}
+int MeshDelta::find_or_add_edge(int v1, int v2, int rep)
+{
+ if (v1 < mesh_.totvert) {
+ for (int i : topo_.vert_edges(v1)) {
+ const MEdge &e = mesh_.edges()[i];
+ if ((e.v1 == v1 && e.v2 == v2) || (e.v1 == v2 && e.v2 == v1)) {
+ return i;
+ }
+ }
+ }
+ /* TODO: have an equivalent of vert_edges() in MeshDelta to make this fast! */
+ for (int i : new_edges_.index_range()) {
+ const MEdge &e = new_edges_[i];
+ if ((e.v1 == v1 && e.v2 == v2) || (e.v1 == v2 && e.v2 == v1)) {
+ return mesh_.totedge + i;
+ }
+ }
+ return new_edge(v1, v2, rep);
+}
+
int MeshDelta::new_loop(int v, int e, int rep)
{
int l = loop_alloc_.alloc();
@@ -1402,7 +1427,7 @@ static Mesh *finish_vertex_bevel(BevelData &bd,
GeometrySet geometry_set,
const MeshComponent &component)
{
- MeshDelta mesh_delta(mesh);
+ MeshDelta mesh_delta(mesh, bd.topo);
MutableSpan<BevelVertexData> beveled_bvds = bd.mutable_beveled_vertices_data();
/* Make the polygons that will replace the beveled vertices. */
@@ -1562,6 +1587,73 @@ static Mesh *finish_vertex_bevel(BevelData &bd,
return mesh_out;
}
+/* Temporary face bevel function. TODO: expand to regional face bevels. */
+static Mesh *calculate_face_bevel(BevelData &bd,
+ const Mesh &mesh,
+ GeometrySet geometry_set,
+ const MeshComponent &component,
+ const IndexMask &to_bevel,
+ const VArray<float> amounts)
+{
+ Span<MPoly> faces = mesh.polys();
+ Span<MVert> verts = mesh.verts();
+ Span<MLoop> loops = mesh.loops();
+ MeshDelta delta(mesh, bd.topo);
+ for (const int i : to_bevel.index_range()) {
+ const int face_index = to_bevel[i];
+ const MPoly &face = faces[face_index];
+ const int n = face.totloop;
+ Array<float3> vert_co(n);
+ Array<int> mi_vert_to_mesh_vert(n);
+ Vector<int> face_vert;
+ for (const int l : IndexRange(n)) {
+ const MLoop &loop = loops[face.loopstart + l];
+ const int v_index = loop.v;
+ vert_co[l] = verts[v_index].co;
+ mi_vert_to_mesh_vert[l] = v_index;
+ face_vert.append(l);
+ }
+ Array<Vector<int>> mi_faces(1);
+ mi_faces[0] = face_vert;
+ meshinset::MeshInset_Input mi_input;
+ mi_input.vert = vert_co.as_span();
+ mi_input.face = mi_faces.as_span();
+ mi_input.contour = mi_faces.as_span();
+ mi_input.inset_amount = amounts[face_index];
+ meshinset::MeshInset_Result mi_result = meshinset::mesh_inset_calc(mi_input);
+ /* Mapping from the result output vert indices to mesh indices. */
+ Array<int> mr_vert_to_mesh_vert(mi_result.vert.size());
+ for (const int i : mi_result.vert.index_range()) {
+ if (mi_result.orig_vert[i] != -1) {
+ mr_vert_to_mesh_vert[i] = mi_vert_to_mesh_vert[mi_result.orig_vert[i]];
+ }
+ else {
+ mr_vert_to_mesh_vert[i] = delta.new_vert(mi_result.vert[i], 0); // TODO: better rep!
+ }
+ }
+ /* Construct the output faces. */
+ for (const int out_face_index : mi_result.face.index_range()) {
+ Vector<int> &mr_face = mi_result.face[out_face_index];
+ const int m = mr_face.size();
+ int lfirst = -1;
+ for (const int i : IndexRange(m)) {
+ int v = mr_vert_to_mesh_vert[mr_face[i]];
+ int v_next = mr_vert_to_mesh_vert[mr_face[(i + 1) % m]];
+ int e = delta.find_or_add_edge(v, v_next, 0); // TODO: better rep!
+ int l = delta.new_loop(v, e, 0); //TODO: better rep!
+ if (lfirst == -1) {
+ lfirst = l;
+ }
+ }
+ delta.new_face(lfirst, m, face_index); // TODO: better rep!
+ }
+ /* The following also deletes the loops. The edges in the original faces should have all been reused. */
+ delta.delete_face(face_index);
+ }
+ Mesh *mesh_out = delta.apply_delta_to_mesh(geometry_set, component);
+ return mesh_out;
+}
+
static Mesh *bevel_mesh_vertices(GeometrySet geometry_set,
const MeshComponent &component,
const Field<bool> &selection_field,
@@ -1583,16 +1675,35 @@ static Mesh *bevel_mesh_vertices(GeometrySet geometry_set,
return finish_vertex_bevel(bdata, mesh, geometry_set, component);
}
-static void bevel_mesh_edges(const MeshComponent &UNUSED(component),
+static Mesh *bevel_mesh_edges(GeometrySet geometry_set,
+ const MeshComponent &component,
const Field<bool> &UNUSED(selection_field),
const Field<float> &UNUSED(amount_field))
{
+ const Mesh &mesh = *component.get_for_read();
+ BevelData bdata(mesh);
+ MeshDelta delta(mesh, bdata.topo);
+ /* TODO: actually bevel the edges! */
+ Mesh *mesh_out = delta.apply_delta_to_mesh(geometry_set, component);
+ return mesh_out;
}
-static void bevel_mesh_faces(const MeshComponent &UNUSED(component),
- const Field<bool> &UNUSED(selection_field),
- const Field<float> &UNUSED(amount_field))
+static Mesh *bevel_mesh_faces(GeometrySet geometry_set,
+ const MeshComponent &component,
+ const Field<bool> &selection_field,
+ const Field<float> &amount_field)
{
+ const Mesh &mesh = *component.get_for_read();
+ bke::MeshFieldContext context{mesh, ATTR_DOMAIN_FACE};
+ FieldEvaluator evaluator{context, mesh.totpoly};
+ evaluator.set_selection(selection_field);
+ evaluator.add(amount_field);
+ evaluator.evaluate();
+ VArray<float> amounts = evaluator.get_evaluated<float>(0);
+ const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
+
+ BevelData bdat
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list