Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/mesh_convert.c
| Show First 20 Lines • Show All 1,059 Lines • ▼ Show 20 Lines | |||||
| static void curve_to_mesh_eval_ensure(Object *object) | static void curve_to_mesh_eval_ensure(Object *object) | ||||
| { | { | ||||
| if (object->runtime.curve_cache == NULL) { | if (object->runtime.curve_cache == NULL) { | ||||
| object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); | object->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for Curve"); | ||||
| } | } | ||||
| Curve *curve = (Curve *)object->data; | Curve *curve = (Curve *)object->data; | ||||
| Curve remapped_curve = *curve; | Curve remapped_curve = *curve; | ||||
| Object remapped_object = *object; | Object remapped_object = *object; | ||||
| remapped_object.runtime.bb = NULL; | |||||
| remapped_object.data = &remapped_curve; | remapped_object.data = &remapped_curve; | ||||
| /* Clear all modifiers for the bevel object. | /* Clear all modifiers for the bevel object. | ||||
| * | * | ||||
| * This is because they can not be reliably evaluated for an original object (at least because | * This is because they can not be reliably evaluated for an original object (at least because | ||||
| * the state of dependencies is not know). | * the state of dependencies is not know). | ||||
| * | * | ||||
| * So we create temporary copy of the object which will use same data as the original bevel, but | * So we create temporary copy of the object which will use same data as the original bevel, but | ||||
| * will have no modifiers. */ | * will have no modifiers. */ | ||||
| Object bevel_object = {{NULL}}; | Object bevel_object = {{NULL}}; | ||||
| if (remapped_curve.bevobj != NULL) { | if (remapped_curve.bevobj != NULL) { | ||||
| bevel_object = *remapped_curve.bevobj; | bevel_object = *remapped_curve.bevobj; | ||||
| bevel_object.runtime.bb = NULL; | |||||
| BLI_listbase_clear(&bevel_object.modifiers); | BLI_listbase_clear(&bevel_object.modifiers); | ||||
| remapped_curve.bevobj = &bevel_object; | remapped_curve.bevobj = &bevel_object; | ||||
| } | } | ||||
| /* Same thing for taper. */ | /* Same thing for taper. */ | ||||
| Object taper_object = {{NULL}}; | Object taper_object = {{NULL}}; | ||||
| if (remapped_curve.taperobj != NULL) { | if (remapped_curve.taperobj != NULL) { | ||||
| taper_object = *remapped_curve.taperobj; | taper_object = *remapped_curve.taperobj; | ||||
| taper_object.runtime.bb = NULL; | |||||
| BLI_listbase_clear(&taper_object.modifiers); | BLI_listbase_clear(&taper_object.modifiers); | ||||
| remapped_curve.taperobj = &taper_object; | remapped_curve.taperobj = &taper_object; | ||||
| } | } | ||||
| /* NOTE: We don't have dependency graph or scene here, so we pass NULL. This is all fine since | /* NOTE: We don't have dependency graph or scene here, so we pass NULL. This is all fine since | ||||
| * they are only used for modifier stack, which we have explicitly disabled for all objects. | * they are only used for modifier stack, which we have explicitly disabled for all objects. | ||||
| * | * | ||||
| * TODO(sergey): This is a very fragile logic, but proper solution requires re-writing quite a | * TODO(sergey): This is a very fragile logic, but proper solution requires re-writing quite a | ||||
| * bit of internal functions (BKE_mesh_from_nurbs_displist, BKE_mesh_nomain_to_mesh) and also | * bit of internal functions (BKE_mesh_from_nurbs_displist, BKE_mesh_nomain_to_mesh) and also | ||||
| * Mesh From Curve operator. | * Mesh From Curve operator. | ||||
| * Brecht says hold off with that. */ | * Brecht says hold off with that. */ | ||||
| Mesh *mesh_eval = NULL; | Mesh *mesh_eval = NULL; | ||||
| BKE_displist_make_curveTypes_forRender( | BKE_displist_make_curveTypes_forRender( | ||||
| NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval, false); | NULL, NULL, &remapped_object, &remapped_object.runtime.curve_cache->disp, &mesh_eval, false); | ||||
| /* Note: this is to be consistent with `BKE_displist_make_curveTypes()`, however that is not a | /* Note: this is to be consistent with `BKE_displist_make_curveTypes()`, however that is not a | ||||
| * real issue currently, code here is broken in more than one way, fix(es) will be done | * real issue currently, code here is broken in more than one way, fix(es) will be done | ||||
| * separately. */ | * separately. */ | ||||
| if (mesh_eval != NULL) { | if (mesh_eval != NULL) { | ||||
| BKE_object_eval_assign_data(&remapped_object, &mesh_eval->id, true); | BKE_object_eval_assign_data(&remapped_object, &mesh_eval->id, true); | ||||
| } | } | ||||
| MEM_SAFE_FREE(remapped_object.runtime.bb); | |||||
| MEM_SAFE_FREE(taper_object.runtime.bb); | |||||
| MEM_SAFE_FREE(bevel_object.runtime.bb); | |||||
| BKE_object_free_curve_cache(&bevel_object); | BKE_object_free_curve_cache(&bevel_object); | ||||
| BKE_object_free_curve_cache(&taper_object); | BKE_object_free_curve_cache(&taper_object); | ||||
| } | } | ||||
| static Mesh *mesh_new_from_curve_type_object(Object *object) | static Mesh *mesh_new_from_curve_type_object(Object *object) | ||||
| { | { | ||||
| Curve *curve = object->data; | Curve *curve = object->data; | ||||
| Object *temp_object = object_for_curve_to_mesh_create(object); | Object *temp_object = object_for_curve_to_mesh_create(object); | ||||
| ▲ Show 20 Lines • Show All 412 Lines • ▼ Show 20 Lines | |||||
| { | { | ||||
| BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN); | BLI_assert(mesh_src->id.tag & LIB_TAG_NO_MAIN); | ||||
| /* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */ | /* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */ | ||||
| /* TODO(Sybren): the above claim came from 2.7x derived-mesh code (DM_to_mesh); | /* TODO(Sybren): the above claim came from 2.7x derived-mesh code (DM_to_mesh); | ||||
| * check whether it is still true with Mesh */ | * check whether it is still true with Mesh */ | ||||
| Mesh tmp = *mesh_dst; | Mesh tmp = *mesh_dst; | ||||
| int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; | int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly; | ||||
| int did_shapekeys = 0; | bool did_shapekeys = false; | ||||
| eCDAllocType alloctype = CD_DUPLICATE; | eCDAllocType alloctype = CD_DUPLICATE; | ||||
| if (take_ownership /* && dm->type == DM_TYPE_CDDM && dm->needsFree */) { | if (take_ownership /* && dm->type == DM_TYPE_CDDM && dm->needsFree */) { | ||||
| bool has_any_referenced_layers = CustomData_has_referenced(&mesh_src->vdata) || | bool has_any_referenced_layers = CustomData_has_referenced(&mesh_src->vdata) || | ||||
| CustomData_has_referenced(&mesh_src->edata) || | CustomData_has_referenced(&mesh_src->edata) || | ||||
| CustomData_has_referenced(&mesh_src->ldata) || | CustomData_has_referenced(&mesh_src->ldata) || | ||||
| CustomData_has_referenced(&mesh_src->fdata) || | CustomData_has_referenced(&mesh_src->fdata) || | ||||
| CustomData_has_referenced(&mesh_src->pdata); | CustomData_has_referenced(&mesh_src->pdata); | ||||
| Show All 38 Lines | if (ob) { | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| /* if no object, set to INT_MAX so we don't mess up any shapekey layers */ | /* if no object, set to INT_MAX so we don't mess up any shapekey layers */ | ||||
| uid = INT_MAX; | uid = INT_MAX; | ||||
| } | } | ||||
| shapekey_layers_to_keyblocks(mesh_src, mesh_dst, uid); | shapekey_layers_to_keyblocks(mesh_src, mesh_dst, uid); | ||||
| did_shapekeys = 1; | did_shapekeys = true; | ||||
| } | } | ||||
| /* copy texture space */ | /* copy texture space */ | ||||
| if (ob) { | if (ob) { | ||||
| BKE_mesh_texspace_copy_from_object(&tmp, ob); | BKE_mesh_texspace_copy_from_object(&tmp, ob); | ||||
| } | } | ||||
| /* not all DerivedMeshes store their verts/edges/faces in CustomData, so | /* not all DerivedMeshes store their verts/edges/faces in CustomData, so | ||||
| Show All 12 Lines | if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) { | ||||
| CustomData_add_layer(&tmp.edata, | CustomData_add_layer(&tmp.edata, | ||||
| CD_MEDGE, | CD_MEDGE, | ||||
| CD_ASSIGN, | CD_ASSIGN, | ||||
| (alloctype == CD_ASSIGN) ? mesh_src->medge : | (alloctype == CD_ASSIGN) ? mesh_src->medge : | ||||
| MEM_dupallocN(mesh_src->medge), | MEM_dupallocN(mesh_src->medge), | ||||
| totedge); | totedge); | ||||
| } | } | ||||
| if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) { | if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) { | ||||
| /* TODO(Sybren): assignment to tmp.mxxx is probably not necessary due to the | CustomData_add_layer(&tmp.ldata, | ||||
| * BKE_mesh_update_customdata_pointers() call below. */ | CD_MLOOP, | ||||
| tmp.mloop = (alloctype == CD_ASSIGN) ? mesh_src->mloop : MEM_dupallocN(mesh_src->mloop); | CD_ASSIGN, | ||||
| tmp.mpoly = (alloctype == CD_ASSIGN) ? mesh_src->mpoly : MEM_dupallocN(mesh_src->mpoly); | (alloctype == CD_ASSIGN) ? mesh_src->mloop : | ||||
| MEM_dupallocN(mesh_src->mloop), | |||||
| CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop); | tmp.totloop); | ||||
| CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly); | CustomData_add_layer(&tmp.pdata, | ||||
| CD_MPOLY, | |||||
| CD_ASSIGN, | |||||
| (alloctype == CD_ASSIGN) ? mesh_src->mpoly : | |||||
| MEM_dupallocN(mesh_src->mpoly), | |||||
| tmp.totpoly); | |||||
| } | } | ||||
| /* object had got displacement layer, should copy this layer to save sculpted data */ | /* object had got displacement layer, should copy this layer to save sculpted data */ | ||||
| /* NOTE: maybe some other layers should be copied? nazgul */ | /* NOTE: maybe some other layers should be copied? nazgul */ | ||||
| if (CustomData_has_layer(&mesh_dst->ldata, CD_MDISPS)) { | if (CustomData_has_layer(&mesh_dst->ldata, CD_MDISPS)) { | ||||
| if (totloop == mesh_dst->totloop) { | if (totloop == mesh_dst->totloop) { | ||||
| MDisps *mdisps = CustomData_get_layer(&mesh_dst->ldata, CD_MDISPS); | MDisps *mdisps = CustomData_get_layer(&mesh_dst->ldata, CD_MDISPS); | ||||
| CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop); | CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop); | ||||
| if (alloctype == CD_ASSIGN) { | |||||
| /* Assign NULL to prevent double-free. */ | |||||
| CustomData_set_layer(&mesh_dst->ldata, CD_MDISPS, NULL); | |||||
| } | |||||
| } | } | ||||
| } | } | ||||
| /* yes, must be before _and_ after tessellate */ | /* yes, must be before _and_ after tessellate */ | ||||
| BKE_mesh_update_customdata_pointers(&tmp, false); | BKE_mesh_update_customdata_pointers(&tmp, false); | ||||
| /* since 2.65 caller must do! */ | |||||
| // BKE_mesh_tessface_calc(&tmp); | |||||
| CustomData_free(&mesh_dst->vdata, mesh_dst->totvert); | CustomData_free(&mesh_dst->vdata, mesh_dst->totvert); | ||||
| CustomData_free(&mesh_dst->edata, mesh_dst->totedge); | CustomData_free(&mesh_dst->edata, mesh_dst->totedge); | ||||
| CustomData_free(&mesh_dst->fdata, mesh_dst->totface); | CustomData_free(&mesh_dst->fdata, mesh_dst->totface); | ||||
| CustomData_free(&mesh_dst->ldata, mesh_dst->totloop); | CustomData_free(&mesh_dst->ldata, mesh_dst->totloop); | ||||
| CustomData_free(&mesh_dst->pdata, mesh_dst->totpoly); | CustomData_free(&mesh_dst->pdata, mesh_dst->totpoly); | ||||
| /* ok, this should now use new CD shapekey data, | /* ok, this should now use new CD shapekey data, | ||||
| * which should be fed through the modifier | * which should be fed through the modifier | ||||
| ▲ Show 20 Lines • Show All 58 Lines • Show Last 20 Lines | |||||