diff options
author | Campbell Barton <ideasman42@gmail.com> | 2006-03-27 12:25:06 +0400 |
---|---|---|
committer | Campbell Barton <ideasman42@gmail.com> | 2006-03-27 12:25:06 +0400 |
commit | 0e8e848588ec8b766e655463ace853db89d87032 (patch) | |
tree | f94ff6c827f875913f2d9d0891d0f716d12d1a59 /source/blender/src/editmesh_lib.c | |
parent | af9573e9eaf9314e9d07575802d34c17bb1091b3 (diff) |
Seperated out some functionality into 3 new functions.
EM_editselection_center
EM_editselection_normal
EM_editselection_plane
These functions are used by the manipulator to get data from an editselection. regardless of weather its a face/edge/vert.
Diffstat (limited to 'source/blender/src/editmesh_lib.c')
-rw-r--r-- | source/blender/src/editmesh_lib.c | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/source/blender/src/editmesh_lib.c b/source/blender/src/editmesh_lib.c index bf64fdc34cc..974519a2844 100644 --- a/source/blender/src/editmesh_lib.c +++ b/source/blender/src/editmesh_lib.c @@ -136,6 +136,124 @@ static void EM_strip_selections(void) } } +/* generic way to get data from an EditSelection type +These functions were written to be used by the Modifier widget when in Rotate about active mode, +but can be used anywhere. +EM_editselection_center +EM_editselection_normal +EM_editselection_plane +*/ +void EM_editselection_center(float *center, EditSelection *ese) +{ + if (ese->type==EDITVERT) { + EditVert *eve= ese->data; + VecCopyf(center, eve->co); + } else if (ese->type==EDITEDGE) { + EditEdge *eed= ese->data; + VecAddf(center, eed->v1->co, eed->v2->co); + VecMulf(center, 0.5); + } else if (ese->type==EDITFACE) { + EditFace *efa= ese->data; + VecCopyf(center, efa->cent); + } +} + +void EM_editselection_normal(float *normal, EditSelection *ese) +{ + if (ese->type==EDITVERT) { + EditVert *eve= ese->data; + VecCopyf(normal, eve->no); + } else if (ese->type==EDITEDGE) { + EditEdge *eed= ese->data; + float plane[3]; /* need a plane to correct the normal */ + float vec[3]; /* temp vec storage */ + + VecAddf(normal, eed->v1->no, eed->v2->no); + VecSubf(plane, eed->v2->co, eed->v1->co); + + /* the 2 vertex normals will be close but not at rightangles to the edge + for rotate about edge we want them to be at right angles, so we need to + do some extra colculation to correct the vert normals, + we need the plane for this */ + Crossf(vec, normal, plane); + Crossf(normal, plane, vec); + Normalise(normal); + + } else if (ese->type==EDITFACE) { + EditFace *efa= ese->data; + VecCopyf(normal, efa->n); + } +} + +/* Calculate a plane that is rightangles to the edge/vert/faces normal +also make the plane run allong an axis that is related to the geometry, +because this is used for the manipulators Y axis.*/ +void EM_editselection_plane(float *plane, EditSelection *ese) +{ + if (ese->type==EDITVERT) { + EditVert *eve= ese->data; + float vec[3]={0,0,0}; + + if (ese->prev) { /*use previously selected data to make a usefull vertex plane */ + EM_editselection_center(vec, ese->prev); + VecSubf(plane, eve->co, vec); + } else { + /* make a fake plane thats at rightangles to the normal + we cant make a crossvec from a vec thats the same as the vec + unlikely but possible, so make sure if the normal is (0,0,1) + that vec isnt the same or in the same direction even.*/ + if (eve->no[0]<0.5) vec[0]=1; + else if (eve->no[1]<0.5) vec[1]=1; + else vec[2]=1; + Crossf(plane, eve->no, vec); + } + } else if (ese->type==EDITEDGE) { + EditEdge *eed= ese->data; + + /*the plane is simple, it runs allong the edge + however selecting different edges can swap the direction of the y axis. + this makes it less likely for the y axis of the manipulator + (running along the edge).. to flip less often. + at least its more pradictable */ + if (eed->v2->co[1] > eed->v1->co[1]) /*check which to do first */ + VecSubf(plane, eed->v2->co, eed->v1->co); + else + VecSubf(plane, eed->v1->co, eed->v2->co); + + } else if (ese->type==EDITFACE) { + EditFace *efa= ese->data; + float vec[3]; + if (efa->v4) { /*if its a quad- set the plane along the 2 longest edges.*/ + float vecA[3], vecB[3]; + VecSubf(vecA, efa->v4->co, efa->v3->co); + VecSubf(vecB, efa->v1->co, efa->v2->co); + VecAddf(plane, vecA, vecB); + + VecSubf(vecA, efa->v1->co, efa->v4->co); + VecSubf(vecB, efa->v2->co, efa->v3->co); + VecAddf(vec, vecA, vecB); + /*use the biggest edge length*/ + if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) + VecCopyf(plane, vec); + } else { + /*start with v1-2 */ + VecSubf(plane, efa->v1->co, efa->v2->co); + + /*test the edge between v2-3, use if longer */ + VecSubf(vec, efa->v2->co, efa->v3->co); + if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) + VecCopyf(plane, vec); + + /*test the edge between v1-3, use if longer */ + VecSubf(vec, efa->v3->co, efa->v1->co); + if (plane[0]*plane[0]+plane[1]*plane[1]+plane[2]*plane[2] < vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]) + VecCopyf(plane, vec); + } + } +} + + + void EM_select_face(EditFace *efa, int sel) { if(sel) { |