Furniture Design with Mathematica

1994 Developer Conference in Champaign, Ill.

Roland Jakschewitz

Various pieces of furniture can be specified textually by end-users by applying a furniture description language defined in Mathematica. The description language models a 'furniture-specialized 3D turtle'. (Specialization/variation of Roman MÊder's article Fractal Curves in TMJ spring 1991)
The results are ground plans, 3D graphics of the furniture objects and of their usable space within, and parts and price lists.
The software uses interchangeable databases of furniture component systems.

Initialization

Environment, ...

(* Tabwidth = 8 spaces *)

workingDirectory = "gamma:Attendee Presentations:Furniture Design";

SetDirectory@workingDirectory

Path need not be changed under Windows, but definitely under Mac OS. Hmm?!

$Path = Join[$Path, {workingDirectory}]

Off[ General::spell1 ];

User specified

Database of furniture component system used (choose your system)

Get[ "Moebel`Databases`Trend9000`" ]

Basic measurements  (fitting to standard parts in database)

stdDepth	 =  42.8;
hoehe		 = 246.2;	(* maximum height *)

breite		 =  59.3;
largeWidth	 =  80.;
smallWidth	 =  49.3;

eckWandTiefe	 =  50.;	(* clear width of corner shelves *)
depthOfCornerWall=  23.6;

highDoor	 =  70.2;
smallDoor	 =  47.8;
tuerGriff	 =   3.4;	(* diameter of door handle *)

drawerHeight	 =  12.6;

Automatic Initialization (per Session)

Tables depending on user specified data (drill holes, clear height)

unterKanten  = bohrLoecher[ hoehe ];
lichteHoehen = unterKanten - unterKanten[[1]] - dicke // Rest;

Definition of Description Language

Needs@"Moebel`MoebelSprech`";

English Notation

Words of Furniture Description Language

Furniture	= Moebel; (* a piece of furniture *)

fWidth		= regalBreite;
fCornerWidth	= eckBreite;
fHeight		= regalHoehe;
fDepth		= regalTiefe;
fDirection	= regalRichtung;

fSideWall	= regalWand;
fSegment	= regal;
fCornerSegment	= eckRegal;
fShelves	= faecher;
fCornerShelves	= eckFaecher;
fDrawer		= regalSchub;
fDoor		= regalTuer;
fCornerDoor	= eckRegalTuer;
fDoubleDoor	= doppelTuer;

Functions

spaceIn		= platzIm;
order		= bestellung;
completeView	= gesamtAnsicht;

Measurements

widthOfCorner		= eckWandTiefe;
myHeight		= hoehe;
doorhandle		= tuerGriff;
heightOfBase		= sockelHoehe;
thicknessOfShelves	= dicke;

Furniture Description Language — some Examples

A Very Simple Cabinet

Description

'furniture-specialzed 3D turtle': describe clockwise from bottom to top

simpleCabinet =
Furniture[
	fHeight[ 160 ],
	fDepth[ 80 ],
	
	fSideWall[],
	fSegment[
		fWidth[ 60 ],
		fDoor[ 40 ],
		fShelves[ {20, 40, 20} ],
		fDrawer[ 40 ]
	],
	fSideWall[],
	fHeight[200],
	fDepth[ 40 ],
	fSegment[
		fWidth[80 ],
		fDoor[20],
		fShelves[{20, 40, 60} ],
		fDoor[40]
	],
	fSideWall[]
];

Ground plan

Show[ Graphics[ simpleCabinet,
		Axes -> True, GridLines -> Automatic,
		AspectRatio -> Automatic, Frame -> True
]];

3D graphics

Show@GraphicsArray@{
     Graphics3D[ simpleCabinet,
		 ViewPoint->{1.300,-2.400,0.840},
		 Boxed->False
     ],
     Graphics3D[ simpleCabinet,
		 ViewPoint->{-4.000,3.470,0.840},
		 Boxed->False
     ]
};

Space in cabinet

Show[ Graphics3D[ spaceIn @ simpleCabinet,
		  ViewPoint -> {0., -1., 0.},
		  Axes -> { True, False, False }
]];

Price & parts list

order[ simpleCabinet ];

Compute a Cabinet

Description

toSequence[ struct_, levels_:{0} ] :=
	Apply[ Sequence, struct, levels ];

height[n_] := heightOfBase + (10+n+n/2)thicknessOfShelves +
	      2*38 + highDoor + n drawerHeight + 12(1+n/2);

variablePart[n_] :=
	fSegment[
	  fWidth[ n 40 ],
		
	  fDoubleDoor[ highDoor, { 38 }	],
	  toSequence @ Table[ fDrawer @ drawerHeight, {n} ],
		       
	  fShelves @ { 38,
		       toSequence @ Table[ 12, { 1 + n/2 } ],
		       38 }
	];

compuCabinet =
Furniture[
	fDepth[ stdDepth ],
	
	toSequence[ 
	       { fHeight[ height@# ],
		 fSideWall[],
		 variablePart[#]
	       }& /@ Range@3,
	       {0,1}
	],
	fSideWall[]
];

3D graphics

Show@GraphicsArray@{
     Graphics3D[ compuCabinet,
		 ViewPoint->{1.300,-2.400,0.840},
		 Boxed->False
     ],
     Graphics3D[ compuCabinet,
		 ViewPoint->{-4.000,3.470,0.840},
		 Boxed->False
     ]
};

Space in cabinet

Show[ Graphics3D[ spaceIn[ compuCabinet ],
		  ViewPoint -> {0., -1., 0.},
		  Axes -> { True, False, False }
]];

Price & parts list

order[ compuCabinet ];

A More Elaborate Piece of Furniture

Description

cornerCabinet = Furniture[

(* size of structure *) fHeight[ myHeight ],
(* ----------------- *) fDepth[ stdDepth ],
				 

(* narrow end *)  fDirection[ west ],
(* ---------- *) 
		  fSideWall[],
		  fSegment[ fWidth[ smallWidth ],
		
			  fDoor[ smallDoor ],
			  fDrawer[ drawerHeight ],
			  fShelves[ { 42, 14, 14, 38 } ],
			  fDoor[ smallDoor ]
		  ],
		  fSideWall[],

(* corner *)	  fCornerSegment[ fCornerWidth[ widthOfCorner ],
(* ------ *)
			   fCornerDoor[ smallDoor ],
			   fCornerShelves[ { 60, 55, 25, 35} ]
		  ],

(* wide end *)    fSideWall[],
(* -------- *)    fSegment[ fWidth[ smallWidth ],
		
			  fDoor[ smallDoor ],
			  fDrawer[ drawerHeight ],
			  fShelves[ { 42, 34, 38 } ],
			  fDoor[ smallDoor ]
		  ],
		  fSideWall[],
		  fSegment[ fWidth[ largeWidth ],
		
			  fDoubleDoor[ highDoor, { 38 } ],
			  fShelves[ { 38, 38, 38, 38 } ]
		  ],
		  fSideWall[],
		  fSegment[ fWidth[ smallWidth ],
		
			  fDoor[ smallDoor ],
			  fDrawer[ drawerHeight ],
			  fShelves[ { 42, 34, 38 } ],
			  fDoor[ smallDoor ]
		  ],
		  fSideWall[]
	];

3D graphics

Show[ Graphics3D[ cornerCabinet,
		  ViewPoint->{1.420, -1.610, 0.200},
		  Axes -> True, FaceGrids -> All
]];

Viewing from several viewpoints:

completeView[ cornerCabinet ];

Space in cabinet

Show[ Graphics3D[ spaceIn @ cornerCabinet,
		  ViewPoint -> {0., -1., 0.},
		  Axes -> { True, False, False }
]];

Price & parts list

order @ cornerCabinet;

Real World Considerations

Rendering of final model

Using function WriteDXF defined in the Mathematica standard package Utilities`DXF`, Graphics3D output can be converted to DXF format that is understood by most rendering applications. Photorealistic rendering can then be applied to produce the final output.

The following picture has been produced from the most recent example above (by Walter P. RohkrÊmer using StrataVision“).

[Note:  The rendered image of the cabinets has been deleted from this notebook and saved in a separate notebook called RenderedPicture.ma.  The MathSource number is 0206-660-0044]

Interchangeable databases of furniture component systems

After preparing parts and price information of  various furniture component systems for Mathematica, the description language can be used for modeling many more classes of pieces of furniture.

Not restricted to normal furniture, could also be used for industrial wall-to-wall shelving in automated warehouses, ²

Perspectives

Generation of manufacturing instructions (CAM)

In analogy to producing output for rendering software, Graphics3D output could be converted to specifications for manufacturing automata.

Generation of assembly instructions

Production of construction manuals could be (semi-)automated — this is one area where "impossible viewpoints" can be quite helpful.

Advantages of using a description language rather than an interactive modeling tool

Automatic placement of base boards and door handles, adjustment of clear height to distance/position of drill holes

Computation and visualization of usable space

Computation of parts & price list as well as  graphics from same furniture description

Easy textual editing of models

Description Language — Structure of Interpreter

Different interpretations of a the same furniture description produce ground plan, 3D visualization, parts & price lists, and visualization of spaces available in the resulting piece of furniture.

One precompiler, four finite state machine interpreters (made up of rewrite rules) convert descriptions in several symbolic steps to either Graphics, Graphics3D, or textual Mathematica output.