Exemplo n.º 1
0
static int add_primitive_cube_exec(bContext *C, wmOperator *op)
{
	Object *obedit;
	BMEditMesh *em;
	float loc[3], rot[3], mat[4][4], dia;
	bool enter_editmode;
	bool was_editmode;
	unsigned int layer;

	ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
	obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Cube"), &dia, mat, &was_editmode, loc, rot, layer);
	em = BKE_editmesh_from_object(obedit);

	if (!EDBM_op_call_and_selectf(
	        em, op, "verts.out", false,
	        "create_cube matrix=%m4 size=%f",
	        mat, RNA_float_get(op->ptr, "radius") * 2.0f))
	{
		return OPERATOR_CANCELLED;
	}

	/* BMESH_TODO make plane side this: M_SQRT2 - plane (diameter of 1.41 makes it unit size) */
	make_prim_finish(C, obedit, was_editmode, enter_editmode);

	return OPERATOR_FINISHED;
}
Exemplo n.º 2
0
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
{
	Object *obedit = CTX_data_edit_object(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.flag = NUM_NO_NEGATIVE;

	/* 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 = true;
		opdata->twtype = v3d->twtype;
		v3d->twtype = 0;
	}

	return true;
}
Exemplo n.º 3
0
static int add_primitive_monkey_exec(bContext *C, wmOperator *op)
{
	Object *obedit;
	BMEditMesh *em;
	float loc[3], rot[3], mat[4][4], dia;
	bool enter_editmode;
	bool is_view_aligned;
	unsigned int layer;
	bool was_editmode;

	ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, &is_view_aligned);
	if (!is_view_aligned)
		rot[0] += (float)M_PI / 2.0f;

	obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Suzanne"), &dia, mat, &was_editmode, loc, rot, layer);
	dia = RNA_float_get(op->ptr, "radius");
	mat[0][0] *= dia;
	mat[1][1] *= dia;
	mat[2][2] *= dia;

	em = BKE_editmesh_from_object(obedit);

	if (!EDBM_op_call_and_selectf(
	        em, op, "verts.out",  false,
	        "create_monkey matrix=%m4", mat))
	{
		return OPERATOR_CANCELLED;
	}

	make_prim_finish(C, obedit, was_editmode, enter_editmode);

	return OPERATOR_FINISHED;
}
Exemplo n.º 4
0
/**
 * Special hack for MESH_OT_loopcut_slide so we get back to the selection mode
 */
static void transformops_loopsel_hack(bContext *C, wmOperator *op)
{
	if (op->type->idname == OP_EDGE_SLIDE) {
		if (op->opm && op->opm->opm && op->opm->opm->prev) {
			wmOperator *op_prev = op->opm->opm->prev;
			Scene *scene = CTX_data_scene(C);
			int mesh_select_mode[3];
			PropertyRNA *prop = RNA_struct_find_property(op_prev->ptr, "mesh_select_mode_init");

			if (prop && RNA_property_is_set(op_prev->ptr, prop)) {
				ToolSettings *ts = scene->toolsettings;
				short selectmode_orig;

				RNA_property_boolean_get_array(op_prev->ptr, prop, mesh_select_mode);
				selectmode_orig = ((mesh_select_mode[0] ? SCE_SELECT_VERTEX : 0) |
				                   (mesh_select_mode[1] ? SCE_SELECT_EDGE   : 0) |
				                   (mesh_select_mode[2] ? SCE_SELECT_FACE   : 0));

				/* still switch if we were originally in face select mode */
				if ((ts->selectmode != selectmode_orig) && (selectmode_orig != SCE_SELECT_FACE)) {
					BMEditMesh *em = BKE_editmesh_from_object(scene->obedit);
					em->selectmode = ts->selectmode = selectmode_orig;
					EDBM_selectmode_set(em);
				}
			}
		}
	}
}
Exemplo n.º 5
0
static void make_duplis_verts(const DupliContext *ctx)
{
	Scene *scene = ctx->scene;
	Object *parent = ctx->object;
	bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW);
	VertexDupliData vdd;

	vdd.ctx = ctx;
	vdd.use_rotation = parent->transflag & OB_DUPLIROT;

	/* gather mesh info */
	{
		Mesh *me = parent->data;
		BMEditMesh *em = BKE_editmesh_from_object(parent);
		CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH);

		if (em)
			vdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
		else
			vdd.dm = mesh_get_derived_final(scene, parent, dm_mask);
		vdd.edit_btmesh = me->edit_btmesh;

		if (use_texcoords)
			vdd.orco = vdd.dm->getVertDataArray(vdd.dm, CD_ORCO);
		else
			vdd.orco = NULL;

		vdd.totvert = vdd.dm->getNumVerts(vdd.dm);
	}

	make_child_duplis(ctx, &vdd, make_child_duplis_verts);

	vdd.dm->release(vdd.dm);
}
Exemplo n.º 6
0
static int add_primitive_cone_exec(bContext *C, wmOperator *op)
{
	Object *obedit;
	BMEditMesh *em;
	float loc[3], rot[3], mat[4][4], dia;
	bool enter_editmode;
	unsigned int layer;
	bool was_editmode;
	const int end_fill_type = RNA_enum_get(op->ptr, "end_fill_type");
	const bool cap_end = (end_fill_type != 0);
	const bool cap_tri = (end_fill_type == 2);

	ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
	obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Cone"), &dia, mat, &was_editmode, loc, rot, layer);
	em = BKE_editmesh_from_object(obedit);

	if (!EDBM_op_call_and_selectf(
	        em, op, "verts.out", false,
	        "create_cone segments=%i diameter1=%f diameter2=%f cap_ends=%b cap_tris=%b depth=%f matrix=%m4",
	        RNA_int_get(op->ptr, "vertices"), RNA_float_get(op->ptr, "radius1"),
	        RNA_float_get(op->ptr, "radius2"), cap_end, cap_tri, RNA_float_get(op->ptr, "depth"), mat))
	{
		return OPERATOR_CANCELLED;
	}

	make_prim_finish(C, obedit, was_editmode, enter_editmode);

	return OPERATOR_FINISHED;
}
Exemplo n.º 7
0
static int add_primitive_icosphere_exec(bContext *C, wmOperator *op)
{
	Object *obedit;
	BMEditMesh *em;
	float loc[3], rot[3], mat[4][4], dia;
	bool enter_editmode;
	bool was_editmode;
	unsigned int layer;

	ED_object_add_generic_get_opts(C, op, loc, rot, &enter_editmode, &layer, NULL);
	obedit = make_prim_init(C, CTX_DATA_(BLF_I18NCONTEXT_ID_MESH, "Icosphere"), &dia, mat, &was_editmode, loc, rot, layer);
	em = BKE_editmesh_from_object(obedit);

	if (!EDBM_op_call_and_selectf(
	        em, op, "verts.out", false,
	        "create_icosphere subdivisions=%i diameter=%f matrix=%m4",
	        RNA_int_get(op->ptr, "subdivisions"),
	        RNA_float_get(op->ptr, "size"), mat))
	{
		return OPERATOR_CANCELLED;
	}

	make_prim_finish(C, obedit, was_editmode, enter_editmode);

	return OPERATOR_FINISHED;
}
Exemplo n.º 8
0
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;
	float pixels_per_inch;
	int i;

	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->value_mode = OFFSET_VALUE;
	opdata->segments = (float) RNA_int_get(op->ptr, "segments");
	pixels_per_inch = U.dpi * U.pixelsize;

	for (i = 0; i < NUM_VALUE_KINDS; i++) {
		opdata->shift_value[i] = -1.0f;
		opdata->initial_length[i] = -1.0f;
		/* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
		opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch; 

		initNumInput(&opdata->num_input[i]);
		opdata->num_input[i].idx_max = 0;
		opdata->num_input[i].val_flag[0] |= NUM_NO_NEGATIVE;
		if (i == SEGMENTS_VALUE) {
			opdata->num_input[i].val_flag[0] |= NUM_NO_FRACTION | NUM_NO_ZERO;
		}
		if (i == OFFSET_VALUE) {
			opdata->num_input[i].unit_sys = scene->unit.system;
		}
		opdata->num_input[i].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;

		if (v3d) {
			opdata->twtype = v3d->twtype;
			v3d->twtype = 0;
		}
	}

	return true;
}
Exemplo n.º 9
0
static int skin_resize_poll(bContext *C)
{
	struct Object *obedit = CTX_data_edit_object(C);
	if (obedit && obedit->type == OB_MESH) {
		BMEditMesh *em = BKE_editmesh_from_object(obedit);
		return (em && CustomData_has_layer(&em->bm->vdata, CD_MVERT_SKIN));
	}
	return 0;
}
Exemplo n.º 10
0
/**************************** 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_select_ungrouped);
	WM_operatortype_append(MESH_OT_hide);
	WM_operatortype_append(MESH_OT_reveal);
	WM_operatortype_append(MESH_OT_select_face_by_sides);
	WM_operatortype_append(MESH_OT_select_loose);
	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_subdivide_edgering);
	WM_operatortype_append(MESH_OT_unsubdivide);
	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_shortest_path_select);
	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_fill_grid);
	WM_operatortype_append(MESH_OT_fill_holes);
	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_verts);
	WM_operatortype_append(MESH_OT_dissolve_edges);
	WM_operatortype_append(MESH_OT_dissolve_faces);
	WM_operatortype_append(MESH_OT_dissolve_mode);
	WM_operatortype_append(MESH_OT_dissolve_limited);
	WM_operatortype_append(MESH_OT_dissolve_degenerate);
	WM_operatortype_append(MESH_OT_delete_edgeloop);
	WM_operatortype_append(MESH_OT_faces_shade_smooth);
	WM_operatortype_append(MESH_OT_faces_shade_flat);
	WM_operatortype_append(MESH_OT_sort_elements);
#ifdef WITH_FREESTYLE
	WM_operatortype_append(MESH_OT_mark_freestyle_face);
#endif

	WM_operatortype_append(MESH_OT_delete);
	WM_operatortype_append(MESH_OT_delete_loose);
	WM_operatortype_append(MESH_OT_edge_collapse);

	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_shortest_path_pick);
	WM_operatortype_append(MESH_OT_select_similar);
	WM_operatortype_append(MESH_OT_select_similar_region);
	WM_operatortype_append(MESH_OT_select_mode);
	WM_operatortype_append(MESH_OT_loop_multi_select);
	WM_operatortype_append(MESH_OT_mark_seam);
	WM_operatortype_append(MESH_OT_mark_sharp);
#ifdef WITH_FREESTYLE
	WM_operatortype_append(MESH_OT_mark_freestyle_edge);
#endif
	WM_operatortype_append(MESH_OT_vertices_smooth);
	WM_operatortype_append(MESH_OT_vertices_smooth_laplacian);
	WM_operatortype_append(MESH_OT_noise);
	WM_operatortype_append(MESH_OT_flip_normals);
	WM_operatortype_append(MESH_OT_rip);
	WM_operatortype_append(MESH_OT_rip_edge);
	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_customdata_mask_clear);
	WM_operatortype_append(MESH_OT_customdata_skin_add);
	WM_operatortype_append(MESH_OT_customdata_skin_clear);
	WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_add);
	WM_operatortype_append(MESH_OT_customdata_custom_splitnormals_clear);
	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_connect_path);
	WM_operatortype_append(MESH_OT_vert_connect_concave);
	WM_operatortype_append(MESH_OT_vert_connect_nonplanar);
	WM_operatortype_append(MESH_OT_face_make_planar);
	WM_operatortype_append(MESH_OT_knife_tool);
	WM_operatortype_append(MESH_OT_knife_project);

	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_offset_edge_loops);
	WM_operatortype_append(MESH_OT_intersect);
	WM_operatortype_append(MESH_OT_face_split_by_edges);
	WM_operatortype_append(MESH_OT_poke);
	WM_operatortype_append(MESH_OT_wireframe);
	WM_operatortype_append(MESH_OT_edge_split);

#ifdef WITH_BULLET
	WM_operatortype_append(MESH_OT_convex_hull);
#endif

	WM_operatortype_append(MESH_OT_bisect);
	WM_operatortype_append(MESH_OT_symmetrize);
	WM_operatortype_append(MESH_OT_symmetry_snap);

#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 = BKE_editmesh_from_object(obedit);
		if (em && em->selectmode & SCE_SELECT_FACE) {
			return 1;
		}
	}
	return 0;
}
Exemplo n.º 11
0
static void rna_Scene_uvedit_aspect(Scene *scene, Object *ob, float *aspect)
{
	if ((ob->type == OB_MESH) && (ob->mode == OB_MODE_EDIT)) {
		BMEditMesh *em;
		em = BKE_editmesh_from_object(ob);
		if (EDBM_mtexpoly_check(em)) {
			ED_uvedit_get_aspect(scene, ob, em->bm, aspect, aspect + 1);
			return;
		}
	}

	aspect[0] = aspect[1] = 1.0f;
}
Exemplo n.º 12
0
void ED_view3d_gizmo_mesh_preselect_get_active(bContext *C,
                                               wmGizmo *gz,
                                               Base **r_base,
                                               BMElem **r_ele)
{
  ViewLayer *view_layer = CTX_data_view_layer(C);

  const int object_index = RNA_int_get(gz->ptr, "object_index");

  /* weak, allocate an array just to access the index. */
  Base *base = NULL;
  Object *obedit = NULL;
  {
    uint bases_len;
    Base **bases = BKE_view_layer_array_from_bases_in_edit_mode(
        view_layer, CTX_wm_view3d(C), &bases_len);
    if (object_index < bases_len) {
      base = bases[object_index];
      obedit = base->object;
    }
    MEM_freeN(bases);
  }

  *r_base = base;
  *r_ele = NULL;

  if (obedit) {
    BMEditMesh *em = BKE_editmesh_from_object(obedit);
    BMesh *bm = em->bm;
    PropertyRNA *prop;

    /* Ring select only defines edge, check properties exist first. */
    prop = RNA_struct_find_property(gz->ptr, "vert_index");
    const int vert_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
    prop = RNA_struct_find_property(gz->ptr, "edge_index");
    const int edge_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;
    prop = RNA_struct_find_property(gz->ptr, "face_index");
    const int face_index = prop ? RNA_property_int_get(gz->ptr, prop) : -1;

    if (vert_index != -1) {
      *r_ele = (BMElem *)BM_vert_at_index_find(bm, vert_index);
    }
    else if (edge_index != -1) {
      *r_ele = (BMElem *)BM_edge_at_index_find(bm, edge_index);
    }
    else if (face_index != -1) {
      *r_ele = (BMElem *)BM_face_at_index_find(bm, face_index);
    }
  }
}
Exemplo n.º 13
0
bool ED_space_image_show_uvedit(SpaceImage *sima, Object *obedit)
{
	if (sima && (ED_space_image_show_render(sima) || ED_space_image_show_paint(sima)))
		return false;

	if (obedit && obedit->type == OB_MESH) {
		struct BMEditMesh *em = BKE_editmesh_from_object(obedit);
		bool ret;

		ret = EDBM_mtexpoly_check(em);

		return ret;
	}

	return false;
}
Exemplo n.º 14
0
static void make_prim_finish(bContext *C, Object *obedit, bool was_editmode, int enter_editmode)
{
	BMEditMesh *em = BKE_editmesh_from_object(obedit);
	const int exit_editmode = ((was_editmode == true) && (enter_editmode == false));

	/* Primitive has all verts selected, use vert select flush
	 * to push this up to edges & faces. */
	EDBM_selectmode_flush_ex(em, SCE_SELECT_VERTEX);

	/* only recalc editmode tessface if we are staying in editmode */
	EDBM_update_generic(em, !exit_editmode, true);

	/* userdef */
	if (exit_editmode) {
		ED_object_editmode_exit(C, EM_FREEDATA); /* adding EM_DO_UNDO messes up operator redo */
	}
	WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obedit);
}
Exemplo n.º 15
0
static int mesh_bisect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
	Object *obedit = CTX_data_edit_object(C);
	BMEditMesh *em = BKE_editmesh_from_object(obedit);
	int ret;

	if (em->bm->totedgesel == 0) {
		BKE_report(op->reports, RPT_ERROR, "Selected edges/faces required");
		return OPERATOR_CANCELLED;
	}

	/* if the properties are set or there is no rv3d,
	 * skip model and exec immediately */

	if ((CTX_wm_region_view3d(C) == NULL) ||
	    (RNA_struct_property_is_set(op->ptr, "plane_co") &&
	     RNA_struct_property_is_set(op->ptr, "plane_no")))
	{
		return mesh_bisect_exec(C, op);
	}

	ret = WM_gesture_straightline_invoke(C, op, event);
	if (ret & OPERATOR_RUNNING_MODAL) {
		View3D *v3d = CTX_wm_view3d(C);

		wmGesture *gesture = op->customdata;
		BisectData *opdata;


		opdata = MEM_mallocN(sizeof(BisectData), "inset_operator_data");
		opdata->mesh_backup = EDBM_redo_state_store(em);
		opdata->is_first = true;
		gesture->userdata = opdata;

		/* misc other vars */
		G.moving = G_TRANSFORM_EDIT;
		opdata->twtype = v3d->twtype;
		v3d->twtype = 0;

		/* initialize modal callout */
		ED_area_headerprint(CTX_wm_area(C), IFACE_("LMB: Click and drag to draw cut line"));
	}
	return ret;
}
static int knifeproject_exec(bContext *C, wmOperator *op)
{
	ARegion *ar = CTX_wm_region(C);
	Scene *scene = CTX_data_scene(C);
	Object *obedit = CTX_data_edit_object(C);
	BMEditMesh *em = BKE_editmesh_from_object(obedit);
	const bool cut_through = RNA_boolean_get(op->ptr, "cut_through");

	LinkNode *polys = NULL;

	CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
	{
		if (ob != obedit) {
			polys = knifeproject_poly_from_object(ar, scene, ob, polys);
		}
	}
	CTX_DATA_END;

	if (polys) {
		EDBM_mesh_knife(C, polys, true, cut_through);

		/* select only tagged faces */
		BM_mesh_elem_hflag_disable_all(em->bm, BM_VERT | BM_EDGE | BM_FACE, BM_ELEM_SELECT, false);

		/* not essential, but switch out of vertex mode since the
		 * selected regions wont be nicely isolated after flushing.
		 * note: call after de-select to avoid selection flushing */
		EDBM_selectmode_disable(scene, em, SCE_SELECT_VERTEX, SCE_SELECT_EDGE);

		BM_mesh_elem_hflag_enable_test(em->bm, BM_FACE, BM_ELEM_SELECT, true, false, BM_ELEM_TAG);

		BM_mesh_select_mode_flush(em->bm);

		BLI_linklist_freeN(polys);

		return OPERATOR_FINISHED;
	}
	else {
		BKE_report(op->reports, RPT_ERROR, "No other selected objects found to use for projection");
		return OPERATOR_CANCELLED;
	}
}
Exemplo n.º 17
0
static void make_duplis_faces(const DupliContext *ctx)
{
	Scene *scene = ctx->scene;
	Object *parent = ctx->object;
	bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW);
	FaceDupliData fdd;

	fdd.use_scale = ((parent->transflag & OB_DUPLIFACES_SCALE) != 0);

	/* gather mesh info */
	{
		BMEditMesh *em = BKE_editmesh_from_object(parent);
		CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH);

		if (em)
			fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
		else
			fdd.dm = mesh_get_derived_final(scene, parent, dm_mask);

		if (use_texcoords) {
			CustomData *ml_data = fdd.dm->getLoopDataLayout(fdd.dm);
			const int uv_idx = CustomData_get_render_layer(ml_data, CD_MLOOPUV);
			fdd.orco = fdd.dm->getVertDataArray(fdd.dm, CD_ORCO);
			fdd.mloopuv = CustomData_get_layer_n(ml_data, CD_MLOOPUV, uv_idx);
		}
		else {
			fdd.orco = NULL;
			fdd.mloopuv = NULL;
		}

		fdd.totface = fdd.dm->getNumPolys(fdd.dm);
		fdd.mpoly = fdd.dm->getPolyArray(fdd.dm);
		fdd.mloop = fdd.dm->getLoopArray(fdd.dm);
		fdd.mvert = fdd.dm->getVertArray(fdd.dm);
	}

	make_child_duplis(ctx, &fdd, make_child_duplis_faces);

	fdd.dm->release(fdd.dm);
}
Exemplo n.º 18
0
static bool edbm_inset_init(bContext *C, wmOperator *op, const bool is_modal)
{
	InsetData *opdata;
	Scene *scene = CTX_data_scene(C);
	Object *obedit = CTX_data_edit_object(C);
	BMEditMesh *em = BKE_editmesh_from_object(obedit);

	if (em->bm->totvertsel == 0) {
		return false;
	}

	op->customdata = opdata = MEM_mallocN(sizeof(InsetData), "inset_operator_data");

	opdata->old_thickness = 0.01;
	opdata->old_depth = 0.0;
	opdata->modify_depth = false;
	opdata->shift = false;
	opdata->shift_amount = 0.0f;
	opdata->is_modal = is_modal;
	opdata->em = em;

	initNumInput(&opdata->num_input);
	opdata->num_input.idx_max = 1; /* Two elements. */
	opdata->num_input.unit_sys = scene->unit.system;
	opdata->num_input.unit_type[0] = B_UNIT_LENGTH;
	opdata->num_input.unit_type[1] = B_UNIT_LENGTH;

	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;
}
Exemplo n.º 19
0
static void make_duplis_faces(const DupliContext *ctx)
{
	Scene *scene = ctx->scene;
	Object *parent = ctx->object;
	bool for_render = ctx->eval_ctx->for_render;
	FaceDupliData fdd;

	fdd.use_scale = ((parent->transflag & OB_DUPLIFACES_SCALE) != 0);

	/* gather mesh info */
	{
		BMEditMesh *em = BKE_editmesh_from_object(parent);
		CustomDataMask dm_mask = (for_render ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH);

		if (em)
			fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
		else
			fdd.dm = mesh_get_derived_final(scene, parent, dm_mask);

		if (for_render) {
			fdd.orco = fdd.dm->getVertDataArray(fdd.dm, CD_ORCO);
			fdd.mloopuv = fdd.dm->getLoopDataArray(fdd.dm, CD_MLOOPUV);
		}
		else {
			fdd.orco = NULL;
			fdd.mloopuv = NULL;
		}

		fdd.totface = fdd.dm->getNumPolys(fdd.dm);
		fdd.mpoly = fdd.dm->getPolyArray(fdd.dm);
		fdd.mloop = fdd.dm->getLoopArray(fdd.dm);
		fdd.mvert = fdd.dm->getVertArray(fdd.dm);
	}

	make_child_duplis(ctx, &fdd, make_child_duplis_faces);

	fdd.dm->release(fdd.dm);
}
Exemplo n.º 20
0
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"));
	}
}
Exemplo n.º 21
0
static int mesh_bisect_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);

	/* both can be NULL, fallbacks values are used */
	View3D *v3d = CTX_wm_view3d(C);
	RegionView3D *rv3d = ED_view3d_context_rv3d(C);

	Object *obedit = CTX_data_edit_object(C);
	BMEditMesh *em = BKE_editmesh_from_object(obedit);
	BMesh *bm;
	BMOperator bmop;
	float plane_co[3];
	float plane_no[3];
	float imat[4][4];

	const float thresh = RNA_float_get(op->ptr, "threshold");
	const bool use_fill = RNA_boolean_get(op->ptr, "use_fill");
	const bool clear_inner = RNA_boolean_get(op->ptr, "clear_inner");
	const bool clear_outer = RNA_boolean_get(op->ptr, "clear_outer");

	PropertyRNA *prop_plane_co;
	PropertyRNA *prop_plane_no;

	prop_plane_co = RNA_struct_find_property(op->ptr, "plane_co");
	if (RNA_property_is_set(op->ptr, prop_plane_co)) {
		RNA_property_float_get_array(op->ptr, prop_plane_co, plane_co);
	}
	else {
		copy_v3_v3(plane_co, ED_view3d_cursor3d_get(scene, v3d));
		RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
	}

	prop_plane_no = RNA_struct_find_property(op->ptr, "plane_no");
	if (RNA_property_is_set(op->ptr, prop_plane_no)) {
		RNA_property_float_get_array(op->ptr, prop_plane_no, plane_no);
	}
	else {
		if (rv3d) {
			copy_v3_v3(plane_no, rv3d->viewinv[1]);
		}
		else {
			/* fallback... */
			plane_no[0] = plane_no[1] = 0.0f; plane_no[2] = 1.0f;
		}
		RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
	}



	/* -------------------------------------------------------------------- */
	/* Modal support */
	/* Note: keep this isolated, exec can work wihout this */
	if ((op->customdata != NULL) &&
	    mesh_bisect_interactive_calc(C, op, em, plane_co, plane_no))
	{
		/* write back to the props */
		RNA_property_float_set_array(op->ptr, prop_plane_no, plane_no);
		RNA_property_float_set_array(op->ptr, prop_plane_co, plane_co);
	}
	/* End Modal */
	/* -------------------------------------------------------------------- */



	bm = em->bm;

	invert_m4_m4(imat, obedit->obmat);
	mul_m4_v3(imat, plane_co);
	mul_mat3_m4_v3(imat, plane_no);

	EDBM_op_init(em, &bmop, op,
	             "bisect_plane geom=%hvef plane_co=%v plane_no=%v dist=%f clear_inner=%b clear_outer=%b",
	             BM_ELEM_SELECT, plane_co, plane_no, thresh, clear_inner, clear_outer);
	BMO_op_exec(bm, &bmop);

	EDBM_flag_disable_all(em, BM_ELEM_SELECT);

	if (use_fill) {
		float normal_fill[3];
		BMOperator bmop_fill;
		BMOperator bmop_attr;

		normalize_v3_v3(normal_fill, plane_no);
		if (clear_outer == true && clear_inner == false) {
			negate_v3(normal_fill);
		}

		/* Fill */
		BMO_op_initf(
		        bm, &bmop_fill, op->flag,
		        "triangle_fill edges=%S normal=%v use_dissolve=%b",
		        &bmop, "geom_cut.out", normal_fill, true);
		BMO_op_exec(bm, &bmop_fill);

		/* Copy Attributes */
		BMO_op_initf(bm, &bmop_attr, op->flag,
		             "face_attribute_fill faces=%S use_normals=%b use_data=%b",
		             &bmop_fill, "geom.out", false, true);
		BMO_op_exec(bm, &bmop_attr);

		BMO_slot_buffer_hflag_enable(bm, bmop_fill.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);

		BMO_op_finish(bm, &bmop_attr);
		BMO_op_finish(bm, &bmop_fill);
	}

	BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom_cut.out", BM_VERT | BM_EDGE, BM_ELEM_SELECT, true);

	if (!EDBM_op_finish(em, &bmop, op, true)) {
		return OPERATOR_CANCELLED;
	}
	else {
		EDBM_update_generic(em, true, true);
		EDBM_selectmode_flush(em);
		return OPERATOR_FINISHED;
	}
}
Exemplo n.º 22
0
static int gizmo_preselect_edgering_test_select(bContext *C, wmGizmo *gz, const int mval[2])
{
  MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
  struct {
    Object *ob;
    BMEdge *eed;
    float dist;
    int base_index;
  } best = {
      .dist = ED_view3d_select_dist_px(),
  };

  struct {
    int base_index;
    int edge_index;
  } prev = {
      .base_index = gz_ring->base_index,
      .edge_index = gz_ring->edge_index,
  };

  {
    ViewLayer *view_layer = CTX_data_view_layer(C);
    View3D *v3d = CTX_wm_view3d(C);
    if (((gz_ring->bases)) == NULL || (gz_ring->bases[0] != view_layer->basact)) {
      MEM_SAFE_FREE(gz_ring->bases);
      gz_ring->bases = BKE_view_layer_array_from_bases_in_edit_mode(
          view_layer, v3d, &gz_ring->bases_len);
    }
  }

  ViewContext vc;
  em_setup_viewcontext(C, &vc);
  copy_v2_v2_int(vc.mval, mval);

  uint base_index;
  BMEdge *eed_test = EDBM_edge_find_nearest_ex(
      &vc, &best.dist, NULL, false, false, NULL, gz_ring->bases, gz_ring->bases_len, &base_index);

  if (eed_test) {
    best.ob = gz_ring->bases[base_index]->object;
    best.eed = eed_test;
    best.base_index = base_index;
  }

  BMesh *bm = NULL;
  if (best.eed) {
    gz_ring->base_index = best.base_index;
    bm = BKE_editmesh_from_object(gz_ring->bases[gz_ring->base_index]->object)->bm;
    BM_mesh_elem_index_ensure(bm, BM_EDGE);
    gz_ring->edge_index = BM_elem_index_get(best.eed);
  }
  else {
    gz_ring->base_index = -1;
    gz_ring->edge_index = -1;
  }

  if ((prev.base_index == gz_ring->base_index) && (prev.edge_index == gz_ring->edge_index)) {
    /* pass (only recalculate on change) */
  }
  else {
    if (best.eed) {
      const float(*coords)[3] = NULL;
      {
        Object *ob = gz_ring->bases[gz_ring->base_index]->object;
        Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
        if (me_eval->runtime.edit_data) {
          coords = me_eval->runtime.edit_data->vertexCos;
        }
      }
      EDBM_preselect_edgering_update_from_edge(gz_ring->psel, bm, best.eed, 1, coords);
    }
    else {
      EDBM_preselect_edgering_clear(gz_ring->psel);
    }

    RNA_int_set(gz->ptr, "object_index", gz_ring->base_index);
    RNA_int_set(gz->ptr, "edge_index", gz_ring->edge_index);

    ARegion *ar = CTX_wm_region(C);
    ED_region_tag_redraw(ar);
  }

  // return best.eed ? 0 : -1;
  return -1;
}

static void gizmo_preselect_edgering_setup(wmGizmo *gz)
{
  MeshEdgeRingGizmo3D *gz_ring = (MeshEdgeRingGizmo3D *)gz;
  if (gz_ring->psel == NULL) {
    gz_ring->psel = EDBM_preselect_edgering_create();
  }
  gz_ring->base_index = -1;
}
Exemplo n.º 23
0
void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
                                   Scene *scene,
                                   Object *ob)
{
	ID *data_id = (ID *)ob->data;
	AnimData *adt = BKE_animdata_from_id(data_id);
	Key *key;
	float ctime = BKE_scene_frame_get(scene);

	if (G.debug & G_DEBUG_DEPSGRAPH)
		printf("recalcdata %s\n", ob->id.name + 2);

	/* TODO(sergey): Only used by legacy depsgraph. */
	if (adt) {
		/* evaluate drivers - datalevel */
		/* XXX: for mesh types, should we push this to derivedmesh instead? */
		BKE_animsys_evaluate_animdata(scene, data_id, adt, ctime, ADT_RECALC_DRIVERS);
	}

	/* TODO(sergey): Only used by legacy depsgraph. */
	key = BKE_key_from_object(ob);
	if (key && key->block.first) {
		if (!(ob->shapeflag & OB_SHAPE_LOCK))
			BKE_animsys_evaluate_animdata(scene, &key->id, key->adt, ctime, ADT_RECALC_DRIVERS);
	}

	/* includes all keys and modifiers */
	switch (ob->type) {
		case OB_MESH:
		{
			BMEditMesh *em = (ob == scene->obedit) ? BKE_editmesh_from_object(ob) : NULL;
			uint64_t data_mask = scene->customdata_mask | CD_MASK_BAREMESH;
#ifdef WITH_FREESTYLE
			/* make sure Freestyle edge/face marks appear in DM for render (see T40315) */
			if (eval_ctx->mode != DAG_EVAL_VIEWPORT) {
				data_mask |= CD_MASK_FREESTYLE_EDGE | CD_MASK_FREESTYLE_FACE;
			}
#endif
			if (em) {
				makeDerivedMesh(scene, ob, em,  data_mask, false); /* was CD_MASK_BAREMESH */
			}
			else {
				makeDerivedMesh(scene, ob, NULL, data_mask, false);
			}
			break;
		}
		case OB_ARMATURE:
			if (ob->id.lib && ob->proxy_from) {
				if (BKE_pose_copy_result(ob->pose, ob->proxy_from->pose) == false) {
					printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
					       ob->id.name + 2, ob->proxy_from->id.name + 2);
				}
			}
			else {
				BKE_pose_where_is(scene, ob);
			}
			break;

		case OB_MBALL:
			BKE_displist_make_mball(eval_ctx, scene, ob);
			break;

		case OB_CURVE:
		case OB_SURF:
		case OB_FONT:
			BKE_displist_make_curveTypes(scene, ob, 0);
			break;

		case OB_LATTICE:
			BKE_lattice_modifiers_calc(scene, ob);
			break;

		case OB_EMPTY:
			if (ob->empty_drawtype == OB_EMPTY_IMAGE && ob->data)
				if (BKE_image_is_animated(ob->data))
					BKE_image_user_check_frame_calc(ob->iuser, (int)ctime, 0);
			break;
	}

	/* related materials */
	/* XXX: without depsgraph tagging, this will always need to be run, which will be slow!
	 * However, not doing anything (or trying to hack around this lack) is not an option
	 * anymore, especially due to Cycles [#31834]
	 */
	if (ob->totcol) {
		int a;
		if (ob->totcol != 0) {
			BLI_mutex_lock(&material_lock);
			for (a = 1; a <= ob->totcol; a++) {
				Material *ma = give_current_material(ob, a);
				if (ma) {
					/* recursively update drivers for this material */
					material_drivers_update(scene, ma, ctime);
				}
			}
			BLI_mutex_unlock(&material_lock);
		}
	}
	else if (ob->type == OB_LAMP)
		lamp_drivers_update(scene, ob->data, ctime);

	/* particles */
	if (ob != scene->obedit && ob->particlesystem.first) {
		ParticleSystem *tpsys, *psys;
		DerivedMesh *dm;
		ob->transflag &= ~OB_DUPLIPARTS;
		psys = ob->particlesystem.first;
		while (psys) {
			/* ensure this update always happens even if psys is disabled */
			if (psys->recalc & PSYS_RECALC_TYPE) {
				psys_changed_type(ob, psys);
			}

			if (psys_check_enabled(ob, psys)) {
				/* check use of dupli objects here */
				if (psys->part && (psys->part->draw_as == PART_DRAW_REND || eval_ctx->mode == DAG_EVAL_RENDER) &&
				    ((psys->part->ren_as == PART_DRAW_OB && psys->part->dup_ob) ||
				     (psys->part->ren_as == PART_DRAW_GR && psys->part->dup_group)))
				{
					ob->transflag |= OB_DUPLIPARTS;
				}

				particle_system_update(scene, ob, psys);
				psys = psys->next;
			}
			else if (psys->flag & PSYS_DELETE) {
				tpsys = psys->next;
				BLI_remlink(&ob->particlesystem, psys);
				psys_free(ob, psys);
				psys = tpsys;
			}
			else
				psys = psys->next;
		}

		if (eval_ctx->mode == DAG_EVAL_RENDER && ob->transflag & OB_DUPLIPARTS) {
			/* this is to make sure we get render level duplis in groups:
			 * the derivedmesh must be created before init_render_mesh,
			 * since object_duplilist does dupliparticles before that */
			CustomDataMask data_mask = CD_MASK_BAREMESH | CD_MASK_MFACE | CD_MASK_MTFACE | CD_MASK_MCOL;
			dm = mesh_create_derived_render(scene, ob, data_mask);
			dm->release(dm);

			for (psys = ob->particlesystem.first; psys; psys = psys->next)
				psys_get_modifier(ob, psys)->flag &= ~eParticleSystemFlag_psys_updated;
		}
	}

	/* quick cache removed */
}
Exemplo n.º 24
0
static bool edbm_bevel_init(bContext *C, wmOperator *op, const bool is_modal)
{
  Scene *scene = CTX_data_scene(C);
  BevelData *opdata;
  ViewLayer *view_layer = CTX_data_view_layer(C);
  float pixels_per_inch;
  int i, otype;

  if (is_modal) {
    RNA_float_set(op->ptr, "offset", 0.0f);
    RNA_float_set(op->ptr, "offset_pct", 0.0f);
  }

  op->customdata = opdata = MEM_mallocN(sizeof(BevelData), "beveldata_mesh_operator");
  uint objects_used_len = 0;
  opdata->max_obj_scale = FLT_MIN;

  {
    uint ob_store_len = 0;
    Object **objects = BKE_view_layer_array_from_objects_in_edit_mode_unique_data(
        view_layer, CTX_wm_view3d(C), &ob_store_len);
    opdata->ob_store = MEM_malloc_arrayN(ob_store_len, sizeof(*opdata->ob_store), __func__);
    for (uint ob_index = 0; ob_index < ob_store_len; ob_index++) {
      Object *obedit = objects[ob_index];
      float scale = mat4_to_scale(obedit->obmat);
      opdata->max_obj_scale = max_ff(opdata->max_obj_scale, scale);
      BMEditMesh *em = BKE_editmesh_from_object(obedit);
      if (em->bm->totvertsel > 0) {
        opdata->ob_store[objects_used_len].em = em;
        objects_used_len++;
      }
    }
    MEM_freeN(objects);
    opdata->ob_store_len = objects_used_len;
  }

  opdata->is_modal = is_modal;
  otype = RNA_enum_get(op->ptr, "offset_type");
  opdata->value_mode = (otype == BEVEL_AMT_PERCENT) ? OFFSET_VALUE_PERCENT : OFFSET_VALUE;
  opdata->segments = (float)RNA_int_get(op->ptr, "segments");
  pixels_per_inch = U.dpi * U.pixelsize;

  for (i = 0; i < NUM_VALUE_KINDS; i++) {
    opdata->shift_value[i] = -1.0f;
    opdata->initial_length[i] = -1.0f;
    /* note: scale for OFFSET_VALUE will get overwritten in edbm_bevel_invoke */
    opdata->scale[i] = value_scale_per_inch[i] / pixels_per_inch;

    initNumInput(&opdata->num_input[i]);
    opdata->num_input[i].idx_max = 0;
    opdata->num_input[i].val_flag[0] |= NUM_NO_NEGATIVE;
    if (i == SEGMENTS_VALUE) {
      opdata->num_input[i].val_flag[0] |= NUM_NO_FRACTION | NUM_NO_ZERO;
    }
    if (i == OFFSET_VALUE) {
      opdata->num_input[i].unit_sys = scene->unit.system;
    }
    /* Not sure this is a factor or a unit? */
    opdata->num_input[i].unit_type[0] = B_UNIT_NONE;
  }

  /* avoid the cost of allocating a bm copy */
  if (is_modal) {
    View3D *v3d = CTX_wm_view3d(C);
    ARegion *ar = CTX_wm_region(C);

    for (uint ob_index = 0; ob_index < opdata->ob_store_len; ob_index++) {
      opdata->ob_store[ob_index].mesh_backup = EDBM_redo_state_store(
          opdata->ob_store[ob_index].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;

    if (v3d) {
      opdata->gizmo_flag = v3d->gizmo_flag;
      v3d->gizmo_flag = V3D_GIZMO_HIDE;
    }
  }

  return true;
}
Exemplo n.º 25
0
static int gizmo_preselect_elem_test_select(bContext *C, wmGizmo *gz, const int mval[2])
{
  MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
  struct {
    Object *ob;
    BMElem *ele;
    float dist;
    int base_index;
  } best = {
      .dist = ED_view3d_select_dist_px(),
  };

  struct {
    int base_index;
    int vert_index;
    int edge_index;
    int face_index;
  } prev = {
      .base_index = gz_ele->base_index,
      .vert_index = gz_ele->vert_index,
      .edge_index = gz_ele->edge_index,
      .face_index = gz_ele->face_index,
  };

  {
    ViewLayer *view_layer = CTX_data_view_layer(C);
    View3D *v3d = CTX_wm_view3d(C);
    if (((gz_ele->bases)) == NULL || (gz_ele->bases[0] != view_layer->basact)) {
      MEM_SAFE_FREE(gz_ele->bases);
      gz_ele->bases = BKE_view_layer_array_from_bases_in_edit_mode(
          view_layer, v3d, &gz_ele->bases_len);
    }
  }

  ViewContext vc;
  em_setup_viewcontext(C, &vc);
  copy_v2_v2_int(vc.mval, mval);

  {
    /* TODO: support faces. */
    int base_index = -1;
    BMVert *eve_test;
    BMEdge *eed_test;

    if (EDBM_unified_findnearest_from_raycast(&vc,
                                              gz_ele->bases,
                                              gz_ele->bases_len,
                                              true,
                                              &base_index,
                                              &eve_test,
                                              &eed_test,
                                              NULL)) {
      Base *base = gz_ele->bases[base_index];
      best.ob = base->object;
      if (eve_test) {
        best.ele = (BMElem *)eve_test;
      }
      else if (eed_test) {
        best.ele = (BMElem *)eed_test;
      }
      else {
        BLI_assert(0);
      }
      best.base_index = base_index;
      /* Check above should never fail, if it does it's an internal error. */
      BLI_assert(best.base_index != -1);
    }
  }

  BMesh *bm = NULL;

  gz_ele->base_index = -1;
  gz_ele->vert_index = -1;
  gz_ele->edge_index = -1;
  gz_ele->face_index = -1;

  if (best.ele) {
    gz_ele->base_index = best.base_index;
    bm = BKE_editmesh_from_object(gz_ele->bases[gz_ele->base_index]->object)->bm;
    BM_mesh_elem_index_ensure(bm, best.ele->head.htype);

    if (best.ele->head.htype == BM_VERT) {
      gz_ele->vert_index = BM_elem_index_get(best.ele);
    }
    else if (best.ele->head.htype == BM_EDGE) {
      gz_ele->edge_index = BM_elem_index_get(best.ele);
    }
    else if (best.ele->head.htype == BM_FACE) {
      gz_ele->face_index = BM_elem_index_get(best.ele);
    }
  }

  if ((prev.base_index == gz_ele->base_index) && (prev.vert_index == gz_ele->vert_index) &&
      (prev.edge_index == gz_ele->edge_index) && (prev.face_index == gz_ele->face_index)) {
    /* pass (only recalculate on change) */
  }
  else {
    if (best.ele) {
      const float(*coords)[3] = NULL;
      {
        Object *ob = gz_ele->bases[gz_ele->base_index]->object;
        Depsgraph *depsgraph = CTX_data_depsgraph(C);
        Mesh *me_eval = (Mesh *)DEG_get_evaluated_id(depsgraph, ob->data);
        if (me_eval->runtime.edit_data) {
          coords = me_eval->runtime.edit_data->vertexCos;
        }
      }
      EDBM_preselect_elem_update_from_single(gz_ele->psel, bm, best.ele, coords);
    }
    else {
      EDBM_preselect_elem_clear(gz_ele->psel);
    }

    RNA_int_set(gz->ptr, "object_index", gz_ele->base_index);
    RNA_int_set(gz->ptr, "vert_index", gz_ele->vert_index);
    RNA_int_set(gz->ptr, "edge_index", gz_ele->edge_index);
    RNA_int_set(gz->ptr, "face_index", gz_ele->face_index);

    ARegion *ar = CTX_wm_region(C);
    ED_region_tag_redraw(ar);
  }

  // return best.eed ? 0 : -1;
  return -1;
}

static void gizmo_preselect_elem_setup(wmGizmo *gz)
{
  MeshElemGizmo3D *gz_ele = (MeshElemGizmo3D *)gz;
  if (gz_ele->psel == NULL) {
    gz_ele->psel = EDBM_preselect_elem_create();
  }
  gz_ele->base_index = -1;
}