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 'archimesh/achm_books_maker.py')
-rw-r--r--archimesh/achm_books_maker.py401
1 files changed, 401 insertions, 0 deletions
diff --git a/archimesh/achm_books_maker.py b/archimesh/achm_books_maker.py
new file mode 100644
index 00000000..1d0f47e2
--- /dev/null
+++ b/archimesh/achm_books_maker.py
@@ -0,0 +1,401 @@
+# ##### 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>
+
+# ----------------------------------------------------------
+# Automatic generation of books
+# Author: Antonio Vazquez (antonioya)
+#
+# ----------------------------------------------------------
+# noinspection PyUnresolvedReferences
+import bpy
+import math
+import random
+import copy
+import colorsys
+from achm_tools import *
+
+
+# ------------------------------------------------------------------
+# Define UI class
+# Books
+# ------------------------------------------------------------------
+class AchmBooks(bpy.types.Operator):
+ bl_idname = "mesh.archimesh_books"
+ bl_label = "Books"
+ bl_description = "Books Generator"
+ bl_category = 'Archimesh'
+ bl_options = {'REGISTER', 'UNDO'}
+
+ width = bpy.props.FloatProperty(
+ name='Width', min=0.001, max=1, default=0.045, precision=3,
+ description='Bounding book width',
+ )
+ depth = bpy.props.FloatProperty(
+ name='Depth', min=0.001, max=1, default=0.22, precision=3,
+ description='Bounding book depth',
+ )
+ height = bpy.props.FloatProperty(
+ name='Height', min=0.001, max=1, default=0.30, precision=3,
+ description='Bounding book height',
+ )
+ num = bpy.props.IntProperty(
+ name='Number of books', min=1, max=100, default=20,
+ description='Number total of books',
+ )
+
+ rX = bpy.props.FloatProperty(
+ name='X', min=0.000, max=0.999, default=0, precision=3,
+ description='Randomness for X axis',
+ )
+ rY = bpy.props.FloatProperty(
+ name='Y', min=0.000, max=0.999, default=0, precision=3,
+ description='Randomness for Y axis',
+ )
+ rZ = bpy.props.FloatProperty(
+ name='Z', min=0.000, max=0.999, default=0, precision=3,
+ description='Randomness for Z axis',
+ )
+
+ rot = bpy.props.FloatProperty(
+ name='Rotation', min=0.000, max=1, default=0, precision=3,
+ description='Randomness for vertical position (0-> All straight)',
+ )
+ afn = bpy.props.IntProperty(
+ name='Affinity', min=0, max=10, default=5,
+ description='Number of books with same rotation angle',
+ )
+
+ # Materials
+ crt_mat = bpy.props.BoolProperty(
+ name="Create default Cycles materials",
+ description="Create default materials for Cycles render",
+ default=True,
+ )
+ objcol = bpy.props.FloatVectorProperty(
+ name="Color",
+ description="Color for material",
+ default=(1.0, 1.0, 1.0, 1.0),
+ min=0.1, max=1,
+ subtype='COLOR',
+ size=4,
+ )
+ rC = bpy.props.FloatProperty(
+ name='Randomness',
+ min=0.000, max=1, default=0, precision=3,
+ description='Randomness for color ',
+ )
+
+ # -----------------------------------------------------
+ # Draw (create UI interface)
+ # -----------------------------------------------------
+ # noinspection PyUnusedLocal
+ def draw(self, context):
+ layout = self.layout
+ space = bpy.context.space_data
+ if not space.local_view:
+ # Imperial units warning
+ if bpy.context.scene.unit_settings.system == "IMPERIAL":
+ row = layout.row()
+ row.label("Warning: Imperial units not supported", icon='COLOR_RED')
+
+ box = layout.box()
+ box.label("Book size")
+ row = box.row()
+ row.prop(self, 'width')
+ row.prop(self, 'depth')
+ row.prop(self, 'height')
+ row = box.row()
+ row.prop(self, 'num', slider=True)
+
+ box = layout.box()
+ box.label("Randomness")
+ row = box.row()
+ row.prop(self, 'rX', slider=True)
+ row.prop(self, 'rY', slider=True)
+ row.prop(self, 'rZ', slider=True)
+ row = box.row()
+ row.prop(self, 'rot', slider=True)
+ row.prop(self, 'afn', slider=True)
+
+ box = layout.box()
+ box.prop(self, 'crt_mat')
+ if self.crt_mat:
+ row = box.row()
+ row.prop(self, 'objcol')
+ row = box.row()
+ row.prop(self, 'rC', slider=True)
+ else:
+ row = layout.row()
+ row.label("Warning: Operator does not work in local view mode", icon='ERROR')
+
+ # -----------------------------------------------------
+ # Execute
+ # -----------------------------------------------------
+ # noinspection PyUnusedLocal
+ def execute(self, context):
+ if bpy.context.mode == "OBJECT":
+ # Create shelves
+ create_book_mesh(self)
+ return {'FINISHED'}
+ else:
+ self.report({'WARNING'}, "Archimesh: Option only valid in Object mode")
+ return {'CANCELLED'}
+
+
+# ------------------------------------------------------------------------------
+# Generate mesh data
+# All custom values are passed using self container (self.myvariable)
+# ------------------------------------------------------------------------------
+def create_book_mesh(self):
+ # deactivate others
+ for o in bpy.data.objects:
+ if o.select is True:
+ o.select = False
+ bpy.ops.object.select_all(False)
+ generate_books(self)
+
+ return
+
+
+# ------------------------------------------------------------------------------
+# Generate books
+# All custom values are passed using self container (self.myvariable)
+# ------------------------------------------------------------------------------
+def generate_books(self):
+ boxes = []
+ location = bpy.context.scene.cursor_location
+ myloc = copy.copy(location) # copy location to keep 3D cursor position
+
+ # Create
+ lastx = myloc.x
+ ox = 0
+ oy = 0
+ oz = 0
+ ot = 0
+ i = 0
+ for x in range(self.num):
+ # reset rotation
+ if i >= self.afn:
+ i = 0
+ ot = -1
+
+ mydata = create_book("Book" + str(x),
+ self.width, self.depth, self.height,
+ lastx, myloc.y, myloc.z,
+ self.crt_mat,
+ self.rX, self.rY, self.rZ, self.rot, ox, oy, oz, ot,
+ self.objcol, self.rC)
+ boxes.extend([mydata[0]])
+ bookdata = mydata[1]
+
+ # calculate rotation using previous book
+ ot = bookdata[3]
+ i += 1
+ oz = 0
+
+ # calculate x size after rotation
+ if i < self.afn:
+ size = 0.0002
+ else:
+ size = 0.0003 + math.cos(math.radians(90 - bookdata[3])) * bookdata[2] # the height is the radius
+ oz = bookdata[2]
+
+ lastx = lastx + bookdata[0] + size
+
+ # refine units
+ for box in boxes:
+ remove_doubles(box)
+ set_normals(box)
+
+ # deactivate others
+ for o in bpy.data.objects:
+ if o.select is True:
+ o.select = False
+
+ boxes[0].select = True
+ bpy.context.scene.objects.active = boxes[0]
+
+ return
+
+
+# ------------------------------------------------------------------------------
+# Create books unit
+#
+# objName: Name for the new object
+# thickness: wood thickness (sides)
+# sX: Size in X axis
+# sY: Size in Y axis
+# sZ: Size in Z axis
+# pX: position X axis
+# pY: position Y axis
+# pZ: position Z axis
+# mat: Flag for creating materials
+# frX: Random factor X
+# frY: Random factor Y
+# frZ: Random factor Z
+# frR: Random factor Rotation
+# oX: override x size
+# oY: override y size
+# oZ: override z size
+# oR: override rotation
+# objcol: color
+# frC: color randomness factor
+# ------------------------------------------------------------------------------
+def create_book(objname, sx, sy, sz, px, py, pz, mat, frx,
+ fry, frz, frr, ox, oy, oz, ot, objcol, frc):
+ # gap Randomness
+ ri = random.randint(10, 150)
+ gap = ri / 100000
+ # Randomness X
+ if ox == 0:
+ ri = random.randint(0, int(frx * 1000))
+ factor = ri / 1000
+ sx -= sx * factor
+ if sx < (gap * 3):
+ sx = gap * 3
+ else:
+ sx = ox
+
+ # Randomness Y
+ if oy == 0:
+ ri = random.randint(0, int(fry * 1000))
+ factor = ri / 1000
+ sy -= sy * factor
+ if sy < (gap * 3):
+ sy = gap * 3
+ else:
+ sy = oy
+
+ # Randomness Z
+ if oz == 0:
+ ri = random.randint(0, int(frz * 1000))
+ factor = ri / 1000
+ sz -= sz * factor
+ if sz < (gap * 3):
+ sz = gap * 3
+ else:
+ sz = oz
+
+ # Randomness rotation
+ rot = 0
+ if frr > 0 and ot != -1:
+ if ot == 0:
+ ri = random.randint(0, int(frr * 1000))
+ factor = ri / 1000
+ rot = 30 * factor
+ else:
+ rot = ot
+
+ # Randomness color (only hue)
+ hsv = colorsys.rgb_to_hsv(objcol[0], objcol[1], objcol[2])
+ hue = hsv[0]
+ if frc > 0:
+ rc1 = random.randint(0, int(hue * 1000)) # 0 to hue
+ rc2 = random.randint(int(hue * 1000), 1000) # hue to maximum
+ rc3 = random.randint(0, 1000) # sign
+
+ if rc3 >= hue * 1000:
+ hue += (rc2 * frc) / 1000
+ else:
+ hue -= (rc1 * frc) / 1000
+ # Convert random color
+ objcol = colorsys.hsv_to_rgb(hue, hsv[1], hsv[2])
+
+ myvertex = []
+ myfaces = []
+ x = 0
+ # Left side
+ myvertex.extend([(x, -sy, 0), (0, 0, 0), (x, 0, sz), (x, -sy, sz)])
+ myfaces.extend([(0, 1, 2, 3)])
+
+ myvertex.extend([(x + gap, -sy + gap, 0), (x + gap, 0, 0), (x + gap, 0, sz),
+ (x + gap, -sy + gap, sz)])
+ myfaces.extend([(4, 5, 6, 7)])
+
+ # Right side
+ x = sx - gap
+ myvertex.extend([(x, -sy + gap, 0), (x, 0, 0), (x, 0, sz), (x, -sy + gap, sz)])
+ myfaces.extend([(8, 9, 10, 11)])
+
+ myvertex.extend([(x + gap, -sy, 0), (x + gap, 0, 0), (x + gap, 0, sz), (x + gap, -sy, sz)])
+ myfaces.extend([(12, 13, 14, 15)])
+
+ myfaces.extend(
+ [(0, 12, 15, 3), (4, 8, 11, 7), (3, 15, 11, 7), (0, 12, 8, 4), (0, 1, 5, 4),
+ (8, 9, 13, 12), (3, 2, 6, 7),
+ (11, 10, 14, 15), (1, 2, 6, 5), (9, 10, 14, 13)])
+
+ # Top inside
+ myvertex.extend([(gap, -sy + gap, sz - gap), (gap, -gap, sz - gap), (sx - gap, -gap, sz - gap),
+ (sx - gap, -sy + gap, sz - gap)])
+ myfaces.extend([(16, 17, 18, 19)])
+
+ # bottom inside and front face
+ myvertex.extend([(gap, -sy + gap, gap), (gap, -gap, gap), (sx - gap, -gap, gap), (sx - gap, -sy + gap, gap)])
+ myfaces.extend([(20, 21, 22, 23), (17, 18, 22, 21)])
+
+ mymesh = bpy.data.meshes.new(objname)
+ mybook = bpy.data.objects.new(objname, mymesh)
+
+ mybook.location[0] = px
+ mybook.location[1] = py
+ mybook.location[2] = pz + math.sin(math.radians(rot)) * sx
+ bpy.context.scene.objects.link(mybook)
+
+ mymesh.from_pydata(myvertex, [], myfaces)
+ mymesh.update(calc_edges=True)
+
+ # ---------------------------------
+ # Materials and UV Maps
+ # ---------------------------------
+ if mat:
+ rgb = objcol
+ # External
+ mat = create_diffuse_material(objname + "_material", True,
+ rgb[0], rgb[1], rgb[2], rgb[0], rgb[1], rgb[2], 0.05)
+ set_material(mybook, mat)
+ # UV unwrap external
+ select_faces(mybook, 0, True)
+ select_faces(mybook, 3, False)
+ select_faces(mybook, 4, False)
+ unwrap_mesh(mybook, False)
+ # Add Internal
+ mat = create_diffuse_material(objname + "_side_material", True, 0.5, 0.5, 0.5, 0.5, 0.5, 0.3, 0.03)
+ mybook.data.materials.append(mat)
+ select_faces(mybook, 14, True)
+ select_faces(mybook, 15, False)
+ select_faces(mybook, 16, False)
+ set_material_faces(mybook, 1)
+ # UV unwrap
+ bpy.ops.object.mode_set(mode='EDIT', toggle=False)
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+ select_faces(mybook, 14, True)
+ select_faces(mybook, 15, False)
+ select_faces(mybook, 16, False)
+ unwrap_mesh(mybook, False)
+
+ # ---------------------------------
+ # Rotation on Y axis
+ # ---------------------------------
+ mybook.rotation_euler = (0.0, math.radians(rot), 0.0) # radians
+
+ # add some gap to the size between books
+ return mybook, (sx, sy, sz, rot)