#!BPY
# """
# Name: 'Auto Masonry'
# Blender: 244
# Group: 'Wizards'
# Tooltip: 'Builds a masonry wall, path, etc.'
# """
__author__ = 'Paul Spooner, aka "Dudecon" or "Ziggy"'
__version__ = '0.1 2007/09/14'
__url__ = ["Author's site, http://www.peripheralarbor.com"]
__email__ = ["Author's personal e-mail, dudecon:hotmail*com"]
__bpydoc__ = """\
This script builds a wall.
Actually, it could be a path, or a tower, or anything made with what looks like bricks or stones.
Arches are not supported yet, but hopefully they will be with the next version.
If a curve is the active object the wall will follow the curve (as long as a closed curve is a circle,
let me know if you can find a work-around for this). In this way, castles or large citys can be quickly
made by creating curve circles for the towers and curve segments for the walls. Crenelations also work
which can double as arrow slits or support beam holes. Let me know about suggested improvements,
I'll try to work them in!
"""
import Blender, time, math, bpy
from Blender.Mathutils import Vector
from math import fmod
SMALL = 0.000000000001
PI = math.pi
MaxW = Blender.Draw.Create(3.2) # maximum brick width, larger than MinW
MinW = Blender.Draw.Create(1.7) # minumum brick width (not the absolute minimum), larger than 2*GroutWidth + 2*Bevel
MaxH = Blender.Draw.Create(1.0) # maximum brick height, larger than MinH
MinH = Blender.Draw.Create(1.5) # minumum brick height (not the absolute minimum), larger than 2*GroutWidth + 2*Bevel
MaxD = Blender.Draw.Create(1.5) # maximum brick depth larger than MinD
MinD = Blender.Draw.Create(1.3) # minimum brick depth (not the absolute minimum), larger than 2*GroutWidth + 2*Bevel
Taper = Blender.Draw.Create(0.0) # fraction of taper at top, can be less than zero or greater than one
Width = Blender.Draw.Create(40.0) # total width of the wall, larger than 2*GroutWidth + 2*Bevel
GroutWidth = Blender.Draw.Create(0.080) # half the width of the grout between the bricks
GroutDepth = Blender.Draw.Create(.100) # depth back from the min face position
Height = Blender.Draw.Create(20.0) # Total height of the wall (minus the crenels), larger than 2*GroutWidth + 2*Bevel
Bevel = Blender.Draw.Create(0.100) # the amount to bevel the edge of the bricks
HWeight = Blender.Draw.Create(0.5) # how much the height of the row affects the width of the bricks in that row, recommended between -4 and 4, 0.5 is a good value
#FlawFraction = 0 # between 0 and 1, the fraction of verticies recieving the first bevel operation
#FlawSize = 0 # the size of the first bevel operation less than half of (MinH or MinW) - Bevel
OpeningType = Blender.Draw.Create(1) # 0 is straight, 1 is angled windows, 2 is angled doors, 3 is both
EdgeType = Blender.Draw.Create(1) # 1 is straight edges, ? is offset left edges, ? is offset right edges(doesn't work), 2 is both
DoorWidth = Blender.Draw.Create(4.)
WindowWidth = Blender.Draw.Create(.2)
CrenelWidth = Blender.Draw.Create(5.5)
DoorHeight = Blender.Draw.Create(7.0)
WindowHeight = Blender.Draw.Create(4.)
CrenelHeight = Blender.Draw.Create(5.5*0.618)
DoorSpacing = Blender.Draw.Create(20.0)
WindowSpacing = Blender.Draw.Create(10.0)
CrenelSpacing = Blender.Draw.Create(6.5)
DoorActive = Blender.Draw.Create(1)
WindowActive = Blender.Draw.Create(1)
CrenelActive = Blender.Draw.Create(0)
DoorAngle = Blender.Draw.Create(0)
WindowAngle = Blender.Draw.Create(1)
#easier way to get to the random function
def rnd(): return Blender.Mathutils.Rand()
def LinearFill(left, right, avedst, mindst, dev=0.0, pad=(0.0,0.0), num=0, center=0):
__doc__ = '''\
LinearFill fills a linear range with points and returns an ordered list of those points
including the end points.
left: the lower boundary
right: the upper boundary
avedst: the average distance between points
mindst: the minimum distance between points
dev: the maximum random deviation from avedst
pad: tends to move the points near the bounds right (positive) or left (negative).
element 0 pads the lower bounds, element 1 pads the upper bounds
num: substitutes a numerical limit for the right limit. LinearFill will then make
a num+1 element list
center: flag to center the elements in the range, 0 == disabled
'''
poslist = [left]
curpos = left+pad[0]
if center:
curpos += ((right-left-mindst*2)%avedst)/2+mindst
if curpos-poslist[-1] 1 : right=Edgedata[posz][1]
else: right = 0
WL = LinearFill(OffsetMaxL+left,Width-OffsetMaxR+right,hwt*(MaxW+MinW)/2,GroutWidth*2+Bevel*2,hwt*(MaxW-MinW)/2,(pad,pad))
WL[0] = left
WL[-1] = Width+right
WLlist += [WL[:]]
for posz in range(len(HL)-1): # loop for rows
bounds[2]=HL[posz] #set the top and bottom bounds
bounds[3]=HL[posz+1]
WL = WLlist[posz]
for posx in range(len(WL)-1): # loop for blocks
bounds[0] = WL[posx] # set the right and left bounds
bounds[1] = WL[posx+1]
if bounds[0] == 0: offsetapply[:4] = Offset[:4]
if bounds[1] == Width: offsetapply[-4:] = Offset[-4:]
if (Width0:
if lowsegs[x][3]==2:
if (OpeningType==2 or OpeningType==3): offsetapply[:4] = Offsets[:4]
else: offsetapply[:4] = OffsetsNone[:4]
if lowsegs[x+1][3]==2:
if (OpeningType==2 or OpeningType==3): offsetapply[-4:] = Offsets[-4:]
else: offsetapply[-4:] = OffsetsNone[-4:]
if x == 0 and fmod(EdgeType,2): edgeapply=1
if x == len(lowsegs)-2 and (EdgeType> 1): edgeapply += 2
speclist.append((lowsegs[x][1], 0, lowsegs[x+1][0]-lowsegs[x][1], DoorHeight-WindowHeight, 0, 0, offsetapply, edgeapply, 0))
offsetapply=[[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]
edgeapply = 0
#spaces between the doors and windows, middle height
for x in range(len(midsegs)-1):
if midsegs[x+1][0]-midsegs[x][1]>0:
if (midsegs[x][3]==1 and (OpeningType==1 or OpeningType==3)) or (midsegs[x][3]==2 and (OpeningType==2 or OpeningType==3)): offsetapply[:4] = Offsets[:4]
elif midsegs[x][2]==1: offsetapply[:4] = OffsetsNone[:4]
if (midsegs[x+1][3]==1 and (OpeningType==1 or OpeningType==3)) or (midsegs[x+1][3]==2 and (OpeningType==2 or OpeningType==3)): offsetapply[-4:] = Offsets[-4:]
elif midsegs[x+1][2]==1:offsetapply[-4:] = OffsetsNone[-4:]
if x == 0 and fmod(EdgeType,2): edgeapply=1
if x == len(midsegs)-2 and (EdgeType> 1): edgeapply += 2
speclist.append((midsegs[x][1], DoorHeight-WindowHeight, midsegs[x+1][0]-midsegs[x][1], WindowHeight, 0, 0, offsetapply[:], edgeapply, 0))
offsetapply=[[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0],[0,0,0]]
edgeapply = 0
if not DoorHeight: ave = 0
# Rows between lintels
for x in range(len(midsegs)-1):
if midsegs[x+1][0]-midsegs[x][1]-midsegs[x][2]*ave-midsegs[x+1][2]*ave>0:
if x == 0 and fmod(EdgeType,2): edgeapply=1
if x == len(midsegs)-2 and (EdgeType> 1): edgeapply += 2
speclist.append((midsegs[x][1]+midsegs[x][2]*ave, DoorHeight, midsegs[x+1][0]-midsegs[x][1]-midsegs[x][2]*ave-midsegs[x+1][2]*ave, ave, 0, 0, offsetapply[:], edgeapply, 0))
edgeapply = 0
#Door and Window lintels
for x in range(1,len(midsegs)-1):
llen = ave
rlen = ave
if midsegs[x][0]-midsegs[x-1][1]