def _updateAnimations(self, activeIndices, mapNamesDict=None): if self.temporalMode == TemporalMode.NONTEMPORAL: for i in range(len(self.animations)): if i not in activeIndices: self.animations[i].SetActive(False) continue anim = [anim for anim in self.animationData if anim.windowIndex == i][0] w, h = self.mapwindows[i].GetClientSize() regions = anim.GetRegions(w, h) self.animations[i].SetFrames( [HashCmds(cmdList, region) for cmdList, region in zip(anim.cmdMatrix, regions)]) self.animations[i].SetActive(True) else: for i in range(len(self.animations)): if i not in activeIndices: self.animations[i].SetActive(False) continue anim = [anim for anim in self.animationData if anim.windowIndex == i][0] w, h = self.mapwindows[i].GetClientSize() regions = anim.GetRegions(w, h) identifiers = sampleCmdMatrixAndCreateNames( anim.cmdMatrix, mapNamesDict[ anim.firstStdsNameType[0]], regions) self.animations[i].SetFrames(identifiers) self.animations[i].SetActive(True)
def Load(self, force=False, bgcolor=(255, 255, 255), nprocs=4): """Loads data, both 2D and 3D. In case of 2D, it creates composites, even when there is only 1 layer to compose (to be changed for speedup) :param force: if True reload all data, otherwise only missing data :param bgcolor: background color as a tuple of 3 values 0 to 255 :param nprocs: number of procs to be used for rendering """ Debug.msg( 2, "BitmapProvider.Load: " "force={f}, bgcolor={b}, nprocs={n}".format(f=force, b=bgcolor, n=nprocs)) cmds = [] regions = [] if self._uniqueCmds: cmds.extend(self._uniqueCmds) regions.extend(self._regionsForUniqueCmds) if self._cmds3D: cmds.extend(self._cmds3D) regions.extend([None] * len(self._cmds3D)) count = self._dryRender(cmds, regions, force=force) self.renderingStarted.emit(count=count) # create no data bitmap if None not in self._bitmapPool or force: self._bitmapPool[None] = createNoDataBitmap( self.imageWidth, self.imageHeight) ok = self._renderer.Render(cmds, regions, regionFor3D=self._regionFor3D, bgcolor=bgcolor, force=force, nprocs=nprocs) self.renderingFinished.emit() if not ok: self.mapsLoaded.emit() # what to do here? return if self._cmdsForComposition: count = self._dryCompose(self._cmdsForComposition, self._regions, force=force) self.compositionStarted.emit(count=count) self._composer.Compose(self._cmdsForComposition, self._regions, self._opacities, bgcolor=bgcolor, force=force, nprocs=nprocs) self.compositionFinished.emit() if self._cmds3D: for cmd in self._cmds3D: self._bitmapPool[HashCmds([cmd], None)] = \ wx.Bitmap(GetFileFromCmd(self._tempDir, cmd, None)) self.mapsLoaded.emit()
def _dryCompose(self, cmdLists, regions, force): """Determines how many lists of (commands) files will be composed (with g.pnmcomp). :param cmdLists: list of commands lists which are to be composed :param regions: list of regions assigned to the commands :param force: if forced rerendering """ count = 0 for cmdList, region in zip(cmdLists, regions): if not force and HashCmds(cmdList, region) in self._bitmapPool and \ self._bitmapPool[HashCmds(cmdList, region)].GetSize() == (self.imageWidth, self.imageHeight): continue count += 1 Debug.msg(2, "BitmapProvider._dryCompose: {c} files to be composed".format(c=count)) return count
def Unload(self): """Unloads currently loaded data. Needs to be called before setting new data. """ Debug.msg(2, "BitmapProvider.Unload") if self._cmdsForComposition: for cmd, region in zip(self._uniqueCmds, self._regionsForUniqueCmds): del self._mapFilesPool[HashCmd(cmd, region)] for cmdList, region in zip(self._cmdsForComposition, self._regions): del self._bitmapPool[HashCmds(cmdList, region)] self._uniqueCmds = [] self._cmdsForComposition = [] self._opacities = [] self._regions = [] self._regionsForUniqueCmds = [] if self._cmds3D: self._cmds3D = [] self._regionFor3D = None
def Compose(self, cmdLists, regions, opacityList, bgcolor, force, nprocs): """Performs the composition of ppm/pgm files. :param cmdLists: lists of rendering commands lists to compose :param regions: regions for 2D rendering assigned to commands :param opacityList: list of lists of opacity values :param bgcolor: background color as a tuple of 3 values 0 to 255 :param force: if True reload all data, otherwise only missing data :param nprocs: number of procs to be used for rendering """ Debug.msg(3, "BitmapComposer.Compose") count = 0 # Variables for parallel rendering proc_count = 0 proc_list = [] queue_list = [] cmd_lists = [] filteredCmdLists = [] for cmdList, region in zip(cmdLists, regions): if (not force and HashCmds(cmdList, region) in self._bitmapPool and self._bitmapPool[HashCmds(cmdList, region)].GetSize() == (self.imageWidth, self.imageHeight)): # TODO: find a better way than to assign the same to increase # the reference self._bitmapPool[HashCmds(cmdList, region)] = self._bitmapPool[HashCmds( cmdList, region)] continue filteredCmdLists.append((cmdList, region)) num = len(filteredCmdLists) self._isComposing = True for cmdList, region in filteredCmdLists: count += 1 # Queue object for interprocess communication q = Queue() # The separate render process p = Process( target=CompositeProcess, args=( self.imageWidth, self.imageHeight, self._tempDir, cmdList, region, opacityList, bgcolor, q, ), ) p.start() queue_list.append(q) proc_list.append(p) cmd_lists.append((cmdList, region)) proc_count += 1 # Wait for all running processes and read/store the created images if proc_count == nprocs or count == num: for i in range(len(cmd_lists)): proc_list[i].join() filename = queue_list[i].get() if filename is None: self._bitmapPool[HashCmds( cmd_lists[i][0], cmd_lists[i][1])] = createNoDataBitmap( self.imageWidth, self.imageHeight, text="Failed to render") else: self._bitmapPool[HashCmds( cmd_lists[i][0], cmd_lists[i][1])] = BitmapFromImage( wx.Image(filename)) os.remove(filename) proc_count = 0 proc_list = [] queue_list = [] cmd_lists = [] self.compositionContinues.emit(current=count, text=_("Overlaying map layers")) if self._stopComposing: self._stopComposing = False break self._isComposing = False