Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/displist.c
| Show First 20 Lines • Show All 842 Lines • ▼ Show 20 Lines | for (; md; md = md->next) { | ||||
| else if (md->mode & eModifierMode_ApplyOnSpline) { | else if (md->mode & eModifierMode_ApplyOnSpline) { | ||||
| pretessellatePoint = md; | pretessellatePoint = md; | ||||
| } | } | ||||
| } | } | ||||
| return pretessellatePoint; | return pretessellatePoint; | ||||
| } | } | ||||
| static void curve_calc_modifiers_pre( | /* Return true if any modifier was applied. */ | ||||
| static bool curve_calc_modifiers_pre( | |||||
| Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *nurb, const bool for_render) | Depsgraph *depsgraph, Scene *scene, Object *ob, ListBase *nurb, const bool for_render) | ||||
| { | { | ||||
| VirtualModifierData virtualModifierData; | VirtualModifierData virtualModifierData; | ||||
| ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); | ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); | ||||
| ModifierData *pretessellatePoint; | ModifierData *pretessellatePoint; | ||||
| Curve *cu = ob->data; | Curve *cu = ob->data; | ||||
| int numElems = 0, numVerts = 0; | int numElems = 0, numVerts = 0; | ||||
| const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); | const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); | ||||
| ModifierApplyFlag app_flag = 0; | ModifierApplyFlag app_flag = 0; | ||||
| float(*deformedVerts)[3] = NULL; | float(*deformedVerts)[3] = NULL; | ||||
| float *keyVerts = NULL; | float *keyVerts = NULL; | ||||
| int required_mode; | int required_mode; | ||||
| bool modified = false; | |||||
| modifiers_clearErrors(ob); | modifiers_clearErrors(ob); | ||||
| if (editmode) { | if (editmode) { | ||||
| app_flag |= MOD_APPLY_USECACHE; | app_flag |= MOD_APPLY_USECACHE; | ||||
| } | } | ||||
| if (for_render) { | if (for_render) { | ||||
| app_flag |= MOD_APPLY_RENDER; | app_flag |= MOD_APPLY_RENDER; | ||||
| Show All 36 Lines | for (; md; md = md->next) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| if (!deformedVerts) { | if (!deformedVerts) { | ||||
| deformedVerts = BKE_curve_nurbs_vert_coords_alloc(nurb, &numVerts); | deformedVerts = BKE_curve_nurbs_vert_coords_alloc(nurb, &numVerts); | ||||
| } | } | ||||
| mti->deformVerts(md, &mectx, NULL, deformedVerts, numVerts); | mti->deformVerts(md, &mectx, NULL, deformedVerts, numVerts); | ||||
| modified = true; | |||||
| if (md == pretessellatePoint) { | if (md == pretessellatePoint) { | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (deformedVerts) { | if (deformedVerts) { | ||||
| BKE_curve_nurbs_vert_coords_apply(nurb, deformedVerts, false); | BKE_curve_nurbs_vert_coords_apply(nurb, deformedVerts, false); | ||||
| MEM_freeN(deformedVerts); | MEM_freeN(deformedVerts); | ||||
| } | } | ||||
| if (keyVerts) { /* these are not passed through modifier stack */ | if (keyVerts) { /* these are not passed through modifier stack */ | ||||
| BKE_curve_nurbs_key_vert_tilts_apply(nurb, keyVerts); | BKE_curve_nurbs_key_vert_tilts_apply(nurb, keyVerts); | ||||
| } | } | ||||
| if (keyVerts) { | if (keyVerts) { | ||||
| MEM_freeN(keyVerts); | MEM_freeN(keyVerts); | ||||
| } | } | ||||
| return modified; | |||||
| } | } | ||||
| static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3] | static float (*displist_vert_coords_alloc(ListBase *dispbase, int *r_vert_len))[3] | ||||
| { | { | ||||
| DispList *dl; | DispList *dl; | ||||
| float(*allverts)[3], *fp; | float(*allverts)[3], *fp; | ||||
| *r_vert_len = 0; | *r_vert_len = 0; | ||||
| Show All 27 Lines | |||||
| } | } | ||||
| static void curve_calc_modifiers_post(Depsgraph *depsgraph, | static void curve_calc_modifiers_post(Depsgraph *depsgraph, | ||||
| Scene *scene, | Scene *scene, | ||||
| Object *ob, | Object *ob, | ||||
| ListBase *nurb, | ListBase *nurb, | ||||
| ListBase *dispbase, | ListBase *dispbase, | ||||
| Mesh **r_final, | Mesh **r_final, | ||||
| const bool for_render) | const bool for_render, | ||||
| const bool force_mesh_conversion) | |||||
| { | { | ||||
| VirtualModifierData virtualModifierData; | VirtualModifierData virtualModifierData; | ||||
| ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); | ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); | ||||
| ModifierData *pretessellatePoint; | ModifierData *pretessellatePoint; | ||||
| Curve *cu = ob->data; | Curve *cu = ob->data; | ||||
| int required_mode = 0, totvert = 0; | int required_mode = 0, totvert = 0; | ||||
| const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); | const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); | ||||
| Mesh *modified = NULL, *mesh_applied; | Mesh *modified = NULL, *mesh_applied; | ||||
| ▲ Show 20 Lines • Show All 137 Lines • ▼ Show 20 Lines | if (vertCos) { | ||||
| else { | else { | ||||
| displist_vert_coords_apply(dispbase, vertCos); | displist_vert_coords_apply(dispbase, vertCos); | ||||
| MEM_freeN(vertCos); | MEM_freeN(vertCos); | ||||
| vertCos = NULL; | vertCos = NULL; | ||||
| } | } | ||||
| } | } | ||||
| if (r_final) { | if (r_final) { | ||||
| if (force_mesh_conversion && !modified) { | |||||
| /* XXX 2.8 : This is a workaround for by some deeper technical depts: | |||||
| * - DRW Batch cache is stored inside the ob->data. | |||||
| * - Curve data is not COWed for instances that use different modifiers. | |||||
sergey: The comment is not complete, and task reference does not give any clear technical insight. | |||||
| * This can causes the modifiers to be applied on all user of the same datablock (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 modifer stack | |||||
| * just like what the mesh modifier does. | |||||
| * */ | |||||
| modified = BKE_mesh_new_nomain_from_curve_displist(ob, dispbase); | |||||
| } | |||||
| if (modified) { | if (modified) { | ||||
| /* XXX2.8(Sybren): make sure the face normals are recalculated as well */ | /* XXX2.8(Sybren): make sure the face normals are recalculated as well */ | ||||
| BKE_mesh_ensure_normals(modified); | BKE_mesh_ensure_normals(modified); | ||||
| /* Special tweaks, needed since neither BKE_mesh_new_nomain_from_template() nor | /* Special tweaks, needed since neither BKE_mesh_new_nomain_from_template() nor | ||||
| * BKE_mesh_new_nomain_from_curve_displist() properly duplicate mat info... | * BKE_mesh_new_nomain_from_curve_displist() properly duplicate mat info... | ||||
| */ | */ | ||||
| ▲ Show 20 Lines • Show All 58 Lines • ▼ Show 20 Lines | void BKE_displist_make_surf(Depsgraph *depsgraph, | ||||
| const bool for_orco) | const bool for_orco) | ||||
| { | { | ||||
| ListBase nubase = {NULL, NULL}; | ListBase nubase = {NULL, NULL}; | ||||
| Nurb *nu; | Nurb *nu; | ||||
| Curve *cu = ob->data; | Curve *cu = ob->data; | ||||
| DispList *dl; | DispList *dl; | ||||
| float *data; | float *data; | ||||
| int len; | int len; | ||||
| bool force_mesh_conversion = false; | |||||
| if (!for_render && cu->editnurb) { | if (!for_render && cu->editnurb) { | ||||
| BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(cu)); | BKE_nurbList_duplicate(&nubase, BKE_curve_editNurbs_get(cu)); | ||||
| } | } | ||||
| else { | else { | ||||
| BKE_nurbList_duplicate(&nubase, &cu->nurb); | BKE_nurbList_duplicate(&nubase, &cu->nurb); | ||||
| } | } | ||||
| if (!for_orco) { | if (!for_orco) { | ||||
| curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); | force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); | ||||
| } | } | ||||
| for (nu = nubase.first; nu; nu = nu->next) { | for (nu = nubase.first; nu; nu = nu->next) { | ||||
| if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) { | if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) { | ||||
| int resolu = nu->resolu, resolv = nu->resolv; | int resolu = nu->resolu, resolv = nu->resolv; | ||||
| if (for_render) { | if (for_render) { | ||||
| if (cu->resolu_ren) { | if (cu->resolu_ren) { | ||||
| ▲ Show 20 Lines • Show All 61 Lines • ▼ Show 20 Lines | if ((for_render || nu->hide == 0) && BKE_nurb_check_valid_uv(nu)) { | ||||
| /* gl array drawing: using indices */ | /* gl array drawing: using indices */ | ||||
| displist_surf_indices(dl); | displist_surf_indices(dl); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| if (!for_orco) { | if (!for_orco) { | ||||
| BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); | BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); | ||||
| curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render); | curve_calc_modifiers_post( | ||||
| depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, force_mesh_conversion); | |||||
| } | } | ||||
| BKE_nurbList_free(&nubase); | BKE_nurbList_free(&nubase); | ||||
| } | } | ||||
| static void rotateBevelPiece(Curve *cu, | static void rotateBevelPiece(Curve *cu, | ||||
| BevPoint *bevp, | BevPoint *bevp, | ||||
| BevPoint *nbevp, | BevPoint *nbevp, | ||||
| ▲ Show 20 Lines • Show All 231 Lines • ▼ Show 20 Lines | static void do_makeDispListCurveTypes(Depsgraph *depsgraph, | ||||
| } | } | ||||
| if (ob->type == OB_SURF) { | if (ob->type == OB_SURF) { | ||||
| BKE_displist_make_surf(depsgraph, scene, ob, dispbase, r_final, for_render, for_orco); | BKE_displist_make_surf(depsgraph, scene, ob, dispbase, r_final, for_render, for_orco); | ||||
| } | } | ||||
| else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { | else if (ELEM(ob->type, OB_CURVE, OB_FONT)) { | ||||
| ListBase dlbev; | ListBase dlbev; | ||||
| ListBase nubase = {NULL, NULL}; | ListBase nubase = {NULL, NULL}; | ||||
| bool force_mesh_conversion = false; | |||||
| BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); | BKE_curve_bevelList_free(&ob->runtime.curve_cache->bev); | ||||
| /* We only re-evaluate path if evaluation is not happening for orco. | /* We only re-evaluate path if evaluation is not happening for orco. | ||||
| * If the calculation happens for orco, we should never free data which | * If the calculation happens for orco, we should never free data which | ||||
| * was needed before and only not needed for orco calculation. | * was needed before and only not needed for orco calculation. | ||||
| */ | */ | ||||
| if (!for_orco) { | if (!for_orco) { | ||||
| if (ob->runtime.curve_cache->path) { | if (ob->runtime.curve_cache->path) { | ||||
| free_path(ob->runtime.curve_cache->path); | free_path(ob->runtime.curve_cache->path); | ||||
| } | } | ||||
| ob->runtime.curve_cache->path = NULL; | ob->runtime.curve_cache->path = NULL; | ||||
| } | } | ||||
| if (ob->type == OB_FONT) { | if (ob->type == OB_FONT) { | ||||
| BKE_vfont_to_curve_nubase(ob, FO_EDIT, &nubase); | BKE_vfont_to_curve_nubase(ob, FO_EDIT, &nubase); | ||||
| } | } | ||||
| else { | else { | ||||
| BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(cu)); | BKE_nurbList_duplicate(&nubase, BKE_curve_nurbs_get(cu)); | ||||
| } | } | ||||
| if (!for_orco) { | if (!for_orco) { | ||||
| curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); | force_mesh_conversion = curve_calc_modifiers_pre(depsgraph, scene, ob, &nubase, for_render); | ||||
| } | } | ||||
| BKE_curve_bevelList_make(ob, &nubase, for_render); | BKE_curve_bevelList_make(ob, &nubase, for_render); | ||||
| /* If curve has no bevel will return nothing */ | /* If curve has no bevel will return nothing */ | ||||
| BKE_curve_bevel_make(ob, &dlbev); | BKE_curve_bevel_make(ob, &dlbev); | ||||
| /* no bevel or extrude, and no width correction? */ | /* no bevel or extrude, and no width correction? */ | ||||
| ▲ Show 20 Lines • Show All 193 Lines • ▼ Show 20 Lines | if (!for_orco) { | ||||
| if ((cu->flag & CU_PATH) || | if ((cu->flag & CU_PATH) || | ||||
| DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CURVE_PATH) { | DEG_get_eval_flags_for_id(depsgraph, &ob->id) & DAG_EVAL_NEED_CURVE_PATH) { | ||||
| calc_curvepath(ob, &nubase); | calc_curvepath(ob, &nubase); | ||||
| } | } | ||||
| } | } | ||||
| if (!for_orco) { | if (!for_orco) { | ||||
| BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); | BKE_nurbList_duplicate(&ob->runtime.curve_cache->deformed_nurbs, &nubase); | ||||
| curve_calc_modifiers_post(depsgraph, scene, ob, &nubase, dispbase, r_final, for_render); | curve_calc_modifiers_post( | ||||
| depsgraph, scene, ob, &nubase, dispbase, r_final, for_render, force_mesh_conversion); | |||||
| } | } | ||||
| if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) { | if (cu->flag & CU_DEFORM_FILL && !ob->runtime.data_eval) { | ||||
| curve_to_filledpoly(cu, &nubase, dispbase); | curve_to_filledpoly(cu, &nubase, dispbase); | ||||
| } | } | ||||
| BKE_nurbList_free(&nubase); | BKE_nurbList_free(&nubase); | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 97 Lines • Show Last 20 Lines | |||||
The comment is not complete, and task reference does not give any clear technical insight.
Comment should state:
Comment should also state that modified Curve is to be decoupled from the input of the modifier stack similar to how it's done for meshes.