[Bf-blender-cvs] [0bc58007543] curve-nodes-modifier: WIP: Geometry Nodes: Support nodes modifier on curve objects

Hans Goudey noreply at git.blender.org
Tue Jul 13 01:40:40 CEST 2021


Commit: 0bc580075430d8233248ae5c23d1abbf0d5818f4
Author: Hans Goudey
Date:   Mon Jun 14 01:14:30 2021 -0500
Branches: curve-nodes-modifier
https://developer.blender.org/rB0bc580075430d8233248ae5c23d1abbf0d5818f4

WIP: Geometry Nodes: Support nodes modifier on curve objects

With this commit, curve objects support the nodes modifier. The goal is
that nodes modifiers will read curve data as the original curve, unless
they are placed after a modifier that must tessalate the curve (convert
it to a mesh). Always converting to a mesh in that case  is basically
just a formalization of the behavior that was already present after
recent fixes for 2.8 versions last year and two years ago. For more
controlled explicit conversions between data types, using geometry
nodes makes so much more sense anyway.

TODO:
 - Add more code comments
 - Fix memory leak(s?)
 - Fix geometry components besides mesh don't display in viewport.

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

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

M	source/blender/blenkernel/BKE_displist.h
M	source/blender/blenkernel/intern/displist.cc
M	source/blender/editors/space_spreadsheet/space_spreadsheet.cc
M	source/blender/modifiers/intern/MOD_nodes.cc

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

diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index a2d9bbcd011..b3726c26619 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -101,7 +101,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 70355f3883d..34a1f956f41 100644
--- a/source/blender/blenkernel/intern/displist.cc
+++ b/source/blender/blenkernel/intern/displist.cc
@@ -47,6 +47,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 +56,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
 
@@ -749,7 +751,7 @@ static ModifierData *curve_get_tessellate_point(const Scene *scene,
 /**
  * \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,
@@ -794,7 +796,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;
@@ -814,7 +815,6 @@ bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
       }
 
       mti->deformVerts(md, &mectx, nullptr, deformedVerts, numVerts);
-      modified = true;
 
       if (md == pretessellatePoint) {
         break;
@@ -833,36 +833,6 @@ 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]
-{
-  *r_vert_len = 0;
-
-  LISTBASE_FOREACH (DispList *, dl, dispbase) {
-    *r_vert_len += (dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr;
-  }
-
-  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;
-  }
-
-  return allverts;
-}
-
-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;
-  }
 }
 
 static void curve_calc_modifiers_post(Depsgraph *depsgraph,
@@ -870,8 +840,8 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
                                       Object *ob,
                                       ListBase *dispbase,
                                       const bool for_render,
-                                      const bool force_mesh_conversion,
-                                      Mesh **r_final)
+                                      Mesh **r_final,
+                                      GeometrySet **r_geometry_set)
 {
   const Curve *cu = (const Curve *)ob->data;
 
@@ -903,6 +873,17 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
   }
 
   Mesh *modified = nullptr;
+  GeometrySet geometry_set;
+  if (md && md->type == eModifierType_Nodes) {
+    geometry_set.replace_curve(curve_eval_from_dna_curve(*cu).release());
+  }
+  else {
+    if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
+      curve_to_filledpoly(cu, dispbase);
+    }
+    modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
+  }
+
   float(*vertCos)[3] = nullptr;
   for (; md; md = md->next) {
     const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
@@ -911,74 +892,51 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
       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 (md->type == eModifierType_Nodes) {
+      MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
+      mesh_component.replace_mesh_but_keep_vertex_group_names(modified,
+                                                              GeometryOwnershipType::Editable);
+      mti->modifyGeometrySet(md, &mectx_apply, &geometry_set);
+      if (geometry_set.has<MeshComponent>()) {
+        MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
+        modified = mesh_component.release();
       }
-
-      if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) {
-        curve_to_filledpoly(cu, dispbase);
+      /* Use an empty mesh instead of null.  */
+      if (modified == nullptr) {
+        modified = BKE_mesh_new_nomain(0, 0, 0, 0, 0);
       }
-
-      modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
+      continue;
     }
 
+    const bool need_normal = mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md);
+
     if (mti->type == eModifierTypeType_OnlyDeform ||
         (mti->type == eModifierTypeType_DeformOrConstruct && !modified)) {
-      if (modified) {
-        int totvert = 0;
-        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);
+      int totvert = 0;
+      if (!vertCos) {
+        vertCos = BKE_mesh_vert_coords_alloc(modified, &totvert);
       }
-      else {
-        int totvert = 0;
-        if (!vertCos) {
-          vertCos = displist_vert_coords_alloc(dispbase, &totvert);
-        }
-        mti->deformVerts(md, &mectx_deform, nullptr, vertCos, totvert);
+      if (need_normal) {
+        BKE_mesh_ensure_normals(modified);
       }
+      mti->deformVerts(md, &mectx_deform, modified, vertCos, totvert);
     }
     else {
-      if (!r_final) {
+      if (!r_final && !r_geometry_set) {
         /* makeDisplistCurveTypes could be used for beveling, where mesh
          * is totally unnecessary, so we could stop modifiers applying
          * when we found constructive modifier but mesh is unwanted. */
         break;
       }
 
-      if (modified) {
-        if (vertCos) {
-          Mesh *temp_mesh = (Mesh *)BKE_id_copy_ex(
-              nullptr, &modified->id, nullptr, LIB_ID_COPY_LOCALIZE);
-          BKE_id_free(nullptr, modified);
-          modified = temp_mesh;
-
-          BKE_mesh_vert_coords_apply(modified, vertCos);
-        }
-      }
-      else {
-        if (vertCos) {
-          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 (vertCos) {
+        Mesh *temp_mesh = (Mesh *)BKE_id_copy_ex(
+            nullptr, &modified->id, nullptr, LIB_ID_COPY_LOCALIZE);
+        BKE_id_free(nullptr, modified);
+        modified = temp_mesh;
 
-        modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
-      }
+        BKE_mesh_vert_coords_apply(modified, vertCos);
 
-      if (vertCos) {
-        /* Vertex coordinates were applied to necessary data, could free it */
         MEM_freeN(vertCos);
         vertCos = nullptr;
       }
@@ -989,7 +947,7 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
       Mesh *mesh_applied = mti->modifyMesh(md, &mectx_apply, modified);
 
       if (mesh_applied) {
-        if (modified && modified != mesh_applied) {
+        if (modified != mesh_applied) {
           BKE_id_free(nullptr, modified);
         }
         modified = mesh_applied;
@@ -998,67 +956,41 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph,
   }
 
   if (vertCos) {
-    if (modified) {
-      Mesh *temp_mesh = (Mesh *)BKE_id_copy_ex(
-          nullptr, &modified->id, nullptr, LIB_ID_COPY_LOCALIZE);
-      BKE_id_free(nullptr, modified);
-      modified = temp_mesh;
+    Mesh *temp_mesh = (Mesh *)BKE_id_copy_ex(
+        nullptr, &modified->id, nullptr, LIB_ID_COPY_LOCALIZE);
+    BKE_id_free(nullptr, modified);
+    modified = temp_mesh;
 
-      BKE_mesh_vert_coords_apply(modified, vertCos);
-      BKE_mesh_calc_normals_mapping_simple(modified);
+    BKE_mesh_vert_coords_apply(modified, vertCos);
+    BKE_mesh_calc_normals_mapping_simple(modified);
 
-      MEM_freeN(vertCos);
-    }
-    else {
-      displist_vert_coords_apply(dispbase, vertCos);
-      MEM_freeN(vertCos);
-      vertCos = nullptr;
-    }
+    MEM_freeN(vertCos);
   }
 
   if (r_final) {
-    if (force_mesh_conversion && !modified) {
-      /* XXX 2.8 : This is a workaround for by some deeper technical debts:
-       * - DRW Batch cache is stored inside the ob->data.
-       * - Curve data is not COWed for instances that use different modifiers.
-       * This can causes the m

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list