svn merge ^/trunk/blender -r46360:46370
authorOve Murberg Henriksen <sorayasilvermoon@hotmail.com>
Mon, 7 May 2012 23:40:17 +0000 (23:40 +0000)
committerOve Murberg Henriksen <sorayasilvermoon@hotmail.com>
Mon, 7 May 2012 23:40:17 +0000 (23:40 +0000)
1  2 
source/blender/bmesh/intern/bmesh_construct.c
source/blender/bmesh/operators/bmo_dissolve.c
source/blender/editors/sculpt_paint/paint_stroke.c
source/blender/editors/sculpt_paint/paint_vertex.c
source/blender/editors/sculpt_paint/sculpt.c

index 8e7723fefdddc405e2a654110360d16491ec3135,1451625d3bb143b3195056890797d62d1a3fe0aa..fae6802684ee099806c7d29675a3a2729ae3f0a9
@@@ -520,14 -520,28 +520,24 @@@ void bmo_dissolve_limit_exec(BMesh *bm
        const float angle_max = (float)M_PI / 2.0f;
        const float angle_limit = minf(angle_max, BMO_slot_float_get(op, "angle_limit"));
        DissolveElemWeight *weight_elems = MEM_mallocN(MAX2(einput->len, vinput->len) *
-                                                        sizeof(DissolveElemWeight), __func__);
+                                                      sizeof(DissolveElemWeight), __func__);
        int i, tot_found;
  
 -      BMIter iter;
 -      BMEdge *e_iter;
 -      BMEdge **earray;
 -
+       int *vert_reverse_lookup;
+       BMEdge **einput_arr = (BMEdge **)einput->data.p;
+       BMVert **vinput_arr = (BMVert **)vinput->data.p;
        /* --- first edges --- */
  
+       /* wire -> tag */
+       BM_ITER_MESH (e_iter, &iter, bm, BM_EDGES_OF_MESH) {
+               BM_elem_flag_set(e_iter, BM_ELEM_TAG, BM_edge_is_wire(e_iter));
+       }
        /* go through and split edge */
        for (i = 0, tot_found = 0; i < einput->len; i++) {
-               BMEdge *e = ((BMEdge **)einput->data.p)[i];
+               BMEdge *e = einput_arr[i];
                const float angle = BM_edge_calc_face_angle(e);
  
                if (angle < angle_limit) {
                                }
                        }
                }
 +
 +              /* remove all edges/verts left behind from dissolving */
 +              for (i = 0; i < einput->len; i++) {
 +                      BMEdge *e = (BMEdge *)weight_elems[i].ele;
 +                      if (BM_edge_is_wire(e)) {
 +                              BMVert *v1 = e->v1;
 +                              BMVert *v2 = e->v2;
 +                              BM_edge_kill(bm, e);
 +                              if (v1->e == NULL) BM_vert_kill(bm, v1);
 +                              if (v2->e == NULL) BM_vert_kill(bm, v2);
 +                      }
 +              }
        }
  
+       /* prepare for cleanup */
+       BM_mesh_elem_index_ensure(bm, BM_VERT);
+       vert_reverse_lookup = MEM_mallocN(sizeof(int) * bm->totvert, __func__);
+       fill_vn_i(vert_reverse_lookup, bm->totvert, -1);
+       for (i = 0, tot_found = 0; i < vinput->len; i++) {
+               BMVert *v = vinput_arr[i];
+               vert_reverse_lookup[BM_elem_index_get(v)] = i;
+       }
+       /* --- cleanup --- */
+       earray = MEM_mallocN(sizeof(BMEdge *) * bm->totedge, __func__);
+       BM_ITER_MESH_INDEX (e_iter, &iter, bm, BM_EDGES_OF_MESH, i) {
+               earray[i] = e_iter;
+       }
+       /* remove all edges/verts left behind from dissolving, NULL'ing the vertex array so we dont re-use */
+       for (i = bm->totedge - 1; i != -1; i--) {
+               e_iter = earray[i];
+               if (BM_edge_is_wire(e_iter) && (BM_elem_flag_test(e_iter, BM_ELEM_TAG) == FALSE)) {
+                       /* edge has become wire */
+                       int vidx_reverse;
+                       BMVert *v1 = e_iter->v1;
+                       BMVert *v2 = e_iter->v2;
+                       BM_edge_kill(bm, e_iter);
+                       if (v1->e == NULL) {
+                               vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v1)];
+                               if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
+                               BM_vert_kill(bm, v1);
+                       }
+                       if (v2->e == NULL) {
+                               vidx_reverse = vert_reverse_lookup[BM_elem_index_get(v2)];
+                               if (vidx_reverse != -1) vinput_arr[vidx_reverse] = NULL;
+                               BM_vert_kill(bm, v2);
+                       }
+               }
+       }
+       MEM_freeN(vert_reverse_lookup);
+       MEM_freeN(earray);
        /* --- second verts --- */
        for (i = 0, tot_found = 0; i < vinput->len; i++) {
-               BMVert *v = ((BMVert **)vinput->data.p)[i];
-               const float angle = bm_vert_edge_face_angle(v);
+               BMVert *v = vinput_arr[i];
+               const float angle = v ? bm_vert_edge_face_angle(v) : angle_limit;
  
                if (angle < angle_limit) {
                        weight_elems[i].ele = (BMHeader *)v;
index 7471787eb95cdf496acbef734c04690758bc88dd,9832bcf1528012bad65a20fc6349f52262811605..3fd0841f0fdce804bc27e1950b8583e90c50b5d4
@@@ -276,11 -280,32 +280,12 @@@ PaintStroke *paint_stroke_new(bContext 
        return stroke;
  }
  
 -void paint_stroke_data_free(struct wmOperator *op)
 +void paint_stroke_free(PaintStroke *stroke)
  {
-       MEM_freeN(stroke);
+       MEM_freeN(op->customdata);
+       op->customdata = NULL;
  }
  
 -static void stroke_done(struct bContext *C, struct wmOperator *op)
 -{
 -      struct PaintStroke *stroke = op->customdata;
 -
 -      if (stroke->stroke_started && stroke->done)
 -              stroke->done(C, stroke);
 -
 -      if (stroke->timer) {
 -              WM_event_remove_timer(
 -                      CTX_wm_manager(C),
 -                      CTX_wm_window(C),
 -                      stroke->timer);
 -      }
 -
 -      if (stroke->smooth_stroke_cursor)
 -              WM_paint_cursor_end(CTX_wm_manager(C), stroke->smooth_stroke_cursor);
 -
 -      paint_stroke_data_free(op);
 -}
 -
  /* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
  int paint_space_stroke_enabled(Brush *br)
  {