def asdf(self, region=None, resolution=None, mm_per_unit=None, merge_leafs=True, interrupt=None): """ @brief Constructs an ASDF from a math tree. @details Runs in up to eight threads. @param region Evaluation region (if None, taken from expression bounds) @param resolution Render resolution in voxels/unit @param mm_per_unit Real-world scale @param merge_leafs Boolean determining whether leaf cells are combined @param interrupt threading.Event that aborts rendering if set @returns ASDF data structure """ if region is None: if not self.bounded: raise Exception('Unknown render region!') elif resolution is None: raise Exception('Region or resolution must be provided!') region = Region( (self.xmin, self.ymin, self.zmin if self.zmin else 0), (self.xmax, self.ymax, self.zmax if self.zmax else 0), resolution ) if interrupt is None: interrupt = threading.Event() # Shared flag to interrupt rendering halt = ctypes.c_int(0) # Split the region into up to 8 sections split = region.octsect(all=True) subregions = [split[i] for i in range(8) if split[i] is not None] ids = [i for i in range(8) if split[i] is not None] threads = len(subregions) clones = [self.clone() for i in range(threads)] packed = [libfab.make_packed(c.ptr) for c in clones] # Generate a root for the tree asdf = ASDF(libfab.asdf_root(packed[0], region), color=self.color) # Multithread the solver process q = Queue.Queue() args = zip(packed, ids, subregions, [q]*threads) # Helper function to construct a single branch def construct_branch(ptree, id, region, queue): asdf = libfab.build_asdf(ptree, region, merge_leafs, halt) queue.put((id, asdf)) # Run the constructor in parallel to make the branches multithread(construct_branch, args, interrupt, halt) for p in packed: libfab.free_packed(p) # Attach the branches to the root for s in subregions: try: id, branch = q.get_nowait() except Queue.Empty: break else: asdf.ptr.contents.branches[id] = branch libfab.get_d_from_children(asdf.ptr) libfab.simplify(asdf.ptr, merge_leafs) # Set a scale on the ASDF if one was provided if mm_per_unit is not None: asdf.rescale(mm_per_unit) return asdf
def asdf(self, region=None, resolution=None, mm_per_unit=None, merge_leafs=True, interrupt=None): """ @brief Constructs an ASDF from a math tree. @details Runs in up to eight threads. @param region Evaluation region (if None, taken from expression bounds) @param resolution Render resolution in voxels/unit @param mm_per_unit Real-world scale @param merge_leafs Boolean determining whether leaf cells are combined @param interrupt threading.Event that aborts rendering if set @returns ASDF data structure """ if region is None: if not self.bounded: raise Exception('Unknown render region!') elif resolution is None: raise Exception('Region or resolution must be provided!') region = Region( (self.xmin, self.ymin, self.zmin if self.zmin else 0), (self.xmax, self.ymax, self.zmax if self.zmax else 0), resolution) if interrupt is None: interrupt = threading.Event() # Shared flag to interrupt rendering halt = ctypes.c_int(0) # Split the region into up to 8 sections split = region.octsect(all=True) subregions = [split[i] for i in range(8) if split[i] is not None] ids = [i for i in range(8) if split[i] is not None] threads = len(subregions) clones = [self.clone() for i in range(threads)] packed = [libfab.make_packed(c.ptr) for c in clones] # Generate a root for the tree asdf = ASDF(libfab.asdf_root(packed[0], region), color=self.color) asdf.lock.acquire() # Multithread the solver process q = Queue.Queue() args = zip(packed, ids, subregions, [q] * threads) # Helper function to construct a single branch def construct_branch(ptree, id, region, queue): asdf = libfab.build_asdf(ptree, region, merge_leafs, halt) queue.put((id, asdf)) # Run the constructor in parallel to make the branches multithread(construct_branch, args, interrupt, halt) for p in packed: libfab.free_packed(p) # Attach the branches to the root for s in subregions: try: id, branch = q.get_nowait() except Queue.Empty: break else: # Make sure we didn't get a NULL pointer back # (which could occur if the halt flag was raised) try: branch.contents except ValueError: asdf.lock.release() return None asdf.ptr.contents.branches[id] = branch libfab.get_d_from_children(asdf.ptr) libfab.simplify(asdf.ptr, merge_leafs) asdf.lock.release() # Set a scale on the ASDF if one was provided if mm_per_unit is not None: asdf.rescale(mm_per_unit) return asdf