-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 974cbcb
Showing
7 changed files
with
670 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
tmp* | ||
temp* | ||
*.gz | ||
backup/ | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,150 @@ | ||
import bpy, bmesh | ||
from math import radians, cos, sin | ||
from bpy_extras.view3d_utils import location_3d_to_region_2d | ||
from mathutils import Vector, Quaternion | ||
import numpy as np | ||
import os | ||
|
||
def purge_orphans(): | ||
bpy.ops.outliner.orphans_purge(do_local_ids=True, do_linked_ids=True, do_recursive=True) | ||
|
||
def clean_scene(): | ||
if bpy.context.active_object and bpy.context.active_object.mode == 'EDIT': | ||
bpy.ops.object.editmode_toggle() | ||
|
||
for obj in bpy.data.objects: | ||
obj.hide_set(False) | ||
obj.hide_select = False | ||
obj.hide_viewport = False | ||
|
||
bpy.ops.object.select_all(action='SELECT') | ||
bpy.ops.object.delete() | ||
|
||
collection_names = [col.name for col in bpy.data.collections] | ||
for name in collection_names: | ||
bpy.data.collections.remove(bpy.data.collections[name]) | ||
|
||
|
||
# Clear default nodes | ||
if bpy.context.scene.node_tree: | ||
try: | ||
nds = [n for n in bpy.context.scene.node_tree.nodes] | ||
for n in nds: | ||
bpy.context.scene.node_tree.nodes.remove(n) | ||
except: | ||
pass | ||
|
||
purge_orphans() | ||
purge_orphans() | ||
purge_orphans() | ||
|
||
def set_render_nodes(depth_scale=0.1): | ||
render = bpy.context.scene.render | ||
render.engine = 'BLENDER_EEVEE' | ||
render.image_settings.color_mode = 'RGBA' # ('RGB', 'RGBA', ...) | ||
render.image_settings.color_depth = '8' | ||
render.image_settings.file_format = 'PNG' | ||
render.resolution_x = 128 | ||
render.resolution_y = 128 | ||
render.resolution_percentage = 100 | ||
render.film_transparent = True | ||
|
||
scene = bpy.context.scene | ||
scene.use_nodes = True | ||
scene.view_layers["ViewLayer"].use_pass_z = True | ||
scene.view_layers["ViewLayer"].use_pass_normal = True | ||
scene.view_layers["ViewLayer"].use_pass_diffuse_color = True | ||
scene.view_layers["ViewLayer"].use_pass_object_index = True | ||
|
||
nodes = bpy.context.scene.node_tree.nodes | ||
links = bpy.context.scene.node_tree.links | ||
|
||
# Create input render layer node | ||
render_layers = nodes.new('CompositorNodeRLayers') | ||
|
||
# Create depth output nodes | ||
depth_file_output = nodes.new(type="CompositorNodeOutputFile") | ||
depth_file_output.label = 'Depth Output' | ||
depth_file_output.base_path = '' | ||
depth_file_output.file_slots[0].use_node_format = True | ||
depth_file_output.format.file_format = 'PNG' | ||
depth_file_output.format.color_depth = '8' | ||
depth_file_output.format.color_mode = "BW" | ||
|
||
# Remap as other types can not represent the full range of depth. | ||
map = nodes.new(type="CompositorNodeMapValue") | ||
# Size is chosen kind of arbitrarily, try out until you're satisfied with resulting depth map. | ||
map.offset = [-0.7] | ||
map.size = [depth_scale] | ||
map.use_min = True | ||
map.min = [0] | ||
|
||
links.new(render_layers.outputs['Depth'], map.inputs[0]) | ||
links.new(map.outputs[0], depth_file_output.inputs[0]) | ||
|
||
return (depth_file_output, ) | ||
|
||
def init_cam(): | ||
origin = bpy.data.objects.new("Empty", None) | ||
origin.location = (0, 0, 0) | ||
bpy.context.scene.collection.objects.link(origin) | ||
|
||
camera_data = bpy.data.cameras.new(name='Camera') | ||
cam = bpy.data.objects.new('Camera', camera_data) | ||
bpy.context.scene.collection.objects.link(cam) | ||
bpy.context.scene.camera = cam | ||
cam.data.lens = 35 | ||
cam.data.sensor_width = 32 | ||
|
||
cam_constraint = cam.constraints.new(type='TRACK_TO') | ||
cam_constraint.track_axis = 'TRACK_NEGATIVE_Z' | ||
cam_constraint.up_axis = 'UP_Y' | ||
cam_constraint.target = origin | ||
|
||
def set_cam_on_sphere(elevation_angle, rotation_angle, cam_dist=5): | ||
rele = radians(elevation_angle) | ||
rrot = radians(rotation_angle) | ||
|
||
cam_x = cam_dist * cos(rele) * cos(rrot) | ||
cam_y = cam_dist * cos(rele) * sin(rrot) | ||
cam_z = cam_dist * sin(rele) | ||
cam = bpy.context.scene.objects['Camera'] | ||
cam.location = (cam_x, cam_y, cam_z) | ||
print(cam_x, cam_y, cam_z) | ||
|
||
def add_cube(objname='Cube'): | ||
bm = bmesh.new() | ||
# Create an empty mesh and the object. | ||
mesh = bpy.data.meshes.new(objname+'_Mesh') | ||
basic_cube = bpy.data.objects.new(objname, mesh) | ||
|
||
# Construct the bmesh cube and assign it to the blender mesh. | ||
bm = bmesh.new() | ||
bmesh.ops.create_cube(bm, size=1.0) | ||
bm.to_mesh(mesh) | ||
bm.free() | ||
|
||
# Add the object into the scene. | ||
bpy.context.collection.objects.link(basic_cube) | ||
|
||
def add_sphere(objname='Sphere'): | ||
bm = bmesh.new() | ||
# Create an empty mesh and the object. | ||
mesh = bpy.data.meshes.new(objname+'_Mesh') | ||
basic_cube = bpy.data.objects.new(objname, mesh) | ||
|
||
# Construct the bmesh cube and assign it to the blender mesh. | ||
bm = bmesh.new() | ||
bmesh.ops.create_uvsphere(bm, u_segments=36, v_segments=12, radius=1) | ||
bm.to_mesh(mesh) | ||
bm.free() | ||
|
||
# Add the object into the scene. | ||
bpy.context.collection.objects.link(basic_cube) | ||
|
||
|
||
if __name__ == "__main__": | ||
clean_scene() | ||
init_cam() | ||
depth_file_output, = set_render_nodes() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
stepsize = 30 | ||
findex = 0 | ||
for ele in [30,]: #[-60, -30, 30, 60]: | ||
s = stepsize if abs(ele) < 45 else stepsize * 2 | ||
for rot in np.arange(0, 360, s): | ||
print(ele, rot) | ||
set_cam_on_sphere(ele, rot) | ||
render_file_path = fp + f'_{findex:03d}' | ||
findex += 1 | ||
bpy.context.scene.render.filepath = render_file_path | ||
depth_file_output.file_slots[0].path = render_file_path + "_depth" | ||
# normal_file_output.file_slots[0].path = render_file_path + "_normal" | ||
# albedo_file_output.file_slots[0].path = render_file_path + "_albedo" | ||
# id_file_output.file_slots[0].path = render_file_path + "_id" | ||
|
||
bpy.ops.render.render(write_still=True) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
* | ||
!.gitignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import numpy as np | ||
from inter import gen_bl_code | ||
import os | ||
import subprocess | ||
from argparse import ArgumentParser | ||
|
||
def gen_script_1(rng): | ||
template_1 = \ | ||
"""ADD CUBE | ||
SELECT FACE LOCATION {sele_face_dir} {sele_portion} | ||
RESIZE ALL {resize_pm} {resize_val} | ||
DELETE | ||
MOD_SOLIDIFY {solidify_val} | ||
""" | ||
sele_face_dir = rng.choice(["UP", "DOWN", "LEFT", "RIGHT", "Y+", "Y-"]) | ||
sele_portion = rng.choice([1, 2, 3]) | ||
resize_pm = rng.choice(["+", "-"]) | ||
resize_val = rng.choice([0, 1, 2, 3, 4, 5]) | ||
solidify_val = rng.choice([1, 2, 3, 4, 5, 6, 7, 8]) | ||
|
||
script = template_1.format( | ||
sele_face_dir=sele_face_dir, | ||
sele_portion=sele_portion, | ||
resize_pm=resize_pm, | ||
resize_val=resize_val, | ||
solidify_val=solidify_val) | ||
return script | ||
|
||
def gen_script_2(): | ||
return "" | ||
|
||
if __name__ == "__main__": | ||
parser = ArgumentParser() | ||
parser.add_argument("--blender-bin", type=str, | ||
default="/Applications/Blender.app/Contents/MacOS/blender") | ||
parser.add_argument("--output-dir", type=str, | ||
default="./data/tmp/") | ||
parser.add_argument("--object-num", type=int, | ||
default=10) | ||
|
||
args = parser.parse_args() | ||
rng = np.random.RandomState(42) | ||
|
||
output_dir = os.path.abspath(os.path.expanduser(args.output_dir)) | ||
if not os.path.exists(output_dir): | ||
os.makedirs(output_dir) | ||
|
||
with open("HEAD.pytemplate", "r") as f: | ||
header_str = f.read() | ||
with open("OUTPUT.pytemplate", "r") as f: | ||
out_str = f.read() | ||
|
||
for i in range(args.object_num): | ||
odir_ = os.path.join(output_dir, f"object{i:03d}") | ||
if not os.path.exists(odir_): | ||
os.makedirs(odir_) | ||
opath = os.path.join(odir_, "a") | ||
|
||
rng = np.random.RandomState(i) | ||
script = gen_script_1(rng) | ||
code_str = gen_bl_code(script) | ||
print(script) | ||
script_str = ' """\n' + script + '"""\n' | ||
setoutdir = f" fp = '{opath}'\n" | ||
with open(opath+"_script.spt", "w") as f: | ||
f.write(script) | ||
|
||
program = header_str + script_str + code_str + setoutdir + out_str | ||
|
||
with open("temp.py", "w") as f: | ||
f.write(program) | ||
|
||
subprocess.run([args.blender_bin, "-b", "-P", "temp.py"]) |
Oops, something went wrong.