[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11936] branches/pyapi_devel/source/ blender/python: added a function to put a method struct into a dict ( to make adding methods to PyTypes easy)
Campbell Barton
cbarton at metavr.com
Tue Sep 4 07:22:42 CEST 2007
Revision: 11936
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11936
Author: campbellbarton
Date: 2007-09-04 07:22:42 +0200 (Tue, 04 Sep 2007)
Log Message:
-----------
added a function to put a method struct into a dict (to make adding methods to PyTypes easy)
moved Matrix constructorfunctions from Mathutils into bpy.types.Matrix.Scale/Rotation/Translation etc...
The changes in the python API are now up to date with meeting decissions (except for some that might not even be possible with python)
Modified Paths:
--------------
branches/pyapi_devel/source/blender/python/BPY_interface.c
branches/pyapi_devel/source/blender/python/api2_2x/Geometry.c
branches/pyapi_devel/source/blender/python/api2_2x/MTex.c
branches/pyapi_devel/source/blender/python/api2_2x/Mathutils.c
branches/pyapi_devel/source/blender/python/api2_2x/Mathutils.h
branches/pyapi_devel/source/blender/python/api2_2x/Mesh.c
branches/pyapi_devel/source/blender/python/api2_2x/gen_utils.c
branches/pyapi_devel/source/blender/python/api2_2x/gen_utils.h
branches/pyapi_devel/source/blender/python/api2_2x/matrix.c
branches/pyapi_devel/source/blender/python/api2_2x/matrix.h
branches/pyapi_devel/source/blender/python/api2_2x/meshPrimitive.c
branches/pyapi_devel/source/blender/python/api2_2x/meshPrimitive.h
branches/pyapi_devel/source/blender/python/api2_2x/sceneSequence.c
Modified: branches/pyapi_devel/source/blender/python/BPY_interface.c
===================================================================
--- branches/pyapi_devel/source/blender/python/BPY_interface.c 2007-09-04 04:59:13 UTC (rev 11935)
+++ branches/pyapi_devel/source/blender/python/BPY_interface.c 2007-09-04 05:22:42 UTC (rev 11936)
@@ -63,7 +63,7 @@
#include "api2_2x/EXPP_interface.h"
#include "api2_2x/gen_utils.h"
#include "api2_2x/gen_library.h" /* GetPyObjectFromID */
-#include "api2_2x/bpy_gl.h"
+#include "api2_2x/bpy_gl.h"
#include "api2_2x/bpy.h"
#include "api2_2x/bpy_state.h"
#include "api2_2x/Camera.h"
Modified: branches/pyapi_devel/source/blender/python/api2_2x/Geometry.c
===================================================================
--- branches/pyapi_devel/source/blender/python/api2_2x/Geometry.c 2007-09-04 04:59:13 UTC (rev 11935)
+++ branches/pyapi_devel/source/blender/python/api2_2x/Geometry.c 2007-09-04 05:22:42 UTC (rev 11936)
@@ -41,6 +41,7 @@
#include "BKE_displist.h"
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
+#include "BLI_arithb.h"
/* needed for EXPP_ReturnPyObjError and EXPP_check_sequence_consistency */
#include "gen_utils.h"
@@ -51,32 +52,6 @@
#define SWAP_FLOAT(a,b,tmp) tmp=a; a=b; b=tmp
#define eul 0.000001
-/*-- forward declarations -- */
-static PyObject *Geometry_PolyFill( PyObject * self, PyObject * args );
-static PyObject *Geometry_LineIntersect2D( PyObject * self, PyObject * args );
-static PyObject *Geometry_PointInTriangle2D( PyObject * self, PyObject * args );
-static PyObject *Geometry_BoxPack2D( PyObject * self, PyObject * args );
-
-/*-------------------------DOC STRINGS ---------------------------*/
-static char Geometry_doc[] = "The Blender Geometry module\n\n";
-static char Geometry_PolyFill_doc[] = "(veclist_list) - takes a list of polylines (each point a vector) and returns the point indicies for a polyline filled with triangles";
-static char Geometry_LineIntersect2D_doc[] = "(lineA_p1, lineA_p2, lineB_p1, lineB_p2) - takes 2 lines (as 4 vectors) and returns a vector for their point of intersection or None";
-static char Geometry_PointInTriangle2D_doc[] = "(pt, tri_p1, tri_p2, tri_p3) - takes 4 vectors, one is the point and the next 3 define the triabgle, only the x and y are used from the vectors";
-static char Geometry_BoxPack2D_doc[] = "";
-/*-----------------------METHOD DEFINITIONS ----------------------*/
-struct PyMethodDef Geometry_methods[] = {
- {"PolyFill", ( PyCFunction ) Geometry_PolyFill, METH_VARARGS, Geometry_PolyFill_doc},
- {"LineIntersect2D", ( PyCFunction ) Geometry_LineIntersect2D, METH_VARARGS, Geometry_LineIntersect2D_doc},
- {"PointInTriangle2D", ( PyCFunction ) Geometry_PointInTriangle2D, METH_VARARGS, Geometry_PointInTriangle2D_doc},
- {"BoxPack2D", ( PyCFunction ) Geometry_BoxPack2D, METH_VARARGS, Geometry_BoxPack2D_doc},
- {NULL, NULL, 0, NULL}
-};
-/*----------------------------MODULE INIT-------------------------*/
-PyObject *Geometry_Init(void)
-{
- return Py_InitModule3("bpy.geometry", Geometry_methods, Geometry_doc);
-}
-
/*----------------------------------Geometry.PolyFill() -------------------*/
/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */
static PyObject *Geometry_PolyFill( PyObject * self, PyObject * args )
@@ -179,6 +154,113 @@
}
+//----------------------------------Mathutils.LineIntersect() -------------------
+/* Line-Line intersection using algorithm from mathworld.wolfram.com */
+PyObject *Geometry_LineIntersect( PyObject * self, PyObject * args )
+{
+ PyObject * tuple;
+ BPyVectorObject *vec1, *vec2, *vec3, *vec4;
+ float v1[3], v2[3], v3[3], v4[3], i1[3], i2[3];
+
+ if( !PyArg_ParseTuple
+ ( args, "O!O!O!O!", &BPyVector_Type, &vec1, &BPyVector_Type, &vec2
+ , &BPyVector_Type, &vec3, &BPyVector_Type, &vec4 ) )
+ return ( EXPP_ReturnPyObjError
+ ( PyExc_TypeError, "expected 4 vector types\n" ) );
+ if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec2->size)
+ return ( EXPP_ReturnPyObjError( PyExc_TypeError,
+ "vectors must be of the same size\n" ) );
+
+ if( vec1->size == 3 || vec1->size == 2) {
+ float a[3], b[3], c[3], ab[3], cb[3], dir1[3], dir2[3];
+ float d;
+ if (vec1->size == 3) {
+ VECCOPY(v1, vec1->vec);
+ VECCOPY(v2, vec2->vec);
+ VECCOPY(v3, vec3->vec);
+ VECCOPY(v4, vec4->vec);
+ }
+ else {
+ v1[0] = vec1->vec[0];
+ v1[1] = vec1->vec[1];
+ v1[2] = 0.0f;
+
+ v2[0] = vec2->vec[0];
+ v2[1] = vec2->vec[1];
+ v2[2] = 0.0f;
+
+ v3[0] = vec3->vec[0];
+ v3[1] = vec3->vec[1];
+ v3[2] = 0.0f;
+
+ v4[0] = vec4->vec[0];
+ v4[1] = vec4->vec[1];
+ v4[2] = 0.0f;
+ }
+
+ VecSubf(c, v3, v1);
+ VecSubf(a, v2, v1);
+ VecSubf(b, v4, v3);
+
+ VECCOPY(dir1, a);
+ Normalize(dir1);
+ VECCOPY(dir2, b);
+ Normalize(dir2);
+ d = Inpf(dir1, dir2);
+ if (d == 1.0f || d == -1.0f) {
+ /* colinear */
+ return EXPP_incr_ret( Py_None );
+ }
+
+ Crossf(ab, a, b);
+ d = Inpf(c, ab);
+
+ /* test if the two lines are coplanar */
+ if (d > -0.000001f && d < 0.000001f) {
+ Crossf(cb, c, b);
+
+ VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
+ VecAddf(i1, v1, a);
+ VECCOPY(i2, i1);
+ }
+ /* if not */
+ else {
+ float n[3], t[3];
+ VecSubf(t, v1, v3);
+
+ /* offset between both plane where the lines lies */
+ Crossf(n, a, b);
+ Projf(t, t, n);
+
+ /* for the first line, offset the second line until it is coplanar */
+ VecAddf(v3, v3, t);
+ VecAddf(v4, v4, t);
+
+ VecSubf(c, v3, v1);
+ VecSubf(a, v2, v1);
+ VecSubf(b, v4, v3);
+
+ Crossf(ab, a, b);
+ Crossf(cb, c, b);
+
+ VecMulf(a, Inpf(cb, ab) / Inpf(ab, ab));
+ VecAddf(i1, v1, a);
+
+ /* for the second line, just substract the offset from the first intersection point */
+ VecSubf(i2, i1, t);
+ }
+
+ tuple = PyTuple_New( 2 );
+ PyTuple_SetItem( tuple, 0, Vector_CreatePyObject(i1, vec1->size, (PyObject *)NULL));
+ PyTuple_SetItem( tuple, 1, Vector_CreatePyObject(i2, vec1->size, (PyObject *)NULL));
+ return tuple;
+ }
+ else {
+ return ( EXPP_ReturnPyObjError( PyExc_TypeError,
+ "2D/3D vectors only\n" ) );
+ }
+}
+
static PyObject *Geometry_LineIntersect2D( PyObject * self, PyObject * args )
{
BPyVectorObject *line_a1, *line_a2, *line_b1, *line_b2;
@@ -385,3 +467,275 @@
return Py_BuildValue( "ff", tot_width, tot_height);
}
+
+//---------------------------------INTERSECTION FUNCTIONS--------------------
+//----------------------------------Mathutils.Intersect() -------------------
+PyObject *Geometry_Intersect( PyObject * self, PyObject * args )
+{
+ BPyVectorObject *ray, *ray_off, *vec1, *vec2, *vec3;
+ float dir[3], orig[3], v1[3], v2[3], v3[3], e1[3], e2[3], pvec[3], tvec[3], qvec[3];
+ float det, inv_det, u, v, t;
+ int clip = 1;
+
+ if( !PyArg_ParseTuple
+ ( args, "O!O!O!O!O!|i", &BPyVector_Type, &vec1, &BPyVector_Type, &vec2
+ , &BPyVector_Type, &vec3, &BPyVector_Type, &ray, &BPyVector_Type, &ray_off , &clip) )
+ return ( EXPP_ReturnPyObjError
+ ( PyExc_TypeError, "expected 5 vector types\n" ) );
+ if( vec1->size != 3 || vec2->size != 3 || vec3->size != 3 ||
+ ray->size != 3 || ray_off->size != 3)
+ return ( EXPP_ReturnPyObjError( PyExc_TypeError,
+ "only 3D vectors for all parameters\n" ) );
+
+ VECCOPY(v1, vec1->vec);
+ VECCOPY(v2, vec2->vec);
+ VECCOPY(v3, vec3->vec);
+
+ VECCOPY(dir, ray->vec);
+ Normalize(dir);
+
+ VECCOPY(orig, ray_off->vec);
+
+ /* find vectors for two edges sharing v1 */
+ VecSubf(e1, v2, v1);
+ VecSubf(e2, v3, v1);
+
+ /* begin calculating determinant - also used to calculated U parameter */
+ Crossf(pvec, dir, e2);
+
+ /* if determinant is near zero, ray lies in plane of triangle */
+ det = Inpf(e1, pvec);
+
+ if (det > -0.000001 && det < 0.000001) {
+ return EXPP_incr_ret( Py_None );
+ }
+
+ inv_det = 1.0f / det;
+
+ /* calculate distance from v1 to ray origin */
+ VecSubf(tvec, orig, v1);
+
+ /* calculate U parameter and test bounds */
+ u = Inpf(tvec, pvec) * inv_det;
+ if (clip && (u < 0.0f || u > 1.0f)) {
+ return EXPP_incr_ret( Py_None );
+ }
+
+ /* prepare to test the V parameter */
+ Crossf(qvec, tvec, e1);
+
+ /* calculate V parameter and test bounds */
+ v = Inpf(dir, qvec) * inv_det;
+
+ if (clip && (v < 0.0f || u + v > 1.0f)) {
+ return EXPP_incr_ret( Py_None );
+ }
+
+ /* calculate t, ray intersects triangle */
+ t = Inpf(e2, qvec) * inv_det;
+
+ VecMulf(dir, t);
+ VecAddf(pvec, orig, dir);
+
+ return Vector_CreatePyObject(pvec, 3, (PyObject *)NULL);
+}
+
+
+//---------------------------------NORMALS FUNCTIONS--------------------
+//----------------------------------Mathutils.QuadNormal() -------------------
+PyObject *Geometry_QuadNormal( PyObject * self, PyObject * args )
+{
+ BPyVectorObject *vec1;
+ BPyVectorObject *vec2;
+ BPyVectorObject *vec3;
+ BPyVectorObject *vec4;
+ float v1[3], v2[3], v3[3], v4[3], e1[3], e2[3], n1[3], n2[3];
+
+ if( !PyArg_ParseTuple
+ ( args, "O!O!O!O!", &BPyVector_Type, &vec1, &BPyVector_Type, &vec2
+ , &BPyVector_Type, &vec3, &BPyVector_Type, &vec4 ) )
+ return ( EXPP_ReturnPyObjError
+ ( PyExc_TypeError, "expected 4 vector types\n" ) );
+ if( vec1->size != vec2->size || vec1->size != vec3->size || vec1->size != vec4->size)
+ return ( EXPP_ReturnPyObjError( PyExc_TypeError,
+ "vectors must be of the same size\n" ) );
+ if( vec1->size != 3 )
+ return ( EXPP_ReturnPyObjError( PyExc_TypeError,
+ "only 3D vectors\n" ) );
+
+ VECCOPY(v1, vec1->vec);
+ VECCOPY(v2, vec2->vec);
+ VECCOPY(v3, vec3->vec);
+ VECCOPY(v4, vec4->vec);
+
+ /* find vectors for two edges sharing v2 */
+ VecSubf(e1, v1, v2);
+ VecSubf(e2, v3, v2);
+
+ Crossf(n1, e2, e1);
+ Normalize(n1);
+
+ /* find vectors for two edges sharing v4 */
+ VecSubf(e1, v3, v4);
+ VecSubf(e2, v1, v4);
+
+ Crossf(n2, e2, e1);
+ Normalize(n2);
+
+ /* adding and averaging the normals of both triangles */
+ VecAddf(n1, n2, n1);
+ Normalize(n1);
+
+ return Vector_CreatePyObject(n1, 3, (PyObject *)NULL);
+}
+
+//----------------------------Mathutils.TriangleNormal() -------------------
+PyObject *Geometry_TriangleNormal( PyObject * self, PyObject * args )
+{
+ BPyVectorObject *vec1, *vec2, *vec3;
+ float v1[3], v2[3], v3[3], e1[3], e2[3], n[3];
+
+ if( !PyArg_ParseTuple
+ ( args, "O!O!O!", &BPyVector_Type, &vec1, &BPyVector_Type, &vec2
+ , &BPyVector_Type, &vec3 ) )
+ return ( EXPP_ReturnPyObjError
+ ( PyExc_TypeError, "expected 3 vector types\n" ) );
+ if( vec1->size != vec2->size || vec1->size != vec3->size )
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list