static ModifierData *curve_get_tesselate_point(Scene *scene, Object *ob, int forRender, int editmode) { ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *preTesselatePoint; int required_mode; if(forRender) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; if(editmode) required_mode |= eModifierMode_Editmode; preTesselatePoint = NULL; for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (!modifier_isEnabled(scene, md, required_mode)) continue; if (mti->type == eModifierTypeType_Constructive) return preTesselatePoint; if (ELEM3(md->type, eModifierType_Hook, eModifierType_Softbody, eModifierType_MeshDeform)) { preTesselatePoint = md; /* this modifiers are moving point of tesselation automatically (some of them even can't be applied on tesselated curve), set flag for incformation button in modifier's header */ md->mode |= eModifierMode_ApplyOnSpline; } else if(md->mode&eModifierMode_ApplyOnSpline) { preTesselatePoint = md; } } return preTesselatePoint; }
/* used for buttons, to find out if the 'draw deformed in editmode' option is * there * * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg * then is NULL) * also used for some mesh tools to give warnings */ int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *lastPossibleCageIndex_r, int virtual_) { ModifierData *md = (virtual_)? modifiers_getVirtualModifierList(ob): ob->modifiers.first; int i, cageIndex = -1; if(lastPossibleCageIndex_r) { /* ensure the value is initialized */ *lastPossibleCageIndex_r= -1; } /* Find the last modifier acting on the cage. */ for (i=0; md; i++,md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene= scene; if (!(md->mode & eModifierMode_Realtime)) continue; if (!(md->mode & eModifierMode_Editmode)) continue; if (mti->isDisabled && mti->isDisabled(md, 0)) continue; if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue; if (md->mode & eModifierMode_DisableTemporary) continue; if (!modifier_supportsMapping(md)) break; if (lastPossibleCageIndex_r) *lastPossibleCageIndex_r = i; if (md->mode & eModifierMode_OnCage) cageIndex = i; } return cageIndex; }
bool *BKE_objdef_validmap_get(Object *ob, const int defbase_tot) { bDeformGroup *dg; ModifierData *md; bool *vgroup_validmap; GHash *gh; int i, step1 = 1; //int defbase_tot = BLI_countlist(&ob->defbase); if (ob->defbase.first == NULL) { return NULL; } gh = BLI_ghash_str_new("BKE_objdef_validmap_get gh"); /* add all names to a hash table */ for (dg = ob->defbase.first; dg; dg = dg->next) { BLI_ghash_insert(gh, dg->name, NULL); } BLI_assert(BLI_ghash_size(gh) == defbase_tot); /* now loop through the armature modifiers and identify deform bones */ for (md = ob->modifiers.first; md; md = !md->next && step1 ? (step1 = 0), modifiers_getVirtualModifierList(ob) : md->next) { if (!(md->mode & (eModifierMode_Realtime | eModifierMode_Virtual))) continue; if (md->type == eModifierType_Armature) { ArmatureModifierData *amd = (ArmatureModifierData *) md; if (amd->object && amd->object->pose) { bPose *pose = amd->object->pose; bPoseChannel *chan; for (chan = pose->chanbase.first; chan; chan = chan->next) { if (chan->bone->flag & BONE_NO_DEFORM) continue; if (BLI_ghash_remove(gh, chan->name, NULL, NULL)) { BLI_ghash_insert(gh, chan->name, SET_INT_IN_POINTER(1)); } } } } } vgroup_validmap = MEM_mallocN(sizeof(*vgroup_validmap) * defbase_tot, "wpaint valid map"); /* add all names to a hash table */ for (dg = ob->defbase.first, i = 0; dg; dg = dg->next, i++) { vgroup_validmap[i] = (BLI_ghash_lookup(gh, dg->name) != NULL); } BLI_assert(i == BLI_ghash_size(gh)); BLI_ghash_free(gh, NULL, NULL); return vgroup_validmap; }
void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) { int totleft= sculpt_get_first_deform_matrices(scene, ob, deformmats, deformcos); if(totleft) { /* there are deformation modifier which doesn't support deformation matricies calculation. Need additional crazyspace correction */ float (*deformedVerts)[3]= *deformcos; float (*origVerts)[3]= MEM_dupallocN(deformedVerts); float *quats= NULL; int i, deformed= 0; ModifierData *md= modifiers_getVirtualModifierList(ob); Mesh *me= (Mesh*)ob->data; for(; md; md= md->next) { ModifierTypeInfo *mti= modifierType_getInfo(md->type); if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; if(mti->type==eModifierTypeType_OnlyDeform) { /* skip leading modifiers which have been already handled in sculpt_get_first_deform_matrices */ if(mti->deformMatrices && !deformed) continue; mti->deformVerts(md, ob, NULL, deformedVerts, me->totvert, 0, 0); deformed= 1; } } quats= MEM_mallocN(me->totvert*sizeof(float)*4, "crazy quats"); crazyspace_set_quats_mesh(me, (float*)origVerts, (float*)deformedVerts, quats); for(i=0; i<me->totvert; i++) { float qmat[3][3], tmat[3][3]; quat_to_mat3(qmat, &quats[i*4]); mul_m3_m3m3(tmat, qmat, (*deformmats)[i]); copy_m3_m3((*deformmats)[i], tmat); } MEM_freeN(origVerts); MEM_freeN(quats); } if(!*deformmats) { int a, numVerts; Mesh *me= (Mesh*)ob->data; *deformcos= mesh_getVertexCos(me, &numVerts); *deformmats= MEM_callocN(sizeof(*(*deformmats))*numVerts, "defmats"); for(a=0; a<numVerts; a++) unit_m3((*deformmats)[a]); } }
int sculpt_get_first_deform_matrices(Scene *scene, Object *ob, float (**deformmats)[3][3], float (**deformcos)[3]) { ModifierData *md; DerivedMesh *dm; int a, numVerts= 0; float (*defmats)[3][3]= NULL, (*deformedVerts)[3]= NULL; MultiresModifierData *mmd= get_multires_modifier(scene, ob, 0); int has_multires = mmd != NULL && mmd->sculptlvl > 0; int numleft= 0; if(has_multires) { *deformmats= NULL; *deformcos= NULL; return numleft; } dm= NULL; md= modifiers_getVirtualModifierList(ob); for(; md; md= md->next) { ModifierTypeInfo *mti= modifierType_getInfo(md->type); if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; if(mti->type==eModifierTypeType_OnlyDeform) { if(!defmats) { Mesh *me= (Mesh*)ob->data; dm= mesh_create_derived(me, ob, NULL); deformedVerts= mesh_getVertexCos(me, &numVerts); defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats"); for(a=0; a<numVerts; a++) unit_m3(defmats[a]); } if(mti->deformMatrices) mti->deformMatrices(md, ob, dm, deformedVerts, defmats, numVerts); else break; } } for(; md; md= md->next) { ModifierTypeInfo *mti= modifierType_getInfo(md->type); if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; if(mti->type==eModifierTypeType_OnlyDeform) numleft++; } if(dm) dm->release(dm); *deformmats= defmats; *deformcos= deformedVerts; return numleft; }
int modifiers_isCorrectableDeformed(Object *ob) { ModifierData *md = modifiers_getVirtualModifierList(ob); for (; md; md = md->next) { if (ob->mode == OB_MODE_EDIT && (md->mode & eModifierMode_Editmode) == 0) ; else if (modifier_isCorrectableDeformed(md)) return 1; } return 0; }
static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *derivedFinal, int forRender) { /* this function represents logic of mesh's orcodm calculation */ /* for displist-based objects */ ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *preTesselatePoint; Curve *cu= ob->data; int required_mode; int editmode = (!forRender && cu->editnurb); DerivedMesh *ndm, *orcodm= 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; } 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_Constructive) continue; if(!orcodm) orcodm= create_orco_dm(scene, ob); ndm = mti->applyModifier(md, ob, orcodm, forRender, 0); if(ndm) { /* if the modifier returned a new dm, release the old one */ if(orcodm && orcodm != ndm) { orcodm->release(orcodm); } orcodm = ndm; } } /* add an orco layer if needed */ add_orco_dm(scene, ob, derivedFinal, orcodm); if(orcodm) orcodm->release(orcodm); }
int editmesh_get_first_deform_matrices(Scene *scene, Object *ob, EditMesh *em, float (**deformmats)[3][3], float (**deformcos)[3]) { ModifierData *md; DerivedMesh *dm; int i, a, numleft = 0, numVerts = 0; int cageIndex = modifiers_getCageIndex(scene, ob, NULL, 1); float (*defmats)[3][3] = NULL, (*deformedVerts)[3] = NULL; modifiers_clearErrors(ob); dm = NULL; md = modifiers_getVirtualModifierList(ob); /* compute the deformation matrices and coordinates for the first modifiers with on cage editing that are enabled and support computing deform matrices */ for(i = 0; md && i <= cageIndex; i++, md = md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if(!editmesh_modifier_is_enabled(scene, md, dm)) continue; if(mti->type==eModifierTypeType_OnlyDeform && mti->deformMatricesEM) { if(!defmats) { dm= editmesh_get_derived(em, NULL); deformedVerts= editmesh_get_vertex_cos(em, &numVerts); defmats= MEM_callocN(sizeof(*defmats)*numVerts, "defmats"); for(a=0; a<numVerts; a++) unit_m3(defmats[a]); } mti->deformMatricesEM(md, ob, em, dm, deformedVerts, defmats, numVerts); } else break; } for(; md && i <= cageIndex; md = md->next, i++) if(editmesh_modifier_is_enabled(scene, md, dm) && modifier_isCorrectableDeformed(md)) numleft++; if(dm) dm->release(dm); *deformmats= defmats; *deformcos= deformedVerts; return numleft; }
int modifiers_usesArmature(Object *ob, bArmature *arm) { ModifierData *md = modifiers_getVirtualModifierList(ob); for (; md; md=md->next) { if (md->type==eModifierType_Armature) { ArmatureModifierData *amd = (ArmatureModifierData*) md; if (amd->object && amd->object->data==arm) return 1; } } return 0; }
bool modifiers_usesArmature(Object *ob, bArmature *arm) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); for (; md; md = md->next) { if (md->type == eModifierType_Armature) { ArmatureModifierData *amd = (ArmatureModifierData *) md; if (amd->object && amd->object->data == arm) return true; } } return false; }
/* Takes an object and returns its first selected lattice, else just its * lattice * This should work for multiple lattics per object */ Object *modifiers_isDeformedByLattice(Object *ob) { ModifierData *md = modifiers_getVirtualModifierList(ob); LatticeModifierData *lmd = NULL; /* return the first selected lattice, this lets us use multiple lattices */ for (; md; md = md->next) { if (md->type == eModifierType_Lattice) { lmd = (LatticeModifierData *) md; if (lmd->object && (lmd->object->flag & SELECT)) return lmd->object; } } if (lmd) /* if were still here then return the last lattice */ return lmd->object; return NULL; }
/* Takes an object and returns its first selected armature, else just its * armature * This should work for multiple armatures per object */ Object *modifiers_isDeformedByArmature(Object *ob) { ModifierData *md = modifiers_getVirtualModifierList(ob); ArmatureModifierData *amd = NULL; /* return the first selected armature, this lets us use multiple armatures */ for (; md; md = md->next) { if (md->type == eModifierType_Armature) { amd = (ArmatureModifierData *) md; if (amd->object && (amd->object->flag & SELECT)) return amd->object; } } if (amd) /* if were still here then return the last armature */ return amd->object; return NULL; }
bool modifiers_isCorrectableDeformed(struct Scene *scene, Object *ob) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); int required_mode = eModifierMode_Realtime; if (ob->mode == OB_MODE_EDIT) required_mode |= eModifierMode_Editmode; for (; md; md = md->next) { if (!modifier_isEnabled(scene, md, required_mode)) { /* pass */ } else if (modifier_isCorrectableDeformed(md)) { return true; } } return false; }
void BKE_lattice_modifiers_calc(Scene *scene, Object *ob) { Lattice *lt = ob->data; VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); float (*vertexCos)[3] = NULL; int numVerts, editmode = (lt->editlatt != NULL); if (ob->curve_cache) { BKE_displist_free(&ob->curve_cache->disp); } else { ob->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for lattice"); } for (; md; md = md->next) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene = scene; if (!(md->mode & eModifierMode_Realtime)) continue; if (editmode && !(md->mode & eModifierMode_Editmode)) continue; if (mti->isDisabled && mti->isDisabled(md, 0)) continue; if (mti->type != eModifierTypeType_OnlyDeform) continue; if (!vertexCos) vertexCos = BKE_lattice_vertexcos_get(ob, &numVerts); mti->deformVerts(md, ob, NULL, vertexCos, numVerts, 0); } /* always displist to make this work like derivedmesh */ if (!vertexCos) vertexCos = BKE_lattice_vertexcos_get(ob, &numVerts); { DispList *dl = MEM_callocN(sizeof(*dl), "lt_dl"); dl->type = DL_VERTS; dl->parts = 1; dl->nr = numVerts; dl->verts = (float *) vertexCos; BLI_addtail(&ob->curve_cache->disp, dl); } }
/* Takes an object and returns its first selected curve, else just its curve * This should work for multiple curves per object */ Object *modifiers_isDeformedByCurve(Object *ob) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); CurveModifierData *cmd = NULL; /* return the first selected curve, this lets us use multiple curves */ for (; md; md = md->next) { if (md->type == eModifierType_Curve) { cmd = (CurveModifierData *) md; if (cmd->object && (cmd->object->flag & SELECT)) return cmd->object; } } if (cmd) /* if were still here then return the last curve */ return cmd->object; return NULL; }
/* used for buttons, to find out if the 'draw deformed in editmode' option is * there * * also used in transform_conversion.c, to detect CrazySpace [tm] (2nd arg * then is NULL) * also used for some mesh tools to give warnings */ int modifiers_getCageIndex(struct Scene *scene, Object *ob, int *r_lastPossibleCageIndex, bool is_virtual) { VirtualModifierData virtualModifierData; ModifierData *md = (is_virtual) ? modifiers_getVirtualModifierList(ob, &virtualModifierData) : ob->modifiers.first; int i, cageIndex = -1; if (r_lastPossibleCageIndex) { /* ensure the value is initialized */ *r_lastPossibleCageIndex = -1; } /* Find the last modifier acting on the cage. */ for (i = 0; md; i++, md = md->next) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); bool supports_mapping; md->scene = scene; if (mti->isDisabled && mti->isDisabled(md, 0)) continue; if (!(mti->flags & eModifierTypeFlag_SupportsEditmode)) continue; if (md->mode & eModifierMode_DisableTemporary) continue; supports_mapping = modifier_supportsMapping(md); if (r_lastPossibleCageIndex && supports_mapping) { *r_lastPossibleCageIndex = i; } if (!(md->mode & eModifierMode_Realtime)) continue; if (!(md->mode & eModifierMode_Editmode)) continue; if (!supports_mapping) break; if (md->mode & eModifierMode_OnCage) cageIndex = i; } return cageIndex; }
static void curve_calc_orcodm(Scene *scene, Object *ob, DerivedMesh *dm_final, const bool for_render, const bool use_render_resolution) { /* this function represents logic of mesh's orcodm calculation * for displist-based objects */ VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); ModifierData *pretessellatePoint; Curve *cu = ob->data; int required_mode; const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); DerivedMesh *ndm, *orcodm = NULL; ModifierApplyFlag app_flag = MOD_APPLY_ORCO; 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 modifiers are disabled, we wouldn't be here because * this function is only called if there're enabled constructive * modifiers applied on the curve. * * This means we can create ORCO DM in advance and assume it's * never NULL. */ orcodm = create_orco_dm(scene, ob); for (; md; md = md->next) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene = scene; if (!modifier_isEnabled(scene, md, required_mode)) continue; if (mti->type != eModifierTypeType_Constructive) continue; ndm = modwrap_applyModifier(md, ob, orcodm, app_flag); if (ndm) { /* if the modifier returned a new dm, release the old one */ if (orcodm && orcodm != ndm) { orcodm->release(orcodm); } orcodm = ndm; } } /* add an orco layer if needed */ add_orco_dm(ob, dm_final, orcodm); orcodm->release(orcodm); }
static void curve_calc_modifiers_pre(Scene *scene, Object *ob, int forRender, float (**originalVerts_r)[3], float (**deformedVerts_r)[3], int *numVerts_r) { ModifierData *md = modifiers_getVirtualModifierList(ob); ModifierData *preTesselatePoint; Curve *cu= ob->data; ListBase *nurb= BKE_curve_nurbs(cu); int numVerts = 0; int editmode = (!forRender && cu->editnurb); float (*originalVerts)[3] = NULL; float (*deformedVerts)[3] = NULL; float *keyVerts= NULL; int required_mode; 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(cu->editnurb==NULL) { keyVerts= do_ob_key(scene, ob); if(keyVerts) { /* split coords from key data, the latter also includes tilts, which is passed through in the modifier stack. this is also the reason curves do not use a virtual shape key modifier yet. */ deformedVerts= curve_getKeyVertexCos(cu, nurb, keyVerts); originalVerts= MEM_dupallocN(deformedVerts); } } if (preTesselatePoint) { 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) continue; if (!deformedVerts) { deformedVerts = curve_getVertexCos(cu, nurb, &numVerts); originalVerts = MEM_dupallocN(deformedVerts); } mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, forRender, editmode); if (md==preTesselatePoint) break; } } if (deformedVerts) curve_applyVertexCos(cu, nurb, deformedVerts); if (keyVerts) /* these are not passed through modifier stack */ curve_applyKeyVertexTilts(cu, nurb, keyVerts); if(keyVerts) MEM_freeN(keyVerts); *originalVerts_r = originalVerts; *deformedVerts_r = deformedVerts; *numVerts_r = numVerts; }
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); } }
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_pre(Scene *scene, Object *ob, ListBase *nurb, const bool for_render, const bool use_render_resolution) { VirtualModifierData virtualModifierData; ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData); ModifierData *pretessellatePoint; Curve *cu = ob->data; int numVerts = 0; const bool editmode = (!for_render && (cu->editnurb || cu->editfont)); ModifierApplyFlag app_flag = 0; float (*deformedVerts)[3] = NULL; float *keyVerts = NULL; int required_mode; modifiers_clearErrors(ob); if (editmode) app_flag |= MOD_APPLY_USECACHE; 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 (!editmode) { keyVerts = BKE_key_evaluate_object(ob, &numVerts); if (keyVerts) { /* split coords from key data, the latter also includes * tilts, which is passed through in the modifier stack. * this is also the reason curves do not use a virtual * shape key modifier yet. */ deformedVerts = BKE_curve_nurbs_keyVertexCos_get(nurb, keyVerts); BLI_assert(BKE_nurbList_verts_count(nurb) == numVerts); } } if (pretessellatePoint) { for (; md; md = md->next) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene = scene; if (!modifier_isEnabled(scene, md, required_mode)) continue; if (mti->type != eModifierTypeType_OnlyDeform) continue; if (!deformedVerts) { deformedVerts = BKE_curve_nurbs_vertexCos_get(nurb, &numVerts); } mti->deformVerts(md, ob, NULL, deformedVerts, numVerts, app_flag); if (md == pretessellatePoint) break; } } if (deformedVerts) { BK_curve_nurbs_vertexCos_apply(nurb, deformedVerts); MEM_freeN(deformedVerts); } if (keyVerts) /* these are not passed through modifier stack */ BKE_curve_nurbs_keyVertexTilts_apply(nurb, keyVerts); if (keyVerts) MEM_freeN(keyVerts); }