import numpy as np from .util import log, now class ToleranceMesh(object): """ ToleranceMesh objects hold tolerance information about meshes. Parameters ---------------- tol.zero : float Floating point numbers smaller than this are considered zero tol.merge : float When merging vertices, consider vertices closer than this to be the same vertex. Here we use the same value (1e-8) as SolidWorks uses, according to their documentation. tol.planar : float The maximum distance from a plane a point can be and still be considered to be on the plane tol.facet_threshold : float Threshold for two facets to be considered coplanar tol.strict : bool If True, run additional in- process checks (slower) """ def __init__(self, **kwargs): # set our zero for floating point comparison to 100x # the resolution of float64 which works out to 1e-13 self.zero = np.finfo(np.float64).resolution * 100 # vertices closer than this should be merged self.merge = 1e-8 # peak to valley flatness to be considered planar self.planar = 1e-5 # coplanar threshold: ratio of (radius / span) ** 2 self.facet_threshold = 5000 # run additional checks and asserts self.strict = False # add any passed kwargs self.__dict__.update(kwargs) class TolerancePath(object): """ TolerancePath objects contain tolerance information used in Path objects. Parameters --------------- tol.zero : float Floating point numbers smaller than this are considered zero tol.merge : float When merging vertices, consider vertices closer than this to be the same vertex. Here we use the same value (1e-8) as SolidWorks uses, according to their documentation. tol.planar : float The maximum distance from a plane a point can be and still be considered to be on the plane tol.seg_frac : float When simplifying line segments what percentage of the drawing scale can a segment be and have a curve fitted tol.seg_angle: when simplifying line segments to arcs, what angle can a segment span to be acceptable. tol.aspect_frac: when simplifying line segments to closed arcs (circles) what percentage can the aspect ratio differfrom 1:1 before escaping the fit early tol.radius_frac: when simplifying line segments to arcs, what percentage of the fit radius can vertices deviate to be acceptable tol.radius_min: when simplifying line segments to arcs, what is the minimum radius multiplied by document scale for an acceptable fit tol.radius_max: when simplifying line segments to arcs, what is the maximum radius multiplied by document scale for an acceptable fit tol.tangent: when simplifying line segments to curves, what is the maximum angle the end sections can deviate from tangent that is acceptable. """ def __init__(self, **kwargs): # default values self.zero = 1e-12 self.merge = 1e-5 self.planar = 1e-5 self.buffer = .05 self.seg_frac = .125 self.seg_angle = np.radians(50) self.seg_angle_min = np.radians(1) self.seg_angle_frac = .5 self.aspect_frac = .1 self.radius_frac = .02 self.radius_min = 1e-4 self.radius_max = 50 self.tangent = np.radians(20) # run additional checks and asserts self.strict = False self.__dict__.update(kwargs) class ResolutionPath(object): """ res.seg_frac: when discretizing curves, what percentage of the drawing scale should we aim to make a single segment res.seg_angle: when discretizing curves, what angle should a section span res.max_sections: when discretizing splines, what is the maximum number of segments per control point res.min_sections: when discretizing splines, what is the minimum number of segments per control point res.export: format string to use when exporting floating point vertices """ def __init__(self, **kwargs): self.seg_frac = .05 self.seg_angle = .08 self.max_sections = 10 self.min_sections = 5 self.export = '.5f' # instantiate mesh tolerances with defaults tol = ToleranceMesh() # instantiate path tolerances with defaults tol_path = TolerancePath() res_path = ResolutionPath() def log_time(method): """ A decorator for methods which will time the method and then emit a log.debug message with the method name and how long it took to execute. """ def timed(*args, **kwargs): tic = now() result = method(*args, **kwargs) log.debug('%s executed in %.4f seconds.', method.__name__, now() - tic) return result timed.__name__ = method.__name__ timed.__doc__ = method.__doc__ return timed