/* 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; }
void modifier_free(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (mti->freeData) mti->freeData(md); if (md->error) MEM_freeN(md->error); MEM_freeN(md); }
void modifier_copyData(ModifierData *md, ModifierData *target) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); target->mode = md->mode; if (mti->copyData) mti->copyData(md, target); }
bool modifier_supportsCage(struct Scene *scene, ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene = scene; return ((!mti->isDisabled || !mti->isDisabled(md, 0)) && (mti->flags & eModifierTypeFlag_SupportsEditmode) && modifier_supportsMapping(md)); }
void modifiers_foreachTexLink(Object *ob, TexWalkFunc walk, void *userData) { ModifierData *md = ob->modifiers.first; for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if(mti->foreachTexLink) mti->foreachTexLink(md, ob, walk, userData); } }
int modifier_couldBeCage(struct Scene *scene, ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene= scene; return ( (md->mode & eModifierMode_Realtime) && (md->mode & eModifierMode_Editmode) && (!mti->isDisabled || !mti->isDisabled(md, 0)) && modifier_supportsMapping(md)); }
CDMaskLink *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode, ModifierData *previewmd, CustomDataMask previewmask) { CDMaskLink *dataMasks = NULL; CDMaskLink *curr, *prev; /* build a list of modifier data requirements in reverse order */ for (; md; md = md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); curr = MEM_callocN(sizeof(CDMaskLink), "CDMaskLink"); if (modifier_isEnabled(scene, md, required_mode)) { if (mti->requiredDataMask) curr->mask = mti->requiredDataMask(ob, md); if (previewmd == md) { curr->mask |= previewmask; } } /* prepend new datamask */ curr->next = dataMasks; dataMasks = curr; } /* build the list of required data masks - each mask in the list must * include all elements of the masks that follow it * * note the list is currently in reverse order, so "masks that follow it" * actually means "masks that precede it" at the moment */ for (curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) { if (prev) { CustomDataMask prev_mask = prev->mask; CustomDataMask curr_mask = curr->mask; curr->mask = curr_mask | prev_mask; } else { CustomDataMask curr_mask = curr->mask; curr->mask = curr_mask | dataMask; } } /* reverse the list so it's in the correct order */ BLI_linklist_reverse((LinkNode **)&dataMasks); return dataMasks; }
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); }
struct DerivedMesh *modwrap_applyModifier( ModifierData *md, Object *ob, struct DerivedMesh *dm, ModifierApplyFlag flag) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); BLI_assert(CustomData_has_layer(&dm->polyData, CD_NORMAL) == false); if (mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } return mti->applyModifier(md, ob, dm, flag); }
bool modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); md->scene = scene; if ((md->mode & required_mode) != required_mode) return false; if (mti->isDisabled && mti->isDisabled(md, required_mode == eModifierMode_Render)) return false; if (md->mode & eModifierMode_DisableTemporary) return false; if ((required_mode & eModifierMode_Editmode) && !(mti->flags & eModifierTypeFlag_SupportsEditmode)) return false; return true; }
void modwrap_deformVertsEM( ModifierData *md, Object *ob, struct BMEditMesh *em, DerivedMesh *dm, float (*vertexCos)[3], int numVerts) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); BLI_assert(!dm || CustomData_has_layer(&dm->polyData, CD_NORMAL) == false); if (dm && mti->dependsOnNormals && mti->dependsOnNormals(md)) { DM_ensure_normals(dm); } mti->deformVertsEM(md, ob, em, dm, vertexCos, numVerts); }
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; }
void modifiers_foreachIDLink(Object *ob, IDWalkFunc walk, void *userData) { ModifierData *md = ob->modifiers.first; for (; md; md=md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if(mti->foreachIDLink) mti->foreachIDLink(md, ob, walk, userData); else if(mti->foreachObjectLink) { /* each Object can masquerade as an ID, so this should be OK */ ObjectWalkFunc fp = (ObjectWalkFunc)walk; mti->foreachObjectLink(md, ob, fp, userData); } } }
ModifierData *modifier_new(int type) { ModifierTypeInfo *mti = modifierType_getInfo(type); ModifierData *md = MEM_callocN(mti->structSize, mti->structName); /* note, this name must be made unique later */ BLI_strncpy(md->name, mti->name, sizeof(md->name)); md->type = type; md->mode = eModifierMode_Realtime | eModifierMode_Render | eModifierMode_Expanded; if (mti->flags & eModifierTypeFlag_EnableInEditmode) md->mode |= eModifierMode_Editmode; if (mti->initData) mti->initData(md); return md; }
ModifierData *modifier_new(int type) { ModifierTypeInfo *mti = modifierType_getInfo(type); ModifierData *md = MEM_callocN(mti->structSize, mti->structName); // FIXME: we need to make the name always be unique somehow... strcpy(md->name, mti->name); md->type = type; md->mode = eModifierMode_Realtime | eModifierMode_Render | eModifierMode_Expanded; if (mti->flags & eModifierTypeFlag_EnableInEditmode) md->mode |= eModifierMode_Editmode; if (mti->initData) mti->initData(md); return md; }
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) { 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); } }
LinkNode *modifiers_calcDataMasks(struct Scene *scene, Object *ob, ModifierData *md, CustomDataMask dataMask, int required_mode) { LinkNode *dataMasks = NULL; LinkNode *curr, *prev; /* build a list of modifier data requirements in reverse order */ for(; md; md = md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); CustomDataMask mask = 0; if(modifier_isEnabled(scene, md, required_mode)) if(mti->requiredDataMask) mask = mti->requiredDataMask(ob, md); BLI_linklist_prepend(&dataMasks, SET_INT_IN_POINTER(mask)); } /* build the list of required data masks - each mask in the list must * include all elements of the masks that follow it * * note the list is currently in reverse order, so "masks that follow it" * actually means "masks that precede it" at the moment */ for(curr = dataMasks, prev = NULL; curr; prev = curr, curr = curr->next) { if(prev) { CustomDataMask prev_mask = (CustomDataMask)GET_INT_FROM_POINTER(prev->link); CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link); curr->link = SET_INT_IN_POINTER(curr_mask | prev_mask); } else { CustomDataMask curr_mask = (CustomDataMask)GET_INT_FROM_POINTER(curr->link); curr->link = SET_INT_IN_POINTER(curr_mask | dataMask); } } /* reverse the list so it's in the correct order */ BLI_linklist_reverse(&dataMasks); return dataMasks; }
/* 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) { 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_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); } }
int modifier_dependsOnTime(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); return mti->dependsOnTime && mti->dependsOnTime(md); }