Fix bio domination bug.

This commit is contained in:
jmsgrogan 2017-10-25 10:58:31 +01:00
parent 2604e3889a
commit 6a97bd6cf7
13 changed files with 64 additions and 134 deletions

View file

@ -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" or "bio": 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,

View file

@ -14,86 +14,56 @@ 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, radius-shape_parameters["fixture_radius"],
previous_radius = shape_parameters["radius"]*shape_parameters["division_radii"][division_index-1] morph_type=shape_parameters["division_pattern"])
if previous_radius< shape_parameters["fixture_radius"]: rad += shape_parameters["fixture_radius"]
previous_radius = shape_parameters["fixture_radius"] vert.co.x = rad*math.sin(theta)
vert.co.y = rad*math.cos(theta)
if division_radius<previous_radius:
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,34 +83,6 @@ 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):
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_mesh_shade(shape_parameters): def generate_mesh_shade(shape_parameters):
radius1 = shape_parameters["radius"] radius1 = shape_parameters["radius"]
@ -152,22 +94,26 @@ def generate_mesh_shade(shape_parameters):
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 = 3
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.05
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/2.0
vert.co.z = vert.co.z - radius1 vert.co.z *= (depth/radius)
vert.co.z = vert.co.z*2.0 vert.co.y = vert.co.y*(slat_thickness/radius)
height = radius1*2.0 vert.co.x = vert.co.x*(slat_thickness/radius)
vert.co.y = vert.co.y*0.03
vert.co.x = vert.co.x*0.1 + radius1/2.0 rad = morph_shape(abs(vert.co.z),
theta = abs(vert.co.z/height) depth,
vert.co.x = vert.co.x + 2.0*radius1*math.sin(theta) radius1,
vert.co.z = vert.co.z + 1.0*radius1 morph_type=shape_parameters["division_pattern"])
vert.co.x += rad
bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.mode_set(mode='OBJECT')
num_slats = 36 num_slats = 36

View file

@ -2,12 +2,14 @@ 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,
"fixture_length": 0.3,
"stem_length": 0.5,
"style": "dark"} "style": "dark"}
_styles = {"dark" : {"shade": (0.1, 0.1, 0.1), _styles = {"dark" : {"shade": (0.1, 0.1, 0.1),
@ -27,14 +29,11 @@ _styles = {"dark" : {"shade": (0.1, 0.1, 0.1),
"wall": (0.9, 0.9, 0.9)}, "wall": (0.9, 0.9, 0.9)},
} }
_division_types = ["straight", _division_types = ["linear",
"square", "logistic",
"inv_square", "sinusoid",
"sine", "hyperbolic_tan",
"inv_sine", "circle"]
"ramp",
"inv_ramp"]
def get_random_shape_description(shape, bbox, feature_min): def get_random_shape_description(shape, bbox, feature_min):
@ -44,27 +43,10 @@ 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_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])
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
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["style"] = random.choice(list(_styles.keys()))
shape_description["division_radii"].sort()
return shape_description return shape_description

View file

@ -23,12 +23,12 @@ 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 = 5.0
bbox_ymax = 5.0 bbox_ymax = 4.0
# Minimum feature sizes # Minimum feature sizes
feature_xmin = 0.4 feature_xmin = 2.0
feature_ymin = 1.0 feature_ymin = 0.5
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])

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1 @@
{"stem_length": 0.5, "shape": "cone", "height": 3.4934284030014817, "output": "test789", "fixture_radius": 0.3, "fixture_length": 0.3, "division_pattern": "sinusoid", "division_param1": 1.0, "style": "dark", "division_param2": 1.0, "radius": 4.155310289141864}

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

View file

@ -20,8 +20,7 @@ def morph_shape(x, L, H, morph_type="linear"):
elif morph_type == "hyperbolic_tan": elif morph_type == "hyperbolic_tan":
y = np.tanh((x/L)*np.pi/2.0) y = np.tanh((x/L)*np.pi/2.0)
elif morph_type == "circle": elif morph_type == "circle":
y = np.tanh((x/L)*np.pi/2.0) y = np.sqrt(L*L-np.power((L-x),2))
return y return y
x_base = np.linspace(0, base_length, 10) x_base = np.linspace(0, base_length, 10)
@ -31,7 +30,7 @@ x_lamp = np.linspace(base_length, height, 100)
y_lamp = base_radius + morph_shape(x_lamp-base_length, y_lamp = base_radius + morph_shape(x_lamp-base_length,
height-base_length, height-base_length,
radius-base_radius, radius-base_radius,
"hyperbolic_tan") "circle")
x = np.append(x_base, x_lamp) x = np.append(x_base, x_lamp)
y = np.append(y_base, y_lamp) y = np.append(y_base, y_lamp)
plt.plot(x, y) plt.plot(x, y)