=bmesh=
authorJoseph Eagar <joeedh@gmail.com>
Mon, 28 Mar 2011 00:29:45 +0000 (00:29 +0000)
committerJoseph Eagar <joeedh@gmail.com>
Mon, 28 Mar 2011 00:29:45 +0000 (00:29 +0000)
Improved edge subdivide.  The last tool panel
is a bit clearer, with a "quad/tri" checkbox
(that, in addition to turning on the old
 singe-edge-triangluation feature also
 automatically switches cornervert to Inner Vert
 if it is Straight, to avoid producing ngons).

I also rewrote fractal to be more likes its name, and
 removed the "smoothness" parameter (which never
 worked, anyway, even in trunk).  Also removed the
 grid fill paramter, it wasn't all that useful.

12 files changed:
release/scripts/ui/space_view3d.py
source/blender/blenkernel/intern/customdata.c
source/blender/bmesh/bmesh.h
source/blender/bmesh/bmesh_operators.h
source/blender/bmesh/intern/bmesh_interp.c
source/blender/bmesh/intern/bmesh_mods.c
source/blender/bmesh/intern/bmesh_opdefines.c
source/blender/bmesh/intern/bmesh_polygon.c
source/blender/bmesh/operators/subdivideop.c
source/blender/bmesh/operators/subdivideop.h
source/blender/editors/mesh/bmesh_tools.c
source/blender/editors/mesh/loopcut.c

index 730c442ad25aaa355d88ded154e57ecbb526104b..cb10d6a3570923b55f74068459f15a5a2a90701f 100644 (file)
@@ -557,7 +557,7 @@ class VIEW3D_MT_select_edit_curve(bpy.types.Menu):
         layout.operator("curve.select_less")
 
 
-class VIEW3D_MT_select_edit_surface(bpy.types.Menu):
+class sVIEW3D_MT_select_edit_surface(bpy.types.Menu):
     bl_label = "Select"
 
     def draw(self, context):
@@ -1366,7 +1366,6 @@ class VIEW3D_MT_edit_mesh_specials(bpy.types.Menu):
         layout.operator_context = 'INVOKE_REGION_WIN'
 
         layout.operator("mesh.subdivide", text="Subdivide")
-        layout.operator("mesh.subdivide", text="Subdivide Smooth").smoothness = 1.0
         layout.operator("mesh.merge", text="Merge...")
         layout.operator("mesh.remove_doubles")
         layout.operator("mesh.hide", text="Hide")
index 346fb5dd85d65ddae223a5dc1f0d4348dc7771c6..e40275121ae06f4fb32d1893dfab3404ad9159dc 100644 (file)
@@ -1450,8 +1450,9 @@ static CustomDataLayer *customData_add_layer__internal(CustomData *data,
        int size = typeInfo->size * totelem, flag = 0, index = data->totlayer;
        void *newlayerdata;
 
-       if (!typeInfo->defaultname && CustomData_has_layer(data, type))
+       if (!typeInfo->defaultname && CustomData_has_layer(data, type)) {
                return &data->layers[CustomData_get_layer_index(data, type)];
+       }
 
        if((alloctype == CD_ASSIGN) || (alloctype == CD_REFERENCE)) {
                newlayerdata = layerdata;
index e5c2daaa016a416ce5a01ff9abf23c22f2ee92ec..97741854f71be44ae900c59469f4e2ba91eb56cb 100644 (file)
@@ -204,6 +204,7 @@ void BM_Edge_UpdateNormals ( BMesh *bm, BMEdge *e );
 
 /*update a vert normal (but not the faces incident on it)*/
 void BM_Vert_UpdateNormal ( BMesh *bm, BMVert *v );
+void BM_Vert_UpdateAllNormals ( BMesh *bm, BMVert *v );
 
 void BM_flip_normal ( BMesh *bm, BMFace *f );
 
@@ -232,11 +233,12 @@ void BM_multires_smooth_bounds(BMesh *bm, BMFace *f);
 void BM_loop_interp_multires(BMesh *bm, BMLoop *target, BMFace *source);
 void BM_vert_interp_from_face(BMesh *bm, BMVert *v, BMFace *source);
 
-void BM_Data_Interp_From_Verts ( struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, float fac );
-void BM_Data_Facevert_Edgeinterp ( struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, struct BMEdge *e1, float fac );
-void BM_add_data_layer ( BMesh *em, CustomData *data, int type );
-void BM_add_data_layer_named ( BMesh *bm, CustomData *data, int type, char *name );
-void BM_free_data_layer ( BMesh *em, CustomData *data, int type );
+void BM_Data_Interp_From_Verts (struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, float fac );
+void BM_Data_Facevert_Edgeinterp (struct BMesh *bm, struct BMVert *v1, struct BMVert *v2, struct BMVert *v, struct BMEdge *e1, float fac );
+void BM_add_data_layer (BMesh *em, CustomData *data, int type );
+void BM_add_data_layer_named (BMesh *bm, CustomData *data, int type, char *name );
+void BM_free_data_layer (BMesh *em, CustomData *data, int type );
+void BM_free_data_layer_n(BMesh *bm, CustomData *data, int type, int n);
 float BM_GetCDf(struct CustomData *cd, void *element, int type);
 void BM_SetCDf(struct CustomData *cd, void *element, int type, float val);
 
index 620d757614132c358aaa7bb3e1ca62e5414e0589..490e9c849d3c7e15fb1cac734cf1cff7dcedf6a9 100644 (file)
@@ -81,7 +81,7 @@ struct EditMesh;
 void BMOP_DupeFromFlag(struct BMesh *bm, int etypeflag, int flag);
 void BM_esubdivideflag(struct Object *obedit, BMesh *bm, int flag, float smooth, 
                       float fractal, int beauty, int numcuts, int seltype,
-                      int cornertype, int singleedge, int gridfill);
+                      int cornertype, int singleedge, int gridfill, int seed);
 void BM_extrudefaceflag(BMesh *bm, int flag);
 
 /*this next one return 1 if they did anything, or zero otherwise.
index c089c20e3d992c2bc12115b1a4132c0f2f7bf6fb..9e1d1fc6176ce54a9e5f7d321e5bbb44ea6c4c59 100644 (file)
@@ -118,7 +118,10 @@ void BM_Data_Facevert_Edgeinterp(BMesh *bm, BMVert *v1, BMVert *UNUSED(v2), BMVe
                        v2loop = (BMLoop*)(l->prev);
                        
                }
-
+               
+               if (!v1loop || !v2loop)
+                       return;
+               
                src[0] = v1loop->head.data;
                src[1] = v2loop->head.data;                                     
 
@@ -719,6 +722,18 @@ void BM_free_data_layer(BMesh *bm, CustomData *data, int type)
        if (olddata.layers) MEM_freeN(olddata.layers);
 }
 
+void BM_free_data_layer_n(BMesh *bm, CustomData *data, int type, int n)
+{
+       CustomData olddata;
+
+       olddata= *data;
+       olddata.layers= (olddata.layers)? MEM_dupallocN(olddata.layers): NULL;
+       CustomData_free_layer(data, type, 0, CustomData_get_layer_index_n(data, type, n));
+       
+       update_data_blocks(bm, &olddata, data);
+       if (olddata.layers) MEM_freeN(olddata.layers);
+}
+
 float BM_GetCDf(CustomData *cd, void *element, int type)
 {
        if (CustomData_has_layer(cd, type)) {
index f8524f1000648aca622946c11071e8a9b72a19a3..1759d6ae3654e2114cf62fb805afcbe958604ee9 100644 (file)
@@ -517,8 +517,8 @@ BMVert *BM_Split_Edge(BMesh *bm, BMVert *v, BMEdge *e, BMEdge **ne, float percen
        }
 
        /*v->nv->v2*/
-       BM_Data_Facevert_Edgeinterp(bm,v2, v, nv, e, percent);  
-       BM_Data_Interp_From_Verts(bm, v2, v, nv, percent);
+       BM_Data_Facevert_Edgeinterp(bm, v2, v, nv, e, percent); 
+       BM_Data_Interp_From_Verts(bm, v, v2, nv, percent);
 
        if (CustomData_has_layer(&bm->ldata, CD_MDISPS) && e->l && nv) {
                int i, j;
index c949d730d8c5640c68d50592a292a5d664d2d6bd..a9fd22a9e2e5dab6ec6bf57f5c9c0c1bf6291df3 100644 (file)
@@ -657,6 +657,7 @@ BMOpDefine def_subdop = {
        {BMOP_OPSLOT_FLT, "smooth"},
        {BMOP_OPSLOT_FLT, "fractal"},
        {BMOP_OPSLOT_INT, "beauty"},
+       {BMOP_OPSLOT_INT, "seed"},
        {BMOP_OPSLOT_MAPPING, "custompatterns"},
        {BMOP_OPSLOT_MAPPING, "edgepercents"},
        
index 89bbfeac478fd25ae1dee86e956382e0904668cc..8eea93e02239e7dcf6adbc7f403c31807ef77bf8 100644 (file)
@@ -445,7 +445,26 @@ void BM_Vert_UpdateNormal(BMesh *bm, BMVert *v)
 
        if (!len) return;
 
-       mul_v3_fl(v->no, 1.0f/(int)len);
+       mul_v3_fl(v->no, 1.0f/(float)len);
+}
+
+void BM_Vert_UpdateAllNormals(BMesh *bm, BMVert *v)
+{
+       BMIter iter;
+       BMFace *f;
+       int len=0;
+
+       v->no[0] = v->no[1] = v->no[2] = 0.0f;
+
+       f = BMIter_New(&iter, bm, BM_FACES_OF_VERT, v);
+       for (; f; f=BMIter_Step(&iter), len++) {
+               BM_Face_UpdateNormal(bm, f);
+               add_v3_v3v3(v->no, f->no, v->no);
+       }
+
+       if (!len) return;
+
+       mul_v3_fl(v->no, 1.0f/(float)len);
 }
 
 void bmesh_update_face_normal(BMesh *bm, BMFace *f, float (*projectverts)[3])
index 320381e664cdfa8171bf04f678f46692bdc0e4af..ca649b86c30b686b43dd9bd3d18d39cb3b9427bf 100644 (file)
@@ -86,6 +86,59 @@ NOTE: beauty has been renamed to flag!
     split the edge only?
 */
 
+#if 0 //misc. code, maps a parametric coordinate to a fractal line
+float lastrnd[3], vec2[3] = {0.0f, 0.0f, 0.0f};
+int seed = BLI_rand();
+int d, i, j, dp, lvl, wid;
+float df;
+
+BLI_srandom(seed);
+
+wid = (params->numcuts+2);
+dp = perc*wid;
+wid /= 2;
+d = lvl = 0;
+while (1) {
+       if (d > dp) {
+               d -= wid;
+       } else if (d < dp) {
+               d += wid;
+       } else {
+               break;
+       }
+       
+       
+       wid = MAX2((wid/2), 1);
+       lvl++;
+}
+
+zero_v3(vec1);
+df = 1.0f;
+for (i=0; i<lvl; i++, df /= 4.0f) {
+       int tot = (1<<i);
+       
+       lastrnd[0] = BLI_drand()-0.5f;
+       lastrnd[1] = BLI_drand()-0.5f;
+       lastrnd[2] = BLI_drand()-0.5f;
+       for (j=0; j<tot; j++) {
+               float a, b, rnd[3], rnd2[3];
+               
+               rnd[0] = BLI_drand()-0.5f;
+               rnd[1] = BLI_drand()-0.5f;
+               rnd[2] = BLI_drand()-0.5f;
+               
+               a = (float)j*(float)((float)params->numcuts/(float)tot);
+               b = (float)(j+1)*(float)((float)params->numcuts/(float)tot);
+               if (d >= a && d <= b) {
+                       interp_v3_v3v3(rnd2, lastrnd, rnd, (((float)d)-a)/(b-a));
+                       mul_v3_fl(rnd2, df);
+                       add_v3_v3(vec1, rnd2);
+               }
+               
+               copy_v3_v3(lastrnd, rnd);
+       }
+}
+#endif
 /*connects face with smallest len, which I think should always be correct for
   edge subdivision*/
 BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf) {
@@ -115,59 +168,88 @@ BMEdge *connect_smallest_face(BMesh *bm, BMVert *v1, BMVert *v2, BMFace **nf) {
        return NULL;
 }
 /* calculates offset for co, based on fractal, sphere or smooth settings  */
-static void alter_co(float *co, BMEdge *UNUSED(edge), subdparams *params, float perc,
+static void alter_co(BMesh *bm, BMVert *v, BMEdge *origed, subdparams *params, float perc,
                     BMVert *vsta, BMVert *vend)
 {
        float vec1[3], fac;
+       float *co=NULL, *origco=NULL;
+       int i, totlayer = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY);
+       
+       BM_Vert_UpdateAllNormals(bm, v);
 
-       if(params->beauty & B_SMOOTH) {
-               /* we calculate an offset vector vec1[], to be added to *co */
-               float len, fac, nor[3], nor1[3], nor2[3], smooth=params->smooth;
-
-               sub_v3_v3v3(nor, vsta->co, vend->co);
-               len= 0.5f*normalize_v3(nor);
-
-               copy_v3_v3(nor1, vsta->no);
-               copy_v3_v3(nor2, vend->no);
-
-               /* cosine angle */
-               fac= nor[0]*nor1[0] + nor[1]*nor1[1] + nor[2]*nor1[2] ;
-
-               vec1[0]= fac*nor1[0];
-               vec1[1]= fac*nor1[1];
-               vec1[2]= fac*nor1[2];
-
-               /* cosine angle */
-               fac= -nor[0]*nor2[0] - nor[1]*nor2[1] - nor[2]*nor2[2] ;
-
-               vec1[0]+= fac*nor2[0];
-               vec1[1]+= fac*nor2[1];
-               vec1[2]+= fac*nor2[2];
-
-               /* falloff for multi subdivide */
-               smooth *= sqrt(fabs(1.0f - 2.0f*fabs(perc)));
-
-               vec1[0]*= smooth*len;
-               vec1[1]*= smooth*len;
-               vec1[2]*= smooth*len;
-
-               co[0] += vec1[0];
-               co[1] += vec1[1];
-               co[2] += vec1[2];
-       }
-       else if(params->beauty & B_SPHERE) { /* subdivide sphere */
-               normalize_v3(co);
-               co[0]*= params->smooth;
-               co[1]*= params->smooth;
-               co[2]*= params->smooth;
+       origco = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, params->origkey);
+       sub_v3_v3v3(vec1, origco, v->co);
+       
+       for (i=0; i<totlayer; i++) {
+               co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, i);
+               sub_v3_v3(co, vec1);
        }
 
-       if(params->beauty & B_FRACTAL) {
-               fac= params->fractal*len_v3v3(vsta->co, vend->co);
-               vec1[0]= fac*(float)(0.5-BLI_drand());
-               vec1[1]= fac*(float)(0.5-BLI_drand());
-               vec1[2]= fac*(float)(0.5-BLI_drand());
-               add_v3_v3v3(co, co, vec1);
+       for (i=0; i<totlayer; i++) {
+               co = CustomData_bmesh_get_n(&bm->vdata, v->head.data, CD_SHAPEKEY, i);
+               
+               if(params->beauty & B_SMOOTH) {
+                       /* we calculate an offset vector vec1[], to be added to *co */
+                       float len, fac, nor[3], nor1[3], nor2[3], smooth=params->smooth;
+       
+                       sub_v3_v3v3(nor, vsta->co, vend->co);
+                       len= 0.5f*normalize_v3(nor);
+       
+                       copy_v3_v3(nor1, vsta->no);
+                       copy_v3_v3(nor2, vend->no);
+       
+                       /* cosine angle */
+                       fac= nor[0]*nor1[0] + nor[1]*nor1[1] + nor[2]*nor1[2] ;
+       
+                       vec1[0]= fac*nor1[0];
+                       vec1[1]= fac*nor1[1];
+                       vec1[2]= fac*nor1[2];
+       
+                       /* cosine angle */
+                       fac= -nor[0]*nor2[0] - nor[1]*nor2[1] - nor[2]*nor2[2] ;
+       
+                       vec1[0]+= fac*nor2[0];
+                       vec1[1]+= fac*nor2[1];
+                       vec1[2]+= fac*nor2[2];
+       
+                       /* falloff for multi subdivide */
+                       smooth *= sqrt(fabs(1.0f - 2.0f*fabs(perc)));
+       
+                       vec1[0]*= smooth*len;
+                       vec1[1]*= smooth*len;
+                       vec1[2]*= smooth*len;
+       
+                       co[0] += vec1[0];
+                       co[1] += vec1[1];
+                       co[2] += vec1[2];
+               }
+               else if(params->beauty & B_SPHERE) { /* subdivide sphere */
+                       normalize_v3(co);
+                       co[0]*= params->smooth;
+                       co[1]*= params->smooth;
+                       co[2]*= params->smooth;
+               }
+       
+               if(params->beauty & B_FRACTAL) {
+                       float len = len_v3v3(vsta->co, vend->co);
+                       float vec2[3] = {0.0f, 0.0f, 0.0f}, co2[3];
+                       
+                       fac= params->fractal*len;
+
+                       add_v3_v3(vec2, vsta->no);
+                       add_v3_v3(vec2, vend->no);
+                       mul_v3_fl(vec2, 0.5f);
+                       
+                       add_v3_v3v3(co2, v->co, params->off);
+                       vec1[0] = fac*(BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 1)-0.5f);
+                       vec1[1] = fac*(BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 1)-0.5f);
+                       vec1[2] = fac*(BLI_gTurbulence(1.0, co2[0], co2[1], co2[2], 15, 0, 1)-0.5f);
+                       
+                       mul_v3_v3(vec2, vec1);
+                       
+                       /*add displacement*/
+                       add_v3_v3v3(co, co, vec2);
+               }
        }
 }
 
@@ -180,15 +262,13 @@ static BMVert *bm_subdivide_edge_addvert(BMesh *bm, BMEdge *edge,BMEdge *oedge,
                                        BMEdge **out,BMVert *vsta,BMVert *vend)
 {
        BMVert *ev;
-//     float co[3];
        
        ev = BM_Split_Edge(bm, edge->v1, edge, out, percent);
-       BM_Vert_UpdateNormal(bm, ev);
 
        BMO_SetFlag(bm, ev, ELE_INNER);
 
        /* offset for smooth or sphere or fractal */
-       alter_co(ev->co, oedge, params, percent2, vsta, vend);
+       alter_co(bm, ev, oedge, params, percent2, vsta, vend);
 
 #if 0 //TODO
        /* clip if needed by mirror modifier */
@@ -220,7 +300,7 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
                                        "edgepercents", edge);
        else {
                percent= 1.0f/(float)(totpoint+1-curpoint);
-               percent2 = (float)curpoint / (float)(totpoint + 1);
+               percent2 = (float)(curpoint+1) / (float)(totpoint+1);
 
        }
        
@@ -232,12 +312,16 @@ static BMVert *subdivideedgenum(BMesh *bm, BMEdge *edge, BMEdge *oedge,
 static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, subdparams *params, 
                                  BMVert *vsta, BMVert *vend) {
        BMEdge *eed = edge, *newe, temp = *edge;
-       BMVert *v;
+       BMVert *v, ov1=*edge->v1, ov2=*edge->v2, *v1=edge->v1, *v2=edge->v2;
        int i, numcuts = params->numcuts;
 
+       temp.v1 = &ov1;
+       temp.v2 = &ov2;
+       
        for(i=0;i<numcuts;i++) {
                v = subdivideedgenum(bm, eed, &temp, i, params->numcuts, params, 
                                     &newe, vsta, vend);
+
                BMO_SetFlag(bm, v, SUBD_SPLIT);
                BMO_SetFlag(bm, eed, SUBD_SPLIT);
                BMO_SetFlag(bm, newe, SUBD_SPLIT);
@@ -250,6 +334,9 @@ static void bm_subdivide_multicut(BMesh *bm, BMEdge *edge, subdparams *params,
                if (v->e) CHECK_ELEMENT(bm, v->e);
                if (v->e && v->e->l) CHECK_ELEMENT(bm, v->e->l->f);
        }
+       
+       alter_co(bm, v1, &temp, params, 0, &ov1, &ov2);
+       alter_co(bm, v2, &temp, params, 1.0, &ov1, &ov2);
 }
 
 /*note: the patterns are rotated as necassary to
@@ -344,7 +431,7 @@ static void quad_2edge_split_innervert(BMesh *bm, BMFace *UNUSED(face), BMVert *
 {
        BMFace *nf;
        BMVert *v, *lastv;
-       BMEdge *e, *ne;
+       BMEdge *e, *ne, olde;
        int i, numcuts = params->numcuts;
        
        lastv = verts[numcuts];
@@ -353,8 +440,12 @@ static void quad_2edge_split_innervert(BMesh *bm, BMFace *UNUSED(face), BMVert *
                e = connect_smallest_face(bm, verts[i], verts[numcuts+(numcuts-i)],
                                   &nf);
                
-               v = BM_Split_Edge(bm, e->v1, e, &ne, 0.5f);
-               connect_smallest_face(bm, lastv, v, &nf);
+               olde = *e;
+               v = bm_subdivide_edge_addvert(bm, e, &olde, params, 0.5f, 0.5f, &ne, e->v1, e->v2);
+
+               if (i != numcuts-1)
+                       connect_smallest_face(bm, lastv, v, &nf);
+               
                lastv = v;
        }
 
@@ -496,7 +587,7 @@ static void quad_4edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts
                temp = *e;
                for (a=0; a<numcuts; a++) {
                        v = subdivideedgenum(bm, e, &temp, a, numcuts, params, &ne,
-                                            v1, v2);
+                                           v1, v2);
                        if (!v)
                                bmesh_error();
 
@@ -561,7 +652,7 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
 {
        BMFace *nf;
        BMEdge *e, *ne, temp;
-       BMVert ***lines, *v;
+       BMVert ***lines, *v, ov1, ov2;
        void *stackarr[1];
        int i, j, a, b, numcuts = params->numcuts;
        
@@ -594,6 +685,10 @@ static void tri_3edge_subdivide(BMesh *bm, BMFace *UNUSED(face), BMVert **verts,
                lines[i+1][1+i] = verts[b];
                
                temp = *e;
+               ov1 = *verts[a];
+               ov2 = *verts[b];
+               temp.v1 = &ov1;
+               temp.v2 = &ov2;
                for (j=0; j<i; j++) {
                        v = subdivideedgenum(bm, e, &temp, j, i, params, &ne,
                                             verts[a], verts[b]);
@@ -670,27 +765,27 @@ typedef struct subd_facedata {
 void esubdivide_exec(BMesh *bmesh, BMOperator *op)
 {
        BMOpSlot *einput;
-       BMEdge *edge, **edges = NULL;
-       BLI_array_declare(edges);
-       BMFace *face;
-       BMLoop *nl;
-       BMVert **verts = NULL;
-       BLI_array_declare(verts);
-       BMIter fiter, liter;
        subdpattern *pat;
        subdparams params;
        subd_facedata *facedata = NULL;
-       BLI_array_declare(facedata);
-       BMLoop *l, **splits = NULL, **loops = NULL;
+       BMIter viter, fiter, liter;
+       BMVert *v, **verts = NULL;
+       BMEdge *edge, **edges = NULL;
+       BMLoop *nl, *l, **splits = NULL, **loops = NULL;
+       BMFace *face;
        BLI_array_declare(splits);
        BLI_array_declare(loops);
+       BLI_array_declare(facedata);
+       BLI_array_declare(edges);
+       BLI_array_declare(verts);
        float smooth, fractal;
        int beauty, cornertype, singleedge, gridfill;
-       int i, j, matched, a, b, numcuts, totesel;
+       int skey, seed, i, j, matched, a, b, numcuts, totesel;
        
        BMO_Flag_Buffer(bmesh, op, "edges", SUBD_SPLIT, BM_EDGE);
        
        numcuts = BMO_Get_Int(op, "numcuts");
+       seed = BMO_Get_Int(op, "seed");
        smooth = BMO_Get_Float(op, "smooth");
        fractal = BMO_Get_Float(op, "fractal");
        beauty = BMO_Get_Int(op, "beauty");
@@ -698,6 +793,8 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
        singleedge = BMO_Get_Int(op, "singleedge");
        gridfill = BMO_Get_Int(op, "gridfill");
        
+       BLI_srandom(seed);
+       
        patterns[1] = NULL;
        //straight cut is patterns[1] == NULL
        switch (cornertype) {
@@ -728,6 +825,15 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                patterns[5] = NULL;
        }
        
+       /*add a temporary shapekey layer to store displacements on current geometry*/
+       BM_add_data_layer(bmesh, &bmesh->vdata, CD_SHAPEKEY);
+       skey = CustomData_number_of_layers(&bmesh->vdata, CD_SHAPEKEY)-1;
+       
+       BM_ITER(v, &viter, bmesh, BM_VERTS_OF_MESH, NULL) {
+               float *co = CustomData_bmesh_get_n(&bmesh->vdata, v->head.data, CD_SHAPEKEY, skey);
+               copy_v3_v3(co, v->co);
+       }
+
        /*first go through and tag edges*/
        BMO_Flag_To_Slot(bmesh, op, "edges",
                 SUBD_SPLIT, BM_EDGE);
@@ -735,9 +841,14 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
        params.numcuts = numcuts;
        params.op = op;
        params.smooth = smooth;
+       params.seed = seed;
        params.fractal = fractal;
        params.beauty = beauty;
-
+       params.origkey = skey;
+       params.off[0] = BLI_drand()*200.0f;
+       params.off[1] = BLI_drand()*200.0f;
+       params.off[2] = BLI_drand()*200.0f;
+       
        BMO_Mapping_To_Flag(bmesh, op, "custompatterns",
                            FACE_CUSTOMFILL);
 
@@ -967,6 +1078,14 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
                pat->connectexec(bmesh, face, verts, &params);
        }
 
+       /*copy original-geometry displacements to current coordinates*/
+       BM_ITER(v, &viter, bmesh, BM_VERTS_OF_MESH, NULL) {
+               float *co = CustomData_bmesh_get_n(&bmesh->vdata, v->head.data, CD_SHAPEKEY, skey);
+               copy_v3_v3(v->co, co);
+       }
+
+       BM_free_data_layer_n(bmesh, &bmesh->vdata, CD_SHAPEKEY, skey);
+       
        if (facedata) BLI_array_free(facedata);
        if (edges) BLI_array_free(edges);
        if (verts) BLI_array_free(verts);
@@ -985,15 +1104,15 @@ void esubdivide_exec(BMesh *bmesh, BMOperator *op)
 /*editmesh-emulating function*/
 void BM_esubdivideflag(Object *UNUSED(obedit), BMesh *bm, int flag, float smooth,
                       float fractal, int beauty, int numcuts, 
-                      int seltype, int cornertype, int singleedge, int gridfill)
+                      int seltype, int cornertype, int singleedge, int gridfill, int seed)
 {
        BMOperator op;
        
        BMO_InitOpf(bm, &op, "esubd edges=%he smooth=%f fractal=%f "
                             "beauty=%d numcuts=%d quadcornertype=%d singleedge=%d "
-                            "gridfill=%d",
+                            "gridfill=%d seed=%d",
                             flag, smooth, fractal, beauty, numcuts,
-                            cornertype, singleedge, gridfill);
+                            cornertype, singleedge, gridfill, seed);
        
        BMO_Exec_Op(bm, &op);
        
@@ -1040,31 +1159,21 @@ void BM_esubdivideflag(Object *UNUSED(obedit), BMesh *bm, int flag, float smooth
        BMO_Finish_Op(bm, &op);
 }
 
-#if 0
-void BM_esubdivideflag_conv(Object *obedit,EditMesh *em,int selflag, float rad, 
-                      int flag, int numcuts, int seltype) {
-       BMesh *bm = editmesh_to_bmesh(em);
-       EditMesh *em2;
-
-       BM_esubdivideflag(obedit, bm, selflag, rad, flag, numcuts, seltype);
-       em2 = bmesh_to_editmesh(bm);
-       
-       free_editMesh(em);
-       *em = *em2;
-       MEM_freeN(em2);
-       BM_Free_Mesh(bm);
-}
-#endif
-
 void esplit_exec(BMesh *bm, BMOperator *op)
 {
        BMOIter siter;
        BMEdge *e;
        subdparams params;
-
+       int skey;
+       
        params.numcuts = BMO_GetSlot(op, "numcuts")->data.i;
        params.op = op;
        
+       BM_add_data_layer(bm, &bm->vdata, CD_SHAPEKEY);
+       skey = CustomData_number_of_layers(&bm->vdata, CD_SHAPEKEY)-1;
+       
+       params.origkey = skey;
+
        /*go through and split edges*/
        BMO_ITER(e, &siter, bm, op, "edges", BM_EDGE) {
                bm_subdivide_multicut(bm, e, &params, e->v1, e->v2);
@@ -1072,4 +1181,6 @@ void esplit_exec(BMesh *bm, BMOperator *op)
 
        BMO_Flag_To_Slot(bm, op, "outsplit",
                         ELE_SPLIT, BM_ALL);
+
+       BM_free_data_layer_n(bm, &bm->vdata, CD_SHAPEKEY, skey);
 }
index 7bb471117d85c7b4d489c099fd9e8f93861b86bf..966cd90cbde36f44721832133b3c33ac0afee07c 100644 (file)
@@ -6,7 +6,10 @@ typedef struct subdparams {
        float smooth;
        float fractal;
        int beauty;
+       int seed;
+       int origkey; /*shapekey holding displaced vertex coordinates for current geometry*/
        BMOperator *op;
+       float off[3];
 } subdparams;
 
 typedef void (*subd_pattern_fill_fp)(BMesh *bm, BMFace *face, BMVert **verts, 
@@ -35,4 +38,4 @@ typedef struct subdpattern {
     split the edge only?
 */
 
-#endif /* _SUBDIVIDEOP_H */
\ No newline at end of file
+#endif /* _SUBDIVIDEOP_H */
index a34c2d86a50b30c2c34a0e2fe39be9b893307547..5b33a6b5d1c08fa1809a02a467fa9de3db4ab925 100644 (file)
@@ -112,21 +112,24 @@ static int subdivide_exec(bContext *C, wmOperator *op)
        Object *obedit= CTX_data_edit_object(C);
        BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
        int cuts= RNA_int_get(op->ptr,"number_cuts");
-       float smooth= 0.292f*RNA_float_get(op->ptr, "smoothness");
-       float fractal= RNA_float_get(op->ptr, "fractal")/100;
+       float fractal= RNA_float_get(op->ptr, "fractal")/2.5;
        int flag= 0;
 
-       if(smooth != 0.0f)
-               flag |= B_SMOOTH;
        if(fractal != 0.0f)
                flag |= B_FRACTAL;
-
+       
+       if (RNA_boolean_get(op->ptr, "quadtri") && 
+           RNA_enum_get(op->ptr, "quadcorner") == SUBD_STRAIGHT_CUT)
+       {
+               RNA_enum_set(op->ptr, "quadcorner", SUBD_INNERVERT);    
+       }
+       
        BM_esubdivideflag(obedit, em->bm, BM_SELECT, 
-                         smooth, fractal, 
+                         0.0f, fractal, 
                          ts->editbutflag|flag, 
                          cuts, 0, RNA_enum_get(op->ptr, "quadcorner"), 
-                         RNA_boolean_get(op->ptr, "tess_single_edge"),
-                         RNA_boolean_get(op->ptr, "gridfill"));
+                         RNA_boolean_get(op->ptr, "quadtri"),
+                         1, RNA_int_get(op->ptr, "seed"));
 
        DAG_id_tag_update(obedit->data, OB_RECALC_DATA);
        WM_event_add_notifier(C, NC_GEOM|ND_DATA, obedit->data);
@@ -158,19 +161,18 @@ void MESH_OT_subdivide(wmOperatorType *ot)
        ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
 
        /* properties */
-       RNA_def_int(ot->srna, "number_cuts", 1, 1, 20, "Number of Cuts", "", 1, INT_MAX);
-       RNA_def_float(ot->srna, "fractal", 0.0, 0.0f, FLT_MAX, "Fractal", "Fractal randomness factor.", 0.0f, 1000.0f);
-       RNA_def_float(ot->srna, "smoothness", 0.0f, 0.0f, 1000.0f, "Smoothness", "Smoothness factor.", 0.0f, FLT_MAX);
+       RNA_def_int(ot->srna, "number_cuts", 1, 1, 50, "Number of Cuts", "", 1, INT_MAX);
 
-       /*props */
-       RNA_def_enum(ot->srna, "quadcorner", prop_mesh_cornervert_types, SUBD_STRAIGHT_CUT, "Quad Corner Type", "Method used for subdividing two adjacent edges in a quad");
-       RNA_def_boolean(ot->srna, "tess_single_edge", 0, "Tesselate Single Edge", "Adds triangles to single edges belonging to triangles or quads");
-       RNA_def_boolean(ot->srna, "gridfill", 1, "Grid Fill", "Fill Fully Selected Triangles and Quads With A Grid");
+       RNA_def_boolean(ot->srna, "quadtri", 0, "Quad/Tri Mode", "Tries to prevent ngons");
+       RNA_def_enum(ot->srna, "quadcorner", prop_mesh_cornervert_types, SUBD_STRAIGHT_CUT, "Quad Corner Type", "How to subdivide quad corners (anything other then Straight Cut will prevent ngons)");
+
+       RNA_def_float(ot->srna, "fractal", 0.0, 0.0f, FLT_MAX, "Fractal", "Fractal randomness factor.", 0.0f, 1000.0f);
+       RNA_def_int(ot->srna, "seed", 0, 0, 10000, "Random Seed", "Seed for the random number generator", 0, 50);
 }
 
 /* individual face extrude */
 /* will use vertex normals for extrusion directions, so *nor is unaffected */
-short EDBM_Extrude_face_indiv(BMEditMesh *em, wmOperator *op, short flag, float *nor
+short EDBM_Extrude_face_indiv(BMEditMesh *em, wmOperator *op, short flag, float *UNUSED(nor)
 {
        BMOIter siter;
        BMIter liter;
@@ -790,7 +792,7 @@ void EDBM_toggle_select_all(BMEditMesh *em) /* exported for UV */
                EDBM_set_flag_all(em, SELECT);
 }
 
-static int toggle_select_all_exec(bContext *C, wmOperator *op)
+static int toggle_select_all_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
@@ -1240,7 +1242,7 @@ void MESH_OT_mark_sharp(wmOperatorType *ot)
 }
 
 
-static int editbmesh_vert_connect(bContext *C, wmOperator *op)
+static int editbmesh_vert_connect(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        BMEditMesh *em= ((Mesh *)obedit->data)->edit_btmesh;
@@ -1675,7 +1677,7 @@ void EDBM_reveal_mesh(BMEditMesh *em)
        EDBM_selectmode_flush(em);
 }
 
-static int reveal_mesh_exec(bContext *C, wmOperator *op)
+static int reveal_mesh_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        BMEditMesh *em= (((Mesh *)obedit->data))->edit_btmesh;
@@ -1804,7 +1806,7 @@ void MESH_OT_vertices_smooth(wmOperatorType *ot)
 }
 
 
-static int bm_test_exec(bContext *C, wmOperator *op)
+static int bm_test_exec(bContext *C, wmOperator *UNUSED(op))
 {
        Object *obedit= CTX_data_edit_object(C);
        RegionView3D *r3d = CTX_wm_region_view3d(C);            
index 711177e817bb6442b52a611b878eac3aea3c7cbc..6cb79039a88c2d9ecfb649e001df9e599a5247d2 100644 (file)
@@ -295,7 +295,7 @@ static void ringsel_finish(bContext *C, wmOperator *op)
                if (lcd->do_cut) {
                        BM_esubdivideflag(lcd->ob, em->bm, BM_SELECT, 0.0f, 
                                          0.0f, 0, cuts, SUBDIV_SELECT_LOOPCUT, 
-                                         SUBD_PATH, 0, 0);
+                                         SUBD_PATH, 0, 0, 0);
                        /* force edge slide to edge select mode in in face select mode */
                        if (em->selectmode & SCE_SELECT_FACE) {
                                if (em->selectmode == SCE_SELECT_FACE)