Refactor RotationTransform, create SelectionTransform

This commit is contained in:
David Vierra 2015-10-02 14:01:08 -10:00
parent c96a8565bc
commit 986a4fb4fe

View File

@ -9,6 +9,7 @@ import itertools
import numpy as np
from mceditlib.cachefunc import lru_cache_object
from mceditlib.geometry import Vector
from mceditlib.multi_block import getBlocks
from mceditlib.selection import BoundingBox
log = logging.getLogger(__name__)
@ -91,45 +92,20 @@ def npRotate(axis, angle):
return rotate
class RotatedSection(object):
class TransformedSection(object):
def __init__(self, transform, cx, cy, cz):
self.transform = transform
self.cx = cx
self.Y = cy
self.cz = cz
shape = (16, 16, 16)
self.Blocks = np.zeros(shape, dtype='uint16')
self.Data = np.zeros(shape, dtype='uint8')
y, z, x = np.indices(shape)
x += (cx << 4)
y += (cy << 4)
z += (cz << 4)
w = np.ones(x.shape)
x = x.ravel()
y = y.ravel()
z = z.ravel()
w = w.ravel()
coords = np.vstack([x, y, z, w]).T
transformed_coords = coords * self.transform.matrix
transformed_coords = np.floor(transformed_coords).astype('int32')
x, y, z, w = transformed_coords.T
result = self.transform.dimension.getBlocks(x, y, z, return_Data=True)
self.Blocks[:] = result.Blocks.reshape(shape)
self.Data[:] = result.Data.reshape(shape)
self.transform.initSection(self)
@property
def blocktypes(self):
return self.transform.blocktypes
class RotatedChunk(object):
class TransformedChunk(object):
def __init__(self, transform, cx, cz):
self.transform = self.dimension = transform
self.cx = cx
@ -152,25 +128,19 @@ class RotatedChunk(object):
def blocktypes(self):
return self.transform.blocktypes
class RotationTransform(object):
def __init__(self, dimension, anchor, rotX, rotY, rotZ):
self.rotX = rotX
self.rotY = rotY
self.rotZ = rotZ
self.anchor = anchor
class DimensionTransformBase(object):
def __init__(self, dimension):
self.dimension = dimension
self.matrix = rotationMatrix(anchor, rotX, rotY, rotZ)
self._transformedBounds = transformBounds(dimension.bounds, self.matrix)
self.sectionCache = lru_cache_object(self._createSection, 1000)
_transformedBounds = NotImplemented
def _createSection(self, cx, cy, cz):
return RotatedSection(self, cx, cy, cz)
return TransformedSection(self, cx, cy, cz)
def getChunk(self, cx, cz):
return RotatedChunk(self, cx, cz)
return TransformedChunk(self, cx, cz)
def chunkCount(self):
return self.bounds.chunkCount
@ -191,4 +161,86 @@ class RotationTransform(object):
@property
def bounds(self):
return self._transformedBounds
return self._transformedBounds
def getBlocks(self, x, y, z,
return_Blocks=True,
return_Data=False,
return_BlockLight=False,
return_SkyLight=False,
return_Biomes=False):
return getBlocks(self, x, y, z,
return_Blocks,
return_Data,
return_BlockLight,
return_SkyLight,
return_Biomes)
class SelectionTransform(DimensionTransformBase):
def __init__(self, dimension, selection):
"""
:param dimension:
:type dimension:
:param selection:
:type selection: SelectionBox
:return:
:rtype:
"""
super(SelectionTransform, self).__init__(dimension)
self._transformedBounds = selection
def initSection(self, section):
shape = (16, 16, 16)
cx, cy, cz = section.cx, section.Y, section.cz
section.Blocks = np.zeros(shape, dtype='uint16')
section.Data = np.zeros(shape, dtype='uint8')
if self.dimension.containsChunk(cx, cz):
chunk = self.dimension.getChunk(cx, cz)
baseSection = chunk.getSection(cy)
if baseSection is not None:
sectionMask = self._transformedBounds.section_mask(cx, cy, cz)
section.Blocks[sectionMask] = baseSection.Blocks[sectionMask]
section.Data[sectionMask] = baseSection.Data[sectionMask]
class DimensionTransform(DimensionTransformBase):
def __init__(self, dimension, anchor, rotX, rotY, rotZ):
super(DimensionTransform, self).__init__(dimension)
self.rotX = rotX
self.rotY = rotY
self.rotZ = rotZ
self.anchor = anchor
self.matrix = rotationMatrix(anchor, rotX, rotY, rotZ)
self._transformedBounds = transformBounds(dimension.bounds, self.matrix)
def initSection(self, section):
shape = (16, 16, 16)
section.Blocks = np.zeros(shape, dtype='uint16')
section.Data = np.zeros(shape, dtype='uint8')
y, z, x = np.indices(shape)
x += (section.cx << 4)
y += (section.Y << 4)
z += (section.cz << 4)
w = np.ones(x.shape)
x = x.ravel()
y = y.ravel()
z = z.ravel()
w = w.ravel()
coords = np.vstack([x, y, z, w]).T
transformed_coords = coords * self.matrix
transformed_coords = np.floor(transformed_coords).astype('int32')
x, y, z, w = transformed_coords.T
result = self.dimension.getBlocks(x, y, z, return_Data=True)
section.Blocks[:] = result.Blocks.reshape(shape)
section.Data[:] = result.Data.reshape(shape)