static Object *make_prim_init(bContext *C, const char *idname, float *dia, float mat[4][4], bool *was_editmode, const float loc[3], const float rot[3], const unsigned int layer) { Object *obedit = CTX_data_edit_object(C); *was_editmode = false; if (obedit == NULL || obedit->type != OB_MESH) { obedit = ED_object_add_type(C, OB_MESH, loc, rot, false, layer); rename_id((ID *)obedit, idname); rename_id((ID *)obedit->data, idname); /* create editmode */ ED_object_editmode_enter(C, EM_DO_UNDO | EM_IGNORE_LAYER); /* rare cases the active layer is messed up */ *was_editmode = true; } *dia = ED_object_new_primitive_matrix(C, obedit, loc, rot, mat, false); return obedit; }
static int lattice_select_more_less(bContext *C, const bool select) { Object *obedit = CTX_data_edit_object(C); Lattice *lt = ((Lattice *)obedit->data)->editlatt->latt; BPoint *bp; const int tot = lt->pntsu * lt->pntsv * lt->pntsw; int u, v, w; BLI_bitmap *selpoints; lt->actbp = LT_ACTBP_NONE; selpoints = BLI_BITMAP_NEW(tot, __func__); BKE_lattice_bitmap_from_flag(lt, selpoints, SELECT, false, false); bp = lt->def; for (w = 0; w < lt->pntsw; w++) { for (v = 0; v < lt->pntsv; v++) { for (u = 0; u < lt->pntsu; u++) { if ((bp->hide == 0) && (((bp->f1 & SELECT) == 0) == select)) { if (lattice_test_bitmap_uvw(lt, selpoints, u + 1, v, w, select) || lattice_test_bitmap_uvw(lt, selpoints, u - 1, v, w, select) || lattice_test_bitmap_uvw(lt, selpoints, u, v + 1, w, select) || lattice_test_bitmap_uvw(lt, selpoints, u, v - 1, w, select) || lattice_test_bitmap_uvw(lt, selpoints, u, v, w + 1, select) || lattice_test_bitmap_uvw(lt, selpoints, u, v, w - 1, select)) { BKE_BIT_TEST_SET(bp->f1, select, SELECT); } } bp++; } } } MEM_freeN(selpoints); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); return OPERATOR_FINISHED; }
void ED_undo_push(bContext *C, const char *str) { wmWindowManager *wm= CTX_wm_manager(C); Object *obedit= CTX_data_edit_object(C); Object *obact= CTX_data_active_object(C); if(obedit) { if (U.undosteps == 0) return; if(obedit->type==OB_MESH) undo_push_mesh(C, str); else if ELEM(obedit->type, OB_CURVE, OB_SURF) undo_push_curve(C, str); else if (obedit->type==OB_FONT) undo_push_font(C, str); else if (obedit->type==OB_MBALL) undo_push_mball(C, str); else if (obedit->type==OB_LATTICE) undo_push_lattice(C, str); else if (obedit->type==OB_ARMATURE) undo_push_armature(C, str); }
static int select_nth_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); struct CheckerIntervalParams op_params; WM_operator_properties_checker_interval_from_op(op, &op_params); if (!ed_curve_select_nth(obedit->data, &op_params)) { if (obedit->type == OB_SURF) { BKE_report(op->reports, RPT_ERROR, "Surface has not got active point"); } else { BKE_report(op->reports, RPT_ERROR, "Curve has not got active point"); } return OPERATOR_CANCELLED; } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); return OPERATOR_FINISHED; }
/* 1= an undo, -1 is a redo. we have to make sure 'curundo' remains at current situation */ void undo_editmode_step(bContext *C, int step) { Object *obedit= CTX_data_edit_object(C); /* prevent undo to happen on wrong object, stack can be a mix */ undo_clean_stack(C); if(step==0) { undo_restore(curundo, curundo->getdata(C)); } else if(step==1) { if(curundo==NULL || curundo->prev==NULL) error("No more steps to undo"); else { if(G.f & G_DEBUG) printf("undo %s\n", curundo->name); curundo= curundo->prev; undo_restore(curundo, curundo->getdata(C)); } } else { /* curundo has to remain current situation! */ if(curundo==NULL || curundo->next==NULL) error("No more steps to redo"); else { undo_restore(curundo->next, curundo->getdata(C)); curundo= curundo->next; if(G.f & G_DEBUG) printf("redo %s\n", curundo->name); } } /* special case for editmesh, mode must be copied back to the scene */ if(obedit->type == OB_MESH) { EM_selectmode_to_scene(CTX_data_scene(C), obedit); } DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); /* XXX notifiers */ }
/* helper to remove clean other objects from undo stack */ static void undo_clean_stack(bContext *C) { UndoElem *uel, *next; Object *obedit= CTX_data_edit_object(C); /* global undo changes pointers, so we also allow identical names */ /* side effect: when deleting/renaming object and start editing new one with same name */ uel= undobase.first; while(uel) { void *editdata= uel->getdata(C); int isvalid= 0; next= uel->next; /* for when objects are converted, renamed, or global undo changes pointers... */ if(uel->type==obedit->type) { if(strcmp(uel->id.name, obedit->id.name)==0) { if(uel->validate_undo==NULL) isvalid= 1; else if(uel->validate_undo(uel->undodata, editdata)) isvalid= 1; } } if(isvalid) uel->ob= obedit; else { if(uel == curundo) curundo= NULL; uel->freedata(uel->undodata); BLI_freelinkN(&undobase, uel); } uel= next; } if(curundo == NULL) curundo= undobase.last; }
static void make_prim_ext(bContext *C, float *loc, float *rot, int enter_editmode, unsigned int layer, int type, int tot, int seg, int subdiv, float dia, float depth, int ext, int fill) { Object *obedit= CTX_data_edit_object(C); int newob = 0; float mat[4][4]; float scale; if(obedit==NULL || obedit->type!=OB_MESH) { obedit= ED_object_add_type(C, OB_MESH, loc, rot, FALSE, layer); rename_id((ID *)obedit, get_mesh_defname(type)); rename_id((ID *)obedit->data, get_mesh_defname(type)); /* create editmode */ ED_object_enter_editmode(C, EM_DO_UNDO|EM_IGNORE_LAYER); /* rare cases the active layer is messed up */ newob = 1; } else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); scale= ED_object_new_primitive_matrix(C, obedit, loc, rot, mat); dia *= scale; depth *= scale * 0.5f; make_prim(obedit, type, mat, tot, seg, subdiv, dia, depth, ext, fill); DAG_id_tag_update(obedit->data, 0); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); /* userdef */ if (newob && !enter_editmode) { ED_object_exit_editmode(C, EM_FREEDATA); /* adding EM_DO_UNDO messes up operator redo */ } WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); }
static int get_undo_system(bContext *C) { Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); ScrArea *sa = CTX_wm_area(C); /* first check for editor undo */ if (sa && (sa->spacetype == SPACE_IMAGE)) { SpaceImage *sima = (SpaceImage *)sa->spacedata.first; if ((obact && (obact->mode & OB_MODE_TEXTURE_PAINT)) || (sima->mode == SI_MODE_PAINT)) { if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE)) return UNDOSYSTEM_IMAPAINT; } } /* find out which undo system */ if (obedit) { if (OB_TYPE_SUPPORT_EDITMODE(obedit->type)) { return UNDOSYSTEM_EDITMODE; } } else { Object *obact = CTX_data_active_object(C); if (obact) { if (obact->mode & OB_MODE_PARTICLE_EDIT) return UNDOSYSTEM_PARTICLE; else if (obact->mode & OB_MODE_TEXTURE_PAINT) { if (!ED_undo_paint_empty(UNDO_PAINT_IMAGE)) return UNDOSYSTEM_IMAPAINT; } } if (U.uiflag & USER_GLOBALUNDO) return UNDOSYSTEM_GLOBAL; } return 0; }
static int select_row_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); Curve *cu = obedit->data; ListBase *editnurb = object_editcurve_get(obedit); static BPoint *last = NULL; static int direction = 0; Nurb *nu = NULL; BPoint *bp = NULL; int u = 0, v = 0, a, b; if (!BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bp)) return OPERATOR_CANCELLED; if (last == bp) { direction = 1 - direction; BKE_nurbList_flag_set(editnurb, 0); } last = bp; u = cu->actvert % nu->pntsu; v = cu->actvert / nu->pntsu; bp = nu->bp; for (a = 0; a < nu->pntsv; a++) { for (b = 0; b < nu->pntsu; b++, bp++) { if (direction) { if (a == v) select_bpoint(bp, SELECT, SELECT, VISIBLE); } else { if (b == u) select_bpoint(bp, SELECT, SELECT, VISIBLE); } } } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); return OPERATOR_FINISHED; }
static int armature_select_similar_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); bArmature *arm = obedit->data; EditBone *ebone_act = CTX_data_active_bone(C); /* Get props */ int type = RNA_enum_get(op->ptr, "type"); float thresh = RNA_float_get(op->ptr, "threshold"); /* Check for active bone */ if (ebone_act == NULL) { BKE_report(op->reports, RPT_ERROR, "Operation requires an active bone"); return OPERATOR_CANCELLED; } switch (type) { case SIMEDBONE_LENGTH: select_similar_length(arm, ebone_act, thresh); break; case SIMEDBONE_DIRECTION: select_similar_direction(arm, ebone_act, thresh); break; case SIMEDBONE_PREFIX: select_similar_prefix(arm, ebone_act); break; case SIMEDBONE_SUFFIX: select_similar_suffix(arm, ebone_act); break; case SIMEDBONE_LAYER: select_similar_layer(arm, ebone_act); break; } WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); return OPERATOR_FINISHED; }
void ED_undo_push(bContext *C, const char *str) { Object *obedit = CTX_data_edit_object(C); Object *obact = CTX_data_active_object(C); if (G.debug & G_DEBUG) printf("%s: %s\n", __func__, str); if (obedit) { if (U.undosteps == 0) return; if (obedit->type == OB_MESH) undo_push_mesh(C, str); else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) undo_push_curve(C, str); else if (obedit->type == OB_FONT) undo_push_font(C, str); else if (obedit->type == OB_MBALL) undo_push_mball(C, str); else if (obedit->type == OB_LATTICE) undo_push_lattice(C, str); else if (obedit->type == OB_ARMATURE) undo_push_armature(C, str); } else if (obact && obact->mode & OB_MODE_PARTICLE_EDIT) { if (U.undosteps == 0) return; PE_undo_push(CTX_data_scene(C), str); } else if (obact && obact->mode & OB_MODE_SCULPT) { /* do nothing for now */ } else { BKE_undo_write(C, str); } WM_file_tag_modified(C); }
/* Duplicate selected MetaElements */ static int duplicate_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); MetaBall *mb = (MetaBall *)obedit->data; MetaElem *ml, *newml; ml = mb->editelems->last; if (ml) { while (ml) { if (ml->flag & SELECT) { newml = MEM_dupallocN(ml); BLI_addtail(mb->editelems, newml); mb->lastelem = newml; ml->flag &= ~SELECT; } ml = ml->prev; } WM_event_add_notifier(C, NC_GEOM | ND_DATA, mb); DAG_id_tag_update(obedit->data, 0); } return OPERATOR_FINISHED; }
/* Delete all selected MetaElems (not MetaBall) */ static int delete_metaelems_exec(bContext *C, wmOperator *UNUSED(op)) { Object *obedit = CTX_data_edit_object(C); MetaBall *mb = (MetaBall *)obedit->data; MetaElem *ml, *next; ml = mb->editelems->first; if (ml) { while (ml) { next = ml->next; if (ml->flag & SELECT) { if (mb->lastelem == ml) mb->lastelem = NULL; BLI_remlink(mb->editelems, ml); MEM_freeN(ml); } ml = next; } WM_event_add_notifier(C, NC_GEOM | ND_DATA, mb); DAG_id_tag_update(obedit->data, 0); } return OPERATOR_FINISHED; }
/* only editmode! */ static int armature_delete_selected_exec(bContext *C, wmOperator *UNUSED(op)) { bArmature *arm; EditBone *curBone, *ebone_next; Object *obedit = CTX_data_edit_object(C); bool changed = false; arm = obedit->data; /* cancel if nothing selected */ if (CTX_DATA_COUNT(C, selected_bones) == 0) return OPERATOR_CANCELLED; armature_select_mirrored(arm); BKE_pose_channels_remove(obedit, armature_delete_ebone_cb, arm); for (curBone = arm->edbo->first; curBone; curBone = ebone_next) { ebone_next = curBone->next; if (arm->layer & curBone->layer) { if (curBone->flag & BONE_SELECTED) { if (curBone == arm->act_edbone) arm->act_edbone = NULL; ED_armature_ebone_remove(arm, curBone); changed = true; } } } if (!changed) return OPERATOR_CANCELLED; ED_armature_edit_sync_selection(arm->edbo); BKE_pose_tag_recalc(CTX_data_main(C), obedit->pose); WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, obedit); return OPERATOR_FINISHED; }
int CTX_data_mode_enum(const bContext *C) { Object *obedit= CTX_data_edit_object(C); if(obedit) { switch(obedit->type) { case OB_MESH: return CTX_MODE_EDIT_MESH; case OB_CURVE: return CTX_MODE_EDIT_CURVE; case OB_SURF: return CTX_MODE_EDIT_SURFACE; case OB_FONT: return CTX_MODE_EDIT_TEXT; case OB_ARMATURE: return CTX_MODE_EDIT_ARMATURE; case OB_MBALL: return CTX_MODE_EDIT_METABALL; case OB_LATTICE: return CTX_MODE_EDIT_LATTICE; } } else { Object *ob = CTX_data_active_object(C); if(ob) { if(ob->mode & OB_MODE_POSE) return CTX_MODE_POSE; else if(ob->mode & OB_MODE_SCULPT) return CTX_MODE_SCULPT; else if(ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT; else if(ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX; else if(ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE; else if(ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE; } } return CTX_MODE_OBJECT; }
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal) { Object *obedit = CTX_data_edit_object(C); Scene *scene = CTX_data_scene(C); BMEditMesh *em = BKE_editmesh_from_object(obedit); BevelData *opdata; if (em->bm->totvertsel == 0) { return false; } op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator"); opdata->em = em; opdata->is_modal = is_modal; opdata->shift_factor = -1.0f; initNumInput(&opdata->num_input); opdata->num_input.idx_max = 0; opdata->num_input.val_flag[0] |= NUM_NO_NEGATIVE; opdata->num_input.unit_sys = scene->unit.system; opdata->num_input.unit_type[0] = B_UNIT_NONE; /* Not sure this is a factor or a unit? */ /* avoid the cost of allocating a bm copy */ if (is_modal) { View3D *v3d = CTX_wm_view3d(C); ARegion *ar = CTX_wm_region(C); opdata->mesh_backup = EDBM_redo_state_store(em); opdata->draw_handle_pixel = ED_region_draw_cb_activate(ar->type, ED_region_draw_mouse_line_cb, opdata->mcenter, REGION_DRAW_POST_PIXEL); G.moving = G_TRANSFORM_EDIT; opdata->twtype = v3d->twtype; v3d->twtype = 0; } return true; }
static int object_armature_add_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); View3D *v3d= CTX_wm_view3d(C); RegionView3D *rv3d= CTX_wm_region_view3d(C); int newob= 0; int enter_editmode; unsigned int layer; float loc[3], rot[3]; object_add_generic_invoke_options(C, op); // XXX these props don't get set right when only exec() is called if(!ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer)) return OPERATOR_CANCELLED; if ((obedit==NULL) || (obedit->type != OB_ARMATURE)) { obedit= ED_object_add_type(C, OB_ARMATURE, loc, rot, TRUE, layer); ED_object_enter_editmode(C, 0); newob = 1; } else DAG_id_tag_update(&obedit->id, OB_RECALC_DATA); if(obedit==NULL) { BKE_report(op->reports, RPT_ERROR, "Cannot create editmode armature."); return OPERATOR_CANCELLED; } /* v3d and rv3d are allowed to be NULL */ add_primitive_bone(CTX_data_scene(C), v3d, rv3d); /* userdef */ if (newob && !enter_editmode) ED_object_exit_editmode(C, EM_FREEDATA); WM_event_add_notifier(C, NC_OBJECT|ND_DRAW, obedit); return OPERATOR_FINISHED; }
static int armature_dissolve_selected_exec(bContext *C, wmOperator *UNUSED(op)) { bArmature *arm; EditBone *ebone, *ebone_next; Object *obedit = CTX_data_edit_object(C); bool changed = false; /* store for mirror */ GHash *ebone_flag_orig = NULL; int ebone_num = 0; arm = obedit->data; for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { ebone->temp.p = NULL; ebone->flag &= ~BONE_DONE; ebone_num++; } if (arm->flag & ARM_MIRROR_EDIT) { GHashIterator gh_iter; ebone_flag_orig = BLI_ghash_ptr_new_ex(__func__, ebone_num); for (ebone = arm->edbo->first; ebone; ebone = ebone->next) { union { int flag; void *p; } val = {0}; val.flag = ebone->flag; BLI_ghash_insert(ebone_flag_orig, ebone, val.p); } armature_select_mirrored_ex(arm, BONE_SELECTED | BONE_ROOTSEL | BONE_TIPSEL); GHASH_ITER (gh_iter, ebone_flag_orig) { union { int flag; void *p; } *val_p = (void *)BLI_ghashIterator_getValue_p(&gh_iter); ebone = BLI_ghashIterator_getKey(&gh_iter); val_p->flag = ebone->flag & ~val_p->flag; } }
void uiTemplateEditModeSelection(uiLayout *layout, struct bContext *C) { Object *obedit = CTX_data_edit_object(C); uiBlock *block = uiLayoutGetBlock(layout); uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL); if (obedit && (obedit->type == OB_MESH)) { BMEditMesh *em = BKE_editmesh_from_object(obedit); uiLayout *row; row = uiLayoutRow(layout, true); block = uiLayoutGetBlock(row); uiDefIconButBitS(block, TOG, SCE_SELECT_VERTEX, B_SEL_VERT, ICON_VERTEXSEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Vertex select - Shift-Click for multiple modes, Ctrl-Click contracts selection")); uiDefIconButBitS(block, TOG, SCE_SELECT_EDGE, B_SEL_EDGE, ICON_EDGESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Edge select - Shift-Click for multiple modes, Ctrl-Click expands/contracts selection")); uiDefIconButBitS(block, TOG, SCE_SELECT_FACE, B_SEL_FACE, ICON_FACESEL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &em->selectmode, 1.0, 0.0, 0, 0, TIP_("Face select - Shift-Click for multiple modes, Ctrl-Click expands selection")); } }
static int add_primitive_cylinder_exec(bContext *C, wmOperator *op) { Object *obedit; Mesh *me; BMEditMesh *em; float loc[3], rot[3], mat[4][4], dia; int enter_editmode; int state, cap_end, cap_tri; unsigned int layer; cap_end = RNA_enum_get(op->ptr, "end_fill_type"); cap_tri = (cap_end == 2); ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL); make_prim_init(C, "Cylinder", &dia, mat, &state, loc, rot, layer); obedit = CTX_data_edit_object(C); me = obedit->data; em = me->edit_btmesh; if (!EDBM_op_call_and_selectf( em, op, "vertout", "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f mat=%m4", RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius"), RNA_float_get(op->ptr, "radius"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat)) { return OPERATOR_CANCELLED; } make_prim_finish(C, &state, enter_editmode); return OPERATOR_FINISHED; }
static int object_hook_remove_exec(bContext *C, wmOperator *op) { int num= RNA_enum_get(op->ptr, "modifier"); Object *ob=NULL; HookModifierData *hmd=NULL; ob = CTX_data_edit_object(C); hmd = (HookModifierData *)BLI_findlink(&ob->modifiers, num); if (!ob || !hmd) { BKE_report(op->reports, RPT_ERROR, "Couldn't find hook modifier"); return OPERATOR_CANCELLED; } /* remove functionality */ BLI_remlink(&ob->modifiers, (ModifierData *)hmd); modifier_free((ModifierData *)hmd); DAG_id_tag_update(&ob->id, OB_RECALC_DATA); WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob); return OPERATOR_FINISHED; }
/* flush any temp data from object editing to DNA before writing files, * rendering, copying, etc. */ void ED_editors_flush_edits(const bContext *C, bool for_render) { Object *obact = CTX_data_active_object(C); Object *obedit = CTX_data_edit_object(C); /* get editmode results */ if (obedit) ED_object_editmode_load(obedit); if (obact && (obact->mode & OB_MODE_SCULPT)) { /* flush multires changes (for sculpt) */ multires_force_update(obact); if (for_render) { /* flush changes from dynamic topology sculpt */ sculptsession_bm_to_me_for_render(obact); } else { /* Set reorder=false so that saving the file doesn't reorder * the BMesh's elements */ sculptsession_bm_to_me(obact, FALSE); } } }
static int navmesh_face_copy_exec(bContext *C, wmOperator *op) { Object *obedit= CTX_data_edit_object(C); EditMesh *em= BKE_mesh_get_editmesh((Mesh *)obedit->data); /* do work here */ EditFace *efa_act= EM_get_actFace(em, 0); if(efa_act) { if(CustomData_has_layer(&em->fdata, CD_RECAST)) { EditFace *efa; int targetPolyIdx= *(int*)CustomData_em_get(&em->fdata, efa_act->data, CD_RECAST); targetPolyIdx= targetPolyIdx>=0? targetPolyIdx : -targetPolyIdx; if(targetPolyIdx > 0) { /* set target poly idx to other selected faces */ for (efa= (EditFace *)em->faces.first; efa; efa= efa->next) { if((efa->f & SELECT) && efa != efa_act) { int* recastDataBlock= (int*)CustomData_em_get(&em->fdata, efa->data, CD_RECAST); *recastDataBlock= targetPolyIdx; } } } else { BKE_report(op->reports, RPT_ERROR, "Active face has no index set"); } } } DAG_id_tag_update((ID*)obedit->data, OB_RECALC_DATA); WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data); BKE_mesh_end_editmesh((Mesh*)obedit->data, em); return OPERATOR_FINISHED; }
/* Select or deselect all MetaElements */ static int mball_select_all_exec(bContext *C, wmOperator *op) { Object *obedit = CTX_data_edit_object(C); MetaBall *mb = (MetaBall *)obedit->data; MetaElem *ml; int action = RNA_enum_get(op->ptr, "action"); if (mb->editelems->first == NULL) return OPERATOR_CANCELLED; if (action == SEL_TOGGLE) { action = SEL_SELECT; for (ml = mb->editelems->first; ml; ml = ml->next) { if (ml->flag & SELECT) { action = SEL_DESELECT; break; } } } switch (action) { case SEL_SELECT: BKE_mball_select_all(mb); break; case SEL_DESELECT: BKE_mball_deselect_all(mb); break; case SEL_INVERT: BKE_mball_select_swap(mb); break; } WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); return OPERATOR_FINISHED; }
/* using context, starts job */ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *event) { /* new render clears all callbacks */ Main *mainp; Scene *scene = CTX_data_scene(C); SceneRenderLayer *srl = NULL; View3D *v3d = CTX_wm_view3d(C); Render *re; wmJob *wm_job; RenderJob *rj; Image *ima; int jobflag; const short is_animation = RNA_boolean_get(op->ptr, "animation"); const short is_write_still = RNA_boolean_get(op->ptr, "write_still"); struct Object *camera_override = v3d ? V3D_CAMERA_LOCAL(v3d) : NULL; const char *name; Object *active_object = CTX_data_active_object(C); /* only one render job at a time */ if (WM_jobs_test(CTX_wm_manager(C), scene, WM_JOB_TYPE_RENDER)) return OPERATOR_CANCELLED; if (!RE_is_rendering_allowed(scene, camera_override, op->reports)) { return OPERATOR_CANCELLED; } if (!is_animation && is_write_still && BKE_imtype_is_movie(scene->r.im_format.imtype)) { BKE_report(op->reports, RPT_ERROR, "Cannot write a single file with an animation format selected"); return OPERATOR_CANCELLED; } /* stop all running jobs, except screen one. currently previews frustrate Render */ WM_jobs_kill_all_except(CTX_wm_manager(C), CTX_wm_screen(C)); /* get main */ if (G.debug_value == 101) { /* thread-safety experiment, copy main from the undo buffer */ mainp = BKE_undo_get_main(&scene); } else mainp = CTX_data_main(C); /* cancel animation playback */ if (ED_screen_animation_playing(CTX_wm_manager(C))) ED_screen_animation_play(C, 0, 0); /* handle UI stuff */ WM_cursor_wait(1); /* flush multires changes (for sculpt) */ multires_force_render_update(active_object); /* flush changes from dynamic topology sculpt */ sculptsession_bm_to_me_for_render(active_object); /* cleanup sequencer caches before starting user triggered render. * otherwise, invalidated cache entries can make their way into * the output rendering. We can't put that into RE_BlenderFrame, * since sequence rendering can call that recursively... (peter) */ BKE_sequencer_cache_cleanup(); /* get editmode results */ ED_object_editmode_load(CTX_data_edit_object(C)); // store spare // get view3d layer, local layer, make this nice api call to render // store spare /* ensure at least 1 area shows result */ render_view_open(C, event->x, event->y); jobflag = WM_JOB_EXCL_RENDER | WM_JOB_PRIORITY | WM_JOB_PROGRESS; /* custom scene and single layer re-render */ screen_render_scene_layer_set(op, mainp, &scene, &srl); if (RNA_struct_property_is_set(op->ptr, "layer")) jobflag |= WM_JOB_SUSPEND; /* job custom data */ rj = MEM_callocN(sizeof(RenderJob), "render job"); rj->main = mainp; rj->scene = scene; rj->win = CTX_wm_window(C); rj->srl = srl; rj->camera_override = camera_override; rj->lay = scene->lay; rj->anim = is_animation; rj->write_still = is_write_still && !is_animation; rj->iuser.scene = scene; rj->iuser.ok = 1; rj->reports = op->reports; if (v3d) { rj->lay = v3d->lay; if (v3d->localvd) rj->lay |= v3d->localvd->lay; } /* setup job */ if (RE_seq_render_active(scene, &scene->r)) name = "Sequence Render"; else name = "Render"; wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, name, jobflag, WM_JOB_TYPE_RENDER); WM_jobs_customdata_set(wm_job, rj, render_freejob); WM_jobs_timer(wm_job, 0.2, NC_SCENE | ND_RENDER_RESULT, 0); WM_jobs_callbacks(wm_job, render_startjob, NULL, NULL, render_endjob); /* get a render result image, and make sure it is empty */ ima = BKE_image_verify_viewer(IMA_TYPE_R_RESULT, "Render Result"); BKE_image_signal(ima, NULL, IMA_SIGNAL_FREE); BKE_image_backup_render(rj->scene, ima); rj->image = ima; /* setup new render */ re = RE_NewRender(scene->id.name); RE_test_break_cb(re, rj, render_breakjob); RE_draw_lock_cb(re, rj, render_drawlock); RE_display_draw_cb(re, rj, image_rect_update); RE_stats_draw_cb(re, rj, image_renderinfo_cb); RE_progress_cb(re, rj, render_progress_update); rj->re = re; G.is_break = FALSE; /* store actual owner of job, so modal operator could check for it, * the reason of this is that active scene could change when rendering * several layers from compositor [#31800] */ op->customdata = scene; WM_jobs_start(CTX_wm_manager(C), wm_job); WM_cursor_wait(0); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, scene); /* we set G.is_rendering here already instead of only in the job, this ensure * main loop or other scene updates are disabled in time, since they may * have started before the job thread */ G.is_rendering = TRUE; /* add modal handler for ESC */ WM_event_add_modal_handler(C, op); return OPERATOR_RUNNING_MODAL; }
static void *get_data(bContext *C) { Object *obedit = CTX_data_edit_object(C); return metaball_get_editelems(obedit); }
/* Select MetaElement with mouse click (user can select radius circle or * stiffness circle) */ int mouse_mball(bContext *C, const int mval[2], int extend, int deselect, int toggle) { static MetaElem *startelem = NULL; Object *obedit = CTX_data_edit_object(C); ViewContext vc; MetaBall *mb = (MetaBall *)obedit->data; MetaElem *ml, *ml_act = NULL; int a, hits; unsigned int buffer[4 * MAXPICKBUF]; rcti rect; view3d_set_viewcontext(C, &vc); rect.xmin = mval[0] - 12; rect.xmax = mval[0] + 12; rect.ymin = mval[1] - 12; rect.ymax = mval[1] + 12; hits = view3d_opengl_select(&vc, buffer, MAXPICKBUF, &rect); /* does startelem exist? */ ml = mb->editelems->first; while (ml) { if (ml == startelem) break; ml = ml->next; } if (ml == NULL) startelem = mb->editelems->first; if (hits > 0) { ml = startelem; while (ml) { for (a = 0; a < hits; a++) { /* index converted for gl stuff */ if (ml->selcol1 == buffer[4 * a + 3]) { ml->flag |= MB_SCALE_RAD; ml_act = ml; } if (ml->selcol2 == buffer[4 * a + 3]) { ml->flag &= ~MB_SCALE_RAD; ml_act = ml; } } if (ml_act) break; ml = ml->next; if (ml == NULL) ml = mb->editelems->first; if (ml == startelem) break; } /* When some metaelem was found, then it is necessary to select or * deselect it. */ if (ml_act) { if (extend) { ml_act->flag |= SELECT; } else if (deselect) { ml_act->flag &= ~SELECT; } else if (toggle) { if (ml_act->flag & SELECT) ml_act->flag &= ~SELECT; else ml_act->flag |= SELECT; } else { /* Deselect all existing metaelems */ BKE_mball_deselect_all(mb); /* Select only metaelem clicked on */ ml_act->flag |= SELECT; } mb->lastelem = ml_act; WM_event_add_notifier(C, NC_GEOM | ND_SELECT, mb); return 1; } } return 0; }
/* function used for WM_OT_save_mainfile too */ static int wm_collada_export_exec(bContext *C, wmOperator *op) { char filepath[FILE_MAX]; int apply_modifiers; int export_mesh_type; int selected; int include_children; int include_armatures; int include_shapekeys; int deform_bones_only; int include_uv_textures; int include_material_textures; int use_texture_copies; int active_uv_only; int triangulate; int use_object_instantiation; int sort_by_name; int export_transformation_type; int open_sim; int export_count; if (!RNA_struct_property_is_set(op->ptr, "filepath")) { BKE_report(op->reports, RPT_ERROR, "No filename given"); return OPERATOR_CANCELLED; } RNA_string_get(op->ptr, "filepath", filepath); BLI_ensure_extension(filepath, sizeof(filepath), ".dae"); /* Avoid File write exceptions in Collada */ if (!BLI_exists(filepath)) { BLI_make_existing_file(filepath); if (!BLI_file_touch(filepath)) { BKE_report(op->reports, RPT_ERROR, "Can't create export file"); fprintf(stdout, "Collada export: Can not create: %s\n", filepath); return OPERATOR_CANCELLED; } } else if (!BLI_file_is_writable(filepath)) { BKE_report(op->reports, RPT_ERROR, "Can't overwrite export file"); fprintf(stdout, "Collada export: Can not modify: %s\n", filepath); return OPERATOR_CANCELLED; } /* Now the exporter can create and write the export file */ /* Options panel */ apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers"); export_mesh_type = RNA_enum_get(op->ptr, "export_mesh_type_selection"); selected = RNA_boolean_get(op->ptr, "selected"); include_children = RNA_boolean_get(op->ptr, "include_children"); include_armatures = RNA_boolean_get(op->ptr, "include_armatures"); include_shapekeys = RNA_boolean_get(op->ptr, "include_shapekeys"); deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only"); include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures"); include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures"); use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies"); active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only"); triangulate = RNA_boolean_get(op->ptr, "triangulate"); use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation"); sort_by_name = RNA_boolean_get(op->ptr, "sort_by_name"); export_transformation_type = RNA_enum_get(op->ptr, "export_transformation_type_selection"); open_sim = RNA_boolean_get(op->ptr, "open_sim"); /* get editmode results */ ED_object_editmode_load(CTX_data_edit_object(C)); export_count = collada_export(CTX_data_scene(C), filepath, apply_modifiers, export_mesh_type, selected, include_children, include_armatures, include_shapekeys, deform_bones_only, active_uv_only, include_uv_textures, include_material_textures, use_texture_copies, triangulate, use_object_instantiation, sort_by_name, export_transformation_type, open_sim); if (export_count == 0) { BKE_report(op->reports, RPT_WARNING, "Export file is empty"); return OPERATOR_CANCELLED; } else { char buff[100]; sprintf(buff, "Exported %d Objects", export_count); BKE_report(op->reports, RPT_INFO, buff); return OPERATOR_FINISHED; } }
static void do_view3d_header_buttons(bContext *C, void *UNUSED(arg), int event) { wmWindow *win = CTX_wm_window(C); ToolSettings *ts = CTX_data_tool_settings(C); ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = NULL; int ctrl = win->eventstate->ctrl, shift = win->eventstate->shift; PointerRNA props_ptr; if (obedit && obedit->type == OB_MESH) { em = BMEdit_FromObject(obedit); } /* watch it: if sa->win does not exist, check that when calling direct drawing routines */ switch (event) { case B_REDR: ED_area_tag_redraw(sa); break; case B_MODESELECT: WM_operator_properties_create(&props_ptr, "OBJECT_OT_mode_set"); RNA_enum_set(&props_ptr, "mode", v3d->modeselect); WM_operator_name_call(C, "OBJECT_OT_mode_set", WM_OP_EXEC_REGION_WIN, &props_ptr); WM_operator_properties_free(&props_ptr); break; case B_SEL_VERT: if (em) { if (shift == 0 || em->selectmode == 0) em->selectmode = SCE_SELECT_VERTEX; ts->selectmode = em->selectmode; EDBM_selectmode_set(em); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Vertex"); } break; case B_SEL_EDGE: if (em) { if (shift == 0 || em->selectmode == 0) { if ( (em->selectmode ^ SCE_SELECT_EDGE) == SCE_SELECT_VERTEX) { if (ctrl) EDBM_selectmode_convert(em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE); } em->selectmode = SCE_SELECT_EDGE; } ts->selectmode = em->selectmode; EDBM_selectmode_set(em); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Edge"); } break; case B_SEL_FACE: if (em) { if (shift == 0 || em->selectmode == 0) { if ( ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_VERTEX) || ((ts->selectmode ^ SCE_SELECT_FACE) == SCE_SELECT_EDGE)) { if (ctrl) EDBM_selectmode_convert(em, (ts->selectmode ^ SCE_SELECT_FACE), SCE_SELECT_FACE); } em->selectmode = SCE_SELECT_FACE; } ts->selectmode = em->selectmode; EDBM_selectmode_set(em); WM_event_add_notifier(C, NC_GEOM | ND_SELECT, obedit->data); ED_undo_push(C, "Selectmode Set: Face"); } break; case B_MAN_TRANS: if (shift == 0 || v3d->twtype == 0) { v3d->twtype = V3D_MANIP_TRANSLATE; } ED_area_tag_redraw(sa); break; case B_MAN_ROT: if (shift == 0 || v3d->twtype == 0) { v3d->twtype = V3D_MANIP_ROTATE; } ED_area_tag_redraw(sa); break; case B_MAN_SCALE: if (shift == 0 || v3d->twtype == 0) { v3d->twtype = V3D_MANIP_SCALE; } ED_area_tag_redraw(sa); break; case B_NDOF: ED_area_tag_redraw(sa); break; case B_MAN_MODE: ED_area_tag_redraw(sa); break; default: break; } }
void uiTemplateHeader3D(uiLayout *layout, struct bContext *C) { bScreen *screen = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); View3D *v3d = sa->spacedata.first; Scene *scene = CTX_data_scene(C); ToolSettings *ts = CTX_data_tool_settings(C); PointerRNA v3dptr, toolsptr, sceneptr; Object *ob = OBACT; Object *obedit = CTX_data_edit_object(C); uiBlock *block; uiBut *but; uiLayout *row; const float dpi_fac = UI_DPI_FAC; int is_paint = 0; RNA_pointer_create(&screen->id, &RNA_SpaceView3D, v3d, &v3dptr); RNA_pointer_create(&scene->id, &RNA_ToolSettings, ts, &toolsptr); RNA_pointer_create(&scene->id, &RNA_Scene, scene, &sceneptr); block = uiLayoutGetBlock(layout); uiBlockSetHandleFunc(block, do_view3d_header_buttons, NULL); /* other buttons: */ uiBlockSetEmboss(block, UI_EMBOSS); /* mode */ if (ob) { v3d->modeselect = ob->mode; is_paint = ELEM4(ob->mode, OB_MODE_SCULPT, OB_MODE_VERTEX_PAINT, OB_MODE_WEIGHT_PAINT, OB_MODE_TEXTURE_PAINT); } else { v3d->modeselect = OB_MODE_OBJECT; } row = uiLayoutRow(layout, TRUE); uiDefIconTextButS(block, MENU, B_MODESELECT, object_mode_icon(v3d->modeselect), view3d_modeselect_pup(scene), 0, 0, 126 * dpi_fac, UI_UNIT_Y, &(v3d->modeselect), 0, 0, 0, 0, TIP_("Mode")); /* Draw type */ uiItemR(layout, &v3dptr, "viewport_shade", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); if (obedit == NULL && is_paint) { /* Manipulators aren't used in paint modes */ if (!ELEM(ob->mode, OB_MODE_SCULPT, OB_MODE_PARTICLE_EDIT)) { /* masks aren't used for sculpt and particle painting */ PointerRNA meshptr; RNA_pointer_create(&ob->id, &RNA_Mesh, ob->data, &meshptr); if (ob->mode & (OB_MODE_TEXTURE_PAINT | OB_MODE_VERTEX_PAINT)) { uiItemR(layout, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } else { row = uiLayoutRow(layout, TRUE); uiItemR(row, &meshptr, "use_paint_mask", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); uiItemR(row, &meshptr, "use_paint_mask_vertex", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } } } else { const char *str_menu; row = uiLayoutRow(layout, TRUE); uiItemR(row, &v3dptr, "pivot_point", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); /* pose/object only however we want to allow in weight paint mode too * so don't be totally strict and just check not-editmode for now */ if (obedit == NULL) { uiItemR(row, &v3dptr, "use_pivot_point_align", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } /* Transform widget / manipulators */ row = uiLayoutRow(layout, TRUE); uiItemR(row, &v3dptr, "show_manipulator", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); block = uiLayoutGetBlock(row); if (v3d->twflag & V3D_USE_MANIPULATOR) { but = uiDefIconButBitC(block, TOG, V3D_MANIP_TRANSLATE, B_MAN_TRANS, ICON_MAN_TRANS, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Translate manipulator - Shift-Click for multiple modes")); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ but = uiDefIconButBitC(block, TOG, V3D_MANIP_ROTATE, B_MAN_ROT, ICON_MAN_ROT, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Rotate manipulator - Shift-Click for multiple modes")); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ but = uiDefIconButBitC(block, TOG, V3D_MANIP_SCALE, B_MAN_SCALE, ICON_MAN_SCALE, 0, 0, UI_UNIT_X, UI_UNIT_Y, &v3d->twtype, 1.0, 0.0, 0, 0, TIP_("Scale manipulator - Shift-Click for multiple modes")); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ } if (v3d->twmode > (BIF_countTransformOrientation(C) - 1) + V3D_MANIP_CUSTOM) { v3d->twmode = 0; } str_menu = BIF_menustringTransformOrientation(C, "Orientation"); but = uiDefButC(block, MENU, B_MAN_MODE, str_menu, 0, 0, 70 * dpi_fac, UI_UNIT_Y, &v3d->twmode, 0, 0, 0, 0, TIP_("Transform Orientation")); uiButClearFlag(but, UI_BUT_UNDO); /* skip undo on screen buttons */ MEM_freeN((void *)str_menu); } if (obedit == NULL && v3d->localvd == NULL) { unsigned int ob_lay = ob ? ob->lay : 0; /* Layers */ uiTemplateLayers(layout, v3d->scenelock ? &sceneptr : &v3dptr, "layers", &v3dptr, "layers_used", ob_lay); /* Scene lock */ uiItemR(layout, &v3dptr, "lock_camera_and_layers", UI_ITEM_R_ICON_ONLY, "", ICON_NONE); } uiTemplateEditModeSelection(layout, C); }