- Stephane Soppera added long missed support for edge data in Blender.NMesh + related doc;
- Michael Reimpell improved script registration (fixes bug report #2160) and the file and image selectors in Blender.Window (improved with suggestions from Yann Vernier).  They now suppport methods as callbacks;
- World.get/setMode were not registered, so could not be directly called (reported by Ken Hughes).  Still needs some work to improve things, including docs.

Scripts:
- Jean-Michel Soler updated his texture baker based on input from Appolux;
- Campbell and Jean-Michel improved the bvh importer: faster, better float units scaling (by Campbell); supports Poser 3.01 files (by jms).

Thanks guys!
This commit is contained in:
2005-01-22 02:48:03 +00:00
parent 5822d4601d
commit 1da3b9f517
8 changed files with 1009 additions and 147 deletions

View File

@@ -2,30 +2,44 @@
"""
Name: 'Motion Capture (.bvh)...'
Blender: 232
Blender: 236
Group: 'Import'
Tip: 'Import a (.bvh) motion capture file'
"""
__author__ = "Campbell Barton"
__url__ = ("blender", "elysiun")
__version__ = "1.0 03/25/04"
__url__ = ("blender", "elysiun", "http://jmsoler.free.fr/util/blenderfile/py/bvh_import.py")
__version__ = "1.0.2 04/12/28"
__bpydoc__ = """\
This script imports BVH motion capture data to Blender.
Supported:<br>
Supported: Poser 3.01<br>
Missing:<br>
Known issues:<br>
Notes:<br>
Jean-Michel Soler improved importer to support Poser 3.01 files.
"""
# $Id$
#
#===============================================#
# BVH Import script 1.03 patched by Campbell #
# Small optimizations and scale input #
# 01/01/2005, #
#===============================================#
#===============================================#
# BVH Import script 1.02 patched by Jm Soler #
# to the Poser 3.01 bvh file #
# 28/12/2004, #
#===============================================#
#===============================================#
# BVH Import script 1.0 by Campbell Barton #
# 25/03/2004, euler rotation code taken from #
@@ -67,7 +81,7 @@ Notes:<br>
import string
import math
import Blender
from Blender import Window, Object, Scene, Ipo
from Blender import Window, Object, Scene, Ipo, Draw
from Blender.Scene import Render
@@ -80,14 +94,13 @@ from Blender.Scene import Render
#
# except:
# print 'psyco is not present on this system'
# Default scale
scale = 0.01
# Update as we load?
debug = 0
# Global scale facctor # sHOULD BE 1 BY DEFAULT
scale = 1
# Get the current scene.
scn = Scene.GetCurrent()
context = scn.getRenderingContext()
@@ -100,6 +113,9 @@ channelCurves = []
# Chenging there rotation to EULER rotation
objectList = []
def getScale():
return Draw.PupFloatInput('BVH Scale: ', 0.01, 0.001, 10.0, 0.1, 3)
def MAT(m):
if len(m) == 3:
return Blender.Mathutils.Matrix(m[0], m[1], m[2])
@@ -127,7 +143,6 @@ def eulerRotate(x,y,z):
for k in range(3):
for j in range(3):
mat3[i][k]=mat3[i][k]+mat1[i][j]*mat2[j][k]
mat1 = mat2 = i = k = j = None # Save memory
return mat3
@@ -162,7 +177,6 @@ def eulerRotate(x,y,z):
mat3[2][1]=t*y*z-s*x
mat3[2][2]=t*z*z+c
rot4 = s = c = t = x = y = z = None # Save some memory
return mat3
eul = [x,y,z]
@@ -202,8 +216,6 @@ def eulerRotate(x,y,z):
y =- eul[1]/-10
z =- eul[2]/-10
eul = mat = zmat = xmat = ymat = jj = None
return x, y, z # Returm euler roration values.
@@ -213,6 +225,7 @@ def eulerRotate(x,y,z):
# from the BVA file to create an empty #
#===============================================#
def makeJoint(name, parent, prefix, offset, channels):
global scale
# Make Empty, with the prefix in front of the name
ob = Object.New('Empty', prefix + name) # New object, ob is shorter and nicer to use.
scn.link(ob) # place the object in the current scene
@@ -253,8 +266,6 @@ def makeJoint(name, parent, prefix, offset, channels):
# Add to object list
objectList.append(ob)
ob = newIpo = opParent = None
# Redraw if debugging
if debug: Blender.Redraw()
@@ -280,13 +291,22 @@ def makeEnd(parent, prefix, offset):
#===============================================#
# MAIN FUNCTION - All things are done from here #
#===============================================#
def loadBVH(filename):
global scale
print ''
print 'BVH Importer 1.0 by Campbell Barton (Ideasman) - ideasman@linuxmail.org'
alpha='abcdefghijklmnopqrstuvewxyz'
ALPHA=alpha+alpha.upper()
ALPHA+=' 0123456789+-{}. '
time1 = Blender.sys.time()
tmpScale = getScale()
if tmpScale != None:
scale = tmpScale
# File loading stuff
# Open the file for importing
file = open(filename, 'r')
@@ -294,10 +314,19 @@ def loadBVH(filename):
# Make a list of lines
lines = []
for fileLine in fileData:
fileLine=fileLine.replace('..','.')
newLine = string.split(fileLine)
if newLine != []:
lines.append(string.split(fileLine))
fileData = None
t=[]
for n in newLine:
for n0 in n:
if n0 not in ALPHA:
n=n.replace(n0,'')
t.append(n)
lines.append(t)
del fileData
# End file loading code
# Call object names with this prefix, mainly for scenes with multiple BVH's - Can imagine most partr names are the same
@@ -320,18 +349,25 @@ def loadBVH(filename):
#channelList [(<objectName>, [channelType1, channelType2...]), (<objectName>, [channelType1, channelType2...)]
channelList = []
channelIndex = -1
lineIdx = 1 # An index for the file.
while lineIdx < len(lines) -1:
#...
if lines[lineIdx][0] == 'ROOT' or lines[lineIdx][0] == 'JOINT':
if lines[lineIdx][0] == 'JOINT' and len(lines[lineIdx])>2:
for j in range(2,len(lines[lineIdx])) :
lines[lineIdx][1]+='_'+lines[lineIdx][j]
# MAY NEED TO SUPPORT MULTIPLE ROOT's HERE!!!, Still unsure weather multiple roots are possible.??
print len(parent) * ' ' + 'node:',lines[lineIdx][1],' parent:',parent[-1]
print lineIdx
name = lines[lineIdx][1]
print name,lines[lineIdx+1],lines[lineIdx+2]
lineIdx += 2 # Incriment to the next line (Offset)
offset = ( eval(lines[lineIdx][1]), eval(lines[lineIdx][2]), eval(lines[lineIdx][3]) )
offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
lineIdx += 1 # Incriment to the next line (Channels)
# newChannel[Xposition, Yposition, Zposition, Xrotation, Yrotation, Zrotation]
@@ -367,7 +403,7 @@ def loadBVH(filename):
# Account for an end node
if lines[lineIdx][0] == 'End' and lines[lineIdx][1] == 'Site': # There is somtimes a name afetr 'End Site' but we will ignore it.
lineIdx += 2 # Incriment to the next line (Offset)
offset = ( eval(lines[lineIdx][1]), eval(lines[lineIdx][2]), eval(lines[lineIdx][3]) )
offset = ( float(lines[lineIdx][1]), float(lines[lineIdx][2]), float(lines[lineIdx][3]) )
makeEnd(parent, prefix, offset)
# Just so we can remove the Parents in a uniform way- End end never has kids
@@ -431,21 +467,46 @@ def loadBVH(filename):
if debug: Blender.Redraw()
while obIdx < len(objectList) -1:
if channelList[obIdx][0] != -1:
objectList[obIdx].getIpo().getCurve('LocX').addBezier((currentFrame, scale * eval(lines[lineIdx][channelList[obIdx][0]])))
VAL0=lines[lineIdx][channelList[obIdx][0]]
if VAL0.find('.')==-1:
VAL0=VAL0[:len(VAL0)-6]+'.'+VAL0[-6:]
objectList[obIdx].getIpo().getCurve('LocX').addBezier((currentFrame, scale * float(VAL0)))
if channelList[obIdx][1] != -1:
objectList[obIdx].getIpo().getCurve('LocY').addBezier((currentFrame, scale * eval(lines[lineIdx][channelList[obIdx][1]])))
VAL1=lines[lineIdx][channelList[obIdx][0]]
if VAL1.find('.')==-1:
VAL1=VAL1[:len(VAL1)-6]+'.'+VAL1[-6:]
objectList[obIdx].getIpo().getCurve('LocY').addBezier((currentFrame, scale * float(VAL1)))
if channelList[obIdx][2] != -1:
objectList[obIdx].getIpo().getCurve('LocZ').addBezier((currentFrame, scale * eval(lines[lineIdx][channelList[obIdx][2]])))
VAL2=lines[lineIdx][channelList[obIdx][0]]
if VAL2.find('.')==-1:
VAL2=VAL2[:len(VAL2)-6]+'.'+VAL2[-6:]
objectList[obIdx].getIpo().getCurve('LocZ').addBezier((currentFrame, scale * float(VAL2)))
if channelList[obIdx][3] != '-1' or channelList[obIdx][4] != '-1' or channelList[obIdx][5] != '-1':
x, y, z = eulerRotate(eval(lines[lineIdx][channelList[obIdx][3]]), eval(lines[lineIdx][channelList[obIdx][4]]), eval(lines[lineIdx][channelList[obIdx][5]]))
VAL3=lines[lineIdx][channelList[obIdx][3]]
if VAL3.find('.')==-1:
VAL3=VAL3[:len(VAL3)-6]+'.'+VAL3[-6:]
VAL4=lines[lineIdx][channelList[obIdx][4]]
if VAL4.find('.')==-1:
VAL4=VAL4[:len(VAL4)-6]+'.'+VAL4[-6:]
VAL5=lines[lineIdx][channelList[obIdx][5]]
if VAL5.find('.')==-1:
VAL5=VAL5[:len(VAL5)-6]+'.'+VAL5[-6:]
x, y, z = eulerRotate(float(VAL3), float(VAL4), float(VAL5))
objectList[obIdx].getIpo().getCurve('RotX').addBezier((currentFrame, x))
objectList[obIdx].getIpo().getCurve('RotY').addBezier((currentFrame, y))
objectList[obIdx].getIpo().getCurve('RotZ').addBezier((currentFrame, z))
obIdx += 1
# Done importing motion data #
lines[lineIdx] = None # Scrap old motion data, save some memory?
# lines[lineIdx] = None # Scrap old motion data, save some memory?
lineIdx += 1
# We have finished now
print currentFrame, 'done.'
@@ -457,5 +518,6 @@ def loadBVH(filename):
# Main file loop
lineIdx += 1
print "bvh import time: ", Blender.sys.time() - time1
Blender.Window.FileSelector(loadBVH, "Import BVH")

View File

@@ -11,7 +11,7 @@ __author__ = "Jean-Michel Soler (jms)"
__url__ = ("blender", "elysiun",
"Script online, http://jmsoler.free.fr/util/blenderfile/py/text2uvbaker.py",
"Communicate problems and errors, http://www.zoo-logique.org/3D.Blender/newsportal/thread.php?group=3D.Blender")
__version__ = "0.2.2 2004/08/01"
__version__ = "0.2.3 2004/12/30"
__bpydoc__ = """\
This script "bakes" Blender procedural materials (including textures): it saves
@@ -33,7 +33,7 @@ Notes:<br>
"""
#---------------------------------------------
# Last release : 0.2.2 , 2004/08/01 , 22h13
# Last release : 0.2.3 , 2004/12/30 , 22h13
#---------------------------------------------
#---------------------------------------------
# (c) jm soler 07/2004 : 'Procedural Texture Baker'
@@ -43,12 +43,40 @@ Notes:<br>
# original mesh.
# released under Blender Artistic Licence
#
# 0.2.2 : if the uv mesh objet exists it used,
# no creation of a new one. As the lamp and
# the camera
# 0.2.1 : This script automaticaly frame and shoot the
# new uv mesh . The image file is saved ine the
# /render folder.
#
# 0.2.3 :
# Great thanks for Apollux who sees a lot of these
# problems
#
# --Everytime you run the script a new set
# of objects is created. File size and memory
# consumption can go pretty high if you are
# not aware of that .
# Now it ONLY creates 3 objects: a flattened
# mesh, a camera and a lamp.
# --all the 3 objects was placed on layer 1, but if
# that layer was not visible while you used the script
# all you will get a is an empty render.
# Now the layer is tst and activated befor the shoot
# --The flattened mesh was really flattend only after
# frame 100 (if you playbacked the animation, you can
# actually see the mesh becoming flat on the first 100
# frames). No more.
# -- When the script is run, it changes temporary to
# the new cammera, set the render output to a square
# (i.e. 1024 x 1024 or else), does the render, and then
# resets the render output and the active camera to the
# original one. But if no original camera was found
# this produce an error.
#
# 0.2.2 :
# if the uv mesh objet exists it used,
# no creation of a new one. As the lamp and
# the camera
# 0.2.1 :
# This script automaticaly frame and shoot the
# new uv mesh . The image file is saved ine the
# /render folder.
#
#---------------------------------------------
# On user-friendly side :
@@ -83,9 +111,9 @@ Basic instructions:
- Run this script and check the console.
"""
def GET_newobject (TYPE):
def GET_newobject (TYPE,NAME):
SCENE = Blender.Scene.getCurrent()
OBJECT = Blender.Object.New(TYPE)
OBJECT = Blender.Object.New(TYPE,NAME)
SCENE.link(OBJECT)
return OBJECT, SCENE
@@ -138,7 +166,7 @@ def SHOOT (XYlimit, frame, obj, name, FRAME):
except:
Cam = Blender.Camera.New()
Cam.name = 'UVCamera'
CAM, SC = GET_newobject('Camera')
CAM, SC = GET_newobject('Camera','UVCAMERA')
CAM.link(Cam)
CAM.setName('UVCAMERA')
Cam.lens = 30
@@ -151,22 +179,23 @@ def SHOOT (XYlimit, frame, obj, name, FRAME):
CAM.setEuler (0.0, 0.0, 0.0)
try:
LAMP = Blender.Object.Get('Eclairage')
LAMP = Blender.Object.Get('ECLAIRAGE')
lampe = LAMP.getData()
SC = Blender.Scene.getCurrent()
except:
lampe = Blender.Lamp.New()
lampe.name = 'lumin'
LAMP, SC = GET_newobject('Lamp')
LAMP, SC = GET_newobject('Lamp','ECLAIRAGE')
LAMP.link(lampe)
LAMP.setName('Eclairage')
LAMP.setName('ECLAIRAGE')
LAMP.setLocation(obj.getLocation())
LAMP.LocX += XYlimit[0] / 2.0
LAMP.LocY += XYlimit[1] / 2.0
LAMP.LocZ += max (XYlimit[0], XYlimit[1])
LAMP.setEuler (0.0, 0.0, 0.0)
context = SC.getRenderingContext()
Camold = SC.getCurrentCamera()
SC.setCurrentCamera(CAM)
@@ -189,16 +218,27 @@ def SHOOT (XYlimit, frame, obj, name, FRAME):
SAVE_image (context, name, FRAME)
context.imageSizeY(OLDy)
context.imageSizeX(OLDx)
SC.setCurrentCamera(Camold)
if Camold :SC.setCurrentCamera(Camold)
Blender.Set ('curframe', frame)
def Mesh2UVCoord ():
try:
if 1:#try:
MESH3D = Object.GetSelected()[0]
if MESH3D.getType() == 'Mesh':
MESH = MESH3D.getData()
MESH2 = Blender.NMesh.GetRaw()
try:
NewOBJECT=Blender.Object.Get('UVOBJECT')
CurSCENE=Blender.Scene.getCurrent()
MESH2 = NewOBJECT.getData()
MESH2.faces=[]
except:
NewOBJECT, CurSCENE = GET_newobject('Mesh','UVOBJECT')
MESH2 = Blender.NMesh.GetRaw()
for f in MESH.faces:
f1 = Blender.NMesh.Face()
@@ -218,25 +258,14 @@ def Mesh2UVCoord ():
MESH2.materials = MESH.materials[:]
try:
NewOBJECT=Blender.Object.Get('UVOBJECT')
CurSCENE=Blender.Scene.getCurrent()
except:
NewOBJECT, CurSCENE = GET_newobject('Mesh')
NewOBJECT.link(MESH2)
#NewOBJECT, CurSCENE = GET_newobject('Mesh')
#NewOBJECT.link(MESH2)
NewOBJECT.setLocation (OBJPOS, OBJPOS, 0.0)
NewOBJECT.setEuler (0.0, 0.0, 0.0)
MESH2.removeAllKeys()
MESH2.update()
MESH2.insertKey (1, 'absolute')
MESH2.update()
for f in MESH2.faces:
for v in f.v:
@@ -248,6 +277,10 @@ def Mesh2UVCoord ():
print XYLIMIT
MESH2.update()
MESH2.insertKey (1, 'absolute')
MESH2.update()
MESH2.update()
MESH2.insertKey (FRAME, 'absolute')
MESH2.update()
@@ -271,9 +304,9 @@ def Mesh2UVCoord ():
result = Draw.PupMenu(name)
print 'problem : no object selected or not mesh'
except:
name = "Error%t|Active object is not a mesh or has no UV coordinates"
result = Draw.PupMenu(name)
#except:
# name = "Error%t|Active object is not a mesh or has no UV coordinates"
# result = Draw.PupMenu(name)
print 'problem : no object selected or not mesh'
Mesh2UVCoord()

View File

@@ -647,14 +647,13 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
int scriptGroup;
BPyMenu *scriptMenu = NULL;
/* other */
int scanDir = 1;
int returnValue = 0;
/* open directory stream */
dir = opendir(dirname);
if (dir != NULL) {
/* directory stream opened */
while (((dirEntry = readdir(dir)) != NULL) && (scanDir == 1)) {
while ((dirEntry = readdir(dir)) != NULL) {
/* Check if filename does not start with a dot,
* ends with '.py' and is a regular file. */
BLI_make_file_string("/", fileName, dirname, dirEntry->d_name);
@@ -722,10 +721,7 @@ static int bpymenu_CreateFromDir( char *dirname, int whichdir )
if (DEBUG) {
fprintf(stderr, "BPyMenus error: Couldn't create entry for: %s\n", fileName);
}
/* abort */
parserState = 0;
scanDir = 0;
returnValue = -2;
} else {
parserState++;
}

File diff suppressed because it is too large Load Diff

View File

@@ -52,6 +52,7 @@ extern PyTypeObject NMesh_Type;
extern PyTypeObject NMFace_Type;
extern PyTypeObject NMVert_Type;
extern PyTypeObject NMCol_Type;
extern PyTypeObject NMEdge_Type;
struct BPy_Object;
@@ -71,6 +72,7 @@ void remove_vert_def_nr( Object * ob, int def_nr, int vertnum );
#define BPy_NMFace_Check(v) ((v)->ob_type == &NMFace_Type)
#define BPy_NMVert_Check(v) ((v)->ob_type == &NMVert_Type)
#define BPy_NMCol_Check(v) ((v)->ob_type == &NMCol_Type)
#define BPy_NMEdge_Check(v) ((v)->ob_type == &NMEdge_Type)
/* Typedefs for the new types */
@@ -103,6 +105,14 @@ typedef struct {
} BPy_NMFace; /* an NMesh face */
typedef struct {
PyObject_HEAD /* required python macro */
PyObject *v1;
PyObject *v2;
char crease;
short flag;
} BPy_NMEdge; /* an NMesh edge */
typedef struct {
PyObject_HEAD /* required python macro */
Mesh * mesh;
@@ -111,6 +121,7 @@ typedef struct {
PyObject *materials;
PyObject *verts;
PyObject *faces;
PyObject *edges;
int sel_face; /*@ XXX remove */
short smoothresh; /* max AutoSmooth angle */
short subdiv[2]; /* SubDiv Levels: display and rendering */
@@ -134,7 +145,7 @@ int NMesh_CheckPyObject( PyObject * pyobj );
void mesh_update( Mesh * mesh );
PyObject *new_NMesh( Mesh * oldmesh );
Mesh *Mesh_fromNMesh( BPy_NMesh * nmesh );
Mesh *Mesh_fromNMesh( BPy_NMesh * nmesh , int store_edges );
PyObject *NMesh_assignMaterials_toObject( BPy_NMesh * nmesh, Object * ob );
Material **nmesh_updateMaterials( BPy_NMesh * nmesh );
Material **newMaterialList_fromPyList( PyObject * list );

View File

@@ -25,7 +25,7 @@
*
* This is a new part of Blender.
*
* Contributor(s): Willian P. Germano, Tom Musgrove
* Contributor(s): Willian P. Germano, Tom Musgrove, Michael Reimpell, Yann Vernier
*
* ***** END GPL/BL DUAL LICENSE BLOCK *****
*/
@@ -68,7 +68,7 @@
extern int EXPP_disable_force_draw;
/* Callback used by the file and image selector access functions */
static PyObject *( *EXPP_FS_PyCallback ) ( PyObject * arg ) = NULL;
static PyObject *EXPP_FS_PyCallback = NULL;
/*****************************************************************************/
/* Python API function prototypes for the Window module. */
@@ -452,13 +452,24 @@ static PyObject *M_Window_QRedrawAll( PyObject * self, PyObject * args )
static void getSelectedFile( char *name )
{
if( !EXPP_FS_PyCallback )
return;
PyObject_CallFunction( ( PyObject * ) EXPP_FS_PyCallback, "s", name );
EXPP_FS_PyCallback = NULL;
PyObject *callback;
PyObject *result;
callback = EXPP_FS_PyCallback;
result = PyObject_CallFunction( EXPP_FS_PyCallback, "s", name );
if ((!result) && (G.f & G_DEBUG)) {
fprintf(stderr, "BPy error: Callback call failed!\n");
}
Py_XDECREF(result);
/* Catch changes of EXPP_FS_PyCallback during the callback call
* due to calls to Blender.Window.FileSelector or
* Blender.Window.ImageSelector inside the python callback. */
if (callback == EXPP_FS_PyCallback) {
Py_DECREF(EXPP_FS_PyCallback);
EXPP_FS_PyCallback = NULL;
} else {
Py_DECREF(callback);
}
return;
}
@@ -470,12 +481,12 @@ static PyObject *M_Window_FileSelector( PyObject * self, PyObject * args )
Script *script = G.main->script.last;
int startspace = 0;
if( !PyArg_ParseTuple( args, "O!|ss",
&PyFunction_Type, &EXPP_FS_PyCallback, &title,
&filename ) )
if( (!PyArg_ParseTuple( args, "O|ss", &EXPP_FS_PyCallback, &title, &filename ) )
|| (!PyCallable_Check(EXPP_FS_PyCallback)))
return EXPP_ReturnPyObjError( PyExc_AttributeError,
"\nexpected a callback function (and optionally one or two strings) "
"as argument(s)" );
Py_XINCREF(EXPP_FS_PyCallback);
/* trick: we move to a spacescript because then the fileselector will properly
* unset our SCRIPT_FILESEL flag when the user chooses a file or cancels the
@@ -514,13 +525,13 @@ static PyObject *M_Window_ImageSelector( PyObject * self, PyObject * args )
Script *script = G.main->script.last;
int startspace = 0;
if( !PyArg_ParseTuple( args, "O!|ss",
&PyFunction_Type, &EXPP_FS_PyCallback, &title,
&filename ) )
if( !PyArg_ParseTuple( args, "O|ss", &EXPP_FS_PyCallback, &title, &filename )
|| (!PyCallable_Check(EXPP_FS_PyCallback)))
return ( EXPP_ReturnPyObjError
( PyExc_AttributeError,
"\nexpected a callback function (and optionally one or two strings) "
"as argument(s)" ) );
Py_XINCREF(EXPP_FS_PyCallback);
/* trick: we move to a spacescript because then the fileselector will properly
* unset our SCRIPT_FILESEL flag when the user chooses a file or cancels the

View File

@@ -68,6 +68,8 @@ static PyObject *World_setIpo( BPy_World * self, PyObject * args );
static PyObject *World_clearIpo( BPy_World * self );
static PyObject *World_getName( BPy_World * self );
static PyObject *World_setName( BPy_World * self, PyObject * args );
static PyObject *World_getMode( BPy_World * self );
static PyObject *World_setMode( BPy_World * self, PyObject * args );
static PyObject *World_getSkytype( BPy_World * self );
static PyObject *World_setSkytype( BPy_World * self, PyObject * args );
static PyObject *World_getMistype( BPy_World * self );
@@ -162,7 +164,11 @@ static PyMethodDef BPy_World_methods[] = {
{"getName", ( PyCFunction ) World_getName, METH_NOARGS,
"() - Return World Data name"},
{"setName", ( PyCFunction ) World_setName, METH_VARARGS,
"() - Return World Data name"},
"() - Set World Data name"},
{"getMode", ( PyCFunction ) World_getMode, METH_NOARGS,
"() - Return World Data mode"},
{"setMode", ( PyCFunction ) World_setMode, METH_VARARGS,
"(i) - Set World Data mode"},
{"getSkytype", ( PyCFunction ) World_getSkytype, METH_NOARGS,
"() - Return World Data skytype"},
{"setSkytype", ( PyCFunction ) World_setSkytype, METH_VARARGS,

View File

@@ -66,6 +66,11 @@ Example::
- ADD - add to background (halo).
- ALPHA - draw with transparency.
- SUB - subtract from background.
@var EdgeFlags: The available edge flags.
- SELECT - selected.
- EDGEDRAW - edge is drawn out of edition mode.
- SEAM - edge is a seam for LSCM UV unwrapping
- FGON - edge is part of a F-Gon.
"""
def Col(col = [255, 255, 255, 255]):
@@ -139,16 +144,18 @@ def GetRawFromObject(name):
be created.
"""
def PutRaw(nmesh, name = None, recalculate_normals = 1):
def PutRaw(nmesh, name = None, recalculate_normals = 1, store_edges = 0):
"""
Put an NMesh object back in Blender.
@type nmesh: NMesh
@type name: string
@type recalculate_normals: int
@type store_edges: int
@param name: The name of the mesh data object in Blender which will receive
this nmesh data. It can be an existing mesh data object or a new one.
@param recalculate_normals: If non-zero, the vertex normals for the mesh will
be recalculated.
@param store_edges: if non-zero, the edges data are stored
@rtype: None or Object
@return: It depends on the 'name' parameter:
- I{name} refers to an existing mesh data obj already linked to an
@@ -193,6 +200,21 @@ class NMVert:
each face can be independently mapped to any part of its texture.
"""
class NMEdge:
"""
The NMEdge object
=================
This object holds mesh edge data.
@type v1: NMVert
@cvar v1: The first vertex of the edge.
@type v2: NMVert
@cvar v2: The second vertex of the edge.
@type crease: int
@cvar crease: The crease value of the edge. It is in the range [0,255].
@type flag: int
@cvar flag: The bitmask describing edge properties. See L{NMesh.EdgeFlags<EdgeFlags>}.
"""
class NMFace:
"""
The NMFace object
@@ -264,11 +286,71 @@ class NMesh:
@cvar verts: The list of NMesh vertices (NMVerts).
@cvar users: The number of Objects using (linked to) this mesh.
@cvar faces: The list of NMesh faces (NMFaces).
@cvar edges: None if mesh has no edge data, else a list of L{NMEdge} edges. Use L{addEdgesData} to create edge data if it do not exist.
@cvar mode: The mode flags for this mesh. See L{setMode}.
@cvar subDivLevels: The [display, rendering] subdivision levels in [1, 6].
@cvar maxSmoothAngle: The max angle for auto smoothing. See L{setMode}.
"""
def addEdge(v1, v2):
"""
Create an edge between two vertices.
If an edge already exists between those vertices, it is returned. (in blender, only zero or one edge can link two vertices).
Created edge is automatically added to edges list.
You can only call this method if mesh has edge data.
@type v1: NMVert
@param v1: the first vertex of the edge.
@type v2: NMVert
@param v2: the second vertex of the edge.
@rtype: NMEdge
@return: The created or already existing edge.
"""
def findEdge(v1, v2):
"""
Try to find an edge between two vertices.
If no edge exists between v1 and v2, None is returned.
You can only call this method if mesh has edge data.
@type v1: NMVert
@param v1: the first vertex of the edge.
@type v2: NMVert
@param v2: the second vertex of the edge.
@rtype: NMEdge
@return: The found edge. None if no edge was found.
"""
def removeEdge():
"""
remove an edge between two vertices.
All faces using this edge are removed from faces list.
You can only call this method if mesh has edge data.
@type v1: NMVert
@param v1: the first vertex of the edge.
@type v2: NMVert
@param v2: the second vertex of the edge.
"""
def addFace(face):
"""
Add a face to face list and add to edge list (if edge data exists) necessary edges.
@type face: NMFace
@param face: the face to add to the mesh.
@rtype: list of NMEdge
@return: If mesh has edge data, return the list of face edges.
"""
def removeFace():
"""
Remove a face for face list and remove edges no more used by any other face (if edge data exists).
@type face: NMFace
@param face: the face to add to the mesh.
"""
def addEdgesData():
"""
If edge data does not exist for the mesh (ie L{edges}==None), then create them.
"""
def addMaterial(material):
"""
Add a new material to this NMesh's list of materials. This method is the
@@ -412,7 +494,7 @@ class NMesh:
add them.
"""
def update(recalc_normals = 0):
def update(recalc_normals = 0, store_edges = 0):
"""
Update the mesh in Blender. The changes made are put back to the mesh in
Blender, if available, or put in a newly created mesh object if this NMesh
@@ -420,6 +502,8 @@ class NMesh:
@type recalc_normals: int
@param recalc_normals: If given and equal to 1, the vertex normals are
recalculated.
@type store_edges: int
@param store_edges: if not 0, then edge data are stored.
@note: if your mesh disappears after it's updated, try
L{Object.Object.makeDisplayList}. 'Subsurf' meshes (see L{getMode},
L{setMode}) need their display lists updated, too.