static int shape_key_move_exec(bContext *C, wmOperator *op) { Object *ob = ED_object_context(C); Key *key = BKE_key_from_object(ob); const int type = RNA_enum_get(op->ptr, "type"); const int totkey = key->totkey; const int act_index = ob->shapenr - 1; int new_index; switch (type) { case KB_MOVE_TOP: /* Replace the ref key only if we're at the top already (only for relative keys) */ new_index = (ELEM(act_index, 0, 1) || key->type == KEY_NORMAL) ? 0 : 1; break; case KB_MOVE_BOTTOM: new_index = totkey - 1; break; case KB_MOVE_UP: case KB_MOVE_DOWN: default: new_index = (totkey + act_index + type) % totkey; break; } if (!BKE_keyblock_move(ob, act_index, new_index)) { return OPERATOR_CANCELLED; } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; }
/* Criteria: * 1) There must be an dopesheet/action editor, and it must be in a mode which uses actions... * OR * The NLA Editor is active (i.e. Animation Data panel -> new action) * 2) The associated AnimData block must not be in tweakmode */ static int action_new_poll(bContext *C) { Scene *scene = CTX_data_scene(C); /* Check tweakmode is off (as you don't want to be tampering with the action in that case) */ /* NOTE: unlike for pushdown, this operator needs to be run when creating an action from nothing... */ if (ED_operator_action_active(C)) { SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C); Object *ob = CTX_data_active_object(C); /* For now, actions are only for the active object, and on object and shapekey levels... */ if (saction->mode == SACTCONT_ACTION) { /* XXX: This assumes that actions are assigned to the active object in this mode */ if (ob) { if ((ob->adt == NULL) || (ob->adt->flag & ADT_NLA_EDIT_ON) == 0) return true; } } else if (saction->mode == SACTCONT_SHAPEKEY) { Key *key = BKE_key_from_object(ob); if (key) { if ((key->adt == NULL) || (key->adt->flag & ADT_NLA_EDIT_ON) == 0) return true; } } } else if (ED_operator_nla_active(C)) { if (!(scene->flag & SCE_NLA_EDIT_ON)) { return true; } } /* something failed... */ return false; }
static int shape_key_move_poll(bContext *C) { /* Same as shape_key_mode_exists_poll above, but ensure we have at least two shapes! */ Object *ob = ED_object_context(C); ID *data = (ob) ? ob->data : NULL; Key *key = BKE_key_from_object(ob); return (ob && !ob->id.lib && data && !data->lib && ob->mode != OB_MODE_EDIT && key && key->totkey > 1); }
static void deformVertsEM(ModifierData *md, Object *ob, struct BMEditMesh *UNUSED(editData), DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts) { Key *key = BKE_key_from_object(ob); if (key && key->type == KEY_RELATIVE) deformVerts(md, ob, derivedData, vertexCos, numVerts, 0); }
static Key *rna_ShapeKey_find_key(ID *id) { switch (GS(id->name)) { case ID_CU: return ((Curve *)id)->key; case ID_KE: return (Key *)id; case ID_LT: return ((Lattice *)id)->key; case ID_ME: return ((Mesh *)id)->key; case ID_OB: return BKE_key_from_object((Object *)id); default: return NULL; } }
static void ED_object_shape_key_add(bContext *C, Object *ob, const bool from_mix) { KeyBlock *kb; if ((kb = BKE_object_shapekey_insert(ob, NULL, from_mix))) { Key *key = BKE_key_from_object(ob); /* for absolute shape keys, new keys may not be added last */ ob->shapenr = BLI_findindex(&key->block, kb) + 1; WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); } }
void ControllerExporter::operator()(Object *ob) { Object *ob_arm = bc_get_assigned_armature(ob); Key *key = BKE_key_from_object(ob); if (ob_arm) { export_skin_controller(ob, ob_arm); } if (key && this->export_settings->include_shapekeys) { export_morph_controller(ob, key); } }
static void rna_Key_update_data(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr) { Key *key = ptr->id.data; Object *ob; for (ob = bmain->object.first; ob; ob = ob->id.next) { if (BKE_key_from_object(ob) == key) { DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_main_add_notifier(NC_OBJECT | ND_MODIFIER, ob); } } }
static bool object_shapekey_remove(Main *bmain, Object *ob) { KeyBlock *kb; Key *key = BKE_key_from_object(ob); if (key == NULL) { return false; } kb = BLI_findlink(&key->block, ob->shapenr - 1); if (kb) { return BKE_object_shapekey_remove(bmain, ob, kb); } return false; }
static void deformVerts(ModifierData *UNUSED(md), Object *ob, DerivedMesh *UNUSED(derivedData), float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { Key *key = BKE_key_from_object(ob); if (key && key->block.first) { int deformedVerts_tot; BKE_key_evaluate_object_ex( ob, &deformedVerts_tot, (float *)vertexCos, sizeof(*vertexCos) * numVerts); } }
static int shape_key_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_context(C); Key *key = BKE_key_from_object(ob); KeyBlock *kb = BKE_keyblock_from_object(ob); if (!key || !kb) return OPERATOR_CANCELLED; for (kb = key->block.first; kb; kb = kb->next) kb->curval = 0.0f; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; }
static void deformVerts(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], int numVerts, ModifierApplyFlag UNUSED(flag)) { DerivedMesh *dm; ClothModifierData *clmd = (ClothModifierData *) md; /* check for alloc failing */ if (!clmd->sim_parms || !clmd->coll_parms) { initData(md); if (!clmd->sim_parms || !clmd->coll_parms) return; } dm = get_dm(ob, NULL, derivedData, NULL, false, false); if (dm == derivedData) dm = CDDM_copy(dm); /* TODO(sergey): For now it actually duplicates logic from DerivedMesh.c * and needs some more generic solution. But starting experimenting with * this so close to the release is not that nice.. * * Also hopefully new cloth system will arrive soon.. */ if (derivedData == NULL && clmd->sim_parms->shapekey_rest) { KeyBlock *kb = BKE_keyblock_from_key(BKE_key_from_object(ob), clmd->sim_parms->shapekey_rest); if (kb && kb->data != NULL) { float (*layerorco)[3]; if (!(layerorco = DM_get_vert_data_layer(dm, CD_CLOTH_ORCO))) { DM_add_vert_layer(dm, CD_CLOTH_ORCO, CD_CALLOC, NULL); layerorco = DM_get_vert_data_layer(dm, CD_CLOTH_ORCO); } memcpy(layerorco, kb->data, sizeof(float) * 3 * numVerts); } } CDDM_apply_vert_coords(dm, vertexCos); DM_ensure_tessface(dm); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */ clothModifier_do(clmd, md->scene, ob, dm, vertexCos); dm->release(dm); }
static PointerRNA rna_Object_shape_key_add( Object *ob, bContext *C, ReportList *reports, const char *name, bool from_mix) { Main *bmain = CTX_data_main(C); KeyBlock *kb = NULL; if ((kb = BKE_object_shapekey_insert(bmain, ob, name, from_mix))) { PointerRNA keyptr; RNA_pointer_create((ID *)BKE_key_from_object(ob), &RNA_ShapeKey, kb, &keyptr); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return keyptr; } else { BKE_reportf(reports, RPT_ERROR, "Object '%s' does not support shapes", ob->id.name + 2); return PointerRNA_NULL; } }
void AnimationExporter::export_morph_animation(Object *ob) { FCurve *fcu; char *transformName; Key *key = BKE_key_from_object(ob); if (!key) return; if (key->adt && key->adt->action) { fcu = (FCurve *)key->adt->action->curves.first; while (fcu) { transformName = extract_transform_name(fcu->rna_path); dae_animation(ob, fcu, transformName, true); fcu = fcu->next; } } }
/* NOTE: This is to support old files from before Blender supported modifiers, * in some cases versioning code updates these so for new files this will * return an empty list. */ ModifierData *modifiers_getVirtualModifierList(Object *ob, VirtualModifierData *virtualModifierData) { ModifierData *md; md = ob->modifiers.first; *virtualModifierData = virtualModifierCommonData; if (ob->parent) { if (ob->parent->type == OB_ARMATURE && ob->partype == PARSKEL) { virtualModifierData->amd.object = ob->parent; virtualModifierData->amd.modifier.next = md; virtualModifierData->amd.deformflag = ((bArmature *)(ob->parent->data))->deformflag; md = &virtualModifierData->amd.modifier; } else if (ob->parent->type == OB_CURVE && ob->partype == PARSKEL) { virtualModifierData->cmd.object = ob->parent; virtualModifierData->cmd.defaxis = ob->trackflag + 1; virtualModifierData->cmd.modifier.next = md; md = &virtualModifierData->cmd.modifier; } else if (ob->parent->type == OB_LATTICE && ob->partype == PARSKEL) { virtualModifierData->lmd.object = ob->parent; virtualModifierData->lmd.modifier.next = md; md = &virtualModifierData->lmd.modifier; } } /* shape key modifier, not yet for curves */ if (ELEM(ob->type, OB_MESH, OB_LATTICE) && BKE_key_from_object(ob)) { if (ob->type == OB_MESH && (ob->shapeflag & OB_SHAPE_EDIT_MODE)) virtualModifierData->smd.modifier.mode |= eModifierMode_Editmode | eModifierMode_OnCage; else virtualModifierData->smd.modifier.mode &= ~eModifierMode_Editmode | eModifierMode_OnCage; virtualModifierData->smd.modifier.next = md; md = &virtualModifierData->smd.modifier; } return md; }
static void deformMatrices(ModifierData *md, Object *ob, DerivedMesh *derivedData, float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) { Key *key = BKE_key_from_object(ob); KeyBlock *kb = BKE_keyblock_from_object(ob); float scale[3][3]; (void)vertexCos; /* unused */ if (kb && kb->totelem == numVerts && kb != key->refkey) { int a; if (ob->shapeflag & OB_SHAPE_LOCK) scale_m3_fl(scale, 1); else scale_m3_fl(scale, kb->curval); for (a = 0; a < numVerts; a++) copy_m3_m3(defMats[a], scale); } deformVerts(md, ob, derivedData, vertexCos, numVerts, 0); }
static void deformMatricesEM(ModifierData *UNUSED(md), Object *ob, struct BMEditMesh *UNUSED(editData), DerivedMesh *UNUSED(derivedData), float (*vertexCos)[3], float (*defMats)[3][3], int numVerts) { Key *key = BKE_key_from_object(ob); KeyBlock *kb = BKE_keyblock_from_object(ob); float scale[3][3]; (void)vertexCos; /* unused */ if (kb && kb->totelem == numVerts && kb != key->refkey) { int a; scale_m3_fl(scale, kb->curval); for (a = 0; a < numVerts; a++) copy_m3_m3(defMats[a], scale); } }
/* starting point and step size could be optional */ static int shape_key_retime_exec(bContext *C, wmOperator *UNUSED(op)) { Object *ob = ED_object_context(C); Key *key = BKE_key_from_object(ob); KeyBlock *kb = BKE_keyblock_from_object(ob); float cfra = 0.0f; if (!key || !kb) { return OPERATOR_CANCELLED; } for (kb = key->block.first; kb; kb = kb->next) { kb->pos = cfra; cfra += 0.1f; } DEG_id_tag_update(&ob->id, ID_RECALC_GEOMETRY); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return OPERATOR_FINISHED; }
/* Helper function to find the active AnimData block from the Action Editor context */ AnimData *ED_actedit_animdata_from_context(bContext *C) { SpaceAction *saction = (SpaceAction *)CTX_wm_space_data(C); Object *ob = CTX_data_active_object(C); AnimData *adt = NULL; /* Get AnimData block to use */ if (saction->mode == SACTCONT_ACTION) { /* Currently, "Action Editor" means object-level only... */ if (ob) { adt = ob->adt; } } else if (saction->mode == SACTCONT_SHAPEKEY) { Key *key = BKE_key_from_object(ob); if (key) { adt = key->adt; } } return adt; }
static void rna_Object_shape_key_remove( Object *ob, Main *bmain, ReportList *reports, PointerRNA *kb_ptr) { KeyBlock *kb = kb_ptr->data; Key *key = BKE_key_from_object(ob); if ((key == NULL) || BLI_findindex(&key->block, kb) == -1) { BKE_reportf(reports, RPT_ERROR, "ShapeKey not found"); return; } if (!BKE_object_shapekey_remove(bmain, ob, kb)) { BKE_reportf(reports, RPT_ERROR, "Could not remove ShapeKey"); return; } DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_main_add_notifier(NC_OBJECT | ND_DRAW, ob); RNA_POINTER_INVALIDATE(kb_ptr); }
bool AnimationExporter::hasAnimations(Scene *sce) { LinkNode *node; for (node=this->export_settings->export_set; node; node=node->next) { Object *ob = (Object *)node->link; FCurve *fcu = 0; //Check for object transform animations if (ob->adt && ob->adt->action) fcu = (FCurve *)ob->adt->action->curves.first; //Check for Lamp parameter animations else if ( (ob->type == OB_LAMP) && ((Lamp *)ob->data)->adt && ((Lamp *)ob->data)->adt->action) fcu = (FCurve *)(((Lamp *)ob->data)->adt->action->curves.first); //Check for Camera parameter animations else if ( (ob->type == OB_CAMERA) && ((Camera *)ob->data)->adt && ((Camera *)ob->data)->adt->action) fcu = (FCurve *)(((Camera *)ob->data)->adt->action->curves.first); //Check Material Effect parameter animations. for (int a = 0; a < ob->totcol; a++) { Material *ma = give_current_material(ob, a + 1); if (!ma) continue; if (ma->adt && ma->adt->action) { fcu = (FCurve *)ma->adt->action->curves.first; } } //check shape key animation if (!fcu) { Key *key = BKE_key_from_object(ob); if (key && key->adt && key->adt->action) fcu = (FCurve *)key->adt->action->curves.first; } if (fcu) return true; } return false; }
static bool ED_object_shape_key_remove_all(Main *bmain, Object *ob) { Key *key; key = BKE_key_from_object(ob); if (key == NULL) return false; switch (GS(key->from->name)) { case ID_ME: ((Mesh *)key->from)->key = NULL; break; case ID_CU: ((Curve *)key->from)->key = NULL; break; case ID_LT: ((Lattice *)key->from)->key = NULL; break; } BKE_libblock_free_us(bmain, key); return true; }
void GeometryExporter::operator()(Object *ob) { // XXX don't use DerivedMesh, Mesh instead? #if 0 DerivedMesh *dm = mesh_get_derived_final(mScene, ob, CD_MASK_BAREMESH); #endif bool use_instantiation = this->export_settings->use_object_instantiation; Mesh *me = bc_get_mesh_copy( mScene, ob, this->export_settings->export_mesh_type, this->export_settings->apply_modifiers, this->export_settings->triangulate); Mesh *mesh = (Mesh *) ob->data; me->flag = mesh->flag; std::string geom_id = get_geometry_id(ob, use_instantiation); std::vector<Normal> nor; std::vector<BCPolygonNormalsIndices> norind; // Skip if linked geometry was already exported from another reference if (use_instantiation && exportedGeometry.find(geom_id) != exportedGeometry.end()) { return; } std::string geom_name = (use_instantiation) ? id_name(ob->data) : id_name(ob); exportedGeometry.insert(geom_id); bool has_color = (bool)CustomData_has_layer(&me->fdata, CD_MCOL); create_normals(nor, norind, me); // openMesh(geoId, geoName, meshId) openMesh(geom_id, geom_name); // writes <source> for vertex coords createVertsSource(geom_id, me); // writes <source> for normal coords createNormalsSource(geom_id, me, nor); bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE); // writes <source> for uv coords if mesh has uv coords if (has_uvs) { createTexcoordsSource(geom_id, me); } if (has_color) { createVertexColorSource(geom_id, me); } // <vertices> COLLADASW::Vertices verts(mSW); verts.setId(getIdBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX)); COLLADASW::InputList &input_list = verts.getInputList(); COLLADASW::Input input(COLLADASW::InputSemantic::POSITION, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::POSITION)); input_list.push_back(input); verts.add(); createLooseEdgeList(ob, me, geom_id); // Only create Polylists if number of faces > 0 if (me->totface > 0) { // XXX slow if (ob->totcol) { for (int a = 0; a < ob->totcol; a++) { createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind); } } else { createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind); } } closeMesh(); if (me->flag & ME_TWOSIDED) { mSW->appendTextBlock("<extra><technique profile=\"MAYA\"><double_sided>1</double_sided></technique></extra>"); } closeGeometry(); if (this->export_settings->include_shapekeys) { Key * key = BKE_key_from_object(ob); if (key) { KeyBlock * kb = (KeyBlock *)key->block.first; //skip the basis kb = kb->next; for (; kb; kb = kb->next) { BKE_keyblock_convert_to_mesh(kb, me); export_key_mesh(ob, me, kb); } } } BKE_libblock_free_us(G.main, me); }
static bool object_shape_key_mirror(bContext *C, Object *ob, int *r_totmirr, int *r_totfail, bool use_topology) { KeyBlock *kb; Key *key; int totmirr = 0, totfail = 0; *r_totmirr = *r_totfail = 0; key = BKE_key_from_object(ob); if (key == NULL) return 0; kb = BLI_findlink(&key->block, ob->shapenr - 1); if (kb) { char *tag_elem = MEM_callocN(sizeof(char) * kb->totelem, "shape_key_mirror"); if (ob->type == OB_MESH) { Mesh *me = ob->data; MVert *mv; int i1, i2; float *fp1, *fp2; float tvec[3]; ED_mesh_mirror_spatial_table(ob, NULL, NULL, 's'); for (i1 = 0, mv = me->mvert; i1 < me->totvert; i1++, mv++) { i2 = mesh_get_x_mirror_vert(ob, i1, use_topology); if (i2 == i1) { fp1 = ((float *)kb->data) + i1 * 3; fp1[0] = -fp1[0]; tag_elem[i1] = 1; totmirr++; } else if (i2 != -1) { if (tag_elem[i1] == 0 && tag_elem[i2] == 0) { fp1 = ((float *)kb->data) + i1 * 3; fp2 = ((float *)kb->data) + i2 * 3; copy_v3_v3(tvec, fp1); copy_v3_v3(fp1, fp2); copy_v3_v3(fp2, tvec); /* flip x axis */ fp1[0] = -fp1[0]; fp2[0] = -fp2[0]; totmirr++; } tag_elem[i1] = tag_elem[i2] = 1; } else { totfail++; } } ED_mesh_mirror_spatial_table(ob, NULL, NULL, 'e'); } else if (ob->type == OB_LATTICE) { Lattice *lt = ob->data; int i1, i2; float *fp1, *fp2; int u, v, w; /* half but found up odd value */ const int pntsu_half = (lt->pntsu / 2) + (lt->pntsu % 2); /* currently editmode isn't supported by mesh so * ignore here for now too */ /* if (lt->editlatt) lt = lt->editlatt->latt; */ for (w = 0; w < lt->pntsw; w++) { for (v = 0; v < lt->pntsv; v++) { for (u = 0; u < pntsu_half; u++) { int u_inv = (lt->pntsu - 1) - u; float tvec[3]; if (u == u_inv) { i1 = BKE_lattice_index_from_uvw(lt, u, v, w); fp1 = ((float *)kb->data) + i1 * 3; fp1[0] = -fp1[0]; totmirr++; } else { i1 = BKE_lattice_index_from_uvw(lt, u, v, w); i2 = BKE_lattice_index_from_uvw(lt, u_inv, v, w); fp1 = ((float *)kb->data) + i1 * 3; fp2 = ((float *)kb->data) + i2 * 3; copy_v3_v3(tvec, fp1); copy_v3_v3(fp1, fp2); copy_v3_v3(fp2, tvec); fp1[0] = -fp1[0]; fp2[0] = -fp2[0]; totmirr++; } } } } } MEM_freeN(tag_elem); } *r_totmirr = totmirr; *r_totfail = totfail; DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, ob); return 1; }
static bool ED_object_shape_key_remove(Main *bmain, Object *ob) { KeyBlock *kb, *rkb; Key *key; key = BKE_key_from_object(ob); if (key == NULL) return false; kb = BLI_findlink(&key->block, ob->shapenr - 1); if (kb) { for (rkb = key->block.first; rkb; rkb = rkb->next) if (rkb->relative == ob->shapenr - 1) rkb->relative = 0; BLI_remlink(&key->block, kb); key->totkey--; if (key->refkey == kb) { key->refkey = key->block.first; if (key->refkey) { /* apply new basis key on original data */ switch (ob->type) { case OB_MESH: BKE_key_convert_to_mesh(key->refkey, ob->data); break; case OB_CURVE: case OB_SURF: BKE_key_convert_to_curve(key->refkey, ob->data, BKE_curve_nurbs_get(ob->data)); break; case OB_LATTICE: BKE_key_convert_to_lattice(key->refkey, ob->data); break; } } } if (kb->data) MEM_freeN(kb->data); MEM_freeN(kb); if (ob->shapenr > 1) { ob->shapenr--; } } if (key->totkey == 0) { switch (GS(key->from->name)) { case ID_ME: ((Mesh *)key->from)->key = NULL; break; case ID_CU: ((Curve *)key->from)->key = NULL; break; case ID_LT: ((Lattice *)key->from)->key = NULL; break; } BKE_libblock_free_us(bmain, key); } return true; }
static int sculpt_undo_restore_coords(bContext *C, DerivedMesh *dm, SculptUndoNode *unode) { Scene *scene = CTX_data_scene(C); Sculpt *sd = CTX_data_tool_settings(C)->sculpt; Object *ob = CTX_data_active_object(C); SculptSession *ss = ob->sculpt; MVert *mvert; int *index, i, j; if (unode->maxvert) { /* regular mesh restore */ if (ss->kb && strcmp(ss->kb->name, unode->shapeName)) { /* shape key has been changed before calling undo operator */ Key *key = BKE_key_from_object(ob); KeyBlock *kb = key ? BKE_keyblock_find_name(key, unode->shapeName) : NULL; if (kb) { ob->shapenr = BLI_findindex(&key->block, kb) + 1; sculpt_update_mesh_elements(scene, sd, ob, 0, FALSE); WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob); } else { /* key has been removed -- skip this undo node */ return 0; } } index = unode->index; mvert = ss->mvert; if (ss->kb) { float (*vertCos)[3]; vertCos = BKE_key_convert_to_vertcos(ob, ss->kb); for (i = 0; i < unode->totvert; i++) { if (ss->modifiers_active) { sculpt_undo_restore_deformed(ss, unode, i, index[i], vertCos[index[i]]); } else { if (unode->orig_co) swap_v3_v3(vertCos[index[i]], unode->orig_co[i]); else swap_v3_v3(vertCos[index[i]], unode->co[i]); } } /* propagate new coords to keyblock */ sculpt_vertcos_to_key(ob, ss->kb, vertCos); /* pbvh uses it's own mvert array, so coords should be */ /* propagated to pbvh here */ BKE_pbvh_apply_vertCos(ss->pbvh, vertCos); MEM_freeN(vertCos); } else { for (i = 0; i < unode->totvert; i++) { if (ss->modifiers_active) { sculpt_undo_restore_deformed(ss, unode, i, index[i], mvert[index[i]].co); } else { if (unode->orig_co) swap_v3_v3(mvert[index[i]].co, unode->orig_co[i]); else swap_v3_v3(mvert[index[i]].co, unode->co[i]); } mvert[index[i]].flag |= ME_VERT_PBVH_UPDATE; } } } else if (unode->maxgrid && dm->getGridData) { /* multires restore */ CCGElem **grids, *grid; CCGKey key; float (*co)[3]; int gridsize; grids = dm->getGridData(dm); gridsize = dm->getGridSize(dm); dm->getGridKey(dm, &key); co = unode->co; for (j = 0; j < unode->totgrid; j++) { grid = grids[unode->grids[j]]; for (i = 0; i < gridsize * gridsize; i++, co++) swap_v3_v3(CCG_elem_offset_co(&key, grid, i), co[0]); } } return 1; }
void BKE_object_handle_data_update(EvaluationContext *eval_ctx, Scene *scene, Object *ob) { ID *data_id = (ID *)ob->data; AnimData *adt = BKE_animdata_from_id(data_id); Key *key; float ctime = BKE_scene_frame_get(scene); if (G.debug & G_DEBUG_DEPSGRAPH) printf("recalcdata %s\n", ob->id.name + 2); /* TODO(sergey): Only used by legacy depsgraph. */ if (adt) { /* evaluate drivers - datalevel */ /* XXX: for mesh types, should we push this to derivedmesh instead? */ BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS); } /* TODO(sergey): Only used by legacy depsgraph. */ key = BKE_key_from_object(ob); if (key && key->block.first) { if (!(ob->shapeflag & OB_SHAPE_LOCK)) BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS); } /* includes all keys and modifiers */ switch (ob->type) { case OB_MESH: { BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL; uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH; #ifdef WITH_FREESTYLE /* make sure Freestyle edge/face marks appear in DM for render (see T40315) */ if (eval_ctx->mode != DAG_EVAL_VIEWPORT) { data_mask |= CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE; } #endif if (em) { makeDerivedMesh(scene, ob, em, data_mask, false); /* was CD_MASK_BAREMESH */ } else { makeDerivedMesh(scene, ob, NULL, data_mask, false); } break; } case OB_ARMATURE: if (ob->id.lib && ob->proxy_from) { if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) { printf("Proxy copy error, lib Object: %s proxy Object: %s\n", ob->id.name + 2, ob->proxy_from->id.name + 2); } } else { BKE_pose_where_is(scene, ob); } break; case OB_MBALL: BKE_displist_make_mball(eval_ctx, scene, ob); break; case OB_CURVE: case OB_SURF: case OB_FONT: BKE_displist_make_curveTypes(scene, ob, 0); break; case OB_LATTICE: BKE_lattice_modifiers_calc(scene, ob); break; case OB_EMPTY: if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data) if (BKE_image_is_animated(ob->data)) BKE_image_user_check_frame_calc(ob->iuser, (int)ctime, 0); break; } /* related materials */ /* XXX: without depsgraph tagging, this will always need to be run, which will be slow! * However, not doing anything (or trying to hack around this lack) is not an option * anymore, especially due to Cycles [#31834] */ if (ob->totcol) { int a; if (ob->totcol != 0) { BLI_mutex_lock(&material_lock); for (a = 1; a <= ob->totcol; a++) { Material *ma = give_current_material(ob, a); if (ma) { /* recursively update drivers for this material */ material_drivers_update(scene, ma, ctime); } } BLI_mutex_unlock(&material_lock); } } else if (ob->type == OB_LAMP) lamp_drivers_update(scene, ob->data, ctime); /* particles */ if (ob != scene->obedit && ob->particlesystem.first) { ParticleSystem *tpsys, *psys; DerivedMesh *dm; ob->transflag &= ~OB_DUPLIPARTS; psys = ob->particlesystem.first; while (psys) { /* ensure this update always happens even if psys is disabled */ if (psys->recalc & PSYS_RECALC_TYPE) { psys_changed_type(ob, psys); } if (psys_check_enabled(ob, psys)) { /* check use of dupli objects here */ if (psys->part && (psys->part->draw_as == PART_DRAW_REND || eval_ctx->mode == DAG_EVAL_RENDER) && ((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob) || (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group))) { ob->transflag |= OB_DUPLIPARTS; } particle_system_update(scene, ob, psys); psys = psys->next; } else if (psys->flag & PSYS_DELETE) { tpsys = psys->next; BLI_remlink(&ob->particlesystem, psys); psys_free(ob, psys); psys = tpsys; } else psys = psys->next; } if (eval_ctx->mode == DAG_EVAL_RENDER && ob->transflag & OB_DUPLIPARTS) { /* this is to make sure we get render level duplis in groups: * the derivedmesh must be created before init_render_mesh, * since object_duplilist does dupliparticles before that */ CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL; dm = mesh_create_derived_render(scene, ob, data_mask); dm->release(dm); for (psys = ob->particlesystem.first; psys; psys = psys->next) psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated; } } /* quick cache removed */ }