- simple but uneditable,
- slightly more complicated but fully real-time editable by values in the Property view fields.
- Create lines with start- and endpoint positions based on the epitrochoid equations.
- Connect lines in a one closed polyline.
- Upgrade polyline (wire) to face.
- Cut epitrochoid face from rectangle face (for simplicity rectangle is the external shape of our block).
- Extrude result face in a solid.
Non-parametric way:
Open a new document. Put below script in the Python interpreter line or create a macro. (Download macro)from __future__ import division # allows floating point division from integers
import FreeCAD, FreeCADGui, Part
from FreeCAD import Base
import math
steps=360 #number of polyline segments
dang=math.radians(360/steps) #step angle
e=10 #eccentricity
r=60 #radius
ang=0 #start anle
z=0 #line z coordinate
halfw=r+e+20
halfh=r+e+20
for i in range(steps): #make many lines and connect they in wire (polyline, epitrochoid)
if i==0: #for first line
x1=e*math.cos(3*ang)+r*math.cos(ang) #coords for line startpoint
y1=e*math.sin(3*ang)+r*math.sin(ang)
ang=dang
x2=e*math.cos(3*ang)+r*math.cos(ang) #coords for line endpoint
y2=e*math.sin(3*ang)+r*math.sin(ang)
seg=Part.makeLine((x1,y1,z),(x2,y2,z))
wire2=Part.Wire([seg])
x1=x2
y1=y2
else:
x2=e*math.cos(3*ang)+r*math.cos(ang)
y2=e*math.sin(3*ang)+r*math.sin(ang)
seg=Part.makeLine((x1,y1,z),(x2,y2,z))
wire2=Part.Wire([wire2,seg])
x1=x2
y1=y2
ang=ang+dang #increment angle
edge1 = Part.makeLine((-halfw,halfh,0), (halfw,halfh,0)) #lines needed to create rectangle
edge2 = Part.makeLine((halfw,halfh,0), (halfw,-halfh,0))
edge3 = Part.makeLine((halfw,-halfh,0), (-halfw,-halfh,0))
edge4 = Part.makeLine((-halfw,-halfh,0), (-halfw,halfh,0))
wire1 = Part.Wire([edge1,edge2,edge3,edge4]) #rectangle
face1 = Part.Face(wire1) #face from rectangle
face2=Part.Face(wire2) #face from epitrochoid http://en.wikipedia.org/wiki/Epitrochoid
diff = face1.cut(face2) #boolean cut epitrochoid from rectangle
ext=diff.extrude(Base.Vector(0,0,30)) #extrude the cut (face)
Part.show(ext) #show extrude in FreeCAD window
You should see Shape object in the Tree view and Wankel block model in the view area. You can click Fits the whole content of the screen button to tune view area. Unfortunately the Shape is not editable:(
Parametric way:
Open a new document and create a macro from below code (download macro):
from __future__ import division # allows floating point division from integers
import FreeCAD, Part, math
from FreeCAD import Base
class WankelBlock:
def __init__(self, obj):
''' Add the properties: Radius, Eccentricity, Height, Segments (see Property View) '''
obj.addProperty("App::PropertyLength","Radius","Wankel","Base radius").Radius=60.0
obj.addProperty("App::PropertyLength","Eccentricity","Wankel","Rotor eccentricity").Eccentricity=12.0
obj.addProperty("App::PropertyLength","Height","Wankel","Height of the block").Height=30.0
obj.addProperty("App::PropertyLength","Segments","Wankel","Number of the line segments").Segments=72
obj.Proxy = self
def onChanged(self, fp, prop):
if prop == "Radius" or prop == "Eccentricity" or prop == "Height" or prop == "Segments": #if one of these is changed
self.execute(fp)
def execute(self, fp): #main part of script
steps=int(fp.Segments) #get value from property
dang=math.radians(360/steps)
e=fp.Eccentricity
r=fp.Radius
h=fp.Height
ang=0
z=0
halfw=r+e+20
halfh=r+e+20
for i in range(steps):
if i==0:
x1=e*math.cos(3*ang)+r*math.cos(ang) #coords for line startpoint
y1=e*math.sin(3*ang)+r*math.sin(ang)
ang=dang
x2=e*math.cos(3*ang)+r*math.cos(ang) #coords for line endpoint
y2=e*math.sin(3*ang)+r*math.sin(ang)
seg=Part.makeLine((x1,y1,z),(x2,y2,z))
wire2=Part.Wire([seg])
x1=x2
y1=y2
else:
x2=e*math.cos(3*ang)+r*math.cos(ang)
y2=e*math.sin(3*ang)+r*math.sin(ang)
seg=Part.makeLine((x1,y1,z),(x2,y2,z))
wire2=Part.Wire([wire2,seg])
x1=x2
y1=y2
ang=ang+dang #increment angle
edge1 = Part.makeLine((-halfw,halfh,0), (halfw,halfh,0)) #lines needed to create rectangle
edge2 = Part.makeLine((halfw,halfh,0), (halfw,-halfh,0))
edge3 = Part.makeLine((halfw,-halfh,0), (-halfw,-halfh,0))
edge4 = Part.makeLine((-halfw,-halfh,0), (-halfw,halfh,0))
wire1 = Part.Wire([edge1,edge2,edge3,edge4]) #rectangle
face1 = Part.Face(wire1) #face from rectangle
face2=Part.Face(wire2) #face from epitrochoid http://en.wikipedia.org/wiki/Epitrochoid
diff = face1.cut(face2) #boolean cut epitrochoid from rectangle
ext=diff.extrude(Base.Vector(0,0,h)) #extrude the cut (face)
fp.Shape = ext #result shape
def makeWankelBlock():
doc = FreeCAD.activeDocument()
if doc == None:
doc = FreeCAD.newDocument()
wankelblock=doc.addObject("Part::FeaturePython","Wankel_Block") #add object to document
wankelblock.Label = "Wankel Block"
WankelBlock(wankelblock)
wankelblock.ViewObject.Proxy=0
if __name__ == "__main__": #feature will be generated after macro execution
makeWankelBlock()
After macro execution effect should be similar to first one. But take look in the Property View-Data. If you change one of the properties (radius, eccentricity, etc.) model will be automatically refreshed.
Properties can be also changed from the command line. As example, type:
App.activeDocument().getObject("Wankel_Block").Radius = 80
Comments are in the scripts code (after "#").
I have used four spaces for indentation.
Download RAW Video.
FreeCAD 0.12 5150 SVN
No comments:
Post a Comment