Upgrade lighting setup and change to 600x600 px.
|
@ -8,26 +8,33 @@ def generate_models(shape, height, radius):
|
||||||
# Shade
|
# Shade
|
||||||
radius2 = 0.3
|
radius2 = 0.3
|
||||||
if shape == "cone":
|
if shape == "cone":
|
||||||
shade = product_gen.generate_shades.generate_cone_shade(radius,
|
shade = product_gen.generate_shades.generate_pendant_shade(radius,
|
||||||
radius2, height)
|
radius2,
|
||||||
|
height)
|
||||||
elif shape == "mesh":
|
elif shape == "mesh":
|
||||||
shade = product_gen.generate_shades.generate_mesh_shade(radius,
|
shade = product_gen.generate_shades.generate_mesh_shade(radius,
|
||||||
radius2, height)
|
radius2, height)
|
||||||
elif shape == "bio":
|
elif shape == "bio":
|
||||||
shade = product_gen.generate_shades.generate_bio_shade(radius,
|
shade = product_gen.generate_shades.generate_bio_shade(radius,
|
||||||
radius2, height)
|
radius2, height)
|
||||||
|
elif shape == "pendant":
|
||||||
|
shade = product_gen.generate_shades.generate_pendant_shade(radius,
|
||||||
|
radius2,
|
||||||
|
height)
|
||||||
|
|
||||||
|
|
||||||
# Base
|
# Base
|
||||||
radius1 = 0.3
|
radius1 = 0.3
|
||||||
radius2 = 0.2
|
radius2 = 0.2
|
||||||
depth = 0.2
|
depth = 0.2
|
||||||
location = (0.0, 0.0, 0.6*height)
|
location = (0.0, 0.0, height/2.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,
|
||||||
depth,
|
depth,
|
||||||
location)
|
location)
|
||||||
# Chord
|
# Chord
|
||||||
radius = 0.05
|
radius = 0.05
|
||||||
height = 5.0
|
height = 6.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,
|
||||||
|
|
|
@ -11,6 +11,8 @@ def generate(shape,
|
||||||
output_prefix,
|
output_prefix,
|
||||||
is_final=False):
|
is_final=False):
|
||||||
|
|
||||||
|
rendering.setup_renderer.setup_renderer()
|
||||||
|
|
||||||
rendering.setup_scene.initialize_scene()
|
rendering.setup_scene.initialize_scene()
|
||||||
|
|
||||||
# Generate models
|
# Generate models
|
||||||
|
@ -27,7 +29,7 @@ def generate(shape,
|
||||||
|
|
||||||
rendering.setup_scene.setup_scene()
|
rendering.setup_scene.setup_scene()
|
||||||
|
|
||||||
rendering.setup_renderer.setup_renderer()
|
|
||||||
|
|
||||||
# Do rendering
|
# Do rendering
|
||||||
prefix = os.getcwd() + "/" + output_prefix + "/" + output_prefix
|
prefix = os.getcwd() + "/" + output_prefix + "/" + output_prefix
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import bpy
|
import bpy
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
import bmesh
|
import bmesh
|
||||||
|
import math
|
||||||
|
|
||||||
def NormalInDirection(normal, direction, limit = 0.99):
|
def NormalInDirection(normal, direction, limit = 0.99):
|
||||||
return abs(direction.dot( normal )) > limit
|
return abs(direction.dot( normal )) > limit
|
||||||
|
@ -13,6 +14,47 @@ def UpOrDown(normal):
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def generate_pendant_shade(radius1, radius2, depth):
|
||||||
|
|
||||||
|
bpy.ops.mesh.primitive_cylinder_add(radius=radius1,
|
||||||
|
depth=depth)
|
||||||
|
cone = bpy.data.objects["Cylinder"]
|
||||||
|
cone.name = "shade"
|
||||||
|
bpy.ops.object.mode_set(mode='EDIT')
|
||||||
|
|
||||||
|
for idx in range(3):
|
||||||
|
bpy.ops.mesh.subdivide()
|
||||||
|
|
||||||
|
bm = bmesh.from_edit_mesh(cone.data)
|
||||||
|
for i in range( len( bm.verts ) ):
|
||||||
|
bm.verts.ensure_lookup_table()
|
||||||
|
vert = bm.verts[i]
|
||||||
|
theta = math.atan2(vert.co.x, vert.co.y)
|
||||||
|
delta = abs(vert.co.z-depth/2.0)
|
||||||
|
|
||||||
|
mapped_rad = radius2 + delta**2
|
||||||
|
vert.co.x = mapped_rad*math.sin(theta)
|
||||||
|
vert.co.y = mapped_rad*math.cos(theta)
|
||||||
|
|
||||||
|
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_cone_shade(radius1, radius2, depth):
|
def generate_cone_shade(radius1, radius2, depth):
|
||||||
|
|
||||||
bpy.ops.mesh.primitive_cone_add(radius1=radius1,
|
bpy.ops.mesh.primitive_cone_add(radius1=radius1,
|
||||||
|
|
|
@ -5,14 +5,15 @@ def setup_renderer(engine="CYCLES"):
|
||||||
# Set up and do the render
|
# Set up and do the render
|
||||||
if engine=="CYCLES":
|
if engine=="CYCLES":
|
||||||
bpy.context.scene.render.engine = 'CYCLES'
|
bpy.context.scene.render.engine = 'CYCLES'
|
||||||
bpy.context.scene.cycles.samples = 30.0
|
bpy.context.scene.cycles.samples = 24.0
|
||||||
bpy.context.scene.cycles.caustics_reflective = False
|
bpy.context.scene.cycles.caustics_reflective = False
|
||||||
bpy.context.scene.cycles.caustics_refractive = False
|
bpy.context.scene.cycles.caustics_refractive = False
|
||||||
bpy.context.scene.cycles.max_bounces = 0.0
|
bpy.context.scene.cycles.max_bounces = 0.0
|
||||||
bpy.data.scenes["Scene"].render.use_border = True # Tell Blender to use border render
|
bpy.data.scenes["Scene"].render.use_border = False # Tell Blender to use border render
|
||||||
bpy.data.scenes["Scene"].render.border_max_y = 0.75 # Set the border top at 3/4 of the image's height
|
bpy.data.scenes["Scene"].render.border_max_y = 0.75 # Set the border top at 3/4 of the image's height
|
||||||
bpy.data.scenes["Scene"].render.border_min_y = 0.33 # Set the border bottom at 1/3 of the image's height
|
bpy.data.scenes["Scene"].render.border_min_y = 0.33 # Set the border bottom at 1/3 of the image's height
|
||||||
bpy.data.scenes["Scene"].render.border_min_x = 0.25 # Set the border left at 1/4 of the image's width
|
bpy.data.scenes["Scene"].render.border_min_x = 0.25 # Set the border left at 1/4 of the image's width
|
||||||
bpy.data.scenes["Scene"].render.border_max_x = 0.65 # Set the border right at the image's right border
|
bpy.data.scenes["Scene"].render.border_max_x = 0.65 # Set the border right at the image's right border
|
||||||
bpy.context.scene.render.resolution_x = 600.0
|
bpy.context.scene.render.resolution_x = 600.0
|
||||||
|
bpy.context.scene.render.resolution_y = 600.0
|
||||||
bpy.context.scene.render.resolution_percentage = 100.0
|
bpy.context.scene.render.resolution_percentage = 100.0
|
|
@ -1,3 +1,4 @@
|
||||||
|
import math
|
||||||
import bpy
|
import bpy
|
||||||
|
|
||||||
def initialize_scene():
|
def initialize_scene():
|
||||||
|
@ -11,11 +12,76 @@ def setup_scene():
|
||||||
|
|
||||||
# Set up world
|
# Set up world
|
||||||
bpy.context.scene.world.use_sky_paper = True
|
bpy.context.scene.world.use_sky_paper = True
|
||||||
bpy.context.scene.world.horizon_color = (0.95, 0.95, 0.95)
|
bpy.context.scene.world.horizon_color = (0.58, 0.58, 0.58)
|
||||||
#bpy.context.scene.world.light_settings.use_environment_light = True
|
#bpy.context.scene.world.light_settings.use_environment_light = True
|
||||||
|
|
||||||
# Set up lamps and cameras
|
# Add back wall
|
||||||
bpy.data.objects["Lamp"].location = bpy.data.objects["Camera"].location
|
bpy.ops.mesh.primitive_plane_add(radius=20, location=(-10.0, 0.0, 0.0))
|
||||||
bpy.data.objects["Lamp"].delta_location = (-3, 0, -3)
|
bpy.ops.transform.rotate(value=math.pi/2.0, axis=(0.0,1.0,0.0))
|
||||||
#bpy.data.objects["Lamp"].type = "POINT"
|
bpy.data.objects["Plane"].name = "back_wall"
|
||||||
bpy.data.objects["Lamp"].name = "front"
|
mat = bpy.data.materials.get("backwall-material")
|
||||||
|
if mat is None:
|
||||||
|
mat = bpy.data.materials.new("backwall-material")
|
||||||
|
mat.diffuse_color = (0.5, 0.5, 0.5)
|
||||||
|
mat.specular_color = (0.5, 0.5, 0.5)
|
||||||
|
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
|
||||||
|
bpy.data.objects["Camera"].location = (10.0, 0.0, -1)
|
||||||
|
fov = 65.0
|
||||||
|
bpy.data.objects["Camera"].data.angle = fov*(math.pi/180.0)
|
||||||
|
bpy.data.objects["Camera"].rotation_mode = 'XYZ'
|
||||||
|
bpy.data.objects["Camera"].rotation_euler[0] = math.pi/2.0
|
||||||
|
bpy.data.objects["Camera"].rotation_euler[1] = 0.0
|
||||||
|
bpy.data.objects["Camera"].rotation_euler[2] = math.pi/2.0
|
||||||
|
|
||||||
|
# Lamps
|
||||||
|
bpy.data.scenes['Scene'].objects.unlink(bpy.data.objects["Lamp"])
|
||||||
|
bpy.data.objects.remove(bpy.data.objects["Lamp"])
|
||||||
|
|
||||||
|
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.data.objects["Plane"].name = "key_lamp"
|
||||||
|
mat = bpy.data.materials.get("key-material")
|
||||||
|
if mat is None:
|
||||||
|
mat = bpy.data.materials.new("key-material")
|
||||||
|
mat.use_nodes = True
|
||||||
|
mat.node_tree.nodes.new('ShaderNodeEmission')
|
||||||
|
inp = mat.node_tree.nodes["Material Output"].inputs["Surface"]
|
||||||
|
outp = mat.node_tree.nodes["Emission"].outputs["Emission"]
|
||||||
|
mat.node_tree.nodes['Emission'].inputs[1].default_value = 30.0
|
||||||
|
mat.node_tree.links.new(inp, outp)
|
||||||
|
|
||||||
|
bpy.context.scene.objects.active = bpy.data.objects["key_lamp"]
|
||||||
|
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)
|
||||||
|
|
||||||
|
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/4.0, axis=(0.0,0.0,1.0))
|
||||||
|
bpy.data.objects["Plane"].name = "fill_lamp"
|
||||||
|
|
||||||
|
mat = bpy.data.materials.get("fill-material")
|
||||||
|
if mat is None:
|
||||||
|
mat = bpy.data.materials.new("fill-material")
|
||||||
|
mat.emit = 12.0
|
||||||
|
bpy.context.scene.objects.active = bpy.data.objects["fill_lamp"]
|
||||||
|
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)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
{"color": [0.2536788765243849, 0.7557341205824731, 0.6786201102941254], "shape": "cone", "height": "1.0", "radius": "1.0", "output": "test456"}
|
|
Before Width: | Height: | Size: 57 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 31 KiB |
Before Width: | Height: | Size: 31 KiB |
|
@ -1 +0,0 @@
|
||||||
{"shape": "cone", "color": [0.1, 0.1, 0.1], "radius": 0.45673644354564086, "height": 1.5622128980241115}
|
|
Before Width: | Height: | Size: 38 KiB |
33819
test/base.stl
15171
test/chord.stl
BIN
test/lamp.png
Before Width: | Height: | Size: 26 KiB |
42107
test/shade.stl
BIN
test/test/test.blend
Normal file
BIN
test/test/test.blend1
Normal file
1
test/test/test.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{"shape": "pendant", "radius": 0.5, "height": 1.5, "color": [0.1, 0.1, 0.1]}
|
BIN
test/test/test.png
Normal file
After Width: | Height: | Size: 523 KiB |
|
@ -1,29 +1,27 @@
|
||||||
import os
|
import os
|
||||||
import product_gen.generate_lamp
|
import sys
|
||||||
import product_gen.render_lamp
|
import random
|
||||||
|
import json
|
||||||
|
import product_gen.generate_product
|
||||||
|
from argparse import ArgumentParser
|
||||||
|
|
||||||
height = 150.0
|
if __name__ == "__main__":
|
||||||
radius = 100.0
|
|
||||||
thickness = 3.0
|
|
||||||
shade = product_gen.generate_lamp.generate_shade(height, radius, thickness)
|
|
||||||
work_dir = os.getcwd()
|
|
||||||
shade.exportStl(work_dir + "/shade.stl")
|
|
||||||
|
|
||||||
height = 20.0
|
shape = "pendant"
|
||||||
radius = 15.0
|
output = "test"
|
||||||
thickness = 3.0
|
|
||||||
base = product_gen.generate_lamp.generate_base(height, radius, thickness)
|
|
||||||
base.exportStl(work_dir + "/base.stl")
|
|
||||||
|
|
||||||
height = 150.0
|
if not os.path.exists(os.getcwd() + "/" + output):
|
||||||
radius = 2.0
|
os.makedirs(os.getcwd() + "/" + output)
|
||||||
thickness = 1.0
|
|
||||||
chord = product_gen.generate_lamp.generate_chord(height, radius, thickness)
|
|
||||||
chord.exportStl(work_dir + "/chord.stl")
|
|
||||||
|
|
||||||
product_gen.render_lamp.render_lamp(work_dir + "/shade.stl",
|
height = 1.5
|
||||||
work_dir + "/base.stl",
|
radius = 0.5
|
||||||
work_dir + "/chord.stl",
|
color = [0.1, 0.1, 0.1]
|
||||||
work_dir + "/lamp.png",
|
|
||||||
color = [25.0, 128.0, 132.0])
|
|
||||||
|
|
||||||
|
product_gen.generate_product.generate(shape, height, radius, color, output)
|
||||||
|
|
||||||
|
shape_parameters = {"shape": shape,
|
||||||
|
"height": height,
|
||||||
|
"radius": radius,
|
||||||
|
"color": color}
|
||||||
|
with open(os.getcwd() + "/" + output + "/"+ output + '.json', 'w') as outfile:
|
||||||
|
json.dump(shape_parameters, outfile)
|
||||||
|
|