2006-07-02 15:25:37 +00:00
/*
* $ Id $
*
* * * * * * BEGIN GPL / BL DUAL LICENSE BLOCK * * * * *
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation ; either version 2
* of the License , or ( at your option ) any later version . The Blender
* Foundation also sells licenses for use in proprietary software under
* the Blender License . See http : //www.blender.org/BL/ for information
* about this .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*
* The Original Code is Copyright ( C ) 2001 - 2002 by NaN Holding BV .
* All rights reserved .
*
* This is a new part of Blender .
*
* Contributor ( s ) : Joseph Gilbert , Campbell Barton
*
* * * * * * END GPL / BL DUAL LICENSE BLOCK * * * * *
*/
# include "Geometry.h"
/* - Not needed for now though other geometry functions will probably need them
# include "BLI_arithb.h"
# include "BKE_utildefines.h"
*/
/* Used for PolyFill */
2006-07-02 18:59:40 +00:00
# include "BKE_displist.h"
2006-07-02 15:25:37 +00:00
# include "MEM_guardedalloc.h"
# include "BLI_blenlib.h"
2006-07-02 18:59:40 +00:00
/* needed for EXPP_ReturnPyObjError and EXPP_check_sequence_consistency */
2006-07-02 15:25:37 +00:00
# include "gen_utils.h"
2006-07-02 23:09:37 +00:00
/*-------------------------DOC STRINGS ---------------------------*/
2006-07-02 15:25:37 +00:00
static char M_Geometry_doc [ ] = " The Blender Geometry module \n \n " ;
static char M_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 " ;
2006-07-02 23:09:37 +00:00
/*-----------------------METHOD DEFINITIONS ----------------------*/
2006-07-02 15:25:37 +00:00
struct PyMethodDef M_Geometry_methods [ ] = {
{ " PolyFill " , ( PyCFunction ) M_Geometry_PolyFill , METH_VARARGS , M_Geometry_PolyFill_doc } ,
{ NULL , NULL , 0 , NULL }
} ;
2006-07-02 23:09:37 +00:00
/*----------------------------MODULE INIT-------------------------*/
2006-07-02 15:25:37 +00:00
PyObject * Geometry_Init ( void )
{
PyObject * submodule ;
submodule = Py_InitModule3 ( " Blender.Geometry " ,
M_Geometry_methods , M_Geometry_doc ) ;
return ( submodule ) ;
}
2006-07-02 23:09:37 +00:00
/*----------------------------------Geometry.PolyFill() -------------------*/
2006-07-02 15:25:37 +00:00
/* PolyFill function, uses Blenders scanfill to fill multiple poly lines */
PyObject * M_Geometry_PolyFill ( PyObject * self , PyObject * args )
{
PyObject * tri_list ; /*return this list of tri's */
2006-07-02 23:09:37 +00:00
PyObject * polyLineSeq , * polyLine , * polyVec ;
2006-07-02 15:25:37 +00:00
int i , len_polylines , len_polypoints ;
/* display listbase */
ListBase dispbase = { NULL , NULL } ;
DispList * dl ;
float * fp ; /*pointer to the array of malloced dl->verts to set the points from the vectors */
int index , * dl_face , totpoints = 0 ;
dispbase . first = dispbase . last = NULL ;
2006-07-02 23:09:37 +00:00
if ( ! PyArg_ParseTuple ( args , " O " , & polyLineSeq ) | | ! PySequence_Check ( polyLineSeq ) ) {
2006-07-02 15:25:37 +00:00
return EXPP_ReturnPyObjError ( PyExc_TypeError ,
2006-07-02 23:09:37 +00:00
" expected a sequence of poly lines " ) ;
2006-07-02 15:25:37 +00:00
}
2006-07-02 23:09:37 +00:00
len_polylines = PySequence_Size ( polyLineSeq ) ;
2006-07-02 15:25:37 +00:00
for ( i = 0 ; i < len_polylines ; + + i ) {
2006-07-02 23:09:37 +00:00
polyLine = PySequence_GetItem ( polyLineSeq , i ) ;
if ( ! PySequence_Check ( polyLineSeq ) ) {
freedisplist ( & dispbase ) ;
Py_DECREF ( polyLine ) ;
return EXPP_ReturnPyObjError ( PyExc_TypeError ,
" expected a sequence of poly lines " ) ;
}
2006-07-02 15:25:37 +00:00
len_polypoints = PySequence_Size ( polyLine ) ;
2006-07-02 23:09:37 +00:00
if ( len_polypoints > 0 ) { /* dont bother adding edges as polylines */
if ( EXPP_check_sequence_consistency ( polyLine , & vector_Type ) ! = 1 ) {
freedisplist ( & dispbase ) ;
Py_DECREF ( polyLine ) ;
2006-07-02 15:25:37 +00:00
return EXPP_ReturnPyObjError ( PyExc_TypeError ,
2006-07-02 23:09:37 +00:00
" expected a sequence of poly lines " ) ;
}
2006-07-02 15:25:37 +00:00
dl = MEM_callocN ( sizeof ( DispList ) , " poly disp " ) ;
BLI_addtail ( & dispbase , dl ) ;
dl - > type = DL_INDEX3 ;
dl - > nr = len_polypoints ;
dl - > type = DL_POLY ;
dl - > parts = 1 ; /* no faces, 1 edge loop */
dl - > col = 0 ; /* no material */
dl - > verts = fp = MEM_callocN ( sizeof ( float ) * 3 * len_polypoints , " dl verts " ) ;
dl - > index = MEM_callocN ( sizeof ( int ) * 3 * len_polypoints , " dl index " ) ;
for ( index = 0 ; index < len_polypoints ; + + index , fp + = 3 ) {
polyVec = PySequence_GetItem ( polyLine , index ) ;
fp [ 0 ] = ( ( VectorObject * ) polyVec ) - > vec [ 0 ] ;
fp [ 1 ] = ( ( VectorObject * ) polyVec ) - > vec [ 1 ] ;
if ( ( ( VectorObject * ) polyVec ) - > size > 2 )
fp [ 2 ] = ( ( VectorObject * ) polyVec ) - > vec [ 2 ] ;
else
fp [ 2 ] = 0.0f ; /* if its a 2d vector then set the z to be zero */
totpoints + + ;
Py_DECREF ( polyVec ) ;
}
}
Py_DECREF ( polyLine ) ;
}
if ( totpoints ) {
/* now make the list to return */
filldisplist ( & dispbase , & dispbase ) ;
/* The faces are stored in a new DisplayList
thats added to the head of the listbase */
dl = dispbase . first ;
tri_list = PyList_New ( dl - > parts ) ;
2006-07-02 23:09:37 +00:00
if ( ! tri_list ) {
freedisplist ( & dispbase ) ;
return EXPP_ReturnPyObjError ( PyExc_RuntimeError ,
" PyList_New() failed " ) ;
}
2006-07-02 15:25:37 +00:00
2006-07-02 23:09:37 +00:00
index = 0 ;
2006-07-02 15:25:37 +00:00
dl_face = dl - > index ;
while ( index < dl - > parts ) {
PyList_SetItem ( tri_list , index , Py_BuildValue ( " iii " , dl_face [ 0 ] , dl_face [ 1 ] , dl_face [ 2 ] ) ) ;
dl_face + = 3 ;
index + + ;
}
freedisplist ( & dispbase ) ;
} else {
/* no points, do this so scripts dont barf */
tri_list = PyList_New ( 0 ) ;
}
return tri_list ;
}