Aus PantheonWiki
- Texteditor in blender öffnen
- Inhalt des Skriptes hineinkopieren
- Vorkommnisse von `Ground` durch den Namen des Meshes auf das gedroppt werden soll ersetzen
- Das Ground-Mesh muss untransformiert sein ( Alt+S, Alt+R, Alt-G )
- Alles anwählen was gedroppt werden soll und über dem Terrain platzieren
- File->Run
#!BPY
"""
Name: 'Drop To Ground'
Blender: 232
Group: 'Positioning'
"""
#!BPY
# Drop Objects to Ground
#
# by Harkyman aka Roland Hess
# rolandhess@comcast.net
# license: Do whatever you want with it.
#
# This Script will drop all objects in the
# current selection onto the mesh object
# named 'Ground'.
#
# The script uses the mesh of Ground, so you
# can use irregular shapes like mountainsides,
# stairsteps, etc. It uses the Object Center
# for the objects to be dropped, so place them
# appropriately.
#
# Currently, the script only works on an untranslated,
# unmoved/sized Ground object. So Hit Cntl-A on all of
# your objects before you use this.
#
# So make your ground, select your objects to drop,
# and hit Alt-P!
#
# Things to do:
# 1. Take into account Ground object translation
import Blender
from Blender import NMesh
from math import *
def sideofline(PA,PB,PP):
return ((PA[0]-PP[0])*(PB[1]-PP[1]))-((PB[0]-PP[0])*(PA[1]-PP[1]))
def InsideQuad(p0,p1,p2,p3,p4):
if (sideofline(p1,p3,p0)>=0):
return (sideofline(p1,p4,p0)<=0) and (sideofline(p4,p3,p0)<=0)
else:
return (sideofline(p1,p2,p0)>=0) and (sideofline(p2,p3,p0)>=0)
def InsideTri(p0,p1,p2,p3):
return (sideofline(p1,p2,p0)>=0) and (sideofline(p2,p3,p0)>=0) and (sideofline(p3,p1,p0)>=0)
def FindZ(TriangleFace,tx,ty,tz,px,py):
[A,B,C]=TriangleFace.no
D=-((A*tx)+(B*ty)+(C*tz))
return -((A*px)+(B*py)+D)/C
def InverseTranslate(InCoords,DeltaVec):
return [InCoords[0]+DeltaVec[0],InCoords[1]+DeltaVec[1],InCoords[2]+DeltaVec[2]]
print '===Drop to Ground - Start==='
Ground = Blender.Object.Get ('Ground')
InvVec = Ground.getLocation ()
#determine min and max bounding values of the ground object
#so we can ignore selected objects not even over the ground
GroundBounds = Ground.getBoundBox ()
GBminX = 0
GBminY = 0
GBmaxX = 0
GBmaxY = 0
for [gbx, gby, gbz] in GroundBounds:
#adjust for Ground object location
gbx = gbx + InvVec[0]
gby = gby + InvVec[1]
gbz = gbz + InvVec[2]
if GBminX > gbx:
GBminX = gbx
else:
if GBmaxX < gbx:
GBmaxX = gbx
if GBminY > gby:
GBminY = gby
else:
if GBmaxY < gby:
GBmaxY = gby
#get the list of selected objects to drop
FloatingObjects = Blender.Object.GetSelected ()
#get the face list of the ground object
GroundMesh = Blender.NMesh.GetRawFromObject ('Ground')
for DropObject in FloatingObjects:
[DropX, DropY, DropZ] = DropObject.getLocation ()
#is the object above the ground's bounding box?
if ((DropX <= GBmaxX) and (DropX >= GBminX) and (DropY >=GBminY) and (DropY <= GBmaxY)):
#find which face the object is over - if the
#object isn't over a ground face, do nothing
GroundFaces = GroundMesh.faces
for GroundFace in GroundFaces:
GroundVerts = GroundFace.v
if len(GroundVerts) == 4:
#check for quad faces
[x1,y1,z1] = InverseTranslate(GroundVerts[0].co,InvVec)
[x2,y2,z2] = InverseTranslate(GroundVerts[1].co,InvVec)
[x3,y3,z3] = InverseTranslate(GroundVerts[2].co,InvVec)
[x4,y4,z4] = InverseTranslate(GroundVerts[3].co,InvVec)
p0=[DropX,DropY,0]
p1=[x1,y1,0]
p2=[x2,y2,0]
p3=[x3,y3,0]
p4=[x4,y4,0]
if InsideQuad(p0,p1,p2,p3,p4):
print 'Moved ', DropObject, ' to a Quad face.'
DropObject.setLocation(DropX,DropY,FindZ(GroundFace,x1,y1,z1,DropX,DropY))
else:
#check for tri faces
[x1,y1,z1] = GroundVerts[0].co
[x2,y2,z2] = GroundVerts[1].co
[x3,y3,z3] = GroundVerts[2].co
p0=[DropX,DropY,0]
p1=[x1,y1,0]
p2=[x2,y2,0]
p3=[x3,y3,0]
if InsideTri(p0,p1,p2,p3):
print 'Moved ', DropObject, ' to a Tri face.'
DropObject.setLocation(DropX,DropY,FindZ(GroundFace,x1,y1,z1,DropX,DropY))
print '===Drop to Ground - Done==='
Blender.Redraw()