Compare commits
10 commits
d440ff4d8f
...
25f03af0e2
Author | SHA1 | Date | |
---|---|---|---|
|
25f03af0e2 | ||
|
7925c4b926 | ||
|
83d88728c5 | ||
|
911ea182b2 | ||
|
aac2496319 | ||
|
6a97bd6cf7 | ||
|
2604e3889a | ||
|
c4e4b090b6 | ||
|
7c154c2ef6 | ||
|
1c015a450d |
|
@ -6,18 +6,20 @@ import product_gen.generate_shades as gs
|
||||||
def generate_models(shape_parameters):
|
def generate_models(shape_parameters):
|
||||||
|
|
||||||
# Shade
|
# Shade
|
||||||
|
print(shape_parameters["shape"])
|
||||||
if shape_parameters["shape"] == "mesh":
|
if shape_parameters["shape"] == "mesh":
|
||||||
shade = gs.generate_mesh_shade(shape_parameters)
|
shade = gs.generate_mesh_shade(shape_parameters)
|
||||||
elif shape_parameters["shape"] == "led":
|
elif shape_parameters["shape"] == "led" or shape_parameters["shape"] == "bio":
|
||||||
shade = gs.generate_led_shade(shape_parameters)
|
shade = gs.generate_led_shade(shape_parameters)
|
||||||
else: # default pendant
|
else: # default pendant
|
||||||
|
print("doing pendant")
|
||||||
shade = gs.generate_pendant_shade(shape_parameters)
|
shade = gs.generate_pendant_shade(shape_parameters)
|
||||||
|
|
||||||
# Base
|
# Base
|
||||||
if "bio" not in shape_parameters["shape"]:
|
if "bio" not in shape_parameters["shape"]:
|
||||||
radius1 = 0.3
|
radius1 = shape_parameters["fixture_radius"]
|
||||||
radius2 = 0.07
|
radius2 = 0.07
|
||||||
depth = 0.5
|
depth = shape_parameters["fixture_length"]
|
||||||
location = (0.0, 0.0, depth/2.0)
|
location = (0.0, 0.0, depth/2.0)
|
||||||
base = product_gen.generate_lamp_base.generate_cone_base(radius1,
|
base = product_gen.generate_lamp_base.generate_cone_base(radius1,
|
||||||
radius2,
|
radius2,
|
||||||
|
@ -25,7 +27,7 @@ def generate_models(shape_parameters):
|
||||||
location)
|
location)
|
||||||
# Chord
|
# Chord
|
||||||
radius = 0.05
|
radius = 0.05
|
||||||
height = 6.0
|
height = 10.0
|
||||||
location = (0.0, 0.0, height/2.0)
|
location = (0.0, 0.0, height/2.0)
|
||||||
chord = product_gen.generate_lamp_base.generate_chord(height,
|
chord = product_gen.generate_lamp_base.generate_chord(height,
|
||||||
radius,
|
radius,
|
||||||
|
|
|
@ -4,10 +4,12 @@ import bpy
|
||||||
import product_gen.generate_lamp
|
import product_gen.generate_lamp
|
||||||
import rendering.setup_scene
|
import rendering.setup_scene
|
||||||
import rendering.setup_renderer
|
import rendering.setup_renderer
|
||||||
|
from shapes.shape_description import _styles
|
||||||
|
|
||||||
def generate(shape_parameters, output_prefix, is_final=False):
|
def generate(shape_parameters, output_prefix, is_final=False):
|
||||||
|
|
||||||
rendering.setup_renderer.setup_renderer(shape_parameters)
|
rendering.setup_renderer.setup_renderer(shape_parameters,
|
||||||
|
is_final)
|
||||||
|
|
||||||
rendering.setup_scene.initialize_scene(shape_parameters)
|
rendering.setup_scene.initialize_scene(shape_parameters)
|
||||||
|
|
||||||
|
@ -18,13 +20,13 @@ def generate(shape_parameters, output_prefix, is_final=False):
|
||||||
product_gen.generate_lamp.optimize_for_render(models)
|
product_gen.generate_lamp.optimize_for_render(models)
|
||||||
|
|
||||||
# Set up materials and textures
|
# Set up materials and textures
|
||||||
color = (0.1, 0.1, 0.1)
|
style = _styles[shape_parameters["style"]]
|
||||||
if "bio" not in shape_parameters["shape"]:
|
if "bio" not in shape_parameters["shape"]:
|
||||||
colormap = {"shade": color,
|
colormap = {"shade": style["shade"],
|
||||||
"base": (132.0/255.0, 64.0/255.0, 11.0/255.0),
|
"base": style["base"],
|
||||||
"chord": (5.0/255.0, 5.0/255.0, 5.0/255.0)}
|
"chord": style["chord"]}
|
||||||
else:
|
else:
|
||||||
colormap = {"shade": color}
|
colormap = {"shade": style["shade"]}
|
||||||
|
|
||||||
product_gen.generate_lamp.apply_textures(colormap, models)
|
product_gen.generate_lamp.apply_textures(colormap, models)
|
||||||
|
|
||||||
|
@ -33,15 +35,8 @@ def generate(shape_parameters, output_prefix, is_final=False):
|
||||||
# Do rendering
|
# Do rendering
|
||||||
prefix = os.getcwd() + "/" + output_prefix + "/" + output_prefix
|
prefix = os.getcwd() + "/" + output_prefix + "/" + output_prefix
|
||||||
if is_final:
|
if is_final:
|
||||||
bpy.context.scene.render.filepath = prefix + "_kitchen.png"
|
bpy.context.scene.render.filepath = prefix + "_highres.png"
|
||||||
bpy.ops.render.render(write_still=True)
|
bpy.ops.render.render(write_still=True)
|
||||||
|
|
||||||
bpy.context.scene.render.filepath = prefix + "_hall.png"
|
|
||||||
bpy.ops.render.render(write_still=True)
|
|
||||||
|
|
||||||
bpy.context.scene.render.filepath = prefix + "_landing.png"
|
|
||||||
bpy.ops.render.render(write_still=True)
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
bpy.context.scene.render.filepath = prefix + ".png"
|
bpy.context.scene.render.filepath = prefix + ".png"
|
||||||
bpy.ops.render.render(write_still=True)
|
bpy.ops.render.render(write_still=True)
|
||||||
|
|
|
@ -14,86 +14,57 @@ def UpOrDown(normal):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def morph_shape(x, L, H, morph_type="linear"):
|
||||||
|
|
||||||
|
y = H
|
||||||
|
if morph_type == "linear":
|
||||||
|
y = (x/L)*H
|
||||||
|
elif morph_type == "logistic":
|
||||||
|
k = 10.0
|
||||||
|
v = 1.0
|
||||||
|
y = H/(1.0 + math.exp(-k*(x-L/4.0))**v)
|
||||||
|
elif morph_type == "sinusoid":
|
||||||
|
y = math.sin((x/L)*math.pi/2.0)
|
||||||
|
elif morph_type == "hyperbolic_tan":
|
||||||
|
y = math.tanh((x/L)*math.pi/2.0)
|
||||||
|
elif morph_type == "circle":
|
||||||
|
y = math.sqrt(L*L-(L-x)**2)
|
||||||
|
return y
|
||||||
|
|
||||||
def generate_pendant_shade(shape_parameters):
|
def generate_pendant_shade(shape_parameters):
|
||||||
|
|
||||||
radius = shape_parameters["radius"]
|
radius = shape_parameters["radius"]
|
||||||
depth = shape_parameters["height"]
|
depth = shape_parameters["height"]
|
||||||
print(depth)
|
|
||||||
|
|
||||||
bpy.ops.mesh.primitive_cylinder_add(radius=radius,
|
bpy.ops.mesh.primitive_cylinder_add(radius=radius,
|
||||||
depth=depth)
|
depth=depth)
|
||||||
|
|
||||||
cone = bpy.data.objects["Cylinder"]
|
cone = bpy.data.objects["Cylinder"]
|
||||||
cone.name = "shade"
|
cone.name = "shade"
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
num_subdivisions = 3
|
num_subdivisions = 3
|
||||||
if len(shape_parameters["division_offsets"])>3:
|
|
||||||
num_subdivisions = 4
|
|
||||||
for idx in range(num_subdivisions):
|
for idx in range(num_subdivisions):
|
||||||
bpy.ops.mesh.subdivide()
|
bpy.ops.mesh.subdivide()
|
||||||
|
|
||||||
bm = bmesh.from_edit_mesh(cone.data)
|
bm = bmesh.from_edit_mesh(cone.data)
|
||||||
num_verts = len(bm.verts)
|
num_verts = len(bm.verts)
|
||||||
|
|
||||||
summed_offset = 0.0
|
|
||||||
for jdx in range(len(shape_parameters["division_offsets"])):
|
|
||||||
summed_offset += shape_parameters["division_offsets"][jdx]
|
|
||||||
|
|
||||||
for idx in range(num_verts):
|
for idx in range(num_verts):
|
||||||
bm.verts.ensure_lookup_table()
|
bm.verts.ensure_lookup_table()
|
||||||
vert = bm.verts[idx]
|
vert = bm.verts[idx]
|
||||||
theta = math.atan2(vert.co.x, vert.co.y)
|
|
||||||
vert.co.z = vert.co.z -depth/2.0
|
vert.co.z = vert.co.z -depth/2.0
|
||||||
|
theta = math.atan2(vert.co.x, vert.co.y)
|
||||||
|
|
||||||
delta = abs(vert.co.z)
|
if abs(vert.co.z)<shape_parameters["stem_length"]:
|
||||||
frac = delta/depth
|
rad = shape_parameters["fixture_radius"]
|
||||||
|
|
||||||
summed_offset = 0.0
|
|
||||||
prev_offset = 0.0
|
|
||||||
|
|
||||||
division_index = len(shape_parameters["division_offsets"])-1
|
|
||||||
for jdx in range(len(shape_parameters["division_offsets"])):
|
|
||||||
prev_offset = summed_offset
|
|
||||||
summed_offset += shape_parameters["division_offsets"][jdx]
|
|
||||||
if frac >=prev_offset and frac <= summed_offset:
|
|
||||||
division_index = jdx
|
|
||||||
current_offset = shape_parameters["division_offsets"][division_index]
|
|
||||||
division_type = shape_parameters["division_patterns"][division_index]
|
|
||||||
|
|
||||||
if division_index==0:
|
|
||||||
division_radius = shape_parameters["fixture_radius"]
|
|
||||||
previous_offset = 0.0
|
|
||||||
previous_radius = division_radius
|
|
||||||
else:
|
else:
|
||||||
division_radius = shape_parameters["radius"]*shape_parameters["division_radii"][division_index]
|
rad = morph_shape(abs(vert.co.z)-shape_parameters["stem_length"],
|
||||||
previous_offset = shape_parameters["division_offsets"][division_index-1]
|
depth-shape_parameters["stem_length"],
|
||||||
previous_radius = shape_parameters["radius"]*shape_parameters["division_radii"][division_index-1]
|
radius-shape_parameters["fixture_radius"],
|
||||||
if previous_radius< shape_parameters["fixture_radius"]:
|
morph_type=shape_parameters["division_pattern"])
|
||||||
previous_radius = shape_parameters["fixture_radius"]
|
rad += shape_parameters["fixture_radius"]
|
||||||
|
vert.co.x = rad*math.sin(theta)
|
||||||
if division_radius<previous_radius:
|
vert.co.y = rad*math.cos(theta)
|
||||||
division_radius = previous_radius
|
|
||||||
|
|
||||||
if division_type == "square":
|
|
||||||
mapped_rad = division_radius + (frac)**2
|
|
||||||
vert.co.x = mapped_rad*math.sin(theta)
|
|
||||||
vert.co.y = mapped_rad*math.cos(theta)
|
|
||||||
elif division_type == "sine":
|
|
||||||
mapped_rad = division_radius + math.sin(math.pi/2.0*frac)
|
|
||||||
vert.co.x = mapped_rad*math.sin(theta)
|
|
||||||
vert.co.y = mapped_rad*math.cos(theta)
|
|
||||||
elif division_type == "ramp":
|
|
||||||
mapped_rad = division_radius + frac
|
|
||||||
vert.co.x = mapped_rad*math.sin(theta)
|
|
||||||
vert.co.y = mapped_rad*math.cos(theta)
|
|
||||||
elif division_type == "inv_ramp":
|
|
||||||
mapped_rad = division_radius + frac
|
|
||||||
vert.co.x = mapped_rad*math.sin(theta)
|
|
||||||
vert.co.y = mapped_rad*math.cos(theta)
|
|
||||||
else: #straight
|
|
||||||
vert.co.x = division_radius*math.sin(theta)
|
|
||||||
vert.co.y = division_radius*math.cos(theta)
|
|
||||||
|
|
||||||
for face in bm.faces:
|
for face in bm.faces:
|
||||||
if UpOrDown(face.normal):
|
if UpOrDown(face.normal):
|
||||||
face.select = True
|
face.select = True
|
||||||
|
@ -113,57 +84,53 @@ def generate_pendant_shade(shape_parameters):
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
return cone
|
return cone
|
||||||
|
|
||||||
def generate_cone_shade(radius1, radius2, depth):
|
def generate_mesh_shade(shape_parameters):
|
||||||
|
|
||||||
bpy.ops.mesh.primitive_cone_add(radius1=radius1,
|
radius1 = shape_parameters["radius"]
|
||||||
radius2=radius2,
|
depth = shape_parameters["height"]
|
||||||
depth=depth)
|
radius2 = shape_parameters["fixture_radius"]
|
||||||
cone = bpy.data.objects["Cone"]
|
|
||||||
cone.name = "shade"
|
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
|
||||||
bm = bmesh.from_edit_mesh(cone.data)
|
|
||||||
for face in bm.faces:
|
|
||||||
if UpOrDown(face.normal):
|
|
||||||
face.select = True
|
|
||||||
else:
|
|
||||||
face.select = False
|
|
||||||
faces_select = [f for f in bm.faces if f.select]
|
|
||||||
bmesh.ops.delete(bm, geom=faces_select, context=3)
|
|
||||||
bmesh.update_edit_mesh(cone.data, True)
|
|
||||||
|
|
||||||
# Extrude faces
|
|
||||||
bpy.ops.mesh.select_mode( type = 'FACE' )
|
|
||||||
bpy.ops.mesh.select_all( action = 'SELECT' )
|
|
||||||
bpy.ops.mesh.extrude_region_move(
|
|
||||||
TRANSFORM_OT_translate={"value":(0, 0, 0.01)} )
|
|
||||||
bpy.ops.mesh.extrude_region_shrink_fatten(
|
|
||||||
TRANSFORM_OT_shrink_fatten={"value":-0.05})
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
|
||||||
return cone
|
|
||||||
|
|
||||||
def generate_mesh_shade(radius1, radius2, depth):
|
|
||||||
|
|
||||||
bpy.ops.mesh.primitive_cube_add(radius=radius1)
|
bpy.ops.mesh.primitive_cube_add(radius=radius1)
|
||||||
cube = bpy.data.objects["Cube"]
|
cube = bpy.data.objects["Cube"]
|
||||||
cube.name = "shade"
|
cube.name = "shade"
|
||||||
bpy.ops.object.mode_set(mode='EDIT')
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
for idx in range(3):
|
num_subdivisions = 4
|
||||||
|
for idx in range(num_subdivisions):
|
||||||
bpy.ops.mesh.subdivide()
|
bpy.ops.mesh.subdivide()
|
||||||
|
|
||||||
bm = bmesh.from_edit_mesh(cube.data)
|
bm = bmesh.from_edit_mesh(cube.data)
|
||||||
|
slat_thickness = 0.06
|
||||||
|
max_rad = 0.0
|
||||||
|
max_z = 0.0
|
||||||
|
min_z = 0.0
|
||||||
|
rad_min_z = 0.0
|
||||||
for i in range( len( bm.verts ) ):
|
for i in range( len( bm.verts ) ):
|
||||||
bm.verts.ensure_lookup_table()
|
bm.verts.ensure_lookup_table()
|
||||||
vert = bm.verts[i]
|
vert = bm.verts[i]
|
||||||
#theta = math.atan2(vert.co.x, vert.co.y)
|
|
||||||
vert.co.z = vert.co.z - radius1
|
vert.co.z = vert.co.z - radius1
|
||||||
vert.co.z = vert.co.z*2.0
|
vert.co.z *= depth/(2.0*radius1)
|
||||||
height = radius1*2.0
|
vert.co.y = vert.co.y*(slat_thickness/(2.0*radius1))
|
||||||
vert.co.y = vert.co.y*0.03
|
vert.co.x = vert.co.x*(slat_thickness/(2.0*radius1))
|
||||||
vert.co.x = vert.co.x*0.1 + radius1/2.0
|
|
||||||
theta = abs(vert.co.z/height)
|
if abs(vert.co.z)<shape_parameters["stem_length"]:
|
||||||
vert.co.x = vert.co.x + 2.0*radius1*math.sin(theta)
|
rad = shape_parameters["fixture_radius"]
|
||||||
vert.co.z = vert.co.z + 1.0*radius1
|
else:
|
||||||
|
rad = morph_shape(1.0*(abs(vert.co.z)-shape_parameters["stem_length"]),
|
||||||
|
depth-shape_parameters["stem_length"],
|
||||||
|
radius1-shape_parameters["fixture_radius"],
|
||||||
|
morph_type=shape_parameters["division_pattern"])
|
||||||
|
rad += shape_parameters["fixture_radius"]
|
||||||
|
vert.co.x += rad
|
||||||
|
if vert.co.x>max_rad:
|
||||||
|
max_rad = vert.co.x
|
||||||
|
max_z = vert.co.z
|
||||||
|
|
||||||
|
if vert.co.z<min_z:
|
||||||
|
min_z = vert.co.z
|
||||||
|
rad_min_z = vert.co.x
|
||||||
|
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
|
|
||||||
num_slats = 36
|
num_slats = 36
|
||||||
|
@ -177,9 +144,14 @@ def generate_mesh_shade(radius1, radius2, depth):
|
||||||
scene.update()
|
scene.update()
|
||||||
|
|
||||||
# Add torus
|
# Add torus
|
||||||
bpy.ops.mesh.primitive_torus_add(location=(0.0, 0.0, -2.6*radius1),
|
bpy.ops.mesh.primitive_torus_add(location=(0.0, 0.0, max_z),
|
||||||
major_radius=2.4*radius1,
|
major_radius=max_rad,
|
||||||
minor_radius=0.02)
|
minor_radius=0.02)
|
||||||
|
|
||||||
|
if (abs(min_z)-abs(max_z))>0.5:
|
||||||
|
bpy.ops.mesh.primitive_torus_add(location=(0.0, 0.0, min_z),
|
||||||
|
major_radius=rad_min_z,
|
||||||
|
minor_radius=0.02)
|
||||||
|
|
||||||
for ob in bpy.context.scene.objects:
|
for ob in bpy.context.scene.objects:
|
||||||
if ob.type == 'MESH':
|
if ob.type == 'MESH':
|
||||||
|
@ -218,8 +190,12 @@ def make_square_ring(radius, depth, thickness):
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode='OBJECT')
|
||||||
return bpy.data.objects["square_ring"]
|
return bpy.data.objects["square_ring"]
|
||||||
|
|
||||||
def generate_led_shade(radius1, radius2, depth):
|
def generate_led_shade(shape_parameters):
|
||||||
|
|
||||||
|
radius1 = shape_parameters["radius"]
|
||||||
|
depth = shape_parameters["height"]
|
||||||
|
radius2 = shape_parameters["fixture_radius"]
|
||||||
|
|
||||||
ring1 = make_square_ring(3.0*radius1, depth/10.0, 0.2)
|
ring1 = make_square_ring(3.0*radius1, depth/10.0, 0.2)
|
||||||
bpy.ops.transform.rotate(value=-math.pi/12.0, axis=(1.0,0.0,0.0))
|
bpy.ops.transform.rotate(value=-math.pi/12.0, axis=(1.0,0.0,0.0))
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,32 @@
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
def setup_renderer(shape_parameters, engine="CYCLES"):
|
def setup_renderer(shape_parameters, is_final=False, engine="CYCLES"):
|
||||||
|
|
||||||
# Set up and do the render
|
# Set up and do the render
|
||||||
this_scene = bpy.context.scene
|
this_scene = bpy.context.scene
|
||||||
if engine=="CYCLES":
|
if engine=="CYCLES":
|
||||||
this_scene.render.engine = 'CYCLES'
|
this_scene.render.engine = 'CYCLES'
|
||||||
this_scene.cycles.device = 'GPU'
|
this_scene.cycles.samples = 100.0
|
||||||
this_scene.cycles.samples = 12.0
|
|
||||||
this_scene.cycles.caustics_reflective = False
|
this_scene.cycles.caustics_reflective = False
|
||||||
this_scene.cycles.caustics_refractive = False
|
this_scene.cycles.caustics_refractive = False
|
||||||
this_scene.cycles.max_bounces = 0.0
|
this_scene.cycles.max_bounces = 0.0
|
||||||
this_scene.render.use_border = False
|
this_scene.render.use_border = False
|
||||||
|
this_scene.render.use_simplify = True
|
||||||
this_scene.render.border_max_y = 0.75
|
this_scene.render.border_max_y = 0.75
|
||||||
this_scene.render.border_min_y = 0.33
|
this_scene.render.border_min_y = 0.33
|
||||||
this_scene.render.border_min_x = 0.25
|
this_scene.render.border_min_x = 0.25
|
||||||
this_scene.render.border_max_x = 0.65
|
this_scene.render.border_max_x = 0.65
|
||||||
this_scene.render.resolution_x = 600.0
|
if is_final:
|
||||||
this_scene.render.resolution_y = 600.0
|
this_scene.render.resolution_x = 1200.0
|
||||||
|
this_scene.render.resolution_y = 1200.0
|
||||||
|
else:
|
||||||
|
this_scene.render.resolution_x = 600.0
|
||||||
|
this_scene.render.resolution_y = 600.0
|
||||||
this_scene.render.tile_x = 32
|
this_scene.render.tile_x = 32
|
||||||
this_scene.render.tile_y = 32
|
this_scene.render.tile_y = 32
|
||||||
this_scene.render.resolution_percentage = 50.0
|
|
||||||
|
if is_final:
|
||||||
|
this_scene.render.resolution_percentage = 70.0
|
||||||
|
else:
|
||||||
|
this_scene.render.resolution_percentage = 100.0
|
||||||
|
this_scene.render.image_settings.compression = 60.0
|
|
@ -11,37 +11,49 @@ def initialize_scene(shape_parameters):
|
||||||
def setup_scene(shape_parameters):
|
def setup_scene(shape_parameters):
|
||||||
|
|
||||||
# Set up world
|
# Set up world
|
||||||
bpy.context.scene.world.use_sky_paper = True
|
use_backwall = False
|
||||||
bpy.context.scene.world.horizon_color = (0.99, 0.8, 0.8)
|
if not use_backwall:
|
||||||
#bpy.context.scene.world.light_settings.use_environment_light = True
|
bpy.context.scene.world.use_sky_paper = True
|
||||||
|
bpy.context.scene.world.horizon_color = (1.0, 1.0, 1.0)
|
||||||
# Add back wall
|
#bpy.context.scene.world.light_settings.use_environment_light = True
|
||||||
bpy.ops.mesh.primitive_plane_add(radius=20, location=(-10.0, 0.0, 0.0))
|
|
||||||
bpy.ops.transform.rotate(value=math.pi/2.0, axis=(0.0,1.0,0.0))
|
|
||||||
bpy.data.objects["Plane"].name = "back_wall"
|
|
||||||
mat = bpy.data.materials.get("backwall-material")
|
|
||||||
if mat is None:
|
|
||||||
mat = bpy.data.materials.new("backwall-material")
|
|
||||||
mat.diffuse_color = (0.25, 0.25, 0.25)
|
|
||||||
mat.specular_color = (0.25, 0.25, 0.25)
|
|
||||||
mat.diffuse_intensity = 1.0
|
|
||||||
mat.specular_intensity = 1.0
|
|
||||||
bpy.context.scene.objects.active = bpy.data.objects["back_wall"]
|
|
||||||
if bpy.context.active_object.data.materials:
|
|
||||||
# assign to 1st material slot
|
|
||||||
bpy.context.active_object.data.materials[0] = mat
|
|
||||||
else:
|
else:
|
||||||
# no slots
|
|
||||||
bpy.context.active_object.data.materials.append(mat)
|
# Add back wall
|
||||||
|
bpy.ops.mesh.primitive_plane_add(radius=20, location=(-10.0, 0.0, 0.0))
|
||||||
|
bpy.ops.transform.rotate(value=math.pi/2.0, axis=(0.0,1.0,0.0))
|
||||||
|
bpy.data.objects["Plane"].name = "back_wall"
|
||||||
|
mat = bpy.data.materials.get("backwall-material")
|
||||||
|
if mat is None:
|
||||||
|
mat = bpy.data.materials.new("backwall-material")
|
||||||
|
mat.diffuse_color = (0.25, 0.25, 0.25)
|
||||||
|
mat.specular_color = (0.25, 0.25, 0.25)
|
||||||
|
mat.diffuse_intensity = 1.0
|
||||||
|
mat.specular_intensity = 1.0
|
||||||
|
bpy.context.scene.objects.active = bpy.data.objects["back_wall"]
|
||||||
|
if bpy.context.active_object.data.materials:
|
||||||
|
# assign to 1st material slot
|
||||||
|
bpy.context.active_object.data.materials[0] = mat
|
||||||
|
else:
|
||||||
|
# no slots
|
||||||
|
bpy.context.active_object.data.materials.append(mat)
|
||||||
|
|
||||||
# Set up cameras
|
# Set up cameras
|
||||||
bpy.data.objects["Camera"].location = (10.0, 0.0, -4)
|
radius = shape_parameters["radius"]
|
||||||
|
height = shape_parameters["height"]
|
||||||
|
xloc = 1.5 + (3.0*radius + height)/2.0
|
||||||
|
zloc = -0.4 - height
|
||||||
|
|
||||||
|
if shape_parameters["shape"] == "bio" or shape_parameters["shape"] == "led":
|
||||||
|
bpy.data.objects["Camera"].location = (13, 0.0000, -3.0)
|
||||||
|
else:
|
||||||
|
bpy.data.objects["Camera"].location = (xloc, 0.0000, zloc)
|
||||||
fov = 65.0
|
fov = 65.0
|
||||||
|
|
||||||
bpy.data.objects["Camera"].data.angle = fov*(math.pi/180.0)
|
bpy.data.objects["Camera"].data.angle = fov*(math.pi/180.0)
|
||||||
bpy.data.objects["Camera"].rotation_mode = 'XYZ'
|
bpy.data.objects["Camera"].rotation_mode = 'XYZ'
|
||||||
bpy.data.objects["Camera"].rotation_euler[0] = math.pi/2.0
|
bpy.data.objects["Camera"].rotation_euler[0] = 1.9326
|
||||||
bpy.data.objects["Camera"].rotation_euler[1] = 0.0
|
bpy.data.objects["Camera"].rotation_euler[1] = 0.0
|
||||||
bpy.data.objects["Camera"].rotation_euler[2] = math.pi/2.0
|
bpy.data.objects["Camera"].rotation_euler[2] = 1.5708
|
||||||
|
|
||||||
# Lamps
|
# Lamps
|
||||||
bpy.data.scenes['Scene'].objects.unlink(bpy.data.objects["Lamp"])
|
bpy.data.scenes['Scene'].objects.unlink(bpy.data.objects["Lamp"])
|
||||||
|
@ -69,9 +81,13 @@ def setup_scene(shape_parameters):
|
||||||
bpy.context.active_object.data.materials.append(mat)
|
bpy.context.active_object.data.materials.append(mat)
|
||||||
|
|
||||||
bpy.ops.mesh.primitive_plane_add(radius=5, location=(10.0, 10.0, -5.0))
|
bpy.ops.mesh.primitive_plane_add(radius=5, location=(10.0, 10.0, -5.0))
|
||||||
bpy.ops.transform.rotate(value=-math.pi/2.0, axis=(1.0,2.0,0.0))
|
#bpy.ops.transform.rotate(value=-math.pi/2.0, axis=(1.0,2.0,0.0))
|
||||||
bpy.ops.transform.rotate(value=-math.pi/4.0, axis=(0.0,0.0,1.0))
|
#bpy.ops.transform.rotate(value=-math.pi/4.0, axis=(0.0,0.0,1.0))
|
||||||
bpy.data.objects["Plane"].name = "fill_lamp"
|
bpy.data.objects["Plane"].name = "fill_lamp"
|
||||||
|
bpy.data.objects["fill_lamp"].location = (10.0, 10.0, -5.0)
|
||||||
|
bpy.data.objects["fill_lamp"].rotation_euler[0] = 0.6454
|
||||||
|
bpy.data.objects["fill_lamp"].rotation_euler[1] = 0.7169
|
||||||
|
bpy.data.objects["fill_lamp"].rotation_euler[2] = 0.0000
|
||||||
|
|
||||||
mat = bpy.data.materials.get("fill-material")
|
mat = bpy.data.materials.get("fill-material")
|
||||||
if mat is None:
|
if mat is None:
|
||||||
|
|
|
@ -2,39 +2,42 @@ import random
|
||||||
import copy
|
import copy
|
||||||
|
|
||||||
_shape_description = {"shape": "pendant",
|
_shape_description = {"shape": "pendant",
|
||||||
"division_patterns": [],
|
"division_pattern": "linear",
|
||||||
"division_offsets": [],
|
"division_param1": 1.0,
|
||||||
"division_radii": [],
|
"division_param2": 1.0,
|
||||||
"radius": 1.0,
|
"radius": 1.0,
|
||||||
"height": 1.0,
|
"height": 1.0,
|
||||||
"fixture_radius": 0.3,
|
"fixture_radius": 0.3,
|
||||||
"style": "dark"}
|
"fixture_length": 0.3,
|
||||||
|
"stem_length": 0.5,
|
||||||
|
"style": "initial"}
|
||||||
|
|
||||||
_styles = {"dark" : {"shade": (0.1, 0.1, 0.1),
|
_styles = { "dark" : {"shade": (0.68, 0.68, 0.6),
|
||||||
"chord": (0.05, 0.05, 0.05),
|
"chord": (5.0/255.0, 5.0/255.0, 5.0/255.0),
|
||||||
"base": (0.05, 0.05, 0.05),
|
"base": (132.0/255.0, 64.0/255.0, 11.0/255.0),
|
||||||
"use_wall": True,
|
"use_wall": True,
|
||||||
"wall": (0.9, 0.9, 0.9)},
|
"wall": (0.9, 0.9, 0.9)},
|
||||||
"billard": {"shade": (0.1, 0.1, 0.1),
|
"initial" : {"shade": (0.1, 0.1, 0.1),
|
||||||
"chord": (0.05, 0.05, 0.05),
|
"chord": (5.0/255.0, 5.0/255.0, 5.0/255.0),
|
||||||
"base": (0.05, 0.05, 0.05),
|
"base": (132.0/255.0, 64.0/255.0, 11.0/255.0),
|
||||||
"use_wall": True,
|
"use_wall": True,
|
||||||
"wall": (0.9, 0.9, 0.9)},
|
"wall": (0.9, 0.9, 0.9)},
|
||||||
"light": {"shade": (0.1, 0.1, 0.1),
|
"billard": {"shade": (0.033, 0.065, 0.376),
|
||||||
"chord": (0.05, 0.05, 0.05),
|
"chord": (5.0/255.0, 5.0/255.0, 5.0/255.0),
|
||||||
"base": (0.05, 0.05, 0.05),
|
"base": (132.0/255.0, 64.0/255.0, 11.0/255.0),
|
||||||
"use_wall": True,
|
"use_wall": True,
|
||||||
"wall": (0.9, 0.9, 0.9)},
|
"wall": (0.9, 0.9, 0.9)},
|
||||||
}
|
"light": {"shade": (0.019, 0.202, 0.032),
|
||||||
|
"chord": (5.0/255.0, 5.0/255.0, 5.0/255.0),
|
||||||
_division_types = ["straight",
|
"base": (132.0/255.0, 64.0/255.0, 11.0/255.0),
|
||||||
"square",
|
"use_wall": True,
|
||||||
"inv_square",
|
"wall": (0.9, 0.9, 0.9)}, }
|
||||||
"sine",
|
|
||||||
"inv_sine",
|
|
||||||
"ramp",
|
|
||||||
"inv_ramp"]
|
|
||||||
|
|
||||||
|
_division_types = ["linear",
|
||||||
|
"logistic",
|
||||||
|
"sinusoid",
|
||||||
|
"hyperbolic_tan",
|
||||||
|
"circle"]
|
||||||
|
|
||||||
def get_random_shape_description(shape, bbox, feature_min):
|
def get_random_shape_description(shape, bbox, feature_min):
|
||||||
|
|
||||||
|
@ -44,27 +47,11 @@ def get_random_shape_description(shape, bbox, feature_min):
|
||||||
|
|
||||||
shape_description = copy.deepcopy(_shape_description)
|
shape_description = copy.deepcopy(_shape_description)
|
||||||
shape_description["shape"] = shape
|
shape_description["shape"] = shape
|
||||||
|
|
||||||
max_divisions = 5
|
|
||||||
num_divisions = int(1 + random.random()*(max_divisions-1))
|
|
||||||
num_divisions = 4
|
|
||||||
|
|
||||||
remaining_offset = 1.0
|
|
||||||
feature_height = feature_min[1] + random.random()*(bbox[1]-feature_min[1])
|
|
||||||
feature_radius = feature_min[0] + random.random()*(bbox[0]-feature_min[0])
|
feature_radius = feature_min[0] + random.random()*(bbox[0]-feature_min[0])
|
||||||
|
feature_height = feature_min[1] + random.random()*(bbox[1]-feature_min[1])
|
||||||
|
|
||||||
shape_description["height"] = feature_height
|
shape_description["height"] = feature_height
|
||||||
shape_description["radius"] = feature_radius
|
shape_description["radius"] = feature_radius
|
||||||
|
shape_description["division_pattern"] = random.choice(_division_types)
|
||||||
min_radius_fraction = feature_min[0]/feature_radius
|
shape_description["style"] = "initial"
|
||||||
for idx in range(num_divisions):
|
|
||||||
shape_description["division_patterns"].append(random.choice(_division_types))
|
|
||||||
|
|
||||||
offset = 1.0/num_divisions
|
|
||||||
#offset = random.random()*remaining_offset
|
|
||||||
remaining_offset -= offset
|
|
||||||
shape_description["division_offsets"].append(offset)
|
|
||||||
radius_fraction = min_radius_fraction+random.random()*(1.0-min_radius_fraction)
|
|
||||||
shape_description["division_radii"].append(radius_fraction)
|
|
||||||
shape_description["style"] = random.choice(list(_styles.keys()))
|
|
||||||
shape_description["division_radii"].sort()
|
|
||||||
return shape_description
|
return shape_description
|
|
@ -1,8 +1,10 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
import ast
|
||||||
import random
|
import random
|
||||||
import json
|
import json
|
||||||
import product_gen.generate_product
|
import product_gen.generate_product
|
||||||
|
from shapes.shape_description import _styles
|
||||||
|
|
||||||
from argparse import ArgumentParser
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
|
@ -17,17 +19,20 @@ if __name__ == "__main__":
|
||||||
if not os.path.exists(os.getcwd() + "/" + output):
|
if not os.path.exists(os.getcwd() + "/" + output):
|
||||||
os.makedirs(os.getcwd() + "/" + output)
|
os.makedirs(os.getcwd() + "/" + output)
|
||||||
|
|
||||||
height = float(shape_params["height"])
|
shape_parameters = {}
|
||||||
radius = float(shape_params["radius"])
|
shape_parameters["shape"] = shape
|
||||||
|
shape_parameters["output"] = output
|
||||||
|
shape_parameters["height"] = float(shape_params["height"])
|
||||||
|
shape_parameters["radius"] = float(shape_params["radius"])
|
||||||
|
shape_parameters["fixture_radius"] = float(shape_params["fixture_radius"])
|
||||||
|
shape_parameters["fixture_length"] = float(shape_params["fixture_length"])
|
||||||
|
shape_parameters["stem_length"] = float(shape_params["stem_length"])
|
||||||
|
shape_parameters["style"] = random.choice(list(_styles.keys()))
|
||||||
|
shape_parameters["division_pattern"] = shape_params["division_pattern"]
|
||||||
|
shape_parameters["division_param1"] = float(shape_params["division_param1"])
|
||||||
|
shape_parameters["division_param2"] = float(shape_params["division_param2"])
|
||||||
|
|
||||||
colors = [(0.1, 0.1, 0.1),
|
product_gen.generate_product.generate(shape_parameters, output)
|
||||||
(0.68, 0.68, 0.68),
|
|
||||||
(0.033, 0.065, 0.376),
|
|
||||||
(0.019, 0.202, 0.032)]
|
|
||||||
color = random.choice(colors)
|
|
||||||
product_gen.generate_product.generate(shape, height, radius, color, output)
|
|
||||||
|
|
||||||
shape_parameters = shape_params
|
|
||||||
shape_parameters["color"] = color
|
|
||||||
with open(os.getcwd() + "/" + output + "/"+ output + '.json', 'w') as outfile:
|
with open(os.getcwd() + "/" + output + "/"+ output + '.json', 'w') as outfile:
|
||||||
json.dump(shape_parameters, outfile)
|
json.dump(shape_parameters, outfile)
|
||||||
|
|
|
@ -18,9 +18,17 @@ if __name__ == "__main__":
|
||||||
if not os.path.exists(os.getcwd() + "/" + output):
|
if not os.path.exists(os.getcwd() + "/" + output):
|
||||||
os.makedirs(os.getcwd() + "/" + output)
|
os.makedirs(os.getcwd() + "/" + output)
|
||||||
|
|
||||||
height = float(shape_params["height"])
|
shape_parameters = {}
|
||||||
radius = float(shape_params["radius"])
|
shape_parameters["shape"] = shape
|
||||||
color = ast.literal_eval(shape_params["color"])
|
shape_parameters["output"] = output
|
||||||
print(color[0])
|
shape_parameters["height"] = float(shape_params["height"])
|
||||||
product_gen.generate_product.generate(shape, height, radius,
|
shape_parameters["radius"] = float(shape_params["radius"])
|
||||||
color, output, is_final=True)
|
shape_parameters["fixture_radius"] = float(shape_params["fixture_radius"])
|
||||||
|
shape_parameters["fixture_length"] = float(shape_params["fixture_length"])
|
||||||
|
shape_parameters["stem_length"] = float(shape_params["stem_length"])
|
||||||
|
shape_parameters["style"] = shape_params["style"]
|
||||||
|
shape_parameters["division_pattern"] = shape_params["division_pattern"]
|
||||||
|
shape_parameters["division_param1"] = float(shape_params["division_param1"])
|
||||||
|
shape_parameters["division_param2"] = float(shape_params["division_param2"])
|
||||||
|
|
||||||
|
product_gen.generate_product.generate(shape_parameters, output, is_final=True)
|
||||||
|
|
|
@ -23,16 +23,18 @@ if __name__ == "__main__":
|
||||||
os.makedirs(os.getcwd() + "/" + output)
|
os.makedirs(os.getcwd() + "/" + output)
|
||||||
|
|
||||||
# Global bounding box
|
# Global bounding box
|
||||||
bbox_xmax = 4.0
|
bbox_xmax = 3.0
|
||||||
bbox_ymax = 5.0
|
bbox_ymax = 3.0
|
||||||
|
|
||||||
# Minimum feature sizes
|
# Minimum feature sizes
|
||||||
feature_xmin = 0.4
|
feature_xmin = 1.0
|
||||||
feature_ymin = 1.0
|
feature_ymin = 1.0
|
||||||
shape_parameters = sd.get_random_shape_description(shape,
|
shape_parameters = sd.get_random_shape_description(shape,
|
||||||
[bbox_xmax, bbox_ymax],
|
[bbox_xmax, bbox_ymax],
|
||||||
[feature_xmin, feature_ymin])
|
[feature_xmin, feature_ymin])
|
||||||
|
|
||||||
shape_parameters = product_gen.generate_product.generate(shape_parameters, output)
|
shape_parameters = product_gen.generate_product.generate(shape_parameters, output)
|
||||||
|
shape_parameters["output"] = output
|
||||||
|
|
||||||
with open(os.getcwd() + "/" + output + "/"+ output + '.json', 'w') as outfile:
|
with open(os.getcwd() + "/" + output + "/"+ output + '.json', 'w') as outfile:
|
||||||
json.dump(shape_parameters, outfile)
|
json.dump(shape_parameters, outfile)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{"fixture_radius": 0.3, "division_radii": [0.7366486532785445, 0.8362702452541098, 0.9661599163089211, 0.9867733391465805], "radius": 0.611924774203075, "division_patterns": ["inv_square", "inv_ramp", "sine", "inv_square"], "shape": "cone", "height": 3.7486713335143, "style": "light", "division_offsets": [0.25, 0.25, 0.25, 0.25]}
|
{"fixture_radius": 0.3, "output": "test456", "radius": 1.8287633826475211, "height": 3.910662786988026, "division_patterns": ["ramp", "sine", "sine", "inv_sine"], "division_radii": [0.4473225094039008, 0.5963619022128677, 0.7765883654637191, 0.889395569488088], "division_offsets": [0.25, 0.25, 0.25, 0.25], "style": "billard", "shape": "bio"}
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 120 KiB |
BIN
src/utility/test456/test456_hall.png
Normal file
After Width: | Height: | Size: 123 KiB |
BIN
src/utility/test456/test456_kitchen.png
Normal file
After Width: | Height: | Size: 123 KiB |
BIN
src/utility/test456/test456_landing.png
Normal file
After Width: | Height: | Size: 123 KiB |
BIN
src/utility/test789/test789.blend
Normal file
BIN
src/utility/test789/test789.blend1
Normal file
1
src/utility/test789/test789.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"division_param2": 1.0, "radius": 1.8509219558134604, "stem_length": 0.5, "division_param1": 1.0, "division_pattern": "hyperbolic_tan", "output": "test789", "shape": "bio", "style": "dark", "height": 1.3296018884322776, "fixture_radius": 0.3, "fixture_length": 0.3}
|
BIN
src/utility/test789/test789.png
Normal file
After Width: | Height: | Size: 15 KiB |
BIN
src/utility/test789/test789.png0001.png
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
src/utility/test789/test789.png0002.png
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
src/utility/test789/test789.png0003.png
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
src/utility/test789/test789.png0004.png
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
src/utility/test789/test789.png0005.png
Normal file
After Width: | Height: | Size: 122 KiB |
BIN
src/utility/test91011/test91011.blend
Normal file
BIN
src/utility/test91011/test91011.blend1
Normal file
1
src/utility/test91011/test91011.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"stem_length": 0.5, "division_param1": 1.0, "fixture_length": 0.3, "output": "test91011", "height": 2.3703425509577607, "division_pattern": "sinusoid", "division_param2": 1.0, "style": "light", "shape": "cone", "radius": 1.1040660329988414, "fixture_radius": 0.3}
|
BIN
src/utility/test91011/test91011.png
Normal file
After Width: | Height: | Size: 71 KiB |
42
test/lamp_shape_generation.py
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
|
||||||
|
height = 3
|
||||||
|
radius = 2
|
||||||
|
base_radius = 0.5
|
||||||
|
base_length = 0.3
|
||||||
|
|
||||||
|
def morph_shape(x, L, H, morph_type="linear"):
|
||||||
|
|
||||||
|
y = np.ones(x.shape[0])
|
||||||
|
if morph_type == "linear":
|
||||||
|
y = (x/L)*H
|
||||||
|
elif morph_type == "logistic":
|
||||||
|
k = 10.0
|
||||||
|
v = 1.0
|
||||||
|
y = H/(1.0 + np.power(np.exp(-k*(x-L/4.0)), v))
|
||||||
|
elif morph_type == "sinusoid":
|
||||||
|
y = np.sin((x/L)*np.pi/2.0)
|
||||||
|
elif morph_type == "hyperbolic_tan":
|
||||||
|
y = np.tanh((x/L)*np.pi/2.0)
|
||||||
|
elif morph_type == "circle":
|
||||||
|
y = np.sqrt(L*L-np.power((L-x),2))
|
||||||
|
return y
|
||||||
|
|
||||||
|
x_base = np.linspace(0, base_length, 10)
|
||||||
|
y_base = base_radius*np.ones(x_base.shape[0])
|
||||||
|
|
||||||
|
x_lamp = np.linspace(base_length, height, 100)
|
||||||
|
y_lamp = base_radius + morph_shape(x_lamp-base_length,
|
||||||
|
height-base_length,
|
||||||
|
radius-base_radius,
|
||||||
|
"circle")
|
||||||
|
x = np.append(x_base, x_lamp)
|
||||||
|
y = np.append(y_base, y_lamp)
|
||||||
|
plt.plot(x, y)
|
||||||
|
|
||||||
|
axes = plt.gca()
|
||||||
|
axes.set_xlim([0, 1.1*base_length+height])
|
||||||
|
axes.set_ylim([0,1.1*radius])
|
||||||
|
plt.axis('equal')
|
||||||
|
plt.show()
|
|
@ -1 +1 @@
|
||||||
{"division_offsets": [0.25, 0.25, 0.25, 0.25], "radius": 0.5151794595751276, "height": 4.115548193330971, "division_patterns": ["inv_square", "inv_square", "square", "inv_sine"], "shape": "pendant", "style": "light", "division_radii": [0.9221841829622927, 0.9489520915432629, 0.9897309968469092, 0.994921834206689], "fixture_radius": 0.3}
|
{"shape": "pendant", "style": "billard", "division_offsets": [0.25, 0.25, 0.25, 0.25], "division_patterns": ["sine", "inv_square", "sine", "sine"], "fixture_radius": 0.3, "radius": 1.108292895591573, "height": 2.3656568205530943, "division_radii": [0.5013193491935374, 0.5714972928268524, 0.7183081060448532, 0.7995437239322076]}
|
Before Width: | Height: | Size: 118 KiB After Width: | Height: | Size: 120 KiB |