Example #1
0
    def create(self,
               generator,
               mins,
               maxs,
               material,
               roundDecimals,
               temp=False):
        wallWidth = self.wallWidth.getValue()
        if wallWidth < 1:
            return []
        numSides = self.numSides.getValue()
        if numSides < 3:
            return []

        # Very similar to the cylinder, except that we have multiple solids this time
        width = maxs.x - mins.x
        length = maxs.y - mins.y
        height = maxs.z - mins.z
        center = (maxs + mins) / 2
        majorOut = width / 2
        majorIn = majorOut - wallWidth
        minorOut = length / 2
        minorIn = minorOut - wallWidth
        angle = 2 * math.pi / numSides

        # Calc the X,Y for the inner and outer ellipses
        outer = []
        inner = []
        for i in range(numSides):
            a = i * angle
            x = center.x + majorOut * math.cos(a)
            y = center.y + minorOut * math.sin(a)
            z = mins.z
            outer.append(LEUtils.roundVector(Point3(x, y, z), roundDecimals))
            x = center.x + majorIn * math.cos(a)
            y = center.y + minorIn * math.sin(a)
            inner.append(LEUtils.roundVector(Point3(x, y, z), roundDecimals))

        color = LEUtils.getRandomSolidColor()

        # Create the solids
        solids = []
        z = LEUtils.roundVector(Point3(0, 0, height), roundDecimals)
        for i in range(numSides):
            faces = []
            next = (i + 1) % numSides
            faces.append(
                [outer[i], outer[i] + z, outer[next] + z, outer[next]])
            faces.append(
                [inner[next], inner[next] + z, inner[i] + z, inner[i]])
            faces.append(
                [outer[next], outer[next] + z, inner[next] + z, inner[next]])
            faces.append([inner[i], inner[i] + z, outer[i] + z, outer[i]])
            faces.append(
                [inner[next] + z, outer[next] + z, outer[i] + z, inner[i] + z])
            faces.append([inner[i], outer[i], outer[next], inner[next]])
            solids.append(
                self.makeSolid(generator, faces, material, temp, color))

        return solids
Example #2
0
    def __pickColor(self):
        self.origColor = LEUtils.strToQColor(self.getItemData())

        color = LEUtils.strToQColor(self.getItemData())
        colorDlg = QtWidgets.QColorDialog(color, self)
        colorDlg.setOptions(QtWidgets.QColorDialog.DontUseNativeDialog)
        colorDlg.setModal(True)
        colorDlg.currentColorChanged.connect(self.adjustToColorAndSetData)
        colorDlg.finished.connect(self.__colorDlgFinished)
        colorDlg.open()
        colorDlg.blockSignals(True)
        colorDlg.setCurrentColor(color)
        colorDlg.blockSignals(False)
        self.colorDlg = colorDlg
Example #3
0
    def getObjectsUnderMouse(self):
        vp = base.viewportMgr.activeViewport
        if not vp:
            return []

        entries = vp.click(self.Mask)
        if not entries or len(entries) == 0:
            return []

        objects = []
        key = self.Key
        for i in range(len(entries)):
            # Our entries have been sorted by distance, so use the first (closest) one.
            entry = entries[i]
            np = entry.getIntoNodePath().findNetPythonTag(key)
            if not np.isEmpty():
                # Don't backface cull if there is a billboard effect on or above this node
                if entry.hasSurfaceNormal() and not LEUtils.hasNetBillboard(
                        entry.getIntoNodePath()):
                    surfNorm = entry.getSurfaceNormal(vp.cam).normalized()
                    rayDir = entry.getFrom().getDirection().normalized()
                    if surfNorm.dot(rayDir) >= 0:
                        # Backface cull
                        continue
                obj = np.getPythonTag(key)

                actual = self.getActualObject(obj, entry)
                objects.append((actual, entry))

        return objects
Example #4
0
 def create(self,
            generator,
            mins,
            maxs,
            material,
            roundDecimals,
            temp=False):
     faces = LEUtils.getBoxFaces(mins, maxs, roundDecimals)
     return [self.makeSolid(generator, faces, material, temp)]
Example #5
0
    def create(self,
               generator,
               mins,
               maxs,
               material,
               roundDecimals,
               temp=False):
        numSides = self.numSides.getValue()
        if numSides < 3:
            return []

        # Cylinders can be elliptical so use both major and minor rather than just the radius
        # NOTE: when a low number (< 10ish) of faces are selected this will cause the cylinder to not touch all edges of the box.
        width = maxs.x - mins.x
        length = maxs.y - mins.y
        height = maxs.z - mins.z
        center = (mins + maxs) / 2
        major = width / 2
        minor = length / 2
        angle = 2 * math.pi / numSides

        # Calculate the X and Y points for the ellipse
        points = []
        for i in range(numSides):
            a = i * angle
            xval = center.x + major * math.cos(a)
            yval = center.y + minor * math.sin(a)
            zval = mins.z
            points.append(
                LEUtils.roundVector(Point3(xval, yval, zval), roundDecimals))

        faces = []
        z = LEUtils.roundVector(Point3(0, 0, height), roundDecimals)
        for i in range(numSides):
            next = (i + 1) % numSides
            faces.append(
                [points[i], points[i] + z, points[next] + z, points[next]])
        # Add the elliptical top and bottom faces
        faces.append(points)
        faces.append([x + z for x in reversed(points)])

        solid = self.makeSolid(generator, faces, material, temp)
        return [solid]
Example #6
0
    def create(self,
               generator,
               mins,
               maxs,
               material,
               roundDecimals,
               temp=False):
        # The lower Z plane will be base
        center = (mins + maxs) / 2
        c1 = LEUtils.roundVector(Point3(mins.x, mins.y, mins.z), roundDecimals)
        c2 = LEUtils.roundVector(Point3(maxs.x, mins.y, mins.z), roundDecimals)
        c3 = LEUtils.roundVector(Point3(maxs.x, maxs.y, mins.z), roundDecimals)
        c4 = LEUtils.roundVector(Point3(mins.x, maxs.y, mins.z), roundDecimals)
        c5 = LEUtils.roundVector(Point3(center.x, center.y, maxs.z),
                                 roundDecimals)

        faces = [[c1, c2, c3, c4], [c2, c1, c5], [c3, c2, c5], [c4, c3, c5],
                 [c1, c4, c5]]

        return [self.makeSolid(generator, faces, material, temp)]
Example #7
0
 def __init__(self, widget, axis):
     TransformWidgetAxis.__init__(self, widget, axis)
     segs = LineSegs()
     segs.setThickness(2)
     vertices = LEUtils.circle(0, 0, 1, 64)
     for i in range(len(vertices)):
         x1, y1 = vertices[i]
         x2, y2 = vertices[(i + 1) % len(vertices)]
         segs.moveTo(x1, 0, y1)
         segs.drawTo(x2, 0, y2)
     self.axisCircle = self.attachNewNode(segs.create())
     self.axisCircle.setAntialias(AntialiasAttrib.MLine)
Example #8
0
    def mouseDown(self):
        vp = base.viewportMgr.activeViewport
        if not vp:
            return

        if vp.is3D():
            # If we clicked in the 3D viewport, try to intersect with an existing MapObject
            # and immediately place the entity at the intersection point. If we didn't click on any
            # MapObject, place the entity on the grid where we clicked.
            entries = vp.click(GeomNode.getDefaultCollideMask())
            if entries and len(entries) > 0:
                for i in range(len(entries)):
                    entry = entries[i]
                    # Don't backface cull if there is a billboard effect on or above this node
                    if not LEUtils.hasNetBillboard(entry.getIntoNodePath()):
                        surfNorm = entry.getSurfaceNormal(vp.cam).normalized()
                        rayDir = entry.getFrom().getDirection().normalized()
                        if surfNorm.dot(rayDir) >= 0:
                            # Backface cull
                            continue
                    # We clicked on an object, use the contact point as the
                    # location of our new entity.
                    self.pos = entry.getSurfacePoint(self.doc.render)
                    self.hasPlaced = True
                    # Create it!
                    self.confirm()
                    break
            else:
                # Didn't click on an object, intersect our mouse ray with the grid plane.
                plane = LPlane(0, 0, 1, 0)
                worldMouse = vp.viewportToWorld(vp.getMouse())
                theCamera = vp.cam.getPos(render)
                # Ensure that the camera and mouse positions are on opposite
                # sides of the plane, or else the entity would place behind us.
                sign1 = plane.distToPlane(worldMouse) >= 0
                sign2 = plane.distToPlane(theCamera) >= 0
                if sign1 != sign2:
                    pointOnPlane = Point3()
                    ret = plane.intersectsLine(pointOnPlane, theCamera,
                                               worldMouse)
                    if ret:
                        # Our mouse intersected the grid plane. Place an entity at the plane intersection point.
                        self.pos = pointOnPlane
                        self.hasPlaced = True
                        self.confirm()
            return

        # The user clicked in the 2D viewport, draw the visualization where they clicked.
        self.showVis()
        self.updatePosFromViewport(vp)
        self.mouseIsDown = True
        self.hasPlaced = True
Example #9
0
    def create(self,
               generator,
               mins,
               maxs,
               material,
               roundDecimals,
               temp=False):
        numSides = self.numSides.getValue()
        if numSides < 3:
            return []

        # This is all very similar to the cylinder brush.
        width = maxs.x - mins.x
        length = maxs.y - mins.y
        center = (mins + maxs) / 2
        major = width / 2
        minor = length / 2
        angle = 2 * math.pi / numSides

        points = []
        for i in range(numSides):
            a = i * angle
            xval = center.x + major * math.cos(a)
            yval = center.y + minor * math.sin(a)
            zval = mins.z
            points.append(
                LEUtils.roundVector(Point3(xval, yval, zval), roundDecimals))

        faces = []
        point = LEUtils.roundVector(Point3(center.x, center.y, maxs.z),
                                    roundDecimals)
        for i in range(numSides):
            next = (i + 1) % numSides
            faces.append([points[i], point, points[next]])
        faces.append(points)

        solid = self.makeSolid(generator, faces, material, temp)
        return [solid]
Example #10
0
    def getPointOnGizmo(self):
        vp = base.viewportMgr.activeViewport
        if not vp or not vp.is3D():
            return

        axis = self.widget.activeAxis.axisIdx
        gray = self.getGizmoRay(axis)
        mray = vp.getMouseRay()
        # Move into world space
        mray.xform(vp.cam.getMat(NodePath()))

        distance = LEUtils.closestDistanceBetweenLines(gray, mray)

        return gray.origin + (gray.direction * -gray.t)
Example #11
0
    def create(self,
               generator,
               mins,
               maxs,
               material,
               roundDecimals,
               temp=False):
        useCentroid = self.useCentroid.getValue()
        center = (mins + maxs) / 2
        # The lower Z plane will be the triangle, with the lower Y value getting the two corners
        c1 = LEUtils.roundVector(Point3(mins.x, mins.y, mins.z), roundDecimals)
        c2 = LEUtils.roundVector(Point3(maxs.x, mins.y, mins.z), roundDecimals)
        c3 = LEUtils.roundVector(Point3(center.x, maxs.y, mins.z),
                                 roundDecimals)
        if useCentroid:
            c4 = Point3((c1.x + c2.x + c3.x) / 3, (c1.y + c2.y + c3.y) / 3,
                        maxs.z)
        else:
            c4 = LEUtils.roundVector(Point3(center.x, center.y, maxs.z),
                                     roundDecimals)

        faces = [[c1, c2, c3], [c4, c1, c3], [c4, c3, c2], [c4, c2, c1]]

        return [self.makeSolid(generator, faces, material, temp)]
Example #12
0
    def __init__(self, parent, item, model):
        BaseEditor.__init__(self, parent, item, model)
        self.lineEdit = QtWidgets.QLineEdit("", self)
        self.lineEdit.returnPressed.connect(self.__confirmColorText)
        self.layout().addWidget(self.lineEdit)
        self.colorLbl = QtWidgets.QLabel("", self)
        self.colorLbl.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                    QtWidgets.QSizePolicy.Preferred)
        self.layout().addWidget(self.colorLbl)
        self.editButton = QtWidgets.QPushButton("Pick Color", self)
        self.editButton.clicked.connect(self.__pickColor)
        self.layout().addWidget(self.editButton)
        self.colorDlg = None

        self.adjustToColor(LEUtils.strToQColor(self.getItemData()))
Example #13
0
    def create(self,
               generator,
               mins,
               maxs,
               material,
               roundDecimals,
               temp=False):
        solids = []

        numSides = self.numSides.getValue()
        if numSides < 3:
            return solids
        wallWidth = self.wallWidth.getValue()
        if wallWidth < 1:
            return solids
        arc = self.arc.getValue()
        if arc < 1:
            return solids
        startAngle = self.startAngle.getValue()
        if startAngle < 0 or startAngle > 359:
            return solids
        addHeight = self.addHeight.getValue()
        curvedRamp = self.curvedRamp.getValue()
        tiltAngle = self.tiltAngle.getValue()
        if abs(tiltAngle % 180) == 90:
            return solids
        tiltInterp = curvedRamp and self.tiltInterp.getValue()

        # Very similar to the pipe brush, except with options for start angle, arc, height, and tilt.
        width = maxs.x - mins.x
        length = maxs.y - mins.y
        height = maxs.z - mins.z

        majorOut = width / 2
        majorIn = majorOut - wallWidth
        minorOut = length / 2
        minorIn = minorOut - wallWidth

        start = deg2Rad(startAngle)
        tilt = deg2Rad(tiltAngle)
        angle = deg2Rad(arc) / numSides

        center = (mins + maxs) / 2

        # Calculate the coordinates of the inner and outer ellipses' points.
        outer = []
        inner = []
        for i in range(numSides + 1):
            a = start + i * angle
            h = i * addHeight
            interp = 1
            if tiltInterp:
                interp = math.cos(math.pi / numSides * (i - numSides / 2))
            tiltHeight = wallWidth / 2 * interp * math.tan(tilt)

            xval = center.x + majorOut * math.cos(a)
            yval = center.y + minorOut * math.sin(a)
            zval = mins.z
            if curvedRamp:
                zval += h + tiltHeight
            outer.append(
                LEUtils.roundVector(Point3(xval, yval, zval), roundDecimals))

            xval = center.x + majorIn * math.cos(a)
            yval = center.y + minorIn * math.sin(a)
            zval = mins.z
            if curvedRamp:
                zval += h - tiltHeight
            inner.append(
                LEUtils.roundVector(Point3(xval, yval, zval), roundDecimals))

        color = LEUtils.getRandomSolidColor()

        # create the solids
        z = LEUtils.roundVector(Point3(0, 0, height), roundDecimals)
        for i in range(numSides):
            faces = []

            # Since we are triangulating/splitting each arch segment, we need to generate 2 brushes per side
            if curvedRamp:
                # The splitting orientation depends on the curving direction of the arch
                if addHeight >= 0:
                    faces.append([
                        outer[i], outer[i] + z, outer[i + 1] + z, outer[i + 1]
                    ])
                    faces.append([
                        outer[i + 1], outer[i + 1] + z, inner[i] + z, inner[i]
                    ])
                    faces.append(
                        [inner[i], inner[i] + z, outer[i] + z, outer[i]])
                    faces.append(
                        [outer[i] + z, inner[i] + z, outer[i + 1] + z])
                    faces.append([outer[i + 1], inner[i], outer[i]])
                else:
                    faces.append([
                        inner[i + 1], inner[i + 1] + z, inner[i] + z, inner[i]
                    ])
                    faces.append([
                        outer[i], outer[i] + z, inner[i + 1] + z, inner[i + 1]
                    ])
                    faces.append(
                        [inner[i], inner[i] + z, outer[i] + z, outer[i]])
                    faces.append(
                        [inner[i + 1] + z, outer[i] + z, inner[i] + z])
                    faces.append([inner[i], outer[i], inner[i + 1]])
                solids.append(
                    self.makeSolid(generator, faces, material, temp, color))

                faces.clear()

                if addHeight >= 0:
                    faces.append([
                        inner[i + 1], inner[i + 1] + z, inner[i] + z, inner[i]
                    ])
                    faces.append([
                        inner[i], inner[i] + z, outer[i + 1] + z, outer[i + 1]
                    ])
                    faces.append([
                        outer[i + 1], outer[i + 1] + z, inner[i + 1] + z,
                        inner[i + 1]
                    ])
                    faces.append(
                        [inner[i + 1] + z, outer[i + 1] + z, inner[i] + z])
                    faces.append([inner[i], outer[i + 1], inner[i + 1]])
                else:
                    faces.append([
                        outer[i], outer[i] + z, outer[i + 1] + z, outer[i + 1]
                    ])
                    faces.append([
                        inner[i + 1], inner[i + 1] + z, outer[i] + z, outer[i]
                    ])
                    faces.append([
                        outer[i + 1], outer[i + 1] + z, inner[i + 1] + z,
                        inner[i + 1]
                    ])
                    faces.append(
                        [outer[i] + z, inner[i + 1] + z, outer[i + 1] + z])
                    faces.append([outer[i + 1], inner[i + 1], outer[i]])

                solids.append(
                    self.makeSolid(generator, faces, material, temp, color))
            else:
                h = Vec3.unitZ() * i * addHeight
                faces.append([
                    outer[i] + h, outer[i] + z + h, outer[i + 1] + z + h,
                    outer[i + 1] + h
                ])
                faces.append([
                    inner[i + 1] + h, inner[i + 1] + z + h, inner[i] + z + h,
                    inner[i] + h
                ])
                faces.append([
                    outer[i + 1] + h, outer[i + 1] + z + h,
                    inner[i + 1] + z + h, inner[i + 1] + h
                ])
                faces.append([
                    inner[i] + h, inner[i] + z + h, outer[i] + z + h,
                    outer[i] + h
                ])
                faces.append([
                    inner[i + 1] + z + h, outer[i + 1] + z + h,
                    outer[i] + z + h, inner[i] + z + h
                ])
                faces.append([
                    inner[i] + h, outer[i] + h, outer[i + 1] + h,
                    inner[i + 1] + h
                ])
                solids.append(
                    self.makeSolid(generator, faces, material, temp, color))

        return solids
Example #14
0
    def create(self,
               generator,
               mins,
               maxs,
               material,
               roundDecimals,
               temp=False):
        numSides = self.numSides.getValue()
        if numSides < 3:
            return []

        roundDecimals = 2  # Don't support rounding

        width = maxs.x - mins.x
        length = maxs.y - mins.y
        height = maxs.z - mins.z
        center = (maxs + mins) / 2
        major = width / 2
        minor = length / 2
        heightRadius = height / 2

        angleV = deg2Rad(180) / numSides
        angleH = deg2Rad(360) / numSides

        faces = []
        bottom = LEUtils.roundVector(Point3(center.x, center.y, mins.z),
                                     roundDecimals)
        top = LEUtils.roundVector(Point3(center.x, center.y, maxs.z),
                                  roundDecimals)

        for i in range(numSides):
            # Top -> bottom
            zAngleStart = angleV * i
            zAngleEnd = angleV * (i + 1)
            zStart = heightRadius * math.cos(zAngleStart)
            zEnd = heightRadius * math.cos(zAngleEnd)
            zMultStart = math.sin(zAngleStart)
            zMultEnd = math.sin(zAngleEnd)
            for j in range(numSides):
                # Go around the circle in X/Y
                xyAngleStart = angleH * j
                xyAngleEnd = angleH * ((j + 1) % numSides)
                xyStartX = major * math.cos(xyAngleStart)
                xyStartY = minor * math.sin(xyAngleStart)
                xyEndX = major * math.cos(xyAngleEnd)
                xyEndY = minor * math.sin(xyAngleEnd)
                a = LEUtils.roundVector(
                    Point3(xyStartX * zMultStart, xyStartY * zMultStart,
                           zStart) + center, roundDecimals)
                b = LEUtils.roundVector(
                    Point3(xyEndX * zMultStart, xyEndY * zMultStart, zStart) +
                    center, roundDecimals)
                c = LEUtils.roundVector(
                    Point3(xyEndX * zMultEnd, xyEndY * zMultEnd, zEnd) +
                    center, roundDecimals)
                d = LEUtils.roundVector(
                    Point3(xyStartX * zMultEnd, xyStartY * zMultEnd, zEnd) +
                    center, roundDecimals)

                if i == 0:
                    # Top faces are triangles
                    faces.append([top, c, d])
                elif i == (numSides - 1):
                    # Bottom faces are also triangles
                    faces.append([bottom, a, b])
                else:
                    # Inner faces are quads
                    faces.append([a, b, c, d])

        return [self.makeSolid(generator, faces, material, temp)]
Example #15
0
 def snapToGrid(self, point):
     if GridSettings.GridSnap:
         return LEUtils.snapToGrid(GridSettings.DefaultStep, point)
     return point
Example #16
0
 def pickRandomColor(self):
     # Picks a random shade of blue/green for this solid.
     self.setColor(LEUtils.getRandomSolidColor())
Example #17
0
 def __confirmColorText(self):
     self.setModelData(self.model, self.item.index())
     self.adjustToColor(LEUtils.strToQColor(self.lineEdit.text()))
Example #18
0
 def computeValueText(self):
     return LEUtils.boolToStr(self.flagsItem.prop.hasFlags(self.spawnFlag.value))
Example #19
0
 def setModelData(self, model, index):
     model.setData(index, LEUtils.boolToStr(self.check.isChecked()), QtCore.Qt.EditRole)
Example #20
0
 def keyPressEvent(self, event):
     button = LEUtils.keyboardButtonFromQtKey(event.key())
     if button:
         self.inputDevice.buttonDown(button)
Example #21
0
 def keyReleaseEvent(self, event):
     button = LEUtils.keyboardButtonFromQtKey(event.key())
     if button:
         self.inputDevice.buttonUp(button)
Example #22
0
 def setEditorData(self, index):
     val = LEUtils.strToBool(self.getItemData())
     self.check.blockSignals(True)
     self.check.setChecked(val)
     self.check.blockSignals(False)
Example #23
0
 def invRotate(self, point):
     quat = Quat()
     quat.setHpr(self.getViewHpr())
     return LEUtils.makeForwardAxis(point, quat)