[Bf-blender-cvs] [3ab49cae0e8] soc-2017-sculpting_improvements: First version calculating the inside and outside vertices. Needs multiple ring support. Holes from earlier misscalculations break the "floodfill" algorithm.
Sebastian Witt
noreply at git.blender.org
Mon Aug 14 13:04:11 CEST 2017
Commit: 3ab49cae0e8c5e86c7e23a5a81ee322a1ef599bd
Author: Sebastian Witt
Date: Mon Aug 14 13:01:54 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rB3ab49cae0e8c5e86c7e23a5a81ee322a1ef599bd
First version calculating the inside and outside vertices. Needs multiple ring support. Holes from earlier misscalculations break the "floodfill" algorithm.
===================================================================
M release/scripts/startup/bl_ui/space_view3d_toolbar.py
M source/blender/editors/sculpt_paint/sculpt.c
M source/blender/makesdna/DNA_scene_types.h
===================================================================
diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
index 0fe8499a3e7..06c7007c9a8 100644
--- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py
+++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py
@@ -1672,6 +1672,12 @@ class VIEW3D_PT_sculpt_silhouette(Panel, View3DPaintPanel):
col.prop(sculpt, "silhouette_smoothness", text="Smoothness", slider=True)
col.prop(sculpt, "silhouette_depth", text="Depth")
col.prop(sculpt, "silhouette_resolution", text="Resolution")
+ sub = col.column()
+
+ sub.row().prop(sculpt, "silhouette_add", text="Add")
+ sub.row().prop(sculpt, "silhouette_subtract", text="Subtract")
+
+ col.separator()
class VIEW3D_PT_tools_brush_appearance(Panel, View3DPaintPanel):
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 196300664b3..5f1e595a226 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -234,9 +234,16 @@ typedef struct IntersectionData {
float *intersection_points; /* exact positions where the two shapes connect */
GHash *edge_hash;
int num_intersection_points; /* 3 times intersection point count*/
+ int first_e;
+ bool flip;
} IntersectionData;
typedef enum {
+ SILHOUETTE_DEFAULT = 0,
+ SILHOUETTE_DO_SUBTRACT = 1
+} SilhouetteToolFlags;
+
+typedef enum {
SIL_INIT = 0,
SIL_DRAWING = 1,
SIL_OP = 2
@@ -259,6 +266,7 @@ typedef struct SilhouetteData {
float depth; /* Depth or thickness of the generated shape */
float smoothness; /* Smoothness of the generated shape */
int resolution; /* Subdivision of the shape*/
+ bool do_subtract; /* Is in subtractive mode? Clipping brush functionality */
float anchor[3]; /* Origin point of the reference plane */
float z_vec[3]; /* Orientation of the reference plane */
MeshElemMap *emap; /* Original Mesh vert -> edges map */
@@ -5242,7 +5250,8 @@ static SilhouetteData *silhouette_data_new(bContext *C)
/*Load RNA Data if present */
sil->smoothness = sd->silhouette_smoothness / 100.0f;
sil->depth = sd->silhouette_depth;
- sil->resolution = sd->silhouette_resolution;
+ sil->resolution = sd->silhouette_resolution;;
+ sil->do_subtract = sd->silhouette_flags & SILHOUETTE_DO_SUBTRACT;
copy_v3_v3(sil->anchor, fp);
@@ -5253,6 +5262,12 @@ static SilhouetteData *silhouette_data_new(bContext *C)
sil->fillet_ring_orig_start = NULL;
sil->inter_edges = NULL;
sil->fillet_ring_bbs = NULL;
+ sil->isect_chunk = NULL;
+ sil->fillet_ring_new = NULL;
+ sil->fillet_ring_new_start = NULL;
+ sil->inter_tris = NULL;
+ sil->tri_nodebind = NULL;
+ sil->v_to_rm = NULL;
sil->scene = scene;
sil->ob = obedit;
@@ -5285,6 +5300,19 @@ static void silhouette_data_free(struct wmOperator *op)
if (data->fillet_ring_bbs) {
MEM_freeN(data->fillet_ring_bbs);
}
+ if (data->inter_tris) {
+ MEM_freeN(data->inter_tris);
+ }
+ if (data->tri_nodebind) {
+ MEM_freeN(data->tri_nodebind);
+ }
+ if (data->v_to_rm) {
+ MEM_freeN(data->v_to_rm);
+ }
+ if (data->isect_chunk) {
+ /*TODO: Free Intersection Data first! */
+ MEM_freeN(data->isect_chunk);
+ }
MEM_SAFE_FREE(data);
}
}
@@ -7133,6 +7161,7 @@ static IntersectionData *add_isect_chunk(SilhouetteData *sil)
return &sil->isect_chunk[sil->num_isect_data - 1];
}
+#if 0
static void prep_float_shared_mem(float **mem, int *r_num, int *r_start, int len, const char *str)
{
if (!mem) {
@@ -7145,6 +7174,7 @@ static void prep_float_shared_mem(float **mem, int *r_num, int *r_start, int len
*mem = MEM_reallocN(*mem, sizeof(float) * (*r_num));
}
}
+#endif
static void prep_int_shared_mem(int **mem, int *r_num, int *r_start, int len, const char *str)
{
@@ -7159,6 +7189,18 @@ static void prep_int_shared_mem(int **mem, int *r_num, int *r_start, int len, co
}
}
+/*TODO: Maybe add real normal calc */
+static bool shared_dir_normal(float e1[3], float e2[3], float v1[3], float v2[3], float v3[3])
+{
+ float d1[3], d2[3], n[3], e[3];
+ sub_v3_v3v3(d1, v2, v1);
+ sub_v3_v3v3(d2, v3, v1);
+ sub_v3_v3v3(e, e2, e1);
+ cross_v3_v3v3(n, d1, d2);
+
+ return dot_v3v3(n, e) > 0;
+}
+
static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userdata_chunk), const int n, const int UNUSED(thread_id))
{
SculptThreadedTaskData *data = userdata;
@@ -7179,7 +7221,8 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
BKE_pbvh_get_tri(bvh, <ris);
GHash *edge_hash = BLI_ghash_int_new("edges within intersection");
float *int_points = NULL;
- int int_points_shared_start;
+ bool first_e_flip;
+ int first_e;
IntersectionData *i_data;
BLI_array_declare(int_points);
@@ -7199,19 +7242,24 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
copy_v3_v3(p2, me->mvert[me->medge[e_start + e].v2].co);
for (int tri_i = 0; tri_i < tri_node_bind_tot; tri_i ++) {
lt = ltris[sil->inter_tris[tri_node_bind + tri_i]];
+ /* Maybe isect with epsilon flexibility needed? */
if (isect_line_segment_tri_v3(p1, p2,
me->mvert[me->mloop[lt.tri[0]].v].co, me->mvert[me->mloop[lt.tri[1]].v].co, me->mvert[me->mloop[lt.tri[2]].v].co,
&t_lambda, NULL))
{
+ if (BLI_array_count(int_points) == 0) {
+ first_e_flip = shared_dir_normal(p1, p2, me->mvert[me->mloop[lt.tri[0]].v].co, me->mvert[me->mloop[lt.tri[1]].v].co, me->mvert[me->mloop[lt.tri[2]].v].co);
+ first_e = e_start + e;
+ }
BLI_ghash_insert(edge_hash, SET_INT_IN_POINTER(e_start + e), SET_INT_IN_POINTER(BLI_array_count(int_points)));
BLI_array_grow_items(int_points, 3);
interp_v3_v3v3(&int_points[BLI_array_count(int_points) - 3], p1, p2, t_lambda);
#ifdef DEBUG_DRAW
- /*bl_debug_color_set(0x0000ff);
+ bl_debug_color_set(0x0000ff);
bl_debug_draw_point(&int_points[BLI_array_count(int_points) - 3], 0.05f);
bl_debug_color_set(0x000000);
bl_debug_draw_edge_add(p1, p2);
- bl_debug_color_set(0x000000);*/
+ bl_debug_color_set(0x000000);
#endif
break;
}
@@ -7221,6 +7269,8 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
BLI_mutex_lock(&data->mutex);
if (BLI_array_count(int_points) > 0) {
i_data = add_isect_chunk(sil);
+ i_data->flip = first_e_flip;
+ i_data->first_e = first_e;
i_data->edge_hash = edge_hash;
i_data->intersection_points = MEM_callocN(sizeof(float) * BLI_array_count(int_points), "exact intersecting points");
i_data->num_intersection_points = BLI_array_count(int_points);
@@ -7263,32 +7313,59 @@ static void check_preceding_intersecting_edges(Object *ob, SilhouetteData *sil,
#endif
}
+static void crawl_mesh_rec (Mesh *me, MeshElemMap *emap, GHash *vert_hash, IntersectionData *i_sect_data, int num_isect_data, int orig)
+{
+ int v_c;
+ for(int e = 0; e < emap[orig].count; e++) {
+ for (int i = 0; i < num_isect_data; i++) {
+ if (BLI_ghash_haskey(i_sect_data[i].edge_hash, SET_INT_IN_POINTER(emap[orig].indices[e]))) {
+ goto next_edge;
+ }
+ }
+ v_c = me->medge[emap[orig].indices[e]].v1 == orig ? me->medge[emap[orig].indices[e]].v2 : me->medge[emap[orig].indices[e]].v1;
+ if (BLI_ghash_reinsert(vert_hash, SET_INT_IN_POINTER(v_c), SET_INT_IN_POINTER(v_c), NULL, NULL)) {
+ crawl_mesh_rec(me, emap, vert_hash, i_sect_data, num_isect_data, v_c);
+ }
+ next_edge:;
+ }
+}
+
static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
{
IntersectionData *data = sil->isect_chunk;
+ MeshElemMap *emap;
+ GHash *vert_hash = BLI_ghash_int_new("vertices within intersection");
+ int *emap_mem;
MEdge *first_e = NULL;
- GHashIterator gh_iter;
+ int inside_vert;
- if (sil->num_isect_data > 0) {
- for (int i = 0; i < sil->num_isect_data; i++) {
- if (BLI_ghash_size(data[i].edge_hash) > 0) {
- GHASH_ITER (gh_iter, data[i].edge_hash) {
- first_e = &me->medge[(int)BLI_ghashIterator_getKey(&gh_iter)];
-#ifdef DEBUG_DRAW
- bl_debug_color_set(0xffffff);
- bl_debug_draw_medge_add(me, (int)BLI_ghashIterator_getKey(&gh_iter));
- bl_debug_color_set(0x000000);
-#endif
- break;
- }
- }
- if(first_e) {
- break;
- }
- }
+ if (!data) {
+ return;
}
- /*TODO: detect which side is inside and which is outside of first_e ...*/
+ /* TODO: Maybe only generate partial map with only the silhouette inside? */
+ BKE_mesh_vert_edge_map_create(&emap, &emap_mem, me->medge, me->totvert, me->totedge);
+
+ first_e = &me->medge[data->first_e];
+
+ /*TODO: Invert for clipping functionality!*/
+ inside_vert = !data->flip ^ sil->do_subtract ? first_e->v2 : first_e->v1;
+
+ BLI_ghash_insert(vert_hash, SET_INT_IN_POINTER(inside_vert), SET_INT_IN_POINTER(inside_vert));
+
+ crawl_mesh_rec(me, emap, vert_hash, data, sil->num_isect_data, inside_vert);
+
+ GHashIterator gh_iter;
+ GHASH_ITER (gh_iter, vert_hash) {
+ int v_c = BLI_ghashIterator_getKey(&gh_iter);
+ bl_debug_color_set(0xffff00);
+ bl_debug_draw_point(me->mvert[v_c].co, 0.025f);
+ bl_debug_color_set(0x000000);
+ }
+
+
+ MEM_freeN(emap);
+ MEM_freeN(emap_mem);
}
/* Generates a 3D shape from a stroke. */
@@ -7354,9 +7431,10 @@ static void silhouette_create_shape_mesh(bContext *C, Mesh *me, SilhouetteData *
e_start = me->totedge;
bridge_all_parts(me, spine, v_steps * 2 + w_steps, n_ori);
- check_preceding_intersecting_edges(ob, sil, NULL, nodes, me->totedge - e_start);
-
- combine_intersection_data(me, sil);
+ if (sil->num_inter_nodes) {
+ check_preceding_intersecting_edges(ob, sil, NULL, nodes, me->totedge - e_start);
+ combine_intersection_data(me, sil);
+ }
/*printf("Joining %i isect data.\n", sil->num_isect_data);
for (int i = 0; i < sil->num_isect_data; i++) {
IntersectionData *isect_data = &sil->isect_chunk[i];
@@ -8072,7 +8150,7 @@ static void do_calc_fillet_line_task_cb_ex(void *userdata, void *UNUSED(userdata
/*TODO: merge rings from multiple threads / nodes*/
#ifdef DEBUG_DRAW
- /*for(int r = 0; r < BLI_array_count(ring_start); r++) {
+ for(int r = 0; r < BLI_array_
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list