This repository has been archived on 2023-01-27. You can view files and clone it, but cannot push or open issues or pull requests.
cad/fusion360/python/Samples/Bottle/Bottle.py
2022-10-15 19:16:08 +02:00

275 lines
11 KiB
Python

#Author-Autodesk Inc.
#Description-Create a bottle.
import adsk.core, adsk.fusion, traceback, math
# scale of the bottle size
scale = 2.0
# unit - cm
height = 21
topWidth = 2.8
topHight = 1.9
bodyTopWidth = 0.4
bottomWidth = 3.2
upperArcCenterToTop = 4.5
upperArcRadius = 16
lowerArcRadius = 15
filletRadius = 0.5
thickness = 0.3
threadPitch = 0.4
# used for direct modeling
upperArcMidPtXOffset = -0.18
upperArcMidPtYOffset = -4.1
upperArcEndPtXOffset = 0.46
upperArcEndPtYOffset = -7.2
lowerArcMidPtXOffsetFromOriginPt = 4.66
lowerArcMidPtYOffsetFromOriginPt = 5.9
bottomCenter = adsk.core.Point3D.create(0, 0, 0)
bottleMaterial = 'PrismMaterial-006'
bottleAppearance = 'Prism-154'
materialLibId = 'C1EEA57C-3F56-45FC-B8CB-A9EC46A9994C'
appearanceLibId = 'BA5EE55E-9982-449B-9D66-9F036540E140'
nearZero = 0.000001
app = adsk.core.Application.get()
ui = app.userInterface
newComp = None
def createNewComponent():
# Get the active design.
product = app.activeProduct
design = adsk.fusion.Design.cast(product)
rootComp = design.rootComponent
allOccs = rootComp.occurrences
newOcc = allOccs.addNewComponent(adsk.core.Matrix3D.create())
return newOcc.component
def createBottle():
product = app.activeProduct
design = adsk.fusion.Design.cast(product)
if not design:
ui.messageBox('It is not supported in current workspace, please change to MODEL workspace and try again.')
return
currentDesignType = design.designType
global newComp
newComp = createNewComponent()
if newComp is None:
ui.messageBox('New component failed to create', 'New Component Failed')
return
# add sketch
sketches = newComp.sketches
sketch = sketches.add(newComp.xYConstructionPlane)
# add sketch curves
sketchlines = sketch.sketchCurves.sketchLines
endPt = bottomCenter.copy() #start from bottomCenter
endPt.y = bottomCenter.y + height
heightLine = sketchlines.addByTwoPoints(bottomCenter, endPt)
endPt.x = endPt.x + topWidth
topLine = sketchlines.addByTwoPoints(heightLine.endSketchPoint, endPt)
endPt.y = endPt.y - topHight
topHightLine = sketchlines.addByTwoPoints(topLine.endSketchPoint, endPt)
endPt.x = endPt.x + bodyTopWidth
topBodyLine = sketchlines.addByTwoPoints(topHightLine.endSketchPoint, endPt)
sketchArcs = sketch.sketchCurves.sketchArcs
if currentDesignType == adsk.fusion.DesignTypes.DirectDesignType:
endPt.x = topBodyLine.endSketchPoint.geometry.x + upperArcEndPtXOffset
endPt.y = topBodyLine.endSketchPoint.geometry.y + upperArcEndPtYOffset
ptOnArc = adsk.core.Point3D.create(topBodyLine.endSketchPoint.geometry.x + upperArcMidPtXOffset, topBodyLine.endSketchPoint.geometry.y + upperArcMidPtYOffset)
upperArc = sketchArcs.addByThreePoints(topBodyLine.endSketchPoint, ptOnArc, endPt)
endPt = bottomCenter.copy()
endPt.x = bottomWidth
ptOnArc = adsk.core.Point3D.create(lowerArcMidPtXOffsetFromOriginPt, lowerArcMidPtYOffsetFromOriginPt)
else:
deltPos = 0.1
endPt.x = topWidth + bodyTopWidth + bodyTopWidth
endPt.y = height / 2
ptOnArc = adsk.core.Point3D.create(endPt.x - deltPos, endPt.y + deltPos)
upperArc = sketchArcs.addByThreePoints(topBodyLine.endSketchPoint, ptOnArc, endPt)
endPt = bottomCenter.copy()
endPt.x = bottomWidth
ptOnArc = adsk.core.Point3D.create(endPt.x + deltPos, endPt.y + deltPos)
lowerArc = sketchArcs.addByThreePoints(upperArc.endSketchPoint, ptOnArc, endPt)
buttomLine = sketchlines.addByTwoPoints(lowerArc.startSketchPoint, heightLine.startSketchPoint)
# add constraints
heightLine.startSketchPoint.isFixed = True
sketchConstraints = sketch.geometricConstraints
sketchConstraints.addHorizontal(buttomLine)
sketchConstraints.addPerpendicular(buttomLine, heightLine)
sketchConstraints.addPerpendicular(heightLine, topLine)
sketchConstraints.addPerpendicular(topLine, topHightLine)
sketchConstraints.addPerpendicular(topHightLine, topBodyLine)
# add dimensions
sketchDims = sketch.sketchDimensions
startPt = heightLine.startSketchPoint.geometry
endPt = heightLine.endSketchPoint.geometry
textPos = adsk.core.Point3D.create((startPt.x + endPt.x) / 2, (startPt.y + endPt.y) / 2, 0)
textPos.x = textPos.x - 1
sketchDims.addDistanceDimension(heightLine.startSketchPoint, heightLine.endSketchPoint, adsk.fusion.DimensionOrientations.AlignedDimensionOrientation, textPos)
startPt = topLine.startSketchPoint.geometry
endPt = topLine.endSketchPoint.geometry
textPos = adsk.core.Point3D.create((startPt.x + endPt.x) / 2, (startPt.y + endPt.y) / 2, 0)
textPos.y = textPos.y + 1
sketchDims.addDistanceDimension(topLine.startSketchPoint, topLine.endSketchPoint, adsk.fusion.DimensionOrientations.AlignedDimensionOrientation, textPos)
startPt = topHightLine.startSketchPoint.geometry
endPt = topHightLine.endSketchPoint.geometry
textPos = adsk.core.Point3D.create((startPt.x + endPt.x) / 2, (startPt.y + endPt.y) / 2, 0)
textPos.x = textPos.x + 1
sketchDims.addDistanceDimension(topHightLine.startSketchPoint, topHightLine.endSketchPoint, adsk.fusion.DimensionOrientations.AlignedDimensionOrientation, textPos)
startPt = topBodyLine.startSketchPoint.geometry
endPt = topBodyLine.endSketchPoint.geometry
textPos = adsk.core.Point3D.create((startPt.x + endPt.x) / 2, (startPt.y + endPt.y) / 2, 0)
textPos.y = textPos.y + 1
sketchDims.addDistanceDimension(topBodyLine.startSketchPoint, topBodyLine.endSketchPoint, adsk.fusion.DimensionOrientations.AlignedDimensionOrientation, textPos)
startPt = buttomLine.startSketchPoint.geometry
endPt = buttomLine.endSketchPoint.geometry
textPos = adsk.core.Point3D.create((startPt.x + endPt.x) / 2, (startPt.y + endPt.y) / 2, 0)
textPos.y = textPos.y - 1
sketchDims.addDistanceDimension(buttomLine.startSketchPoint, buttomLine.endSketchPoint, adsk.fusion.DimensionOrientations.AlignedDimensionOrientation, textPos)
startPt = topLine.endSketchPoint.geometry
endPt = upperArc.centerSketchPoint.geometry
textPos = adsk.core.Point3D.create((startPt.x + endPt.x) / 2, (startPt.y + endPt.y) / 2, 0)
if currentDesignType == adsk.fusion.DesignTypes.DirectDesignType:
sketchDims.addDistanceDimension(topLine.endSketchPoint, upperArc.centerSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, textPos)
else:
distDim = sketchDims.addDistanceDimension(topLine.endSketchPoint, upperArc.centerSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, textPos)
distDim.parameter.value = upperArcCenterToTop
startPt = upperArc.centerSketchPoint.geometry
textPos = adsk.core.Point3D.create(startPt.x + deltPos, startPt.y, 0)
radialArc = sketchDims.addRadialDimension(upperArc, textPos)
radialArc.parameter.value = upperArcRadius
startPt = lowerArc.centerSketchPoint.geometry
textPos = adsk.core.Point3D.create(startPt.x + deltPos, startPt.y, 0)
radialArc = sketchDims.addRadialDimension(lowerArc, textPos)
radialArc.parameter.value = lowerArcRadius
# create revolve
revolveFeats = newComp.features.revolveFeatures
revolveInput = revolveFeats.createInput(sketch.profiles[0], heightLine, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
revolveInput.setAngleExtent(True, adsk.core.ValueInput.createByReal(2 * math.pi))
revolveFeat = revolveFeats.add(revolveInput)
# create fillets
filletFeats = newComp.features.filletFeatures
# select the edges to do fillets
faces = revolveFeat.faces
body = faces[0].body
edgeCol = adsk.core.ObjectCollection.create()
for edge in body.edges:
circle = edge.geometry
if math.fabs(circle.radius - bottomWidth) < nearZero or math.fabs(circle.radius - topWidth - bodyTopWidth) < nearZero:
edgeCol.add(edge)
filletInput = filletFeats.createInput()
filletInput.addConstantRadiusEdgeSet(edgeCol, adsk.core.ValueInput.createByReal(filletRadius), True)
filletFeats.add(filletInput)
# create shell
shellFeats = newComp.features.shellFeatures
# select the faces to remove
faceCol = adsk.core.ObjectCollection.create()
for face in faces:
# find the top face
if face.geometry.surfaceType == adsk.core.SurfaceTypes.PlaneSurfaceType:
edge0 = face.edges[0]
if edge0.geometry.center.isEqualTo(heightLine.endSketchPoint.worldGeometry):
faceCol.add(face)
break
shellInput = shellFeats.createInput(faceCol)
shellInput.insideThickness = adsk.core.ValueInput.createByReal(thickness)
shellFeats.add(shellInput)
# create thread
threadFeats = newComp.features.threadFeatures
# select the face to do thread
threadFace = None
for faceTemp in faces:
surf = faceTemp.geometry
if surf.surfaceType == adsk.core.SurfaceTypes.CylinderSurfaceType and math.fabs(surf.radius - topWidth) < nearZero:
threadFace = faceTemp
break
threadQuery = threadFeats.threadDataQuery
threadType = threadQuery.defaultMetricThreadType
designation = ''
threadClass = ''
results = threadQuery.recommendThreadData(topWidth * 2, False, threadType)
if results[0]:
designation = results[1]
threadClass = results[2]
# find closest thread pitch
threadInfo = threadFeats.createThreadInfo(False, threadType, designation, threadClass)
designations = threadQuery.allDesignations(threadType, threadInfo.threadSize)
minGap = math.fabs(threadInfo.threadPitch - threadPitch)
for des in designations :
tempThreadInfo = threadFeats.createThreadInfo(False, threadType, des, threadClass)
tempGap = math.fabs(tempThreadInfo.threadPitch - threadPitch)
if tempGap < minGap :
threadInfo = tempThreadInfo
minGap = tempGap
faces = adsk.core.ObjectCollection.create()
faces.add(threadFace)
threadInput = threadFeats.createInput(faces, threadInfo)
threadInput.isModeled = True
threadFeats.add(threadInput)
# create scale
scaleFeats = newComp.features.scaleFeatures
objCol = adsk.core.ObjectCollection.create()
objCol.add(body)
scaleInput = scaleFeats.createInput(objCol, newComp.originConstructionPoint, adsk.core.ValueInput.createByReal(scale))
scaleFeats.add(scaleInput)
# set material
materialLibs = app.materialLibraries
materials = materialLibs.itemById(materialLibId).materials
appearances = materialLibs.itemById(appearanceLibId).appearances
body.material = materials.itemById(bottleMaterial)
body.appearance = appearances.itemById(bottleAppearance)
app.activeViewport.refresh()
def run(context):
try:
createBottle()
except:
if ui:
ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))