Switch all generation and rendering to blender.

This commit is contained in:
jmsgrogan 2017-10-23 12:49:23 +01:00
parent 57c2414e6b
commit ea74f4c7ab
38 changed files with 248 additions and 385933 deletions

Binary file not shown.

View file

@ -1,59 +1,111 @@
import os
import os
import bpy
import product_gen.generate_lamp_base
import product_gen.generate_shades
import product_gen.render_lamp
def generate(shape, height, radius, color, output_prefix,
def generate(shape,
height,
radius,
color,
output_prefix,
is_final=False):
thickness = 3.0
prefix = os.getcwd() + "/" + output_prefix + "/" + output_prefix
# Set up scene
objs = bpy.data.objects
objs.remove(objs["Cube"], True)
# Shade
radius2 = 0.3
if shape == "cone":
shade = product_gen.generate_shades.generate_cone_shade(height, radius, thickness)
shade = product_gen.generate_shades.generate_cone_shade(radius,
radius2, height)
elif shape == "mesh":
shade = product_gen.generate_shades.generate_mesh_shade(height, radius, thickness)
shade = product_gen.generate_shades.generate_mesh_shade(radius,
radius2, height)
elif shape == "bio":
shade = product_gen.generate_shades.generate_bio_shade(height, radius, thickness)
shade = product_gen.generate_shades.generate_bio_shade(radius,
radius2, height)
shade.exportStl(prefix + "_temp_shade.stl")
# Base
radius1 = 0.3
radius2 = 0.2
depth = 0.2
location = (0.0, 0.0, 0.6*height)
base = product_gen.generate_lamp_base.generate_cone_base(radius1,
radius2,
depth,
location)
# Chord
radius = 0.05
height = 5.0
location = (0.0, 0.0, height/2.0)
chord = product_gen.generate_lamp_base.generate_chord(height,
radius,
location)
base_height = 20.0
base_radius = 15.0
thickness = 3.0
base = product_gen.generate_lamp_base.generate_base(base_height,
base_radius,
thickness)
base.exportStl(prefix + "_temp_base.stl")
models = {shade.name: shade,
chord.name: chord,
base.name: base}
chord_height = 150.0
chord_radius = 2.0
thickness = 1.0
chord = product_gen.generate_lamp_base.generate_chord(chord_height,
chord_radius,
thickness)
chord.exportStl(prefix + "_temp_chord.stl")
# Smooth shapes
for eachModel in models.values():
bpy.context.scene.objects.active = eachModel
for poly in bpy.context.object.data.polygons:
poly.use_smooth = True
# Set up materials and textures
# Get material
colormap = {"shade": color,
"base": (220.0/255.0, 220.0/255.0, 220.0/255.0),
"chord": (20.0/255.0, 20.0/255.0, 20.0/255.0)}
if not is_final:
product_gen.render_lamp.render_lamp(prefix + "_temp_shade.stl",
prefix + "_temp_base.stl",
prefix + "_temp_chord.stl",
prefix + ".png",
color = color)
for eachName in colormap.keys():
mat = bpy.data.materials.get(eachName + "-material")
if mat is None:
mat = bpy.data.materials.new(name=eachName + "-material")
mat.diffuse_color = colormap[eachName]
mat.specular_color = colormap[eachName]
mat.diffuse_intensity = 1.0
mat.specular_intensity = 1.0
if "shade" in eachName:
mat.emit = 0.0
mat.translucency = 10
mat.use_transparency = True
bpy.context.scene.objects.active = models[eachName]
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 world
bpy.context.scene.world.use_sky_paper = True
bpy.context.scene.world.horizon_color = (0.9, 0.9, 0.9)
#bpy.context.scene.world.light_settings.use_environment_light = True
# Set up lamps and cameras
objs["Lamp"].location = objs["Camera"].location
objs["Lamp"].delta_location = (-3, 0, -1)
# Set up and do the render
bpy.context.scene.render.resolution_x = 600.0
bpy.context.scene.render.resolution_percentage = 99.0
if is_final:
bpy.context.scene.render.filepath = prefix + "_kitchen.png"
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:
product_gen.render_lamp.render_lamp(prefix + "_temp_shade.stl",
prefix + "_temp_base.stl",
prefix + "_temp_chord.stl",
prefix + "_kitchen.png",
color = color)
product_gen.render_lamp.render_lamp(prefix + "_temp_shade.stl",
prefix + "_temp_base.stl",
prefix + "_temp_chord.stl",
prefix + "_hall.png",
color = color)
product_gen.render_lamp.render_lamp(prefix + "_temp_shade.stl",
prefix + "_temp_base.stl",
prefix + "_temp_chord.stl",
prefix + "_landing.png",
color = color)
bpy.context.scene.render.filepath = prefix + ".png"
bpy.ops.render.render(write_still=True)

Binary file not shown.

View file

@ -1,46 +1,52 @@
import bpy
from mathutils import Vector
import bmesh
import sys
# freecad setup
FREECADPATH = "/usr/lib/freecad/lib/"
sys.path.append(FREECADPATH)
import numpy as np
import FreeCAD
import Part
def NormalInDirection(normal, direction, limit = 0.99):
return abs(direction.dot( normal )) > limit
def generate_chord(height, radius, thickness):
def UpOrDown(normal):
edge0 = Part.makeLine((0.0, height, 0),
(-radius, 0.0, 0))
edge1 = Part.makeLine((-radius, 0.0, 0),
(-radius -thickness, 0.0, 0))
edge2 = Part.makeLine((-radius -thickness, 0.0, 0),
(-radius -thickness, height, 0))
edge3 = Part.makeLine((-radius -thickness, height, 0),
(0.0, height, 0))
wire1 = Part.Wire([edge0, edge1, edge2, edge3])
face = Part.Face([wire1,])
pos = FreeCAD.Vector(0.0, 0.0, 0.0)
vec = FreeCAD.Vector(0.0, 1.0, 0.0)
angle = 360
solid = face.revolve(pos, vec, angle)
return solid
up = NormalInDirection(normal, Vector((0.0, 0.0, 1.0)), limit = 0.99)
down = NormalInDirection(normal, Vector((0.0, 0.0, -1.0)), limit = 0.99)
if up or down:
return True
return False
def generate_base(height, radius, thickness):
def generate_chord(depth, radius, location):
edge0 = Part.makeLine((0.0, 0.0, 0),
(-radius, -height, 0))
edge1 = Part.makeLine((-radius, -height, 0),
(-radius -thickness, -height, 0))
edge2 = Part.makeLine((-radius -thickness, -height, 0),
(-thickness, 0.0, 0))
edge3 = Part.makeLine((-thickness, 0.0, 0),
(0.0, 0.0, 0))
wire1 = Part.Wire([edge0, edge1, edge2, edge3])
face = Part.Face([wire1,])
bpy.ops.mesh.primitive_cylinder_add(radius=radius,
depth=depth,
location=location)
chord = bpy.data.objects["Cylinder"]
chord.name = "chord"
return chord
def generate_cone_base(radius1, radius2, depth, location):
bpy.ops.mesh.primitive_cone_add(radius1=radius1,
radius2=radius2,
depth=depth,
location=location)
cone = bpy.data.objects["Cone"]
cone.name = "base"
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)
pos = FreeCAD.Vector(0.0, 0.0, 0.0)
vec = FreeCAD.Vector(0.0, 1.0, 0.0)
angle = 360
solid = face.revolve(pos, vec, angle)
return solid
# 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

View file

@ -1,65 +1,100 @@
import bpy
from mathutils import Vector
import bmesh
import sys
# freecad setup
FREECADPATH = "/usr/lib/freecad/lib/"
sys.path.append(FREECADPATH)
import numpy as np
import FreeCAD
import Part
def NormalInDirection(normal, direction, limit = 0.99):
return abs(direction.dot( normal )) > limit
def generate_cone_shade(height, radius, thickness):
edge0 = Part.makeLine((0.0, 0.0, 0),
(-radius, -height, 0))
edge1 = Part.makeLine((-radius, -height, 0),
(-radius -thickness, -height, 0))
edge2 = Part.makeLine((-radius -thickness, -height, 0),
(-thickness, 0.0, 0))
edge3 = Part.makeLine((-thickness, 0.0, 0),
(0.0, 0.0, 0))
wire1 = Part.Wire([edge0, edge1, edge2, edge3])
face = Part.Face([wire1,])
def UpOrDown(normal):
pos = FreeCAD.Vector(0.0, 0.0, 0.0)
vec = FreeCAD.Vector(0.0, 1.0, 0.0)
angle = 360
solid = face.revolve(pos, vec, angle)
return solid
up = NormalInDirection(normal, Vector((0.0, 0.0, 1.0)), limit = 0.99)
down = NormalInDirection(normal, Vector((0.0, 0.0, -1.0)), limit = 0.99)
if up or down:
return True
return False
def generate_mesh_shade(height, radius, thickness):
def generate_cone_shade(radius1, radius2, depth):
edge0 = Part.makeLine((0.0, 0.0, 0),
(-radius, -height, 0))
edge1 = Part.makeLine((-radius, -height, 0),
(-radius -thickness, -height, 0))
edge2 = Part.makeLine((-radius -thickness, -height, 0),
(-thickness, 0.0, 0))
edge3 = Part.makeLine((-thickness, 0.0, 0),
(0.0, 0.0, 0))
wire1 = Part.Wire([edge0, edge1, edge2, edge3])
face = Part.Face([wire1,])
bpy.ops.mesh.primitive_cone_add(radius1=radius1,
radius2=radius2,
depth=depth)
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)
pos = FreeCAD.Vector(0.0, 0.0, 0.0)
vec = FreeCAD.Vector(0.0, 1.0, 0.0)
angle = 360
solid = face.revolve(pos, vec, angle)
return solid
# 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_bio_shade(height, radius, thickness):
def generate_mesh_shade(radius1, radius2, depth):
edge0 = Part.makeLine((0.0, 0.0, 0),
(-radius, -height, 0))
edge1 = Part.makeLine((-radius, -height, 0),
(-radius -thickness, -height, 0))
edge2 = Part.makeLine((-radius -thickness, -height, 0),
(-thickness, 0.0, 0))
edge3 = Part.makeLine((-thickness, 0.0, 0),
(0.0, 0.0, 0))
wire1 = Part.Wire([edge0, edge1, edge2, edge3])
face = Part.Face([wire1,])
bpy.ops.mesh.primitive_cone_add(radius1=radius1,
radius2=radius2,
depth=depth)
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)
pos = FreeCAD.Vector(0.0, 0.0, 0.0)
vec = FreeCAD.Vector(0.0, 1.0, 0.0)
angle = 360
solid = face.revolve(pos, vec, angle)
return solid
# 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_bio_shade(radius1, radius2, depth):
bpy.ops.mesh.primitive_cone_add(radius1=radius1,
radius2=radius2,
depth=depth)
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

Binary file not shown.

View file

@ -1,109 +0,0 @@
import numpy as np
import vtk
def render_lamp(shade_file_path,
base_file_path,
chord_file_path,
image_file_path,
color):
# create a rendering window and renderer
ren = vtk.vtkRenderer()
ren.SetBackground(1.0, 1.0, 1.0)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
WIDTH=640*2
HEIGHT=480*2
renWin.SetSize(WIDTH,HEIGHT)
# create a renderwindowinteractor
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
# shade
reader = vtk.vtkSTLReader()
reader.SetFileName(shade_file_path)
reader.Update()
shade = reader.GetOutput()
shade_mapper = vtk.vtkPolyDataMapper()
shade_mapper.SetInputData(shade)
shade_actor = vtk.vtkActor()
shade_actor.SetMapper(shade_mapper)
shade_actor.GetProperty().SetColor(np.array(color)/255.0)
shade_actor.GetProperty().SetAmbient(0.3)
shade_actor.GetProperty().SetDiffuse(0.75)
shade_actor.GetProperty().SetSpecular(0.5)
shade_actor.GetProperty().SetOpacity(0.4)
# base
base_reader = vtk.vtkSTLReader()
base_reader.SetFileName(base_file_path)
base_reader.Update()
base = base_reader.GetOutput()
base_mapper = vtk.vtkPolyDataMapper()
base_mapper.SetInputData(base)
base_actor = vtk.vtkActor()
base_actor.SetMapper(base_mapper)
base_actor.GetProperty().SetColor(16.0/255.0, 17.0/255.0, 17.0/255.0)
#
# # chord
chord_reader = vtk.vtkSTLReader()
chord_reader.SetFileName(chord_file_path)
chord_reader.Update()
chord = chord_reader.GetOutput()
chord_mapper = vtk.vtkPolyDataMapper()
chord_mapper.SetInputData(chord)
chord_actor = vtk.vtkActor()
chord_actor.SetMapper(chord_mapper)
chord_actor.GetProperty().SetColor(16.0/255.0, 17.0/255.0, 17.0/255.0)
# Add a light
light = vtk.vtkLight()
light.SetPositional(True)
light.SetLightTypeToSceneLight()
light.SetFocalPoint(0.0,-100.0, 0.0)
light.SetIntensity(1.0)
lightActor = vtk.vtkLightActor()
lightActor.SetLight(light)
light.SetColor(0.0,0.0,0.0)
light.SetSwitch(1)
light.SetConeAngle(60)
ren.AddViewProp(lightActor)
cone = vtk.vtkConeSource()
cone.SetResolution(60)
cone.SetCenter(0.0,-150.0,0)
cone.SetHeight(20.0)
cone.SetRadius(20.0)
cone_mapper = vtk.vtkPolyDataMapper()
cone_mapper.SetInputConnection(cone.GetOutputPort())
cone_mapper.SetScalarVisibility(0)
cone_actor = vtk.vtkActor()
cone_actor.SetMapper(cone_mapper)
cone_actor.SetVisibility(1)
cone_actor.GetProperty().SetColor(1.0, 1.0, 1.0)
# assign actor to the renderer
ren.AddActor(shade_actor)
ren.AddActor(base_actor)
ren.AddActor(chord_actor)
#ren.AddActor(cone_actor)
# Do render and output
#iren.Initialize()
renWin.Modified()
renWin.Render()
ren.AddLight(light)
window_to_image = vtk.vtkWindowToImageFilter()
window_to_image.SetInput(renWin)
window_to_image.Update()
png_writer = vtk.vtkPNGWriter()
png_writer.SetFileName(image_file_path)
png_writer.SetInputData(window_to_image.GetOutput())
png_writer.Write()
#iren.Start()

View file

@ -8,7 +8,9 @@ from argparse import ArgumentParser
if __name__ == "__main__":
shape_params = json.loads(sys.argv[1])
argv = sys.argv
argv = argv[argv.index("--") + 1:]
shape_params = json.loads(argv[0])
shape = shape_params['shape']
output = shape_params['output']

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,5 @@
import os
import ast
import sys
import random
import json
@ -8,7 +9,9 @@ from argparse import ArgumentParser
if __name__ == "__main__":
shape_params = json.loads(sys.argv[1])
argv = sys.argv
argv = argv[argv.index("--") + 1:]
shape_params = json.loads(argv[0])
shape = shape_params['shape']
output = shape_params['output']
@ -17,6 +20,7 @@ if __name__ == "__main__":
height = float(shape_params["height"])
radius = float(shape_params["radius"])
color = shape_params["color"]
color = ast.literal_eval(shape_params["color"])
print(color[0])
product_gen.generate_lamp.generate(shape, height, radius,
color, output, is_final=True)

View file

@ -7,15 +7,17 @@ from argparse import ArgumentParser
if __name__ == "__main__":
shape_params = json.loads(sys.argv[1])
argv = sys.argv
argv = argv[argv.index("--") + 1:]
shape_params = json.loads(argv[0])
shape = shape_params['shape']
output = shape_params['output']
if not os.path.exists(os.getcwd() + "/" + output):
os.makedirs(os.getcwd() + "/" + output)
height = 100.0 + random.random()*150.0
radius = 20.0 + random.random()*100.0
height = 1.0 + random.random()*1.5
radius = 0.2 + random.random()*1.0
color = [18.0, 18.0, 18.0]
product_gen.generate_lamp.generate(shape, height, radius, color, output)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -1 +0,0 @@
{"color": [217.20423766974022, 233.50459158117596, 216.9490977511184], "output": "test123", "shape": "cone", "radius": "12.0", "height": "120"}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1 @@
{"output": "test456", "radius": "1.0", "color": [154.90465134747797, 85.00668266837187, 234.34599434969277], "height": "1.0", "shape": "cone"}

Binary file not shown.

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

File diff suppressed because it is too large Load diff