[Bf-blender-cvs] [3bf36fa33bb] blender2.8: Manipulator: alternate cage2d draw style

Campbell Barton noreply at git.blender.org
Wed Sep 13 19:46:33 CEST 2017


Commit: 3bf36fa33bbebaa5631acd6744d73e72f3e3deda
Author: Campbell Barton
Date:   Thu Sep 14 03:53:37 2017 +1000
Branches: blender2.8
https://developer.blender.org/rB3bf36fa33bbebaa5631acd6744d73e72f3e3deda

Manipulator: alternate cage2d draw style

Doesn't rely on hovering, more consistent with 2D drawing tools.

===================================================================

M	source/blender/editors/include/ED_manipulator_library.h
M	source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c

===================================================================

diff --git a/source/blender/editors/include/ED_manipulator_library.h b/source/blender/editors/include/ED_manipulator_library.h
index 9a74a9f50ed..14e28e18ced 100644
--- a/source/blender/editors/include/ED_manipulator_library.h
+++ b/source/blender/editors/include/ED_manipulator_library.h
@@ -97,11 +97,17 @@ enum {
 	ED_MANIPULATOR_CAGE2D_XFORM_FLAG_SCALE_SIGNED     = (1 << 4), /* Negative scale allowed */
 };
 
+/* draw_style */
+enum {
+	ED_MANIPULATOR_CAGE2D_STYLE_BOX = 0,
+	ED_MANIPULATOR_CAGE2D_STYLE_CIRCLE = 1,
+};
+
 /* draw_options */
 enum {
 	/** Draw a central handle (instead of having the entire area selectable)
 	 * Needed for large rectangles that we don't want to swallow all events. */
-	ED_MANIPULATOR_CAGE2D_STYLE_FLAG_XFORM_CENTER_HANDLE = (1 << 0),
+	ED_MANIPULATOR_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE = (1 << 0),
 };
 
 /** #wmManipulator.highlight_part */
diff --git a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
index c13fe1d0ff0..09aa441e647 100644
--- a/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
+++ b/source/blender/editors/manipulator_library/manipulator_types/cage2d_manipulator.c
@@ -49,6 +49,7 @@
 #include "GPU_matrix.h"
 #include "GPU_shader.h"
 #include "GPU_immediate.h"
+#include "GPU_immediate_util.h"
 #include "GPU_select.h"
 
 #include "MEM_guardedalloc.h"
@@ -63,6 +64,7 @@
 #include "../manipulator_library_intern.h"
 
 #define MANIPULATOR_RESIZER_SIZE 10.0f
+#define MANIPULATOR_MARGIN_OFFSET_SCALE 1.5f
 
 static void manipulator_calc_matrix_final_no_offset(
         const wmManipulator *mpr, float orig_matrix_final_no_offset[4][4])
@@ -134,8 +136,14 @@ static void manipulator_rect_pivot_from_scale_part(int part, float r_pt[2], bool
 	r_constrain_axis[1] = y;
 }
 
-static void rect_transform_draw_corners(
-        const rctf *r, const float offsetx, const float offsety, const float color[3])
+/* -------------------------------------------------------------------- */
+/** \name Box Draw Style
+ *
+ * Useful for 3D views, see: #ED_MANIPULATOR_CAGE2D_STYLE_BOX
+ * \{ */
+
+static void cage2d_draw_box_corners(
+        const rctf *r, const float margin[2], const float color[3])
 {
 	uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 
@@ -144,32 +152,32 @@ static void rect_transform_draw_corners(
 
 	immBegin(GWN_PRIM_LINES, 16);
 
-	immVertex2f(pos, r->xmin, r->ymin + offsety);
+	immVertex2f(pos, r->xmin, r->ymin + margin[1]);
 	immVertex2f(pos, r->xmin, r->ymin);
 	immVertex2f(pos, r->xmin, r->ymin);
-	immVertex2f(pos, r->xmin + offsetx, r->ymin);
+	immVertex2f(pos, r->xmin + margin[0], r->ymin);
 
-	immVertex2f(pos, r->xmax, r->ymin + offsety);
+	immVertex2f(pos, r->xmax, r->ymin + margin[1]);
 	immVertex2f(pos, r->xmax, r->ymin);
 	immVertex2f(pos, r->xmax, r->ymin);
-	immVertex2f(pos, r->xmax - offsetx, r->ymin);
+	immVertex2f(pos, r->xmax - margin[0], r->ymin);
 
-	immVertex2f(pos, r->xmax, r->ymax - offsety);
+	immVertex2f(pos, r->xmax, r->ymax - margin[1]);
 	immVertex2f(pos, r->xmax, r->ymax);
 	immVertex2f(pos, r->xmax, r->ymax);
-	immVertex2f(pos, r->xmax - offsetx, r->ymax);
+	immVertex2f(pos, r->xmax - margin[0], r->ymax);
 
-	immVertex2f(pos, r->xmin, r->ymax - offsety);
+	immVertex2f(pos, r->xmin, r->ymax - margin[1]);
 	immVertex2f(pos, r->xmin, r->ymax);
 	immVertex2f(pos, r->xmin, r->ymax);
-	immVertex2f(pos, r->xmin + offsetx, r->ymax);
+	immVertex2f(pos, r->xmin + margin[0], r->ymax);
 
 	immEnd();
 
 	immUnbindProgram();
 }
 
-static void rect_transform_draw_interaction(
+static void cage2d_draw_box_interaction(
         const float color[4], const int highlighted,
         const float size[2], const float margin[2],
         const float line_width, const bool is_solid, const int draw_options)
@@ -365,7 +373,7 @@ static void rect_transform_draw_interaction(
 		}
 
 		case ED_MANIPULATOR_CAGE2D_PART_TRANSLATE:
-			if (draw_options & ED_MANIPULATOR_CAGE2D_STYLE_FLAG_XFORM_CENTER_HANDLE) {
+			if (draw_options & ED_MANIPULATOR_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
 				ARRAY_SET_ITEMS(verts[0], -margin[0] / 2, -margin[1] / 2);
 				ARRAY_SET_ITEMS(verts[1],  margin[0] / 2,  margin[1] / 2);
 				ARRAY_SET_ITEMS(verts[2], -margin[0] / 2,  margin[1] / 2);
@@ -443,23 +451,112 @@ static void rect_transform_draw_interaction(
 	}
 
 	immUnbindProgram();
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Circle Draw Style
+ *
+ * Useful for 2D views, see: #ED_MANIPULATOR_CAGE2D_STYLE_CIRCLE
+ * \{ */
+
+static void imm_draw_point_aspect_2d(
+        uint pos, float x, float y, float rad_x, float rad_y, bool solid)
+{
+	immBegin(solid ? GWN_PRIM_TRI_FAN : GWN_PRIM_LINE_LOOP, 4);
+	immVertex2f(pos, x - rad_x, y - rad_y);
+	immVertex2f(pos, x - rad_x, y + rad_y);
+	immVertex2f(pos, x + rad_x, y + rad_y);
+	immVertex2f(pos, x + rad_x, y - rad_y);
+	immEnd();
+}
+
+static void cage2d_draw_circle_wire(
+        const rctf *r, const float margin[2], const float color[3],
+        const int transform_flag, const int draw_options)
+{
+	uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+
+	immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+	immUniformColor3fv(color);
+
+	immBegin(GWN_PRIM_LINE_LOOP, 4);
+	immVertex2f(pos, r->xmin, r->ymin);
+	immVertex2f(pos, r->xmax, r->ymin);
+	immVertex2f(pos, r->xmax, r->ymax);
+	immVertex2f(pos, r->xmin, r->ymax);
+	immEnd();
+
+	if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE) {
+		immBegin(GWN_PRIM_LINE_LOOP, 2);
+		immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax);
+		immVertex2f(pos, BLI_rctf_cent_x(r), r->ymax + margin[1]);
+		immEnd();
+	}
+
+	if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_TRANSLATE) {
+		if (draw_options & ED_MANIPULATOR_CAGE2D_DRAW_FLAG_XFORM_CENTER_HANDLE) {
+			const float rad[2] = {margin[0] / 2, margin[1] / 2};
+			const float center[2] = {BLI_rctf_cent_x(r), BLI_rctf_cent_y(r)};
+
+			immBegin(GWN_PRIM_LINES, 4);
+			immVertex2f(pos, center[0] - rad[0], center[1] - rad[1]);
+			immVertex2f(pos, center[0] + rad[0], center[1] + rad[1]);
+			immVertex2f(pos, center[0] + rad[0], center[1] - rad[1]);
+			immVertex2f(pos, center[0] - rad[0], center[1] + rad[1]);
+			immEnd();
+		}
+	}
+
+	immUnbindProgram();
+}
+
+static void cage2d_draw_circle_handles(
+        const rctf *r, const float margin[2], const float color[3],
+        const int transform_flag,
+        bool solid)
+{
+	uint pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
+	void (*circle_fn)(uint, float, float, float, float, int) =
+	        (solid) ? imm_draw_circle_fill_aspect_2d : imm_draw_circle_wire_aspect_2d;
+	const int resolu = 12;
+	const float rad[2] = {margin[0] / 3, margin[1] / 3};
 
+	immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+	immUniformColor3fv(color);
+
+	/* should  really divide by two, but looks too bulky. */
+	{
+		imm_draw_point_aspect_2d(pos, r->xmin, r->ymin, rad[0], rad[1], solid);
+		imm_draw_point_aspect_2d(pos, r->xmax, r->ymin, rad[0], rad[1], solid);
+		imm_draw_point_aspect_2d(pos, r->xmax, r->ymax, rad[0], rad[1], solid);
+		imm_draw_point_aspect_2d(pos, r->xmin, r->ymax, rad[0], rad[1], solid);
+	}
+
+	if (transform_flag & ED_MANIPULATOR_CAGE2D_XFORM_FLAG_ROTATE) {
+		const float handle[2] = {BLI_rctf_cent_x(r), r->ymax + (margin[1] * MANIPULATOR_MARGIN_OFFSET_SCALE)};
+		circle_fn(pos, handle[0], handle[1], rad[0], rad[1], resolu);
+	}
+
+	immUnbindProgram();
 }
 
-static void manipulator_rect_transform_draw_intern(
+/** \} */
+
+static void manipulator_cage2d_draw_intern(
         wmManipulator *mpr, const bool select, const bool highlight, const int select_id)
 {
 	// const bool use_clamp = (mpr->parent_mgroup->type->flag & WM_MANIPULATORGROUPTYPE_3D) == 0;
 	float dims[2];
 	RNA_float_get_array(mpr->ptr, "dimensions", dims);
-	const float w = dims[0];
-	const float h = dims[1];
 	float matrix_final[4][4];
 
 	const int transform_flag = RNA_enum_get(mpr->ptr, "transform");
+	const int draw_style = RNA_enum_get(mpr->ptr, "draw_style");
 	const int draw_options = RNA_enum_get(mpr->ptr, "draw_options");
 
-	const float size[2] = {w / 2.0f, h / 2.0f};
+	const float size[2] = {dims[0] / 2.0f, dims[1] / 2.0f};
 	const rctf r = {
 		.xmin = -size[0],
 		.ymin = -size[1],
@@ -475,10 +572,6 @@ static void manipulator_rect_transform_draw_intern(
 	float margin[2];
 	manipulator_calc_rect_view_margin(mpr, dims, margin);
 
-	/* corner manipulators */
-	glLineWidth(mpr->line_width + 3.0f);
-	rect_transform_draw_corners(&r, margin[0], margin[1], (const float[3]){0, 0, 0});
-
 	/* Handy for quick testing draw (if it's outside bounds). */
 	if (false) {
 		glEnable(GL_BLEND);
@@ -491,12 +584,39 @@ static void manipulator_rect_transform_draw_intern(
 		glDisable(GL_BLEND);
 	}
 
-	/* corner manipulators */
-	{
+	if (draw_style == ED_MANIPULATOR_CAGE2D_STYLE_BOX) {
+		/* corner manipulators */
+		glLineWidth(mpr->line_width + 3.0f);
+		cage2d_draw_box_corners(&r, margin, (const float[3]){0, 0, 0});
+
+		/* corner manipulators */
 		float color[4];
 		manipulator_color_get(mpr, highlight, color);
 		glLineWidth(mpr->line_width);
-		rect_transform_draw_corners(&r, margin[0], margin[1], color);
+		cage2d_draw_box_corners(&r, margin, color);
+	}
+	else if (draw_style == ED_MANIPULATOR_CAGE2D_STYLE_CIRCLE) {
+		float color[4];
+		manipulator_color_get(mpr, highlight, color);
+
+		glEnable(GL_LINE_SMOOTH);
+		glEnable(GL_BLEND);
+
+		glLineWidth(mpr->line_width + 3.0f);
+		cage2d_draw_circle_wire(&r, margin, (const float[3]){0, 0, 0}, transform_flag, draw_options);
+		glLineWidth(mpr->line_width);
+		cage2d_draw_circle_wire(&r, margin, color, transform_flag, draw_options);
+
+
+		/* corner manipulators */
+		cage2d_draw_circle_handles(&r, margin, color, transform_flag, true);
+		cage2d_draw_circle_handles(&r, margin, (const float[3]){0, 0, 0}, transform_flag, false);
+
+		glDisable(GL_BLEND);
+		glDisable(GL_LINE_SMOOTH);
+	}
+	else {
+		BLI_assert(0);
 	}
 
 	if (select) {
@@ -514,43 +634,45 @@ static void manipulat

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list