def preview(self, event): """ @brief Load a downsampled version of the full ASDF """ params = self.get_params(get_bounds=False) if params is None: return for p in params: exec('{0} = params["{0}"]'.format(p)) voxels = ni * nj * nk shift = int(ceil(log(voxels / 128.**3, 8))) full = Region( (0, 0, 0), (ni-1, nj-1, nk-1), 1, dummy=True ) libfab.build_arrays( full, 0, 0, 0, ni*mm, nj*mm, nk*mm ) full.free_arrays = True asdf = ASDF( libfab.import_vol_region( self.filename, ni, nj, nk, full, shift, density, True, close_boundary ) ) mesh = asdf.triangulate() koko.FRAME.get_menu('View', '3D').Check(True) koko.APP.render_mode('3D') koko.GLCANVAS.load_mesh(mesh) koko.GLCANVAS.snap = True
def run(self, event): params = self.get_params() for p in params: exec('{0} = params["{0}"]'.format(p)) full = Region( (imin, jmin, kmin), (imax, jmax, kmax), 1, dummy=True ) libfab.build_arrays( full, imin*mm, jmin*mm, kmin*mm, (imax+1)*mm, (jmax+1)*mm, (kmax+1)*mm ) # Position the lower corner based on imin, jmin, kmin full.imin = imin full.jmin = jmin full.kmin = kmin full.free_arrays = True koko.FRAME.status = 'Importing ASDF' wx.Yield() asdf = ASDF( libfab.import_vol_region( self.filename, ni, nj, nk, full, 0, density, True, close_boundary ) ) koko.FRAME.status = 'Triangulating' wx.Yield() mesh = asdf.triangulate() koko.FRAME.get_menu('View', '3D').Check(True) koko.APP.render_mode('3D') koko.GLCANVAS.load_mesh(mesh) koko.GLCANVAS.snap = True koko.FAB.set_input(asdf) koko.FRAME.status = '' koko.APP.mode = 'asdf' koko.APP.filename = None koko.APP.savepoint(False)
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