Message 1 of 3
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi everyone,
I am relatively new to Fusion API and am trying to use it to create a model of a propeller. The code I wrote creates a series of cross sections at several radial points of the blade. I would like to have my code loft those features together to create the whole model of the blade. When using loftFeature in code it produces an error but if I then go into the UI and edit the loft feature it created it will produce the model no problem. The part that is troubling me is at the end of the run function. Is there a way to get past this error?
Thanks in advance!
Peter
import adsk.core, adsk.fusion, adsk.cam, traceback, math def run(context): ui = None try: app = adsk.core.Application.get() ui = app.userInterface #define geometry PropOD = 17.78 # outer diameter of the whole propeller numSections = 20 # number of airfoil cross sections defined per blade heightVal = PropOD*.0486 #define the thickness of the hub as a percent of the Propeller diameter #roR = radius of cross section/propeller radius #coD = chord/propeller diameter #t0oc = max thickness/chord #f0oc = max camber/chord roR = [0.0675, 0.1407, 0.2134, 0.2852, 0.3557, 0.4243, 0.4908, 0.5547, 0.6156, 0.6731, 0.7269, 0.7766, 0.8219, 0.8626, 0.8984, 0.929, 0.9544, 0.9742, 0.9885, 0.9971, 1.0] coD = [0.0409, 0.0622, 0.0846, 0.1019, 0.1116, 0.1151, 0.1138, 0.1088, 0.1015, 0.0927, 0.0834, 0.0745, 0.0662, 0.058, 0.0518, 0.0486, 0.0416, 0.0315, 0.0208, 0.0102, 0.001] t0oc = [0.1157, 0.081, 0.0719, 0.0711, 0.071, 0.071, 0.0713, 0.0714, 0.0716, 0.0715, 0.0708, 0.0705, 0.0704, 0.0715, 0.0718, 0.0702, 0.072, 0.064, 0.0465, 0.0244, -0.0] f0oc = [0.3638, 0.2974, 0.1941, 0.1415, 0.1137, 0.098, 0.0888, 0.0838, 0.0817, 0.0815, 0.0825, 0.0838, 0.085, 0.0861, 0.0826, 0.077, 0.0737, 0.0716, 0.0704, 0.0697, 0.0695] pitch = [37.8052, 36.0376, 28.5569, 23.1935, 19.4709, 16.8137, 14.8683, 13.4188, 12.3222, 11.485, 10.836, 10.3208, 9.9027, 9.5636, 9.1906, 8.8226, 8.5587, 8.3667, 8.2378, 8.1642, 8.1403] #---------------------------------------------------------------------- design = app.activeProduct # what's open at the time # Get the root component of the active design. rootComp = design.rootComponent #create planes planes = rootComp.constructionPlanes planeInput = planes.createInput() R = PropOD/2 #propeller radius attackAngleList = pitch offsetVals = [] #create a list of values for the offset planes for i in range(0,numSections): offsetVal = adsk.core.ValueInput.createByReal(roR[i]*R) offsetVals.append(offsetVal) xSec0 = .4632*heightVal #define the radius of the initial cross section chordScale = [] #creat list of chord scaling attackAngleList_rad = [] #create list of attack angles in radians for i in range(0,len(roR)): attackAngleList_rad.append(attackAngleList[i]*math.pi/180) # make the angles into radians chordScale.append(coD[i]*PropOD) # Create a new sketch on the xy plane. sketches = rootComp.sketches #sketches comes from the object model(that big tree) xyPlane = rootComp.xYConstructionPlane # tell it to use xy plane sketch = sketches.add(xyPlane) #take sketches object and add it to the xy plane # add cross section 0 in here (the xy plane) the radius should be adjusted to reflect the height value circles = sketch.sketchCurves.sketchCircles circle1 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), xSec0) #get sketch profile profile = sketch.profiles.item(0) # Create loft feature input loftFeats = rootComp.features.loftFeatures loftInput = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation) loftSectionsObj = loftInput.loftSections loftSectionsObj.add(profile) #create the second profile planeInput.setByOffset(xyPlane, offsetVals[0]) Plane_1 = planes.add(planeInput) sketches = rootComp.sketches #sketches comes from the object model(that big tree) sketch_2 = sketches.add(Plane_1) #take sketches object and add it to the PLane_1 circles = sketch.sketchCurves.sketchCircles circle2 = circles.addByCenterRadius(adsk.core.Point3D.create(0, 0, 0), xSec0) profile = sketch.profiles.item(0) loftSectionsObj.add(profile) for i in range(2,numSections): #create the cross sections for each point of the radius, starting from the 3rd radial point becasue the first two cross section wer too thin and had too much camber profile = crossSectionCreator(attackAngleList_rad[i],chordScale[i],PropOD,numSections,offsetVals[i],f0oc[i],t0oc[i]) loftSectionsObj.add(profile) loftInput.isSolid = True blade = loftFeats.add(loftInput) except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc())) def crossSectionCreator(attackAngle,chord,PropOD,numSections,offset,f0oc,t0oc): ui = None try: app = adsk.core.Application.get() ui = app.userInterface design = app.activeProduct #what's open at the time # Get the root component of the active design. rootComp = design.rootComponent #sets up the top level component of the design in fusion xyPlane = rootComp.xYConstructionPlane # tell it to use xy plane #create 16 planes from 0 to R planes = rootComp.constructionPlanes planeInput = planes.createInput() planeInput.setByOffset(xyPlane, offset) Plane_1 = planes.add(planeInput) # Create a new sketch on the work plane 1. sketches = rootComp.sketches #sketches comes from the object model(that big tree) sketch_1 = sketches.add(Plane_1) #take sketches object and add it to the PLane_1 pointsList_1 = [] #a list of all the points for the first cross section points_1 = adsk.core.ObjectCollection.create() #create the point collection for the first cross section xCoorList = [] #create a list of all x coordinates xCoordList = [0,.005,.0075,.0125,.025,.05,.075,.10,.15,.20,.25,.30,.35,.40,.45,.50,.55,.60,.65,.70,.75,.80,.85,.90,.95,1] yCoorList = [] #toc is the thickness/chord at each x value toc = [0,.00765,.00928,.01183,.01623,.02182,.0265,.0304,.03658,.04127,.04483,.04742,.04912,.04995,.04983,.04863,.04632,.04304,.03899,.03432,.02912,.02352,.01771,.01188,.00604,.00021] t0oc_scale = t0oc/max(toc) toc = [i * t0oc_scale for i in toc] pointsList = [] # create an empty list to keep track of the points to plot the airfoil xyCoordList = [0,0] for i in range(0,len(xCoordList)-1): #run thru the list backwards to create negative y coor xCoord = xCoordList[len(xCoordList)-1-i] yCoord = (-(toc[len(toc)-1-i])/2) xyCoordList[0] = xCoord xyCoordList[1] = yCoord pointsList.append(xyCoordList[:]) xyCoordList = [0,0] pointsList.append(xyCoordList[:]) for i in range(1,len(xCoordList)):#run thru the list forward to create positive y coor xCoord = xCoordList[i] yCoord = ((toc[i])/2) xyCoordList[0] = xCoord xyCoordList[1] = yCoord pointsList.append(xyCoordList[:]) #add camber fof0 = [0,0.0422424851726010,0.0593926061968285,0.0906323084802032,0.158483525134397,0.270931306877788,0.365394143890664,0.447811008675706,0.586552890627142,0.698817437077800,0.789957166562438,0.862944523603016,0.919556283803553,0.960850115191575,0.987381517219326,0.999299100103072,0.996365017088989,0.977907976432830,0.942682218138460,0.888536838448501,0.811548821711142,0.702243798510330,0.542003516481535,0.358366674805168,0.171113059574976,4.65743561188795e-11] yCoorMeanCamberLine = [] #this is f #dfof0dxoc is dimensionless slope of the mean camber line dfof0dxoc = [8.86648212455747,7.14348529861109,6.61217039234403,5.94005607895737,5.01947707446513,4.07954342980629,3.51284803126115,3.09821832429069,2.48609887456089,2.02135629339510,1.63380592532664,1.29146814418333,0.976460919354681,0.677114163075186,0.384630792942005,0.0912942925837331,-0.210851915769909,-0.531483751613063,-0.884477130569965,-1.29366100928359,-1.81194534231248,-2.70919436130699,-3.52064353360441,-3.76526230389796,-3.66538904077040,-3.00042531135620] for i in range(0,len(fof0)): #loop for upper values yCoorMeanCamberLine.append(fof0[i]*f0oc) theta = math.atan(dfof0dxoc[i]*f0oc) yCoord = yCoorMeanCamberLine[i]+(toc[i]/2)*math.cos(theta) xCoord = pointsList[len(pointsList)-len(fof0)+i][0]-(toc[i]/2)*math.sin(theta) xyCoordList = [xCoord,yCoord] pointsList[len(pointsList)-len(fof0)+i] = (xyCoordList[:]) for i in range(0,len(fof0)):#loop for lower values theta = math.atan(dfof0dxoc[len(dfof0dxoc)-1-i]*f0oc) yCoord = yCoorMeanCamberLine[len(yCoorMeanCamberLine)-1-i]-(toc[len(toc)-1-i]/2)*math.cos(theta) xCoord = pointsList[i][0]+(toc[len(toc)-1-i]/2)*math.sin(theta) xyCoordList = [xCoord,yCoord] pointsList[i] = xyCoordList[:] for i in range(0,len(pointsList)): #this loop will step through and manipulate each point #get the x and y point as a decimal xcoord = float(pointsList[i][0]) ycoord = float(pointsList[i][1]) if xcoord == 0 or ycoord == 0:#leave the point at 0,0 alone xcoord = xcoord ycoord = ycoord else: #scale the chord length of the cross section xcoord = xcoord*chord ycoord = ycoord*chord #change the attack angle of the cross section s = (xcoord**2+ycoord**2)**(1/2) #length from origin to the point theta = attackAngle-math.atan(ycoord/xcoord) xcoord = s*math.cos(theta) ycoord = -s*math.sin(theta) # make a list of the x and y coordinates xCoorList.append(xcoord) yCoorList.append(ycoord) #save the coordinate in the list xy_1 = [xcoord,ycoord] pointsList_1.append(xy_1) for i in range(0,len(pointsList_1)): #move the the cross section to the middle now that its been scaled and twisted xcoord = float(pointsList_1[i][0]) ycoord = float(pointsList_1[i][1]) xcoord = xcoord-max(xCoorList)/2 ycoord = ycoord-min(yCoorList)/2 xy_1 = [xcoord,ycoord] pointsList_1[i] = xy_1 points_1.add(adsk.core.Point3D.create(xcoord, ycoord, 0)) #add the new point to the collection lines = sketch_1.sketchCurves.sketchLines; # connect the end of the spline to complete the sketch lines.addByTwoPoints(adsk.core.Point3D.create(pointsList_1[0][0], pointsList_1[0][1], 0), adsk.core.Point3D.create(pointsList_1[i][0], pointsList_1[i][1], 0)) sketch_1.sketchCurves.sketchFittedSplines.add(points_1) # create a spline curve connecting the points profile = sketch_1.profiles.item(0) #creates the profile to be lofted return profile # allow to profile to be accessed outside this function except: if ui: ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
Solved! Go to Solution.