[Bf-blender-cvs] [a09c182b345] soc-2017-sculpting_improvements: Started connecting the silhouette to existing geometry. Intersecting vertices get detected. (define DEBUG_DRAW to see)

Sebastian Witt noreply at git.blender.org
Fri Jul 28 13:04:58 CEST 2017


Commit: a09c182b3454e576f5137de316b10d8d799f929d
Author: Sebastian Witt
Date:   Fri Jul 28 13:02:43 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rBa09c182b3454e576f5137de316b10d8d799f929d

Started connecting the silhouette to existing geometry. Intersecting vertices get detected. (define DEBUG_DRAW to see)

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

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

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

diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 6d9c36279ed..93bfef1834d 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -118,6 +118,7 @@
 #include "BLI_alloca.h"
 #include "BLI_array.h"
 
+#define SILHOUETTE_STROKE_STORE_CHUNK 512
 /*#define DEBUG_DRAW*/
 #ifdef DEBUG_DRAW
 /* static void bl_debug_draw(void);*/
@@ -142,6 +143,47 @@ static void bl_debug_draw_point(const float pos[3],const float thickness)
 }
 #endif
 
+typedef struct {
+	float bmin[3], bmax[3];
+} BB;
+
+/*	init data:
+ * 	Silhouette Data */
+typedef struct SilhouetteStroke {
+	float *points;
+	float *points_v2;
+	int totvert;
+	int max_verts;
+	BB bb;
+} SilhouetteStroke;
+
+typedef enum {
+	SIL_INIT = 0,
+	SIL_DRAWING = 1,
+	SIL_OP = 2
+} SilhouetteState;
+
+typedef struct SilhouetteData {
+	ARegion *ar;        	/* region that Silhouette started drawn in */
+	void *draw_handle;  	/* for drawing preview loop */
+	ViewContext vc;
+	SilhouetteStroke *current_stroke;
+	Object *ob;
+	BMEditMesh *em;			/*Triangulated stroke for spine generation*/
+	Scene *scene;
+
+	float add_col[3];		/* preview color */
+	float last_mouse_pos[2];
+
+	SilhouetteState state;	/* Operator state */
+
+	float depth;			/* Depth or thickness of the generated shape */
+	float smoothness;		/* Smoothness of the generated shape */
+	int resolution;			/* Subdivision of the shape*/
+	float anchor[3];		/* Origin point of the reference plane */
+	float z_vec[3];			/* Orientation of the reference plane */
+} SilhouetteData;
+
 /** \name Tool Capabilities
  *
  * Avoid duplicate checks, internal logic only,
@@ -548,6 +590,7 @@ typedef struct SculptThreadedTaskData {
 	float strength;
 	bool smooth_mask;
 	bool has_bm_orco;
+	SilhouetteData *sil;
 
 	SculptProjectVector *spvc;
 	float *offset;
@@ -5024,40 +5067,23 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
 
 /****************** Topology tools Silhouette ******************/
 
-/*	init data:
- * 	Silhouette Data */
-typedef struct SilhouetteStroke {
-	float *points;
-	int totvert;
-	int max_verts;
-}SilhouetteStroke;
-
-typedef enum {
-	SIL_INIT = 0,
-	SIL_DRAWING = 1,
-	SIL_OP = 2
-} SilhouetteState;
-
-typedef struct SilhouetteData {
-	ARegion *ar;        	/* region that Silhouette started drawn in */
-	void *draw_handle;  	/* for drawing preview loop */
-	ViewContext vc;
-	SilhouetteStroke *current_stroke;
-	Object *ob;
-	BMEditMesh *em;			/*Triangulated stroke for spine generation*/
-	Scene *scene;
+/* Axis-aligned bounding box (Same as in pbvh_intern.h)*/
 
-	float add_col[3];		/* preview color */
-	float last_mouse_pos[2];
-
-	SilhouetteState state;	/* Operator state */
+/* TODO: import BB functions */
+/* Expand the bounding box to include a new coordinate */
+static void BB_expand(BB *bb, const float co[3])
+{
+	for (int i = 0; i < 3; ++i) {
+		bb->bmin[i] = min_ff(bb->bmin[i], co[i]);
+		bb->bmax[i] = max_ff(bb->bmax[i], co[i]);
+	}
+}
 
-	float depth;			/* Depth or thickness of the generated shape */
-	float smoothness;		/* Smoothness of the generated shape */
-	int resolution;			/* Subdivision of the shape*/
-	float anchor[3];		/* Origin point of the reference plane */
-	float z_vec[3];			/* Orientation of the reference plane */
-} SilhouetteData;
+static void BB_reset(BB *bb)
+{
+	bb->bmin[0] = bb->bmin[1] = bb->bmin[2] = FLT_MAX;
+	bb->bmax[0] = bb->bmax[1] = bb->bmax[2] = -FLT_MAX;
+}
 
 static void silhouette_stroke_free(SilhouetteStroke *stroke)
 {
@@ -5069,13 +5095,14 @@ static void silhouette_stroke_free(SilhouetteStroke *stroke)
 	}
 }
 
-static SilhouetteStroke *silhouette_stroke_new(int max_verts)
+static SilhouetteStroke *silhouette_stroke_new()
 {
 	SilhouetteStroke *stroke = MEM_callocN(sizeof(SilhouetteStroke), "SilhouetteStroke");
-	stroke->points = 0;
-	stroke->points = MEM_callocN(sizeof(float) * 3 * max_verts,"SilhouetteStrokePoints");/* TODO: Dynamic length */
+	stroke->points = MEM_callocN(sizeof(float) * 3 * SILHOUETTE_STROKE_STORE_CHUNK,"SilhouetteStrokePoints");
+	stroke->points_v2 = MEM_callocN(sizeof(float) * 2 * SILHOUETTE_STROKE_STORE_CHUNK,"SilhouetteStrokePoints");
 	stroke->totvert = 0;
-	stroke->max_verts = max_verts;
+	stroke->max_verts = SILHOUETTE_STROKE_STORE_CHUNK;
+	BB_reset(&stroke->bb);
 	return stroke;
 }
 
@@ -5089,7 +5116,7 @@ static SilhouetteData *silhouette_data_new(bContext *C)
 	const float *fp = ED_view3d_cursor3d_get(scene, v3d);
 
 	sil->ar = CTX_wm_region(C);
-	sil->current_stroke = silhouette_stroke_new(1024);
+	sil->current_stroke = silhouette_stroke_new();
 	view3d_set_viewcontext(C, &sil->vc);
 
 	sil->add_col[0] = 1.00; /* add mode color is light red */
@@ -5125,25 +5152,33 @@ static void silhoute_stroke_point_to_3d(SilhouetteData *sil, int point, float r_
 	/*ED_view3d_win_to_3d(sil->vc.v3d, sil->ar, sil->anchor, &sil->current_stroke->points[point], r_v);*/
 }
 
+#if 0
 /* TODO: Add dynamic memory allocation */
 static void silhouette_stroke_add_3Dpoint(SilhouetteStroke *stroke, float point[3])
 {
-	if (stroke->totvert < stroke->max_verts) {
-		copy_v3_v3(&stroke->points[stroke->totvert * 3], point);
-		stroke->totvert ++;
-	} else {
-		printf("Stroke reached maximum vert count.\n");
+	if (stroke->totvert >= stroke->max_verts) {
+		stroke->max_verts += SILHOUETTE_STROKE_STORE_CHUNK;
+		stroke->points = MEM_reallocN(stroke->points, sizeof(float) * 3 * stroke->max_verts);
+		stroke->points_v2 = MEM_reallocN(stroke->points_v2, sizeof(float) * 2 * stroke->max_verts);
 	}
+
+	copy_v3_v3(&stroke->points[stroke->totvert * 3], point);
+	stroke->totvert ++;
 }
+#endif
 
 static void silhouette_stroke_add_point(SilhouetteData *sil, SilhouetteStroke *stroke, float point[2])
 {
-	if (stroke->totvert < stroke->max_verts) {
-		ED_view3d_win_to_3d(sil->vc.v3d, sil->ar, sil->anchor, point, &sil->current_stroke->points[stroke->totvert * 3]);
-		stroke->totvert ++;
-	} else {
-		printf("Stroke reached maximum vert count.\n");
+	if (stroke->totvert >= stroke->max_verts) {
+		stroke->max_verts += SILHOUETTE_STROKE_STORE_CHUNK;
+		stroke->points = MEM_reallocN(stroke->points, sizeof(float) * 3 * stroke->max_verts);
+		stroke->points_v2 = MEM_reallocN(stroke->points_v2, sizeof(float) * 2 * stroke->max_verts);
 	}
+
+	copy_v2_v2(&stroke->points_v2[stroke->totvert * 2], point);
+	ED_view3d_win_to_3d(sil->vc.v3d, sil->ar, sil->anchor, point, &sil->current_stroke->points[stroke->totvert * 3]);
+	BB_expand(&stroke->bb, &sil->current_stroke->points[stroke->totvert * 3]);
+	stroke->totvert ++;
 }
 
 /* Set reference plane, 3D plane which is drawn on in 2D */
@@ -5203,6 +5238,31 @@ typedef struct Spine{
 	SpineBranch **branches; /* All branches. Can contain Null pointers if branches got removed*/
 }Spine;
 
+typedef struct {
+	SculptSession *ss;
+	BB *bb_target;
+	bool original;
+} SculptSearchBBData;
+
+/* Search nodes to integrate another BB into (used for silhouette)*/
+static bool sculpt_search_BB_cb(PBVHNode *node, void *data_v)
+{
+	SculptSearchBBData *data = data_v;
+	BB *bb_target = data->bb_target;
+	float bb_min[3], bb_max[3];
+	int i;
+
+	BKE_pbvh_node_get_BB(node, bb_min, bb_max);
+
+	/* min is inclusive max is exclusive? BB*/
+	for (i = 0; i < 3; ++i) {
+		if(bb_target->bmin[i] >= bb_max[i] || bb_target->bmax[i] < bb_min[i]){
+			return false;
+		}
+	}
+	return true;
+}
+
 static int get_adjacent_faces(BMFace *f, BMFace **ad_f, BMFace *last_f)
 {
 	int ad_faces = 0;
@@ -6947,25 +7007,73 @@ static void silhouette_create_shape_mesh(bContext *C, Mesh *me, SilhouetteData *
 }
 
 /* Adds additional points to the stroke if start and end are far apart. */
-static void stroke_smooth_cap(SilhouetteStroke *stroke, float max_dist)
+static void stroke_smooth_cap(SilhouetteData *sil, SilhouetteStroke *stroke, float max_dist)
 {
-	float v1[3], v2[3], dv[3];
+	float v1[2], v2[2], dv[2];
 	float length = 0;
-	copy_v3_v3(v1, &stroke->points[0]);
-	copy_v3_v3(v2, &stroke->points[stroke->totvert * 3 - 3]);
+	copy_v2_v2(v1, &stroke->points_v2[0]);
+	copy_v2_v2(v2, &stroke->points_v2[stroke->totvert * 2 - 2]);
 
-	sub_v3_v3v3(dv,v1,v2);
-	length = len_v3(dv);
+	sub_v2_v2v2(dv,v1,v2);
+	length = len_v2(dv);
 
 	if (length > max_dist) {
 		int steps = floorf(length / (float)max_dist);
-		mul_v3_fl(dv, 1.0f / (float)steps);
+		mul_v2_fl(dv, 1.0f / (float)steps);
 		for (int i = 1; i < steps; i++) {
-			mul_v3_v3fl(v1, dv, i);
-			add_v3_v3(v1, v2);
-			silhouette_stroke_add_3Dpoint(stroke, v1);
+			mul_v2_v2fl(v1, dv, i);
+			add_v2_v2(v1, v2);
+			silhouette_stroke_add_point(sil, stroke, v1);
+		}
+	}
+}
+
+/* Calculate the intersections with existing geometry. Used to connect the new Silhouette to the old mesh
+ * Fillets are the smooth transition from one part to another.
+ */
+static void do_calc_fillet_line_task_cb_ex(
+										   void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id))
+{
+	SculptThreadedTaskData *data = userdata;
+	SculptSession *ss = data->ob->sculpt;
+	SilhouetteData *sil = data->sil;
+
+	PBVHVertexIter vd;
+	float (*proxy)[3];
+	float point[2];
+
+	proxy = BKE_pbvh_node_add_proxy(ss->pbvh, data->nodes[n])->co;
+
+	BKE_pbvh_vertex_iter_begin(ss->pbvh, data->nodes[n], vd, PBVH_ITER_UNIQUE)
+	{
+		/* get the interior vertices of the 2d drawn silhouette and all relevant vertices */
+		ED_view3d_project_float_v2_m4(sil->ar, vd.co, point, data->mat);
+		if (isect_point_poly_v2(point, (float(*)[2])sil->current_stroke->points_v2, sil->current_stroke->totvert, false)){
+#ifdef DEBUG_DRAW
+			bl_debug_color_set(0xff0000);
+			bl_debug_draw_point(vd.co, 0.2f);
+			bl_debug_color_set(0x000000);
+#endif
 		}
 	}
+	BKE_pbvh_vertex_iter_end;
+}
+
+static void do_calc_fillet_line(Object *ob, SilhouetteData *silhouette, PBVHNode **nodes, int totnode)
+{
+	float projmat[4][4];
+	/* calc the projection matrix used to convert 3d vertice in 2d space */
+	ED_view3d_ob_project_mat_get(silhouette->ar->regiondata, ob, projmat);
+
+	/* threaded loop over nodes */
+	SculptThreadedTaskData data = {
+		.ob = ob, .nodes = nodes,
+		.sil = silhouette, .mat = projmat
+	};
+
+	BLI_task_parallel_range_ex(
+							   0, totnode, &data, NULL, 0, do_calc_fillet_line_task_

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list