/**************************** registration **********************************/ void ED_operatortypes_mesh(void) { WM_operatortype_append(MESH_OT_select_all); WM_operatortype_append(MESH_OT_select_interior_faces); WM_operatortype_append(MESH_OT_select_more); WM_operatortype_append(MESH_OT_select_less); WM_operatortype_append(MESH_OT_select_non_manifold); WM_operatortype_append(MESH_OT_select_linked); WM_operatortype_append(MESH_OT_select_linked_pick); WM_operatortype_append(MESH_OT_select_random); WM_operatortype_append(MESH_OT_hide); WM_operatortype_append(MESH_OT_reveal); WM_operatortype_append(MESH_OT_select_by_number_vertices); WM_operatortype_append(MESH_OT_select_loose_verts); WM_operatortype_append(MESH_OT_select_mirror); WM_operatortype_append(MESH_OT_normals_make_consistent); WM_operatortype_append(MESH_OT_merge); WM_operatortype_append(MESH_OT_subdivide); WM_operatortype_append(MESH_OT_faces_select_linked_flat); WM_operatortype_append(MESH_OT_edges_select_sharp); WM_operatortype_append(MESH_OT_primitive_plane_add); WM_operatortype_append(MESH_OT_primitive_cube_add); WM_operatortype_append(MESH_OT_primitive_circle_add); WM_operatortype_append(MESH_OT_primitive_cylinder_add); WM_operatortype_append(MESH_OT_primitive_cone_add); WM_operatortype_append(MESH_OT_primitive_grid_add); WM_operatortype_append(MESH_OT_primitive_monkey_add); WM_operatortype_append(MESH_OT_primitive_uv_sphere_add); WM_operatortype_append(MESH_OT_primitive_ico_sphere_add); WM_operatortype_append(MESH_OT_duplicate); WM_operatortype_append(MESH_OT_remove_doubles); WM_operatortype_append(MESH_OT_spin); WM_operatortype_append(MESH_OT_screw); WM_operatortype_append(MESH_OT_extrude_region); WM_operatortype_append(MESH_OT_extrude_faces_indiv); WM_operatortype_append(MESH_OT_extrude_edges_indiv); WM_operatortype_append(MESH_OT_extrude_verts_indiv); WM_operatortype_append(MESH_OT_split); WM_operatortype_append(MESH_OT_extrude_repeat); WM_operatortype_append(MESH_OT_edge_rotate); WM_operatortype_append(MESH_OT_select_vertex_path); WM_operatortype_append(MESH_OT_loop_to_region); WM_operatortype_append(MESH_OT_region_to_loop); WM_operatortype_append(MESH_OT_select_axis); WM_operatortype_append(MESH_OT_uvs_rotate); WM_operatortype_append(MESH_OT_uvs_reverse); WM_operatortype_append(MESH_OT_colors_rotate); WM_operatortype_append(MESH_OT_colors_reverse); WM_operatortype_append(MESH_OT_fill); WM_operatortype_append(MESH_OT_beautify_fill); WM_operatortype_append(MESH_OT_quads_convert_to_tris); WM_operatortype_append(MESH_OT_tris_convert_to_quads); WM_operatortype_append(MESH_OT_dissolve); WM_operatortype_append(MESH_OT_dissolve_limited); WM_operatortype_append(MESH_OT_faces_shade_smooth); WM_operatortype_append(MESH_OT_faces_shade_flat); WM_operatortype_append(MESH_OT_sort_elements); WM_operatortype_append(MESH_OT_delete); WM_operatortype_append(MESH_OT_edge_collapse); WM_operatortype_append(MESH_OT_edge_collapse_loop); WM_operatortype_append(MESH_OT_separate); WM_operatortype_append(MESH_OT_dupli_extrude_cursor); WM_operatortype_append(MESH_OT_loop_select); WM_operatortype_append(MESH_OT_edge_face_add); WM_operatortype_append(MESH_OT_select_shortest_path); WM_operatortype_append(MESH_OT_select_similar); WM_operatortype_append(MESH_OT_loop_multi_select); WM_operatortype_append(MESH_OT_mark_seam); WM_operatortype_append(MESH_OT_mark_sharp); WM_operatortype_append(MESH_OT_vertices_smooth); WM_operatortype_append(MESH_OT_noise); WM_operatortype_append(MESH_OT_flip_normals); //WM_operatortype_append(MESH_OT_knife_cut); WM_operatortype_append(MESH_OT_rip); WM_operatortype_append(MESH_OT_blend_from_shape); WM_operatortype_append(MESH_OT_shape_propagate_to_all); WM_operatortype_append(MESH_OT_uv_texture_add); WM_operatortype_append(MESH_OT_uv_texture_remove); WM_operatortype_append(MESH_OT_vertex_color_add); WM_operatortype_append(MESH_OT_vertex_color_remove); WM_operatortype_append(MESH_OT_sticky_add); WM_operatortype_append(MESH_OT_sticky_remove); WM_operatortype_append(MESH_OT_drop_named_image); WM_operatortype_append(MESH_OT_edgering_select); WM_operatortype_append(MESH_OT_loopcut); WM_operatortype_append(MESH_OT_solidify); WM_operatortype_append(MESH_OT_select_nth); WM_operatortype_append(MESH_OT_vert_connect); WM_operatortype_append(MESH_OT_vert_slide); WM_operatortype_append(MESH_OT_knife_tool); WM_operatortype_append(MESH_OT_bevel); WM_operatortype_append(MESH_OT_select_next_loop); WM_operatortype_append(MESH_OT_bridge_edge_loops); WM_operatortype_append(MESH_OT_inset); WM_operatortype_append(MESH_OT_wireframe); WM_operatortype_append(MESH_OT_edge_split); WM_operatortype_append(MESH_OT_convex_hull); #ifdef WITH_GAMEENGINE WM_operatortype_append(MESH_OT_navmesh_make); WM_operatortype_append(MESH_OT_navmesh_face_copy); WM_operatortype_append(MESH_OT_navmesh_face_add); WM_operatortype_append(MESH_OT_navmesh_reset); WM_operatortype_append(MESH_OT_navmesh_clear); #endif } #if 0 /* UNUSED, remove? */ static int ED_operator_editmesh_face_select(bContext *C) { Object *obedit = CTX_data_edit_object(C); if (obedit && obedit->type == OB_MESH) { BMEditMesh *em = BMEdit_FromObject(obedit); if (em && em->selectmode & SCE_SELECT_FACE) { return 1; } } return 0; }
int ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit) { if (sima && (ED_space_image_show_render(sima) || ED_space_image_show_paint(sima))) return 0; if (obedit && obedit->type == OB_MESH) { struct BMEditMesh *em = BMEdit_FromObject(obedit); int ret; ret = EDBM_mtexpoly_check(em); return ret; } return 0; }
static void make_prim_finish(bContext *C, int *state, int enter_editmode) { Object *obedit = CTX_data_edit_object(C); BMEditMesh *em = BMEdit_FromObject(obedit); /* Primitive has all verts selected, use vert select flush * to push this up to edges & faces. */ EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX); EDBM_update_generic(C, em, TRUE); /* userdef */ if (*state && !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); }
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 = BMEdit_FromObject(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, "Vertex select - Shift-Click for multiple modes"); 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, "Edge select - Shift-Click for multiple modes"); 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, "Face select - Shift-Click for multiple modes"); } }
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 ED_object_enter_editmode(bContext *C, int flag) { Scene *scene= CTX_data_scene(C); Base *base= NULL; Object *ob; ScrArea *sa= CTX_wm_area(C); View3D *v3d= NULL; int ok= 0; if (scene->id.lib) return; if (sa && sa->spacetype==SPACE_VIEW3D) v3d= sa->spacedata.first; if ((flag & EM_IGNORE_LAYER)==0) { base= CTX_data_active_base(C); /* active layer checked here for view3d */ if (base==NULL) return; else if (v3d && (base->lay & v3d->lay)==0) return; else if (!v3d && (base->lay & scene->lay)==0) return; } else { base= scene->basact; } if (ELEM3(NULL, base, base->object, base->object->data)) return; ob = base->object; if (object_data_is_libdata(ob)) { error_libdata(); return; } if (flag & EM_WAITCURSOR) waitcursor(1); ob->restore_mode = ob->mode; /* note, when switching scenes the object can have editmode data but * not be scene->obedit: bug 22954, this avoids calling self eternally */ if ((ob->restore_mode & OB_MODE_EDIT)==0) ED_object_toggle_modes(C, ob->mode); ob->mode= OB_MODE_EDIT; if (ob->type==OB_MESH) { BMEditMesh *em; ok= 1; scene->obedit = ob; /* context sees this */ EDBM_mesh_make(CTX_data_tool_settings(C), scene, ob); em = BMEdit_FromObject(ob); if (LIKELY(em)) { /* order doesn't matter */ EDBM_mesh_normals_update(em); BMEdit_RecalcTessellation(em); BM_mesh_select_mode_flush(em->bm); } WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MESH, scene); } else if (ob->type==OB_ARMATURE) { bArmature *arm= base->object->data; if (!arm) return; /* * The function object_data_is_libdata make a problem here, the * check for ob->proxy return 0 and let blender enter to edit mode * this causes a crash when you try leave the edit mode. * The problem is that i can't remove the ob->proxy check from * object_data_is_libdata that prevent the bugfix #6614, so * i add this little hack here. */ if (arm->id.lib) { error_libdata(); return; } ok=1; scene->obedit= ob; ED_armature_to_edit(ob); /* to ensure all goes in restposition and without striding */ DAG_id_tag_update(&ob->id, OB_RECALC_OB|OB_RECALC_DATA|OB_RECALC_TIME); // XXX: should this be OB_RECALC_DATA? WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_ARMATURE, scene); } else if (ob->type==OB_FONT) { scene->obedit= ob; // XXX for context ok= 1; make_editText(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_TEXT, scene); } else if (ob->type==OB_MBALL) { scene->obedit= ob; // XXX for context ok= 1; make_editMball(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_MBALL, scene); } else if (ob->type==OB_LATTICE) { scene->obedit= ob; // XXX for context ok= 1; make_editLatt(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_LATTICE, scene); } else if (ob->type==OB_SURF || ob->type==OB_CURVE) { ok= 1; scene->obedit= ob; // XXX for context make_editNurb(ob); WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_EDITMODE_CURVE, scene); } if (ok) { DAG_id_tag_update(&ob->id, OB_RECALC_DATA); } else { scene->obedit= NULL; // XXX for context ob->mode &= ~OB_MODE_EDIT; WM_event_add_notifier(C, NC_SCENE|ND_MODE|NS_MODE_OBJECT, scene); } if (flag & EM_DO_UNDO) ED_undo_push(C, "Enter Editmode"); if (flag & EM_WAITCURSOR) waitcursor(0); }
static void vertex_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *ob_iter; Mesh *me = par->data; Base *base = NULL; DerivedMesh *dm; VertexDupliData vdd; Scene *sce = NULL; Group *group = NULL; GroupObject *go = NULL; BMEditMesh *em; float vec[3], no[3], pmat[4][4]; int totvert, a, oblay; unsigned int lay; copy_m4_m4(pmat, par->obmat); /* simple preventing of too deep nested groups */ if (level > MAX_DUPLI_RECUR) return; em = BMEdit_FromObject(par); if (em) { dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); } else dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); if (flag & DUPLILIST_FOR_RENDER) { vdd.orco = (float(*)[3])BKE_mesh_orco_verts_get(par); BKE_mesh_orco_verts_transform(me, vdd.orco, me->totvert, 0); } else vdd.orco = NULL; totvert = dm->getNumVerts(dm); /* having to loop on scene OR group objects is NOT FUN */ if (GS(id->name) == ID_SCE) { sce = (Scene *)id; lay = sce->lay; base = sce->base.first; } else { group = (Group *)id; lay = group->layer; go = group->gobject.first; } /* Start looping on Scene OR Group objects */ while (base || go) { if (sce) { ob_iter = base->object; oblay = base->lay; } else { ob_iter = go->ob; oblay = ob_iter->lay; } if (lay & oblay && scene->obedit != ob_iter) { ob = ob_iter->parent; while (ob) { if (ob == par) { ob = ob_iter; /* End Scene/Group object loop, below is generic */ /* par_space_mat - only used for groups so we can modify the space dupli's are in * when par_space_mat is NULL ob->obmat can be used instead of ob__obmat */ if (par_space_mat) mult_m4_m4m4(vdd.obmat, par_space_mat, ob->obmat); else copy_m4_m4(vdd.obmat, ob->obmat); vdd.id = id; vdd.level = level; vdd.flag = flag; vdd.lb = lb; vdd.ob = ob; vdd.scene = scene; vdd.par = par; copy_m4_m4(vdd.pmat, pmat); vdd.persistent_id = persistent_id; /* mballs have a different dupli handling */ if (ob->type != OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ if (me->edit_btmesh) { dm->foreachMappedVert(dm, vertex_dupli__mapFunc, (void *) &vdd); } else { for (a = 0; a < totvert; a++) { dm->getVertCo(dm, a, vec); dm->getVertNo(dm, a, no); vertex_dupli__mapFunc(&vdd, a, vec, no, NULL); } } if (sce) { /* Set proper layer in case of scene looping, * in case of groups the object layer will be * changed when it's duplicated due to the * group duplication. */ ob->lay = vdd.par->lay; } break; } ob = ob->parent; } } if (sce) base = base->next; /* scene loop */ else go = go->next; /* group loop */ } if (vdd.orco) MEM_freeN(vdd.orco); dm->release(dm); }
static void face_duplilist(ListBase *lb, ID *id, Scene *scene, Object *par, float par_space_mat[4][4], int persistent_id[MAX_DUPLI_RECUR], int level, short flag) { Object *ob, *ob_iter; Base *base = NULL; DupliObject *dob; DerivedMesh *dm; Mesh *me = par->data; MLoopUV *mloopuv; MPoly *mpoly, *mp; MLoop *mloop; MVert *mvert; float pmat[4][4], imat[3][3], (*orco)[3] = NULL, w; int lay, oblay, totface, a; Scene *sce = NULL; Group *group = NULL; GroupObject *go = NULL; BMEditMesh *em; float ob__obmat[4][4]; /* needed for groups where the object matrix needs to be modified */ /* simple preventing of too deep nested groups */ if (level > MAX_DUPLI_RECUR) return; copy_m4_m4(pmat, par->obmat); em = BMEdit_FromObject(par); if (em) { dm = editbmesh_get_derived_cage(scene, par, em, CD_MASK_BAREMESH); } else { dm = mesh_get_derived_deform(scene, par, CD_MASK_BAREMESH); } totface = dm->getNumPolys(dm); mpoly = dm->getPolyArray(dm); mloop = dm->getLoopArray(dm); mvert = dm->getVertArray(dm); if (flag & DUPLILIST_FOR_RENDER) { orco = (float(*)[3])BKE_mesh_orco_verts_get(par); BKE_mesh_orco_verts_transform(me, orco, me->totvert, 0); mloopuv = me->mloopuv; } else { orco = NULL; mloopuv = NULL; } /* having to loop on scene OR group objects is NOT FUN */ if (GS(id->name) == ID_SCE) { sce = (Scene *)id; lay = sce->lay; base = sce->base.first; } else { group = (Group *)id; lay = group->layer; go = group->gobject.first; } /* Start looping on Scene OR Group objects */ while (base || go) { if (sce) { ob_iter = base->object; oblay = base->lay; } else { ob_iter = go->ob; oblay = ob_iter->lay; } if (lay & oblay && scene->obedit != ob_iter) { ob = ob_iter->parent; while (ob) { if (ob == par) { ob = ob_iter; /* End Scene/Group object loop, below is generic */ /* par_space_mat - only used for groups so we can modify the space dupli's are in * when par_space_mat is NULL ob->obmat can be used instead of ob__obmat */ if (par_space_mat) mult_m4_m4m4(ob__obmat, par_space_mat, ob->obmat); else copy_m4_m4(ob__obmat, ob->obmat); copy_m3_m4(imat, ob->parentinv); /* mballs have a different dupli handling */ if (ob->type != OB_MBALL) ob->flag |= OB_DONE; /* doesnt render */ for (a = 0, mp = mpoly; a < totface; a++, mp++) { int mv1; int mv2; int mv3; /* int mv4; */ /* UNUSED */ float *v1; float *v2; float *v3; /* float *v4; */ /* UNUSED */ float cent[3], quat[4], mat[3][3], mat3[3][3], tmat[4][4], obmat[4][4]; float f_no[3]; MLoop *loopstart = mloop + mp->loopstart; if (UNLIKELY(mp->totloop < 3)) { continue; } else { BKE_mesh_calc_poly_normal(mp, mloop + mp->loopstart, mvert, f_no); v1 = mvert[(mv1 = loopstart[0].v)].co; v2 = mvert[(mv2 = loopstart[1].v)].co; v3 = mvert[(mv3 = loopstart[2].v)].co; } /* translation */ BKE_mesh_calc_poly_center(mp, loopstart, mvert, cent); mul_m4_v3(pmat, cent); sub_v3_v3v3(cent, cent, pmat[3]); add_v3_v3(cent, ob__obmat[3]); copy_m4_m4(obmat, ob__obmat); copy_v3_v3(obmat[3], cent); /* rotation */ tri_to_quat_ex(quat, v1, v2, v3, f_no); quat_to_mat3(mat, quat); /* scale */ if (par->transflag & OB_DUPLIFACES_SCALE) { float size = BKE_mesh_calc_poly_area(mp, loopstart, mvert, f_no); size = sqrtf(size) * par->dupfacesca; mul_m3_fl(mat, size); } copy_m3_m3(mat3, mat); mul_m3_m3m3(mat, imat, mat3); copy_m4_m4(tmat, obmat); mul_m4_m4m3(obmat, tmat, mat); dob = new_dupli_object(lb, ob, obmat, par->lay, persistent_id, level, a, OB_DUPLIFACES, (flag & DUPLILIST_ANIMATED)); if (flag & DUPLILIST_FOR_RENDER) { w = 1.0f / (float)mp->totloop; if (orco) { int j; for (j = 0; j < mpoly->totloop; j++) { madd_v3_v3fl(dob->orco, orco[loopstart[j].v], w); } } if (mloopuv) { int j; for (j = 0; j < mpoly->totloop; j++) { madd_v2_v2fl(dob->orco, mloopuv[loopstart[j].v].uv, w); } } } if (ob->transflag & OB_DUPLI) { float tmpmat[4][4]; copy_m4_m4(tmpmat, ob->obmat); copy_m4_m4(ob->obmat, obmat); /* pretend we are really this mat */ object_duplilist_recursive((ID *)id, scene, ob, lb, ob->obmat, persistent_id, level + 1, a, flag); copy_m4_m4(ob->obmat, tmpmat); } } break; } ob = ob->parent; } } if (sce) base = base->next; /* scene loop */ else go = go->next; /* group loop */ } if (orco) MEM_freeN(orco); dm->release(dm); }