static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *nurb, ListBase *dispbase, DerivedMesh **r_dm_final, const bool for_render, const bool use_render_resolution) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); ModifierData *pretessellatePoint; Curve *cu = ob->data; int required_mode = 0, totvert = 0; const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); DerivedMesh *dm = NULL, *ndm; float (*vertCos)[3] = NULL; int useCache = !for_render; ModifierApplyFlag app_flag = 0; if (use_render_resolution) { app_flag |= MOD_APPLY_RENDER; required_mode = eModifierMode_Render; } else required_mode = eModifierMode_Realtime; pretessellatePoint = curve_get_tessellate_point(scene, ob, use_render_resolution, editmode); if (editmode) required_mode |= eModifierMode_Editmode; if (pretessellatePoint) { md = pretessellatePoint->next; } if (r_dm_final && *r_dm_final) { (*r_dm_final)->release(*r_dm_final); } for (; md; md = md->next) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); ModifierApplyFlag appf = app_flag; md->scene = scene; if (!modifier_isEnabled(scene, md, required_mode)) continue; if (mti->type == eModifierTypeType_OnlyDeform || (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) { if (editmode) appf |= MOD_APPLY_USECACHE; if (dm) { if (!vertCos) { totvert = dm->getNumVerts(dm); vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv"); dm->getVertCos(dm, vertCos); } mti->deformVerts(md, ob, dm, vertCos, totvert, appf); } else { if (!vertCos) { vertCos = displist_get_allverts(dispbase, &totvert); } mti->deformVerts(md, ob, NULL, vertCos, totvert, appf); } } else { if (!r_dm_final) { /* makeDisplistCurveTypes could be used for beveling, where derived mesh * is totally unnecessary, so we could stop modifiers applying * when we found constructive modifier but derived mesh is unwanted result */ break; } if (dm) { if (vertCos) { DerivedMesh *tdm = CDDM_copy(dm); dm->release(dm); dm = tdm; CDDM_apply_vert_coords(dm, vertCos); } } else { if (vertCos) { displist_apply_allverts(dispbase, vertCos); } if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) { curve_to_filledpoly(cu, nurb, dispbase); } dm = CDDM_from_curve_displist(ob, dispbase); } if (vertCos) { /* Vertex coordinates were applied to necessary data, could free it */ MEM_freeN(vertCos); vertCos = NULL; } if (useCache) appf |= MOD_APPLY_USECACHE; ndm = modwrap_applyModifier(md, ob, dm, appf); if (ndm) { /* Modifier returned a new derived mesh */ if (dm && dm != ndm) /* Modifier */ dm->release(dm); dm = ndm; } } } if (vertCos) { if (dm) { DerivedMesh *tdm = CDDM_copy(dm); dm->release(dm); dm = tdm; CDDM_apply_vert_coords(dm, vertCos); CDDM_calc_normals_mapping(dm); MEM_freeN(vertCos); } else { displist_apply_allverts(dispbase, vertCos); MEM_freeN(vertCos); vertCos = NULL; } } if (r_dm_final) { if (dm) { /* see: mesh_calc_modifiers */ if (dm->getNumTessFaces(dm) == 0) { dm->recalcTessellation(dm); } /* Even if tessellation is not needed, some modifiers might have modified CD layers * (like mloopcol or mloopuv), hence we have to update those. */ else if (dm->dirty & DM_DIRTY_TESS_CDLAYERS) { DM_update_tessface_data(dm); } if (dm->type == DM_TYPE_CDDM) { CDDM_calc_normals_mapping_ex(dm, (dm->dirty & DM_DIRTY_NORMALS) ? false : true); } } (*r_dm_final) = dm; } }
static void curve_calc_modifiers_post(Scene *scene, Object *ob, ListBase *dispbase, DerivedMesh **derivedFinal, int forRender, float (*originalVerts)[3], float (*deformedVerts)[3]) { ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *preTesselatePoint; Curve *cu= ob->data; ListBase *nurb= BKE_curve_nurbs(cu); int required_mode = 0, totvert = 0; int editmode = (!forRender && cu->editnurb); DerivedMesh *dm= NULL, *ndm; float (*vertCos)[3] = NULL; if(forRender) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; preTesselatePoint = curve_get_tesselate_point(scene, ob, forRender, editmode); if(editmode) required_mode |= eModifierMode_Editmode; if (preTesselatePoint) { md = preTesselatePoint->next; } if (derivedFinal && *derivedFinal) { (*derivedFinal)->release (*derivedFinal); } for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene= scene; if ((md->mode & required_mode) != required_mode) continue; if (mti->isDisabled && mti->isDisabled(md, forRender)) continue; if (mti->type == eModifierTypeType_OnlyDeform || (mti->type == eModifierTypeType_DeformOrConstruct && !dm)) { if (dm) { if (!vertCos) { totvert = dm->getNumVerts(dm); vertCos = MEM_mallocN(sizeof(*vertCos) * totvert, "dfmv"); dm->getVertCos(dm, vertCos); } mti->deformVerts(md, ob, dm, vertCos, totvert, forRender, editmode); } else { if (!vertCos) { vertCos= displist_get_allverts(dispbase, &totvert); } mti->deformVerts(md, ob, NULL, vertCos, totvert, forRender, editmode); } } else { if (!derivedFinal) { /* makeDisplistCurveTypes could be used for beveling, where derived mesh */ /* is totally unnecessary, so we could stop modifiers applying */ /* when we found constructive modifier but derived mesh is unwanted result */ break; } if (dm) { if (vertCos) { DerivedMesh *tdm = CDDM_copy(dm); dm->release(dm); dm = tdm; CDDM_apply_vert_coords(dm, vertCos); CDDM_calc_normals(dm); } } else { if (vertCos) { displist_apply_allverts(dispbase, vertCos); } if (ELEM(ob->type, OB_CURVE, OB_FONT) && (cu->flag & CU_DEFORM_FILL)) { curve_to_filledpoly(cu, nurb, dispbase); } dm= CDDM_from_curve_customDB(ob, dispbase); CDDM_calc_normals(dm); } if (vertCos) { /* Vertex coordinates were applied to necessary data, could free it */ MEM_freeN(vertCos); vertCos= NULL; } ndm = mti->applyModifier(md, ob, dm, forRender, editmode); if (ndm) { /* Modifier returned a new derived mesh */ if (dm && dm != ndm) /* Modifier */ dm->release (dm); dm = ndm; } } } if (vertCos) { if (dm) { DerivedMesh *tdm = CDDM_copy(dm); dm->release(dm); dm = tdm; CDDM_apply_vert_coords(dm, vertCos); CDDM_calc_normals(dm); MEM_freeN(vertCos); } else { displist_apply_allverts(dispbase, vertCos); MEM_freeN(vertCos); vertCos= NULL; } } if (derivedFinal) { (*derivedFinal) = dm; } if (deformedVerts) { curve_applyVertexCos(ob->data, nurb, originalVerts); MEM_freeN(originalVerts); MEM_freeN(deformedVerts); } }