diff options
-rw-r--r-- | release/scripts/modules/bpy/utils.py | 5 | ||||
-rw-r--r-- | release/scripts/ui/space_view3d_toolbar.py | 5 | ||||
-rw-r--r-- | source/blender/editors/include/ED_mesh.h | 2 | ||||
-rw-r--r-- | source/blender/editors/mesh/editmesh_mods.c | 10 | ||||
-rw-r--r-- | source/blender/editors/mesh/meshtools.c | 299 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_buttons.c | 20 | ||||
-rw-r--r-- | source/blender/editors/transform/transform_conversions.c | 40 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_mesh_types.h | 2 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_mesh.c | 4 |
9 files changed, 358 insertions, 29 deletions
diff --git a/release/scripts/modules/bpy/utils.py b/release/scripts/modules/bpy/utils.py index 1f4866836a1..1732f68d192 100644 --- a/release/scripts/modules/bpy/utils.py +++ b/release/scripts/modules/bpy/utils.py @@ -187,7 +187,10 @@ def load_scripts(reload_scripts=False, refresh_scripts=False): for module_name in sorted(used_ext): mod = _test_import(module_name, loaded_modules) test_register(mod) - + + if reload_scripts: + import gc + print("gc.collect() -> %d" % gc.collect()) if _bpy.app.debug: print("Time %.4f" % (time.time() - t_main)) diff --git a/release/scripts/ui/space_view3d_toolbar.py b/release/scripts/ui/space_view3d_toolbar.py index c96fdc4daf0..e45d79f622e 100644 --- a/release/scripts/ui/space_view3d_toolbar.py +++ b/release/scripts/ui/space_view3d_toolbar.py @@ -156,6 +156,7 @@ class VIEW3D_PT_tools_meshedit_options(View3DPanel): mesh = context.active_object.data col = layout.column(align=True) col.prop(mesh, "use_mirror_x") + col.prop(mesh, "use_mirror_topology") col.prop(context.tool_settings, "edge_path_mode") # ********** default tools for editmode_curve **************** @@ -810,7 +811,9 @@ class VIEW3D_PT_tools_weightpaint_options(View3DPanel): obj = context.weight_paint_object if obj.type == 'MESH': - col.prop(obj.data, "use_mirror_x") + mesh = obj.data + col.prop(mesh, "use_mirror_x") + col.prop(mesh, "use_mirror_topology") # Commented out because the Apply button isn't an operator yet, making these settings useless # col.label(text="Gamma:") diff --git a/source/blender/editors/include/ED_mesh.h b/source/blender/editors/include/ED_mesh.h index cf2d16574df..886da0820a2 100644 --- a/source/blender/editors/include/ED_mesh.h +++ b/source/blender/editors/include/ED_mesh.h @@ -78,7 +78,7 @@ struct rcti; /* meshtools.c */ intptr_t mesh_octree_table(struct Object *ob, struct EditMesh *em, float *co, char mode); -struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, struct EditMesh *em, float *co); +struct EditVert *editmesh_get_x_mirror_vert(struct Object *ob, struct EditMesh *em, struct EditVert *eve, float *co, int index); int mesh_get_x_mirror_vert(struct Object *ob, int index); int *mesh_get_x_mirror_faces(struct Object *ob, struct EditMesh *em); diff --git a/source/blender/editors/mesh/editmesh_mods.c b/source/blender/editors/mesh/editmesh_mods.c index b2ae7ddf7e0..c5ec1214be9 100644 --- a/source/blender/editors/mesh/editmesh_mods.c +++ b/source/blender/editors/mesh/editmesh_mods.c @@ -104,14 +104,15 @@ static int pupmenu() {return 0;} void EM_cache_x_mirror_vert(struct Object *ob, struct EditMesh *em) { EditVert *eve, *eve_mirror; + int index= 0; for(eve= em->verts.first; eve; eve= eve->next) { eve->tmp.v= NULL; } - for(eve= em->verts.first; eve; eve= eve->next) { + for(eve= em->verts.first; eve; eve= eve->next, index++) { if(eve->tmp.v==NULL) { - eve_mirror = editmesh_get_x_mirror_vert(ob, em, eve->co); + eve_mirror = editmesh_get_x_mirror_vert(ob, em, eve, eve->co, index); if(eve_mirror) { eve->tmp.v= eve_mirror; eve_mirror->tmp.v = eve; @@ -4239,6 +4240,7 @@ static int smooth_vertex(bContext *C, wmOperator *op) float fvec[3]; int teller=0; ModifierData *md; + int index; /* count */ eve= em->verts.first; @@ -4313,13 +4315,14 @@ static int smooth_vertex(bContext *C, wmOperator *op) eed= eed->next; } + index= 0; eve= em->verts.first; while(eve) { if(eve->f & SELECT) { if(eve->f1) { if (((Mesh *)obedit->data)->editflag & ME_EDIT_MIRROR_X) { - eve_mir= editmesh_get_x_mirror_vert(obedit, em, eve->co); + eve_mir= editmesh_get_x_mirror_vert(obedit, em, eve, eve->co, index); } adr = eve->tmp.p; @@ -4352,6 +4355,7 @@ static int smooth_vertex(bContext *C, wmOperator *op) } eve->tmp.p= NULL; } + index++; eve= eve->next; } MEM_freeN(adror); diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c index 55e8b55dcd5..e345d743172 100644 --- a/source/blender/editors/mesh/meshtools.c +++ b/source/blender/editors/mesh/meshtools.c @@ -989,7 +989,200 @@ intptr_t mesh_octree_table(Object *ob, EditMesh *em, float *co, char mode) return 0; } -int mesh_get_x_mirror_vert(Object *ob, int index) + +/* ********************* MESH VERTEX MIRR TOPO LOOKUP *************** */ + +#define MIRRHASH_TYPE int + +typedef struct MirrTopoPair { + long hash; + int vIndex; +} MirrTopoPair; + +static int MirrTopo_long_sort(const void *l1, const void *l2) +{ + if( (MIRRHASH_TYPE)(intptr_t)l1 > (MIRRHASH_TYPE)(intptr_t)l2 ) return 1; + else if( (MIRRHASH_TYPE)(intptr_t)l1 < (MIRRHASH_TYPE)(intptr_t)l2 ) return -1; + return 0; +} + +static int MirrTopo_item_sort(const void *v1, const void *v2) +{ + if( ((MirrTopoPair *)v1)->hash > ((MirrTopoPair *)v2)->hash ) return 1; + else if( ((MirrTopoPair *)v1)->hash < ((MirrTopoPair *)v2)->hash ) return -1; + return 0; +} + +static long *mesh_topo_lookup = NULL; +static int mesh_topo_lookup_tot = -1; +static int mesh_topo_lookup_mode = -1; + +/* mode is 's' start, or 'e' end, or 'u' use */ +/* if end, ob can be NULL */ +long mesh_mirrtopo_table(Object *ob, char mode) +{ + if(mode=='u') { /* use table */ + Mesh *me= ob->data; + if( (mesh_topo_lookup==NULL) || + (mesh_topo_lookup_mode != ob->mode) || + (me->edit_mesh && me->edit_mesh->totvert != mesh_topo_lookup_tot) || + (me->edit_mesh==NULL && me->totvert != mesh_topo_lookup_tot) + ) { + mesh_mirrtopo_table(ob, 's'); + } + } else if(mode=='s') { /* start table */ + Mesh *me= ob->data; + MEdge *medge; + EditMesh *em= me->edit_mesh; + + mesh_topo_lookup_mode= ob->mode; + + /* editmode*/ + EditEdge *eed; + + int a, last, totvert; + int totUnique= -1, totUniqueOld= -1; + + MIRRHASH_TYPE *MirrTopoHash = NULL; + MIRRHASH_TYPE *MirrTopoHash_Prev = NULL; + MirrTopoPair *MirrTopoPairs; + + /* reallocate if needed */ + if (mesh_topo_lookup) { + MEM_freeN(mesh_topo_lookup); + mesh_topo_lookup = NULL; + } + + if(em) { + EditVert *eve; + totvert= 0; + for(eve= em->verts.first; eve; eve= eve->next) { + eve->hash = totvert++; + } + } else { + totvert = me->totvert; + } + + MirrTopoHash = MEM_callocN( totvert * sizeof(MIRRHASH_TYPE), "TopoMirr" ); + + /* Initialize the vert-edge-user counts used to detect unique topology */ + if(em) { + for(eed=em->edges.first; eed; eed= eed->next) { + MirrTopoHash[eed->v1->hash]++; + MirrTopoHash[eed->v2->hash]++; + } + } else { + for(a=0, medge=me->medge; a<me->totedge; a++, medge++) { + MirrTopoHash[medge->v1]++; + MirrTopoHash[medge->v2]++; + } + } + + MirrTopoHash_Prev = MEM_dupallocN( MirrTopoHash ); + + totUniqueOld = -1; + while(1) { + /* use the number of edges per vert to give verts unique topology IDs */ + + if(em) { + for(eed=em->edges.first; eed; eed= eed->next) { + MirrTopoHash[eed->v1->hash] += MirrTopoHash_Prev[eed->v2->hash]; + MirrTopoHash[eed->v2->hash] += MirrTopoHash_Prev[eed->v1->hash]; + } + } else { + for(a=0, medge=me->medge; a<me->totedge; a++, medge++) { + /* This can make realy big numbers, wrapping around here is fine */ + MirrTopoHash[medge->v1] += MirrTopoHash_Prev[medge->v2]; + MirrTopoHash[medge->v2] += MirrTopoHash_Prev[medge->v1]; + } + } + memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MIRRHASH_TYPE) * totvert); + + /* sort so we can count unique values */ + qsort(MirrTopoHash_Prev, totvert, sizeof(MIRRHASH_TYPE), MirrTopo_long_sort); + + totUnique = 1; /* account for skiping the first value */ + for(a=1; a<totvert; a++) { + if (MirrTopoHash_Prev[a-1] != MirrTopoHash_Prev[a]) { + totUnique++; + } + } + + if (totUnique <= totUniqueOld) { + /* Finish searching for unique valus when 1 loop dosnt give a + * higher number of unique values compared to the previous loop */ + break; + } else { + totUniqueOld = totUnique; + } + /* Copy the hash calculated this iter, so we can use them next time */ + memcpy(MirrTopoHash_Prev, MirrTopoHash, sizeof(MIRRHASH_TYPE) * totvert); + } + + /* Hash/Index pairs are needed for sorting to find index pairs */ + MirrTopoPairs= MEM_callocN( sizeof(MirrTopoPair) * totvert, "MirrTopoPairs"); + + /* since we are looping through verts, initialize these values here too */ + mesh_topo_lookup = MEM_mallocN( totvert * sizeof(long), "mesh_topo_lookup" ); + + if(em) { + EM_init_index_arrays(em,1,0,0); + } + + + for(a=0; a<totvert; a++) { + MirrTopoPairs[a].hash= MirrTopoHash[a]; + MirrTopoPairs[a].vIndex = a; + + /* initialize lookup */ + mesh_topo_lookup[a] = -1; + } + + qsort(MirrTopoPairs, totvert, sizeof(MirrTopoPair), MirrTopo_item_sort); + + /* Since the loop starts at 2, we must define the last index where the hash's differ */ + last = ((totvert >= 2) && (MirrTopoPairs[0].hash == MirrTopoPairs[1].hash)) ? 0 : 1; + + /* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2, + * but you cant ever access the last 'a' index of MirrTopoPairs */ + for(a=2; a < totvert+1; a++) { + /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].vIndex ); */ + if ((a==totvert) || (MirrTopoPairs[a-1].hash != MirrTopoPairs[a].hash)) { + if (a-last==2) { + if(em) { + mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = (long)EM_get_vert_for_index(MirrTopoPairs[a-2].vIndex); + mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = (long)EM_get_vert_for_index(MirrTopoPairs[a-1].vIndex); + } else { + mesh_topo_lookup[MirrTopoPairs[a-1].vIndex] = MirrTopoPairs[a-2].vIndex; + mesh_topo_lookup[MirrTopoPairs[a-2].vIndex] = MirrTopoPairs[a-1].vIndex; + } + } + last= a; + } + } + if(em) { + EM_free_index_arrays(); + } + + MEM_freeN( MirrTopoPairs ); + MirrTopoPairs = NULL; + + MEM_freeN( MirrTopoHash ); + MEM_freeN( MirrTopoHash_Prev ); + + mesh_topo_lookup_tot = totvert; + + } else if(mode=='e') { /* end table */ + if (mesh_topo_lookup) { + MEM_freeN(mesh_topo_lookup); + } + mesh_topo_lookup = NULL; + mesh_topo_lookup_tot= -1; + } + return 0; +} + +int mesh_get_x_mirror_vert_spacial(Object *ob, int index) { Mesh *me= ob->data; MVert *mvert; @@ -1003,7 +1196,24 @@ int mesh_get_x_mirror_vert(Object *ob, int index) return mesh_octree_table(ob, NULL, vec, 'u'); } -EditVert *editmesh_get_x_mirror_vert(Object *ob, EditMesh *em, float *co) +static int mesh_get_x_mirror_vert_topo(Object *ob, int index) +{ + if (mesh_mirrtopo_table(ob, 'u')==-1) + return -1; + + return mesh_topo_lookup[index]; +} + +int mesh_get_x_mirror_vert(Object *ob, int index) +{ + if (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_TOPO) { + return mesh_get_x_mirror_vert_topo(ob, index); + } else { + return mesh_get_x_mirror_vert_spacial(ob, index); + } +} + +static EditVert *editmesh_get_x_mirror_vert_spacial(Object *ob, EditMesh *em, float *co) { float vec[3]; intptr_t poinval; @@ -1025,6 +1235,91 @@ EditVert *editmesh_get_x_mirror_vert(Object *ob, EditMesh *em, float *co) return NULL; } +static EditVert *editmesh_get_x_mirror_vert_topo(Object *ob, struct EditMesh *em, EditVert *eve, int index) +{ + long poinval; + if (mesh_mirrtopo_table(ob, 'u')==-1) + return NULL; + + if (index!=-1) { + index = BLI_findindex(&em->verts, eve); + } + + if (index==-1) + return NULL; + + poinval= mesh_topo_lookup[ index ]; + + if(poinval != -1) + return (EditVert *)(poinval); + return NULL; +} + +EditVert *editmesh_get_x_mirror_vert(Object *ob, struct EditMesh *em, EditVert *eve, float *co, int index) +{ + if (((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_TOPO) { + return editmesh_get_x_mirror_vert_topo(ob, em, eve, index); + } else { + return editmesh_get_x_mirror_vert_spacial(ob, em, eve->co); + } +} + + +#if 0 +float *editmesh_get_mirror_uv(int axis, float *uv, float *mirrCent, float *face_cent) +{ + float vec[2]; + float cent_vec[2]; + float cent[2]; + + /* ignore nan verts */ + if (isnan(uv[0]) || !finite(uv[0]) || + isnan(uv[1]) || !finite(uv[1]) + ) + return NULL; + + if (axis) { + vec[0]= uv[0]; + vec[1]= -((uv[1])-mirrCent[1]) + mirrCent[1]; + + cent_vec[0] = face_cent[0]; + cent_vec[1]= -((face_cent[1])-mirrCent[1]) + mirrCent[1]; + } else { + vec[0]= -((uv[0])-mirrCent[0]) + mirrCent[0]; + vec[1]= uv[1]; + + cent_vec[0]= -((face_cent[0])-mirrCent[0]) + mirrCent[0]; + cent_vec[1] = face_cent[1]; + } + + /* + G.v2d->cursor[0] = mirrCent[0]; + G.v2d->cursor[1] = mirrCent[1]; + */ + + /* TODO - Optimize */ + { + EditFace *efa; + int i, len; + for(efa=em->faces.first; efa; efa=efa->next) { + MTFace *tf= (MTFace *)CustomData_em_get(&em->fdata, efa->data, CD_MTFACE); + uv_center(tf->uv, cent, (void *)efa->v4); + + if ( (fabs(cent[0] - cent_vec[0]) < 0.001) && (fabs(cent[1] - cent_vec[1]) < 0.001) ) { + len = efa->v4 ? 4 : 3; + for (i=0; i<len; i++) { + if ( (fabs(tf->uv[i][0] - vec[0]) < 0.001) && (fabs(tf->uv[i][1] - vec[1]) < 0.001) ) { + return tf->uv[i]; + } + } + } + } + } + + return NULL; +} +#endif + static unsigned int mirror_facehash(void *ptr) { MFace *mf= ptr; diff --git a/source/blender/editors/space_view3d/view3d_buttons.c b/source/blender/editors/space_view3d/view3d_buttons.c index 1fc6ab2fc5b..f1668190ea8 100644 --- a/source/blender/editors/space_view3d/view3d_buttons.c +++ b/source/blender/editors/space_view3d/view3d_buttons.c @@ -502,13 +502,13 @@ static void act_vert_def(Object *ob, EditVert **eve, MDeformVert **dvert) *dvert= NULL; } -static void editvert_mirror_update(Object *ob, EditVert *eve, int def_nr) +static void editvert_mirror_update(Object *ob, EditVert *eve, int def_nr, int index) { Mesh *me= ob->data; EditMesh *em = BKE_mesh_get_editmesh(me); EditVert *eve_mirr; - eve_mirr= editmesh_get_x_mirror_vert(ob, em, eve->co); + eve_mirr= editmesh_get_x_mirror_vert(ob, em, eve, eve->co, index); if(eve_mirr && eve_mirr != eve) { MDeformVert *dvert_src= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); @@ -541,7 +541,7 @@ static void vgroup_adjust_active(Object *ob, int def_nr) if(dvert_act) { if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve_act, def_nr); + editvert_mirror_update(ob, eve_act, def_nr, -1); } } @@ -560,15 +560,16 @@ static void vgroup_copy_active_to_sel(Object *ob) EditMesh *em = BKE_mesh_get_editmesh(me); EditVert *eve; MDeformVert *dvert; + int index= 0; - for(eve= em->verts.first; eve; eve= eve->next) { + for(eve= em->verts.first; eve; eve= eve->next, index++) { if(eve->f & SELECT && eve != eve_act) { dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); if(dvert) { defvert_copy(dvert, dvert_act); if(me->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve, -1); + editvert_mirror_update(ob, eve, -1, index); } } @@ -594,6 +595,7 @@ static void vgroup_copy_active_to_sel_single(Object *ob, int def_nr) MDeformWeight *dw; float act_weight = -1.0f; int i; + int index= 0; for(i=0, dw=dvert_act->dw; i < dvert_act->totweight; i++, dw++) { if(def_nr == dw->def_nr) { @@ -605,7 +607,7 @@ static void vgroup_copy_active_to_sel_single(Object *ob, int def_nr) if(act_weight < -0.5f) return; - for(eve= em->verts.first; eve; eve= eve->next) { + for(eve= em->verts.first; eve; eve= eve->next, index++) { if(eve->f & SELECT && eve != eve_act) { dvert= CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT); if(dvert) { @@ -614,7 +616,7 @@ static void vgroup_copy_active_to_sel_single(Object *ob, int def_nr) dw->weight= act_weight; if(me->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve, -1); + editvert_mirror_update(ob, eve, -1, index); break; } @@ -624,7 +626,7 @@ static void vgroup_copy_active_to_sel_single(Object *ob, int def_nr) } if(me->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve_act, -1); + editvert_mirror_update(ob, eve_act, -1, -1); } } @@ -642,7 +644,7 @@ static void vgroup_normalize_active(Object *ob) defvert_normalize(dvert_act); if(((Mesh *)ob->data)->editflag & ME_EDIT_MIRROR_X) - editvert_mirror_update(ob, eve_act, -1); + editvert_mirror_update(ob, eve_act, -1, -1); diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c index 7738299358a..8d01174ae2e 100644 --- a/source/blender/editors/transform/transform_conversions.c +++ b/source/blender/editors/transform/transform_conversions.c @@ -2272,8 +2272,10 @@ static void createTransEditVerts(bContext *C, TransInfo *t) /* Mirror? */ if( (mirror>0 && tob->iloc[0]>0.0f) || (mirror<0 && tob->iloc[0]<0.0f)) { - EditVert *vmir= editmesh_get_x_mirror_vert(t->obedit, em, tob->iloc); /* initializes octree on first call */ - if(vmir != eve) tob->extra = vmir; + EditVert *vmir= editmesh_get_x_mirror_vert(t->obedit, em, eve, tob->iloc, a); /* initializes octree on first call */ + if(vmir != eve) { + tob->extra = vmir; + } } tob++; } @@ -3283,7 +3285,7 @@ static void createTransActionData(bContext *C, TransInfo *t) /* Helper function for createTransGraphEditData, which is reponsible for associating * source data with transform data */ -static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, float *loc, float *cent, short selected, short ishandle, short intvals) +static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, float *loc, float *cent, short selected, short ishandle, short intvals, float iaspy) { /* New location from td gets dumped onto the old-location of td2d, which then * gets copied to the actual data at td2d->loc2d (bezt->vec[n]) @@ -3294,20 +3296,20 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, if (adt) { td2d->loc[0] = BKE_nla_tweakedit_remap(adt, loc[0], NLATIME_CONVERT_MAP); - td2d->loc[1] = loc[1]; + td2d->loc[1] = loc[1] * iaspy; td2d->loc[2] = 0.0f; td2d->loc2d = loc; td->loc = td2d->loc; td->center[0] = BKE_nla_tweakedit_remap(adt, cent[0], NLATIME_CONVERT_MAP); - td->center[1] = cent[1]; + td->center[1] = cent[1] * iaspy; td->center[2] = 0.0f; VECCOPY(td->iloc, td->loc); } else { td2d->loc[0] = loc[0]; - td2d->loc[1] = loc[1]; + td2d->loc[1] = loc[1] * iaspy; td2d->loc[2] = 0.0f; td2d->loc2d = loc; @@ -3340,6 +3342,13 @@ static void bezt_to_transdata (TransData *td, TransData2D *td2d, AnimData *adt, unit_m3(td->smtx); } +static float UI_view2d_aspect_y(View2D *v2d) +{ + float viewx, viewy; + UI_view2d_region_to_view(v2d, 1, 1, &viewx, &viewy); + return -1.0 / (viewx / viewy); +} + static void createTransGraphEditData(bContext *C, TransInfo *t) { SpaceIpo *sipo= CTX_wm_space_graph(C); @@ -3444,7 +3453,13 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) AnimData *adt= ANIM_nla_mapping_get(&ac, ale); FCurve *fcu= (FCurve *)ale->key_data; short intvals= (fcu->flag & FCURVE_INT_VALUES); - + + float iaspy; + if(intvals) + iaspy= 1.0f; + else + iaspy= 1.0f/UI_view2d_aspect_y(v2d); + /* convert current-frame to action-time (slightly less accurate, espcially under * higher scaling ratios, but is faster than converting all points) */ @@ -3468,14 +3483,14 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) /* only include handles if selected, irrespective of the interpolation modes */ if (bezt->f1 & SELECT) { hdata = initTransDataCurveHandles(td, bezt); - bezt_to_transdata(td++, td2d++, adt, bezt->vec[0], bezt->vec[1], 1, 1, intvals); + bezt_to_transdata(td++, td2d++, adt, bezt->vec[0], bezt->vec[1], 1, 1, intvals, iaspy); } else h1= 0; if (bezt->f3 & SELECT) { if (hdata==NULL) hdata = initTransDataCurveHandles(td, bezt); - bezt_to_transdata(td++, td2d++, adt, bezt->vec[2], bezt->vec[1], 1, 1, intvals); + bezt_to_transdata(td++, td2d++, adt, bezt->vec[2], bezt->vec[1], 1, 1, intvals, iaspy); } else h2= 0; @@ -3490,7 +3505,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t) hdata = initTransDataCurveHandles(td, bezt); } - bezt_to_transdata(td++, td2d++, adt, bezt->vec[1], bezt->vec[1], 1, 0, intvals); + bezt_to_transdata(td++, td2d++, adt, bezt->vec[1], bezt->vec[1], 1, 0, intvals, iaspy); } /* special hack (must be done after initTransDataCurveHandles(), as that stores handle settings to restore...): @@ -3713,7 +3728,8 @@ void flushTransGraphData(TransInfo *t) Scene *scene= t->scene; double secf= FPS; int a; - + float aspy= UI_view2d_aspect_y(&t->ar->v2d); + /* flush to 2d vector from internally used 3d vector */ for (a=0, td= t->data, td2d=t->data2d; a<t->total; a++, td++, td2d++) { AnimData *adt= (AnimData *)td->extra; /* pointers to relevant AnimData blocks are stored in the td->extra pointers */ @@ -3747,7 +3763,7 @@ void flushTransGraphData(TransInfo *t) if (td->flag & TD_INTVALUES) td2d->loc2d[1]= (float)((int)td2d->loc[1]); else - td2d->loc2d[1]= td2d->loc[1]; + td2d->loc2d[1]= td2d->loc[1] * aspy; } } diff --git a/source/blender/makesdna/DNA_mesh_types.h b/source/blender/makesdna/DNA_mesh_types.h index 472850283d8..9f8d07b987f 100644 --- a/source/blender/makesdna/DNA_mesh_types.h +++ b/source/blender/makesdna/DNA_mesh_types.h @@ -124,6 +124,8 @@ typedef struct TFace { #define ME_EDIT_MIRROR_Z (1 << 2) // unused so far #define ME_EDIT_PAINT_MASK (1 << 3) +#define ME_EDIT_MIRROR_TOPO (1 << 4) // unused so far + /* me->flag */ #define ME_ISDONE 1 diff --git a/source/blender/makesrna/intern/rna_mesh.c b/source/blender/makesrna/intern/rna_mesh.c index db9f0ddb14f..aca8ce174b4 100644 --- a/source/blender/makesrna/intern/rna_mesh.c +++ b/source/blender/makesrna/intern/rna_mesh.c @@ -1819,6 +1819,10 @@ static void rna_def_mesh(BlenderRNA *brna) RNA_def_property_ui_text(prop, "Z Mirror", "Z Axis mirror editing"); */ + prop= RNA_def_property(srna, "use_mirror_topology", PROP_BOOLEAN, PROP_NONE); + RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_MIRROR_TOPO); + RNA_def_property_ui_text(prop, "Topology Mirror", "Use topology based mirroring"); + prop= RNA_def_property(srna, "use_paint_mask", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "editflag", ME_EDIT_PAINT_MASK); RNA_def_property_ui_text(prop, "Paint Mask", "Face selection masking for painting"); |