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 'archipack/archipack_floor.py')
-rw-r--r--archipack/archipack_floor.py1190
1 files changed, 1190 insertions, 0 deletions
diff --git a/archipack/archipack_floor.py b/archipack/archipack_floor.py
new file mode 100644
index 00000000..24917c16
--- /dev/null
+++ b/archipack/archipack_floor.py
@@ -0,0 +1,1190 @@
+# -*- coding:utf-8 -*-
+
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110- 1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+# <pep8 compliant>
+
+# ----------------------------------------------------------
+# Base code inspired by JARCH Vis
+# Original Author: Jacob Morris
+# Author : Stephen Leger (s-leger)
+# ----------------------------------------------------------
+
+import bpy
+from bpy.types import Operator, PropertyGroup, Mesh, Panel
+from bpy.props import (
+ BoolProperty, EnumProperty, FloatProperty,
+ IntProperty, CollectionProperty
+ )
+from random import uniform, randint
+from math import tan, pi, sqrt
+from mathutils import Vector
+from .bmesh_utils import BmeshEdit as bmed
+from .archipack_manipulator import Manipulable
+from .archipack_preset import ArchipackPreset, PresetMenuOperator
+from .archipack_object import ArchipackCreateTool, ArchipackObject
+
+
+def create_flooring(if_tile, over_width, over_length, b_width, b_length, b_length2, is_length_vary,
+ length_vary, num_boards, space_l, space_w, spacing, t_width, t_length, is_offset, offset,
+ is_ran_offset, offset_vary, t_width2, is_width_vary, width_vary, max_boards, is_ran_thickness,
+ ran_thickness, th, hb_dir):
+
+ # create siding
+ if if_tile == "1": # Tiles Regular
+ return tile_regular(over_width, over_length, t_width, t_length, spacing, is_offset, offset,
+ is_ran_offset, offset_vary, th)
+ elif if_tile == "2": # Large + Small
+ return tile_ls(over_width, over_length, t_width, t_length, spacing, th)
+ elif if_tile == "3": # Large + Many Small
+ return tile_lms(over_width, over_length, t_width, spacing, th)
+ elif if_tile == "4": # Hexagonal
+ return tile_hexagon(over_width, over_length, t_width2, spacing, th)
+ elif if_tile == "21": # Planks
+ return wood_regular(over_width, over_length, b_width, b_length, space_l, space_w,
+ is_length_vary, length_vary,
+ is_width_vary, width_vary,
+ is_offset, offset,
+ is_ran_offset, offset_vary,
+ max_boards, is_ran_thickness,
+ ran_thickness, th)
+ elif if_tile == "22": # Parquet
+ return wood_parquet(over_width, over_length, b_width, spacing, num_boards, th)
+ elif if_tile == "23": # Herringbone Parquet
+ return wood_herringbone(over_width, over_length, b_width, b_length2, spacing, th, hb_dir, True)
+ elif if_tile == "24": # Herringbone
+ return wood_herringbone(over_width, over_length, b_width, b_length2, spacing, th, hb_dir, False)
+
+ return [], []
+
+
+def wood_herringbone(ow, ol, bw, bl, s, th, hb_dir, stepped):
+ verts = []
+ faces = []
+ an_45 = 0.5 * sqrt(2)
+ x, y, z = 0.0, 0.0, th
+ x_off, y_off = 0.0, 0.0 # used for finding farther forwards points when stepped
+ ang_s = s * an_45
+ s45 = s / an_45
+
+ # step variables
+ if stepped:
+ x_off = an_45 * bw
+ y_off = an_45 * bw
+
+ wid_off = an_45 * bl # offset from one end of the board to the other inline with width
+ len_off = an_45 * bl # offset from one end of the board to the other inline with length
+ w = bw / an_45 # width adjusted for 45 degree rotation
+
+ # figure out starting position
+ if hb_dir == "1":
+ y = -wid_off
+
+ elif hb_dir == "2":
+ x = ow
+ y = ol + wid_off
+
+ elif hb_dir == "3":
+ x = -wid_off
+ y = ol
+
+ elif hb_dir == "4":
+ x = ow + wid_off
+
+ # loop going forwards
+ while (hb_dir == "1" and y < ol + wid_off) or (hb_dir == "2" and y > 0 - wid_off) or \
+ (hb_dir == "3" and x < ow + wid_off) or (hb_dir == "4" and x > 0 - wid_off):
+ going_forwards = True
+
+ # loop going right
+ while (hb_dir == "1" and x < ow) or (hb_dir == "2" and x > 0) or (hb_dir == "3" and y > 0 - y_off) or \
+ (hb_dir == "4" and y < ol + y_off):
+ p = len(verts)
+
+ # add verts
+ # forwards
+ verts.append((x, y, z))
+
+ if hb_dir == "1":
+
+ if stepped and x != 0:
+ verts.append((x - x_off, y + y_off, z))
+ else:
+ verts.append((x, y + w, z))
+
+ if going_forwards:
+ y += wid_off
+ else:
+ y -= wid_off
+ x += len_off
+
+ verts.append((x, y, z))
+ if stepped:
+ verts.append((x - x_off, y + y_off, z))
+ x -= x_off - ang_s
+ if going_forwards:
+ y += y_off + ang_s
+ else:
+ y -= y_off + ang_s
+ else:
+ verts.append((x, y + w, z))
+ x += s
+
+ # backwards
+ elif hb_dir == "2":
+
+ if stepped and x != ow:
+ verts.append((x + x_off, y - y_off, z))
+ else:
+ verts.append((x, y - w, z))
+
+ if going_forwards:
+ y -= wid_off
+ else:
+ y += wid_off
+ x -= len_off
+
+ verts.append((x, y, z))
+ if stepped:
+ verts.append((x + x_off, y - y_off, z))
+ x += x_off - ang_s
+ if going_forwards:
+ y -= y_off + ang_s
+ else:
+ y += y_off + ang_s
+ else:
+ verts.append((x, y - w, z))
+ x -= s
+ # right
+ elif hb_dir == "3":
+
+ if stepped and y != ol:
+ verts.append((x + y_off, y + x_off, z))
+ else:
+ verts.append((x + w, y, z))
+
+ if going_forwards:
+ x += wid_off
+ else:
+ x -= wid_off
+ y -= len_off
+
+ verts.append((x, y, z))
+ if stepped:
+ verts.append((x + y_off, y + x_off, z))
+ y += x_off - ang_s
+ if going_forwards:
+ x += y_off + ang_s
+ else:
+ x -= y_off + ang_s
+ else:
+ verts.append((x + w, y, z))
+ y -= s
+ # left
+ else:
+
+ if stepped and y != 0:
+ verts.append((x - y_off, y - x_off, z))
+ else:
+ verts.append((x - w, y, z))
+
+ if going_forwards:
+ x -= wid_off
+ else:
+ x += wid_off
+ y += len_off
+
+ verts.append((x, y, z))
+ if stepped:
+ verts.append((x - y_off, y - x_off, z))
+ y -= x_off - ang_s
+ if going_forwards:
+ x -= y_off + ang_s
+ else:
+ x += y_off + ang_s
+ else:
+ verts.append((x - w, y, z))
+ y += s
+
+ # faces
+ faces.append((p, p + 2, p + 3, p + 1))
+
+ # flip going_right
+ going_forwards = not going_forwards
+ x_off *= -1
+
+ # if not in forwards position, then move back before adjusting values for next row
+ if not going_forwards:
+ x_off = abs(x_off)
+ if hb_dir == "1":
+ y -= wid_off
+ if stepped:
+ y -= y_off + ang_s
+ elif hb_dir == "2":
+ y += wid_off
+ if stepped:
+ y += y_off + ang_s
+ elif hb_dir == "3":
+ x -= wid_off
+ if stepped:
+ x -= y_off + ang_s
+ else:
+ x += wid_off
+ if stepped:
+ x += y_off + ang_s
+
+ # adjust forwards
+ if hb_dir == "1":
+ y += w + s45
+ x = 0
+ elif hb_dir == "2":
+ y -= w + s45
+ x = ow
+ elif hb_dir == "3":
+ x += w + s45
+ y = ol
+ else:
+ x -= w + s45
+ y = 0
+
+ return verts, faces
+
+
+def tile_ls(ow, ol, tw, tl, s, z):
+ """
+ pattern:
+ _____
+ | |_|
+ |___|
+
+ x and y are axis of big one
+ """
+
+ verts = []
+ faces = []
+
+ # big half size
+ hw = (tw / 2) - (s / 2)
+ hl = (tl / 2) - (s / 2)
+ # small half size
+ hws = (tw / 4) - (s / 2)
+ hls = (tl / 4) - (s / 2)
+
+ # small, offset from big x,y
+ xo = 0.75 * tw
+ yo = 0.25 * tl
+
+ # offset for pattern
+ rx = 2.5 * tw
+ ry = 0.5 * tl
+
+ # width and a half of big
+ ow_x = ow + 0.5 * tw
+ ol_y = ol + 0.5 * tl
+
+ # start pattern with big one
+ x = tw
+ y = -tl
+
+ while y < ol_y:
+
+ while x < ow_x:
+
+ p = len(verts)
+
+ # Large
+ x0 = max(0, x - hw)
+ y0 = max(0, y - hl)
+ x1 = min(ow, x + hw)
+ y1 = min(ol, y + hl)
+ if y1 > 0:
+ if x1 > 0 and x0 < ow and y0 < ol:
+
+ verts.extend([(x0, y1, z), (x1, y1, z), (x1, y0, z), (x0, y0, z)])
+ faces.append((p, p + 1, p + 2, p + 3))
+ p = len(verts)
+
+ # Small
+ x0 = x + xo - hws
+ y0 = y + yo - hls
+ x1 = min(ow, x + xo + hws)
+
+ if x1 > 0 and x0 < ow and y0 < ol:
+
+ y1 = min(ol, y + yo + hls)
+ verts.extend([(x0, y1, z), (x1, y1, z), (x1, y0, z), (x0, y0, z)])
+ faces.append((p, p + 1, p + 2, p + 3))
+
+ x += rx
+
+ y += ry
+ x = x % rx - tw
+ if x < -tw:
+ x += rx
+
+ return verts, faces
+
+
+def tile_hexagon(ow, ol, tw, s, z):
+ verts = []
+ faces = []
+ offset = False
+
+ w = tw / 2
+ y = 0.0
+ h = w * tan(pi / 6)
+ r = sqrt((w * w) + (h * h))
+
+ while y < ol + tw:
+ if not offset:
+ x = 0.0
+ else:
+ x = w + (s / 2)
+
+ while x < ow + tw:
+ p = len(verts)
+
+ verts.extend([(x + w, y + h, z), (x, y + r, z), (x - w, y + h, z),
+ (x - w, y - h, z), (x, y - r, z), (x + w, y - h, z)])
+ faces.extend([(p, p + 1, p + 2, p + 3), (p + 3, p + 4, p + 5, p)])
+
+ x += tw + s
+
+ y += r + h + s
+ offset = not offset
+
+ return verts, faces
+
+
+def tile_lms(ow, ol, tw, s, z):
+ verts = []
+ faces = []
+ small = True
+
+ y = 0.0
+ ref = (tw - s) / 2
+
+ while y < ol:
+ x = 0.0
+ large = False
+ while x < ow:
+ if small:
+ x1 = min(x + ref, ow)
+ y1 = min(y + ref, ol)
+ p = len(verts)
+ verts.extend([(x, y1, z), (x, y, z)])
+ verts.extend([(x1, y1, z), (x1, y, z)])
+ faces.append((p, p + 1, p + 3, p + 2))
+ x += ref
+ else:
+ if not large:
+ x1 = min(x + ref, ow)
+ for i in range(2):
+ y0 = y + i * (ref + s)
+ if x < ow and y0 < ol:
+ y1 = min(y0 + ref, ol)
+ p = len(verts)
+ verts.extend([(x, y1, z), (x, y0, z)])
+ verts.extend([(x1, y1, z), (x1, y0, z)])
+ faces.append((p, p + 1, p + 3, p + 2))
+ x += ref
+ else:
+ x1 = min(x + tw, ow)
+ y1 = min(y + tw, ol)
+ p = len(verts)
+ verts.extend([(x, y1, z), (x, y, z)])
+ verts.extend([(x1, y1, z), (x1, y, z)])
+ faces.append((p, p + 1, p + 3, p + 2))
+ x += tw
+ large = not large
+ x += s
+ if small:
+ y += ref + s
+ else:
+ y += tw + s
+ small = not small
+
+ return verts, faces
+
+
+def tile_regular(ow, ol, tw, tl, s, is_offset, offset, is_ran_offset, offset_vary, z):
+ verts = []
+ faces = []
+ off = False
+ o = 1 / (100 / offset)
+ y = 0.0
+
+ while y < ol:
+
+ tw2 = 0
+ if is_offset:
+ if is_ran_offset:
+ v = tw * 0.0049 * offset_vary
+ tw2 = uniform((tw / 2) - v, (tw / 2) + v)
+ elif off:
+ tw2 = o * tw
+ x = -tw2
+ y1 = min(ol, y + tl)
+
+ while x < ow:
+ p = len(verts)
+ x0 = max(0, x)
+ x1 = min(ow, x + tw)
+
+ verts.extend([(x0, y1, z), (x0, y, z), (x1, y, z), (x1, y1, z)])
+ faces.append((p, p + 1, p + 2, p + 3))
+ x = x1 + s
+
+ y += tl + s
+ off = not off
+
+ return verts, faces
+
+
+def wood_parquet(ow, ol, bw, s, num_boards, z):
+ verts = []
+ faces = []
+ x = 0.0
+
+ start_orient_length = True
+
+ # figure board length
+ bl = (bw * num_boards) + (s * (num_boards - 1))
+ while x < ow:
+
+ y = 0.0
+
+ orient_length = start_orient_length
+
+ while y < ol:
+
+ if orient_length:
+ y0 = y
+ y1 = min(y + bl, ol)
+
+ for i in range(num_boards):
+
+ bx = x + i * (bw + s)
+
+ if bx < ow and y < ol:
+
+ # make sure board should be placed
+ x0 = bx
+ x1 = min(bx + bw, ow)
+
+ p = len(verts)
+ verts.extend([(x0, y0, z), (x1, y0, z), (x1, y1, z), (x0, y1, z)])
+ faces.append((p, p + 1, p + 2, p + 3))
+
+ else:
+ x0 = x
+ x1 = min(x + bl, ow)
+
+ for i in range(num_boards):
+
+ by = y + i * (bw + s)
+
+ if x < ow and by < ol:
+ y0 = by
+ y1 = min(by + bw, ol)
+ p = len(verts)
+
+ verts.extend([(x0, y0, z), (x1, y0, z), (x1, y1, z), (x0, y1, z)])
+ faces.append((p, p + 1, p + 2, p + 3))
+
+ y += bl + s
+
+ orient_length = not orient_length
+
+ start_orient_length = not start_orient_length
+
+ x += bl + s
+
+ return verts, faces
+
+
+def wood_regular(ow, ol, bw, bl, s_l, s_w,
+ is_length_vary, length_vary,
+ is_width_vary, width_vary,
+ is_offset, offset,
+ is_ran_offset, offset_vary,
+ max_boards, is_r_h,
+ r_h, th):
+ verts = []
+ faces = []
+ x = 0.0
+ row = 0
+ while x < ow:
+
+ if is_width_vary:
+ v = bw * (width_vary / 100) * 0.499
+ bw2 = uniform(bw / 2 - v, bw / 2 + v)
+ else:
+ bw2 = bw
+
+ x1 = min(x + bw2, ow)
+ if is_offset:
+ if is_ran_offset:
+ v = bl * (offset_vary / 100) * 0.5
+ y = -uniform(bl / 2 - v, bl / 2 + v)
+ else:
+ y = -(row % 2) * bl * (offset / 100)
+ else:
+ y = 0
+
+ row += 1
+ counter = 1
+
+ while y < ol:
+
+ z = th
+
+ if is_r_h:
+ v = z * 0.5 * (r_h / 100)
+ z = uniform(z / 2 - v, z / 2 + v)
+
+ bl2 = bl
+
+ if is_length_vary:
+ if (counter >= max_boards):
+ bl2 = ol
+ else:
+ v = bl * (length_vary / 100) * 0.5
+ bl2 = uniform(bl / 2 - v, bl / 2 + v)
+
+ y0 = max(0, y)
+ y1 = min(y + bl2, ol)
+
+ if y1 > y0:
+ p = len(verts)
+
+ verts.extend([(x, y0, z), (x1, y0, z), (x1, y1, z), (x, y1, z)])
+ faces.append((p, p + 1, p + 2, p + 3))
+
+ y += bl2 + s_l
+
+ counter += 1
+
+ x += bw2 + s_w
+
+ return verts, faces
+
+
+def tile_grout(ow, ol, depth, th):
+ z = min(th - 0.001, max(0.001, th - depth))
+ x = ow
+ y = ol
+
+ verts = [(0.0, 0.0, 0.0), (0.0, 0.0, z), (x, 0.0, z), (x, 0.0, 0.0),
+ (0.0, y, 0.0), (0.0, y, z), (x, y, z), (x, y, 0.0)]
+
+ faces = [(0, 3, 2, 1), (4, 5, 6, 7), (0, 1, 5, 4),
+ (1, 2, 6, 5), (3, 7, 6, 2), (0, 4, 7, 3)]
+
+ return verts, faces
+
+
+def update(self, context):
+ self.update(context)
+
+
+class archipack_floor(ArchipackObject, Manipulable, PropertyGroup):
+ tile_types = EnumProperty(
+ items=(
+ ("1", "Tiles", ""),
+ ("2", "Large + Small", ""),
+ ("3", "Large + Many Small", ""),
+ ("4", "Hexagonal", ""),
+ ("21", "Planks", ""),
+ ("22", "Parquet", ""),
+ ("23", "Herringbone Parquet", ""),
+ ("24", "Herringbone", "")
+ ),
+ default="1",
+ description="Tile Type",
+ update=update,
+ name="")
+ b_length_s = FloatProperty(
+ name="Board Length",
+ min=0.01,
+ default=2.0,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Board Length",
+ update=update)
+ hb_direction = EnumProperty(
+ items=(
+ ("1", "Forwards (+y)", ""),
+ ("2", "Backwards (-y)", ""),
+ ("3", "Right (+x)", ""),
+ ("4", "Left (-x)", "")
+ ),
+ name="Direction",
+ description="Herringbone Direction",
+ update=update)
+ thickness = FloatProperty(
+ name="Floor Thickness",
+ min=0.01,
+ default=0.1,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Thickness Of Flooring",
+ update=update)
+ num_boards = IntProperty(
+ name="# Of Boards",
+ min=2,
+ max=6,
+ default=4,
+ description="Number Of Boards In Square",
+ update=update)
+ space_l = FloatProperty(
+ name="Length Spacing",
+ min=0.001,
+ default=0.005,
+ step=0.01,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Space Between Boards Length Ways",
+ update=update)
+ space_w = FloatProperty(
+ name="Width Spacing",
+ min=0.001,
+ default=0.005,
+ step=0.01,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Space Between Boards Width Ways",
+ update=update)
+ spacing = FloatProperty(
+ name="Spacing",
+ min=0.001,
+ default=0.005,
+ step=0.01,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Space Between Tiles/Boards",
+ update=update)
+ is_bevel = BoolProperty(
+ name="Bevel?",
+ default=False,
+ update=update)
+ bevel_res = IntProperty(
+ name="Bevel Resolution",
+ min=1,
+ max=10,
+ default=1,
+ update=update)
+ bevel_amo = FloatProperty(
+ name="Bevel Amount",
+ min=0.001,
+ default=0.0015,
+ step=0.01,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Bevel Amount",
+ update=update)
+ is_ran_thickness = BoolProperty(
+ name="Random Thickness?",
+ default=False,
+ update=update)
+ ran_thickness = FloatProperty(
+ name="Thickness Variance",
+ min=0.1,
+ max=100.0,
+ default=50.0,
+ subtype="PERCENTAGE",
+ update=update)
+ is_floor_bottom = BoolProperty(
+ name="Floor bottom",
+ default=True,
+ update=update)
+ t_width = FloatProperty(
+ name="Tile Width",
+ min=0.01,
+ default=0.3,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Tile Width",
+ update=update)
+ t_length = FloatProperty(
+ name="Tile Length",
+ min=0.01,
+ default=0.3,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Tile Length",
+ update=update)
+ is_grout = BoolProperty(
+ name="Grout",
+ default=False,
+ description="Enable grout",
+ update=update)
+ grout_depth = FloatProperty(
+ name="Grout Depth",
+ min=0.001,
+ default=0.005,
+ step=0.01,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Grout Depth",
+ update=update)
+ is_offset = BoolProperty(
+ name="Offset ?",
+ default=False,
+ description="Offset Rows",
+ update=update)
+ offset = FloatProperty(
+ name="Offset",
+ min=0.001,
+ max=100.0,
+ default=50.0,
+ subtype="PERCENTAGE",
+ description="Tile Offset Amount",
+ update=update)
+ is_random_offset = BoolProperty(
+ name="Random Offset?",
+ default=False,
+ description="Offset Tile Rows Randomly",
+ update=update)
+ offset_vary = FloatProperty(
+ name="Offset Variance",
+ min=0.001,
+ max=100.0,
+ default=50.0,
+ subtype="PERCENTAGE",
+ description="Offset Variance",
+ update=update)
+ t_width_s = FloatProperty(
+ name="Small Tile Width",
+ min=0.02,
+ default=0.2,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Small Tile Width",
+ update=update)
+ over_width = FloatProperty(
+ name="Overall Width",
+ min=0.02,
+ default=4,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Overall Width",
+ update=update)
+ over_length = FloatProperty(
+ name="Overall Length",
+ min=0.02,
+ default=4,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Overall Length",
+ update=update)
+ b_width = FloatProperty(
+ name="Board Width",
+ min=0.01,
+ default=0.2,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Board Width",
+ update=update)
+ b_length = FloatProperty(
+ name="Board Length",
+ min=0.01,
+ default=0.8,
+ unit='LENGTH', subtype='DISTANCE',
+ description="Board Length",
+ update=update)
+ is_length_vary = BoolProperty(
+ name="Vary Length?",
+ default=False,
+ description="Vary Lengths?",
+ update=update)
+ length_vary = FloatProperty(
+ name="Length Variance",
+ min=1.00,
+ max=100.0,
+ default=50.0,
+ subtype="PERCENTAGE",
+ description="Length Variance",
+ update=update)
+ max_boards = IntProperty(
+ name="Max # Of Boards",
+ min=2,
+ default=2,
+ description="Maximum Number Of Boards Possible In One Length",
+ update=update)
+ is_width_vary = BoolProperty(
+ name="Vary Width?",
+ default=False,
+ description="Vary Widths?",
+ update=update)
+ width_vary = FloatProperty(
+ name="Width Variance",
+ min=1.00,
+ max=100.0,
+ default=50.0,
+ subtype="PERCENTAGE",
+ description="Width Variance",
+ update=update)
+ is_mat_vary = BoolProperty(
+ name="Vary Material?",
+ default=False,
+ description="Vary Material indexes",
+ update=update)
+ mat_vary = IntProperty(
+ name="#variations",
+ min=1,
+ max=10,
+ default=1,
+ description="Material index maxi",
+ update=update)
+ auto_update = BoolProperty(
+ options={'SKIP_SAVE'},
+ default=True,
+ update=update
+ )
+
+ def setup_manipulators(self):
+ if len(self.manipulators) < 1:
+ # add manipulator for x property
+ s = self.manipulators.add()
+ s.prop1_name = "over_width"
+ # s.prop2_name = "x"
+ s.type_key = 'SIZE'
+
+ # add manipulator for y property
+ s = self.manipulators.add()
+ s.prop1_name = "over_length"
+ # s.prop2_name = "y"
+ s.type_key = 'SIZE'
+
+ def update(self, context):
+
+ o = self.find_in_selection(context, self.auto_update)
+
+ if o is None:
+ return
+
+ self.setup_manipulators()
+
+ verts, faces = create_flooring(self.tile_types, self.over_width,
+ self.over_length, self.b_width, self.b_length, self.b_length_s,
+ self.is_length_vary, self.length_vary, self.num_boards, self.space_l,
+ self.space_w, self.spacing, self.t_width, self.t_length, self.is_offset,
+ self.offset, self.is_random_offset, self.offset_vary, self.t_width_s,
+ self.is_width_vary, self.width_vary, self.max_boards, self.is_ran_thickness,
+ self.ran_thickness, self.thickness, self.hb_direction)
+
+ if self.is_mat_vary:
+ # hexagon made of 2 faces
+ if self.tile_types == '4':
+ matids = []
+ for i in range(int(len(faces) / 2)):
+ id = randint(1, self.mat_vary)
+ matids.extend([id, id])
+ else:
+ matids = [randint(1, self.mat_vary) for i in faces]
+ else:
+ matids = [1 for i in faces]
+
+ uvs = [[(0, 0), (0, 1), (1, 1), (1, 0)] for i in faces]
+
+ bmed.buildmesh(context,
+ o,
+ verts,
+ faces,
+ matids=matids,
+ uvs=uvs,
+ weld=False,
+ auto_smooth=False)
+
+ # cut hexa and herringbone wood
+ # disable when boolean modifier is found
+ enable_bissect = True
+ for m in o.modifiers:
+ if m.type == 'BOOLEAN':
+ enable_bissect = False
+
+ if enable_bissect and self.tile_types in ('4', '23', '24'):
+ bmed.bissect(context, o, Vector((0, 0, 0)), Vector((0, -1, 0)))
+ # Up
+ bmed.bissect(context, o, Vector((0, self.over_length, 0)), Vector((0, 1, 0)))
+ # left
+ bmed.bissect(context, o, Vector((0, 0, 0)), Vector((-1, 0, 0)))
+ # right
+ bmed.bissect(context, o, Vector((self.over_width, 0, 0)), Vector((1, 0, 0)))
+
+ if self.is_bevel:
+ bevel = self.bevel_amo
+ else:
+ bevel = 0
+
+ if self.is_grout:
+ th = min(self.grout_depth + bevel, self.thickness - 0.001)
+ bottom = th
+ else:
+ th = self.thickness
+ bottom = 0
+
+ bmed.solidify(context,
+ o,
+ th,
+ floor_bottom=(
+ self.is_floor_bottom and
+ self.is_ran_thickness and
+ self.tile_types in ('21')
+ ),
+ altitude=bottom)
+
+ # bevel mesh
+ if self.is_bevel:
+ bmed.bevel(context, o, self.bevel_amo, segments=self.bevel_res)
+
+ # create grout
+ if self.is_grout:
+ verts, faces = tile_grout(self.over_width, self.over_length, self.grout_depth, self.thickness)
+ matids = [0 for i in faces]
+ uvs = [[(0, 0), (0, 1), (1, 1), (1, 0)] for i in faces]
+ bmed.addmesh(context,
+ o,
+ verts,
+ faces,
+ matids=matids,
+ uvs=uvs,
+ weld=False,
+ auto_smooth=False)
+
+ x, y = self.over_width, self.over_length
+ self.manipulators[0].set_pts([(0, 0, 0), (x, 0, 0), (1, 0, 0)])
+ self.manipulators[1].set_pts([(0, 0, 0), (0, y, 0), (-1, 0, 0)])
+
+ self.restore_context(context)
+
+
+class ARCHIPACK_PT_floor(Panel):
+ bl_idname = "ARCHIPACK_PT_floor"
+ bl_label = "Flooring"
+ bl_space_type = "VIEW_3D"
+ bl_region_type = "UI"
+ bl_category = "Archipack"
+
+ @classmethod
+ def poll(cls, context):
+ # ensure your object panel only show when active object is the right one
+ return archipack_floor.filter(context.active_object)
+
+ def draw(self, context):
+ o = context.active_object
+ if not archipack_floor.filter(o):
+ return
+ layout = self.layout
+
+ # retrieve datablock of your object
+ props = archipack_floor.datablock(o)
+
+ # Manipulate mode operator
+ layout.operator('archipack.floor_manipulate', icon='HAND')
+
+ box = layout.box()
+ row = box.row(align=True)
+
+ # Presets operators
+ row.operator("archipack.floor_preset_menu",
+ text=bpy.types.ARCHIPACK_OT_floor_preset_menu.bl_label)
+ row.operator("archipack.floor_preset",
+ text="",
+ icon='ZOOMIN')
+ row.operator("archipack.floor_preset",
+ text="",
+ icon='ZOOMOUT').remove_active = True
+
+ layout.prop(props, "tile_types", icon="OBJECT_DATA")
+
+ layout.separator()
+
+ layout.prop(props, "over_width")
+ layout.prop(props, "over_length")
+ layout.separator()
+
+ # width and lengths
+ layout.prop(props, "thickness")
+
+ type = int(props.tile_types)
+
+ if type > 20:
+ # Wood types
+ layout.prop(props, "b_width")
+ else:
+ # Tiles types
+ if type != 4:
+ # Not hexagonal
+ layout.prop(props, "t_width")
+ layout.prop(props, "t_length")
+ else:
+ layout.prop(props, "t_width_s")
+
+ # Herringbone
+ if type in (23, 24):
+ layout.prop(props, "b_length_s")
+ layout.prop(props, "hb_direction")
+
+ # Parquet
+ if type == 22:
+ layout.prop(props, "num_boards")
+
+ # Planks
+ if type == 21:
+ layout.prop(props, "b_length")
+ layout.prop(props, "space_w")
+ layout.prop(props, "space_l")
+
+ layout.separator()
+ layout.prop(props, "is_length_vary", icon="NLA")
+ if props.is_length_vary:
+ layout.prop(props, "length_vary")
+ layout.prop(props, "max_boards")
+
+ layout.separator()
+ layout.prop(props, "is_width_vary", icon="UV_ISLANDSEL")
+ if props.is_width_vary:
+ layout.prop(props, "width_vary")
+
+ layout.separator()
+ layout.prop(props, "is_ran_thickness", icon="RNDCURVE")
+ if props.is_ran_thickness:
+ layout.prop(props, "ran_thickness")
+ layout.prop(props, "is_floor_bottom", icon="MOVE_DOWN_VEC")
+ else:
+ layout.prop(props, "spacing")
+
+ # Planks and tiles
+ if type in (1, 21):
+ layout.separator()
+ layout.prop(props, "is_offset", icon="OOPS")
+ if props.is_offset:
+ layout.prop(props, "is_random_offset", icon="NLA")
+ if not props.is_random_offset:
+ layout.prop(props, "offset")
+ else:
+ layout.prop(props, "offset_vary")
+
+ # bevel
+ layout.separator()
+ layout.prop(props, "is_bevel", icon="MOD_BEVEL")
+ if props.is_bevel:
+ layout.prop(props, "bevel_res", icon="OUTLINER_DATA_CURVE")
+ layout.prop(props, "bevel_amo")
+
+ # Grout
+ layout.separator()
+ layout.prop(props, "is_grout", icon="OBJECT_DATA")
+ if props.is_grout:
+ layout.prop(props, "grout_depth")
+
+ layout.separator()
+ layout.prop(props, "is_mat_vary", icon="MATERIAL")
+ if props.is_mat_vary:
+ layout.prop(props, "mat_vary")
+
+
+class ARCHIPACK_OT_floor(ArchipackCreateTool, Operator):
+ bl_idname = "archipack.floor"
+ bl_label = "Floor"
+ bl_description = "Create Floor"
+ bl_category = 'Archipack'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def create(self, context):
+
+ # Create an empty mesh datablock
+ m = bpy.data.meshes.new("Floor")
+
+ # Create an object using the mesh datablock
+ o = bpy.data.objects.new("Floor", m)
+
+ # Add your properties on mesh datablock
+ d = m.archipack_floor.add()
+
+ # Link object into scene
+ context.scene.objects.link(o)
+
+ # select and make active
+ o.select = True
+ context.scene.objects.active = o
+
+ # Load preset into datablock
+ self.load_preset(d)
+
+ # add a material
+ self.add_material(o)
+ return o
+
+ def execute(self, context):
+ if context.mode == "OBJECT":
+ bpy.ops.object.select_all(action="DESELECT")
+ o = self.create(context)
+ o.location = bpy.context.scene.cursor_location
+ o.select = True
+ context.scene.objects.active = o
+
+ # Start manipulate mode
+ self.manipulate()
+ return {'FINISHED'}
+ else:
+ self.report({'WARNING'}, "Archipack: Option only valid in Object mode")
+ return {'CANCELLED'}
+
+
+class ARCHIPACK_OT_floor_preset_menu(PresetMenuOperator, Operator):
+ bl_idname = "archipack.floor_preset_menu"
+ bl_label = "Floor preset"
+ preset_subdir = "archipack_floor"
+
+
+class ARCHIPACK_OT_floor_preset(ArchipackPreset, Operator):
+ """Add a Floor Preset"""
+ bl_idname = "archipack.floor_preset"
+ bl_label = "Add Floor preset"
+ preset_menu = "ARCHIPACK_OT_floor_preset_menu"
+
+ @property
+ def blacklist(self):
+ return ['manipulators', 'over_length', 'over_width']
+
+
+class ARCHIPACK_OT_floor_manipulate(Operator):
+ bl_idname = "archipack.floor_manipulate"
+ bl_label = "Manipulate"
+ bl_description = "Manipulate"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ @classmethod
+ def poll(self, context):
+ return archipack_floor.filter(context.active_object)
+
+ def invoke(self, context, event):
+ d = archipack_floor.datablock(context.active_object)
+ d.manipulable_invoke(context)
+ return {'FINISHED'}
+
+
+def register():
+ bpy.utils.register_class(archipack_floor)
+ Mesh.archipack_floor = CollectionProperty(type=archipack_floor)
+ bpy.utils.register_class(ARCHIPACK_PT_floor)
+ bpy.utils.register_class(ARCHIPACK_OT_floor)
+ bpy.utils.register_class(ARCHIPACK_OT_floor_preset_menu)
+ bpy.utils.register_class(ARCHIPACK_OT_floor_preset)
+ bpy.utils.register_class(ARCHIPACK_OT_floor_manipulate)
+
+
+def unregister():
+ bpy.utils.unregister_class(archipack_floor)
+ del Mesh.archipack_floor
+ bpy.utils.unregister_class(ARCHIPACK_PT_floor)
+ bpy.utils.unregister_class(ARCHIPACK_OT_floor)
+ bpy.utils.unregister_class(ARCHIPACK_OT_floor_preset_menu)
+ bpy.utils.unregister_class(ARCHIPACK_OT_floor_preset)
+ bpy.utils.unregister_class(ARCHIPACK_OT_floor_manipulate)