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 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):
|
||||||
|
28
level.py
28
level.py
@ -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)
|
(slice(localMinX, localMaxX), slice(localMinZ, localMaxZ), slice(miny, maxy)),
|
||||||
except ChunkNotPresent, e:
|
(newMinX, newMinY, newMinZ)
|
||||||
continue;
|
)
|
||||||
|
|
||||||
yield (ch,
|
if not level.containsChunk(cx,cz):
|
||||||
(slice(localMinX, localMaxX), slice(localMinZ, localMaxZ), slice(miny, maxy)),
|
if create and hasattr(level, 'createChunk'):
|
||||||
(newMinX, newMinY, newMinZ))
|
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
3
mce.py
@ -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;
|
||||||
|
16
schematic.py
16
schematic.py
@ -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
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user