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; _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org List details, subscription details or unsubscribe: https://lists.blender.org/mailman/listinfo/bf-blender-cvs