[Closed] Custom Geo + Tube
Below in my script I create my own custom plane. When users hit the enable button I want them to be able to create with it a Tube, but rather than me creating the tube from scratch I wanted to just create and instance of the primitive tube and then modifier it from there. How can I integrate the tube to my custom plane and it actually be part of the mesh along with the settings adjusting the size of the tube?
plugin simpleObject IntegratedMesh
name:"IntegratedMesh"
category:"Standard Primitives"
classID:#(0x512e8ff9, 0x51aefc78)
(
parameters main rollout:rltParams
(
enableTube type:#boolean default:false ui:uiEnableTube
tubeRadius type:#worldUnits default:6 ui:uiTubeRadius
frameWidth type:#worldUnits default:30 ui:uiFrameWidth
frameSegs type:#integer default:4 ui:uiFrameSegs
)
rollout rltParams "Parameters"
(
checkbox uiEnableTube "Enable Tube" offset:[6,4]
spinner uiTubeRadius "Tube Radius:" range:[.1,1e9,0] type:#worldUnits
spinner uiFrameWidth "Frame Width:" range:[0,1e9,0] type:#worldunits offset:[0,6]
spinner uiFrameSegs "Segments:" range:[2,1e9,1] type:#integer
)
fn genFramePlatform start:[0,0,0] =
(
local FrameVerts = #()
/* Create first strip of verts */
for r = 0 to frameSegs-1 do
(
rowSet = (frameWidth/(frameSegs-1))*r
for s = 0 to frameSegs-1 do
(
offset = (frameWidth/(frameSegs-1))*s
vertPos = start + [offset,rowSet,0]
append FrameVerts vertPos
)
)
return FrameVerts
)
fn genMesh =
(
/*Set Vertices*/
local verticesArr = #()
/* Platform of Verts */
frameVerts = genFramePlatform start:[0,0,0]
join verticesArr frameVerts
/*Set Faces*/
local facesArr = #()
local count = frameSegs
local endCounter = count
local loops = frameSegs * frameSegs - frameSegs --total number of verts minus last set
for l = 1 to loops do
(
if l < endCounter then --less then
(
append facesArr [l+1, l, l+count]
append facesArr [l+count , l+count+1 , l+1 ]
)else(
--only needed if planning on connecting start/end edges like a tube
endCounter += count --reset strip of verts
)
)
/*Set Mesh*/
platformMesh = setMesh mesh verts:verticesArr faces:facesArr
/* Tube */
if enableTube do
(
local tub = createinstance Tube pos:[0,0,0] sides:8 heightsegs:20 capsegs:1 height:30 radius1:tubeRadius radius2:(tubeRadius/2) smooth:on
setMesh mesh tub.mesh
free tub
)
update mesh
)
on buildMesh do (genMesh())
tool create
(
on mousePoint click do ()
on mouseMove click do ()
)
)
delete objects
clearlistener()
m = IntegratedMesh()
m.vertexticks = true
select m
updated the code above. I got the tube to display but not with the plane i create…?
I saw this practice used in Denis plugin http://forums.cgsociety.org/showthread.php?t=1030472
I tried to see how he went about doing it, but it was not clear to me how it would work in my case where it’s part custom geo and part primitive.
Aaaaaa… nice That does the trick
so close.
Now I tried looking up what the term
‘free’ meant in maxscript and there was no description that I could find.
I saw it here on cgtalk in a few posts of geo plugins. Does anyone know what the point of that function is?
Thanks again bobo for your help!
Free() Method
The free() method has been implemented since 3ds Max 9 but has remained undocumented. This method frees the memory used by the value without waiting for a garbage collection to occur. It is implemented for the following classes: String Value, StringStream Value, FileStream Value, BitMap Value, Array Value, BitArray Value, Mesh Value
Nicely done. I tried searching for it online in the docs but they were taking forever and turning up results that didn’t help.
On a side note.
Now in the script below, I use a for-loop which allows me to copy the mesh multiple times and I store it in variable called meshes=#().
From there I then attach all those to the main mesh by using the meshop.attach mesh m.
Is there an easy way to offset each one of those elements by a random value for example
how would I apply this offset to each mesh before or after it gets attached?
offset = [random 0 50,0,0]
Unless the only way to do it is by going vert by vert for each mesh, that works to I suppose.
plugin simpleObject IntegratedMesh
name:"IntegratedMesh"
category:"Standard Primitives"
classID:#(0x512e8ff9, 0x51aefc78)
(
parameters main rollout:rltParams
(
enableTube type:#boolean default:false ui:uiEnableTube
tubeRadius type:#worldUnits default:6 ui:uiTubeRadius
frameWidth type:#worldUnits default:30 ui:uiFrameWidth
frameSegs type:#integer default:4 ui:uiFrameSegs
)
rollout rltParams "Parameters"
(
checkbox uiEnableTube "Enable Tube" offset:[6,4]
spinner uiTubeRadius "Tube Radius:" range:[.1,1e9,0] type:#worldUnits
spinner uiFrameWidth "Frame Width:" range:[0,1e9,0] type:#worldunits offset:[0,6]
spinner uiFrameSegs "Segments:" range:[2,1e9,1] type:#integer
)
fn genFramePlatform start:[0,0,0] =
(
local FrameVerts = #()
/* Create first strip of verts */
for r = 0 to frameSegs-1 do
(
rowSet = (frameWidth/(frameSegs-1))*r
for s = 0 to frameSegs-1 do
(
offset = (frameWidth/(frameSegs-1))*s
vertPos = start + [offset,rowSet,0]
append FrameVerts vertPos
)
)
return FrameVerts
)
fn genMesh =
(
/*Set Vertices*/
local verticesArr = #()
/* Platform of Verts */
frameVerts = genFramePlatform start:[0,0,0]
join verticesArr frameVerts
/*Set Faces*/
local facesArr = #()
local count = frameSegs
local endCounter = count
local loops = frameSegs * frameSegs - frameSegs --total number of verts minus last set
for l = 1 to loops do
(
if l < endCounter then --less then
(
append facesArr [l+1, l, l+count]
append facesArr [l+count , l+count+1 , l+1 ]
)else(
--only needed if planning on connecting start/end edges like a tube
endCounter += count --reset strip of verts
)
)
/*Set Mesh*/
platformMesh = setMesh mesh verts:verticesArr faces:facesArr
/*Dupe Meshes*/
local meshes = #()
for i = 1 to 5 do
(
append meshes (copy mesh)
)
for m in meshes do
(
meshop.attach mesh m
)
/* Tube */
if enableTube do
(
local tub = createinstance Tube pos:[0,0,0] sides:8 heightsegs:20 capsegs:1 height:30 radius1:tubeRadius radius2:(tubeRadius/2) smooth:on
meshop.attach mesh tub.mesh
free tub
)
update mesh
)
on buildMesh do (genMesh())
tool create
(
on mousePoint click do ()
on mouseMove click do ()
)
)
delete objects
clearlistener()
m = IntegratedMesh()
m.vertexticks = true
select m
Got it working
Now I can just throw a weld in there and its a wrap. This by no means is a complete tool, but more so just an R&D setup
plugin simpleObject IntegratedMesh
name:"IntegratedMesh"
category:"Standard Primitives"
classID:#(0x512e8ff9, 0x51aefc78)
(
parameters main rollout:rltParams
(
enableTube type:#boolean default:false ui:uiEnableTube
tubeRadius type:#worldUnits default:6 ui:uiTubeRadius
frameWidth type:#worldUnits default:30 ui:uiFrameWidth
frameSegs type:#integer default:4 ui:uiFrameSegs
)
rollout rltParams "Parameters"
(
checkbox uiEnableTube "Enable Tube" offset:[6,4]
spinner uiTubeRadius "Tube Radius:" range:[.1,1e9,0] type:#worldUnits
spinner uiFrameWidth "Frame Width:" range:[0,1e9,0] type:#worldunits offset:[0,6]
spinner uiFrameSegs "Segments:" range:[2,1e9,1] type:#integer
)
fn genFramePlatform start:[0,0,0] =
(
local FrameVerts = #()
/* Create first strip of verts */
for r = 0 to frameSegs-1 do
(
rowSet = (frameWidth/(frameSegs-1))*r
for s = 0 to frameSegs-1 do
(
offset = (frameWidth/(frameSegs-1))*s
vertPos = start + [offset,rowSet,0]
append FrameVerts vertPos
)
)
return FrameVerts
)
fn genMesh =
(
/*Set Vertices*/
local verticesArr = #()
/* Platform of Verts */
frameVerts = genFramePlatform start:[0,0,0]
join verticesArr frameVerts
/*Set Faces*/
local facesArr = #()
local count = frameSegs
local endCounter = count
local loops = frameSegs * frameSegs - frameSegs --total number of verts minus last set
for l = 1 to loops do
(
if l < endCounter then --less then
(
append facesArr [l+1, l, l+count]
append facesArr [l+count , l+count+1 , l+1 ]
)else(
--only needed if planning on connecting start/end edges like a tube
endCounter += count --reset strip of verts
)
)
/*Set Mesh*/
platformMesh = setMesh mesh verts:verticesArr faces:facesArr
/*Dupe Meshes*/
local meshes = #()
for i = 1 to 5 do
(
tmpMesh = copy mesh
offsetVerts = for v in tmpMesh.vertices collect (v.pos+[frameWidth*i,0,0])
setmesh tmpMesh vertices:offsetVerts
append meshes tmpMesh
)
for m in meshes do
(
meshop.attach mesh m
)
/* Tube */
if enableTube do
(
local tub = createinstance Tube pos:[0,0,0] sides:8 heightsegs:20 capsegs:1 height:30 radius1:tubeRadius radius2:(tubeRadius/2) smooth:on
meshop.attach mesh tub.mesh
free tub
)
update mesh
)
on buildMesh do (genMesh())
tool create
(
on mousePoint click do ()
on mouseMove click do ()
)
)
delete objects
clearlistener()
m = IntegratedMesh()
m.vertexticks = true
select m
plugin simpleObject IntegratedMesh
name:"IntegratedMesh"
category:"Standard Primitives"
classID:#(0x512e8ff9, 0x51aefc78)
(
parameters main rollout:rltParams
(
enableTube type:#boolean default:false ui:uiEnableTube
tubeRadius type:#worldUnits default:6 ui:uiTubeRadius
frameWidth type:#worldUnits default:30 ui:uiFrameWidth
frameSegs type:#integer default:4 ui:uiFrameSegs
numDupes type:#integer default:5 ui:uiNumDupes
DupeDist type:#float default:10 ui:uiDupeDist
)
rollout rltParams "Parameters"
(
checkbox uiEnableTube "Enable Tube" offset:[6,4]
spinner uiTubeRadius "Tube Radius:" range:[.1,1e9,0] type:#worldUnits
spinner uiFrameWidth "Frame Width:" range:[0,1e9,0] type:#worldunits offset:[0,6]
spinner uiFrameSegs "Segments:" range:[2,1e9,1] type:#integer
spinner uiNumDupes "Duplicates:" range:[0,100,5] type:#integer offset:[0,3]
spinner uiDupeDist "Distance:" range:[0,100000,10] type:#worldunits offset:[0,3]
)
fn genFramePlatform start:[0,0,0] =
(
local FrameVerts = #()
/* Create first strip of verts */
for r = 0 to frameSegs-1 do
(
rowSet = (frameWidth/(frameSegs-1))*r
for s = 0 to frameSegs-1 do
(
offset = (frameWidth/(frameSegs-1))*s
vertPos = start + [offset,rowSet,0]
append FrameVerts vertPos
)
)
return FrameVerts
)
fn genMesh =
(
/*Set Vertices*/
local verticesArr = #()
/* Platform of Verts */
frameVerts = genFramePlatform start:[0,0,0]
join verticesArr frameVerts
/*Set Faces*/
local facesArr = #()
local count = frameSegs
local endCounter = count
local loops = frameSegs * frameSegs - frameSegs --total number of verts minus last set
for l = 1 to loops do
(
if l < endCounter then --less then
(
append facesArr [l+1, l, l+count]
append facesArr [l+count , l+count+1 , l+1 ]
)else(
--only needed if planning on connecting start/end edges like a tube
endCounter += count --reset strip of verts
)
)
/*Set Mesh*/
platformMesh = setMesh mesh verts:verticesArr faces:facesArr
/*Dupe Meshes*/
local meshes = #()
for i = 1 to numDupes do
(
local newMesh = copy mesh
meshop.moveVert newMesh #{1..(newMesh.numverts)} [0,0,i*DupeDist]
append meshes newMesh
)
for m in meshes do
(
meshop.attach mesh m
free m
)
free meshes
/* Tube */
if enableTube do
(
local tub = createinstance Tube pos:[0,0,0] sides:8 heightsegs:20 capsegs:1 height:30 radius1:tubeRadius radius2:(tubeRadius/2) smooth:on
meshop.attach mesh tub.mesh
free tub
)
update mesh
)
on buildMesh do (genMesh())
tool create
(
on mousePoint click do ()
on mouseMove click do ()
)
)
delete objects
clearlistener()
m = IntegratedMesh()
m.vertexticks = true
select m
Now in this case say that I attached the meshes and I want to further adjust the placement of the verts within the entire main mesh. How can I go about adjusting those verts?
Would I place something like this right above the ‘update mesh’?
meshop.moveVert mesh #{1..(mesh.numverts)} [0,0,i*50]
Nicely done Bobo.
This will sure make for some interesting custom geo ideas I have. Thank you for your help on all of this.
Can you add a modifier to a mesh in the custom geo? for example a shell modifier?