static void group_linkobs2scene_cb(bContext *UNUSED(C), Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { Group *group = (Group *)tselem->id; GroupObject *gob; Base *base; for (gob = group->gobject.first; gob; gob = gob->next) { base = BKE_scene_base_find(scene, gob->ob); if (base) { base->object->flag |= SELECT; base->flag |= SELECT; } else { /* link to scene */ base = MEM_callocN(sizeof(Base), "add_base"); BLI_addhead(&scene->base, base); base->lay = gob->ob->lay; gob->ob->flag |= SELECT; base->flag = gob->ob->flag; base->object = gob->ob; id_lib_extern((ID *)gob->ob); /* in case these are from a linked group */ } } }
static void libblock_remap_data_preprocess(IDRemap *r_id_remap_data) { switch (GS(r_id_remap_data->id->name)) { case ID_SCE: { Scene *sce = (Scene *)r_id_remap_data->id; if (!r_id_remap_data->new_id) { const bool is_indirect = (sce->id.lib != NULL); const bool skip_indirect = (r_id_remap_data->flag & ID_REMAP_SKIP_INDIRECT_USAGE) != 0; /* In case we are unlinking... */ if (!r_id_remap_data->old_id) { /* ... everything from scene. */ Base *base, *base_next; for (base = sce->base.first; base; base = base_next) { base_next = base->next; libblock_remap_data_preprocess_scene_base_unlink( r_id_remap_data, sce, base, skip_indirect, is_indirect); } } else if (GS(r_id_remap_data->old_id->name) == ID_OB) { /* ... a specific object from scene. */ Object *old_ob = (Object *)r_id_remap_data->old_id; Base *base = BKE_scene_base_find(sce, old_ob); if (base) { libblock_remap_data_preprocess_scene_base_unlink( r_id_remap_data, sce, base, skip_indirect, is_indirect); } } } break; } case ID_OB: { ID *old_id = r_id_remap_data->old_id; if (!old_id || GS(old_id->name) == ID_AR) { Object *ob = (Object *)r_id_remap_data->id; /* Object's pose holds reference to armature bones... sic */ /* Note that in theory, we should have to bother about linked/non-linked/never-null/etc. flags/states. * Fortunately, this is just a tag, so we can accept to 'over-tag' a bit for pose recalc, and avoid * another complex and risky condition nightmare like the one we have in * foreach_libblock_remap_callback()... */ if (ob->pose && (!old_id || ob->data == old_id)) { BLI_assert(ob->type == OB_ARMATURE); ob->pose->flag |= POSE_RECALC; /* We need to clear pose bone pointers immediately, things like undo writefile may be called * before pose is actually recomputed, can lead to segfault... */ BKE_pose_clear_pointers(ob->pose); } } break; } default: break; } }
void object_toggle_renderability_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { Base *base = (Base *)te->directdata; if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id); if (base) { base->object->restrictflag ^= OB_RESTRICT_RENDER; } }
static int tree_element_set_active_object(bContext *C, Scene *scene, SpaceOops *soops, TreeElement *te, int set, bool recursive) { TreeStoreElem *tselem = TREESTORE(te); Scene *sce; Base *base; Object *ob = NULL; /* if id is not object, we search back */ if (te->idcode == ID_OB) { ob = (Object *)tselem->id; } else { ob = (Object *)outliner_search_back(soops, te, ID_OB); if (ob == OBACT) return 0; } if (ob == NULL) return 0; sce = (Scene *)outliner_search_back(soops, te, ID_SCE); if (sce && scene != sce) { ED_screen_set_scene(C, CTX_wm_screen(C), sce); scene = sce; } /* find associated base in current scene */ base = BKE_scene_base_find(scene, ob); if (base) { if (set == 2) { /* swap select */ if (base->flag & SELECT) ED_base_object_select(base, BA_DESELECT); else ED_base_object_select(base, BA_SELECT); } else { /* deleselect all */ BKE_scene_base_deselect_all(scene); ED_base_object_select(base, BA_SELECT); } if (recursive) { /* Recursive select/deselect for Object hierarchies */ do_outliner_object_select_recursive(scene, ob, (ob->flag & SELECT) != 0); } if (C) { ED_base_object_activate(C, base); /* adds notifier */ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } } if (ob != scene->obedit) ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); return 1; }
static void object_deselect_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { Base *base = (Base *)te->directdata; if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id); if (base) { base->flag &= ~SELECT; base->object->flag &= ~SELECT; } }
static void object_select_cb(bContext *UNUSED(C), Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { Base *base = (Base *)te->directdata; if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id); if (base && ((base->object->restrictflag & OB_RESTRICT_VIEW) == 0)) { base->flag |= SELECT; base->object->flag |= SELECT; } }
void object_toggle_visibility_cb(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { Base *base = (Base *)te->directdata; Object *ob = (Object *)tselem->id; /* add check for edit mode */ if (!common_restrict_check(C, ob)) return; if (base || (base = BKE_scene_base_find(scene, ob))) { if ((base->object->restrictflag ^= OB_RESTRICT_VIEW)) { ED_base_object_select(base, BA_DESELECT); } } }
static void object_delete_cb(bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { Base *base = (Base *)te->directdata; if (base == NULL) base = BKE_scene_base_find(scene, (Object *)tselem->id); if (base) { // check also library later if (scene->obedit == base->object) ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); ED_base_object_free_and_unlink(CTX_data_main(C), scene, base); te->directdata = NULL; tselem->id = NULL; } }
static int parent_clear_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event)) { Scene *scene = CTX_data_scene(C); Object *ob = NULL; char obname[MAX_ID_NAME]; RNA_string_get(op->ptr, "dragged_obj", obname); ob = (Object *)BKE_libblock_find_name(ID_OB, obname); /* 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); ED_object_parent_clear(C, RNA_enum_get(op->ptr, "type")); return OPERATOR_FINISHED; }
static int tree_element_active_pose(bContext *C, Scene *scene, TreeElement *UNUSED(te), TreeStoreElem *tselem, int set) { Object *ob = (Object *)tselem->id; Base *base = BKE_scene_base_find(scene, ob); if (set) { if (scene->obedit) ED_object_exit_editmode(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); if (ob->mode & OB_MODE_POSE) ED_armature_exit_posemode(C, base); else ED_armature_enter_posemode(C, base); } else { if (ob->mode & OB_MODE_POSE) return 1; } return 0; }
static void object_delete_hierarchy_cb( bContext *C, Scene *scene, TreeElement *te, TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem) { Base *base = (Base *)te->directdata; Object *obedit = scene->obedit; if (!base) { base = BKE_scene_base_find(scene, (Object *)tselem->id); } if (base) { /* Check also library later. */ for (; obedit && (obedit != base->object); obedit = obedit->parent); if (obedit == base->object) { ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); } outline_delete_hierarchy(C, scene, base); te->directdata = NULL; tselem->id = NULL; } WM_event_add_notifier(C, NC_SCENE | ND_OB_ACTIVE, scene); }
static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool camera) { ListBase *markers = ED_context_get_markers(C); ARegion *ar = CTX_wm_region(C); View2D *v2d = UI_view2d_fromcontext(C); float viewx; int x, y, cfra; if (markers == NULL) return OPERATOR_PASS_THROUGH; x = event->x - ar->winrct.xmin; y = event->y - ar->winrct.ymin; UI_view2d_region_to_view(v2d, x, y, &viewx, NULL); cfra = ED_markers_find_nearest_marker_time(markers, viewx); if (extend) select_timeline_marker_frame(markers, cfra, 1); else select_timeline_marker_frame(markers, cfra, 0); #ifdef DURIAN_CAMERA_SWITCH if (camera) { Scene *scene = CTX_data_scene(C); Base *base; TimeMarker *marker; int sel = 0; if (!extend) BKE_scene_base_deselect_all(scene); for (marker = markers->first; marker; marker = marker->next) { if (marker->frame == cfra) { sel = (marker->flag & SELECT); break; } } for (marker = markers->first; marker; marker = marker->next) { if (marker->camera) { if (marker->frame == cfra) { base = BKE_scene_base_find(scene, marker->camera); if (base) { ED_base_object_select(base, sel); if (sel) ED_base_object_activate(C, base); } } } } WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } #else (void)camera; #endif WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL); WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL); /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails... [#25987] */ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH; }
void DocumentImporter::finish() { if (mImportStage != General) return; Main *bmain = CTX_data_main(mContext); // TODO: create a new scene except the selected <visual_scene> - use current blender scene for it Scene *sce = CTX_data_scene(mContext); unit_converter.calculate_scale(*sce); std::vector<Object *> *objects_to_scale = new std::vector<Object *>(); /** 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; // 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"); if (this->import_settings->import_units) { 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; } float unit_factor = unit_converter.getLinearMeter(); RNA_property_float_set(&unit_settings, scale, unit_factor); fprintf(stdout, "Collada: Adjusting Blender units to Importset units: %f.\n", unit_factor); } // Write nodes to scene const COLLADAFW::NodePointerArray& roots = (*it)->getRootNodes(); for (unsigned int i = 0; i < roots.getCount(); i++) { std::vector<Object *> *objects_done = write_node(roots[i], NULL, sce, NULL, false); objects_to_scale->insert(objects_to_scale->end(), objects_done->begin(), objects_done->end()); delete objects_done; } // update scene DAG_relations_tag_update(bmain); WM_event_add_notifier(mContext, NC_OBJECT | ND_TRANSFORM, NULL); } mesh_importer.optimize_material_assignements(); armature_importer.set_tags_map(this->uid_tags_map); armature_importer.make_armatures(mContext); armature_importer.make_shape_keys(); DAG_relations_tag_update(bmain); #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 = BKE_scene_base_find(sce, ob); if (base) { BLI_remlink(&sce->base, base); BKE_libblock_free_us(G.main, base->object); if (sce->basact == base) sce->basact = NULL; MEM_freeN(base); } } libnode_ob.clear(); DAG_relations_tag_update(bmain); } bc_match_scale(objects_to_scale, unit_converter, !this->import_settings->import_units); delete objects_to_scale; }
static int do_outliner_item_activate(bContext *C, Scene *scene, ARegion *ar, SpaceOops *soops, TreeElement *te, int extend, const float mval[2]) { if (mval[1] > te->ys && mval[1] < te->ys + UI_UNIT_Y) { TreeStoreElem *tselem = TREESTORE(te); int openclose = 0; /* open close icon */ if ((te->flag & TE_ICONROW) == 0) { // hidden icon, no open/close if (mval[0] > te->xs && mval[0] < te->xs + UI_UNIT_X) openclose = 1; } if (openclose) { /* all below close/open? */ if (extend) { tselem->flag &= ~TSE_CLOSED; outliner_set_flag(soops, &te->subtree, TSE_CLOSED, !outliner_has_one_flag(soops, &te->subtree, TSE_CLOSED, 1)); } else { if (tselem->flag & TSE_CLOSED) tselem->flag &= ~TSE_CLOSED; else tselem->flag |= TSE_CLOSED; } return 1; } /* name and first icon */ else if (mval[0] > te->xs + UI_UNIT_X && mval[0] < te->xend) { /* always makes active object */ if (tselem->type != TSE_SEQUENCE && tselem->type != TSE_SEQ_STRIP && tselem->type != TSE_SEQUENCE_DUP) tree_element_set_active_object(C, scene, soops, te, 1 + (extend != 0 && tselem->type == 0)); if (tselem->type == 0) { // the lib blocks /* editmode? */ if (te->idcode == ID_SCE) { if (scene != (Scene *)tselem->id) { ED_screen_set_scene(C, CTX_wm_screen(C), (Scene *)tselem->id); } } else if (te->idcode == ID_GR) { Group *gr = (Group *)tselem->id; GroupObject *gob; if (extend) { int sel = BA_SELECT; for (gob = gr->gobject.first; gob; gob = gob->next) { if (gob->ob->flag & SELECT) { sel = BA_DESELECT; break; } } for (gob = gr->gobject.first; gob; gob = gob->next) { ED_base_object_select(BKE_scene_base_find(scene, gob->ob), sel); } } else { BKE_scene_base_deselect_all(scene); for (gob = gr->gobject.first; gob; gob = gob->next) { if ((gob->ob->flag & SELECT) == 0) ED_base_object_select(BKE_scene_base_find(scene, gob->ob), BA_SELECT); } } WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene); } else if (ELEM5(te->idcode, ID_ME, ID_CU, ID_MB, ID_LT, ID_AR)) { WM_operator_name_call(C, "OBJECT_OT_editmode_toggle", WM_OP_INVOKE_REGION_WIN, NULL); } else { // rest of types tree_element_active(C, scene, soops, te, 1); } } else tree_element_type_active(C, scene, soops, te, tselem, 1 + (extend != 0)); return 1; } } for (te = te->subtree.first; te; te = te->next) { if (do_outliner_item_activate(C, scene, ar, soops, te, extend, mval)) return 1; } return 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; }