Created
March 17, 2016 03:17
-
-
Save JokerMartini/7d0b27ed4af4b8ff3b9c to your computer and use it in GitHub Desktop.
Maxscript: Generates random points on a targeted surface. Credit Bobo.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
fn GenerateRandomPointsOnSurface theObj PointCount useIntersection:true numAttempts:10 = | |
( | |
delete $Teapot* --delete previous teapots (remove if you are not making teapots) | |
local st = timestamp() --get the start time | |
seed 12345 --set the random seed to a static number to get the same distribution each run | |
local theMesh = snapshotasMesh theObj --snapshot the TriMesh of the object | |
local theCount = theMesh.numfaces --get the number of faces in the TriMesh | |
local theNewObjectsArray = #() --init. an array for the objects to create | |
local theArea = 0 --init. a variable to hold the count. | |
for f = 1 to theCount do theArea += meshop.getFaceArea theMesh f --collect the area of the mesh | |
local ObjectsPerArea = PointCount / theArea --calculate the objects per square unit | |
local theIndices = for f = 1 to theCount collect f --collect the indices of the faces | |
local theRandomIndices = #() --init. an array to collect them randomly | |
while theIndices.count > 0 do --repeat until there are no indices left | |
( | |
theIndex = random 1 theIndices.count --pick a random face from the list | |
append theRandomIndices theIndices[theIndex] --add to the random list | |
deleteItem theIndices theIndex --and delete from the original list | |
) | |
local cnt = 0 --initialize a counter of the created points | |
for f in theRandomIndices while cnt < PointCount do --loop through the random faces until the count is reached | |
( | |
local theFace = getFace theMesh f --get the face def. of the random face | |
local theFactor = ceil ((meshop.getFaceArea theMesh f)*ObjectsPerArea) --calculate the points for the face, at least one. | |
local theVert1 = (getVert theMesh theFace.x) --get the first vertex' position | |
local theVert2 = (getVert theMesh theFace.y) --get the second vertex' position | |
local theVert3 = (getVert theMesh theFace.z) --get the third vertex' position | |
for i = 1 to theFactor while cnt < PointCount do --loop from 1 to the number of points on the face | |
( | |
local theNewObj = teapot radius:(random 2.0 5.0) wirecolor:red --create a teapot with random radius | |
theNewObj.transform = matrixFromNormal (getFaceNormal theMesh f) --set TM based on normal | |
local positionNotValid = true --raise a flag that the position is not valid yet | |
for attempts = 1 to numAttempts while positionNotValid do --repeat until position is valid or max. attempts have been made | |
( | |
local theX = random 0.0 1.0 --get a random X | |
local theY = random 0.0 1.0 --get a random Y | |
if theX+theY > 1.0 do --if the sum is greater than 1, subtract them from 1.0 | |
( | |
theX = 1.0 - theX | |
theY = 1.0 - theY | |
) | |
local theZ = 1.0 - theX - theY --the third bary coord is 1.0 minus the other two | |
theNewObj.pos = (theVert1*theX + theVert2*theY + theVert3*theZ) --set position using barycentric coords. | |
--if no intersection is requested, or if there is no intersection with existing objects, | |
if not useIntersection or (for o in theNewObjectsArray where intersects theNewObj o collect o).count == 0 do | |
( | |
append theNewObjectsArray theNewObj --add the new object to the array | |
cnt += 1 --increase the index | |
positionNotValid = false --lower the flag to stop iterating | |
) | |
)--end attempts loop | |
if positionNotValid do delete theNewObj --if all attempts failed due to intersections, delete the object | |
)--end i loop | |
)--end f loop | |
delete theMesh --free the memory from the TriMesh | |
format "Time: % ms\n" (timestamp()-st) --report the time | |
cnt --returns number of created objects | |
) | |
GenerateRandomPointsOnSurface $Plane001 1000 useIntersection:true numAttempts:10 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment