[Bf-blender-cvs] [fa86bbb0542] soc-2017-sculpting_improvements: Inner vertices now get calculated as well as edgerings. Problem with holes in the edgerings.
Sebastian Witt
noreply at git.blender.org
Tue Aug 15 09:59:51 CEST 2017
Commit: fa86bbb054281c0b3911c08549f4781f5af3bd6d
Author: Sebastian Witt
Date: Tue Aug 15 09:58:30 2017 +0200
Branches: soc-2017-sculpting_improvements
https://developer.blender.org/rBfa86bbb054281c0b3911c08549f4781f5af3bd6d
Inner vertices now get calculated as well as edgerings. Problem with holes in the edgerings.
===================================================================
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 5f1e595a226..9b2e3600616 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -234,8 +234,6 @@ 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 {
@@ -7221,8 +7219,7 @@ 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;
- bool first_e_flip;
- int first_e;
+ bool e_flip_orientation;
IntersectionData *i_data;
BLI_array_declare(int_points);
@@ -7242,20 +7239,22 @@ 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,
+ /* TODO: Negative epsilon for better results. Still produces holes. */
+ if (isect_line_segment_tri_epsilon_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))
+ &t_lambda, NULL, -0.00001f))
{
- 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)));
+ e_flip_orientation = 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);
+ /*TODO: Bad practise? Pointer is negative if edge orientation needs to be flipped to target inwards. */
+ BLI_ghash_insert(edge_hash, SET_INT_IN_POINTER(e_start + e), SET_INT_IN_POINTER(e_flip_orientation ? (BLI_array_count(int_points) + 1) : -(BLI_array_count(int_points) + 1)));
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);
+ if(t_lambda > 0.999999f || t_lambda < 0.000001f) {
+ bl_debug_color_set(0xff3333);
+ } else {
+ 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);
@@ -7269,17 +7268,11 @@ 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);
memcpy(i_data->intersection_points, int_points, BLI_array_count(int_points) * sizeof(float));
- //if (sil->isect_chunk)
- //prep_float_shared_mem((float**)&sil->intersection_points, &sil->num_intersection_points, &int_points_shared_start, BLI_array_count(int_points), "exact intersecting points");
- //memcpy(&sil->intersection_points[int_points_shared_start], int_points, BLI_array_count(int_points) * sizeof(float));
}
-
BLI_mutex_unlock(&data->mutex);
BLI_array_free(int_points);
@@ -7290,6 +7283,82 @@ static void do_calc_sil_intersect_task_cb_ex(void *userdata, void *UNUSED(userda
BLI_ghash_free(edge_hash, NULL, NULL);
}
+static void remove_connected_from_edgehash(MeshElemMap *emap, GHash *edge_hash, int v) {
+ for (int e = 0; e < emap[v].count; e++) {
+ BLI_ghash_remove(edge_hash, emap[v].indices[e], NULL, NULL);
+ }
+}
+
+static void remove_connected_from_edgehash_list(MeshElemMap *emap, GHash **edge_hash, int num_hash, int v) {
+ for (int e = 0; e < emap[v].count; e++) {
+ for(int i = 0; i < num_hash; i++) {
+ BLI_ghash_remove(edge_hash[i], emap[v].indices[e], NULL, NULL);
+ }
+ }
+}
+
+static bool has_cross_border_neighbour(Mesh *me, GHash *vert_hash, GHash *edge_hash, MeshElemMap *emap, int edge, int l_v_edge, int depth) {
+ int v_edge;
+
+ v_edge = me->medge[edge].v1 == l_v_edge ? me->medge[edge].v2 : me->medge[edge].v1;
+
+ if (depth == 0) {
+ return BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(v_edge));
+ } else {
+ if(!BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(v_edge))){
+ for (int e = 0; e < emap[v_edge].count; e++) {
+ if(emap[v_edge].indices[e] != edge) {
+ if(has_cross_border_neighbour(me, vert_hash, edge_hash, emap, emap[v_edge].indices[e], v_edge, depth - 1)){
+ return true;
+ }
+ }
+ }
+ } else {
+ BLI_ghash_remove(edge_hash, edge, NULL, NULL);
+ }
+ }
+ return false;
+}
+
+/* Get the adjacent edge which connects the edges within the edge_hash. Used to create multiple ordered loops
+ * v_edge is the endpoint off curr_edge from which to branch off
+ * TODO: One wide strips might get cutoff */
+static int get_adjacent_edge(Mesh *me, MeshElemMap *emap, int curr_edge, int v_edge, GHash *edge_hash, GHash *vert_hash)
+{
+ for (int e = 0; e < emap[v_edge].count; e++) {
+ if(emap[v_edge].indices[e] != curr_edge && has_cross_border_neighbour(me, vert_hash, edge_hash, emap, emap[v_edge].indices[e], v_edge, 1)) {
+ return emap[v_edge].indices[e];
+ }
+ }
+ for (int e = 0; e < emap[v_edge].count; e++) {
+ if(emap[v_edge].indices[e] != curr_edge && has_cross_border_neighbour(me, vert_hash, edge_hash, emap, emap[v_edge].indices[e], v_edge, 2)) {
+ return emap[v_edge].indices[e];
+ }
+ }
+ /*End Of Loop. Shouldn't happen with two manifold meshes*/
+ return -1;
+}
+
+static int get_adjacent_edge_from_list(Mesh *me, MeshElemMap *emap, int curr_edge, int v_edge, GHash **edge_hash, int num_hash, GHash *vert_hash)
+{
+ for (int e = 0; e < emap[v_edge].count; e++) {
+ for (int i = 0; i < num_hash; i++) {
+ if(emap[v_edge].indices[e] != curr_edge && has_cross_border_neighbour(me, vert_hash, edge_hash[i], emap, emap[v_edge].indices[e], v_edge, 1)) {
+ return emap[v_edge].indices[e];
+ }
+ }
+ }
+ for (int e = 0; e < emap[v_edge].count; e++) {
+ for (int i = 0; i < num_hash; i++) {
+ if(emap[v_edge].indices[e] != curr_edge && has_cross_border_neighbour(me, vert_hash, edge_hash[i], emap, emap[v_edge].indices[e], v_edge, 2)) {
+ return emap[v_edge].indices[e];
+ }
+ }
+ }
+ /*End Of Loop. Shouldn't happen with two manifold meshes*/
+ return -1;
+}
+
static void check_preceding_intersecting_edges(Object *ob, SilhouetteData *sil, SpineBranch *branch, PBVHNode **nodes, int tot_edge)
{
printf("Checking preceding edges.\n Total edges to check: %i\n Total Triangles: %i\n Total Nodes: %i\n", tot_edge, sil->num_inter_tris, sil->num_inter_nodes);
@@ -7333,11 +7402,23 @@ static void crawl_mesh_rec (Mesh *me, MeshElemMap *emap, GHash *vert_hash, Inter
static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
{
IntersectionData *data = sil->isect_chunk;
+ GHash **isect_ghash_dupe;
MeshElemMap *emap;
GHash *vert_hash = BLI_ghash_int_new("vertices within intersection");
int *emap_mem;
- MEdge *first_e = NULL;
+ int start_edge;
int inside_vert;
+ GHashIterState pop_state;
+ void *tkey, *tv;
+ int first_e, comp_v, curr_edge, last_edge, tmp_curr_edge, r_size;
+
+ /*TODO: remove, while loop safety if bug occurs*/
+ int breaker;
+
+ int *edge_ring_fillet = NULL;
+ int *ring_start = NULL;
+ BLI_array_declare(edge_ring_fillet);
+ BLI_array_declare(ring_start);
if (!data) {
return;
@@ -7346,14 +7427,77 @@ static void combine_intersection_data(Mesh *me, SilhouetteData *sil)
/* 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;
+ isect_ghash_dupe = MEM_callocN(sizeof(GHash *) * sil->num_isect_data, "edge hash duplicate");
+ for (int i = 0; i < sil->num_isect_data; i++) {
+ isect_ghash_dupe[i] = BLI_ghash_copy(data[i].edge_hash, NULL, NULL);
+ }
+
+ for(int i = 0; i < sil->num_isect_data; i++) {
+ memset(&pop_state, 0, sizeof(GHashIterState));
+ while (BLI_ghash_pop(isect_ghash_dupe[i], &pop_state, &tkey, &tv)) {
+ first_e = (int) tkey;
+ inside_vert = ((int)tv > 0) ^ sil->do_subtract ? me->medge[first_e].v1 : me->medge[first_e].v2;
+
+ crawl_mesh_rec(me, emap, vert_hash, data, sil->num_isect_data, inside_vert);
+
+ breaker = me->totedge;
+ comp_v = BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(me->medge[first_e].v1)) ? me->medge[first_e].v2 : me->medge[first_e].v1;
+ BLI_assert(!BLI_ghash_haskey(vert_hash, SET_INT_IN_POINTER(comp_v)));
+ start_edge = -1;
+ start_edge = get_adjacent_edge_from_list(me, emap, first_e, comp_v, isect_ghash_dupe, sil->num_isect_data, vert_hash);
+ if(start_edge >= 0) {
+ BLI_array_append(ring_start, BLI_array_count(edge_ring_fillet));
+ curr_edge = start_edge;
+ last_edge = -1;
+
+ while(!(curr_edge == start_edge && last_edge != -1) && curr_edge != -1 && breaker > 0) {
+ BLI_array_append(edge_ring_fillet, curr_edge);
+ if(last_edge == -1) {
+ comp_v = me->medge[start_edge].v1;
+ } else {
+ if (me->medge[curr_edge].v1 == me->medge[last_edge].v1 || me->medge[curr_edge].v1 == me->medge[last_edge].v2) {
+ comp_v = me->medge[curr_edge].v2;
+ } else {
+ comp_v = me->medge[curr_edge].v1;
+ }
+ }
+ remove_connected_from_edgehash_list(e
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list