From 62087935ec92e24bce362489cadc944bc256e8cc Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sun, 5 May 2013 05:56:41 +0000 Subject: [PATCH] Fix #35209: cycles generated texture coordinates did not stick to deforming meshes. --- intern/cycles/blender/blender_mesh.cpp | 7 +++--- intern/cycles/blender/blender_util.h | 4 ++-- source/blender/blenkernel/BKE_DerivedMesh.h | 2 +- .../blender/blenkernel/intern/DerivedMesh.c | 10 ++++---- source/blender/blenkernel/intern/mesh.c | 2 +- source/blender/collada/collada_utils.cpp | 2 +- source/blender/editors/object/object_add.c | 2 +- .../blender/editors/object/object_modifier.c | 2 +- source/blender/makesrna/intern/rna_internal.h | 2 +- source/blender/makesrna/intern/rna_main_api.c | 8 +++++-- source/blender/makesrna/intern/rna_mesh.c | 23 +++++++++++++++++++ .../blender/makesrna/intern/rna_object_api.c | 5 ++-- source/blender/makesrna/intern/rna_texture.c | 4 ++-- .../modifiers/intern/MOD_boolean_util.c | 2 +- 14 files changed, 52 insertions(+), 23 deletions(-) diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 10e3946dbd2..c545ad240c4 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -336,7 +336,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector< size_t i = 0; for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v) - generated[i++] = get_float3(v->co())*size - loc; + generated[i++] = get_float3(v->undeformed_co())*size - loc; } } @@ -435,7 +435,8 @@ Mesh *BlenderSync::sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tri mesh_synced.insert(mesh); /* create derived mesh */ - BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview); + bool need_undeformed = mesh->need_attribute(scene, ATTR_STD_GENERATED); + BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, need_undeformed); PointerRNA cmesh = RNA_pointer_get(&b_ob_data.ptr, "cycles"); vector oldtriangle = mesh->triangles; @@ -507,7 +508,7 @@ void BlenderSync::sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion) return; /* get derived mesh */ - BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview); + BL::Mesh b_mesh = object_to_mesh(b_data, b_ob, b_scene, true, !preview, false); if(b_mesh) { BL::Mesh::vertices_iterator v; diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h index 747008fc7c4..1c2576d0b3b 100644 --- a/intern/cycles/blender/blender_util.h +++ b/intern/cycles/blender/blender_util.h @@ -39,9 +39,9 @@ float *BKE_image_get_float_pixels_for_frame(void *image, int frame); CCL_NAMESPACE_BEGIN -static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render) +static inline BL::Mesh object_to_mesh(BL::BlendData data, BL::Object object, BL::Scene scene, bool apply_modifiers, bool render, bool calc_undeformed) { - return data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, true); + return data.meshes.new_from_object(scene, object, apply_modifiers, (render)? 2: 1, true, calc_undeformed); } static inline void colorramp_to_array(BL::ColorRamp ramp, float4 *data, int size) diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 2cb9d42b479..f0df766ffde 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -468,7 +468,7 @@ int DM_release(DerivedMesh *dm); /** utility function to convert a DerivedMesh to a Mesh */ -void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob); +void DM_to_mesh(DerivedMesh *dm, struct Mesh *me, struct Object *ob, CustomDataMask mask); struct BMEditMesh *DM_to_editbmesh(struct DerivedMesh *dm, struct BMEditMesh *existing, int do_tessellate); diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 8efd9ae133e..b728bbcf047 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -470,7 +470,7 @@ void DM_update_tessface_data(DerivedMesh *dm) dm->dirty &= ~DM_DIRTY_TESS_CDLAYERS; } -void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) +void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob, CustomDataMask mask) { /* dm might depend on me, so we need to do everything with a local copy */ Mesh tmp = *me; @@ -489,10 +489,10 @@ void DM_to_mesh(DerivedMesh *dm, Mesh *me, Object *ob) totpoly = tmp.totpoly = dm->getNumPolys(dm); tmp.totface = 0; - CustomData_copy(&dm->vertData, &tmp.vdata, CD_MASK_MESH, CD_DUPLICATE, totvert); - CustomData_copy(&dm->edgeData, &tmp.edata, CD_MASK_MESH, CD_DUPLICATE, totedge); - CustomData_copy(&dm->loopData, &tmp.ldata, CD_MASK_MESH, CD_DUPLICATE, totloop); - CustomData_copy(&dm->polyData, &tmp.pdata, CD_MASK_MESH, CD_DUPLICATE, totpoly); + CustomData_copy(&dm->vertData, &tmp.vdata, mask, CD_DUPLICATE, totvert); + CustomData_copy(&dm->edgeData, &tmp.edata, mask, CD_DUPLICATE, totedge); + CustomData_copy(&dm->loopData, &tmp.ldata, mask, CD_DUPLICATE, totloop); + CustomData_copy(&dm->polyData, &tmp.pdata, mask, CD_DUPLICATE, totpoly); tmp.cd_flag = dm->cd_flag; if (CustomData_has_layer(&dm->vertData, CD_SHAPEKEY)) { diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c index 93b398cec55..3c4900e8a6a 100644 --- a/source/blender/blenkernel/intern/mesh.c +++ b/source/blender/blenkernel/intern/mesh.c @@ -1599,7 +1599,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use } else { me = BKE_mesh_add(G.main, "Mesh"); - DM_to_mesh(dm, me, ob); + DM_to_mesh(dm, me, ob, CD_MASK_MESH); } me->totcol = cu->totcol; diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp index 6a18ac09615..66cef6dd20a 100644 --- a/source/blender/collada/collada_utils.cpp +++ b/source/blender/collada/collada_utils.cpp @@ -160,7 +160,7 @@ Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh } tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here - DM_to_mesh(dm, tmpmesh, ob); + DM_to_mesh(dm, tmpmesh, ob, CD_MASK_MESH); dm->release(dm); if (triangulate) { diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c index ffdfe053127..5ad6bd4993a 100644 --- a/source/blender/editors/object/object_add.c +++ b/source/blender/editors/object/object_add.c @@ -1528,7 +1528,7 @@ static int convert_exec(bContext *C, wmOperator *op) dm = mesh_get_derived_final(scene, newob, CD_MASK_MESH); // dm = mesh_create_derived_no_deform(ob1, NULL); /* this was called original (instead of get_derived). man o man why! (ton) */ - DM_to_mesh(dm, newob->data, newob); + DM_to_mesh(dm, newob->data, newob, CD_MASK_MESH); /* re-tessellation is called by DM_to_mesh */ diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c index b743f891f66..c4b2f6c515b 100644 --- a/source/blender/editors/object/object_modifier.c +++ b/source/blender/editors/object/object_modifier.c @@ -616,7 +616,7 @@ static int modifier_apply_obdata(ReportList *reports, Scene *scene, Object *ob, return 0; } - DM_to_mesh(dm, me, ob); + DM_to_mesh(dm, me, ob, CD_MASK_MESH); dm->release(dm); diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 0a2c876ec50..b78972ea64c 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -405,7 +405,7 @@ int rna_parameter_size_alloc(struct PropertyRNA *parm); struct Mesh *rna_Main_meshes_new_from_object( struct Main *bmain, struct ReportList *reports, struct Scene *sce, - struct Object *ob, int apply_modifiers, int settings, int calc_tessface); + struct Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed); /* XXX, these should not need to be defined here~! */ struct MTex *rna_mtex_texture_slots_add(struct ID *self, struct bContext *C, struct ReportList *reports); diff --git a/source/blender/makesrna/intern/rna_main_api.c b/source/blender/makesrna/intern/rna_main_api.c index 5d554f4393c..1e77a799cd4 100644 --- a/source/blender/makesrna/intern/rna_main_api.c +++ b/source/blender/makesrna/intern/rna_main_api.c @@ -276,7 +276,7 @@ static Mesh *rna_Main_meshes_new(Main *bmain, const char *name) /* settings: 1 - preview, 2 - render */ Mesh *rna_Main_meshes_new_from_object( Main *bmain, ReportList *reports, Scene *sce, - Object *ob, int apply_modifiers, int settings, int calc_tessface) + Object *ob, int apply_modifiers, int settings, int calc_tessface, int calc_undeformed) { Mesh *tmpmesh; Curve *tmpcu = NULL, *copycu; @@ -379,6 +379,9 @@ Mesh *rna_Main_meshes_new_from_object( CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter, * for example, needs CD_MASK_MDEFORMVERT */ + if (calc_undeformed) + mask |= CD_MASK_ORCO; + /* Write the display mesh into the dummy mesh */ if (render) dm = mesh_create_derived_render(sce, ob, mask); @@ -386,7 +389,7 @@ Mesh *rna_Main_meshes_new_from_object( dm = mesh_create_derived_view(sce, ob, mask); tmpmesh = BKE_mesh_add(bmain, "Mesh"); - DM_to_mesh(dm, tmpmesh, ob); + DM_to_mesh(dm, tmpmesh, ob, mask); dm->release(dm); } @@ -1172,6 +1175,7 @@ void RNA_def_main_meshes(BlenderRNA *brna, PropertyRNA *cprop) parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply"); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces"); + RNA_def_boolean(func, "calc_undeformed", false, "Calculate Undeformed", "Calculate undeformed vertex coordinates"); parm = RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export"); RNA_def_function_return(func, parm); diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index ecdd0c949bd..86b2aa4fb2b 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -591,6 +591,23 @@ static void rna_MeshVertex_groups_begin(CollectionPropertyIterator *iter, Pointe rna_iterator_array_begin(iter, NULL, 0, 0, 0, NULL); } +static void rna_MeshVertex_undeformed_co_get(PointerRNA *ptr, float values[3]) +{ + Mesh *me = rna_mesh(ptr); + MVert *mvert = (MVert *)ptr->data; + float (*orco)[3] = CustomData_get_layer(&me->vdata, CD_ORCO); + + if (orco) { + /* orco is normalized to 0..1, we do inverse to match mvert->co */ + float loc[3], size[3]; + + BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, loc, NULL, size); + madd_v3_v3v3v3(values, loc, orco[(mvert - me->mvert)], size); + } + else + copy_v3_v3(values, mvert->co); +} + static int rna_CustomDataLayer_active_get(PointerRNA *ptr, CustomData *data, int type, int render) { int n = ((CustomDataLayer *)ptr->data) - data->layers; @@ -1638,6 +1655,12 @@ static void rna_def_mvert(BlenderRNA *brna) RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_int_funcs(prop, "rna_MeshVertex_index_get", NULL, NULL); RNA_def_property_ui_text(prop, "Index", "Index number of the vertex"); + + prop = RNA_def_property(srna, "undeformed_co", PROP_FLOAT, PROP_TRANSLATION); + RNA_def_property_array(prop, 3); + RNA_def_property_ui_text(prop, "Undeformed Location", "For meshes with modifiers applied, the coordinate of the vertex with no deforming modifiers applied, as used for generated texture coordinates. "); + RNA_def_property_float_funcs(prop, "rna_MeshVertex_undeformed_co_get", NULL, NULL); + RNA_def_property_clear_flag(prop, PROP_EDITABLE); } static void rna_def_medge(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c index 7715dfa64de..a4e532660f1 100644 --- a/source/blender/makesrna/intern/rna_object_api.c +++ b/source/blender/makesrna/intern/rna_object_api.c @@ -115,9 +115,9 @@ static void rna_Scene_mat_convert_space(Object *ob, ReportList *reports, bPoseCh /* settings: 0 - preview, 1 - render */ static Mesh *rna_Object_to_mesh( Object *ob, ReportList *reports, Scene *sce, - int apply_modifiers, int settings, int calc_tessface) + int apply_modifiers, int settings, int calc_tessface, int calc_undeformed) { - return rna_Main_meshes_new_from_object(G.main, reports, sce, ob, apply_modifiers, settings, calc_tessface); + return rna_Main_meshes_new_from_object(G.main, reports, sce, ob, apply_modifiers, settings, calc_tessface, calc_undeformed); } /* mostly a copy from convertblender.c */ @@ -456,6 +456,7 @@ void RNA_api_object(StructRNA *srna) parm = RNA_def_enum(func, "settings", mesh_type_items, 0, "", "Modifier settings to apply"); RNA_def_property_flag(parm, PROP_REQUIRED); RNA_def_boolean(func, "calc_tessface", true, "Calculate Tessellation", "Calculate tessellation faces"); + RNA_def_boolean(func, "calc_undeformed", false, "Calculate Undeformed", "Calculate undeformed vertex coordinates"); parm = RNA_def_pointer(func, "mesh", "Mesh", "", "Mesh created from object, remove it if it is only used for export"); RNA_def_function_return(func, parm); diff --git a/source/blender/makesrna/intern/rna_texture.c b/source/blender/makesrna/intern/rna_texture.c index d01eab053bd..be6defa11d7 100644 --- a/source/blender/makesrna/intern/rna_texture.c +++ b/source/blender/makesrna/intern/rna_texture.c @@ -1625,7 +1625,7 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) {0, NULL, 0, NULL, NULL} }; - static EnumPropertyItem vertice_cache_items[] = { + static EnumPropertyItem vertex_cache_items[] = { {TEX_PD_OBJECTLOC, "OBJECT_LOCATION", 0, "Object Location", ""}, {TEX_PD_OBJECTSPACE, "OBJECT_SPACE", 0, "Object Space", ""}, {TEX_PD_WORLDSPACE, "WORLD_SPACE", 0, "Global Space", ""}, @@ -1695,7 +1695,7 @@ static void rna_def_texture_pointdensity(BlenderRNA *brna) prop = RNA_def_property(srna, "vertex_cache_space", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "ob_cache_space"); - RNA_def_property_enum_items(prop, vertice_cache_items); + RNA_def_property_enum_items(prop, vertex_cache_items); RNA_def_property_ui_text(prop, "Vertices Cache", "Coordinate system to cache vertices in"); RNA_def_property_update(prop, 0, "rna_Texture_update"); diff --git a/source/blender/modifiers/intern/MOD_boolean_util.c b/source/blender/modifiers/intern/MOD_boolean_util.c index c9a7dc9a73d..0616db36afa 100644 --- a/source/blender/modifiers/intern/MOD_boolean_util.c +++ b/source/blender/modifiers/intern/MOD_boolean_util.c @@ -625,7 +625,7 @@ int NewBooleanMesh(Scene *scene, Base *base, Base *base_select, int int_op_type) ob_new = AddNewBlenderMesh(scene, base_select); me_new = ob_new->data; - DM_to_mesh(result, me_new, ob_new); + DM_to_mesh(result, me_new, ob_new, CD_MASK_MESH); result->release(result); dm->release(dm);