=bmesh= fixed a memory leak
authorJoseph Eagar <joeedh@gmail.com>
Sat, 16 Apr 2011 13:00:41 +0000 (13:00 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Sat, 16 Apr 2011 13:00:41 +0000 (13:00 +0000)
source/blender/blenkernel/intern/customdata.c
source/blender/bmesh/intern/bmesh_interp.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_queries.c
source/blender/bmesh/operators/bevel.c
source/blender/editors/mesh/bmesh_tools.c

index 7276e4eb246ac1ad2f77663a43f1c9efd06e5aee..52519f95d30247db8dfcd887256ffe962dd311b6 100644 (file)
@@ -350,6 +350,24 @@ static void layerDefault_tface(void *data, int count)
                tf[i] = default_tf;
 }
 
+static void layerCopy_propFloat(const void *source, void *dest,
+                                                                 int count)
+{
+       memcpy(dest, source, sizeof(MFloatProperty)*count);
+}
+
+static void layerCopy_propInt(const void *source, void *dest,
+                                                                 int count)
+{
+       memcpy(dest, source, sizeof(MIntProperty)*count);
+}
+
+static void layerCopy_propString(const void *source, void *dest,
+                                                                 int count)
+{
+       memcpy(dest, source, sizeof(MStringProperty)*count);
+}
+
 static void layerCopy_origspace_face(const void *source, void *dest, int count)
 {
        const OrigSpaceFace *source_tf = (const OrigSpaceFace*)source;
@@ -905,9 +923,9 @@ static const LayerTypeInfo LAYERTYPEINFO[CD_NUMTYPES] = {
        /* 3 floats per normal vector */
        {sizeof(float)*3, "vec3f", 1, NULL, NULL, NULL, NULL, NULL, NULL},
        {sizeof(int), "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
-       {sizeof(MFloatProperty), "MFloatProperty",1,"Float",NULL,NULL,NULL,NULL},
-       {sizeof(MIntProperty), "MIntProperty",1,"Int",NULL,NULL,NULL,NULL},
-       {sizeof(MStringProperty), "MStringProperty",1,"String",NULL,NULL,NULL,NULL},
+       {sizeof(MFloatProperty), "MFloatProperty",1,"Float", layerCopy_propFloat,NULL,NULL,NULL},
+       {sizeof(MIntProperty), "MIntProperty",1,"Int",layerCopy_propInt,NULL,NULL,NULL},
+       {sizeof(MStringProperty), "MStringProperty",1,"String",layerCopy_propString,NULL,NULL,NULL},
        {sizeof(OrigSpaceFace), "OrigSpaceFace", 1, "UVTex", layerCopy_origspace_face, NULL,
         layerInterp_origspace_face, layerSwap_origspace_face, layerDefault_origspace_face},
        {sizeof(float)*3, "", 0, NULL, NULL, NULL, NULL, NULL, NULL},
index e33d7fd986223d5bbbd7a0b58a42d69fb0b36ef8..bb560b6fdb6cb4df589c006c9609d24b2643bd71 100644 (file)
@@ -719,9 +719,11 @@ void BM_loop_interp_from_face(BMesh *bm, BMLoop *target, BMFace *source,
        
        interp_weights_poly_v3(w, cos, source->len, co);
        CustomData_bmesh_interp(&bm->ldata, blocks, w, NULL, source->len, target->head.data);
-       if (do_vertex) 
+       if (do_vertex) {
                CustomData_bmesh_interp(&bm->vdata, vblocks, w, NULL, source->len, target->v->head.data);
-
+               BLI_array_free(vblocks);
+       }
+       
        BLI_array_free(cos);
        BLI_array_free(w);
        BLI_array_free(blocks);
index dee12bc82a82b13d91428d41dbce2c4a90ce5308..799241d052a2948a8c8a6b82444f2c4626ad63db 100644 (file)
@@ -931,6 +931,8 @@ BMOpDefine def_bevel = {
        {{BMOP_OPSLOT_ELEMENT_BUF, "geom"}, /* input edges and vertices */
         {BMOP_OPSLOT_ELEMENT_BUF, "face_spans"}, /* new geometry */
         {BMOP_OPSLOT_ELEMENT_BUF, "face_holes"}, /* new geometry */
+        {BMOP_OPSLOT_INT, "uselengths"}, /* grab edge lengths from a PROP_FLT customdata layer*/
+        {BMOP_OPSLOT_INT, "lengthlayer"}, /* which PROP_FLT layer to use*/
         {BMOP_OPSLOT_FLT, "percent"}, /* percentage to expand bevelled edges*/
         {0} /*null-terminating sentinel*/},
        bmesh_bevel_exec,
index 6b0fd5103434f3fba42edc383f33bf584bf2c8c9..3e2de929eb1b5981d229d24db013cd8e0c537e3b 100644 (file)
@@ -465,7 +465,7 @@ float BM_Face_Angle(BMesh *UNUSED(bm), BMEdge *e)
                l2 = e->l->radial_next;
                edge_angle_cos = INPR(l1->f->no, l2->f->no);
        }
-       return edge_angle_cos;
+       return acos(edge_angle_cos);
 
 }
 
index cbec009a0d5e207e8a14ab4b72791ef82f6fde40..9bd4f00668fb9dc3495649aee00782246591a4f8 100644 (file)
@@ -54,8 +54,8 @@ void calc_corner_co(BMesh *bm, BMLoop *l, float *co, float fac)
                copy_v3_v3(v3, l->v->co);
                
                BM_ITER(l2, &iter, bm, BM_LOOPS_OF_VERT, l->v) {
-                       if (l2->f != l) {
-                               copy_v3_v3(v4, BM_OtherEdgeVert(l2->e, l2->next->v));
+                       if (l2->f != l->f) {
+                               copy_v3_v3(v4, BM_OtherEdgeVert(l2->e, l2->next->v)->co);
                                break;
                        }
                }
@@ -88,11 +88,13 @@ void calc_corner_co(BMesh *bm, BMLoop *l, float *co, float fac)
        }
        
        /*compute offsets*/
-       l1 = len_v3(vec1)*fac;
+       l1 = len_v3(vec1)*fac; //(1.0-(cos(angle_v3v3(vec1, vec2))*0.5+0.5))
        l2 = len_v3(vec2)*fac;
+
+       l2 = (l1 + l2)*0.5;
+       l1 = l2;
        if (dot_v3v3(no, l->f->no) < 0.0) {
-               l1 = -l1;
-               l2 = -l2;
+               negate_v3(no);
        }       
        
        /*compute tangent and offset first edge*/
@@ -115,11 +117,6 @@ void calc_corner_co(BMesh *bm, BMLoop *l, float *co, float fac)
        
        /*compute intersection*/
        ret = isect_line_line_v3(v1, v2, v3, v4, p1, p2);
-       if (len_v3v3(p1, v1) > len_v3v3(v1, v2) || len_v3v3(p1, v2) > len_v3v3(v1, v2))
-               copy_v3_v3(p1, v2);
-       
-       if (len_v3v3(p1, v3) > len_v3v3(v3, v4) || len_v3v3(p1, v4) > len_v3v3(v3, v4))
-               copy_v3_v3(p2, v3);
        
        if (ret==1) {
                copy_v3_v3(co, p1);
@@ -165,7 +162,12 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
        BLI_array_declare(edges);
        SmallHash hash;
        float fac = BMO_Get_Float(op, "percent");
-       int i, HasMDisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
+       int i, li, has_elens, HasMDisps = CustomData_has_layer(&bm->ldata, CD_MDISPS);
+       
+       has_elens = CustomData_has_layer(&bm->edata, CD_PROP_FLT) && BMO_Get_Int(op, "uselengths");
+       if (has_elens) {
+               li = BMO_Get_Int(op, "lengthlayer");
+       }
        
        BLI_smallhash_init(&hash);
        
@@ -301,6 +303,13 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
                                
                                v2 = BM_OtherEdgeVert(e, v);
                                sub_v3_v3v3(co, v2->co, v->co);
+                               if (has_elens) {
+                                       float elen = *(float*)CustomData_bmesh_get_n(&bm->edata, e->head.data, CD_PROP_FLT, li);
+
+                                       normalize_v3(co);
+                                       mul_v3_fl(co, elen);
+                               }
+                               
                                mul_v3_fl(co, fac);
                                add_v3_v3(co, v->co);
                                
@@ -331,6 +340,13 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
                                        
                                        if (!tag->newv) {
                                                sub_v3_v3v3(co, l->prev->v->co, l->v->co);
+                                               if (has_elens) {
+                                                       float elen = *(float*)CustomData_bmesh_get_n(&bm->edata, l->prev->e->head.data, CD_PROP_FLT, li);
+
+                                                       normalize_v3(co);
+                                                       mul_v3_fl(co, elen);
+                                               }
+                                                               
                                                mul_v3_fl(co, fac);
                                                add_v3_v3(co, l->v->co);
                                        
@@ -345,6 +361,13 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
                
                                if (!tag->newv) {
                                        sub_v3_v3v3(co, l->next->v->co, l->v->co);
+                                       if (has_elens) {
+                                               float elen = *(float*)CustomData_bmesh_get_n(&bm->edata, l->e->head.data, CD_PROP_FLT, li);
+
+                                               normalize_v3(co);
+                                               mul_v3_fl(co, elen);
+                                       }
+                                       
                                        mul_v3_fl(co, fac);
                                        add_v3_v3(co, l->v->co);
                        
@@ -366,8 +389,8 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
                BMLoop *l;
                BMIter liter;
                BMFace *f;
-               int j;
-               
+               BMVert *lastv=NULL, *firstv=NULL;
+
                BMO_SetFlag(bm, faces[i], BEVEL_DEL);
                
                BLI_array_empty(verts);
@@ -379,43 +402,35 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
                        tag = tags + BMINDEX_GET(l);
                        BLI_array_append(verts, tag->newv);
                        
+                       if (!firstv)
+                               firstv = tag->newv;
+                       
+                       if (lastv) {
+                               e = BM_Make_Edge(bm, lastv, tag->newv, l->e, 1);
+                               BM_Copy_Attributes(bm, bm, l->prev->e, e);
+                               BLI_array_append(edges, e);
+                       }
+                       lastv=tag->newv;
+                       
                        etag = etags + BMINDEX_GET(l->e);
                        v2 = l->next->v == l->e->v1 ? etag->newv1 : etag->newv2;
                        
                        tag = tags + BMINDEX_GET(l->next);
                        if (!BMO_TestFlag(bm, l->e, BEVEL_FLAG) && v2 && v2 != tag->newv) {
                                BLI_array_append(verts, v2);
-                       }
-               }
-               
-               if (BLI_array_count(verts) == 2) {
-                       BMEdge *e1=NULL, *e2=NULL;
-                       
-                       BM_ITER(l, &liter, bm, BM_LOOPS_OF_VERT, verts[0]) {
-                               if (BM_Vert_In_Edge(l->e, verts[1])) {
-                                       if (!e1)
-                                               e1 = l->e;
-                                       else if (!e2) 
-                                               e2 = l->e;
-                               }       
-                       }
-                       
-                       if (!e1)
-                               e1 = BM_Make_Edge(bm, verts[0], verts[1], NULL, 0);
-                       if (!e2) 
-                               e2 = BM_Make_Edge(bm, verts[0], verts[1], NULL, 0);
-                       
-                       BLI_array_append(edges, e1);
-                       BLI_array_append(edges, e2);
-               } else {
-                       for (j=0; j<BLI_array_count(verts); j++) {
-                               BMVert *next = verts[(j+1)%BLI_array_count(verts)];
                                
-                               e = BM_Make_Edge(bm, next, verts[j], NULL, 1);
+                               e = BM_Make_Edge(bm, lastv, v2, l->e, 1);
+                               BM_Copy_Attributes(bm, bm, l->e, e);
+                               
                                BLI_array_append(edges, e);
+                               lastv = v2;
                        }
                }
                
+               e = BM_Make_Edge(bm, firstv, lastv, bm_firstfaceloop(faces[i])->e, 1);
+               BM_Copy_Attributes(bm, bm, bm_firstfaceloop(faces[i])->prev->e, e);
+               BLI_array_append(edges, e);
+               
                f = BM_Make_Ngon(bm, verts[0], verts[1], edges, BLI_array_count(verts), 0);
                if (!f) {
                        printf("eck!!\n");
@@ -423,9 +438,15 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
                }
                        
                BMO_SetFlag(bm, f, FACE_NEW);
+       }
+
+       for (i=0; i<BLI_array_count(faces); i++) {
+               BMLoop *l;
+               BMIter liter;
+               BMVert *lastv=NULL, *firstv=NULL;
+               int j;
                
                /*create quad spans between split edges*/
-               BMO_SetFlag(bm, f, FACE_NEW);
                BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, faces[i]) {
                        BMVert *v1=NULL, *v2=NULL, *v3=NULL, *v4=NULL;
                        
@@ -476,8 +497,9 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
                        
                        if (v1 != v2 && v2 != v3 && v3 != v4) {
                                BMIter liter2;
-                               BMLoop *l2;
-                               BMEdge *e1, *e2;
+                               BMLoop *l2, *l3;
+                               BMEdge *e1, *e2, *e3, *e4;
+                               float d1, d2, *d3;
                                
                                f = BM_Make_QuadTri(bm, v4, v3, v2, v1, l->f, 1);
 
@@ -485,6 +507,36 @@ void bmesh_bevel_exec(BMesh *bm, BMOperator *op)
                                e2 = BM_Edge_Exist(v2, v1);
                                BM_Copy_Attributes(bm, bm, l->e, e1);
                                BM_Copy_Attributes(bm, bm, l->e, e2);
+                               
+                               /*set edge lengths of cross edges as the average of the cross edges they're based on*/
+                               if (has_elens) {
+                                       float ang;
+                                       
+                                       e1 = BM_Edge_Exist(v1, v4);
+                                       e2 = BM_Edge_Exist(v2, v3);
+                                       
+                                       if (l->radial_next->v == l->v) {
+                                               l2 = l->radial_next->prev;
+                                               l3 = l->radial_next->next;
+                                       } else {
+                                               l2 = l->radial_next->next;
+                                               l3 = l->radial_next->prev;
+                                       }
+                                       
+                                       d3 = CustomData_bmesh_get_n(&bm->edata, e1->head.data, CD_PROP_FLT, li);
+                                       d1 = *(float*)CustomData_bmesh_get_n(&bm->edata, l->prev->e->head.data, CD_PROP_FLT, li);
+                                       d2 = *(float*)CustomData_bmesh_get_n(&bm->edata, l2->e->head.data, CD_PROP_FLT, li);
+                                       
+                                       ang = angle_v3v3v3(l->prev->v->co, l->v->co, BM_OtherEdgeVert(l2->e, l->v)->co);
+                                       *d3 = (d1+d2)*0.5;
+                                       
+                                       d3 = CustomData_bmesh_get_n(&bm->edata, e2->head.data, CD_PROP_FLT, li);
+                                       d1 = *(float*)CustomData_bmesh_get_n(&bm->edata, l->next->e->head.data, CD_PROP_FLT, li);
+                                       d2 = *(float*)CustomData_bmesh_get_n(&bm->edata, l3->e->head.data, CD_PROP_FLT, li);
+
+                                       ang = angle_v3v3v3(BM_OtherEdgeVert(l->next->e, l->next->v)->co, l->next->v->co, BM_OtherEdgeVert(l3->e, l->next->v)->co);
+                                       *d3 = (d1+d2)*0.5;
+                               }
 
                                if (!f) {
                                        printf("eek!\n");
index f4d01e067e58647954bb8bf0d8b7807f93557478..397693da23062275a4800d59e44e6ebc787521dc 100644 (file)
@@ -4809,24 +4809,60 @@ static int mesh_bevel_exec(bContext *C, wmOperator *op)
        Tex *tex;
        BMVert *eve;
        BMIter iter;
+       BMEdge *eed;
        BMOperator bmop;
-       float factor= RNA_float_get(op->ptr, "percent"), fac=factor;
-       int i, recursion = RNA_int_get(op->ptr, "recursion");
+       float factor= RNA_float_get(op->ptr, "percent"), fac=factor, dfac, df, s;
+       /*float p2 = RNA_float_get(op->ptr, "param2");
+       float p3 = RNA_float_get(op->ptr, "param3");
+       float p4 = RNA_float_get(op->ptr, "param4");
+       float p5 = RNA_float_get(op->ptr, "param5");*/
+       int i, tot, recursion = RNA_int_get(op->ptr, "recursion");
+       float *w = NULL, ftot;
+       int li;
+       BLI_array_declare(w);
+       
+       BM_add_data_layer(em->bm, &em->bm->edata, CD_PROP_FLT);
+       li = CustomData_number_of_layers(&em->bm->edata, CD_PROP_FLT)-1;
+       
+       BM_ITER(eed, &iter, em->bm, BM_EDGES_OF_MESH, NULL) {
+               float d = len_v3v3(eed->v1->co, eed->v2->co);
+               float *dv = CustomData_bmesh_get_n(&em->bm->edata, eed->head.data, CD_PROP_FLT, li);
+               
+               *dv = d;
+       }
        
        if(em==NULL) return OPERATOR_CANCELLED;
        
-       while (recursion-- > 0) {
-               if (!EDBM_InitOpf(em, &bmop, op, "bevel geom=%hev percent=%f", BM_SELECT, fac))
+       /*ugh, stupid math depends somewhat on angles!*/
+       dfac = 1.0/(float)(recursion+1);
+       df = 1.0;
+       for (i=0, ftot=0.0f; i<recursion; i++) {
+               s = pow(df, 1.25);
+               
+               BLI_array_append(w, s);
+               ftot += s;
+               
+               df *= 2.0;
+       }
+       
+       for (i=0; i<BLI_array_count(w); i++) {
+               w[i] /= ftot;
+       }
+
+       fac = factor;
+       for (i=0; i<BLI_array_count(w); i++) {
+               fac = w[BLI_array_count(w)-i-1]*factor;
+
+               if (!EDBM_InitOpf(em, &bmop, op, "bevel geom=%hev percent=%f lengthlayer=%i uselengths=%i", BM_SELECT, fac, li, 1))
                        return OPERATOR_CANCELLED;
                
                BMO_Exec_Op(em->bm, &bmop);
-               //BMO_HeaderFlag_Buffer(em->bm, &bmop, "face_spans", BM_SELECT, BM_FACE);
-               //BMO_HeaderFlag_Buffer(em->bm, &bmop, "face_holes", BM_SELECT, BM_FACE);
                BMO_Finish_Op(em->bm, &bmop);
-               
-               fac = fac + (sqrt(fac) - fac)*0.25;
        }
        
+       BM_free_data_layer_n(em->bm, &em->bm->edata, CD_MASK_PROP_FLT, li);
+       
+       BLI_array_free(w);
        EDBM_RecalcNormals(em);
 
        DAG_id_tag_update(obedit->data, 0);
@@ -4849,6 +4885,10 @@ void MESH_OT_bevel(wmOperatorType *ot)
        /* flags */
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
-       RNA_def_float(ot->srna, "percent", 0.1f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 0.5f);
+       RNA_def_float(ot->srna, "percent", 0.5f, -FLT_MAX, FLT_MAX, "Percentage", "", 0.0f, 1.0f);
        RNA_def_int(ot->srna, "recursion", 1, 1, 50, "Recursion Level", "Recursion Level", 1, 8);
+       //RNA_def_float(ot->srna, "param2", 1.0f, -FLT_MAX, FLT_MAX, "Parameter 2", "", -1000.0f, 1000.0f);
+       //RNA_def_float(ot->srna, "param3", 0.5f, -FLT_MAX, FLT_MAX, "Parameter 3", "", -1000.0f, 1000.0f);
+       //RNA_def_float(ot->srna, "param4", 0.5f, -FLT_MAX, FLT_MAX, "Parameter 4", "", -1000.0f, 1000.0f);
+       //RNA_def_float(ot->srna, "param5", 0.5f, -FLT_MAX, FLT_MAX, "Parameter 5", "", -1000.0f, 1000.0f);
 }