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 modifier_supportsMapping(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); return (mti->type==eModifierTypeType_OnlyDeform || (mti->flags & eModifierTypeFlag_SupportsMapping)); }
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; }
static EnumPropertyItem *modifier_add_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), int *free) { Object *ob= ED_object_active_context(C); EnumPropertyItem *item= NULL, *md_item; ModifierTypeInfo *mti; int totitem= 0, a; if(!ob) return modifier_type_items; for(a=0; modifier_type_items[a].identifier; a++) { md_item= &modifier_type_items[a]; if(md_item->identifier[0]) { mti= modifierType_getInfo(md_item->value); if(mti->flags & eModifierTypeFlag_NoUserAdd) continue; if(!((mti->flags & eModifierTypeFlag_AcceptsCVs) || (ob->type==OB_MESH && (mti->flags & eModifierTypeFlag_AcceptsMesh)))) continue; } RNA_enum_item_add(&item, &totitem, md_item); } RNA_enum_item_end(&item, &totitem); *free= 1; return item; }
void modifier_unique_name(ListBase *modifiers, ModifierData *md) { if (modifiers && md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); BLI_uniquename(modifiers, md, mti->name, '.', offsetof(ModifierData, name), sizeof(md->name)); } }
void multiresModifier_join(Object *ob) { Base *base = NULL; int highest_lvl = 0; /* First find the highest level of subdivision */ base = FIRSTBASE; while(base) { if(TESTBASELIB_BGMODE(v3d, base) && base->object->type==OB_MESH) { ModifierData *md; for(md = base->object->modifiers.first; md; md = md->next) { if(md->type == eModifierType_Multires) { int totlvl = ((MultiresModifierData*)md)->totlvl; if(totlvl > highest_lvl) highest_lvl = totlvl; /* Ensure that all updates are processed */ multires_force_update(base->object); } } } base = base->next; } /* No multires meshes selected */ if(highest_lvl == 0) return; /* Subdivide all the displacements to the highest level */ base = FIRSTBASE; while(base) { if(TESTBASELIB_BGMODE(v3d, base) && base->object->type==OB_MESH) { ModifierData *md = NULL; MultiresModifierData *mmd = NULL; for(md = base->object->modifiers.first; md; md = md->next) { if(md->type == eModifierType_Multires) mmd = (MultiresModifierData*)md; } /* If the object didn't have multires enabled, give it a new modifier */ if(!mmd) { md = base->object->modifiers.first; while(md && modifierType_getInfo(md->type)->type == eModifierTypeType_OnlyDeform) md = md->next; mmd = (MultiresModifierData*)modifier_new(eModifierType_Multires); BLI_insertlinkbefore(&base->object->modifiers, md, mmd); modifier_unique_name(&base->object->modifiers, mmd); } if(mmd) multiresModifier_subdivide(mmd, base->object, highest_lvl - mmd->totlvl, 0, 0); } base = base->next; } }
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]); } }
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); }
bool modifier_unique_name(ListBase *modifiers, ModifierData *md) { if (modifiers && md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); return BLI_uniquename(modifiers, md, DATA_(mti->name), '.', offsetof(ModifierData, name), sizeof(md->name)); } return false; }
void modifier_copyData(ModifierData *md, ModifierData *target) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); target->mode = md->mode; if (mti->copyData) mti->copyData(md, target); }
Mesh *BKE_mesh_create_derived_for_modifier(struct Depsgraph *depsgraph, Scene *scene, Object *ob_eval, ModifierData *md_eval, int build_shapekey_layers) { Mesh *me = ob_eval->runtime.mesh_orig ? ob_eval->runtime.mesh_orig : ob_eval->data; const ModifierTypeInfo *mti = modifierType_getInfo(md_eval->type); Mesh *result; KeyBlock *kb; ModifierEvalContext mectx = {depsgraph, ob_eval, 0}; if (!(md_eval->mode & eModifierMode_Realtime)) { return NULL; } if (mti->isDisabled && mti->isDisabled(scene, md_eval, 0)) { return NULL; } if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob_eval->shapenr - 1))) { BKE_keyblock_convert_to_mesh(kb, me); } if (mti->type == eModifierTypeType_OnlyDeform) { int numVerts; float(*deformedVerts)[3] = BKE_mesh_vertexCos_get(me, &numVerts); BKE_id_copy_ex(NULL, &me->id, (ID **)&result, LIB_ID_COPY_LOCALIZE); mti->deformVerts(md_eval, &mectx, result, deformedVerts, numVerts); BKE_mesh_apply_vert_coords(result, deformedVerts); if (build_shapekey_layers) { add_shapekey_layers(result, me); } MEM_freeN(deformedVerts); } else { Mesh *mesh_temp; BKE_id_copy_ex(NULL, &me->id, (ID **)&mesh_temp, LIB_ID_COPY_LOCALIZE); if (build_shapekey_layers) { add_shapekey_layers(mesh_temp, me); } result = mti->applyModifier(md_eval, &mectx, mesh_temp); ASSERT_IS_VALID_MESH(result); if (mesh_temp != result) { BKE_id_free(NULL, mesh_temp); } } return result; }
/* callback's can use this * to avoid copying every member. */ void modifier_copyData_generic(const ModifierData *md_src, ModifierData *md_dst) { ModifierTypeInfo *mti = modifierType_getInfo(md_src->type); const size_t data_size = sizeof(ModifierData); const char *md_src_data = ((char *)md_src) + data_size; char *md_dst_data = ((char *)md_dst) + data_size; BLI_assert(data_size <= (size_t)mti->structSize); memcpy(md_dst_data, md_src_data, (size_t)mti->structSize - data_size); }
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)); }
int ED_object_modifier_move_up(ReportList *reports, Object *ob, ModifierData *md) { if(md->prev) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if(mti->type!=eModifierTypeType_OnlyDeform) { ModifierTypeInfo *nmti = modifierType_getInfo(md->prev->type); if(nmti->flags&eModifierTypeFlag_RequiresOriginalData) { BKE_report(reports, RPT_WARNING, "Cannot move above a modifier requiring original data"); return 0; } } BLI_remlink(&ob->modifiers, md); BLI_insertlink(&ob->modifiers, md->prev->prev, md); } return 1; }
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)); }
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 ED_object_modifier_move_down(ReportList *reports, Object *ob, ModifierData *md) { if(md->next) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if(mti->flags&eModifierTypeFlag_RequiresOriginalData) { ModifierTypeInfo *nmti = modifierType_getInfo(md->next->type); if(nmti->type!=eModifierTypeType_OnlyDeform) { BKE_report(reports, RPT_WARNING, "Cannot move beyond a non-deforming modifier"); return 0; } } BLI_remlink(&ob->modifiers, md); BLI_insertlink(&ob->modifiers, md->next, md); } return 1; }
int modifier_isPreview(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (!(mti->flags & eModifierTypeFlag_UsesPreview)) return FALSE; if (md->mode & eModifierMode_Realtime) return TRUE; return FALSE; }
bool modifier_isPreview(ModifierData *md) { ModifierTypeInfo *mti = modifierType_getInfo(md->type); if (!(mti->flags & eModifierTypeFlag_UsesPreview)) return false; if (md->mode & eModifierMode_Realtime) return true; return false; }
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); }
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; }
bool modifier_isEnabled(struct Scene *scene, ModifierData *md, int required_mode) { const 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); }
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); }
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 modwrap_deformVerts( ModifierData *md, Object *ob, DerivedMesh *dm, float (*vertexCos)[3], int numVerts, ModifierApplyFlag flag) { const 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->deformVerts(md, ob, dm, vertexCos, numVerts, flag); }
static int modifier_apply_shape(ReportList *reports, Scene *scene, Object *ob, ModifierData *md) { ModifierTypeInfo *mti= modifierType_getInfo(md->type); md->scene= scene; if (mti->isDisabled && mti->isDisabled(md, 0)) { BKE_report(reports, RPT_ERROR, "Modifier is disabled, skipping apply"); return 0; } if (ob->type==OB_MESH) { DerivedMesh *dm; Mesh *me= ob->data; Key *key=me->key; KeyBlock *kb; if(!modifier_sameTopology(md)) { BKE_report(reports, RPT_ERROR, "Only deforming modifiers can be applied to Shapes"); return 0; } mesh_pmv_off(me); dm = mesh_create_derived_for_modifier(scene, ob, md); if (!dm) { BKE_report(reports, RPT_ERROR, "Modifier is disabled or returned error, skipping apply"); return 0; } if(key == NULL) { key= me->key= add_key((ID *)me); key->type= KEY_RELATIVE; /* if that was the first key block added, then it was the basis. * Initialise it with the mesh, and add another for the modifier */ kb= add_keyblock(key, NULL); mesh_to_key(me, kb); } kb= add_keyblock(key, md->name); DM_to_meshkey(dm, me, kb); dm->release(dm); } else { BKE_report(reports, RPT_ERROR, "Cannot apply modifier for this object type"); return 0; } return 1; }
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); } } }
bool modifier_isPreview(ModifierData *md) { const ModifierTypeInfo *mti = modifierType_getInfo(md->type); /* Constructive modifiers are highly likely to also modify data like vgroups or vcol! */ if (!((mti->flags & eModifierTypeFlag_UsesPreview) || (mti->type == eModifierTypeType_Constructive))) { return false; } if (md->mode & eModifierMode_Realtime) { return true; } return false; }