PDA

View Full Version : AutoArch - Because I'm too lazy to model buildings


MarcoBrunetta
04-14-2009, 06:08 PM
Here's something I wrote on a downtime yesterday, maybe someone else will be interested in playing with it or improving it.

The idea was that since I'm inherently lazy and most of the work I do is architectural rendering, I wanted to create a script that, given a set of splines (ground plan, elevations, etc) would create the whole building mesh automagically.

While the premise is certainly interesting it is also pretty far-fetched. However here's a (VERY) primordial attempt at doing that:

(
/*************
FUNCTIONS
*************/

fn findBiggerNumber numArray =
--Finds the bigger number in an array
(
local result = numArray[1]
FOR num in numArray DO
(
IF num > result DO result = num
)
result
)

fn findSmallerNumber numArray =
--Finds the smaller number in an array
(
local result = numArray[1]
FOR num in numArray DO
(
IF num < result DO result = num
)
result
)

fn findDifferentValues numArray =
--Returns an array with only unique values
(
local valueArray = #()
FOR num in numArray DO
(
IF (findItem valueArray num == 0) DO append valueArray num
)
valueArray
)

fn selectHorizontalEdges theMesh =
--Selects only the horizontal edges in a mesh
(
local edgeArray = #()
FOR edgeIndex = 1 to (polyop.getNumEdges theMesh) DO
(
local edgeVertices = polyop.getEdgeVerts theMesh edgeIndex
local vert1 = theMesh.GetVertex edgeVertices[1]
local vert2 = theMesh.GetVertex edgeVertices[2]
IF vert1[1] == vert2[1] AND vert1[2] != vert2[2] AND vert1[3] == vert2[3] DO append edgeArray edgeIndex
IF vert1[1] != vert2[1] AND vert1[2] == vert2[2] AND vert1[3] == vert2[3] DO append edgeArray edgeIndex
)
polyop.setEdgeSelection theMesh edgeArray
)

fn selectVerticalEdges theMesh =
--Selects only the vertical edges in a mesh
(
local edgeArray = #()
FOR edgeIndex = 1 to (polyop.getNumEdges theMesh) DO
(
local edgeVertices = polyop.getEdgeVerts theMesh edgeIndex
local vert1 = theMesh.GetVertex edgeVertices[1]
local vert2 = theMesh.GetVertex edgeVertices[2]
IF vert1[1] == vert2[1] AND vert1[2] == vert2[2] AND vert1[3] != vert2[3] DO append edgeArray edgeIndex
)
polyop.setEdgeSelection theMesh edgeArray
)

fn sliceMesh theMesh windowSpline =
--Slices the mesh according to a spline
--NOTE: the fist approach used this function instead of pure boolean substraction.
--While harder to implement this function (if compleated) could yeld a "cleaner" mesh
(
local ZArray = #()
local XYArray = #()
theNumSplines = numSplines windowSpline
FOR theSpline = 1 to theNumSplines DO
(
local numVerts = numKnots windowSpline theSpline
FOR vertIndex = 1 to numVerts DO
(
local newVert = getKnotPoint windowSpline theSpline vertIndex
append ZArray newVert[3]
local thePoint = [newvert[1],newvert[2]]
append XYArray thePoint
)
)
theHeights = findDifferentValues ZArray
theVerticals = findDifferentValues XYArray

FOR height in theHeights DO
(
theMesh.slice [0,0,1] [0,0,height]
)

FOR vertical in theVerticals DO
(
theMesh.slice [0,1,0] [0,vertical[2],0]
)
)

fn findHeight splineArray =
--Finds the heigher point in an array of splines
(
local heightArray = #()
FOR spline in splineArray DO
(
local vertArray = #()
local numVerts = numKnots spline
FOR vertIndex = 1 to numVerts DO
(
local newVert = getKnotPoint spline 1 vertIndex
append vertArray newVert[3]
)
local maxHeight = findBiggerNumber vertArray
local minHeight = findSmallerNumber vertArray
local splineHeight = (maxHeight-minHeight)
append heightArray splineHeight
)
theHeight = (findBiggerNumber heightArray)
)

/**********
ROLLOUTS
**********/

rollout AutoArchMain "AutoArch"
--The main rollout
(
subRollout subRoll height:320 width:350 pos:[5,5]
button buildButton "BUILD!"

ON buildButton PRESSED DO
(
newMesh = copy subRoll.rollouts[1].basePlan
local theHeight = findHeight subRoll.rollouts[1].elevArray
local extrudeMod = extrude amount:theHeight
addModifier newMesh extrudeMod
convertTo newMesh editable_poly
local holeExtrude = extrude amount:subRoll.rollouts[2].wallWidth.value
FOR spline in subRoll.rollouts[1].holeArray DO
(
meshToSubstract = copy spline
ResetPivot meshToSubstract
addModifier meshToSubstract holeExtrude
convertTo meshToSubstract editable_poly
newMesh = newMesh - meshToSubstract
delete meshToSubstract
)
select newMesh
destroyDialog AutoArchMain
)
)

rollout AutoArchInput "Spline Input"
--The user chooses the splines that serve as input here
(

local elevArray = #() --An array to hold the different elevations
local holeArray = #() --An array to hold the splines to substract (windows and doors)
local basePlan --A variable to hold the ground plan
group "Ground Plan"
(
pickbutton planPick "Choose Base Plan" autoDisplay:true
)
group "Elevations"
(
--NOTE: there's no real reason why only 4 splines can be choosen for either the holes or the elevations
--It's just that I haven't really worked on a nicer GUI
pickbutton elev1Pick "Choose Elevation" autoDisplay:true across:2
pickButton hole1Pick "Choose Windows" autoDisplay:true
pickbutton elev2Pick "Choose Elevation" autoDisplay:true across:2
pickButton hole2Pick "Choose Windows" autoDisplay:true
pickbutton elev3Pick "Choose Elevation" autoDisplay:true across:2
pickButton hole3Pick "Choose Windows" autoDisplay:true
pickbutton elev4Pick "Choose Elevation" autoDisplay:true across:2
pickButton hole4Pick "Choose Windows" autoDisplay:true
)

ON planPick PICKED arg DO
(
IF classOf arg == SplineShape DO basePlan = arg
)

ON elev1Pick PICKED arg DO
(
IF classOf arg == SplineShape DO append elevArray arg
)

ON hole1Pick PICKED arg DO
(
IF classOf arg == SplineShape DO append holeArray arg
)

ON elev2Pick PICKED arg DO
(
IF classOf arg == SplineShape DO append elevArray arg
)

ON hole2Pick PICKED arg DO
(
IF classOf arg == SplineShape DO append holeArray arg
)

ON elev3Pick PICKED arg DO
(
IF classOf arg == SplineShape DO append elevArray arg
)

ON hole3Pick PICKED arg DO
(
IF classOf arg == SplineShape DO append holeArray arg
)

ON elev4Pick PICKED arg DO
(
IF classOf arg == SplineShape DO append elevArray arg
)

ON hole4Pick PICKED arg DO
(
IF classOf arg == SplineShape DO append holeArray arg
)
)

rollout AutoArchOptions "Options"
--Other options
(
spinner wallWidth "Wall Width:" align:#left range:[0.1,100,14] type:#worldunits
)

rollout AutoArchAbout "About"
--That's me!
(
label label00 "- VERSION 0.001 -"
label label01 "Created by Marco Brunetta"
hyperlink link01 "mbrunetta@gmail.com" align:#center address:"mailto:mbrunetta@gmail.com"
)

/*********
LOADING
*********/

createDialog AutoArchMain 360 400
addSubRollout AutoArchMain.subRoll AutoArchInput
addSubRollout AutoArchMain.subRoll AutoArchOptions
addSubRollout AutoArchMain.subRoll AutoArchAbout rolledup:true
)

The script creates a rollout where the user can choose the ground spline and as many as 4 elevations and window/door splines (the number 4 is arbitrary, the script can work with as many as needed, just haven't feel like doing a proper GUI yet).
Once the BUILD button is pressed the script extrudes the ground plane taking the height from the elevations and thus creating walls, extrudes the windows, and finally substracts the windows from the walls.

Let me asure you that this script is PURELY experimental and in no way rady to be used in a pipeline. For example the window splines have to manually be set up and rotated so that once they are extruded they will interject the walls...

But it is somwhat promissing. Fell free to play around with the script, modify it or use to impress your friends.

Oh, and here are some before and after shots:
http://i42.tinypic.com/xqi9w8.jpg
http://i40.tinypic.com/sl5gg8.jpg

CGTalk Moderation
04-14-2009, 06:08 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.