diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_displist.h | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/displist.cc | 328 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/geometry_component_curve.cc | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/geometry_set.cc | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/geometry_set_instances.cc | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_convert.c | 36 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object_dupli.cc | 2 |
8 files changed, 159 insertions, 231 deletions
diff --git a/source/blender/blenkernel/BKE_displist.h b/source/blender/blenkernel/BKE_displist.h index 0f37ba6c4ce..37e144ebbd3 100644 --- a/source/blender/blenkernel/BKE_displist.h +++ b/source/blender/blenkernel/BKE_displist.h @@ -99,7 +99,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 58509e95de6..bdab508eb1f 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" @@ -47,6 +48,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 +57,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. */ @@ -745,10 +748,7 @@ static ModifierData *curve_get_tessellate_point(const Scene *scene, return pretessellatePoint; } -/** - * \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, @@ -793,7 +793,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; @@ -813,7 +812,6 @@ bool BKE_curve_calc_modifiers_pre(Depsgraph *depsgraph, } mti->deformVerts(md, &mectx, nullptr, deformedVerts, numVerts); - modified = true; if (md == pretessellatePoint) { break; @@ -832,48 +830,59 @@ 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] +/** + * \return True if the deformed curve control point data should be implicitly + * converted directly to a mesh, or false if it can be left as curve data via #CurveEval. + */ +static bool do_curve_implicit_mesh_conversion(const Curve *curve, + ModifierData *first_modifier, + const Scene *scene, + const ModifierMode required_mode) { - *r_vert_len = 0; + /* Skip implicit filling and conversion to mesh when using "fast text editing". */ + if (curve->flag & CU_FAST) { + return false; + } - LISTBASE_FOREACH (DispList *, dl, dispbase) { - *r_vert_len += (dl->type == DL_INDEX3) ? dl->nr : dl->parts * dl->nr; + /* Do implicit conversion to mesh with the object bevel mode. */ + if (curve->bevel_mode == CU_BEV_MODE_OBJECT && curve->bevobj != nullptr) { + return true; } - 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; + /* 2D curves are sometimes implicitly filled and converted to a mesh. */ + if (CU_DO_2DFILL(curve)) { + return true; } - return allverts; -} + /* Curve objects with implicit "tube" meshes should convert implicitly to a mesh. */ + if (curve->ext1 != 0.0f || curve->ext2 != 0.0f) { + return true; + } -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; + /* If a non-geometry-nodes modifier is enabled before a nodes modifier, + * force conversion to mesh, since only the nodes modifier supports 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 void curve_calc_modifiers_post(Depsgraph *depsgraph, - const Scene *scene, - Object *ob, - ListBase *dispbase, - const bool for_render, - const bool force_mesh_conversion, - Mesh **r_final) +static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph, + const Scene *scene, + Object *ob, + const ListBase *dispbase, + const bool for_render) { const Curve *cu = (const Curve *)ob->data; - const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); const bool use_cache = !for_render; @@ -897,166 +906,64 @@ static void curve_calc_modifiers_post(Depsgraph *depsgraph, BKE_modifiers_get_virtual_modifierlist(ob, &virtualModifierData) : pretessellatePoint->next; - if (r_final && *r_final) { - BKE_id_free(nullptr, *r_final); + GeometrySet geometry_set; + if (ob->type == OB_SURF || do_curve_implicit_mesh_conversion(cu, md, scene, required_mode)) { + Mesh *mesh = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase); + 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()); } - Mesh *modified = nullptr; - float(*vertCos)[3] = nullptr; - int totvert = 0; for (; md; md = md->next) { const ModifierTypeInfo *mti = BKE_modifier_get_info((ModifierType)md->type); - if (!BKE_modifier_is_enabled(scene, md, required_mode)) { 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 (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) { - curve_to_filledpoly(cu, dispbase); - } + if (md->type == eModifierType_Nodes) { + mti->modifyGeometrySet(md, &mectx_apply, &geometry_set); + continue; + } - modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase); + if (!geometry_set.has_mesh()) { + geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0, 0)); } + Mesh *mesh = geometry_set.get_mesh_for_write(); - if (mti->type == eModifierTypeType_OnlyDeform || - (mti->type == eModifierTypeType_DeformOrConstruct && !modified)) { - if (modified) { - 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); - } - else { - if (!vertCos) { - vertCos = displist_vert_coords_alloc(dispbase, &totvert); - } - mti->deformVerts(md, &mectx_deform, nullptr, vertCos, totvert); + if (mti->type == eModifierTypeType_OnlyDeform) { + int totvert; + float(*vertex_coords)[3] = BKE_mesh_vert_coords_alloc(mesh, &totvert); + if (mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md)) { + BKE_mesh_ensure_normals(mesh); } + mti->deformVerts(md, &mectx_deform, mesh, vertex_coords, totvert); + BKE_mesh_vert_coords_apply(mesh, vertex_coords); + MEM_freeN(vertex_coords); } else { - if (!r_final) { - /* 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); - } - - modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase); - } - - if (vertCos) { - /* Vertex coordinates were applied to necessary data, could free it */ - MEM_freeN(vertCos); - vertCos = nullptr; - } - - if (need_normal) { - BKE_mesh_ensure_normals(modified); + if (mti->dependsOnNormals != nullptr && mti->dependsOnNormals(md)) { + BKE_mesh_ensure_normals(mesh); } - Mesh *mesh_applied = mti->modifyMesh(md, &mectx_apply, modified); - - if (mesh_applied) { - if (modified && modified != mesh_applied) { - BKE_id_free(nullptr, modified); - } - modified = mesh_applied; + Mesh *output_mesh = mti->modifyMesh(md, &mectx_apply, mesh); + if (mesh != output_mesh) { + geometry_set.replace_mesh(output_mesh); } } } - 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; + if (geometry_set.has_mesh()) { + Mesh *final_mesh = geometry_set.get_mesh_for_write(); - BKE_mesh_vert_coords_apply(modified, vertCos); - BKE_mesh_calc_normals(modified); + BKE_mesh_calc_normals(final_mesh); - MEM_freeN(vertCos); - } - else { - displist_vert_coords_apply(dispbase, vertCos); - MEM_freeN(vertCos); - vertCos = nullptr; - } + BLI_strncpy(final_mesh->id.name, cu->id.name, sizeof(final_mesh->id.name)); + *((short *)final_mesh->id.name) = ID_ME; } - 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 modifiers to be applied on all user of the same data-block - * (see T71055) - * - * The easy workaround is to force to generate a Mesh that will be used for display data - * since a Mesh output is already used for generative modifiers. - * However it does not fix problems with actual edit data still being shared. - * - * The right solution would be to COW the Curve data block at the input of the modifier - * stack just like what the mesh modifier does. - */ - modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase); - } - - if (modified) { - - /* XXX2.8(Sybren): make sure the face normals are recalculated as well */ - BKE_mesh_ensure_normals(modified); - - /* Special tweaks, needed since neither BKE_mesh_new_nomain_from_template() nor - * BKE_mesh_new_nomain_from_curve_displist() properly duplicate mat info... */ - BLI_strncpy(modified->id.name, cu->id.name, sizeof(modified->id.name)); - *((short *)modified->id.name) = ID_ME; - MEM_SAFE_FREE(modified->mat); - /* Set flag which makes it easier to see what's going on in a debugger. */ - modified->id.tag |= LIB_TAG_COPIED_ON_WRITE_EVAL_RESULT; - modified->mat = (Material **)MEM_dupallocN(cu->mat); - modified->totcol = cu->totcol; - - (*r_final) = modified; - } - else { - (*r_final) = nullptr; - } - } - else if (modified != nullptr) { - /* Pretty stupid to generate that whole mesh if it's unused, yet we have to free it. */ - BKE_id_free(nullptr, modified); - } + return geometry_set; } static void displist_surf_indices(DispList *dl) @@ -1109,8 +1016,7 @@ static void evaluate_surface_object(Depsgraph *depsgraph, BKE_nurbList_duplicate(deformed_nurbs, &cu->nurb); } - bool force_mesh_conversion = BKE_curve_calc_modifiers_pre( - depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render); + BKE_curve_calc_modifiers_pre(depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render); LISTBASE_FOREACH (const Nurb *, nu, deformed_nurbs) { if (!(for_render || nu->hide == 0) || !BKE_nurb_check_valid_uv(nu)) { @@ -1173,8 +1079,14 @@ static void evaluate_surface_object(Depsgraph *depsgraph, } } - curve_calc_modifiers_post( - depsgraph, scene, ob, r_dispbase, for_render, force_mesh_conversion, r_final); + curve_to_filledpoly(cu, r_dispbase); + GeometrySet geometry_set = curve_calc_modifiers_post( + depsgraph, scene, ob, r_dispbase, for_render); + if (!geometry_set.has_mesh()) { + geometry_set.replace_mesh(BKE_mesh_new_nomain(0, 0, 0, 0, 0)); + } + MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>(); + *r_final = mesh_component.release(); } static void rotateBevelPiece(const Curve *cu, @@ -1394,12 +1306,11 @@ static void calc_bevfac_mapping(const Curve *cu, } } -static void evaluate_curve_type_object(Depsgraph *depsgraph, - const Scene *scene, - Object *ob, - const bool for_render, - ListBase *r_dispbase, - Mesh **r_final) +static GeometrySet evaluate_curve_type_object(Depsgraph *depsgraph, + const Scene *scene, + Object *ob, + const bool for_render, + ListBase *r_dispbase) { BLI_assert(ELEM(ob->type, OB_CURVE, OB_FONT)); const Curve *cu = (const Curve *)ob->data; @@ -1413,8 +1324,7 @@ static void evaluate_curve_type_object(Depsgraph *depsgraph, BKE_nurbList_duplicate(deformed_nurbs, BKE_curve_nurbs_get_for_read(cu)); } - bool force_mesh_conversion = BKE_curve_calc_modifiers_pre( - depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render); + BKE_curve_calc_modifiers_pre(depsgraph, scene, ob, deformed_nurbs, deformed_nurbs, for_render); BKE_curve_bevelList_make(ob, deformed_nurbs, for_render); @@ -1603,16 +1513,8 @@ static void evaluate_curve_type_object(Depsgraph *depsgraph, BKE_displist_free(&dlbev); - if (!(cu->flag & CU_DEFORM_FILL)) { - curve_to_filledpoly(cu, r_dispbase); - } - - curve_calc_modifiers_post( - depsgraph, scene, ob, r_dispbase, for_render, force_mesh_conversion, r_final); - - if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) { - curve_to_filledpoly(cu, r_dispbase); - } + curve_to_filledpoly(cu, r_dispbase); + return curve_calc_modifiers_post(depsgraph, scene, ob, r_dispbase, for_render); } void BKE_displist_make_curveTypes(Depsgraph *depsgraph, @@ -1621,25 +1523,43 @@ void BKE_displist_make_curveTypes(Depsgraph *depsgraph, const bool for_render) { BLI_assert(ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)); + Curve &cow_curve = *(Curve *)ob->data; BKE_object_free_derived_caches(ob); + cow_curve.curve_eval = nullptr; - if (!ob->runtime.curve_cache) { - ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache), __func__); - } - + ob->runtime.curve_cache = (CurveCache *)MEM_callocN(sizeof(CurveCache), __func__); ListBase *dispbase = &(ob->runtime.curve_cache->disp); - Mesh *mesh_eval = nullptr; if (ob->type == OB_SURF) { + Mesh *mesh_eval; evaluate_surface_object(depsgraph, scene, ob, for_render, dispbase, &mesh_eval); + BKE_object_eval_assign_data(ob, &mesh_eval->id, true); } else { - evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase, &mesh_eval); - } + GeometrySet geometry = evaluate_curve_type_object(depsgraph, scene, ob, for_render, dispbase); + + if (geometry.has_curve()) { + /* Assign the evaluated curve to the object's "data_eval". In addition to the curve_eval + * added to the curve here, it will also contain a copy of the original curve's data. This is + * essential, because it maintains the expected behavior for evaluated curve data from before + * the CurveEval data type was introduced, when an evaluated object's curve data was just a + * copy of the original curve and everything else ended up in #CurveCache. */ + CurveComponent &curve_component = geometry.get_component_for_write<CurveComponent>(); + cow_curve.curve_eval = curve_component.get_for_write(); + BKE_object_eval_assign_data(ob, &cow_curve.id, false); + } + else if (geometry.has_mesh()) { + /* Most areas of Blender don't yet know how to look in #geometry_set_eval for evaluated mesh + * data, and look in #data_eval instead. When the object evaluates to a curve, that field + * must be used for the evaluated curve data, but otherwise we can use the field to store a + * pointer to the mesh, so more areas can retrieve the mesh. */ + MeshComponent &mesh_component = geometry.get_component_for_write<MeshComponent>(); + Mesh *mesh_eval = mesh_component.get_for_write(); + BKE_object_eval_assign_data(ob, &mesh_eval->id, false); + } - if (mesh_eval != nullptr) { - BKE_object_eval_assign_data(ob, &mesh_eval->id, true); + ob->runtime.geometry_set_eval = new GeometrySet(std::move(geometry)); } boundbox_displist_object(ob); @@ -1656,7 +1576,9 @@ void BKE_displist_make_curveTypes_forRender( evaluate_surface_object(depsgraph, scene, ob, true, r_dispbase, r_final); } else { - evaluate_curve_type_object(depsgraph, scene, ob, true, r_dispbase, r_final); + 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(); } } diff --git a/source/blender/blenkernel/intern/geometry_component_curve.cc b/source/blender/blenkernel/intern/geometry_component_curve.cc index a24b60ee288..afafd766760 100644 --- a/source/blender/blenkernel/intern/geometry_component_curve.cc +++ b/source/blender/blenkernel/intern/geometry_component_curve.cc @@ -64,6 +64,8 @@ void CurveComponent::clear() delete curve_; } if (curve_for_render_ != nullptr) { + /* The curve created by this component should not have any edit mode data. */ + BLI_assert(curve_for_render_->editfont == nullptr && curve_for_render_->editnurb == nullptr); BKE_id_free(nullptr, curve_for_render_); curve_for_render_ = nullptr; } diff --git a/source/blender/blenkernel/intern/geometry_set.cc b/source/blender/blenkernel/intern/geometry_set.cc index dafebef1812..e717d289894 100644 --- a/source/blender/blenkernel/intern/geometry_set.cc +++ b/source/blender/blenkernel/intern/geometry_set.cc @@ -408,7 +408,7 @@ bool BKE_object_has_geometry_set_instances(const Object *ob) if (ob->type == OB_VOLUME) { return has_mesh || has_pointcloud || has_curve; } - if (ob->type == OB_CURVE) { + if (ELEM(ob->type, OB_CURVE, OB_FONT)) { return has_mesh || has_pointcloud || has_volume; } return false; diff --git a/source/blender/blenkernel/intern/geometry_set_instances.cc b/source/blender/blenkernel/intern/geometry_set_instances.cc index 0e19324a3c1..9dca2c2907e 100644 --- a/source/blender/blenkernel/intern/geometry_set_instances.cc +++ b/source/blender/blenkernel/intern/geometry_set_instances.cc @@ -51,16 +51,6 @@ static void add_final_mesh_as_geometry_component(const Object &object, GeometryS } } -static void add_curve_data_as_geometry_component(const Object &object, GeometrySet &geometry_set) -{ - BLI_assert(object.type == OB_CURVE); - if (object.data != nullptr) { - std::unique_ptr<CurveEval> curve = curve_eval_from_dna_curve(*(const Curve *)object.data); - CurveComponent &curve_component = geometry_set.get_component_for_write<CurveComponent>(); - curve_component.replace(curve.release(), GeometryOwnershipType::Owned); - } -} - /** * \note This doesn't extract instances from the "dupli" system for non-geometry-nodes instances. */ @@ -84,9 +74,6 @@ static GeometrySet object_get_geometry_set_for_read(const Object &object) if (object.type == OB_MESH) { add_final_mesh_as_geometry_component(object, geometry_set); } - else if (object.type == OB_CURVE) { - add_curve_data_as_geometry_component(object, geometry_set); - } /* TODO: Cover the case of point-clouds without modifiers-- they may not be covered by the * #geometry_set_eval case above. */ diff --git a/source/blender/blenkernel/intern/mesh_convert.c b/source/blender/blenkernel/intern/mesh_convert.c index d5524312612..9fd75be0d35 100644 --- a/source/blender/blenkernel/intern/mesh_convert.c +++ b/source/blender/blenkernel/intern/mesh_convert.c @@ -483,8 +483,24 @@ static int mesh_nurbs_displist_to_mdata(const Curve *cu, return 0; } +/** + * Copy evaluated texture space from curve to mesh. + * + * \note We disable auto texture space feature since that will cause texture space to evaluate + * differently for curve and mesh, since curves use control points and handles to calculate the + * bounding box, and mesh uses the tessellated curve. + */ +static void mesh_copy_texture_space_from_curve_type(const Curve *cu, Mesh *me) +{ + me->texflag = cu->texflag & ~CU_AUTOSPACE; + copy_v3_v3(me->loc, cu->loc); + copy_v3_v3(me->size, cu->size); + BKE_mesh_texspace_calc(me); +} + Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase *dispbase) { + const Curve *cu = ob->data; Mesh *mesh; MVert *allvert; MEdge *alledge; @@ -493,7 +509,7 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase * MLoopUV *alluv = NULL; int totvert, totedge, totloop, totpoly; - if (mesh_nurbs_displist_to_mdata(ob->data, + if (mesh_nurbs_displist_to_mdata(cu, dispbase, &allvert, &totvert, @@ -529,6 +545,12 @@ Mesh *BKE_mesh_new_nomain_from_curve_displist(const Object *ob, const ListBase * CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname); } + mesh_copy_texture_space_from_curve_type(cu, mesh); + + /* Copy curve materials. */ + mesh->mat = (Material **)MEM_dupallocN(cu->mat); + mesh->totcol = cu->totcol; + MEM_freeN(allvert); MEM_freeN(alledge); MEM_freeN(allloop); @@ -612,17 +634,7 @@ static void mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const char me->totcol = cu->totcol; me->mat = cu->mat; - /* Copy evaluated texture space from curve to mesh. - * - * Note that we disable auto texture space feature since that will cause - * texture space to evaluate differently for curve and mesh, since curve - * uses CV to calculate bounding box, and mesh uses what is coming from - * tessellated curve. - */ - me->texflag = cu->texflag & ~CU_AUTOSPACE; - copy_v3_v3(me->loc, cu->loc); - copy_v3_v3(me->size, cu->size); - BKE_mesh_texspace_calc(me); + mesh_copy_texture_space_from_curve_type(cu, me); cu->mat = NULL; cu->totcol = 0; diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index b4343578eab..465ec9dc665 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -1341,6 +1341,11 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type) { const ModifierTypeInfo *mti = BKE_modifier_get_info(modifier_type); + /* Surface and lattice objects don't output geometry sets. */ + if (mti->modifyGeometrySet != NULL && ELEM(ob->type, OB_SURF, OB_LATTICE)) { + return false; + } + /* Only geometry objects should be able to get modifiers T25291. */ if (ob->type == OB_HAIR) { return (mti->modifyHair != NULL) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly); diff --git a/source/blender/blenkernel/intern/object_dupli.cc b/source/blender/blenkernel/intern/object_dupli.cc index 47d4d03d1e1..04739ec19d3 100644 --- a/source/blender/blenkernel/intern/object_dupli.cc +++ b/source/blender/blenkernel/intern/object_dupli.cc @@ -855,7 +855,7 @@ static void make_duplis_geometry_set_impl(const DupliContext *ctx, dupli->ob_data = (ID *)volume; } } - if (ctx->object->type != OB_CURVE || geometry_set_is_instance) { + if (!ELEM(ctx->object->type, OB_CURVE, OB_FONT) || geometry_set_is_instance) { const CurveComponent *curve_component = geometry_set.get_component_for_read<CurveComponent>(); if (curve_component != nullptr) { const Curve *curve = curve_component->get_curve_for_render(); |