forked from bartvdbraak/blender
- New script:
Wim Van Hoydonck contributed the famous Knife script (put under Modifiers group) developed by Stefano Selleri and himself (thank to both!) - Added helper function Blender.sys.makename, updated docs and script ac3d_export to use it (shall update other exporters too): this function is just a simple helper to format a filename as needed (change extension, strip dirname, it defaults to use G.sce as path). - Added a test method: Blender.Scene.getScriptlinks(eventName): just testing, if this path proves useful other functions will be added and made general, for objects, etc.
This commit is contained in:
parent
317e067ecb
commit
467311ad34
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
""" Registration info for Blender menus:
|
""" Registration info for Blender menus:
|
||||||
Name: 'AC3D (.ac)...'
|
Name: 'AC3D (.ac)...'
|
||||||
Blender: 232
|
Blender: 233
|
||||||
Group: 'Export'
|
Group: 'Export'
|
||||||
Submenu: 'All meshes...' all
|
Submenu: 'All meshes...' all
|
||||||
Submenu: 'Only selected...' sel
|
Submenu: 'Only selected...' sel
|
||||||
@ -13,8 +13,9 @@ Tip: 'Export to AC3D (.ac) format.'
|
|||||||
# $Id$
|
# $Id$
|
||||||
#
|
#
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# AC3DExport version 2.32-1 Jan 21, 2004
|
# AC3DExport version 2.34
|
||||||
# Program versions: Blender 2.32+ and AC3Db files (means version 0xb)
|
# Program versions: Blender 2.34 and AC3Db files (means version 0xb)
|
||||||
|
# new: minor tweaks, exporter didn't change
|
||||||
# --------------------------------------------------------------------------
|
# --------------------------------------------------------------------------
|
||||||
# ***** BEGIN GPL LICENSE BLOCK *****
|
# ***** BEGIN GPL LICENSE BLOCK *****
|
||||||
#
|
#
|
||||||
@ -420,4 +421,5 @@ def fs_callback(filename):
|
|||||||
if __script__['arg'] == 'config':
|
if __script__['arg'] == 'config':
|
||||||
Draw.Register(gui, event, b_event)
|
Draw.Register(gui, event, b_event)
|
||||||
else:
|
else:
|
||||||
Blender.Window.FileSelector(fs_callback, "Export AC3D")
|
fname = Blender.sys.makename(ext=".ac")
|
||||||
|
Blender.Window.FileSelector(fs_callback, "Export AC3D", fname)
|
||||||
|
690
release/scripts/knife.py
Normal file
690
release/scripts/knife.py
Normal file
@ -0,0 +1,690 @@
|
|||||||
|
#!BPY
|
||||||
|
|
||||||
|
"""
|
||||||
|
Name: 'Blender Knife Tool'
|
||||||
|
Blender: 232
|
||||||
|
Group: 'Modifiers'
|
||||||
|
Tooltip: 'Cut a mesh along a plane w/o creating doubles'
|
||||||
|
"""
|
||||||
|
|
||||||
|
# $Id$
|
||||||
|
#
|
||||||
|
###################################################################
|
||||||
|
# #
|
||||||
|
# Blender Knife Tool #
|
||||||
|
# #
|
||||||
|
# v. 0.0.0 - 0.0.6 (C) December 2002 Stefano <S68> Selleri #
|
||||||
|
# v. 0.0.7 (C) March 2004 Wim Van Hoydonck #
|
||||||
|
# v. 0.0.8 (C) March 2004 Wim Van Hoydonck & Stefano <S68> Selleri#
|
||||||
|
# #
|
||||||
|
# Released under the Blender Artistic Licence (BAL) #
|
||||||
|
# See www.blender.org #
|
||||||
|
# #
|
||||||
|
# Works in Blender 2.32 and higher #
|
||||||
|
# #
|
||||||
|
# this script can be found online at: #
|
||||||
|
# http://users.pandora.be/tuinbels/scripts/knife-0.0.8.py #
|
||||||
|
# http://www.selleri.org/Blender #
|
||||||
|
# #
|
||||||
|
# email: tuinbels@hotmail.com #
|
||||||
|
# selleri@det.unifi.it #
|
||||||
|
###################################################################
|
||||||
|
# History #
|
||||||
|
# V: 0.0.0 - 08-12-02 - The script starts to take shape, a #
|
||||||
|
# history is now deserved :) #
|
||||||
|
# 0.0.1 - 09-12-02 - The faces are correctly selected and #
|
||||||
|
# assigned to the relevant objects now the #
|
||||||
|
# hard (splitting) part... #
|
||||||
|
# 0.0.2 - 14-12-02 - Still hacking on the splitting... #
|
||||||
|
# It works, but I have to de-globalize #
|
||||||
|
# the intersection coordinates #
|
||||||
|
# 0.0.3 - 15-12-02 - First Alpha version #
|
||||||
|
# 0.0.4 - 17-12-02 - Upgraded accordingly to eeshlo tips #
|
||||||
|
# Use Matrices for coordinate transf. #
|
||||||
|
# Add a GUI #
|
||||||
|
# Make it Run on 2.23 #
|
||||||
|
# 0.0.5 - 17-12-02 - Eeshlo solved some problems.... #
|
||||||
|
# Theeth too adviced me #
|
||||||
|
# 0.0.6 - 18-12-02 - Better error messages #
|
||||||
|
# 0.0.7 - 26-03-04 - Developer team doubles! #
|
||||||
|
# This version is by Wim! #
|
||||||
|
# Doesn't create doubles (AFAIK) #
|
||||||
|
# - Faster (for small meshes), global #
|
||||||
|
# coordinates of verts are calculated only #
|
||||||
|
# once #
|
||||||
|
# - Editing the CutPlane in editmode (move) #
|
||||||
|
# shouldn't cause problems anymore #
|
||||||
|
# - Menu button added to choose between the #
|
||||||
|
# different Edit Methods #
|
||||||
|
# - If a mesh is cut twice at the same place, #
|
||||||
|
# this gives errors :( (also happened in #
|
||||||
|
# previous versions) #
|
||||||
|
# - Willian Padovani Germano solved #
|
||||||
|
# a problem, many thanks :) #
|
||||||
|
# - Stefano Selleri made some good #
|
||||||
|
# suggestions, thanks :) #
|
||||||
|
# 0.0.8 - 26-03-04 - General Interface rewrite (Stefano) #
|
||||||
|
# 0.0.8a- 31-03-04 - Added some error messages #
|
||||||
|
# - Cut multiple meshes at once #
|
||||||
|
# #
|
||||||
|
###################################################################
|
||||||
|
|
||||||
|
import Blender
|
||||||
|
from Blender import *
|
||||||
|
from Blender.sys import time
|
||||||
|
from math import *
|
||||||
|
|
||||||
|
Epsilon = 0.00001
|
||||||
|
msg = ''
|
||||||
|
RBmesh0 = Draw.Create(0)
|
||||||
|
RBmesh1 = Draw.Create(0)
|
||||||
|
RBmesh2 = Draw.Create(1)
|
||||||
|
|
||||||
|
VERSION = '0.0.8'
|
||||||
|
|
||||||
|
# see if time module is available
|
||||||
|
#try:
|
||||||
|
# import time
|
||||||
|
# timport = 1
|
||||||
|
#except:
|
||||||
|
# timport = 0
|
||||||
|
|
||||||
|
|
||||||
|
BL_VERSION = Blender.Get('version')
|
||||||
|
if (BL_VERSION<=223):
|
||||||
|
import Blender210
|
||||||
|
|
||||||
|
#=================================#
|
||||||
|
# Vector and matrix manipulations #
|
||||||
|
#=================================#
|
||||||
|
|
||||||
|
# vector addition
|
||||||
|
def vecadd(a, b):
|
||||||
|
return [a[0] - b[0], a[1] - b[1], a[2] + b[2]]
|
||||||
|
|
||||||
|
# vector substration
|
||||||
|
def vecsub(a, b):
|
||||||
|
return [a[0] - b[0], a[1] - b[1], a[2] - b[2]]
|
||||||
|
|
||||||
|
# vector crossproduct
|
||||||
|
def veccross(x, y):
|
||||||
|
v = [0, 0, 0]
|
||||||
|
v[0] = x[1]*y[2] - x[2]*y[1]
|
||||||
|
v[1] = x[2]*y[0] - x[0]*y[2]
|
||||||
|
v[2] = x[0]*y[1] - x[1]*y[0]
|
||||||
|
return v
|
||||||
|
|
||||||
|
# vector dotproduct
|
||||||
|
def vecdot(x, y):
|
||||||
|
return x[0]*y[0] + x[1]*y[1] + x[2]*y[2]
|
||||||
|
|
||||||
|
# vector length
|
||||||
|
def length(v):
|
||||||
|
return sqrt(v[0]*v[0] + v[1]*v[1] + v[2]*v[2])
|
||||||
|
|
||||||
|
# vector multiplied by constant s
|
||||||
|
def vecmul(a, s):
|
||||||
|
return[a[0]*s, a[1]*s, a[2]*s]
|
||||||
|
|
||||||
|
# vector divided by constant s
|
||||||
|
def vecdiv(a, s):
|
||||||
|
if s!=0.0: s = 1.0/s
|
||||||
|
return vecmul(a, s)
|
||||||
|
|
||||||
|
# matrix(4x3) vector multiplication
|
||||||
|
def mulmatvec4x3(a, b):
|
||||||
|
# a is vector, b is matrix
|
||||||
|
r = [0, 0, 0]
|
||||||
|
r[0] = a[0]*b[0][0] + a[1]*b[1][0] + a[2]*b[2][0] + b[3][0]
|
||||||
|
r[1] = a[0]*b[0][1] + a[1]*b[1][1] + a[2]*b[2][1] + b[3][1]
|
||||||
|
r[2] = a[0]*b[0][2] + a[1]*b[1][2] + a[2]*b[2][2] + b[3][2]
|
||||||
|
return r
|
||||||
|
|
||||||
|
# Normalization of a vector
|
||||||
|
def Normalize(a):
|
||||||
|
lengte = length(a)
|
||||||
|
return vecdiv(a, lengte)
|
||||||
|
|
||||||
|
# calculate normal from 3 verts
|
||||||
|
def Normal(v0, v1, v2):
|
||||||
|
return veccross(vecsub(v0, v1),vecsub(v0, v2))
|
||||||
|
|
||||||
|
#===========================#
|
||||||
|
# Coordinatetransformations #
|
||||||
|
#===========================#
|
||||||
|
|
||||||
|
def GlobalPosition(P, Obj):
|
||||||
|
|
||||||
|
if (BL_VERSION<=223):
|
||||||
|
m = Obj.matrix
|
||||||
|
else:
|
||||||
|
m = Obj.getMatrix()
|
||||||
|
|
||||||
|
return mulmatvec4x3(P, m)
|
||||||
|
|
||||||
|
def LocalPosition(P, Obj):
|
||||||
|
|
||||||
|
if (BL_VERSION<=223):
|
||||||
|
m = Blender210.getObject(Obj.name).inverseMatrix
|
||||||
|
else:
|
||||||
|
m = Obj.getInverseMatrix()
|
||||||
|
|
||||||
|
return mulmatvec4x3(P, m)
|
||||||
|
|
||||||
|
#================#
|
||||||
|
# Get Plane Data #
|
||||||
|
#================#
|
||||||
|
|
||||||
|
def PlaneData(Plane):
|
||||||
|
global msg
|
||||||
|
#
|
||||||
|
# Calculate:
|
||||||
|
# - the normal of the plane,
|
||||||
|
# - the offset of the plane wrt the global coordinate system
|
||||||
|
# in the direction of the normal of the plane
|
||||||
|
#
|
||||||
|
PlaneMesh = NMesh.GetRawFromObject(Plane.name)
|
||||||
|
|
||||||
|
if (len(PlaneMesh.faces)>1):
|
||||||
|
msg = "ERROR: Active object must be a single face plane"
|
||||||
|
return ((0,0,0),(0,0,0),1)
|
||||||
|
else:
|
||||||
|
if (len(PlaneMesh.verts)<3):
|
||||||
|
msg = "ERROR: 3 vertices needed to define a plane"
|
||||||
|
return ((0,0,0),(0,0,0),1)
|
||||||
|
else:
|
||||||
|
v0 = GlobalPosition(PlaneMesh.faces[0].v[0].co, Plane)
|
||||||
|
v1 = GlobalPosition(PlaneMesh.faces[0].v[1].co, Plane)
|
||||||
|
v2 = GlobalPosition(PlaneMesh.faces[0].v[2].co, Plane)
|
||||||
|
|
||||||
|
# the normal of the plane, calculated from the first 3 verts
|
||||||
|
PNormal = Normalize(Normal(v0,v1,v2))
|
||||||
|
|
||||||
|
# offset of the plane, using 1st vertex instead of Plane.getLocaction()
|
||||||
|
POffset = vecdot(v0,PNormal)
|
||||||
|
|
||||||
|
return PNormal, POffset, 0
|
||||||
|
|
||||||
|
#====================================#
|
||||||
|
# Position with respect to Cut Plane #
|
||||||
|
#====================================#
|
||||||
|
|
||||||
|
def Distance(P, N, d0):
|
||||||
|
#
|
||||||
|
# distance from a point to a plane
|
||||||
|
#
|
||||||
|
return vecdot(P, N) - d0
|
||||||
|
|
||||||
|
def FacePosition(dist):
|
||||||
|
#
|
||||||
|
# position of a face wrt to the plane
|
||||||
|
#
|
||||||
|
np, nn, nz = 0, 0, 0
|
||||||
|
|
||||||
|
for d in dist:
|
||||||
|
|
||||||
|
# the distances are calculated in advance
|
||||||
|
if d > 0:
|
||||||
|
np += 1
|
||||||
|
elif d < 0:
|
||||||
|
nn += 1
|
||||||
|
else:
|
||||||
|
nz += 1
|
||||||
|
|
||||||
|
if np == 0:
|
||||||
|
return -1
|
||||||
|
if nn == 0:
|
||||||
|
return 1
|
||||||
|
return 0
|
||||||
|
|
||||||
|
#==========================================#
|
||||||
|
# Append existing faces / create new faces #
|
||||||
|
#==========================================#
|
||||||
|
|
||||||
|
def FaceAppend(me, fidx):
|
||||||
|
#
|
||||||
|
# append a face to a mesh based on a list of vertex-indices
|
||||||
|
#
|
||||||
|
nf = NMesh.Face()
|
||||||
|
|
||||||
|
for i in fidx:
|
||||||
|
nf.v.append(me.verts[i])
|
||||||
|
me.faces.append(nf)
|
||||||
|
|
||||||
|
def FaceMake(me, vl):
|
||||||
|
#
|
||||||
|
# make one or two new faces based on a list of vertex-indices
|
||||||
|
#
|
||||||
|
idx = len(me.verts)
|
||||||
|
|
||||||
|
if len(vl) <= 4:
|
||||||
|
nf = NMesh.Face()
|
||||||
|
for i in range(len(vl)):
|
||||||
|
nf.v.append(me.verts[vl[i]])
|
||||||
|
me.faces.append(nf)
|
||||||
|
else:
|
||||||
|
nf = NMesh.Face()
|
||||||
|
nf.v.append(me.verts[vl[0]])
|
||||||
|
nf.v.append(me.verts[vl[1]])
|
||||||
|
nf.v.append(me.verts[vl[2]])
|
||||||
|
nf.v.append(me.verts[vl[3]])
|
||||||
|
me.faces.append(nf)
|
||||||
|
|
||||||
|
nf = NMesh.Face()
|
||||||
|
nf.v.append(me.verts[vl[3]])
|
||||||
|
nf.v.append(me.verts[vl[4]])
|
||||||
|
nf.v.append(me.verts[vl[0]])
|
||||||
|
me.faces.append(nf)
|
||||||
|
|
||||||
|
#=====================================#
|
||||||
|
# Generate vertex lists for new faces #
|
||||||
|
#=====================================#
|
||||||
|
|
||||||
|
def Split(Obj, MeshPos, MeshNeg, Vglob, Vidx, N, d0, newvidx, newvcoo, totverts, d):
|
||||||
|
#
|
||||||
|
# - calculate intersectionpoints of the plane with faces
|
||||||
|
# - see if this intersectionpoint already exists (look for vertices close to the new vertex)
|
||||||
|
# - if it does not yet exist, append a vertex to the mesh,
|
||||||
|
# remember its index and location and append the index to the appropriate vertex-lists
|
||||||
|
# - if it does, use that vertex (and its index) to create the face
|
||||||
|
#
|
||||||
|
|
||||||
|
vp = []
|
||||||
|
vn = []
|
||||||
|
|
||||||
|
# distances of the verts wrt the plane are calculated in main part of script
|
||||||
|
|
||||||
|
for i in range(len(d)):
|
||||||
|
# the previous vertex
|
||||||
|
dim1 = d[int(fmod(i-1,len(d)))]
|
||||||
|
Vim1 = Vglob[int(fmod(i-1,len(d)))]
|
||||||
|
|
||||||
|
if abs(d[i]) < Epsilon:
|
||||||
|
# if the vertex lies in the cutplane
|
||||||
|
vp.append(Vidx[i])
|
||||||
|
vn.append(Vidx[i])
|
||||||
|
else:
|
||||||
|
if abs(dim1) < Epsilon:
|
||||||
|
# if the previous vertex lies in cutplane
|
||||||
|
if d[i] > 0:
|
||||||
|
vp.append(Vidx[i])
|
||||||
|
else:
|
||||||
|
vn.append(Vidx[i])
|
||||||
|
else:
|
||||||
|
if d[i]*dim1 > 0:
|
||||||
|
# if they are on the same side of the plane
|
||||||
|
if d[i] > 0:
|
||||||
|
vp.append(Vidx[i])
|
||||||
|
else:
|
||||||
|
vn.append(Vidx[i])
|
||||||
|
else:
|
||||||
|
# the vertices are not on the same side of the plane, so we have an intersection
|
||||||
|
|
||||||
|
Den = vecdot(vecsub(Vglob[i],Vim1),N)
|
||||||
|
|
||||||
|
Vi = []
|
||||||
|
Vi.append ( ((Vim1[0]*Vglob[i][1]-Vim1[1]*Vglob[i][0])*N[1]+(Vim1[0]*Vglob[i][2]-Vim1[2]*Vglob[i][0])*N[2]+(Vglob[i][0]-Vim1[0])*d0)/Den)
|
||||||
|
Vi.append ( ((Vim1[1]*Vglob[i][0]-Vim1[0]*Vglob[i][1])*N[0]+(Vim1[1]*Vglob[i][2]-Vim1[2]*Vglob[i][1])*N[2]+(Vglob[i][1]-Vim1[1])*d0)/Den)
|
||||||
|
Vi.append ( ((Vim1[2]*Vglob[i][0]-Vim1[0]*Vglob[i][2])*N[0]+(Vim1[2]*Vglob[i][1]-Vim1[1]*Vglob[i][2])*N[1]+(Vglob[i][2]-Vim1[2])*d0)/Den)
|
||||||
|
|
||||||
|
ViL = LocalPosition(Vi, Obj)
|
||||||
|
|
||||||
|
if newvidx == []:
|
||||||
|
# if newvidx is empty (the first time Split is called), append a new vertex
|
||||||
|
# to the mesh and remember its vertex-index and location
|
||||||
|
ViLl = NMesh.Vert(ViL[0],ViL[1],ViL[2])
|
||||||
|
|
||||||
|
if MeshPos == MeshNeg:
|
||||||
|
MeshPos.verts.append(ViLl)
|
||||||
|
|
||||||
|
else:
|
||||||
|
MeshPos.verts.append(ViLl)
|
||||||
|
MeshNeg.verts.append(ViLl)
|
||||||
|
|
||||||
|
nvidx = totverts
|
||||||
|
newvidx.append(nvidx)
|
||||||
|
newvcoo.append(ViL)
|
||||||
|
|
||||||
|
vp.append(nvidx)
|
||||||
|
vn.append(nvidx)
|
||||||
|
else:
|
||||||
|
# newvidx is not empty
|
||||||
|
dist1 = []
|
||||||
|
tlr = 0
|
||||||
|
for j in range(len(newvidx)):
|
||||||
|
# calculate the distance from the new vertex to the vertices
|
||||||
|
# in the list with new vertices
|
||||||
|
dist1.append(length(vecsub(ViL, newvcoo[j])))
|
||||||
|
for k in range(len(dist1)):
|
||||||
|
if dist1[k] < Epsilon:
|
||||||
|
# if distance is smaller than epsilon, use the other vertex
|
||||||
|
# use newvidx[k] as vert
|
||||||
|
vp.append(newvidx[k])
|
||||||
|
vn.append(newvidx[k])
|
||||||
|
break # get out of closest loop
|
||||||
|
else:
|
||||||
|
tlr += 1
|
||||||
|
|
||||||
|
if tlr == len(newvidx):
|
||||||
|
nvidx = totverts + len(newvidx)
|
||||||
|
ViLl = NMesh.Vert(ViL[0],ViL[1],ViL[2])
|
||||||
|
|
||||||
|
if MeshPos == MeshNeg:
|
||||||
|
MeshPos.verts.append(ViLl)
|
||||||
|
|
||||||
|
else:
|
||||||
|
MeshPos.verts.append(ViLl)
|
||||||
|
MeshNeg.verts.append(ViLl)
|
||||||
|
|
||||||
|
newvidx.append(nvidx)
|
||||||
|
newvcoo.append(ViL)
|
||||||
|
vp.append(nvidx)
|
||||||
|
vn.append(nvidx)
|
||||||
|
|
||||||
|
if d[i] > 0:
|
||||||
|
vp.append(Vidx[i])
|
||||||
|
else:
|
||||||
|
vn.append(Vidx[i])
|
||||||
|
|
||||||
|
return vp, vn, newvidx, newvcoo
|
||||||
|
|
||||||
|
#===========#
|
||||||
|
# Main part #
|
||||||
|
#===========#
|
||||||
|
|
||||||
|
def CutMesh():
|
||||||
|
global msg
|
||||||
|
global RBmesh0,RBmesh1,RBmesh2
|
||||||
|
#if timport == 1:
|
||||||
|
# start = time.clock()
|
||||||
|
start = time()
|
||||||
|
|
||||||
|
selected_obs = Object.GetSelected()
|
||||||
|
|
||||||
|
total = len(selected_obs)
|
||||||
|
|
||||||
|
NoErrors=0
|
||||||
|
|
||||||
|
meshes = 0
|
||||||
|
|
||||||
|
# check to see if every selected object is a mesh
|
||||||
|
for ob in selected_obs:
|
||||||
|
type = ob.getType()
|
||||||
|
if type == 'Mesh':
|
||||||
|
meshes += 1
|
||||||
|
|
||||||
|
# at least select two objects
|
||||||
|
if meshes <= 1:
|
||||||
|
msg = "ERROR: At least two objects should be selected"
|
||||||
|
NoErrors = 1
|
||||||
|
|
||||||
|
# if not every object is a mesh
|
||||||
|
if meshes != total:
|
||||||
|
msg = "ERROR: You should only select meshobjects"
|
||||||
|
NoErrors=1
|
||||||
|
|
||||||
|
# everything is ok
|
||||||
|
if NoErrors == 0:
|
||||||
|
Pln = selected_obs[0]
|
||||||
|
PNormal, POffset, NoErrors = PlaneData(Pln)
|
||||||
|
|
||||||
|
# loop to cut multiple meshes at once
|
||||||
|
for o in range(1, total):
|
||||||
|
|
||||||
|
Obj = selected_obs[o]
|
||||||
|
|
||||||
|
if (NoErrors == 0) :
|
||||||
|
|
||||||
|
m = Obj.getData()
|
||||||
|
|
||||||
|
if RBmesh1.val == 1:
|
||||||
|
|
||||||
|
MeshNew = NMesh.GetRaw()
|
||||||
|
|
||||||
|
if RBmesh2.val == 1:
|
||||||
|
|
||||||
|
MeshPos = NMesh.GetRaw()
|
||||||
|
MeshNeg = NMesh.GetRaw()
|
||||||
|
|
||||||
|
# get the indices of the faces of the mesh
|
||||||
|
idx = []
|
||||||
|
for i in range(len(m.faces)):
|
||||||
|
idx.append(i)
|
||||||
|
|
||||||
|
# if idx is not reversed, this results in a list index out of range if
|
||||||
|
# the original mesh is used (RBmesh1 == 0)
|
||||||
|
idx.reverse()
|
||||||
|
|
||||||
|
lenface, vertglob, vertidx, vertdist = [], [], [], []
|
||||||
|
|
||||||
|
# total number of vertices
|
||||||
|
totverts = len(m.verts)
|
||||||
|
|
||||||
|
# for every face: calculate global coordinates of the vertices
|
||||||
|
# append the vertex-index to a list
|
||||||
|
# calculate distance of vertices to cutplane in advance
|
||||||
|
|
||||||
|
for i in idx:
|
||||||
|
fvertidx, Ve, dist = [], [], []
|
||||||
|
fa = m.faces[i]
|
||||||
|
lenface.append(len(fa))
|
||||||
|
for v in fa.v:
|
||||||
|
globpos = GlobalPosition(v.co, Obj)
|
||||||
|
Ve.append(globpos)
|
||||||
|
fvertidx.append(v.index)
|
||||||
|
dist.append(Distance(globpos, PNormal, POffset))
|
||||||
|
vertidx.append(fvertidx)
|
||||||
|
vertglob.append(Ve)
|
||||||
|
vertdist.append(dist)
|
||||||
|
|
||||||
|
|
||||||
|
# append the verts of the original mesh to the new mesh
|
||||||
|
if RBmesh1.val == 1:
|
||||||
|
for v in m.verts:
|
||||||
|
MeshNew.verts.append(v)
|
||||||
|
|
||||||
|
if RBmesh2.val == 1:
|
||||||
|
idx2 = []
|
||||||
|
dist2 = []
|
||||||
|
for v in m.verts:
|
||||||
|
MeshPos.verts.append(v)
|
||||||
|
MeshNeg.verts.append(v)
|
||||||
|
idx2.append(v.index)
|
||||||
|
dist2.append(Distance(GlobalPosition(v.co, Obj), PNormal, POffset))
|
||||||
|
|
||||||
|
# remove all faces of m if the original object has to be used
|
||||||
|
|
||||||
|
if RBmesh0.val == 1:
|
||||||
|
m.faces = []
|
||||||
|
|
||||||
|
newvidx, newvcoo = [], []
|
||||||
|
testidxpos, testidxneg = [], []
|
||||||
|
|
||||||
|
# what its all about...
|
||||||
|
for i in idx:
|
||||||
|
fp = FacePosition(vertdist[i])
|
||||||
|
|
||||||
|
# no intersection
|
||||||
|
if fp > 0:
|
||||||
|
if RBmesh0.val == 1:
|
||||||
|
FaceAppend(m, vertidx[i])
|
||||||
|
|
||||||
|
elif RBmesh1.val == 1:
|
||||||
|
FaceAppend(MeshNew, vertidx[i])
|
||||||
|
|
||||||
|
elif RBmesh2.val == 1:
|
||||||
|
FaceAppend(MeshPos, vertidx[i])
|
||||||
|
|
||||||
|
if testidxpos == []:
|
||||||
|
testidxpos = vertidx[i]
|
||||||
|
elif fp < 0:
|
||||||
|
if RBmesh0.val == 1:
|
||||||
|
FaceAppend(m, vertidx[i])
|
||||||
|
elif RBmesh1.val == 1:
|
||||||
|
FaceAppend(MeshNew, vertidx[i])
|
||||||
|
|
||||||
|
elif RBmesh2.val == 1:
|
||||||
|
FaceAppend(MeshNeg, vertidx[i])
|
||||||
|
|
||||||
|
if testidxneg == []:
|
||||||
|
testidxneg = vertidx[i]
|
||||||
|
|
||||||
|
# intersected faces
|
||||||
|
else:
|
||||||
|
# make new mesh
|
||||||
|
if RBmesh1.val == 1:
|
||||||
|
vlp, vln, newvidx, newvcoo = Split(Obj, MeshNew, MeshNew, vertglob[i], vertidx[i], PNormal, POffset, newvidx, newvcoo, totverts, vertdist[i])
|
||||||
|
|
||||||
|
if vlp != 0 and vln != 0:
|
||||||
|
FaceMake(MeshNew, vlp)
|
||||||
|
FaceMake(MeshNew, vln)
|
||||||
|
# two new meshes
|
||||||
|
elif RBmesh2.val == 1:
|
||||||
|
vlp, vln, newvidx, newvcoo = Split(Obj, MeshPos, MeshNeg, vertglob[i], vertidx[i], PNormal, POffset, newvidx, newvcoo, totverts, vertdist[i])
|
||||||
|
|
||||||
|
if vlp != 0 and vln != 0:
|
||||||
|
FaceMake(MeshPos, vlp)
|
||||||
|
FaceMake(MeshNeg, vln)
|
||||||
|
|
||||||
|
# use old mesh
|
||||||
|
elif RBmesh0.val == 1:
|
||||||
|
|
||||||
|
vlp, vln, newvidx, newvcoo = Split(Obj, m, m, vertglob[i], vertidx[i], PNormal, POffset, newvidx, newvcoo, totverts, vertdist[i])
|
||||||
|
|
||||||
|
if vlp != 0 and vln != 0:
|
||||||
|
FaceMake(m, vlp)
|
||||||
|
FaceMake(m, vln)
|
||||||
|
|
||||||
|
if RBmesh1.val == 1:
|
||||||
|
|
||||||
|
ObOne = NMesh.PutRaw(MeshNew)
|
||||||
|
|
||||||
|
ObOne.LocX, ObOne.LocY, ObOne.LocZ = Obj.LocX, Obj.LocY, Obj.LocZ
|
||||||
|
ObOne.RotX, ObOne.RotY, ObOne.RotZ = Obj.RotX, Obj.RotY, Obj.RotZ
|
||||||
|
ObOne.SizeX, ObOne.SizeY, ObOne.SizeZ = Obj.SizeX, Obj.SizeY, Obj.SizeZ
|
||||||
|
|
||||||
|
elif RBmesh2.val == 1:
|
||||||
|
|
||||||
|
# remove verts that do not belong to a face
|
||||||
|
idx2.reverse()
|
||||||
|
dist2.reverse()
|
||||||
|
|
||||||
|
for i in range(len(idx2)):
|
||||||
|
if dist2[i] < 0:
|
||||||
|
v = MeshPos.verts[idx2[i]]
|
||||||
|
MeshPos.verts.remove(v)
|
||||||
|
if dist2[i] > 0:
|
||||||
|
v = MeshNeg.verts[idx2[i]]
|
||||||
|
MeshNeg.verts.remove(v)
|
||||||
|
|
||||||
|
ObPos = NMesh.PutRaw(MeshPos)
|
||||||
|
|
||||||
|
ObPos.LocX, ObPos.LocY, ObPos.LocZ = Obj.LocX, Obj.LocY, Obj.LocZ
|
||||||
|
ObPos.RotX, ObPos.RotY, ObPos.RotZ = Obj.RotX, Obj.RotY, Obj.RotZ
|
||||||
|
ObPos.SizeX, ObPos.SizeY, ObPos.SizeZ = Obj.SizeX, Obj.SizeY, Obj.SizeZ
|
||||||
|
|
||||||
|
ObNeg = NMesh.PutRaw(MeshNeg)
|
||||||
|
|
||||||
|
ObNeg.LocX, ObNeg.LocY, ObNeg.LocZ = Obj.LocX, Obj.LocY, Obj.LocZ
|
||||||
|
ObNeg.RotX, ObNeg.RotY, ObNeg.RotZ = Obj.RotX, Obj.RotY, Obj.RotZ
|
||||||
|
ObNeg.SizeX, ObNeg.SizeY, ObNeg.SizeZ = Obj.SizeX, Obj.SizeY, Obj.SizeZ
|
||||||
|
|
||||||
|
elif RBmesh0.val == 1:
|
||||||
|
m.update()
|
||||||
|
|
||||||
|
|
||||||
|
#if timport == 1:
|
||||||
|
#end = time.clock()
|
||||||
|
#total = end - start
|
||||||
|
#print "mesh(es) cut in", total, "seconds"
|
||||||
|
|
||||||
|
end = time()
|
||||||
|
total = end - start
|
||||||
|
print "mesh(es) cut in", total, "seconds"
|
||||||
|
|
||||||
|
#############################################################
|
||||||
|
# Graphics #
|
||||||
|
#############################################################
|
||||||
|
def Warn():
|
||||||
|
BGL.glRasterPos2d(115, 23)
|
||||||
|
Blender.Window.Redraw(Blender.Window.Const.TEXT)
|
||||||
|
|
||||||
|
def draw():
|
||||||
|
global msg
|
||||||
|
global RBmesh0,RBmesh1,RBmesh2
|
||||||
|
global VERSION
|
||||||
|
|
||||||
|
BGL.glClearColor(0.5, 0.5, 0.5, 0.0)
|
||||||
|
BGL.glClear(BGL.GL_COLOR_BUFFER_BIT)
|
||||||
|
BGL.glColor3f(0, 0, 0) # Black
|
||||||
|
BGL.glRectf(2, 2, 482, 220)
|
||||||
|
BGL.glColor3f(0.48, 0.4, 0.57) # Light Purple
|
||||||
|
BGL.glRectf(4, 179, 480, 210)
|
||||||
|
BGL.glRectf(4, 34, 480, 150)
|
||||||
|
BGL.glColor3f(0.3, 0.27, 0.35) # Dark purple
|
||||||
|
BGL.glRectf(4, 151,480, 178)
|
||||||
|
BGL.glRectf(4, 4, 480, 33)
|
||||||
|
|
||||||
|
|
||||||
|
BGL.glColor3f(1, 1, 1)
|
||||||
|
BGL.glRasterPos2d(8, 200)
|
||||||
|
Draw.Text("Blender Knife Tool - V. 0.0.8a - 26 March 2004")
|
||||||
|
BGL.glRasterPos2d(8, 185)
|
||||||
|
Draw.Text("by Wim <tuinbels> Van Hoydonck & Stefano <S68> Selleri")
|
||||||
|
Draw.Button("Exit", 1, 430, 185, 40, 20)
|
||||||
|
|
||||||
|
RBmesh0 = Draw.Toggle("Edit Object", 10,10,157,153,18,RBmesh0.val, "The knife creates new vertices in the selected object.");
|
||||||
|
RBmesh1 = Draw.Toggle("New Object", 11,165,157,153,18,RBmesh1.val, "The knife duplicates the object and creates new vertices in the new object.");
|
||||||
|
RBmesh2 = Draw.Toggle("Two New Objects",12,320,157,153,18,RBmesh2.val, "The knife creates two new separate objects.");
|
||||||
|
|
||||||
|
BGL.glRasterPos2d(8, 128)
|
||||||
|
Draw.Text("1 - Draw a Mesh Plane defining the Cut Plane")
|
||||||
|
BGL.glRasterPos2d(8, 108)
|
||||||
|
Draw.Text("2 - Select the Meshes to be Cut and the Cut Plane")
|
||||||
|
BGL.glRasterPos2d(8, 88)
|
||||||
|
Draw.Text(" (Meshes Dark Purple, Plane Light Purple)")
|
||||||
|
BGL.glRasterPos2d(8, 68)
|
||||||
|
Draw.Text("3 - Choose the Edit Method (Radio Buttons above)")
|
||||||
|
BGL.glRasterPos2d(8, 48)
|
||||||
|
Draw.Text("4 - Push the 'CUT' button (below)")
|
||||||
|
#Create Buttons
|
||||||
|
Draw.Button("CUT", 4, 10, 10, 465, 18, "Cut the selected mesh along the plane")
|
||||||
|
|
||||||
|
|
||||||
|
BGL.glRasterPos2d(10, 223)
|
||||||
|
BGL.glColor3f(1,0,0)
|
||||||
|
Draw.Text(msg)
|
||||||
|
msg = ''
|
||||||
|
|
||||||
|
def event(evt, val):
|
||||||
|
if evt == Draw.QKEY and not val:
|
||||||
|
Draw.Exit()
|
||||||
|
if evt == Draw.CKEY and not val:
|
||||||
|
CutMesh()
|
||||||
|
Draw.Redraw()
|
||||||
|
|
||||||
|
def bevent(evt):
|
||||||
|
global RBmesh0,RBmesh1,RBmesh2
|
||||||
|
|
||||||
|
if evt == 1:
|
||||||
|
Draw.Exit()
|
||||||
|
elif evt == 4:
|
||||||
|
CutMesh()
|
||||||
|
Draw.Redraw()
|
||||||
|
elif evt == 10:
|
||||||
|
RBmesh0.val = 1
|
||||||
|
RBmesh1.val = 0
|
||||||
|
RBmesh2.val = 0
|
||||||
|
Draw.Redraw()
|
||||||
|
elif evt == 11:
|
||||||
|
RBmesh0.val = 0
|
||||||
|
RBmesh1.val = 1
|
||||||
|
RBmesh2.val = 0
|
||||||
|
Draw.Redraw()
|
||||||
|
elif evt == 12:
|
||||||
|
RBmesh0.val = 0
|
||||||
|
RBmesh1.val = 0
|
||||||
|
RBmesh2.val = 1
|
||||||
|
Draw.Redraw()
|
||||||
|
|
||||||
|
Draw.Register(draw, event, bevent)
|
@ -37,6 +37,7 @@
|
|||||||
#include <BSE_headerbuttons.h> /* for copy_scene */
|
#include <BSE_headerbuttons.h> /* for copy_scene */
|
||||||
#include <BIF_drawscene.h> /* for set_scene */
|
#include <BIF_drawscene.h> /* for set_scene */
|
||||||
#include <BIF_space.h> /* for copy_view3d_lock() */
|
#include <BIF_space.h> /* for copy_view3d_lock() */
|
||||||
|
#include <DNA_scriptlink_types.h>
|
||||||
#include <MEM_guardedalloc.h> /* for MEM_callocN */
|
#include <MEM_guardedalloc.h> /* for MEM_callocN */
|
||||||
#include <mydevice.h> /* for #define REDRAW */
|
#include <mydevice.h> /* for #define REDRAW */
|
||||||
|
|
||||||
@ -97,6 +98,7 @@ static PyObject *Scene_getChildren(BPy_Scene *self);
|
|||||||
static PyObject *Scene_getCurrentCamera(BPy_Scene *self);
|
static PyObject *Scene_getCurrentCamera(BPy_Scene *self);
|
||||||
static PyObject *Scene_setCurrentCamera(BPy_Scene *self, PyObject *args);
|
static PyObject *Scene_setCurrentCamera(BPy_Scene *self, PyObject *args);
|
||||||
static PyObject *Scene_getRenderingContext(BPy_Scene *self);
|
static PyObject *Scene_getRenderingContext(BPy_Scene *self);
|
||||||
|
static PyObject *Scene_getScriptlinks(BPy_Scene *self, PyObject *args);
|
||||||
|
|
||||||
//deprecated methods
|
//deprecated methods
|
||||||
static PyObject *Scene_currentFrame(BPy_Scene *self, PyObject *args);
|
static PyObject *Scene_currentFrame(BPy_Scene *self, PyObject *args);
|
||||||
@ -140,6 +142,9 @@ static PyMethodDef BPy_Scene_methods[] = {
|
|||||||
"() - Return list of all objects linked to scene self"},
|
"() - Return list of all objects linked to scene self"},
|
||||||
{"getCurrentCamera", (PyCFunction)Scene_getCurrentCamera, METH_NOARGS,
|
{"getCurrentCamera", (PyCFunction)Scene_getCurrentCamera, METH_NOARGS,
|
||||||
"() - Return current active Camera"},
|
"() - Return current active Camera"},
|
||||||
|
{"getScriptlinks", (PyCFunction)Scene_getScriptlinks, METH_VARARGS,
|
||||||
|
"(eventname) - Get a list of this scene's scriptlinks (Text names) of the given type\n"
|
||||||
|
"(eventname) - string: FrameChanged, OnLoad or Redraw."},
|
||||||
{"setCurrentCamera", (PyCFunction)Scene_setCurrentCamera, METH_VARARGS,
|
{"setCurrentCamera", (PyCFunction)Scene_setCurrentCamera, METH_VARARGS,
|
||||||
"() - Set the currently active Camera"},
|
"() - Set the currently active Camera"},
|
||||||
//DEPRECATED
|
//DEPRECATED
|
||||||
@ -693,7 +698,7 @@ static PyObject *Scene_setCurrentCamera (BPy_Scene *self, PyObject *args)
|
|||||||
{
|
{
|
||||||
Object *object;
|
Object *object;
|
||||||
BPy_Object *cam_obj;
|
BPy_Object *cam_obj;
|
||||||
Scene *scene = self->scene;
|
Scene *scene = self->scene;
|
||||||
|
|
||||||
if (!scene)
|
if (!scene)
|
||||||
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
@ -725,6 +730,55 @@ static PyObject *Scene_getRenderingContext (BPy_Scene *self)
|
|||||||
|
|
||||||
return RenderData_CreatePyObject(self->scene);
|
return RenderData_CreatePyObject(self->scene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Scene.getScriptlinks */
|
||||||
|
static PyObject *Scene_getScriptlinks (BPy_Scene *self, PyObject *args)
|
||||||
|
{
|
||||||
|
Scene *scene = self->scene;
|
||||||
|
char *eventname = NULL;
|
||||||
|
int event = 0;
|
||||||
|
ScriptLink *slink = &(scene)->scriptlink;
|
||||||
|
|
||||||
|
if (!scene)
|
||||||
|
return EXPP_ReturnPyObjError (PyExc_RuntimeError,
|
||||||
|
"Blender Scene was deleted!");
|
||||||
|
|
||||||
|
if (!PyArg_ParseTuple(args, "s", &eventname))
|
||||||
|
return EXPP_ReturnPyObjError (PyExc_TypeError,
|
||||||
|
"expected event name (string) as argument");
|
||||||
|
|
||||||
|
if (!strcmp(eventname, "FrameChanged"))
|
||||||
|
event = SCRIPT_FRAMECHANGED;
|
||||||
|
else if (!strcmp(eventname, "OnLoad"))
|
||||||
|
event = SCRIPT_ONLOAD;
|
||||||
|
else if (!strcmp(eventname, "Redraw"))
|
||||||
|
event = SCRIPT_REDRAW;
|
||||||
|
else
|
||||||
|
return EXPP_ReturnPyObjError (PyExc_AttributeError,
|
||||||
|
"unknown event");
|
||||||
|
|
||||||
|
/* actually !scriptlink shouldn't happen ... */
|
||||||
|
if (!slink || !slink->totscript) {
|
||||||
|
Py_INCREF(Py_None);
|
||||||
|
return Py_None;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PyObject *list = PyList_New(0);
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (!list)
|
||||||
|
return EXPP_ReturnPyObjError (PyExc_MemoryError,
|
||||||
|
"couldn't create PyList!");
|
||||||
|
|
||||||
|
for (i = 0; i < slink->totscript; i++) {
|
||||||
|
if ((slink->flag[i] == event) && slink->scripts[i])
|
||||||
|
PyList_Append(list, PyString_FromString(slink->scripts[i]->name+2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
// DEPRECATED
|
// DEPRECATED
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
static PyObject *M_sys_basename (PyObject *self, PyObject *args);
|
static PyObject *M_sys_basename (PyObject *self, PyObject *args);
|
||||||
static PyObject *M_sys_dirname (PyObject *self, PyObject *args);
|
static PyObject *M_sys_dirname (PyObject *self, PyObject *args);
|
||||||
static PyObject *M_sys_splitext (PyObject *self, PyObject *args);
|
static PyObject *M_sys_splitext (PyObject *self, PyObject *args);
|
||||||
|
static PyObject *M_sys_makename (PyObject *self, PyObject *args, PyObject *kw);
|
||||||
static PyObject *M_sys_exists (PyObject *self, PyObject *args);
|
static PyObject *M_sys_exists (PyObject *self, PyObject *args);
|
||||||
static PyObject *M_sys_time (PyObject *self);
|
static PyObject *M_sys_time (PyObject *self);
|
||||||
|
|
||||||
@ -69,6 +70,17 @@ static char M_sys_splitext_doc[] =
|
|||||||
/this/that/file.ext -> ('/this/that/file','.ext').\n\
|
/this/that/file.ext -> ('/this/that/file','.ext').\n\
|
||||||
Return the pair (root, extension).";
|
Return the pair (root, extension).";
|
||||||
|
|
||||||
|
static char M_sys_makename_doc[] =
|
||||||
|
"(path = Blender.Get('filename'), ext = \"\", strip = 0) -\n\
|
||||||
|
Strip dir and extension from path, leaving only a name, then append 'ext'\n\
|
||||||
|
to it (if given) and return the resulting string.\n\n\
|
||||||
|
(path) - string: a pathname -- Blender.Get('filename') if 'path' isn't given;\n\
|
||||||
|
(ext = \"\") - string: the extension to append.\n\
|
||||||
|
(strip = 0) - int: strip dirname from 'path' if given and non-zero.\n\
|
||||||
|
Ex: makename('/path/to/file/myfile.foo','-01.abc') returns 'myfile-01.abc'\n\
|
||||||
|
Ex: makename(ext='.txt') returns 'untitled.txt' if Blender.Get('filename')\n\
|
||||||
|
returns a path to the file 'untitled.blend'";
|
||||||
|
|
||||||
static char M_sys_time_doc[] =
|
static char M_sys_time_doc[] =
|
||||||
"() - Return a float representing time elapsed in seconds.\n\
|
"() - Return a float representing time elapsed in seconds.\n\
|
||||||
Each successive call is garanteed to return values greater than or\n\
|
Each successive call is garanteed to return values greater than or\n\
|
||||||
@ -84,6 +96,8 @@ struct PyMethodDef M_sys_methods[] = {
|
|||||||
{"basename", M_sys_basename, METH_VARARGS, M_sys_basename_doc},
|
{"basename", M_sys_basename, METH_VARARGS, M_sys_basename_doc},
|
||||||
{"dirname", M_sys_dirname, METH_VARARGS, M_sys_dirname_doc},
|
{"dirname", M_sys_dirname, METH_VARARGS, M_sys_dirname_doc},
|
||||||
{"splitext", M_sys_splitext, METH_VARARGS, M_sys_splitext_doc},
|
{"splitext", M_sys_splitext, METH_VARARGS, M_sys_splitext_doc},
|
||||||
|
{"makename", (PyCFunction)M_sys_makename, METH_VARARGS|METH_KEYWORDS,
|
||||||
|
M_sys_makename_doc},
|
||||||
{"exists", M_sys_exists, METH_VARARGS, M_sys_exists_doc},
|
{"exists", M_sys_exists, METH_VARARGS, M_sys_exists_doc},
|
||||||
{"time", (PyCFunction)M_sys_time, METH_NOARGS, M_sys_time_doc},
|
{"time", (PyCFunction)M_sys_time, METH_NOARGS, M_sys_time_doc},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
@ -145,7 +159,7 @@ static PyObject *M_sys_basename (PyObject *self, PyObject *args)
|
|||||||
return EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
|
return EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
|
||||||
|
|
||||||
strncpy(basename, p+1, n); /* + 1 to skip the sep */
|
strncpy(basename, p+1, n); /* + 1 to skip the sep */
|
||||||
basename[n] = 0;
|
basename[n] = '\0';
|
||||||
return Py_BuildValue("s", basename);
|
return Py_BuildValue("s", basename);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,11 +191,11 @@ static PyObject *M_sys_dirname (PyObject *self, PyObject *args)
|
|||||||
return EXPP_ReturnPyObjError (PyExc_RuntimeError, "path too long");
|
return EXPP_ReturnPyObjError (PyExc_RuntimeError, "path too long");
|
||||||
|
|
||||||
strncpy(dirname, name, n);
|
strncpy(dirname, name, n);
|
||||||
dirname[n] = 0;
|
dirname[n] = '\0';
|
||||||
return Py_BuildValue("s", dirname);
|
return Py_BuildValue("s", dirname);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Py_BuildValue("s", "."); /* XXX need to fix this? (is crossplatform?)*/
|
return Py_BuildValue("s", ".");
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *M_sys_splitext (PyObject *self, PyObject *args)
|
static PyObject *M_sys_splitext (PyObject *self, PyObject *args)
|
||||||
@ -220,13 +234,71 @@ static PyObject *M_sys_splitext (PyObject *self, PyObject *args)
|
|||||||
EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
|
EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
|
||||||
|
|
||||||
strncpy(ext, dot, n);
|
strncpy(ext, dot, n);
|
||||||
ext[n] = 0;
|
ext[n] = '\0';
|
||||||
strncpy(path, name, dot - name);
|
strncpy(path, name, dot - name);
|
||||||
path[dot - name] = 0;
|
path[dot - name] = '\0';
|
||||||
|
|
||||||
return Py_BuildValue("ss", path, ext);
|
return Py_BuildValue("ss", path, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static PyObject *M_sys_makename(PyObject *self, PyObject *args, PyObject *kw)
|
||||||
|
{
|
||||||
|
char *path = G.sce, *ext = NULL;
|
||||||
|
int strip = 0;
|
||||||
|
static char *kwlist[] = {"path", "ext", "strip", NULL};
|
||||||
|
char *dot = NULL, *p = NULL, basename[FILE_MAXFILE];
|
||||||
|
char sep;
|
||||||
|
int n, len, lenext = 0;
|
||||||
|
PyObject *c;
|
||||||
|
|
||||||
|
if (!PyArg_ParseTupleAndKeywords(args, kw, "|ssi", kwlist,
|
||||||
|
&path, &ext, &strip))
|
||||||
|
return EXPP_ReturnPyObjError (PyExc_TypeError,
|
||||||
|
"expected one or two strings and an int (or nothing) as arguments");
|
||||||
|
|
||||||
|
len = strlen(path);
|
||||||
|
if (ext) lenext = strlen(ext);
|
||||||
|
|
||||||
|
if ((len + lenext) > FILE_MAXFILE)
|
||||||
|
return EXPP_ReturnPyObjError(PyExc_RuntimeError, "path too long");
|
||||||
|
|
||||||
|
c = PyObject_GetAttrString (g_sysmodule, "dirsep");
|
||||||
|
sep = PyString_AsString(c)[0];
|
||||||
|
Py_DECREF(c);
|
||||||
|
|
||||||
|
p = strrchr(path, sep);
|
||||||
|
|
||||||
|
if (p && strip) {
|
||||||
|
n = path + len - p - 1; /* - 1 because we don't want the sep */
|
||||||
|
|
||||||
|
strncpy(basename, p+1, n); /* + 1 to skip the sep */
|
||||||
|
basename[n] = 0;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
strncpy(basename, path, len);
|
||||||
|
n = len;
|
||||||
|
basename[n] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
dot = strrchr(basename, '.');
|
||||||
|
|
||||||
|
/* now the extension: always remove the one in basename */
|
||||||
|
if (dot || ext) {
|
||||||
|
if (!ext)
|
||||||
|
basename[dot - basename] = '\0';
|
||||||
|
else { /* if user gave an ext, append it */
|
||||||
|
|
||||||
|
if (dot) n = dot - basename;
|
||||||
|
else n = strlen(basename);
|
||||||
|
|
||||||
|
strncpy(basename + n, ext, lenext);
|
||||||
|
basename[n+lenext] = '\0';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return PyString_FromString(basename);
|
||||||
|
}
|
||||||
|
|
||||||
static PyObject *M_sys_time (PyObject *self)
|
static PyObject *M_sys_time (PyObject *self)
|
||||||
{
|
{
|
||||||
double t = PIL_check_seconds_timer();
|
double t = PIL_check_seconds_timer();
|
||||||
|
@ -68,6 +68,35 @@ def splitext (path):
|
|||||||
@return: (root, ext)
|
@return: (root, ext)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def makename (path = "Blender.Get('filename')", ext = "", strip = 0):
|
||||||
|
"""
|
||||||
|
Remove extension from 'path', append extension 'ext' (if given)
|
||||||
|
to the result and return it. If 'strip' is non-zero, also remove
|
||||||
|
dirname from path.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
import Blender
|
||||||
|
from Blender.sys import *
|
||||||
|
print makename('/path/to/myfile.txt','.abc', 1) # returns 'myfile.abc'
|
||||||
|
|
||||||
|
print makename('/path/to/myfile.obj', '-01.obj') # '/path/to/myfile-01.obj'
|
||||||
|
|
||||||
|
print makename('/path/to/myfile.txt', strip = 1) # 'myfile'
|
||||||
|
|
||||||
|
# note that:
|
||||||
|
print makename(ext = '.txt')
|
||||||
|
# is equivalent to:
|
||||||
|
print sys.splitext(Blender.Get('filename'))[0]) + '.txt'
|
||||||
|
|
||||||
|
@type path: string
|
||||||
|
@param path: a path name or Blender.Get('filename'), if not given.
|
||||||
|
@type ext: string
|
||||||
|
@param ext: an extension to append. For flexibility, a dot ('.') is
|
||||||
|
not automatically included.
|
||||||
|
@rtype: string
|
||||||
|
@return: the resulting string
|
||||||
|
"""
|
||||||
|
|
||||||
def exists(path):
|
def exists(path):
|
||||||
"""
|
"""
|
||||||
Tell if the given pathname (file or dir) exists.
|
Tell if the given pathname (file or dir) exists.
|
||||||
|
Loading…
Reference in New Issue
Block a user