Skip to content

Instantly share code, notes, and snippets.

@JanHmmr
Created May 4, 2024 14:14
Show Gist options
  • Select an option

  • Save JanHmmr/78eaf488a0e848b598daae94a96e0a7b to your computer and use it in GitHub Desktop.

Select an option

Save JanHmmr/78eaf488a0e848b598daae94a96e0a7b to your computer and use it in GitHub Desktop.
Blender Remesh Function
import subprocess
def remesh(blender_path: str, # Path to blender executable
model_path: str, # Path to input model
export_path: str, # Path to output model
faces: int, # Number of faces for remesh
merge: bool = False, # Merge duplicate vertices before exporting
preserve_uvs: bool = False
) -> None:
"""
Remesh a model using Blender and export it
Parameters:
blender_path (str): Path to blender executable
model_path (str): Path to input model
export_path (str): Path to output model
faces (int): Number of faces for remesh
merge (bool): Merge duplicate vertices before exporting
Returns:
None
"""
code = f"""
# Import the module
import bpy
from pathlib import Path
# Enable CUDA for better performance
bpy.context.preferences.addons['cycles'].preferences.compute_device_type = 'CUDA'
bpy.context.preferences.addons['cycles'].preferences.get_devices()
# Set empty scene
bpy.ops.wm.read_factory_settings(use_empty=True)
# Delete all current meshes
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_by_type(type='MESH')
bpy.ops.object.delete()
# Import the model
export_path = r'{export_path}'
import_path = r'{model_path}'
if import_path.endswith('.glb'):
bpy.ops.import_scene.gltf(filepath=import_path)
elif import_path.endswith('.fbx'):
bpy.ops.import_scene.fbx(filepath=import_path)
if not bpy.context.object:
bpy.context.view_layer.objects.active = bpy.data.objects[0]
bpy.data.objects[0].select_set(True)
else:
print("Unsupported file format. Please use .glb or .fbx.")
raise SystemExit
if {preserve_uvs} and not export_path.endswith('.stl'):
blend_path = Path(r'{export_path}').with_suffix("." + "blend")
bpy.ops.wm.save_as_mainfile(filepath=str(blend_path))
# Select the imported model
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.shade_smooth_by_angle()
obj = bpy.context.object
if {preserve_uvs}:
orignal_obj = obj.copy()
orignal_obj.data = obj.data.copy()
if {merge}:
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.remove_doubles()
bpy.ops.object.mode_set(mode='OBJECT')
# Remesh the model
obj.data.remesh_mode = 'QUAD'
bpy.ops.object.quadriflow_remesh(
target_faces={faces},
use_mesh_symmetry=False,
use_preserve_sharp=True,
use_preserve_boundary=True
)
if {preserve_uvs}:
transfer_mod = obj.modifiers.new(name="DataTransferMod", type='DATA_TRANSFER')
transfer_mod.object = orignal_obj
transfer_mod.use_loop_data = True
transfer_mod.data_types_loops = {{'UV'}}
transfer_mod.loop_mapping = 'POLYINTERP_NEAREST'
transfer_mod.use_object_transform = False
bpy.ops.object.datalayout_transfer(modifier = transfer_mod.name)
bpy.ops.object.modifier_apply(modifier=transfer_mod.name)
bpy.ops.file.unpack_all(method = 'USE_LOCAL')
# Merge vertices
if {merge}:
print("Merging")
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.remove_doubles()
bpy.ops.object.mode_set(mode='OBJECT')
# Export the model
if export_path.endswith('.glb'):
bpy.ops.export_scene.gltf(filepath=export_path)
elif export_path.endswith('.fbx'):
bpy.ops.export_scene.fbx(filepath=export_path)
elif export_path.endswith('.obj'):
bpy.ops.wm.obj_export(filepath=export_path)
elif export_path.endswith('.stl'):
bpy.ops.wm.stl_export(filepath=export_path)
elif export_path.endswith('.usdc'):
bpy.ops.wm.usd_export(filepath=export_path)
else:
print("Unsupported file format. Please use .glb, .fbx, .obj, .stl, or .usdc.")
raise SystemExit
if {preserve_uvs} and not export_path.endswith('.stl') and blend_path.exists():
blend_path.unlink()
"""
# Run the script using blender
cmd = [blender_path, "-b", "--python-expr", code]
result = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# Print the output
print(result.stdout.decode())
# Print any errors that occurred
# print("Error:", result.stderr.decode())
if __name__ == "__main__":
blender_path = r"C:\Program Files\Blender Foundation\Blender 4.1\blender.exe"
model_path = r"C:\Users\janun\Documents\3DAI\Blender Remesh\test2.glb"
export_path = r"C:\Users\janun\Documents\3DAI\Blender Remesh\test_remesh.obj"
faces = 5000
merge = True
preserve_uvs = True
remesh(blender_path, model_path, export_path , faces , merge , preserve_uvs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment