added an inf-to-inf copy function that uses a small temporary area and existing copy code to copy a huge area.

This commit is contained in:
David Vierra 2010-11-15 03:55:25 -10:00
parent 3f76661672
commit 8633850f25

View File

@ -2747,7 +2747,33 @@ class MCInfdevOldLevel(MCLevel):
info( "Finished {2} chunks in {0} ({1} per chunk)".format(d, d / i, i) )
#chunk.compress(); #xxx find out why this trashes changes to tile entities
def copyBlocksFromInfinite(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy):
""" copy blocks between two infinite levels via repeated export/import. hilariously slow. """
#assumes destination point and bounds have already been checked.
tempSize = 64
def iterateSubsections():
#tempShape = (tempSize, sourceBox.height, tempSize)
dx, dy, dz = destinationPoint
ox, oy, oz = sourceBox.origin
sx, sy, sz = sourceBox.size
mx, my, mz = sourceBox.maximum
for x,z in itertools.product(arange(ox, ox+sx, tempSize), arange(oz, oz+sz, tempSize)):
box = BoundingBox((x, oy, z), (min(tempSize, mx-x), sy, min(tempSize, mz-z)))
destPoint = (dx + x - ox, dy, dz + z - oz)
yield box, destPoint
i=0;
for box, destPoint in iterateSubsections():
info( "Subsection {0} at {1}".format(i, destPoint) )
temp = sourceLevel.extractSchematic(box);
self.copyBlocksFrom(temp, BoundingBox( (0,0,0), box.size ), destPoint);
i+= 1;
def copyBlocksFrom(self, sourceLevel, sourceBox, destinationPoint, blocksToCopy = None):
(x,y,z) = destinationPoint;
(lx,ly,lz) = sourceBox.size
@ -2759,36 +2785,12 @@ class MCInfdevOldLevel(MCLevel):
startTime = datetime.now()
if(not isinstance(sourceLevel, MCInfdevOldLevel)):
blocksCopied = self.copyBlocksFromFinite(sourceLevel, sourceBox, destinationPoint, blocksToCopy)
self.copyBlocksFromFinite(sourceLevel, sourceBox, destinationPoint, blocksToCopy)
else: #uggh clone tool will still be slow if it weren't for schematics
filterTable = sourceLevel.materials.conversionTables[self.materials]
copyOffset = map(lambda x,y:x-y, destinationPoint, sourceBox.origin)
for s in itertools.product(*map(lambda x:range(x[0], x[0]+x[1]), zip(sourceBox.origin, sourceBox.size))):
destX, destZ, destY = copyOffset[0]+s[0], copyOffset[2]+s[2], copyOffset[1]+s[1]
destChunkX,destChunkZ = destX>>4,destZ>>4
destBlockX = destX & 0xf
destBlockZ = destZ & 0xf
try:
chunk = self.getChunk( destChunkX,destChunkZ )
blocks=chunk.Blocks
blockType = sourceLevel.blockAt(*s)
blockType = filterTable[blockType]
if not (blocksToCopy is None) and not (blockType in blocksToCopy): continue
blocks[destBlockX,destBlockZ,destY] = blockType
self.setBlockDataAt(destX, destY, destZ, sourceLevel.blockDataAt(*s))
except ChunkNotPresent, e:
continue;
else:
chunk.chunkChanged();
blocksCopied += 1;
else:
self.copyBlocksFromInfinite(sourceLevel, sourceBox, destinationPoint, blocksToCopy)
self.copyEntitiesFrom(sourceLevel, sourceBox, destinationPoint)
info( "Duration: {0}".format(datetime.now()-startTime) )
#self.saveInPlace()