[Bf-blender-cvs] [845d525099c] bevelv2: Add slope parameter to mesh_inset and use that in face bevel.
Howard Trickey
noreply at git.blender.org
Thu Sep 15 00:05:28 CEST 2022
Commit: 845d525099cc1c16ee3ea0a3cad7289781d0cf75
Author: Howard Trickey
Date: Wed Sep 14 18:04:46 2022 -0400
Branches: bevelv2
https://developer.blender.org/rB845d525099cc1c16ee3ea0a3cad7289781d0cf75
Add slope parameter to mesh_inset and use that in face bevel.
===================================================================
M source/blender/blenlib/BLI_mesh_inset.hh
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/BLI_mesh_inset.hh b/source/blender/blenlib/BLI_mesh_inset.hh
index cd7dfcb57df..599ea061b2e 100644
--- a/source/blender/blenlib/BLI_mesh_inset.hh
+++ b/source/blender/blenlib/BLI_mesh_inset.hh
@@ -26,6 +26,7 @@ public:
/** The contours to inset; ints are vert indices; contour is on left side of implied edges. */
Span<Vector<int>> contour;
float inset_amount;
+ float slope;
bool need_ids;
};
diff --git a/source/blender/blenlib/intern/mesh_inset.cc b/source/blender/blenlib/intern/mesh_inset.cc
index 0a862b106bb..58513280a69 100644
--- a/source/blender/blenlib/intern/mesh_inset.cc
+++ b/source/blender/blenlib/intern/mesh_inset.cc
@@ -462,6 +462,28 @@ static float3 vertex_normal(const Vert *vert)
return ans;
}
+/** Analog of BM_vert_calc_shell_factor. */
+static float vertex_shell_factor(Vert *vert)
+{
+ float accum_shell = 0.0f;
+ float accum_angle = 0.0f;
+ Edge e = vert->e;
+ float3 vnorm = vertex_normal(vert);
+ do {
+ if (!e.tri()->is_ghost()) {
+ Edge eprev = e.triangle_pred();
+ float face_angle = angle_v3v3v3(v_src(eprev)->co, v_src(e)->co, v_dst(e)->co);
+ accum_shell += shell_v3v3_normalized_to_dist(vnorm, e.tri()->normal()) * face_angle;
+ accum_angle += face_angle;
+ }
+ e = rot_ccw(e);
+ } while (e != vert->e);
+ if (accum_angle != 0.0f) {
+ return accum_shell / accum_angle;
+ }
+ return 1.0f;
+}
+
class TriangleMesh {
Vector<Triangle *> triangles_;
Vector<Vert *> verts_;
@@ -3186,10 +3208,27 @@ MeshInset_Result mesh_inset_calc(const MeshInset_Input &input)
TriangleMesh trimesh = triangulate_input(input);
StraightSkeleton ss(trimesh, input.contour, input.inset_amount);
ss.compute();
- Array<Triangle *> remaining_triangles = triangle_set_to_sorted_array(ss.remaining_triangles_set);
- /* TODO: take in slope and offset arguments and use to adjust position of results in the normal
- * direction, using ss.vertex_height_map
- */
+ if (input.slope != 0.0f) {
+ /* Gather all the deltas before applying, as changing height changes the vertex normals. */
+ Array<float3> vco_delta(trimesh.all_verts().size(), float3(0.0f, 0.0f, 0.0f));
+ trimesh.calculate_all_tri_normals();
+ for (int v_index : trimesh.all_verts().index_range()) {
+ Vert *v = trimesh.get_vert_by_index(v_index);
+ if (!v->is_deleted()) {
+ if (ss.vertex_height_map.contains(v->id)) {
+ float h = ss.vertex_height_map.lookup(v->id);
+ if (h != 0.0f) {
+ float shell_factor = vertex_shell_factor(v);
+ vco_delta[v_index] = vertex_normal(v) * shell_factor * h * input.slope;
+ }
+ }
+ }
+ }
+ for (int v_index : trimesh.all_verts().index_range()) {
+ Vert *v = trimesh.get_vert_by_index(v_index);
+ v->co += vco_delta[v->id];
+ }
+ }
if (dbg_level > 0) {
trimesh_draw("after ss " + std::to_string(input.inset_amount), trimesh);
std::cout << trimesh << "\n";
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 dcbada546fb..088b2d06ece 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_bevel_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_bevel_mesh.cc
@@ -34,6 +34,16 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_input<decl::Geometry>("Mesh").supported_type(GEO_COMPONENT_TYPE_MESH);
b.add_input<decl::Bool>(N_("Selection")).default_value(true).supports_field().hide_value();
b.add_input<decl::Float>(N_("Amount")).default_value(1.0f).supports_field();
+ b.add_input<decl::Float>(N_("Slope")).default_value(0.0f).supports_field()
+ .description(N_("Face inset will raise up with this slope"))
+ .make_available([](bNode &node) {
+ node_storage(node).mode = GEO_NODE_BEVEL_MESH_FACES;
+ });
+ b.add_input<decl::Bool>(N_("Use Regions")).default_value(false)
+ .description(N_("Combine adjacent faces into regions and inset regions as a whole"))
+ .make_available([](bNode &node) {
+ node_storage(node).mode = GEO_NODE_BEVEL_MESH_FACES;
+ });
b.add_output<decl::Geometry>("Mesh");
}
@@ -51,8 +61,13 @@ static void node_init(bNodeTree *UNUSED(tree), bNode *node)
node->storage = data;
}
-static void node_update(bNodeTree *UNUSED(ntree), bNode *UNUSED(node))
+static void node_update(bNodeTree *ntree, bNode *node)
{
+ const NodeGeometryBevelMesh &storage = node_storage(*node);
+ bNodeSocket *slope_socket = nodeFindSocket(node, SOCK_IN, "Slope");
+ nodeSetSocketAvailability(ntree, slope_socket, storage.mode == GEO_NODE_BEVEL_MESH_FACES);
+ bNodeSocket *use_regions_socket = nodeFindSocket(node, SOCK_IN, "Use Regions");
+ nodeSetSocketAvailability(ntree, use_regions_socket, storage.mode == GEO_NODE_BEVEL_MESH_FACES);
}
/** MeshTopology encapsulates data needed to answer topological queries about a mesh,
@@ -1591,8 +1606,13 @@ static Mesh *calculate_face_bevel(BevelData &bd,
GeometrySet geometry_set,
const MeshComponent &component,
const IndexMask &to_bevel,
- const VArray<float> amounts)
+ const VArray<float> amounts,
+ const VArray<float> slopes,
+ bool use_regions)
{
+ if (use_regions) {
+ std::cout << "TODO: Implement use_regions";
+ }
Span<MPoly> faces = mesh.polys();
Span<MVert> verts = mesh.verts();
Span<MLoop> loops = mesh.loops();
@@ -1618,6 +1638,7 @@ static Mesh *calculate_face_bevel(BevelData &bd,
mi_input.face = mi_faces.as_span();
mi_input.contour = mi_faces.as_span();
mi_input.inset_amount = amounts[face_index];
+ mi_input.slope = slopes[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());
@@ -1689,19 +1710,23 @@ static Mesh *bevel_mesh_edges(GeometrySet geometry_set,
static Mesh *bevel_mesh_faces(GeometrySet geometry_set,
const MeshComponent &component,
const Field<bool> &selection_field,
- const Field<float> &amount_field)
+ const Field<float> &amount_field,
+ const Field<float> &slope_field,
+ bool use_regions)
{
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.add(slope_field);
evaluator.evaluate();
VArray<float> amounts = evaluator.get_evaluated<float>(0);
+ VArray<float> slopes = evaluator.get_evaluated<float>(1);
const IndexMask selection = evaluator.get_evaluated_selection_as_mask();
BevelData bdata(mesh);
- return calculate_face_bevel(bdata, mesh, geometry_set, component, selection, amounts);
+ return calculate_face_bevel(bdata, mesh, geometry_set, component, selection, amounts, slopes, use_regions);
}
static void node_geo_exec(GeoNodeExecParams params)
@@ -1721,10 +1746,16 @@ static void node_geo_exec(GeoNodeExecParams params)
mesh_out = bevel_mesh_vertices(geometry_set, component, selection_field, amount_field);
break;
case GEO_NODE_BEVEL_MESH_EDGES:
- mesh_out = bevel_mesh_edges(geometry_set, component, selection_field, amount_field);
+ {
+ mesh_out = bevel_mesh_edges(geometry_set, component, selection_field, amount_field);
+ }
break;
case GEO_NODE_BEVEL_MESH_FACES:
- mesh_out = bevel_mesh_faces(geometry_set, component, selection_field, amount_field);
+ {
+ Field<float> slope_field = params.extract_input<Field<float>>("Slope");
+ bool use_regions = params.get_input<bool>("Use Regions");
+ mesh_out = bevel_mesh_faces(geometry_set, component, selection_field, amount_field, slope_field, use_regions);
+ }
break;
}
BLI_assert(BKE_mesh_is_valid(mesh_out));
More information about the Bf-blender-cvs
mailing list