Added some shortcuts to Mesh
authorCampbell Barton <ideasman42@gmail.com>
Thu, 11 May 2006 10:06:15 +0000 (10:06 +0000)
committerCampbell Barton <ideasman42@gmail.com>
Thu, 11 May 2006 10:06:15 +0000 (10:06 +0000)
 MFace.area
 MFace.cent
 MEdge.length

Updated some scripts that used these.

release/scripts/bpymodules/BPyMesh.py
release/scripts/vertexpaint_selfshadow_ao.py
release/scripts/weightpaint_grow_shrink.py
source/blender/python/api2_2x/Mesh.c
source/blender/python/api2_2x/doc/Mesh.py

index ec580c00125113b174298f1990b6082c6031aee3..d5e24781cbbb8c82dcca24e6b7016008c5f4cce2 100644 (file)
@@ -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):
index 7f1dea1c7613e5e80af3246bf7ffdd9a16382e5e..557e7cd3f29dc029be745c2617df9c4ab825aacb 100644 (file)
@@ -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
index bfe651bdea521f15c62eba55bb060acf33a3ddef..cfc31a2f7e6228cdb5de0bc32440cfc4249bfb62 100644 (file)
@@ -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
index 68676764b0ca928a24482c9cc268ae3af6bdd488..a952fc3587d069f587456c826142bca41827ee82 100644 (file)
@@ -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;j<i;j++) {
+               for (k=0;k<3;k++) {
+                       cent[k]+=vert[j][k];
+               }
+       }
+       
+       for (j=0;j<3;j++) {
+               cent[j]=cent[j]/i;
+       }
+       return newVectorObject( cent, 3, Py_NEW );
+}
+
+/*
+ * get face's area
+ */
+static PyObject *MFace_getArea( BPy_MFace * self )
+{
+       float *v1,*v2,*v3,*v4;
+       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" );
+
+       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,
index dbfca9eb90371a8ca1c7785c09a63bd4563658f5..cae7df6e6417c7730023adffdebe53e314269080 100644 (file)
@@ -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