def undo(self): """ Undo the operation. Ought to leave the Operation in a state where it can be performed again. Default implementation copies all chunks in undoLevel back into level. Non-chunk-based operations should override this.""" if self.undoLevel: self.redoLevel = self.extractUndo(self.level, self.dirtyBox()) def _undo(): yield 0, 0, "Undoing..." if hasattr(self.level, 'copyChunkFrom'): for i, (cx, cz) in enumerate(self.undoLevel.allChunks): self.level.copyChunkFrom(self.undoLevel, cx, cz) yield i, self.undoLevel.chunkCount, "Copying chunk %s..." % ((cx, cz),) else: for i in self.level.copyBlocksFromIter(self.undoLevel, self.undoLevel.bounds, self.undoLevel.sourcePoint, biomes=True): yield i, self.undoLevel.chunkCount, "Copying..." if self.undoLevel.chunkCount > 25: showProgress("Undoing...", _undo()) else: exhaust(_undo()) self.editor.invalidateChunks(self.undoLevel.allChunks)
def undo(self): """ Undo the operation. Ought to leave the Operation in a state where it can be performed again. Default implementation copies all chunks in undoLevel back into level. Non-chunk-based operations should override this.""" if self.undoLevel: self.redoLevel = self.extractUndo(self.level, self.dirtyBox()) def _undo(): yield 0, 0, "Undoing..." if hasattr(self.level, 'copyChunkFrom'): for i, (cx, cz) in enumerate(self.undoLevel.allChunks): self.level.copyChunkFrom(self.undoLevel, cx, cz) yield i, self.undoLevel.chunkCount, "Copying chunk %s..." % ( (cx, cz), ) else: for i in self.level.copyBlocksFromIter( self.undoLevel, self.undoLevel.bounds, self.undoLevel.sourcePoint, biomes=True): yield i, self.undoLevel.chunkCount, "Copying..." if self.undoLevel.chunkCount > 25: showProgress("Undoing...", _undo()) else: exhaust(_undo()) self.editor.invalidateChunks(self.undoLevel.allChunks)
def extractUndoChunks(self, level, chunks, chunkCount=None): if not isinstance(level, pymclevel.MCInfdevOldLevel): chunks = numpy.array(list(chunks)) mincx, mincz = numpy.min(chunks, 0) maxcx, maxcz = numpy.max(chunks, 0) box = BoundingBox((mincx << 4, 0, mincz << 4), (maxcx << 4, level.Height, maxcz << 4)) return self.extractUndoSchematic(level, box) undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) if not chunkCount: try: chunkCount = len(chunks) except TypeError: chunkCount = -1 def _extractUndo(): yield 0, 0, "Recording undo..." for i, (cx, cz) in enumerate(chunks): undoLevel.copyChunkFrom(level, cx, cz) yield i, chunkCount, _("Copying chunk %s...") % ((cx, cz),) undoLevel.saveInPlace() if chunkCount > 25 or chunkCount < 1: if "Canceled" == showProgress("Recording undo...", _extractUndo(), cancel=True): if albow.ask("Continue with undo disabled?", ["Continue", "Cancel"]) == "Cancel": raise Cancel else: return None else: exhaust(_extractUndo()) return undoLevel
def extractUndoChunks(self, level, chunks, chunkCount=None): if not isinstance(level, pymclevel.MCInfdevOldLevel): chunks = numpy.array(list(chunks)) mincx, mincz = numpy.min(chunks, 0) maxcx, maxcz = numpy.max(chunks, 0) box = BoundingBox((mincx << 4, 0, mincz << 4), (maxcx << 4, level.Height, maxcz << 4)) return self.extractUndoSchematic(level, box) undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) if not chunkCount: try: chunkCount = len(chunks) except TypeError: chunkCount = -1 def _extractUndo(): yield 0, 0, "Recording undo..." for i, (cx, cz) in enumerate(chunks): undoLevel.copyChunkFrom(level, cx, cz) yield i, chunkCount, _("Copying chunk %s...") % ((cx, cz),) undoLevel.saveInPlace() if chunkCount > 25 or chunkCount < 1: if "Canceled" == showProgress("Recording undo...", _extractUndo(), cancel=True): if albow.ask("Continue with undo disabled?", ["Continue", "Cancel"]) == "Cancel": raise Cancel else: return None else: exhaust(_extractUndo()) return undoLevel
def perform(self, recordUndo=True): if self.level.saving: alert(_("Cannot perform action while saving is taking place")) return if recordUndo: self.canUndo = True self.undoLevel = self.extractUndo(self.level, self._dirtyBox) def _perform(): yield 0, len(self.points), _("Applying {0} brush...").format( _(self.brushMode.displayName)) if hasattr(self.brushMode, 'apply'): for i, point in enumerate(self.points): f = self.brushMode.apply(self.brushMode, self, point) if hasattr(f, "__iter__"): for progress in f: yield progress else: yield i, len( self.points), _("Applying {0} brush...").format( _(self.brushMode.displayName)) if hasattr(self.brushMode, 'applyToChunkSlices'): for j, cPos in enumerate(self._dirtyBox.chunkPositions): if not self.level.containsChunk(*cPos): continue chunk = self.level.getChunk(*cPos) for i, point in enumerate(self.points): brushBox = self.tool.getDirtyBox(point, self.tool) brushBoxThisChunk, slices = chunk.getChunkSlicesForBox( brushBox) f = self.brushMode.applyToChunkSlices( self.brushMode, self, chunk, slices, brushBox, brushBoxThisChunk) if brushBoxThisChunk.volume == 0: f = None if hasattr(f, "__iter__"): for progress in f: yield progress else: yield j * len(self.points) + i, len( self.points) * self._dirtyBox.chunkCount, _( "Applying {0} brush...").format( _(self.brushMode.displayName)) chunk.chunkChanged() if len(self.points) > 10: showProgress("Performing brush...", _perform(), cancel=True) else: exhaust(_perform())
def redo(self): if self.redoLevel: def _redo(): yield 0, 0, "Redoing..." if hasattr(self.level, 'copyChunkFrom'): for i, (cx, cz) in enumerate(self.redoLevel.allChunks): self.level.copyChunkFrom(self.redoLevel, cx, cz) yield i, self.redoLevel.chunkCount, "Copying chunk %s..." % ((cx, cz),) else: for i in self.level.copyBlocksFromIter(self.redoLevel, self.redoLevel.bounds, self.redoLevel.sourcePoint, biomes=True): yield i, self.undoLevel.chunkCount, "Copying..." if self.redoLevel.chunkCount > 25: showProgress("Redoing...", _redo()) else: exhaust(_redo())
def redo(self): if self.redoLevel: def _redo(): yield 0, 0, "Redoing..." if hasattr(self.level, 'copyChunkFrom'): for i, (cx, cz) in enumerate(self.redoLevel.allChunks): self.level.copyChunkFrom(self.redoLevel, cx, cz) yield i, self.redoLevel.chunkCount, "Copying chunk %s..." % ((cx, cz),) else: for i in self.level.copyBlocksFromIter(self.redoLevel, self.redoLevel.bounds, self.redoLevel.sourcePoint, biomes=True): yield i, self.undoLevel.chunkCount, "Copying..." if self.redoLevel.chunkCount > 25: showProgress("Redoing...", _redo()) else: exhaust(_redo())
def undo(self): """ Undo the operation. Ought to leave the Operation in a state where it can be performed again. Default implementation copies all chunks in undoLevel back into level. Non-chunk-based operations should override this.""" if self.undoLevel: def _undo(): yield 0, 0, "Undoing..." for i, (cx, cz) in enumerate(self.undoLevel.allChunks): self.level.copyChunkFrom(self.undoLevel, cx, cz) yield i, self.undoLevel.chunkCount, "Copying chunk %s..." % ((cx, cz),) if self.undoLevel.chunkCount > 25: showProgress("Undoing...", _undo()) else: exhaust(_undo()) self.editor.invalidateChunks(self.undoLevel.allChunks)
def undo(self): """ Undo the operation. Ought to leave the Operation in a state where it can be performed again. Default implementation copies all chunks in undoLevel back into level. Non-chunk-based operations should override this.""" if self.undoLevel: def _undo(): yield 0, 0, "Undoing..." for i, (cx, cz) in enumerate(self.undoLevel.allChunks): self.level.copyChunkFrom(self.undoLevel, cx, cz) yield i, self.undoLevel.chunkCount, "Copying chunk %s..." % ( (cx, cz), ) if self.undoLevel.chunkCount > 25: showProgress("Undoing...", _undo()) else: exhaust(_undo()) self.editor.invalidateChunks(self.undoLevel.allChunks)
def extractUndoChunks(self, level, chunks, chunkCount = None): undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) if not chunkCount: try: chunkCount = len(chunks) except TypeError: chunkCount = -1 def _extractUndo(): yield 0, 0, "Recording undo..." for i, (cx, cz) in enumerate(chunks): undoLevel.copyChunkFrom(level, cx, cz) yield i, chunkCount, "Copying chunk %s..." % ((cx, cz),) undoLevel.saveInPlace() if chunkCount > 25 or chunkCount < 1: showProgress("Recording undo...", _extractUndo()) else: exhaust(_extractUndo()) return undoLevel
def extractUndoChunks(self, level, chunks, chunkCount=None): undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) if not chunkCount: try: chunkCount = len(chunks) except TypeError: chunkCount = -1 def _extractUndo(): yield 0, 0, "Recording undo..." for i, (cx, cz) in enumerate(chunks): undoLevel.copyChunkFrom(level, cx, cz) yield i, chunkCount, "Copying chunk %s..." % ((cx, cz), ) undoLevel.saveInPlace() if chunkCount > 25 or chunkCount < 1: showProgress("Recording undo...", _extractUndo()) else: exhaust(_extractUndo()) return undoLevel
def perform(self, recordUndo=True): if self.level.saving: alert(_("Cannot perform action while saving is taking place")) return if recordUndo: self.canUndo = True self.undoLevel = self.extractUndo(self.level, self._dirtyBox) def _perform(): yield 0, len(self.points), _("Applying {0} brush...").format(_(self.brushMode.displayName)) if hasattr(self.brushMode, 'apply'): for i, point in enumerate(self.points): f = self.brushMode.apply(self.brushMode, self, point) if hasattr(f, "__iter__"): for progress in f: yield progress else: yield i, len(self.points), _("Applying {0} brush...").format(_(self.brushMode.displayName)) if hasattr(self.brushMode, 'applyToChunkSlices'): for j, cPos in enumerate(self._dirtyBox.chunkPositions): if not self.level.containsChunk(*cPos): continue chunk = self.level.getChunk(*cPos) for i, point in enumerate(self.points): brushBox = self.tool.getDirtyBox(point, self.tool) brushBoxThisChunk, slices = chunk.getChunkSlicesForBox(brushBox) f = self.brushMode.applyToChunkSlices(self.brushMode, self, chunk, slices, brushBox, brushBoxThisChunk) if brushBoxThisChunk.volume == 0: f = None if hasattr(f, "__iter__"): for progress in f: yield progress else: yield j * len(self.points) + i, len(self.points) * self._dirtyBox.chunkCount, _("Applying {0} brush...").format(_(self.brushMode.displayName)) chunk.chunkChanged() if len(self.points) > 10: showProgress("Performing brush...", _perform(), cancel=True) else: exhaust(_perform())