added a 'create' option to copyBlocksFrom and getChunkSlices.
This commit is contained in:
parent
2e4b8e43ad
commit
a94c032c94
@ -2495,7 +2495,7 @@ class MCInfdevOldLevel(EntityLevel):
|
||||
return slice(None, None)
|
||||
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.
|
||||
(sx, sy, sz) = sourceBox.origin
|
||||
|
||||
@ -2561,7 +2561,7 @@ class MCInfdevOldLevel(EntityLevel):
|
||||
|
||||
#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. """
|
||||
|
||||
#assumes destination point and bounds have already been checked.
|
||||
@ -2569,8 +2569,20 @@ class MCInfdevOldLevel(EntityLevel):
|
||||
chunkCount = destBox.chunkCount
|
||||
i = 0
|
||||
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
|
||||
yield (i, chunkCount)
|
||||
if i % 100 == 0:
|
||||
@ -2578,9 +2590,7 @@ class MCInfdevOldLevel(EntityLevel):
|
||||
|
||||
dstblocks = chunk.Blocks[slices]
|
||||
dstdata = chunk.Data[slices]
|
||||
size = [s.stop - s.start for s in slices]
|
||||
size[1], size[2] = size[2], size[1]
|
||||
sourceSubBox = BoundingBox([p + a for p, a in zip(point, sourceBox.origin)], size)
|
||||
sourceSubBox = subbox(slices, point)
|
||||
for srcchunk, srcslices, srcpoint in sourceLevel.getChunkSlices(sourceSubBox):
|
||||
srcpoint = srcpoint[0], srcpoint[2], srcpoint[1]
|
||||
sourceBlocks = srcchunk.Blocks[srcslices]
|
||||
@ -2597,10 +2607,10 @@ class MCInfdevOldLevel(EntityLevel):
|
||||
|
||||
|
||||
|
||||
def copyBlocksFrom(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True):
|
||||
return exhaust(self.copyBlocksFromIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy, entities))
|
||||
def copyBlocksFrom(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy=None, entities=True, create=False):
|
||||
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;
|
||||
(lx, ly, lz) = sourceBox.size
|
||||
#sourcePoint, sourcePoint1 = sourceBox
|
||||
@ -2611,12 +2621,12 @@ class MCInfdevOldLevel(EntityLevel):
|
||||
startTime = datetime.now()
|
||||
|
||||
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
|
||||
|
||||
|
||||
else:
|
||||
for i in self.copyBlocksFromInfiniteIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy):
|
||||
for i in self.copyBlocksFromInfiniteIter(sourceLevel, sourceBox, destinationPoint, blocksToCopy, create):
|
||||
yield i
|
||||
|
||||
for i in self.copyEntitiesFromIter(sourceLevel, sourceBox, destinationPoint, entities):
|
||||
|
32
level.py
32
level.py
@ -180,8 +180,10 @@ class MCLevel(object):
|
||||
|
||||
yield (chunk, slices, (xPos * 16 - x, 0, zPos * 16 - z))
|
||||
|
||||
|
||||
def getChunkSlices(self, box):
|
||||
def getChunkSlicesCreating(self, box):
|
||||
return self.getChunkSlices(box, create=True)
|
||||
|
||||
def getChunkSlices(self, box, create=False):
|
||||
""" call this method to iterate through a large slice of the world by
|
||||
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
|
||||
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.
|
||||
|
||||
'create' controls whether to create absent chunks or skip over them.
|
||||
create can be False, True, or a function of (slices, point)
|
||||
"""
|
||||
level = self
|
||||
|
||||
@ -229,14 +234,21 @@ class MCLevel(object):
|
||||
localMaxZ = maxzoff
|
||||
newMinZ = localMinZ + (cz << 4) - box.minz
|
||||
newMaxZ = localMaxZ + (cz << 4) - box.minz
|
||||
try:
|
||||
ch = level.getChunk(cx, cz)
|
||||
except ChunkNotPresent, e:
|
||||
continue;
|
||||
|
||||
yield (ch,
|
||||
(slice(localMinX, localMaxX), slice(localMinZ, localMaxZ), slice(miny, maxy)),
|
||||
(newMinX, newMinY, newMinZ))
|
||||
slices, point = (
|
||||
(slice(localMinX, localMaxX), slice(localMinZ, localMaxZ), slice(miny, maxy)),
|
||||
(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):
|
||||
|
3
mce.py
3
mce.py
@ -522,9 +522,8 @@ class mce(object):
|
||||
importLevel = mclevel.fromFile(filename)
|
||||
|
||||
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;
|
||||
|
16
schematic.py
16
schematic.py
@ -516,21 +516,7 @@ def extractZipSchematicFromIter(sourceLevel, box, zipfilename=None, entities=Tru
|
||||
|
||||
destBox = BoundingBox(destPoint, sourceBox.size);
|
||||
|
||||
if (sourceBox.isChunkAligned):
|
||||
#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):
|
||||
for i in tempSchematic.copyBlocksFromIter(sourceLevel, sourceBox, destPoint, entities=entities, create=True):
|
||||
yield i
|
||||
tempSchematic.saveInPlace(); #lights not needed for this format - crashes minecraft though
|
||||
|
||||
|
Reference in New Issue
Block a user