Spaces:
Runtime error
Runtime error
import gradio as gr | |
import base64 | |
from PIL import ImageColor | |
from pathlib import Path | |
import bpy | |
from tqdm import tqdm | |
from math import pi | |
import tempfile | |
def enable_GPUS(): | |
bpy.data.scenes[0].render.engine = "CYCLES" #"CYCLES" | |
# Set the device_type | |
bpy.context.preferences.addons[ | |
"cycles" | |
].preferences.compute_device_type = "CUDA" # or "OPENCL" | |
# Set the device and feature set | |
bpy.context.scene.cycles.device = "GPU" | |
for scene in bpy.data.scenes: | |
scene.cycles.device = "GPU" | |
bpy.context.preferences.addons["cycles"].preferences.get_devices() | |
print(bpy.context.preferences.addons["cycles"].preferences.compute_device_type) | |
for d in bpy.context.preferences.addons["cycles"].preferences.devices: | |
d["use"] = True # Using all devices, include GPU and CPU | |
print(d["name"]) | |
enable_GPUS() | |
# bpy.ops.wm.read_factory_settings(use_empty=True) | |
def generate( | |
color1, | |
color2, | |
camera_X, | |
camera_Y, | |
camera_Z, | |
fov, | |
torus_X, | |
torus_Y, | |
torus_Z, | |
progress=gr.Progress(track_tqdm=True), | |
): | |
rgb1 = ImageColor.getcolor(color1, "RGBA") | |
rgb1 = tuple(v / 255.0 for v in rgb1) | |
rgb2 = ImageColor.getcolor(color2, "RGBA") | |
rgb2 = tuple(v / 255.0 for v in rgb2) | |
# Delete all mesh objects from the scene | |
for obj in bpy.context.scene.objects: | |
# If the object is of MESH type | |
if obj.type == 'MESH': | |
# Delete the object | |
bpy.data.objects.remove(obj, do_unlink=True) | |
# Add a torus | |
bpy.ops.mesh.primitive_torus_add( | |
major_radius=1.5, | |
minor_radius=0.75, | |
major_segments=12*4, | |
minor_segments=12*4, | |
align="WORLD", | |
location=(0, 1, 1), | |
rotation=(torus_X,torus_Y,torus_Z) | |
) | |
# Assigning the torus to a variable | |
torus = bpy.context.view_layer.objects.active | |
# Create a new material and assign it to the torus | |
material = bpy.data.materials.new(name="RainbowGradient") | |
torus.data.materials.append(material) | |
material.use_nodes = True | |
nodes = material.node_tree.nodes | |
# Clear default nodes | |
for node in nodes: | |
nodes.remove(node) | |
# Add a Gradient Texture and set it to a color ramp of a rainbow | |
gradient = nodes.new(type="ShaderNodeTexGradient") | |
gradient.gradient_type = "LINEAR" | |
gradient.location = (0, 0) | |
ramp = nodes.new(type="ShaderNodeValToRGB") | |
ramp.color_ramp.interpolation = "LINEAR" | |
ramp.location = (200, 0) | |
ramp.color_ramp.elements[0].color = rgb1 | |
ramp.color_ramp.elements[1].color = rgb2 | |
# Add Shader nodes | |
bsdf = nodes.new(type="ShaderNodeBsdfPrincipled") | |
bsdf.location = (400, 0) | |
output = nodes.new(type="ShaderNodeOutputMaterial") | |
output.location = (600, 0) | |
# Connect the nodes | |
material.node_tree.links.new | |
material.node_tree.links.new(gradient.outputs["Color"], ramp.inputs[0]) | |
material.node_tree.links.new(ramp.outputs["Color"], bsdf.inputs["Base Color"]) | |
material.node_tree.links.new(bsdf.outputs["BSDF"], output.inputs["Surface"]) | |
# Rotate the gradient to apply it from left to right | |
torus = bpy.context.view_layer.objects.active | |
# torus.rotation_euler = | |
# Light | |
light = bpy.data.objects["Light"] | |
light.location = (0.1, 0, 2) # Position the light | |
# Camera | |
camera = bpy.data.objects["Camera"] | |
camera.location = (camera_X, camera_Y, camera_Z) | |
camera.data.dof.use_dof = True | |
camera.data.dof.focus_distance = 5 | |
camera.data.dof.aperture_fstop = 4 | |
camera.data.angle = fov | |
camera.data.type = 'PERSP' | |
# Render | |
with tempfile.NamedTemporaryFile(suffix=".JPEG", delete=False) as f: | |
bpy.context.scene.render.resolution_y = 288 | |
bpy.context.scene.render.resolution_x = 512 | |
bpy.context.scene.render.image_settings.file_format = "JPEG" | |
bpy.context.scene.render.filepath = f.name | |
with tqdm() as pbar: | |
def elapsed(dummy): | |
pbar.update() | |
bpy.app.handlers.render_stats.append(elapsed) | |
bpy.context.scene.frame_set(1) | |
bpy.context.scene.frame_current = 1 | |
# bpy.ops.render.render(animation=False, write_still=True) | |
# bpy.ops.render.render(animation=False, write_still=True) | |
bpy.ops.render.render(animation=False, write_still=True) | |
bpy.data.images["Render Result"].save_render( | |
filepath=bpy.context.scene.render.filepath | |
) | |
bpy.app.handlers.render_stats.clear() | |
return f.name | |
# generate("#ffffff", "#aaa", 1) | |
with gr.Blocks() as demo: | |
gr.Markdown("""# Gradio with Blender bpy | |
based on [kolibril13](https://github.com/kolibril13/ipyblender-experimental) | |
""") | |
with gr.Row(): | |
with gr.Column(): | |
color1 = gr.ColorPicker(value="#59C173") | |
color2 = gr.ColorPicker(value="#5D26C1") | |
torus_X = gr.Slider(minimum=-pi, maximum=pi, value=0, label="Torus φ") | |
torus_Y = gr.Slider(minimum=-pi, maximum=pi, value=-3, label="Torus θ") | |
torus_Z = gr.Slider(minimum=-pi, maximum=pi, value=1.5, label="Torus ψ") | |
fov = gr.Slider(minimum=0.0, maximum=pi, value=pi/3, label="FOV") | |
camera_X = gr.Slider(minimum=-100, maximum=100, value=5, label="Camera X") | |
camera_Y = gr.Slider(minimum=-100, maximum=100, value=-3, label="Camera Y") | |
camera_Z = gr.Slider(minimum=-100, maximum=100, value=4, label="Camera Z") | |
render_btn = gr.Button("Render") | |
with gr.Column(scale=3): | |
image = gr.Image(type="filepath") | |
render_btn.click( | |
generate, | |
inputs=[ | |
color1, | |
color2, | |
camera_X, | |
camera_Y, | |
camera_Z, | |
fov, | |
torus_X, | |
torus_Y, | |
torus_Z, | |
], | |
outputs=[image], | |
) | |
demo.queue(concurrency_count=1) | |
demo.launch(debug=True, inline=True) |