[Bf-blender-cvs] [bb6b926b04e] curve-nodes-modifier: Add smarter mesh conversion logic

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


Commit: bb6b926b04ebb8c13bad314205dbab994658b9d4
Author: Hans Goudey
Date:   Tue Jul 6 16:09:49 2021 -0500
Branches: curve-nodes-modifier
https://developer.blender.org/rBbb6b926b04ebb8c13bad314205dbab994658b9d4

Add smarter mesh conversion logic

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

M	source/blender/blenkernel/intern/displist.cc
M	source/blender/blenkernel/intern/geometry_component_curve.cc
M	source/blender/depsgraph/intern/depsgraph_query_iter.cc
M	source/blender/draw/intern/draw_cache_impl_curve.cc
M	source/blender/makesdna/DNA_curve_types.h
M	source/blender/makesdna/DNA_object_types.h

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

diff --git a/source/blender/blenkernel/intern/displist.cc b/source/blender/blenkernel/intern/displist.cc
index 172c9fd8ff9..b542ec2ea00 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"
 
@@ -831,6 +832,45 @@ void BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph,
   }
 }
 
+/**
+ * \return True if the deformed curve control point data should be implicitly
+ * converted directly to a mesh, or false it can be left as curve data via #CurveEval.
+ */
+static bool do_mesh_conversion(const Curve *curve,
+                               ModifierData *first_modifier,
+                               const Scene *scene,
+                               const ModifierMode required_mode)
+{
+  /* Do implicit conversion to mesh with the object bevel mode. */
+  if (curve->bevel_mode == CU_BEV_MODE_OBJECT && curve->bevobj != nullptr) {
+    return true;
+  }
+
+  /* 2D curves are implicitly filled and converted to a mesh. */
+  if (CU_IS_2D(curve)) {
+    return true;
+  }
+
+  /* Curve objects with implicit "tube" meshes should convert implicitly to a mesh. */
+  if (curve->ext1 != 0.0f || curve->ext2 != 0.0f) {
+    return true;
+  }
+
+  /* If a non-geometry-nodes modifier is enabled before a nodes modifier,
+   * force conversion to mesh, since it doesn't support 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 GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
                                              const Scene *scene,
                                              Object *ob,
@@ -862,14 +902,7 @@ static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
                          pretessellatePoint->next;
 
   GeometrySet geometry_set;
-  if (ELEM(ob->type, OB_CURVE, OB_FONT) &&
-      (md == nullptr ||
-       (md->type == eModifierType_Nodes && BKE_modifier_is_enabled(scene, md, required_mode)))) {
-    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());
-  }
-  else {
+  if (ELEM(ob->type, OB_CURVE, OB_FONT) && do_mesh_conversion(cu, md, scene, required_mode)) {
     Mesh *mesh = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase);
     /* Copy materials, since BKE_mesh_new_nomain_from_curve_displist() doesn't. */
     mesh->mat = (Material **)MEM_dupallocN(cu->mat);
@@ -877,6 +910,11 @@ static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
 
     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());
+  }
 
   for (; md; md = md->next) {
     const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type);
@@ -1502,15 +1540,15 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph,
   else {
     GeometrySet geometry_set;
     evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase, &geometry_set);
+
     if (BKE_curve_editNurbs_get_for_read((const Curve *)ob->data) &&
         !geometry_set.has<CurveComponent>()) {
       geometry_set.get_component_for_write<CurveComponent>();
     }
-    ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry_set));
 
-    if (geometry_set.has<MeshComponent>()) {
-      std::cout << "Output has mesh component\n";
-    }
+    ob->runtime.curve_eval = (void *)geometry_set.get_curve_for_read();
+
+    ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry_set));
   }
 
   boundbox_displist_object(ob);
diff --git a/source/blender/blenkernel/intern/geometry_component_curve.cc b/source/blender/blenkernel/intern/geometry_component_curve.cc
index b5c49dbb8b2..e177cceb091 100644
--- a/source/blender/blenkernel/intern/geometry_component_curve.cc
+++ b/source/blender/blenkernel/intern/geometry_component_curve.cc
@@ -146,7 +146,6 @@ const Curve *CurveComponent::get_curve_for_render() const
   }
 
   curve_for_render_ = (Curve *)BKE_id_new_nomain(ID_CU, nullptr);
-  curve_for_render_->curve_eval = curve_;
 
   return curve_for_render_;
 }
diff --git a/source/blender/depsgraph/intern/depsgraph_query_iter.cc b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
index 2d4e5286e35..5d7c51be562 100644
--- a/source/blender/depsgraph/intern/depsgraph_query_iter.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query_iter.cc
@@ -238,6 +238,7 @@ bool deg_iterator_components_step(BLI_Iterator *iter)
         *temp_object = *data->geometry_component_owner;
         temp_object->type = OB_CURVE;
         temp_object->data = (void *)curve;
+        temp_object->runtime.curve_eval = (void *)component->get_for_read();
         temp_object->runtime.select_id = data->geometry_component_owner->runtime.select_id;
         iter->current = temp_object;
         return true;
diff --git a/source/blender/draw/intern/draw_cache_impl_curve.cc b/source/blender/draw/intern/draw_cache_impl_curve.cc
index 51bd4c535cd..96c1a267d22 100644
--- a/source/blender/draw/intern/draw_cache_impl_curve.cc
+++ b/source/blender/draw/intern/draw_cache_impl_curve.cc
@@ -245,9 +245,7 @@ enum {
 /*
  * ob_curve_cache can be NULL, only needed for CU_DATATYPE_WIRE
  */
-static CurveRenderData *curve_render_data_create(Curve *cu,
-                                                 CurveCache *ob_curve_cache,
-                                                 const int types)
+static CurveRenderData *curve_render_data_create(Curve *cu, Object *object, const int types)
 {
   CurveRenderData *rdata = (CurveRenderData *)MEM_callocN(sizeof(*rdata), __func__);
   rdata->types = types;
@@ -256,9 +254,8 @@ static CurveRenderData *curve_render_data_create(Curve *cu,
   rdata->actnu = cu->actnu;
   rdata->actvert = cu->actvert;
 
-  rdata->ob_curve_cache = ob_curve_cache;
-
-  rdata->curve_eval = cu->curve_eval;
+  rdata->ob_curve_cache = object->runtime.curve_cache;
+  rdata->curve_eval = (const CurveEval *)object->runtime.curve_eval;
 
   if (types & CU_DATATYPE_WIRE) {
     if (rdata->curve_eval != nullptr) {
@@ -1148,7 +1145,7 @@ void DRW_curve_batch_cache_create_requested(Object *ob, const struct Scene *scen
   printf("  mr_flag %d\n\n", mr_flag);
 #endif
 
-  CurveRenderData *rdata = curve_render_data_create(cu, ob->runtime.curve_cache, mr_flag);
+  CurveRenderData *rdata = curve_render_data_create(cu, ob, mr_flag);
 
   /* The object's curve cache can be empty (in one case because we use #CurveEval's cache instead),
    * If so, point to an empty DispList list to avoid the need to check for null in the following
diff --git a/source/blender/makesdna/DNA_curve_types.h b/source/blender/makesdna/DNA_curve_types.h
index bdc07a6d264..2ea6dfd4c97 100644
--- a/source/blender/makesdna/DNA_curve_types.h
+++ b/source/blender/makesdna/DNA_curve_types.h
@@ -300,12 +300,6 @@ typedef struct Curve {
   char _pad2[6];
   float fsize_realtime;
 
-  /**
-   * A pointer to curve data from geometry nodes, currently only set for evaluated
-   * objects by the dependency graph iterator, and owned by #geometry_set_eval.
-   */
-  struct CurveEval *curve_eval;
-
   void *batch_cache;
 } Curve;
 
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index 262d650c1ef..d4227fabe36 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -210,6 +210,16 @@ typedef struct Object_Runtime {
   /** Runtime evaluated curve-specific data, not stored in the file. */
   struct CurveCache *curve_cache;
 
+  /**
+   * A pointer to evaluated curve data owned by #geometry_set_eval (const CurveEval *).
+   * Stored as a `void *` because DNA doesn't support const pointers right now.
+   *
+   * This is necessary because curve object data does not use CoW. Normally we use a "fake" CoW
+   * in the geometry component, but for curve objects we must use the original #Curve in order to
+   * display edit mode data, and the evaluated data cannot be stored in the original #Curve.
+   */
+  void *curve_eval;
+
   unsigned short local_collections_bits;
   short _pad2[3];
 } Object_Runtime;



More information about the Bf-blender-cvs mailing list