[Bf-blender-cvs] [dc1a17501d6] sculpt-mode-features: Brush cursor: Radial symmetry and tiling preview support

Pablo Dobarro noreply at git.blender.org
Sat Mar 16 02:09:40 CET 2019


Commit: dc1a17501d6be4a74a9ac49b5c25960861ccfe94
Author: Pablo Dobarro
Date:   Sat Mar 16 02:09:04 2019 +0100
Branches: sculpt-mode-features
https://developer.blender.org/rBdc1a17501d6be4a74a9ac49b5c25960861ccfe94

Brush cursor: Radial symmetry and tiling preview support

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

M	source/blender/editors/sculpt_paint/paint_cursor.c

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

diff --git a/source/blender/editors/sculpt_paint/paint_cursor.c b/source/blender/editors/sculpt_paint/paint_cursor.c
index c9880ae3af1..b4633a0a3fd 100644
--- a/source/blender/editors/sculpt_paint/paint_cursor.c
+++ b/source/blender/editors/sculpt_paint/paint_cursor.c
@@ -45,6 +45,7 @@
 #include "BKE_node.h"
 #include "BKE_paint.h"
 #include "BKE_colortools.h"
+#include "BKE_object.h"
 
 #include "WM_api.h"
 #include "wm_cursors.h"
@@ -1044,37 +1045,93 @@ static bool ommit_cursor_drawing(Paint *paint, ePaintMode mode, Brush *brush)
 	return true;
 }
 
-void cursor_draw_point_with_symmetry(const uint gpuatrr, const ARegion *ar,const float pos[3], const char symm, const float obmat[4][4], const float persmat[4][4]){
+void cursor_draw_point_screen_space(const uint gpuattr, const ARegion *ar, float location[3],
+                                    float obmat[4][4], float persmat[4][4])
+{
 	float ar_width = ar->winrct.xmax - ar->winrct.xmin;
 	float ar_height = ar->winrct.ymax - ar->winrct.ymin;
-	int  i = 0;
-	for (i = 0; i <= symm; ++i) {
-		if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
-			float vertex_pos[3] = {
-				pos[0],
-				pos[1],
-				pos[2],
-			};
-			flip_v3_v3(vertex_pos, vertex_pos, (char)i);
-
-			float translation_vertex_cursor[2];
-			mul_m4_v3(obmat, vertex_pos);
-			float pv4[4] = {
-				vertex_pos[0],
-				vertex_pos[1],
-				vertex_pos[2],
-				1.0f,
-			};
-			mul_m4_v4(persmat, pv4);
-
-			if (pv4[3] > 0.0f) {
-				float width_half = ar_width * 0.5f;
-				float height_half = ar_height * 0.5f;
-				translation_vertex_cursor[0] = width_half + width_half * (pv4[0] / pv4[3]);
-				translation_vertex_cursor[1] = height_half + height_half * (pv4[1] / pv4[3]);
+	float pv4[4], translation_vertex_cursor[2];
+	mul_m4_v3(obmat, location);
+	copy_v3_v3(pv4, location);
+	pv4[3] = 1.0f;
+	mul_m4_v4(persmat, pv4);
+	if (pv4[3] > 0.0f) {
+		float width_half = ar_width * 0.5f;
+		float height_half = ar_height * 0.5f;
+		translation_vertex_cursor[0] = width_half + width_half * (pv4[0] / pv4[3]);
+		translation_vertex_cursor[1] = height_half + height_half * (pv4[1] / pv4[3]);
+	}
+	imm_draw_circle_fill_3d(gpuattr, translation_vertex_cursor[0], translation_vertex_cursor[1], 3, 10);
+}
+
+void cursor_draw_tiling_preview(const uint gpuattr, const ARegion *ar, float true_location[3],
+                                     Sculpt *sd, Object *ob, float persmat[4][4], float radius)
+{
+	BoundBox *bb = BKE_object_boundbox_get(ob);
+	float orgLoc[3], location[3], pv4[4], translation_vertex_cursor[2];
+	int  dim, tile_pass = 0;
+	int start[3];
+	int end[3];
+	int cur[3];
+	const float *bbMin = bb->vec[0];
+	const float *bbMax = bb->vec[6];
+	const float *step = sd->paint.tile_offset;
+
+	copy_v3_v3(orgLoc, true_location);
+	for (dim = 0; dim < 3; ++dim) {
+		if ((sd->paint.symmetry_flags & (PAINT_TILE_X << dim)) && step[dim] > 0) {
+			start[dim] = (bbMin[dim] - orgLoc[dim] - radius) / step[dim];
+			end[dim] = (bbMax[dim] - orgLoc[dim] + radius) / step[dim];
+		}
+		else
+			start[dim] = end[dim] = 0;
+	}
+	copy_v3_v3_int(cur, start);
+	for (cur[0] = start[0]; cur[0] <= end[0]; ++cur[0]) {
+		for (cur[1] = start[1]; cur[1] <= end[1]; ++cur[1]) {
+			for (cur[2] = start[2]; cur[2] <= end[2]; ++cur[2]) {
+				if (!cur[0] && !cur[1] && !cur[2])
+					continue; /* skip tile at orgLoc, this was already handled before all others */
+				++tile_pass;
+				for (dim = 0; dim < 3; ++dim) {
+					location[dim] = cur[dim] * step[dim] + orgLoc[dim];
+				}
+				cursor_draw_point_screen_space(gpuattr, ar, location, ob->obmat, persmat);
 			}
+		}
+	}
+}
+void cursor_draw_point_with_symmetry(const uint gpuattr, const ARegion *ar,const float true_location[3],
+                                     Sculpt *sd, Object *ob, float persmat[4][4], float radius)
+{
+	const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
+	float location[3], pv4[4], translation_vertex_cursor[2], symm_rot_mat[4][4];
+
+	copy_v3_v3(location, true_location);
+	for (int i = 0; i <= symm; ++i) {
+		if (i == 0 || (symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5)))) {
 
-			imm_draw_circle_fill_3d(gpuatrr, translation_vertex_cursor[0], translation_vertex_cursor[1], 3, 10);
+			/* Axis Symmetry */
+			flip_v3_v3(location, true_location, (char)i);
+			cursor_draw_point_screen_space(gpuattr, ar, location, ob->obmat, persmat);
+
+			/* Tiling */
+			copy_v3_v3(location, true_location);
+			cursor_draw_tiling_preview(gpuattr, ar, location, sd, ob, persmat, radius);
+
+			/* Radial Symmetry */
+			for (char raxis = 0; raxis < 3; raxis++) {
+				for (int r = 1; r < sd->radial_symm[raxis]; r++) {
+					float angle = 2 * M_PI * r / sd->radial_symm[(int)raxis];
+					flip_v3_v3(location, true_location, (char)i);
+					unit_m4(symm_rot_mat);
+					rotate_m4(symm_rot_mat, raxis+'X', angle);
+					mul_m4_v3(symm_rot_mat, location);
+
+					cursor_draw_tiling_preview(gpuattr, ar, location, sd, ob, persmat, radius);
+					cursor_draw_point_screen_space(gpuattr, ar, location, ob->obmat, persmat);
+				}
+			}
 		}
 	}
 }
@@ -1082,7 +1139,6 @@ void cursor_draw_point_with_symmetry(const uint gpuatrr, const ARegion *ar,const
 static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
 {
 	Scene *scene = CTX_data_scene(C);
-	Depsgraph *depsgraph = CTX_data_depsgraph(C);
 	ARegion *ar = CTX_wm_region(C);
 	UnifiedPaintSettings *ups = &scene->toolsettings->unified_paint_settings;
 	Paint *paint = BKE_paint_get_active_from_context(C);
@@ -1183,8 +1239,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
 	/* Only sculpt cursor for now */
 	if ((mode == PAINT_MODE_SCULPT) && vc.obact->sculpt) {
 		Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
-		const char symm = sd->paint.symmetry_flags & PAINT_SYMM_AXIS_ALL;
-
 		wmWindow *win = CTX_wm_window(C);
 		if (sd->paint.brush->overlay_flags & BRUSH_OVERLAY_CURSOR) {
 			WM_cursor_set(win, CURSOR_STD);
@@ -1199,7 +1253,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
 			gi.use_sampled_normal = true;
 			hit = sculpt_stroke_get_geometry_info(C, &gi, mouse);
 			if (hit && !alpha_overlay_active) {
-
 				float rds;
 				if (!BKE_brush_use_locked_size(scene, brush)) {
 					rds = paint_calc_object_space_radius(&vc, gi.location, BKE_brush_size_get(scene, brush));
@@ -1212,7 +1265,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
 
 				/* draw 3D vertex preview */
 				if (len_v3v3(gi.nearest_vertex_co, gi.location) < rds) {
-					cursor_draw_point_with_symmetry(pos3d, ar, gi.nearest_vertex_co, symm, vc.obact->obmat, vc.rv3d->persmat);
+					cursor_draw_point_with_symmetry(pos3d, ar, gi.nearest_vertex_co, sd, vc.obact, vc.rv3d->persmat, rds);
 				}
 
 				/* draw brush cursor */
@@ -1250,7 +1303,7 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
 				if (ss->cache->brush->sculpt_tool == SCULPT_TOOL_GRAB) {
 					add_v3_v3(cursor_location, ss->cache->grab_delta);
 				}
-				cursor_draw_point_with_symmetry(pos3d, ar, cursor_location, symm, vc.obact->obmat, vc.rv3d->persmat);
+				cursor_draw_point_with_symmetry(pos3d, ar, cursor_location, sd, vc.obact, vc.rv3d->persmat, ss->cache->radius);
 			}
 		}
 	}
@@ -1259,7 +1312,6 @@ static void paint_draw_cursor(bContext *C, int x, int y, void *UNUSED(unused))
 		imm_draw_circle_wire_3d(pos3d, translation[0], translation[1], final_radius, 40);
 	}
 
-
 	immUnbindProgram();
 
 	/* restore GL state */



More information about the Bf-blender-cvs mailing list