Pull masklevel.py, modes.py, shapes.py out of brush/__init__.py
Move shapes out of shapewidget.py, too.
This commit is contained in:
parent
b420e29613
commit
b482e8d952
@ -4,22 +4,19 @@
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
import logging
|
||||
|
||||
from PySide import QtGui, QtCore
|
||||
import numpy
|
||||
from PySide import QtGui
|
||||
|
||||
from mcedit2.editortools import EditorTool
|
||||
from mcedit2.command import SimplePerformCommand
|
||||
from mcedit2.editortools.brush.masklevel import FakeBrushSection
|
||||
from mcedit2.editortools.brush.modes import BrushModes
|
||||
from mcedit2.rendering import worldscene, scenegraph
|
||||
from mcedit2.rendering.depths import DepthOffset
|
||||
from mcedit2.util.load_ui import load_ui, registerCustomWidget
|
||||
from mcedit2.util.settings import Settings
|
||||
from mcedit2.util.showprogress import showProgress
|
||||
from mcedit2.util.worldloader import WorldLoader
|
||||
from mcedit2.widgets.blockpicker import BlockTypeButton
|
||||
from mcedit2.widgets.layout import Row, Column
|
||||
from mceditlib.anvil.biome_types import BiomeTypes
|
||||
from mceditlib.geometry import Vector
|
||||
from mceditlib.selection import ShapedSelection, BoundingBox
|
||||
from mceditlib.selection import ShapedSelection
|
||||
from mceditlib.util import exhaust
|
||||
|
||||
|
||||
@ -47,9 +44,9 @@ class BrushCommand(SimplePerformCommand):
|
||||
self.points = points
|
||||
|
||||
self.brushSize = options['brushSize']
|
||||
self.brushStyle = options['brushStyle']
|
||||
self.brushShape = options['brushShape']
|
||||
self.brushMode = options['brushMode']
|
||||
self.setText("%s %s Brush" % (self.brushMode.name, self.brushStyle.ID))
|
||||
self.setText("%s %s Brush" % (self.brushMode.name, self.brushShape.ID))
|
||||
|
||||
if max(self.brushSize) > BrushTool.maxBrushSize:
|
||||
self.brushSize = (BrushTool.maxBrushSize,) * 3
|
||||
@ -74,7 +71,7 @@ class BrushCommand(SimplePerformCommand):
|
||||
yield 0, len(self.points), "Applying {0} brush...".format(self.brushMode.name)
|
||||
try:
|
||||
#xxx combine selections
|
||||
selections = [ShapedSelection(self.brushMode.brushBoxForPoint(point, self.options), self.brushStyle.shapeFunc) for point in self.points]
|
||||
selections = [ShapedSelection(self.brushMode.brushBoxForPoint(point, self.options), self.brushShape.shapeFunc) for point in self.points]
|
||||
self.brushMode.applyToSelections(self, selections)
|
||||
except NotImplementedError:
|
||||
for i, point in enumerate(self.points):
|
||||
@ -88,245 +85,6 @@ class BrushCommand(SimplePerformCommand):
|
||||
self.performed = True
|
||||
|
||||
|
||||
class BrushMode(QtCore.QObject):
|
||||
optionsWidget = None
|
||||
|
||||
def brushBoundingBox(self, center, options={}):
|
||||
# Return a box of size options['brushSize'] centered around point.
|
||||
# also used to position the preview cursor
|
||||
size = options['brushSize']
|
||||
x, y, z = size
|
||||
origin = Vector(*center) - (Vector(x, y, z) / 2) + Vector((x % 2) * 0.5, (y % 2) * 0.5, (z % 2) * 0.5)
|
||||
return BoundingBox(origin, size)
|
||||
|
||||
def applyToPoint(self, command, point):
|
||||
"""
|
||||
Called by BrushCommand for brush modes that can't be implemented using applyToChunk
|
||||
:type point: Vector
|
||||
:type command: BrushCommand
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def applyToSelections(self, command, selections):
|
||||
"""
|
||||
Called by BrushCommand to apply this brush mode to the given selection. Selection is generated
|
||||
by calling
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def createOptionsWidget(self, brushTool):
|
||||
return None
|
||||
|
||||
def createCursorLevel(self, brushTool):
|
||||
return None
|
||||
|
||||
class Fill(BrushMode):
|
||||
name = "fill"
|
||||
|
||||
def __init__(self):
|
||||
super(Fill, self).__init__()
|
||||
self.displayName = self.tr("Fill")
|
||||
|
||||
def createOptionsWidget(self, brushTool):
|
||||
if self.optionsWidget:
|
||||
return self.optionsWidget
|
||||
|
||||
self.optionsWidget = QtGui.QWidget()
|
||||
label = QtGui.QLabel(self.tr("Fill Block:"))
|
||||
self.blockTypeButton = BlockTypeButton()
|
||||
self.blockTypeButton.editorSession = brushTool.editorSession
|
||||
self.blockTypeButton.block = brushTool.editorSession.worldEditor.blocktypes['minecraft:stone']
|
||||
self.blockTypeButton.blocksChanged.connect(brushTool.updateCursor)
|
||||
|
||||
self.optionsWidget.setLayout(Column(
|
||||
Row(label, self.blockTypeButton, margin=0),
|
||||
None, margin=0))
|
||||
return self.optionsWidget
|
||||
|
||||
def getOptions(self):
|
||||
return {'blockInfo': self.blockTypeButton.block}
|
||||
|
||||
def applyToSelections(self, command, selections):
|
||||
"""
|
||||
|
||||
:type command: BrushCommand
|
||||
"""
|
||||
fill = command.editorSession.currentDimension.fillBlocksIter(selections[0], command.options['blockInfo'])
|
||||
showProgress("Applying brush...", fill)
|
||||
|
||||
def brushBoxForPoint(self, point, options):
|
||||
return self.brushBoundingBox(point, options)
|
||||
|
||||
def createCursorLevel(self, brushTool):
|
||||
selection = ShapedSelection(self.brushBoxForPoint((0, 0, 0), brushTool.options), brushTool.brushStyle.shapeFunc)
|
||||
cursorLevel = MaskLevel(selection,
|
||||
self.blockTypeButton.block,
|
||||
brushTool.editorSession.worldEditor.blocktypes)
|
||||
return cursorLevel
|
||||
|
||||
class Biome(BrushMode):
|
||||
name = "biome"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Biome, self).__init__(*args, **kwargs)
|
||||
self.displayName = self.tr("Biome")
|
||||
|
||||
def getOptions(self):
|
||||
return {'biomeID': self.biomeTypeBox.itemData(self.biomeTypeBox.currentIndex())}
|
||||
|
||||
def createOptionsWidget(self, brushTool):
|
||||
if self.optionsWidget:
|
||||
return self.optionsWidget
|
||||
|
||||
self.optionsWidget = QtGui.QWidget()
|
||||
label = QtGui.QLabel(self.tr("Fill Biome:"))
|
||||
self.biomeTypeBox = QtGui.QComboBox()
|
||||
self.biomeTypes = BiomeTypes()
|
||||
for biome in self.biomeTypes.types.values():
|
||||
self.biomeTypeBox.addItem(biome.name, biome.ID)
|
||||
|
||||
self.biomeTypeBox.activated.connect(brushTool.updateCursor)
|
||||
self.optionsWidget.setLayout(Column(Row(label, self.biomeTypeBox, margin=0), None, margin=0))
|
||||
return self.optionsWidget
|
||||
|
||||
def applyToSelections(self, command, selections):
|
||||
"""
|
||||
|
||||
:type command: BrushCommand
|
||||
"""
|
||||
#task = command.editorSession.currentDimension.fillBlocksIter(selections[0], command.blockInfo)
|
||||
#showProgress("Applying brush...", task)
|
||||
selection = selections[0]
|
||||
biomeID = command.options['biomeID']
|
||||
for x, _, z in selection.positions:
|
||||
command.editorSession.currentDimension.setBiomeID(x, z, biomeID)
|
||||
|
||||
def brushBoxForPoint(self, point, options):
|
||||
x, y, z = options['brushSize']
|
||||
options['brushSize'] = x, 1, z
|
||||
|
||||
return self.brushBoundingBox(point, options)
|
||||
|
||||
def createCursorLevel(self, brushTool):
|
||||
box = self.brushBoxForPoint((0, 0, 0), brushTool.options)
|
||||
|
||||
selection = ShapedSelection(box, brushTool.brushStyle.shapeFunc)
|
||||
cursorLevel = MaskLevel(selection,
|
||||
brushTool.editorSession.worldEditor.blocktypes["minecraft:grass"],
|
||||
brushTool.editorSession.worldEditor.blocktypes,
|
||||
biomeID=self.getOptions()['biomeID'])
|
||||
return cursorLevel
|
||||
|
||||
class BrushModes(object):
|
||||
# load from plugins here
|
||||
fill = Fill()
|
||||
biome = Biome()
|
||||
allModes = [fill, biome]
|
||||
modesByName = {mode.name: mode for mode in allModes}
|
||||
|
||||
|
||||
class Style(object):
|
||||
ID = NotImplemented
|
||||
icon = NotImplemented
|
||||
shapeFunc = NotImplemented
|
||||
|
||||
|
||||
NULL_ID = 255 # xxx
|
||||
|
||||
|
||||
class MaskLevel(object):
|
||||
def __init__(self, selection, fillBlock, blocktypes, biomeID=None):
|
||||
"""
|
||||
Level emulator to be used for rendering brushes and selections.
|
||||
|
||||
:type selection: mceditlib.selection.ShapedSelection
|
||||
:param selection:
|
||||
:param fillBlock:
|
||||
:param blocktypes:
|
||||
"""
|
||||
self.bounds = self.selection = selection
|
||||
|
||||
self.blocktypes = blocktypes
|
||||
self.sectionCache = {}
|
||||
self.fillBlock = fillBlock
|
||||
self.biomeID = biomeID
|
||||
self.filename = "Temporary Level (%s %s %s)" % (selection, fillBlock, blocktypes)
|
||||
|
||||
def chunkPositions(self):
|
||||
return self.bounds.chunkPositions()
|
||||
|
||||
def getChunk(self, cx, cz, create=False):
|
||||
return FakeBrushChunk(self, cx, cz, self.biomeID)
|
||||
|
||||
def containsChunk(self, cx, cz):
|
||||
return self.bounds.containsChunk(cx, cz)
|
||||
|
||||
class FakeBrushSection(object):
|
||||
BlockLight = numpy.empty((16, 16, 16), dtype=numpy.uint8)
|
||||
BlockLight[:] = 15
|
||||
SkyLight = numpy.empty((16, 16, 16), dtype=numpy.uint8)
|
||||
SkyLight[:] = 15
|
||||
pass
|
||||
|
||||
class FakeBrushChunk(object):
|
||||
Entities = ()
|
||||
TileEntities = ()
|
||||
|
||||
def __init__(self, world, cx, cz, biomeID=None):
|
||||
"""
|
||||
|
||||
:type world: MaskLevel
|
||||
"""
|
||||
self.dimension = world
|
||||
self.cx = cx
|
||||
self.cz = cz
|
||||
self.Biomes = numpy.zeros((16, 16), numpy.uint8)
|
||||
if biomeID:
|
||||
self.Biomes[:] = biomeID
|
||||
|
||||
@property
|
||||
def blocktypes(self):
|
||||
return self.dimension.blocktypes
|
||||
|
||||
@property
|
||||
def chunkPosition(self):
|
||||
return self.cx, self.cz
|
||||
|
||||
def sectionPositions(self):
|
||||
return self.dimension.selection.sectionPositions(self.cx, self.cz)
|
||||
|
||||
@property
|
||||
def bounds(self):
|
||||
return BoundingBox((self.cx << 4, self.dimension.bounds.miny, self.cz << 4),
|
||||
(16, self.dimension.bounds.height, 16))
|
||||
|
||||
|
||||
_sentinel = object()
|
||||
|
||||
def getSection(self, y, create=False):
|
||||
selection = self.dimension.selection
|
||||
sectionCache = self.dimension.sectionCache
|
||||
fillBlock = self.dimension.fillBlock
|
||||
cx, cz = self.chunkPosition
|
||||
|
||||
section = sectionCache.get((cx, y, cz), self._sentinel)
|
||||
if section is self._sentinel:
|
||||
mask = selection.section_mask(cx, y, cz)
|
||||
if mask is None:
|
||||
sectionCache[cx, y, cz] = None
|
||||
return None
|
||||
|
||||
section = FakeBrushSection()
|
||||
section.Y = y
|
||||
if fillBlock.ID:
|
||||
section.Blocks = numpy.array([0, fillBlock.ID], dtype=numpy.uint16)[mask.astype(numpy.uint8)]
|
||||
section.Data = numpy.array([0, fillBlock.meta], dtype=numpy.uint8)[mask.astype(numpy.uint8)]
|
||||
else:
|
||||
section.Blocks = numpy.array([0, NULL_ID])[mask.astype(numpy.uint8)]
|
||||
|
||||
sectionCache[cx, y, cz] = section
|
||||
|
||||
return section
|
||||
|
||||
class BrushTool(EditorTool):
|
||||
name = "Brush"
|
||||
@ -336,6 +94,8 @@ class BrushTool(EditorTool):
|
||||
def __init__(self, editorSession, *args, **kwargs):
|
||||
super(BrushTool, self).__init__(editorSession, *args, **kwargs)
|
||||
self.toolWidget = load_ui("editortools/brush.ui")
|
||||
self.brushMode = None
|
||||
self.brushLoader = None
|
||||
|
||||
BrushModeSetting.connectAndCall(self.modeSettingChanged)
|
||||
|
||||
@ -361,6 +121,7 @@ class BrushTool(EditorTool):
|
||||
self.toolWidget.zSpinSlider.setValue(self.brushSize[2])
|
||||
|
||||
_brushSize = (0, 0, 0)
|
||||
|
||||
@property
|
||||
def brushSize(self):
|
||||
return self._brushSize
|
||||
@ -406,7 +167,7 @@ class BrushTool(EditorTool):
|
||||
@property
|
||||
def options(self):
|
||||
options = {'brushSize': self.brushSize,
|
||||
'brushStyle': self.brushStyle,
|
||||
'brushShape': self.brushShape,
|
||||
'brushMode': self.brushMode}
|
||||
options.update(self.brushMode.getOptions())
|
||||
return options
|
||||
@ -420,9 +181,8 @@ class BrushTool(EditorTool):
|
||||
if widget:
|
||||
stack.addWidget(widget)
|
||||
|
||||
|
||||
@property
|
||||
def brushStyle(self):
|
||||
def brushShape(self):
|
||||
return self.toolWidget.brushShapeInput.currentShape
|
||||
|
||||
def updateCursor(self):
|
||||
@ -441,6 +201,7 @@ class BrushTool(EditorTool):
|
||||
self.brushLoader.timer.start()
|
||||
|
||||
|
||||
# xxx button palette?
|
||||
@registerCustomWidget
|
||||
class BrushModeWidget(QtGui.QComboBox):
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
108
src/mcedit2/editortools/brush/masklevel.py
Normal file
108
src/mcedit2/editortools/brush/masklevel.py
Normal file
@ -0,0 +1,108 @@
|
||||
"""
|
||||
masklevel
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
import numpy
|
||||
|
||||
from mceditlib.selection import BoundingBox
|
||||
|
||||
import logging
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
NULL_ID = 255 # xxx WHAT IS THIS FOR?
|
||||
|
||||
|
||||
class MaskLevel(object):
|
||||
def __init__(self, selection, fillBlock, blocktypes, biomeID=None):
|
||||
"""
|
||||
Level emulator to be used for rendering brushes and selections.
|
||||
|
||||
:type selection: mceditlib.selection.ShapedSelection
|
||||
:param selection:
|
||||
:param fillBlock:
|
||||
:param blocktypes:
|
||||
"""
|
||||
self.bounds = self.selection = selection
|
||||
|
||||
self.blocktypes = blocktypes
|
||||
self.sectionCache = {}
|
||||
self.fillBlock = fillBlock
|
||||
self.biomeID = biomeID
|
||||
self.filename = "Temporary Level (%s %s %s)" % (selection, fillBlock, blocktypes)
|
||||
|
||||
def chunkPositions(self):
|
||||
return self.bounds.chunkPositions()
|
||||
|
||||
def getChunk(self, cx, cz, create=False):
|
||||
return FakeBrushChunk(self, cx, cz, self.biomeID)
|
||||
|
||||
def containsChunk(self, cx, cz):
|
||||
return self.bounds.containsChunk(cx, cz)
|
||||
|
||||
|
||||
class FakeBrushSection(object):
|
||||
BlockLight = numpy.empty((16, 16, 16), dtype=numpy.uint8)
|
||||
BlockLight[:] = 15
|
||||
SkyLight = numpy.empty((16, 16, 16), dtype=numpy.uint8)
|
||||
SkyLight[:] = 15
|
||||
pass
|
||||
|
||||
|
||||
class FakeBrushChunk(object):
|
||||
Entities = ()
|
||||
TileEntities = ()
|
||||
|
||||
def __init__(self, world, cx, cz, biomeID=None):
|
||||
"""
|
||||
|
||||
:type world: mcedit2.editortools.brush.masklevel.MaskLevel
|
||||
"""
|
||||
self.dimension = world
|
||||
self.cx = cx
|
||||
self.cz = cz
|
||||
self.Biomes = numpy.zeros((16, 16), numpy.uint8)
|
||||
if biomeID:
|
||||
self.Biomes[:] = biomeID
|
||||
|
||||
@property
|
||||
def blocktypes(self):
|
||||
return self.dimension.blocktypes
|
||||
|
||||
@property
|
||||
def chunkPosition(self):
|
||||
return self.cx, self.cz
|
||||
|
||||
def sectionPositions(self):
|
||||
return self.dimension.selection.sectionPositions(self.cx, self.cz)
|
||||
|
||||
@property
|
||||
def bounds(self):
|
||||
return BoundingBox((self.cx << 4, self.dimension.bounds.miny, self.cz << 4),
|
||||
(16, self.dimension.bounds.height, 16))
|
||||
|
||||
_sentinel = object()
|
||||
|
||||
def getSection(self, y, create=False):
|
||||
selection = self.dimension.selection
|
||||
sectionCache = self.dimension.sectionCache
|
||||
fillBlock = self.dimension.fillBlock
|
||||
cx, cz = self.chunkPosition
|
||||
|
||||
section = sectionCache.get((cx, y, cz), self._sentinel)
|
||||
if section is self._sentinel:
|
||||
mask = selection.section_mask(cx, y, cz)
|
||||
if mask is None:
|
||||
sectionCache[cx, y, cz] = None
|
||||
return None
|
||||
|
||||
section = FakeBrushSection()
|
||||
section.Y = y
|
||||
if fillBlock.ID:
|
||||
section.Blocks = numpy.array([0, fillBlock.ID], dtype=numpy.uint16)[mask.astype(numpy.uint8)]
|
||||
section.Data = numpy.array([0, fillBlock.meta], dtype=numpy.uint8)[mask.astype(numpy.uint8)]
|
||||
else:
|
||||
section.Blocks = numpy.array([0, NULL_ID])[mask.astype(numpy.uint8)]
|
||||
|
||||
sectionCache[cx, y, cz] = section
|
||||
|
||||
return section
|
156
src/mcedit2/editortools/brush/modes.py
Normal file
156
src/mcedit2/editortools/brush/modes.py
Normal file
@ -0,0 +1,156 @@
|
||||
"""
|
||||
modes
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
import logging
|
||||
from PySide import QtGui, QtCore
|
||||
from mcedit2.editortools.brush.masklevel import MaskLevel
|
||||
from mcedit2.util.showprogress import showProgress
|
||||
from mcedit2.widgets.blockpicker import BlockTypeButton
|
||||
from mcedit2.widgets.layout import Column, Row
|
||||
from mceditlib.anvil.biome_types import BiomeTypes
|
||||
from mceditlib.geometry import Vector
|
||||
from mceditlib.selection import ShapedSelection, BoundingBox
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
||||
class BrushMode(QtCore.QObject):
|
||||
optionsWidget = None
|
||||
|
||||
def brushBoundingBox(self, center, options={}):
|
||||
# Return a box of size options['brushSize'] centered around point.
|
||||
# also used to position the preview cursor
|
||||
size = options['brushSize']
|
||||
x, y, z = size
|
||||
origin = Vector(*center) - (Vector(x, y, z) / 2) + Vector((x % 2) * 0.5, (y % 2) * 0.5, (z % 2) * 0.5)
|
||||
return BoundingBox(origin, size)
|
||||
|
||||
def applyToPoint(self, command, point):
|
||||
"""
|
||||
Called by BrushCommand for brush modes that can't be implemented using applyToChunk
|
||||
:type point: Vector
|
||||
:type command: BrushCommand
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def applyToSelections(self, command, selections):
|
||||
"""
|
||||
Called by BrushCommand to apply this brush mode to the given selection. Selection is generated
|
||||
by calling
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def createOptionsWidget(self, brushTool):
|
||||
return None
|
||||
|
||||
def createCursorLevel(self, brushTool):
|
||||
return None
|
||||
|
||||
|
||||
class Fill(BrushMode):
|
||||
name = "fill"
|
||||
|
||||
def __init__(self):
|
||||
super(Fill, self).__init__()
|
||||
self.displayName = self.tr("Fill")
|
||||
|
||||
def createOptionsWidget(self, brushTool):
|
||||
if self.optionsWidget:
|
||||
return self.optionsWidget
|
||||
|
||||
self.optionsWidget = QtGui.QWidget()
|
||||
label = QtGui.QLabel(self.tr("Fill Block:"))
|
||||
self.blockTypeButton = BlockTypeButton()
|
||||
self.blockTypeButton.editorSession = brushTool.editorSession
|
||||
self.blockTypeButton.block = brushTool.editorSession.worldEditor.blocktypes['minecraft:stone']
|
||||
self.blockTypeButton.blocksChanged.connect(brushTool.updateCursor)
|
||||
|
||||
self.optionsWidget.setLayout(Column(
|
||||
Row(label, self.blockTypeButton, margin=0),
|
||||
None, margin=0))
|
||||
return self.optionsWidget
|
||||
|
||||
def getOptions(self):
|
||||
return {'blockInfo': self.blockTypeButton.block}
|
||||
|
||||
def applyToSelections(self, command, selections):
|
||||
"""
|
||||
|
||||
:type command: BrushCommand
|
||||
"""
|
||||
fill = command.editorSession.currentDimension.fillBlocksIter(selections[0], command.options['blockInfo'])
|
||||
showProgress("Applying brush...", fill)
|
||||
|
||||
def brushBoxForPoint(self, point, options):
|
||||
return self.brushBoundingBox(point, options)
|
||||
|
||||
def createCursorLevel(self, brushTool):
|
||||
selection = ShapedSelection(self.brushBoxForPoint((0, 0, 0), brushTool.options), brushTool.brushShape.shapeFunc)
|
||||
cursorLevel = MaskLevel(selection,
|
||||
self.blockTypeButton.block,
|
||||
brushTool.editorSession.worldEditor.blocktypes)
|
||||
return cursorLevel
|
||||
|
||||
|
||||
class Biome(BrushMode):
|
||||
name = "biome"
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Biome, self).__init__(*args, **kwargs)
|
||||
self.displayName = self.tr("Biome")
|
||||
|
||||
def getOptions(self):
|
||||
return {'biomeID': self.biomeTypeBox.itemData(self.biomeTypeBox.currentIndex())}
|
||||
|
||||
def createOptionsWidget(self, brushTool):
|
||||
if self.optionsWidget:
|
||||
return self.optionsWidget
|
||||
|
||||
self.optionsWidget = QtGui.QWidget()
|
||||
label = QtGui.QLabel(self.tr("Fill Biome:"))
|
||||
self.biomeTypeBox = QtGui.QComboBox()
|
||||
self.biomeTypes = BiomeTypes()
|
||||
for biome in self.biomeTypes.types.values():
|
||||
self.biomeTypeBox.addItem(biome.name, biome.ID)
|
||||
|
||||
self.biomeTypeBox.activated.connect(brushTool.updateCursor)
|
||||
self.optionsWidget.setLayout(Column(Row(label, self.biomeTypeBox, margin=0), None, margin=0))
|
||||
return self.optionsWidget
|
||||
|
||||
def applyToSelections(self, command, selections):
|
||||
"""
|
||||
|
||||
:type command: BrushCommand
|
||||
"""
|
||||
#task = command.editorSession.currentDimension.fillBlocksIter(selections[0], command.blockInfo)
|
||||
#showProgress("Applying brush...", task)
|
||||
selection = selections[0]
|
||||
biomeID = command.options['biomeID']
|
||||
for x, _, z in selection.positions:
|
||||
command.editorSession.currentDimension.setBiomeID(x, z, biomeID)
|
||||
|
||||
def brushBoxForPoint(self, point, options):
|
||||
x, y, z = options['brushSize']
|
||||
options['brushSize'] = x, 1, z
|
||||
|
||||
return self.brushBoundingBox(point, options)
|
||||
|
||||
def createCursorLevel(self, brushTool):
|
||||
box = self.brushBoxForPoint((0, 0, 0), brushTool.options)
|
||||
|
||||
selection = ShapedSelection(box, brushTool.brushShape.shapeFunc)
|
||||
cursorLevel = MaskLevel(selection,
|
||||
brushTool.editorSession.worldEditor.blocktypes["minecraft:grass"],
|
||||
brushTool.editorSession.worldEditor.blocktypes,
|
||||
biomeID=self.getOptions()['biomeID'])
|
||||
return cursorLevel
|
||||
|
||||
|
||||
class BrushModes(object):
|
||||
# load from plugins here
|
||||
fill = Fill()
|
||||
biome = Biome()
|
||||
allModes = [fill, biome]
|
||||
modesByName = {mode.name: mode for mode in allModes}
|
39
src/mcedit2/editortools/brush/shapes.py
Normal file
39
src/mcedit2/editortools/brush/shapes.py
Normal file
@ -0,0 +1,39 @@
|
||||
"""
|
||||
shapes
|
||||
"""
|
||||
from __future__ import absolute_import, division, print_function, unicode_literals
|
||||
import logging
|
||||
from mceditlib import selection
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BrushShape(object):
|
||||
ID = NotImplemented
|
||||
icon = NotImplemented
|
||||
shapeFunc = NotImplemented
|
||||
|
||||
class Round(BrushShape):
|
||||
ID = "Round"
|
||||
icon = "shapes/round.png"
|
||||
shapeFunc = staticmethod(selection.SphereShape)
|
||||
|
||||
|
||||
class Square(BrushShape):
|
||||
ID = "Square"
|
||||
icon = "shapes/square.png"
|
||||
shapeFunc = staticmethod(selection.BoxShape)
|
||||
|
||||
|
||||
class Diamond(BrushShape):
|
||||
ID = "Diamond"
|
||||
icon = "shapes/diamond.png"
|
||||
shapeFunc = staticmethod(selection.DiamondShape)
|
||||
|
||||
|
||||
|
||||
# load from plugins here, rename to selection shapes?
|
||||
allShapes = (Square(), Round(), Diamond())
|
||||
|
||||
def getShapes():
|
||||
return allShapes
|
@ -8,6 +8,7 @@ from OpenGL import GL
|
||||
from PySide import QtGui, QtCore
|
||||
|
||||
from mcedit2.editortools import EditorTool
|
||||
from mcedit2.editortools.brush import shapes
|
||||
from mcedit2.handles.boxhandle import BoxHandle
|
||||
from mcedit2.rendering import cubes
|
||||
from mcedit2.rendering.selection import SelectionScene, SelectionFaceNode
|
||||
@ -15,7 +16,6 @@ from mcedit2.util.load_ui import load_ui
|
||||
from mcedit2.util.glutils import gl
|
||||
from mcedit2.rendering.depths import DepthOffset
|
||||
from mcedit2.rendering import scenegraph, rendergraph
|
||||
from mcedit2.widgets import shapewidget
|
||||
from mcedit2.widgets.layout import Column
|
||||
from mcedit2.widgets.shapewidget import ShapeWidget
|
||||
from mceditlib import faces
|
||||
@ -282,8 +282,8 @@ class SelectionTool(EditorTool):
|
||||
showPreviousSelection = True
|
||||
|
||||
def createShapedSelection(self, box):
|
||||
if self.shapeInput.currentShape is shapewidget.Square:
|
||||
return box
|
||||
if self.shapeInput.currentShape is shapes.Square:
|
||||
return box # ugly hack
|
||||
else:
|
||||
return selection.ShapedSelection(box, self.shapeInput.currentShape.shapeFunc)
|
||||
|
||||
|
@ -5,11 +5,11 @@ from __future__ import absolute_import, division, print_function
|
||||
import logging
|
||||
import os
|
||||
from PySide import QtGui, QtCore
|
||||
from mcedit2.editortools.brush import BrushShapeSetting, Style
|
||||
from mcedit2.editortools.brush import BrushShapeSetting
|
||||
from mcedit2.editortools.brush.shapes import getShapes
|
||||
from mcedit2.util.load_ui import registerCustomWidget
|
||||
from mcedit2.util.resources import resourcePath
|
||||
from mcedit2.widgets import flowlayout
|
||||
from mceditlib import selection
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
@ -24,12 +24,13 @@ class ShapeWidget(QtGui.QWidget):
|
||||
actionGroup.setExclusive(True)
|
||||
iconBase = resourcePath("mcedit2/assets/mcedit2/icons")
|
||||
actions = {}
|
||||
for shape in Shapes.allShapes:
|
||||
for shape in getShapes():
|
||||
filename = os.path.join(iconBase, shape.icon)
|
||||
assert os.path.exists(filename), "%r does not exist" % filename
|
||||
icon = QtGui.QIcon(filename)
|
||||
if icon is None:
|
||||
raise ValueError("Failed to read shape icon file %s" % filename)
|
||||
|
||||
def _handler(shape):
|
||||
def handler():
|
||||
self.currentShape = shape
|
||||
@ -47,33 +48,12 @@ class ShapeWidget(QtGui.QWidget):
|
||||
actions[shape.ID] = action
|
||||
|
||||
self.setLayout(layout)
|
||||
currentID = BrushShapeSetting.value(Shapes.allShapes[0].ID)
|
||||
shapesByID = {shape.ID:shape for shape in Shapes.allShapes}
|
||||
currentID = BrushShapeSetting.value(getShapes()[0].ID)
|
||||
shapesByID = {shape.ID:shape for shape in getShapes()}
|
||||
actions[currentID].setChecked(True)
|
||||
|
||||
self.currentShape = shapesByID.get(currentID, Shapes.allShapes[0])
|
||||
self.currentShape = shapesByID.get(currentID, getShapes()[0])
|
||||
|
||||
shapeChanged = QtCore.Signal()
|
||||
|
||||
|
||||
class Round(Style):
|
||||
ID = "Round"
|
||||
icon = "shapes/round.png"
|
||||
shapeFunc = staticmethod(selection.SphereShape)
|
||||
|
||||
|
||||
class Square(Style):
|
||||
ID = "Square"
|
||||
icon = "shapes/square.png"
|
||||
shapeFunc = staticmethod(selection.BoxShape)
|
||||
|
||||
|
||||
class Diamond(Style):
|
||||
ID = "Diamond"
|
||||
icon = "shapes/diamond.png"
|
||||
shapeFunc = staticmethod(selection.DiamondShape)
|
||||
|
||||
|
||||
class Shapes(object):
|
||||
# load from plugins here, rename to selection shapes?
|
||||
allShapes = (Square(), Round(), Diamond())
|
||||
|
Reference in New Issue
Block a user