This repository has been archived on 2023-10-09. You can view files and clone it, but cannot push or open issues or pull requests.
Files
blender-archive/source/blender/python/api2_2x/NMesh.c

4202 lines
112 KiB
C
Raw Normal View History

/*
* $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, but it borrows all the old NMesh code.
*
* Contributor(s): Willian P. Germano, Jordi Rovira i Bonet, Joseph Gilbert,
* Bala Gi, Alexander Szakaly, Stephane Soppera, Campbell Barton, Ken Hughes,
* Daniel Dunbar.
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
#include "NMesh.h" /*This must come first*/
#include "MEM_guardedalloc.h"
#include "DNA_key_types.h"
#include "DNA_armature_types.h"
#include "DNA_scene_types.h"
#include "DNA_oops_types.h"
#include "DNA_space_types.h"
2005-08-01 06:01:24 +00:00
#include "DNA_curve_types.h"
#include "BDR_editface.h" /* make_tfaces */
#include "BDR_vpaint.h"
#include "BDR_editobject.h"
#include "BIF_editdeform.h"
#include "BIF_editkey.h" /* insert_meshkey */
#include "BIF_editview.h"
#include "BIF_space.h"
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
#include "BKE_customdata.h"
#include "BKE_deform.h"
#include "BKE_mesh.h"
#include "BKE_material.h"
#include "BKE_main.h"
#include "BKE_global.h"
#include "BKE_library.h"
#include "BKE_DerivedMesh.h"
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
#include "BKE_displist.h"
#include "BKE_object.h"
2005-08-01 06:01:24 +00:00
#include "BKE_mball.h"
Mathutils update - also included is some fixes for preprocessor inclues and some clean up of the previous commit -rewrite and bugfixes ---------------------------------- Here's my changelog: -fixed Rand() so that it doesn't seed everytime and should generate better random numbers - changed a few error return types to something more appropriate - clean up of uninitialized variables & removal of unneccessary objects - NMesh returns wrapped vectors now - World returns wrapped matrices now - Object.getEuler() and Object.getBoundingBox() return Wrapped data when data is present - Object.getMatrix() returns wrapped data if it's worldspace, 'localspace' returns a new matrix - Vector, Euler, Mat, Quat, call all now internally wrap object without destroying internal datablocks - Removed memory allocation (unneeded) from all methods - Vector's resize methods are only applicable to new vectors not wrapped data. - Matrix(), Quat(), Euler(), Vector() now accepts ANY sequence list, including tuples, list, or a self object to copy - matrices accept multiple sequences - Fixed Slerp() so that it now works correctly values are clamped between 0 and 1 - Euler.rotate does internal rotation now - Slice assignment now works better for all types - Vector * Vector and Quat * Quat are defined and return the DOT product - Mat * Vec and Vec * Mat are defined now - Moved #includes to .c file from headers. Also fixed prototypes in mathutils - Added new helper functions for incref'ing to genutils - Major cleanup of header files includes - include Mathutils.h for access to math types - matrix.toQuat() and .toEuler() now fixed take appropriate matrix sizes - Matrix() with no parameters now returns an identity matrix by default not a zero matrix - printf() now prints with 6 digits instead of 4 - printf() now prints output with object descriptor - Matrices now support [x][y] assignment (e.g. matrix[x][y] = 5.4) - Matrix[index] = value now expectes a sequence not an integer. This will now set a ROW of the matrix through a sequence. index cannot go above the row size of the matrix. - slice operations on matrices work with sequences now (rows of the matrix) example: mymatrix[0:2] returns a list of 2 wrapped vectors with access to the matrix data. - slice assignment will no longer modify the data if the assignment operation fails - fixed error in matrix * scalar multiplication - euler.toMatrix(), toQuat() no longer causes "creep" from repeated use - Wrapped data will generate wrapped objects when toEuler(), toQuat(), toMatrix() is used - Quats can be created with angle/axis, axis/angle - 4x4 matrices can be multiplied by 3D vectors (by popular demand :)) - vec *quat / quat * vec is now defined - vec.magnitude alias for vec.length - all self, internal methods return a pointer to self now so you can do print vector.internalmethod() or vector.internalmethod().nextmethod() (no more print matrix.inverse() returning 'none') - these methods have been deprecated (still functioning but suggested to use the corrected functionality): * CopyVec() - replaced by Vector() functionality * CopyMat() - replaced by Matrix() functionality * CopyQuat() - replace by Quaternion() functionality * CopyEuler() - replaced by Euler() functionality * RotateEuler() - replaced by Euler.rotate() funtionality * MatMultVec() - replaced by matrix * vector * VecMultMat() - replaced by vector * matrix - New struct containers references to python object data or internally allocated blender data for wrapping * Explaination here: math structs now function as a 'simple wrapper' or a 'py_object' - data that is created on the fly will now be a 'py_object' with its memory managed by python * otherwise if the data is returned by blender's G.main then the math object is a 'simple wrapper' and data can be accessed directly from the struct just like other python objects.
2005-07-14 03:34:56 +00:00
#include "BKE_utildefines.h"
2005-08-01 06:01:24 +00:00
#include "BKE_depsgraph.h"
#include "BKE_idprop.h"
#include "BLI_arithb.h"
#include "BLI_blenlib.h"
2005-08-01 06:01:24 +00:00
#include "blendef.h"
#include "mydevice.h"
#include "Object.h"
#include "Key.h"
Mathutils update - also included is some fixes for preprocessor inclues and some clean up of the previous commit -rewrite and bugfixes ---------------------------------- Here's my changelog: -fixed Rand() so that it doesn't seed everytime and should generate better random numbers - changed a few error return types to something more appropriate - clean up of uninitialized variables & removal of unneccessary objects - NMesh returns wrapped vectors now - World returns wrapped matrices now - Object.getEuler() and Object.getBoundingBox() return Wrapped data when data is present - Object.getMatrix() returns wrapped data if it's worldspace, 'localspace' returns a new matrix - Vector, Euler, Mat, Quat, call all now internally wrap object without destroying internal datablocks - Removed memory allocation (unneeded) from all methods - Vector's resize methods are only applicable to new vectors not wrapped data. - Matrix(), Quat(), Euler(), Vector() now accepts ANY sequence list, including tuples, list, or a self object to copy - matrices accept multiple sequences - Fixed Slerp() so that it now works correctly values are clamped between 0 and 1 - Euler.rotate does internal rotation now - Slice assignment now works better for all types - Vector * Vector and Quat * Quat are defined and return the DOT product - Mat * Vec and Vec * Mat are defined now - Moved #includes to .c file from headers. Also fixed prototypes in mathutils - Added new helper functions for incref'ing to genutils - Major cleanup of header files includes - include Mathutils.h for access to math types - matrix.toQuat() and .toEuler() now fixed take appropriate matrix sizes - Matrix() with no parameters now returns an identity matrix by default not a zero matrix - printf() now prints with 6 digits instead of 4 - printf() now prints output with object descriptor - Matrices now support [x][y] assignment (e.g. matrix[x][y] = 5.4) - Matrix[index] = value now expectes a sequence not an integer. This will now set a ROW of the matrix through a sequence. index cannot go above the row size of the matrix. - slice operations on matrices work with sequences now (rows of the matrix) example: mymatrix[0:2] returns a list of 2 wrapped vectors with access to the matrix data. - slice assignment will no longer modify the data if the assignment operation fails - fixed error in matrix * scalar multiplication - euler.toMatrix(), toQuat() no longer causes "creep" from repeated use - Wrapped data will generate wrapped objects when toEuler(), toQuat(), toMatrix() is used - Quats can be created with angle/axis, axis/angle - 4x4 matrices can be multiplied by 3D vectors (by popular demand :)) - vec *quat / quat * vec is now defined - vec.magnitude alias for vec.length - all self, internal methods return a pointer to self now so you can do print vector.internalmethod() or vector.internalmethod().nextmethod() (no more print matrix.inverse() returning 'none') - these methods have been deprecated (still functioning but suggested to use the corrected functionality): * CopyVec() - replaced by Vector() functionality * CopyMat() - replaced by Matrix() functionality * CopyQuat() - replace by Quaternion() functionality * CopyEuler() - replaced by Euler() functionality * RotateEuler() - replaced by Euler.rotate() funtionality * MatMultVec() - replaced by matrix * vector * VecMultMat() - replaced by vector * matrix - New struct containers references to python object data or internally allocated blender data for wrapping * Explaination here: math structs now function as a 'simple wrapper' or a 'py_object' - data that is created on the fly will now be a 'py_object' with its memory managed by python * otherwise if the data is returned by blender's G.main then the math object is a 'simple wrapper' and data can be accessed directly from the struct just like other python objects.
2005-07-14 03:34:56 +00:00
#include "Mathutils.h"
#include "IDProp.h"
#include "constant.h"
#include "gen_utils.h"
extern void countall(void);
/* EXPP Mesh defines */
#define NMESH_FRAME_MAX 30000
#define NMESH_SMOOTHRESH 30
#define NMESH_SMOOTHRESH_MIN 1
#define NMESH_SMOOTHRESH_MAX 80
#define NMESH_SUBDIV 1
#define NMESH_SUBDIV_MIN 0
#define NMESH_SUBDIV_MAX 6
/* Globals */
static PyObject *g_nmeshmodule = NULL;
static int unlink_existingMeshData( Mesh * mesh );
static int convert_NMeshToMesh( Mesh *mesh, BPy_NMesh *nmesh );
static void check_dverts(Mesh *me, int old_totverts);
static PyObject *NMesh_printDebug( PyObject * self );
static PyObject *NMesh_addEdge( PyObject * self, PyObject * args );
static PyObject *NMesh_findEdge( PyObject * self, PyObject * args );
static PyObject *NMesh_removeEdge( PyObject * self, PyObject * args );
static PyObject *NMesh_addFace( PyObject * self, PyObject * args );
static PyObject *NMesh_removeFace( PyObject * self, PyObject * args );
static PyObject *NMesh_addVertGroup( PyObject * self, PyObject * args );
static PyObject *NMesh_removeVertGroup( PyObject * self, PyObject * args );
static PyObject *NMesh_assignVertsToGroup( PyObject * self, PyObject * args );
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
static PyObject *NMesh_removeVertsFromGroup( PyObject * self,PyObject * args );
static PyObject *NMesh_getVertsFromGroup( PyObject * self, PyObject * args );
static PyObject *NMesh_renameVertGroup( PyObject * self, PyObject * args );
static PyObject *NMesh_getVertGroupNames( PyObject * self );
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
static PyObject *NMesh_transform (PyObject *self, PyObject *args);
static char NMesh_printDebug_doc[] =
"print debug info about the mesh.";
static char NMesh_getKey_doc[] =
"get the Key object linked to this mesh";
static char NMesh_addEdge_doc[] =
"create an edge between two vertices.\n\
If an edge already exists between those vertices, it is returned.\n\
(In Blender, only zero or one edge can link two vertices.)\n\
Created edge is automatically added to edges list.";
static char NMesh_findEdge_doc[] =
"find an edge between two vertices.";
static char NMesh_removeEdge_doc[] =
"remove an edge between two vertices.\n\
All faces using this edge are removed from faces list.";
static char NMesh_addFace_doc[] =
"add a face to face list and add to edge list (if edge data exists) necessary edges.";
static char NMesh_removeFace_doc[] =
"remove a face for face list and remove edges no more used by any other face (if \
edge data exists).";
static char NMesh_addVertGroup_doc[] =
"add a named and empty vertex(deform) Group to a mesh that has been linked\n\
to an object. ";
static char NMesh_removeVertGroup_doc[] =
"remove a named vertex(deform) Group from a mesh that has been linked\n\
to an object. Will remove all verts assigned to group.";
static char NMesh_assignVertsToGroup_doc[] =
"Adds an array (a python list) of vertex points (by index) to a named\n\
vertex group. The list will have an associated wieght assigned to them.\n\
The weight represents the amount of influence this group has over these\n\
vertex points. Weights should be in the range of 0.0 - 1.0.\n\
The assignmode can be either 'add', 'subtract', or 'replace'. If this vertex\n\
is not assigned to the group 'add' creates a new association with the weight\n\
specified, otherwise the weight given is added to the current weight of the\n\
vertex.\n\
'subtract' will attempt to subtract the weight passed from a vertex already\n\
associated with a group, else it does nothing. 'replace' attempts to replace\n\
the weight with the new weight value for an already associated vertex/group,\n\
else it does nothing. The mesh must have all it's vertex points set before\n\
attempting to assign any vertex points to a vertex group.";
static char NMesh_removeVertsFromGroup_doc[] =
"Remove an array (a python list) of vertex points from a named group in a\n\
mesh that has been linked to an object. If no list is given this will remove\n\
all vertex point associations with the group passed";
static char NMesh_getVertsFromGroup_doc[] =
"By passing a python list of vertex indices and a named group, this will\n\
return a python list representing the indeces that are a part of this vertex.\n\
group. If no association was found for the index passed nothing will be\n\
return for the index. An optional flag will also return the weights as well";
static char NMesh_renameVertGroup_doc[] = "Renames a vertex group";
static char NMesh_getVertGroupNames_doc[] =
"Returns a list of all the vertex group names";
static char M_NMesh_doc[] = "The Blender.NMesh submodule";
static char M_NMesh_Col_doc[] = "([r, g, b, a]) - Get a new mesh color\n\n\
[r=255, g=255, b=255, a=255] Specify the color components";
static char M_NMesh_Face_doc[] =
"(vertexlist = None) - Get a new face, and pass optional vertex list";
static char NMFace_append_doc[] =
"(vert) - appends Vertex 'vert' to face vertex list";
static char M_NMesh_Vert_doc[] = "([x, y, z]) - Get a new vertex\n\n\
[x, y, z] Specify new coordinates";
static char NMesh_getMaterials_doc[] =
"(i = -1) - Get this mesh's list of materials.\n\
(i = -1) - int: determines the list's contents:\n\
-1: return the current list, possibly modified by the script (default);\n\
0: get a fresh list from the Blender mesh -- modifications not included,\n\
unless the script called mesh.update() first;\n\
1: like 0, but does not ignore empty slots, returns them as 'None'.";
static char NMesh_setMaterials_doc[] =
"(matlist) - Set this mesh's list of materials. This method makes sure\n\
the passed matlist is valid (can only include up to 16 materials and None's).";
static char NMesh_addMaterial_doc[] =
"(material) - add a new Blender Material 'material' to this Mesh's materials\n\
list.";
static char NMesh_insertKey_doc[] =
"(frame = None, type = 'relative') - inserts a Mesh key at the given frame\n\
if called without arguments, it inserts the key at the current Scene frame.\n\
(type) - 'relative' or 'absolute'. Only relevant on the first call to this\n\
function for each nmesh.";
static char NMesh_removeAllKeys_doc[] =
"() - removes all keys from this mesh\n\
returns True if successful or False if this NMesh wasn't linked to a real\n\
Blender Mesh yet or the Mesh had no keys";
static char NMesh_getSelectedFaces_doc[] =
"(flag = None) - returns list of selected Faces\n\
If flag = 1, return indices instead";
static char NMesh_getActiveFace_doc[] =
"returns the index of the active face ";
static char NMesh_hasVertexUV_doc[] =
"(flag = None) - returns 1 if Mesh has per vertex UVs ('Sticky')\n\
The optional argument sets the Sticky flag";
static char NMesh_hasFaceUV_doc[] =
"(flag = None) - returns 1 if Mesh has textured faces\n\
The optional argument sets the textured faces flag";
static char NMesh_hasVertexColours_doc[] =
"(flag = None) - returns 1 if Mesh has vertex colours.\n\
The optional argument sets the vertex colour flag";
static char NMesh_getVertexInfluences_doc[] =
"Return a list of the influences of bones in the vertex \n\
specified by index. The list contains pairs with the \n\
bone name and the weight.";
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
static char NMesh_update_doc[] =
"(recalc_normals = 0, store_edges = 0, vertex_shade = 0) - Updates the Mesh.\n\
Optional arguments: if given and nonzero:\n\
'recalc_normals': normal vectors are recalculated;\n\
'store_edges': edges data is stored.\n\
'vertex_shade': vertex colors are added based on the current lamp setup.";
static char NMesh_getMode_doc[] =
"() - get the mode flags of this nmesh as an or'ed int value.";
static char NMesh_setMode_doc[] =
"(int or none to 5 strings) - set the mode flags of this nmesh.\n\
() - unset all flags.";
static char NMesh_getMaxSmoothAngle_doc[] =
"() - get the max smooth angle for mesh auto smoothing.";
static char NMesh_setMaxSmoothAngle_doc[] =
"(int) - set the max smooth angle for mesh auto smoothing in the range\n\
[1,80] in degrees.";
static char NMesh_getSubDivLevels_doc[] =
"() - get the subdivision levels for display and rendering: [display, render]";
static char NMesh_setSubDivLevels_doc[] =
"([int, int]) - set the subdivision levels for [display, render] -- they are\n\
clamped to the range [0,6].";
static char M_NMesh_New_doc[] =
"() - returns a new, empty NMesh mesh object\n";
static char M_NMesh_GetRaw_doc[] = "([name]) - Get a raw mesh from Blender\n\n\
[name] Name of the mesh to be returned\n\n\
If name is not specified a new empty mesh is\n\
returned, otherwise Blender returns an existing\n\
mesh.";
BPython: bug fixes / patches from trackers (excuse me for not committing earlier) Patches by Ken Hughes (thanks for all bug fixes!): 1) Setting a scene's MapOld and MapNew values in python does nothing: bug #2566 submitted by Dominic Agoro-Ombaka (dmao): https://projects.blender.org/tracker/?func=detail&aid=2566&group_id=9&atid=125 patch #2571: https://projects.blender.org/tracker/index.php?func=detail&aid=2571&group_id=9&atid=127 2) Calling the file selector after setting the progress bar crashes Blender: bug #2418 submitted by Alessandro Garosi (brandano): https://projects.blender.org/tracker/?func=detail&aid=2418&group_id=9&atid=125 patch #2568: https://projects.blender.org/tracker/index.php?func=detail&aid=2568&group_id=9&atid=127 3) Menus always generate same event when canceled: bug #2429 submitted by Campbell Barton: https://projects.blender.org/tracker/?func=detail&aid=2429&group_id=9&atid=125 patch #2579: https://projects.blender.org/tracker/?func=detail&aid=2579&group_id=9&atid=127 4) Add a vertex to a mesh with groups using a script and then edit that mesh hangs blender: bug #2211 reported by German Alonso Tamayo (servivo): https://projects.blender.org/tracker/index.php?func=detail&aid=2211&group_id=9&atid=125 patch #2580 #https://projects.blender.org/tracker/index.php?func=detail&aid=2580&group_id=9&atid=127 About bug #2033, I'm still looking at it, committing a small fix now. ===== Patches by Campbell Barton (thanks!): #2482: BGL pydocs fix broken links https://projects.blender.org/tracker/index.php?func=detail&aid=2482&group_id=9&atid=127 #2426: Large text in Draw.Text and Draw.GetStreingWidth https://projects.blender.org/tracker/index.php?func=detail&aid=2462&group_id=9&atid=127 #2521: scene.getActiveObject() https://projects.blender.org/tracker/index.php?func=detail&aid=2521&group_id=9&atid=127 #2523: NMesh.GetNames() https://projects.blender.org/tracker/index.php?func=detail&aid=2523&group_id=9&atid=127 - docs also updated
2005-05-20 05:14:03 +00:00
static char M_NMesh_GetNames_doc[] = "\
() - Get a list with the names of all available meshes in Blender\n\n\
Any of these names can be passed to NMesh.GetRaw() for the actual mesh data.";
static char M_NMesh_GetRawFromObject_doc[] =
"(name) - Get the raw mesh used by a Blender object\n\n\
(name) Name of the object to get the mesh from\n\n\
This returns the mesh as used by the object, which\n\
means it contains all deformations and modifications.";
static char M_NMesh_PutRaw_doc[] =
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
"(mesh, name = None, recalc_normals = 1, store_edges = 0]) -\n\
Return a raw mesh to Blender\n\n\
(mesh) The NMesh object to store\n\
[name] The mesh to replace\n\
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
[recalc_normals = 1] Flag to control vertex normal recalculation\n\
[store_edges=0] Store edges data in the blender mesh\n\
If the name of a mesh to replace is not given a new\n\
object is created and returned.";
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
static char NMesh_transform_doc[] =
"(matrix, recalc_normals = 0) - Transform the mesh by the supplied 4x4 matrix\n\
if recalc_normals is True, vertex normals are transformed along with \n\
vertex coordinatess.\n";
void mesh_update( Mesh * mesh, Object * ob )
{
if (ob) {
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
}
else {
ob = G.main->object.first;
while (ob) {
if (ob->data == mesh) {
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
break;
}
ob = ob->id.next;
}
}
}
/*
* before trying to convert NMesh data back to mesh, verify that the
* lists contain the right type of data
*/
static int check_NMeshLists( BPy_NMesh *nmesh )
{
int i;
if( !PySequence_Check( nmesh->verts ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh verts are not a sequence" );
if( !PySequence_Check( nmesh->edges ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh edges are not a sequence" );
if( !PySequence_Check( nmesh->faces ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh faces are not a sequence" );
if( !PySequence_Check( nmesh->materials ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh materials are not a sequence" );
if( EXPP_check_sequence_consistency( nmesh->verts, &NMVert_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh vertices must be NMVerts" );
if( EXPP_check_sequence_consistency( nmesh->edges, &NMEdge_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh edges must be NMEdges" );
if( EXPP_check_sequence_consistency( nmesh->faces, &NMFace_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh faces must be NMFaces" );
for( i = 0 ; i < PySequence_Length(nmesh->faces); ++i ) {
int j, err=0;
PyObject *col, *v, *uv;
BPy_NMFace *face=(BPy_NMFace *)PySequence_GetItem(nmesh->faces, i);
col = face->col;
uv = face->uv;
v = face->v;
Py_DECREF( face );
if( EXPP_check_sequence_consistency( face->col, &NMCol_Type ) != 1 ) {
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh face col must be NMCols" );
}
if( EXPP_check_sequence_consistency( face->v, &NMVert_Type ) != 1 )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh face v must be NMVerts" );
for( j = 0 ; !err && j < PySequence_Length( face->uv ); ++j ) {
PyObject *uv = PySequence_GetItem( face->uv, j);
if( PySequence_Check(uv) && PySequence_Length(uv) == 2 ) {
PyObject *p1 = PySequence_GetItem(uv, 0);
PyObject *p2 = PySequence_GetItem(uv, 1);
if( !PyNumber_Check(p1) || !PyNumber_Check(p2) )
err = 1;
Py_DECREF( p1 );
Py_DECREF( p2 );
}
else {
err = 1;
}
Py_DECREF( uv );
}
if( err )
return EXPP_ReturnIntError( PyExc_AttributeError,
"nmesh face uv must contain sequence of 2 floats" );
}
return 0;
}
2005-08-01 06:01:24 +00:00
/*****************************/
/* Mesh Color Object */
/*****************************/
static void NMCol_dealloc( PyObject * self )
{
PyObject_DEL( self );
}
static BPy_NMCol *newcol( char r, char g, char b, char a )
{
BPy_NMCol *mc = ( BPy_NMCol * ) PyObject_NEW( BPy_NMCol, &NMCol_Type );
mc->r = r;
mc->g = g;
mc->b = b;
mc->a = a;
return mc;
}
static PyObject *M_NMesh_Col( PyObject * self, PyObject * args )
{
2005-08-01 06:01:24 +00:00
char r = 255, g = 255, b = 255, a = 255;
2005-08-01 06:01:24 +00:00
if( PyArg_ParseTuple( args, "|bbbb", &r, &g, &b, &a ) )
return ( PyObject * ) newcol( r, g, b, a );
return NULL;
}
static PyObject *NMCol_getattr( PyObject * self, char *name )
{
BPy_NMCol *mc = ( BPy_NMCol * ) self;
if( strcmp( name, "r" ) == 0 )
return Py_BuildValue( "i", mc->r );
else if( strcmp( name, "g" ) == 0 )
return Py_BuildValue( "i", mc->g );
else if( strcmp( name, "b" ) == 0 )
return Py_BuildValue( "i", mc->b );
else if( strcmp( name, "a" ) == 0 )
return Py_BuildValue( "i", mc->a );
else if( strcmp( name, "__members__" ) == 0 )
return Py_BuildValue( "[s,s,s,s]", "r", "g", "b", "a" );
return EXPP_ReturnPyObjError( PyExc_AttributeError, name );
}
static int NMCol_setattr( PyObject * self, char *name, PyObject * v )
{
BPy_NMCol *mc = ( BPy_NMCol * ) self;
2005-08-01 06:01:24 +00:00
char ival;
2005-08-01 06:01:24 +00:00
if( !PyArg_Parse( v, "b", &ival ) )
return -1;
2005-08-01 06:01:24 +00:00
ival = ( char ) EXPP_ClampInt( ival, 0, 255 );
if( strcmp( name, "r" ) == 0 )
mc->r = (unsigned char)ival;
else if( strcmp( name, "g" ) == 0 )
mc->g = (unsigned char)ival;
else if( strcmp( name, "b" ) == 0 )
mc->b = (unsigned char)ival;
else if( strcmp( name, "a" ) == 0 )
mc->a = (unsigned char)ival;
else
return -1;
return 0;
}
static PyObject *NMCol_repr( BPy_NMCol * self )
{
static char s[256];
sprintf( s, "[NMCol - <%d, %d, %d, %d>]", self->r, self->g, self->b,
self->a );
return Py_BuildValue( "s", s );
}
PyTypeObject NMCol_Type = {
PyObject_HEAD_INIT( NULL ) 0, /* ob_size */
"Blender NMCol", /* tp_name */
sizeof( BPy_NMCol ), /* tp_basicsize */
0, /* tp_itemsize */
/* methods */
( destructor ) NMCol_dealloc, /* tp_dealloc */
( printfunc ) 0, /* tp_print */
( getattrfunc ) NMCol_getattr, /* tp_getattr */
( setattrfunc ) NMCol_setattr, /* tp_setattr */
0, /* tp_compare */
( reprfunc ) NMCol_repr, /* tp_repr */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_hash */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* up to tp_del to avoid a warning */
};
/*****************************/
/* NMesh Python Object */
/*****************************/
static void NMFace_dealloc( PyObject * self )
{
BPy_NMFace *mf = ( BPy_NMFace * ) self;
Py_DECREF( mf->v );
Py_DECREF( mf->uv );
Py_DECREF( mf->col );
PyObject_DEL( self );
}
static PyObject *new_NMFace( PyObject * vertexlist )
{
BPy_NMFace *mf = PyObject_NEW( BPy_NMFace, &NMFace_Type );
PyObject *vlcopy;
if( vertexlist ) { /* create a copy of the given vertex list */
PyObject *item;
int i, len = PyList_Size( vertexlist );
vlcopy = PyList_New( len );
if( !vlcopy )
return EXPP_ReturnPyObjError( PyExc_MemoryError,
"couldn't create PyList" );
for( i = 0; i < len; i++ ) {
item = PySequence_GetItem( vertexlist, i ); /* PySequence increfs */
if( item )
PyList_SET_ITEM( vlcopy, i, item );
else
return EXPP_ReturnPyObjError
( PyExc_RuntimeError,
"couldn't get vertex from a PyList" );
}
} else /* create an empty vertex list */
vlcopy = PyList_New( 0 );
mf->v = vlcopy;
mf->uv = PyList_New( 0 );
mf->image = NULL;
mf->mode = TF_DYNAMIC + TF_TEX;
mf->flag = TF_SELECT;
mf->transp = TF_SOLID;
mf->col = PyList_New( 0 );
mf->mf_flag = 0;
mf->mat_nr = 0;
return ( PyObject * ) mf;
}
static PyObject *M_NMesh_Face( PyObject * self, PyObject * args )
{
PyObject *vertlist = NULL;
if( !PyArg_ParseTuple( args, "|O!", &PyList_Type, &vertlist ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a list of vertices or nothing as argument" );
/* if (!vertlist) vertlist = PyList_New(0); */
return new_NMFace( vertlist );
}
static PyObject *NMFace_append( PyObject * self, PyObject * args )
{
PyObject *vert;
BPy_NMFace *f = ( BPy_NMFace * ) self;
if( !PyArg_ParseTuple( args, "O!", &NMVert_Type, &vert ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected an NMVert object" );
PyList_Append( f->v, vert );
return EXPP_incr_ret( Py_None );
}
#undef MethodDef
#define MethodDef(func) {#func, NMFace_##func, METH_VARARGS, NMFace_##func##_doc}
static struct PyMethodDef NMFace_methods[] = {
MethodDef( append ),
{NULL, NULL, 0, NULL}
};
static PyObject *NMFace_getattr( PyObject * self, char *name )
{
BPy_NMFace *mf = ( BPy_NMFace * ) self;
if( strcmp( name, "v" ) == 0 )
return Py_BuildValue( "O", mf->v );
else if( strcmp( name, "col" ) == 0 )
return Py_BuildValue( "O", mf->col );
else if( strcmp( name, "mat" ) == 0 ) // emulation XXX
return Py_BuildValue( "i", mf->mat_nr );
else if( strcmp( name, "materialIndex" ) == 0 )
return Py_BuildValue( "i", mf->mat_nr );
else if( strcmp( name, "smooth" ) == 0 )
return Py_BuildValue( "i", (mf->mf_flag & ME_SMOOTH) ? 1:0 );
else if( strcmp( name, "sel" ) == 0 )
return Py_BuildValue( "i", (mf->mf_flag & ME_FACE_SEL) ? 1:0 );
else if( strcmp( name, "hide" ) == 0 )
return Py_BuildValue( "i", (mf->mf_flag & ME_HIDE) ? 1:0 );
else if( strcmp( name, "image" ) == 0 ) {
if( mf->image )
return Image_CreatePyObject( mf->image );
else
return EXPP_incr_ret( Py_None );
}
else if( strcmp( name, "mode" ) == 0 )
return Py_BuildValue( "i", mf->mode );
else if( strcmp( name, "flag" ) == 0 )
return Py_BuildValue( "i", mf->flag );
else if( strcmp( name, "transp" ) == 0 )
return Py_BuildValue( "i", mf->transp );
else if( strcmp( name, "uv" ) == 0 )
return Py_BuildValue( "O", mf->uv );
else if( ( strcmp( name, "normal" ) == 0 )
|| ( strcmp( name, "no" ) == 0 ) ) {
if( EXPP_check_sequence_consistency( mf->v, &NMVert_Type ) ==
1 ) {
float fNormal[3] = { 0.0, 0.0, 0.0 };
float *vco[4] = { NULL, NULL, NULL, NULL };
int nSize = PyList_Size( mf->v );
int loop;
if( nSize != 3 && nSize != 4 )
return EXPP_ReturnPyObjError
( PyExc_AttributeError,
"face must contain either 3 or 4 verts" );
for( loop = 0; loop < nSize; loop++ ) {
BPy_NMVert *v =
( BPy_NMVert * ) PyList_GetItem( mf->v,
loop );
vco[loop] = ( float * ) v->co;
}
if( nSize == 4 )
CalcNormFloat4( vco[0], vco[1], vco[2], vco[3],
fNormal );
else
CalcNormFloat( vco[0], vco[1], vco[2],
fNormal );
return Py_BuildValue( "[f,f,f]", fNormal[0],
fNormal[1], fNormal[2] );
} else // EXPP_check_sequence_consistency failed
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"this face does not contain a series of NMVerts" );
}
else if( strcmp( name, "__members__" ) == 0 )
return Py_BuildValue( "[s,s,s,s,s,s,s,s,s,s,s,s,s]",
"v", "col", "mat", "materialIndex",
"smooth", "image", "mode", "flag",
"transp", "uv", "normal", "sel", "hide");
return Py_FindMethod( NMFace_methods, ( PyObject * ) self, name );
}
static int NMFace_setattr( PyObject * self, char *name, PyObject * v )
{
BPy_NMFace *mf = ( BPy_NMFace * ) self;
short ival;
2005-08-01 06:01:24 +00:00
char cval;
if( strcmp( name, "v" ) == 0 ) {
if( PySequence_Check( v ) ) {
Py_DECREF( mf->v );
mf->v = EXPP_incr_ret( v );
return 0;
}
} else if( strcmp( name, "col" ) == 0 ) {
if( PySequence_Check( v ) ) {
Py_DECREF( mf->col );
mf->col = EXPP_incr_ret( v );
return 0;
}
} else if( !strcmp( name, "mat" ) || !strcmp( name, "materialIndex" ) ) {
2005-08-01 06:01:24 +00:00
PyArg_Parse( v, "b", &cval );
mf->mat_nr = cval;
return 0;
} else if( strcmp( name, "smooth" ) == 0 ) {
PyArg_Parse( v, "h", &ival );
if (ival) mf->mf_flag |= ME_SMOOTH;
else mf->mf_flag &= ~ME_SMOOTH;
return 0;
} else if( strcmp( name, "sel" ) == 0 ) {
PyArg_Parse( v, "h", &ival );
if (ival) mf->mf_flag |= ME_FACE_SEL;
else mf->mf_flag &= ~ME_FACE_SEL;
return 0;
} else if( strcmp( name, "hide" ) == 0 ) {
PyArg_Parse( v, "h", &ival );
if (ival) mf->mf_flag |= ME_HIDE;
else mf->mf_flag &= ~ME_HIDE;
return 0;
} else if( strcmp( name, "uv" ) == 0 ) {
if( PySequence_Check( v ) ) {
Py_DECREF( mf->uv );
mf->uv = EXPP_incr_ret( v );
return 0;
}
} else if( strcmp( name, "flag" ) == 0 ) {
PyArg_Parse( v, "h", &ival );
mf->flag = ival;
return 0;
} else if( strcmp( name, "mode" ) == 0 ) {
PyArg_Parse( v, "h", &ival );
mf->mode = ival;
return 0;
} else if( strcmp( name, "transp" ) == 0 ) {
2005-08-01 06:01:24 +00:00
PyArg_Parse( v, "b", &cval );
mf->transp = cval;
return 0;
} else if( strcmp( name, "image" ) == 0 ) {
PyObject *pyimg;
if( !PyArg_Parse( v, "O!", &Image_Type, &pyimg ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected image object" );
if( pyimg == Py_None ) {
mf->image = NULL;
return 0;
}
mf->image = ( ( BPy_Image * ) pyimg )->image;
return 0;
}
return EXPP_ReturnIntError( PyExc_AttributeError, name );
}
static PyObject *NMFace_repr( PyObject * self )
{
return PyString_FromString( "[NMFace]" );
}
static int NMFace_len( BPy_NMFace * self )
{
return PySequence_Length( self->v );
}
static PyObject *NMFace_item( BPy_NMFace * self, int i )
{
return PySequence_GetItem( self->v, i ); // new ref
}
static PyObject *NMFace_slice( BPy_NMFace * self, int begin, int end )
{
return PyList_GetSlice( self->v, begin, end ); // new ref
}
static PySequenceMethods NMFace_SeqMethods = {
( inquiry ) NMFace_len, /* sq_length */
( binaryfunc ) 0, /* sq_concat */
( intargfunc ) 0, /* sq_repeat */
( intargfunc ) NMFace_item, /* sq_item */
( intintargfunc ) NMFace_slice, /* sq_slice */
( intobjargproc ) 0, /* sq_ass_item */
( intintobjargproc ) 0, /* sq_ass_slice */
0,0,0,
};
PyTypeObject NMFace_Type = {
PyObject_HEAD_INIT( NULL ) 0, /*ob_size */
"Blender NMFace", /*tp_name */
sizeof( BPy_NMFace ), /*tp_basicsize */
0, /*tp_itemsize */
/* methods */
( destructor ) NMFace_dealloc, /*tp_dealloc */
( printfunc ) 0, /*tp_print */
( getattrfunc ) NMFace_getattr, /*tp_getattr */
( setattrfunc ) NMFace_setattr, /*tp_setattr */
0, /*tp_compare */
( reprfunc ) NMFace_repr, /*tp_repr */
0, /*tp_as_number */
&NMFace_SeqMethods, /*tp_as_sequence */
0, /*tp_as_mapping */
0, /*tp_hash */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* up to tp_del to avoid a warning */
};
static BPy_NMVert *newvert( float *co )
{
BPy_NMVert *mv = PyObject_NEW( BPy_NMVert, &NMVert_Type );
mv->co[0] = co[0];
mv->co[1] = co[1];
mv->co[2] = co[2];
mv->no[0] = mv->no[1] = mv->no[2] = 0.0;
mv->uvco[0] = mv->uvco[1] = mv->uvco[2] = 0.0;
mv->flag = 0;
return mv;
}
static PyObject *M_NMesh_Vert( PyObject * self, PyObject * args )
{
float co[3] = { 0.0, 0.0, 0.0 };
if( !PyArg_ParseTuple( args, "|fff", &co[0], &co[1], &co[2] ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected three floats (or nothing) as arguments" );
return ( PyObject * ) newvert( co );
}
static void NMVert_dealloc( PyObject * self )
{
PyObject_DEL( self );
}
static PyObject *NMVert_getattr( PyObject * self, char *name )
{
BPy_NMVert *mv = ( BPy_NMVert * ) self;
if( !strcmp( name, "co" ) || !strcmp( name, "loc" ) )
Mathutils update - also included is some fixes for preprocessor inclues and some clean up of the previous commit -rewrite and bugfixes ---------------------------------- Here's my changelog: -fixed Rand() so that it doesn't seed everytime and should generate better random numbers - changed a few error return types to something more appropriate - clean up of uninitialized variables & removal of unneccessary objects - NMesh returns wrapped vectors now - World returns wrapped matrices now - Object.getEuler() and Object.getBoundingBox() return Wrapped data when data is present - Object.getMatrix() returns wrapped data if it's worldspace, 'localspace' returns a new matrix - Vector, Euler, Mat, Quat, call all now internally wrap object without destroying internal datablocks - Removed memory allocation (unneeded) from all methods - Vector's resize methods are only applicable to new vectors not wrapped data. - Matrix(), Quat(), Euler(), Vector() now accepts ANY sequence list, including tuples, list, or a self object to copy - matrices accept multiple sequences - Fixed Slerp() so that it now works correctly values are clamped between 0 and 1 - Euler.rotate does internal rotation now - Slice assignment now works better for all types - Vector * Vector and Quat * Quat are defined and return the DOT product - Mat * Vec and Vec * Mat are defined now - Moved #includes to .c file from headers. Also fixed prototypes in mathutils - Added new helper functions for incref'ing to genutils - Major cleanup of header files includes - include Mathutils.h for access to math types - matrix.toQuat() and .toEuler() now fixed take appropriate matrix sizes - Matrix() with no parameters now returns an identity matrix by default not a zero matrix - printf() now prints with 6 digits instead of 4 - printf() now prints output with object descriptor - Matrices now support [x][y] assignment (e.g. matrix[x][y] = 5.4) - Matrix[index] = value now expectes a sequence not an integer. This will now set a ROW of the matrix through a sequence. index cannot go above the row size of the matrix. - slice operations on matrices work with sequences now (rows of the matrix) example: mymatrix[0:2] returns a list of 2 wrapped vectors with access to the matrix data. - slice assignment will no longer modify the data if the assignment operation fails - fixed error in matrix * scalar multiplication - euler.toMatrix(), toQuat() no longer causes "creep" from repeated use - Wrapped data will generate wrapped objects when toEuler(), toQuat(), toMatrix() is used - Quats can be created with angle/axis, axis/angle - 4x4 matrices can be multiplied by 3D vectors (by popular demand :)) - vec *quat / quat * vec is now defined - vec.magnitude alias for vec.length - all self, internal methods return a pointer to self now so you can do print vector.internalmethod() or vector.internalmethod().nextmethod() (no more print matrix.inverse() returning 'none') - these methods have been deprecated (still functioning but suggested to use the corrected functionality): * CopyVec() - replaced by Vector() functionality * CopyMat() - replaced by Matrix() functionality * CopyQuat() - replace by Quaternion() functionality * CopyEuler() - replaced by Euler() functionality * RotateEuler() - replaced by Euler.rotate() funtionality * MatMultVec() - replaced by matrix * vector * VecMultMat() - replaced by vector * matrix - New struct containers references to python object data or internally allocated blender data for wrapping * Explaination here: math structs now function as a 'simple wrapper' or a 'py_object' - data that is created on the fly will now be a 'py_object' with its memory managed by python * otherwise if the data is returned by blender's G.main then the math object is a 'simple wrapper' and data can be accessed directly from the struct just like other python objects.
2005-07-14 03:34:56 +00:00
return newVectorObject(mv->co,3,Py_WRAP);
else if( strcmp( name, "no" ) == 0 )
Mathutils update - also included is some fixes for preprocessor inclues and some clean up of the previous commit -rewrite and bugfixes ---------------------------------- Here's my changelog: -fixed Rand() so that it doesn't seed everytime and should generate better random numbers - changed a few error return types to something more appropriate - clean up of uninitialized variables & removal of unneccessary objects - NMesh returns wrapped vectors now - World returns wrapped matrices now - Object.getEuler() and Object.getBoundingBox() return Wrapped data when data is present - Object.getMatrix() returns wrapped data if it's worldspace, 'localspace' returns a new matrix - Vector, Euler, Mat, Quat, call all now internally wrap object without destroying internal datablocks - Removed memory allocation (unneeded) from all methods - Vector's resize methods are only applicable to new vectors not wrapped data. - Matrix(), Quat(), Euler(), Vector() now accepts ANY sequence list, including tuples, list, or a self object to copy - matrices accept multiple sequences - Fixed Slerp() so that it now works correctly values are clamped between 0 and 1 - Euler.rotate does internal rotation now - Slice assignment now works better for all types - Vector * Vector and Quat * Quat are defined and return the DOT product - Mat * Vec and Vec * Mat are defined now - Moved #includes to .c file from headers. Also fixed prototypes in mathutils - Added new helper functions for incref'ing to genutils - Major cleanup of header files includes - include Mathutils.h for access to math types - matrix.toQuat() and .toEuler() now fixed take appropriate matrix sizes - Matrix() with no parameters now returns an identity matrix by default not a zero matrix - printf() now prints with 6 digits instead of 4 - printf() now prints output with object descriptor - Matrices now support [x][y] assignment (e.g. matrix[x][y] = 5.4) - Matrix[index] = value now expectes a sequence not an integer. This will now set a ROW of the matrix through a sequence. index cannot go above the row size of the matrix. - slice operations on matrices work with sequences now (rows of the matrix) example: mymatrix[0:2] returns a list of 2 wrapped vectors with access to the matrix data. - slice assignment will no longer modify the data if the assignment operation fails - fixed error in matrix * scalar multiplication - euler.toMatrix(), toQuat() no longer causes "creep" from repeated use - Wrapped data will generate wrapped objects when toEuler(), toQuat(), toMatrix() is used - Quats can be created with angle/axis, axis/angle - 4x4 matrices can be multiplied by 3D vectors (by popular demand :)) - vec *quat / quat * vec is now defined - vec.magnitude alias for vec.length - all self, internal methods return a pointer to self now so you can do print vector.internalmethod() or vector.internalmethod().nextmethod() (no more print matrix.inverse() returning 'none') - these methods have been deprecated (still functioning but suggested to use the corrected functionality): * CopyVec() - replaced by Vector() functionality * CopyMat() - replaced by Matrix() functionality * CopyQuat() - replace by Quaternion() functionality * CopyEuler() - replaced by Euler() functionality * RotateEuler() - replaced by Euler.rotate() funtionality * MatMultVec() - replaced by matrix * vector * VecMultMat() - replaced by vector * matrix - New struct containers references to python object data or internally allocated blender data for wrapping * Explaination here: math structs now function as a 'simple wrapper' or a 'py_object' - data that is created on the fly will now be a 'py_object' with its memory managed by python * otherwise if the data is returned by blender's G.main then the math object is a 'simple wrapper' and data can be accessed directly from the struct just like other python objects.
2005-07-14 03:34:56 +00:00
return newVectorObject(mv->no,3,Py_WRAP);
else if( strcmp( name, "uvco" ) == 0 )
Mathutils update - also included is some fixes for preprocessor inclues and some clean up of the previous commit -rewrite and bugfixes ---------------------------------- Here's my changelog: -fixed Rand() so that it doesn't seed everytime and should generate better random numbers - changed a few error return types to something more appropriate - clean up of uninitialized variables & removal of unneccessary objects - NMesh returns wrapped vectors now - World returns wrapped matrices now - Object.getEuler() and Object.getBoundingBox() return Wrapped data when data is present - Object.getMatrix() returns wrapped data if it's worldspace, 'localspace' returns a new matrix - Vector, Euler, Mat, Quat, call all now internally wrap object without destroying internal datablocks - Removed memory allocation (unneeded) from all methods - Vector's resize methods are only applicable to new vectors not wrapped data. - Matrix(), Quat(), Euler(), Vector() now accepts ANY sequence list, including tuples, list, or a self object to copy - matrices accept multiple sequences - Fixed Slerp() so that it now works correctly values are clamped between 0 and 1 - Euler.rotate does internal rotation now - Slice assignment now works better for all types - Vector * Vector and Quat * Quat are defined and return the DOT product - Mat * Vec and Vec * Mat are defined now - Moved #includes to .c file from headers. Also fixed prototypes in mathutils - Added new helper functions for incref'ing to genutils - Major cleanup of header files includes - include Mathutils.h for access to math types - matrix.toQuat() and .toEuler() now fixed take appropriate matrix sizes - Matrix() with no parameters now returns an identity matrix by default not a zero matrix - printf() now prints with 6 digits instead of 4 - printf() now prints output with object descriptor - Matrices now support [x][y] assignment (e.g. matrix[x][y] = 5.4) - Matrix[index] = value now expectes a sequence not an integer. This will now set a ROW of the matrix through a sequence. index cannot go above the row size of the matrix. - slice operations on matrices work with sequences now (rows of the matrix) example: mymatrix[0:2] returns a list of 2 wrapped vectors with access to the matrix data. - slice assignment will no longer modify the data if the assignment operation fails - fixed error in matrix * scalar multiplication - euler.toMatrix(), toQuat() no longer causes "creep" from repeated use - Wrapped data will generate wrapped objects when toEuler(), toQuat(), toMatrix() is used - Quats can be created with angle/axis, axis/angle - 4x4 matrices can be multiplied by 3D vectors (by popular demand :)) - vec *quat / quat * vec is now defined - vec.magnitude alias for vec.length - all self, internal methods return a pointer to self now so you can do print vector.internalmethod() or vector.internalmethod().nextmethod() (no more print matrix.inverse() returning 'none') - these methods have been deprecated (still functioning but suggested to use the corrected functionality): * CopyVec() - replaced by Vector() functionality * CopyMat() - replaced by Matrix() functionality * CopyQuat() - replace by Quaternion() functionality * CopyEuler() - replaced by Euler() functionality * RotateEuler() - replaced by Euler.rotate() funtionality * MatMultVec() - replaced by matrix * vector * VecMultMat() - replaced by vector * matrix - New struct containers references to python object data or internally allocated blender data for wrapping * Explaination here: math structs now function as a 'simple wrapper' or a 'py_object' - data that is created on the fly will now be a 'py_object' with its memory managed by python * otherwise if the data is returned by blender's G.main then the math object is a 'simple wrapper' and data can be accessed directly from the struct just like other python objects.
2005-07-14 03:34:56 +00:00
return newVectorObject(mv->uvco,3,Py_WRAP);
else if( strcmp( name, "index" ) == 0 )
return PyInt_FromLong( mv->index );
else if( strcmp( name, "sel" ) == 0 )
return PyInt_FromLong( mv->flag & 1 );
else if( strcmp( name, "__members__" ) == 0 )
return Py_BuildValue( "[s,s,s,s,s]", "co", "no", "uvco",
"index", "sel" );
return EXPP_ReturnPyObjError( PyExc_AttributeError, name );
}
static int NMVert_setattr( PyObject * self, char *name, PyObject * v )
{
BPy_NMVert *mv = ( BPy_NMVert * ) self;
int i;
if( strcmp( name, "index" ) == 0 ) {
PyArg_Parse( v, "i", &i );
mv->index = i;
return 0;
} else if( strcmp( name, "sel" ) == 0 ) {
PyArg_Parse( v, "i", &i );
mv->flag = i ? 1 : 0;
return 0;
} else if( strcmp( name, "uvco" ) == 0 ) {
if( !PyArg_ParseTuple( v, "ff|f",
&( mv->uvco[0] ), &( mv->uvco[1] ),
&( mv->uvco[2] ) ) )
return EXPP_ReturnIntError( PyExc_AttributeError,
"Vector tuple or triple expected" );
return 0;
}
return EXPP_ReturnIntError( PyExc_AttributeError, name );
}
static int NMVert_len( BPy_NMVert * self )
{
return 3;
}
static PyObject *NMVert_item( BPy_NMVert * self, int i )
{
if( i < 0 || i >= 3 )
return EXPP_ReturnPyObjError( PyExc_IndexError,
"array index out of range" );
return Py_BuildValue( "f", self->co[i] );
}
static PyObject *NMVert_slice( BPy_NMVert * self, int begin, int end )
{
PyObject *list;
int count;
if( begin < 0 )
begin = 0;
if( end > 3 )
end = 3;
if( begin > end )
begin = end;
list = PyList_New( end - begin );
for( count = begin; count < end; count++ )
PyList_SetItem( list, count - begin,
PyFloat_FromDouble( self->co[count] ) );
return list;
}
static int NMVert_ass_item( BPy_NMVert * self, int i, PyObject * ob )
{
if( i < 0 || i >= 3 )
return EXPP_ReturnIntError( PyExc_IndexError,
"array assignment index out of range" );
if( !PyNumber_Check( ob ) )
return EXPP_ReturnIntError( PyExc_IndexError,
"NMVert member must be a number" );
self->co[i] = (float)PyFloat_AsDouble( ob );
return 0;
}
static int NMVert_ass_slice( BPy_NMVert * self, int begin, int end,
PyObject * seq )
{
int count;
if( begin < 0 )
begin = 0;
if( end > 3 )
end = 3;
if( begin > end )
begin = end;
if( !PySequence_Check( seq ) )
EXPP_ReturnIntError( PyExc_TypeError,
"illegal argument type for built-in operation" );
if( PySequence_Length( seq ) != ( end - begin ) )
EXPP_ReturnIntError( PyExc_TypeError,
"size mismatch in slice assignment" );
for( count = begin; count < end; count++ ) {
PyObject *ob = PySequence_GetItem( seq, count );
if( !PyArg_Parse( ob, "f", &self->co[count] ) ) {
Py_DECREF( ob );
return -1;
}
Py_DECREF( ob );
}
return 0;
}
static PySequenceMethods NMVert_SeqMethods = {
( inquiry ) NMVert_len, /* sq_length */
( binaryfunc ) 0, /* sq_concat */
( intargfunc ) 0, /* sq_repeat */
( intargfunc ) NMVert_item, /* sq_item */
( intintargfunc ) NMVert_slice, /* sq_slice */
( intobjargproc ) NMVert_ass_item, /* sq_ass_item */
( intintobjargproc ) NMVert_ass_slice, /* sq_ass_slice */
0,0,0,
};
PyTypeObject NMVert_Type = {
PyObject_HEAD_INIT( NULL )
0, /*ob_size */
"Blender NMVert", /*tp_name */
sizeof( BPy_NMVert ), /*tp_basicsize */
0, /*tp_itemsize */
/* methods */
( destructor ) NMVert_dealloc, /*tp_dealloc */
( printfunc ) 0, /*tp_print */
( getattrfunc ) NMVert_getattr, /*tp_getattr */
( setattrfunc ) NMVert_setattr, /*tp_setattr */
0, /*tp_compare */
( reprfunc ) 0, /*tp_repr */
0, /*tp_as_number */
&NMVert_SeqMethods, /*tp_as_sequence */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0, /* tp_del */
};
/*****************************
* NMEdge
*****************************/
static BPy_NMEdge *new_NMEdge( BPy_NMVert * v1, BPy_NMVert * v2, char crease, short flag)
{
BPy_NMEdge *edge=NULL;
if (!v1 || !v2) return NULL;
if (!BPy_NMVert_Check(v1) || !BPy_NMVert_Check(v2)) return NULL;
edge = PyObject_NEW( BPy_NMEdge, &NMEdge_Type );
edge->v1=EXPP_incr_ret((PyObject*)v1);
edge->v2=EXPP_incr_ret((PyObject*)v2);
edge->flag=flag;
edge->crease=crease;
return edge;
}
static void NMEdge_dealloc( PyObject * self )
{
BPy_NMEdge *edge=(BPy_NMEdge *)self;
Py_DECREF(edge->v1);
Py_DECREF(edge->v2);
PyObject_DEL(self);
}
static PyObject *NMEdge_getattr( PyObject * self, char *name )
{
BPy_NMEdge *edge=(BPy_NMEdge *)self;
if ( strcmp( name, "v1" ) == 0 )
return EXPP_incr_ret( edge->v1 );
else if ( strcmp( name, "v2" ) == 0 )
return EXPP_incr_ret( edge->v2 );
else if ( strcmp( name, "flag" ) == 0 )
return PyInt_FromLong( edge->flag );
else if ( strcmp( name, "crease" ) == 0 )
return PyInt_FromLong( edge->crease );
else if( strcmp( name, "__members__" ) == 0 )
return Py_BuildValue( "[s,s,s,s]",
"v1", "v2", "flag", "crease" );
return EXPP_ReturnPyObjError( PyExc_AttributeError, name );
}
static int NMEdge_setattr( PyObject * self, char *name, PyObject * v )
{
BPy_NMEdge *edge=(BPy_NMEdge *)self;
if ( strcmp( name, "flag" ) == 0 )
{
short flag=0;
if( !PyInt_Check( v ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
flag = ( short ) PyInt_AsLong( v );
edge->flag = flag;
return 0;
}
else if ( strcmp( name, "crease" ) == 0 )
{
char crease=0;
if( !PyInt_Check( v ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
crease = ( char ) PyInt_AsLong( v );
edge->crease = crease;
return 0;
}
return EXPP_ReturnIntError( PyExc_AttributeError, name );
}
PyTypeObject NMEdge_Type = {
PyObject_HEAD_INIT( NULL )
0, /*ob_size */
"Blender NMEdge", /*tp_name */
sizeof( BPy_NMEdge ), /*tp_basicsize */
0, /*tp_itemsize */
/* methods */
( destructor ) NMEdge_dealloc, /*tp_dealloc */
( printfunc ) 0, /*tp_print */
( getattrfunc ) NMEdge_getattr, /*tp_getattr */
( setattrfunc ) NMEdge_setattr, /*tp_setattr */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,
};
static void NMesh_dealloc( PyObject * self )
{
BPy_NMesh *me = ( BPy_NMesh * ) self;
Py_DECREF( me->name );
Py_DECREF( me->verts );
Py_DECREF( me->faces );
Py_DECREF( me->materials );
Py_DECREF( me->edges );
PyObject_DEL( self );
}
static PyObject *NMesh_getMaterials( PyObject * self, PyObject * args )
{
BPy_NMesh *nm = ( BPy_NMesh * ) self;
PyObject *list = NULL;
Mesh *me = nm->mesh;
int all = -1;
if( !PyArg_ParseTuple( args, "|i", &all ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected nothing or an int (bool) as argument" );
if( all >= 0 ) {
BPython bug fixes: - #2781, reported by Ed Blake: crash on undo when there were active space handlers. Space Handler script links belong to screen areas, which do not get saved on undo. Thanks Ton for pointing out the function that restores ui pointers gone bad. - Applied patch #2822 by Ken Hughes for bug #2647 ("Setting a Face UV"), reported by Campbell Barton. - #3022, reported by Timothy Wakeham: "Blender.BGL.glDrawPixels crashes when drawing more pixels then buffer size". Made glDrawPixels check buffer dimensions. - #2882, reported by Campbell: crash in nmesh.getMaterials(arg == 0 or 1) when nmesh came from GetRawFromMesh(). Raw nmeshes are not linked to Blender meshes, so the method doesn't support these options (getting mat info from the actual mesh) for it. - #2817, reported by Tod Koeckeritz: Dir_Depth var was not being decremented in BPY_Menus.c, causing dir depth limits to be reached prematurely. - #2954, reported by Daniel Holtz: "Python scripts crash hard with valid windows paths". Blender.Load() was not meant for background mode, now it's been update to support it, using BKE_read_file instead of BIF_read_file in this case. Also found another issue with command line scripts using Blender.Load() that could crash Blender: trying to free the Text when it wasn't available anymore (loading a new .blend already removed it). There are still issues with one case, though, causing a crash on start or "Memoryblock winopen: double free" at end, when running a script that is already a Blender Text (only if the script calls Blender.Load, of course). Will investigate. - #2897: reported by Timothy Wakeham: object.setMaterials was asking the length of a Python list w/o confirming first if the passed obj was really a list. Thanks all for the help and for being patient (long delay, again).
2005-10-03 19:12:11 +00:00
if (!me)
return EXPP_ReturnPyObjError(PyExc_TypeError,
"meshes obtained with GetRawFromObject don't support this option");
list = EXPP_PyList_fromMaterialList( me->mat, me->totcol,
all );
Py_DECREF( nm->materials ); /* update nmesh.materials attribute */
nm->materials = EXPP_incr_ret( list );
} else
list = EXPP_incr_ret( nm->materials );
return list;
}
static PyObject *NMesh_setMaterials( PyObject * self, PyObject * args )
{
BPy_NMesh *me = ( BPy_NMesh * ) self;
PyObject *pymats = NULL;
if( !PyArg_ParseTuple( args, "O!", &PyList_Type, &pymats ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected a list of materials (None's also accepted) as argument" );
if( !EXPP_check_sequence_consistency( pymats, &Material_Type ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"list should only contain materials (None's also accepted)" );
if( PyList_Size( pymats ) > 16 )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"list can't have more than 16 materials" );
Py_DECREF( me->materials );
me->materials = EXPP_incr_ret( pymats );
return EXPP_incr_ret( Py_None );
}
static PyObject *NMesh_addMaterial( PyObject * self, PyObject * args )
{
BPy_NMesh *me = ( BPy_NMesh * ) self;
BPy_Material *pymat;
Material *mat;
PyObject *iter;
int i, len = 0;
if( !PyArg_ParseTuple( args, "O!", &Material_Type, &pymat ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected Blender Material PyObject" );
mat = pymat->material;
len = PyList_Size( me->materials );
if( len >= 16 )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"object data material lists can't have more than 16 materials" );
for( i = 0; i < len; i++ ) {
iter = PyList_GetItem( me->materials, i );
if( mat == Material_FromPyObject( iter ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"material already in the list" );
}
PyList_Append( me->materials, ( PyObject * ) pymat );
return EXPP_incr_ret( Py_None );
}
static PyObject *NMesh_getKey( BPy_NMesh * self )
{
PyObject *keyobj;
if( self->mesh->key )
keyobj = Key_CreatePyObject(self->mesh->key);
else
keyobj = EXPP_incr_ret(Py_None);
return keyobj;
}
static PyObject *NMesh_removeAllKeys( PyObject * self, PyObject * args )
{
BPy_NMesh *nm = ( BPy_NMesh * ) self;
Mesh *me = nm->mesh;
if( !PyArg_ParseTuple( args, "" ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"this function expects no arguments" );
if( !me || !me->key )
return EXPP_incr_ret_False();
me->key->id.us--;
me->key = 0;
return EXPP_incr_ret_True();
}
static PyObject *NMesh_insertKey( PyObject * self, PyObject * args )
{
int fra = -1, oldfra = -1;
char *type = NULL;
short typenum;
BPy_NMesh *nm = ( BPy_NMesh * ) self;
Mesh *mesh = nm->mesh;
if( !PyArg_ParseTuple( args, "|is", &fra, &type ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected nothing or an int and optionally a string as arguments" );
if( !type || !strcmp( type, "relative" ) )
typenum = 1;
else if( !strcmp( type, "absolute" ) )
typenum = 2;
else
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"if given, type should be 'relative' or 'absolute'" );
if( fra > 0 ) {
fra = EXPP_ClampInt( fra, 1, NMESH_FRAME_MAX );
oldfra = G.scene->r.cfra;
G.scene->r.cfra = (int)fra;
}
if( !mesh )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"update this NMesh first with its .update() method" );
insert_meshkey( mesh, typenum );
allspace(REMAKEIPO, 0);
if( fra > 0 )
G.scene->r.cfra = (int)oldfra;
return EXPP_incr_ret( Py_None );
}
static PyObject *NMesh_getSelectedFaces( PyObject * self, PyObject * args )
{
BPy_NMesh *nm = ( BPy_NMesh * ) self;
Mesh *me = nm->mesh;
int flag = 0;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
MTFace *tf;
int i;
PyObject *l = PyList_New( 0 );
if( me == NULL )
return NULL;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
tf = me->mtface;
if( tf == 0 )
return l;
if( !PyArg_ParseTuple( args, "|i", &flag ) )
return NULL;
if( flag ) {
for( i = 0; i < me->totface; i++ ) {
if( tf[i].flag & TF_SELECT )
PyList_Append( l, PyInt_FromLong( i ) );
}
} else {
for( i = 0; i < me->totface; i++ ) {
if( tf[i].flag & TF_SELECT )
PyList_Append( l,
PyList_GetItem( nm->faces,
i ) );
}
}
return l;
}
static PyObject *NMesh_getActiveFace( PyObject * self )
{
if( ( ( BPy_NMesh * ) self )->sel_face < 0 )
return EXPP_incr_ret( Py_None );
return Py_BuildValue( "i", ( ( BPy_NMesh * ) self )->sel_face );
}
static PyObject *NMesh_hasVertexUV( PyObject * self, PyObject * args )
{
BPy_NMesh *me = ( BPy_NMesh * ) self;
int flag = -1;
if( !PyArg_ParseTuple( args, "|i", &flag ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected int argument (or nothing)" );
switch ( flag ) {
case 0:
me->flags &= ~NMESH_HASVERTUV;
break;
case 1:
me->flags |= NMESH_HASVERTUV;
break;
default:
break;
}
if( me->flags & NMESH_HASVERTUV )
return EXPP_incr_ret_True();
else
return EXPP_incr_ret_False();
}
static PyObject *NMesh_hasFaceUV( PyObject * self, PyObject * args )
{
BPy_NMesh *me = ( BPy_NMesh * ) self;
int flag = -1;
if( !PyArg_ParseTuple( args, "|i", &flag ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected int argument (or nothing)" );
switch ( flag ) {
case 0:
me->flags &= ~NMESH_HASFACEUV;
break;
case 1:
me->flags |= NMESH_HASFACEUV;
break;
default:
break;
}
if( me->flags & NMESH_HASFACEUV )
return EXPP_incr_ret_True();
else
return EXPP_incr_ret_False();
}
static PyObject *NMesh_hasVertexColours( PyObject * self, PyObject * args )
{
BPy_NMesh *me = ( BPy_NMesh * ) self;
int flag = -1;
if( !PyArg_ParseTuple( args, "|i", &flag ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected int argument (or nothing)" );
switch ( flag ) {
case 0:
me->flags &= ~NMESH_HASMCOL;
break;
case 1:
me->flags |= NMESH_HASMCOL;
break;
default:
break;
}
if( me->flags & NMESH_HASMCOL )
return EXPP_incr_ret_True();
else
return EXPP_incr_ret_False();
}
static PyObject *NMesh_update( PyObject *self, PyObject *a, PyObject *kwd )
{
BPy_NMesh *nmesh = ( BPy_NMesh * ) self;
Mesh *mesh = nmesh->mesh;
int recalc_normals = 0, store_edges = 0, vertex_shade = 0;
static char *kwlist[] = {"recalc_normals", "store_edges",
"vertex_shade", NULL};
int needs_redraw = 1;
int old_totvert = 0;
if (!PyArg_ParseTupleAndKeywords(a, kwd, "|iii", kwlist, &recalc_normals,
&store_edges, &vertex_shade ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected nothing or one to three bool(s) (0 or 1) as argument" );
if( check_NMeshLists( nmesh ) )
return NULL;
if( mesh ) {
old_totvert = mesh->totvert;
unlink_existingMeshData( mesh );
if( !convert_NMeshToMesh( mesh, nmesh ) )
return NULL;
if (mesh->dvert) check_dverts(mesh, old_totvert);
} else {
mesh = Mesh_fromNMesh( nmesh );
/* if mesh is NULL, there was an error */
if( !mesh )
return NULL;
nmesh->mesh = mesh;
}
if( recalc_normals )
mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
mesh_update( mesh, nmesh->object );
nmesh_updateMaterials( nmesh );
if( nmesh->name && nmesh->name != Py_None )
new_id( &( G.main->mesh ), &mesh->id,
PyString_AsString( nmesh->name ) );
if (vertex_shade) {
Base *base = FIRSTBASE;
if (!nmesh->object)
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
"link this mesh to an object first with ob.link(mesh)" );
if (G.obedit)
return EXPP_ReturnPyObjError(PyExc_RuntimeError,
"can't shade vertices while in edit mode" );
while (base) {
if (base->object == nmesh->object) {
base->flag |= SELECT;
nmesh->object->flag = (short)base->flag;
set_active_base (base);
needs_redraw = 0; /* already done in make_vertexcol */
break;
}
base = base->next;
}
/* recalculate the derived mesh before trying to use it */
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
makeDerivedMesh(nmesh->object);
make_vertexcol(1);
countall();
}
if( !during_script( ) && needs_redraw)
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
EXPP_allqueue( REDRAWVIEW3D, 0 );
return PyInt_FromLong( 1 );
}
/** Implementation of the python method getVertexInfluence for an NMesh object.
* This method returns a list of pairs (string,float) with bone names and
* influences that this vertex receives.
* @author Jordi Rovira i Bonet
*/
static PyObject *NMesh_getVertexInfluences( PyObject * self, PyObject * args )
{
int index;
PyObject *influence_list = NULL;
Object *object = ( ( BPy_NMesh * ) self )->object;
Mesh *me = ( ( BPy_NMesh * ) self )->mesh;
/* Get a reference to the mesh object wrapped in here. */
if( !me )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"unlinked nmesh: call its .update() method first" );
if( !object )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"This mesh must be linked to an object" );
/* Parse the parameters: only on integer (vertex index) */
if( !PyArg_ParseTuple( args, "i", &index ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected int argument (index of the vertex)" );
/* check for valid index */
if( index < 0 || index >= me->totvert )
return EXPP_ReturnPyObjError( PyExc_IndexError,
"vertex index out of range" );
influence_list = PyList_New( 0 );
/* Proceed only if we have vertex deformation information */
if( me->dvert ) {
int i;
MDeformWeight *sweight = NULL;
/* Number of bones influencing the vertex */
int totinfluences = me->dvert[index].totweight;
/* Get the reference of the first weight structure */
sweight = me->dvert[index].dw;
/* Build the list only with weights and names of the influent bones */
for( i = 0; i < totinfluences; i++, sweight++ ) {
bDeformGroup *defgroup = (bDeformGroup *) BLI_findlink( &object->defbase,
sweight->def_nr );
if( defgroup )
PyList_Append( influence_list, Py_BuildValue( "[sf]",
defgroup->name, sweight->weight ) );
}
}
return influence_list;
}
Mesh *Mesh_fromNMesh( BPy_NMesh * nmesh )
{
Mesh *mesh = NULL;
mesh = add_mesh( );
if( !mesh ) {
PyErr_SetString( PyExc_RuntimeError,
"FATAL: could not create mesh object" );
return NULL;
}
mesh->id.us = 0; /* no user yet */
G.totmesh++;
if( !convert_NMeshToMesh( mesh, nmesh ) )
return NULL;
return mesh;
}
static PyObject *NMesh_getMaxSmoothAngle( BPy_NMesh * self )
{
PyObject *attr = PyInt_FromLong( self->smoothresh );
if( attr )
return attr;
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't get NMesh.maxSmoothAngle attribute" );
}
static PyObject *NMesh_setMaxSmoothAngle( PyObject * self, PyObject * args )
{
short value = 0;
BPy_NMesh *nmesh = ( BPy_NMesh * ) self;
if( !PyArg_ParseTuple( args, "h", &value ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected an int in [1, 80] as argument" );
nmesh->smoothresh =
( short ) EXPP_ClampInt( value, NMESH_SMOOTHRESH_MIN,
NMESH_SMOOTHRESH_MAX );
Py_INCREF( Py_None );
return Py_None;
}
static PyObject *NMesh_getSubDivLevels( BPy_NMesh * self )
{
PyObject *attr =
Py_BuildValue( "[h,h]", self->subdiv[0], self->subdiv[1] );
if( attr )
return attr;
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't get NMesh.subDivLevels attribute" );
}
static PyObject *NMesh_setSubDivLevels( PyObject * self, PyObject * args )
{
short display = 0, render = 0;
BPy_NMesh *nmesh = ( BPy_NMesh * ) self;
if( !PyArg_ParseTuple( args, "(hh)", &display, &render ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected a sequence [int, int] as argument" );
nmesh->subdiv[0] =
( short ) EXPP_ClampInt( display, NMESH_SUBDIV_MIN,
NMESH_SUBDIV_MAX );
nmesh->subdiv[1] =
( short ) EXPP_ClampInt( render, NMESH_SUBDIV_MIN,
NMESH_SUBDIV_MAX );
Py_INCREF( Py_None );
return Py_None;
}
static PyObject *NMesh_getMode( BPy_NMesh * self )
{
PyObject *attr = PyInt_FromLong( self->mode );
if( attr )
return attr;
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"couldn't get NMesh.mode attribute" );
}
static PyObject *NMesh_setMode( PyObject * self, PyObject * args )
{
BPy_NMesh *nmesh = ( BPy_NMesh * ) self;
PyObject *arg1 = NULL;
char *m[5] = { NULL, NULL, NULL, NULL, NULL };
short i, mode = 0;
if( !PyArg_ParseTuple ( args, "|Ossss", &arg1, &m[1], &m[2], &m[3], &m[4] ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected an int or from none to 5 strings as argument(s)" );
if (arg1) {
if (PyInt_Check(arg1)) {
mode = (short)PyInt_AsLong(arg1);
}
else if (PyString_Check(arg1)) {
m[0] = PyString_AsString(arg1);
for( i = 0; i < 5; i++ ) {
if( !m[i] ) break;
else if( strcmp( m[i], "NoVNormalsFlip" ) == 0 )
mode |= ME_NOPUNOFLIP;
else if( strcmp( m[i], "TwoSided" ) == 0 )
mode |= ME_TWOSIDED;
else if( strcmp( m[i], "AutoSmooth" ) == 0 )
mode |= ME_AUTOSMOOTH;
else if( m[i][0] == '\0' )
mode = 0;
else
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"unknown NMesh mode" );
}
}
else return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected an int or from none to 5 strings as argument(s)" );
}
nmesh->mode = mode;
Py_INCREF( Py_None );
return Py_None;
}
/* METH_VARARGS: function(PyObject *self, PyObject *args) */
#undef MethodDef
#define MethodDef(func) {#func, NMesh_##func, METH_VARARGS, NMesh_##func##_doc}
static struct PyMethodDef NMesh_methods[] = {
MethodDef( addEdge ),
MethodDef( findEdge ),
MethodDef( removeEdge ),
MethodDef( addFace ),
MethodDef( removeFace ),
MethodDef( addVertGroup ),
MethodDef( removeVertGroup ),
MethodDef( assignVertsToGroup ),
MethodDef( removeVertsFromGroup ),
MethodDef( getVertsFromGroup ),
MethodDef( renameVertGroup ),
MethodDef( hasVertexColours ),
MethodDef( hasFaceUV ),
MethodDef( hasVertexUV ),
MethodDef( getSelectedFaces ),
MethodDef( getVertexInfluences ),
MethodDef( getMaterials ),
MethodDef( setMaterials ),
MethodDef( addMaterial ),
MethodDef( insertKey ),
MethodDef( removeAllKeys ),
MethodDef( setMode ),
MethodDef( setMaxSmoothAngle ),
MethodDef( setSubDivLevels ),
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
MethodDef( transform ),
/* METH_NOARGS: function(PyObject *self) */
#undef MethodDef
#define MethodDef(func) {#func, (PyCFunction)NMesh_##func, METH_NOARGS,\
NMesh_##func##_doc}
MethodDef( printDebug ),
MethodDef( getVertGroupNames ),
MethodDef( getActiveFace ),
MethodDef( getKey ),
MethodDef( getMode ),
MethodDef( getMaxSmoothAngle ),
MethodDef( getSubDivLevels ),
/* METH_VARARGS | METH_KEYWORDS:
* function(PyObject *self, PyObject *args, PyObject *keywords) */
#undef MethodDef
#define MethodDef(func) {#func, (PyCFunction)NMesh_##func,\
METH_VARARGS | METH_KEYWORDS, NMesh_##func##_doc}
MethodDef( update ),
{NULL, NULL, 0, NULL}
};
static PyObject *NMesh_getattr( PyObject * self, char *name )
{
BPy_NMesh *me = ( BPy_NMesh * ) self;
if( strcmp( name, "name" ) == 0 )
return EXPP_incr_ret( me->name );
else if ( strcmp( name, "properties" ) == 0 )
return BPy_Wrap_IDProperty( (ID*)me->mesh, IDP_GetProperties((ID*)me->mesh, 1), NULL );
else if( strcmp( name, "mode" ) == 0 )
return PyInt_FromLong( me->mode );
else if( strcmp( name, "block_type" ) == 0 ) /* for compatibility */
return PyString_FromString( "NMesh" );
else if( strcmp( name, "materials" ) == 0 )
return EXPP_incr_ret( me->materials );
else if( strcmp( name, "verts" ) == 0 )
return EXPP_incr_ret( me->verts );
else if( strcmp( name, "maxSmoothAngle" ) == 0 )
return PyInt_FromLong( me->smoothresh );
else if( strcmp( name, "subDivLevels" ) == 0 )
return Py_BuildValue( "[h,h]", me->subdiv[0], me->subdiv[1] );
else if( strcmp( name, "users" ) == 0 ) {
if( me->mesh ) {
return PyInt_FromLong( me->mesh->id.us );
} else { /* it's a free mesh: */
return Py_BuildValue( "i", 0 );
}
}
else if (strcmp( name, "key") == 0)
return NMesh_getKey((BPy_NMesh*)self);
else if( strcmp( name, "faces" ) == 0 )
return EXPP_incr_ret( me->faces );
else if( strcmp( name, "edges" ) == 0 )
{
return EXPP_incr_ret( me->edges );
}
else if (strcmp(name, "oopsLoc") == 0) {
if (G.soops) {
Oops *oops = G.soops->oops.first;
while(oops) {
if(oops->type==ID_ME) {
if ((Mesh *)oops->id == me->mesh) {
return (Py_BuildValue ("ff", oops->x, oops->y));
}
}
oops = oops->next;
}
}
Py_INCREF (Py_None);
return (Py_None);
}
/* Select in the oops view only since it's a mesh */
else if (strcmp(name, "oopsSel") == 0) {
if (G.soops) {
Oops *oops = G.soops->oops.first;
while(oops) {
if(oops->type==ID_ME) {
if ((Mesh *)oops->id == me->mesh) {
if (oops->flag & SELECT) {
return EXPP_incr_ret_True();
} else {
return EXPP_incr_ret_False();
}
}
}
oops = oops->next;
}
}
return EXPP_incr_ret(Py_None);
}
else if( strcmp( name, "__members__" ) == 0 )
return Py_BuildValue( "[s,s,s,s,s,s,s,s,s,s,s]",
"name", "materials", "verts", "users",
"faces", "maxSmoothAngle",
"subdivLevels", "edges", "oopsLoc", "oopsSel", "key" );
return Py_FindMethod( NMesh_methods, ( PyObject * ) self, name );
}
static int NMesh_setattr( PyObject * self, char *name, PyObject * v )
{
BPy_NMesh *me = ( BPy_NMesh * ) self;
if( !strcmp( name, "name" ) ) {
if( !PyString_Check( v ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected string argument" );
Py_DECREF( me->name );
me->name = EXPP_incr_ret( v );
}
else if( !strcmp( name, "mode" ) ) {
short mode;
if( !PyInt_Check( v ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
mode = ( short ) PyInt_AsLong( v );
if( mode >= 0 )
me->mode = mode;
else
return EXPP_ReturnIntError( PyExc_ValueError,
"expected positive int argument" );
}
else if( !strcmp( name, "verts" ) || !strcmp( name, "faces" ) ||
!strcmp( name, "materials" ) ) {
if( PySequence_Check( v ) ) {
if( strcmp( name, "materials" ) == 0 ) {
Py_DECREF( me->materials );
me->materials = EXPP_incr_ret( v );
} else if( strcmp( name, "verts" ) == 0 ) {
Py_DECREF( me->verts );
me->verts = EXPP_incr_ret( v );
} else {
Py_DECREF( me->faces );
me->faces = EXPP_incr_ret( v );
}
}
else
return EXPP_ReturnIntError( PyExc_TypeError,
BPython bug fixes: - #2781, reported by Ed Blake: crash on undo when there were active space handlers. Space Handler script links belong to screen areas, which do not get saved on undo. Thanks Ton for pointing out the function that restores ui pointers gone bad. - Applied patch #2822 by Ken Hughes for bug #2647 ("Setting a Face UV"), reported by Campbell Barton. - #3022, reported by Timothy Wakeham: "Blender.BGL.glDrawPixels crashes when drawing more pixels then buffer size". Made glDrawPixels check buffer dimensions. - #2882, reported by Campbell: crash in nmesh.getMaterials(arg == 0 or 1) when nmesh came from GetRawFromMesh(). Raw nmeshes are not linked to Blender meshes, so the method doesn't support these options (getting mat info from the actual mesh) for it. - #2817, reported by Tod Koeckeritz: Dir_Depth var was not being decremented in BPY_Menus.c, causing dir depth limits to be reached prematurely. - #2954, reported by Daniel Holtz: "Python scripts crash hard with valid windows paths". Blender.Load() was not meant for background mode, now it's been update to support it, using BKE_read_file instead of BIF_read_file in this case. Also found another issue with command line scripts using Blender.Load() that could crash Blender: trying to free the Text when it wasn't available anymore (loading a new .blend already removed it). There are still issues with one case, though, causing a crash on start or "Memoryblock winopen: double free" at end, when running a script that is already a Blender Text (only if the script calls Blender.Load, of course). Will investigate. - #2897: reported by Timothy Wakeham: object.setMaterials was asking the length of a Python list w/o confirming first if the passed obj was really a list. Thanks all for the help and for being patient (long delay, again).
2005-10-03 19:12:11 +00:00
"expected a list" );
}
else if( !strcmp( name, "maxSmoothAngle" ) ) {
short smoothresh = 0;
if( !PyInt_Check( v ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected int argument" );
smoothresh = ( short ) PyInt_AsLong( v );
me->smoothresh =
(short)EXPP_ClampInt( smoothresh, NMESH_SMOOTHRESH_MIN,
NMESH_SMOOTHRESH_MAX );
}
else if( !strcmp( name, "subDivLevels" ) ) {
int subdiv[2] = { 0, 0 };
int i;
PyObject *tmp;
if( !PySequence_Check( v ) || ( PySequence_Length( v ) != 2 ) )
return EXPP_ReturnIntError( PyExc_TypeError,
"expected a list [int, int] as argument" );
for( i = 0; i < 2; i++ ) {
tmp = PySequence_GetItem( v, i );
if( tmp ) {
if( !PyInt_Check( tmp ) ) {
Py_DECREF( tmp );
return EXPP_ReturnIntError
( PyExc_TypeError,
"expected a list [int, int] as argument" );
}
subdiv[i] = PyInt_AsLong( tmp );
me->subdiv[i] =
( short ) EXPP_ClampInt( subdiv[i],
NMESH_SUBDIV_MIN,
NMESH_SUBDIV_MAX );
Py_DECREF( tmp );
} else
return EXPP_ReturnIntError( PyExc_RuntimeError,
"couldn't retrieve subdiv values from list" );
}
}
else if( strcmp( name, "edges" ) == 0 )
{
if (PySequence_Check(v))
{
Py_DECREF(me->edges);
me->edges = EXPP_incr_ret( v );
}
}
else if (!strcmp(name, "oopsLoc")) {
if (G.soops) {
Oops *oops = G.soops->oops.first;
while(oops) {
if(oops->type==ID_ME) {
if ((Mesh *)oops->id == me->mesh) {
return (!PyArg_ParseTuple (v, "ff", &(oops->x),&(oops->y)));
}
}
oops = oops->next;
}
}
return 0;
}
/* Select in the oops view only since its a mesh */
else if (!strcmp(name, "oopsSel")) {
int sel;
if (!PyArg_Parse (v, "i", &sel))
return EXPP_ReturnIntError
(PyExc_TypeError, "expected an integer, 0 or 1");
if (G.soops) {
Oops *oops = G.soops->oops.first;
while(oops) {
if(oops->type==ID_ME) {
if ((Mesh *)oops->id == me->mesh) {
if(sel == 0) oops->flag &= ~SELECT;
else oops->flag |= SELECT;
return 0;
}
}
oops = oops->next;
}
}
return 0;
}
else
return EXPP_ReturnIntError( PyExc_AttributeError, name );
return 0;
}
PyTypeObject NMesh_Type = {
PyObject_HEAD_INIT( NULL ) 0, /*ob_size */
"Blender NMesh", /*tp_name */
sizeof( BPy_NMesh ), /*tp_basicsize */
0, /*tp_itemsize */
/* methods */
( destructor ) NMesh_dealloc, /*tp_dealloc */
( printfunc ) 0, /*tp_print */
( getattrfunc ) NMesh_getattr, /*tp_getattr */
( setattrfunc ) NMesh_setattr, /*tp_setattr */
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
};
static BPy_NMFace *nmface_from_data( BPy_NMesh * mesh, int vidxs[4],
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
char mat_nr, char flag, MTFace * tface, MCol * col )
{
BPy_NMFace *newf = PyObject_NEW( BPy_NMFace, &NMFace_Type );
int i, len;
if( vidxs[3] )
len = 4;
else
len = 3;
newf->v = PyList_New( len );
for( i = 0; i < len; i++ )
PyList_SetItem( newf->v, i,
EXPP_incr_ret( PyList_GetItem
( mesh->verts, vidxs[i] ) ) );
if( tface ) {
newf->uv = PyList_New( len ); // per-face UV coordinates
for( i = 0; i < len; i++ ) {
PyList_SetItem( newf->uv, i,
Py_BuildValue( "(ff)", tface->uv[i][0],
tface->uv[i][1] ) );
}
if( tface->tpage ) /* pointer to image per face: */
newf->image = ( Image * ) tface->tpage;
else
newf->image = NULL;
newf->mode = tface->mode; /* draw mode */
newf->flag = tface->flag; /* select flag */
newf->transp = tface->transp; /* transparency flag */
} else {
newf->mode = TF_DYNAMIC; /* just to initialize it to something meaninful, */
/* since without tfaces there are no tface->mode's, obviously. */
newf->image = NULL;
newf->uv = PyList_New( 0 );
}
newf->mat_nr = mat_nr;
newf->mf_flag = flag; /* MFace flag */
if( col ) {
newf->col = PyList_New( 4 );
for( i = 0; i < 4; i++, col++ ) {
PyList_SetItem( newf->col, i,
( PyObject * ) newcol( col->b, col->g,
col->r,
col->a ) );
}
} else
newf->col = PyList_New( 0 );
return newf;
}
static BPy_NMEdge *nmedge_from_index( BPy_NMesh * mesh, int v0idx, int v1idx)
{
BPy_NMVert *v1=(BPy_NMVert *)PyList_GetItem( mesh->verts, v0idx);
BPy_NMVert *v2=(BPy_NMVert *)PyList_GetItem( mesh->verts, v1idx);
return new_NMEdge(v1, v2, (char)0.0, 0);
}
static BPy_NMEdge *nmedge_from_data( BPy_NMesh * mesh, MEdge *edge )
{
BPy_NMVert *v1=(BPy_NMVert *)PyList_GetItem( mesh->verts, edge->v1 );
BPy_NMVert *v2=(BPy_NMVert *)PyList_GetItem( mesh->verts, edge->v2 );
return new_NMEdge(v1, v2, edge->crease, edge->flag);
}
static BPy_NMVert *nmvert_from_data( MVert * vert, MSticky * st, float *co,
int idx, char flag )
{
BPy_NMVert *mv = PyObject_NEW( BPy_NMVert, &NMVert_Type );
mv->co[0] = co[0];
mv->co[1] = co[1];
mv->co[2] = co[2];
mv->no[0] = (float)(vert->no[0] / 32767.0);
mv->no[1] = (float)(vert->no[1] / 32767.0);
mv->no[2] = (float)(vert->no[2] / 32767.0);
if( st ) {
mv->uvco[0] = st->co[0];
mv->uvco[1] = st->co[1];
mv->uvco[2] = 0.0;
} else
mv->uvco[0] = mv->uvco[1] = mv->uvco[2] = 0.0;
mv->index = idx;
mv->flag = flag & 1;
return mv;
}
static int get_active_faceindex( Mesh * me )
{
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
MTFace *tf;
int i;
if( me == NULL )
return -1;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
tf = me->mtface;
if( tf == 0 )
return -1;
for( i = 0; i < me->totface; i++ )
if( tf[i].flag & TF_ACTIVE )
return i;
return -1;
}
2005-08-01 06:01:24 +00:00
static BPy_NMVert *nmvert_from_float(float *co, float *no, int idx) {
BPy_NMVert *mv;
mv = PyObject_NEW( BPy_NMVert, &NMVert_Type );
mv->index = idx;
mv->co[0] = co[0];
mv->co[1] = co[1];
mv->co[2] = co[2];
mv->no[0] = no[0];
mv->no[1] = no[1];
mv->no[2] = no[2];
mv->uvco[0] = mv->uvco[1] = mv->uvco[2] = 0.0;
mv->flag = 0;
return mv;
}
static BPy_NMFace *nmface_from_index( BPy_NMesh * mesh, int vidxs[4], char mat_nr )
{
BPy_NMFace *newf = PyObject_NEW( BPy_NMFace, &NMFace_Type );
int i, len;
if( vidxs[3] )
len = 4;
else if( vidxs[2] )
len = 3;
else
len = 2;
newf->v = PyList_New( len );
for( i = 0; i < len; i++ )
PyList_SetItem( newf->v, i,
EXPP_incr_ret( PyList_GetItem
( mesh->verts, vidxs[i] ) ) );
newf->mode = TF_DYNAMIC; /* just to initialize it to something meaninful, */
/* since without tfaces there are no tface->mode's, obviously. */
newf->image = NULL;
newf->uv = PyList_New( 0 );
newf->mat_nr = mat_nr;
newf->mf_flag = 0;
newf->col = PyList_New( 0 );
return newf;
}
/* RATHER EVIL FUNCTION BORROWED FROM fix_faceindices IN editmesh.c */
static void correctFaceIndex(int vidx[4])
{
if (vidx[3]) {
if (vidx[1] == 0) {
vidx[1] = vidx[2];
vidx[2] = vidx[3];
vidx[3] = vidx[0];
vidx[0] = 0;
}
if (vidx[2] == 0) {
int t = vidx[1];
vidx[2] = vidx[0];
vidx[1] = vidx[3];
vidx[3] = t;
vidx[0] = 0;
}
if (vidx[3] == 0) {
vidx[3] = vidx[2];
vidx[2] = vidx[1];
vidx[1] = vidx[0];
vidx[0] = 0;
}
}
else if (vidx[1] == 0) {
vidx[1] = vidx[2];
vidx[2] = vidx[0];
vidx[0] = 0;
}
else if (vidx[2] == 0) {
vidx[2] = vidx[1];
vidx[1] = vidx[0];
vidx[0] = 0;
}
}
/*
CREATES A NMESH FROM DISPLIST DATA. INSPIRED BY THE FUNCTIONS CALLED WHEN
CONVERTING OBJECTS TO MESH.
*/
static PyObject *new_NMesh_displist(ListBase *lb, Object *ob)
{
BPy_NMesh *me;
DispList *dl;
float *data, *ndata;
float normal[3] = {1, 0, 0};
int vidx[4];
int parts, p1, p2, p3, p4, a, b, one_normal=0, ioffset=0;
int *index;
/* Note: This routine does not create new edges for the faces
* it adds... should be fixed for consistency.
*/
2005-08-01 06:01:24 +00:00
if (ob->type == OB_CURVE || ob->type == OB_FONT)
one_normal = 1;
me = PyObject_NEW( BPy_NMesh, &NMesh_Type );
me->name = EXPP_incr_ret( Py_None );
me->flags = 0;
me->mode = ME_TWOSIDED; /* default for new meshes */
me->subdiv[0] = NMESH_SUBDIV;
me->subdiv[1] = NMESH_SUBDIV;
me->smoothresh = NMESH_SMOOTHRESH;
me->edges = PyList_New( 0 );
2005-08-01 06:01:24 +00:00
me->object = ob;
me->materials = EXPP_PyList_fromMaterialList( ob->mat, ob->totcol, 0 );
me->verts = PyList_New( 0 );
me->faces = PyList_New( 0 );
dl= lb->first;
while(dl) {
parts= dl->parts;
index= dl->index;
data= dl->verts;
ndata= dl->nors;
switch(dl->type) {
case DL_SEGM:
for(a=0; a<dl->parts*dl->nr; a++, data+=3) {
PyList_Append(me->verts, ( PyObject * ) nmvert_from_float(data, normal, a));
}
vidx[2] = vidx[3] = 0;
for(a=0; a<dl->parts; a++) {
for(b=1; b<dl->nr; b++) {
int v0 = ioffset + a * dl->nr + b-1;
int v1 = ioffset + a * dl->nr + b;
PyList_Append(me->edges, ( PyObject * ) nmedge_from_index(me, v0, v1));
2005-08-01 06:01:24 +00:00
}
}
ioffset += dl->parts * dl->nr;
break;
case DL_POLY:
for(a=0; a<dl->parts*dl->nr; a++, data+=3) {
PyList_Append(me->verts, ( PyObject * ) nmvert_from_float(data, normal, a));
}
vidx[2] = vidx[3] = 0;
for(a=0; a<dl->parts; a++) {
for(b=0; b<dl->nr; b++) {
int v1, v0 = ioffset + a * dl->nr + b;
if(b==dl->nr-1) v1 = ioffset + a * dl->nr;
else v1= ioffset + a * dl->nr + b+1;
PyList_Append(me->edges, ( PyObject * ) nmedge_from_index(me, v0, v1));
2005-08-01 06:01:24 +00:00
}
}
ioffset += dl->parts * dl->nr;
break;
case DL_SURF:
for(a=0; a<dl->parts*dl->nr; a++, data+=3, ndata+=3) {
PyList_Append(me->verts, ( PyObject * ) nmvert_from_float(data, ndata, a));
}
for(a=0; a<dl->parts; a++) {
DL_SURFINDEX(dl->flag & DL_CYCL_U, dl->flag & DL_CYCL_V, dl->nr, dl->parts);
for(; b<dl->nr; b++) {
vidx[0] = p2 + ioffset;
vidx[1] = p1 + ioffset;
vidx[2] = p3 + ioffset;
vidx[3] = p4 + ioffset;
correctFaceIndex(vidx);
PyList_Append(me->faces, ( PyObject * ) nmface_from_index(me, vidx, (char)dl->col));
p2 = p1;
p4 = p3;
p1++;
p3++;
}
}
ioffset += dl->parts * dl->nr;
break;
case DL_INDEX3:
if (one_normal)
for(a=0; a<dl->nr; a++, data+=3)
PyList_Append(me->verts, ( PyObject * ) nmvert_from_float(data, ndata, a));
else
for(a=0; a<dl->nr; a++, data+=3, ndata+=3)
PyList_Append(me->verts, ( PyObject * ) nmvert_from_float(data, ndata, a));
while(parts--) {
vidx[0] = index[0] + ioffset;
vidx[1] = index[1] + ioffset;
vidx[2] = index[2] + ioffset;
vidx[3] = 0;
correctFaceIndex(vidx);
PyList_Append(me->faces, ( PyObject * ) nmface_from_index(me, vidx, (char)dl->col));
index+= 3;
}
ioffset += dl->nr;
break;
case DL_INDEX4:
for(a=0; a<dl->nr; a++, data+=3, ndata+=3) {
PyList_Append(me->verts, ( PyObject * ) nmvert_from_float(data, ndata, a));
}
while(parts--) {
vidx[0] = index[0] + ioffset;
vidx[1] = index[1] + ioffset;
vidx[2] = index[2] + ioffset;
vidx[3] = index[3] + ioffset;
correctFaceIndex(vidx);
PyList_Append(me->faces, ( PyObject * ) nmface_from_index(me, vidx, (char)dl->col));
index+= 4;
}
ioffset += dl->nr;
break;
}
dl= dl->next;
}
return ( PyObject * ) me;
}
static PyObject *new_NMesh_internal( Mesh * oldmesh,
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
DerivedMesh *dm )
{
BPy_NMesh *me = PyObject_NEW( BPy_NMesh, &NMesh_Type );
me->flags = 0;
me->mode = ME_TWOSIDED; /* default for new meshes */
me->subdiv[0] = NMESH_SUBDIV;
me->subdiv[1] = NMESH_SUBDIV;
me->smoothresh = NMESH_SMOOTHRESH;
me->object = NULL; /* not linked to any object yet */
if( !oldmesh ) {
me->name = EXPP_incr_ret( Py_None );
me->materials = PyList_New( 0 );
me->verts = PyList_New( 0 );
me->edges = PyList_New( 0 );
me->faces = PyList_New( 0 );
me->mesh = 0;
} else {
MVert *mverts;
MSticky *msticky;
MFace *mfaces;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
MTFace *tfaces;
MCol *mcols;
MEdge *medges;
int i, totvert, totface, totedge;
me->name = PyString_FromString( oldmesh->id.name + 2 );
me->mesh = oldmesh;
me->mode = oldmesh->flag; /* yes, we save the mesh flags in nmesh->mode */
me->subdiv[0] = oldmesh->subdiv;
me->subdiv[1] = oldmesh->subdivr;
me->smoothresh = oldmesh->smoothresh;
me->sel_face = get_active_faceindex( oldmesh );
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
if( dm ) {
msticky = NULL;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
mverts = dm->getVertArray(dm);
mfaces = dm->getFaceArray(dm);
tfaces = dm->getFaceDataArray(dm, CD_MTFACE);
mcols = dm->getFaceDataArray(dm, CD_MCOL);
medges = dm->getEdgeArray(dm);
totvert = dm->getNumVerts(dm);
totedge = dm->getNumEdges(dm);
totface = dm->getNumFaces(dm);;
} else {
msticky = oldmesh->msticky;
mverts = oldmesh->mvert;
mfaces = oldmesh->mface;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
tfaces = oldmesh->mtface;
mcols = oldmesh->mcol;
medges = oldmesh->medge;
totvert = oldmesh->totvert;
totface = oldmesh->totface;
totedge = oldmesh->totedge;
}
if( msticky )
me->flags |= NMESH_HASVERTUV;
if( tfaces )
me->flags |= NMESH_HASFACEUV;
if( mcols )
me->flags |= NMESH_HASMCOL;
me->verts = PyList_New( totvert );
for( i = 0; i < totvert; i++ ) {
MVert *oldmv = &mverts[i];
MSticky *oldst = msticky ? &msticky[i] : NULL;
PyList_SetItem( me->verts, i,
( PyObject * ) nmvert_from_data( oldmv,
oldst,
oldmv->co,
i,
oldmv->flag ) );
}
me->faces = PyList_New( totface );
for( i = 0; i < totface; i++ ) {
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
MTFace *oldtf = tfaces ? &tfaces[i] : NULL;
MCol *oldmc = mcols ? &mcols[i * 4] : NULL;
MFace *oldmf = &mfaces[i];
int vidxs[4];
vidxs[0] = oldmf->v1;
vidxs[1] = oldmf->v2;
vidxs[2] = oldmf->v3;
vidxs[3] = oldmf->v4;
PyList_SetItem( me->faces, i,
( PyObject * ) nmface_from_data( me,
vidxs,
oldmf->
mat_nr,
oldmf->
flag,
oldtf,
oldmc ) );
}
me->edges = PyList_New( totedge );
for( i = 0; i < totedge; i++ )
2005-08-01 06:01:24 +00:00
{
MEdge *edge = &medges[i];
PyList_SetItem( me->edges, i, (PyObject*)nmedge_from_data ( me, edge ) );
2005-08-01 06:01:24 +00:00
}
2005-08-01 06:01:24 +00:00
me->materials = EXPP_PyList_fromMaterialList( oldmesh->mat, oldmesh->totcol, 0 );
}
return ( PyObject * ) me;
}
PyObject *new_NMesh( Mesh * oldmesh )
{
return new_NMesh_internal( oldmesh, NULL );
}
static PyObject *M_NMesh_New( PyObject * self, PyObject * args )
{
char *name = NULL;
PyObject *ret = NULL;
if( !PyArg_ParseTuple( args, "|s", &name ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected nothing or a string as argument" );
ret = new_NMesh( NULL );
if( ret && name ) {
BPy_NMesh *nmesh = ( BPy_NMesh * ) ret;
Py_DECREF( nmesh->name );
nmesh->name = PyString_FromString( name );
}
return ret;
}
static PyObject *M_NMesh_GetRaw( PyObject * self, PyObject * args )
{
char *name = NULL;
Mesh *oldmesh = NULL;
if( !PyArg_ParseTuple( args, "|s", &name ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument (or nothing)" );
if( name ) {
oldmesh = ( Mesh * ) GetIdFromList( &( G.main->mesh ), name );
if( !oldmesh )
return EXPP_incr_ret( Py_None );
}
return new_NMesh( oldmesh );
}
BPython: bug fixes / patches from trackers (excuse me for not committing earlier) Patches by Ken Hughes (thanks for all bug fixes!): 1) Setting a scene's MapOld and MapNew values in python does nothing: bug #2566 submitted by Dominic Agoro-Ombaka (dmao): https://projects.blender.org/tracker/?func=detail&aid=2566&group_id=9&atid=125 patch #2571: https://projects.blender.org/tracker/index.php?func=detail&aid=2571&group_id=9&atid=127 2) Calling the file selector after setting the progress bar crashes Blender: bug #2418 submitted by Alessandro Garosi (brandano): https://projects.blender.org/tracker/?func=detail&aid=2418&group_id=9&atid=125 patch #2568: https://projects.blender.org/tracker/index.php?func=detail&aid=2568&group_id=9&atid=127 3) Menus always generate same event when canceled: bug #2429 submitted by Campbell Barton: https://projects.blender.org/tracker/?func=detail&aid=2429&group_id=9&atid=125 patch #2579: https://projects.blender.org/tracker/?func=detail&aid=2579&group_id=9&atid=127 4) Add a vertex to a mesh with groups using a script and then edit that mesh hangs blender: bug #2211 reported by German Alonso Tamayo (servivo): https://projects.blender.org/tracker/index.php?func=detail&aid=2211&group_id=9&atid=125 patch #2580 #https://projects.blender.org/tracker/index.php?func=detail&aid=2580&group_id=9&atid=127 About bug #2033, I'm still looking at it, committing a small fix now. ===== Patches by Campbell Barton (thanks!): #2482: BGL pydocs fix broken links https://projects.blender.org/tracker/index.php?func=detail&aid=2482&group_id=9&atid=127 #2426: Large text in Draw.Text and Draw.GetStreingWidth https://projects.blender.org/tracker/index.php?func=detail&aid=2462&group_id=9&atid=127 #2521: scene.getActiveObject() https://projects.blender.org/tracker/index.php?func=detail&aid=2521&group_id=9&atid=127 #2523: NMesh.GetNames() https://projects.blender.org/tracker/index.php?func=detail&aid=2523&group_id=9&atid=127 - docs also updated
2005-05-20 05:14:03 +00:00
static PyObject *M_NMesh_GetNames(PyObject *self)
{
PyObject *names = PyList_New(0);
Mesh *me = G.main->mesh.first;
while (me) {
PyList_Append(names, PyString_FromString(me->id.name+2));
me = me->id.next;
}
return names;
}
/* Note: NMesh.GetRawFromObject gets the display list mesh from Blender:
* the vertices are already transformed / deformed. */
static PyObject *M_NMesh_GetRawFromObject( PyObject * self, PyObject * args )
{
Object *ob;
PyObject *nmesh;
2005-08-01 06:01:24 +00:00
ListBase *lb=0;
DispList *dl;
char *name;
if( !PyArg_ParseTuple( args, "s", &name ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
ob = ( Object * ) GetIdFromList( &( G.main->object ), name );
if( !ob )
return EXPP_ReturnPyObjError( PyExc_AttributeError, name );
2005-08-01 06:01:24 +00:00
switch (ob->type) {
case OB_MBALL:
if( is_basis_mball(ob)) {
lb= &ob->disp;
if(lb->first==0) makeDispListMBall(ob);
nmesh = new_NMesh_displist(lb, ob);
}
else {
return EXPP_ReturnPyObjError( PyExc_AttributeError, "Object does not have geometry data" );
}
break;
case OB_FONT:
case OB_CURVE:
{
Curve *cu= ob->data;
lb= &cu->disp;
if(lb->first==0) makeDispListCurveTypes(ob, 0);
2005-08-01 06:01:24 +00:00
dl= lb->first;
if(dl==0)
return EXPP_ReturnPyObjError( PyExc_AttributeError, "Object does not have geometry data" );
if(dl->nors==0) addnormalsDispList(ob, lb);
nmesh = new_NMesh_displist(lb, ob);
}
break;
case OB_SURF:
lb= &((Curve *)ob->data)->disp;
if(lb->first==0) makeDispListCurveTypes(ob, 0);
2005-08-01 06:01:24 +00:00
dl= lb->first;
if(dl==0)
return EXPP_ReturnPyObjError( PyExc_AttributeError, "Object does not have geometry data" );
if(dl->nors==0) addnormalsDispList(ob, lb);
nmesh = new_NMesh_displist(lb, ob);
break;
case OB_MESH:
{
DerivedMesh *dm = mesh_create_derived_render( ob );
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
nmesh = new_NMesh_internal( ob->data, dm );
dm->release(dm);
2005-08-01 06:01:24 +00:00
}
break;
default:
return EXPP_ReturnPyObjError( PyExc_AttributeError, "Object does not have geometry data" );
}
/* @hack: to mark that (deformed) mesh is readonly, so the update function
* will not try to write it. */
( ( BPy_NMesh * ) nmesh )->mesh = 0;
return nmesh;
}
static void mvert_from_data( MVert * mv, MSticky * st, BPy_NMVert * from )
{
mv->co[0] = from->co[0];
mv->co[1] = from->co[1];
mv->co[2] = from->co[2];
mv->no[0] = (short)(from->no[0] * 32767.0);
mv->no[1] = (short)(from->no[1] * 32767.0);
mv->no[2] = (short)(from->no[2] * 32767.0);
mv->flag = ( from->flag & 1 );
mv->mat_nr = 0;
if( st ) {
st->co[0] = from->uvco[0];
st->co[1] = from->uvco[1];
}
}
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
static int assignFaceUV( MTFace * tf, BPy_NMFace * nmface )
{
PyObject *fuv, *tmp;
int i;
int len;
fuv = nmface->uv;
/* if no UV info, allows things to proceed as normal */
if( PySequence_Length( fuv ) == 0 ) {
tf->uv[0][0] = 0.0f; tf->uv[0][1] = 1.0f;
tf->uv[1][0] = 0.0f; tf->uv[1][1] = 0.0f;
tf->uv[2][0] = 1.0f; tf->uv[2][1] = 0.0f;
tf->uv[3][1] = 1.0f; tf->uv[3][1] = 1.0f;
return 1;
}
/* if there are too many uv coordinates, only take the first 4 */
len = PySequence_Length( fuv );
if( len > 4 )
len = 4;
/* fuv = [(u_1, v_1), ... (u_n, v_n)] */
for( i = 0; i < len; i++ ) {
tmp = PyList_GetItem( fuv, i ); /* stolen reference ! */
if( !PyArg_ParseTuple
( tmp, "ff", &( tf->uv[i][0] ), &( tf->uv[i][1] ) ) ) {
PyErr_SetString ( PyExc_TypeError,
"expected tuple of two floats for uv" );
return 0;
}
}
if( nmface->image ) { /* image assigned ? */
tf->tpage = ( void * ) nmface->image;
} else
tf->tpage = 0;
tf->mode = nmface->mode; /* copy mode */
tf->flag = (char)nmface->flag; /* copy flag */
tf->transp = nmface->transp; /* copy transp flag */
return 1;
}
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
static int mface_from_data( MFace * mf, CustomData *fdata, int findex,
BPy_NMFace * from )
{
BPy_NMVert *nmv;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
MTFace *tf = CustomData_get(fdata, findex, CD_MTFACE);
MCol *col = CustomData_get(fdata, findex, CD_MCOL);
int numverts = PyList_Size( from->v );
if( numverts != 3 && numverts != 4 ) { /* face can only have three or four verts */
PyErr_SetString ( PyExc_RuntimeError,
"faces must have at 3 or 4 vertices" );
return 0;
}
nmv = ( BPy_NMVert * ) PyList_GetItem( from->v, 0 );
if( BPy_NMVert_Check( nmv ) && nmv->index != -1 )
mf->v1 = nmv->index;
else
mf->v1 = 0;
nmv = ( BPy_NMVert * ) PyList_GetItem( from->v, 1 );
if( BPy_NMVert_Check( nmv ) && nmv->index != -1 )
mf->v2 = nmv->index;
else
mf->v2 = 0;
nmv = ( BPy_NMVert * ) PyList_GetItem( from->v, 2 );
if( BPy_NMVert_Check( nmv ) && nmv->index != -1 )
mf->v3 = nmv->index;
else
mf->v3 = 0;
if( numverts == 4 ) {
nmv = ( BPy_NMVert * ) PyList_GetItem( from->v, 3 );
if( BPy_NMVert_Check( nmv ) && nmv->index != -1 )
mf->v4 = nmv->index;
else
mf->v4 = 0;
}
if( tf )
if( !assignFaceUV( tf, from ) )
return 0;
mf->mat_nr = from->mat_nr;
mf->flag = from->mf_flag;
if( col ) {
int i, len = PySequence_Length( from->col );
if( len > 4 )
len = 4;
for( i = 0; i < len; i++, col++ ) {
BPy_NMCol *mc =
( BPy_NMCol * ) PySequence_GetItem( from->col,
i );
if( !BPy_NMCol_Check( mc ) ) {
Py_DECREF( mc );
continue;
}
col->b = mc->r;
col->g = mc->g;
col->r = mc->b;
col->a = mc->a;
Py_DECREF( mc );
}
}
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
test_index_face(mf, fdata, findex, numverts);
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
return 1;
}
/* check for a valid UV sequence */
static int check_validFaceUV( BPy_NMesh * nmesh )
{
PyObject *faces;
BPy_NMFace *nmface;
int i, n;
faces = nmesh->faces;
for( i = 0; i < PySequence_Length( faces ); i++ ) {
nmface = ( BPy_NMFace * ) PyList_GetItem( faces, i );
n = PySequence_Length( nmface->uv );
if( n != PySequence_Length( nmface->v ) ) {
if( n > 0 )
printf( "Warning: different length of vertex and UV coordinate " "list in face!\n" );
return 0;
}
}
return 1;
}
/* this is a copy of unlink_mesh in mesh.c, because ... */
static void EXPP_unlink_mesh( Mesh * me )
{
int a;
if( me == 0 )
return;
for( a = 0; a < me->totcol; a++ ) {
if( me->mat[a] )
me->mat[a]->id.us--;
me->mat[a] = 0;
}
/* ... here we want to preserve mesh keys */
/* if users want to get rid of them, they can use mesh.removeAllKeys() */
/*
if(me->key) me->key->id.us--;
me->key= 0;
*/
if( me->texcomesh )
me->texcomesh = 0;
me->totcol = 0;
}
static int unlink_existingMeshData( Mesh * mesh )
{
MDeformVert *dvert= NULL;
EXPP_unlink_mesh( mesh );
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
if(mesh->dvert) {
/* we don't want to remove dvert here, check_dverts still needs it */
dvert= mesh->dvert;
CustomData_set_layer( &mesh->vdata, CD_MDEFORMVERT, NULL );
}
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
CustomData_free( &mesh->vdata, mesh->totvert );
CustomData_free( &mesh->edata, mesh->totedge );
CustomData_free( &mesh->fdata, mesh->totface );
mesh_update_customdata_pointers( mesh );
if(dvert)
mesh->dvert= CustomData_add_layer( &mesh->vdata, CD_MDEFORMVERT, 0,
dvert, mesh->totvert );
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
mesh->totedge = 0;
if( mesh->mat ) {
MEM_freeN( mesh->mat );
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
mesh->mat = NULL;
}
return 1;
}
Material **nmesh_updateMaterials( BPy_NMesh * nmesh )
{
Material **matlist;
Mesh *mesh = nmesh->mesh;
int len = PyList_Size( nmesh->materials );
if( !mesh ) {
printf( "FATAL INTERNAL ERROR: illegal call to updateMaterials()\n" );
return 0;
}
if( len > 0 ) {
matlist = EXPP_newMaterialList_fromPyList( nmesh->materials );
EXPP_incr_mats_us( matlist, len );
if( mesh->mat )
MEM_freeN( mesh->mat );
mesh->mat = matlist;
} else {
matlist = 0;
}
mesh->totcol = (short)len;
/**@ This is another ugly fix due to the weird material handling of blender.
* it makes sure that object material lists get updated (by their length)
* according to their data material lists, otherwise blender crashes.
* It just stupidly runs through all objects...BAD BAD BAD.
*/
test_object_materials( ( ID * ) mesh );
return matlist;
}
PyObject *NMesh_assignMaterials_toObject( BPy_NMesh * nmesh, Object * ob )
{
BPy_Material *pymat;
Material *ma;
int i;
short old_matmask;
Mesh *mesh = nmesh->mesh;
int nmats; /* number of mats == len(nmesh->materials) */
old_matmask = ob->colbits; /*@ HACK: save previous colbits */
ob->colbits = 0; /* make assign_material work on mesh linked material */
nmats = PyList_Size( nmesh->materials );
if( nmats > 0 && !mesh->mat ) {
ob->totcol = (char)nmats;
mesh->totcol = (short)nmats;
mesh->mat =
MEM_callocN( sizeof( void * ) * nmats, "bpy_memats" );
if( ob->mat )
MEM_freeN( ob->mat );
ob->mat =
MEM_callocN( sizeof( void * ) * nmats, "bpy_obmats" );
}
for( i = 0; i < nmats; i++ ) {
pymat = ( BPy_Material * ) PySequence_GetItem( nmesh->
materials, i );
if( Material_CheckPyObject( ( PyObject * ) pymat ) ) {
ma = pymat->material;
assign_material( ob, ma, i + 1 ); /*@ XXX don't use this function anymore */
} else {
Py_DECREF( pymat );
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected Material type in attribute list 'materials'!" );
}
Py_DECREF( pymat );
}
ob->colbits = old_matmask; /*@ HACK */
ob->actcol = 1;
return EXPP_incr_ret( Py_None );
}
static void fill_medge_from_nmesh(Mesh * mesh, BPy_NMesh * nmesh)
{
int i,j;
MEdge *faces_edges=NULL;
int tot_faces_edges=0;
int tot_valid_faces_edges=0;
int nmeshtotedges=PyList_Size(nmesh->edges);
int tot_valid_nmedges=0;
BPy_NMEdge **valid_nmedges=NULL;
valid_nmedges=MEM_callocN(nmeshtotedges*sizeof(BPy_NMEdge *), "make BPy_NMEdge");
/* First compute the list of edges that exists because faces exists */
make_edges(mesh, 0); /* 0 = draw all edges */
faces_edges=mesh->medge;
tot_faces_edges=mesh->totedge;
tot_valid_faces_edges=tot_faces_edges;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
mesh->medge= CustomData_set_layer(&mesh->edata, CD_MEDGE, NULL);
CustomData_free_layer(&mesh->edata, CD_MEDGE, mesh->totedge);
mesh->totedge = 0;
/* Flag each edge in faces_edges that is already in nmesh->edges list.
* Flaging an edge means MEdge v1=v2=0.
* Each time an edge is flagged, tot_valid_faces_edges is decremented.
*
* Also store in valid_nmedges pointers to each valid NMEdge in nmesh->edges.
* An invalid NMEdge is an edge that has a vertex that is not in the vertices
* list. Ie its index is -1.
* Each time an valid NMEdge is flagged, tot_valid_nmedges is incremented.
*/
for( i = 0; i < nmeshtotedges; ++i )
{
int v1idx,v2idx;
BPy_NMEdge *edge=( BPy_NMEdge *) PyList_GetItem(nmesh->edges, i);
BPy_NMVert *v=(BPy_NMVert *)edge->v1;
v1idx=v->index;
v=(BPy_NMVert *)edge->v2;
v2idx=v->index;
if (-1 == v1idx || -1 == v2idx) continue;
valid_nmedges[tot_valid_nmedges]=edge;
++tot_valid_nmedges;
for( j = 0; j < tot_faces_edges; j++ )
{
MEdge *me=faces_edges+j;
if ( ((int)me->v1==v1idx && (int)me->v2==v2idx) ||
((int)me->v1==v2idx && (int)me->v2==v1idx) )
{
me->v1=0; me->v2=0;
--tot_valid_faces_edges;
}
}
}
/* tot_valid_faces_edges < 0 causes a sigsegv crash, so we
* clamp to prevent it
* (this is related to faces (correctly) requiring at least 3 verts now,
* which can break old scripts -- maybe we should also warn about the
* 'broken' mesh the user created, but for now, until we investigate
* better, this should do) */
if (tot_valid_faces_edges < 0) tot_valid_faces_edges = 0;
/* Now we have the total count of valid edges */
mesh->totedge=tot_valid_nmedges+tot_valid_faces_edges;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
mesh->medge= CustomData_add_layer(&mesh->edata, CD_MEDGE, 0, NULL, mesh->totedge);
for ( i = 0; i < tot_valid_nmedges; ++i )
{
BPy_NMEdge *edge=valid_nmedges[i];
MEdge *medge=mesh->medge+i;
int v1=((BPy_NMVert *)edge->v1)->index;
int v2=((BPy_NMVert *)edge->v2)->index;
medge->v1=v1;
medge->v2=v2;
medge->flag=edge->flag;
medge->crease=edge->crease;
}
for ( i = 0, j = tot_valid_nmedges; i < tot_faces_edges; ++i )
{
MEdge *edge=faces_edges+i;
if (edge->v1!=0 || edge->v2!=0) // valid edge
{
MEdge *medge=mesh->medge+j;
medge->v1=edge->v1;
medge->v2=edge->v2;
medge->flag=ME_EDGEDRAW|ME_EDGERENDER;
medge->crease=0;
++j;
}
}
MEM_freeN( valid_nmedges );
MEM_freeN( faces_edges );
}
/* this should ensure meshes don't end up with wrongly sized
* me->dvert arrays, which can cause hangs; it's not ideal,
* it's better to wrap dverts in NMesh, but it should do for now
* since there are also methods in NMesh to edit dverts in the actual
* mesh in Blender and anyway this is memory friendly */
static void check_dverts(Mesh *me, int old_totvert)
{
int totvert = me->totvert;
/* if vert count didn't change or there are no dverts, all is fine */
if ((totvert == old_totvert) || (!me->dvert)) return;
/* if all verts have been deleted, free old dverts */
else if (totvert == 0) {
CustomData_free_layer( &me->vdata, CD_MDEFORMVERT, old_totvert );
me->dvert= NULL;
}
else {
/* verts added or removed, make new me->dvert */
MDeformVert *mdv = MEM_callocN( sizeof(MDeformVert)*totvert, "mdv" );
copy_dverts( mdv, me->dvert, MIN2( old_totvert, totvert ) );
free_dverts( me->dvert, old_totvert );
me->dvert= CustomData_set_layer( &me->vdata, CD_MDEFORMVERT, mdv );
}
}
static int convert_NMeshToMesh( Mesh * mesh, BPy_NMesh * nmesh)
{
MFace *newmf;
MVert *newmv;
MSticky *newst;
int nmeshtotedges;
int i, j, ok;
/* Minor note: we used 'mode' because 'flag' was already used internally
* by nmesh */
mesh->flag = nmesh->mode;
mesh->smoothresh = nmesh->smoothresh;
mesh->subdiv = nmesh->subdiv[0];
mesh->subdivr = nmesh->subdiv[1];
/*@ material assignment moved to PutRaw */
mesh->totvert = PySequence_Length( nmesh->verts );
if( mesh->totvert ) {
if( nmesh->flags & NMESH_HASVERTUV )
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
mesh->msticky = CustomData_add_layer( &mesh->vdata, CD_MSTICKY, 0,
NULL, mesh->totvert );
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
mesh->mvert = CustomData_add_layer( &mesh->vdata, CD_MVERT, 0, NULL,
mesh->totvert );
}
if( mesh->totvert )
mesh->totface = PySequence_Length( nmesh->faces );
else
mesh->totface = 0;
if( mesh->totface ) {
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
if( nmesh->flags & NMESH_HASMCOL )
mesh->mcol = CustomData_add_layer( &mesh->fdata, CD_MCOL, 0, NULL,
mesh->totface );
mesh->mface = CustomData_add_layer( &mesh->fdata, CD_MFACE, 0, NULL,
mesh->totface );
}
/*@ This stuff here is to tag all the vertices referenced
* by faces, then untag the vertices which are actually
* in the vert list. Any vertices untagged will be ignored
* by the mface_from_data function. It comes from my
* screwed up decision to not make faces only store the
* index. - Zr
*/
for( i = 0; i < mesh->totface; i++ ) {
BPy_NMFace *mf =
( BPy_NMFace * ) PySequence_GetItem( nmesh->faces, i );
j = PySequence_Length( mf->v );
while( j-- ) {
BPy_NMVert *mv =
( BPy_NMVert * ) PySequence_GetItem( mf->v,
j );
if( BPy_NMVert_Check( mv ) )
mv->index = -1;
Py_DECREF( mv );
}
Py_DECREF( mf );
}
/* do the same for edges if there is edge data */
nmeshtotedges=PyList_Size(nmesh->edges);
for( i = 0; i < nmeshtotedges; ++i )
{
BPy_NMEdge *edge=( BPy_NMEdge *) PyList_GetItem(nmesh->edges, i);
BPy_NMVert *v=(BPy_NMVert *)edge->v1;
v->index=-1;
v=(BPy_NMVert *)edge->v2;
v->index=-1;
}
for( i = 0; i < mesh->totvert; i++ ) {
BPy_NMVert *mv =
( BPy_NMVert * ) PySequence_GetItem( nmesh->verts, i );
mv->index = i;
Py_DECREF( mv );
}
newmv = mesh->mvert;
newst = mesh->msticky;
for( i = 0; i < mesh->totvert; i++ ) {
PyObject *mv = PySequence_GetItem( nmesh->verts, i );
mvert_from_data( newmv, newst, ( BPy_NMVert * ) mv );
Py_DECREF( mv );
newmv++;
if( newst )
newst++;
}
/* assign per face texture UVs */
/* check face UV flag, then check whether there was one
* UV coordinate assigned, if yes, make tfaces */
if( ( nmesh->flags & NMESH_HASFACEUV )
|| ( check_validFaceUV( nmesh ) ) ) {
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
make_tfaces( mesh ); /* initialize MTFaces */
nmesh->flags |= NMESH_HASFACEUV;
Added custom vertex/edge/face data for meshes: All data layers, including MVert/MEdge/MFace, are now managed as custom data layers. The pointers like Mesh.mvert, Mesh.dvert or Mesh.mcol are still used of course, but allocating, copying or freeing these arrays should be done through the CustomData API. Work in progress documentation on this is here: http://mediawiki.blender.org/index.php/BlenderDev/BlenderArchitecture/CustomData Replaced TFace by MTFace: This is the same struct, except that it does not contain color, that now always stays separated in MCol. This was not a good design decision to begin with, and it is needed for adding multiple color layers later. Note that this does mean older Blender versions will not be able to read UV coordinates from the next release, due to an SDNA limitation. Removed DispListMesh: This now fully replaced by DerivedMesh. To provide access to arrays of vertices, edges and faces, like DispListMesh does. The semantics of the DerivedMesh.getVertArray() and similar functions were changed to return a pointer to an array if one exists, or otherwise allocate a temporary one. On releasing the DerivedMesh, this temporary array will be removed automatically. Removed ssDM and meshDM DerivedMesh backends: The ssDM backend was for DispListMesh, so that became obsolete automatically. The meshDM backend was replaced by the custom data backend, that now figures out which layers need to be modified, and only duplicates those. This changes code in many places, and overall removes 2514 lines of code. So, there's a good chance this might break some stuff, although I've been testing it for a few days now. The good news is, adding multiple color and uv layers should now become easy.
2006-11-20 04:28:02 +00:00
}
newmf = mesh->mface;
for( i = 0; i < mesh->totface; i++ ) {
PyObject *mf = PySequence_GetItem( nmesh->faces, i );
ok = mface_from_data( newmf, &mesh->fdata, i, ( BPy_NMFace * ) mf );
Py_DECREF( mf );
if( !ok )
return 0;
newmf++;
}
/* Always do this to ensure no loose edges in faces */
fill_medge_from_nmesh(mesh, nmesh);
return 1;
}
static PyObject *M_NMesh_PutRaw( PyObject * self, PyObject * args )
{
char *name = NULL;
Mesh *mesh = NULL;
Object *ob = NULL;
BPy_NMesh *nmesh;
int recalc_normals = 1;
int store_edges = 0;
int old_totvert = 0;
if( !PyArg_ParseTuple( args, "O!|sii",
&NMesh_Type, &nmesh, &name, &recalc_normals, &store_edges ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"expected an NMesh object and optionally also a string and two ints" );
if( check_NMeshLists( nmesh ) )
return NULL;
if( name )
mesh = ( Mesh * ) GetIdFromList( &( G.main->mesh ), name );
if( !mesh || mesh->id.us == 0 ) {
ob = add_object( OB_MESH );
if( !ob ) {
PyErr_SetString( PyExc_RuntimeError,
Note: this commit includes new functionality to save and restore scripts configure options. This is ongoing work, scripts still have to be updated to use this feature and more tests are needed, though many have been performed. The new Scripts Config Editor script is the main part of this. If anyone wants to check it, only the AC3D importer and exporter have already been updated to use it: simply open them (you can then cancel with ESC) to have the data created, then try the config editor. Scripts: - Thanks Jean-Michel Soler (jms) for updated versions of dispaint, fixfromarmature and unweld (also renamed to remove version part). - Thanks Bart for the upgraded VRML exporter (great doc webpage!). It is available as VRML 97 and the original VRML 2 is for now still there, to help users testing the new version. For the next release the old one should be removed, of course. - New script: Scripts Config Editor (Scripts win -> Scripts -> System). Scripts with config options (simple data that is to be set according to user needs or preferences) can use this facility instead of providing a gui and writing config files to disk themselves. - Added new menu: System, available in the Scripts win. - Updated sys_info.py, help_browse.py and the AC3D importer and exporter. - Removed use of the Scrollbar and added arrow keys and mouse wheel support instead in Daniel Dunbar's old doc_browser.py. The scrollbar events handling doesn't exist, Ton suggested removing the scrollbar from the API months ago. For now its ref doc is gone and no bundled script uses it, until we get time to implement it properly. - Added module BPyRegistry.py with functions to handle reading / writing config files automatically to the scripts/bpydata/config dir. - Removing dir release/bpydata and its contents (moved earlier to release/scripts/bpydata/) - Bug #2379: made small changes to bevel_center's ui to fix a problem reported by Alexander Ewering (intrr): http://projects.blender.org/tracker/?func=detail&atid=125&aid=2379&group_id=9 BPython: - Thanks Campbell Barton for new functionality: Blender.Get() now can also return all the paths from the user prefs -> file paths win and there is a new function: Blender.sys.expandpath() to transform Blender paths (those starting with '//' and ending with '#') to absolute paths. - Added function Blender.ShowHelp(), to open the Scripts Help Browser with a given help page -- just a time saver for scripts. - Improved function Blender.Run() to also work with gui and file select scripts. - Found a (new?) crash related to NMesh.PutRaw when creating a new object while in edit mode. Leaving / entering edit mode fixes the problem, so a check for obj created, edit mode and leaving / re-entering it were added to the code for now (gdb didn't help much, no backtrace) - doc updates, including splitting intro page in two, with bpython related stuff (registering / documenting / configuring scripts and command line mode (thanks Chris Want for "use system variables to pass parameters to scripts" idea). - Registry: functions have been updated to support writing to / reading from disk, for the config editor -- only simple config data supported, for large amounts coders should write to a file themselves. This is done with a new parameter: Registry.GetKey(keyname, True) will also search for the key on the config dir, if not already loaded; equiv. for Registry.SetKey(keyname, dict, True). Data is only written to / read from disk when needed and only scripts already used (assuming they support this functionality) will have config data saved.
2005-04-16 05:25:42 +00:00
"Fatal: could not create mesh object" );
return 0;
}
if( !mesh )
mesh = ( Mesh * ) ob->data;
else
set_mesh( ob, mesh ); // also does id.us++
2005-08-01 06:01:24 +00:00
nmesh->object = ob; // linking so vgrouping methods know which obj to work on
}
if( name )
new_id( &( G.main->mesh ), &mesh->id, name );
else if( nmesh->name && nmesh->name != Py_None )
new_id( &( G.main->mesh ), &mesh->id,
PyString_AsString( nmesh->name ) );
old_totvert = mesh->totvert;
unlink_existingMeshData( mesh );
if( !convert_NMeshToMesh( mesh, nmesh ) )
return NULL;
nmesh->mesh = mesh;
if (mesh->dvert) check_dverts(mesh, old_totvert);
if( recalc_normals )
mesh_calc_normals(mesh->mvert, mesh->totvert, mesh->mface, mesh->totface, NULL);
mesh_update( mesh, nmesh->object );
if( !during_script( ) )
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
EXPP_allqueue( REDRAWVIEW3D, 0 );
Note: this commit includes new functionality to save and restore scripts configure options. This is ongoing work, scripts still have to be updated to use this feature and more tests are needed, though many have been performed. The new Scripts Config Editor script is the main part of this. If anyone wants to check it, only the AC3D importer and exporter have already been updated to use it: simply open them (you can then cancel with ESC) to have the data created, then try the config editor. Scripts: - Thanks Jean-Michel Soler (jms) for updated versions of dispaint, fixfromarmature and unweld (also renamed to remove version part). - Thanks Bart for the upgraded VRML exporter (great doc webpage!). It is available as VRML 97 and the original VRML 2 is for now still there, to help users testing the new version. For the next release the old one should be removed, of course. - New script: Scripts Config Editor (Scripts win -> Scripts -> System). Scripts with config options (simple data that is to be set according to user needs or preferences) can use this facility instead of providing a gui and writing config files to disk themselves. - Added new menu: System, available in the Scripts win. - Updated sys_info.py, help_browse.py and the AC3D importer and exporter. - Removed use of the Scrollbar and added arrow keys and mouse wheel support instead in Daniel Dunbar's old doc_browser.py. The scrollbar events handling doesn't exist, Ton suggested removing the scrollbar from the API months ago. For now its ref doc is gone and no bundled script uses it, until we get time to implement it properly. - Added module BPyRegistry.py with functions to handle reading / writing config files automatically to the scripts/bpydata/config dir. - Removing dir release/bpydata and its contents (moved earlier to release/scripts/bpydata/) - Bug #2379: made small changes to bevel_center's ui to fix a problem reported by Alexander Ewering (intrr): http://projects.blender.org/tracker/?func=detail&atid=125&aid=2379&group_id=9 BPython: - Thanks Campbell Barton for new functionality: Blender.Get() now can also return all the paths from the user prefs -> file paths win and there is a new function: Blender.sys.expandpath() to transform Blender paths (those starting with '//' and ending with '#') to absolute paths. - Added function Blender.ShowHelp(), to open the Scripts Help Browser with a given help page -- just a time saver for scripts. - Improved function Blender.Run() to also work with gui and file select scripts. - Found a (new?) crash related to NMesh.PutRaw when creating a new object while in edit mode. Leaving / entering edit mode fixes the problem, so a check for obj created, edit mode and leaving / re-entering it were added to the code for now (gdb didn't help much, no backtrace) - doc updates, including splitting intro page in two, with bpython related stuff (registering / documenting / configuring scripts and command line mode (thanks Chris Want for "use system variables to pass parameters to scripts" idea). - Registry: functions have been updated to support writing to / reading from disk, for the config editor -- only simple config data supported, for large amounts coders should write to a file themselves. This is done with a new parameter: Registry.GetKey(keyname, True) will also search for the key on the config dir, if not already loaded; equiv. for Registry.SetKey(keyname, dict, True). Data is only written to / read from disk when needed and only scripts already used (assuming they support this functionality) will have config data saved.
2005-04-16 05:25:42 +00:00
if (ob && G.obedit) { /* prevents a crash when a new object is created */
exit_editmode(EM_FREEDATA);
enter_editmode(0);
Note: this commit includes new functionality to save and restore scripts configure options. This is ongoing work, scripts still have to be updated to use this feature and more tests are needed, though many have been performed. The new Scripts Config Editor script is the main part of this. If anyone wants to check it, only the AC3D importer and exporter have already been updated to use it: simply open them (you can then cancel with ESC) to have the data created, then try the config editor. Scripts: - Thanks Jean-Michel Soler (jms) for updated versions of dispaint, fixfromarmature and unweld (also renamed to remove version part). - Thanks Bart for the upgraded VRML exporter (great doc webpage!). It is available as VRML 97 and the original VRML 2 is for now still there, to help users testing the new version. For the next release the old one should be removed, of course. - New script: Scripts Config Editor (Scripts win -> Scripts -> System). Scripts with config options (simple data that is to be set according to user needs or preferences) can use this facility instead of providing a gui and writing config files to disk themselves. - Added new menu: System, available in the Scripts win. - Updated sys_info.py, help_browse.py and the AC3D importer and exporter. - Removed use of the Scrollbar and added arrow keys and mouse wheel support instead in Daniel Dunbar's old doc_browser.py. The scrollbar events handling doesn't exist, Ton suggested removing the scrollbar from the API months ago. For now its ref doc is gone and no bundled script uses it, until we get time to implement it properly. - Added module BPyRegistry.py with functions to handle reading / writing config files automatically to the scripts/bpydata/config dir. - Removing dir release/bpydata and its contents (moved earlier to release/scripts/bpydata/) - Bug #2379: made small changes to bevel_center's ui to fix a problem reported by Alexander Ewering (intrr): http://projects.blender.org/tracker/?func=detail&atid=125&aid=2379&group_id=9 BPython: - Thanks Campbell Barton for new functionality: Blender.Get() now can also return all the paths from the user prefs -> file paths win and there is a new function: Blender.sys.expandpath() to transform Blender paths (those starting with '//' and ending with '#') to absolute paths. - Added function Blender.ShowHelp(), to open the Scripts Help Browser with a given help page -- just a time saver for scripts. - Improved function Blender.Run() to also work with gui and file select scripts. - Found a (new?) crash related to NMesh.PutRaw when creating a new object while in edit mode. Leaving / entering edit mode fixes the problem, so a check for obj created, edit mode and leaving / re-entering it were added to the code for now (gdb didn't help much, no backtrace) - doc updates, including splitting intro page in two, with bpython related stuff (registering / documenting / configuring scripts and command line mode (thanks Chris Want for "use system variables to pass parameters to scripts" idea). - Registry: functions have been updated to support writing to / reading from disk, for the config editor -- only simple config data supported, for large amounts coders should write to a file themselves. This is done with a new parameter: Registry.GetKey(keyname, True) will also search for the key on the config dir, if not already loaded; equiv. for Registry.SetKey(keyname, dict, True). Data is only written to / read from disk when needed and only scripts already used (assuming they support this functionality) will have config data saved.
2005-04-16 05:25:42 +00:00
}
// @OK...this requires some explanation:
// Materials can be assigned two ways:
// a) to the object data (in this case, the mesh)
// b) to the Object
//
// Case a) is wanted, if Mesh data should be shared among objects,
// as well as its materials (up to 16)
// Case b) is wanted, when Mesh data should be shared, but not the
// materials. For example, you want several checker boards sharing their
// mesh data, but having different colors. So you would assign material
// index 0 to all even, index 1 to all odd faces and bind the materials
// to the Object instead (MaterialButtons: [OB] "link materials to object")
//
// This feature implies that pointers to materials can be stored in
// an object or a mesh. The number of total materials MUST be
// synchronized (ob->totcol <-> mesh->totcol). We avoid the dangerous
// direct access by calling blenderkernel/material.c:assign_material().
// The flags setting the material binding is found in ob->colbits, where
// each bit indicates the binding PER MATERIAL
if( ob ) { // we created a new object
NMesh_assignMaterials_toObject( nmesh, ob );
EXPP_synchronizeMaterialLists( ob );
return Object_CreatePyObject( ob );
} else {
mesh->mat =
EXPP_newMaterialList_fromPyList( nmesh->materials );
EXPP_incr_mats_us( mesh->mat,
PyList_Size( nmesh->materials ) );
return EXPP_incr_ret( Py_None );
}
2003-10-12 16:13:12 +00:00
}
#undef MethodDef
#define MethodDef(func) \
{#func, M_NMesh_##func, METH_VARARGS, M_NMesh_##func##_doc}
static struct PyMethodDef M_NMesh_methods[] = {
MethodDef( Col ),
MethodDef( Vert ),
MethodDef( Face ),
MethodDef( New ),
MethodDef( GetRaw ),
MethodDef( GetRawFromObject ),
MethodDef( PutRaw ),
BPython: bug fixes / patches from trackers (excuse me for not committing earlier) Patches by Ken Hughes (thanks for all bug fixes!): 1) Setting a scene's MapOld and MapNew values in python does nothing: bug #2566 submitted by Dominic Agoro-Ombaka (dmao): https://projects.blender.org/tracker/?func=detail&aid=2566&group_id=9&atid=125 patch #2571: https://projects.blender.org/tracker/index.php?func=detail&aid=2571&group_id=9&atid=127 2) Calling the file selector after setting the progress bar crashes Blender: bug #2418 submitted by Alessandro Garosi (brandano): https://projects.blender.org/tracker/?func=detail&aid=2418&group_id=9&atid=125 patch #2568: https://projects.blender.org/tracker/index.php?func=detail&aid=2568&group_id=9&atid=127 3) Menus always generate same event when canceled: bug #2429 submitted by Campbell Barton: https://projects.blender.org/tracker/?func=detail&aid=2429&group_id=9&atid=125 patch #2579: https://projects.blender.org/tracker/?func=detail&aid=2579&group_id=9&atid=127 4) Add a vertex to a mesh with groups using a script and then edit that mesh hangs blender: bug #2211 reported by German Alonso Tamayo (servivo): https://projects.blender.org/tracker/index.php?func=detail&aid=2211&group_id=9&atid=125 patch #2580 #https://projects.blender.org/tracker/index.php?func=detail&aid=2580&group_id=9&atid=127 About bug #2033, I'm still looking at it, committing a small fix now. ===== Patches by Campbell Barton (thanks!): #2482: BGL pydocs fix broken links https://projects.blender.org/tracker/index.php?func=detail&aid=2482&group_id=9&atid=127 #2426: Large text in Draw.Text and Draw.GetStreingWidth https://projects.blender.org/tracker/index.php?func=detail&aid=2462&group_id=9&atid=127 #2521: scene.getActiveObject() https://projects.blender.org/tracker/index.php?func=detail&aid=2521&group_id=9&atid=127 #2523: NMesh.GetNames() https://projects.blender.org/tracker/index.php?func=detail&aid=2523&group_id=9&atid=127 - docs also updated
2005-05-20 05:14:03 +00:00
{"GetNames", (PyCFunction)M_NMesh_GetNames, METH_NOARGS,
M_NMesh_GetNames_doc},
{NULL, NULL, 0, NULL}
};
static PyObject *M_NMesh_Modes( void )
{
PyObject *Modes = PyConstant_New( );
if( Modes ) {
BPy_constant *d = ( BPy_constant * ) Modes;
PyConstant_Insert( d, "NOVNORMALSFLIP",
PyInt_FromLong
( ME_NOPUNOFLIP ) );
PyConstant_Insert( d, "TWOSIDED",
PyInt_FromLong( ME_TWOSIDED ) );
PyConstant_Insert( d, "AUTOSMOOTH",
PyInt_FromLong
( ME_AUTOSMOOTH ) );
}
return Modes;
}
#undef EXPP_ADDCONST
#define EXPP_ADDCONST(dict, name) \
PyConstant_Insert(dict, #name, PyInt_FromLong(TF_##name))
/* Set constants for face drawing mode -- see drawmesh.c */
static PyObject *M_NMesh_FaceModesDict( void )
{
PyObject *FM = PyConstant_New( );
if( FM ) {
BPy_constant *d = ( BPy_constant * ) FM;
PyConstant_Insert( d, "BILLBOARD",
PyInt_FromLong( TF_BILLBOARD2 ) );
PyConstant_Insert( d, "ALL", PyInt_FromLong( 0x7fff ) );
PyConstant_Insert( d, "HALO", PyInt_FromLong( TF_BILLBOARD ) );
PyConstant_Insert( d, "DYNAMIC", PyInt_FromLong( TF_DYNAMIC ) );
PyConstant_Insert( d, "INVISIBLE", PyInt_FromLong( TF_INVISIBLE ) );
PyConstant_Insert( d, "LIGHT", PyInt_FromLong( TF_LIGHT ) );
PyConstant_Insert( d, "OBCOL", PyInt_FromLong( TF_OBCOL ) );
PyConstant_Insert( d, "SHADOW", PyInt_FromLong( TF_SHADOW ) );
PyConstant_Insert( d, "TEXT", PyInt_FromLong( TF_BMFONT ) );
PyConstant_Insert( d, "SHAREDVERT", PyInt_FromLong( TF_SHAREDVERT ) );
PyConstant_Insert( d, "SHAREDCOL", PyInt_FromLong( TF_SHAREDCOL ) );
PyConstant_Insert( d, "TEX", PyInt_FromLong( TF_TEX ) );
PyConstant_Insert( d, "TILES", PyInt_FromLong( TF_TILES ) );
PyConstant_Insert( d, "TWOSIDE", PyInt_FromLong( TF_TWOSIDE ) );
}
return FM;
}
static PyObject *M_NMesh_FaceFlagsDict( void )
{
PyObject *FF = PyConstant_New( );
if( FF ) {
BPy_constant *d = ( BPy_constant * ) FF;
EXPP_ADDCONST( d, SELECT );
EXPP_ADDCONST( d, HIDE );
EXPP_ADDCONST( d, ACTIVE );
}
return FF;
}
static PyObject *M_NMesh_FaceTranspModesDict( void )
{
PyObject *FTM = PyConstant_New( );
if( FTM ) {
BPy_constant *d = ( BPy_constant * ) FTM;
EXPP_ADDCONST( d, SOLID );
EXPP_ADDCONST( d, ADD );
EXPP_ADDCONST( d, ALPHA );
EXPP_ADDCONST( d, SUB );
}
return FTM;
}
static PyObject *M_NMesh_EdgeFlagsDict( void )
{
PyObject *EF = PyConstant_New( );
if( EF ) {
BPy_constant *d = ( BPy_constant * ) EF;
PyConstant_Insert(d, "SELECT", PyInt_FromLong(1));
PyConstant_Insert(d, "EDGEDRAW", PyInt_FromLong(ME_EDGEDRAW));
PyConstant_Insert(d, "EDGERENDER", PyInt_FromLong(ME_EDGERENDER));
PyConstant_Insert(d, "SEAM", PyInt_FromLong(ME_SEAM));
PyConstant_Insert(d, "FGON", PyInt_FromLong(ME_FGON));
}
return EF;
}
PyObject *NMesh_Init( void )
{
PyObject *submodule;
PyObject *Modes = M_NMesh_Modes( );
PyObject *FaceFlags = M_NMesh_FaceFlagsDict( );
PyObject *FaceModes = M_NMesh_FaceModesDict( );
PyObject *FaceTranspModes = M_NMesh_FaceTranspModesDict( );
PyObject *EdgeFlags = M_NMesh_EdgeFlagsDict( );
NMCol_Type.ob_type = &PyType_Type;
NMFace_Type.ob_type = &PyType_Type;
NMVert_Type.ob_type = &PyType_Type;
NMesh_Type.ob_type = &PyType_Type;
submodule =
Py_InitModule3( "Blender.NMesh", M_NMesh_methods,
M_NMesh_doc );
if( Modes )
PyModule_AddObject( submodule, "Modes", Modes );
if( FaceFlags )
PyModule_AddObject( submodule, "FaceFlags", FaceFlags );
if( FaceModes )
PyModule_AddObject( submodule, "FaceModes", FaceModes );
if( FaceTranspModes )
PyModule_AddObject( submodule, "FaceTranspModes",
FaceTranspModes );
if( EdgeFlags )
PyModule_AddObject( submodule, "EdgeFlags", EdgeFlags );
g_nmeshmodule = submodule;
return submodule;
}
/* These are needed by Object.c */
PyObject *NMesh_CreatePyObject( Mesh * me, Object * ob )
{
BPy_NMesh *nmesh = ( BPy_NMesh * ) new_NMesh( me );
if( nmesh )
nmesh->object = ob; /* linking nmesh and object for vgrouping methods */
return ( PyObject * ) nmesh;
}
int NMesh_CheckPyObject( PyObject * pyobj )
{
return ( pyobj->ob_type == &NMesh_Type );
}
Mesh *NMesh_FromPyObject( PyObject * pyobj, Object * ob )
{
if( pyobj->ob_type == &NMesh_Type ) {
Mesh *mesh;
BPy_NMesh *nmesh = ( BPy_NMesh * ) pyobj;
if( nmesh->mesh ) {
mesh = nmesh->mesh;
} else {
mesh = Mesh_fromNMesh( nmesh );
if( !mesh ) /* NULL means an PyError */
return NULL;
nmesh->mesh = mesh;
nmesh->object = ob; /* linking for vgrouping methods */
if( nmesh->name && nmesh->name != Py_None )
new_id( &( G.main->mesh ), &mesh->id,
PyString_AsString( nmesh->name ) );
mesh_update( mesh, nmesh->object );
nmesh_updateMaterials( nmesh );
}
return mesh;
}
PyErr_SetString( PyExc_AttributeError,
"link argument type is not supported " );
return NULL;
}
2003-10-12 16:13:12 +00:00
#define POINTER_CROSS_EQ(a1, a2, b1, b2) (((a1)==(b1) && (a2)==(b2)) || ((a1)==(b2) && (a2)==(b1)))
static PyObject *findEdge( BPy_NMesh *nmesh, BPy_NMVert *v1, BPy_NMVert *v2, int create)
{
int i;
for ( i = 0; i < PyList_Size(nmesh->edges); ++i )
{
BPy_NMEdge *edge=(BPy_NMEdge*)PyList_GetItem( nmesh->edges, i );
if (!BPy_NMEdge_Check(edge)) continue;
if ( POINTER_CROSS_EQ((BPy_NMVert*)edge->v1, (BPy_NMVert*)edge->v2, v1, v2) )
{
return EXPP_incr_ret((PyObject*)edge);
}
}
/* if this line is reached, edge has not been found */
if (create)
{
PyObject *newEdge=(PyObject *)new_NMEdge(v1, v2, 0, ME_EDGEDRAW|ME_EDGERENDER);
PyList_Append(nmesh->edges, newEdge);
return newEdge;
}
else
return EXPP_incr_ret( Py_None );
}
static void removeEdge( BPy_NMesh *nmesh, BPy_NMVert *v1, BPy_NMVert *v2, int ununsedOnly)
{
int i,j;
BPy_NMEdge *edge=NULL;
int edgeUsedByFace=0;
int totedge=PyList_Size(nmesh->edges);
/* find the edge in the edge list */
for ( i = 0; i < totedge; ++i )
{
edge=(BPy_NMEdge*)PyList_GetItem( nmesh->edges, i );
if (!BPy_NMEdge_Check(edge)) continue;
if ( POINTER_CROSS_EQ((BPy_NMVert*)edge->v1, (BPy_NMVert*)edge->v2, v1, v2) )
{
break;
}
}
if (i==totedge || !edge) // edge not found
return;
for ( j = PyList_Size(nmesh->faces)-1; j >= 0 ; --j )
{
BPy_NMFace *face=(BPy_NMFace *)PyList_GetItem(nmesh->faces, j);
int k, del_face=0;
int totv;
if (!BPy_NMFace_Check(face)) continue;
totv=PyList_Size(face->v);
if (totv<2) continue;
for ( k = 0; k < totv && !del_face; ++k )
{
BPy_NMVert *fe_v1=(BPy_NMVert *)PyList_GetItem(face->v, k ? k-1 : totv-1);
BPy_NMVert *fe_v2=(BPy_NMVert *)PyList_GetItem(face->v, k);
if ( POINTER_CROSS_EQ(v1, v2, fe_v1, fe_v2) )
{
edgeUsedByFace=1;
del_face=1;
}
}
if (del_face && !ununsedOnly)
{
PySequence_DelItem(nmesh->faces, j);
}
}
if (!ununsedOnly || (ununsedOnly && !edgeUsedByFace) )
PySequence_DelItem(nmesh->edges, PySequence_Index(nmesh->edges, (PyObject*)edge));
}
static PyObject *NMesh_addEdge( PyObject * self, PyObject * args )
{
BPy_NMesh *bmesh=(BPy_NMesh *)self;
BPy_NMVert *v1=NULL, *v2=NULL;
if (!PyArg_ParseTuple
( args, "O!O!", &NMVert_Type, &v1, &NMVert_Type, &v2 ) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected NMVert, NMVert" );
}
if (v1==v2)
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"vertices must be different" );
return findEdge(bmesh, v1, v2, 1);
}
static PyObject *NMesh_findEdge( PyObject * self, PyObject * args )
{
BPy_NMesh *bmesh=(BPy_NMesh *)self;
BPy_NMVert *v1=NULL, *v2=NULL;
if (!PyArg_ParseTuple
( args, "O!O!", &NMVert_Type, &v1, &NMVert_Type, &v2 ) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected NMVert, NMVert" );
}
if (v1==v2)
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"vertices must be different" );
return findEdge(bmesh, v1, v2, 0);
}
static PyObject *NMesh_removeEdge( PyObject * self, PyObject * args )
{
BPy_NMesh *bmesh=(BPy_NMesh *)self;
BPy_NMVert *v1=NULL, *v2=NULL;
if (!PyArg_ParseTuple
( args, "O!O!", &NMVert_Type, &v1, &NMVert_Type, &v2 ) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected NMVert, NMVert" );
}
if (v1==v2)
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"vertices must be different" );
removeEdge(bmesh, v1, v2, 0);
return EXPP_incr_ret( Py_None );
}
static PyObject *NMesh_addFace( PyObject * self, PyObject * args )
{
BPy_NMesh *nmesh=(BPy_NMesh *)self;
BPy_NMFace *face;
int totv=0;
if (!PyArg_ParseTuple
( args, "O!", &NMFace_Type, &face ) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected NMFace argument" );
}
totv=PyList_Size(face->v);
/*
* Before edges data exists, having faces with two vertices was
* the only way of storing edges not attached to any face.
*/
if (totv!=2)
PyList_Append(nmesh->faces, (PyObject*)face);
if (totv>=2)
{
/* when totv==2, there is only one edge, when totv==3 there is three edges
* and when totv==4 there is four edges.
* that's why in the following line totv==2 is a special case */
PyObject *edges = PyList_New((totv==2) ? 1 : totv);
if (totv==2)
{
BPy_NMVert *fe_v1=(BPy_NMVert *)PyList_GetItem(face->v, 0);
BPy_NMVert *fe_v2=(BPy_NMVert *)PyList_GetItem(face->v, 1);
BPy_NMEdge *edge=(BPy_NMEdge *)findEdge(nmesh, fe_v1, fe_v2, 1);
PyList_SetItem(edges, 0, (PyObject*)edge); // PyList_SetItem steals the reference
}
else
{
int k;
for ( k = 0; k < totv; ++k )
{
BPy_NMVert *fe_v1=(BPy_NMVert *)PyList_GetItem(face->v, k ? k-1 : totv-1);
BPy_NMVert *fe_v2=(BPy_NMVert *)PyList_GetItem(face->v, k);
BPy_NMEdge *edge=(BPy_NMEdge *)findEdge(nmesh, fe_v1, fe_v2, 1);
PyList_SetItem(edges, k, (PyObject*)edge); // PyList_SetItem steals the reference
}
}
return edges;
}
return EXPP_incr_ret( Py_None );
}
static PyObject *NMesh_removeFace( PyObject * self, PyObject * args )
{
BPy_NMesh *nmesh=(BPy_NMesh *)self;
BPy_NMFace *face;
int totv=0;
if (!PyArg_ParseTuple
( args, "O!", &NMFace_Type, &face ) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected NMFace argument" );
}
totv=PyList_Size(face->v);
{
int index=PySequence_Index(nmesh->faces, (PyObject*)face);
if (index>=0)
PySequence_DelItem(nmesh->faces, index);
}
if (totv>=2)
{
/* when totv==2, there is only one edge, when totv==3 there is three edges
* and when totv==4 there is four edges.
* that's why in the following line totv==2 is a special case */
if (totv==2)
{
BPy_NMVert *fe_v1=(BPy_NMVert *)PyList_GetItem(face->v, 0);
BPy_NMVert *fe_v2=(BPy_NMVert *)PyList_GetItem(face->v, 1);
removeEdge(nmesh, fe_v1, fe_v2, 1);
}
else
{
int k;
for ( k = 0; k < totv; ++k )
{
BPy_NMVert *fe_v1=(BPy_NMVert *)PyList_GetItem(face->v, k ? k-1 : totv-1);
BPy_NMVert *fe_v2=(BPy_NMVert *)PyList_GetItem(face->v, k);
removeEdge(nmesh, fe_v1, fe_v2, 1);
}
}
}
return EXPP_incr_ret( Py_None );
}
static PyObject *NMesh_printDebug( PyObject * self )
{
BPy_NMesh *bmesh=(BPy_NMesh *)self;
Mesh *mesh=bmesh->mesh;
printf("**Vertices\n");
{
int i;
for (i=0; i<mesh->totvert; ++i)
{
MVert *v=mesh->mvert+i;
double x=v->co[0];
double y=v->co[1];
double z=v->co[2];
printf(" %2d : %.3f %.3f %.3f\n", i, x, y, z);
}
}
printf("**Edges\n");
{
int i;
for (i=0; i<mesh->totedge; ++i)
{
MEdge *e=mesh->medge+i;
int v1 = e->v1;
int v2 = e->v2;
int flag = e->flag;
printf(" %2d : %2d %2d flag=%d\n", i, v1, v2, flag);
}
}
printf("**Faces\n");
{
int i;
for (i=0; i<mesh->totface; ++i)
{
MFace *e=((MFace*)(mesh->mface))+i;
int v1 = e->v1;
int v2 = e->v2;
int v3 = e->v3;
int v4 = e->v4;
printf(" %2d : %2d %2d %2d %2d\n", i, v1, v2, v3, v4);
}
}
return EXPP_incr_ret( Py_None );
}
static PyObject *NMesh_addVertGroup( PyObject * self, PyObject * args )
2003-10-12 16:13:12 +00:00
{
char *groupStr;
struct Object *object;
PyObject *tempStr;
2003-10-12 16:13:12 +00:00
if( !PyArg_ParseTuple( args, "s", &groupStr ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
2003-10-12 16:13:12 +00:00
if( ( ( BPy_NMesh * ) self )->object == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"mesh must be linked to an object first..." );
2003-10-12 16:13:12 +00:00
object = ( ( BPy_NMesh * ) self )->object;
//get clamped name
tempStr = PyString_FromStringAndSize( groupStr, 32 );
groupStr = PyString_AsString( tempStr );
add_defgroup_name( object, groupStr );
2003-10-12 16:13:12 +00:00
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
EXPP_allqueue( REDRAWBUTSALL, 1 );
return EXPP_incr_ret( Py_None );
2003-10-12 16:13:12 +00:00
}
static PyObject *NMesh_removeVertGroup( PyObject * self, PyObject * args )
2003-10-12 16:13:12 +00:00
{
char *groupStr;
struct Object *object;
2003-10-12 16:13:12 +00:00
int nIndex;
bDeformGroup *pGroup;
2003-10-12 16:13:12 +00:00
if( !PyArg_ParseTuple( args, "s", &groupStr ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string argument" );
2003-10-12 16:13:12 +00:00
if( ( ( BPy_NMesh * ) self )->object == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"mesh must be linked to an object first..." );
2003-10-12 16:13:12 +00:00
object = ( ( BPy_NMesh * ) self )->object;
2003-10-12 16:13:12 +00:00
pGroup = get_named_vertexgroup( object, groupStr );
if( pGroup == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"group does not exist!" );
2003-10-12 16:13:12 +00:00
nIndex = get_defgroup_num( object, pGroup );
if( nIndex == -1 )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"no deform groups assigned to mesh" );
2003-10-12 16:13:12 +00:00
nIndex++;
object->actdef = (unsigned short)nIndex;
2003-10-12 16:13:12 +00:00
del_defgroup( object );
2003-10-12 16:13:12 +00:00
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
EXPP_allqueue( REDRAWBUTSALL, 1 );
return EXPP_incr_ret( Py_None );
2003-10-12 16:13:12 +00:00
}
static PyObject *NMesh_assignVertsToGroup( PyObject * self, PyObject * args )
2003-10-12 16:13:12 +00:00
{
//listObject is an integer list of vertex indices to add to group
2003-10-12 16:13:12 +00:00
//groupStr = group name
//weight is a float defining the weight this group has on this vertex
//assignmode = "replace", "add", "subtract"
// replace weight - add addition weight to vertex for this group
// - remove group influence from this vertex
//the function will not like it if your in editmode...
2003-10-12 16:13:12 +00:00
char *groupStr;
char *assignmodeStr = NULL;
int nIndex;
int assignmode;
float weight = 1.0;
struct Object *object;
bDeformGroup *pGroup;
PyObject *listObject;
int tempInt;
2003-10-12 16:13:12 +00:00
int x;
if( ( ( BPy_NMesh * ) self )->object == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"mesh must be linked to an object first..." );
if( !PyArg_ParseTuple
( args, "sO!fs", &groupStr, &PyList_Type, &listObject, &weight,
&assignmodeStr ) ) {
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string, list, float, string arguments" );
2003-10-12 16:13:12 +00:00
}
object = ( ( BPy_NMesh * ) self )->object;
if( object->data == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"object contains no data..." );
2003-10-12 16:13:12 +00:00
pGroup = get_named_vertexgroup( object, groupStr );
if( pGroup == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"group does not exist!" );
2003-10-12 16:13:12 +00:00
nIndex = get_defgroup_num( object, pGroup );
if( nIndex == -1 )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"no deform groups assigned to mesh" );
2003-10-12 16:13:12 +00:00
if( assignmodeStr == NULL )
assignmode = 1; /* default */
else if( STREQ( assignmodeStr, "replace" ) )
2003-10-12 16:13:12 +00:00
assignmode = 1;
else if( STREQ( assignmodeStr, "add" ) )
2003-10-12 16:13:12 +00:00
assignmode = 2;
else if( STREQ( assignmodeStr, "subtract" ) )
2003-10-12 16:13:12 +00:00
assignmode = 3;
else
return EXPP_ReturnPyObjError( PyExc_ValueError,
"bad assignment mode" );
2003-10-12 16:13:12 +00:00
//makes a set of dVerts corresponding to the mVerts
if( !( ( Mesh * ) object->data )->dvert ) {
create_dverts( object->data );
2003-10-12 16:13:12 +00:00
}
//loop list adding verts to group
for( x = 0; x < PyList_Size( listObject ); x++ ) {
if( !
( PyArg_Parse
( ( PyList_GetItem( listObject, x ) ), "i",
&tempInt ) ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"python list integer not parseable" );
2003-10-12 16:13:12 +00:00
if( tempInt < 0
|| tempInt >= ( ( Mesh * ) object->data )->totvert )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"bad vertex index in list" );
2003-10-12 16:13:12 +00:00
add_vert_defnr( object, nIndex, tempInt, weight, assignmode );
2003-10-12 16:13:12 +00:00
}
return EXPP_incr_ret( Py_None );
2003-10-12 16:13:12 +00:00
}
static PyObject *NMesh_removeVertsFromGroup( PyObject * self, PyObject * args )
2003-10-12 16:13:12 +00:00
{
//not passing a list will remove all verts from group
char *groupStr;
int nIndex;
struct Object *object;
bDeformGroup *pGroup;
PyObject *listObject;
int tempInt;
int x, argc;
/* argc is the number of parameters passed in: 1 (no list given) or 2: */
argc = PyObject_Length( args );
2003-10-12 16:13:12 +00:00
if( !PyArg_ParseTuple
( args, "s|O!", &groupStr, &PyList_Type, &listObject ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string and optional list argument" );
2003-10-12 16:13:12 +00:00
if( ( ( BPy_NMesh * ) self )->object == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"mesh must be linked to an object first..." );
2003-10-12 16:13:12 +00:00
object = ( ( BPy_NMesh * ) self )->object;
if( object->data == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"object contains no data..." );
2003-10-12 16:13:12 +00:00
if( ( !( ( Mesh * ) object->data )->dvert ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"this mesh contains no deform vertices...'" );
2003-10-12 16:13:12 +00:00
pGroup = get_named_vertexgroup( object, groupStr );
if( pGroup == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"group does not exist!" );
2003-10-12 16:13:12 +00:00
nIndex = get_defgroup_num( object, pGroup );
if( nIndex == -1 )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"no deform groups assigned to mesh" );
2003-10-12 16:13:12 +00:00
if( argc == 1 ) { /* no list given */
2003-10-12 16:13:12 +00:00
//enter editmode
if( ( G.obedit == 0 ) ) {
2003-10-12 16:13:12 +00:00
//set current object
BASACT->object = object;
G.obedit = BASACT->object;
2003-10-12 16:13:12 +00:00
}
//set current vertex group
nIndex++;
object->actdef = (unsigned short)nIndex;
2003-10-12 16:13:12 +00:00
//clear all dVerts in active group
remove_verts_defgroup( 1 );
2003-10-12 16:13:12 +00:00
//exit editmode
G.obedit = 0;
} else {
if( G.obedit != 0 ) //remove_vert_def_nr doesn't like it if your in editmode
G.obedit = 0;
2003-10-12 16:13:12 +00:00
//loop list adding verts to group
for( x = 0; x < PyList_Size( listObject ); x++ ) {
if( !
( PyArg_Parse
( ( PyList_GetItem( listObject, x ) ), "i",
&tempInt ) ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"python list integer not parseable" );
if( tempInt < 0
|| tempInt >=
( ( Mesh * ) object->data )->totvert )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"bad vertex index in list" );
remove_vert_def_nr( object, nIndex, tempInt );
2003-10-12 16:13:12 +00:00
}
}
return EXPP_incr_ret( Py_None );
2003-10-12 16:13:12 +00:00
}
static PyObject *NMesh_getVertsFromGroup( PyObject * self, PyObject * args )
2003-10-12 16:13:12 +00:00
{
//not passing a list will return all verts from group
//passing indecies not part of the group will not return data in pyList
//can be used as a index/group check for a vertex
char *groupStr;
int nIndex;
2003-10-12 16:13:12 +00:00
int weightRet;
struct Object *object;
bDeformGroup *pGroup;
2003-10-12 16:13:12 +00:00
MVert *mvert;
MDeformVert *dvert;
float weight;
int i, k, l1, l2, count;
int num = 0;
PyObject *tempVertexList = NULL;
PyObject *vertexList;
PyObject *listObject;
int tempInt;
2003-10-12 16:13:12 +00:00
int x;
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
listObject = Py_None; //can't use NULL macro because compiler thinks
//it's a 0 and we need to check 0 index vertex pos
2003-10-12 16:13:12 +00:00
l1 = FALSE;
l2 = FALSE;
weightRet = 0;
if( !PyArg_ParseTuple( args, "s|iO!", &groupStr, &weightRet,
&PyList_Type, &listObject ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"expected string and optional int and list arguments" );
2003-10-12 16:13:12 +00:00
if( weightRet < 0 || weightRet > 1 )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"return weights flag must be 0 or 1..." );
2003-10-12 16:13:12 +00:00
if( ( ( BPy_NMesh * ) self )->object == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"mesh must be linked to an object first..." );
2003-10-12 16:13:12 +00:00
object = ( ( BPy_NMesh * ) self )->object;
if( object->data == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"object contains no data..." );
2003-10-12 16:13:12 +00:00
if( ( !( ( Mesh * ) object->data )->dvert ) )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"this mesh contains no deform vertices...'" );
2003-10-12 16:13:12 +00:00
pGroup = get_named_vertexgroup( object, groupStr );
if( pGroup == NULL )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"group does not exist!" );
2003-10-12 16:13:12 +00:00
nIndex = get_defgroup_num( object, pGroup );
if( nIndex == -1 )
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"no deform groups assigned to mesh" );
2003-10-12 16:13:12 +00:00
//temporary list
tempVertexList = PyList_New( ( ( Mesh * ) object->data )->totvert );
if( tempVertexList == NULL )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"getVertsFromGroup: can't create pylist!" );
2003-10-12 16:13:12 +00:00
count = 0;
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
if( listObject == Py_None ) //do entire group
{
for( k = 0; k < ( ( Mesh * ) object->data )->totvert; k++ ) {
dvert = ( ( Mesh * ) object->data )->dvert + k;
for( i = 0; i < dvert->totweight; i++ ) {
if( dvert->dw[i].def_nr == nIndex ) {
mvert = ( ( Mesh * ) object->data )->
mvert + k;
2003-10-12 16:13:12 +00:00
weight = dvert->dw[i].weight;
//printf("index =%3d weight:%10f\n", k, weight);
if( weightRet == 1 )
PyList_SetItem( tempVertexList,
count,
Py_BuildValue
( "(i,f)", k,
weight ) );
else if( weightRet == 0 )
PyList_SetItem( tempVertexList,
count,
Py_BuildValue
( "i", k ) );
2003-10-12 16:13:12 +00:00
count++;
}
}
}
} else //do single vertex
2003-10-12 16:13:12 +00:00
{
//loop list adding verts to group
for( x = 0; x < PyList_Size( listObject ); x++ ) {
if( !
( PyArg_Parse
( ( PyList_GetItem( listObject, x ) ), "i",
&tempInt ) ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"python list integer not parseable" );
if( tempInt < 0
|| tempInt >=
( ( Mesh * ) object->data )->totvert )
return EXPP_ReturnPyObjError( PyExc_ValueError,
"bad vertex index in list" );
2003-10-12 16:13:12 +00:00
num = tempInt;
dvert = ( ( Mesh * ) object->data )->dvert + num;
for( i = 0; i < dvert->totweight; i++ ) {
2003-10-12 16:13:12 +00:00
l1 = TRUE;
if( dvert->dw[i].def_nr == nIndex ) {
2003-10-12 16:13:12 +00:00
l2 = TRUE;
mvert = ( ( Mesh * ) object->data )->
mvert + num;
2003-10-12 16:13:12 +00:00
weight = dvert->dw[i].weight;
//printf("index =%3d weight:%10f\n", num, weight);
if( weightRet == 1 ) {
PyList_SetItem( tempVertexList,
count,
Py_BuildValue
( "(i,f)", num,
weight ) );
} else if( weightRet == 0 )
PyList_SetItem( tempVertexList,
count,
Py_BuildValue
( "i", num ) );
2003-10-12 16:13:12 +00:00
count++;
}
if( l2 == FALSE )
printf( "vertex at index %d is not part of passed group...\n", tempInt );
2003-10-12 16:13:12 +00:00
}
if( l1 == FALSE )
printf( "vertex at index %d is not assigned to a vertex group...\n", tempInt );
2003-10-12 16:13:12 +00:00
l1 = l2 = FALSE; //reset flags
}
}
//only return what we need
vertexList = PyList_GetSlice( tempVertexList, 0, count );
2003-10-12 16:13:12 +00:00
Py_DECREF( tempVertexList );
return ( vertexList );
2003-10-12 16:13:12 +00:00
}
static PyObject *NMesh_renameVertGroup( PyObject * self, PyObject * args )
{
char *oldGr = NULL;
char *newGr = NULL;
bDeformGroup *defGroup = NULL;
/*PyObject *tempStr; */
if( !( ( BPy_NMesh * ) self )->object )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"This mesh must be linked to an object" );
if( !PyArg_ParseTuple( args, "ss", &oldGr, &newGr ) )
return EXPP_ReturnPyObjError( PyExc_TypeError,
"Expected string & string argument" );
defGroup =
get_named_vertexgroup( ( ( BPy_NMesh * ) self )->object,
oldGr );
if( defGroup == NULL )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Couldn't find the expected vertex group" );
PyOS_snprintf( defGroup->name, 32, newGr );
unique_vertexgroup_name( defGroup, ( ( BPy_NMesh * ) self )->object );
return EXPP_incr_ret( Py_None );
}
static PyObject *NMesh_getVertGroupNames( PyObject * self )
{
bDeformGroup *defGroup;
PyObject *list;
if( !( ( BPy_NMesh * ) self )->object )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"This mesh must be linked to an object" );
list = PyList_New( 0 );
for( defGroup = ( ( ( BPy_NMesh * ) self )->object )->defbase.first;
defGroup; defGroup = defGroup->next ) {
if( PyList_Append
( list, PyString_FromString( defGroup->name ) ) < 0 )
return EXPP_ReturnPyObjError( PyExc_RuntimeError,
"Couldn't add item to list" );
}
return list;
}
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
static PyObject *NMesh_transform (PyObject *self, PyObject *args)
{
BPy_NMesh *nmesh = ( BPy_NMesh * ) self;
BPy_NMVert *mv;
PyObject *ob1 = NULL;
MatrixObject *mat;
float vx, vy, vz;
int i, recalc_normals = 0;
if( !PyArg_ParseTuple( args, "O!|i", &matrix_Type, &ob1, &recalc_normals ) )
return ( EXPP_ReturnPyObjError( PyExc_TypeError,
"expected matrix and optionally an int as arguments" ) );
mat = ( MatrixObject * ) ob1;
if( mat->colSize != 4 || mat->rowSize != 4 )
return ( EXPP_ReturnPyObjError( PyExc_AttributeError,
"matrix must be a 4x4 transformation matrix\n"
"for example as returned by object.getMatrix()" ) );
/* loop through all the verts and transform locations by the supplied
* matrix */
for( i = 0; i < PySequence_Length(nmesh->verts); i++ ) {
mv = ( BPy_NMVert * ) PySequence_GetItem( nmesh->verts, i );
vx = mv->co[0];
vy = mv->co[1];
vz = mv->co[2];
/* Mat4MulVecfl(mat->matrix, mv->co); */
mv->co[0] = vx*mat->matrix[0][0] + vy*mat->matrix[1][0] +
vz*mat->matrix[2][0] + mat->matrix[3][0];
mv->co[1] = vx*mat->matrix[0][1] + vy*mat->matrix[1][1] +
vz*mat->matrix[2][1] + mat->matrix[3][1];
mv->co[2] = vx*mat->matrix[0][2] + vy*mat->matrix[1][2] +
vz*mat->matrix[2][2] + mat->matrix[3][2];
Py_DECREF(mv);
}
if ( recalc_normals ) {
/* loop through all the verts and transform normals by the inverse
* of the transpose of the supplied matrix */
float invmat[4][4];
/* we only need to invert a 3x3 submatrix, because the 4th component of
* affine vectors is 0, but Mat4Invert reports non invertible matrices */
if (!Mat4Invert((float(*)[4])*invmat, (float(*)[4])*mat->matrix))
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
return EXPP_ReturnPyObjError (PyExc_AttributeError,
"given matrix is not invertible");
for( i = 0; i < PySequence_Length(nmesh->verts); i++ ) {
mv = ( BPy_NMVert * ) PySequence_GetItem( nmesh->verts, i );
vx = mv->no[0];
vy = mv->no[1];
vz = mv->no[2];
mv->no[0] = vx*invmat[0][0] + vy*invmat[0][1] + vz*invmat[0][2];
mv->no[1] = vx*invmat[1][0] + vy*invmat[1][1] + vz*invmat[1][2];
mv->no[2] = vx*invmat[2][0] + vy*invmat[2][1] + vz*invmat[2][2];
BPython: - Scripts: fixed error in "Save Current Theme" which prevented it from automatically updating script registration in menus. cosmetic changes in a couple of Campbell's sel_same.py script strings + more descriptive name for its new menu place (3d view, face mode -> select menu). small updates to help_browser.py script. The above changes are related to this: - Added new script menu entries: Render (for exporters to renderers), Themes, FaceSelect (this already at the proper place). Updated Scripts win->Scripts menu so it won't show all available entries, only the ones we mean to see there. - Updated menu registration so that scripts folders can become trees. The release/scripts/ dir should be updated soon with subdirs like converters/, modifiers/, generators/ or whatever -- better discuss first (or is it? /me afraid of long irc discussions during meetings :) ). - Modules: Blender: added 'udatadir' option to .Get() function and added var Blender.mode to tell if Blender is in bg or interactive mode. NMesh: added Campbell's nmesh.transform(matrix, recalc_normals = False) method (reworked, so my fault if it doesn't work). - Bugs fixed: #2123: http://projects.blender.org/tracker/?func=detail&atid=125&aid=2123&group_id=9 Reported by Ken Hughes (thanks!), who also found the exact problem later (it was in Text.Load, not with script links -- if only I had checked emails these days ... lost > 1 hour today to find the problem: passed filename to M_Text_Load was later being written over by a function called by add_text). Also saw that Text.Load wasn't checking existence of passed filename (duh!), now it does. #1655: http://projects.blender.org/tracker/?func=detail&atid=125&aid=1655&group_id=9 Reported by Chris Want (thanks!): command line "blender -P script" not working properly for bg mode ("blender -b blendfile -P script"). Had to make some small updates to get it working (bg mode for scripts was never explicitely handled, it worked due to collateral effects, let's say), interested readers can check the report after I update it or the API_intro.py doc file. After more testing we can make further updates. Updated many places to not call redraws if in bg mode, now it is officially available. Blender outputs its own info when rendering in bg mode, if that is considered a nuissance we'll have to add a few "if (during_script())" calls outside bpython. - Removed a few warnings here and there and also updated docs.
2005-03-19 06:24:55 +00:00
Normalise(mv->no);
Py_DECREF(mv);
}
}
/* should we alternatively return a list of changed verts (and preserve
* the original ones) ? */
Py_INCREF( Py_None );
return Py_None;
}