added a 'create' option to copyBlocksFrom and getChunkSlices.

This commit is contained in:
David Vierra 2011-09-13 16:03:58 -10:00
parent 2e4b8e43ad
commit a94c032c94
4 changed files with 46 additions and 39 deletions

View File

@ -2495,7 +2495,7 @@ class MCInfdevOldLevel(EntityLevel):
return slice(None, None) return slice(None, None)
return sourceMask return sourceMask
def copyBlocksFromFiniteIter(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy): def copyBlocksFromFiniteIter(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy, create = False):
#assumes destination point and bounds have already been checked. #assumes destination point and bounds have already been checked.
(sx, sy, sz) = sourceBox.origin (sx, sy, sz) = sourceBox.origin
@ -2561,7 +2561,7 @@ class MCInfdevOldLevel(EntityLevel):
#chunk.compress(); #xxx find out why this trashes changes to tile entities #chunk.compress(); #xxx find out why this trashes changes to tile entities
def copyBlocksFromInfiniteIter(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy): def copyBlocksFromInfiniteIter(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy, create = False):
""" copy blocks between two infinite levels via repeated export/import. hilariously slow. """ """ copy blocks between two infinite levels via repeated export/import. hilariously slow. """
#assumes destination point and bounds have already been checked. #assumes destination point and bounds have already been checked.
@ -2570,7 +2570,19 @@ class MCInfdevOldLevel(EntityLevel):
i = 0 i = 0
sourceMask = self.sourceMaskFunc(blocksToCopy) sourceMask = self.sourceMaskFunc(blocksToCopy)
for chunk, slices, point in self.getChunkSlices(destBox): def subbox(slices, point):
size = [s.stop - s.start for s in slices]
size[1], size[2] = size[2], size[1]
return BoundingBox([p + a for p, a in zip(point, sourceBox.origin)], size)
def shouldCreateFunc(slices, point):
box = subbox(slices, point)
b = any(list(sourceLevel.containsChunk(*c) for c in box.chunkPositions)) #any() won't take a generator-expression :(
if b == False:
print 'Skipped ', list(box.chunkPositions)
return b
for chunk, slices, point in self.getChunkSlices(destBox, create=(create and shouldCreateFunc)):
i += 1 i += 1
yield (i, chunkCount) yield (i, chunkCount)
if i % 100 == 0: if i % 100 == 0:
@ -2578,9 +2590,7 @@ class MCInfdevOldLevel(EntityLevel):
dstblocks = chunk.Blocks[slices] dstblocks = chunk.Blocks[slices]
dstdata = chunk.Data[slices] dstdata = chunk.Data[slices]
size = [s.stop - s.start for s in slices] sourceSubBox = subbox(slices, point)
size[1], size[2] = size[2], size[1]
sourceSubBox = BoundingBox([p + a for p, a in zip(point, sourceBox.origin)], size)
for srcchunk, srcslices, srcpoint in sourceLevel.getChunkSlices(sourceSubBox): for srcchunk, srcslices, srcpoint in sourceLevel.getChunkSlices(sourceSubBox):
srcpoint = srcpoint[0], srcpoint[2], srcpoint[1] srcpoint = srcpoint[0], srcpoint[2], srcpoint[1]
sourceBlocks = srcchunk.Blocks[srcslices] sourceBlocks = srcchunk.Blocks[srcslices]
@ -2597,10 +2607,10 @@ class MCInfdevOldLevel(EntityLevel):
def copyBlocksFrom(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True): def copyBlocksFrom(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True, create=False):
return exhaust(self.copyBlocksFromIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy, entities)) return exhaust(self.copyBlocksFromIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy, entities, create))
def copyBlocksFromIter(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True): def copyBlocksFromIter(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True, create=False):
(x, y, z) = destinationPoint; (x, y, z) = destinationPoint;
(lx, ly, lz) = sourceBox.size (lx, ly, lz) = sourceBox.size
#sourcePoint, sourcePoint1 = sourceBox #sourcePoint, sourcePoint1 = sourceBox
@ -2611,12 +2621,12 @@ class MCInfdevOldLevel(EntityLevel):
startTime = datetime.now() startTime = datetime.now()
if(not isinstance(sourceLevel, MCInfdevOldLevel)): if(not isinstance(sourceLevel, MCInfdevOldLevel)):
for i in self.copyBlocksFromFiniteIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy): for i in self.copyBlocksFromFiniteIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy, create):
yield i yield i
else: else:
for i in self.copyBlocksFromInfiniteIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy): for i in self.copyBlocksFromInfiniteIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy, create):
yield i yield i
for i in self.copyEntitiesFromIter(sourceLevel, sourceBox, destinationPoint, entities): for i in self.copyEntitiesFromIter(sourceLevel, sourceBox, destinationPoint, entities):

View File

@ -180,8 +180,10 @@ class MCLevel(object):
yield (chunk, slices, (xPos * 16 - x, 0, zPos * 16 - z)) yield (chunk, slices, (xPos * 16 - x, 0, zPos * 16 - z))
def getChunkSlicesCreating(self, box):
return self.getChunkSlices(box, create=True)
def getChunkSlices(self, box): def getChunkSlices(self, box, create=False):
""" call this method to iterate through a large slice of the world by """ call this method to iterate through a large slice of the world by
visiting each chunk and indexing its data with a subslice. visiting each chunk and indexing its data with a subslice.
@ -194,6 +196,9 @@ class MCLevel(object):
and the 'offset' triplet. x,z,y ordering is used only and the 'offset' triplet. x,z,y ordering is used only
to index arrays, since it reflects the order of the blocks in memory. to index arrays, since it reflects the order of the blocks in memory.
In all other places, including an entity's 'Pos', the order is x,y,z. In all other places, including an entity's 'Pos', the order is x,y,z.
'create' controls whether to create absent chunks or skip over them.
create can be False, True, or a function of (slices, point)
""" """
level = self level = self
@ -229,14 +234,21 @@ class MCLevel(object):
localMaxZ = maxzoff localMaxZ = maxzoff
newMinZ = localMinZ + (cz << 4) - box.minz newMinZ = localMinZ + (cz << 4) - box.minz
newMaxZ = localMaxZ + (cz << 4) - box.minz newMaxZ = localMaxZ + (cz << 4) - box.minz
try: slices, point = (
ch = level.getChunk(cx, cz)
except ChunkNotPresent, e:
continue;
yield (ch,
(slice(localMinX, localMaxX), slice(localMinZ, localMaxZ), slice(miny, maxy)), (slice(localMinX, localMaxX), slice(localMinZ, localMaxZ), slice(miny, maxy)),
(newMinX, newMinY, newMinZ)) (newMinX, newMinY, newMinZ)
)
if not level.containsChunk(cx,cz):
if create and hasattr(level, 'createChunk'):
if not hasattr(create, "__call__") or create(slices, point):
level.createChunk(cx,cz)
else:
continue
else:
continue;
chunk = level.getChunk(cx,cz)
yield chunk, slices, point
def containsPoint(self, x, y, z): def containsPoint(self, x, y, z):

3
mce.py
View File

@ -522,9 +522,8 @@ class mce(object):
importLevel = mclevel.fromFile(filename) importLevel = mclevel.fromFile(filename)
destBox = BoundingBox(destPoint, importLevel.size) destBox = BoundingBox(destPoint, importLevel.size)
self.level.createChunksInBox(destBox);
self.level.copyBlocksFrom(importLevel, importLevel.bounds, destPoint, blocksToCopy); self.level.copyBlocksFrom(importLevel, importLevel.bounds, destPoint, blocksToCopy, create=True);
self.needsSave = True; self.needsSave = True;

View File

@ -516,21 +516,7 @@ def extractZipSchematicFromIter(sourceLevel, box, zipfilename=None, entities=Tru
destBox = BoundingBox(destPoint, sourceBox.size); destBox = BoundingBox(destPoint, sourceBox.size);
if (sourceBox.isChunkAligned): for i in tempSchematic.copyBlocksFromIter(sourceLevel, sourceBox, destPoint, entities=entities, create=True):
#create chunks in the destination area corresponding only to chunks
#present in the source
chunks = sourceBox.chunkPositions
destChunks = destBox.chunkPositions
chunkIter = itertools.izip(chunks, destChunks)
for i, (src, chunk) in enumerate(chunkIter):
if sourceLevel.containsChunk(*src):
tempSchematic.createChunk(*chunk)
yield i, sourceBox.chunkCount
else:
tempSchematic.createChunksInBox(destBox)
for i in tempSchematic.copyBlocksFromIter(sourceLevel, sourceBox, destPoint, entities=entities):
yield i yield i
tempSchematic.saveInPlace(); #lights not needed for this format - crashes minecraft though tempSchematic.saveInPlace(); #lights not needed for this format - crashes minecraft though