Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'add_mesh_extra_objects/Blocks.py')
-rw-r--r--add_mesh_extra_objects/Blocks.py279
1 files changed, 191 insertions, 88 deletions
diff --git a/add_mesh_extra_objects/Blocks.py b/add_mesh_extra_objects/Blocks.py
index f798cf52..bade30d0 100644
--- a/add_mesh_extra_objects/Blocks.py
+++ b/add_mesh_extra_objects/Blocks.py
@@ -1,4 +1,4 @@
-# GPL # "author":
+# GPL # "authors": dudecon, jambay
# Module notes:
#
@@ -8,87 +8,150 @@
# auto-clip wall edge to SMALL for radial and domes.
# unregister doesn't release all references.
# repeat for opening doesn't distribute evenly when radialized - see wrap around
-# note above.
+# note above.
# if opening width == indent*2 the edge blocks fail (row of blocks cross opening).
# if openings overlap fills inverse with blocks - see h/v slots.
# Negative grout width creates a pair of phantom blocks, seperated by grout
-# width, inside the edges.
-# if block width variance is 0, and edging is on, right edge blocks create a "vertical seam".
+# width, inside the edges.
+# if block width variance is 0, and edging is on, right edge blocks create a "vertical seam"
import bpy
from random import random
-from math import fmod, sqrt, sin, cos, atan, pi as PI
+from math import (
+ fmod, sqrt,
+ sin, cos, atan,
+ pi as PI,
+ )
+
+# Set to True to enable debug_prints
+DEBUG = False
# A few constants
SMALL = 0.000000000001
-NOTZERO = 0.01 # for values that must be != 0; see UI options/variables - sort of a bug to be fixed.
+# for values that must be != 0; see UI options/variables - sort of a bug to be fixed
+NOTZERO = 0.01
-# global variables
+# Global variables
# General masonry Settings
-settings = {'w': 1.2, 'wv': 0.3, 'h': .6, 'hv': 0.3, 'd': 0.3, 'dv': 0.1,
- 'g': 0.1, 'gv': 0.07, 'gd': 0.01, 'gdv': 0.0, 'b': 0, 'bv': 0,
- 'f': 0.0, 'fv': 0.0, 't': 0.0, 'sdv': 0.1, 'hwt': 0.5, 'aln': 0,
- 'wm': 0.8, 'hm': 0.3, 'dm': 0.1,
- 'woff': 0.0, 'woffv': 0.0, 'eoff': 0.3, 'eoffv': 0.0, 'rwhl': 1,
- 'hb': 0, 'ht': 0, 'ge': 0, 'physics': 0}
-# 'w':width 'wv':widthVariation
-# 'h':height 'hv':heightVariation
-# 'd':depth 'dv':depthVariation
-# 'g':grout 'gv':groutVariation 'gd':groutDepth 'gdv':groutDepthVariation
-# 'b':bevel 'bv':bevelVariation
-# 'f':flawSize 'fv':flawSizeVariation 'ff':flawFraction
-# 't':taper
-# 'sdv':subdivision(distance or angle)
-# 'hwt':row height effect on block widths in the row (0=no effect,
-# 1=1:1 relationship, negative values allowed, 0.5 works well)
-# 'aln':alignment(0=none, 1=rows w/features, 2=features w/rows)
-# (currently un-used)
-# 'wm':width minimum 'hm':height minimum 'dm':depth minimum
-# 'woff':row start offset(fraction of width)
-# 'woffv':width offset variation(fraction of width)
-# 'eoff':edge offset 'eoffv':edge offset variation
-# 'rwhl':row height lock(1 is all blocks in row have same height)
-# 'hb':bottom row height 'ht': top row height 'ge': grout the edges
-# 'physics': set up for physics
+# ------------------------
+settings = {
+ 'w': 1.2, 'wv': 0.3, 'h': .6, 'hv': 0.3, 'd': 0.3, 'dv': 0.1,
+ 'g': 0.1, 'gv': 0.07, 'gd': 0.01, 'gdv': 0.0, 'b': 0, 'bv': 0,
+ 'f': 0.0, 'fv': 0.0, 't': 0.0, 'sdv': 0.1, 'hwt': 0.5, 'aln': 0,
+ 'wm': 0.8, 'hm': 0.3, 'dm': 0.1,
+ 'woff': 0.0, 'woffv': 0.0, 'eoff': 0.3, 'eoffv': 0.0, 'rwhl': 1,
+ 'hb': 0, 'ht': 0, 'ge': 0, 'physics': 0
+ }
+"""
+ settings DOCUMENTATION:
+ 'w':width 'wv':widthVariation
+ 'h':height 'hv':heightVariation
+ 'd':depth 'dv':depthVariation
+ 'g':grout 'gv':groutVariation 'gd':groutDepth 'gdv':groutDepthVariation
+ 'b':bevel 'bv':bevelVariation
+ 'f':flawSize 'fv':flawSizeVariation 'ff':flawFraction
+ 't':taper
+ 'sdv':subdivision(distance or angle)
+ 'hwt':row height effect on block widths in the row (0=no effect,
+ 1=1:1 relationship, negative values allowed, 0.5 works well)
+ 'aln':alignment(0=none, 1=rows w/features, 2=features w/rows)
+ (currently unused)
+ 'wm':width minimum 'hm':height minimum 'dm':depth minimum
+ 'woff':row start offset(fraction of width)
+ 'woffv':width offset variation(fraction of width)
+ 'eoff':edge offset 'eoffv':edge offset variation
+ 'rwhl':row height lock(1 is all blocks in row have same height)
+ 'hb':bottom row height 'ht': top row height 'ge': grout the edges
+ 'physics': set up for physics
+"""
# dims = area of wall (face)
-dims = {'s': 0, 'e': PI * 3 / 2, 'b': 0.1, 't': 12.3} # radial
-# 's':start x or theta 'e':end x or theta 'b':bottom z or r 't':top z or r
-# 'w' = e-s and h = t-b; calculated to optimize for various operations/usages
-# dims = {'s':-12, 'e':15, 'w':27, 'b':-15., 't':15., 'h':30}
-# dims = {'s':-bayDim/2, 'e':bayDim/2, 'b':-5., 't':10.} # bay settings?
-
+# ------------------------
+dims = {
+ 's': 0, 'e': PI * 3 / 2, 'b': 0.1, 't': 12.3
+ } # radial
+"""
+ dims DOCUMENTATION:
+ 's':start x or theta 'e':end x or theta 'b':bottom z or r 't':top z or r
+ 'w' = e-s and h = t-b; calculated to optimize for various operations/usages
+ dims = {'s':-12, 'e':15, 'w':27, 'b':-15., 't':15., 'h':30}
+ dims = {'s':-bayDim/2, 'e':bayDim/2, 'b':-5., 't':10.} # bay settings?
+"""
+
+# ------------------------
radialized = 0 # Radiating from one point - round/disc; instead of square
-slope = 0 # Warp/slope; curved over like a vaulted tunnel
+slope = 0 # Warp/slope; curved over like a vaulted tunnel
+
# 'bigblock': merge adjacent blocks into single large blocks
-bigBlock = 0 # Merge blocks
+bigBlock = 0 # Merge blocks
-# Gaps in blocks for various apertures.
+
+# Gaps in blocks for various apertures
+# ------------------------
# openingSpecs = []
-openingSpecs = [{'w': 0.5, 'h': 0.5, 'x': 0.8, 'z': 2.7, 'rp': 1, 'b': 0.0,
- 'v': 0, 'vl': 0, 't': 0, 'tl': 0}]
-# 'w': opening width, 'h': opening height,
-# 'x': horizontal position, 'z': vertical position,
-# 'rp': make multiple openings, with a spacing of x,
-# 'b': bevel the opening, inside only, like an arrow slit.
-# 'v': height of the top arch, 'vl':height of the bottom arch,
-# 't': thickness of the top arch, 'tl': thickness of the bottom arch
-
-# Add blocks to make platforms.
+openingSpecs = [
+ {'w': 0.5, 'h': 0.5, 'x': 0.8, 'z': 2.7, 'rp': 1, 'b': 0.0,
+ 'v': 0, 'vl': 0, 't': 0, 'tl': 0}
+ ]
+"""
+ openingSpecs DOCUMENTATION:
+ 'w': opening width, 'h': opening height,
+ 'x': horizontal position, 'z': vertical position,
+ 'rp': make multiple openings, with a spacing of x,
+ 'b': bevel the opening, inside only, like an arrow slit.
+ 'v': height of the top arch, 'vl':height of the bottom arch,
+ 't': thickness of the top arch, 'tl': thickness of the bottom arch
+"""
+
+# Add blocks to make platforms
+# ------------------------
shelfExt = 0
-shelfSpecs = {'w': 0.5, 'h': 0.5, 'd': 0.3, 'x': 0.8, 'z': 2.7}
-# 'w': block width, 'h': block height, 'd': block depth (shelf size; offset from wall)
-# 'x': horizontal start position, 'z': vertical start position
-# Add blocks to make steps.
+shelfSpecs = {
+ 'w': 0.5, 'h': 0.5, 'd': 0.3, 'x': 0.8, 'z': 2.7
+ }
+"""
+ shelfSpecs DOCUMENTATION:
+ 'w': block width, 'h': block height, 'd': block depth (shelf size; offset from wall)
+ 'x': horizontal start position, 'z': vertical start position
+"""
+
+# Add blocks to make steps
+# ------------------------
stepMod = 0
-stepSpecs = {'x': 0.0, 'z': -10, 'w': 10.0, 'h': 10.0,
- 'v': 0.7, 't': 1.0, 'd': 1.0}
-# 'x': horizontal start position, 'z': vertical start position,
-# 'w': step area width, 'h': step area height,
-# 'v': riser height, 't': tread width, 'd': block depth (step size; offset from wall)
+
+stepSpecs = {
+ 'x': 0.0, 'z': -10, 'w': 10.0, 'h': 10.0,
+ 'v': 0.7, 't': 1.0, 'd': 1.0
+ }
+"""
+ stepSpecs DOCUMENTATION:
+ 'x': horizontal start position, 'z': vertical start position,
+ 'w': step area width, 'h': step area height,
+ 'v': riser height, 't': tread width, 'd': block depth (step size; offset from wall)
+"""
+stepLeft = 0
+shelfBack = 0
+stepOnly = 0
+stepBack = 0
+
+
+# switchable prints
+def debug_prints(func="", text="Message", var=None):
+ global DEBUG
+ if DEBUG:
+ print("\n[{}]\nmessage: {}".format(func, text))
+ if var:
+ print("Error: ", var)
+
+
+# pass variables just like for the regular prints
+def debug_print_vars(*args, **kwargs):
+ global DEBUG
+ if DEBUG:
+ print(*args, **kwargs)
# easier way to get to the random function
@@ -126,6 +189,7 @@ def test(TestN=13):
't': float(t), 'tl': float(tl)}]
return dims, openingSpecs
+
# dims, openingSpecs = test(15)
@@ -290,7 +354,8 @@ def MakeABlock(bounds, segsize, vll=0, Offsets=None, FaceExclude=[],
def MakeAKeystone(xpos, width, zpos, ztop, zbtm, thick, bevel, vll=0, FaceExclude=[], xBevScl=1):
__doc__ = """\
- MakeAKeystone returns lists of points and faces to be made into a square cornered keystone, with optional bevels.
+ MakeAKeystone returns lists of points and faces to be made into a
+ square cornered keystone, with optional bevels.
xpos: x position of the centerline
width: x width of the keystone at the widest point (discounting bevels)
zpos: z position of the widest point
@@ -299,7 +364,8 @@ def MakeAKeystone(xpos, width, zpos, ztop, zbtm, thick, bevel, vll=0, FaceExclud
thick: thickness
bevel: the amount to raise the back vertex to account for arch beveling
vll: the number of vertexes already in the mesh. len(mesh.verts) should give this number
- faceExclude: list of faces to exclude from the faces list. 0:left, 1:right, 2:bottom, 3:top, 4:back, 5:front
+ faceExclude: list of faces to exclude from the faces list.
+ 0:left, 1:right, 2:bottom, 3:top, 4:back, 5:front
xBevScl: how much to divide the end (+- x axis) bevel dimensions.
Set to current average radius to compensate for angular distortion on curved blocks
"""
@@ -427,6 +493,7 @@ class opening:
# ht is the z position; s is the side: 1 for right, -1 for left
# if the height passed is above or below the opening, return None
def edgeS(self, ht, s):
+
# set the row radius: 1 for standard wall (flat)
if radialized:
if slope:
@@ -496,6 +563,7 @@ class opening:
# get the top or bottom of the opening
# ht is the x position; s is the side: 1 for top, -1 for bottom
def edgeV(self, ht, s):
+
dist = abs(self.x - ht)
def radialAdjust(dist, sideVal):
@@ -556,9 +624,11 @@ class opening:
else:
return self.z - self.h / 2 - self.vl + self.rl - circVal
- # and this never happens - but, leave it as failsafe :)
- print("got all the way out of the edgeV! Not good!")
- print("opening x = ", self.x, ", opening z = ", self.z)
+ # and this never happens - but, leave it as failsafe :)
+ debug_prints(func="opening.EdgeV",
+ text="Got all the way out of the edgeV! Not good!")
+ debug_print_vars("opening x = ", self.x, ", opening z = ", self.z)
+
return 0.0
def edgeBev(self, ht):
@@ -618,11 +688,9 @@ class opening:
# class for the whole wall boundaries; a sub-class of "opening"
-
-class OpeningInv(opening):
+class openingInvert(opening):
# this is supposed to switch the sides of the opening
# so the wall will properly enclose the whole wall.
- # We'll see if it works.
def edgeS(self, ht, s):
return opening.edgeS(self, ht, -s)
@@ -776,8 +844,10 @@ def arch(ra, rt, x, z, archStart, archEnd, bevel, bevAngle, vll):
else:
ThisOffset = offsets
- geom = MakeABlock([divs[i] + grt, divs[i + 1] - grt, ArchInner, ArchOuter, DepthBack, DepthFront],
- subdivision, len(avlist) + vll, ThisOffset, [], None, ra)
+ geom = MakeABlock(
+ [divs[i] + grt, divs[i + 1] - grt, ArchInner, ArchOuter, DepthBack, DepthFront],
+ subdivision, len(avlist) + vll, ThisOffset, [], None, ra
+ )
avlist += geom[0]
aflist += geom[1]
@@ -929,6 +999,7 @@ def rowProcessing(row, Thesketch, WallBoundaries):
# initially just the left and right edge of the wall
edgetop = [[dims['s'] + row.EdgeOffset / r1 + edgrt, WallBoundaries],
[dims['e'] + row.EdgeOffset / r1 - edgrt, WallBoundaries]]
+
# Same as edgetop, but for the bottms of the rows
edgebtm = [[dims['s'] + row.EdgeOffset / r1 + edgrt, WallBoundaries],
[dims['e'] + row.EdgeOffset / r1 - edgrt, WallBoundaries]]
@@ -959,9 +1030,17 @@ def rowProcessing(row, Thesketch, WallBoundaries):
# We want to make the walls in order, so sort the intersects.
# This is where you would want to remove edge points that are out of order
- # so that you don't get the "oddity where overlapping openings create blocks inversely" problem
- edgetop.sort()
- edgebtm.sort()
+ # so that you don't get the "oddity where overlapping openings
+ # create blocks inversely" problem
+
+ # Note: sort ended up comparing function pointers
+ # if both Openings and Slots were enabled with Repeats in one of them
+ try:
+ edgetop.sort(key=lambda x: x[0])
+ edgebtm.sort(key=lambda x: x[0])
+ except Exception as ex:
+ debug_prints(func="rowProcessing",
+ text="Sorting has failed", var=ex)
# these two loops trim the edges to the limits of the wall.
# This way openings extending outside the wall don't enlarge the wall.
@@ -1232,7 +1311,7 @@ def plan(Thesketch, oldrows=0):
z = (dims['t'] + dims['b']) / 2
w = (dims['e'] - dims['s'])
h = (dims['t'] - dims['b'])
- WallBoundaries = OpeningInv(x, z, w, h)
+ WallBoundaries = openingInvert(x, z, w, h)
# Go over each row in the list, set up edge blocks and block sections
for rownum in range(len(rows)):
@@ -1348,7 +1427,8 @@ def archGeneration(hole, vlist, flist, sideSign):
flist += aflist
# remove "debug note" once bevel is finalized.
else:
- print("keystone was too narrow - " + str(Wdth))
+ debug_prints(func="archGeneration",
+ text="Keystone was too narrow - " + str(Wdth))
else: # only one arc - curve not peak.
# bottom (sideSign -1) arch has poorly sized blocks...
@@ -1409,8 +1489,11 @@ def archGeneration(hole, vlist, flist, sideSign):
# Do some stuff to incorporate bev here
bevelBlockOffsets(offsets, bev, -1)
- avlist, aflist = MakeABlock([x - xstart - width, x - xstart - woffset, btmSide, topSide,
- - depth / 2, depth / 2], subdivision, len(vlist), Offsets=offsets, xBevScl=1)
+ avlist, aflist = MakeABlock(
+ [x - xstart - width, x - xstart - woffset, btmSide, topSide,
+ -depth / 2, depth / 2], subdivision, len(vlist),
+ Offsets=offsets, xBevScl=1
+ )
# top didn't use radialized in prev version;
# just noting for clarity - may need to revise for "sideSign == 1"
@@ -1439,8 +1522,11 @@ def archGeneration(hole, vlist, flist, sideSign):
# Do some stuff to incorporate bev here
bevelBlockOffsets(offsets, bev, 1)
- avlist, aflist = MakeABlock([x + xstart + woffset, x + xstart + width, btmSide, topSide,
- -depth / 2, depth / 2], subdivision, len(vlist), Offsets=offsets, xBevScl=1)
+ avlist, aflist = MakeABlock(
+ [x + xstart + woffset, x + xstart + width, btmSide, topSide,
+ -depth / 2, depth / 2], subdivision, len(vlist),
+ Offsets=offsets, xBevScl=1
+ )
# top didn't use radialized in prev version;
# just noting for clarity - may need to revise for "sideSign == 1"
@@ -1544,11 +1630,19 @@ def build(Aplan):
# - this way no gaps between platform and wall face due to wall block depth.
wallDepth = settings['d'] / 2 # offset by wall depth so step depth matches UI setting :)
if shelfBack: # place blocks on backside of wall
- ShelfOffsets = [[0, ShelfThk / 2, 0], [0, wallDepth, 0], [0, ShelfThk / 2, 0], [0, wallDepth, 0],
- [0, ShelfThk / 2, 0], [0, wallDepth, 0], [0, ShelfThk / 2, 0], [0, wallDepth, 0]]
+ ShelfOffsets = [
+ [0, ShelfThk / 2, 0], [0, wallDepth, 0],
+ [0, ShelfThk / 2, 0], [0, wallDepth, 0],
+ [0, ShelfThk / 2, 0], [0, wallDepth, 0],
+ [0, ShelfThk / 2, 0], [0, wallDepth, 0]
+ ]
else:
- ShelfOffsets = [[0, -wallDepth, 0], [0, -ShelfThk / 2, 0], [0, -wallDepth, 0], [0, -ShelfThk / 2, 0],
- [0, -wallDepth, 0], [0, -ShelfThk / 2, 0], [0, -wallDepth, 0], [0, -ShelfThk / 2, 0]]
+ ShelfOffsets = [
+ [0, -wallDepth, 0], [0, -ShelfThk / 2, 0],
+ [0, -wallDepth, 0], [0, -ShelfThk / 2, 0],
+ [0, -wallDepth, 0], [0, -ShelfThk / 2, 0],
+ [0, -wallDepth, 0], [0, -ShelfThk / 2, 0]
+ ]
# Add blocks for each "shelf row" in area
while ShelfBtm < ShelfTop:
@@ -1591,11 +1685,19 @@ def build(Aplan):
# Also, will work fine as stand-alone if not used with wall (try block depth 0 and see what happens).
wallDepth = settings['d'] / 2
if stepBack: # place blocks on backside of wall
- StepOffsets = [[0, StepThk / 2, 0], [0, wallDepth, 0], [0, StepThk / 2, 0], [0, wallDepth, 0],
- [0, StepThk / 2, 0], [0, wallDepth, 0], [0, StepThk / 2, 0], [0, wallDepth, 0]]
+ StepOffsets = [
+ [0, StepThk / 2, 0], [0, wallDepth, 0],
+ [0, StepThk / 2, 0], [0, wallDepth, 0],
+ [0, StepThk / 2, 0], [0, wallDepth, 0],
+ [0, StepThk / 2, 0], [0, wallDepth, 0]
+ ]
else:
- StepOffsets = [[0, -wallDepth, 0], [0, -StepThk / 2, 0], [0, -wallDepth, 0], [0, -StepThk / 2, 0],
- [0, -wallDepth, 0], [0, -StepThk / 2, 0], [0, -wallDepth, 0], [0, -StepThk / 2, 0]]
+ StepOffsets = [
+ [0, -wallDepth, 0], [0, -StepThk / 2, 0],
+ [0, -wallDepth, 0], [0, -StepThk / 2, 0],
+ [0, -wallDepth, 0], [0, -StepThk / 2, 0],
+ [0, -wallDepth, 0], [0, -StepThk / 2, 0]
+ ]
# Add steps for each "step row" in area (neg width is interesting but prevented)
while StepBtm < StepTop and StepWide > 0:
@@ -1645,7 +1747,8 @@ def build(Aplan):
else:
r1 = 1
- geom = MakeABlock([x - w / 2, x + w / 2, z - h / 2, z + h / 2, -d / 2, d / 2], settings['sdv'], len(vlist),
+ geom = MakeABlock([x - w / 2, x + w / 2, z - h / 2, z + h / 2, -d / 2, d / 2],
+ settings['sdv'], len(vlist),
corners, None, settings['b'] + rndd() * settings['bv'], r1)
vlist += geom[0]
flist += geom[1]