Upstream: https://github.com/Rhoban/onshape-to-robot Upstream-Commit: 80e710700aac9573a2230f74f7ce9e094833a0bc Upstream-Branch: master
90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
import os
|
|
from .config import Config
|
|
from .robot import Robot
|
|
from .processor import Processor
|
|
from .message import bright, info, error
|
|
|
|
|
|
class ProcessorSimplifySTLs(Processor):
|
|
"""
|
|
Allow for mesh simplifications using MeshLab
|
|
"""
|
|
|
|
def __init__(self, config: Config):
|
|
super().__init__(config)
|
|
|
|
# STL merge / simplification
|
|
self.simplify_stls = config.get("simplify_stls", False)
|
|
self.max_stl_size = config.get("max_stl_size", 3)
|
|
|
|
if self.simplify_stls:
|
|
self.pymeshlab = self.check_meshlab()
|
|
|
|
def check_meshlab(self):
|
|
print(bright("* Checking pymeshlab presence..."))
|
|
try:
|
|
import pymeshlab
|
|
|
|
return pymeshlab
|
|
except ImportError:
|
|
self.simplify_stls = False
|
|
print(error("No pymeshlab, disabling STL simplification support"))
|
|
print(info("TIP: consider installing pymeshlab:"))
|
|
print(info("pip install pymeshlab"))
|
|
|
|
def process(self, robot: Robot):
|
|
if self.simplify_stls:
|
|
simplify_all = (
|
|
self.simplify_stls != "visual" and self.simplify_stls != "collision"
|
|
)
|
|
simplified = set()
|
|
getcwd = os.getcwd()
|
|
# Changing directory to output to have relative paths working
|
|
os.chdir(self.config.output_directory)
|
|
for link in robot.links:
|
|
for part in link.parts:
|
|
for mesh in part.meshes:
|
|
if (
|
|
simplify_all or mesh.is_type(self.simplify_stls)
|
|
) and mesh.filename not in simplified:
|
|
simplified.add(mesh.filename)
|
|
self.simplify_stl(mesh.filename)
|
|
os.chdir(getcwd)
|
|
|
|
def reduce_faces(self, filename: str, reduction: float = 0.9):
|
|
mesh_set = self.pymeshlab.MeshSet()
|
|
|
|
# Add input mesh
|
|
mesh_set.load_new_mesh(filename)
|
|
|
|
# Apply filter
|
|
mesh_set.apply_filter(
|
|
"meshing_decimation_quadric_edge_collapse",
|
|
targetperc=reduction,
|
|
qualitythr=0.5,
|
|
preserveboundary=False,
|
|
boundaryweight=1,
|
|
preservenormal=True,
|
|
preservetopology=False,
|
|
optimalplacement=True,
|
|
planarquadric=True,
|
|
qualityweight=False,
|
|
planarweight=0.001,
|
|
autoclean=True,
|
|
selected=False,
|
|
)
|
|
|
|
# Save mesh
|
|
mesh_set.save_current_mesh(filename)
|
|
|
|
def simplify_stl(self, filename: str):
|
|
size_M = os.path.getsize(filename) / (1024 * 1024)
|
|
|
|
if size_M > self.max_stl_size:
|
|
print(
|
|
info(
|
|
f"+ {os.path.basename(filename)} is {size_M:.2f} M, running mesh simplification"
|
|
)
|
|
)
|
|
self.reduce_faces(filename, self.max_stl_size / size_M)
|