From a3783d32e08be1c750d9fed07bd72404fe13dfeb Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 11 May 2006 10:06:15 +0000 Subject: [PATCH] Added some shortcuts to Mesh MFace.area MFace.cent MEdge.length Updated some scripts that used these. --- release/scripts/bpymodules/BPyMesh.py | 9 -- release/scripts/vertexpaint_selfshadow_ao.py | 6 +- release/scripts/weightpaint_grow_shrink.py | 2 +- source/blender/python/api2_2x/Mesh.c | 114 ++++++++++++++++++- source/blender/python/api2_2x/doc/Mesh.py | 25 +++- 5 files changed, 136 insertions(+), 20 deletions(-) diff --git a/release/scripts/bpymodules/BPyMesh.py b/release/scripts/bpymodules/BPyMesh.py index ec580c00125..d5e24781cbb 100644 --- a/release/scripts/bpymodules/BPyMesh.py +++ b/release/scripts/bpymodules/BPyMesh.py @@ -413,15 +413,6 @@ def pointInsideMesh(ob, pt): return len([None for f in me.faces if ptInFaceXYBounds(f, obSpacePt) if faceIntersect(f)]) % 2 -# Get face center -def faceCent(f): - cent= Blender.Mathutils.Vector() - l= len(f.v) - for v in f.v: - cent+=v.co - return cent*(1.0/l) - - # NMesh wrapper Vector= Blender.Mathutils.Vector class NMesh(object): diff --git a/release/scripts/vertexpaint_selfshadow_ao.py b/release/scripts/vertexpaint_selfshadow_ao.py index 7f1dea1c761..557e7cd3f29 100644 --- a/release/scripts/vertexpaint_selfshadow_ao.py +++ b/release/scripts/vertexpaint_selfshadow_ao.py @@ -57,22 +57,20 @@ def vertexFakeAO(me, PREF_BLUR_ITERATIONS, PREF_BLUR_SCALE, PREF_CLAMP_CONCAVE, ed_face_users = [ [] for i in xrange(len(me.edges)) ] - fcent= [BPyMesh.faceCent(f) for f in me.faces] + fcent= [f.cent for f in me.faces] min_tone=0 max_tone=0 for i, f in enumerate(me.faces): c= fcent[i] - fno = f.no*0.0001 + fno = f.no for v in f.v: - #vno=v.no*0.001 # get a scaled down normal. vno=v.no # get a scaled down normal. l1= (c-(v.co-vno)).length l2= (c-(v.co+vno)).length - #l2= ((c+fno) - (v.co+vno)).length vert_tone_count[v.index]+=1 if abs(l1-l2) < 0.0000001: pass diff --git a/release/scripts/weightpaint_grow_shrink.py b/release/scripts/weightpaint_grow_shrink.py index bfe651bdea5..cfc31a2f7e6 100644 --- a/release/scripts/weightpaint_grow_shrink.py +++ b/release/scripts/weightpaint_grow_shrink.py @@ -68,7 +68,7 @@ def actWeightNormalize(me, PREF_MODE, PREF_MAX_DIST, PREF_STRENGTH, PREF_ITERATI op= min for ed in me.edges: - if not PREF_MAX_DIST or (ed.v1.co-ed.v2.co).length < PREF_MAX_DIST: + if not PREF_MAX_DIST or ed.length < PREF_MAX_DIST: i1= ed.v1.index i2= ed.v2.index diff --git a/source/blender/python/api2_2x/Mesh.c b/source/blender/python/api2_2x/Mesh.c index 68676764b0c..a952fc3587d 100644 --- a/source/blender/python/api2_2x/Mesh.c +++ b/source/blender/python/api2_2x/Mesh.c @@ -2377,6 +2377,32 @@ static PyObject *MEdge_getMFlagBits( BPy_MEdge * self, void * type ) return EXPP_getBitfield( &edge->flag, (int)((long)type & 0xff), 'b' ); } +/* + * get an edge's select state + */ + +static PyObject *MEdge_getLength( BPy_MEdge * self, void * type ) +{ + MEdge *edge = MEdge_get_pointer( self ); + double dot = 0.0f; + float tmpf; + int i; + float *v1, *v2; + + /* get the 2 edges vert locations */ + v1= (&((Mesh *)self->mesh)->mvert[edge->v1])->co; + v2= (&((Mesh *)self->mesh)->mvert[edge->v2])->co; + + if( !edge ) + return NULL; + + for(i = 0; i < 3; i++){ + tmpf= v1[i] - v2[i]; + dot += tmpf*tmpf; + } + return PyFloat_FromDouble(sqrt(dot)); +} + /* * set an edge's select state */ @@ -2439,6 +2465,10 @@ static PyGetSetDef BPy_MEdge_getseters[] = { (getter)MEdge_getMFlagBits, (setter)MEdge_setSel, "edge selected in edit mode", (void *)SELECT}, + {"length", + (getter)MEdge_getLength, (setter)NULL, + "edge's length, read only", + NULL}, {NULL,NULL,NULL,NULL,NULL} /* Sentinel */ }; @@ -3608,15 +3638,85 @@ static PyObject *MFace_getNormal( BPy_MFace * self ) vert[0] = self->mesh->mvert[face->v1].co; vert[1] = self->mesh->mvert[face->v2].co; vert[2] = self->mesh->mvert[face->v3].co; - vert[3] = self->mesh->mvert[face->v4].co; - if( face->v4 ) + if( face->v4 ) { + vert[3] = self->mesh->mvert[face->v4].co; CalcNormFloat4( vert[0], vert[1], vert[2], vert[3], no ); - else + } else CalcNormFloat( vert[0], vert[1], vert[2], no ); return newVectorObject( no, 3, Py_NEW ); } +/* + * get face's center location + */ + +static PyObject *MFace_getCent( BPy_MFace * self ) +{ + float *vert[4]; + float cent[3]= {0,0,0}; + int i=3, j, k; + MFace *face = MFace_get_pointer( self ); + + if( !face ) + return NULL; + + if( (int)face->v1 >= self->mesh->totvert || + (int)face->v2 >= self->mesh->totvert || + (int)face->v3 >= self->mesh->totvert || + (int)face->v4 >= self->mesh->totvert ) + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "one or more MFace vertices are no longer valid" ); + + vert[0] = self->mesh->mvert[face->v1].co; + vert[1] = self->mesh->mvert[face->v2].co; + vert[2] = self->mesh->mvert[face->v3].co; + if( face->v4 ) { + vert[3] = self->mesh->mvert[face->v4].co; + i=4; + } + + for (j=0;jv1 >= self->mesh->totvert || + (int)face->v2 >= self->mesh->totvert || + (int)face->v3 >= self->mesh->totvert || + (int)face->v4 >= self->mesh->totvert ) + return EXPP_ReturnPyObjError( PyExc_RuntimeError, + "one or more MFace vertices are no longer valid" ); + + v1 = self->mesh->mvert[face->v1].co; + v2 = self->mesh->mvert[face->v2].co; + v3 = self->mesh->mvert[face->v3].co; + + if( face->v4 ) { + v4 = self->mesh->mvert[face->v4].co; + return PyFloat_FromDouble( AreaQ3Dfl(v1, v2, v3, v4)); + } else + return PyFloat_FromDouble( AreaT3Dfl(v1, v2, v3)); +} + /* * get one of a face's mface flag bits */ @@ -4189,6 +4289,14 @@ static PyGetSetDef BPy_MFace_getseters[] = { (getter)MFace_getNormal, (setter)NULL, "face's normal", NULL}, + {"cent", + (getter)MFace_getCent, (setter)NULL, + "face's center", + NULL}, + {"area", + (getter)MFace_getArea, (setter)NULL, + "face's 3D area", + NULL}, {"hide", (getter)MFace_getMFlagBits, (setter)MFace_setMFlagBits, diff --git a/source/blender/python/api2_2x/doc/Mesh.py b/source/blender/python/api2_2x/doc/Mesh.py index dbfca9eb903..cae7df6e641 100644 --- a/source/blender/python/api2_2x/doc/Mesh.py +++ b/source/blender/python/api2_2x/doc/Mesh.py @@ -169,9 +169,22 @@ class MVert: This object holds mesh vertex data. @ivar co: The vertex coordinates (x, y, z). @type co: vector (WRAPPED DATA) - @ivar no: The vertex's unit normal vector (x, y, z). Read-only. B{Note}: - if vertex coordinates are changed, it may be necessary to use + @ivar no: The vertex's unit normal vector (x, y, z). + B{Note}: if vertex coordinates are changed, it may be necessary to use L{Mesh.calcNormals()} to update the vertex normals. + B{Note}: Vertex normals can be set, but arnt wrapped so modifying a normal + vector will not effect the verts normal. The result is only visible + when faces have the smooth option enabled. + Example:: + # This wont work. + for v in me.verts: + v.no.x= 0 + v.no.y= 0 + v.no.z= 1 + # This will work + no= Blender.Mathutils.Vector(0,0,1) + for v in me.verts: + v.no= no @type no: vector @ivar uvco: (MVerts only). The vertex texture "sticky" coordinates (x, y), if present. @@ -322,6 +335,8 @@ class MEdge: @type v1: MVert @ivar v2: The second vertex of the edge. @type v2: MVert + @ivar length: The length of the edge, same as (ed.v1.co-ed.v2.co).length where "ed" is an MEdge. + @type length: float @ivar crease: The crease value of the edge. It is in the range [0,255]. @type crease: int @ivar flag: The bitfield describing edge properties. See L{EdgeFlags}. @@ -501,9 +516,13 @@ class MFace: Setting this attribute will create UV faces if they do not exist. Getting this attribute throw an exception if the mesh does not have UV faces; use L{Mesh.faceUV} to test. - @type uvSel: list of ints + @type uvSel: tuple of ints @ivar no: The face's normal vector (x, y, z). Read-only. @type no: vector + @ivar cent: The center of the face. Read-only. + @type cent: vector + @ivar area: The area of the face. Read-only. + @type area: float @note: there are regular faces and textured faces in Blender, both currently with their own selection and visibility states, due to a mix of old and new code. To (un)select or (un)hide regular faces (visible in EditMode), use