Last active
December 27, 2015 08:49
-
-
Save egamble/7299765 to your computer and use it in GitHub Desktop.
Modified version of the MCEdit smoothing filter https://github.com/mcedit/mcedit/blob/master/filters/smooth.py. This version smooths under water correctly, uses the surrounding terrain blocks for fill, and both raises and lowers terrain correctly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from numpy import zeros, array | |
import itertools | |
from pymclevel.level import extractHeights | |
terrainBlocktypes = [1, 2, 3, 7, 12, 13, 14, 15, 16, 24, 56, 73, 74, 82, 87, 88, 89] | |
terrainBlockmask = zeros((256,), dtype='bool') | |
terrainBlockmask[terrainBlocktypes] = True | |
inputs = ( | |
("Repeat count", (1, 50)), | |
) | |
def perform(level, box, options): | |
if box.volume > 16000000: | |
raise ValueError("Volume too big for this filter method!") | |
repeatCount = options["Repeat count"] | |
schema = level.extractSchematic(box) | |
schema.removeEntitiesInBox(schema.bounds) | |
schema.removeTileEntitiesInBox(schema.bounds) | |
for i in xrange(repeatCount): | |
terrainBlocks = terrainBlockmask[schema.Blocks] | |
heightmap = extractHeights(terrainBlocks) | |
newHeightmap = (heightmap[1:-1, 1:-1] + (heightmap[0:-2, 1:-1] + heightmap[2:, 1:-1] + heightmap[1:-1, 0:-2] + heightmap[1:-1, 2:]) * 0.7) / 3.8 | |
newHeightmap += 0.5 | |
newHeightmap[newHeightmap < 0] = 0 | |
newHeightmap[newHeightmap > schema.Height] = schema.Height | |
newHeightmap = array(newHeightmap, dtype='uint16') | |
for x, z in itertools.product(xrange(1, schema.Width - 1), xrange(1, schema.Length - 1)): | |
oh = heightmap[x, z] | |
nh = newHeightmap[x - 1, z - 1] | |
column = array(schema.Blocks[x, z]) | |
# fill with terrain blocks from whichever adjacent column is at least as high | |
if nh > oh: | |
if terrainBlocks[x-1, z, nh] != 0: | |
column[oh:nh] = schema.Blocks[x-1, z][oh:nh] | |
elif terrainBlocks[x+1, z, nh] != 0: | |
column[oh:nh] = schema.Blocks[x+1, z][oh:nh] | |
elif terrainBlocks[x, z-1, nh] != 0: | |
column[oh:nh] = schema.Blocks[x, z-1][oh:nh] | |
elif terrainBlocks[x, z+1, nh] != 0: | |
column[oh:nh] = schema.Blocks[x, z+1][oh:nh] | |
column[nh:oh] = 0 # clear removed terrain blocks | |
column[nh:63] = 8 # fill with water from new height up to sea level | |
schema.Blocks[x, z] = column | |
level.copyBlocksFrom(schema, schema.bounds, box.origin) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment