[Bf-blender-cvs] [b9febb54a49] master: Geometry Nodes: Support modifier on curve objects

Hans Goudey noreply at git.blender.org
Sat Sep 11 20:55:03 CEST 2021


Commit: b9febb54a492ac6c93802fb0aa189d4c3fd99b0b
Author: Hans Goudey
Date:   Sat Sep 11 13:54:40 2021 -0500
Branches: master
https://developer.blender.org/rBb9febb54a492ac6c93802fb0aa189d4c3fd99b0b

Geometry Nodes: Support modifier on curve objects

With this commit, curve objects support the geometry nodes modifier.

Curves objects now evaluate to `CurveEval` unless there was a previous
implicit conversion (tessellating modifiers, mesh modifiers, or the
settings in the curve "Geometry" panel). In the new code, curves are
only considered to be the wire edges-- any generated surface is a mesh
instead, stored in the evaluated geometry set.

The consolidation of concepts mentioned above allows remove a lot of
code that had to do with maintaining the `DispList` type temporarily
for modifiers and rendering. Instead, render engines see a separate
object for the mesh from the mesh geometry component, and when the
curve object evaluates to a curve, the `CurveEval` is always used for
drawing wire edges.

However, currently the `DispList` type is still maintained and used as
an intermediate step in implicit mesh conversion. In the future, more
uses of it could be changed to use `CurveEval` and `Mesh` instead.

This is mostly not changed behavior, it is just a formalization of
existing logic after recent fixes for 2.8 versions last year and two
years ago. Also, in the future more functionality can be converted
to nodes, removing cases of implicit conversions. For more discussion
on that topic, see T89676.

The `use_fill_deform` option is removed. It has not worked properly
since 2.62, and the choice for filling a curve before or after
deformation will work much better and be clearer with a node system.

Applying the geometry nodes modifier to generate a curve is not
implemented with this commit, so applying the modifier won't work
at all. This is a separate technical challenge, and should be solved
in a separate step.

Differential Revision: https://developer.blender.org/D11597

===================================================================

M	release/scripts/startup/bl_operators/geometry_nodes.py
M	release/scripts/startup/bl_ui/properties_data_curve.py
M	source/blender/blenkernel/BKE_displist.h
M	source/blender/blenkernel/intern/displist.cc
M	source/blender/blenkernel/intern/geometry_component_curve.cc
M	source/blender/blenkernel/intern/geometry_set.cc
M	source/blender/blenkernel/intern/geometry_set_instances.cc
M	source/blender/blenkernel/intern/mesh_convert.c
M	source/blender/blenkernel/intern/object.c
M	source/blender/blenkernel/intern/object_dupli.cc
M	source/blender/depsgraph/intern/eval/deg_eval_runtime_backup_object.cc
M	source/blender/draw/engines/overlay/overlay_edit_text.c
M	source/blender/draw/engines/overlay/overlay_wireframe.c
M	source/blender/draw/intern/draw_cache.c
M	source/blender/draw/intern/draw_cache.h
M	source/blender/draw/intern/draw_cache_impl_curve.cc
M	source/blender/editors/curve/editcurve_add.c
M	source/blender/editors/space_spreadsheet/space_spreadsheet.cc
M	source/blender/io/alembic/intern/abc_reader_curves.cc
M	source/blender/io/usd/intern/usd_reader_curve.cc
M	source/blender/io/usd/intern/usd_reader_nurbs.cc
M	source/blender/makesdna/DNA_curve_types.h
M	source/blender/makesdna/DNA_object_types.h
M	source/blender/makesrna/intern/rna_curve.c
M	source/blender/modifiers/intern/MOD_nodes.cc

===================================================================

diff --git a/release/scripts/startup/bl_operators/geometry_nodes.py b/release/scripts/startup/bl_operators/geometry_nodes.py
index ec2887a1a74..258a73bd70b 100644
--- a/release/scripts/startup/bl_operators/geometry_nodes.py
+++ b/release/scripts/startup/bl_operators/geometry_nodes.py
@@ -42,8 +42,8 @@ def geometry_node_group_empty_new():
 def geometry_modifier_poll(context):
     ob = context.object
 
-    # Test object support for geometry node modifier (No curve, or hair object support yet)
-    if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME'}:
+    # Test object support for geometry node modifier (No hair object support yet)
+    if not ob or ob.type not in {'MESH', 'POINTCLOUD', 'VOLUME', 'CURVE', 'FONT'}:
         return False
 
     return True
diff --git a/release/scripts/startup/bl_ui/properties_data_curve.py b/release/scripts/startup/bl_ui/properties_data_curve.py
index 85f672cd50f..e5b675db2c5 100644
--- a/release/scripts/startup/bl_ui/properties_data_curve.py
+++ b/release/scripts/startup/bl_ui/properties_data_curve.py
@@ -120,7 +120,6 @@ class DATA_PT_shape_curve(CurveButtonsPanel, Panel):
             sub = col.column()
             sub.active = (curve.dimensions == '2D' or (curve.bevel_mode != 'OBJECT' and curve.dimensions == '3D'))
             sub.prop(curve, "fill_mode")
-            col.prop(curve, "use_fill_deform")
 
         if is_curve:
             col = layout.column()
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index 0f37ba6c4ce..37e144ebbd3 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -99,7 +99,7 @@ void BKE_displist_make_mball_forRender(struct Depsgraph *depsgraph,
                                        struct Object *ob,
                                        struct ListBase *dispbase);
 
-bool BKE_curve_calc_modifiers_pre(struct Depsgraph *depsgraph,
+void BKE_curve_calc_modifiers_pre(struct Depsgraph *depsgraph,
                                   const struct Scene *scene,
                                   struct Object *ob,
                                   struct ListBase *source_nurb,
diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc
index 58509e95de6..bdab508eb1f 100644
--- a/source/blender/blenkernel/intern/displist.cc
+++ b/source/blender/blenkernel/intern/displist.cc
@@ -40,6 +40,7 @@
 #include "BLI_math.h"
 #include "BLI_memarena.h"
 #include "BLI_scanfill.h"
+#include "BLI_span.hh"
 #include "BLI_string.h"
 #include "BLI_utildefines.h"
 
@@ -47,6 +48,7 @@
 #include "BKE_curve.h"
 #include "BKE_displist.h"
 #include "BKE_font.h"
+#include "BKE_geometry_set.hh"
 #include "BKE_key.h"
 #include "BKE_lattice.h"
 #include "BKE_lib_id.h"
@@ -55,6 +57,7 @@
 #include "BKE_mesh.h"
 #include "BKE_modifier.h"
 #include "BKE_object.h"
+#include "BKE_spline.hh"
 
 #include "BLI_sys_types.h" /* For #intptr_t support. */
 
@@ -745,10 +748,7 @@ static ModifierData *curve_get_tessellate_point(const Scene *scene,
   return pretessellatePoint;
 }
 
-/**
- * \return True if any modifier was applied.
- */
-bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
+void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
                                   const Scene *scene,
                                   Object *ob,
                                   ListBase *source_nurb,
@@ -793,7 +793,6 @@ bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
 
   const ModifierEvalContext mectx = {depsgraph, ob, apply_flag};
   ModifierData *pretessellatePoint = curve_get_tessellate_point(scene, ob, for_render, editmode);
-  bool modified = false;
 
   if (pretessellatePoint) {
     VirtualModifierData virtualModifierData;
@@ -813,7 +812,6 @@ bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
       }
 
       mti->deformVerts(md, &mectx, nullptr, deformedVerts, numVerts);
-      modified = true;
 
       if (md == pretessellatePoint) {
         break;
@@ -832,48 +830,59 @@ bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
   if (keyVerts) {
     MEM_freeN(keyVerts);
   }
-  return modified;
 }
 
-static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3]
+/**
+ * \return True if the deformed curve control point data should be implicitly
+ * converted directly to a mesh, or false if it can be left as curve data via #CurveEval.
+ */
+static bool do_curve_implicit_mesh_conversion(const Curve *curve,
+                                              ModifierData *first_modifier,
+                                              const Scene *scene,
+                                              const ModifierMode required_mode)
 {
-  *r_vert_len = 0;
+  /* Skip implicit filling and conversion to mesh when using "fast text editing". */
+  if (curve->flag & CU_FAST) {
+    return false;
+  }
 
-  LISTBASE_FOREACH (DispList *, dl, dispbase) {
-    *r_vert_len += (dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr;
+  /* Do implicit conversion to mesh with the object bevel mode. */
+  if (curve->bevel_mode == CU_BEV_MODE_OBJECT && curve->bevobj != nullptr) {
+    return true;
   }
 
-  float(*allverts)[3] = (float(*)[3])MEM_mallocN(sizeof(float[3]) * (*r_vert_len), __func__);
-  float *fp = (float *)allverts;
-  LISTBASE_FOREACH (DispList *, dl, dispbase) {
-    const int ofs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr);
-    memcpy(fp, dl->verts, sizeof(float) * ofs);
-    fp += ofs;
+  /* 2D curves are sometimes implicitly filled and converted to a mesh. */
+  if (CU_DO_2DFILL(curve)) {
+    return true;
   }
 
-  return allverts;
-}
+  /* Curve objects with implicit "tube" meshes should convert implicitly to a mesh. */
+  if (curve->ext1 != 0.0f || curve->ext2 != 0.0f) {
+    return true;
+  }
 
-static void displist_vert_coords_apply(ListBase *dispbase, const float (*allverts)[3])
-{
-  const float *fp = (float *)allverts;
-  LISTBASE_FOREACH (DispList *, dl, dispbase) {
-    int ofs = 3 * ((dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr);
-    memcpy(dl->verts, fp, sizeof(float) * ofs);
-    fp += ofs;
+  /* If a non-geometry-nodes modifier is enabled before a nodes modifier,
+   * force conversion to mesh, since only the nodes modifier supports curve data. */
+  ModifierData *md = first_modifier;
+  for (; md; md = md->next) {
+    if (BKE_modifier_is_enabled(scene, md, required_mode)) {
+      if (md->type == eModifierType_Nodes) {
+        break;
+      }
+      return true;
+    }
   }
+
+  return false;
 }
 
-static void curve_calc_modifiers_post(Depsgraph *depsgraph,
-                                      const Scene *scene,
-                                      Object *ob,
-                                      ListBase *dispbase,
-                                      const bool for_render,
-                                      const bool force_mesh_conversion,
-                                      Mesh **r_final)
+static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
+                                             const Scene *scene,
+                                             Object *ob,
+                                             const ListBase *dispbase,
+                                             const bool for_render)
 {
   const Curve *cu = (const Curve *)ob->data;
-
   const bool editmode = (!for_render && (cu->editnurb || cu->editfont));
   const bool use_cache = !for_render;
 
@@ -897,166 +906,64 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
                          BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) :
                          pretessellatePoint->next;
 
-  if (r_final && *r_final) {
-    BKE_id_free(nullptr, *r_final);
+  GeometrySet geometry_set;
+  if (ob->type == OB_SURF || do_curve_implicit_mesh_conversion(cu, md, scene, required_mode)) {
+    Mesh *mesh = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
+    geometry_set.replace_mesh(mesh);
+  }
+  else {
+    std::unique_ptr<CurveEval> curve_eval = curve_eval_from_dna_curve(
+        *cu, ob->runtime.curve_cache->deformed_nurbs);
+    geometry_set.replace_curve(curve_eval.release());
   }
 
-  Mesh *modified = nullptr;
-  float(*vertCos)[3] = nullptr;
-  int totvert = 0;
   for (; md; md = md->next) {
     const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
-
     if (!BKE_modifier_is_enabled(scene, md, required_mode)) {
       continue;
     }
 
-    /* If we need normals, no choice, have to convert to mesh now. */
-    const bool need_normal = mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md);
-    /* XXX 2.8 : now that batch cache is stored inside the ob->data
-     * we need to create a Mesh for each curve that uses modifiers. */
-    if (modified == nullptr /* && need_normal */) {
-      if (vertCos != nullptr) {
-        displist_vert_coords_apply(dispbase, vertCos);
-      }
-
-      if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
-        curve_to_filledpoly(cu, dispbase);
-      }
+    if (md->type == eModifierType_Nodes) {
+      mti->modifyGeometrySet(md, &mectx_apply, &geometry_set);
+      continue;
+    }
 
-      modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
+    if (!geometry_set.has_mesh()) {
+      geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0, 0));
     }
+    Mesh *mesh = geometry_set.get_mesh_for_write();
 
-    if (mti->type == eModifierTypeType_OnlyDeform ||
-        (mti->type == eModifierTypeType_DeformOrConstruct && !modified)) {
-      if (modified) {
-        if (!vertCos) {
-          vertCos = BKE_mesh_vert_coords_alloc(modified, &totvert);
-        }
-        if (need_normal) {
-          BKE_mesh_ensure_normals(modified);
-        }
-        mti->deformVerts(md, &mectx_deform, modified, vertCos, totvert);
-      }
-      else {
-        if (!vertCos) {
-          vertCos = displist_vert_coords_alloc(dispbase, &totvert);
-        }
-        mti->deformVerts(md, &mectx_deform, nullptr, vertCos, totvert);
+    if (mti->type == eModifierTypeType_OnlyDeform) {
+      int totvert;
+      float(*vertex_coords)[3] = BKE_mesh_vert_coords_alloc(mes

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list