def init_body_group(self): if self.path_group is None: return # Initialize a BodyGroup() containing a 2D pymunk space to detect events # and perform point queries based on device. # Note that we cannot (can't be pickled) and do not want to save a # pymunk space, since it represents state information from the device. self.body_group = BodyGroup(self.path_group.paths)
class DmfDevice(): class_version = str(Version(0,3,0)) def __init__(self): self.electrodes = {} self.x_min = np.Inf self.x_max = 0 self.y_min = np.Inf self.y_max = 0 self.name = None self.scale = None self.path_group = None # svg_model.path_group.PathGroup self.version = self.class_version self.body_group = None self.electrode_name_map = {} self.name_electrode_map = {} def init_body_group(self): if self.path_group is None: return # Initialize a BodyGroup() containing a 2D pymunk space to detect events # and perform point queries based on device. # Note that we cannot (can't be pickled) and do not want to save a # pymunk space, since it represents state information from the device. self.body_group = BodyGroup(self.path_group.paths) def add_path_group(self, path_group): self.path_group = path_group self.electrode_name_map = {} self.name_electrode_map = {} for name, p in self.path_group.paths.iteritems(): eid = self.add_electrode_path(p) self.electrode_name_map[eid] = name self.name_electrode_map[name] = eid def get_electrode_from_body(self, body): name = self.body_group.get_name(body) eid = self.name_electrode_map[name] return self.electrodes[eid] @classmethod def load_svg(cls, svg_path): with warnings.catch_warnings(record=True) as warning_list: path_group = PathGroup.load_svg(svg_path, on_error=parse_warning) if warning_list: logger.warning('The following paths could not be parsed properly ' 'and have been ignored:\n%s' % \ '\n'.join([str(w.message) for w in warning_list])) # Assign the color blue to all paths that have no colour assigned for p in path_group.paths.values(): if p.color is None: p.color = (0, 0, 255) # If the first and last vertices in a loop are too close together, # it can cause tessellation to fail (Ticket # 106). for loop in p.loops: # distance between first and last point in a loop d = sqrt((loop.verts[0][0] - loop.verts[-1][0])**2 + \ (loop.verts[0][1] - loop.verts[-1][1])**2) # diagonal across device bounding box device_diag = sqrt(path_group.get_bounding_box()[2]**2 + \ path_group.get_bounding_box()[3]**2) # If the distance between the vertices is below a threshold, # remove the last vertex (the threshold is scaled by the device # diagonal so that we are insensitive to device size). if d/device_diag < 1e-3: loop.verts.pop() dmf_device = DmfDevice() dmf_device.add_path_group(path_group) dmf_device.init_body_group() return dmf_device @classmethod def load(cls, filename): """ Load a DmfDevice from a file. Args: filename: path to file. Raises: TypeError: file is not a DmfDevice. FutureVersionError: file was written by a future version of the software. """ logger.debug("[DmfDevice].load(\"%s\")" % filename) logger.info("Loading DmfDevice from %s" % filename) start_time = time.time() out=None with open(filename, 'rb') as f: try: out = pickle.load(f) logger.debug("Loaded object from pickle.") except Exception, e: logger.debug("Not a valid pickle file. %s." % e) if out==None: with open(filename, 'rb') as f: try: out = yaml.load(f) logger.debug("Loaded object from YAML file.") except Exception, e: logger.debug("Not a valid YAML file. %s." % e)