예제 #1
0
 def __init__(self, sch, **kw):
     GLPerspective.__init__(self, **kw)  # self, xmin= -32, xmax=32, ymin= -32, ymax=32, near= -1000, far=1000)
     self.far = 16000
     self.schematic = sch
     self.renderer = PreviewRenderer(sch)
     self.fboSize = (128, 128)
     self.root = self.get_root()
예제 #2
0
 def setupPreview(self, alpha=1.0):
     self.discardPreviewer()
     if self.level:
         self.previewRenderer = PreviewRenderer(self.level, alpha)
         self.previewRenderer.position = self.editor.renderer.position
         self.editor.addWorker(self.previewRenderer)
     else:
         self.editor.toolbar.selectTool(-1)
예제 #3
0
 def __init__(self, sch, **kw):
     GLPerspective.__init__(self, **kw)  # self, xmin= -32, xmax=32, ymin= -32, ymax=32, near= -1000, far=1000)
     self.p_margin = 0
     self.p_spacing = 0
     self.widget_index = 0
     self.set_position_modifiers()
     self.far = 16000
     self.schematic = sch
     self.renderer = PreviewRenderer(sch)
     self.fboSize = (128, 128)
     self.root = self.get_root()
예제 #4
0
 def __init__(self, sch, **kw):
     GLPerspective.__init__(self, **kw)  # self, xmin= -32, xmax=32, ymin= -32, ymax=32, near= -1000, far=1000)
     self.far = 16000
     self.schematic = sch
     self.renderer = PreviewRenderer(sch)
     self.fboSize = (128, 128)
     self.root = self.get_root()
예제 #5
0
 def setupPreview(self, alpha=1.0):
     self.discardPreviewer()
     if self.level:
         self.previewRenderer = PreviewRenderer(self.level, alpha)
         self.previewRenderer.position = self.editor.renderer.position
         self.editor.addWorker(self.previewRenderer)
     else:
         self.editor.toolbar.selectTool(-1)
예제 #6
0
 def __init__(self, sch, **kw):
     GLPerspective.__init__(self, **kw)  # self, xmin= -32, xmax=32, ymin= -32, ymax=32, near= -1000, far=1000)
     self.p_margin = 0
     self.p_spacing = 0
     self.widget_index = 0
     self.set_position_modifiers()
     self.far = 16000
     self.schematic = sch
     self.renderer = PreviewRenderer(sch)
     self.fboSize = (128, 128)
     self.root = self.get_root()
예제 #7
0
class CloneTool(EditorTool):
    surfaceBuild = True
    toolIconName = "clone"
    tooltipText = "Clone\nRight-click for options"
    level = None
    repeatCount = 1
    _scaleFactor = 1.0
    _chunkAlign = False

    @property
    def scaleFactor(self):
        return self._scaleFactor

    @scaleFactor.setter
    def scaleFactor(self, val):
        self.rescaleLevel(val)
        self._scaleFactor = val

    @property
    def chunkAlign(self):
        return self._chunkAlign

    @chunkAlign.setter
    def chunkAlign(self, value):
        self._chunkAlign = value
        self.alignDestPoint()

    def alignDestPoint(self):
        if self.destPoint is not None:
            x, y, z = self.destPoint
            self.destPoint = Vector((x >> 4) << 4, y, (z >> 4) << 4)

    placeImmediately = config.clone.placeImmediately.property()

    panelClass = CloneToolPanel
    color = (0.3, 1.0, 0.3, 0.19)

    def __init__(self, *args):
        self.rotation = 0

        EditorTool.__init__(self, *args)
        self.previewRenderer = None
        self.panel = None

        self.optionsPanel = CloneToolOptions(self)

        self.destPoint = None

        self.snapCloneKey = 0
        self.root = get_root()

    @property
    def statusText(self):
        if self.destPoint is None:
            return "Click to set this item down."
        if self.draggingFace is not None:
            return _("Mousewheel to move along the third axis. Hold {0} to only move along one axis.").format(
                _(config.keys.snapCloneToAxis.get())
            )

        return (
            "Click and drag to reposition the item. Double-click to pick it up. Click Clone or press Enter to confirm."
        )

    def quickNudge(self, nudge):
        if config.fastNudgeSettings.cloneWidth.get():
            return map(int.__mul__, nudge, self.selectionBox().size)
        nudgeWidth = config.fastNudgeSettings.cloneWidthNumber.get()
        return map(lambda x: x * nudgeWidth, nudge)

    copyAir = config.clone.copyAir.property()
    copyWater = config.clone.copyWater.property()
    copyBiomes = config.clone.copyBiomes.property()
    staticCommands = config.clone.staticCommands.property()
    moveSpawnerPos = config.clone.moveSpawnerPos.property()
    regenerateUUID = config.clone.regenerateUUID.property()

    def nudge(self, nudge):
        if self.destPoint is None:
            if self.selectionBox() is None:
                return
            self.destPoint = self.selectionBox().origin

        if self.chunkAlign:
            x, y, z = nudge
            nudge = x << 4, y, z << 4

        if self.editor.rightClickNudge:
            nudge = self.quickNudge(nudge)

        # self.panel.performButton.enabled = True
        self.destPoint = self.destPoint + nudge
        self.updateOffsets()

    def selectionChanged(self):
        if self.selectionBox() is not None and "CloneToolPanel" in str(self.panel):
            self.updateSchematic()
            self.updateOffsets()

    def updateOffsets(self):
        if self.panel and self.panel.useOffsetInput and self.destPoint is not None:
            self.panel.offsetInput.setCoords(self.destPoint - self.selectionBox().origin)

    def offsetChanged(self):
        if self.panel:
            if not self.panel.useOffsetInput:
                return
            box = self.selectionBox()
            if box is None:
                return

            delta = self.panel.offsetInput.coords
            self.destPoint = box.origin + delta

    def toolEnabled(self):
        return not (self.selectionBox() is None)

    def cancel(self):
        self.discardPreviewer()
        if self.panel:
            self.panel.parent.remove(self.panel)
            self.panel = None

        self.destPoint = None
        self.level = None
        self.originalLevel = None

    def toolReselected(self):
        self.pickUp()

    def safeToolDistance(self):
        return numpy.sqrt(sum([self.level.Width ** 2, self.level.Height ** 2, self.level.Length ** 2]))

    def toolSelected(self):
        box = self.selectionBox()
        if box is None:
            self.editor.toolbar.selectTool(-1)
            return

        if box.volume > self.maxBlocks:
            self.editor.mouseLookOff()
            alert(
                _("Selection exceeds {0:n} blocks. Increase the block buffer setting and try again.").format(
                    self.maxBlocks
                )
            )
            self.editor.toolbar.selectTool(-1)
            return

        self.rotation = 0
        self.repeatCount = 1
        self._scaleFactor = 1.0

        if self.placeImmediately:
            self.destPoint = box.origin
        else:
            self.destPoint = None

        self.updateSchematic()
        self.cloneCameraDistance = max(self.cloneCameraDistance, self.safeToolDistance())
        self.showPanel()

    cloneCameraDistance = 0

    @property
    def cameraDistance(self):
        return self.cloneCameraDistance

    @alertException
    def rescaleLevel(self, factor):
        # if self.level.cloneToolScaleFactor == newFactor:
        # return
        # oldfactor = self.level.cloneToolScaleFactor
        # factor = newFactor / oldfactor
        if factor == 1:
            self.level = self.originalLevel
            self.setupPreview()
            return

        oldshape = self.originalLevel.Blocks.shape
        blocks = self.originalLevel.Blocks
        data = self.originalLevel.Data

        roundedShape = oldshape

        newshape = map(lambda x: int(x * factor), oldshape)
        for i, part in enumerate(newshape):
            if part == 0:
                newshape[i] = 1
        xyzshape = newshape[0], newshape[2], newshape[1]
        newlevel = pymclevel.MCSchematic(xyzshape, mats=self.editor.level.materials)

        srcgrid = numpy.mgrid[
            0 : roundedShape[0] : 1.0 / factor, 0 : roundedShape[1] : 1.0 / factor, 0 : roundedShape[2] : 1.0 / factor
        ].astype("uint")
        dstgrid = numpy.mgrid[0 : newshape[0], 0 : newshape[1], 0 : newshape[2]].astype("uint")
        srcgrid = srcgrid[map(slice, dstgrid.shape)]
        dstgrid = dstgrid[map(slice, srcgrid.shape)]

        def copyArray(dest, src):
            dest[dstgrid[0], dstgrid[1], dstgrid[2]] = src[srcgrid[0], srcgrid[1], srcgrid[2]]

        copyArray(newlevel.Blocks, blocks)
        copyArray(newlevel.Data, data)

        self.level = newlevel
        self.setupPreview()

    #
    # """
    #        use array broadcasting to fill in the extra dimensions with copies of the
    #        existing ones, then later change the shape to "fold" the extras back
    #        into the original three
    #        """
    #        # if factor > 1.0:
    #        sourceSlice = slice(0, 1)
    #        destSlice = slice(None)
    #
    #        # if factor < 1.0:
    #
    #        destfactor = factor
    #        srcfactor = 1
    #        if factor < 1.0:
    #            destfactor = 1.0
    #            srcfactor = 1.0 / factor
    #
    #        intershape = newshape[0]/destfactor, destfactor, newshape[1]/destfactor, destfactor, newshape[2]/destfactor, destfactor
    #        srcshape = roundedShape[0]/srcfactor, srcfactor, roundedShape[1]/srcfactor, srcfactor, roundedShape[2]/srcfactor, srcfactor
    #
    #        newlevel = MCSchematic(xyzshape)
    #
    #        def copyArray(dest, src):
    #            dest.shape = intershape
    #            src.shape = srcshape
    #
    #            dest[:, destSlice, :, destSlice, :, destSlice] = src[:, sourceSlice, :, sourceSlice, :, sourceSlice]
    #            dest.shape = newshape
    #            src.shape = roundedShape
    #
    #        copyArray(newlevel.Blocks, blocks)
    #        copyArray(newlevel.Data, data)
    #
    #        newlevel.cloneToolScaleFactor = newFactor
    #

    @alertException
    def updateSchematic(self):
        # extract blocks
        with setWindowCaption("COPYING - "):
            self.editor.freezeStatus("Copying to clone buffer...")
            box = self.selectionBox()
            self.level = self.editor.level.extractSchematic(box)
            self.originalLevel = self.level
            # self.level.cloneToolScaleFactor = 1.0
            self.rescaleLevel(self.scaleFactor)
            self.setupPreview()

    def showPanel(self):
        if self.panel:
            self.panel.set_parent(None)

        self.panel = self.panelClass(self, self.editor)
        # self.panel.performButton.enabled = False

        #        max_height = self.tool.editor.mainViewport.height - self.tool.editor.toolbar.height - self.tool.editor.subwidgets[0].height
        self.panel.centery = (
            self.editor.mainViewport.height - self.editor.toolbar.height
        ) / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left
        self.editor.add(self.panel)

    def setupPreview(self, alpha=1.0):
        self.discardPreviewer()
        if self.level:
            self.previewRenderer = PreviewRenderer(self.level, alpha)
            self.previewRenderer.position = self.editor.renderer.position
            self.editor.addWorker(self.previewRenderer)
        else:
            self.editor.toolbar.selectTool(-1)

    @property
    def canRotateLevel(self):
        return not isinstance(self.level, (pymclevel.MCInfdevOldLevel, PocketWorld))

    def rotatedSelectionSize(self):
        if self.canRotateLevel:
            sizes = self.level.Blocks.shape
            return sizes[0], sizes[2], sizes[1]
        else:
            return self.level.size

    # ===========================================================================
    # def getSelectionRanges(self):
    #    return self.editor.selectionTool.selectionBox()
    #
    # ===========================================================================
    @staticmethod
    def getBlockAt():
        return None  # use level's blockAt

    def getReticleOrigin(self):
        # returns a new origin for the current selection, where the old origin is at the new selection's center.
        pos, direction = self.editor.blockFaceUnderCursor

        lev = self.editor.level
        size = self.rotatedSelectionSize()
        if not size:
            return
        if size[1] >= self.editor.level.Height:
            direction = (
                0,
                1,
                0,
            )  # always use the upward face whenever we're splicing full-height pieces, to avoid "jitter"

        # print size; raise SystemExit
        if any(direction) and pos[1] >= 0:
            x, y, z = map(lambda p, s, d: p - s / 2 + s * d / 2 + (d > 0), pos, size, direction)
        else:
            x, y, z = map(lambda p, s: p - s / 2, pos, size)

        if self.chunkAlign:
            x &= ~0xF
            z &= ~0xF

        sy = size[1]
        if sy > lev.Height:  # don't snap really tall stuff to the height
            return Vector(x, y, z)

        if y + sy > lev.Height:
            y = lev.Height - sy
        if y < 0:
            y = 0

        if not lev.Width == 0 and lev.Length == 0:
            sx = size[0]
            if x + sx > lev.Width:
                x = lev.Width - sx
            if x < 0:
                x = 0

            sz = size[2]
            if z + sz > lev.Length:
                z = lev.Length - sz
            if z < 0:
                z = 0

        return Vector(x, y, z)

    def getReticleBox(self):

        pos = self.getReticleOrigin()
        sizes = self.rotatedSelectionSize()

        if None is sizes:
            return

        return BoundingBox(pos, sizes)

    def getDestBox(self):
        selectionSize = self.rotatedSelectionSize()
        return BoundingBox(self.destPoint, selectionSize)

    def drawTerrainReticle(self):
        if self.level is None:
            return

        if self.destPoint is not None:
            destPoint = self.destPoint
            if self.draggingFace is not None:
                # debugDrawPoint()
                destPoint = self.draggingOrigin()

            self.drawTerrainPreview(destPoint)
        else:
            self.drawTerrainPreview(self.getReticleBox().origin)

    draggingColor = (0.77, 1.0, 0.55, 0.05)

    def drawToolReticle(self):
        if self.level is None:
            return

        GL.glPolygonOffset(DepthOffset.CloneMarkers, DepthOffset.CloneMarkers)

        color = self.color
        if self.destPoint is not None:
            color = (self.color[0], self.color[1], self.color[2], 0.06)
            box = self.getDestBox()
            if self.draggingFace is not None:
                o = list(self.draggingOrigin())
                s = list(box.size)
                for i in range(3):
                    if i == self.draggingFace >> 1:
                        continue
                    o[i] -= 1000
                    s[i] += 2000
                guideBox = BoundingBox(o, s)

                color = self.draggingColor
                GL.glColor(1.0, 1.0, 1.0, 0.33)
                with gl.glEnable(GL.GL_BLEND, GL.GL_TEXTURE_2D, GL.GL_DEPTH_TEST):
                    self.editor.sixteenBlockTex.bind()
                    drawFace(guideBox, self.draggingFace ^ 1)
        else:
            box = self.getReticleBox()
            if box is None:
                return
        self.drawRepeatedCube(box, color)

        GL.glPolygonOffset(DepthOffset.CloneReticle, DepthOffset.CloneReticle)
        if self.destPoint:
            box = self.getDestBox()
            if self.draggingFace is not None:
                face = self.draggingFace
                box = BoundingBox(self.draggingOrigin(), box.size)
            face, point = self.boxFaceUnderCursor(box)
            if face is not None:
                GL.glEnable(GL.GL_BLEND)
                GL.glDisable(GL.GL_DEPTH_TEST)

                GL.glColor(*self.color)
                drawFace(box, face)
                GL.glDisable(GL.GL_BLEND)
                GL.glEnable(GL.GL_DEPTH_TEST)

    def drawRepeatedCube(self, box, color):
        # draw several cubes according to the repeat count
        # it's not really sensible to repeat a crane because the origin point is literally out of this world.
        delta = box.origin - self.selectionBox().origin

        for i in range(self.repeatCount):
            self.editor.drawConstructionCube(box, color)
            box = BoundingBox(box.origin + delta, box.size)

    def drawToolMarkers(self):
        selectionBox = self.selectionBox()
        if selectionBox:
            widg = self.editor.find_widget(pygame.mouse.get_pos())
            try:
                if self.panel and (widg is self.panel.nudgeButton or widg.parent is self.panel.nudgeButton):
                    color = self.color
            except:
                try:
                    if self.panel and (
                        widg is self.panel.offsetInput.nudgeButton or widg.parent is self.panel.offsetInput.nudgeButton
                    ):
                        color = self.color
                except:
                    pass
            finally:
                try:
                    self.editor.drawConstructionCube(self.getDestBox(), color)
                except:
                    pass

    def sourceLevel(self):
        return self.level

    @alertException
    def rotate(self, amount=1, blocksOnly=False):
        if self.canRotateLevel:
            self.rotation += amount
            self.rotation &= 0x3
            for i in range(amount & 0x3):
                if blocksOnly:
                    self.level.rotateLeftBlocks()
                else:
                    self.level.rotateLeft()

            self.previewRenderer.level = self.level

    @alertException
    def roll(self, amount=1, blocksOnly=False):
        if self.canRotateLevel:
            for i in range(amount & 0x3):
                if blocksOnly:
                    self.level.rollBlocks()
                else:
                    self.level.roll()

            self.previewRenderer.level = self.level

    @alertException
    def flip(self, amount=1, blocksOnly=False):
        if self.canRotateLevel:
            for i in range(amount & 0x1):
                if blocksOnly:
                    self.level.flipVerticalBlocks()
                else:
                    self.level.flipVertical()
            self.previewRenderer.level = self.level

    @alertException
    def mirror(self, blocksOnly=False):
        if self.canRotateLevel:
            yaw = int(self.editor.mainViewport.yaw) % 360
            if (45 <= yaw < 135) or (225 < yaw <= 315):
                if blocksOnly:
                    self.level.flipEastWestBlocks()
                else:
                    self.level.flipEastWest()
            else:
                if blocksOnly:
                    self.level.flipNorthSouthBlocks()
                else:
                    self.level.flipNorthSouth()
            self.previewRenderer.level = self.level

    def option1(self):
        self.copyAir = not self.copyAir

    def option2(self):
        self.copyWater = not self.copyWater

    def option3(self):
        self.copyBiomes = not self.copyBiomes

    def option4(self):
        self.staticCommands = not self.staticCommands

    def option5(self):
        self.moveSpawnerPos = not self.moveSpawnerPos

    draggingFace = None
    draggingStartPoint = None

    def draggingOrigin(self):
        p = self._draggingOrigin()
        return p

    def _draggingOrigin(self):
        dragPos = map(int, map(numpy.floor, self.positionOnDraggingPlane()))
        delta = map(lambda s, e: e - int(numpy.floor(s)), self.draggingStartPoint, dragPos)

        if self.snapCloneKey == 1:
            ad = map(abs, delta)
            midx = ad.index(max(ad))
            d = [0, 0, 0]
            d[midx] = delta[midx]
            dragY = self.draggingFace >> 1
            d[dragY] = delta[dragY]
            delta = d

        p = self.destPoint + delta
        if self.chunkAlign:
            p = [i // 16 * 16 for i in p]
        return Vector(*p)

    def positionOnDraggingPlane(self):
        pos = self.editor.mainViewport.cameraPosition
        dim = self.draggingFace >> 1
        #        if key.get_mods() & KMOD_SHIFT:
        #            dim = self.findBestTrackingPlane(self.draggingFace)
        #
        distance = self.draggingStartPoint[dim] - pos[dim]
        distance += self.draggingY

        mouseVector = self.editor.mainViewport.mouseVector
        scale = distance / (mouseVector[dim] or 1)
        point = map(lambda a, b: a * scale + b, mouseVector, pos)
        return point

    draggingY = 0

    @alertException
    def mouseDown(self, evt, pos, direction):
        box = self.selectionBox()
        if not box:
            return
        self.draggingY = 0

        if self.destPoint is not None:
            if evt.num_clicks == 2:
                self.pickUp()
                return

            face, point = self.boxFaceUnderCursor(self.getDestBox())
            if face is not None:
                self.draggingFace = face
                self.draggingStartPoint = point

        else:
            self.destPoint = self.getReticleOrigin()

            if self.panel and self.panel.useOffsetInput:
                self.panel.offsetInput.setCoords(self.destPoint - box.origin)
            print "Destination: ", self.destPoint

    @alertException
    def mouseUp(self, evt, pos, direction):
        if self.draggingFace is not None:
            self.destPoint = self.draggingOrigin()
            self.updateOffsets()

        self.draggingFace = None
        self.draggingStartPoint = None

    def keyDown(self, evt):
        keyname = evt.dict.get("keyname", None) or self.root.getKey(evt)
        if keyname == config.keys.snapCloneToAxis.get():
            self.snapCloneKey = 1

    def keyUp(self, evt):
        keyname = evt.dict.get("keyname", None) or self.root.getKey(evt)
        if keyname == config.keys.snapCloneToAxis.get():
            self.snapCloneKey = 0

    def increaseToolReach(self):
        if self.draggingFace is not None:
            d = (1, -1)[self.draggingFace & 1]
            if self.draggingFace >> 1 != 1:  # xxxxx y
                d = -d
            self.draggingY += d
            x, y, z = self.editor.mainViewport.cameraPosition
            pos = [x, y, z]
            pos[self.draggingFace >> 1] += d
            self.editor.mainViewport.cameraPosition = tuple(pos)

        else:
            self.cloneCameraDistance = self.editor._incrementReach(self.cloneCameraDistance)
        return True

    def decreaseToolReach(self):
        if self.draggingFace is not None:
            d = (1, -1)[self.draggingFace & 1]
            if self.draggingFace >> 1 != 1:  # xxxxx y
                d = -d

            self.draggingY -= d
            x, y, z = self.editor.mainViewport.cameraPosition
            pos = [x, y, z]
            pos[self.draggingFace >> 1] -= d
            self.editor.mainViewport.cameraPosition = tuple(pos)

        else:
            self.cloneCameraDistance = self.editor._decrementReach(self.cloneCameraDistance)
        return True

    def resetToolReach(self):
        if self.draggingFace is not None:
            x, y, z = self.editor.mainViewport.cameraPosition
            pos = [x, y, z]
            pos[self.draggingFace >> 1] += (1, -1)[self.draggingFace & 1] * -self.draggingY
            self.editor.mainViewport.cameraPosition = tuple(pos)
            self.draggingY = 0

        else:
            self.cloneCameraDistance = max(self.editor.defaultCameraToolDistance, self.safeToolDistance())

        return True

    def pickUp(self):
        if self.destPoint is None:
            return

        box = self.selectionBox()

        # pick up the object. reset the tool distance to the object's distance from the camera
        d = map(lambda a, b, c: abs(a - b - c / 2), self.editor.mainViewport.cameraPosition, self.destPoint, box.size)
        self.cloneCameraDistance = numpy.sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2])
        self.destPoint = None
        # self.panel.performButton.enabled = False
        print "Picked up"

    @alertException
    def confirm(self):
        destPoint = self.destPoint
        if destPoint is None:
            return

        sourceLevel = self.sourceLevel()
        sourceBox = sourceLevel.bounds

        destLevel = self.editor.level
        op = CloneOperation(
            editor=self.editor,
            sourceLevel=sourceLevel,
            sourceBox=sourceBox,
            originSourceBox=self.selectionBox(),
            destLevel=destLevel,
            destPoint=self.destPoint,
            copyAir=self.copyAir,
            copyWater=self.copyWater,
            copyBiomes=self.copyBiomes,
            staticCommands=self.staticCommands,
            moveSpawnerPos=self.moveSpawnerPos,
            regenerateUUID=self.regenerateUUID,
            repeatCount=self.repeatCount,
        )

        self.editor.toolbar.selectTool(
            -1
        )  # deselect tool so that the clone tool's selection change doesn't update its schematic

        self.editor.addOperation(op)
        if op.canUndo:
            self.editor.addUnsavedEdit()

        dirtyBox = op.dirtyBox()
        if dirtyBox:
            self.editor.invalidateBox(dirtyBox)
        self.editor.renderer.invalidateChunkMarkers()

        self.editor.currentOperation = None

        self.destPoint = None
        self.level = None

    def discardPreviewer(self):
        if self.previewRenderer is None:
            return
        self.previewRenderer.stopWork()
        self.previewRenderer.discardAllChunks()
        self.editor.removeWorker(self.previewRenderer)
        self.previewRenderer = None
예제 #8
0
class CloneTool(EditorTool):
    surfaceBuild = True
    toolIconName = "clone"
    tooltipText = "Clone\nRight-click for options"
    level = None
    repeatCount = 1
    _scaleFactor = 1.0
    _chunkAlign = False

    @property
    def scaleFactor(self):
        return self._scaleFactor

    @scaleFactor.setter
    def scaleFactor(self, val):
        self.rescaleLevel(val)
        self._scaleFactor = val

    @property
    def chunkAlign(self):
        return self._chunkAlign

    @chunkAlign.setter
    def chunkAlign(self, value):
        self._chunkAlign = value
        self.alignDestPoint()

    def alignDestPoint(self):
        if self.destPoint is not None:
            x, y, z = self.destPoint
            self.destPoint = Vector((x >> 4) << 4, y, (z >> 4) << 4)

    placeImmediately = config.clone.placeImmediately.property()

    panelClass = CloneToolPanel
    color = (0.3, 1.0, 0.3, 0.19)

    def __init__(self, *args):
        self.rotation = 0

        EditorTool.__init__(self, *args)
        self.previewRenderer = None
        self.panel = None

        self.optionsPanel = CloneToolOptions(self)

        self.destPoint = None

        self.snapCloneKey = 0
        self.root = get_root()

    @property
    def statusText(self):
        if self.destPoint is None:
            return "Click to set this item down."
        if self.draggingFace is not None:
            return "Mousewheel to move along the third axis. Hold {0} to only move along one axis.".format(
                config.keys.snapCloneToAxis.get())

        return "Click and drag to reposition the item. Double-click to pick it up. Click Clone or press Enter to confirm."

    def quickNudge(self, nudge):
        if config.fastNudgeSettings.cloneWidth.get():
            return map(int.__mul__, nudge, self.selectionBox().size)
        nudgeWidth = config.fastNudgeSettings.cloneWidthNumber.get()
        return map(lambda x: x * nudgeWidth, nudge)

    copyAir = config.clone.copyAir.property()
    copyWater = config.clone.copyWater.property()
    copyBiomes = config.clone.copyBiomes.property()
    staticCommands = config.clone.staticCommands.property()
    moveSpawnerPos = config.clone.moveSpawnerPos.property()
    regenerateUUID = config.clone.regenerateUUID.property()

    def nudge(self, nudge):
        if self.destPoint is None:
            if self.selectionBox() is None:
                return
            self.destPoint = self.selectionBox().origin

        if self.chunkAlign:
            x, y, z = nudge
            nudge = x << 4, y, z << 4

        if self.editor.rightClickNudge:
            nudge = self.quickNudge(nudge)

        # self.panel.performButton.enabled = True
        self.destPoint = self.destPoint + nudge
        self.updateOffsets()

    def selectionChanged(self):
        if self.selectionBox() is not None and "CloneToolPanel" in str(
                self.panel):
            self.updateSchematic()
            self.updateOffsets()

    def updateOffsets(self):
        if self.panel and self.panel.useOffsetInput and self.destPoint is not None:
            self.panel.offsetInput.setCoords(self.destPoint -
                                             self.selectionBox().origin)

    def offsetChanged(self):
        if self.panel:
            if not self.panel.useOffsetInput:
                return
            box = self.selectionBox()
            if box is None:
                return

            delta = self.panel.offsetInput.coords
            self.destPoint = box.origin + delta

    def toolEnabled(self):
        return not (self.selectionBox() is None)

    def cancel(self):
        self.discardPreviewer()
        if self.panel:
            self.panel.parent.remove(self.panel)
            self.panel = None

        self.destPoint = None
        self.level = None
        self.originalLevel = None

    def toolReselected(self):
        self.pickUp()

    def safeToolDistance(self):
        return numpy.sqrt(
            sum([
                self.level.Width**2, self.level.Height**2, self.level.Length**2
            ]))

    def toolSelected(self):
        box = self.selectionBox()
        if box is None:
            self.editor.toolbar.selectTool(-1)
            return

        if box.volume > self.maxBlocks:
            self.editor.mouseLookOff()
            alert(
                _("Selection exceeds {0:n} blocks. Increase the block buffer setting and try again."
                  ).format(self.maxBlocks))
            self.editor.toolbar.selectTool(-1)
            return

        self.rotation = 0
        self.repeatCount = 1
        self._scaleFactor = 1.0

        if self.placeImmediately:
            self.destPoint = box.origin
        else:
            self.destPoint = None

        self.updateSchematic()
        self.cloneCameraDistance = max(self.cloneCameraDistance,
                                       self.safeToolDistance())
        self.showPanel()

    cloneCameraDistance = 0

    @property
    def cameraDistance(self):
        return self.cloneCameraDistance

    @alertException
    def rescaleLevel(self, factor):
        # if self.level.cloneToolScaleFactor == newFactor:
        # return
        # oldfactor = self.level.cloneToolScaleFactor
        # factor = newFactor / oldfactor
        if factor == 1:
            self.level = self.originalLevel
            self.setupPreview()
            return

        oldshape = self.originalLevel.Blocks.shape
        blocks = self.originalLevel.Blocks
        data = self.originalLevel.Data

        roundedShape = oldshape

        newshape = map(lambda x: int(x * factor), oldshape)
        for i, part in enumerate(newshape):
            if part == 0:
                newshape[i] = 1
        xyzshape = newshape[0], newshape[2], newshape[1]
        newlevel = pymclevel.MCSchematic(xyzshape,
                                         mats=self.editor.level.materials)

        srcgrid = numpy.mgrid[0:roundedShape[0]:1.0 / factor,
                              0:roundedShape[1]:1.0 / factor,
                              0:roundedShape[2]:1.0 / factor].astype('uint')
        dstgrid = numpy.mgrid[0:newshape[0], 0:newshape[1],
                              0:newshape[2]].astype('uint')
        srcgrid = srcgrid[map(slice, dstgrid.shape)]
        dstgrid = dstgrid[map(slice, srcgrid.shape)]

        def copyArray(dest, src):
            dest[dstgrid[0], dstgrid[1],
                 dstgrid[2]] = src[srcgrid[0], srcgrid[1], srcgrid[2]]

        copyArray(newlevel.Blocks, blocks)
        copyArray(newlevel.Data, data)

        self.level = newlevel
        self.setupPreview()

    #
    # """
    #        use array broadcasting to fill in the extra dimensions with copies of the
    #        existing ones, then later change the shape to "fold" the extras back
    #        into the original three
    #        """
    #        # if factor > 1.0:
    #        sourceSlice = slice(0, 1)
    #        destSlice = slice(None)
    #
    #        # if factor < 1.0:
    #
    #        destfactor = factor
    #        srcfactor = 1
    #        if factor < 1.0:
    #            destfactor = 1.0
    #            srcfactor = 1.0 / factor
    #
    #        intershape = newshape[0]/destfactor, destfactor, newshape[1]/destfactor, destfactor, newshape[2]/destfactor, destfactor
    #        srcshape = roundedShape[0]/srcfactor, srcfactor, roundedShape[1]/srcfactor, srcfactor, roundedShape[2]/srcfactor, srcfactor
    #
    #        newlevel = MCSchematic(xyzshape)
    #
    #        def copyArray(dest, src):
    #            dest.shape = intershape
    #            src.shape = srcshape
    #
    #            dest[:, destSlice, :, destSlice, :, destSlice] = src[:, sourceSlice, :, sourceSlice, :, sourceSlice]
    #            dest.shape = newshape
    #            src.shape = roundedShape
    #
    #        copyArray(newlevel.Blocks, blocks)
    #        copyArray(newlevel.Data, data)
    #
    #        newlevel.cloneToolScaleFactor = newFactor
    #

    @alertException
    def updateSchematic(self):
        # extract blocks
        with setWindowCaption("COPYING - "):
            self.editor.freezeStatus("Copying to clone buffer...")
            box = self.selectionBox()
            self.level = self.editor.level.extractSchematic(box)
            self.originalLevel = self.level
            # self.level.cloneToolScaleFactor = 1.0
            self.rescaleLevel(self.scaleFactor)
            self.setupPreview()

    def showPanel(self):
        if self.panel:
            self.panel.set_parent(None)

        self.panel = self.panelClass(self, self.editor)
        # self.panel.performButton.enabled = False

        #        max_height = self.tool.editor.mainViewport.height - self.tool.editor.toolbar.height - self.tool.editor.subwidgets[0].height
        self.panel.centery = (
            self.editor.mainViewport.height -
            self.editor.toolbar.height) / 2 + self.editor.subwidgets[0].height
        self.panel.left = self.editor.left
        self.editor.add(self.panel)

    def setupPreview(self, alpha=1.0):
        self.discardPreviewer()
        if self.level:
            self.previewRenderer = PreviewRenderer(self.level, alpha)
            self.previewRenderer.position = self.editor.renderer.position
            self.editor.addWorker(self.previewRenderer)
        else:
            self.editor.toolbar.selectTool(-1)

    @property
    def canRotateLevel(self):
        return not isinstance(self.level,
                              (pymclevel.MCInfdevOldLevel, PocketWorld))

    def rotatedSelectionSize(self):
        if self.canRotateLevel:
            sizes = self.level.Blocks.shape
            return sizes[0], sizes[2], sizes[1]
        else:
            return self.level.size

    # ===========================================================================
    # def getSelectionRanges(self):
    #    return self.editor.selectionTool.selectionBox()
    #
    # ===========================================================================
    @staticmethod
    def getBlockAt():
        return None  # use level's blockAt

    def getReticleOrigin(self):
        # returns a new origin for the current selection, where the old origin is at the new selection's center.
        pos, direction = self.editor.blockFaceUnderCursor

        lev = self.editor.level
        size = self.rotatedSelectionSize()
        if not size:
            return
        if size[1] >= self.editor.level.Height:
            direction = (
                0, 1, 0
            )  # always use the upward face whenever we're splicing full-height pieces, to avoid "jitter"

        # print size; raise SystemExit
        if any(direction) and pos[1] >= 0:
            x, y, z = map(lambda p, s, d: p - s / 2 + s * d / 2 + (d > 0), pos,
                          size, direction)
        else:
            x, y, z = map(lambda p, s: p - s / 2, pos, size)

        if self.chunkAlign:
            x &= ~0xf
            z &= ~0xf

        sy = size[1]
        if sy > lev.Height:  # don't snap really tall stuff to the height
            return Vector(x, y, z)

        if y + sy > lev.Height:
            y = lev.Height - sy
        if y < 0:
            y = 0

        if not isinstance(lev, pymclevel.MCInfdevOldLevel):
            sx = size[0]
            if x + sx > lev.Width:
                x = lev.Width - sx
            if x < 0:
                x = 0

            sz = size[2]
            if z + sz > lev.Length:
                z = lev.Length - sz
            if z < 0:
                z = 0

        return Vector(x, y, z)

    def getReticleBox(self):

        pos = self.getReticleOrigin()
        sizes = self.rotatedSelectionSize()

        if None is sizes:
            return

        return BoundingBox(pos, sizes)

    def getDestBox(self):
        selectionSize = self.rotatedSelectionSize()
        return BoundingBox(self.destPoint, selectionSize)

    def drawTerrainReticle(self):
        if self.level is None:
            return

        if self.destPoint is not None:
            destPoint = self.destPoint
            if self.draggingFace is not None:
                # debugDrawPoint()
                destPoint = self.draggingOrigin()

            self.drawTerrainPreview(destPoint)
        else:
            self.drawTerrainPreview(self.getReticleBox().origin)

    draggingColor = (0.77, 1.0, 0.55, 0.05)

    def drawToolReticle(self):
        if self.level is None:
            return

        GL.glPolygonOffset(DepthOffset.CloneMarkers, DepthOffset.CloneMarkers)

        color = self.color
        if self.destPoint is not None:
            color = (self.color[0], self.color[1], self.color[2], 0.06)
            box = self.getDestBox()
            if self.draggingFace is not None:
                o = list(self.draggingOrigin())
                s = list(box.size)
                for i in range(3):
                    if i == self.draggingFace >> 1:
                        continue
                    o[i] -= 1000
                    s[i] += 2000
                guideBox = BoundingBox(o, s)

                color = self.draggingColor
                GL.glColor(1.0, 1.0, 1.0, 0.33)
                with gl.glEnable(GL.GL_BLEND, GL.GL_TEXTURE_2D,
                                 GL.GL_DEPTH_TEST):
                    self.editor.sixteenBlockTex.bind()
                    drawFace(guideBox, self.draggingFace ^ 1)
        else:
            box = self.getReticleBox()
            if box is None:
                return
        self.drawRepeatedCube(box, color)

        GL.glPolygonOffset(DepthOffset.CloneReticle, DepthOffset.CloneReticle)
        if self.destPoint:
            box = self.getDestBox()
            if self.draggingFace is not None:
                face = self.draggingFace
                box = BoundingBox(self.draggingOrigin(), box.size)
            face, point = self.boxFaceUnderCursor(box)
            if face is not None:
                GL.glEnable(GL.GL_BLEND)
                GL.glDisable(GL.GL_DEPTH_TEST)

                GL.glColor(*self.color)
                drawFace(box, face)
                GL.glDisable(GL.GL_BLEND)
                GL.glEnable(GL.GL_DEPTH_TEST)

    def drawRepeatedCube(self, box, color):
        # draw several cubes according to the repeat count
        # it's not really sensible to repeat a crane because the origin point is literally out of this world.
        delta = box.origin - self.selectionBox().origin

        for i in range(self.repeatCount):
            self.editor.drawConstructionCube(box, color)
            box = BoundingBox(box.origin + delta, box.size)

    def drawToolMarkers(self):
        selectionBox = self.selectionBox()
        if selectionBox:
            widg = self.editor.find_widget(pygame.mouse.get_pos())
            try:
                if self.panel and (widg is self.panel.nudgeButton
                                   or widg.parent is self.panel.nudgeButton):
                    color = self.color
            except:
                try:
                    if self.panel and (
                            widg is self.panel.offsetInput.nudgeButton or
                            widg.parent is self.panel.offsetInput.nudgeButton):
                        color = self.color
                except:
                    pass
            finally:
                try:
                    self.editor.drawConstructionCube(self.getDestBox(), color)
                except:
                    pass

    def sourceLevel(self):
        return self.level

    @alertException
    def rotate(self, amount=1, blocksOnly=False):
        if self.canRotateLevel:
            self.rotation += amount
            self.rotation &= 0x3
            for i in range(amount & 0x3):
                if blocksOnly:
                    self.level.rotateLeftBlocks()
                else:
                    self.level.rotateLeft()

            self.previewRenderer.level = self.level

    @alertException
    def roll(self, amount=1, blocksOnly=False):
        if self.canRotateLevel:
            for i in range(amount & 0x3):
                if blocksOnly:
                    self.level.rollBlocks()
                else:
                    self.level.roll()

            self.previewRenderer.level = self.level

    @alertException
    def flip(self, amount=1, blocksOnly=False):
        if self.canRotateLevel:
            for i in range(amount & 0x1):
                if blocksOnly:
                    self.level.flipVertical()
                else:
                    self.level.flipVerticalBlocks()
            self.previewRenderer.level = self.level

    @alertException
    def mirror(self, blocksOnly=False):
        if self.canRotateLevel:
            yaw = int(self.editor.mainViewport.yaw) % 360
            if (45 <= yaw < 135) or (225 < yaw <= 315):
                if blocksOnly:
                    self.level.flipEastWestBlocks()
                else:
                    self.level.flipEastWest()
            else:
                if blocksOnly:
                    self.level.flipNorthSouthBlocks()
                else:
                    self.level.flipNorthSouth()
            self.previewRenderer.level = self.level

    def option1(self):
        self.copyAir = not self.copyAir

    def option2(self):
        self.copyWater = not self.copyWater

    def option3(self):
        self.copyBiomes = not self.copyBiomes

    def option4(self):
        self.staticCommands = not self.staticCommands

    def option5(self):
        self.moveSpawnerPos = not self.moveSpawnerPos

    draggingFace = None
    draggingStartPoint = None

    def draggingOrigin(self):
        p = self._draggingOrigin()
        return p

    def _draggingOrigin(self):
        dragPos = map(int, map(numpy.floor, self.positionOnDraggingPlane()))
        delta = map(lambda s, e: e - int(numpy.floor(s)),
                    self.draggingStartPoint, dragPos)

        if self.snapCloneKey == 1:
            ad = map(abs, delta)
            midx = ad.index(max(ad))
            d = [0, 0, 0]
            d[midx] = delta[midx]
            dragY = self.draggingFace >> 1
            d[dragY] = delta[dragY]
            delta = d

        p = self.destPoint + delta
        if self.chunkAlign:
            p = [i // 16 * 16 for i in p]
        return Vector(*p)

    def positionOnDraggingPlane(self):
        pos = self.editor.mainViewport.cameraPosition
        dim = self.draggingFace >> 1
        #        if key.get_mods() & KMOD_SHIFT:
        #            dim = self.findBestTrackingPlane(self.draggingFace)
        #
        distance = self.draggingStartPoint[dim] - pos[dim]
        distance += self.draggingY

        mouseVector = self.editor.mainViewport.mouseVector
        scale = distance / (mouseVector[dim] or 1)
        point = map(lambda a, b: a * scale + b, mouseVector, pos)
        return point

    draggingY = 0

    @alertException
    def mouseDown(self, evt, pos, direction):
        box = self.selectionBox()
        if not box:
            return
        self.draggingY = 0

        if self.destPoint is not None:
            if evt.num_clicks == 2:
                self.pickUp()
                return

            face, point = self.boxFaceUnderCursor(self.getDestBox())
            if face is not None:
                self.draggingFace = face
                self.draggingStartPoint = point

        else:
            self.destPoint = self.getReticleOrigin()

            if self.panel and self.panel.useOffsetInput:
                self.panel.offsetInput.setCoords(self.destPoint - box.origin)
            print "Destination: ", self.destPoint

    @alertException
    def mouseUp(self, evt, pos, direction):
        if self.draggingFace is not None:
            self.destPoint = self.draggingOrigin()

        self.draggingFace = None
        self.draggingStartPoint = None

    def keyDown(self, evt):
        keyname = evt.dict.get('keyname', None) or self.root.getKey(evt)
        if keyname == config.keys.snapCloneToAxis.get():
            self.snapCloneKey = 1

    def keyUp(self, evt):
        keyname = evt.dict.get('keyname', None) or self.root.getKey(evt)
        if keyname == config.keys.snapCloneToAxis.get():
            self.snapCloneKey = 0

    def increaseToolReach(self):
        if self.draggingFace is not None:
            d = (1, -1)[self.draggingFace & 1]
            if self.draggingFace >> 1 != 1:  # xxxxx y
                d = -d
            self.draggingY += d
            x, y, z = self.editor.mainViewport.cameraPosition
            pos = [x, y, z]
            pos[self.draggingFace >> 1] += d
            self.editor.mainViewport.cameraPosition = tuple(pos)

        else:
            self.cloneCameraDistance = self.editor._incrementReach(
                self.cloneCameraDistance)
        return True

    def decreaseToolReach(self):
        if self.draggingFace is not None:
            d = (1, -1)[self.draggingFace & 1]
            if self.draggingFace >> 1 != 1:  # xxxxx y
                d = -d

            self.draggingY -= d
            x, y, z = self.editor.mainViewport.cameraPosition
            pos = [x, y, z]
            pos[self.draggingFace >> 1] -= d
            self.editor.mainViewport.cameraPosition = tuple(pos)

        else:
            self.cloneCameraDistance = self.editor._decrementReach(
                self.cloneCameraDistance)
        return True

    def resetToolReach(self):
        if self.draggingFace is not None:
            x, y, z = self.editor.mainViewport.cameraPosition
            pos = [x, y, z]
            pos[self.draggingFace
                >> 1] += (1, -1)[self.draggingFace & 1] * -self.draggingY
            self.editor.mainViewport.cameraPosition = tuple(pos)
            self.draggingY = 0

        else:
            self.cloneCameraDistance = max(
                self.editor.defaultCameraToolDistance, self.safeToolDistance())

        return True

    def pickUp(self):
        if self.destPoint is None:
            return

        box = self.selectionBox()

        # pick up the object. reset the tool distance to the object's distance from the camera
        d = map(lambda a, b, c: abs(a - b - c / 2),
                self.editor.mainViewport.cameraPosition, self.destPoint,
                box.size)
        self.cloneCameraDistance = numpy.sqrt(d[0] * d[0] + d[1] * d[1] +
                                              d[2] * d[2])
        self.destPoint = None
        # self.panel.performButton.enabled = False
        print "Picked up"

    @alertException
    def confirm(self):
        destPoint = self.destPoint
        if destPoint is None:
            return

        sourceLevel = self.sourceLevel()
        sourceBox = sourceLevel.bounds

        destLevel = self.editor.level
        destVolume = BoundingBox(destPoint, sourceBox.size).volume
        op = CloneOperation(editor=self.editor,
                            sourceLevel=sourceLevel,
                            sourceBox=sourceBox,
                            originSourceBox=self.selectionBox(),
                            destLevel=destLevel,
                            destPoint=self.destPoint,
                            copyAir=self.copyAir,
                            copyWater=self.copyWater,
                            copyBiomes=self.copyBiomes,
                            staticCommands=self.staticCommands,
                            moveSpawnerPos=self.moveSpawnerPos,
                            regenerateUUID=self.regenerateUUID,
                            repeatCount=self.repeatCount)

        self.editor.toolbar.selectTool(
            -1
        )  # deselect tool so that the clone tool's selection change doesn't update its schematic

        self.editor.addOperation(op)
        if op.canUndo:
            self.editor.addUnsavedEdit()

        dirtyBox = op.dirtyBox()
        if dirtyBox:
            self.editor.invalidateBox(dirtyBox)
        self.editor.renderer.invalidateChunkMarkers()

        self.editor.currentOperation = None

        self.destPoint = None
        self.level = None

    def discardPreviewer(self):
        if self.previewRenderer is None:
            return
        self.previewRenderer.stopWork()
        self.previewRenderer.discardAllChunks()
        self.editor.removeWorker(self.previewRenderer)
        self.previewRenderer = None
예제 #9
0
class ThumbView(GLPerspective):
    def __init__(self, sch, **kw):
        GLPerspective.__init__(self, **kw)  # self, xmin= -32, xmax=32, ymin= -32, ymax=32, near= -1000, far=1000)
        self.far = 16000
        self.schematic = sch
        self.renderer = PreviewRenderer(sch)
        self.fboSize = (128, 128)
        self.root = self.get_root()
        # self.renderer.position = (sch.Length / 2, 0, sch.Height / 2)

    def setup_modelview(self):
        GLU.gluLookAt(-self.schematic.Width * 2.8, self.schematic.Height * 2.5 + 1, -self.schematic.Length * 1.5,
                      self.schematic.Width, 0, self.schematic.Length,
                      0, 1, 0)

    fbo = None

    def gl_draw_tex(self):
        self.clear()
        self.renderer.draw()

    def clear(self):
        if self.drawBackground:
            GL.glClearColor(0.25, 0.27, 0.77, 1.0)
        else:
            GL.glClearColor(0.0, 0.0, 0.0, 0.0)
        GL.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT)

    def gl_draw(self):
        if self.schematic.chunkCount > len(self.renderer.chunkRenderers):
            self.gl_draw_thumb()
        else:
            if self.fbo is None:
                w, h = self.fboSize
                self.fbo = FramebufferTexture(w, h, self.gl_draw_tex)
            GL.glMatrixMode(GL.GL_PROJECTION)
            GL.glLoadIdentity()
            GL.glMatrixMode(GL.GL_MODELVIEW)
            GL.glLoadIdentity()
            GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY)
            GL.glColor(1.0, 1.0, 1.0, 1.0)
            GL.glVertexPointer(2, GL.GL_FLOAT, 0, array([-1, -1,
                                                         - 1, 1,
                                                         1, 1,
                                                         1, -1, ], dtype='float32'))
            GL.glTexCoordPointer(2, GL.GL_FLOAT, 0, array([0, 0, 0, 256, 256, 256, 256, 0], dtype='float32'))
            e = (GL.GL_TEXTURE_2D,)
            if not self.drawBackground:
                e += (GL.GL_ALPHA_TEST,)
            with gl.glEnable(*e):
                self.fbo.bind()
                GL.glDrawArrays(GL.GL_QUADS, 0, 4)
            GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY)

    drawBackground = True

    def gl_draw_thumb(self):
        GL.glPushAttrib(GL.GL_SCISSOR_BIT)
        r = self.rect
        r = r.move(*self.local_to_global_offset())
        GL.glScissor(r.x, self.root.height - r.y - r.height, r.width, r.height)
        with gl.glEnable(GL.GL_SCISSOR_TEST):
            self.clear()
            self.renderer.draw()
        GL.glPopAttrib()
예제 #10
0
class ThumbView(GLPerspective):
    def __init__(self, sch, **kw):
        GLPerspective.__init__(self, **kw)  # self, xmin= -32, xmax=32, ymin= -32, ymax=32, near= -1000, far=1000)
        self.far = 16000
        self.schematic = sch
        self.renderer = PreviewRenderer(sch)
        self.fboSize = (128, 128)
        # self.renderer.position = (sch.Length / 2, 0, sch.Height / 2)

    def setup_modelview(self):
        GLU.gluLookAt(-self.schematic.Width * 2.8, self.schematic.Height * 2.5 + 1, -self.schematic.Length * 1.5,
                      self.schematic.Width, 0, self.schematic.Length,
                      0, 1, 0)

    fbo = None

    def gl_draw_tex(self):
        self.clear()
        self.renderer.draw()

    def clear(self):
        if self.drawBackground:
            GL.glClearColor(0.25, 0.27, 0.77, 1.0)
        else:
            GL.glClearColor(0.0, 0.0, 0.0, 0.0)
        GL.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT)

    def gl_draw(self):
        if self.schematic.chunkCount > len(self.renderer.chunkRenderers):
            self.gl_draw_thumb()
        else:
            if self.fbo is None:
                w, h = self.fboSize
                self.fbo = FramebufferTexture(w, h, self.gl_draw_tex)
            GL.glMatrixMode(GL.GL_PROJECTION)
            GL.glLoadIdentity()
            GL.glMatrixMode(GL.GL_MODELVIEW)
            GL.glLoadIdentity()
            GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY)
            GL.glColor(1.0, 1.0, 1.0, 1.0)
            GL.glVertexPointer(2, GL.GL_FLOAT, 0, array([-1, -1,
                                                         - 1, 1,
                                                         1, 1,
                                                         1, -1, ], dtype='float32'))
            GL.glTexCoordPointer(2, GL.GL_FLOAT, 0, array([0, 0, 0, 256, 256, 256, 256, 0], dtype='float32'))
            e = (GL.GL_TEXTURE_2D,)
            if not self.drawBackground:
                e += (GL.GL_ALPHA_TEST,)
            with gl.glEnable(*e):
                self.fbo.bind()
                GL.glDrawArrays(GL.GL_QUADS, 0, 4)
            GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY)

    drawBackground = True

    def gl_draw_thumb(self):
        GL.glPushAttrib(GL.GL_SCISSOR_BIT)
        r = self.rect
        r = r.move(*self.local_to_global_offset())
        GL.glScissor(r.x, self.get_root().height - r.y - r.height, r.width, r.height)
        with gl.glEnable(GL.GL_SCISSOR_TEST):
            self.clear()
            self.renderer.draw()
        GL.glPopAttrib()
예제 #11
0
class ThumbView(GLPerspective):
    def __init__(self, sch, **kw):
        GLPerspective.__init__(
            self, **kw
        )  # self, xmin= -32, xmax=32, ymin= -32, ymax=32, near= -1000, far=1000)
        self.p_margin = 0
        self.p_spacing = 0
        self.widget_index = 0
        self.set_position_modifiers()
        self.far = 16000
        self.schematic = sch
        self.renderer = PreviewRenderer(sch)
        self.fboSize = (128, 128)
        self.root = self.get_root()
        # self.renderer.position = (sch.Length / 2, 0, sch.Height / 2)

    def set_position_modifiers(self):
        if getattr(self, 'parent', None) is not None:
            self.p_margin = getattr(self.parent, 'margin', 0)
            self.p_spacing = getattr(self.parent, 'spacing', 0)
            if hasattr(self.parent,
                       'subwidgets') and self in self.parent.subwidgets:
                self.widget_index = self.parent.subwidgets.index(self)

    def setup_modelview(self):
        GLU.gluLookAt(-self.schematic.Width * 2.8,
                      self.schematic.Height * 2.5 + 1,
                      -self.schematic.Length * 1.5, self.schematic.Width, 0,
                      self.schematic.Length, 0, 1, 0)

    fbo = None

    def gl_draw_tex(self):
        self.clear()
        self.renderer.draw()

    def clear(self):
        if self.drawBackground:
            GL.glClearColor(0.25, 0.27, 0.77, 1.0)
        else:
            GL.glClearColor(0.0, 0.0, 0.0, 0.0)
        GL.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT)

    def gl_draw(self):
        if self.schematic.chunkCount > len(self.renderer.chunkRenderers):
            self.gl_draw_thumb()
        else:
            if self.fbo is None:
                w, h = self.fboSize
                self.fbo = FramebufferTexture(w, h, self.gl_draw_tex)
            GL.glMatrixMode(GL.GL_PROJECTION)
            GL.glLoadIdentity()
            GL.glMatrixMode(GL.GL_MODELVIEW)
            GL.glLoadIdentity()
            GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY)
            GL.glColor(1.0, 1.0, 1.0, 1.0)
            GL.glVertexPointer(
                2, GL.GL_FLOAT, 0,
                array([
                    -1,
                    -1,
                    -1,
                    1,
                    1,
                    1,
                    1,
                    -1,
                ], dtype='float32'))
            GL.glTexCoordPointer(
                2, GL.GL_FLOAT, 0,
                array([0, 0, 0, 256, 256, 256, 256, 0], dtype='float32'))
            e = (GL.GL_TEXTURE_2D, )
            if not self.drawBackground:
                e += (GL.GL_ALPHA_TEST, )
            with gl.glEnable(*e):
                self.fbo.bind()
                GL.glDrawArrays(GL.GL_QUADS, 0, 4)
            GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY)

    drawBackground = True

    def gl_draw_thumb(self):
        GL.glPushAttrib(GL.GL_SCISSOR_BIT)
        r = self.rect
        x, y = self.local_to_global_offset()
        self.set_position_modifiers()
        if hasattr(self.parent, 'axis'):
            s_sz = 0
            if self.widget_index > 0:
                s_sz = getattr(self.parent.subwidgets[self.widget_index - 1],
                               self.parent.longways, 0)
            #-# Do we have a bad hack or the real solution with `(self.parent.height - self.height) / 2 + 1` stuff?
            #-# Need extensive tests to confirm...
            if self.parent.axis == 'h':
                r = r.move(
                    x + (self.parent.height - self.height) / 2 + 1 +
                    self.p_margin - self.p_spacing - s_sz,
                    y - (self.parent.height - self.height) / 2)
            else:
                r = r.move(
                    x - (self.parent.width - self.height) / 2,
                    y - (self.parent.width - self.height) / 2 + 1 +
                    self.p_margin - self.p_spacing - s_sz)
        else:
            r = r.move(*self.local_to_global_offset())
        GL.glScissor(r.x, self.root.height - r.y - r.height, r.width, r.height)
        with gl.glEnable(GL.GL_SCISSOR_TEST):
            self.clear()
            self.renderer.draw()
        GL.glPopAttrib()
예제 #12
0
class ThumbView(GLPerspective):
    def __init__(self, sch, **kw):
        GLPerspective.__init__(self, **kw)  # self, xmin= -32, xmax=32, ymin= -32, ymax=32, near= -1000, far=1000)
        self.p_margin = 0
        self.p_spacing = 0
        self.widget_index = 0
        self.set_position_modifiers()
        self.far = 16000
        self.schematic = sch
        self.renderer = PreviewRenderer(sch)
        self.fboSize = (128, 128)
        self.root = self.get_root()
        # self.renderer.position = (sch.Length / 2, 0, sch.Height / 2)

    def set_position_modifiers(self):
        if getattr(self, 'parent', None) is not None:
            self.p_margin = getattr(self.parent, 'margin', 0)
            self.p_spacing = getattr(self.parent, 'spacing', 0)
            if hasattr(self.parent, 'subwidgets') and self in self.parent.subwidgets:
                self.widget_index = self.parent.subwidgets.index(self)

    def setup_modelview(self):
        GLU.gluLookAt(-self.schematic.Width * 2.8, self.schematic.Height * 2.5 + 1, -self.schematic.Length * 1.5,
                      self.schematic.Width, 0, self.schematic.Length,
                      0, 1, 0)

    fbo = None

    def gl_draw_tex(self):
        self.clear()
        self.renderer.draw()

    def clear(self):
        if self.drawBackground:
            GL.glClearColor(0.25, 0.27, 0.77, 1.0)
        else:
            GL.glClearColor(0.0, 0.0, 0.0, 0.0)
        GL.glClear(GL.GL_DEPTH_BUFFER_BIT | GL.GL_COLOR_BUFFER_BIT)

    def gl_draw(self):
        if self.schematic.chunkCount > len(self.renderer.chunkRenderers):
            self.gl_draw_thumb()
        else:
            if self.fbo is None:
                w, h = self.fboSize
                self.fbo = FramebufferTexture(w, h, self.gl_draw_tex)
            GL.glMatrixMode(GL.GL_PROJECTION)
            GL.glLoadIdentity()
            GL.glMatrixMode(GL.GL_MODELVIEW)
            GL.glLoadIdentity()
            GL.glEnableClientState(GL.GL_TEXTURE_COORD_ARRAY)
            GL.glColor(1.0, 1.0, 1.0, 1.0)
            GL.glVertexPointer(2, GL.GL_FLOAT, 0, array([-1, -1,
                                                         - 1, 1,
                                                         1, 1,
                                                         1, -1, ], dtype='float32'))
            GL.glTexCoordPointer(2, GL.GL_FLOAT, 0, array([0, 0, 0, 256, 256, 256, 256, 0], dtype='float32'))
            e = (GL.GL_TEXTURE_2D,)
            if not self.drawBackground:
                e += (GL.GL_ALPHA_TEST,)
            with gl.glEnable(*e):
                self.fbo.bind()
                GL.glDrawArrays(GL.GL_QUADS, 0, 4)
            GL.glDisableClientState(GL.GL_TEXTURE_COORD_ARRAY)

    drawBackground = True

    def gl_draw_thumb(self):
        GL.glPushAttrib(GL.GL_SCISSOR_BIT)
        r = self.rect
        x, y = self.local_to_global_offset()
        self.set_position_modifiers()
        if hasattr(self.parent, 'axis'):
            s_sz = 0
            if self.widget_index > 0:
                s_sz = getattr(self.parent.subwidgets[self.widget_index - 1], self.parent.longways, 0)
            #-# Do we have a bad hack or the real solution with `(self.parent.height - self.height) / 2 + 1` stuff?
            #-# Need extensive tests to confirm...
            if self.parent.axis == 'h':
                r = r.move(x + (self.parent.height - self.height) / 2 + 1 + self.p_margin - self.p_spacing - s_sz, y - (self.parent.height - self.height) / 2)
            else:
                r = r.move(x - (self.parent.width - self.height) / 2, y - (self.parent.width - self.height) / 2 + 1 + self.p_margin - self.p_spacing - s_sz)
        else:
            r = r.move(*self.local_to_global_offset())
        GL.glScissor(r.x, self.root.height - r.y - r.height, r.width, r.height)
        with gl.glEnable(GL.GL_SCISSOR_TEST):
            self.clear()
            self.renderer.draw()
        GL.glPopAttrib()