Pyramid addition to Geometric Primitives

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
Post Reply
Tilarta
Posts: 41
Joined: Sat Aug 10, 2019 4:53 am
Contact:

Pyramid addition to Geometric Primitives

Post by Tilarta »

Many times now I've wanted to make a Pyramid type shape for various reasons and the process in converting a wedge to a Pyramid is rather laborious/tedious.
Also, the wedge when created is never vertical, which is an added annoyance, as I have to rotate the axis before performing any other tasks.

Then there is the additional complication of moving the points around to match the shape of the object the pyramid will be anchored to:
DBwedge2Point.png
DBwedge2Point.png (20.08 KiB) Viewed 1150 times
To make this process a whole lot easier/more efficient, I am requesting that a preformatted Pyramid shape be added to Geometric primitives.
I can then tailor this shape to the task needed without having to mess around with the point values relating to the apex point and just move the base/height points around instead.
chrisb
Veteran
Posts: 53919
Joined: Tue Mar 17, 2015 9:14 am

Re: Pyramid addition to Geometric Primitives

Post by chrisb »

You can achieve the same result with a draft point and a sketch.
Nevertheless I would support this with an arbitrary regular polygon as base shape.
A Sketcher Lecture with in-depth information is available in English, auf Deutsch, en français, en español.
Syres
Veteran
Posts: 2893
Joined: Thu Aug 09, 2018 11:14 am

Re: Pyramid addition to Geometric Primitives

Post by Syres »

Tilarta wrote: Fri Aug 16, 2019 2:02 am Many times now I've wanted to make a Pyramid type shape for various reasons and the process in converting a wedge to a Pyramid is rather laborious/tedious.
While you're waiting for the proper fix to be applied to the source code, you might find a use for this crude macro but it's only tested on 0.18.3 and above on Windows:

Code: Select all

from PySide import QtCore, QtGui
from PySide.QtGui import QLineEdit, QRadioButton
import Draft

class makePyramid():
    def __init__(self):
        self.dialog = None
        self.s1 = None
		
        # Make dialog box
        self.dialog = QtGui.QDialog()
        self.dialog.resize(350,200)
        self.dialog.setWindowTitle("Create a Pyramid Solid")
        la = QtGui.QVBoxLayout(self.dialog)
        t1 = QtGui.QLabel("Length of Base (mm)")
        la.addWidget(t1)
        self.s1 = QtGui.QLineEdit()
        self.s1.setText("10")
        la.addWidget(self.s1)

        t2 = QtGui.QLabel("Width of Base (mm)")
        la.addWidget(t2)
        self.s2 = QtGui.QLineEdit()
        self.s2.setText("10")
        la.addWidget(self.s2)

        t3 = QtGui.QLabel("Point Height (mm)")
        la.addWidget(t3)
        self.s3 = QtGui.QLineEdit()
        self.s3.setText("10")
        la.addWidget(self.s3)

        self.radio1 = QtGui.QRadioButton("Radius Corners")
        self.radio2 = QtGui.QRadioButton("Non-radius Corners")

        self.radio2.setChecked(True)
        la.addWidget(self.radio1)
        la.addWidget(self.radio2)

        # Add OK / Cancel buttons
        okbox = QtGui.QDialogButtonBox(self.dialog)
        okbox.setOrientation(QtCore.Qt.Horizontal)
        okbox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.Ok)
        la.addWidget(okbox)
        QtCore.QObject.connect(okbox, QtCore.SIGNAL("accepted()"), self.proceed)
        QtCore.QObject.connect(okbox, QtCore.SIGNAL("rejected()"), self.close)
        QtCore.QMetaObject.connectSlotsByName(self.dialog)
        self.dialog.show()
        self.dialog.exec_()

    def proceed(self):

        if self.s1.text()=="" or self.s2.text()=="" or self.s3.text()=="":
            FreeCAD.Console.PrintError("All three dimension text boxes must be completed\n")
        else:
            fLength = float(self.s1.text())
            fWidth = float(self.s2.text())
            fHeight = float(self.s3.text())
            fXpos = float(self.s1.text())/2
            fYpos = float(self.s2.text())/2
            fRadius = (fLength + fWidth) /100
            tRadius = str(fRadius)+" mm"
            pl = FreeCAD.Placement()
            pl.Rotation.Q = (0.0,-0.0,-0.0,1.0)
            pl.Base = FreeCAD.Vector(-fXpos, -fYpos, 0.0)
            rec = Draft.makeRectangle(length=fLength,height=fWidth,placement=pl,face=False,support=None)
            Draft.autogroup(rec)
            point = Draft.makePoint(0.0,0.0,fHeight)
            Draft.autogroup(point)
            from FreeCAD import Base
            App.ActiveDocument.addObject('Part::Loft','PyramidLoft')
            App.ActiveDocument.ActiveObject.Sections=[App.ActiveDocument.Rectangle, App.ActiveDocument.Point, ]
            App.ActiveDocument.ActiveObject.Solid=True
            App.ActiveDocument.ActiveObject.Ruled=False
            App.ActiveDocument.ActiveObject.Closed=False
            if self.radio1.isChecked():
                App.ActiveDocument.getObject("Rectangle").FilletRadius = tRadius
            App.activeDocument().recompute()
            Gui.ActiveDocument.getObject("Point").Visibility=False
            App.ActiveDocument.getObject("Point").Label = 'PyramidPoint'
            Gui.ActiveDocument.getObject("Rectangle").Visibility=False
            App.ActiveDocument.getObject("Rectangle").Label = 'PyramidBase'
            Gui.SendMsgToActiveView("ViewFit")
            Gui.activeDocument().activeView().viewDimetric()
            App.ActiveDocument.addObject('Part::Feature','Pyramid').Shape=App.ActiveDocument.PyramidLoft.Shape
            App.ActiveDocument.ActiveObject.Label=App.ActiveDocument.Pyramid.Label
            Gui.ActiveDocument.ActiveObject.ShapeColor=Gui.ActiveDocument.Pyramid.ShapeColor
            Gui.ActiveDocument.ActiveObject.LineColor=Gui.ActiveDocument.Pyramid.LineColor
            Gui.ActiveDocument.ActiveObject.PointColor=Gui.ActiveDocument.Pyramid.PointColor
            Gui.ActiveDocument.ActiveObject.DiffuseColor=Gui.ActiveDocument.Pyramid.DiffuseColor
            App.ActiveDocument.removeObject("PyramidLoft")
            App.ActiveDocument.removeObject("Rectangle")
            App.ActiveDocument.removeObject("Point")
            App.ActiveDocument.recompute()
            self.close()

    def close(self):
        self.dialog.hide()


makePyramid()

OS: Windows 7
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.18.16131 (Git)
Build type: Release
Branch: releases/FreeCAD-0-18
Hash: 3129ae4296e40ed20e7b3d460b86e6969acbe1c3
Python version: 3.6.6
Qt version: 5.6.2
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: English/UnitedKingdom (en_GB)

OS: Windows 7 SP 1 (6.1)
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.19.17651 (Git)
Build type: Release
Branch: master
Hash: 16c26cb3b1cd7209ea8efc8cb30b3b18fd80cf95
Python version: 3.6.8
Qt version: 5.12.1
Coin version: 4.0.0a
OCC version: 7.3.0
Locale: English/United Kingdom (en_GB)
TheMarkster
Veteran
Posts: 5505
Joined: Thu Apr 05, 2018 1:53 am

Re: Pyramid addition to Geometric Primitives

Post by TheMarkster »

Extrude a regular polygon with 4 sides. Apply this formula to the Extrude taper angle property:

Code: Select all

57.29578 * pi / 180 * atan(2 * LengthFwd / Base.Circumradius / sqrt(2)) - 90deg
This requires circumradius of the polygon to be used to determine the base of the pyramid. Through some experimentation I have found if you set the circumradius to s / 2 * sqrt(2) you get s for the pyramid base size (side length dimension).

So, if you want base = 10 mm and height = 20 mm you extrude to length forward = 20 mm, then set the circumradius of the polygon to 10 / 2 * sqrt(2).

This only works with 4 sided polygons. I haven't worked out the general formula for n-sided polygons.

Edit: had base and height backwards.
User avatar
DeepSOIC
Veteran
Posts: 7896
Joined: Fri Aug 29, 2014 12:45 am
Location: used to be Saint-Petersburg, Russia

Re: Pyramid addition to Geometric Primitives

Post by DeepSOIC »

I think we might want a full workbench of primitives. You know, prisms, pyramids, regular polyhedra, other polyhedra, geodesic domes, ellipsoids, paraboloids, gyroids, logarithmic and hyperbolic spirals, gaussians ...
Joyas
Posts: 532
Joined: Sat Jul 12, 2014 8:39 pm

Re: Pyramid addition to Geometric Primitives

Post by Joyas »

DeepSOIC wrote: Fri Aug 16, 2019 9:45 pm I think we might want a full workbench of primitives. You know, prisms, pyramids, regular polyhedra, other polyhedra, geodesic domes, ellipsoids, paraboloids, gyroids, logarithmic and hyperbolic spirals, gaussians ...
I agree, I tried something like that two years ago, but I couldn't because I didn't know how handle thee drawing functions and it was too difficult for me.

It was called "pwned workbench" or "parts with new enhanced details". It was planned to have not only primitives (icosahedron spheres, antiprisms...), but also modifiers, for example, an array over the vertexes of a dodecahedron or a icosahedron. Also It has a function which takes the edges of a body and converts it into a thick wires.

Most of its functions can be done with other workbenches (Lattice2, Sketcher, Draft and Part), but I wanted something easy for beginners.

If someone find it useful, use its code.
Estudié ingeniería técnica industrial en España y sólo me ha servido para estar en el paro, no me contratan porque no tengo experiencia, y no tengo experiencia porque no me contratan. No debí estudiar esa carrera.
Post Reply