kopia lustrzana https://github.com/lzzcd001/MeshDiffusion
added blender viz
rodzic
f1a0f85dc2
commit
d31c582c9a
|
@ -136,6 +136,10 @@ Follow the instructions in https://github.com/TEXTurePaper/TEXTurePaper and crea
|
|||
|
||||
If tetrahedral grids of higher resolutions are needed, first follow the README in `nvdiffrec/data/tets` and use quartet (https://github.com/crawforddoran/quartet) to generate a uniform tetrahedral grid. Then run `nvdiffrec/data/tets/crop_tets.py` to remove the boundary (so that translational symmetry holds in the resulted grid).
|
||||
|
||||
## Blender Visualization
|
||||
|
||||
To visualize generated meshes with blender, please see `blender_viz/` for more details.
|
||||
|
||||
## Citation
|
||||
If you find our work useful to your research, please consider citing:
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
## Usage
|
||||
|
||||
1. Download [Blender](https://www.blender.org/download/) and unzip to `$PATH_TO_BLENDER`. We used Blender 3.3.0.
|
||||
2. Clone `https://github.com/HTDerekLiu/BlenderToolbox` under `$BLENDER_PATH`
|
||||
3. In blender_script.py, set `BLENDER_PATH` accordingly. Also set 'mesh_folder_path' and 'output_path' to the source mesh folder path and the desired output path.
|
||||
4. Additionally, change the scale and orientation of the mesh to render in `blender_script.py`
|
||||
5. Run `$PATH_TO_BLENDER/blender --background --python ./blender_script.py`
|
||||
|
||||
|
||||
## Acknowledgement
|
||||
|
||||
Blender scripts and settings adapted from https://github.com/HTDerekLiu/BlenderToolbox and https://www.silviasellan.com/blender_figure.html.
|
|
@ -0,0 +1,139 @@
|
|||
import sys
|
||||
BLENDER_PATH = './' # change this to your path to “path/to/BlenderToolbox/
|
||||
sys.path.append(BLENDER_PATH)
|
||||
import BlenderToolBox as bt
|
||||
import os, bpy, bmesh
|
||||
import glob
|
||||
import numpy as np
|
||||
cwd = os.getcwd()
|
||||
|
||||
|
||||
import mathutils
|
||||
|
||||
|
||||
mesh_folder_path = 'PLACEHOLDER'
|
||||
output_path = 'PLACEHOLDER'
|
||||
os.makedirs(output_path, exist_ok=True)
|
||||
|
||||
def readOBJ(filePath, location, rotation_euler, scale):
|
||||
x = rotation_euler[0] * 1.0 / 180.0 * np.pi
|
||||
y = rotation_euler[1] * 1.0 / 180.0 * np.pi
|
||||
z = rotation_euler[2] * 1.0 / 180.0 * np.pi
|
||||
angle = (x,y,z)
|
||||
|
||||
prev = []
|
||||
for ii in range(len(list(bpy.data.objects))):
|
||||
prev.append(bpy.data.objects[ii].name)
|
||||
bpy.ops.import_scene.obj(filepath=filePath, split_mode='OFF')
|
||||
after = []
|
||||
for ii in range(len(list(bpy.data.objects))):
|
||||
after.append(bpy.data.objects[ii].name)
|
||||
name = list(set(after) - set(prev))[0]
|
||||
mesh = bpy.data.objects[name]
|
||||
|
||||
mesh.location = location
|
||||
mesh.rotation_euler = angle
|
||||
mesh.scale = scale
|
||||
bpy.context.view_layer.update()
|
||||
|
||||
return mesh
|
||||
|
||||
blend_path = './scene.blend'
|
||||
with bpy.data.libraries.load(blend_path, link=False) as (data_from, data_to):
|
||||
data_to.materials = data_from.materials
|
||||
bpy.ops.wm.open_mainfile(filepath=blend_path)
|
||||
|
||||
# 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"
|
||||
|
||||
# get_devices() to let Blender detects GPU device
|
||||
bpy.context.preferences.addons["cycles"].preferences.get_devices()
|
||||
for d in bpy.context.preferences.addons["cycles"].preferences.devices:
|
||||
d["use"] = 1 # Using all devices, include GPU and CPU
|
||||
|
||||
## set shading (uncomment one of them)
|
||||
bpy.ops.object.shade_smooth() # Option1: Gouraud shading
|
||||
# bpy.ops.object.shade_flat() # Option2: Flat shading
|
||||
# bt.edgeNormals(mesh, angle = 10) # Option3: Edge normal shading
|
||||
|
||||
## set light
|
||||
## Option1: Three Point Light System
|
||||
# bt.setLight_threePoints(radius=4, height=10, intensity=1700, softness=6, keyLoc='left')
|
||||
## Option2: simple sun light
|
||||
lightAngle = (6, -30, -155)
|
||||
strength = 2
|
||||
shadowSoftness = 0.10
|
||||
|
||||
sun = bt.setLight_sun(lightAngle, strength, shadowSoftness)
|
||||
|
||||
## set ambient light
|
||||
bt.setLight_ambient(color=(0.2, 0.2, 0.2, 1))
|
||||
|
||||
|
||||
path_list = sorted(glob.glob(os.path.join(mesh_folder_path, '*.obj')))
|
||||
|
||||
for k, meshPath in enumerate(path_list):
|
||||
out_file_path = os.path.join(output_path, '{:06d}.png'.format(k))
|
||||
if os.path.exists(out_file_path):
|
||||
continue
|
||||
|
||||
imgRes_x = 720 # recommend > 1080
|
||||
imgRes_y = 720 # recommend > 1080
|
||||
numSamples = 10 # for car
|
||||
# numSamples = 100 # for car
|
||||
# numSamples = 1000 # recommend > 200
|
||||
exposure = 1.5
|
||||
bpy.context.scene.render.film_transparent = True
|
||||
bpy.context.scene.cycles.samples = numSamples
|
||||
# bpy.context.scene.cycles.max_bounces = 6
|
||||
bpy.context.scene.cycles.max_bounces = 24
|
||||
bpy.context.scene.cycles.film_exposure = exposure
|
||||
|
||||
## read mesh
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
location = (1.0, 2.0, 1.6) # (GUI: click mesh > Transform > Location)
|
||||
# rotation = (90, 0, 270) # (GUI: click mesh > Transform > Rotation) ## for car
|
||||
rotation = (90, 0, 180) # (GUI: click mesh > Transform > Rotation)
|
||||
# scale = (7.,7.,7.) # (GUI: click mesh > Transform > Scale) ## for car
|
||||
scale = (3.,3.,3.) # (GUI: click mesh > Transform > Scale)
|
||||
mesh = readOBJ(meshPath, location, rotation, scale)
|
||||
|
||||
## subdivision
|
||||
bt.subdivision(mesh, level = 1)
|
||||
|
||||
mesh.active_material = bpy.data.materials.get("cbrewer medium red")
|
||||
|
||||
minz = 999999.0
|
||||
|
||||
for vertex in mesh.data.vertices:
|
||||
# object vertices are in object space, translate to world space
|
||||
v_world = mesh.matrix_world @ mathutils.Vector((vertex.co[0],vertex.co[1],vertex.co[2]))
|
||||
|
||||
if v_world[2] < minz:
|
||||
minz = v_world[2]
|
||||
|
||||
mesh.location.z = mesh.location.z - minz
|
||||
|
||||
|
||||
## save blender file so that you can adjust parameters in the UI
|
||||
# bpy.ops.wm.save_mainfile(filepath=os.getcwd() + '/test.blend')
|
||||
|
||||
bpy.data.scenes['Scene'].render.filepath = out_file_path
|
||||
bpy.ops.render.render(write_still = True)
|
||||
|
||||
|
||||
# Remember which meshes were just imported
|
||||
meshes_to_remove = []
|
||||
for ob in bpy.context.selected_objects:
|
||||
meshes_to_remove.append(ob.data)
|
||||
|
||||
bpy.ops.object.delete()
|
||||
|
||||
# Remove the meshes from memory too
|
||||
for mesh in meshes_to_remove:
|
||||
bpy.data.meshes.remove(mesh)
|
Plik binarny nie jest wyświetlany.
Ładowanie…
Reference in New Issue