Macro Pyramid: Difference between revisions
(minor changes to the text) |
mNo edit summary |
||
(19 intermediate revisions by 6 users not shown) | |||
Line 1: | Line 1: | ||
<languages/> |
<languages/> |
||
<translate> |
<translate> |
||
<!--T:1--> |
<!--T:1--> |
||
{{Macro |
{{Macro |
||
|Name=Macro Pyramid |
|Name=Macro Pyramid |
||
|Icon=Pyramidicon.svg |
|Icon=Pyramidicon.svg |
||
|Description=This macro creates a parametric pyramid. The radiuses and the height will be set at creation time similar to Part Cone. |
|Description=This macro creates a parametric pyramid. The radiuses and the height will be set at creation time similar to Part Cone. All parameters can be adjusted. It is possible to create pyramids with a perfect tip. |
||
All parameters can be adjusted. It is possible to create pyramids with a perfect tip. |
|||
|Author=Eddy Verlinden, Genk, Belgium |
|Author=Eddy Verlinden, Genk, Belgium |
||
|Version=01. |
|Version=01.01 |
||
|Date=2019-11-10 |
|Date=2019-11-10 |
||
|FCVersion=All |
|FCVersion=All |
||
|Download=[https:// |
|Download=[https://wiki.freecad.org/images/4/46/Pyramidicon.svg ToolBar Icon] |
||
|SeeAlso=[[Macro_Polyhedrons|Macro Polyhedrons]] |
|||
}} |
}} |
||
==Description== |
==Description== <!--T:9--> |
||
<!--T:10--> |
|||
This macro creates a parametric pyramid. |
This macro creates a parametric pyramid. |
||
* Both radiuses and the height will be set at creation time, similar to Part Cone. |
* Both radiuses and the height will be set at creation time, similar to Part Cone. |
||
Line 22: | Line 23: | ||
* It is possible to create pyramids with a perfect tip. |
* It is possible to create pyramids with a perfect tip. |
||
<!--T:11--> |
|||
Note: |
Note: |
||
<!--T:12--> |
|||
If you're also interested in polyhedrons, then you can also make use of the the external workbench [https://github.com/eddyverl/FreeCad-Pyramids-and-Polyhedrons Pyramids_and_Polyhedrons] (github link) that contains the same function. |
|||
If you're also interested in polyhedrons, then you can use <b>Macro Polyhedrons</b>.<br> |
|||
You can also make use of the the external workbench [https://github.com/eddyverl/FreeCad-Pyramids-and-Polyhedrons Pyramids_and_Polyhedrons] that contains the same function. |
|||
<!--T:13--> |
|||
==How to use== |
|||
[[Image:Polyhedrons.png]] |
|||
<!--T:14--> |
|||
{{Caption|Example creation with the external workbench [https://github.com/eddyverl/FreeCad-Pyramids-and-Polyhedrons Pyramids_and_Polyhedrons] that contains the same function.}} |
|||
==Usage== <!--T:15--> |
|||
* Install: See info at [https://github.com/eddyverl/FreeCad-Pyramids-and-Polyhedrons Pyramids_and_Polyhedrons] (github README) |
|||
<!--T:16--> |
|||
* Install: use [[Image:AddonManager.svg|24px]] [[Std_AddonMgr|Addon Manager]] to install the macro. |
|||
* Once installed, open Menu → Macro → Macros. Click on pyramid.py and then click on button {{button|execute}}. |
* Once installed, open Menu → Macro → Macros. Click on pyramid.py and then click on button {{button|execute}}. |
||
* A knotted pyramid will appear, similar to Part Cone |
* A knotted pyramid will appear, similar to Part Cone |
||
* Change the parameters just like with Part Cone. |
* Change the parameters just like with Part Cone. |
||
* More info at [https://github.com/eddyverl/FreeCad-Pyramids-and-Polyhedrons Pyramids_and_Polyhedrons]. |
|||
==Script== <!--T:6--> |
==Script== <!--T:6--> |
||
<!--T:17--> |
|||
</translate> |
|||
Icon ToolBar [[File:Pyramidicon.svg|64px]] |
Icon ToolBar [[File:Pyramidicon.svg|64px]] |
||
</translate> |
|||
'''pyramid.py''' |
'''pyramid.py''' |
||
{{ |
{{MacroCode|code= |
||
# *************************************************************************** |
# *************************************************************************** |
||
# * Copyright (c) 2019 Eddy Verlinden * |
# * Copyright (c) 2019 Eddy Verlinden * |
||
Line 65: | Line 77: | ||
# *************************************************************************** |
# *************************************************************************** |
||
__Title__="Macro_Pyramid" |
|||
__Title__ = "Macro_Pyramid" |
|||
__Author__ = "Eddy Verlinden" |
|||
__Author__ = "Eddy Verlinden" |
|||
__Version__ = "01.00" |
|||
__Version__ = "01.02" |
|||
__Date__ = "2019-11-10" |
|||
__Date__ = "2021-01-09" |
|||
__Comment__ = "This macro creates a parametric pyramid." |
__Comment__ = "This macro creates a parametric pyramid." |
||
import sys |
|||
import FreeCAD,FreeCADGui |
import FreeCAD,FreeCADGui |
||
import Part |
import Part |
||
import math |
import math |
||
import sys |
|||
def create(obj_name): |
|||
obj=FreeCAD.ActiveDocument.addObject("Part::FeaturePython",obj_name) |
|||
fpo = Pyramid(obj) |
|||
ViewProviderBox(obj.ViewObject) |
|||
FreeCAD.ActiveDocument.recompute() |
|||
return fpo |
|||
Line 90: | Line 112: | ||
def horizontal_regular_pyramid_vertexes(sidescount,radius,z, startangle = 0): |
|||
vertexes = [] |
|||
odd = 0 |
|||
if (sidescount % 2) == 0: |
|||
odd = 1 |
|||
if radius != 0 : |
|||
for i in range(0,sidescount+1): |
|||
angle = 2 * math.pi * i / sidescount + (math.pi * (odd/sidescount + 1/2)) + startangle * math.pi / 180 |
|||
vertex = (radius * math.cos(angle), radius * math.sin(angle), z) |
|||
vertexes.append(vertex) |
|||
else: |
|||
vertex = (0,0,z) |
|||
vertexes.append(vertex) |
|||
return vertexes |
|||
# =========================================================================== |
|||
class Pyramid: |
class Pyramid: |
||
radius1value = 0 |
radius1value = 0 |
||
radius2value = 0 |
radius2value = 0 |
||
Line 98: | Line 136: | ||
side1value = 0 |
side1value = 0 |
||
side2value = 0 |
side2value = 0 |
||
anglez = 0 |
|||
def __init__(self, obj, sidescount = 5,radius_bottom = 2 , radius_top = 4, height = 10): |
|||
def __init__(self, obj, sidescount = 5,radius_bottom = 2 , radius_top = 4, height = 10, angz = 0): |
|||
obj.addProperty("App::PropertyLength","Radius1","Pyramid","Radius of the pyramid").Radius1=radius_bottom |
obj.addProperty("App::PropertyLength","Radius1","Pyramid","Radius of the pyramid").Radius1=radius_bottom |
||
obj.addProperty("App::PropertyLength","Radius2","Pyramid","Radius of the pyramid").Radius2=radius_top |
obj.addProperty("App::PropertyLength","Radius2","Pyramid","Radius of the pyramid").Radius2=radius_top |
||
Line 106: | Line 145: | ||
obj.addProperty("App::PropertyLength","Sidelength1","Pyramid","Sidelength1 of the pyramid") |
obj.addProperty("App::PropertyLength","Sidelength1","Pyramid","Sidelength1 of the pyramid") |
||
obj.addProperty("App::PropertyLength","Sidelength2","Pyramid","Sidelength2 of the pyramid") |
obj.addProperty("App::PropertyLength","Sidelength2","Pyramid","Sidelength2 of the pyramid") |
||
obj.addProperty("App::PropertyAngle","Z_rotation","Pyramid","alfa angle around Z").Z_rotation = angz |
|||
obj.Proxy = self |
obj.Proxy = self |
||
Line 111: | Line 152: | ||
def execute (self,obj): |
def execute (self,obj): |
||
sidescount = obj.Sidescount |
sidescount = int(obj.Sidescount) |
||
angle = 2 * math.pi / sidescount |
angle = 2 * math.pi / sidescount |
||
radius_bottom = obj.Radius1 |
radius_bottom = float(obj.Radius1) |
||
radius_top = obj.Radius2 |
radius_top = float(obj.Radius2) |
||
sidelength_top = float(obj.Sidelength2) |
|||
sidelength_bottom = float(obj.Sidelength1) |
|||
height = float(obj.Height) |
|||
anglez = float(obj.Z_rotation) |
|||
if radius_bottom != self.radius1value: # or sidescount != self.sidescountvalue |
|||
if radius_bottom != self.radius1value or sidescount != self.sidescountvalue: |
|||
obj.Sidelength1 = radius_bottom * math.sin(angle/2) * 2 |
obj.Sidelength1 = radius_bottom * math.sin(angle/2) * 2 |
||
self.radius1value = radius_bottom |
self.radius1value = radius_bottom |
||
self.side1value = obj.Sidelength1 |
self.side1value = float(obj.Sidelength1) |
||
elif |
elif sidelength_bottom != self.side1value: |
||
self.radius1value = (obj.Sidelength1 / 2) / math.sin(angle/2) |
self.radius1value = float(obj.Sidelength1 / 2) / math.sin(angle/2) |
||
obj.Radius1 = self.radius1value |
obj.Radius1 = self.radius1value |
||
radius_bottom = self.radius1value |
radius_bottom = self.radius1value |
||
side1value = obj.Sidelength1 |
self.side1value = float(obj.Sidelength1) |
||
if radius_top != self.radius2value |
if radius_top != self.radius2value or sidescount != self.sidescountvalue: |
||
obj.Sidelength2 = radius_top * math.sin(angle/2) * 2 |
obj.Sidelength2 = radius_top * math.sin(angle/2) * 2 |
||
self.radius2value = radius_top |
self.radius2value = float(radius_top) |
||
self.side2value = obj.Sidelength2 |
self.side2value = float(obj.Sidelength2) |
||
elif |
elif sidelength_top != self.side2value: |
||
self.radius2value = (obj.Sidelength2 / 2) / math.sin(angle/2) |
self.radius2value = float(obj.Sidelength2 / 2) / math.sin(angle/2) |
||
obj.Radius2 = self.radius2value |
obj.Radius2 = self.radius2value |
||
radius_top = self.radius2value |
radius_top = self.radius2value |
||
side2value = obj.Sidelength2 |
self.side2value = float(obj.Sidelength2) |
||
self.sidescountvalue = sidescount |
|||
faces = [] |
faces = [] |
||
if radius_bottom == 0 and radius_top == 0: |
if radius_bottom == 0 and radius_top == 0: |
||
FreeCAD.Console.PrintMessage("Both radiuses are zero" + "\n") |
FreeCAD.Console.PrintMessage("Both radiuses are zero" + "\n") |
||
else: |
else: |
||
vertexes_bottom = |
vertexes_bottom = horizontal_regular_pyramid_vertexes(sidescount,radius_bottom,0 ,anglez) |
||
vertexes_top = |
vertexes_top = horizontal_regular_pyramid_vertexes(sidescount,radius_top ,height,anglez) |
||
if radius_bottom != 0: |
if radius_bottom != 0: |
||
Line 166: | Line 210: | ||
shell = Part.makeShell(faces) |
shell = Part.makeShell(faces) |
||
solid = Part.makeSolid(shell) |
solid = Part.makeSolid(shell) |
||
obj.Shape = solid |
obj.Shape = solid |
||
Line 193: | Line 236: | ||
def onChanged(self, vobj, prop): |
def onChanged(self, vobj, prop): |
||
pass |
pass |
||
class ViewProviderBox: |
|||
def __init__(self, obj): |
|||
obj.Proxy = self |
|||
def attach(self, obj): |
|||
return |
|||
def updateData(self, fp, prop): |
|||
return |
|||
def getDisplayModes(self,obj): |
|||
return "As Is" |
|||
def getDefaultDisplayMode(self): |
|||
return "As Is" |
|||
def setDisplayMode(self,mode): |
|||
return "As Is" |
|||
def onChanged(self, vobj, prop): |
|||
pass |
|||
def getIcon(self): |
def getIcon(self): |
||
return """ |
return """ |
||
Line 263: | Line 284: | ||
" "}; |
" "}; |
||
""" |
""" |
||
def __getstate__(self): |
|||
return None |
|||
def __setstate__(self,state): |
|||
return None |
|||
# =========================================================================== |
# =========================================================================== |
||
if FreeCAD.ActiveDocument == None: |
if FreeCAD.ActiveDocument == None: |
||
FreeCAD.newDocument() |
|||
obj=FreeCAD.ActiveDocument.addObject("Part::FeaturePython","Pyramid") |
|||
Pyramid(obj) |
|||
ViewProviderBox(obj.ViewObject) |
|||
FreeCAD.ActiveDocument.recompute() |
|||
create ("Pyramid") |
|||
FreeCADGui.SendMsgToActiveView("ViewFit") |
|||
}} |
}} |
||
<translate> |
<translate> |
||
Latest revision as of 22:00, 29 December 2023
Description |
---|
This macro creates a parametric pyramid. The radiuses and the height will be set at creation time similar to Part Cone. All parameters can be adjusted. It is possible to create pyramids with a perfect tip. Macro version: 01.01 Last modified: 2019-11-10 FreeCAD version: All Download: ToolBar Icon Author: Eddy Verlinden, Genk, Belgium |
Author |
Eddy Verlinden, Genk, Belgium |
Download |
ToolBar Icon |
Links |
Macros recipes How to install macros How to customize toolbars |
Macro Version |
01.01 |
Date last modified |
2019-11-10 |
FreeCAD Version(s) |
All |
Default shortcut |
None |
See also |
Macro Polyhedrons |
Description
This macro creates a parametric pyramid.
- Both radiuses and the height will be set at creation time, similar to Part Cone.
- All parameters can be adjusted.
- It is possible to create pyramids with a perfect tip.
Note:
If you're also interested in polyhedrons, then you can use Macro Polyhedrons.
You can also make use of the the external workbench Pyramids_and_Polyhedrons that contains the same function.
Example creation with the external workbench Pyramids_and_Polyhedrons that contains the same function.
Usage
- Install: use Addon Manager to install the macro.
- Once installed, open Menu → Macro → Macros. Click on pyramid.py and then click on button execute.
- A knotted pyramid will appear, similar to Part Cone
- Change the parameters just like with Part Cone.
- More info at Pyramids_and_Polyhedrons.
Script
pyramid.py
# *************************************************************************** # * Copyright (c) 2019 Eddy Verlinden * # * * # * This file is part of the FreeCAD CAx development system. * # * * # * This program is free software; you can redistribute it and/or modify * # * it under the terms of the GNU Lesser General Public License (LGPL) * # * as published by the Free Software Foundation; either version 2 of * # * the License, or (at your option) any later version. * # * for detail see the LICENCE text file. * # * * # * FreeCAD is distributed in the hope that it will be useful, * # * but WITHOUT ANY WARRANTY; without even the implied warranty of * # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * # * GNU Lesser General Public License for more details. * # * * # * You should have received a copy of the GNU Library General Public * # * License along with FreeCAD; if not, write to the Free Software * # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * # * USA * # * * # *************************************************************************** __Title__ = "Macro_Pyramid" __Author__ = "Eddy Verlinden" __Version__ = "01.02" __Date__ = "2021-01-09" __Comment__ = "This macro creates a parametric pyramid." import sys import FreeCAD,FreeCADGui import Part import math def create(obj_name): obj=FreeCAD.ActiveDocument.addObject("Part::FeaturePython",obj_name) fpo = Pyramid(obj) ViewProviderBox(obj.ViewObject) FreeCAD.ActiveDocument.recompute() return fpo def horizontal_regular_polygon_vertexes(sidescount,radius,z, startangle = 0): vertexes = [] if radius != 0 : for i in range(0,sidescount+1): angle = 2 * math.pi * i / sidescount + math.pi + startangle vertex = (radius * math.cos(angle), radius * math.sin(angle), z) vertexes.append(vertex) else: vertex = (0,0,z) vertexes.append(vertex) return vertexes def horizontal_regular_pyramid_vertexes(sidescount,radius,z, startangle = 0): vertexes = [] odd = 0 if (sidescount % 2) == 0: odd = 1 if radius != 0 : for i in range(0,sidescount+1): angle = 2 * math.pi * i / sidescount + (math.pi * (odd/sidescount + 1/2)) + startangle * math.pi / 180 vertex = (radius * math.cos(angle), radius * math.sin(angle), z) vertexes.append(vertex) else: vertex = (0,0,z) vertexes.append(vertex) return vertexes # =========================================================================== class Pyramid: radius1value = 0 radius2value = 0 sidescountvalue = 0 side1value = 0 side2value = 0 anglez = 0 def __init__(self, obj, sidescount = 5,radius_bottom = 2 , radius_top = 4, height = 10, angz = 0): obj.addProperty("App::PropertyLength","Radius1","Pyramid","Radius of the pyramid").Radius1=radius_bottom obj.addProperty("App::PropertyLength","Radius2","Pyramid","Radius of the pyramid").Radius2=radius_top obj.addProperty("App::PropertyLength","Height","Pyramid","Height of the pyramid").Height = height obj.addProperty("App::PropertyInteger","Sidescount","Pyramid","Sidescount of the pyramid").Sidescount = sidescount obj.addProperty("App::PropertyLength","Sidelength1","Pyramid","Sidelength1 of the pyramid") obj.addProperty("App::PropertyLength","Sidelength2","Pyramid","Sidelength2 of the pyramid") obj.addProperty("App::PropertyAngle","Z_rotation","Pyramid","alfa angle around Z").Z_rotation = angz obj.Proxy = self def execute (self,obj): sidescount = int(obj.Sidescount) angle = 2 * math.pi / sidescount radius_bottom = float(obj.Radius1) radius_top = float(obj.Radius2) sidelength_top = float(obj.Sidelength2) sidelength_bottom = float(obj.Sidelength1) height = float(obj.Height) anglez = float(obj.Z_rotation) if radius_bottom != self.radius1value or sidescount != self.sidescountvalue: obj.Sidelength1 = radius_bottom * math.sin(angle/2) * 2 self.radius1value = radius_bottom self.side1value = float(obj.Sidelength1) elif sidelength_bottom != self.side1value: self.radius1value = float(obj.Sidelength1 / 2) / math.sin(angle/2) obj.Radius1 = self.radius1value radius_bottom = self.radius1value self.side1value = float(obj.Sidelength1) if radius_top != self.radius2value or sidescount != self.sidescountvalue: obj.Sidelength2 = radius_top * math.sin(angle/2) * 2 self.radius2value = float(radius_top) self.side2value = float(obj.Sidelength2) elif sidelength_top != self.side2value: self.radius2value = float(obj.Sidelength2 / 2) / math.sin(angle/2) obj.Radius2 = self.radius2value radius_top = self.radius2value self.side2value = float(obj.Sidelength2) self.sidescountvalue = sidescount faces = [] if radius_bottom == 0 and radius_top == 0: FreeCAD.Console.PrintMessage("Both radiuses are zero" + "\n") else: vertexes_bottom = horizontal_regular_pyramid_vertexes(sidescount,radius_bottom,0 ,anglez) vertexes_top = horizontal_regular_pyramid_vertexes(sidescount,radius_top ,height,anglez) if radius_bottom != 0: polygon_bottom = Part.makePolygon(vertexes_bottom) face_bottom = Part.Face(polygon_bottom) faces.append(face_bottom) if radius_top != 0: polygon_top = Part.makePolygon(vertexes_top) face_top = Part.Face(polygon_top) faces.append(face_top) for i in range(sidescount): if radius_top == 0: vertexes_side=[vertexes_bottom[i],vertexes_bottom[i+1],vertexes_top[0],vertexes_bottom[i]] elif radius_bottom == 0: vertexes_side=[vertexes_bottom[0],vertexes_top[i+1],vertexes_top[i],vertexes_bottom[0]] else: vertexes_side=[vertexes_bottom[i],vertexes_bottom[i+1],vertexes_top[i+1],vertexes_top[i],vertexes_bottom[i]] polygon_side=Part.makePolygon(vertexes_side) faces.append(Part.Face(polygon_side)) shell = Part.makeShell(faces) solid = Part.makeSolid(shell) obj.Shape = solid # =========================================================================== class ViewProviderBox: def __init__(self, obj): obj.Proxy = self def attach(self, obj): return def updateData(self, fp, prop): return def getDisplayModes(self,obj): return "As Is" def getDefaultDisplayMode(self): return "As Is" def setDisplayMode(self,mode): return "As Is" def onChanged(self, vobj, prop): pass def getIcon(self): return """ /* XPM */ static char * xpm[] = { "32 32 9 1", " c None", ". c #01035E", "+ c #0F0C1D", "@ c #4849B7", "# c #5F5E61", "$ c #6567FE", "% c #8E9192", "& c #A5A6A4", "* c #FBFEFA", " ", " ", " # ", " +# ", " &++# ", " #+++% ", " ++.@+& ", " &++.$++& ", " %++@$$++& ", " #++@$$@++& ", " &+++@$$$@++& ", " %+.+@$$$$+.+& ", " #+.+@$$$$$+.+& ", " &+..+@$$$$$@+.+& ", " &+..+@$$$$$$@+.+& ", " #+..+@$$$$$$$+..+& ", " +..++@$$$$$$$$+..+& ", " %+++++++@$$$$$$@+..+& ", " #++++...+++@$$$$.+..+& ", " +........+++@$$+...+& ", " &+.........+++.+...+ ", " #+...........++...+ ", " #+...........++..+ ", " +............+..+ ", " &++...........+.+ ", " %+++........+++ ", " &#++.......++ ", " #++..+++++& ", " %++#% ", " ", " ", " "}; """ def __getstate__(self): return None def __setstate__(self,state): return None # =========================================================================== if FreeCAD.ActiveDocument == None: FreeCAD.newDocument() create ("Pyramid") FreeCADGui.SendMsgToActiveView("ViewFit")
Link
The forum discussion Macros for pyramids and polyhedrons