[Closed] Sample Simple Object Plug-in
Could I use your mesh attach method for a normal object array?
Like snapshot meshes and attach like that instead of using EPoly? Would it be alot faster?
of course it might be done this way, but i think the converting big mesh to poly will whittle any advantage of using this method.
I ended up taking Lo’s attach function from one of the challenges and having it use meshop instead of polyop.
Also with turning off undo and whatnot, now from before taking almost 30 seconds to attach many HP models, now it takes like 2-3 seconds to attach 1 million polys worth in a couple hundred meshes.
Edit: Although before I forgot to turn off undo with my old method, so it was killing max and causing memory leaks or something. Now max runs 100x better and attach is much better.
30 vs 3 seconds… could you show the final code? how long does it take to convert 1 million face mesh to poly?
Well the 30seconds was prob from leaking, I had to restart max.
But in any case, it still is like 2-4x faster than what I had before.
To attach 841,921K Polys, 99 Objects, being ones with modifiers, turbosmoothed, ect.
Processing took 1.729 seconds
--Thanks to Lo of CGTalk for this one
fn customAttach source nodes =
(
with undo off
(
insertitem source nodes 1
local count = nodes.count
local att = meshop.attach
local vertArr = for o in nodes collect o.numVerts
local sortedVertArr = deepcopy vertArr
for i = 1 to nodes.count-1 do if not keyboard.escpressed do
(
-- pb.value = 100 - nodes.count*100./count
sort sortedVertArr
local a = findItem vertArr sortedVertArr[1]
vertArr[a]=-1
local b = findItem vertArr sortedVertArr[2]
local nA = nodes[a]
att nA nodes[b]
sortedVertArr[1]=vertArr[a]=nA.numVerts
deleteItem vertArr b
deleteItem sortedVertArr 2
deleteItem nodes b
--verts += nA.numverts
)
)
nodes[1]
)
the mode for fast preview or fast manual creation added:
/* denisT script collection (2012)*/
plugin simpleObject BrickChimney
name:"Chimney"
classID:#(0x10001967,0xA0000001)
category:"Scripted Primitives"
(
local attach = meshop.attach
local numBricks = 0, numBrickVerts = 0, numBrickFaces = 0
parameters params rollout:params
(
useClone type:#boolean default:on ui:ui_useClone
manualUpdate type:#boolean default:on ui:ui_manualUpdate
height type:#worldunits default:5 ui:ui_height
radius type:#worldunits default:5 ui:ui_radius
shift type:#float default:0.5 ui:ui_shift
sector type:#boolean default:off ui:ui_sector
on sector set val do this.params.ui_sectorFrom.enabled = this.params.ui_sectorTo.enabled = val
sectorFrom type:#float default:0 ui:ui_sectorFrom
sectorTo type:#float default:360 ui:ui_sectorTo
brickLength type:#worldunits default:2.5 ui:ui_brickLength
brickWidth type:#worldunits default:1.6 ui:ui_brickWidth
brickHeight type:#worldunits default:1 ui:ui_brickHeight
brickFillet type:#worldunits default:0.15 ui:ui_brickFillet
brickFilletSegs type:#integer default:2 ui:ui_brickFilletSegs
brickTaper type:#boolean default:on ui:ui_brickTaper
brickSmooth type:#integer default:1 ui:ui_brickSmooth
brickMapCoords type:#integer default:1 ui:ui_brickMapCoords
brickRealWorldMapSize type:#boolean default:off ui:ui_brickRealWorldMapSize
)
rollout params "Parameters"
(
checkbox ui_useClone "Use Clone Method" offset:[0,0]
checkbox ui_manualUpdate "Preview Mode" offset:[0,0]
group "Chimney:"
(
spinner ui_height "Height: " type:#worldunits range:[0,1e9,0] scale:0.1 fieldwidth:56
spinner ui_radius "Radius: " type:#worldunits range:[0,1e9,0] scale:0.1 fieldwidth:56 offset:[0,-2]
spinner ui_shift "Shift: " type:#float range:[0,1,0] scale:0.01 fieldwidth:56 offset:[0,-2]
checkbox ui_sector "Sector" offset:[71,2]
spinner ui_sectorFrom "Sector From: " type:#integer range:[0,360,0] fieldwidth:56 enabled:sector
spinner ui_sectorTo "Sector To: " type:#integer range:[0,360,0] fieldwidth:56 offset:[0,-2] enabled:sector
)
group "Brick:"
(
spinner ui_brickLength "Length: " type:#worldunits range:[0,1e9,0] scale:0.01 fieldwidth:56
spinner ui_brickWidth "Width: " type:#worldunits range:[0,1e9,0] scale:0.01 fieldwidth:56 offset:[0,-2]
spinner ui_brickHeight "Height: " type:#worldunits range:[0,1e9,0] scale:0.01 fieldwidth:56 offset:[0,-2]
spinner ui_brickFillet "Fillet: " type:#worldunits range:[0,1e9,0] scale:0.01 fieldwidth:56 offset:[0,2]
spinner ui_brickFilletSegs "Fillet Segs: " type:#integer range:[0,5,0] fieldwidth:56 offset:[0,-2]
checkbox ui_brickTaper "Taper" offset:[71,2]
checkbox ui_brickSmooth "Smooth" offset:[71,-2]
checkbox ui_brickMapCoords "Apply Mapping Coords." offset:[0,2]
checkbox ui_brickRealWorldMapSize "Real-World Map Size" offset:[0,-2]
)
)
fn round d pre:1 = (ceil(d/pre)*pre)
fn roundFloat d pre:0.001 =
(
d = (d as float)/pre
v = if (d - (v1 = floor d)) > ((v2 = ceil d) - d) then v2 else v1
v*pre
)
fn numberRows =
(
(if (height*brickHeight) == 0 then 0 else (height/brickHeight) as integer) + 1
)
fn numberBricksInRow =
(
--brickLength = 2*radius*sin(pi/n)
if (radius*brickLength) == 0 then 0 else
(
n = 180./(asin(brickLength/(2*radius)))
if (bit.isNAN n) then 0 else (n as integer)
)
)
fn transformMesh mesh verts offset: angle: =
(
for v=1 to verts.count do
(
tm = transmatrix (verts[v] + offset)
tm = rotateZ tm angle
setvert mesh v tm.pos
)
mesh
)
fn transformVerts mesh verts offset: angle: =
(
list = for v=1 to verts.count collect
(
tm = transmatrix (verts[v] + offset)
(rotateZ tm angle).pos
)
setmesh mesh vertices:list
mesh
)
fn attachMeshes meshes =
(
n = meshes.count
while (num = n/2) > 0 do for k=1 to num do
(
attach meshes[k] meshes[n]
n -= 1
)
meshes[1]
)
fn getShift angle index:0 =
(
local s = shift*angle*index
s = mod s angle
if s > angle/2 do s = s - angle
s
)
on buildMesh do
(
t1 = timestamp()
setMesh mesh numverts:0 numfaces:0
numBricks = 0
local n = numberBricksInRow()
local h = numberRows()
local angle = 360.0/n
if n >= 3 do
if manualUpdate then
(
local b =
(
local start = 0, end = 0, k = n, slide = 0
if sector do
(
slide = 1
start = 360 - (round sectorFrom pre:angle) + (angle/2)
end = 360 - (round sectorTo pre:angle) + (angle/2)
k = (start - end)/angle
--format "% % %
" start end k
)
createinstance Tube sides:k heightsegs:h capsegs:1 \
height:(h*brickHeight) radius1:radius radius2:(radius-brickWidth) \
slice_on:slide sliceFrom:start sliceTo:end \
smooth:off mapcoords:(brickMapCoords > 0) realWorldMapSize:brickRealWorldMapSize
)
setMesh mesh b.mesh
free b
--format "time:% bricks:%
" (timestamp()-t1) numBricks
)
else
(
local b = if brickFilletSegs > 0 then
(
createinstance ChamferBox Length_Segments:1 Width_Segments:1 Height_Segments:1 Fillet_Segments:brickFilletSegs \
length:brickLength width:brickWidth height:brickHeight Fillet:brickFillet \
smooth:brickSmooth mapcoords:brickMapCoords realWorldMapSize:brickRealWorldMapSize
)
else
(
createinstance Box lengthsegs:1 widthsegs:1 heightsegs:1 \
length:brickLength width:brickWidth height:brickHeight \
mapcoords:(brickMapCoords > 0) realWorldMapSize:brickRealWorldMapSize
)
brick = copy b.mesh
numBrickVerts = brick.numverts
numBrickFaces = brick.numfaces
local verts = #{1..numBrickVerts}
local w = brickWidth/2
local r = radius * cos(angle/2) - w
local offset = [r,0,0]
local vert_array = for v in verts collect
(
p = (getvert brick v) + offset
if brickTaper do
(
--format "v:% % % %
" v p r (r+w)
p.y *= p.x/(r+w)
)
p
)
local meshes = #()
offset = [0,0,0]
if useClone then
(
local bricks = #()
for k=0 to n-1 do
(
ang = k*angle
if not sector or (ang >= sectorFrom and ang <= sectorTo) do
(
transformVerts brick vert_array offset:offset angle:(90 - ang)
numBricks += 1
append bricks (copy brick)
)
)
if numBricks > 0 do
(
setmesh brick (attachMeshes bricks)
offset = [0,0,0]
vert_array = for v=1 to brick.numverts collect (getvert brick v)
for z=0 to h-1 do
(
offset.z = brickHeight*z
s = getShift angle index:z
transformVerts brick vert_array offset:offset angle:-s
append meshes (copy brick)
)
numBricks *= h
)
)
else
(
for z=0 to h-1 do
(
offset_z = brickHeight*z
s = getShift angle index:z
for k=0 to n-1 do
(
ang = k*angle
if not sector or (ang >= sectorFrom and ang <= sectorTo) do
(
--offset.x = random -0.2 0.2
offset.z = offset_z --+ (random -0.1 0.1)
transformVerts brick vert_array offset:offset angle:(90 - ang - s)
numBricks += 1
append meshes (copy brick)
)
)
)
)
if numBricks > 0 do setmesh mesh (attachMeshes meshes)
free b
free meshes
format "time:% bricks:%
" (timestamp()-t1) numBricks
)
)
tool create
(
on mousePoint click do case click of
(
1:
(
manualUpdate = on
nodeTM.translation = gridPoint
height = 0
radius = 0
)
3:
(
manualUpdate = off
#stop
)
)
on mouseMove click do case click of
(
2:
(
radius = sqrt (gridDist.x^2 + gridDist.y^2)
)
3: height = gridDist.z
)
)
)
during manual creation i use tube instance for faster preview. using #stop of tool creation i build the real mesh …