[Bf-blender-cvs] [eb0eb54d964] master: Fix D12533: Simplify curve object to mesh conversion

Hans Goudey noreply at git.blender.org
Thu Sep 23 18:41:55 CEST 2021


Commit: eb0eb54d9644c5139ef139fee1e14da35c4fab7e
Author: Hans Goudey
Date:   Thu Sep 23 11:41:46 2021 -0500
Branches: master
https://developer.blender.org/rBeb0eb54d9644c5139ef139fee1e14da35c4fab7e

Fix D12533: Simplify curve object to mesh conversion

This patch simplifies the curve object to mesh conversion
used by the object convert operator and exporters.

The existing code had a convoluted model of ownership, and did quite
a bit of unnecessary work. It also assumed that curve objects always
evaluated to a mesh, which is not the case anymore.

Now the code checks if the object it receives is evaluated. If so,
it can simply return a copy of the evaluated mesh (or convert the
evaluated curve wire edges to a mesh if there was no evaluated mesh).
If the object isn't evaluated, it uses a temporary copy of the object
with modifiers removed to create the mesh in the same way.

This follows up on the recent changes to curve evaluation,
namely that the result is always either a mesh or a wire curve.

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

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

M	source/blender/blenkernel/BKE_displist.h
M	source/blender/blenkernel/intern/displist.cc
M	source/blender/blenkernel/intern/mesh_convert.cc

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

diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h
index db5663fcc94..8fb596a8096 100644
--- a/source/blender/blenkernel/BKE_displist.h
+++ b/source/blender/blenkernel/BKE_displist.h
@@ -87,11 +87,6 @@ void BKE_displist_make_curveTypes(struct Depsgraph *depsgraph,
                                   const struct Scene *scene,
                                   struct Object *ob,
                                   const bool for_render);
-void BKE_displist_make_curveTypes_forRender(struct Depsgraph *depsgraph,
-                                            const struct Scene *scene,
-                                            struct Object *ob,
-                                            struct ListBase *dispbase,
-                                            struct Mesh **r_final);
 void BKE_displist_make_mball(struct Depsgraph *depsgraph, struct Scene *scene, struct Object *ob);
 
 void BKE_curve_calc_modifiers_pre(struct Depsgraph *depsgraph,
diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc
index e756daa1156..79e913d266f 100644
--- a/source/blender/blenkernel/intern/displist.cc
+++ b/source/blender/blenkernel/intern/displist.cc
@@ -1540,23 +1540,6 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
   boundbox_displist_object(ob);
 }
 
-void BKE_displist_make_curveTypes_forRender(
-    Depsgraph *depsgraph, const Scene *scene, Object *ob, ListBase *r_dispbase, Mesh **r_final)
-{
-  if (ob->runtime.curve_cache == nullptr) {
-    ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache), __func__);
-  }
-
-  if (ob->type == OB_SURF) {
-    evaluate_surface_object(depsgraph, scene, ob, true, r_dispbase, r_final);
-  }
-  else {
-    GeometrySet geometry_set = evaluate_curve_type_object(depsgraph, scene, ob, true, r_dispbase);
-    MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
-    *r_final = mesh_component.release();
-  }
-}
-
 void BKE_displist_minmax(const ListBase *dispbase, float min[3], float max[3])
 {
   bool doit = false;
diff --git a/source/blender/blenkernel/intern/mesh_convert.cc b/source/blender/blenkernel/intern/mesh_convert.cc
index 72ccfffbc3c..51acbeb8f5b 100644
--- a/source/blender/blenkernel/intern/mesh_convert.cc
+++ b/source/blender/blenkernel/intern/mesh_convert.cc
@@ -41,6 +41,7 @@
 #include "BKE_deform.h"
 #include "BKE_displist.h"
 #include "BKE_editmesh.h"
+#include "BKE_geometry_set.hh"
 #include "BKE_key.h"
 #include "BKE_lib_id.h"
 #include "BKE_lib_query.h"
@@ -51,6 +52,7 @@
 #include "BKE_mesh_runtime.h"
 #include "BKE_mesh_wrapper.h"
 #include "BKE_modifier.h"
+#include "BKE_spline.hh"
 /* these 2 are only used by conversion functions */
 #include "BKE_curve.h"
 /* -- */
@@ -58,6 +60,8 @@
 /* -- */
 #include "BKE_pointcloud.h"
 
+#include "BKE_curve_to_mesh.hh"
+
 #include "DEG_depsgraph.h"
 #include "DEG_depsgraph_query.h"
 
@@ -573,90 +577,6 @@ Mesh *BKE_mesh_new_nomain_from_curve(const Object *ob)
   return BKE_mesh_new_nomain_from_curve_displist(ob, &disp);
 }
 
-static void mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const char *obdata_name)
-{
-  if (ob->runtime.data_eval && GS(((ID *)ob->runtime.data_eval)->name) != ID_ME) {
-    return;
-  }
-
-  Mesh *me_eval = (Mesh *)ob->runtime.data_eval;
-  Mesh *me;
-  MVert *allvert = nullptr;
-  MEdge *alledge = nullptr;
-  MLoop *allloop = nullptr;
-  MLoopUV *alluv = nullptr;
-  MPoly *allpoly = nullptr;
-  int totvert, totedge, totloop, totpoly;
-
-  Curve *cu = (Curve *)ob->data;
-
-  if (me_eval == nullptr) {
-    if (mesh_nurbs_displist_to_mdata(cu,
-                                     dispbase,
-                                     &allvert,
-                                     &totvert,
-                                     &alledge,
-                                     &totedge,
-                                     &allloop,
-                                     &allpoly,
-                                     &alluv,
-                                     &totloop,
-                                     &totpoly) != 0) {
-      /* Error initializing */
-      return;
-    }
-
-    /* make mesh */
-    me = (Mesh *)BKE_id_new_nomain(ID_ME, obdata_name);
-
-    me->totvert = totvert;
-    me->totedge = totedge;
-    me->totloop = totloop;
-    me->totpoly = totpoly;
-
-    me->mvert = (MVert *)CustomData_add_layer(
-        &me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert);
-    me->medge = (MEdge *)CustomData_add_layer(
-        &me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge);
-    me->mloop = (MLoop *)CustomData_add_layer(
-        &me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
-    me->mpoly = (MPoly *)CustomData_add_layer(
-        &me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
-
-    if (alluv) {
-      const char *uvname = "UVMap";
-      me->mloopuv = (MLoopUV *)CustomData_add_layer_named(
-          &me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
-    }
-
-    BKE_mesh_calc_normals(me);
-  }
-  else {
-    me = (Mesh *)BKE_id_new_nomain(ID_ME, obdata_name);
-
-    ob->runtime.data_eval = nullptr;
-    BKE_mesh_nomain_to_mesh(me_eval, me, ob, &CD_MASK_MESH, true);
-  }
-
-  me->totcol = cu->totcol;
-  me->mat = cu->mat;
-
-  mesh_copy_texture_space_from_curve_type(cu, me);
-
-  cu->mat = nullptr;
-  cu->totcol = 0;
-
-  /* Do not decrement ob->data usercount here,
-   * it's done at end of func with BKE_id_free_us() call. */
-  ob->data = me;
-  ob->type = OB_MESH;
-
-  /* For temporary objects in BKE_mesh_new_from_object don't remap
-   * the entire scene with associated depsgraph updates, which are
-   * problematic for renderers exporting data. */
-  BKE_id_free(nullptr, cu);
-}
-
 struct EdgeLink {
   struct EdgeLink *next, *prev;
   void *edge;
@@ -948,47 +868,25 @@ void BKE_pointcloud_to_mesh(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(sce
   BKE_object_free_derived_caches(ob);
 }
 
-/* Create a temporary object to be used for nurbs-to-mesh conversion.
- *
- * This is more complex that it should be because #mesh_from_nurbs_displist will do more than
- * simply conversion and will attempt to take over ownership of evaluated result and will also
- * modify the input object. */
-static Object *object_for_curve_to_mesh_create(Object *object)
+/* Create a temporary object to be used for nurbs-to-mesh conversion. */
+static Object *object_for_curve_to_mesh_create(const Object *object)
 {
-  Curve *curve = (Curve *)object->data;
+  const Curve *curve = (const Curve *)object->data;
 
-  /* Create object itself. */
+  /* reate a temporary object which can be evaluated and modified by generic
+   * curve evaluation (hence the LIB_ID_COPY_SET_COPIED_ON_WRITE flag). */
   Object *temp_object = (Object *)BKE_id_copy_ex(
-      nullptr, &object->id, nullptr, LIB_ID_COPY_LOCALIZE);
+      nullptr, &object->id, nullptr, LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_SET_COPIED_ON_WRITE);
 
   /* Remove all modifiers, since we don't want them to be applied. */
   BKE_object_free_modifiers(temp_object, LIB_ID_CREATE_NO_USER_REFCOUNT);
 
-  /* Copy relevant evaluated fields of curve cache.
-   *
-   * Note that there are extra fields in there like bevel and path, but those are not needed during
-   * conversion, so they are not copied to save unnecessary allocations. */
-  if (temp_object->runtime.curve_cache == nullptr) {
-    temp_object->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
-                                                                 "CurveCache for curve types");
-  }
-
-  if (object->runtime.curve_cache != nullptr) {
-    BKE_displist_copy(&temp_object->runtime.curve_cache->disp, &object->runtime.curve_cache->disp);
-  }
-
-  /* Constructive modifiers will use mesh to store result. */
-  if (object->runtime.data_eval != nullptr) {
-    BKE_id_copy_ex(
-        nullptr, object->runtime.data_eval, &temp_object->runtime.data_eval, LIB_ID_COPY_LOCALIZE);
-  }
-
-  /* Need to create copy of curve itself as well, it will be freed by underlying conversion
-   * functions.
-   *
-   * NOTE: Copies the data, but not the shapekeys. */
-  BKE_id_copy_ex(
-      nullptr, (const ID *)object->data, (ID **)&temp_object->data, LIB_ID_COPY_LOCALIZE);
+  /* Need to create copy of curve itself as well, since it will be changed by the curve evaluation
+   * process. NOTE: Copies the data, but not the shapekeys. */
+  temp_object->data = BKE_id_copy_ex(nullptr,
+                                     (const ID *)object->data,
+                                     nullptr,
+                                     LIB_ID_COPY_LOCALIZE | LIB_ID_COPY_SET_COPIED_ON_WRITE);
   Curve *temp_curve = (Curve *)temp_object->data;
 
   /* Make sure texture space is calculated for a copy of curve, it will be used for the final
@@ -1006,23 +904,10 @@ static Object *object_for_curve_to_mesh_create(Object *object)
 /**
  * Populate `object->runtime.curve_cache` which is then used to create the mesh.
  */
-static void curve_to_mesh_eval_ensure(Object *object)
+static void curve_to_mesh_eval_ensure(Object &object)
 {
-  Curve *curve = (Curve *)object->data;
-  Curve remapped_curve = *curve;
-  Object remapped_object = *object;
-  BKE_object_runtime_reset(&remapped_object);
-
-  remapped_object.data = &remapped_curve;
-
-  if (object->runtime.curve_cache == nullptr) {
-    object->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache),
-                                                            "CurveCache for Curve");
-  }
-
-  /* Temporarily share the curve-cache with the temporary object, owned by `object`. */
-  remapped_object.runtime.curve_cache = object->runtime.curve_cache;
-
+  BLI_assert(GS(static_cast<ID *>(object.data)->name) == ID_CU);
+  Curve &curve = *static_cast<Curve *>(object.data);
   /* Clear all modifiers for the bevel object.
    *
    * This is because they can not be reliably evaluated for an original object (at least because
@@ -1031,83 +916,97 @@ static void curve_to_mesh_eval_ensure(Object *object)
    * So we create temporary copy of the object which will use same data as the original bevel, but
    * will have no mod

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list