[Bf-blender-cvs] [c95b2cefab2] geometry-nodes-curve-support: Geometry Nodes Curves: More progress on curve to mesh node
Hans Goudey
noreply at git.blender.org
Sun Apr 4 20:23:00 CEST 2021
Commit: c95b2cefab25252469e50404f04293db681df825
Author: Hans Goudey
Date: Sun Apr 4 13:22:53 2021 -0500
Branches: geometry-nodes-curve-support
https://developer.blender.org/rBc95b2cefab25252469e50404f04293db681df825
Geometry Nodes Curves: More progress on curve to mesh node
===================================================================
M source/blender/blenkernel/BKE_derived_curve.hh
M source/blender/blenkernel/intern/derived_curve.cc
M source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
===================================================================
diff --git a/source/blender/blenkernel/BKE_derived_curve.hh b/source/blender/blenkernel/BKE_derived_curve.hh
index 40a87af7101..bbe06eb6a0e 100644
--- a/source/blender/blenkernel/BKE_derived_curve.hh
+++ b/source/blender/blenkernel/BKE_derived_curve.hh
@@ -84,7 +84,7 @@ class BezierSpline : public Spline {
static constexpr inline Type static_type = Spline::Type::Bezier;
private:
- bool cache_dirty;
+ bool cache_dirty = true;
int32_t flag; /* Cyclic, smooth. */
diff --git a/source/blender/blenkernel/intern/derived_curve.cc b/source/blender/blenkernel/intern/derived_curve.cc
index 0bf1b81792e..e4efff12308 100644
--- a/source/blender/blenkernel/intern/derived_curve.cc
+++ b/source/blender/blenkernel/intern/derived_curve.cc
@@ -107,6 +107,8 @@ static void evaluate_bezier_part_3d(const float3 point_0,
int BezierSpline::evaluated_points_size() const
{
+ BLI_assert(control_points.size() > 0);
+
int total_len = 1;
for (const int i : IndexRange(1, this->control_points.size() - 1)) {
const ControlPointBezier &point_prev = this->control_points[i - 1];
@@ -157,5 +159,7 @@ void BezierSpline::ensure_evaluation_cache() const
}
}
+ positions.last() = control_points.last().position;
+
mutable_self->cache_dirty = false;
}
diff --git a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
index 6a2b8fc813c..4d1aafacbaf 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_curve_to_mesh.cc
@@ -27,6 +27,7 @@
static bNodeSocketTemplate geo_node_curve_to_mesh_in[] = {
{SOCK_GEOMETRY, N_("Curve")},
+ {SOCK_GEOMETRY, N_("Profile Curve")},
{-1, ""},
};
@@ -37,54 +38,186 @@ static bNodeSocketTemplate geo_node_point_translate_out[] = {
namespace blender::nodes {
-// static void spline_to_mesh_data(const Spline &spline)
-// {
-// Span<float3> positions = spline.evaluated_positions();
+static void vert_extrude_to_mesh_data(const Spline &spline,
+ const float3 profile_vert,
+ MutableSpan<MVert> verts,
+ MutableSpan<MEdge> edges,
+ int &vert_offset,
+ int &edge_offset)
+{
+ Span<float3> positions = spline.evaluated_positions();
-// for (const int i : verts.index_range()) {
-// copy_v3_v3(mesh->mvert[i].co, positions[i]);
-// }
+ for (const int i : IndexRange(positions.size() - 1)) {
+ MEdge &edge = edges[i];
+ edge.v1 = vert_offset + i;
+ edge.v2 = vert_offset + i + 1;
+ edge.flag = ME_LOOSEEDGE;
+ }
-// for (const int i : edges.index_range()) {
-// MEdge &edge = mesh->medge[i];
-// edge.v1 = i;
-// edge.v2 = i + 1;
-// edge.flag = ME_LOOSEEDGE;
-// }
-// }
+ float3 co = profile_vert;
+ for (const int i : IndexRange(positions.size() - 1)) {
+ const float3 delta = positions[i + 1] - positions[i];
+ MVert &vert = verts[vert_offset++];
+ copy_v3_v3(vert.co, co);
+ co += delta;
+ }
+ MVert &last_vert = verts[vert_offset++];
+ if (spline.type == Spline::Bezier) {
+ const BezierSpline &bezier_spline = static_cast<const BezierSpline &>(spline);
+ const float3 offset = profile_vert - bezier_spline.control_points.begin()->position;
+ copy_v3_v3(last_vert.co, bezier_spline.control_points.last().position + offset);
+ }
+}
-static Mesh *curve_to_mesh_calculate(const DCurve &curve)
+static void spline_extrude_to_mesh_data(const Spline &spline,
+ Span<float3> profile_spline,
+ MutableSpan<MVert> verts,
+ MutableSpan<MEdge> edges,
+ MutableSpan<MLoop> loops,
+ MutableSpan<MPoly> polys,
+ int &vert_offset,
+ int &edge_offset,
+ int &loop_offset,
+ int &poly_offset)
{
- const int profile_verts_len = 1;
+ Span<float3> positions = spline.evaluated_positions();
- int verts_total = 0;
- for (const Spline *spline : curve.splines) {
- verts_total += spline->evaluated_points_size() * profile_verts_len;
+ if (positions.size() == 0) {
+ return;
+ }
+
+ if (profile_spline.size() == 1) {
+ vert_extrude_to_mesh_data(spline, profile_spline[0], verts, edges, vert_offset, edge_offset);
+ return;
+ }
+
+ /* TODO: This code path isn't finished, crashes, and needs more thought. */
+
+ Array<float3> profile(profile_spline);
+
+ // const bool is_cyclic = profile_spline.last() == profile_spline.first();
+ const int vert_offset_start = vert_offset;
+
+ for (const int i : IndexRange(positions.size() - 1)) {
+ const float3 delta = positions[i + 1] - positions[i];
+ for (float3 &profile_co : profile) {
+ MVert &vert = verts[vert_offset++];
+ copy_v3_v3(vert.co, profile_co);
+ profile_co += delta;
+ }
+ }
+
+ const int profile_len = profile.size();
+ for (const int i : IndexRange(positions.size() - 1)) {
+ const int ring_offset = vert_offset_start + profile_len * i;
+ const int next_ring_offset = vert_offset_start + profile_len * (i + 1);
+ for (const int UNUSED(i_profile) : profile.index_range()) {
+ MEdge &edge_v = edges[edge_offset++];
+ edge_v.v1 = ring_offset + i;
+ edge_v.v2 = next_ring_offset + i;
+ edge_v.flag = ME_LOOSEEDGE | ME_EDGEDRAW | ME_EDGERENDER;
+
+ if (profile_len > 1) {
+ MEdge &edge_u = edges[edge_offset++];
+ edge_u.v1 = ring_offset + i;
+ edge_u.v2 = ring_offset + (i + 1) % profile_len;
+ edge_u.flag = ME_LOOSEEDGE | ME_EDGEDRAW | ME_EDGERENDER;
+ }
+ }
+ }
+}
+
+static Mesh *curve_to_mesh_calculate(const DCurve &curve, const DCurve &profile_curve)
+{
+ int profile_vert_total = 0;
+ int profile_edge_total = 0;
+ Vector<Span<float3>> profile_splines;
+ for (const Spline *spline : profile_curve.splines) {
+ Span<float3> positions = spline->evaluated_positions();
+ profile_vert_total += positions.size();
+ profile_edge_total += std::max(positions.size() - 2, 0L);
+ profile_splines.append(spline->evaluated_positions());
+ }
+
+ int vert_total = 0;
+ int edge_total = 0;
+ int poly_total = 0;
+ for (const int i : curve.splines.index_range()) {
+ const Spline &spline = *curve.splines[i];
+ const int spline_len = spline.evaluated_points_size();
+ vert_total += spline_len * profile_vert_total;
+ /* An edge for every point for every curve segment, and edges for for the original profile's
+ * edges. */
+ edge_total += (spline_len - 1) * profile_vert_total + spline_len * profile_edge_total;
+ poly_total += spline_len * profile_edge_total;
}
+ const int corner_total = poly_total * 4;
- Mesh *mesh = BKE_mesh_new_nomain(verts_total, verts_total - 2, 0, 0, 0);
+ if (vert_total == 0) {
+ return nullptr;
+ }
+
+ // Mesh *mesh = BKE_mesh_new_nomain(vert_total, edge_total, 0, corner_total, poly_total);
+ Mesh *mesh = BKE_mesh_new_nomain(vert_total, edge_total, 0, 0, 0);
MutableSpan<MVert> verts{mesh->mvert, mesh->totvert};
MutableSpan<MEdge> edges{mesh->medge, mesh->totedge};
+ MutableSpan<MLoop> loops{mesh->mloop, mesh->totloop};
+ MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly};
+ int vert_offset = 0;
+ int edge_offset = 0;
+ int loop_offset = 0;
+ int poly_offset = 0;
for (const Spline *spline : curve.splines) {
- // spline_to_mesh_data(*spline);
+ for (Span<float3> profile_spline : profile_splines) {
+ spline_extrude_to_mesh_data(*spline,
+ profile_spline,
+ verts,
+ edges,
+ loops,
+ polys,
+ vert_offset,
+ edge_offset,
+ loop_offset,
+ poly_offset);
+ }
}
BKE_mesh_calc_normals(mesh);
- // BLI_assert(BKE_mesh_is_valid(mesh));
+ BLI_assert(BKE_mesh_is_valid(mesh));
return mesh;
}
+static DCurve get_curve_single_vert()
+{
+ DCurve curve;
+ BezierSpline *spline = new BezierSpline();
+ ControlPointBezier control_point;
+ control_point.position = float3(0);
+ control_point.handle_position_a = float3(0);
+ control_point.handle_position_b = float3(0);
+ spline->control_points.append(control_point);
+ curve.splines.append(static_cast<Spline *>(spline));
+
+ return curve;
+}
+
static void geo_node_curve_to_mesh_exec(GeoNodeExecParams params)
{
- GeometrySet set_in = params.extract_input<GeometrySet>("Curve");
+ GeometrySet curve_set = params.extract_input<GeometrySet>("Curve");
+ GeometrySet profile_set = params.extract_input<GeometrySet>("Profile Curve");
- if (!set_in.has_curve()) {
+ if (!curve_set.has_curve()) {
params.set_output("Mesh", GeometrySet());
}
- Mesh *mesh = curve_to_mesh_calculate(*set_in.get_curve_for_read());
+ const DCurve *profile_curve = profile_set.get_curve_for_read();
+
+ const DCurve vert_curve = get_curve_single_vert();
+
+ Mesh *mesh = curve_to_mesh_calculate(*curve_set.get_curve_for_read(),
+ (profile_curve == nullptr) ? vert_curve : *profile_curve);
params.set_output("Mesh", GeometrySet::create_with_mesh(mesh));
}
More information about the Bf-blender-cvs
mailing list