[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