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 os import bpy
import product_gen.generate_lamp_base import product_gen.generate_lamp_base
import product_gen.generate_shades 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): is_final=False):
thickness = 3.0
prefix = os.getcwd() + "/" + output_prefix + "/" + output_prefix 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": 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": 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": 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 models = {shade.name: shade,
base_radius = 15.0 chord.name: chord,
thickness = 3.0 base.name: base}
base = product_gen.generate_lamp_base.generate_base(base_height,
base_radius,
thickness)
base.exportStl(prefix + "_temp_base.stl")
chord_height = 150.0 # Smooth shapes
chord_radius = 2.0 for eachModel in models.values():
thickness = 1.0 bpy.context.scene.objects.active = eachModel
chord = product_gen.generate_lamp_base.generate_chord(chord_height, for poly in bpy.context.object.data.polygons:
chord_radius, poly.use_smooth = True
thickness)
chord.exportStl(prefix + "_temp_chord.stl") # 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)}
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)
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)
else: else:
product_gen.render_lamp.render_lamp(prefix + "_temp_shade.stl", bpy.context.scene.render.filepath = prefix + ".png"
prefix + "_temp_base.stl", bpy.ops.render.render(write_still=True)
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)

Binary file not shown.

View file

@ -1,46 +1,52 @@
import bpy
from mathutils import Vector
import bmesh
import sys def NormalInDirection(normal, direction, limit = 0.99):
# freecad setup return abs(direction.dot( normal )) > limit
FREECADPATH = "/usr/lib/freecad/lib/"
sys.path.append(FREECADPATH)
import numpy as np
import FreeCAD
import Part
def generate_chord(height, radius, thickness): def UpOrDown(normal):
edge0 = Part.makeLine((0.0, height, 0), up = NormalInDirection(normal, Vector((0.0, 0.0, 1.0)), limit = 0.99)
(-radius, 0.0, 0)) down = NormalInDirection(normal, Vector((0.0, 0.0, -1.0)), limit = 0.99)
edge1 = Part.makeLine((-radius, 0.0, 0), if up or down:
(-radius -thickness, 0.0, 0)) return True
edge2 = Part.makeLine((-radius -thickness, 0.0, 0), return False
(-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) def generate_chord(depth, radius, location):
vec = FreeCAD.Vector(0.0, 1.0, 0.0)
angle = 360
solid = face.revolve(pos, vec, angle)
return solid
def generate_base(height, radius, thickness): bpy.ops.mesh.primitive_cylinder_add(radius=radius,
depth=depth,
location=location)
chord = bpy.data.objects["Cylinder"]
chord.name = "chord"
return chord
edge0 = Part.makeLine((0.0, 0.0, 0), def generate_cone_base(radius1, radius2, depth, location):
(-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,])
pos = FreeCAD.Vector(0.0, 0.0, 0.0) bpy.ops.mesh.primitive_cone_add(radius1=radius1,
vec = FreeCAD.Vector(0.0, 1.0, 0.0) radius2=radius2,
angle = 360 depth=depth,
solid = face.revolve(pos, vec, angle) location=location)
return solid 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)
# 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 def NormalInDirection(normal, direction, limit = 0.99):
# freecad setup return abs(direction.dot( normal )) > limit
FREECADPATH = "/usr/lib/freecad/lib/"
sys.path.append(FREECADPATH)
import numpy as np
import FreeCAD
import Part
def generate_cone_shade(height, radius, thickness): def UpOrDown(normal):
edge0 = Part.makeLine((0.0, 0.0, 0), up = NormalInDirection(normal, Vector((0.0, 0.0, 1.0)), limit = 0.99)
(-radius, -height, 0)) down = NormalInDirection(normal, Vector((0.0, 0.0, -1.0)), limit = 0.99)
edge1 = Part.makeLine((-radius, -height, 0), if up or down:
(-radius -thickness, -height, 0)) return True
edge2 = Part.makeLine((-radius -thickness, -height, 0), return False
(-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,])
pos = FreeCAD.Vector(0.0, 0.0, 0.0) def generate_cone_shade(radius1, radius2, depth):
vec = FreeCAD.Vector(0.0, 1.0, 0.0)
angle = 360
solid = face.revolve(pos, vec, angle)
return solid
def generate_mesh_shade(height, radius, thickness): 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)
edge0 = Part.makeLine((0.0, 0.0, 0), # Extrude faces
(-radius, -height, 0)) bpy.ops.mesh.select_mode( type = 'FACE' )
edge1 = Part.makeLine((-radius, -height, 0), bpy.ops.mesh.select_all( action = 'SELECT' )
(-radius -thickness, -height, 0)) bpy.ops.mesh.extrude_region_move(
edge2 = Part.makeLine((-radius -thickness, -height, 0), TRANSFORM_OT_translate={"value":(0, 0, 0.01)} )
(-thickness, 0.0, 0)) bpy.ops.mesh.extrude_region_shrink_fatten(
edge3 = Part.makeLine((-thickness, 0.0, 0), TRANSFORM_OT_shrink_fatten={"value":-0.05})
(0.0, 0.0, 0)) bpy.ops.object.mode_set(mode='OBJECT')
wire1 = Part.Wire([edge0, edge1, edge2, edge3]) return cone
face = Part.Face([wire1,])
pos = FreeCAD.Vector(0.0, 0.0, 0.0) def generate_mesh_shade(radius1, radius2, depth):
vec = FreeCAD.Vector(0.0, 1.0, 0.0)
angle = 360
solid = face.revolve(pos, vec, angle)
return solid
def generate_bio_shade(height, radius, thickness): 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
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
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,])
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

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__": 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'] shape = shape_params['shape']
output = shape_params['output'] 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 os
import ast
import sys import sys
import random import random
import json import json
@ -8,7 +9,9 @@ from argparse import ArgumentParser
if __name__ == "__main__": 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'] shape = shape_params['shape']
output = shape_params['output'] output = shape_params['output']
@ -17,6 +20,7 @@ if __name__ == "__main__":
height = float(shape_params["height"]) height = float(shape_params["height"])
radius = float(shape_params["radius"]) 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, product_gen.generate_lamp.generate(shape, height, radius,
color, output, is_final=True) color, output, is_final=True)

View file

@ -7,15 +7,17 @@ from argparse import ArgumentParser
if __name__ == "__main__": 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'] shape = shape_params['shape']
output = shape_params['output'] output = shape_params['output']
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 = 100.0 + random.random()*150.0 height = 1.0 + random.random()*1.5
radius = 20.0 + random.random()*100.0 radius = 0.2 + random.random()*1.0
color = [18.0, 18.0, 18.0] color = [18.0, 18.0, 18.0]
product_gen.generate_lamp.generate(shape, height, radius, color, output) 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