[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55788] trunk/blender/source/blender: py api, bmesh

Campbell Barton ideasman42 at gmail.com
Thu Apr 4 20:22:01 CEST 2013


Revision: 55788
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55788
Author:   campbellbarton
Date:     2013-04-04 18:22:01 +0000 (Thu, 04 Apr 2013)
Log Message:
-----------
py api, bmesh
- add BMEdge.calc_face_angle_signed() which gives a negative angle for for concave edges.
- add BMEdge.is_convex

Modified Paths:
--------------
    trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
    trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
    trunk/blender/source/blender/python/bmesh/bmesh_py_types.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.c	2013-04-04 17:01:51 UTC (rev 55787)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.c	2013-04-04 18:22:01 UTC (rev 55788)
@@ -776,6 +776,27 @@
 }
 
 /**
+ * Check if the edge is convex or concave
+ * (depends on face winding)
+ */
+bool BM_edge_is_convex(BMEdge *e)
+{
+	if (BM_edge_is_manifold(e)) {
+		BMLoop *l1 = e->l;
+		BMLoop *l2 = e->l->radial_next;
+		if (!equals_v3v3(l1->f->no, l2->f->no)) {
+			float cross[3];
+			float l_dir[3];
+			cross_v3_v3v3(cross, l1->f->no, l2->f->no);
+			/* we assume contiguous normals, otherwise the result isn't meaningful */
+			sub_v3_v3v3(l_dir, l1->next->v->co, l1->v->co);
+			return (dot_v3v3(l_dir, cross) > 0.0f);
+		}
+	}
+	return true;
+}
+
+/**
  * Tests whether or not an edge is on the boundary
  * of a shell (has one face associated with it)
  */
@@ -1153,6 +1174,27 @@
 }
 
 /**
+ * \brief BMESH EDGE/FACE ANGLE
+ *
+ *  Calculates the angle between two faces.
+ *  Assumes the face normals are correct.
+ *
+ * \return angle in radians
+ */
+float BM_edge_calc_face_angle_signed(BMEdge *e)
+{
+	if (BM_edge_is_manifold(e)) {
+		BMLoop *l1 = e->l;
+		BMLoop *l2 = e->l->radial_next;
+		const float angle = angle_normalized_v3v3(l1->f->no, l2->f->no);
+		return BM_edge_is_convex(e) ? angle : -angle;
+	}
+	else {
+		return DEG2RADF(90.0f);
+	}
+}
+
+/**
  * \brief BMESH EDGE/FACE TANGENT
  *
  * Calculate the tangent at this loop corner or fallback to the face normal on straight lines.

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_queries.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_queries.h	2013-04-04 17:01:51 UTC (rev 55787)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_queries.h	2013-04-04 18:22:01 UTC (rev 55788)
@@ -62,6 +62,7 @@
 bool    BM_edge_is_manifold(BMEdge *e);
 bool    BM_edge_is_boundary(BMEdge *e);
 bool    BM_edge_is_contiguous(BMEdge *e);
+bool    BM_edge_is_convex(BMEdge *e);
 
 bool    BM_loop_is_convex(BMLoop *l);
 
@@ -71,6 +72,7 @@
 void    BM_loop_calc_face_tangent(BMLoop *l, float r_tangent[3]);
 
 float   BM_edge_calc_face_angle(BMEdge *e);
+float   BM_edge_calc_face_angle_signed(BMEdge *e);
 void    BM_edge_calc_face_tangent(BMEdge *e, BMLoop *e_loop, float r_tangent[3]);
 
 float   BM_vert_calc_edge_angle(BMVert *v);

Modified: trunk/blender/source/blender/python/bmesh/bmesh_py_types.c
===================================================================
--- trunk/blender/source/blender/python/bmesh/bmesh_py_types.c	2013-04-04 17:01:51 UTC (rev 55787)
+++ trunk/blender/source/blender/python/bmesh/bmesh_py_types.c	2013-04-04 18:22:01 UTC (rev 55788)
@@ -423,6 +423,15 @@
 	return PyBool_FromLong(BM_edge_is_contiguous(self->e));
 }
 
+PyDoc_STRVAR(bpy_bmedge_is_convex_doc,
+"True when this edge joins 2 convex faces, depends on a valid face normal (read-only).\n\n:type: boolean"
+);
+static PyObject *bpy_bmedge_is_convex_get(BPy_BMEdge *self)
+{
+	BPY_BM_CHECK_OBJ(self);
+	return PyBool_FromLong(BM_edge_is_convex(self->e));
+}
+
 PyDoc_STRVAR(bpy_bmedge_is_wire_doc,
 "True when this edge is not connected to any faces (read-only).\n\n:type: boolean"
 );
@@ -569,10 +578,10 @@
 	return BPy_BMLoop_CreatePyObject(self->bm, self->l->radial_prev);
 }
 
-PyDoc_STRVAR(bpy_bm_is_convex_doc,
-"True when this loop is at the convex corner of a face, depends on a valid face normal (read-only).\n\n:type: :class:`BMLoop`"
+PyDoc_STRVAR(bpy_bmloop_is_convex_doc,
+"True when this loop is at the convex corner of a face, depends on a valid face normal (read-only).\n\n:type: boolean"
 );
-static PyObject *bpy_bm_is_convex_get(BPy_BMLoop *self)
+static PyObject *bpy_bmloop_is_convex_get(BPy_BMLoop *self)
 {
 	BPY_BM_CHECK_OBJ(self);
 	return PyBool_FromLong(BM_loop_is_convex(self->l));
@@ -690,6 +699,7 @@
 	/* readonly checks */
 	{(char *)"is_manifold",   (getter)bpy_bmedge_is_manifold_get,   (setter)NULL, (char *)bpy_bmedge_is_manifold_doc, NULL},
 	{(char *)"is_contiguous", (getter)bpy_bmedge_is_contiguous_get, (setter)NULL, (char *)bpy_bmedge_is_contiguous_doc, NULL},
+	{(char *)"is_convex",     (getter)bpy_bmedge_is_convex_get,     (setter)NULL, (char *)bpy_bmedge_is_convex_doc, NULL},
 	{(char *)"is_wire",       (getter)bpy_bmedge_is_wire_get,       (setter)NULL, (char *)bpy_bmedge_is_wire_doc, NULL},
 	{(char *)"is_boundary",   (getter)bpy_bmedge_is_boundary_get,   (setter)NULL, (char *)bpy_bmedge_is_boundary_doc, NULL},
 	{(char *)"is_valid",      (getter)bpy_bm_is_valid_get,          (setter)NULL, (char *)bpy_bm_is_valid_doc, NULL},
@@ -741,8 +751,8 @@
 	{(char *)"link_loop_radial_prev", (getter)bpy_bmloop_link_loop_radial_prev_get, (setter)NULL, (char *)bpy_bmloop_link_loop_radial_prev_doc, NULL},
 
 	/* readonly checks */
-	{(char *)"is_convex",  (getter)bpy_bm_is_convex_get, (setter)NULL, (char *)bpy_bm_is_convex_doc, NULL},
-	{(char *)"is_valid",   (getter)bpy_bm_is_valid_get,  (setter)NULL, (char *)bpy_bm_is_valid_doc,  NULL},
+	{(char *)"is_convex",  (getter)bpy_bmloop_is_convex_get, (setter)NULL, (char *)bpy_bmloop_is_convex_doc, NULL},
+	{(char *)"is_valid",   (getter)bpy_bm_is_valid_get,      (setter)NULL, (char *)bpy_bm_is_valid_doc,  NULL},
 
 	{NULL, NULL, NULL, NULL, NULL} /* Sentinel */
 };
@@ -1398,6 +1408,18 @@
 	return PyFloat_FromDouble(BM_edge_calc_face_angle(self->e));
 }
 
+PyDoc_STRVAR(bpy_bmedge_calc_face_angle_signed_doc,
+".. method:: calc_face_angle_signed()\n"
+"\n"
+"   :return: The angle between 2 connected faces in radians (negative for concave join).\n"
+"   :rtype: float\n"
+);
+static PyObject *bpy_bmedge_calc_face_angle_signed(BPy_BMEdge *self)
+{
+	BPY_BM_CHECK_OBJ(self);
+	return PyFloat_FromDouble(BM_edge_calc_face_angle_signed(self->e));
+}
+
 PyDoc_STRVAR(bpy_bmedge_calc_tangent_doc,
 ".. method:: calc_tangent(loop)\n"
 "\n"
@@ -2440,6 +2462,7 @@
 
 	{"calc_length",     (PyCFunction)bpy_bmedge_calc_length,     METH_NOARGS,  bpy_bmedge_calc_length_doc},
 	{"calc_face_angle", (PyCFunction)bpy_bmedge_calc_face_angle, METH_NOARGS,  bpy_bmedge_calc_face_angle_doc},
+	{"calc_face_angle_signed", (PyCFunction)bpy_bmedge_calc_face_angle_signed, METH_NOARGS,  bpy_bmedge_calc_face_angle_signed_doc},
 	{"calc_tangent",    (PyCFunction)bpy_bmedge_calc_tangent,    METH_VARARGS, bpy_bmedge_calc_tangent_doc},
 
 	{"normal_update",  (PyCFunction)bpy_bmedge_normal_update,  METH_NOARGS,  bpy_bmedge_normal_update_doc},




More information about the Bf-blender-cvs mailing list