Script permettant de faire « tomber » des objets sur une face, c'est à dire les placer automatiquement au point d'intersection avec la surface, comme s'ils étaient physiquement posés dessus. L'intersection se calcule verticalement (vecteur Z) mais on peut choisir d'utiliser le z d'un plan de construction. On a également la possibilité d'ajouter une marge supplémentaire (offset) à la chute pour masquer certaines parties de l'objet (racines d'un arbre par exemple).
import rhinoscriptsyntax as rs
objectIds = rs.GetObjects("Select objects")
projectionSrfId = rs.GetObject("Select surface or polysurface to project to", rs.filter.polysurface | rs.filter.surface)
planes = []
planes.append("WorldXY") # add World XY
cplanes = rs.NamedCPlanes() # add named CPlanes
if cplanes:
for cplane in cplanes:
planes.append(cplane)
projectionPlane = rs.GetString("Plane to use for direction of projection (World or named CPlanes)", "WorldXY", planes)
offset = rs.GetReal("z Offset", 0)
if projectionSrfId:
if objectIds:
for objectId in objectIds:
box = rs.BoundingBox(objectId,rs.NamedCPlane(projectionPlane), True) #if CPlane name is not found, falls back on WorldXY
if box:
bottomRightPt = [0,0,0]
topLeftPt = [0,0,0]
bottomLeftPt = [0,0,0]
for i, point in enumerate(box):
if i==1:
bottomRightPt = point
if i==7:
topLeftPt = point
if i==3:
bottomLeftPt = point
diagonal = rs.AddLine(topLeftPt, bottomRightPt)
centroidPt = rs.CurveMidPoint(diagonal)
rs.DeleteObject(diagonal)
zVector = rs.VectorCreate(bottomLeftPt, topLeftPt)
zVector = rs.VectorDivide(zVector, 2)
zVectorU = rs.VectorUnitize(zVector)
offsetVector = rs.VectorScale(zVectorU,-offset)
bottomCentroidPt = [centroidPt[0] + zVector[0], centroidPt[1] + zVector[1], centroidPt[2] + zVector[2]]
projectedPts = rs.ProjectPointToSurface(bottomCentroidPt, projectionSrfId, zVector)
if projectedPts:
nearestProjectedPtId = rs.PointArrayClosestPoint(projectedPts, bottomCentroidPt)
destinationPt = projectedPts[nearestProjectedPtId]
rs.AddPoint(destinationPt)
projectVector = rs.VectorCreate(destinationPt,bottomCentroidPt)
if offset != 0:
projectVector = rs.VectorAdd(projectVector,offsetVector)
rs.MoveObject(objectId, projectVector)
else:
print "Object cannot be projected on surface."
else:
print "Bounding-boxes couldn't be created."
else:
print "No object selected."
else:
print "No surface selected."