[Closed] CgTalk Maxscript Challenge 001: "Make a Dining Table"
CgTalk Maxscript Challenge 001: “Make a Dining Table”
DESCRIPTION: Create a configuarable table creator, allowing adjustment for table dimensions, leg height and width.
RULES:
[ul]
[li]Must be code only. No pre-setup scenes.[/li][li]Code from scratch. Try not to use pre-exisitng functions or plugins.[/li][li]Show your script references, if any (eg. Looking at another script to assist you).[/li][li]You are encouraged to ask for help where needed, but try to do it on your own. The maxscript reference is an invaluable resource.[/li][li]Post your final script inside [/li]“`
tags (located on your posting toolbar).
[li]Post all code into THIS thread. [/li][/ul]
As I said earlier, I wanted to start small, but this challenge isn’t without it’s difficulties. You can take this to any level you like, but try to have code complete by Sunday night, as I’ll post new challenges every monday (Australian time).
Here is mine, this is my first ever maxscript :bounce:
references: just the maxscript help
rollout TableTool "Inaudable's Table Maker"
(
spinner t_lenght "Table Top Lenght: " type:#integer range:[10,200,50]
spinner t_width "Table Top Width: " type:#integer range:[10,200,50]
spinner t_height "Table Top Height: " type:#integer range:[2,100,5]
spinner l_width "Leg Width: " type:#integer range:[2,100,5]
spinner l_height "Leg Height: " type:#integer range:[2,200,40]
button create "Create Table"
on create pressed do
(
tabletopwidth = t_width.value
tabletoplenght = t_lenght.value
tabletopheight = t_height.value
legwidth = l_width.value
legheight = l_height.value
mytabletop = box length: tabletoplenght width: tabletopwidth height: tabletopheight
mytabletop.pos = [0,0,legheight]
myleg1 = box length: legwidth width: legwidth height: legheight
myleg2 = box length: legwidth width: legwidth height: legheight
myleg3 = box length: legwidth width: legwidth height: legheight
myleg4 = box length: legwidth width: legwidth height: legheight
myleg1.pos = [tabletopwidth/2.5,-tabletoplenght/2.5,0]
myleg2.pos = [-tabletopwidth/2.5,-tabletoplenght/2.5,0]
myleg3.pos = [tabletopwidth/2.5,tabletoplenght/2.5,0]
myleg4.pos = [-tabletopwidth/2.5,tabletoplenght/2.5,0]
)
)
createDialog TableTool width:250
It works but is very simple, One thing thing i would like to add to it would be to limit the width of the legs to like 20% the width of the table top. So the legs dont get out of proprotion if you make them too large or the top too small.
I tried setting the spinner to
l_width "Leg Width: " type:#integer range:[1,t_width/10,5]
but it doesn’t update when changing values of the table width.
Im sure there is another easyer way of doing it (and probably for the entire script :D) maybe two seperate dialog boxes, one for the top of the table, then once u have set that, the next one pops up for the legs, that way the width is already set, and can be put into the leg spinner properly.
Its by far not the best script in the world, or the best looking table, but im very happy that i actually got the basics of it to work
YAY im the first looking forward to what others come up with!
plugin simpleObject DinnerTable
name:"DinnerTable"
category:"CG Talk"
classID:#(0x2e2cb806, 0x61044495)
(
parameters main rollout:params
(
height type:#float ui:height default:0.0
num_faces type:#integer ui:num_faces default:3
radius1 type:#float ui:radius1 default:0
radius2 type:#float ui:radius2 default:0
lock_radii type:#boolean ui:lock_radii default:true
width type:#float ui:width default:1
thickness type:#float ui:thickness default:10.0
legwidth type:#float ui:legwidth default:5.0
leglength type:#float ui:leglength default:5.0
lock_leg type:#boolean ui:lock_leg default:false
legoffset type:#float ui:legoffset default:0.5
on radius1 set val do if lock_radii do radius2 = val
on radius2 set val do if lock_radii do radius1 = val
on legwidth set val do if lock_leg do leglength = val
on leglength set val do if lock_leg do legwidth = val
)
rollout params "Bobo's Dinner Table"
(
spinner height "Height:" range:[0,1000,100] type:#worldUnits fieldwidth:60
spinner thickness "Thickness:" range:[0,1000,1] type:#worldUnits fieldwidth:60
spinner width "Center Piece:" range:[0,1000,1] type:#worldUnits fieldwidth:60
group "Side Elements:"
(
spinner radius1 "Radius 1:" range:[0,10000,0] type:#worldUnits fieldwidth:60
checkbutton lock_radii "L" width:18 height:18 across:2 align:#left offset:[-5,-3]
spinner radius2 "Radius 2:" range:[0,10000,0] type:#worldUnits fieldwidth:60
spinner num_faces "Segments:" range:[2,100,10] type:#integer fieldwidth:60
)
group "Legs"
(
spinner legwidth "Width:" range:[0.0001,1000,5] type:#worldUnits fieldwidth:60
checkbutton lock_leg "L" width:18 height:18 across:2 align:#left offset:[-5,-3]
spinner leglength "Length:" range:[0.0001,1000,5] type:#worldUnits fieldwidth:60
spinner legoffset "Offset:" range:[0.0001,1.0,0.5] type:#float fieldwidth:60 scale:0.001
)
)
on buildMesh do
(
vert_array = #()
face_array = #()
center1 = [0,width/2,height]
center2 = [0,-width/2,height]
append vert_array center1
vert_count = 1
theStep = 180.0/num_faces
for a = 0 to 180-theStep by theStep do
(
append vert_array (center1 + [radius1*cos(a),radius1*sin(a),0])
append vert_array (center1 + [radius1*cos(a+theStep),radius1*sin(a+theStep),0])
append face_array [1 ,vert_count+1,vert_count+2]
vert_count += 2
)--end a loop
append vert_array center2
center2Index = vert_count += 1
for a = 180 to 360-theStep by theStep do
(
append vert_array (center2 + [radius2*cos(a),radius2*sin(a),0])
append vert_array (center2 + [radius2*cos(a+theStep),radius2*sin(a+theStep),0])
append face_array [center2Index ,vert_count+1,vert_count+2]
vert_count += 2
)--end a loop
append face_array [center2Index ,vert_count, 2]
append face_array [1, center2Index , 2]
append face_array [center2Index - 1, center2Index + 1, 1 ]
append face_array [center2Index + 1, center2Index, 1 ]
half_count = face_array.count
join face_array (for f in face_array collect [f.x,f.z,f.y])
--DEFINE THE LEGS
table_count = face_array.count
legs_faces = #()
join vert_array #([radius1*legoffset,width/2,0.0], [radius1*legoffset-legwidth,width/2,0.0], [radius1*legoffset-legwidth,width/2-leglength,0.0], [radius1*legoffset,width/2-leglength,0.0])
join legs_faces #([vert_count+1,vert_count+2,vert_count+3],[vert_count+1,vert_count+3,vert_count+4])
vert_count += 4
join vert_array #([-radius1*legoffset,width/2,0.0], [-radius1*legoffset+legwidth,width/2,0.0], [-radius1*legoffset+legwidth,width/2-leglength,0.0], [-radius1*legoffset,width/2-leglength,0.0])
join legs_faces #([vert_count+1,vert_count+3,vert_count+2],[vert_count+1,vert_count+4,vert_count+3])
vert_count += 4
join vert_array #([-radius2*legoffset,-width/2,0.0], [-radius2*legoffset+legwidth,-width/2,0.0], [-radius2*legoffset+legwidth,-width/2+leglength,0.0], [-radius2*legoffset,-width/2+leglength,0.0])
join legs_faces #([vert_count+1,vert_count+2,vert_count+3],[vert_count+1,vert_count+3,vert_count+4])
vert_count += 4
join vert_array #([radius2*legoffset,-width/2,0.0], [radius2*legoffset-legwidth,-width/2,0.0], [radius2*legoffset-legwidth,-width/2+leglength,0.0], [radius2*legoffset,-width/2+leglength,0.0])
join legs_faces #([vert_count+1,vert_count+3,vert_count+2],[vert_count+1,vert_count+4,vert_count+3])
vert_count += 4
join legs_faces ((for f in legs_faces collect [f.x,f.z,f.y]))
join face_array legs_faces
setMesh mesh vertices:vert_array faces:face_array --set the base mesh
--extrude all legs
meshop.extrudeFaces mesh #{(table_count+1)..(table_count+2)} height 0
meshop.extrudeFaces mesh #{(table_count+3)..(table_count+4)} height 0
meshop.extrudeFaces mesh #{(table_count+5)..(table_count+6)} height 0
meshop.extrudeFaces mesh #{(table_count+7)..(table_count+8)} height 0
--extrude the table top
meshop.extrudeFaces mesh #{1..half_count} thickness 0.0 --dir:#common
)--end buildMesh
tool create
(
on mousePoint click do
(
case click of
(
1: coordsys grid (nodeTM.translation = gridPoint)
)
)
on mouseMove click do
(
case click of
(
2: (radius1 = radius2 = length gridDist)
3: (width = length gridDist)
4: (height = length gridDist)
5: (#stop)
)--end case
)--end mouseClick
)--end create
)--end plugin
This implements a table design with two half-circles and a rectangular piece inserted between them (my parents have one of those back at home in Bulgaria). It is four-legged and the radii can be adjusted together or independently for funnier designs.
The code is based on an example I wrote a while ago for someone on CGTalk (it was called ExtCircle or something like that). I added some more controls, the thickness of the table top and the legs. Since it is based on my own code, it is SORT OF from scratch, but feel free to disqualify me
As always, I used only the MAXScript Reference.
The geometry is far from perfect, and I am not setting edge visibility (the original ExtCircle script did). There are lots of internal faces that should be removed. Max has problems retaining edge visibility in scripted plugins when using extrudeFaces, I would have to implement all extrusions myself to avoid internal faces. Since I did it for fun in an hour, I would rather not spend more time on this at this point…
Hey, I had some time over today so I decided to give it a go. Here is my version:
Tried to put code here but the formatting was too horrible and when I tried to copy/paste the code it failed so...anybody got any tips on how to post the code so it looks like in the script?
I have uploaded the script, you can get it here: http://hem.bredband.net/millman/Tablecreator.ms
CML
edit: there was a case where the tool stopped when click+dragging that has been fixed now:)
Inaudable- pretty good for you first script, a bit simple but working still:)
Bobo- That’s cool, for an hour that is very good work. The script works ok but like you said there are some problems with internal faces.
cheers,
CML
Nice work all! I’m glad to see people delving in early!
I’ll try and put my own effort up sometime this week.
I’m making a plugin simpleObject (this is my first 😮 ), but I want to create geometry using extruded and bevelled splines and then attach them to the plugin mesh. Is there a way you can do this? Mine just creates the geometry from the extruded shape and doesn’t create my plugin object.
Here is my code so far.
plugin simpleObject WahooneyTable
name:"Wahooney Table"
category:"CG Talk"
classID:#(0x6ab21a87, 0x4530a1ab)
(
parameters main rollout:roParams
(
topLength type:#worldUnits ui:spnTopLength default:200
topWidth type:#worldUnits ui:spnTopWidth default:100
legLength type:#worldUnits ui:spnLegLength default:100
legWidth type:#worldUnits ui:spnLegWidth default:8
legSegments type:#Integer ui:spnLegSegs default:8
)
rollout roParams "Parameters" width:162 height:150
(
spinner spnTopLength "" pos:[67,18] width:70 height:16
spinner spnTopWidth "" pos:[67,37] width:70 height:16
spinner spnLegLength "" pos:[67,79] width:70 height:16
spinner spnLegWidth "" pos:[67,100] width:70 height:16
spinner spnLegSegs "" pos:[67,121] width:70 height:16
label lblTopLength "Length:" pos:[30,18] width:36 height:16
label lblTopWidth "Width:" pos:[36,37] width:30 height:16
label lblLegLength "Length:" pos:[31,79] width:35 height:16
label lblLegWidth "Width:" pos:[36,100] width:30 height:16
label lblLegSegs "Segments:" pos:[17,121] width:49 height:16
GroupBox grpTop "Table Top" pos:[5,4] width:154 height:53
GroupBox grpLegs "Table Legs" pos:[5,61] width:154 height:85
)
on BuildMesh do
(
c = ellipse length:topLength width:topWidth
addModifier c (Shell())
meshop.attach mesh c.mesh
)
tool create
(
on mousePoint click do
(
case click of
(
1: nodeTM.translation = gridPoint
2: #stop
)
)
)
)
Thanks.
Hello,
Great, the first Maxscript challenge!
I’ve used a scripted plugin to make a modern box table design. There are controls for adjusting the table width, length, height, the thickness of the table, the thickness of the legs and an offset set for setting the legs back from the table edge.
The table top and the legs have a different face ID, and I’ve implemented very basic mapping (things started to get a little complicated and I couldn’t afford to spend any more time!).
I’ve also added code to ensure that the mesh is always valid.
All up it’s probably taken me about 2 to 2 and a half hours, since I had trouble getting my head the vertex positions (always helps to draw a picture!).
I was thinking about doing a more complicated table like the techno nomos table but since it’s not really adjustable in any way, it doesn’t fir the brief and I thought I’d be better of keeping it simple.
(I’ll upload that later it you all want!)
anyway, ENJOY!
Josh.
--------------------------------------------------------------------------------
-- Table scripted Plugin
-- version 1.0
-- max version 6, 7
-- written by Joshua Newman
-- [www.joshuanewman.net]( http://www.joshuanewman.net/)
-- written 14/06/05
-- last updated 1426/06/05
-- copyright 2005
--------------------------------------------------------------------------------
--
-- Maxscript competition 1!
--
-- I've chosen a basic modern table design, mostly because all of my vertices and faces are mapped by hand, or looped where possible.
--
-- the mapping could be implemented better.
--
-- ENJOY!
--
--------------------------------------------------------------------------------
plugin simpleObject cgtalktable name:"Table_Josh" ClassID:#(0x23f8c87b, 0x12b8e715) category:"CGTalk"
(
parameters main rollout:params
(
w type:#worldUnits ui:w default:0
l type:#worldUnits ui:l default:0
h type:#worldUnits ui:h default:0
top type:#worldUnits ui:top default:0
leg type:#worldUnits ui:leg default:0
edg type:#worldUnits ui:edg default:0
map type:#boolean ui:map default:false animatable:false
on h set val do if val<top then h=top -- check height!
on top set val do if val>h then top=h -- check table top thickness!
on w set val do if val<(x=(edg*2+leg*2))then w=x -- check width!
on l set val do if val<(x=(edg*2+leg*2))then l=x -- check length!
on leg set val do -- check leg thickness
(
if w<l then min=w else min=l -- find the shortest edge
if val>(local x=((min/2)-edg)) then leg=x -- correct the leg, taking into account the edge, and the middle
)
on edg set val do -- check edge length
(
if w<l then min=w else min=l -- find the shortest edge
if val>(local x=((min/2)-leg)) then edg=x
)
)
rollout params "Parameters"
(
group "Table top"
(
spinner w "Width" type:#worldunits range:[0,1000,0]
spinner l "Length" type:#worldunits range:[0,1000,0]
spinner h "Height" type:#worldunits range:[0,1000,0]
spinner top "Top Thickness" type:#worldunits range:[0,1000,1]
)
group "Table Legs"
(
spinner leg "Leg thickness" type:#worldunits range:[0,1000,1]
spinner edg "Offset edge" type:#worldunits range:[0,1000,1]
)
checkbox map "Generate Mapping"
label l1 "\xa9 2005 Joshua Newman" offset:[-8,0]
hyperlink hl "[www.joshuanewman.net]( http://www.joshuanewman.net/ )" address:"[www.joshuanewman.net]( http://www.joshuanewman.net/ )" offset:[4,0]
)
on hasUVW do map -- turn of mapping if required!
on setgenuvw m do map=m -- set the map checkbox to true if mapping is required
on buildMesh do
(
-- build the vertex array
va =#([0,0,h],[0,l,h],[w,0,h],[w,l,h],[0,0,h-top],[0,l,h-top],[w,0,h-top],[w,l,h-top]) -- tabletop
va+=#([edg,edg,0],[edg+leg,edg,0],[edg,edg+leg,0],[edg+leg,edg+leg,0],[edg,edg,h-top],[edg+leg,edg,h-top],[edg,edg+leg,h-top],[edg+leg,edg+leg,h-top]) -- leg 1
va+=#([w-edg,edg,0],[w-edg,edg+leg,0],[w-edg-leg,edg,0],[w-edg-leg,edg+leg,0],[w-edg,edg,h-top],[w-edg,edg+leg,h-top],[w-edg-leg,edg,h-top],[w-edg-leg,edg+leg,h-top]) -- leg 2
va+=#([edg,l-edg,0],[edg,l-edg-leg,0],[edg+leg,l-edg,0],[edg+leg,l-edg-leg,0],[edg,l-edg,h-top],[edg,l-edg-leg,h-top],[edg+leg,l-edg,h-top],[edg+leg,l-edg-leg,h-top]) -- leg 3
va+=#([w-edg,l-edg,0],[w-edg-leg,l-edg,0],[w-edg,l-edg-leg,0],[w-edg-leg,l-edg-leg,0],[w-edg,l-edg,h-top],[w-edg-leg,l-edg,h-top],[w-edg,l-edg-leg,h-top],[w-edg-leg,l-edg-leg,h-top]) -- leg 4
-- build the face array
fa=#() -- face array
for i=0 to 4 do fa+=#([1+(i*8),3+(i*8),4+(i*8)],[4+(i*8),2+(i*8),1+(i*8)],[5+(i*8),6+(i*8),8+(i*8)],[8+(i*8),7+(i*8),5+(i*8)],[1+(i*8),2+(i*8),6+(i*8)],[6+(i*8),5+(i*8),1+(i*8)],[2+(i*8),4+(i*8),8+(i*8)],[8+(i*8),6+(i*8),2+(i*8)],[4+(i*8),3+(i*8),7+(i*8)],[7+(i*8),8+(i*8),4+(i*8)],[3+(i*8),1+(i*8),5+(i*8)],[5+(i*8),7+(i*8),3+(i*8)]) -- build face array
-- build the face ID array
id=#() -- face number ID's
for i=1 to 12 do append id 1 -- table top face ID's
for i=1 to 48 do append id 2 -- legs face ID's
-- build the mesh!
setMesh mesh verts:va faces:fa materialids:id -- create the mesh!
for f=1 to mesh.numfaces do setfacesmoothgroup mesh f 0 -- clear all face smoothing groups
-- build the texure mapping, ok I'm being slack, this just creates TVvertices for each vertex, and TVfaces for each face. it's probably a bit suspect to use in a scripted plugin like this
if map then meshop.defaultmapfaces mesh 1
)
-- Create tool
tool create
(
on mousePoint click do
case click of
(
1: nodeTM.translation = gridpoint
3: #stop
)
on mouseMove click do
case click of
(
2: ((if gridDist.x<0 then w=gridDist.x*-1 else w=gridDist.x);(if gridDist.y<0 then l=gridDist.y*-1 else l=gridDist.y)) -- set width and length
3: (if gridDist.z>0 then (h=gridDist.z;top=h*.1;leg=top;edg=h*.02) else (h=gridDist.z*-1;top=h*.1;leg=top;edg=h*.02)) -- set overall heigh, table top, and edge.
)
)
-- end create
-- end script
)
Heya j_man,
Just a quick note – I’m doing a script that is making object based on mousetool also and rather than doing an if test on griddist.x to see if it’s less than 0 and multiplying by -1 you can use abs(griddist.x) which will always come back with the positive value of griddist – makes things a little simpler!
Must try and get around to an entry soon – really nice to see how other people code and pick up some new tricks.
P.s. bobo – how’s the matrix dvd coming on? Can’t wait for that one