static int object_delete_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); int islamp= 0; if(CTX_data_edit_object(C)) return OPERATOR_CANCELLED; CTX_DATA_BEGIN(C, Base*, base, selected_bases) { if(base->object->type==OB_LAMP) islamp= 1; /* deselect object -- it could be used in other scenes */ base->object->flag &= ~SELECT; /* remove from current scene only */ ED_base_object_free_and_unlink(bmain, scene, base); } CTX_DATA_END; if(islamp) reshadeall_displist(scene); /* only frees displist */ DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_SCENE|ND_OB_ACTIVE, scene); WM_event_add_notifier(C, NC_SCENE|ND_LAYER_CONTENT, scene); return OPERATOR_FINISHED; }
static int remove_driver_button_exec (bContext *C, wmOperator *op) { PointerRNA ptr= {{NULL}}; PropertyRNA *prop= NULL; short success= 0; int index, all= RNA_boolean_get(op->ptr, "all"); /* try to find driver using property retrieved from UI */ uiContextActiveProperty(C, &ptr, &prop, &index); if (all) index= -1; if (ptr.id.data && ptr.data && prop) { char *path= get_driver_path_hack(C, &ptr, prop); success= ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0); MEM_freeN(path); } if (success) { /* send updates */ uiContextAnimUpdate(C); DAG_ids_flush_update(CTX_data_main(C), 0); WM_event_add_notifier(C, NC_ANIMATION|ND_FCURVES_ORDER, NULL); // XXX } return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; }
static int object_origin_clear_exec(bContext *C, wmOperator *UNUSED(op)) { Main *bmain = CTX_data_main(C); float *v1, *v3; float mat[3][3]; CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { if (ob->parent) { /* vectors pointed to by v1 and v3 will get modified */ v1 = ob->loc; v3 = ob->parentinv[3]; copy_m3_m4(mat, ob->parentinv); negate_v3_v3(v3, v1); mul_m3_v3(mat, v3); } DAG_id_tag_update(&ob->id, OB_RECALC_OB); } CTX_DATA_END; DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; }
static int add_driver_button_exec (bContext *C, wmOperator *op) { PointerRNA ptr= {{NULL}}; PropertyRNA *prop= NULL; short success= 0; int index, all= RNA_boolean_get(op->ptr, "all"); /* try to create driver using property retrieved from UI */ uiContextActiveProperty(C, &ptr, &prop, &index); if (all) index= -1; if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { char *path= get_driver_path_hack(C, &ptr, prop); short flags = CREATEDRIVER_WITH_DEFAULT_DVAR; if (path) { success+= ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON); MEM_freeN(path); } } if (success) { /* send updates */ uiContextAnimUpdate(C); DAG_ids_flush_update(CTX_data_main(C), 0); WM_event_add_notifier(C, NC_ANIMATION|ND_FCURVES_ORDER, NULL); // XXX } return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; }
static int remove_keyingset_button_exec (bContext *C, wmOperator *op) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); KeyingSet *ks = NULL; PropertyRNA *prop= NULL; PointerRNA ptr= {{NULL}}; char *path = NULL; short success= 0; int index=0; /* verify the Keying Set to use: * - use the active one for now (more control over this can be added later) * - return error if it doesn't exist */ if (scene->active_keyingset == 0) { BKE_report(op->reports, RPT_ERROR, "No active Keying Set to remove property from"); return OPERATOR_CANCELLED; } else if (scene->active_keyingset < 0) { BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in Keying Set"); return OPERATOR_CANCELLED; } else ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); /* try to add to keyingset using property retrieved from UI */ uiContextActiveProperty(C, &ptr, &prop, &index); if (ptr.id.data && ptr.data && prop) { path= RNA_path_from_ID_to_property(&ptr, prop); if (path) { KS_Path *ksp; /* try to find a path matching this description */ ksp= BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME); if (ksp) { BKE_keyingset_free_path(ks, ksp); success= 1; } /* free temp path used */ MEM_freeN(path); } } if (success) { /* send updates */ DAG_ids_flush_update(bmain, 0); /* for now, only send ND_KEYS for KeyingSets */ WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL); } return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; }
/* return success (1) */ int BKE_copybuffer_paste(bContext *C, char *libname, ReportList *reports) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); Main *mainl = NULL; Library *lib; BlendHandle *bh; bh = BLO_blendhandle_from_file(libname, reports); if (bh == NULL) { /* error reports will have been made by BLO_blendhandle_from_file() */ return 0; } BKE_scene_base_deselect_all(scene); /* tag everything, all untagged data can be made local * its also generally useful to know what is new * * take extra care flag_all_listbases_ids(LIB_LINK_TAG, 0) is called after! */ flag_all_listbases_ids(LIB_PRE_EXISTING, 1); /* here appending/linking starts */ mainl = BLO_library_append_begin(bmain, &bh, libname); BLO_library_append_all(mainl, bh); BLO_library_append_end(C, mainl, &bh, 0, 0); /* mark all library linked objects to be updated */ recalc_all_library_objects(bmain); IMB_colormanagement_check_file_config(bmain); /* append, rather than linking */ lib = BLI_findstring(&bmain->library, libname, offsetof(Library, filepath)); BKE_library_make_local(bmain, lib, 1); /* important we unset, otherwise these object wont * link into other scenes from this blend file */ flag_all_listbases_ids(LIB_PRE_EXISTING, 0); /* recreate dependency graph to include new objects */ DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); BLO_blendhandle_close(bh); /* remove library... */ return 1; }
static void do_graph_region_driver_buttons(bContext *C, void *UNUSED(arg), int event) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); switch (event) { case B_IPO_DEPCHANGE: { /* rebuild depsgraph for the new deps */ DAG_scene_sort(bmain, scene); /* force an update of depsgraph */ DAG_ids_flush_update(bmain, 0); } break; } /* default for now */ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); // XXX could use better notifier }
/* generic exec for clear-transform operators */ static int object_clear_transform_generic_exec(bContext *C, wmOperator *op, void (*clear_func)(Object *), const char default_ksName[]) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); KeyingSet *ks; /* sanity checks */ if (ELEM(NULL, clear_func, default_ksName)) { BKE_report(op->reports, RPT_ERROR, "Programming error: missing clear transform func or Keying Set Name"); return OPERATOR_CANCELLED; } /* get KeyingSet to use */ ks = ANIM_get_keyingset_for_autokeying(scene, default_ksName); /* operate on selected objects only if they aren't in weight-paint mode * (so that object-transform clearing won't be applied at same time as bone-clearing) */ CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects) { if (!(ob->mode & OB_MODE_WEIGHT_PAINT)) { /* run provided clearing function */ clear_func(ob); ED_autokeyframe_object(C, scene, ob, ks); /* tag for updates */ DAG_id_tag_update(&ob->id, OB_RECALC_OB); } } CTX_DATA_END; /* this is needed so children are also updated */ DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); return OPERATOR_FINISHED; }
// a shortened version of parent_set_exec() // if is_parent_space is true then ob->obmat will be multiplied by par->obmat before parenting int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space) { Object workob; Main *bmain = CTX_data_main(C); Scene *sce = CTX_data_scene(C); if (!par || bc_test_parent_loop(par, ob)) return false; ob->parent = par; ob->partype = PAROBJECT; ob->parsubstr[0] = 0; if (is_parent_space) { float mat[4][4]; // calc par->obmat where_is_object(sce, par); // move child obmat into world space mul_m4_m4m4(mat, ob->obmat, par->obmat); copy_m4_m4(ob->obmat, mat); } // apply child obmat (i.e. decompose it into rot/loc/size) object_apply_mat4(ob, ob->obmat, 0, 0); // compute parentinv what_does_parent(sce, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); ob->recalc |= OB_RECALC_OB | OB_RECALC_DATA; par->recalc |= OB_RECALC_OB; DAG_scene_sort(bmain, sce); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); return true; }
static int parent_drop_exec(bContext *C, wmOperator *op) { Object *par = NULL, *ob = NULL; Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); int partype = -1; char parname[MAX_ID_NAME], childname[MAX_ID_NAME]; partype = RNA_enum_get(op->ptr, "type"); RNA_string_get(op->ptr, "parent", parname); par = (Object *)BKE_libblock_find_name(ID_OB, parname); RNA_string_get(op->ptr, "child", childname); ob = (Object *)BKE_libblock_find_name(ID_OB, childname); ED_object_parent_set(op->reports, bmain, scene, ob, par, partype); DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); return OPERATOR_FINISHED; }
/* UNUSED, keep in case we want to copy functionality for use elsewhere */ static void copy_attr(Main *bmain, Scene *scene, View3D *v3d, short event) { Object *ob; Base *base; Curve *cu, *cu1; Nurb *nu; int do_scene_sort= 0; if (scene->id.lib) return; if (!(ob=OBACT)) return; if (scene->obedit) { // XXX get from context /* obedit_copymenu(); */ return; } if (event==9) { copymenu_properties(scene, v3d, ob); return; } else if (event==10) { copymenu_logicbricks(scene, v3d, ob); return; } else if (event==24) { /* moved to object_link_modifiers */ /* copymenu_modifiers(bmain, scene, v3d, ob); */ return; } for (base= FIRSTBASE; base; base= base->next) { if (base != BASACT) { if (TESTBASELIB(v3d, base)) { base->object->recalc |= OB_RECALC_OB; if (event==1) { /* loc */ copy_v3_v3(base->object->loc, ob->loc); copy_v3_v3(base->object->dloc, ob->dloc); } else if (event==2) { /* rot */ copy_v3_v3(base->object->rot, ob->rot); copy_v3_v3(base->object->drot, ob->drot); copy_qt_qt(base->object->quat, ob->quat); copy_qt_qt(base->object->dquat, ob->dquat); } else if (event==3) { /* size */ copy_v3_v3(base->object->size, ob->size); copy_v3_v3(base->object->dscale, ob->dscale); } else if (event==4) { /* drawtype */ base->object->dt= ob->dt; base->object->dtx= ob->dtx; base->object->empty_drawtype= ob->empty_drawtype; base->object->empty_drawsize= ob->empty_drawsize; } else if (event==5) { /* time offs */ base->object->sf= ob->sf; } else if (event==6) { /* dupli */ base->object->dupon= ob->dupon; base->object->dupoff= ob->dupoff; base->object->dupsta= ob->dupsta; base->object->dupend= ob->dupend; base->object->transflag &= ~OB_DUPLI; base->object->transflag |= (ob->transflag & OB_DUPLI); base->object->dup_group= ob->dup_group; if (ob->dup_group) id_lib_extern(&ob->dup_group->id); } else if (event==7) { /* mass */ base->object->mass= ob->mass; } else if (event==8) { /* damping */ base->object->damping= ob->damping; base->object->rdamping= ob->rdamping; } else if (event==11) { /* all physical attributes */ base->object->gameflag = ob->gameflag; base->object->inertia = ob->inertia; base->object->formfactor = ob->formfactor; base->object->damping= ob->damping; base->object->rdamping= ob->rdamping; base->object->min_vel= ob->min_vel; base->object->max_vel= ob->max_vel; if (ob->gameflag & OB_BOUNDS) { base->object->collision_boundtype = ob->collision_boundtype; } base->object->margin= ob->margin; base->object->bsoft= copy_bulletsoftbody(ob->bsoft); } else if (event==17) { /* tex space */ copy_texture_space(base->object, ob); } else if (event==18) { /* font settings */ if (base->object->type==ob->type) { cu= ob->data; cu1= base->object->data; cu1->spacemode= cu->spacemode; cu1->spacing= cu->spacing; cu1->linedist= cu->linedist; cu1->shear= cu->shear; cu1->fsize= cu->fsize; cu1->xof= cu->xof; cu1->yof= cu->yof; cu1->textoncurve= cu->textoncurve; cu1->wordspace= cu->wordspace; cu1->ulpos= cu->ulpos; cu1->ulheight= cu->ulheight; if (cu1->vfont) cu1->vfont->id.us--; cu1->vfont= cu->vfont; id_us_plus((ID *)cu1->vfont); if (cu1->vfontb) cu1->vfontb->id.us--; cu1->vfontb= cu->vfontb; id_us_plus((ID *)cu1->vfontb); if (cu1->vfonti) cu1->vfonti->id.us--; cu1->vfonti= cu->vfonti; id_us_plus((ID *)cu1->vfonti); if (cu1->vfontbi) cu1->vfontbi->id.us--; cu1->vfontbi= cu->vfontbi; id_us_plus((ID *)cu1->vfontbi); BKE_text_to_curve(bmain, scene, base->object, 0); /* needed? */ BLI_strncpy(cu1->family, cu->family, sizeof(cu1->family)); base->object->recalc |= OB_RECALC_DATA; } } else if (event==19) { /* bevel settings */ if (ELEM(base->object->type, OB_CURVE, OB_FONT)) { cu= ob->data; cu1= base->object->data; cu1->bevobj= cu->bevobj; cu1->taperobj= cu->taperobj; cu1->width= cu->width; cu1->bevresol= cu->bevresol; cu1->ext1= cu->ext1; cu1->ext2= cu->ext2; base->object->recalc |= OB_RECALC_DATA; } } else if (event==25) { /* curve resolution */ if (ELEM(base->object->type, OB_CURVE, OB_FONT)) { cu= ob->data; cu1= base->object->data; cu1->resolu= cu->resolu; cu1->resolu_ren= cu->resolu_ren; nu= cu1->nurb.first; while (nu) { nu->resolu= cu1->resolu; nu= nu->next; } base->object->recalc |= OB_RECALC_DATA; } } else if (event==21) { if (base->object->type==OB_MESH) { ModifierData *md = modifiers_findByType(ob, eModifierType_Subsurf); if (md) { ModifierData *tmd = modifiers_findByType(base->object, eModifierType_Subsurf); if (!tmd) { tmd = modifier_new(eModifierType_Subsurf); BLI_addtail(&base->object->modifiers, tmd); } modifier_copyData(md, tmd); base->object->recalc |= OB_RECALC_DATA; } } } else if (event==22) { /* Copy the constraint channels over */ copy_constraints(&base->object->constraints, &ob->constraints, TRUE); do_scene_sort= 1; } else if (event==23) { base->object->softflag= ob->softflag; if (base->object->soft) sbFree(base->object->soft); base->object->soft= copy_softbody(ob->soft); if (!modifiers_findByType(base->object, eModifierType_Softbody)) { BLI_addhead(&base->object->modifiers, modifier_new(eModifierType_Softbody)); } } else if (event==26) { #if 0 // XXX old animation system copy_nlastrips(&base->object->nlastrips, &ob->nlastrips); #endif // XXX old animation system } else if (event==27) { /* autosmooth */ if (base->object->type==OB_MESH) { Mesh *me= ob->data; Mesh *cme= base->object->data; cme->smoothresh= me->smoothresh; if (me->flag & ME_AUTOSMOOTH) cme->flag |= ME_AUTOSMOOTH; else cme->flag &= ~ME_AUTOSMOOTH; } } else if (event==28) { /* UV orco */ if (ELEM(base->object->type, OB_CURVE, OB_SURF)) { cu= ob->data; cu1= base->object->data; if (cu->flag & CU_UV_ORCO) cu1->flag |= CU_UV_ORCO; else cu1->flag &= ~CU_UV_ORCO; } } else if (event==29) { /* protected bits */ base->object->protectflag= ob->protectflag; } else if (event==30) { /* index object */ base->object->index= ob->index; } else if (event==31) { /* object color */ copy_v4_v4(base->object->col, ob->col); } } } } if (do_scene_sort) DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); }
Object* DocumentImporter::create_instance_node(Object *source_ob, COLLADAFW::Node *source_node, COLLADAFW::Node *instance_node, Scene *sce, Object *par_ob, bool is_library_node) { Object *obn = copy_object(source_ob); obn->recalc |= OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME; scene_add_base(sce, obn); if (instance_node) { anim_importer.read_node_transform(instance_node, obn); // if we also have a source_node (always ;), take its // transformation matrix and apply it to the newly instantiated // object to account for node hierarchy transforms in // .dae if(source_node) { COLLADABU::Math::Matrix4 mat4 = source_node->getTransformationMatrix(); COLLADABU::Math::Matrix4 bmat4 = mat4.transpose(); // transpose to get blender row-major order float mat[4][4]; for (int i = 0; i < 4; i++) { for (int j = 0; j < 4; j++) { mat[i][j] = bmat4[i][j]; } } // calc new matrix and apply mul_m4_m4m4(obn->obmat, mat, obn->obmat); object_apply_mat4(obn, obn->obmat, 0, 0); } } else { anim_importer.read_node_transform(source_node, obn); } DAG_scene_sort(CTX_data_main(mContext), sce); DAG_ids_flush_update(CTX_data_main(mContext), 0); COLLADAFW::NodePointerArray &children = source_node->getChildNodes(); if (children.getCount()) { for (unsigned int i = 0; i < children.getCount(); i++) { COLLADAFW::Node *child_node = children[i]; const COLLADAFW::UniqueId& child_id = child_node->getUniqueId(); if (object_map.find(child_id) == object_map.end()) continue; COLLADAFW::InstanceNodePointerArray &inodes = child_node->getInstanceNodes(); Object *new_child = NULL; if (inodes.getCount()) { // \todo loop through instance nodes const COLLADAFW::UniqueId& id = inodes[0]->getInstanciatedObjectId(); new_child = create_instance_node(object_map[id], node_map[id], child_node, sce, NULL, is_library_node); } else { new_child = create_instance_node(object_map[child_id], child_node, NULL, sce, NULL, is_library_node); } bc_set_parent(new_child, obn, mContext, true); if (is_library_node) libnode_ob.push_back(new_child); } } // when we have an instance_node, don't return the object, because otherwise // its correct location gets overwritten in write_node(). Fixes bug #26012. if(instance_node) { if (par_ob && obn) bc_set_parent(obn, par_ob, mContext); return NULL; } else return obn; }
void DocumentImporter::finish() { if(mImportStage!=General) return; /** TODO Break up and put into 2-pass parsing of DAE */ std::vector<const COLLADAFW::VisualScene*>::iterator it; for (it = vscenes.begin(); it != vscenes.end(); it++) { PointerRNA sceneptr, unit_settings; PropertyRNA *system, *scale; // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it Scene *sce = CTX_data_scene(mContext); // for scene unit settings: system, scale_length RNA_id_pointer_create(&sce->id, &sceneptr); unit_settings = RNA_pointer_get(&sceneptr, "unit_settings"); system = RNA_struct_find_property(&unit_settings, "system"); scale = RNA_struct_find_property(&unit_settings, "scale_length"); switch(unit_converter.isMetricSystem()) { case UnitConverter::Metric: RNA_property_enum_set(&unit_settings, system, USER_UNIT_METRIC); break; case UnitConverter::Imperial: RNA_property_enum_set(&unit_settings, system, USER_UNIT_IMPERIAL); break; default: RNA_property_enum_set(&unit_settings, system, USER_UNIT_NONE); break; } RNA_property_float_set(&unit_settings, scale, unit_converter.getLinearMeter()); const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes(); for (unsigned int i = 0; i < roots.getCount(); i++) { write_node(roots[i], NULL, sce, NULL, false); } } armature_importer.set_tags_map(this->uid_tags_map); armature_importer.make_armatures(mContext); #if 0 armature_importer.fix_animation(); #endif for (std::vector<const COLLADAFW::VisualScene*>::iterator it = vscenes.begin(); it != vscenes.end(); it++) { const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes(); for (unsigned int i = 0; i < roots.getCount(); i++) translate_anim_recursive(roots[i],NULL,NULL); } if (libnode_ob.size()) { Scene *sce = CTX_data_scene(mContext); fprintf(stderr, "got %d library nodes to free\n", (int)libnode_ob.size()); // free all library_nodes std::vector<Object*>::iterator it; for (it = libnode_ob.begin(); it != libnode_ob.end(); it++) { Object *ob = *it; Base *base = object_in_scene(ob, sce); if (base) { BLI_remlink(&sce->base, base); free_libblock_us(&G.main->object, base->object); if (sce->basact==base) sce->basact= NULL; MEM_freeN(base); } } libnode_ob.clear(); DAG_scene_sort(CTX_data_main(mContext), sce); DAG_ids_flush_update(CTX_data_main(mContext), 0); } }
static int parent_drop_invoke(bContext *C, wmOperator *op, wmEvent *event) { Object *par = NULL; Object *ob = NULL; SpaceOops *soops = CTX_wm_space_outliner(C); ARegion *ar = CTX_wm_region(C); Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); TreeElement *te = NULL; TreeElement *te_found = NULL; char childname[MAX_ID_NAME]; char parname[MAX_ID_NAME]; int partype = 0; float fmval[2]; UI_view2d_region_to_view(&ar->v2d, event->mval[0], event->mval[1], &fmval[0], &fmval[1]); /* Find object hovered over */ for (te = soops->tree.first; te; te = te->next) { te_found = outliner_dropzone_parent(C, event, te, fmval); if (te_found) break; } if (te_found) { RNA_string_set(op->ptr, "parent", te_found->name); /* Identify parent and child */ RNA_string_get(op->ptr, "child", childname); ob = (Object *)BKE_libblock_find_name(ID_OB, childname); RNA_string_get(op->ptr, "parent", parname); par = (Object *)BKE_libblock_find_name(ID_OB, parname); if (ELEM(NULL, ob, par)) { if (par == NULL) printf("par==NULL\n"); return OPERATOR_CANCELLED; } if (ob == par) { return OPERATOR_CANCELLED; } /* check dragged object (child) is active */ if (ob != CTX_data_active_object(C)) ED_base_object_select(BKE_scene_base_find(scene, ob), BA_SELECT); if ((par->type != OB_ARMATURE) && (par->type != OB_CURVE) && (par->type != OB_LATTICE)) { if (ED_object_parent_set(op->reports, bmain, scene, ob, par, partype)) { DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, NULL); WM_event_add_notifier(C, NC_OBJECT | ND_PARENT, NULL); } } else { /* Menu creation */ uiPopupMenu *pup = uiPupMenuBegin(C, IFACE_("Set Parent To"), ICON_NONE); uiLayout *layout = uiPupMenuLayout(pup); PointerRNA ptr; WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_OBJECT); /* Cannot use uiItemEnumO()... have multiple properties to set. */ uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_("Object"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); /* par becomes parent, make the associated menus */ if (par->type == OB_ARMATURE) { WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_ARMATURE); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_("Armature Deform"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_ARMATURE_NAME); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_(" With Empty Groups"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_ARMATURE_ENVELOPE); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_(" With Envelope Weights"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_ARMATURE_AUTO); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_(" With Automatic Weights"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_BONE); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_("Bone"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); } else if (par->type == OB_CURVE) { WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_CURVE); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_("Curve Deform"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_FOLLOW); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_("Follow Path"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_PATH_CONST); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_("Path Constraint"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); } else if (par->type == OB_LATTICE) { WM_operator_properties_create(&ptr, "OUTLINER_OT_parent_drop"); RNA_string_set(&ptr, "parent", parname); RNA_string_set(&ptr, "child", childname); RNA_enum_set(&ptr, "type", PAR_LATTICE); uiItemFullO(layout, "OUTLINER_OT_parent_drop", IFACE_("Lattice Deform"), 0, ptr.data, WM_OP_EXEC_DEFAULT, 0); } uiPupMenuEnd(C, pup); return OPERATOR_CANCELLED; } } else { return OPERATOR_CANCELLED; } return OPERATOR_FINISHED; }
static int add_keyingset_button_exec (bContext *C, wmOperator *op) { Main *bmain= CTX_data_main(C); Scene *scene= CTX_data_scene(C); KeyingSet *ks = NULL; PropertyRNA *prop= NULL; PointerRNA ptr= {{NULL}}; char *path = NULL; short success= 0; int index=0, pflag=0; int all= RNA_boolean_get(op->ptr, "all"); /* verify the Keying Set to use: * - use the active one for now (more control over this can be added later) * - add a new one if it doesn't exist */ if (scene->active_keyingset == 0) { short flag=0, keyingflag=0; /* validate flags * - absolute KeyingSets should be created by default */ flag |= KEYINGSET_ABSOLUTE; keyingflag |= ANIM_get_keyframing_flags(scene, 0); if (IS_AUTOKEY_FLAG(scene, XYZ2RGB)) keyingflag |= INSERTKEY_XYZ2RGB; /* call the API func, and set the active keyingset index */ ks= BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", flag, keyingflag); scene->active_keyingset= BLI_countlist(&scene->keyingsets); } else if (scene->active_keyingset < 0) { BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in Keying Set"); return OPERATOR_CANCELLED; } else ks= BLI_findlink(&scene->keyingsets, scene->active_keyingset-1); /* try to add to keyingset using property retrieved from UI */ uiContextActiveProperty(C, &ptr, &prop, &index); /* check if property is able to be added */ if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) { path= RNA_path_from_ID_to_property(&ptr, prop); if (path) { /* set flags */ if (all) { pflag |= KSP_FLAG_WHOLE_ARRAY; /* we need to set the index for this to 0, even though it may break in some cases, this is * necessary if we want the entire array for most cases to get included without the user * having to worry about where they clicked */ index= 0; } /* add path to this setting */ BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME); ks->active_path= BLI_countlist(&ks->paths); success= 1; /* free the temp path created */ MEM_freeN(path); } } if (success) { /* send updates */ DAG_ids_flush_update(bmain, 0); /* for now, only send ND_KEYS for KeyingSets */ WM_event_add_notifier(C, NC_SCENE|ND_KEYINGSET, NULL); } return (success)? OPERATOR_FINISHED: OPERATOR_CANCELLED; }
static int outliner_animdata_operation_exec(bContext *C, wmOperator *op) { SpaceOops *soops= CTX_wm_space_outliner(C); int scenelevel=0, objectlevel=0, idlevel=0, datalevel=0; eOutliner_AnimDataOps event; short updateDeps = 0; /* check for invalid states */ if (soops == NULL) return OPERATOR_CANCELLED; event= RNA_enum_get(op->ptr, "type"); set_operation_types(soops, &soops->tree, &scenelevel, &objectlevel, &idlevel, &datalevel); if (datalevel != TSE_ANIM_DATA) return OPERATOR_CANCELLED; /* perform the core operation */ switch (event) { case OUTLINER_ANIMOP_SET_ACT: /* delegate once again... */ WM_operator_name_call(C, "OUTLINER_OT_action_set", WM_OP_INVOKE_REGION_WIN, NULL); break; case OUTLINER_ANIMOP_CLEAR_ACT: /* clear active action - using standard rules */ outliner_do_data_operation(soops, datalevel, event, &soops->tree, unlinkact_animdata_cb); WM_event_add_notifier(C, NC_ANIMATION|ND_NLA_ACTCHANGE, NULL); ED_undo_push(C, "Unlink action"); break; case OUTLINER_ANIMOP_REFRESH_DRV: outliner_do_data_operation(soops, datalevel, event, &soops->tree, refreshdrivers_animdata_cb); WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN, NULL); //ED_undo_push(C, "Refresh Drivers"); /* no undo needed - shouldn't have any impact? */ updateDeps = 1; break; case OUTLINER_ANIMOP_CLEAR_DRV: outliner_do_data_operation(soops, datalevel, event, &soops->tree, cleardrivers_animdata_cb); WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN, NULL); ED_undo_push(C, "Clear Drivers"); updateDeps = 1; break; default: // invalid break; } /* update dependencies */ if (updateDeps) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); /* rebuild depsgraph for the new deps */ DAG_scene_sort(bmain, scene); /* force an update of depsgraph */ DAG_ids_flush_update(bmain, 0); } return OPERATOR_FINISHED; }
void SkinInfo::link_armature(bContext *C, Object *ob, std::map<COLLADAFW::UniqueId, COLLADAFW::Node*>& joint_by_uid, TransformReader *tm) { Main *bmain = CTX_data_main(C); Scene *scene = CTX_data_scene(C); ModifierData *md = ED_object_modifier_add(NULL, bmain, scene, ob, NULL, eModifierType_Armature); ((ArmatureModifierData *)md)->object = ob_arm; copy_m4_m4(ob->obmat, bind_shape_matrix); object_apply_mat4(ob, ob->obmat, 0, 0); #if 1 bc_set_parent(ob, ob_arm, C); #else Object workob; ob->parent = ob_arm; ob->partype = PAROBJECT; what_does_parent(scene, ob, &workob); invert_m4_m4(ob->parentinv, workob.obmat); ob->recalc |= OB_RECALC_OB|OB_RECALC_DATA; DAG_scene_sort(bmain, scene); DAG_ids_flush_update(bmain, 0); WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL); #endif ((bArmature*)ob_arm->data)->deformflag = ARM_DEF_VGROUP; // create all vertex groups std::vector<JointData>::iterator it; int joint_index; for (it = joint_data.begin(), joint_index = 0; it != joint_data.end(); it++, joint_index++) { const char *name = "Group"; // skip joints that have invalid UID if ((*it).joint_uid == COLLADAFW::UniqueId::INVALID) continue; // name group by joint node name if (joint_by_uid.find((*it).joint_uid) != joint_by_uid.end()) { name = bc_get_joint_name(joint_by_uid[(*it).joint_uid]); } ED_vgroup_add_name(ob, (char*)name); } // <vcount> - number of joints per vertex - joints_per_vertex // <v> - [[bone index, weight index] * joints per vertex] * vertices - weight indices // ^ bone index can be -1 meaning weight toward bind shape, how to express this in Blender? // for each vertex in weight indices // for each bone index in vertex // add vertex to group at group index // treat group index -1 specially // get def group by index with BLI_findlink for (unsigned int vertex = 0, weight = 0; vertex < joints_per_vertex.getCount(); vertex++) { unsigned int limit = weight + joints_per_vertex[vertex]; for ( ; weight < limit; weight++) { int joint = joint_indices[weight], joint_weight = weight_indices[weight]; // -1 means "weight towards the bind shape", we just don't assign it to any group if (joint != -1) { bDeformGroup *def = (bDeformGroup*)BLI_findlink(&ob->defbase, joint); ED_vgroup_vert_add(ob, def, vertex, weights[joint_weight], WEIGHT_REPLACE); } } } }