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; }
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; }
static bool isDisabled(ModifierData *md, int useRenderParams) { ParticleInstanceModifierData *pimd = (ParticleInstanceModifierData *)md; ParticleSystem *psys; ModifierData *ob_md; if (!pimd->ob) return true; psys = BLI_findlink(&pimd->ob->particlesystem, pimd->psys - 1); if (psys == NULL) return true; /* If the psys modifier is disabled we cannot use its data. * First look up the psys modifier from the object, then check if it is enabled. */ for (ob_md = pimd->ob->modifiers.first; ob_md; ob_md = ob_md->next) { if (ob_md->type == eModifierType_ParticleSystem) { ParticleSystemModifierData *psmd = (ParticleSystemModifierData *)ob_md; if (psmd->psys == psys) { int required_mode; if (useRenderParams) required_mode = eModifierMode_Render; else required_mode = eModifierMode_Realtime; if (!modifier_isEnabled(md->scene, ob_md, required_mode)) return true; break; } } } return false; }
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]); } }
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; }
ModifierData *modifiers_getLastPreview(struct Scene *scene, ModifierData *md, int required_mode) { ModifierData *tmp_md = NULL; if (required_mode != eModifierMode_Realtime) return tmp_md; /* Find the latest modifier in stack generating preview. */ for (; md; md = md->next) { if (modifier_isEnabled(scene, md, required_mode) && modifier_isPreview(md)) tmp_md = md; } return tmp_md; }
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; }
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; }
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); }
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 int multiresbake_check(bContext *C, wmOperator *op) { Scene *scene= CTX_data_scene(C); Object *ob; Mesh *me; MultiresModifierData *mmd; int ok= 1, a; CTX_DATA_BEGIN(C, Base*, base, selected_editable_bases) { ob= base->object; if(ob->type != OB_MESH) { BKE_report(op->reports, RPT_ERROR, "Basking of multires data only works with active object which is a mesh"); ok= 0; break; } me= (Mesh*)ob->data; mmd= get_multires_modifier(scene, ob, 0); /* Multi-resolution should be and be last in the stack */ if(ok && mmd) { ModifierData *md; ok= mmd->totlvl>0; for(md = (ModifierData*)mmd->modifier.next; md && ok; md = md->next) { if (modifier_isEnabled(scene, md, eModifierMode_Realtime)) { ok= 0; } } } else ok= 0; if(!ok) { BKE_report(op->reports, RPT_ERROR, "Multires data baking requires multi-resolution object"); break; } if(!me->mtface) { BKE_report(op->reports, RPT_ERROR, "Mesh should be unwrapped before multires data baking"); ok= 0; } else { a= me->totface; while (ok && a--) { Image *ima= me->mtface[a].tpage; if(!ima) { BKE_report(op->reports, RPT_ERROR, "You should have active texture to use multires baker"); ok= 0; } else { ImBuf *ibuf= BKE_image_get_ibuf(ima, NULL); if(!ibuf) { BKE_report(op->reports, RPT_ERROR, "Baking should happend to image with image buffer"); ok= 0; } else { if(ibuf->rect==NULL && ibuf->rect_float==NULL) ok= 0; if(ibuf->rect_float && !(ibuf->channels==0 || ibuf->channels==4)) ok= 0; if(!ok) BKE_report(op->reports, RPT_ERROR, "Baking to unsupported image type"); } } } } if(!ok) break; }