Fixed some issues when inserting new meshdata into a pbvh.
authorwitt <sebastian.witt@rwth-aachen.de>
Fri, 9 Jun 2017 15:27:52 +0000 (17:27 +0200)
committerwitt <sebastian.witt@rwth-aachen.de>
Fri, 9 Jun 2017 15:27:52 +0000 (17:27 +0200)
Buffers now get reset and primitives are written.
Works for the simplest cornercase: Alt+Leftclick draw on a mesh with one node outside of that node.

source/blender/blenkernel/BKE_pbvh.h
source/blender/blenkernel/intern/pbvh.c
source/blender/editors/sculpt_paint/sculpt.c

index 23b67ff85de5ae3b2eca14bd381a32cf7b07cf0b..d6bdca81b38f2aea4a351e36cfe482199c543768 100644 (file)
@@ -62,7 +62,7 @@ typedef void (*BKE_pbvh_HitOccludedCallback)(PBVHNode *node, void *data, float *
 /* Building */
 
 PBVH *BKE_pbvh_new(void);
-void BKE_pbvh_attach_mesh(PBVH *pbvh, PBVHNode *node, Mesh *me, int totvert, float *max_bmin, float *max_bmax);
+void BKE_pbvh_attach_mesh(PBVH *pbvh, PBVHNode *node, Mesh *me, int totprim, float *max_bmin, float *max_bmax);
 void BKE_pbvh_build_mesh(
         PBVH *bvh,
         const struct MPoly *mpoly, const struct MLoop *mloop,
@@ -195,7 +195,7 @@ void BKE_pbvh_node_get_verts(
         PBVH *bvh, PBVHNode *node,
         const int **r_vert_indices, struct MVert **r_verts);
 
-void BKE_pbvh_recalc_looptri_from_me(PBVH *pbvh, Mesh *me);
+int BKE_pbvh_recalc_looptri_from_me(PBVH *pbvh, Mesh *me);
 PBVHNode *BKE_search_closest_pbvh_leaf_node(PBVH *pbvh, PBVHNode *p_node, float *target_bmin, float *target_bmax);
 
 void BKE_pbvh_node_get_BB(PBVHNode *node, float bb_min[3], float bb_max[3]);
index c3d814c81095f4555df9d0d4f849a46841fbcc90..fe3b44e8b76cc93ff59a65337c7a916e57aef13a 100644 (file)
@@ -519,16 +519,46 @@ static void pbvh_build(PBVH *bvh, BB *cb, BBC *prim_bbc, int totprim)
  * Attach a new mesh to a node of the PBVH
  * vertdata etc needs to be already in the basemesh
  */
-void BKE_pbvh_attach_mesh(PBVH *pbvh, PBVHNode *node, Mesh *me, int totvert, float *max_bmin, float *max_bmax){
+void BKE_pbvh_attach_mesh(PBVH *pbvh, PBVHNode *node, Mesh *me, int totprim, float *max_bmin, float *max_bmax){
        BB new_BB;
        copy_v3_v3(new_BB.bmin, max_bmin);
        copy_v3_v3(new_BB.bmax, max_bmax);
+       int d_prim = totprim-pbvh->totprim;
 
-       if(totvert <= pbvh->leaf_limit){
+       /*for(int i = 0; i < pbvh->totprim; i++){
+               printf("%i,",pbvh->prim_indices[i]);
+       }*/
+
+       if(me->totvert <= pbvh->leaf_limit){
                pbvh->totvert = me->totvert;
+               pbvh->totprim = totprim;
+               MEM_freeN(pbvh->prim_indices);
+
+               pbvh->prim_indices = MEM_mallocN(sizeof(int) * pbvh->totprim,
+                                                                               "bvh prim indices");
+
+               //TODO: parent nodes need to be scaled as well
+               node->totprim += d_prim;
+               node->prim_indices = pbvh->prim_indices;
+
+               //Fill with all prim to test
+               for(int i = 0; i < pbvh->totprim; i++){
+                       pbvh->prim_indices[i] = i;
+               }
+
                BB_expand_with_bb( &node->vb, &new_BB);
 
-               //build_mesh_leaf_node(pbvh, node);
+               pbvh->verts = me->mvert;
+               pbvh->mloop = me->mloop;
+               pbvh->mpoly = me->mpoly;
+
+               build_mesh_leaf_node(pbvh, node);
+
+               MEM_freeN(node->draw_buffers);
+               node->draw_buffers = NULL;
+
+               BKE_pbvh_node_mark_rebuild_draw(node);
+               printf("Attached new shape to pbvh.\n");
        }else{
                //TODO: Attach to multiple nodes.
        }
@@ -1468,9 +1498,9 @@ float get_bb_distance_sqr(BB a, BB b){
        return dist;
 }
 
-void BKE_pbvh_recalc_looptri_from_me(PBVH *pbvh, Mesh *me){
+int BKE_pbvh_recalc_looptri_from_me(PBVH *pbvh, Mesh *me){
        MEM_freeN(pbvh->looptri);
-       MLoopTri *looptri;
+       MLoopTri *looptri = NULL;
        int looptri_num = poly_to_tri_count(me->totpoly, me->totloop);
        looptri = MEM_mallocN(sizeof(*looptri) * looptri_num, __func__);
 
@@ -1479,7 +1509,12 @@ void BKE_pbvh_recalc_looptri_from_me(PBVH *pbvh, Mesh *me){
                                                        me->mvert,
                                                        me->totloop, me->totpoly,
                                                        looptri);
+       /*for(int i = 0; i < looptri_num; i++){
+               printf("Tri (%i,%i,%i), Poly %i\n", looptri[i].tri[0], looptri[i].tri[1], looptri[i].tri[2], looptri[i].poly);
+       }*/
+
        pbvh->looptri = looptri;
+       return looptri_num;
 }
 
 PBVHNode *BKE_search_closest_pbvh_leaf_node(PBVH *pbvh, PBVHNode *p_node, float *target_bmin, float *target_bmax){
index ba5667fbb08d010343c7f6792b68941d9d7bbf1b..e8146bd2188a61fdf8fbe953acde79e3dd6acb17 100644 (file)
@@ -5219,78 +5219,74 @@ void silhouette_create_shape_mesh(const bContext *C, Mesh *me, SilhouetteData *s
        float v_offset[3] = {0.0f,0.0f,1.0f};
        ED_view3d_global_to_vector(sil->ar->regiondata, (float[3]){0.0f,0.0f,0.0f}, v_offset);
 
-       ED_mesh_vertices_add(me, NULL, stroke->totvert*2);//Barely used is there a better one?
-
-       MVert nu_vert;
-       nu_vert.flag = 0;
-       nu_vert.bweight = 0;
-       for(int i = 0; i < stroke->totvert; i ++){
-               float v1[3], zDepth[3] = {0.0f,0.0f,0.0f};
-
-               ED_view3d_win_to_3d(v3d, sil->ar, zDepth, stroke->points+i*2, v1);
-               copy_v3_v3(nu_vert.co,v1);
-               me->mvert[me->totvert-stroke->totvert*2+i*2] = nu_vert;
-               copy_v3_v3(nu_vert.co,v1);
-               add_v3_v3(nu_vert.co,v_offset);
-               me->mvert[me->totvert-stroke->totvert*2+i*2+1] = nu_vert;
-       }
-
+       float v1[3], zDepth[3] = {0.0f,0.0f,0.0f};
+       int vstart = me->totvert, estart = me->totedge, lstart = me->totloop, pstart = me->totpoly;
+       ED_mesh_vertices_add(me, NULL, stroke->totvert*2);
        ED_mesh_edges_add(me, NULL, stroke->totvert*3-2);
+       ED_mesh_loops_add(me, NULL, stroke->totvert*4-4);
+       ED_mesh_polys_add(me, NULL, stroke->totvert-1);
+       for(int i = 0; i < stroke->totvert; i++){
+               //Add Verts
+               MVert ref_v;
+               ref_v.flag = 0; ref_v.bweight = 0;
+               ED_view3d_win_to_3d(v3d, sil->ar, zDepth, stroke->points+i*2, v1);
+               copy_v3_v3(ref_v.co,v1);
+               me->mvert[vstart] = ref_v;
+               vstart ++;
+               add_v3_v3(ref_v.co,v_offset);
+               me->mvert[vstart] = ref_v;
+               vstart ++;
+
+               //Add Edges
+               MEdge ref_e;
+               ref_e.crease = 0; ref_e.bweight = 0; ref_e.flag = 0;
+               ref_e.v1 = vstart-2;
+               ref_e.v2 = vstart-1;
+               me->medge[estart] = ref_e;
+               estart ++;
+               if(i < stroke->totvert-1){
+                       ref_e.v1 = vstart-2;
+                       ref_e.v2 = vstart;
+                       me->medge[estart] = ref_e;
+                       estart ++;
+                       ref_e.v1 = vstart-1;
+                       ref_e.v2 = vstart+1;
+                       me->medge[estart] = ref_e;
+                       estart ++;
+               }
 
-       MEdge nu_edge;
-       nu_edge.crease = 0;
-       nu_edge.bweight = 0;
-       nu_edge.flag = 0;
-       for(int i = 0; i < stroke->totvert-1; i ++){
-               nu_edge.v1 = me->totvert-stroke->totvert*2+i*2;
-               nu_edge.v2 = me->totvert-stroke->totvert*2+i*2+1;
-               me->medge[me->totedge-stroke->totvert*3+2 + i*3] = nu_edge;
-
-               nu_edge.v1 = me->totvert-stroke->totvert*2+i*2;
-               nu_edge.v2 = me->totvert-stroke->totvert*2+i*2+2;
-               me->medge[me->totedge-stroke->totvert*3+2 + i*3+1] = nu_edge;
-
-               nu_edge.v1 = me->totvert-stroke->totvert*2+i*2+1;
-               nu_edge.v2 = me->totvert-stroke->totvert*2+i*2+3;
-               me->medge[me->totedge-stroke->totvert*3+2 + i*3+2] = nu_edge;
-       }
-       nu_edge.v1 = me->totvert-2;
-       nu_edge.v2 = me->totvert-1;
-       me->medge[me->totedge-1] = nu_edge;
-
-       /*ED_mesh_loops_add(me, NULL, stroke->totvert*4-4);
-       MLoop nu_loop;
-       for(int i = 0; i < stroke->totvert-1; i++){
-               nu_loop.v = me->totvert-stroke->totvert*2+i*2;
-               nu_loop.e = me->totedge-stroke->totvert*3+2+i*2;
-               me->mloop[me->totloop-stroke->totvert*4+i*4+4] = nu_loop;
-
-               nu_loop.v = me->totvert-stroke->totvert*2+1+i*2;
-               nu_loop.e = me->totedge-stroke->totvert*3+4+i*2;
-               me->mloop[me->totloop-stroke->totvert*4+i*4+5] = nu_loop;
-
-               nu_loop.v = me->totvert-stroke->totvert*2+3+i*2;
-               nu_loop.e = me->totedge-stroke->totvert*3+5+i*2;
-               me->mloop[me->totloop-stroke->totvert*4+i*4+6] = nu_loop;
+               //Add Loops
+               MLoop ref_l;
+               if(i < stroke->totvert-1){
+                       ref_l.v = vstart-2;
+                       ref_l.e = estart-3;
+                       me->mloop[lstart] = ref_l;
+                       lstart ++;
+                       ref_l.v = vstart-1;
+                       ref_l.e = estart-1;
+                       me->mloop[lstart] = ref_l;
+                       lstart ++;
+                       ref_l.v = vstart+1;
+                       ref_l.e = estart;
+                       me->mloop[lstart] = ref_l;
+                       lstart ++;
+                       ref_l.v = vstart;
+                       ref_l.e = estart-2;
+                       me->mloop[lstart] = ref_l;
+                       lstart ++;
+               }
 
-               nu_loop.v = me->totvert-stroke->totvert*2+2+i*2;
-               nu_loop.e = me->totedge-stroke->totvert*3+3+i*2;
-               me->mloop[me->totloop-stroke->totvert*4+i*4+7] = nu_loop;
+               //Add Poly
+               MPoly ref_p;
+               ref_p.mat_nr = 0; ref_p.flag = 0; ref_p.pad = 0;
+               if(i < stroke->totvert-1){
+                       ref_p.loopstart = lstart-4;
+                       ref_p.totloop = 4;
+                       me->mpoly[pstart] = ref_p;
+                       pstart ++;
+               }
        }
 
-       //Loops
-       ED_mesh_polys_add(me, NULL, stroke->totvert-1);
-
-       MPoly nu_poly;
-       nu_poly.mat_nr = 0;
-       nu_poly.flag = 0;
-       nu_poly.pad = 0;
-       for(int i = 0; i < stroke->totvert-1; i++){
-               nu_poly.totloop = 4;
-               nu_poly.loopstart = me->totloop-stroke->totvert*4+4+i*4;
-               me->mpoly[me->totpoly-stroke->totvert+i+1] = nu_poly;
-       }*/
-
        //ED_mesh_update(me, C, 1, 1);
 
        //Extend BB
@@ -5303,6 +5299,34 @@ void silhouette_create_shape_mesh(const bContext *C, Mesh *me, SilhouetteData *s
        }
 }
 
+void debug_mesh(Mesh *me){
+       printf("Logging Mesh:\n");
+       printf("Verts in mesh %i\n",me->totvert);
+       printf("Edges in mesh %i\n",me->totedge);
+       printf("Loops in mesh %i\n",me->totloop);
+       printf("Polys in mesh %i\n",me->totpoly);
+
+       printf("\nVert log:\n");
+       for(int i = 0; i < me->totvert; i++){
+               printf("\nVert %i (%f,%f,%f)", i, me->mvert[i].co[0], me->mvert[i].co[1], me->mvert[i].co[2]);
+       }
+
+       printf("\nEdge log:\n");
+       for(int i = 0; i < me->totedge;i++){
+               printf("Edge %i, v1v2(%i,%i)\n",i,me->medge[i].v1,me->medge[i].v2);
+       }
+
+       printf("\nLoop Log:\n");
+       for(int i = 0; i < me->totloop; i++){
+               printf("Loop %i, v(%i), e(%i)\n", i, me->mloop[i].v, me->mloop[i].e);
+       }
+
+       printf("\nPoly log:\n");
+       for(int i = 0; i < me->totpoly; i++){
+               printf("Poly %i, start(%i), totloop(%i)\n", i, me->mpoly[i].loopstart, me->mpoly[i].totloop);
+       }
+}
+
 static void sculpt_silhouette_stroke_done(const bContext *C, wmOperator *op)
 {
        /*finalize stroke*/
@@ -5391,7 +5415,10 @@ static void sculpt_silhouette_stroke_done(const bContext *C, wmOperator *op)
                PBVHNode *closest_node;
 
                silhouette_create_shape_mesh(C, me, sil, stroke, v3d, &shape_bb);
-               BKE_pbvh_recalc_looptri_from_me(pbvh, me);
+
+               int totprim = BKE_pbvh_recalc_looptri_from_me(pbvh, me);
+
+
 
                root = BKE_pbvh_node_get_root(pbvh);
                closest_node = BKE_search_closest_pbvh_leaf_node(pbvh, root, &shape_bb.bmin, &shape_bb.bmax);
@@ -5401,10 +5428,10 @@ static void sculpt_silhouette_stroke_done(const bContext *C, wmOperator *op)
                bl_debug_draw_BB_add(&res_bb,0xFF0000);
                bl_debug_draw_BB_add(&shape_bb,0xFF0000);
 
-               BKE_pbvh_attach_mesh(pbvh, closest_node, me, stroke->totvert*2, &shape_bb.bmin, &shape_bb.bmax);
+               //Todo: unique verts and prim renwe etc.
+               BKE_pbvh_attach_mesh(pbvh, closest_node, me, totprim, &shape_bb.bmin, &shape_bb.bmax);
        }
 
-
        /*cleanup*/
        WM_cursor_modal_restore(CTX_wm_window(C));
        ED_region_draw_cb_exit(sil->ar->type,sil->draw_handle);