diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..1734f57
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,8 @@
+*.pyc
+__pycache__
+.env
+.vscode/*
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
diff --git a/Builders/BodyBlankBuilder.py b/Builders/BodyBlankBuilder.py
new file mode 100644
index 0000000..fe48dde
--- /dev/null
+++ b/Builders/BodyBlankBuilder.py
@@ -0,0 +1,87 @@
+import os, sys
+import adsk.core, adsk.fusion, adsk.cam, traceback, math
+from math import sqrt
+from ..ParameterValues import ParameterValues
+
+class BodyBlankBuilder:
+
+ def __init__(self, app):
+ self.app = app
+ self.design = app.activeProduct
+
+ def buildBodyBlank(self, parameters: ParameterValues):
+ rootComp = self.design.rootComponent
+ allOccs = rootComp.occurrences
+ blanksOcc = allOccs.addNewComponent(adsk.core.Matrix3D.create())
+
+ blanksComp = adsk.fusion.Component.cast(blanksOcc.component)
+
+ bodyLength = parameters.bodyLength
+ bodyWidth = parameters.bodyWidth
+ bodyThickness = parameters.bodyThickness
+ headstockLength = parameters.headstockLength
+ headstockWidth = parameters.headstockWidth
+ headstockThickness = parameters.headstockThickness
+ guitarLength = parameters.guitarLength
+
+ # Create a new sketch.
+ sketches = blanksComp.sketches
+ xzPlane = blanksComp.xYConstructionPlane
+
+ #Get extrude features
+ extrudes = blanksComp.features.extrudeFeatures
+
+ #Create sketch for bridge spacing
+ sketch1 = sketches.add(xzPlane)
+ sketch1.isComputeDeferred = False
+ sketch1.name = 'Body Blank'
+ bodyBlankSketch = sketch1.sketchCurves.sketchLines
+ bodyBlank = bodyBlankSketch.addTwoPointRectangle(adsk.core.Point3D.create(0, -bodyWidth/2, 0), adsk.core.Point3D.create(bodyLength, bodyWidth/2, 0))
+
+ #Create sketch for bridge spacing
+ sketch2 = sketches.add(xzPlane)
+ sketch2.isComputeDeferred = False
+ sketch2.name = 'Headstock Blank'
+ headstockBlankSketch = sketch2.sketchCurves.sketchLines
+ headstockBlank = headstockBlankSketch.addTwoPointRectangle(adsk.core.Point3D.create(guitarLength-headstockLength, -headstockWidth/2, 0), adsk.core.Point3D.create(guitarLength, headstockWidth/2, 0))
+
+ #Get extrude features
+ extrudes = blanksComp.features.extrudeFeatures
+ bodyProf = sketch1.profiles.item(0)
+ headstockProf = sketch2.profiles.item(0)
+ bodyExtrude = extrudes.addSimple(bodyProf, adsk.core.ValueInput.createByReal(-bodyThickness), adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+
+ # Get the extrusion body
+ bodyBody = bodyExtrude.bodies.item(0)
+ bodyExtrude.name = "Extrusion: Body Blank"
+ bodyBody.name = "Body Blank"
+ headstockExtrude = extrudes.addSimple(headstockProf, adsk.core.ValueInput.createByReal(-headstockThickness), adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+
+ # Get the extrusion body
+ headstockBody = headstockExtrude.bodies.item(0)
+ headstockExtrude.name = "Extrusion: Headstock Blank"
+ headstockBody.name = "Headstock Blank"
+
+ # Get a reference to an appearance in the library.
+ lib = self.app.materialLibraries.itemByName('Fusion 360 Appearance Library')
+ libAppear1 = lib.appearances.itemByName('Wax (White)')
+ blanksAppearance1 = blanksComp.bRepBodies.item(0)
+ blanksAppearance1.appearance = libAppear1
+ blanksAppearance2 = blanksComp.bRepBodies.item(1)
+ blanksAppearance2.appearance = libAppear1
+
+ #Centers the camera to fit the entire fretboard
+ cam = self.app.activeViewport.camera
+ cam.isFitView = True
+ cam.isSmoothTransition = False
+ self.app.activeViewport.camera = cam
+
+ # Group everything used to create the fretboard in the timeline.
+ timelineGroupsBlanks = self.design.timeline.timelineGroups
+ blanksOccIndex = blanksOcc.timelineObject.index
+ blanksEndIndex = headstockExtrude.timelineObject.index
+ timelineGroupBlanks = timelineGroupsBlanks.add(blanksOccIndex, blanksEndIndex)
+ timelineGroupBlanks.name = 'Blanks'
+ blanksComp.name = 'Blanks'
+
+ return blanksComp
\ No newline at end of file
diff --git a/Builders/DimensionsBuilder.py b/Builders/DimensionsBuilder.py
new file mode 100644
index 0000000..79b292e
--- /dev/null
+++ b/Builders/DimensionsBuilder.py
@@ -0,0 +1,525 @@
+import os, sys
+import adsk.core, adsk.fusion, adsk.cam, traceback, math
+from math import sqrt
+from ..ParameterValues import ParameterValues
+
+class DimensionsBuilder:
+
+ def __init__(self, app):
+ self.app = app
+ self.design = app.activeProduct
+
+ def buildDimensions(self, parameters: ParameterValues):
+
+ rootComp = self.design.rootComponent
+ allOccs2 = rootComp.occurrences
+ newOcc2 = allOccs2.addNewComponent(adsk.core.Matrix3D.create())
+ dimsComp = adsk.fusion.Component.cast(newOcc2.component)
+
+ fretNumber = parameters.fretNumber
+ scaleLength = parameters.scaleLength
+ nutLength = parameters.nutLength
+ endLength = parameters.endLength
+ nutRadius = parameters.nutRadius
+ endRadius = parameters.endRadius
+ fretboardHeight = parameters.fretboardHeight
+ filletRadius = parameters.filletRadius
+ endCurve = parameters.endCurve
+ tangWidth = parameters.tangWidth
+ bridgeStringSpacing = parameters.bridgeStringSpacing
+ tangDepth = parameters.tangDepth
+ nutSlotWidth = parameters.nutSlotWidth
+ nutSlotDepth = parameters.nutSlotDepth
+ markerDiameter = parameters.markerDiameter
+ markerDepth = parameters.markerDepth
+ markerSpacing = parameters.markerSpacing
+ guitarLength = parameters.guitarLength
+ bodyWidth = parameters.bodyWidth
+ headstockLength = parameters.headstockLength
+ bodyLength = parameters.bodyLength
+ stringCount = parameters.stringCount
+ nutToPost = parameters.nutToPost
+ machinePostHoleSpacing = parameters.machinePostHoleSpacing
+ machinePostHoleDiameter = parameters.machinePostHoleDiameter
+ machinePostDiameter = parameters.machinePostDiameter
+ nutStringSpacing = parameters.nutStringSpacing
+ fretboardLength = parameters.fretboardLength + parameters.fretboardLengthOffset
+ headstockStyle = parameters.headstockStyle
+ neckSpacing = parameters.neckSpacing
+ bridgeSpacing = parameters.bridgeSpacing
+ singleCoilLength = parameters.singleCoilLength
+ singleCoilWidth = parameters.singleCoilWidth
+ singleCoilDepth = parameters.singleCoilDepth
+ humbuckerLength = parameters.humbuckerLength
+ humbuckerWidth = parameters.humbuckerWidth
+ humbuckerDepth = parameters.humbuckerDepth
+ humbuckerFillet = parameters.humbuckerFillet
+ pickupNeck = parameters.pickupNeck
+ pickupMiddle = parameters.pickupMiddle
+ pickupBridge = parameters.pickupBridge
+ pickupCavityMountLength = parameters.pickupCavityMountLength
+ pickupCavityMountTabWidth = parameters.pickupCavityMountTabWidth
+ bridgePickupAngle = self.design.unitsManager.convert(parameters.bridgePickupAngle, 'deg', 'rad')
+
+ #Equation for fret spacing
+ for fretNum in range(1,int((fretNumber))+1):
+ fretDistance = (scaleLength)-((scaleLength)/(2**(fretNum/12.0)))
+
+ #This calculates and rounds the total length of the fretboard using the scale length and number of frets
+ L = fretboardLength
+ stringInset = (nutLength - nutStringSpacing)/2
+ nutDistance = guitarLength - headstockLength
+ width = (nutLength-(stringInset*2)) + (2*sqrt(((L/(math.cos(math.radians(math.acos((scaleLength**2+(sqrt((((bridgeStringSpacing-(nutLength-(stringInset*2)))/2)**2)+(scaleLength**2)))**2-
+ ((bridgeStringSpacing-(nutLength-(stringInset*2)))/2)**2)/(2*scaleLength*(sqrt((((bridgeStringSpacing-(nutLength-(stringInset*2)))/2)**2)+(scaleLength**2)))))*((180)/math.pi)))))**2)
+ -(L**2)))
+
+ # Create a new sketch.
+ sketches = dimsComp.sketches
+ yzPlane = dimsComp.yZConstructionPlane
+ xzPlane = dimsComp.xYConstructionPlane
+ xyPlane = dimsComp.xYConstructionPlane
+
+ #Create construction lines
+ sketch1 = sketches.add(xzPlane)
+ sketch1.isComputeDeferred = True
+ lines = sketch1.sketchCurves.sketchLines
+ sketch1.name = 'Boundary Dimensions'
+ sketch1.isVisible = True
+ sketch1.areDimensionsShown = True
+ sketch1.areConstraintsShown = False
+ sketch1.arePointsShown = False
+ sketch1.areProfilesShown = False
+ centerLine = lines.addByTwoPoints(adsk.core.Point3D.create(0, 0, 0), adsk.core.Point3D.create(guitarLength, 0, 0))
+ centerLine.isConstruction = True
+ centerLine.isFixed = True
+ originBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(0, bodyWidth/2, 0), adsk.core.Point3D.create(0, -bodyWidth/2, 0))
+ originBoundary.isConstruction = True
+ endBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(guitarLength, bodyWidth/2, 0), adsk.core.Point3D.create(guitarLength, -bodyWidth/2, 0))
+ endBoundary.isConstruction = True
+ topBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(0, bodyWidth/2, 0), adsk.core.Point3D.create(guitarLength, bodyWidth/2, 0))
+ topBoundary.isConstruction = True
+ bottomBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(0, -bodyWidth/2, 0), adsk.core.Point3D.create(guitarLength, -bodyWidth/2, 0))
+ bottomBoundary.isConstruction = True
+ bodyBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(bodyLength, bodyWidth/2, 0), adsk.core.Point3D.create(bodyLength, -bodyWidth/2, 0))
+ bodyBoundary.isConstruction = True
+ nutBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(nutDistance, bodyWidth/4, 0), adsk.core.Point3D.create(nutDistance, -bodyWidth/4, 0))
+ nutBoundary.isConstruction = True
+ bridgeBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength, bodyWidth/4, 0), adsk.core.Point3D.create(nutDistance-scaleLength, -bodyWidth/4, 0))
+ bridgeBoundary.isConstruction = True
+ fret12Boundary = lines.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength/2, bodyWidth/4, 0), adsk.core.Point3D.create(nutDistance-scaleLength/2, -bodyWidth/4, 0))
+ fret12Boundary.isConstruction = True
+
+ #Create dimension lines
+ sketch1.areDimensionsShown = True
+ sketch1.sketchDimensions.addDistanceDimension(topBoundary.startSketchPoint, topBoundary.endSketchPoint,
+ adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
+ adsk.core.Point3D.create((topBoundary.length/2), bodyWidth/2+4, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(originBoundary.startSketchPoint, originBoundary.endSketchPoint,
+ adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
+ adsk.core.Point3D.create(-4, 0, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(bridgeBoundary.startSketchPoint, fret12Boundary.startSketchPoint,
+ adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
+ adsk.core.Point3D.create((nutDistance-scaleLength+scaleLength/4), bodyWidth/4+2, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(fret12Boundary.startSketchPoint, nutBoundary.startSketchPoint,
+ adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
+ adsk.core.Point3D.create((nutDistance-scaleLength/4), bodyWidth/4+2, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(topBoundary.startSketchPoint, bodyBoundary.startSketchPoint,
+ adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
+ adsk.core.Point3D.create((bodyLength/2), bodyWidth/2+2, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(bodyBoundary.startSketchPoint, topBoundary.endSketchPoint,
+ adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
+ adsk.core.Point3D.create(((guitarLength+bodyLength)/2), bodyWidth/2+2, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(topBoundary.startSketchPoint, centerLine.startSketchPoint,
+ adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
+ adsk.core.Point3D.create(-2, bodyWidth/4, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(centerLine.startSketchPoint, bottomBoundary.startSketchPoint,
+ adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
+ adsk.core.Point3D.create(-2, -bodyWidth/4, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(centerLine.startSketchPoint, bridgeBoundary.startSketchPoint,
+ adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
+ adsk.core.Point3D.create(((guitarLength-headstockLength-scaleLength)/2), bodyWidth/4+2, 0), False)
+ sketch1.sketchDimensions.addDistanceDimension(nutBoundary.startSketchPoint, centerLine.endSketchPoint,
+ adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
+ adsk.core.Point3D.create((guitarLength-headstockLength/2), bodyWidth/4+2, 0), False)
+
+ sketch2 = sketches.add(xzPlane)
+ sketch2.isComputeDeferred = True
+ dimensionFrets = sketch2.sketchCurves.sketchLines
+ dimensionFrets2 = sketch2.sketchCurves.sketchLines
+ dimensionCircles = sketch2.sketchCurves.sketchCircles
+ dimensionCircles2 = sketch2.sketchCurves.sketchCircles
+ dimensionLines = sketch2.sketchCurves.sketchLines
+ humbuckerCavitySketch = sketch2.sketchCurves.sketchLines
+ sketch2.name = 'Core Dimensions'
+ sketch2.isVisible = True
+ sketch2.areDimensionsShown = True
+ sketch2.areConstraintsShown = False
+ sketch2.arePointsShown = False
+ sketch2.areProfilesShown = False
+
+ for fret in range(int(fretNumber)+1):
+ fretDistance = scaleLength-(scaleLength/(2**(fret/12.0)))
+
+ fretLength = nutLength + 2*sqrt(((fretDistance/(math.cos(math.radians(math.acos((L**2+(sqrt((((endLength-nutLength)/2)**2) +(L**2)))**2-
+ ((endLength-nutLength)/2)**2)/(2*L*(sqrt((((endLength-nutLength)/2)**2)+(L**2)))))*((180)/math.pi)))))**2)
+ -(fretDistance**2))
+
+ dimensioning = dimensionFrets.addByTwoPoints(adsk.core.Point3D.create((nutDistance-fretDistance), (fretLength/2), 0),
+ adsk.core.Point3D.create((nutDistance-fretDistance), (-fretLength/2), 0))
+ dimensioning.isConstruction = True
+
+ dimensioning2 = dimensionFrets2.addByTwoPoints(adsk.core.Point3D.create(nutDistance-L, (endLength/2), 0), adsk.core.Point3D.create(nutDistance-L, (-endLength/2), 0))
+ dimensioning2.isConstruction = True
+ bridgeLine2 = dimensionFrets2.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength, (bridgeStringSpacing/2), 0), adsk.core.Point3D.create(nutDistance-scaleLength, (-bridgeStringSpacing/2), 0))
+ bridgeLine2.isConstruction = True
+
+ for dime in range(int(fretNumber)):
+ sketchDime1 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets[0+dime].startSketchPoint, dimensionFrets[1+dime].startSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((nutDistance-scaleLength-(scaleLength/(-2**((dime+0.5)/12.0)))), 5, 0), False);
+
+ for dime in range(1, int(fretNumber)+1):
+ sketchDime1 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets[0].endSketchPoint, dimensionFrets[0+dime].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((nutDistance-scaleLength-(scaleLength/(-2**((dime-0.5)/12.0)))), -5-(dime/4), 0), False);
+
+ sketchDime2 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets[0].startSketchPoint,
+ dimensionFrets[0].endSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(nutDistance+2, 0, 0), False)
+ sketchDime3 = sketch2.sketchDimensions.addDistanceDimension(dimensioning2.startSketchPoint,
+ dimensioning2.endSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(nutDistance-L-1, 0, 0), False)
+ sketchDime4 = sketch2.sketchDimensions.addDistanceDimension(dimensioning2.endSketchPoint,
+ dimensionFrets[0].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance-L/2, -12, 0), False)
+ sketchDime5 = sketch2.sketchDimensions.addDistanceDimension(bridgeLine2.startSketchPoint,
+ dimensionFrets[0].startSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance-scaleLength/2, 8, 0), False)
+ sketchDime6 = sketch2.sketchDimensions.addDistanceDimension(bridgeLine2.startSketchPoint,
+ bridgeLine2.endSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(nutDistance-scaleLength-1, 0, 0), False)
+
+ if headstockStyle == 'Straight In-line':
+ #Create sketch for bridge spacing
+ for spacing in range(int(stringCount)):
+ holeSpacingVert = (nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/(int(stringCount)-1))*spacing
+ holeSpacingHor = spacing*machinePostHoleSpacing
+ machinePosts = dimensionCircles.addByTwoPoints(adsk.core.Point3D.create(nutDistance+nutToPost+holeSpacingHor, holeSpacingVert, 0), adsk.core.Point3D.create(nutDistance+nutToPost+holeSpacingHor, holeSpacingVert+(machinePostDiameter), 0))
+ machinePosts.isConstruction = True
+ for dime in range(int(stringCount)-1):
+ sketchDime7 = sketch2.sketchDimensions.addDistanceDimension(dimensionCircles[0+dime].centerSketchPoint, dimensionCircles[1+dime].centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
+ adsk.core.Point3D.create((nutDistance+nutToPost+machinePostHoleSpacing*dime)+machinePostHoleSpacing/2, 4, 0), False);
+ sketchDime8 = sketch2.sketchDimensions.addDistanceDimension(dimensionCircles[0+dime].centerSketchPoint, dimensionCircles[1+dime].centerSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
+ adsk.core.Point3D.create(guitarLength+2, (nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/(int(stringCount)-1))*dime, 0), False);
+ sketchDime9 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets.item(0).startSketchPoint, dimensionCircles.item(0).centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance+nutToPost/2, 4, 0), False);
+ else:
+ pass
+ machinePosts = sketch2.sketchCurves.sketchCircles
+ machinePostHole1 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostDiameter/2)
+ machinePostHole1.isConstruction = True
+ machinePostHole2 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostDiameter/2)
+ machinePostHole2.isConstruction = True
+ machinePostHole3 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostDiameter/2)
+ machinePostHole3.isConstruction = True
+ machinePostHole4 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostDiameter/2)
+ machinePostHole4.isConstruction = True
+ machinePostHole5 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostDiameter/2)
+ machinePostHole5.isConstruction = True
+ machinePostHole6 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostDiameter/2)
+ machinePostHole6.isConstruction = True
+ sketchDime10 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets.item(0).startSketchPoint, machinePostHole1.centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance+nutToPost/2, 4, 0), False)
+ sketchDime11 = sketch2.sketchDimensions.addDistanceDimension(machinePostHole1.centerSketchPoint, machinePostHole2.centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing/2, 4, 0), False)
+ sketchDime12 = sketch2.sketchDimensions.addDistanceDimension(machinePostHole2.centerSketchPoint, machinePostHole3.centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*1.5, 4, 0), False)
+ sketchDime13 = sketch2.sketchDimensions.addDistanceDimension(machinePostHole3.centerSketchPoint, machinePostHole4.centerSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(nutDistance+machinePostHoleSpacing*3+2, 0, 0), False)
+
+ ### PICKUPS
+ sketch3 = sketches.add(xzPlane)
+ sketch3.isComputeDeferred = True
+ sketch3.name = 'Pickup Dimensions'
+ sketch3.isVisible = True
+ sketch3.areDimensionsShown = True
+ sketch3.areConstraintsShown = False
+ sketch3.arePointsShown = False
+ sketch3.areProfilesShown = False
+ neckDistance = guitarLength - headstockLength - fretboardLength - neckSpacing
+ bridgeDistance = guitarLength - headstockLength - scaleLength + bridgeSpacing
+ middleDistance = bridgeDistance + (neckDistance - bridgeDistance)/2
+ neckLines = sketch3.sketchCurves.sketchLines
+ cavityNeckLines = sketch3.sketchCurves.sketchLines
+
+ if pickupNeck == "Single-Coil":
+ # Create sketch lines
+ pickupNeck1 = neckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2)+singleCoilWidth/2, (singleCoilLength/2), 0))
+ pickupNeck1[0].isConstruction = True
+ pickupNeck1[1].isConstruction = True
+ pickupNeck1[2].isConstruction = True
+ pickupNeck1[3].isConstruction = True
+ pickupNeck2 = neckLines.addByTwoPoints(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), (pickupCavityMountLength/2), 0))
+ pickupNeck2.isConstruction = True
+ pickupNeckFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[0], pickupNeck1[0].endSketchPoint.geometry, pickupNeck1[1], pickupNeck1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupNeckFillet1.isConstruction = True
+ pickupNeckFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[1], pickupNeck1[1].endSketchPoint.geometry, pickupNeck1[2], pickupNeck1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupNeckFillet2.isConstruction = True
+ pickupNeckFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[2], pickupNeck1[2].endSketchPoint.geometry, pickupNeck1[3], pickupNeck1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupNeckFillet3.isConstruction = True
+ pickupNeckFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[3], pickupNeck1[3].endSketchPoint.geometry, pickupNeck1[0], pickupNeck1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupNeckFillet4.isConstruction = True
+ cavityNeck1 = cavityNeckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2)+singleCoilWidth/2, (pickupCavityMountLength/2), 0))
+ cavityNeck1[0].isConstruction = True
+ cavityNeck1[1].isConstruction = True
+ cavityNeck1[2].isConstruction = True
+ cavityNeck1[3].isConstruction = True
+ cavityNeckFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[0], cavityNeck1[0].endSketchPoint.geometry, cavityNeck1[1], cavityNeck1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityNeckFillet1.isConstruction = True
+ cavityNeckFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[1], cavityNeck1[1].endSketchPoint.geometry, cavityNeck1[2], cavityNeck1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityNeckFillet2.isConstruction = True
+ cavityNeckFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[2], cavityNeck1[2].endSketchPoint.geometry, cavityNeck1[3], cavityNeck1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityNeckFillet3.isConstruction = True
+ cavityNeckFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[3], cavityNeck1[3].endSketchPoint.geometry, cavityNeck1[0], cavityNeck1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityNeckFillet4.isConstruction = True
+ elif pickupNeck == "Humbucker":
+ pickupNeck1 = neckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2)+humbuckerWidth/2, (humbuckerLength/2), 0))
+ pickupNeck1[0].isConstruction = True
+ pickupNeck1[1].isConstruction = True
+ pickupNeck1[2].isConstruction = True
+ pickupNeck1[3].isConstruction = True
+ pickupNeck2 = neckLines.addByTwoPoints(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), (pickupCavityMountLength/2), 0))
+ pickupNeck2.isConstruction = True
+ pickupNeckFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[0], pickupNeck1[0].endSketchPoint.geometry, pickupNeck1[1], pickupNeck1[1].startSketchPoint.geometry, humbuckerFillet)
+ pickupNeckFillet1.isConstruction = True
+ pickupNeckFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[1], pickupNeck1[1].endSketchPoint.geometry, pickupNeck1[2], pickupNeck1[2].startSketchPoint.geometry, humbuckerFillet)
+ pickupNeckFillet2.isConstruction = True
+ pickupNeckFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[2], pickupNeck1[2].endSketchPoint.geometry, pickupNeck1[3], pickupNeck1[3].startSketchPoint.geometry, humbuckerFillet)
+ pickupNeckFillet3.isConstruction = True
+ pickupNeckFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[3], pickupNeck1[3].endSketchPoint.geometry, pickupNeck1[0], pickupNeck1[0].startSketchPoint.geometry, humbuckerFillet)
+ pickupNeckFillet4.isConstruction = True
+ cavityNeck1 = cavityNeckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2)-pickupCavityMountTabWidth/2, (pickupCavityMountLength/2), 0))
+ cavityNeck1[0].isConstruction = True
+ cavityNeck1[1].isConstruction = True
+ cavityNeck1[2].isConstruction = True
+ cavityNeck1[3].isConstruction = True
+ cavityNeckFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[0], cavityNeck1[0].endSketchPoint.geometry, cavityNeck1[1], cavityNeck1[1].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityNeckFillet1.isConstruction = True
+ cavityNeckFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[1], cavityNeck1[1].endSketchPoint.geometry, cavityNeck1[2], cavityNeck1[2].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityNeckFillet2.isConstruction = True
+ cavityNeckFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[2], cavityNeck1[2].endSketchPoint.geometry, cavityNeck1[3], cavityNeck1[3].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityNeckFillet3.isConstruction = True
+ cavityNeckFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[3], cavityNeck1[3].endSketchPoint.geometry, cavityNeck1[0], cavityNeck1[0].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityNeckFillet4.isConstruction = True
+ else:
+ pass
+
+ middleLines = sketch3.sketchCurves.sketchLines
+ cavitymiddleLines = sketch3.sketchCurves.sketchLines
+
+ if pickupMiddle == "Single-Coil":
+ # Create sketch lines
+ pickupMiddle1 = middleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+singleCoilWidth/2), (singleCoilLength/2), 0))
+ pickupMiddle1[0].isConstruction = True
+ pickupMiddle1[1].isConstruction = True
+ pickupMiddle1[2].isConstruction = True
+ pickupMiddle1[3].isConstruction = True
+ pickupMiddle2 = middleLines.addByTwoPoints(adsk.core.Point3D.create((middleDistance), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((middleDistance), (pickupCavityMountLength/2), 0))
+ pickupMiddle2.isConstruction = True
+ pickupMiddleFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[0], pickupMiddle1[0].endSketchPoint.geometry, pickupMiddle1[1], pickupMiddle1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupMiddleFillet1.isConstruction = True
+ pickupMiddleFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[1], pickupMiddle1[1].endSketchPoint.geometry, pickupMiddle1[2], pickupMiddle1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupMiddleFillet2.isConstruction = True
+ pickupMiddleFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[2], pickupMiddle1[2].endSketchPoint.geometry, pickupMiddle1[3], pickupMiddle1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupMiddleFillet3.isConstruction = True
+ pickupMiddleFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[3], pickupMiddle1[3].endSketchPoint.geometry, pickupMiddle1[0], pickupMiddle1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupMiddleFillet4.isConstruction = True
+ cavityMiddle1 = cavitymiddleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+singleCoilWidth/2), (pickupCavityMountLength/2), 0))
+ cavityMiddle1[0].isConstruction = True
+ cavityMiddle1[1].isConstruction = True
+ cavityMiddle1[2].isConstruction = True
+ cavityMiddle1[3].isConstruction = True
+ cavityMiddleFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[0], cavityMiddle1[0].endSketchPoint.geometry, cavityMiddle1[1], cavityMiddle1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityMiddleFillet1.isConstruction = True
+ cavityMiddleFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[1], cavityMiddle1[1].endSketchPoint.geometry, cavityMiddle1[2], cavityMiddle1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityMiddleFillet2.isConstruction = True
+ cavityMiddleFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[2], cavityMiddle1[2].endSketchPoint.geometry, cavityMiddle1[3], cavityMiddle1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityMiddleFillet3.isConstruction = True
+ cavityMiddleFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[3], cavityMiddle1[3].endSketchPoint.geometry, cavityMiddle1[0], cavityMiddle1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityMiddleFillet4.isConstruction = True
+ elif pickupMiddle == "Humbucker":
+ # Create sketch lines
+ pickupMiddle1 = middleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+humbuckerWidth/2), (humbuckerLength/2), 0))
+ pickupMiddle1[0].isConstruction = True
+ pickupMiddle1[1].isConstruction = True
+ pickupMiddle1[2].isConstruction = True
+ pickupMiddle1[3].isConstruction = True
+ pickupMiddle2 = middleLines.addByTwoPoints(adsk.core.Point3D.create((middleDistance), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((middleDistance), (pickupCavityMountLength/2), 0))
+ pickupMiddle2.isConstruction = True
+ pickupMiddleFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[0], pickupMiddle1[0].endSketchPoint.geometry, pickupMiddle1[1], pickupMiddle1[1].startSketchPoint.geometry, humbuckerFillet)
+ pickupMiddleFillet1.isConstruction = True
+ pickupMiddleFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[1], pickupMiddle1[1].endSketchPoint.geometry, pickupMiddle1[2], pickupMiddle1[2].startSketchPoint.geometry, humbuckerFillet)
+ pickupMiddleFillet2.isConstruction = True
+ pickupMiddleFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[2], pickupMiddle1[2].endSketchPoint.geometry, pickupMiddle1[3], pickupMiddle1[3].startSketchPoint.geometry, humbuckerFillet)
+ pickupMiddleFillet3.isConstruction = True
+ pickupMiddleFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[3], pickupMiddle1[3].endSketchPoint.geometry, pickupMiddle1[0], pickupMiddle1[0].startSketchPoint.geometry, humbuckerFillet)
+ pickupMiddleFillet4.isConstruction = True
+ cavityMiddle1 = cavitymiddleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+pickupCavityMountTabWidth/2), (pickupCavityMountLength/2), 0))
+ cavityMiddle1[0].isConstruction = True
+ cavityMiddle1[1].isConstruction = True
+ cavityMiddle1[2].isConstruction = True
+ cavityMiddle1[3].isConstruction = True
+ cavityMiddleFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[0], cavityMiddle1[0].endSketchPoint.geometry, cavityMiddle1[1], cavityMiddle1[1].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityMiddleFillet1.isConstruction = True
+ cavityMiddleFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[1], cavityMiddle1[1].endSketchPoint.geometry, cavityMiddle1[2], cavityMiddle1[2].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityMiddleFillet2.isConstruction = True
+ cavityMiddleFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[2], cavityMiddle1[2].endSketchPoint.geometry, cavityMiddle1[3], cavityMiddle1[3].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityMiddleFillet3.isConstruction = True
+ cavityMiddleFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[3], cavityMiddle1[3].endSketchPoint.geometry, cavityMiddle1[0], cavityMiddle1[0].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityMiddleFillet4.isConstruction = True
+ else:
+ pass
+
+ bridgeLines = sketch3.sketchCurves.sketchLines
+ cavitybridgeLines = sketch3.sketchCurves.sketchLines
+ sketchPoints = sketch3.sketchPoints
+
+ # Create sketch point
+ if pickupBridge == "Single-Coil":
+ point1 = adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0)
+ elif pickupBridge == "Humbucker":
+ point1 = adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0)
+ else:
+ pass
+
+ sketchPoint1 = sketchPoints.add(point1)
+ sketchPoint1.isFixed = True
+
+ if pickupBridge == "Single-Coil":
+ # Create sketch lines
+ pickupBridge1 = bridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2)+singleCoilWidth/2, (singleCoilLength/2), 0))
+ pickupBridge1[0].isConstruction = True
+ pickupBridge1[1].isConstruction = True
+ pickupBridge1[2].isConstruction = True
+ pickupBridge1[3].isConstruction = True
+ pickupBridge2 = bridgeLines.addByTwoPoints(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), (pickupCavityMountLength/2), 0))
+ pickupBridge2.isConstruction = True
+ pickupBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[0], pickupBridge1[0].endSketchPoint.geometry, pickupBridge1[1], pickupBridge1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupBridgeFillet1.isConstruction = True
+ pickupBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[1], pickupBridge1[1].endSketchPoint.geometry, pickupBridge1[2], pickupBridge1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupBridgeFillet2.isConstruction = True
+ pickupBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[2], pickupBridge1[2].endSketchPoint.geometry, pickupBridge1[3], pickupBridge1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupBridgeFillet3.isConstruction = True
+ pickupBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[3], pickupBridge1[3].endSketchPoint.geometry, pickupBridge1[0], pickupBridge1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupBridgeFillet4.isConstruction = True
+ cavityBridge1 = cavitybridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2)+singleCoilWidth/2, (pickupCavityMountLength/2), 0))
+ cavityBridge1[0].isConstruction = True
+ cavityBridge1[1].isConstruction = True
+ cavityBridge1[2].isConstruction = True
+ cavityBridge1[3].isConstruction = True
+ cavityBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[0], cavityBridge1[0].endSketchPoint.geometry, cavityBridge1[1], cavityBridge1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityBridgeFillet1.isConstruction = True
+ cavityBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[1], cavityBridge1[1].endSketchPoint.geometry, cavityBridge1[2], cavityBridge1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityBridgeFillet2.isConstruction = True
+ cavityBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[2], cavityBridge1[2].endSketchPoint.geometry, cavityBridge1[3], cavityBridge1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityBridgeFillet3.isConstruction = True
+ cavityBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[3], cavityBridge1[3].endSketchPoint.geometry, cavityBridge1[0], cavityBridge1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityBridgeFillet4.isConstruction = True
+ pickupBridgeAngle = bridgeLines.addByTwoPoints(adsk.core.Point3D.create(bridgeDistance, 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth), 0, 0))
+ pickupBridgeAngle.isConstruction = True
+ # Constrain the Rectangle to stay rectangular
+ constraints = sketch3.geometricConstraints
+ constraints.addMidPoint(sketchPoint1, bridgeLines.item(22))
+ constraints.addMidPoint(sketchPoint1, bridgeLines.item(27))
+ constraints.addMidPoint(bridgeLines.item(27).startSketchPoint, bridgeLines.item(19))
+ constraints.addMidPoint(bridgeLines.item(27).endSketchPoint, bridgeLines.item(21))
+ constraints.addMidPoint(bridgeLines.item(27).startSketchPoint, cavitybridgeLines.item(24))
+ constraints.addMidPoint(bridgeLines.item(27).endSketchPoint, cavitybridgeLines.item(26))
+ constraints.addPerpendicular(bridgeLines.item(27), bridgeLines.item(22))
+ # all = adsk.core.ObjectCollection.create()
+ # for lines in range(bridgeLines[19:]):
+ # all.add(lines)
+ all = adsk.core.ObjectCollection.create()
+ all.add(bridgeLines.item(19))
+ all.add(bridgeLines.item(20))
+ all.add(bridgeLines.item(21))
+ all.add(bridgeLines.item(22))
+ all.add(bridgeLines.item(23))
+ all.add(bridgeLines.item(24))
+ all.add(bridgeLines.item(25))
+ all.add(bridgeLines.item(26))
+ all.add(bridgeLines.item(27))
+ all.add(sketchPoint1)
+ normal = sketch3.xDirection.crossProduct(sketch3.yDirection)
+ normal.transformBy(sketch3.transform)
+ origin = sketch3.origin
+ origin.transformBy(sketch3.transform)
+ matrix = adsk.core.Matrix3D.create()
+ matrix.setToRotation(-bridgePickupAngle, normal, origin)
+ sketch3.move(all, matrix)
+ elif pickupBridge == "Humbucker":
+ pickupBridge1 = bridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance), (humbuckerLength/2), 0))
+ pickupBridge1[0].isConstruction = True
+ pickupBridge1[1].isConstruction = True
+ pickupBridge1[2].isConstruction = True
+ pickupBridge1[3].isConstruction = True
+ pickupBridge2 = bridgeLines.addByTwoPoints(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), (pickupCavityMountLength/2), 0))
+ pickupBridge2.isConstruction = True
+ pickupBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[0], pickupBridge1[0].endSketchPoint.geometry, pickupBridge1[1], pickupBridge1[1].startSketchPoint.geometry, humbuckerFillet)
+ pickupBridgeFillet1.isConstruction = True
+ pickupBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[1], pickupBridge1[1].endSketchPoint.geometry, pickupBridge1[2], pickupBridge1[2].startSketchPoint.geometry, humbuckerFillet)
+ pickupBridgeFillet2.isConstruction = True
+ pickupBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[2], pickupBridge1[2].endSketchPoint.geometry, pickupBridge1[3], pickupBridge1[3].startSketchPoint.geometry, humbuckerFillet)
+ pickupBridgeFillet3.isConstruction = True
+ pickupBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[3], pickupBridge1[3].endSketchPoint.geometry, pickupBridge1[0], pickupBridge1[0].startSketchPoint.geometry, humbuckerFillet)
+ pickupBridgeFillet4.isConstruction = True
+ cavityBridge1 = cavitybridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2)-pickupCavityMountTabWidth/2, (pickupCavityMountLength/2), 0))
+ cavityBridge1[0].isConstruction = True
+ cavityBridge1[1].isConstruction = True
+ cavityBridge1[2].isConstruction = True
+ cavityBridge1[3].isConstruction = True
+ cavityBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[0], cavityBridge1[0].endSketchPoint.geometry, cavityBridge1[1], cavityBridge1[1].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityBridgeFillet1.isConstruction = True
+ cavityBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[1], cavityBridge1[1].endSketchPoint.geometry, cavityBridge1[2], cavityBridge1[2].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityBridgeFillet2.isConstruction = True
+ cavityBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[2], cavityBridge1[2].endSketchPoint.geometry, cavityBridge1[3], cavityBridge1[3].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityBridgeFillet3.isConstruction = True
+ cavityBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[3], cavityBridge1[3].endSketchPoint.geometry, cavityBridge1[0], cavityBridge1[0].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityBridgeFillet4.isConstruction = True
+ else:
+ pass
+ if pickupNeck == "Single-Coil":
+ pickupNeckDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck1[3].startSketchPoint, pickupNeck1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), -6, 0), False)
+ pickupNeckDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityNeck1[3].startSketchPoint, cavityNeck1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), -5, 0), False)
+ elif pickupNeck == "Humbucker":
+ pickupNeckDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck1[3].startSketchPoint, pickupNeck1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), -6, 0), False)
+ pickupNeckDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityNeck1[3].startSketchPoint, cavityNeck1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), -5, 0), False)
+ else:
+ pass
+ if pickupMiddle == "Single-Coil":
+ pickupMiddleDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupMiddle1[3].startSketchPoint, pickupMiddle1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((middleDistance), -6, 0), False)
+ pickupMiddleDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityMiddle1[3].startSketchPoint, cavityMiddle1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((middleDistance), -5, 0), False)
+ elif pickupMiddle == "Humbucker":
+ pickupMiddleDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupMiddle1[3].startSketchPoint, pickupMiddle1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((middleDistance), -6, 0), False)
+ pickupMiddleDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityMiddle1[3].startSketchPoint, cavityMiddle1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((middleDistance), -5, 0), False)
+ else:
+ pass
+ if pickupBridge == "Single-Coil":
+ pickupMiddleDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupBridge1[3].startSketchPoint, pickupBridge1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), -6, 0), False)
+ pickupMiddleDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityBridge1[3].startSketchPoint, cavityBridge1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), -5, 0), False)
+ elif pickupBridge == "Humbucker":
+ pickupMiddleDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupBridge1[3].startSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), -6, 0), False)
+ pickupMiddleDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityBridge1[3].startSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), -5, 0), False)
+ else:
+ pass
+ if pickupMiddle == "None":
+ pickupGapDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck2.endSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance + (neckDistance - bridgeDistance)/2, 7, 0), False)
+ else:
+ pickupGapDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck2.endSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance + (neckDistance - bridgeDistance)/2, 7, 0), False)
+ pickupGapDims2 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck2.endSketchPoint, pickupMiddle2.endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(middleDistance + (neckDistance - middleDistance)/2, 6, 0), False)
+ pickupGapDims2 = sketch3.sketchDimensions.addDistanceDimension(pickupMiddle2.endSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance + (middleDistance - bridgeDistance)/2, 6, 0), False)
+ pickupDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupBridge1[0].startSketchPoint, pickupBridge1[2].endSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance - 4, 0, 0), False)
+ pickupDims2 = sketch3.sketchDimensions.addDistanceDimension(pickupBridge2.endSketchPoint, pickupBridge2.startSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance - 5, 0, 0), False)
+
+ #Centers the camera to fit the entire fretboard
+ cam = self.app.activeViewport.camera
+ cam.isFitView = True
+ cam.isSmoothTransition = True
+ cam.viewOrientation = adsk.core.ViewOrientations.TopViewOrientation
+ self.app.activeViewport.camera = cam
+
+ # Group everything used to create the fretboard in the timeline.
+ timelineGroups2 = self.design.timeline.timelineGroups
+ newOccIndex2 = newOcc2.timelineObject.index
+ endIndex2 = sketch3.timelineObject.index
+ timelineGroup2 = timelineGroups2.add(newOccIndex2, endIndex2)
+ timelineGroup2.name = 'Dimensions'
+ dimsComp.name = 'Dimensions'
+
+ return dimsComp
\ No newline at end of file
diff --git a/Builders/FretboardBuilder.py b/Builders/FretboardBuilder.py
new file mode 100644
index 0000000..0070a4d
--- /dev/null
+++ b/Builders/FretboardBuilder.py
@@ -0,0 +1,429 @@
+import os, sys
+import adsk.core, adsk.fusion, adsk.cam, traceback, math
+from math import sqrt
+from ..ParameterValues import ParameterValues
+
+class FretboardBuilder:
+
+ def __init__(self, app):
+ self.app = app
+ self.design = app.activeProduct
+
+ def buildFretboard(self, parameters: ParameterValues):
+ rootComp = self.design.rootComponent
+ allOccs = rootComp.occurrences
+ newOcc = allOccs.addNewComponent(adsk.core.Matrix3D.create())
+
+ # Set local variables from parameters object to preserve existing code, refactor at some point..
+ fretboardStyle = parameters.fretboardStyle
+ fretNumber = parameters.fretNumber
+ scaleLength = parameters.scaleLength
+ nutLength = parameters.nutLength
+ endLength = parameters.endLength
+ radius = parameters.radius
+ nutRadius = parameters.nutRadius
+ endRadius = parameters.endRadius
+ fretboardHeight = parameters.fretboardHeight
+ filletRadius = parameters.filletRadius
+ endCurve = parameters.endCurve
+ tangWidth = parameters.tangWidth
+ tangDepth = parameters.tangDepth
+ blindFrets = parameters.blindFretInset
+ nutSlotWidth = parameters.nutSlotWidth
+ nutSlotDepth = parameters.nutSlotDepth
+ markerDiameter = parameters.markerDiameter
+ markerDepth = parameters.markerDepth
+ markerSpacing = parameters.markerSpacing
+ guitarLength = parameters.guitarLength
+ headstockLength = parameters.headstockLength
+ fretboardLength = parameters.fretboardLength + parameters.fretboardLengthOffset
+ firstFretThickness = parameters.firstFretThickness
+ twelfthfretThickness = parameters.twelfthfretThickness
+ neckThickness = parameters.neckThickness
+ headstockWidth = parameters.headstockWidth
+ headstockThickness = parameters.headstockThickness
+
+
+ fretboardComp = adsk.fusion.Component.cast(newOcc.component)
+ fretboardComp.description = 'Fretboard'
+
+ #Equation for fret spacing
+ for fretNum in range(1,int((fretNumber))+1):
+ fretDistance = (scaleLength)-((scaleLength)/(2**(fretNum/12.0)))
+
+ nutDistance = guitarLength - headstockLength
+
+ #This calculates and rounds the total length of the fretboard using the scale length and number of frets
+ L = fretboardLength
+
+ if fretboardStyle == "Straight Radius":
+ endRadius = nutRadius = radius
+ else:
+ pass
+
+ #Equation for defining the proper radii
+ endR = endRadius-sqrt(endRadius**2-(endLength/2)**2)
+ nutR = nutRadius-sqrt(nutRadius**2-(nutLength/2)**2)
+ endC = endCurve-sqrt(endCurve**2-(endLength/2)**2)
+
+ # Points defined for curves
+ if fretboardStyle == "Flat/No Radius":
+ endTopL = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/-2), fretboardHeight)
+ endTopC = adsk.core.Point3D.create(nutDistance-L, 0, fretboardHeight)
+ endTopR = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/2), fretboardHeight)
+ else:
+ endTopL = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/-2), fretboardHeight-endR)
+ endTopC = adsk.core.Point3D.create(nutDistance-L, 0, fretboardHeight)
+ endTopR = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/2), fretboardHeight-endR)
+
+ endBotL = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/-2), 0)
+ endBotC = adsk.core.Point3D.create(nutDistance-L, 0, 0)
+ endBotR = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/2), 0)
+ nutTopL = adsk.core.Point3D.create(nutDistance, (nutLength/-2), fretboardHeight-nutR)
+ nutTopC = adsk.core.Point3D.create(nutDistance, 0, fretboardHeight)
+ nutTopR = adsk.core.Point3D.create(nutDistance, (nutLength/2), fretboardHeight-nutR)
+
+ # Create a new sketch.
+ sketches = fretboardComp.sketches
+ xyPlane = fretboardComp.xYConstructionPlane
+ xzPlane = fretboardComp.xZConstructionPlane
+ yzPlane = fretboardComp.yZConstructionPlane
+
+ #create curve for bridge-end top arc
+ sketch1 = sketches.add(xyPlane)
+ sketch1.isComputeDeferred = True
+ sketchArc1 = sketch1.sketchCurves.sketchArcs
+ line1 = sketch1.sketchCurves.sketchLines
+
+ if parameters.createEndCurve and fretboardStyle == "Flat/No Radius":
+ path1 = sketchArc1.addByThreePoints(adsk.core.Point3D.create(nutDistance+endC-L, (endLength/2), fretboardHeight), adsk.core.Point3D.create(nutDistance-L, 0, fretboardHeight),
+ adsk.core.Point3D.create(nutDistance+endC-L, (endLength/-2), fretboardHeight))
+ elif parameters.createEndCurve:
+ path1 = sketchArc1.addByThreePoints(endTopL, endTopC, endTopR)
+ else:
+ path1 = sketchArc1.addByThreePoints(adsk.core.Point3D.create(nutDistance-L, (endLength/2), fretboardHeight-endR), adsk.core.Point3D.create(nutDistance-L, 0, fretboardHeight),
+ adsk.core.Point3D.create(nutDistance-L, (endLength/-2), fretboardHeight-endR))
+
+ openProfile1 = adsk.fusion.Path.create(path1.createForAssemblyContext(newOcc), adsk.fusion.ChainedCurveOptions.noChainedCurves)
+
+ if parameters.createEndCurve:
+ path2 = sketchArc1.addByThreePoints(endBotL, endBotC, endBotR)
+ else:
+ path2 = line1.addByTwoPoints(adsk.core.Point3D.create(nutDistance-L, (endLength/2), 0), adsk.core.Point3D.create(nutDistance-L, (endLength/-2), 0))
+
+ openProfile2 = adsk.fusion.Path.create(path2.createForAssemblyContext(newOcc), adsk.fusion.ChainedCurveOptions.noChainedCurves)
+
+ if fretboardStyle == "Flat/No Radius":
+ path3 = line1.addByTwoPoints(adsk.core.Point3D.create(nutDistance, (nutLength/-2), fretboardHeight), adsk.core.Point3D.create(nutDistance, (nutLength/2), fretboardHeight))
+ else:
+ path3 = sketchArc1.addByThreePoints(nutTopL, nutTopC, nutTopR)
+
+ openProfile3 = adsk.fusion.Path.create(path3.createForAssemblyContext(newOcc), adsk.fusion.ChainedCurveOptions.noChainedCurves)
+
+ path4 = line1.addByTwoPoints(adsk.core.Point3D.create(nutDistance, (nutLength/-2), 0), adsk.core.Point3D.create(nutDistance, (nutLength/2), 0))
+
+ openProfile4 = adsk.fusion.Path.create(path4.createForAssemblyContext(newOcc), adsk.fusion.ChainedCurveOptions.noChainedCurves)
+
+ line1.addByTwoPoints(path1.startSketchPoint, path3.startSketchPoint)
+ line1.addByTwoPoints(path2.startSketchPoint, path4.endSketchPoint)
+ line1.addByTwoPoints(path1.endSketchPoint, path3.endSketchPoint)
+ line1.addByTwoPoints(path2.endSketchPoint, path4.startSketchPoint)
+
+ sketch1.name = 'Fretboard curves'
+ sketch1.arePointsShown = False
+ sketch1.isVisible = False
+
+ #Create sketch for fret lines
+ sketch5 = sketches.add(xyPlane)
+ sketch5.isComputeDeferred = True
+ frets = sketch5.sketchCurves.sketchLines
+ sketch5.name = 'Fret Lines (Reference)'
+ sketch5.isVisible = False
+
+ #Create sketch for fret cuts
+ sketch6 = sketches.add(xyPlane)
+ sketch6.isComputeDeferred = False
+ cuts = sketch6.sketchCurves.sketchLines
+ sketch6.name = 'Fret slots [ ' + str(fretNumber) + ' frets ]'
+ sketch6.isVisible = False
+
+ #create sketch for nut cut
+ sketch7 = sketches.add(xyPlane)
+ sketch7.isComputeDeferred = False
+ nutSketch = sketch7.sketchCurves.sketchLines
+ nutSlotsketch = nutSketch.addTwoPointRectangle(adsk.core.Point3D.create(nutDistance, nutLength, fretboardHeight),
+ adsk.core.Point3D.create(nutDistance+nutSlotWidth, -nutLength, fretboardHeight))
+ nutProfile = sketch7.profiles.item(0)
+ sketch7.name = 'Nut slot profile'
+ sketch7.isVisible = False
+
+ #create sketch for nut cut
+ sketch9 = sketches.add(xyPlane)
+ sketch9.isComputeDeferred = False
+ fretMarker = sketch9.sketchCurves.sketchCircles
+ sketch9.name = 'Inlays'
+ sketch9.isVisible = False
+ sketch10 = sketches.add(xyPlane)
+ sketch10.isComputeDeferred = True
+ inplayPoints = sketch10.sketchPoints
+ sketch10.name = 'Default Marker Positions'
+ sketch10.isVisible = False
+
+ # Create surface for bridge-end of fretboard
+ loftFeats = fretboardComp.features.loftFeatures
+ loftInput1 = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+ loftSections1 = loftInput1.loftSections
+ loftSections1.add(openProfile2)
+ loftSections1.add(openProfile1)
+ loftInput1.isSolid = False
+ loft1 = loftFeats.add(loftInput1)
+ l1 = loft1.faces[0]
+ loft1.name = 'Loft: Fretboard End'
+
+ # Create surface for nut-end of fretboard
+ loftInput2 = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+ loftSections2 = loftInput2.loftSections
+ loftSections2.add(openProfile3)
+ loftSections2.add(openProfile4)
+ loftInput2.isSolid = False
+ loft2 = loftFeats.add(loftInput2)
+ l2 = loft2.faces[0]
+ loft2.name = 'Loft: Fretboard Start'
+
+ # Create new surface using previous surfaces
+ loftInput3 = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+ loftSections3 = loftInput3.loftSections
+ loftSections3.add(l1)
+ loftSections3.add(l2)
+ loftInput3.isSolid = False
+ loft3 = loftFeats.add(loftInput3)
+ l3 = loft3.faces[0]
+ loft3.name = 'Loft: Fretboard'
+
+ # Get surface bodies and add them to object collection
+ surface1 = loft1.bodies.item(0)
+ surface2 = loft2.bodies.item(0)
+ surface3 = loft3.bodies.item(0)
+ surfaces = adsk.core.ObjectCollection.create()
+ surfaces.add(surface1)
+ surfaces.add(surface2)
+ surfaces.add(surface3)
+
+ # Define tolerance
+ tolerance = adsk.core.ValueInput.createByString('0.001 in')
+
+ # Create a stitch input to be able to define the input needed for an stitch.
+ stitches = fretboardComp.features.stitchFeatures
+ stitchInput = stitches.createInput(surfaces, tolerance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+
+ # Create a stitch feature.
+ stitch = stitches.add(stitchInput)
+ stitch.name = 'Stitch: Fretboard'
+
+ #Select edges of bridge-end of fretboard to make fillets
+ fretboardEndFace = stitch.bodies.item(0)
+ fretboardEndEdge1 = fretboardEndFace.edges.item(1)
+ fretboardEndEdge2 = fretboardEndFace.edges.item(3)
+
+ #Create collection
+ endEdges = adsk.core.ObjectCollection.create()
+ endEdges.add(fretboardEndEdge1)
+ endEdges.add(fretboardEndEdge2)
+
+ if parameters.createFilletRadius:
+ #Creating fillets
+ fillets = fretboardComp.features.filletFeatures
+ filletInput = fillets.createInput()
+ filletInput.addConstantRadiusEdgeSet(endEdges, adsk.core.ValueInput.createByReal(filletRadius), True)
+ filletInput.isG2 = False
+ filletInput.isRollingBallCorner = True
+ fillet = fillets.add(filletInput)
+ fillet.name = 'Rounded Corners'
+ else:
+ pass
+
+ # Get the body created by the stitch
+ face = stitch.bodies.item(0)
+ if parameters.createFilletRadius:
+ topFace = face.faces.item(6)
+ else:
+ topFace = face.faces.item(4)
+
+ # Create input entities for offset feature
+ inputEntities = adsk.core.ObjectCollection.create()
+ inputEntities.add(topFace)
+
+ # Create an input for offset feature
+ offsetFeature = fretboardComp.features.offsetFeatures
+ offsetInput = offsetFeature.createInput(inputEntities, adsk.core.ValueInput.createByReal(-tangDepth),
+ adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+
+ #Get the surface body.
+ extrudeFeature = offsetFeature.add(offsetInput)
+ extrudeFeature.name = 'Offset: Fret Projections'
+ offSurf = extrudeFeature.bodies.item(0)
+ offSurf.name = 'Reference for fret cuts'
+ offSurf.isVisible = False
+
+ #Get an edge from surface, and add it to object collection.
+ extend = offSurf.edges
+ ext1 = extend.item(0)
+ ext2 = extend.item(1)
+ ext3 = extend.item(2)
+ ext4 = extend.item(3)
+ inputEdges = adsk.core.ObjectCollection.create()
+ inputEdges.add(ext1)
+ inputEdges.add(ext2)
+ inputEdges.add(ext3)
+ inputEdges.add(ext4)
+
+ #Define a distance to extend.
+ distance = adsk.core.ValueInput.createByString('0.5 in')
+
+ #Create an extend input to be able to define the input needed for an extend.
+ extendFeatures = fretboardComp.features.extendFeatures
+ extendFeatureInput1 = extendFeatures.createInput(inputEdges, distance, adsk.fusion.SurfaceExtendTypes.NaturalSurfaceExtendType)
+
+ #Create an extend feature.
+ extendFeature1 = extendFeatures.add(extendFeatureInput1)
+ extendFeature1.name = 'Extend: Fret Projections'
+
+ #Create loop for fret spacing and creation
+ fretSpacing = []
+ for fret in range(1,int(fretNumber)+1):
+ fretDistance = scaleLength-(scaleLength/(2**(fret/12.0)))
+ fretSpacing.append(fretDistance)
+ fretLength = nutLength + 2*sqrt(((fretDistance/(math.cos(math.radians(math.acos((L**2+(sqrt((((endLength-nutLength)/2)**2) +(L**2)))**2-
+ ((endLength-nutLength)/2)**2)/(2*L*(sqrt((((endLength-nutLength)/2)**2)+(L**2)))))*((180)/math.pi)))))**2)
+ -(fretDistance**2))
+ if parameters.createBlindFrets:
+ #Create fret lines for fret spacing reference
+ fretLines = frets.addByTwoPoints(adsk.core.Point3D.create((nutDistance-fretDistance), ((fretLength/2)-(blindFrets/2)), fretboardHeight),
+ adsk.core.Point3D.create((nutDistance-fretDistance), ((-fretLength/2)+(blindFrets/2)), fretboardHeight))
+ #Create fret cuts
+ cutLines = cuts.addTwoPointRectangle(adsk.core.Point3D.create((nutDistance-fretDistance-(tangWidth/2)), ((-fretLength/2)+(blindFrets/2)), fretboardHeight),
+ adsk.core.Point3D.create((nutDistance-fretDistance+(tangWidth/2)), ((fretLength/2)-(blindFrets/2)), fretboardHeight))
+ else:
+ #Create fret lines for fret spacing reference
+ fretLines = frets.addByTwoPoints(adsk.core.Point3D.create((nutDistance-fretDistance), ((fretLength/2)+(1)), fretboardHeight),
+ adsk.core.Point3D.create((nutDistance-fretDistance), ((-fretLength/2)-(1)), fretboardHeight))
+ #Create fret cuts
+ cutLines = cuts.addTwoPointRectangle(adsk.core.Point3D.create((nutDistance-fretDistance-(tangWidth/2)), ((-fretLength/2)-(1)), fretboardHeight),
+ adsk.core.Point3D.create((nutDistance-fretDistance+(tangWidth/2)), ((fretLength/2)+(1)), fretboardHeight))
+
+ inlays = [((y-x)/2)+x for x, y in zip(fretSpacing,fretSpacing[1:])]
+
+ for inlayOdd in inlays[1:9:2] + inlays[13:21:2]:
+ fretMarker.addByCenterRadius(adsk.core.Point3D.create(nutDistance-inlayOdd, 0, fretboardHeight), markerDiameter)
+ points = adsk.core.Point3D.create(nutDistance-inlayOdd, 0, fretboardHeight)
+ sketch10 = inplayPoints.add(points)
+
+ for inlayOdd in inlays[25:33:2]:
+ fretMarker.addByCenterRadius(adsk.core.Point3D.create(nutDistance-inlayOdd, 0, fretboardHeight), markerDiameter/2)
+ points = adsk.core.Point3D.create(nutDistance-inlayOdd, 0, fretboardHeight)
+ sketch10 = inplayPoints.add(points)
+
+ for inlayEven in inlays[10:24:12]:
+ fretMarker.addByCenterRadius(adsk.core.Point3D.create(nutDistance-inlayEven, markerSpacing/2, fretboardHeight), markerDiameter)
+ fretMarker.addByCenterRadius(adsk.core.Point3D.create(nutDistance-inlayEven, -markerSpacing/2, fretboardHeight), markerDiameter)
+ points = adsk.core.Point3D.create(nutDistance-inlayEven, 0, fretboardHeight)
+ sketch10 = inplayPoints.add(points)
+
+ fretMarkers = adsk.core.ObjectCollection.create()
+
+ for markers in sketch9.profiles:
+ fretMarkers.add(markers)
+
+ fretboard = stitch.bodies.item(0)
+ fretboard.name = 'Fretboard' + ' [ ' + str(fretNumber) + ' frets ]'
+ fretboardFaces = [face for face in fretboard.faces]
+
+ if parameters.createFilletRadius:
+ fretboardSurf = fretboardFaces[6::2]
+ else:
+ fretboardSurf = fretboardFaces[4::2]
+
+ fretCurves = [curve for curve in sketch5.sketchCurves]
+ sketch8 = sketches.add(xyPlane)
+ sketch8.isComputeDeferred = True
+ fretProj = sketch8.projectToSurface(fretboardSurf, fretCurves, adsk.fusion.SurfaceProjectTypes.AlongVectorSurfaceProjectType,
+ fretboardComp.zConstructionAxis)
+ sketch8.name = 'Fret Lines [ ' + str(fretNumber) + ' frets ]'
+ sketch8.isVisible = False
+
+ #Create an object collection to use an input.
+ profs = adsk.core.ObjectCollection.create()
+
+ #Add all of the profiles to the collection.
+ for prof in sketch6.profiles:
+ profs.add(prof)
+
+ #Get extrude features
+ extrudes = fretboardComp.features.extrudeFeatures
+
+ if parameters.createFretMarkers:
+ #Extrusion for fret markers
+ markerExtrude = extrudes.addSimple(fretMarkers, adsk.core.ValueInput.createByReal(-markerDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ markerExtrude.name = 'Extrusion: Fret Markers'
+ else:
+ pass
+
+ # Extrude Sample 4: Create an extrusion that goes from the profile plane to a specified entity.
+ extrudeInput1 = extrudes.createInput(profs, adsk.fusion.FeatureOperations.CutFeatureOperation)
+ extentToEntity = adsk.fusion.ToEntityExtentDefinition.create(extrudeFeature.faces.item(0), True)
+
+ # Set the one side extent with the to-entity-extent-definition, and with a taper angle of 0 degree
+ extrudeInput1.setOneSideExtent(extentToEntity, adsk.fusion.ExtentDirections.PositiveExtentDirection)
+
+ #Extrusion for adding material to the nut-end of the fretboard
+ if parameters.createFilletRadius:
+ nutExtend = extrudes.addSimple(fretboardFaces[4], distance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+ else:
+ nutExtend = extrudes.addSimple(fretboardFaces[1], distance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
+
+ nutExt = nutExtend.bodies.item(0)
+ nutExt.name = 'Extension'
+ nutExtend.name = 'Extrusion: Extension'
+ nutSlot = extrudes.addSimple(nutProfile, adsk.core.ValueInput.createByReal(-nutSlotDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ nutSlot.name = 'Extrusion: Nut Slot'
+
+ if parameters.createFretCuts:
+ #Create the extrusion
+ extrude1 = extrudes.add(extrudeInput1)
+ extrude1.name = 'Extrusion: Cutting Frets'
+
+ if parameters.extensionVisible:
+ nutExt.isVisible = True
+ else:
+ nutExt.isVisible = False
+
+ # Get a reference to an appearance in the library.
+ lib = self.app.materialLibraries.itemByName('Fusion 360 Appearance Library')
+ libAppear1 = lib.appearances.itemByName('Paint - Enamel Glossy (Yellow)')
+ libAppear2 = lib.appearances.itemByName('Wax (White)')
+ fretboardAppearance1 = fretboardComp.bRepBodies.item(0)
+ fretboardAppearance1.appearance = libAppear1
+ fretboardAppearance2 = fretboardComp.bRepBodies.item(1)
+ fretboardAppearance2.appearance = libAppear1
+ offSurf.appearance = libAppear2
+
+ #Centers the camera to fit the entire fretboard
+ cam = self.app.activeViewport.camera
+ cam.isFitView = True
+ cam.isSmoothTransition = False
+ self.app.activeViewport.camera = cam
+
+ # Group everything used to create the fretboard in the timeline.
+ timelineGroups = self.design.timeline.timelineGroups
+ newOccIndex = newOcc.timelineObject.index
+
+ if parameters.createFretCuts:
+ endIndex = extrude1.timelineObject.index
+ else:
+ endIndex = nutSlot.timelineObject.index
+
+ timelineGroup = timelineGroups.add(newOccIndex, endIndex)
+ timelineGroup.name = 'Fretboard [ ' + str(fretNumber) + ' Frets ]'
+ fretboardComp.name = 'Fretboard' + ' [ ' + str(fretNumber) + ' Frets ]'
+
+ return fretboardComp
diff --git a/Builders/PickupsBuilder.py b/Builders/PickupsBuilder.py
new file mode 100644
index 0000000..572180f
--- /dev/null
+++ b/Builders/PickupsBuilder.py
@@ -0,0 +1,329 @@
+import os, sys
+import adsk.core, adsk.fusion, adsk.cam, traceback, math
+from math import sqrt
+from ..ParameterValues import ParameterValues
+
+class PickupsBuilder:
+
+ def __init__(self, app):
+ self.app = app
+ self.design = app.activeProduct
+
+ def buildPickups(self, parameters: ParameterValues):
+
+ rootComp = self.design.rootComponent
+ pickupsOccs = rootComp.occurrences
+ pickupsOcc = pickupsOccs.addNewComponent(adsk.core.Matrix3D.create())
+ pickupsComp = adsk.fusion.Component.cast(pickupsOcc.component)
+
+ guitarLength = parameters.guitarLength
+ headstockLength = parameters.headstockLength
+ scaleLength = parameters.scaleLength
+ fretboardLength = parameters.fretboardLength + parameters.fretboardLengthOffset
+ neckSpacing = parameters.neckSpacing
+ bridgeSpacing = parameters.bridgeSpacing
+ singleCoilLength = parameters.singleCoilLength
+ singleCoilWidth = parameters.singleCoilWidth
+ singleCoilDepth = parameters.singleCoilDepth
+ humbuckerLength = parameters.humbuckerLength
+ humbuckerWidth = parameters.humbuckerWidth
+ humbuckerDepth = parameters.humbuckerDepth
+ humbuckerFillet = parameters.humbuckerFillet
+ pickupNeck = parameters.pickupNeck
+ pickupMiddle = parameters.pickupMiddle
+ pickupBridge = parameters.pickupBridge
+ pickupCavityMountLength = parameters.pickupCavityMountLength
+ pickupCavityMountTabWidth = parameters.pickupCavityMountTabWidth
+ bridgePickupAngle = self.design.unitsManager.convert(parameters.bridgePickupAngle, 'deg', 'rad')
+
+ # Create a new sketch.
+ sketches = pickupsComp.sketches
+ xzPlane = pickupsComp.xYConstructionPlane
+ neckDistance = guitarLength - headstockLength - fretboardLength - neckSpacing
+ bridgeDistance = guitarLength - headstockLength - scaleLength + bridgeSpacing
+ middleDistance = bridgeDistance + (neckDistance - bridgeDistance)/2
+
+ if pickupNeck == "None":
+ neckPickupType = ''
+ else:
+ #Create sketch for bridge spacing
+ sketch1 = sketches.add(xzPlane)
+ neckLines = sketch1.sketchCurves.sketchLines
+ cavityNeckLines = sketch1.sketchCurves.sketchLines
+
+ # Get sketch points
+ sketchPoints = sketch1.sketchPoints
+ sketch1.isComputeDeferred = True
+ sketch1.areConstraintsShown = False
+ sketch1.arePointsShown = False
+
+ if pickupNeck == "Single-Coil":
+ # Create sketch lines
+ pickupNeck1 = neckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2)+singleCoilWidth/2, (singleCoilLength/2), 0))
+ pickupNeck2 = neckLines.addByTwoPoints(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), (pickupCavityMountLength/2), 0))
+ pickupNeck2.isConstruction = True
+ pickupNeckFillet1 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[0], pickupNeck1[0].endSketchPoint.geometry, pickupNeck1[1], pickupNeck1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupNeckFillet2 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[1], pickupNeck1[1].endSketchPoint.geometry, pickupNeck1[2], pickupNeck1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupNeckFillet3 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[2], pickupNeck1[2].endSketchPoint.geometry, pickupNeck1[3], pickupNeck1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupNeckFillet4 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[3], pickupNeck1[3].endSketchPoint.geometry, pickupNeck1[0], pickupNeck1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityNeck1 = cavityNeckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2)+singleCoilWidth/2, (pickupCavityMountLength/2), 0))
+ cavityNeckFillet1 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[0], cavityNeck1[0].endSketchPoint.geometry, cavityNeck1[1], cavityNeck1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityNeckFillet2 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[1], cavityNeck1[1].endSketchPoint.geometry, cavityNeck1[2], cavityNeck1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityNeckFillet3 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[2], cavityNeck1[2].endSketchPoint.geometry, cavityNeck1[3], cavityNeck1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityNeckFillet4 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[3], cavityNeck1[3].endSketchPoint.geometry, cavityNeck1[0], cavityNeck1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ sketch1.name = 'Neck Pickup [Single-Coil]'
+ neckPickupType = 'S'
+ elif pickupNeck == "Humbucker":
+ pickupNeck1 = neckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2)+humbuckerWidth/2, (humbuckerLength/2), 0))
+ pickupNeck2 = neckLines.addByTwoPoints(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), (pickupCavityMountLength/2), 0))
+ pickupNeck2.isConstruction = True
+ pickupNeckFillet1 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[0], pickupNeck1[0].endSketchPoint.geometry, pickupNeck1[1], pickupNeck1[1].startSketchPoint.geometry, humbuckerFillet)
+ pickupNeckFillet2 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[1], pickupNeck1[1].endSketchPoint.geometry, pickupNeck1[2], pickupNeck1[2].startSketchPoint.geometry, humbuckerFillet)
+ pickupNeckFillet3 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[2], pickupNeck1[2].endSketchPoint.geometry, pickupNeck1[3], pickupNeck1[3].startSketchPoint.geometry, humbuckerFillet)
+ pickupNeckFillet4 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[3], pickupNeck1[3].endSketchPoint.geometry, pickupNeck1[0], pickupNeck1[0].startSketchPoint.geometry, humbuckerFillet)
+ cavityNeck1 = cavityNeckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2)-pickupCavityMountTabWidth/2, (pickupCavityMountLength/2), 0))
+ cavityNeckFillet1 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[0], cavityNeck1[0].endSketchPoint.geometry, cavityNeck1[1], cavityNeck1[1].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityNeckFillet2 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[1], cavityNeck1[1].endSketchPoint.geometry, cavityNeck1[2], cavityNeck1[2].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityNeckFillet3 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[2], cavityNeck1[2].endSketchPoint.geometry, cavityNeck1[3], cavityNeck1[3].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityNeckFillet4 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[3], cavityNeck1[3].endSketchPoint.geometry, cavityNeck1[0], cavityNeck1[0].startSketchPoint.geometry, humbuckerFillet/2)
+ sketch1.name = 'Neck Pickup [Humbucker]'
+ neckPickupType = 'H'
+ else:
+ pass
+
+ if pickupMiddle == "None":
+ middlePickupType = ''
+ else:
+ #Create sketch for bridge spacing
+ sketch2 = sketches.add(xzPlane)
+ middleLines = sketch2.sketchCurves.sketchLines
+ cavitymiddleLines = sketch2.sketchCurves.sketchLines
+
+ # Get sketch points
+ sketchPoints = sketch2.sketchPoints
+ sketch2.isComputeDeferred = True
+ sketch2.areConstraintsShown = False
+ sketch2.arePointsShown = False
+
+ if pickupMiddle == "Single-Coil":
+ # Create sketch lines
+ pickupMiddle1 = middleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+singleCoilWidth/2), (singleCoilLength/2), 0))
+ pickupMiddle2 = middleLines.addByTwoPoints(adsk.core.Point3D.create((middleDistance), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((middleDistance), (pickupCavityMountLength/2), 0))
+ pickupMiddle2.isConstruction = True
+ pickupMiddleFillet1 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[0], pickupMiddle1[0].endSketchPoint.geometry, pickupMiddle1[1], pickupMiddle1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupMiddleFillet2 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[1], pickupMiddle1[1].endSketchPoint.geometry, pickupMiddle1[2], pickupMiddle1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupMiddleFillet3 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[2], pickupMiddle1[2].endSketchPoint.geometry, pickupMiddle1[3], pickupMiddle1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupMiddleFillet4 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[3], pickupMiddle1[3].endSketchPoint.geometry, pickupMiddle1[0], pickupMiddle1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityMiddle1 = cavitymiddleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+singleCoilWidth/2), (pickupCavityMountLength/2), 0))
+ cavityMiddleFillet1 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[0], cavityMiddle1[0].endSketchPoint.geometry, cavityMiddle1[1], cavityMiddle1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityMiddleFillet2 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[1], cavityMiddle1[1].endSketchPoint.geometry, cavityMiddle1[2], cavityMiddle1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityMiddleFillet3 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[2], cavityMiddle1[2].endSketchPoint.geometry, cavityMiddle1[3], cavityMiddle1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityMiddleFillet4 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[3], cavityMiddle1[3].endSketchPoint.geometry, cavityMiddle1[0], cavityMiddle1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ sketch2.name = 'Middle Pickup [Single-Coil]'
+ middlePickupType = 'S'
+ elif pickupMiddle == "Humbucker":
+ # Create sketch lines
+ pickupMiddle1 = middleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+humbuckerWidth/2), (humbuckerLength/2), 0))
+ pickupMiddle2 = middleLines.addByTwoPoints(adsk.core.Point3D.create((middleDistance), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((middleDistance), (pickupCavityMountLength/2), 0))
+ pickupMiddle2.isConstruction = True
+ pickupMiddleFillet1 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[0], pickupMiddle1[0].endSketchPoint.geometry, pickupMiddle1[1], pickupMiddle1[1].startSketchPoint.geometry, humbuckerFillet)
+ pickupMiddleFillet2 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[1], pickupMiddle1[1].endSketchPoint.geometry, pickupMiddle1[2], pickupMiddle1[2].startSketchPoint.geometry, humbuckerFillet)
+ pickupMiddleFillet3 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[2], pickupMiddle1[2].endSketchPoint.geometry, pickupMiddle1[3], pickupMiddle1[3].startSketchPoint.geometry, humbuckerFillet)
+ pickupMiddleFillet4 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[3], pickupMiddle1[3].endSketchPoint.geometry, pickupMiddle1[0], pickupMiddle1[0].startSketchPoint.geometry, humbuckerFillet)
+ cavityMiddle1 = cavitymiddleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+pickupCavityMountTabWidth/2), (pickupCavityMountLength/2), 0))
+ cavityMiddleFillet1 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[0], cavityMiddle1[0].endSketchPoint.geometry, cavityMiddle1[1], cavityMiddle1[1].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityMiddleFillet2 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[1], cavityMiddle1[1].endSketchPoint.geometry, cavityMiddle1[2], cavityMiddle1[2].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityMiddleFillet3 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[2], cavityMiddle1[2].endSketchPoint.geometry, cavityMiddle1[3], cavityMiddle1[3].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityMiddleFillet4 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[3], cavityMiddle1[3].endSketchPoint.geometry, cavityMiddle1[0], cavityMiddle1[0].startSketchPoint.geometry, humbuckerFillet/2)
+ sketch2.name = 'Middle Pickup [Humbucker]'
+ middlePickupType = 'H'
+ else:
+ pass
+
+ #Create sketch for bridge spacing
+ sketch3 = sketches.add(xzPlane)
+ bridgeLines = sketch3.sketchCurves.sketchLines
+ cavitybridgeLines = sketch3.sketchCurves.sketchLines
+
+ # Get sketch points
+ sketchPoints = sketch3.sketchPoints
+ if parameters.generateBlanks:
+ sketch3.isComputeDeferred = False
+ else:
+ sketch3.isComputeDeferred = True
+
+ sketch3.areConstraintsShown = True
+ sketch3.arePointsShown = False
+
+ if pickupBridge == "Single-Coil":
+ # Create sketch lines
+ pickupBridge1 = bridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2)+singleCoilWidth/2, (singleCoilLength/2), 0))
+ pickupBridge2 = bridgeLines.addByTwoPoints(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), (pickupCavityMountLength/2), 0))
+ pickupBridge2.isConstruction = True
+ pickupBridgeAngle = bridgeLines.addByTwoPoints(adsk.core.Point3D.create(bridgeDistance, 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth), 0, 0))
+ pickupBridgeAngle.isConstruction = True
+ # Create sketch point
+ point1 = adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0)
+ sketchPoint1 = sketchPoints.add(point1)
+ sketchPoint1.isFixed = True
+ pickupBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[0], pickupBridge1[0].endSketchPoint.geometry, pickupBridge1[1], pickupBridge1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[1], pickupBridge1[1].endSketchPoint.geometry, pickupBridge1[2], pickupBridge1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[2], pickupBridge1[2].endSketchPoint.geometry, pickupBridge1[3], pickupBridge1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ pickupBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[3], pickupBridge1[3].endSketchPoint.geometry, pickupBridge1[0], pickupBridge1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityBridge1 = cavitybridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2)+singleCoilWidth/2, (pickupCavityMountLength/2), 0))
+ cavityBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[0], cavityBridge1[0].endSketchPoint.geometry, cavityBridge1[1], cavityBridge1[1].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[1], cavityBridge1[1].endSketchPoint.geometry, cavityBridge1[2], cavityBridge1[2].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[2], cavityBridge1[2].endSketchPoint.geometry, cavityBridge1[3], cavityBridge1[3].startSketchPoint.geometry, singleCoilWidth/2)
+ cavityBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[3], cavityBridge1[3].endSketchPoint.geometry, cavityBridge1[0], cavityBridge1[0].startSketchPoint.geometry, singleCoilWidth/2)
+ # Constrain the Rectangle to stay rectangular
+ constraints = sketch3.geometricConstraints
+ constraints.addMidPoint(sketchPoint1, bridgeLines.item(4))
+ constraints.addMidPoint(sketchPoint1, bridgeLines.item(5))
+ constraints.addMidPoint(bridgeLines.item(5).startSketchPoint, bridgeLines.item(3))
+ constraints.addMidPoint(bridgeLines.item(5).endSketchPoint, bridgeLines.item(1))
+ constraints.addMidPoint(bridgeLines.item(5).startSketchPoint, cavitybridgeLines.item(9))
+ constraints.addMidPoint(bridgeLines.item(5).endSketchPoint, cavitybridgeLines.item(7))
+ constraints.addPerpendicular(bridgeLines.item(5), bridgeLines.item(4))
+ all = adsk.core.ObjectCollection.create()
+ for curves in sketch3.sketchCurves:
+ all.add(curves)
+ for points in sketch3.sketchPoints:
+ all.add(points)
+ normal = sketch3.xDirection.crossProduct(sketch3.yDirection)
+ normal.transformBy(sketch3.transform)
+ origin = sketch3.origin
+ origin.transformBy(sketch3.transform)
+ matrix = adsk.core.Matrix3D.create()
+ matrix.setToRotation(-bridgePickupAngle, normal, origin)
+ sketch3.move(all, matrix)
+ sketch3.name = 'Bridge Pickup [Single-Coil]'
+ bridgePickupType = 'S'
+ elif pickupBridge == "Humbucker":
+ pickupBridge1 = bridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance), (humbuckerLength/2), 0))
+ pickupBridge2 = bridgeLines.addByTwoPoints(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), (pickupCavityMountLength/2), 0))
+ pickupBridge2.isConstruction = True
+ pickupBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[0], pickupBridge1[0].endSketchPoint.geometry, pickupBridge1[1], pickupBridge1[1].startSketchPoint.geometry, humbuckerFillet)
+ pickupBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[1], pickupBridge1[1].endSketchPoint.geometry, pickupBridge1[2], pickupBridge1[2].startSketchPoint.geometry, humbuckerFillet)
+ pickupBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[2], pickupBridge1[2].endSketchPoint.geometry, pickupBridge1[3], pickupBridge1[3].startSketchPoint.geometry, humbuckerFillet)
+ pickupBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[3], pickupBridge1[3].endSketchPoint.geometry, pickupBridge1[0], pickupBridge1[0].startSketchPoint.geometry, humbuckerFillet)
+ cavityBridge1 = cavitybridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2)-pickupCavityMountTabWidth/2, (pickupCavityMountLength/2), 0))
+ cavityBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[0], cavityBridge1[0].endSketchPoint.geometry, cavityBridge1[1], cavityBridge1[1].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[1], cavityBridge1[1].endSketchPoint.geometry, cavityBridge1[2], cavityBridge1[2].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[2], cavityBridge1[2].endSketchPoint.geometry, cavityBridge1[3], cavityBridge1[3].startSketchPoint.geometry, humbuckerFillet/2)
+ cavityBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[3], cavityBridge1[3].endSketchPoint.geometry, cavityBridge1[0], cavityBridge1[0].startSketchPoint.geometry, humbuckerFillet/2)
+ sketch3.name = 'Bridge Pickup [Humbucker]'
+ bridgePickupType = 'H'
+ else:
+ pass
+
+ if parameters.generateBlanks:
+ #Get extrude features
+ extrudes = pickupsComp.features.extrudeFeatures
+
+ # Get the profiles of the pickups
+ if pickupNeck == "Single-Coil":
+ #Create an object collection to use an input.
+ neckProfs = adsk.core.ObjectCollection.create()
+ for prof in sketch1.profiles:
+ neckProfs.add(prof)
+ elif pickupNeck == "Humbucker":
+ #Create an object collection to use an input.
+ neckProfs = adsk.core.ObjectCollection.create()
+ for prof in sketch1.profiles:
+ neckProfs.add(prof)
+ else:
+ pass
+
+ if pickupMiddle == "Single-Coil":
+ #Create an object collection to use an input.
+ middleProfs = adsk.core.ObjectCollection.create()
+ for prof in sketch2.profiles:
+ middleProfs.add(prof)
+ elif pickupMiddle == "Humbucker":
+ #Create an object collection to use an input.
+ middleProfs = adsk.core.ObjectCollection.create()
+ for prof in sketch2.profiles:
+ middleProfs.add(prof)
+ else:
+ pass
+
+ if pickupBridge == "Single-Coil":
+ #Create an object collection to use an input.
+ bridgeProfs = adsk.core.ObjectCollection.create()
+ for prof in sketch3.profiles:
+ bridgeProfs.add(prof)
+ elif pickupBridge == "Humbucker":
+ #Create an object collection to use an input.
+ bridgeProfs = adsk.core.ObjectCollection.create()
+ for prof in sketch3.profiles:
+ bridgeProfs.add(prof)
+ else:
+ pass
+
+ if pickupNeck == "Single-Coil":
+ neckExtrude = extrudes.addSimple(neckProfs, adsk.core.ValueInput.createByReal(-singleCoilDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ # Get the extrusion body
+ neckPickupBody = neckExtrude.bodies.item(0)
+ neckExtrude.name = "Extrusion: Neck Pickup [Single-Coil]"
+ # bneckPickupBody.name = "Neck Pickup [Single-Coil]"
+ elif pickupNeck == "Humbucker":
+ neckExtrude = extrudes.addSimple(neckProfs, adsk.core.ValueInput.createByReal(-humbuckerDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ # Get the extrusion body
+ neckPickupBody = neckExtrude.bodies.item(0)
+ neckExtrude.name = "Extrusion: Neck Pickup [Humbucker]"
+ # bneckPickupBody.name = "Neck Pickup [Humbucker]"
+ else:
+ pass
+
+ if pickupMiddle == "Single-Coil":
+ middleExtrude = extrudes.addSimple(middleProfs, adsk.core.ValueInput.createByReal(-singleCoilDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ # Get the extrusion body
+ middlePickupBody = middleExtrude.bodies.item(0)
+ middleExtrude.name = "Extrusion: Middle Pickup [Single-Coil]"
+ # bmiddlePickupBody.name = "Middle Pickup [Single-Coil]"
+ elif pickupMiddle == "Humbucker":
+ middleExtrude = extrudes.addSimple(middleProfs, adsk.core.ValueInput.createByReal(-humbuckerDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ # Get the extrusion body
+ middlePickupBody = middleExtrude.bodies.item(0)
+ middleExtrude.name = "Extrusion: Middle Pickup [Humbucker]"
+ # bmiddlePickupBody.name = "Middle Pickup [Humbucker]"
+ else:
+ pass
+
+ if pickupBridge == "Single-Coil":
+ bridgeExtrude = extrudes.addSimple(bridgeProfs, adsk.core.ValueInput.createByReal(-singleCoilDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ # Get the extrusion body
+ bridgePickupBody = bridgeExtrude.bodies.item(0)
+ bridgeExtrude.name = "Extrusion: Bridge Pickup [Single-Coil]"
+ # bbridgePickupBody.name = "Bridge Pickup [Single-Coil]"
+ elif pickupBridge == "Humbucker":
+ bridgeExtrude = extrudes.addSimple(bridgeProfs, adsk.core.ValueInput.createByReal(-humbuckerDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ # Get the extrusion body
+ bridgePickupBody = bridgeExtrude.bodies.item(0)
+ bridgeExtrude.name = "Extrusion: Bridge Pickup [Humbucker]"
+ # bridgePickupBody.name = "Bridge Pickup [Humbucker]"
+ else:
+ pass
+ else:
+ pass
+
+ #Centers the camera to fit the entire fretboard
+ cam = self.app.activeViewport.camera
+ cam.isFitView = True
+ cam.isSmoothTransition = False
+ self.app.activeViewport.camera = cam
+
+ # Group everything used to create the fretboard in the timeline.
+ timelineGroupspickups = self.design.timeline.timelineGroups
+ pickupsOccIndex = pickupsOcc.timelineObject.index
+
+ if parameters.generateBlanks:
+ pickupsEndIndex = bridgeExtrude.timelineObject.index
+ else:
+ pickupsEndIndex = sketch3.timelineObject.index
+
+ timelineGroupPickups = timelineGroupspickups.add(pickupsOccIndex, pickupsEndIndex)
+ timelineGroupPickups.name = 'Pickups [' + bridgePickupType + middlePickupType + neckPickupType + ']'
+ pickupsComp.name = 'Pickups [' + bridgePickupType + middlePickupType + neckPickupType + ']'
+
+ return pickupsComp
diff --git a/Builders/StringsBuilder.py b/Builders/StringsBuilder.py
new file mode 100644
index 0000000..275685e
--- /dev/null
+++ b/Builders/StringsBuilder.py
@@ -0,0 +1,130 @@
+import os, sys
+import adsk.core, adsk.fusion, adsk.cam, traceback, math
+from math import sqrt
+from ..ParameterValues import ParameterValues
+
+class StringsBuilder:
+
+ def __init__(self, app):
+ self.app = app
+ self.design = app.activeProduct
+
+ def buildStrings(self, parameters):
+
+ rootComp = self.design.rootComponent
+ stringsOccs = rootComp.occurrences
+ stringsOcc = stringsOccs.addNewComponent(adsk.core.Matrix3D.create())
+ stringsComp = adsk.fusion.Component.cast(stringsOcc.component)
+
+ stringCount = parameters.stringCount
+ bridgeStringSpacing = parameters.bridgeStringSpacing
+ nutStringSpacing = parameters.nutStringSpacing
+ guitarLength = parameters.guitarLength
+ headstockLength = parameters.headstockLength
+ scaleLength = parameters.scaleLength
+ nutLength = parameters.nutLength
+ fretboardHeight = parameters.fretboardHeight
+ machinePostHoleSpacing = parameters.machinePostHoleSpacing
+ machinePostHoleDiameter = parameters.machinePostHoleDiameter
+ machinePostDiameter = parameters.machinePostDiameter
+ nutToPost = parameters.nutToPost
+ headstockStyle = parameters.headstockStyle
+ headstockThickness = parameters.headstockThickness
+
+ # Create a new sketch.
+ sketches = stringsComp.sketches
+ xzPlane = stringsComp.xYConstructionPlane
+
+ #Get extrude features
+ extrudes = stringsComp.features.extrudeFeatures
+ stringInset = (nutLength - nutStringSpacing)/2
+ nutDistance = guitarLength - headstockLength
+
+ if headstockStyle == 'Straight In-line':
+ #Create sketch for bridge spacing
+ sketch1 = sketches.add(xzPlane)
+ sketch1.isComputeDeferred = True
+ sketch1.arePointsShown = False
+ sketch1.name = 'Strings [ ' + str((int(stringCount))) + ' strings ]'
+ stringSketch = sketch1.sketchCurves.sketchLines
+
+ for string in range(int(stringCount)):
+ spacing = bridgeStringSpacing/2 - (bridgeStringSpacing/((int(stringCount))-1))*string
+ nutSpacing = (nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/((int(stringCount))-1))*string
+ holeSpacingHor = string*machinePostHoleSpacing
+ stringsSketch = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength, spacing, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance, nutSpacing, fretboardHeight+0.125))
+ stringsSketch = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, nutSpacing, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+holeSpacingHor, nutSpacing, 0))
+
+ #Create sketch for bridge spacing
+ sketch2 = sketches.add(xzPlane)
+ sketch2.isComputeDeferred = True
+ sketch2.arePointsShown = False
+ sketch2.name = 'Machine Post Holes'
+ machinePost = sketch2.sketchCurves.sketchCircles
+
+ for spacing in range(int(stringCount)):
+ holeSpacingVert = ((nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/((int(stringCount))-1))*spacing)
+ holeSpacingHor = spacing*machinePostHoleSpacing
+ machinePostHoles = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+holeSpacingHor, holeSpacingVert+machinePostDiameter/2, 0), machinePostHoleDiameter/2)
+
+ else:
+ #Create sketch for bridge spacing
+ sketch1 = sketches.add(xzPlane)
+ sketch1.isComputeDeferred = True
+ sketch1.arePointsShown = False
+ sketch1.name = 'Strings [ ' + str((int(stringCount))) + ' strings ]'
+ stringSketch = sketch1.sketchCurves.sketchLines
+
+ for string in range(int(stringCount)):
+ spacing = bridgeStringSpacing/2 - (bridgeStringSpacing/((int(stringCount))-1))*string
+ nutSpacing = (nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/((int(stringCount))-1))*string
+ holeSpacingHor = string*machinePostHoleSpacing
+ stringsSketch = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength, spacing, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance, nutSpacing, fretboardHeight+0.125))
+
+ stringsSketch1 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, nutStringSpacing/2, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost, nutStringSpacing/2, 0))
+ stringsSketch2 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, nutStringSpacing/2-(nutStringSpacing/5), fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, nutStringSpacing/2, 0))
+ stringsSketch3 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, nutStringSpacing/2-(nutStringSpacing/5*2), fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, nutStringSpacing/2, 0))
+ stringsSketch4 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, -nutStringSpacing/2+(nutStringSpacing/5*2), fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, -nutStringSpacing/2, 0))
+ stringsSketch5 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, -nutStringSpacing/2+(nutStringSpacing/5), fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, -nutStringSpacing/2, 0))
+ stringsSketch6 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, -nutStringSpacing/2, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost, -nutStringSpacing/2, 0))
+
+ #Create sketch for bridge spacing
+ sketch2 = sketches.add(xzPlane)
+ sketch2.isComputeDeferred = True
+ sketch2.arePointsShown = False
+ sketch2.name = 'Machine Post Holes'
+ machinePost = sketch2.sketchCurves.sketchCircles
+ machinePostHole1 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
+ machinePostHole2 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
+ machinePostHole3 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
+ machinePostHole4 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
+ machinePostHole5 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
+ machinePostHole6 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
+
+ tuningHoles = adsk.core.ObjectCollection.create()
+
+ for holes in sketch2.profiles:
+ tuningHoles.add(holes)
+
+ #Get extrude features
+ extrudes = stringsComp.features.extrudeFeatures
+
+ if parameters.generateBlanks:
+ #Extrusion for fret markers
+ holesExtrude = extrudes.addSimple(tuningHoles, adsk.core.ValueInput.createByReal(-headstockThickness*2), adsk.fusion.FeatureOperations.CutFeatureOperation)
+ holesExtrude.name = 'Extrusion: Tuning Machine Holes'
+
+ # Group everything used to create the fretboard in the timeline.
+ timelineGroupsStrings = self.design.timeline.timelineGroups
+ stringsOccIndex = stringsOcc.timelineObject.index
+
+ if parameters.generateBlanks:
+ stringsEndIndex = holesExtrude.timelineObject.index
+ else:
+ stringsEndIndex = sketch2.timelineObject.index
+
+ timelineGroupStrings = timelineGroupsStrings.add(stringsOccIndex, stringsEndIndex)
+ timelineGroupStrings.name = 'Strings [ ' + str((int(stringCount))) + ' strings ]'
+ stringsComp.name = 'Strings [ ' + str((int(stringCount))) + ' strings ]'
+
+ return stringsComp
\ No newline at end of file
diff --git a/Builders/__init__.py b/Builders/__init__.py
new file mode 100644
index 0000000..a0861c9
--- /dev/null
+++ b/Builders/__init__.py
@@ -0,0 +1,5 @@
+from .FretboardBuilder import FretboardBuilder
+from .BodyBlankBuilder import BodyBlankBuilder
+from .StringsBuilder import StringsBuilder
+from .DimensionsBuilder import DimensionsBuilder
+from .PickupsBuilder import PickupsBuilder
\ No newline at end of file
diff --git a/DesignParameters.py b/DesignParameters.py
new file mode 100644
index 0000000..9979fdd
--- /dev/null
+++ b/DesignParameters.py
@@ -0,0 +1,57 @@
+import os, sys
+import adsk.core, adsk.fusion, adsk.cam, traceback
+from .Modules import simplejson
+from .ParameterValues import ParameterValues
+from .UIElements import UIElements
+
+class DesignParameters:
+
+ def __init__(self, app):
+ self.app = app
+ self.design = app.activeProduct
+
+ def setAndStoreParameterValues(self, values: ParameterValues):
+
+ for key, control in UIElements.floatValueControls.items():
+ setattr(values, key, float(control.value))
+
+ for key, control in UIElements.boolValueControls.items():
+ setattr(values, key, bool(control.value))
+
+ for key, control in UIElements.intSpinnerControls.items():
+ setattr(values, key, float(control.value))
+
+ for key, control in UIElements.floatSpinnerControls.items():
+ if (control.unitType == 'deg'):
+ setattr(values, key, self.design.unitsManager.convert(float(control.value), 'rad', 'deg'))
+ else:
+ setattr(values, key, float(control.value))
+
+ self.calculateGuitarLength(values)
+
+ for key, control in UIElements.dropdownControls.items():
+ setattr(values, key, control.selectedItem.name)
+
+ paramJson = simplejson.dumps(values.__dict__, use_decimal=True)
+
+ self.design.attributes.add("guitarEngine", "parameterValues", paramJson)
+
+ def calculateGuitarLength(self, values: ParameterValues):
+
+ values.guitarLength = (values.bodyLength + values.fretboardLength + values.headstockLength) - values.neckPocketLength
+
+ def getStoredParameters(self):
+
+ valueAttribute = self.design.attributes.itemByName("guitarEngine", "parameterValues")
+
+ if (valueAttribute is not None):
+ paramDictionary = simplejson.loads(valueAttribute.value)
+
+ parameters = ParameterValues()
+
+ for key in paramDictionary:
+ setattr(parameters, key, paramDictionary[key])
+
+ return parameters
+ else:
+ return None
diff --git a/Guitar Engine [Beta].py b/Guitar Engine [Beta].py
deleted file mode 100644
index 5e65ee7..0000000
--- a/Guitar Engine [Beta].py
+++ /dev/null
@@ -1,2523 +0,0 @@
-#Author-Brad Anderson Jr
-#Description - Generates a guitar
-import adsk.core, adsk.fusion, traceback, math
-from math import sqrt
-from .defaultParameters import defaultParameters
-
-# Globals
-app = adsk.core.Application.cast(None)
-ui = adsk.core.UserInterface.cast(None)
-units = ''
-
-#Default Inputs
-defaultStandard = adsk.core.DropDownCommandInput.cast(None)
-defaultFretboardStyle = adsk.core.DropDownCommandInput.cast(None)
-defaultPickupNeck = adsk.core.DropDownCommandInput.cast(None)
-defaultPickupMiddle = adsk.core.DropDownCommandInput.cast(None)
-defaultPickupBridge = adsk.core.DropDownCommandInput.cast(None)
-defaultFretNumber = adsk.core.ValueCommandInput.cast(None)
-defaultScaleLength = adsk.core.ValueCommandInput.cast(None)
-defaultNutLength = adsk.core.ValueCommandInput.cast(None)
-defaultEndLength = adsk.core.ValueCommandInput.cast(None)
-defaultRadius = adsk.core.ValueCommandInput.cast(None)
-defaultNutRadius = adsk.core.ValueCommandInput.cast(None)
-defaultEndRadius = adsk.core.ValueCommandInput.cast(None)
-defaultEndCurve = adsk.core.ValueCommandInput.cast(None)
-defaultfretboardHeight = adsk.core.ValueCommandInput.cast(None)
-defaultFilletRadius = adsk.core.ValueCommandInput.cast(None)
-defaultTangWidth = adsk.core.ValueCommandInput.cast(None)
-defaultTangDepth = adsk.core.ValueCommandInput.cast(None)
-defaultBlindFrets = adsk.core.ValueCommandInput.cast(None)
-defaultNutSlotWidth = adsk.core.ValueCommandInput.cast(None)
-defaultNutSlotDepth = adsk.core.ValueCommandInput.cast(None)
-defaultMarkerDiameter = adsk.core.ValueCommandInput.cast(None)
-defaultMarkerDepth = adsk.core.ValueCommandInput.cast(None)
-defaultMarkerSpacing = adsk.core.ValueCommandInput.cast(None)
-defaultFretboardLength = adsk.core.ValueCommandInput.cast(None)
-defaultGuitarLength = adsk.core.ValueCommandInput.cast(None)
-defaultBodyWidth = adsk.core.ValueCommandInput.cast(None)
-defaultBodyThickness = adsk.core.ValueCommandInput.cast(None)
-defaultBodyLength = adsk.core.ValueCommandInput.cast(None)
-defaultNeckLength = adsk.core.ValueCommandInput.cast(None)
-defaultNeckWidth = adsk.core.ValueCommandInput.cast(None)
-defaultNeckThickness = adsk.core.ValueCommandInput.cast(None)
-defaultHeadstockLength = adsk.core.ValueCommandInput.cast(None)
-defaultHeadstockWidth = adsk.core.ValueCommandInput.cast(None)
-defaultHeadstockThickness = adsk.core.ValueCommandInput.cast(None)
-defaultBridgeStringSpacing = adsk.core.ValueCommandInput.cast(None)
-defaultNutStringSpacing = adsk.core.ValueCommandInput.cast(None)
-defaultNutToPost = adsk.core.ValueCommandInput.cast(None)
-defaultMachinePostHoleDiameter = adsk.core.ValueCommandInput.cast(None)
-defaultMachinePostDiameter = adsk.core.ValueCommandInput.cast(None)
-defaultMachinePostHoleSpacing = adsk.core.ValueCommandInput.cast(None)
-defaultStringCount = adsk.core.ValueCommandInput.cast(None)
-defaultfirstFretThickness = adsk.core.ValueCommandInput.cast(None)
-defaulttwelfthfretThickness = adsk.core.ValueCommandInput.cast(None)
-defaultHeadstockStyle = adsk.core.DropDownCommandInput.cast(None)
-defaultNeckSpacing = adsk.core.ValueCommandInput.cast(None)
-defaultBridgeSpacing = adsk.core.ValueCommandInput.cast(None)
-defaultSingleCoilLength = adsk.core.ValueCommandInput.cast(None)
-defaultSingleCoilWidth = adsk.core.ValueCommandInput.cast(None)
-defaultSingleCoilDepth = adsk.core.ValueCommandInput.cast(None)
-defaultHumbuckerLength = adsk.core.ValueCommandInput.cast(None)
-defaultHumbuckerWidth = adsk.core.ValueCommandInput.cast(None)
-defaultHumbuckerDepth = adsk.core.ValueCommandInput.cast(None)
-defaultHumbuckerFillet = adsk.core.ValueCommandInput.cast(None)
-defaultPickupCavityMountLength = adsk.core.ValueCommandInput.cast(None)
-defaultPickupCavityMountTabWidth = adsk.core.ValueCommandInput.cast(None)
-defaultBridgePickupAngle = adsk.core.ValueCommandInput.cast(None)
-
-handlers = []
-
-def run(context):
- try:
- global app, ui
- app = adsk.core.Application.get()
- ui = app.userInterface
-
- # Create a command definition and add a button to the CREATE panel.
- cmdDef = ui.commandDefinitions.addButtonDefinition('adskFretboardPythonAddIn', 'Guitar Engine [Beta] (v2020.06.13)', 'Creates a fretboard component\n\n', 'Resources/Icons')
- createPanel = ui.allToolbarPanels.itemById('SolidCreatePanel')
- fretboardButton = createPanel.controls.addCommand(cmdDef)
-
- # Connect to the command created event.
- onCommandCreated = FretboardCommandCreatedHandler()
- cmdDef.commandCreated.add(onCommandCreated)
- handlers.append(onCommandCreated)
-
- # Make the button available in the panel.
- fretboardButton.isPromotedByDefault = True
- fretboardButton.isPromoted = True
- if context['IsApplicationStartup'] == False:
- ui.messageBox('Guitar Engine [Beta] (v2020.06.13) has been added to the SOLID tab of the DESIGN workspace.
This is a beta version.
')
-
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-def stop(context):
- try:
- createPanel = ui.allToolbarPanels.itemById('SolidCreatePanel')
- fretboardButton = createPanel.controls.itemById('adskFretboardPythonAddIn')
-
- if fretboardButton:
- fretboardButton.deleteMe()
-
- cmdDef = ui.commandDefinitions.itemById('adskFretboardPythonAddIn')
-
- if cmdDef:
- cmdDef.deleteMe()
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-def getCommandInputValue(commandInput, unitType):
- try:
- valCommandInput = adsk.core.ValueCommandInput.cast(commandInput)
-
- if not valCommandInput:
- return (False, 0)
-
- # Verify that the expression is valid.
- design = adsk.fusion.Design.cast(app.activeProduct)
- unitsMgr = design.unitsManager
- userParams = design.userParameters
-
- if unitsMgr.isValidExpression(valCommandInput.expression, unitType):
- value = unitsMgr.evaluateExpression(valCommandInput.expression, unitType)
- return (True, value)
- else:
- return (False, 0)
-
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-class FretboardCommandCreatedHandler(adsk.core.CommandCreatedEventHandler):
- def __init__(self):
- super().__init__()
- def notify(self, args):
- try:
- eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
-
- # Verify that a Fusion design is active.
- design = adsk.fusion.Design.cast(app.activeProduct)
-
- if not design:
- ui.messageBox('A Fusion design must be active when invoking this command.')
- return()
-
- defaultUnits = design.unitsManager.defaultLengthUnits
- userParams = design.userParameters
-
- # Determine whether to use inches or millimeters as the initial default.
- global units
- if defaultUnits == 'in' or defaultUnits == 'ft':
- units = 'in'
- else:
- units = 'mm'
-
- # Define the default values and get the previous values from the attributes.
- if units == 'in':
- standard = 'Imperial'
- else:
- standard = 'Metric'
-
- standardAttrib = design.attributes.itemByName('Fretboard', 'standard')
-
- if standardAttrib:
- standard = standardAttrib.value
- if standard == 'Imperial':
- units = 'in'
- else:
- units = 'mm'
-
- fretNumber = str(defaultParameters.fretNumber)
- fretNumberAttrib = design.attributes.itemByName('Fretboard', 'fretNumber')
- if fretNumberAttrib:
- fretNumber = fretNumberAttrib.value
-
- scaleLength = str(defaultParameters.scaleLength * defaultParameters.userUnit)
- scaleLengthAttrib = design.attributes.itemByName('Fretboard', 'scaleLength')
- if scaleLengthAttrib:
- scaleLength = scaleLengthAttrib.value
-
- #Equation for fret spacing
- for fretNum in range(1,int((fretNumber))+2):
- fretDistance = (float(scaleLength))-((float(scaleLength))/(2**(fretNum/12.0)))
-
- fretboardLength = str(math.ceil(float(fretDistance)*8)/8)
- fretboardLengthAttrib = design.attributes.itemByName('Fretboard', 'fretboardLength')
- if fretboardLengthAttrib:
- fretboardLength = fretboardLengthAttrib.value
-
- nutLength = str(defaultParameters.nutLength * defaultParameters.userUnit)
- nutLengthAttrib = design.attributes.itemByName('Fretboard', 'nutLength')
- if nutLengthAttrib:
- nutLength = nutLengthAttrib.value
-
- endLength = str(defaultParameters.endLength * defaultParameters.userUnit)
- endLengthAttrib = design.attributes.itemByName('Fretboard', 'endLength')
- if endLengthAttrib:
- endLength = endLengthAttrib.value
-
- radius = str(defaultParameters.radius * defaultParameters.userUnit)
- radiusAttrib = design.attributes.itemByName('Fretboard', 'radius')
- if radiusAttrib:
- radius = radiusAttrib.value
-
- nutRadius = str(defaultParameters.nutRadius * defaultParameters.userUnit)
- nutRadiusAttrib = design.attributes.itemByName('Fretboard', 'nutRadius')
- if nutRadiusAttrib:
- nutRadius = nutRadiusAttrib.value
-
- endRadius = str(defaultParameters.endRadius * defaultParameters.userUnit)
- endRadiusAttrib = design.attributes.itemByName('Fretboard', 'endRadius')
- if endRadiusAttrib:
- endRadius = nutRadiusAttrib.value
-
- fretboardHeight = str(defaultParameters.fretboardHeight * defaultParameters.userUnit)
- fretboardHeightAttrib = design.attributes.itemByName('Fretboard', 'fretboardHeight')
- if fretboardHeightAttrib:
- fretboardHeight = fretboardHeightAttrib.value
-
- filletRadius = str(defaultParameters.filletRadius * defaultParameters.userUnit)
- filletRadiusAttrib = design.attributes.itemByName('Fretboard', 'filletRadius')
- if filletRadiusAttrib:
- filletRadius = filletRadiusAttrib.value
-
- endCurve = str(defaultParameters.endCurve * defaultParameters.userUnit)
- endCurveAttrib = design.attributes.itemByName('Fretboard', 'endCurve')
- if endCurveAttrib:
- endCurve = endCurveAttrib.value
-
- tangWidth = str(defaultParameters.tangWidth * defaultParameters.userUnit)
- tangWidthAttrib = design.attributes.itemByName('Fretboard', 'tangWidth')
- if tangWidthAttrib:
- tangWidth = tangWidthAttrib.value
-
- tangDepth = str(defaultParameters.tangDepth * defaultParameters.userUnit)
- tangDepthAttrib = design.attributes.itemByName('Fretboard', 'tangDepth')
- if tangDepthAttrib:
- tangDepth = tangDepthAttrib.value
-
- blindFrets = str(defaultParameters.blindFrets * defaultParameters.userUnit)
- blindFretsAttrib = design.attributes.itemByName('Fretboard', 'blindFrets')
- if blindFretsAttrib:
- blindFrets = blindFretsAttrib.value
-
- nutSlotWidth = str(defaultParameters.nutSlotWidth * defaultParameters.userUnit)
- nutSlotWidthAttrib = design.attributes.itemByName('Fretboard', 'nutSlotWidth')
- if nutSlotWidthAttrib:
- nutSlotWidth = nutSlotWidthAttrib.value
-
- nutSlotDepth = str(defaultParameters.nutSlotDepth * defaultParameters.userUnit)
- nutSlotDepthAttrib = design.attributes.itemByName('Fretboard', 'nutSlotDepth')
- if nutSlotDepthAttrib:
- nutSlotDepth = nutSlotDepthAttrib.value
-
- markerDiameter = str(defaultParameters.markerDiameter * defaultParameters.userUnit)
- markerDiameterAttrib = design.attributes.itemByName('Fretboard', 'markerDiameter')
- if markerDiameterAttrib:
- markerDiameter = markerDiameterAttrib.value
-
- markerDepth = str(defaultParameters.markerDepth * defaultParameters.userUnit)
- markerDepthAttrib = design.attributes.itemByName('Fretboard', 'markerDepth')
- if markerDepthAttrib:
- markerDepth = markerDepthAttrib.value
-
- markerSpacing = str(defaultParameters.markerSpacing * defaultParameters.userUnit)
- markerSpacingAttrib = design.attributes.itemByName('Fretboard', 'markerSpacing')
- if markerSpacingAttrib:
- markerSpacing = markerSpacingAttrib.value
-
- guitarLength = str(defaultParameters.guitarLength * defaultParameters.userUnit)
- guitarLengthAttrib = design.attributes.itemByName('Fretboard', 'guitarLength')
- if guitarLengthAttrib:
- guitarLength = guitarLengthAttrib.value
-
- bodyWidth = str(defaultParameters.bodyWidth * defaultParameters.userUnit)
- bodyWidthAttrib = design.attributes.itemByName('Fretboard', 'bodyWidth')
- if bodyWidthAttrib:
- bodyWidth = bodyWidthAttrib.value
-
- bodyThickness = str(defaultParameters.bodyThickness * defaultParameters.userUnit)
- bodyThicknessAttrib = design.attributes.itemByName('Fretboard', 'bodyThickness')
- if bodyThicknessAttrib:
- bodyThickness = bodyThicknessAttrib.value
-
- bodyLength = str(defaultParameters.bodyLength * defaultParameters.userUnit)
- bodyLengthAttrib = design.attributes.itemByName('Fretboard', 'bodyLength')
- if bodyLengthAttrib:
- bodyLength = bodyLengthAttrib.value
-
- firstFretThickness = str(defaultParameters.firstFretThickness * defaultParameters.userUnit)
- firstFretThicknessAttrib = design.attributes.itemByName('Fretboard', 'firstFretThickness')
- if firstFretThicknessAttrib:
- firstFretThickness = firstFretThicknessAttrib.value
-
- twelfthfretThickness = str(defaultParameters.twelfthfretThickness * defaultParameters.userUnit)
- twelfthfretThicknessAttrib = design.attributes.itemByName('Fretboard', 'twelfthfretThickness')
- if twelfthfretThicknessAttrib:
- twelfthfretThickness = twelfthfretThicknessAttrib.value
-
- neckThickness = str(defaultParameters.neckThickness * defaultParameters.userUnit)
- neckThicknessAttrib = design.attributes.itemByName('Fretboard', 'neckThickness')
- if neckThicknessAttrib:
- neckThickness = neckThicknessAttrib.value
-
- headstockLength = str(defaultParameters.headstockLength * defaultParameters.userUnit)
- headstockLengthAttrib = design.attributes.itemByName('Fretboard', 'headstockLength')
- if headstockLengthAttrib:
- headstockLength = headstockLengthAttrib.value
-
- headstockWidth = str(defaultParameters.headstockWidth * defaultParameters.userUnit)
- headstockWidthAttrib = design.attributes.itemByName('Fretboard', 'headstockWidth')
- if headstockWidthAttrib:
- headstockWidth = headstockWidthAttrib.value
-
- headstockThickness = str(defaultParameters.headstockThickness * defaultParameters.userUnit)
- headstockThicknessAttrib = design.attributes.itemByName('Fretboard', 'headstockThickness')
- if headstockThicknessAttrib:
- headstockThickness = headstockThicknessAttrib.value
-
- bridgeStringSpacing = str(defaultParameters.bridgeStringSpacing * defaultParameters.userUnit)
- bridgeStringSpacingAttrib = design.attributes.itemByName('Fretboard', 'bridgeStringSpacing')
- if bridgeStringSpacingAttrib:
- bridgeStringSpacing = bridgeStringSpacingAttrib.value
-
- nutStringSpacing = str(defaultParameters.nutStringSpacing * defaultParameters.userUnit)
- nutStringSpacingAttrib = design.attributes.itemByName('Fretboard', 'nutStringSpacing')
- if nutStringSpacingAttrib:
- nutStringSpacing = nutStringSpacingAttrib.value
-
- nutToPost = str(defaultParameters.nutToPost * defaultParameters.userUnit)
- nutToPostAttrib = design.attributes.itemByName('Fretboard', 'nutToPost')
- if nutToPostAttrib:
- nutToPost = nutToPostAttrib.value
-
- stringCount = str(defaultParameters.stringCount)
- stringCountAttrib = design.attributes.itemByName('Fretboard', 'stringCount')
- if stringCountAttrib:
- stringCount = stringCountAttrib.value
-
- machinePostHoleDiameter = str(defaultParameters.machinePostHoleDiameter * defaultParameters.userUnit)
- machinePostHoleDiameterAttrib = design.attributes.itemByName('Fretboard', 'machinePostHoleDiameter')
- if machinePostHoleDiameterAttrib:
- machinePostHoleDiameter = machinePostHoleDiameterAttrib.value
-
- machinePostDiameter = str(defaultParameters.machinePostDiameter * defaultParameters.userUnit)
- machinePostDiameterAttrib = design.attributes.itemByName('Fretboard', 'machinePostDiameter')
- if machinePostDiameterAttrib:
- machinePostDiameter = machinePostDiameterAttrib.value
-
- machinePostHoleSpacing = str(defaultParameters.machinePostHoleSpacing * defaultParameters.userUnit)
- machinePostHoleSpacingAttrib = design.attributes.itemByName('Fretboard', 'machinePostHoleSpacing')
- if machinePostHoleSpacingAttrib:
- machinePostHoleSpacing = machinePostHoleSpacingAttrib.value
-
- headstockStyle = 'Straight In-line'
- headstockStyleAttrib = design.attributes.itemByName('Fretboard', 'headstockStyle')
- if headstockStyleAttrib:
- headstockStyle = headstockStyleAttrib.value
-
- fretboardStyle = 'Straight Radius'
- fretboardStyleAttrib = design.attributes.itemByName('Fretboard', 'fretboardStyle')
- if fretboardStyleAttrib:
- fretboardStyle = fretboardStyleAttrib.value
-
- pickupNeck = 'Single-Coil'
- pickupNeckAttrib = design.attributes.itemByName('pickups', 'pickupNeck')
- if pickupNeckAttrib:
- pickupNeck = pickupNeckAttrib.value
-
- pickupMiddle = 'Single-Coil'
- pickupMiddleAttrib = design.attributes.itemByName('pickups', 'pickupMiddle')
- if pickupMiddleAttrib:
- pickupMiddle = pickupMiddleAttrib.value
-
- pickupBridge = 'Single-Coil'
- pickupBridgeAttrib = design.attributes.itemByName('pickups', 'pickupBridge')
- if pickupBridgeAttrib:
- pickupBridge = pickupBridgeAttrib.value
-
- neckSpacing = str(defaultParameters.neckSpacing * defaultParameters.userUnit)
- neckSpacingAttrib = design.attributes.itemByName('Fretboard', 'neckSpacing')
- if neckSpacingAttrib:
- neckSpacing = neckSpacingAttrib.value
-
- bridgeSpacing = str(defaultParameters.bridgeSpacing * defaultParameters.userUnit)
- bridgeSpacingAttrib = design.attributes.itemByName('Fretboard', 'bridgeSpacing')
- if bridgeSpacingAttrib:
- bridgeSpacing = bridgeSpacingAttrib.value
-
- singleCoilLength = str(defaultParameters.singleCoilLength * defaultParameters.userUnit)
- singleCoilLengthAttrib = design.attributes.itemByName('Fretboard', 'singleCoilLength')
- if singleCoilLengthAttrib:
- singleCoilLength = singleCoilLengthAttrib.value
-
- singleCoilWidth = str(defaultParameters.singleCoilWidth * defaultParameters.userUnit)
- singleCoilWidthAttrib = design.attributes.itemByName('Fretboard', 'singleCoilWidth')
- if singleCoilWidthAttrib:
- singleCoilWidth = singleCoilWidthAttrib.value
-
- singleCoilDepth = str(defaultParameters.singleCoilDepth * defaultParameters.userUnit)
- singleCoilDepthAttrib = design.attributes.itemByName('Fretboard', 'singleCoilDepth')
- if singleCoilDepthAttrib:
- singleCoilDepth = singleCoilDepthAttrib.value
-
- humbuckerLength = str(defaultParameters.humbuckerLength * defaultParameters.userUnit)
- humbuckerLengthAttrib = design.attributes.itemByName('Fretboard', 'humbuckerLength')
- if humbuckerLengthAttrib:
- humbuckerLength = humbuckerLengthAttrib.value
-
- humbuckerWidth = str(defaultParameters.humbuckerWidth * defaultParameters.userUnit)
- humbuckerWidthAttrib = design.attributes.itemByName('Fretboard', 'humbuckerWidth')
- if humbuckerWidthAttrib:
- humbuckerWidth = humbuckerWidthAttrib.value
-
- humbuckerDepth = str(defaultParameters.humbuckerDepth * defaultParameters.userUnit)
- humbuckerDepthAttrib = design.attributes.itemByName('Fretboard', 'humbuckerDepth')
- if humbuckerDepthAttrib:
- humbuckerDepth = humbuckerDepthAttrib.value
-
- humbuckerFillet = str(defaultParameters.humbuckerFillet * defaultParameters.userUnit)
- humbuckerFilletAttrib = design.attributes.itemByName('Fretboard', 'humbuckerFillet')
- if humbuckerFilletAttrib:
- humbuckerFillet = humbuckerFilletAttrib.value
-
- pickupCavityMountLength = str(defaultParameters.pickupCavityMountLength * defaultParameters.userUnit)
- pickupCavityMountLengthAttrib = design.attributes.itemByName('Fretboard', 'pickupCavityMountLength')
- if pickupCavityMountLengthAttrib:
- pickupCavityMountLength = pickupCavityMountLengthAttrib.value
-
- pickupCavityMountTabWidth = str(defaultParameters.pickupCavityMountTabWidth * defaultParameters.userUnit)
- pickupCavityMountTabWidthAttrib = design.attributes.itemByName('Fretboard', 'pickupCavityMountTabWidth')
- if pickupCavityMountTabWidthAttrib:
- pickupCavityMountTabWidth = pickupCavityMountTabWidthAttrib.value
-
- bridgePickupAngle = str(defaultParameters.bridgePickupAngle)
- bridgePickupAngleAttrib = design.attributes.itemByName('Fretboard', 'bridgePickupAngle')
- if bridgePickupAngleAttrib:
- bridgePickupAngle = bridgePickupAngleAttrib.value
-
- global defaultStandard, defaultFretNumber, defaultScaleLength, defaultNutLength, defaultEndLength, createFlatFretboard, defaultRadius, defaultNutRadius, defaultEndRadius, defaultfretboardHeight, \
- createFilletRadius, defaultFilletRadius, createEndCurve, extensionVisibility, defaultEndCurve, createFretCuts, defaultTangWidth, defaultTangDepth, createBlindFrets, defaultBlindFrets, \
- defaultNutSlotWidth, defaultPickupNeck, defaultPickupMiddle, defaultPickupBridge, defaultNutSlotDepth, createFretMarkers, defaultMarkerDiameter, defaultMarkerDepth, defaultMarkerSpacing, \
- defaultFretboardLength, defaultFretboardStyle, defaultGuitarLength, defaultBodyWidth, defaultBodyThickness, defaultBodyLength, defaultNeckLength, defaultNeckWidth, defaultNeckThickness, \
- defaultHeadstockLength, defaultHeadstockWidth, defaultHeadstockThickness, defaultBridgeStringSpacing, defaultNutStringSpacing, defaultNutToPost, defaultMachinePostHoleDiameter, createBlanks, \
- defaultMachinePostDiameter, defaultMachinePostHoleSpacing, defaultStringCount, defaultfirstFretThickness, defaulttwelfthfretThickness, createDimensions, defaultHeadstockStyle, defaultNeckSpacing, \
- defaultBridgeSpacing, defaultSingleCoilLength, defaultSingleCoilWidth, defaultSingleCoilDepth, defaultHumbuckerLength, defaultHumbuckerWidth, defaultHumbuckerDepth, defaultHumbuckerFillet, \
- defaultPickupCavityMountLength, defaultPickupCavityMountTabWidth, defaultBridgePickupAngle, createOnlyFretboard, errorMessage
-
- cmd = eventArgs.command
- cmd.isExecutedWhenPreEmpted = False
- inputs = cmd.commandInputs
- cmd.helpFile = 'help.html'
- cmd.okButtonText = 'Create Fretboard'
-
- # Set the size of the dialog.
- cmd.setDialogInitialSize(275, 800)
- cmd.setDialogMinimumSize(275, 800)
- cmd.okButtonText = 'Create Guitar'
-
- # Create a tab input.
- tabCmdInput1 = inputs.addTabCommandInput('general', 'General')
- tab1ChildInputs = tabCmdInput1.children
- imgInput = tab1ChildInputs.addImageCommandInput('fretboardImage', '', 'Resources/guitarEngine.png')
- imgInput.isFullWidth = True
-
- defaultStandard = tab1ChildInputs.addDropDownCommandInput('standard', 'Standard', adsk.core.DropDownStyles.TextListDropDownStyle)
- if standard == "Imperial":
- defaultStandard.listItems.add('Imperial', True)
- defaultStandard.listItems.add('Metric', False)
- else:
- defaultStandard.listItems.add('Imperial', False)
- defaultStandard.listItems.add('Metric', True)
-
- errorMessage = tab1ChildInputs.addTextBoxCommandInput('errorMessage', '', '', 1, True)
- errorMessage.isFullWidth = True
-
- defaultFretNumber = tab1ChildInputs.addIntegerSpinnerCommandInput('fretNumber', 'Number of Frets', 12, 36, 1, int(fretNumber))
-
-
- defaultStringCount = tab1ChildInputs.addIntegerSpinnerCommandInput('stringCount', 'Number of Strings', 4, 12, 1, int(stringCount))
-
-
- defaultScaleLength = tab1ChildInputs.addValueInput('scaleLength', 'Scale Length', units, adsk.core.ValueInput.createByReal(float(scaleLength)))
-
-
- defaultGuitarLength = tab1ChildInputs.addValueInput('guitarLength', 'Guitar Length', units, adsk.core.ValueInput.createByReal(float(guitarLength)))
-
-
- defaultBodyLength = tab1ChildInputs.addValueInput('bodyLength', 'Body Length', units, adsk.core.ValueInput.createByReal(float(bodyLength)))
-
-
- defaultBodyWidth = tab1ChildInputs.addValueInput('bodyWidth', 'Body Width', units, adsk.core.ValueInput.createByReal(float(bodyWidth)))
-
-
- defaultBodyThickness = tab1ChildInputs.addValueInput('bodyThickness', 'Body Thickness', units, adsk.core.ValueInput.createByReal(float(bodyThickness)))
-
-
- defaultNeckThickness = tab1ChildInputs.addValueInput('neckThickness', 'Neck Thickness', units, adsk.core.ValueInput.createByReal(float(neckThickness)))
-
-
- defaultfirstFretThickness = tab1ChildInputs.addValueInput('firstFretThickness', 'First Fret Thickness', units, adsk.core.ValueInput.createByReal(float(firstFretThickness)))
-
-
- defaulttwelfthfretThickness = tab1ChildInputs.addValueInput('twelfthfretThickness', 'Twelfth Fret Thickness', units, adsk.core.ValueInput.createByReal(float(twelfthfretThickness)))
-
-
- message = '
'
- tab1ChildInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 1, True)
- createOnlyFretboard = tab1ChildInputs.addBoolValueInput('onlyFretboard', 'Generate Fretboard Only?', True, '', False)
-
-
- createBlanks = tab1ChildInputs.addBoolValueInput('blanks', 'Generate Guitar Blanks?', True, '', True)
-
-
- createDimensions = tab1ChildInputs.addBoolValueInput('dimensions', 'Generate Guitar Dimensions?', True, '', False)
-
-
- # Create a tab input.
- tabCmdInput2 = inputs.addTabCommandInput('fretboard', 'Fretboard')
- tab2ChildInputs = tabCmdInput2.children
-
- # Create group input.
- groupCmdInput1 = tab2ChildInputs.addGroupCommandInput('fretboard', 'Fretboard')
- groupCmdInput1.isExpanded = True
- groupCmdInput1.isEnabledCheckBoxDisplayed = False
- groupChildInputs1 = groupCmdInput1.children
-
- defaultFretboardStyle = groupChildInputs1.addDropDownCommandInput('fretboardStyle', 'Fretboard Style', adsk.core.DropDownStyles.TextListDropDownStyle)
- if fretboardStyle == "Straight Radius":
- defaultFretboardStyle.listItems.add('Straight Radius', True)
- defaultFretboardStyle.listItems.add('Compound Radius', False)
- defaultFretboardStyle.listItems.add('Flat/No Radius', False)
- elif fretboardStyle == "Compound Radius":
- defaultFretboardStyle.listItems.add('Straight Radius', False)
- defaultFretboardStyle.listItems.add('Compound Radius', True)
- defaultFretboardStyle.listItems.add('Flat/No Radius', False)
- elif fretboardStyle == "Flat/No Radius":
- defaultFretboardStyle.listItems.add('Straight Radius', False)
- defaultFretboardStyle.listItems.add('Compound Radius', False)
- defaultFretboardStyle.listItems.add('Flat/No Radius', True)
- else:
- pass
-
- defaultRadius = groupChildInputs1.addValueInput('radius', 'Radius', units, adsk.core.ValueInput.createByReal(float(radius)))
-
-
- defaultNutRadius = groupChildInputs1.addValueInput('nutRadius', 'Nut Radius', units, adsk.core.ValueInput.createByReal(float(nutRadius)))
-
-
- defaultEndRadius = groupChildInputs1.addValueInput('endRadius', 'End Radius', units, adsk.core.ValueInput.createByReal(float(endRadius)))
-
-
- message = '
'
- groupChildInputs1.addTextBoxCommandInput('fullWidth_textBox', '', message, 1, True)
- defaultFretboardLength = groupChildInputs1.addValueInput('fretboardLength', 'Fretboard Length', units, adsk.core.ValueInput.createByReal(float(fretboardLength)))
-
-
- defaultfretboardHeight = groupChildInputs1.addValueInput('fretboardHeight', 'Fretboard Height', units, adsk.core.ValueInput.createByReal(float(fretboardHeight)))
-
-
- defaultBridgeStringSpacing = groupChildInputs1.addValueInput('bridgeStringSpacing', 'Bridge String Spacing', units, adsk.core.ValueInput.createByReal(float(bridgeStringSpacing)))
-
-
- defaultNutStringSpacing = groupChildInputs1.addValueInput('nutStringSpacing', 'Nut String Spacing', units, adsk.core.ValueInput.createByReal(float(nutStringSpacing)))
-
-
- defaultNutLength = groupChildInputs1.addValueInput('nutLength', 'Nut Length', units, adsk.core.ValueInput.createByReal(float(nutLength)))
-
-
- defaultEndLength = groupChildInputs1.addValueInput('endLength', 'End Length', units, adsk.core.ValueInput.createByReal(float(endLength)))
-
-
- defaultNutSlotWidth = groupChildInputs1.addValueInput('nutSlotWidth', 'Nut Slot Width', units, adsk.core.ValueInput.createByReal(float(nutSlotWidth)))
-
-
- defaultNutSlotDepth = groupChildInputs1.addValueInput('nutSlotDepth', 'Nut Slot Depth', units, adsk.core.ValueInput.createByReal(float(nutSlotDepth)))
-
-
- createFilletRadius = groupChildInputs1.addBoolValueInput('filletRadius', 'Create Fillet Radius?', True, '', True)
-
-
- defaultFilletRadius = groupChildInputs1.addValueInput('filletRadius', 'Fillet Radius', units, adsk.core.ValueInput.createByReal(float(filletRadius)))
-
-
- createEndCurve = groupChildInputs1.addBoolValueInput('endCurve', 'Create End Curve?', True, '', True)
-
-
- defaultEndCurve = groupChildInputs1.addValueInput('endCurve', 'End Curve', units, adsk.core.ValueInput.createByReal(float(endCurve)))
-
-
- extensionVisibility = groupChildInputs1.addBoolValueInput('extensionVisibility', 'Extension Visible?', True, '', True)
-
-
- # Create group input.
- groupCmdInput2 = tab2ChildInputs.addGroupCommandInput('fretCuts', 'Fret Cuts')
- groupCmdInput2.isExpanded = True
- groupChildInputs2 = groupCmdInput2.children
- createFretCuts = groupChildInputs2.addBoolValueInput('fretCuts', 'Create Fret Cuts?', True, '', True)
-
-
- defaultTangWidth = groupChildInputs2.addValueInput('tangWidth', 'Tang Width', units,adsk.core.ValueInput.createByReal(float(tangWidth)))
-
-
- defaultTangDepth = groupChildInputs2.addValueInput('tangDepth', 'Tang Depth', units, adsk.core.ValueInput.createByReal(float(tangDepth)))
-
-
- createBlindFrets = groupChildInputs2.addBoolValueInput('blindFrets', 'Create Blind Frets?', True, '', True)
-
-
- if createFretCuts.value:
- createBlindFrets.isEnabled = True
- else:
- createBlindFrets.isEnabled = False
-
- defaultBlindFrets = groupChildInputs2.addValueInput('blindFrets', 'Blind Fret Inset', units, adsk.core.ValueInput.createByReal(float(blindFrets)))
-
-
- # Create group input.
- groupCmdInput3 = tab2ChildInputs.addGroupCommandInput('markerCuts', 'Fret Marker Cuts')
- groupCmdInput3.isExpanded = True
- groupChildInputs3 = groupCmdInput3.children
- createFretMarkers = groupChildInputs3.addBoolValueInput('fretMarkers', 'Create Fret Markers?', True, '', True)
-
-
- defaultMarkerDiameter = groupChildInputs3.addValueInput('markerDiameter', 'Marker Diameter', units, adsk.core.ValueInput.createByReal(float(markerDiameter)))
-
-
- defaultMarkerDepth = groupChildInputs3.addValueInput('markerDepth', 'Marker Depth', units, adsk.core.ValueInput.createByReal(float(markerDepth)))
-
-
- defaultMarkerSpacing = groupChildInputs3.addValueInput('markerSpacing', 'Marker Spacing', units, adsk.core.ValueInput.createByReal(float(markerSpacing)))
-
-
- # Create a tab input.
- tabCmdInput3 = inputs.addTabCommandInput('headstock', 'Headstock')
- tab3ChildInputs = tabCmdInput3.children
- defaultHeadstockStyle = tab3ChildInputs.addDropDownCommandInput('headstockStyle', 'Headstock Style', adsk.core.DropDownStyles.TextListDropDownStyle)
-
-
- if headstockStyle == "Straight In-line":
- defaultHeadstockStyle.listItems.add('Straight In-line', True)
- defaultHeadstockStyle.listItems.add('Symmetrical', False)
- else:
- defaultHeadstockStyle.listItems.add('Straight In-line', False)
- defaultHeadstockStyle.listItems.add('Symmetrical', True)
-
- message = 'Notice: Symmetrical only supports 6 strings.
'
-
- tab3ChildInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 1, True)
-
- defaultHeadstockLength = tab3ChildInputs.addValueInput('headstockLength', 'Headstock Length', units, adsk.core.ValueInput.createByReal(float(headstockLength)))
-
-
- defaultHeadstockWidth = tab3ChildInputs.addValueInput('headstockWidth', 'Headstock Width', units, adsk.core.ValueInput.createByReal(float(headstockWidth)))
-
-
- defaultHeadstockThickness = tab3ChildInputs.addValueInput('headstockThickness', 'Headstock Thickness', units, adsk.core.ValueInput.createByReal(float(headstockThickness)))
-
-
- defaultNutToPost = tab3ChildInputs.addValueInput('nutToPost', 'Nut To Post', units, adsk.core.ValueInput.createByReal(float(nutToPost)))
-
-
- defaultMachinePostHoleDiameter = tab3ChildInputs.addValueInput('machinePostHoleDiameter', 'Machine Post Hole Diameter', units, adsk.core.ValueInput.createByReal(float(machinePostHoleDiameter)))
-
-
- defaultMachinePostDiameter = tab3ChildInputs.addValueInput('machinePostDiameter', 'Machine Post Diameter', units, adsk.core.ValueInput.createByReal(float(machinePostDiameter)))
-
-
- defaultMachinePostHoleSpacing = tab3ChildInputs.addValueInput('machinePostHoleSpacing', 'Machine Post Hole Spacing', units, adsk.core.ValueInput.createByReal(float(machinePostHoleSpacing)))
-
-
- # Create a tab input.
- tabCmdInput4 = inputs.addTabCommandInput('pickups', 'Pickups')
- tab4ChildInputs = tabCmdInput4.children
- defaultPickupNeck = tab4ChildInputs.addDropDownCommandInput('pickups', 'Neck Pickup', adsk.core.DropDownStyles.TextListDropDownStyle)
-
-
- if pickupNeck == "Single-Coil":
- defaultPickupNeck.listItems.add('Single-Coil', True)
- defaultPickupNeck.listItems.add('Humbucker', False)
- defaultPickupNeck.listItems.add('None', False)
- elif pickupNeck == "Humbucker":
- defaultPickupNeck.listItems.add('Single-Coil', False)
- defaultPickupNeck.listItems.add('Humbucker', True)
- defaultPickupNeck.listItems.add('None', False)
- elif pickupNeck == "None":
- defaultPickupNeck.listItems.add('Single-Coil', False)
- defaultPickupNeck.listItems.add('Humbucker', False)
- defaultPickupNeck.listItems.add('None', True)
- else:
- pass
-
- defaultPickupMiddle = tab4ChildInputs.addDropDownCommandInput('pickups', 'Middle Pickup', adsk.core.DropDownStyles.TextListDropDownStyle)
-
-
- if pickupMiddle == "Single-Coil":
- defaultPickupMiddle.listItems.add('Single-Coil', True)
- defaultPickupMiddle.listItems.add('Humbucker', False)
- defaultPickupMiddle.listItems.add('None', False)
- elif pickupMiddle == "Humbucker":
- defaultPickupMiddle.listItems.add('Single-Coil', False)
- defaultPickupMiddle.listItems.add('Humbucker', True)
- defaultPickupMiddle.listItems.add('None', False)
- elif pickupMiddle == "None":
- defaultPickupMiddle.listItems.add('Single-Coil', False)
- defaultPickupMiddle.listItems.add('Humbucker', False)
- defaultPickupMiddle.listItems.add('None', True)
- else:
- pass
-
- defaultPickupBridge = tab4ChildInputs.addDropDownCommandInput('pickups', 'Bridge Pickup', adsk.core.DropDownStyles.TextListDropDownStyle)
-
-
- if pickupBridge == "Single-Coil":
- defaultPickupBridge.listItems.add('Single-Coil', True)
- defaultPickupBridge.listItems.add('Humbucker', False)
- # defaultPickupBridge.listItems.add('None', False)
- elif pickupBridge == "Humbucker":
- defaultPickupBridge.listItems.add('Single-Coil', False)
- defaultPickupBridge.listItems.add('Humbucker', True)
- else:
- pass
-
- # defaultBridgePickupAngle = tab4ChildInputs.addValueInput('pickups', 'Bridge Pickup Angle', 'deg', adsk.core.ValueInput.createByReal(math.radians(float(bridgePickupAngle))))
- defaultBridgePickupAngle = tab4ChildInputs.addFloatSpinnerCommandInput('pickups', 'Bridge Pickup Angle', 'deg', 0, 20, 1, float(bridgePickupAngle))
-
-
- defaultNeckSpacing = tab4ChildInputs.addValueInput('pickups', 'Neck Spacing', units, adsk.core.ValueInput.createByReal(float(neckSpacing)))
-
-
- defaultBridgeSpacing = tab4ChildInputs.addValueInput('pickups', 'Bridge Spacing', units, adsk.core.ValueInput.createByReal(float(bridgeSpacing)))
-
-
- groupCmdInput4 = tab4ChildInputs.addGroupCommandInput('pickUps', 'Single-Coil')
- groupCmdInput4.isExpanded = True
- groupChildInputs4 = groupCmdInput4.children
- defaultSingleCoilLength = groupChildInputs4.addValueInput('pickups', 'Single-Coil Length', units, adsk.core.ValueInput.createByReal(float(singleCoilLength)))
-
-
- defaultSingleCoilWidth = groupChildInputs4.addValueInput('pickups', 'Single-Coil Width', units, adsk.core.ValueInput.createByReal(float(singleCoilWidth)))
-
-
- defaultSingleCoilDepth = groupChildInputs4.addValueInput('pickups', 'Single-Coil Depth', units, adsk.core.ValueInput.createByReal(float(singleCoilDepth)))
-
-
- groupCmdInput5 = tab4ChildInputs.addGroupCommandInput('pickUps', 'Humbucker')
- groupCmdInput5.isExpanded = True
- groupChildInputs5 = groupCmdInput5.children
- defaultHumbuckerLength = groupChildInputs5.addValueInput('pickups', 'Humbucker Length', units, adsk.core.ValueInput.createByReal(float(humbuckerLength)))
-
-
- defaultHumbuckerWidth = groupChildInputs5.addValueInput('pickups', 'Humbucker Width', units, adsk.core.ValueInput.createByReal(float(humbuckerWidth)))
-
-
- defaultHumbuckerDepth = groupChildInputs5.addValueInput('pickups', 'Humbucker Depth', units, adsk.core.ValueInput.createByReal(float(humbuckerDepth)))
-
-
- defaultHumbuckerFillet = groupChildInputs5.addValueInput('pickups', 'Humbucker Corner Radius', units, adsk.core.ValueInput.createByReal(float(humbuckerFillet)))
-
-
- defaultPickupCavityMountLength = groupChildInputs5.addValueInput('pickups', 'Length of pickup cavity', units, adsk.core.ValueInput.createByReal(float(pickupCavityMountLength)))
-
-
- defaultPickupCavityMountTabWidth = groupChildInputs5.addValueInput('pickups', 'Width of pickup cavity rout', units, adsk.core.ValueInput.createByReal(float(pickupCavityMountTabWidth)))
-
-
- # Create a tab input.
- tabCmdInput5 = inputs.addTabCommandInput('info', 'Info')
- tab5ChildInputs = tabCmdInput5.children
-
- message = ''
- tab5ChildInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 10, True)
-
- message = ''
- tab5ChildInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 10, True)
-
- message = ''
- tab5ChildInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 3, True)
-
- # Connect to the command related events.
- onExecute = FretboardCommandExecuteHandler()
- cmd.execute.add(onExecute)
- handlers.append(onExecute)
- onInputChanged = FretboardCommandInputChangedHandler()
- cmd.inputChanged.add(onInputChanged)
- handlers.append(onInputChanged)
- onValidateInputs = FretboardCommandValidateInputsHandler()
- cmd.validateInputs.add(onValidateInputs)
- handlers.append(onValidateInputs)
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-# Event handler for the execute event.
-class FretboardCommandExecuteHandler(adsk.core.CommandEventHandler):
- def __init__(self):
- super().__init__()
- def notify(self, args):
- try:
- eventArgs = adsk.core.CommandEventArgs.cast(args)
-
- # Save the current values as attributes.
- design = adsk.fusion.Design.cast(app.activeProduct)
- attribs = design.attributes
- attribs.add('Fretboard', 'standard', defaultStandard.selectedItem.name)
- attribs.add('Fretboard', 'headstockStyle', defaultHeadstockStyle.selectedItem.name)
- attribs.add('Fretboard', 'fretNumber', str(defaultFretNumber.value))
- attribs.add('Fretboard', 'stringCount', str(defaultStringCount.value))
- attribs.add('Fretboard', 'scaleLength', str(defaultScaleLength.value))
- attribs.add('Fretboard', 'fretboardLength', str(defaultFretboardLength.value))
- attribs.add('Fretboard', 'nutLength', str(defaultNutLength.value))
- attribs.add('Fretboard', 'endLength', str(defaultEndLength.value))
- attribs.add('Fretboard', 'radius', str(defaultRadius.value))
- attribs.add('Fretboard', 'nutRadius', str(defaultNutRadius.value))
- attribs.add('Fretboard', 'endRadius', str(defaultEndRadius.value))
- attribs.add('Fretboard', 'fretboardHeight', str(defaultfretboardHeight.value))
- attribs.add('Fretboard', 'filletRadius', str(defaultFilletRadius.value))
- attribs.add('Fretboard', 'endCurve', str(defaultEndCurve.value))
- attribs.add('Fretboard', 'tangWidth', str(defaultTangWidth.value))
- attribs.add('Fretboard', 'tangDepth', str(defaultTangDepth.value))
- attribs.add('Fretboard', 'blindFrets', str(defaultBlindFrets.value))
- attribs.add('Fretboard', 'nutSlotWidth', str(defaultNutSlotWidth.value))
- attribs.add('Fretboard', 'nutSlotDepth', str(defaultNutSlotWidth.value))
- attribs.add('Fretboard', 'markerDiameter', str(defaultMarkerDiameter.value))
- attribs.add('Fretboard', 'markerDepth', str(defaultMarkerDepth.value))
- attribs.add('Fretboard', 'markerSpacing', str(defaultMarkerSpacing.value))
- attribs.add('Fretboard', 'guitarLength', str(defaultGuitarLength.value))
- attribs.add('Fretboard', 'bodyWidth', str(defaultBodyWidth.value))
- attribs.add('Fretboard', 'bodyLength', str(defaultBodyLength.value))
- attribs.add('Fretboard', 'bodyThickness', str(defaultBodyThickness.value))
- attribs.add('Fretboard', 'headstockLength', str(defaultHeadstockLength.value))
- attribs.add('Fretboard', 'firstFretThickness', str(defaultfirstFretThickness.value))
- attribs.add('Fretboard', 'twelfthfretThickness', str(defaulttwelfthfretThickness.value))
- attribs.add('Fretboard', 'bridgeStringSpacing', str(defaultBridgeStringSpacing.value))
- attribs.add('Fretboard', 'nutStringSpacing', str(defaultNutStringSpacing.value))
- attribs.add('Fretboard', 'nutToPost', str(defaultNutToPost.value))
- attribs.add('Fretboard', 'machinePostHoleDiameter', str(defaultMachinePostHoleDiameter.value))
- attribs.add('Fretboard', 'machinePostDiameter', str(defaultMachinePostDiameter.value))
- attribs.add('Fretboard', 'machinePostHoleSpacing', str(defaultMachinePostHoleSpacing.value))
- attribs.add('Fretboard', 'neckThickness', str(defaultNeckThickness.value))
- attribs.add('Fretboard', 'headstockWidth', str(defaultHeadstockWidth.value))
- attribs.add('Fretboard', 'headstockThickness', str(defaultHeadstockThickness.value))
- attribs.add('Fretboard', 'neckSpacing', str(defaultNeckSpacing.value))
- attribs.add('Fretboard', 'bridgeSpacing', str(defaultBridgeSpacing.value))
- attribs.add('Fretboard', 'singleCoilLength', str(defaultSingleCoilLength.value))
- attribs.add('Fretboard', 'singleCoilWidth', str(defaultSingleCoilWidth.value))
- attribs.add('Fretboard', 'singleCoilDepth', str(defaultSingleCoilDepth.value))
- attribs.add('Fretboard', 'humbuckerLength', str(defaultHumbuckerLength.value))
- attribs.add('Fretboard', 'humbuckerWidth', str(defaultHumbuckerWidth.value))
- attribs.add('Fretboard', 'humbuckerDepth', str(defaultHumbuckerDepth.value))
- attribs.add('Fretboard', 'humbuckerFillet', str(defaultHumbuckerFillet.value))
- attribs.add('Fretboard', 'pickupCavityMountLength', str(defaultPickupCavityMountLength.value))
- attribs.add('Fretboard', 'pickupCavityMountTabWidth', str(defaultPickupCavityMountTabWidth.value))
- attribs.add('Fretboard', 'bridgePickupAngle', str(defaultBridgePickupAngle.value))
-
- if defaultHeadstockStyle.selectedItem.name == "Straight In-line":
- headstockStyle = 'Straight In-line'
- else:
- headstockStyle = 'Symmetrical'
-
- if defaultFretboardStyle.selectedItem.name == "Straight Radius":
- fretboardStyle = 'Straight Radius'
- elif defaultFretboardStyle.selectedItem.name == "Compound Radius":
- fretboardStyle = 'Compound Radius'
- elif defaultFretboardStyle.selectedItem.name == "Flat/No Radius":
- fretboardStyle = 'Flat/No Radius'
- else:
- pass
-
- if defaultPickupNeck.selectedItem.name == "Single-Coil":
- pickupNeck = 'Single-Coil'
- elif defaultPickupNeck.selectedItem.name == "Humbucker":
- pickupNeck = 'Humbucker'
- elif defaultPickupNeck.selectedItem.name == "None":
- pickupNeck = 'None'
- else:
- pass
-
- if defaultPickupMiddle.selectedItem.name == "Single-Coil":
- pickupMiddle = 'Single-Coil'
- elif defaultPickupMiddle.selectedItem.name == "Humbucker":
- pickupMiddle = 'Humbucker'
- elif defaultPickupMiddle.selectedItem.name == "None":
- pickupMiddle = 'None'
- else:
- pass
-
- if defaultPickupBridge.selectedItem.name == "Single-Coil":
- pickupBridge = 'Single-Coil'
- elif defaultPickupBridge.selectedItem.name == "Humbucker":
- pickupBridge = 'Humbucker'
- elif defaultPickupBridge.selectedItem.name == "None":
- pickupBridge = 'None'
- else:
- pass
-
- fretNumber = defaultFretNumber.value
- stringCount = defaultStringCount.value
- scaleLength = defaultScaleLength.value
- fretboardLength = defaultFretboardLength.value
- nutLength = defaultNutLength.value
- endLength = defaultEndLength.value
- radius = defaultRadius.value
- nutRadius = defaultNutRadius.value
- endRadius = defaultEndRadius.value
- fretboardHeight = defaultfretboardHeight.value
- filletRadius = defaultFilletRadius.value
- endCurve = defaultEndCurve.value
- tangWidth = defaultTangWidth.value
- tangDepth = defaultTangDepth.value
- blindFrets = defaultBlindFrets.value
- nutSlotWidth = defaultNutSlotWidth.value
- nutSlotDepth = defaultNutSlotWidth.value
- markerDiameter = defaultMarkerDiameter.value
- markerDepth = defaultMarkerDepth.value
- markerSpacing = defaultMarkerSpacing.value
- guitarLength = defaultGuitarLength.value
- bodyWidth = defaultBodyWidth.value
- bodyLength = defaultBodyLength.value
- bodyThickness = defaultBodyThickness.value
- headstockLength = defaultHeadstockLength.value
- firstFretThickness = defaultfirstFretThickness.value
- twelfthfretThickness = defaulttwelfthfretThickness.value
- bridgeStringSpacing = defaultBridgeStringSpacing.value
- nutStringSpacing = defaultNutStringSpacing.value
- nutToPost = defaultNutToPost.value
- machinePostHoleDiameter = defaultMachinePostHoleDiameter.value
- machinePostDiameter = defaultMachinePostDiameter.value
- machinePostHoleSpacing = defaultMachinePostHoleSpacing.value
- neckThickness = defaultNeckThickness.value
- headstockWidth = defaultHeadstockWidth.value
- headstockThickness = defaultHeadstockThickness.value
- neckSpacing = defaultNeckSpacing.value
- bridgeSpacing = defaultBridgeSpacing.value
- singleCoilLength = defaultSingleCoilLength.value
- singleCoilWidth = defaultSingleCoilWidth.value
- singleCoilDepth = defaultSingleCoilDepth.value
- humbuckerLength = defaultHumbuckerLength.value
- humbuckerWidth = defaultHumbuckerWidth.value
- humbuckerDepth = defaultHumbuckerDepth.value
- humbuckerFillet = defaultHumbuckerFillet.value
- pickupCavityMountLength = defaultPickupCavityMountLength.value
- pickupCavityMountTabWidth = defaultPickupCavityMountTabWidth.value
- bridgePickupAngle = defaultBridgePickupAngle.value
-
- if createOnlyFretboard.value:
- # Create the fretboard.
- fretboardComp = buildFretboard(design, fretNumber, scaleLength, nutLength, endLength, radius, nutRadius, endRadius, fretboardHeight, filletRadius, endCurve, tangWidth, tangDepth, blindFrets,
- nutSlotWidth, nutSlotDepth, markerDiameter, markerDepth, markerSpacing, guitarLength, headstockLength, fretboardLength, firstFretThickness, twelfthfretThickness, neckThickness,
- headstockWidth, headstockThickness)
- elif createOnlyFretboard.value == False:
- # Create the fretboard.
- fretboardComp = buildFretboard(design, fretNumber, scaleLength, nutLength, endLength, radius, nutRadius, endRadius, fretboardHeight, filletRadius, endCurve, tangWidth, tangDepth, blindFrets,
- nutSlotWidth, nutSlotDepth, markerDiameter, markerDepth, markerSpacing, guitarLength, headstockLength, fretboardLength, firstFretThickness, twelfthfretThickness, neckThickness,
- headstockWidth, headstockThickness)
-
- # Create blanks for body and headstock
- if createBlanks.value:
- blanksComp = buildBlanks(design, bodyLength, bodyWidth, bodyThickness, headstockLength, headstockWidth, headstockThickness, guitarLength)
- else:
- pass
-
- # Create the strings.
- stringsComp = buildStrings(design, stringCount, bridgeStringSpacing, nutStringSpacing, guitarLength, headstockLength, scaleLength, nutLength, fretboardHeight, machinePostHoleSpacing,
- machinePostHoleDiameter, machinePostDiameter, nutToPost, headstockStyle, headstockThickness)
-
- # Create the pickup cavities.
- pickupsComp = buildPickups(design, guitarLength, headstockLength, scaleLength, fretboardLength, neckSpacing, bridgeSpacing, singleCoilLength, singleCoilWidth, singleCoilDepth, humbuckerLength,
- humbuckerWidth, humbuckerDepth, humbuckerFillet, pickupNeck, pickupMiddle, pickupBridge, pickupCavityMountLength, pickupCavityMountTabWidth, bridgePickupAngle)
-
- # Create dimension sketches
- if createDimensions.value:
- dimsComp = guitarDimensions(design, fretNumber, scaleLength, nutLength, endLength, nutRadius, endRadius, fretboardHeight, filletRadius, endCurve, tangWidth, bridgeStringSpacing, tangDepth,
- nutSlotWidth, nutSlotDepth, markerDiameter, markerDepth, markerSpacing, guitarLength, bodyWidth, headstockLength, bodyLength, stringCount, nutToPost,
- machinePostHoleSpacing, machinePostHoleDiameter, machinePostDiameter, nutStringSpacing, fretboardLength, headstockStyle, neckSpacing, bridgeSpacing,
- singleCoilLength, singleCoilWidth, singleCoilDepth, humbuckerLength, humbuckerWidth, humbuckerDepth, humbuckerFillet, pickupNeck, pickupMiddle,
- pickupBridge, pickupCavityMountLength, pickupCavityMountTabWidth, bridgePickupAngle)
- else:
- pass
-
- # Create a list of usable paramters
- parameters = buildParameters(design, fretboardHeight, headstockLength, firstFretThickness, twelfthfretThickness, neckThickness, headstockWidth, headstockThickness, machinePostHoleSpacing,
- machinePostHoleDiameter, machinePostDiameter, nutToPost, bodyLength, bodyWidth, bodyThickness)
-
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-# Event handler for the inputChanged event.
-class FretboardCommandInputChangedHandler(adsk.core.InputChangedEventHandler):
- def __init__(self):
- super().__init__()
- def notify(self, args):
- try:
- eventArgs = adsk.core.InputChangedEventArgs.cast(args)
- changedInput = eventArgs.input
- design = adsk.fusion.Design.cast(app.activeProduct)
- unitsMgr = design.unitsManager
- defaultUnits = design.unitsManager.defaultLengthUnits
-
- fretNumber = defaultFretNumber.value
- stringCount = defaultStringCount.value
- scaleLength = defaultScaleLength.value
- fretboardLength = defaultFretboardLength.value
- nutLength = defaultNutLength.value
- endLength = defaultEndLength.value
- radius = defaultRadius.value
- nutRadius = defaultNutRadius.value
- endRadius = defaultEndRadius.value
- fretboardHeight = defaultfretboardHeight.value
- filletRadius = defaultFilletRadius.value
- endCurve = defaultEndCurve.value
- tangWidth = defaultTangWidth.value
- tangDepth = defaultTangDepth.value
- blindFrets = defaultBlindFrets.value
- nutSlotWidth = defaultNutSlotWidth.value
- nutSlotDepth = defaultNutSlotWidth.value
- markerDiameter = defaultMarkerDiameter.value
- markerDepth = defaultMarkerDepth.value
- markerSpacing = defaultMarkerSpacing.value
- guitarLength = defaultGuitarLength.value
- bodyWidth = defaultBodyWidth.value
- bodyLength = defaultBodyLength.value
- bodyThickness = defaultBodyThickness.value
- headstockLength = defaultHeadstockLength.value
- firstFretThickness = defaultfirstFretThickness.value
- twelfthfretThickness = defaulttwelfthfretThickness.value
- bridgeStringSpacing = defaultBridgeStringSpacing.value
- nutStringSpacing = defaultNutStringSpacing.value
- nutToPost = defaultNutToPost.value
- machinePostHoleDiameter = defaultMachinePostHoleDiameter.value
- machinePostDiameter = defaultMachinePostDiameter.value
- machinePostHoleSpacing = defaultMachinePostHoleSpacing.value
- neckThickness = defaultNeckThickness.value
- headstockWidth = defaultHeadstockWidth.value
- headstockThickness = defaultHeadstockThickness.value
- neckSpacing = defaultNeckSpacing.value
- bridgeSpacing = defaultBridgeSpacing.value
- singleCoilLength = defaultSingleCoilLength.value
- singleCoilWidth = defaultSingleCoilWidth.value
- singleCoilDepth = defaultSingleCoilDepth.value
- humbuckerLength = defaultHumbuckerLength.value
- humbuckerWidth = defaultHumbuckerWidth.value
- humbuckerDepth = defaultHumbuckerDepth.value
- humbuckerFillet = defaultHumbuckerFillet.value
- pickupCavityMountLength = defaultPickupCavityMountLength.value
- pickupCavityMountTabWidth = defaultPickupCavityMountTabWidth.value
- bridgePickupAngle = defaultBridgePickupAngle.value
-
- global units
- if changedInput.id == 'standard':
- if defaultStandard.selectedItem.name == 'Imperial':
- units = 'in'
- elif defaultStandard.selectedItem.name == 'Metric':
- units = 'mm'
-
- defaultScaleLength.value = defaultScaleLength.value
- defaultScaleLength.unitType = units
-
- defaultFretboardLength.value = defaultFretboardLength.value
- defaultFretboardLength.unitType = units
-
- defaultNutLength.value = defaultNutLength.value
- defaultNutLength.unitType = units
-
- defaultEndLength.value = defaultEndLength.value
- defaultEndLength.unitType = units
-
- defaultRadius.value = defaultRadius.value
- defaultRadius.unitType = units
-
- defaultNutRadius.value = defaultNutRadius.value
- defaultNutRadius.unitType = units
-
- defaultEndRadius.value = defaultEndRadius.value
- defaultEndRadius.unitType = units
-
- defaultfretboardHeight.value = defaultfretboardHeight.value
- defaultfretboardHeight.unitType = units
-
- defaultFilletRadius.value = defaultFilletRadius.value
- defaultFilletRadius.unitType = units
-
- defaultEndCurve.value = defaultEndCurve.value
- defaultEndCurve.unitType = units
-
- defaultTangWidth.value = defaultTangWidth.value
- defaultTangWidth.unitType = units
-
- defaultTangDepth.value = defaultTangDepth.value
- defaultTangDepth.unitType = units
-
- defaultBlindFrets.value = defaultBlindFrets.value
- defaultBlindFrets.unitType = units
-
- defaultNutSlotWidth.value = defaultNutSlotWidth.value
- defaultNutSlotWidth.unitType = units
-
- defaultNutSlotDepth.value = defaultNutSlotDepth.value
- defaultNutSlotDepth.unitType = units
-
- defaultMarkerDiameter.value = defaultMarkerDiameter.value
- defaultMarkerDiameter.unitType = units
-
- defaultMarkerDepth.value = defaultMarkerDepth.value
- defaultMarkerDepth.unitType = units
-
- defaultMarkerSpacing.value = defaultMarkerSpacing.value
- defaultMarkerSpacing.unitType = units
-
- defaultGuitarLength.value = defaultGuitarLength.value
- defaultGuitarLength.unitType = units
-
- defaultBodyWidth.value = defaultBodyWidth.value
- defaultBodyWidth.unitType = units
-
- defaultBodyLength.value = defaultBodyLength.value
- defaultBodyLength.unitType = units
-
- defaultBodyThickness.value = defaultBodyThickness.value
- defaultBodyThickness.unitType = units
-
- defaultHeadstockLength.value = defaultHeadstockLength.value
- defaultHeadstockLength.unitType = units
-
- defaultfirstFretThickness.value = defaultfirstFretThickness.value
- defaultfirstFretThickness.unitType = units
-
- defaulttwelfthfretThickness.value = defaulttwelfthfretThickness.value
- defaulttwelfthfretThickness.unitType = units
-
- defaultBridgeStringSpacing.value = defaultBridgeStringSpacing.value
- defaultBridgeStringSpacing.unitType = units
-
- defaultNutStringSpacing.value = defaultNutStringSpacing.value
- defaultNutStringSpacing.unitType = units
-
- defaultNutToPost.value = defaultNutToPost.value
- defaultNutToPost.unitType = units
-
- defaultMachinePostDiameter.value = defaultMachinePostDiameter.value
- defaultMachinePostDiameter.unitType = units
-
- defaultMachinePostHoleDiameter.value = defaultMachinePostHoleDiameter.value
- defaultMachinePostHoleDiameter.unitType = units
-
- defaultMachinePostHoleSpacing.value = defaultMachinePostHoleSpacing.value
- defaultMachinePostHoleSpacing.unitType = units
-
- defaultNeckThickness.value = defaultNeckThickness.value
- defaultNeckThickness.unitType = units
-
- defaultHeadstockWidth.value = defaultHeadstockWidth.value
- defaultHeadstockWidth.unitType = units
-
- defaultHeadstockThickness.value = defaultHeadstockThickness.value
- defaultHeadstockThickness.unitType = units
-
- defaultNeckSpacing.value = defaultNeckSpacing.value
- defaultNeckSpacing.unitType = units
-
- defaultBridgeSpacing.value = defaultBridgeSpacing.value
- defaultBridgeSpacing.unitType = units
-
- defaultSingleCoilLength.value = defaultSingleCoilLength.value
- defaultSingleCoilLength.unitType = units
-
- defaultSingleCoilWidth.value = defaultSingleCoilWidth.value
- defaultSingleCoilWidth.unitType = units
-
- defaultSingleCoilDepth.value = defaultSingleCoilDepth.value
- defaultSingleCoilDepth.unitType = units
-
- defaultHumbuckerLength.value = defaultHumbuckerLength.value
- defaultHumbuckerLength.unitType = units
-
- defaultHumbuckerWidth.value = defaultHumbuckerWidth.value
- defaultHumbuckerWidth.unitType = units
-
- defaultHumbuckerDepth.value = defaultHumbuckerDepth.value
- defaultHumbuckerDepth.unitType = units
-
- defaultHumbuckerFillet.value = defaultHumbuckerFillet.value
- defaultHumbuckerFillet.unitType = units
-
- defaultPickupCavityMountLength.value = defaultPickupCavityMountLength.value
- defaultPickupCavityMountLength.unitType = units
-
- defaultPickupCavityMountTabWidth.value = defaultPickupCavityMountTabWidth.value
- defaultPickupCavityMountTabWidth.unitType = units
-
- defaultBridgePickupAngle.value = defaultBridgePickupAngle.value
- defaultBridgePickupAngle.unitType = 'deg'
-
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-# Event handler for the validateInputs event.
-class FretboardCommandValidateInputsHandler(adsk.core.ValidateInputsEventHandler):
- def __init__(self):
- super().__init__()
- def notify(self, args):
- eventArgs = adsk.core.ValidateInputsEventArgs.cast(args)
-
- errorMessage.text = ''
-
- if defaultFretboardStyle.selectedItem.name == "Straight Radius":
- defaultRadius.isVisible = True
- defaultNutRadius.isVisible = False
- defaultEndRadius.isVisible = False
- elif defaultFretboardStyle.selectedItem.name == "Compound Radius":
- defaultRadius.isVisible = False
- defaultNutRadius.isVisible = True
- defaultEndRadius.isVisible = True
- elif defaultFretboardStyle.selectedItem.name == "Flat/No Radius":
- defaultRadius.isVisible = False
- defaultNutRadius.isVisible = False
- defaultEndRadius.isVisible = False
- else:
- pass
-
- if createFretCuts.value:
- defaultTangWidth.isEnabled = True
- defaultTangDepth.isEnabled = True
- else:
- defaultTangWidth.isEnabled = False
- defaultTangDepth.isEnabled = False
-
- if createFilletRadius.value:
- defaultFilletRadius.isEnabled = True
- else:
- defaultFilletRadius.isEnabled = False
-
- if createEndCurve.value:
- defaultEndCurve.isEnabled = True
- else:
- defaultEndCurve.isEnabled = False
-
- if createBlindFrets.value:
- defaultBlindFrets.isEnabled = True
- else:
- defaultBlindFrets.isEnabled = False
-
- if createFretMarkers.value:
- defaultMarkerDiameter.isEnabled = True
- defaultMarkerDepth.isEnabled = True
- defaultMarkerSpacing.isEnabled = True
- else:
- defaultMarkerDiameter.isEnabled = False
- defaultMarkerDepth.isEnabled = False
- defaultMarkerSpacing.isEnabled = False
-
- if defaultPickupBridge.selectedItem.name == "Single-Coil":
- defaultBridgePickupAngle.isVisible = True
- elif defaultPickupBridge.selectedItem.name == "Humbucker":
- defaultBridgePickupAngle.isVisible = False
-
- if createOnlyFretboard.value:
- createBlanks.isEnabled = False
- createDimensions.isEnabled = False
- else:
- createBlanks.isEnabled = True
- createDimensions.isEnabled = True
-
-def buildParameters(design, fretboardHeight, headstockLength, firstFretThickness, twelfthfretThickness, neckThickness, headstockWidth, headstockThickness, machinePostHoleSpacing,
- machinePostHoleDiameter, machinePostDiameter, nutToPost, bodyLength, bodyWidth, bodyThickness):
- try:
- design = adsk.fusion.Design.cast(app.activeProduct)
- unitsMgr = design.unitsManager
- defaultUnits = design.unitsManager.defaultLengthUnits
- userParams = design.userParameters
- bodyLengthParam = userParams.add('BodyLength', adsk.core.ValueInput.createByReal(float(bodyLength)), defaultUnits, '')
- bodyWidthParam = userParams.add('BodyWidth', adsk.core.ValueInput.createByReal(float(bodyWidth)), defaultUnits, '')
- bodyThicknessParam = userParams.add('BodyThickness', adsk.core.ValueInput.createByReal(float(bodyThickness)), defaultUnits, '')
- fretboardHeightParam = userParams.add('FretboardHeight', adsk.core.ValueInput.createByReal(float(fretboardHeight)), defaultUnits, '')
- neckThicknessParam = userParams.add('NeckThickness', adsk.core.ValueInput.createByReal(float(neckThickness)), defaultUnits, '')
- firstFretThicknessParam = userParams.add('FirstFretThickness', adsk.core.ValueInput.createByReal(float(firstFretThickness)), defaultUnits, '')
- twelfthfretThicknessParam = userParams.add('TwelfthfretThickness', adsk.core.ValueInput.createByReal(float(twelfthfretThickness)), defaultUnits, '')
- headstockLengthParam = userParams.add('HeadstockLength', adsk.core.ValueInput.createByReal(float(headstockLength)), defaultUnits, '')
- headstockWidthParam = userParams.add('HeadstockWidth', adsk.core.ValueInput.createByReal(float(headstockWidth)), defaultUnits, '')
- headstockThicknessParam = userParams.add('HeadstockThickness', adsk.core.ValueInput.createByReal(float(headstockThickness)), defaultUnits, '')
- headstockAngleParam = userParams.add('HeadstockAngle', adsk.core.ValueInput.createByString('10'), 'deg', '')
- hyoidDistanceParam = userParams.add('HyoidDistance', adsk.core.ValueInput.createByReal(1.5*2.54), defaultUnits, '')
- hyoidAngleParam = userParams.add('HyoidAngle', adsk.core.ValueInput.createByString('90'), 'deg', '')
- nutToPostParam = userParams.add('PutToPost', adsk.core.ValueInput.createByReal(float(nutToPost)), defaultUnits, '')
- machinePostHoleSpacingParam = userParams.add('MachinePostHoleSpacing', adsk.core.ValueInput.createByReal(float(machinePostHoleSpacing)), defaultUnits, '')
- machinePostHoleDiameterParam = userParams.add('MachinePostHoleDiameter', adsk.core.ValueInput.createByReal(float(machinePostHoleDiameter)), defaultUnits, '')
- machinePostDiameterParam = userParams.add('MachinePostDiameter', adsk.core.ValueInput.createByReal(float(machinePostDiameter)), defaultUnits, '')
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-def buildFretboard(design, fretNumber, scaleLength, nutLength, endLength, radius, nutRadius, endRadius, fretboardHeight, filletRadius, endCurve, tangWidth, tangDepth, blindFrets,
- nutSlotWidth, nutSlotDepth, markerDiameter, markerDepth, markerSpacing, guitarLength, headstockLength, fretboardLength, firstFretThickness, twelfthfretThickness, neckThickness,
- headstockWidth, headstockThickness):
- try:
- design = adsk.fusion.Design.cast(app.activeProduct)
- rootComp = design.rootComponent
- allOccs = rootComp.occurrences
- newOcc = allOccs.addNewComponent(adsk.core.Matrix3D.create())
- fretboardComp = adsk.fusion.Component.cast(newOcc.component)
- fretboardComp.description = 'Fretboard'
- #Equation for fret spacing
- for fretNum in range(1,int((fretNumber))+1):
- fretDistance = (scaleLength)-((scaleLength)/(2**(fretNum/12.0)))
- nutDistance = guitarLength - headstockLength
- #This calculates and rounds the total length of the fretboard using the scale length and number of frets
- L = fretboardLength
- print(L/2.54)
- if defaultFretboardStyle.selectedItem.name == "Straight Radius":
- endRadius = nutRadius = radius
- else:
- pass
- #Equation for defining the proper radii
- endR = endRadius-sqrt(endRadius**2-(endLength/2)**2)
- nutR = nutRadius-sqrt(nutRadius**2-(nutLength/2)**2)
- endC = endCurve-sqrt(endCurve**2-(endLength/2)**2)
- # Points defined for curves
- if defaultFretboardStyle.selectedItem.name == "Flat/No Radius":
- endTopL = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/-2), fretboardHeight)
- else:
- endTopL = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/-2), fretboardHeight-endR)
- if defaultFretboardStyle.selectedItem.name == "Flat/No Radius":
- endTopC = adsk.core.Point3D.create(nutDistance-L, 0, fretboardHeight)
- else:
- endTopC = adsk.core.Point3D.create(nutDistance-L, 0, fretboardHeight)
- if defaultFretboardStyle.selectedItem.name == "Flat/No Radius":
- endTopR = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/2), fretboardHeight)
- else:
- endTopR = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/2), fretboardHeight-endR)
- endBotL = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/-2), 0)
- endBotC = adsk.core.Point3D.create(nutDistance-L, 0, 0)
- endBotR = adsk.core.Point3D.create(nutDistance+endC-L, (endLength/2), 0)
- nutTopL = adsk.core.Point3D.create(nutDistance, (nutLength/-2), fretboardHeight-nutR)
- nutTopC = adsk.core.Point3D.create(nutDistance, 0, fretboardHeight)
- nutTopR = adsk.core.Point3D.create(nutDistance, (nutLength/2), fretboardHeight-nutR)
- # Create a new sketch.
- sketches = fretboardComp.sketches
- xyPlane = fretboardComp.xYConstructionPlane
- xzPlane = fretboardComp.xZConstructionPlane
- yzPlane = fretboardComp.yZConstructionPlane
- #create curve for bridge-end top arc
- sketch1 = sketches.add(xyPlane)
- sketch1.isComputeDeferred = True
- sketchArc1 = sketch1.sketchCurves.sketchArcs
- line1 = sketch1.sketchCurves.sketchLines;
- if createEndCurve.value and defaultFretboardStyle.selectedItem.name == "Flat/No Radius":
- path1 = sketchArc1.addByThreePoints(adsk.core.Point3D.create(nutDistance+endC-L, (endLength/2), fretboardHeight), adsk.core.Point3D.create(nutDistance-L, 0, fretboardHeight),
- adsk.core.Point3D.create(nutDistance+endC-L, (endLength/-2), fretboardHeight))
- elif createEndCurve.value:
- path1 = sketchArc1.addByThreePoints(endTopL, endTopC, endTopR)
- else:
- path1 = sketchArc1.addByThreePoints(adsk.core.Point3D.create(nutDistance-L, (endLength/2), fretboardHeight-endR), adsk.core.Point3D.create(nutDistance-L, 0, fretboardHeight),
- adsk.core.Point3D.create(nutDistance-L, (endLength/-2), fretboardHeight-endR))
- # else:
- # path1 = line1.addByTwoPoints(adsk.core.Point3D.create((endLength/2), fretboardHeight, nutDistance-L), adsk.core.Point3D.create((endLength/-2), fretboardHeight, nutDistance-L))
- openProfile1 = adsk.fusion.Path.create(path1.createForAssemblyContext(newOcc), adsk.fusion.ChainedCurveOptions.noChainedCurves)
- if createEndCurve.value:
- path2 = sketchArc1.addByThreePoints(endBotL, endBotC, endBotR)
- else:
- path2 = line1.addByTwoPoints(adsk.core.Point3D.create(nutDistance-L, (endLength/2), 0), adsk.core.Point3D.create(nutDistance-L, (endLength/-2), 0))
- openProfile2 = adsk.fusion.Path.create(path2.createForAssemblyContext(newOcc), adsk.fusion.ChainedCurveOptions.noChainedCurves)
- if defaultFretboardStyle.selectedItem.name == "Flat/No Radius":
- path3 = line1.addByTwoPoints(adsk.core.Point3D.create(nutDistance, (nutLength/-2), fretboardHeight), adsk.core.Point3D.create(nutDistance, (nutLength/2), fretboardHeight))
- else:
- path3 = sketchArc1.addByThreePoints(nutTopL, nutTopC, nutTopR)
- openProfile3 = adsk.fusion.Path.create(path3.createForAssemblyContext(newOcc), adsk.fusion.ChainedCurveOptions.noChainedCurves)
- path4 = line1.addByTwoPoints(adsk.core.Point3D.create(nutDistance, (nutLength/-2), 0), adsk.core.Point3D.create(nutDistance, (nutLength/2), 0))
- openProfile4 = adsk.fusion.Path.create(path4.createForAssemblyContext(newOcc), adsk.fusion.ChainedCurveOptions.noChainedCurves)
- line1.addByTwoPoints(path1.startSketchPoint, path3.startSketchPoint)
- line1.addByTwoPoints(path2.startSketchPoint, path4.endSketchPoint)
- line1.addByTwoPoints(path1.endSketchPoint, path3.endSketchPoint)
- line1.addByTwoPoints(path2.endSketchPoint, path4.startSketchPoint)
- sketch1.name = 'Fretboard curves'
- sketch1.arePointsShown = False
- sketch1.isVisible = False
- #Create sketch for fret lines
- sketch5 = sketches.add(xyPlane)
- sketch5.isComputeDeferred = True
- frets = sketch5.sketchCurves.sketchLines;
- sketch5.name = 'Fret Lines (Reference)'
- sketch5.isVisible = False
- #Create sketch for fret cuts
- sketch6 = sketches.add(xyPlane)
- sketch6.isComputeDeferred = False
- cuts = sketch6.sketchCurves.sketchLines;
- sketch6.name = 'Fret slots [ ' + str(fretNumber) + ' frets ]'
- sketch6.isVisible = False
- #create sketch for nut cut
- sketch7 = sketches.add(xyPlane)
- sketch7.isComputeDeferred = False
- nutSketch = sketch7.sketchCurves.sketchLines;
- nutSlotsketch = nutSketch.addTwoPointRectangle(adsk.core.Point3D.create(nutDistance, nutLength, fretboardHeight),
- adsk.core.Point3D.create(nutDistance+nutSlotWidth, -nutLength, fretboardHeight))
- nutProfile = sketch7.profiles.item(0)
- sketch7.name = 'Nut slot profile'
- sketch7.isVisible = False
- #create sketch for nut cut
- sketch9 = sketches.add(xyPlane)
- sketch9.isComputeDeferred = False
- fretMarker = sketch9.sketchCurves.sketchCircles;
- sketch9.name = 'Inlays'
- sketch9.isVisible = False
- sketch10 = sketches.add(xyPlane)
- sketch10.isComputeDeferred = True
- inplayPoints = sketch10.sketchPoints
- sketch10.name = 'Default Marker Positions'
- sketch10.isVisible = False
- # Create surface for bridge-end of fretboard
- loftFeats = fretboardComp.features.loftFeatures
- loftInput1 = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- loftSections1 = loftInput1.loftSections
- loftSections1.add(openProfile2)
- loftSections1.add(openProfile1)
- loftInput1.isSolid = False
- loft1 = loftFeats.add(loftInput1)
- l1 = loft1.faces[0]
- loft1.name = 'Loft: Fretboard End'
- # Create surface for nut-end of fretboard
- loftInput2 = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- loftSections2 = loftInput2.loftSections
- loftSections2.add(openProfile3)
- loftSections2.add(openProfile4)
- loftInput2.isSolid = False
- loft2 = loftFeats.add(loftInput2)
- l2 = loft2.faces[0]
- loft2.name = 'Loft: Fretboard Start'
- # Create new surface using previous surfaces
- loftInput3 = loftFeats.createInput(adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- loftSections3 = loftInput3.loftSections
- loftSections3.add(l1)
- loftSections3.add(l2)
- loftInput3.isSolid = False
- loft3 = loftFeats.add(loftInput3)
- l3 = loft3.faces[0]
- loft3.name = 'Loft: Fretboard'
- # Get surface bodies and add them to object collection
- surface1 = loft1.bodies.item(0)
- surface2 = loft2.bodies.item(0)
- surface3 = loft3.bodies.item(0)
- surfaces = adsk.core.ObjectCollection.create()
- surfaces.add(surface1)
- surfaces.add(surface2)
- surfaces.add(surface3)
- # Define tolerance
- tolerance = adsk.core.ValueInput.createByString('0.001 in')
- # Create a stitch input to be able to define the input needed for an stitch.
- stitches = fretboardComp.features.stitchFeatures
- stitchInput = stitches.createInput(surfaces, tolerance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- # Create a stitch feature.
- stitch = stitches.add(stitchInput)
- stitch.name = 'Stitch: Fretboard'
- #Select edges of bridge-end of fretboard to make fillets
- fretboardEndFace = stitch.bodies.item(0)
- fretboardEndEdge1 = fretboardEndFace.edges.item(1)
- fretboardEndEdge2 = fretboardEndFace.edges.item(3)
- #Create collection
- endEdges = adsk.core.ObjectCollection.create()
- endEdges.add(fretboardEndEdge1)
- endEdges.add(fretboardEndEdge2)
- if createFilletRadius.value:
- #Creating fillets
- fillets = fretboardComp.features.filletFeatures
- filletInput = fillets.createInput()
- filletInput.addConstantRadiusEdgeSet(endEdges, adsk.core.ValueInput.createByReal(filletRadius), True)
- filletInput.isG2 = False
- filletInput.isRollingBallCorner = True
- fillet = fillets.add(filletInput)
- fillet.name = 'Rounded Corners'
- else:
- pass
- # Get the body created by the stitch
- face = stitch.bodies.item(0)
- if createFilletRadius.value:
- topFace = face.faces.item(6)
- else:
- topFace = face.faces.item(4)
- # Create input entities for offset feature
- inputEntities = adsk.core.ObjectCollection.create()
- inputEntities.add(topFace)
- # Create an input for offset feature
- offsetFeature = fretboardComp.features.offsetFeatures
- offsetInput = offsetFeature.createInput(inputEntities, adsk.core.ValueInput.createByReal(-tangDepth),
- adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- #Get the surface body.
- extrudeFeature = offsetFeature.add(offsetInput)
- extrudeFeature.name = 'Offset: Fret Projections'
- offSurf = extrudeFeature.bodies.item(0)
- offSurf.name = 'Reference for fret cuts'
- offSurf.isVisible = False
- #Get an edge from surface, and add it to object collection.
- extend = offSurf.edges
- ext1 = extend.item(0)
- ext2 = extend.item(1)
- ext3 = extend.item(2)
- ext4 = extend.item(3)
- inputEdges = adsk.core.ObjectCollection.create()
- inputEdges.add(ext1)
- inputEdges.add(ext2)
- inputEdges.add(ext3)
- inputEdges.add(ext4)
- #Define a distance to extend.
- distance = adsk.core.ValueInput.createByString('0.5 in')
- #Create an extend input to be able to define the input needed for an extend.
- extendFeatures = fretboardComp.features.extendFeatures
- extendFeatureInput1 = extendFeatures.createInput(inputEdges, distance, adsk.fusion.SurfaceExtendTypes.NaturalSurfaceExtendType)
- #Create an extend feature.
- extendFeature1 = extendFeatures.add(extendFeatureInput1)
- extendFeature1.name = 'Extend: Fret Projections'
-
- #Create loop for fret spacing and creation
- fretSpacing = []
- for fret in range(1,int(fretNumber)+1):
- fretDistance = scaleLength-(scaleLength/(2**(fret/12.0)))
- fretSpacing.append(fretDistance)
- fretLength = nutLength + 2*sqrt(((fretDistance/(math.cos(math.radians(math.acos((L**2+(sqrt((((endLength-nutLength)/2)**2) +(L**2)))**2-
- ((endLength-nutLength)/2)**2)/(2*L*(sqrt((((endLength-nutLength)/2)**2)+(L**2)))))*((180)/math.pi)))))**2)
- -(fretDistance**2))
- if createBlindFrets.value:
- #Create fret lines for fret spacing reference
- fretLines = frets.addByTwoPoints(adsk.core.Point3D.create((nutDistance-fretDistance), ((fretLength/2)-(blindFrets/2)), fretboardHeight),
- adsk.core.Point3D.create((nutDistance-fretDistance), ((-fretLength/2)+(blindFrets/2)), fretboardHeight))
- #Create fret cuts
- cutLines = cuts.addTwoPointRectangle(adsk.core.Point3D.create((nutDistance-fretDistance-(tangWidth/2)), ((-fretLength/2)+(blindFrets/2)), fretboardHeight),
- adsk.core.Point3D.create((nutDistance-fretDistance+(tangWidth/2)), ((fretLength/2)-(blindFrets/2)), fretboardHeight))
- else:
- #Create fret lines for fret spacing reference
- fretLines = frets.addByTwoPoints(adsk.core.Point3D.create((nutDistance-fretDistance), ((fretLength/2)+(1)), fretboardHeight),
- adsk.core.Point3D.create((nutDistance-fretDistance), ((-fretLength/2)-(1)), fretboardHeight))
- #Create fret cuts
- cutLines = cuts.addTwoPointRectangle(adsk.core.Point3D.create((nutDistance-fretDistance-(tangWidth/2)), ((-fretLength/2)-(1)), fretboardHeight),
- adsk.core.Point3D.create((nutDistance-fretDistance+(tangWidth/2)), ((fretLength/2)+(1)), fretboardHeight))
- inlays = [((y-x)/2)+x for x, y in zip(fretSpacing,fretSpacing[1:])]
- for inlayOdd in inlays[1:9:2] + inlays[13:21:2]:
- fretMarker.addByCenterRadius(adsk.core.Point3D.create(nutDistance-inlayOdd, 0, fretboardHeight), markerDiameter)
- points = adsk.core.Point3D.create(nutDistance-inlayOdd, 0, fretboardHeight)
- sketch10 = inplayPoints.add(points)
- for inlayOdd in inlays[25:33:2]:
- fretMarker.addByCenterRadius(adsk.core.Point3D.create(nutDistance-inlayOdd, 0, fretboardHeight), markerDiameter/2)
- points = adsk.core.Point3D.create(nutDistance-inlayOdd, 0, fretboardHeight)
- sketch10 = inplayPoints.add(points)
- for inlayEven in inlays[10:24:12]:
- fretMarker.addByCenterRadius(adsk.core.Point3D.create(nutDistance-inlayEven, markerSpacing/2, fretboardHeight), markerDiameter)
- fretMarker.addByCenterRadius(adsk.core.Point3D.create(nutDistance-inlayEven, -markerSpacing/2, fretboardHeight), markerDiameter)
- points = adsk.core.Point3D.create(nutDistance-inlayEven, 0, fretboardHeight)
- sketch10 = inplayPoints.add(points)
- fretMarkers = adsk.core.ObjectCollection.create()
- for markers in sketch9.profiles:
- fretMarkers.add(markers)
- fretboard = stitch.bodies.item(0)
- fretboard.name = 'Fretboard' + ' [ ' + str(fretNumber) + ' frets ]'
- fretboardFaces = [face for face in fretboard.faces]
- if createFilletRadius.value:
- fretboardSurf = fretboardFaces[6::2]
- else:
- fretboardSurf = fretboardFaces[4::2]
- fretCurves = [curve for curve in sketch5.sketchCurves]
- sketch8 = sketches.add(xyPlane)
- sketch8.isComputeDeferred = True
- fretProj = sketch8.projectToSurface(fretboardSurf, fretCurves, adsk.fusion.SurfaceProjectTypes.AlongVectorSurfaceProjectType,
- fretboardComp.zConstructionAxis)
- sketch8.name = 'Fret Lines [ ' + str(fretNumber) + ' frets ]'
- sketch8.isVisible = False
- #Create an object collection to use an input.
- profs = adsk.core.ObjectCollection.create()
- #Add all of the profiles to the collection.
- for prof in sketch6.profiles:
- profs.add(prof)
- #Get extrude features
- extrudes = fretboardComp.features.extrudeFeatures
- if createFretMarkers.value:
- #Extrusion for fret markers
- markerExtrude = extrudes.addSimple(fretMarkers, adsk.core.ValueInput.createByReal(-markerDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
- markerExtrude.name = 'Extrusion: Fret Markers'
- else:
- pass
- # Extrude Sample 4: Create an extrusion that goes from the profile plane to a specified entity.
- extrudeInput1 = extrudes.createInput(profs, adsk.fusion.FeatureOperations.CutFeatureOperation)
- extentToEntity = adsk.fusion.ToEntityExtentDefinition.create(extrudeFeature.faces.item(0), True)
- # Set the one side extent with the to-entity-extent-definition, and with a taper angle of 0 degree
- extrudeInput1.setOneSideExtent(extentToEntity, adsk.fusion.ExtentDirections.PositiveExtentDirection)
- #Extrusion for adding material to the nut-end of the fretboard
- if createFilletRadius.value:
- nutExtend = extrudes.addSimple(fretboardFaces[4], distance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- else:
- nutExtend = extrudes.addSimple(fretboardFaces[1], distance, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- nutExt = nutExtend.bodies.item(0)
- nutExt.name = 'Extension'
- nutExtend.name = 'Extrusion: Extension'
- nutSlot = extrudes.addSimple(nutProfile, adsk.core.ValueInput.createByReal(-nutSlotDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
- nutSlot.name = 'Extrusion: Nut Slot'
- if createFretCuts.value:
- #Create the extrusion
- extrude1 = extrudes.add(extrudeInput1)
- extrude1.name = 'Extrusion: Cutting Frets'
- if extensionVisibility.value:
- nutExt.isVisible = True
- else:
- nutExt.isVisible = False
- # Get a reference to an appearance in the library.
- lib = app.materialLibraries.itemByName('Fusion 360 Appearance Library')
- libAppear1 = lib.appearances.itemByName('Paint - Enamel Glossy (Yellow)')
- libAppear2 = lib.appearances.itemByName('Wax (White)')
- fretboardAppearance1 = fretboardComp.bRepBodies.item(0)
- fretboardAppearance1.appearance = libAppear1
- fretboardAppearance2 = fretboardComp.bRepBodies.item(1)
- fretboardAppearance2.appearance = libAppear1
- offSurf.appearance = libAppear2
- #Centers the camera to fit the entire fretboard
- cam = app.activeViewport.camera
- cam.isFitView = True
- cam.isSmoothTransition = False
- app.activeViewport.camera = cam
- # Group everything used to create the fretboard in the timeline.
- timelineGroups = design.timeline.timelineGroups
- newOccIndex = newOcc.timelineObject.index
- if createFretCuts.value:
- endIndex = extrude1.timelineObject.index
- else:
- endIndex = nutSlot.timelineObject.index
- timelineGroup = timelineGroups.add(newOccIndex, endIndex)
- timelineGroup.name = 'Fretboard [ ' + str(fretNumber) + ' Frets ]'
- fretboardComp.name = 'Fretboard' + ' [ ' + str(fretNumber) + ' Frets ]'
- return fretboardComp
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-def buildBlanks(design, bodyLength, bodyWidth, bodyThickness, headstockLength, headstockWidth, headstockThickness, guitarLength):
- try:
- design = adsk.fusion.Design.cast(app.activeProduct)
- rootComp = design.rootComponent
- blanksOccs = rootComp.occurrences
- blanksOcc = blanksOccs.addNewComponent(adsk.core.Matrix3D.create())
- blanksComp = adsk.fusion.Component.cast(blanksOcc.component)
- # Create a new sketch.
- sketches = blanksComp.sketches
- xzPlane = blanksComp.xYConstructionPlane
- #Get extrude features
- extrudes = blanksComp.features.extrudeFeatures
- #Create sketch for bridge spacing
- sketch1 = sketches.add(xzPlane)
- sketch1.isComputeDeferred = False
- sketch1.name = 'Body Blank'
- bodyBlankSketch = sketch1.sketchCurves.sketchLines;
- bodyBlank = bodyBlankSketch.addTwoPointRectangle(adsk.core.Point3D.create(0, -bodyWidth/2, 0), adsk.core.Point3D.create(bodyLength, bodyWidth/2, 0))
- #Create sketch for bridge spacing
- sketch2 = sketches.add(xzPlane)
- sketch2.isComputeDeferred = False
- sketch2.name = 'Headstock Blank'
- headstockBlankSketch = sketch2.sketchCurves.sketchLines;
- headstockBlank = headstockBlankSketch.addTwoPointRectangle(adsk.core.Point3D.create(guitarLength-headstockLength, -headstockWidth/2, 0), adsk.core.Point3D.create(guitarLength, headstockWidth/2, 0))
- #Get extrude features
- extrudes = blanksComp.features.extrudeFeatures
- bodyProf = sketch1.profiles.item(0)
- headstockProf = sketch2.profiles.item(0)
- bodyExtrude = extrudes.addSimple(bodyProf, adsk.core.ValueInput.createByReal(-bodyThickness), adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- # Get the extrusion body
- bodyBody = bodyExtrude.bodies.item(0)
- bodyExtrude.name = "Extrusion: Body Blank"
- bodyBody.name = "Body Blank"
- headstockExtrude = extrudes.addSimple(headstockProf, adsk.core.ValueInput.createByReal(-headstockThickness), adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
- # Get the extrusion body
- headstockBody = headstockExtrude.bodies.item(0)
- headstockExtrude.name = "Extrusion: Headstock Blank"
- headstockBody.name = "Headstock Blank"
- # Get a reference to an appearance in the library.
- lib = app.materialLibraries.itemByName('Fusion 360 Appearance Library')
- libAppear1 = lib.appearances.itemByName('Wax (White)')
- blanksAppearance1 = blanksComp.bRepBodies.item(0)
- blanksAppearance1.appearance = libAppear1
- blanksAppearance2 = blanksComp.bRepBodies.item(1)
- blanksAppearance2.appearance = libAppear1
- #Centers the camera to fit the entire fretboard
- cam = app.activeViewport.camera
- cam.isFitView = True
- cam.isSmoothTransition = False
- app.activeViewport.camera = cam
- # Group everything used to create the fretboard in the timeline.
- timelineGroupsBlanks = design.timeline.timelineGroups
- blanksOccIndex = blanksOcc.timelineObject.index
- blanksEndIndex = headstockExtrude.timelineObject.index
- timelineGroupBlanks = timelineGroupsBlanks.add(blanksOccIndex, blanksEndIndex)
- timelineGroupBlanks.name = 'Blanks'
- blanksComp.name = 'Blanks'
- return blanksComp
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-def buildStrings(design, stringCount, bridgeStringSpacing, nutStringSpacing, guitarLength, headstockLength, scaleLength, nutLength, fretboardHeight, machinePostHoleSpacing,
- machinePostHoleDiameter, machinePostDiameter, nutToPost, headstockStyle, headstockThickness):
- try:
- design = adsk.fusion.Design.cast(app.activeProduct)
- rootComp = design.rootComponent
- stringsOccs = rootComp.occurrences
- stringsOcc = stringsOccs.addNewComponent(adsk.core.Matrix3D.create())
- stringsComp = adsk.fusion.Component.cast(stringsOcc.component)
- # Create a new sketch.
- sketches = stringsComp.sketches
- xzPlane = stringsComp.xYConstructionPlane
- #Get extrude features
- extrudes = stringsComp.features.extrudeFeatures
- stringInset = (nutLength - nutStringSpacing)/2
- nutDistance = guitarLength - headstockLength
- if headstockStyle == 'Straight In-line':
- #Create sketch for bridge spacing
- sketch1 = sketches.add(xzPlane)
- sketch1.isComputeDeferred = True
- sketch1.arePointsShown = False
- sketch1.name = 'Strings [ ' + str((int(stringCount))) + ' strings ]'
- stringSketch = sketch1.sketchCurves.sketchLines;
- for string in range(int(stringCount)):
- spacing = bridgeStringSpacing/2 - (bridgeStringSpacing/((int(stringCount))-1))*string
- nutSpacing = (nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/((int(stringCount))-1))*string
- holeSpacingHor = string*machinePostHoleSpacing
- stringsSketch = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength, spacing, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance, nutSpacing, fretboardHeight+0.125))
- stringsSketch = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, nutSpacing, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+holeSpacingHor, nutSpacing, 0))
- #Create sketch for bridge spacing
- sketch2 = sketches.add(xzPlane)
- sketch2.isComputeDeferred = True
- sketch2.arePointsShown = False
- sketch2.name = 'Machine Post Holes'
- machinePost = sketch2.sketchCurves.sketchCircles;
- for spacing in range(int(stringCount)):
- holeSpacingVert = ((nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/((int(stringCount))-1))*spacing)
- holeSpacingHor = spacing*machinePostHoleSpacing
- machinePostHoles = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+holeSpacingHor, holeSpacingVert+machinePostDiameter/2, 0), machinePostHoleDiameter/2)
- else:
- #Create sketch for bridge spacing
- sketch1 = sketches.add(xzPlane)
- sketch1.isComputeDeferred = True
- sketch1.arePointsShown = False
- sketch1.name = 'Strings [ ' + str((int(stringCount))) + ' strings ]'
- stringSketch = sketch1.sketchCurves.sketchLines;
- for string in range(int(stringCount)):
- spacing = bridgeStringSpacing/2 - (bridgeStringSpacing/((int(stringCount))-1))*string
- nutSpacing = (nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/((int(stringCount))-1))*string
- holeSpacingHor = string*machinePostHoleSpacing
- stringsSketch = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength, spacing, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance, nutSpacing, fretboardHeight+0.125))
- stringsSketch1 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, nutStringSpacing/2, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost, nutStringSpacing/2, 0))
- stringsSketch2 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, nutStringSpacing/2-(nutStringSpacing/5), fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, nutStringSpacing/2, 0))
- stringsSketch3 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, nutStringSpacing/2-(nutStringSpacing/5*2), fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, nutStringSpacing/2, 0))
- stringsSketch4 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, -nutStringSpacing/2+(nutStringSpacing/5*2), fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, -nutStringSpacing/2, 0))
- stringsSketch5 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, -nutStringSpacing/2+(nutStringSpacing/5), fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, -nutStringSpacing/2, 0))
- stringsSketch6 = stringSketch.addByTwoPoints(adsk.core.Point3D.create(nutDistance, -nutStringSpacing/2, fretboardHeight+0.125), adsk.core.Point3D.create(nutDistance+nutToPost, -nutStringSpacing/2, 0))
- #Create sketch for bridge spacing
- sketch2 = sketches.add(xzPlane)
- sketch2.isComputeDeferred = True
- sketch2.arePointsShown = False
- sketch2.name = 'Machine Post Holes'
- machinePost = sketch2.sketchCurves.sketchCircles;
- machinePostHole1 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
- machinePostHole2 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
- machinePostHole3 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
- machinePostHole4 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
- machinePostHole5 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
- machinePostHole6 = machinePost.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostHoleDiameter/2)
- tuningHoles = adsk.core.ObjectCollection.create()
- for holes in sketch2.profiles:
- tuningHoles.add(holes)
- #Get extrude features
- extrudes = stringsComp.features.extrudeFeatures
- if createBlanks.value:
- #Extrusion for fret markers
- holesExtrude = extrudes.addSimple(tuningHoles, adsk.core.ValueInput.createByReal(-headstockThickness*2), adsk.fusion.FeatureOperations.CutFeatureOperation)
- holesExtrude.name = 'Extrusion: Tuning Machine Holes'
- else:
- pass
- # Group everything used to create the fretboard in the timeline.
- timelineGroupsStrings = design.timeline.timelineGroups
- stringsOccIndex = stringsOcc.timelineObject.index
- if createBlanks.value:
- stringsEndIndex = holesExtrude.timelineObject.index
- else:
- stringsEndIndex = sketch2.timelineObject.index
- timelineGroupStrings = timelineGroupsStrings.add(stringsOccIndex, stringsEndIndex)
- timelineGroupStrings.name = 'Strings [ ' + str((int(stringCount))) + ' strings ]'
- stringsComp.name = 'Strings [ ' + str((int(stringCount))) + ' strings ]'
- return stringsComp
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-def buildPickups(design, guitarLength, headstockLength, scaleLength, fretboardLength, neckSpacing, bridgeSpacing, singleCoilLength, singleCoilWidth, singleCoilDepth, humbuckerLength,
- humbuckerWidth, humbuckerDepth, humbuckerFillet, pickupNeck, pickupMiddle, pickupBridge, pickupCavityMountLength, pickupCavityMountTabWidth, bridgePickupAngle):
- try:
- design = adsk.fusion.Design.cast(app.activeProduct)
- rootComp = design.rootComponent
- pickupsOccs = rootComp.occurrences
- pickupsOcc = pickupsOccs.addNewComponent(adsk.core.Matrix3D.create())
- pickupsComp = adsk.fusion.Component.cast(pickupsOcc.component)
- # Create a new sketch.
- sketches = pickupsComp.sketches
- xzPlane = pickupsComp.xYConstructionPlane
- neckDistance = guitarLength - headstockLength - fretboardLength - neckSpacing
- bridgeDistance = guitarLength - headstockLength - scaleLength + bridgeSpacing
- middleDistance = bridgeDistance + (neckDistance - bridgeDistance)/2
- if pickupNeck == "None":
- neckPickupType = ''
- else:
- #Create sketch for bridge spacing
- sketch1 = sketches.add(xzPlane)
- neckLines = sketch1.sketchCurves.sketchLines;
- cavityNeckLines = sketch1.sketchCurves.sketchLines;
- # Get sketch points
- sketchPoints = sketch1.sketchPoints
- sketch1.isComputeDeferred = True
- sketch1.areConstraintsShown = False
- sketch1.arePointsShown = False
- if pickupNeck == "Single-Coil":
- # Create sketch lines
- pickupNeck1 = neckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2)+singleCoilWidth/2, (singleCoilLength/2), 0))
- pickupNeck2 = neckLines.addByTwoPoints(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), (pickupCavityMountLength/2), 0))
- pickupNeck2.isConstruction = True
- pickupNeckFillet1 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[0], pickupNeck1[0].endSketchPoint.geometry, pickupNeck1[1], pickupNeck1[1].startSketchPoint.geometry, singleCoilWidth/2)
- pickupNeckFillet2 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[1], pickupNeck1[1].endSketchPoint.geometry, pickupNeck1[2], pickupNeck1[2].startSketchPoint.geometry, singleCoilWidth/2)
- pickupNeckFillet3 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[2], pickupNeck1[2].endSketchPoint.geometry, pickupNeck1[3], pickupNeck1[3].startSketchPoint.geometry, singleCoilWidth/2)
- pickupNeckFillet4 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[3], pickupNeck1[3].endSketchPoint.geometry, pickupNeck1[0], pickupNeck1[0].startSketchPoint.geometry, singleCoilWidth/2)
- cavityNeck1 = cavityNeckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2)+singleCoilWidth/2, (pickupCavityMountLength/2), 0))
- cavityNeckFillet1 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[0], cavityNeck1[0].endSketchPoint.geometry, cavityNeck1[1], cavityNeck1[1].startSketchPoint.geometry, singleCoilWidth/2)
- cavityNeckFillet2 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[1], cavityNeck1[1].endSketchPoint.geometry, cavityNeck1[2], cavityNeck1[2].startSketchPoint.geometry, singleCoilWidth/2)
- cavityNeckFillet3 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[2], cavityNeck1[2].endSketchPoint.geometry, cavityNeck1[3], cavityNeck1[3].startSketchPoint.geometry, singleCoilWidth/2)
- cavityNeckFillet4 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[3], cavityNeck1[3].endSketchPoint.geometry, cavityNeck1[0], cavityNeck1[0].startSketchPoint.geometry, singleCoilWidth/2)
- sketch1.name = 'Neck Pickup [Single-Coil]'
- neckPickupType = 'S'
- elif pickupNeck == "Humbucker":
- pickupNeck1 = neckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2)+humbuckerWidth/2, (humbuckerLength/2), 0))
- pickupNeck2 = neckLines.addByTwoPoints(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), (pickupCavityMountLength/2), 0))
- pickupNeck2.isConstruction = True
- pickupNeckFillet1 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[0], pickupNeck1[0].endSketchPoint.geometry, pickupNeck1[1], pickupNeck1[1].startSketchPoint.geometry, humbuckerFillet)
- pickupNeckFillet2 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[1], pickupNeck1[1].endSketchPoint.geometry, pickupNeck1[2], pickupNeck1[2].startSketchPoint.geometry, humbuckerFillet)
- pickupNeckFillet3 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[2], pickupNeck1[2].endSketchPoint.geometry, pickupNeck1[3], pickupNeck1[3].startSketchPoint.geometry, humbuckerFillet)
- pickupNeckFillet4 = sketch1.sketchCurves.sketchArcs.addFillet(pickupNeck1[3], pickupNeck1[3].endSketchPoint.geometry, pickupNeck1[0], pickupNeck1[0].startSketchPoint.geometry, humbuckerFillet)
- cavityNeck1 = cavityNeckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2)-pickupCavityMountTabWidth/2, (pickupCavityMountLength/2), 0))
- cavityNeckFillet1 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[0], cavityNeck1[0].endSketchPoint.geometry, cavityNeck1[1], cavityNeck1[1].startSketchPoint.geometry, humbuckerFillet/2)
- cavityNeckFillet2 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[1], cavityNeck1[1].endSketchPoint.geometry, cavityNeck1[2], cavityNeck1[2].startSketchPoint.geometry, humbuckerFillet/2)
- cavityNeckFillet3 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[2], cavityNeck1[2].endSketchPoint.geometry, cavityNeck1[3], cavityNeck1[3].startSketchPoint.geometry, humbuckerFillet/2)
- cavityNeckFillet4 = sketch1.sketchCurves.sketchArcs.addFillet(cavityNeck1[3], cavityNeck1[3].endSketchPoint.geometry, cavityNeck1[0], cavityNeck1[0].startSketchPoint.geometry, humbuckerFillet/2)
- sketch1.name = 'Neck Pickup [Humbucker]'
- neckPickupType = 'H'
- else:
- pass
- if pickupMiddle == "None":
- middlePickupType = ''
- else:
- #Create sketch for bridge spacing
- sketch2 = sketches.add(xzPlane)
- middleLines = sketch2.sketchCurves.sketchLines;
- cavitymiddleLines = sketch2.sketchCurves.sketchLines;
- # Get sketch points
- sketchPoints = sketch2.sketchPoints
- sketch2.isComputeDeferred = True
- sketch2.areConstraintsShown = False
- sketch2.arePointsShown = False
- if pickupMiddle == "Single-Coil":
- # Create sketch lines
- pickupMiddle1 = middleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+singleCoilWidth/2), (singleCoilLength/2), 0))
- pickupMiddle2 = middleLines.addByTwoPoints(adsk.core.Point3D.create((middleDistance), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((middleDistance), (pickupCavityMountLength/2), 0))
- pickupMiddle2.isConstruction = True
- pickupMiddleFillet1 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[0], pickupMiddle1[0].endSketchPoint.geometry, pickupMiddle1[1], pickupMiddle1[1].startSketchPoint.geometry, singleCoilWidth/2)
- pickupMiddleFillet2 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[1], pickupMiddle1[1].endSketchPoint.geometry, pickupMiddle1[2], pickupMiddle1[2].startSketchPoint.geometry, singleCoilWidth/2)
- pickupMiddleFillet3 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[2], pickupMiddle1[2].endSketchPoint.geometry, pickupMiddle1[3], pickupMiddle1[3].startSketchPoint.geometry, singleCoilWidth/2)
- pickupMiddleFillet4 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[3], pickupMiddle1[3].endSketchPoint.geometry, pickupMiddle1[0], pickupMiddle1[0].startSketchPoint.geometry, singleCoilWidth/2)
- cavityMiddle1 = cavitymiddleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+singleCoilWidth/2), (pickupCavityMountLength/2), 0))
- cavityMiddleFillet1 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[0], cavityMiddle1[0].endSketchPoint.geometry, cavityMiddle1[1], cavityMiddle1[1].startSketchPoint.geometry, singleCoilWidth/2)
- cavityMiddleFillet2 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[1], cavityMiddle1[1].endSketchPoint.geometry, cavityMiddle1[2], cavityMiddle1[2].startSketchPoint.geometry, singleCoilWidth/2)
- cavityMiddleFillet3 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[2], cavityMiddle1[2].endSketchPoint.geometry, cavityMiddle1[3], cavityMiddle1[3].startSketchPoint.geometry, singleCoilWidth/2)
- cavityMiddleFillet4 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[3], cavityMiddle1[3].endSketchPoint.geometry, cavityMiddle1[0], cavityMiddle1[0].startSketchPoint.geometry, singleCoilWidth/2)
- sketch2.name = 'Middle Pickup [Single-Coil]'
- middlePickupType = 'S'
- elif pickupMiddle == "Humbucker":
- # Create sketch lines
- pickupMiddle1 = middleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+humbuckerWidth/2), (humbuckerLength/2), 0))
- pickupMiddle2 = middleLines.addByTwoPoints(adsk.core.Point3D.create((middleDistance), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((middleDistance), (pickupCavityMountLength/2), 0))
- pickupMiddle2.isConstruction = True
- pickupMiddleFillet1 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[0], pickupMiddle1[0].endSketchPoint.geometry, pickupMiddle1[1], pickupMiddle1[1].startSketchPoint.geometry, humbuckerFillet)
- pickupMiddleFillet2 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[1], pickupMiddle1[1].endSketchPoint.geometry, pickupMiddle1[2], pickupMiddle1[2].startSketchPoint.geometry, humbuckerFillet)
- pickupMiddleFillet3 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[2], pickupMiddle1[2].endSketchPoint.geometry, pickupMiddle1[3], pickupMiddle1[3].startSketchPoint.geometry, humbuckerFillet)
- pickupMiddleFillet4 = sketch2.sketchCurves.sketchArcs.addFillet(pickupMiddle1[3], pickupMiddle1[3].endSketchPoint.geometry, pickupMiddle1[0], pickupMiddle1[0].startSketchPoint.geometry, humbuckerFillet)
- cavityMiddle1 = cavitymiddleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+pickupCavityMountTabWidth/2), (pickupCavityMountLength/2), 0))
- cavityMiddleFillet1 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[0], cavityMiddle1[0].endSketchPoint.geometry, cavityMiddle1[1], cavityMiddle1[1].startSketchPoint.geometry, humbuckerFillet/2)
- cavityMiddleFillet2 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[1], cavityMiddle1[1].endSketchPoint.geometry, cavityMiddle1[2], cavityMiddle1[2].startSketchPoint.geometry, humbuckerFillet/2)
- cavityMiddleFillet3 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[2], cavityMiddle1[2].endSketchPoint.geometry, cavityMiddle1[3], cavityMiddle1[3].startSketchPoint.geometry, humbuckerFillet/2)
- cavityMiddleFillet4 = sketch2.sketchCurves.sketchArcs.addFillet(cavityMiddle1[3], cavityMiddle1[3].endSketchPoint.geometry, cavityMiddle1[0], cavityMiddle1[0].startSketchPoint.geometry, humbuckerFillet/2)
- sketch2.name = 'Middle Pickup [Humbucker]'
- middlePickupType = 'H'
- else:
- pass
- #Create sketch for bridge spacing
- sketch3 = sketches.add(xzPlane)
- bridgeLines = sketch3.sketchCurves.sketchLines;
- cavitybridgeLines = sketch3.sketchCurves.sketchLines;
- # Get sketch points
- sketchPoints = sketch3.sketchPoints
- if createBlanks.value:
- sketch3.isComputeDeferred = False
- else:
- sketch3.isComputeDeferred = True
- sketch3.areConstraintsShown = True
- sketch3.arePointsShown = False
- if pickupBridge == "Single-Coil":
- # Create sketch lines
- pickupBridge1 = bridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2)+singleCoilWidth/2, (singleCoilLength/2), 0))
- pickupBridge2 = bridgeLines.addByTwoPoints(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), (pickupCavityMountLength/2), 0))
- pickupBridge2.isConstruction = True
- pickupBridgeAngle = bridgeLines.addByTwoPoints(adsk.core.Point3D.create(bridgeDistance, 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth), 0, 0))
- pickupBridgeAngle.isConstruction = True
- # Create sketch point
- point1 = adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0)
- sketchPoint1 = sketchPoints.add(point1)
- sketchPoint1.isFixed = True
- pickupBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[0], pickupBridge1[0].endSketchPoint.geometry, pickupBridge1[1], pickupBridge1[1].startSketchPoint.geometry, singleCoilWidth/2)
- pickupBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[1], pickupBridge1[1].endSketchPoint.geometry, pickupBridge1[2], pickupBridge1[2].startSketchPoint.geometry, singleCoilWidth/2)
- pickupBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[2], pickupBridge1[2].endSketchPoint.geometry, pickupBridge1[3], pickupBridge1[3].startSketchPoint.geometry, singleCoilWidth/2)
- pickupBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[3], pickupBridge1[3].endSketchPoint.geometry, pickupBridge1[0], pickupBridge1[0].startSketchPoint.geometry, singleCoilWidth/2)
- cavityBridge1 = cavitybridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2)+singleCoilWidth/2, (pickupCavityMountLength/2), 0))
- cavityBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[0], cavityBridge1[0].endSketchPoint.geometry, cavityBridge1[1], cavityBridge1[1].startSketchPoint.geometry, singleCoilWidth/2)
- cavityBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[1], cavityBridge1[1].endSketchPoint.geometry, cavityBridge1[2], cavityBridge1[2].startSketchPoint.geometry, singleCoilWidth/2)
- cavityBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[2], cavityBridge1[2].endSketchPoint.geometry, cavityBridge1[3], cavityBridge1[3].startSketchPoint.geometry, singleCoilWidth/2)
- cavityBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[3], cavityBridge1[3].endSketchPoint.geometry, cavityBridge1[0], cavityBridge1[0].startSketchPoint.geometry, singleCoilWidth/2)
- # Constrain the Rectangle to stay rectangular
- constraints = sketch3.geometricConstraints
- constraints.addMidPoint(sketchPoint1, bridgeLines.item(4))
- constraints.addMidPoint(sketchPoint1, bridgeLines.item(5))
- constraints.addMidPoint(bridgeLines.item(5).startSketchPoint, bridgeLines.item(3))
- constraints.addMidPoint(bridgeLines.item(5).endSketchPoint, bridgeLines.item(1))
- constraints.addMidPoint(bridgeLines.item(5).startSketchPoint, cavitybridgeLines.item(9))
- constraints.addMidPoint(bridgeLines.item(5).endSketchPoint, cavitybridgeLines.item(7))
- constraints.addPerpendicular(bridgeLines.item(5), bridgeLines.item(4))
- all = adsk.core.ObjectCollection.create()
- for curves in sketch3.sketchCurves:
- all.add(curves)
- for points in sketch3.sketchPoints:
- all.add(points)
- normal = sketch3.xDirection.crossProduct(sketch3.yDirection)
- normal.transformBy(sketch3.transform)
- origin = sketch3.origin
- origin.transformBy(sketch3.transform)
- matrix = adsk.core.Matrix3D.create()
- matrix.setToRotation(-bridgePickupAngle, normal, origin)
- sketch3.move(all, matrix)
- sketch3.name = 'Bridge Pickup [Single-Coil]'
- bridgePickupType = 'S'
- elif pickupBridge == "Humbucker":
- pickupBridge1 = bridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance), (humbuckerLength/2), 0))
- pickupBridge2 = bridgeLines.addByTwoPoints(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), (pickupCavityMountLength/2), 0))
- pickupBridge2.isConstruction = True
- pickupBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[0], pickupBridge1[0].endSketchPoint.geometry, pickupBridge1[1], pickupBridge1[1].startSketchPoint.geometry, humbuckerFillet)
- pickupBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[1], pickupBridge1[1].endSketchPoint.geometry, pickupBridge1[2], pickupBridge1[2].startSketchPoint.geometry, humbuckerFillet)
- pickupBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[2], pickupBridge1[2].endSketchPoint.geometry, pickupBridge1[3], pickupBridge1[3].startSketchPoint.geometry, humbuckerFillet)
- pickupBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[3], pickupBridge1[3].endSketchPoint.geometry, pickupBridge1[0], pickupBridge1[0].startSketchPoint.geometry, humbuckerFillet)
- cavityBridge1 = cavitybridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2)-pickupCavityMountTabWidth/2, (pickupCavityMountLength/2), 0))
- cavityBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[0], cavityBridge1[0].endSketchPoint.geometry, cavityBridge1[1], cavityBridge1[1].startSketchPoint.geometry, humbuckerFillet/2)
- cavityBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[1], cavityBridge1[1].endSketchPoint.geometry, cavityBridge1[2], cavityBridge1[2].startSketchPoint.geometry, humbuckerFillet/2)
- cavityBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[2], cavityBridge1[2].endSketchPoint.geometry, cavityBridge1[3], cavityBridge1[3].startSketchPoint.geometry, humbuckerFillet/2)
- cavityBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[3], cavityBridge1[3].endSketchPoint.geometry, cavityBridge1[0], cavityBridge1[0].startSketchPoint.geometry, humbuckerFillet/2)
- sketch3.name = 'Bridge Pickup [Humbucker]'
- bridgePickupType = 'H'
- else:
- pass
- if createBlanks.value:
- #Get extrude features
- extrudes = pickupsComp.features.extrudeFeatures
- # Get the profiles of the pickups
- if pickupNeck == "Single-Coil":
- #Create an object collection to use an input.
- neckProfs = adsk.core.ObjectCollection.create()
- for prof in sketch1.profiles:
- neckProfs.add(prof)
- elif pickupNeck == "Humbucker":
- #Create an object collection to use an input.
- neckProfs = adsk.core.ObjectCollection.create()
- for prof in sketch1.profiles:
- neckProfs.add(prof)
- else:
- pass
- if pickupMiddle == "Single-Coil":
- #Create an object collection to use an input.
- middleProfs = adsk.core.ObjectCollection.create()
- for prof in sketch2.profiles:
- middleProfs.add(prof)
- elif pickupMiddle == "Humbucker":
- #Create an object collection to use an input.
- middleProfs = adsk.core.ObjectCollection.create()
- for prof in sketch2.profiles:
- middleProfs.add(prof)
- else:
- pass
- if pickupBridge == "Single-Coil":
- #Create an object collection to use an input.
- bridgeProfs = adsk.core.ObjectCollection.create()
- for prof in sketch3.profiles:
- bridgeProfs.add(prof)
- elif pickupBridge == "Humbucker":
- #Create an object collection to use an input.
- bridgeProfs = adsk.core.ObjectCollection.create()
- for prof in sketch3.profiles:
- bridgeProfs.add(prof)
- else:
- pass
- if pickupNeck == "Single-Coil":
- neckExtrude = extrudes.addSimple(neckProfs, adsk.core.ValueInput.createByReal(-singleCoilDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
- # Get the extrusion body
- neckPickupBody = neckExtrude.bodies.item(0)
- neckExtrude.name = "Extrusion: Neck Pickup [Single-Coil]"
- # bneckPickupBody.name = "Neck Pickup [Single-Coil]"
- elif pickupNeck == "Humbucker":
- neckExtrude = extrudes.addSimple(neckProfs, adsk.core.ValueInput.createByReal(-humbuckerDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
- # Get the extrusion body
- neckPickupBody = neckExtrude.bodies.item(0)
- neckExtrude.name = "Extrusion: Neck Pickup [Humbucker]"
- # bneckPickupBody.name = "Neck Pickup [Humbucker]"
- else:
- pass
- if pickupMiddle == "Single-Coil":
- middleExtrude = extrudes.addSimple(middleProfs, adsk.core.ValueInput.createByReal(-singleCoilDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
- # Get the extrusion body
- middlePickupBody = middleExtrude.bodies.item(0)
- middleExtrude.name = "Extrusion: Middle Pickup [Single-Coil]"
- # bmiddlePickupBody.name = "Middle Pickup [Single-Coil]"
- elif pickupMiddle == "Humbucker":
- middleExtrude = extrudes.addSimple(middleProfs, adsk.core.ValueInput.createByReal(-humbuckerDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
- # Get the extrusion body
- middlePickupBody = middleExtrude.bodies.item(0)
- middleExtrude.name = "Extrusion: Middle Pickup [Humbucker]"
- # bmiddlePickupBody.name = "Middle Pickup [Humbucker]"
- else:
- pass
- if pickupBridge == "Single-Coil":
- bridgeExtrude = extrudes.addSimple(bridgeProfs, adsk.core.ValueInput.createByReal(-singleCoilDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
- # Get the extrusion body
- bridgePickupBody = bridgeExtrude.bodies.item(0)
- bridgeExtrude.name = "Extrusion: Bridge Pickup [Single-Coil]"
- # bbridgePickupBody.name = "Bridge Pickup [Single-Coil]"
- elif pickupBridge == "Humbucker":
- bridgeExtrude = extrudes.addSimple(bridgeProfs, adsk.core.ValueInput.createByReal(-humbuckerDepth), adsk.fusion.FeatureOperations.CutFeatureOperation)
- # Get the extrusion body
- bridgePickupBody = bridgeExtrude.bodies.item(0)
- bridgeExtrude.name = "Extrusion: Bridge Pickup [Humbucker]"
- # bridgePickupBody.name = "Bridge Pickup [Humbucker]"
- else:
- pass
- else:
- pass
- #Centers the camera to fit the entire fretboard
- cam = app.activeViewport.camera
- cam.isFitView = True
- cam.isSmoothTransition = False
- app.activeViewport.camera = cam
- # Group everything used to create the fretboard in the timeline.
- timelineGroupspickups = design.timeline.timelineGroups
- pickupsOccIndex = pickupsOcc.timelineObject.index
- if createBlanks.value:
- pickupsEndIndex = bridgeExtrude.timelineObject.index
- else:
- pickupsEndIndex = sketch3.timelineObject.index
- timelineGroupPickups = timelineGroupspickups.add(pickupsOccIndex, pickupsEndIndex)
- timelineGroupPickups.name = 'Pickups [' + bridgePickupType + middlePickupType + neckPickupType + ']'
- pickupsComp.name = 'Pickups [' + bridgePickupType + middlePickupType + neckPickupType + ']'
- return pickupsComp
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
-
-def guitarDimensions(design, fretNumber, scaleLength, nutLength, endLength, nutRadius, endRadius, fretboardHeight, filletRadius, endCurve, tangWidth, bridgeStringSpacing, tangDepth,
- nutSlotWidth, nutSlotDepth, markerDiameter, markerDepth, markerSpacing, guitarLength, bodyWidth, headstockLength, bodyLength, stringCount, nutToPost,
- machinePostHoleSpacing, machinePostHoleDiameter, machinePostDiameter, nutStringSpacing, fretboardLength, headstockStyle, neckSpacing, bridgeSpacing,
- singleCoilLength, singleCoilWidth, singleCoilDepth, humbuckerLength, humbuckerWidth, humbuckerDepth, humbuckerFillet, pickupNeck, pickupMiddle,
- pickupBridge, pickupCavityMountLength, pickupCavityMountTabWidth, bridgePickupAngle):
- try:
- design = adsk.fusion.Design.cast(app.activeProduct)
- rootComp = design.rootComponent
- allOccs2 = rootComp.occurrences
- newOcc2 = allOccs2.addNewComponent(adsk.core.Matrix3D.create())
- dimsComp = adsk.fusion.Component.cast(newOcc2.component)
- #Equation for fret spacing
- for fretNum in range(1,int((fretNumber))+1):
- fretDistance = (scaleLength)-((scaleLength)/(2**(fretNum/12.0)))
- #This calculates and rounds the total length of the fretboard using the scale length and number of frets
- L = fretboardLength
- stringInset = (nutLength - nutStringSpacing)/2
- nutDistance = guitarLength - headstockLength
- width = (nutLength-(stringInset*2)) + (2*sqrt(((L/(math.cos(math.radians(math.acos((scaleLength**2+(sqrt((((bridgeStringSpacing-(nutLength-(stringInset*2)))/2)**2)+(scaleLength**2)))**2-
- ((bridgeStringSpacing-(nutLength-(stringInset*2)))/2)**2)/(2*scaleLength*(sqrt((((bridgeStringSpacing-(nutLength-(stringInset*2)))/2)**2)+(scaleLength**2)))))*((180)/math.pi)))))**2)
- -(L**2)))
- # Create a new sketch.
- sketches = dimsComp.sketches
- yzPlane = dimsComp.yZConstructionPlane
- xzPlane = dimsComp.xYConstructionPlane
- xyPlane = dimsComp.xYConstructionPlane
- #Create construction lines
- sketch1 = sketches.add(xzPlane)
- sketch1.isComputeDeferred = True
- lines = sketch1.sketchCurves.sketchLines;
- sketch1.name = 'Boundary Dimensions'
- sketch1.isVisible = True
- sketch1.areDimensionsShown = True
- sketch1.areConstraintsShown = False
- sketch1.arePointsShown = False
- sketch1.areProfilesShown = False
- centerLine = lines.addByTwoPoints(adsk.core.Point3D.create(0, 0, 0), adsk.core.Point3D.create(guitarLength, 0, 0))
- centerLine.isConstruction = True
- centerLine.isFixed = True
- originBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(0, bodyWidth/2, 0), adsk.core.Point3D.create(0, -bodyWidth/2, 0))
- originBoundary.isConstruction = True
- endBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(guitarLength, bodyWidth/2, 0), adsk.core.Point3D.create(guitarLength, -bodyWidth/2, 0))
- endBoundary.isConstruction = True
- topBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(0, bodyWidth/2, 0), adsk.core.Point3D.create(guitarLength, bodyWidth/2, 0))
- topBoundary.isConstruction = True
- bottomBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(0, -bodyWidth/2, 0), adsk.core.Point3D.create(guitarLength, -bodyWidth/2, 0))
- bottomBoundary.isConstruction = True
- bodyBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(bodyLength, bodyWidth/2, 0), adsk.core.Point3D.create(bodyLength, -bodyWidth/2, 0))
- bodyBoundary.isConstruction = True
- nutBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(nutDistance, bodyWidth/4, 0), adsk.core.Point3D.create(nutDistance, -bodyWidth/4, 0))
- nutBoundary.isConstruction = True
- bridgeBoundary = lines.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength, bodyWidth/4, 0), adsk.core.Point3D.create(nutDistance-scaleLength, -bodyWidth/4, 0))
- bridgeBoundary.isConstruction = True
- fret12Boundary = lines.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength/2, bodyWidth/4, 0), adsk.core.Point3D.create(nutDistance-scaleLength/2, -bodyWidth/4, 0))
- fret12Boundary.isConstruction = True
- #Create dimension lines
- sketch1.areDimensionsShown = True
- sketch1.sketchDimensions.addDistanceDimension(topBoundary.startSketchPoint, topBoundary.endSketchPoint,
- adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
- adsk.core.Point3D.create((topBoundary.length/2), bodyWidth/2+4, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(originBoundary.startSketchPoint, originBoundary.endSketchPoint,
- adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
- adsk.core.Point3D.create(-4, 0, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(bridgeBoundary.startSketchPoint, fret12Boundary.startSketchPoint,
- adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
- adsk.core.Point3D.create((nutDistance-scaleLength+scaleLength/4), bodyWidth/4+2, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(fret12Boundary.startSketchPoint, nutBoundary.startSketchPoint,
- adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
- adsk.core.Point3D.create((nutDistance-scaleLength/4), bodyWidth/4+2, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(topBoundary.startSketchPoint, bodyBoundary.startSketchPoint,
- adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
- adsk.core.Point3D.create((bodyLength/2), bodyWidth/2+2, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(bodyBoundary.startSketchPoint, topBoundary.endSketchPoint,
- adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
- adsk.core.Point3D.create(((guitarLength+bodyLength)/2), bodyWidth/2+2, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(topBoundary.startSketchPoint, centerLine.startSketchPoint,
- adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
- adsk.core.Point3D.create(-2, bodyWidth/4, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(centerLine.startSketchPoint, bottomBoundary.startSketchPoint,
- adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
- adsk.core.Point3D.create(-2, -bodyWidth/4, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(centerLine.startSketchPoint, bridgeBoundary.startSketchPoint,
- adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
- adsk.core.Point3D.create(((guitarLength-headstockLength-scaleLength)/2), bodyWidth/4+2, 0), False);
- sketch1.sketchDimensions.addDistanceDimension(nutBoundary.startSketchPoint, centerLine.endSketchPoint,
- adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
- adsk.core.Point3D.create((guitarLength-headstockLength/2), bodyWidth/4+2, 0), False);
- sketch2 = sketches.add(xzPlane)
- sketch2.isComputeDeferred = True
- dimensionFrets = sketch2.sketchCurves.sketchLines;
- dimensionFrets2 = sketch2.sketchCurves.sketchLines;
- dimensionCircles = sketch2.sketchCurves.sketchCircles;
- dimensionCircles2 = sketch2.sketchCurves.sketchCircles;
- dimensionLines = sketch2.sketchCurves.sketchLines;
- humbuckerCavitySketch = sketch2.sketchCurves.sketchLines;
- sketch2.name = 'Core Dimensions'
- sketch2.isVisible = True
- sketch2.areDimensionsShown = True
- sketch2.areConstraintsShown = False
- sketch2.arePointsShown = False
- sketch2.areProfilesShown = False
- for fret in range(int(fretNumber)+1):
- fretDistance = scaleLength-(scaleLength/(2**(fret/12.0)))
- fretLength = nutLength + 2*sqrt(((fretDistance/(math.cos(math.radians(math.acos((L**2+(sqrt((((endLength-nutLength)/2)**2) +(L**2)))**2-
- ((endLength-nutLength)/2)**2)/(2*L*(sqrt((((endLength-nutLength)/2)**2)+(L**2)))))*((180)/math.pi)))))**2)
- -(fretDistance**2))
- dimensioning = dimensionFrets.addByTwoPoints(adsk.core.Point3D.create((nutDistance-fretDistance), (fretLength/2), 0),
- adsk.core.Point3D.create((nutDistance-fretDistance), (-fretLength/2), 0))
- dimensioning.isConstruction = True
- dimensioning2 = dimensionFrets2.addByTwoPoints(adsk.core.Point3D.create(nutDistance-L, (endLength/2), 0), adsk.core.Point3D.create(nutDistance-L, (-endLength/2), 0))
- dimensioning2.isConstruction = True
- bridgeLine2 = dimensionFrets2.addByTwoPoints(adsk.core.Point3D.create(nutDistance-scaleLength, (bridgeStringSpacing/2), 0), adsk.core.Point3D.create(nutDistance-scaleLength, (-bridgeStringSpacing/2), 0))
- bridgeLine2.isConstruction = True
- for dime in range(int(fretNumber)):
- sketchDime1 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets[0+dime].startSketchPoint, dimensionFrets[1+dime].startSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((nutDistance-scaleLength-(scaleLength/(-2**((dime+0.5)/12.0)))), 5, 0), False);
- for dime in range(1, int(fretNumber)+1):
- sketchDime1 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets[0].endSketchPoint, dimensionFrets[0+dime].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((nutDistance-scaleLength-(scaleLength/(-2**((dime-0.5)/12.0)))), -5-(dime/4), 0), False);
- sketchDime2 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets[0].startSketchPoint,
- dimensionFrets[0].endSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(nutDistance+2, 0, 0), False);
- sketchDime3 = sketch2.sketchDimensions.addDistanceDimension(dimensioning2.startSketchPoint,
- dimensioning2.endSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(nutDistance-L-1, 0, 0), False);
- sketchDime4 = sketch2.sketchDimensions.addDistanceDimension(dimensioning2.endSketchPoint,
- dimensionFrets[0].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance-L/2, -12, 0), False);
- sketchDime5 = sketch2.sketchDimensions.addDistanceDimension(bridgeLine2.startSketchPoint,
- dimensionFrets[0].startSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance-scaleLength/2, 8, 0), False);
- sketchDime6 = sketch2.sketchDimensions.addDistanceDimension(bridgeLine2.startSketchPoint,
- bridgeLine2.endSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(nutDistance-scaleLength-1, 0, 0), False);
- if headstockStyle == 'Straight In-line':
- #Create sketch for bridge spacing
- for spacing in range(int(stringCount)):
- holeSpacingVert = (nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/(int(stringCount)-1))*spacing
- holeSpacingHor = spacing*machinePostHoleSpacing
- machinePosts = dimensionCircles.addByTwoPoints(adsk.core.Point3D.create(nutDistance+nutToPost+holeSpacingHor, holeSpacingVert, 0), adsk.core.Point3D.create(nutDistance+nutToPost+holeSpacingHor, holeSpacingVert+(machinePostDiameter), 0))
- machinePosts.isConstruction = True
- for dime in range(int(stringCount)-1):
- sketchDime7 = sketch2.sketchDimensions.addDistanceDimension(dimensionCircles[0+dime].centerSketchPoint, dimensionCircles[1+dime].centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation,
- adsk.core.Point3D.create((nutDistance+nutToPost+machinePostHoleSpacing*dime)+machinePostHoleSpacing/2, 4, 0), False);
- sketchDime8 = sketch2.sketchDimensions.addDistanceDimension(dimensionCircles[0+dime].centerSketchPoint, dimensionCircles[1+dime].centerSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation,
- adsk.core.Point3D.create(guitarLength+2, (nutLength-stringInset*2)/2 - ((nutLength-stringInset*2)/(int(stringCount)-1))*dime, 0), False);
- sketchDime9 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets.item(0).startSketchPoint, dimensionCircles.item(0).centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance+nutToPost/2, 4, 0), False);
- else:
- pass
- machinePosts = sketch2.sketchCurves.sketchCircles;
- machinePostHole1 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostDiameter/2)
- machinePostHole1.isConstruction = True
- machinePostHole2 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostDiameter/2)
- machinePostHole2.isConstruction = True
- machinePostHole3 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, (nutStringSpacing/2)+(machinePostDiameter/2), 0), machinePostDiameter/2)
- machinePostHole3.isConstruction = True
- machinePostHole4 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*2, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostDiameter/2)
- machinePostHole4.isConstruction = True
- machinePostHole5 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostDiameter/2)
- machinePostHole5.isConstruction = True
- machinePostHole6 = machinePosts.addByCenterRadius(adsk.core.Point3D.create(nutDistance+nutToPost, (-nutStringSpacing/2)-(machinePostDiameter/2), 0), machinePostDiameter/2)
- machinePostHole6.isConstruction = True
- sketchDime10 = sketch2.sketchDimensions.addDistanceDimension(dimensionFrets.item(0).startSketchPoint, machinePostHole1.centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance+nutToPost/2, 4, 0), False);
- sketchDime11 = sketch2.sketchDimensions.addDistanceDimension(machinePostHole1.centerSketchPoint, machinePostHole2.centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing/2, 4, 0), False);
- sketchDime12 = sketch2.sketchDimensions.addDistanceDimension(machinePostHole2.centerSketchPoint, machinePostHole3.centerSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(nutDistance+nutToPost+machinePostHoleSpacing*1.5, 4, 0), False);
- sketchDime13 = sketch2.sketchDimensions.addDistanceDimension(machinePostHole3.centerSketchPoint, machinePostHole4.centerSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(nutDistance+machinePostHoleSpacing*3+2, 0, 0), False);
- ### PICKUPS
- sketch3 = sketches.add(xzPlane)
- sketch3.isComputeDeferred = True
- sketch3.name = 'Pickup Dimensions'
- sketch3.isVisible = True
- sketch3.areDimensionsShown = True
- sketch3.areConstraintsShown = False
- sketch3.arePointsShown = False
- sketch3.areProfilesShown = False
- neckDistance = guitarLength - headstockLength - fretboardLength - neckSpacing
- bridgeDistance = guitarLength - headstockLength - scaleLength + bridgeSpacing
- middleDistance = bridgeDistance + (neckDistance - bridgeDistance)/2
- neckLines = sketch3.sketchCurves.sketchLines;
- cavityNeckLines = sketch3.sketchCurves.sketchLines;
- if pickupNeck == "Single-Coil":
- # Create sketch lines
- pickupNeck1 = neckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2)+singleCoilWidth/2, (singleCoilLength/2), 0))
- pickupNeck1[0].isConstruction = True
- pickupNeck1[1].isConstruction = True
- pickupNeck1[2].isConstruction = True
- pickupNeck1[3].isConstruction = True
- pickupNeck2 = neckLines.addByTwoPoints(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), (pickupCavityMountLength/2), 0))
- pickupNeck2.isConstruction = True
- pickupNeckFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[0], pickupNeck1[0].endSketchPoint.geometry, pickupNeck1[1], pickupNeck1[1].startSketchPoint.geometry, singleCoilWidth/2)
- pickupNeckFillet1.isConstruction = True
- pickupNeckFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[1], pickupNeck1[1].endSketchPoint.geometry, pickupNeck1[2], pickupNeck1[2].startSketchPoint.geometry, singleCoilWidth/2)
- pickupNeckFillet2.isConstruction = True
- pickupNeckFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[2], pickupNeck1[2].endSketchPoint.geometry, pickupNeck1[3], pickupNeck1[3].startSketchPoint.geometry, singleCoilWidth/2)
- pickupNeckFillet3.isConstruction = True
- pickupNeckFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[3], pickupNeck1[3].endSketchPoint.geometry, pickupNeck1[0], pickupNeck1[0].startSketchPoint.geometry, singleCoilWidth/2)
- pickupNeckFillet4.isConstruction = True
- cavityNeck1 = cavityNeckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-singleCoilWidth/2)+singleCoilWidth/2, (pickupCavityMountLength/2), 0))
- cavityNeck1[0].isConstruction = True
- cavityNeck1[1].isConstruction = True
- cavityNeck1[2].isConstruction = True
- cavityNeck1[3].isConstruction = True
- cavityNeckFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[0], cavityNeck1[0].endSketchPoint.geometry, cavityNeck1[1], cavityNeck1[1].startSketchPoint.geometry, singleCoilWidth/2)
- cavityNeckFillet1.isConstruction = True
- cavityNeckFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[1], cavityNeck1[1].endSketchPoint.geometry, cavityNeck1[2], cavityNeck1[2].startSketchPoint.geometry, singleCoilWidth/2)
- cavityNeckFillet2.isConstruction = True
- cavityNeckFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[2], cavityNeck1[2].endSketchPoint.geometry, cavityNeck1[3], cavityNeck1[3].startSketchPoint.geometry, singleCoilWidth/2)
- cavityNeckFillet3.isConstruction = True
- cavityNeckFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[3], cavityNeck1[3].endSketchPoint.geometry, cavityNeck1[0], cavityNeck1[0].startSketchPoint.geometry, singleCoilWidth/2)
- cavityNeckFillet4.isConstruction = True
- elif pickupNeck == "Humbucker":
- pickupNeck1 = neckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2)+humbuckerWidth/2, (humbuckerLength/2), 0))
- pickupNeck1[0].isConstruction = True
- pickupNeck1[1].isConstruction = True
- pickupNeck1[2].isConstruction = True
- pickupNeck1[3].isConstruction = True
- pickupNeck2 = neckLines.addByTwoPoints(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), (pickupCavityMountLength/2), 0))
- pickupNeck2.isConstruction = True
- pickupNeckFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[0], pickupNeck1[0].endSketchPoint.geometry, pickupNeck1[1], pickupNeck1[1].startSketchPoint.geometry, humbuckerFillet)
- pickupNeckFillet1.isConstruction = True
- pickupNeckFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[1], pickupNeck1[1].endSketchPoint.geometry, pickupNeck1[2], pickupNeck1[2].startSketchPoint.geometry, humbuckerFillet)
- pickupNeckFillet2.isConstruction = True
- pickupNeckFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[2], pickupNeck1[2].endSketchPoint.geometry, pickupNeck1[3], pickupNeck1[3].startSketchPoint.geometry, humbuckerFillet)
- pickupNeckFillet3.isConstruction = True
- pickupNeckFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupNeck1[3], pickupNeck1[3].endSketchPoint.geometry, pickupNeck1[0], pickupNeck1[0].startSketchPoint.geometry, humbuckerFillet)
- pickupNeckFillet4.isConstruction = True
- cavityNeck1 = cavityNeckLines.addCenterPointRectangle(adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((neckDistance-humbuckerWidth/2)-pickupCavityMountTabWidth/2, (pickupCavityMountLength/2), 0))
- cavityNeck1[0].isConstruction = True
- cavityNeck1[1].isConstruction = True
- cavityNeck1[2].isConstruction = True
- cavityNeck1[3].isConstruction = True
- cavityNeckFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[0], cavityNeck1[0].endSketchPoint.geometry, cavityNeck1[1], cavityNeck1[1].startSketchPoint.geometry, humbuckerFillet/2)
- cavityNeckFillet1.isConstruction = True
- cavityNeckFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[1], cavityNeck1[1].endSketchPoint.geometry, cavityNeck1[2], cavityNeck1[2].startSketchPoint.geometry, humbuckerFillet/2)
- cavityNeckFillet2.isConstruction = True
- cavityNeckFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[2], cavityNeck1[2].endSketchPoint.geometry, cavityNeck1[3], cavityNeck1[3].startSketchPoint.geometry, humbuckerFillet/2)
- cavityNeckFillet3.isConstruction = True
- cavityNeckFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityNeck1[3], cavityNeck1[3].endSketchPoint.geometry, cavityNeck1[0], cavityNeck1[0].startSketchPoint.geometry, humbuckerFillet/2)
- cavityNeckFillet4.isConstruction = True
- else:
- pass
- middleLines = sketch3.sketchCurves.sketchLines;
- cavitymiddleLines = sketch3.sketchCurves.sketchLines;
- if pickupMiddle == "Single-Coil":
- # Create sketch lines
- pickupMiddle1 = middleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+singleCoilWidth/2), (singleCoilLength/2), 0))
- pickupMiddle1[0].isConstruction = True
- pickupMiddle1[1].isConstruction = True
- pickupMiddle1[2].isConstruction = True
- pickupMiddle1[3].isConstruction = True
- pickupMiddle2 = middleLines.addByTwoPoints(adsk.core.Point3D.create((middleDistance), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((middleDistance), (pickupCavityMountLength/2), 0))
- pickupMiddle2.isConstruction = True
- pickupMiddleFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[0], pickupMiddle1[0].endSketchPoint.geometry, pickupMiddle1[1], pickupMiddle1[1].startSketchPoint.geometry, singleCoilWidth/2)
- pickupMiddleFillet1.isConstruction = True
- pickupMiddleFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[1], pickupMiddle1[1].endSketchPoint.geometry, pickupMiddle1[2], pickupMiddle1[2].startSketchPoint.geometry, singleCoilWidth/2)
- pickupMiddleFillet2.isConstruction = True
- pickupMiddleFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[2], pickupMiddle1[2].endSketchPoint.geometry, pickupMiddle1[3], pickupMiddle1[3].startSketchPoint.geometry, singleCoilWidth/2)
- pickupMiddleFillet3.isConstruction = True
- pickupMiddleFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[3], pickupMiddle1[3].endSketchPoint.geometry, pickupMiddle1[0], pickupMiddle1[0].startSketchPoint.geometry, singleCoilWidth/2)
- pickupMiddleFillet4.isConstruction = True
- cavityMiddle1 = cavitymiddleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+singleCoilWidth/2), (pickupCavityMountLength/2), 0))
- cavityMiddle1[0].isConstruction = True
- cavityMiddle1[1].isConstruction = True
- cavityMiddle1[2].isConstruction = True
- cavityMiddle1[3].isConstruction = True
- cavityMiddleFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[0], cavityMiddle1[0].endSketchPoint.geometry, cavityMiddle1[1], cavityMiddle1[1].startSketchPoint.geometry, singleCoilWidth/2)
- cavityMiddleFillet1.isConstruction = True
- cavityMiddleFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[1], cavityMiddle1[1].endSketchPoint.geometry, cavityMiddle1[2], cavityMiddle1[2].startSketchPoint.geometry, singleCoilWidth/2)
- cavityMiddleFillet2.isConstruction = True
- cavityMiddleFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[2], cavityMiddle1[2].endSketchPoint.geometry, cavityMiddle1[3], cavityMiddle1[3].startSketchPoint.geometry, singleCoilWidth/2)
- cavityMiddleFillet3.isConstruction = True
- cavityMiddleFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[3], cavityMiddle1[3].endSketchPoint.geometry, cavityMiddle1[0], cavityMiddle1[0].startSketchPoint.geometry, singleCoilWidth/2)
- cavityMiddleFillet4.isConstruction = True
- elif pickupMiddle == "Humbucker":
- # Create sketch lines
- pickupMiddle1 = middleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+humbuckerWidth/2), (humbuckerLength/2), 0))
- pickupMiddle1[0].isConstruction = True
- pickupMiddle1[1].isConstruction = True
- pickupMiddle1[2].isConstruction = True
- pickupMiddle1[3].isConstruction = True
- pickupMiddle2 = middleLines.addByTwoPoints(adsk.core.Point3D.create((middleDistance), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((middleDistance), (pickupCavityMountLength/2), 0))
- pickupMiddle2.isConstruction = True
- pickupMiddleFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[0], pickupMiddle1[0].endSketchPoint.geometry, pickupMiddle1[1], pickupMiddle1[1].startSketchPoint.geometry, humbuckerFillet)
- pickupMiddleFillet1.isConstruction = True
- pickupMiddleFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[1], pickupMiddle1[1].endSketchPoint.geometry, pickupMiddle1[2], pickupMiddle1[2].startSketchPoint.geometry, humbuckerFillet)
- pickupMiddleFillet2.isConstruction = True
- pickupMiddleFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[2], pickupMiddle1[2].endSketchPoint.geometry, pickupMiddle1[3], pickupMiddle1[3].startSketchPoint.geometry, humbuckerFillet)
- pickupMiddleFillet3.isConstruction = True
- pickupMiddleFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupMiddle1[3], pickupMiddle1[3].endSketchPoint.geometry, pickupMiddle1[0], pickupMiddle1[0].startSketchPoint.geometry, humbuckerFillet)
- pickupMiddleFillet4.isConstruction = True
- cavityMiddle1 = cavitymiddleLines.addCenterPointRectangle(adsk.core.Point3D.create((middleDistance), 0, 0), adsk.core.Point3D.create((middleDistance+pickupCavityMountTabWidth/2), (pickupCavityMountLength/2), 0))
- cavityMiddle1[0].isConstruction = True
- cavityMiddle1[1].isConstruction = True
- cavityMiddle1[2].isConstruction = True
- cavityMiddle1[3].isConstruction = True
- cavityMiddleFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[0], cavityMiddle1[0].endSketchPoint.geometry, cavityMiddle1[1], cavityMiddle1[1].startSketchPoint.geometry, humbuckerFillet/2)
- cavityMiddleFillet1.isConstruction = True
- cavityMiddleFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[1], cavityMiddle1[1].endSketchPoint.geometry, cavityMiddle1[2], cavityMiddle1[2].startSketchPoint.geometry, humbuckerFillet/2)
- cavityMiddleFillet2.isConstruction = True
- cavityMiddleFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[2], cavityMiddle1[2].endSketchPoint.geometry, cavityMiddle1[3], cavityMiddle1[3].startSketchPoint.geometry, humbuckerFillet/2)
- cavityMiddleFillet3.isConstruction = True
- cavityMiddleFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityMiddle1[3], cavityMiddle1[3].endSketchPoint.geometry, cavityMiddle1[0], cavityMiddle1[0].startSketchPoint.geometry, humbuckerFillet/2)
- cavityMiddleFillet4.isConstruction = True
- else:
- pass
- bridgeLines = sketch3.sketchCurves.sketchLines;
- cavitybridgeLines = sketch3.sketchCurves.sketchLines;
- sketchPoints = sketch3.sketchPoints
- # Create sketch point
- if pickupBridge == "Single-Coil":
- point1 = adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0)
- elif pickupBridge == "Humbucker":
- point1 = adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0)
- else:
- pass
- sketchPoint1 = sketchPoints.add(point1)
- sketchPoint1.isFixed = True
- if pickupBridge == "Single-Coil":
- # Create sketch lines
- pickupBridge1 = bridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2)+singleCoilWidth/2, (singleCoilLength/2), 0))
- pickupBridge1[0].isConstruction = True
- pickupBridge1[1].isConstruction = True
- pickupBridge1[2].isConstruction = True
- pickupBridge1[3].isConstruction = True
- pickupBridge2 = bridgeLines.addByTwoPoints(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), (pickupCavityMountLength/2), 0))
- pickupBridge2.isConstruction = True
- pickupBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[0], pickupBridge1[0].endSketchPoint.geometry, pickupBridge1[1], pickupBridge1[1].startSketchPoint.geometry, singleCoilWidth/2)
- pickupBridgeFillet1.isConstruction = True
- pickupBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[1], pickupBridge1[1].endSketchPoint.geometry, pickupBridge1[2], pickupBridge1[2].startSketchPoint.geometry, singleCoilWidth/2)
- pickupBridgeFillet2.isConstruction = True
- pickupBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[2], pickupBridge1[2].endSketchPoint.geometry, pickupBridge1[3], pickupBridge1[3].startSketchPoint.geometry, singleCoilWidth/2)
- pickupBridgeFillet3.isConstruction = True
- pickupBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[3], pickupBridge1[3].endSketchPoint.geometry, pickupBridge1[0], pickupBridge1[0].startSketchPoint.geometry, singleCoilWidth/2)
- pickupBridgeFillet4.isConstruction = True
- cavityBridge1 = cavitybridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2)+singleCoilWidth/2, (pickupCavityMountLength/2), 0))
- cavityBridge1[0].isConstruction = True
- cavityBridge1[1].isConstruction = True
- cavityBridge1[2].isConstruction = True
- cavityBridge1[3].isConstruction = True
- cavityBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[0], cavityBridge1[0].endSketchPoint.geometry, cavityBridge1[1], cavityBridge1[1].startSketchPoint.geometry, singleCoilWidth/2)
- cavityBridgeFillet1.isConstruction = True
- cavityBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[1], cavityBridge1[1].endSketchPoint.geometry, cavityBridge1[2], cavityBridge1[2].startSketchPoint.geometry, singleCoilWidth/2)
- cavityBridgeFillet2.isConstruction = True
- cavityBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[2], cavityBridge1[2].endSketchPoint.geometry, cavityBridge1[3], cavityBridge1[3].startSketchPoint.geometry, singleCoilWidth/2)
- cavityBridgeFillet3.isConstruction = True
- cavityBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[3], cavityBridge1[3].endSketchPoint.geometry, cavityBridge1[0], cavityBridge1[0].startSketchPoint.geometry, singleCoilWidth/2)
- cavityBridgeFillet4.isConstruction = True
- pickupBridgeAngle = bridgeLines.addByTwoPoints(adsk.core.Point3D.create(bridgeDistance, 0, 0), adsk.core.Point3D.create((bridgeDistance+singleCoilWidth), 0, 0))
- pickupBridgeAngle.isConstruction = True
- # Constrain the Rectangle to stay rectangular
- constraints = sketch3.geometricConstraints
- constraints.addMidPoint(sketchPoint1, bridgeLines.item(22))
- constraints.addMidPoint(sketchPoint1, bridgeLines.item(27))
- constraints.addMidPoint(bridgeLines.item(27).startSketchPoint, bridgeLines.item(19))
- constraints.addMidPoint(bridgeLines.item(27).endSketchPoint, bridgeLines.item(21))
- constraints.addMidPoint(bridgeLines.item(27).startSketchPoint, cavitybridgeLines.item(24))
- constraints.addMidPoint(bridgeLines.item(27).endSketchPoint, cavitybridgeLines.item(26))
- constraints.addPerpendicular(bridgeLines.item(27), bridgeLines.item(22))
- # all = adsk.core.ObjectCollection.create()
- # for lines in range(bridgeLines[19:]):
- # all.add(lines)
- all = adsk.core.ObjectCollection.create()
- all.add(bridgeLines.item(19))
- all.add(bridgeLines.item(20))
- all.add(bridgeLines.item(21))
- all.add(bridgeLines.item(22))
- all.add(bridgeLines.item(23))
- all.add(bridgeLines.item(24))
- all.add(bridgeLines.item(25))
- all.add(bridgeLines.item(26))
- all.add(bridgeLines.item(27))
- all.add(sketchPoint1)
- normal = sketch3.xDirection.crossProduct(sketch3.yDirection)
- normal.transformBy(sketch3.transform)
- origin = sketch3.origin
- origin.transformBy(sketch3.transform)
- matrix = adsk.core.Matrix3D.create()
- matrix.setToRotation(-bridgePickupAngle, normal, origin)
- sketch3.move(all, matrix)
- elif pickupBridge == "Humbucker":
- pickupBridge1 = bridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance), (humbuckerLength/2), 0))
- pickupBridge1[0].isConstruction = True
- pickupBridge1[1].isConstruction = True
- pickupBridge1[2].isConstruction = True
- pickupBridge1[3].isConstruction = True
- pickupBridge2 = bridgeLines.addByTwoPoints(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), (-pickupCavityMountLength/2), 0), adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), (pickupCavityMountLength/2), 0))
- pickupBridge2.isConstruction = True
- pickupBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[0], pickupBridge1[0].endSketchPoint.geometry, pickupBridge1[1], pickupBridge1[1].startSketchPoint.geometry, humbuckerFillet)
- pickupBridgeFillet1.isConstruction = True
- pickupBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[1], pickupBridge1[1].endSketchPoint.geometry, pickupBridge1[2], pickupBridge1[2].startSketchPoint.geometry, humbuckerFillet)
- pickupBridgeFillet2.isConstruction = True
- pickupBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[2], pickupBridge1[2].endSketchPoint.geometry, pickupBridge1[3], pickupBridge1[3].startSketchPoint.geometry, humbuckerFillet)
- pickupBridgeFillet3.isConstruction = True
- pickupBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(pickupBridge1[3], pickupBridge1[3].endSketchPoint.geometry, pickupBridge1[0], pickupBridge1[0].startSketchPoint.geometry, humbuckerFillet)
- pickupBridgeFillet4.isConstruction = True
- cavityBridge1 = cavitybridgeLines.addCenterPointRectangle(adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), 0, 0), adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2)-pickupCavityMountTabWidth/2, (pickupCavityMountLength/2), 0))
- cavityBridge1[0].isConstruction = True
- cavityBridge1[1].isConstruction = True
- cavityBridge1[2].isConstruction = True
- cavityBridge1[3].isConstruction = True
- cavityBridgeFillet1 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[0], cavityBridge1[0].endSketchPoint.geometry, cavityBridge1[1], cavityBridge1[1].startSketchPoint.geometry, humbuckerFillet/2)
- cavityBridgeFillet1.isConstruction = True
- cavityBridgeFillet2 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[1], cavityBridge1[1].endSketchPoint.geometry, cavityBridge1[2], cavityBridge1[2].startSketchPoint.geometry, humbuckerFillet/2)
- cavityBridgeFillet2.isConstruction = True
- cavityBridgeFillet3 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[2], cavityBridge1[2].endSketchPoint.geometry, cavityBridge1[3], cavityBridge1[3].startSketchPoint.geometry, humbuckerFillet/2)
- cavityBridgeFillet3.isConstruction = True
- cavityBridgeFillet4 = sketch3.sketchCurves.sketchArcs.addFillet(cavityBridge1[3], cavityBridge1[3].endSketchPoint.geometry, cavityBridge1[0], cavityBridge1[0].startSketchPoint.geometry, humbuckerFillet/2)
- cavityBridgeFillet4.isConstruction = True
- else:
- pass
- if pickupNeck == "Single-Coil":
- pickupNeckDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck1[3].startSketchPoint, pickupNeck1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), -6, 0), False);
- pickupNeckDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityNeck1[3].startSketchPoint, cavityNeck1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((neckDistance-singleCoilWidth/2), -5, 0), False);
- elif pickupNeck == "Humbucker":
- pickupNeckDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck1[3].startSketchPoint, pickupNeck1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), -6, 0), False);
- pickupNeckDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityNeck1[3].startSketchPoint, cavityNeck1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((neckDistance-humbuckerWidth/2), -5, 0), False);
- else:
- pass
- if pickupMiddle == "Single-Coil":
- pickupMiddleDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupMiddle1[3].startSketchPoint, pickupMiddle1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((middleDistance), -6, 0), False);
- pickupMiddleDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityMiddle1[3].startSketchPoint, cavityMiddle1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((middleDistance), -5, 0), False);
- elif pickupMiddle == "Humbucker":
- pickupMiddleDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupMiddle1[3].startSketchPoint, pickupMiddle1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((middleDistance), -6, 0), False);
- pickupMiddleDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityMiddle1[3].startSketchPoint, cavityMiddle1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((middleDistance), -5, 0), False);
- else:
- pass
- if pickupBridge == "Single-Coil":
- pickupMiddleDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupBridge1[3].startSketchPoint, pickupBridge1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), -6, 0), False);
- pickupMiddleDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityBridge1[3].startSketchPoint, cavityBridge1[1].endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((bridgeDistance+singleCoilWidth/2), -5, 0), False);
- elif pickupBridge == "Humbucker":
- pickupMiddleDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupBridge1[3].startSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), -6, 0), False);
- pickupMiddleDims2 = sketch3.sketchDimensions.addDistanceDimension(cavityBridge1[3].startSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create((bridgeDistance+humbuckerWidth/2), -5, 0), False);
- else:
- pass
- if pickupMiddle == "None":
- pickupGapDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck2.endSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance + (neckDistance - bridgeDistance)/2, 7, 0), False);
- else:
- pickupGapDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck2.endSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance + (neckDistance - bridgeDistance)/2, 7, 0), False);
- pickupGapDims2 = sketch3.sketchDimensions.addDistanceDimension(pickupNeck2.endSketchPoint, pickupMiddle2.endSketchPoint, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(middleDistance + (neckDistance - middleDistance)/2, 6, 0), False);
- pickupGapDims2 = sketch3.sketchDimensions.addDistanceDimension(pickupMiddle2.endSketchPoint, sketchPoint1, adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance + (middleDistance - bridgeDistance)/2, 6, 0), False);
- pickupDims1 = sketch3.sketchDimensions.addDistanceDimension(pickupBridge1[0].startSketchPoint, pickupBridge1[2].endSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance - 4, 0, 0), False);
- pickupDims2 = sketch3.sketchDimensions.addDistanceDimension(pickupBridge2.endSketchPoint, pickupBridge2.startSketchPoint, adsk.fusion.DimensionOrientations.VerticalDimensionOrientation, adsk.core.Point3D.create(bridgeDistance - 5, 0, 0), False);
- #Centers the camera to fit the entire fretboard
- cam = app.activeViewport.camera
- cam.isFitView = True
- cam.isSmoothTransition = True
- cam.viewOrientation = adsk.core.ViewOrientations.TopViewOrientation
- app.activeViewport.camera = cam
- # Group everything used to create the fretboard in the timeline.
- timelineGroups2 = design.timeline.timelineGroups
- newOccIndex2 = newOcc2.timelineObject.index
- endIndex2 = sketch3.timelineObject.index
- timelineGroup2 = timelineGroups2.add(newOccIndex2, endIndex2)
- timelineGroup2.name = 'Dimensions'
- dimsComp.name = 'Dimensions'
- return dimsComp
- # except:
- # pass
- except:
- if ui:
- ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
\ No newline at end of file
diff --git a/Guitar Engine [Beta].manifest b/Guitar Engine.manifest
similarity index 100%
rename from Guitar Engine [Beta].manifest
rename to Guitar Engine.manifest
diff --git a/Guitar Engine.py b/Guitar Engine.py
new file mode 100644
index 0000000..5a8a012
--- /dev/null
+++ b/Guitar Engine.py
@@ -0,0 +1,239 @@
+#import system modules
+import os, sys
+import adsk.core, adsk.fusion, adsk.cam, traceback
+
+from .GuitarEngineUI import UIElements, UIManager
+from .ParameterValues import ParameterValues
+from .DesignParameters import DesignParameters
+from .Builders import FretboardBuilder, BodyBlankBuilder, StringsBuilder, DimensionsBuilder, PickupsBuilder
+
+handlers = []
+commandHandlers = []
+parameters: ParameterValues = None
+uiManager: UIManager
+
+def run(context):
+ try:
+ app = adsk.core.Application.get()
+ ui = app.userInterface
+ createPanel = ui.allToolbarPanels.itemById('SolidCreatePanel')
+
+ fretboardButton = createPanel.controls.itemById('adskFretboardPythonAddIn2')
+
+ if fretboardButton:
+ fretboardButton.deleteMe()
+
+ cmdDef = ui.commandDefinitions.itemById('adskFretboardPythonAddIn2')
+
+ if cmdDef:
+ cmdDef.deleteMe()
+
+ # Create a command definition and add a button to the CREATE panel.
+ cmdDef = ui.commandDefinitions.addButtonDefinition('adskFretboardPythonAddIn2', 'Guitar Engine', 'Creates a guitar component\n\n', 'Resources/Icons')
+ fretboardButton = createPanel.controls.addCommand(cmdDef)
+
+ # Connect to the command created event.
+ onCommandCreated = GuitarEngineClickCommandHandler()
+ cmdDef.commandCreated.add(onCommandCreated)
+ handlers.append(onCommandCreated)
+
+ # Make the button available in the panel.
+ fretboardButton.isPromotedByDefault = True
+ fretboardButton.isPromoted = True
+ if context['IsApplicationStartup'] == False:
+ ui.messageBox('Guitar Engine [has been added to the SOLID tab of the DESIGN workspace.')
+
+ except:
+ if ui:
+ ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
+
+def stop(context):
+ ui = None
+ try:
+ app = adsk.core.Application.get()
+ ui = app.userInterface
+
+ createPanel = ui.allToolbarPanels.itemById('SolidCreatePanel')
+ fretboardButton = createPanel.controls.itemById('adskFretboardPythonAddIn2')
+
+ if fretboardButton:
+ fretboardButton.deleteMe()
+
+ cmdDef = ui.commandDefinitions.itemById('adskFretboardPythonAddIn2')
+
+ if cmdDef:
+ cmdDef.deleteMe()
+
+ except:
+ if ui:
+ ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
+
+class GuitarEngineClickCommandHandler(adsk.core.CommandCreatedEventHandler):
+ def __init__(self):
+ super().__init__()
+ def notify(self, args):
+ try:
+
+ app = adsk.core.Application.get()
+ ui = app.userInterface
+ eventArgs = adsk.core.CommandCreatedEventArgs.cast(args)
+
+ # Verify that a Fusion design is active.
+ design = adsk.fusion.Design.cast(app.activeProduct)
+
+ if not design:
+ ui.messageBox('A Fusion design must be active when invoking this command.')
+ return()
+
+ cmd = eventArgs.command
+ cmd.isExecutedWhenPreEmpted = False
+
+ cmd.helpFile = 'help.html'
+ cmd.setDialogInitialSize(310, 800)
+ cmd.setDialogMinimumSize(310, 800)
+ cmd.okButtonText = 'Create Guitar'
+
+ global parameters
+
+ designParameters = DesignParameters(app)
+ designStoredParameters = designParameters.getStoredParameters()
+
+ if (designStoredParameters is not None):
+ parameters = designStoredParameters
+ else:
+ if (parameters is None):
+ parameters = ParameterValues()
+
+ defaultUnits = design.unitsManager.defaultLengthUnits
+
+ if defaultUnits == 'in' or defaultUnits == 'ft':
+ parameters.units = 'in'
+ else:
+ parameters.units = 'mm'
+
+ global uiManager
+
+ uiManager = UIManager(app, ui, parameters)
+
+ uiManager.createUIElements(cmd.commandInputs)
+
+ onInputChanged = GuitarEngineInputChangedCommandHandler()
+ cmd.inputChanged.add(onInputChanged)
+ commandHandlers.append(onInputChanged)
+
+ onExecute = GuitarEngineCommandExecuteHandler()
+ cmd.execute.add(onExecute)
+ commandHandlers.append(onExecute)
+
+ onDestroy = GuitarEngineDestroyHandler()
+ cmd.destroy.add(onDestroy)
+ commandHandlers.append(onDestroy)
+
+ except:
+ if ui:
+ ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
+
+class GuitarEngineCommandExecuteHandler(adsk.core.CommandEventHandler):
+ def __init__(self):
+ super().__init__()
+
+ def notify(self, args):
+ try:
+ eventArgs = adsk.core.CommandEventArgs.cast(args)
+ app = adsk.core.Application.get()
+ ui = app.userInterface
+
+ # Make sure the fretboard length value is correct as multiple undo/redo's can screw it up
+ uiManager.recalculateFretboardLength()
+
+ designParameters = DesignParameters(app)
+
+ designParameters.setAndStoreParameterValues(parameters)
+
+ fretboardBuilder = FretboardBuilder(app)
+
+ if parameters.generateOnlyFretboard:
+ fretboardBuilder.buildFretboard(parameters)
+ else:
+
+ stepsRequired = self.getStepsRequired()
+
+ progressDialog = ui.createProgressDialog()
+ progressDialog.isBackgroundTranslucent = False
+ progressDialog.isCancelButtonShown = False
+ progressDialog.show('Generating Guitar', 'Generation %p percent complete, completed %v of %m steps', 0, stepsRequired, 1)
+
+ stringsBuilder = StringsBuilder(app)
+ pickupsBuilder = PickupsBuilder(app)
+
+ fretboardBuilder.buildFretboard(parameters)
+ progressDialog.progressValue += 1
+
+ if parameters.generateBlanks:
+ bodyBlankBuilder = BodyBlankBuilder(app)
+ blanksComponent = bodyBlankBuilder.buildBodyBlank(parameters)
+ progressDialog.progressValue += 1
+
+ # Create the strings.
+ stringsComponent = stringsBuilder.buildStrings(parameters)
+ progressDialog.progressValue += 1
+
+ # Create the pickup cavities.
+ pickupsComponent = pickupsBuilder.buildPickups(parameters)
+ progressDialog.progressValue += 1
+
+ # Create dimension sketches
+ if parameters.generateDimensions:
+ dimensionsBuilder = DimensionsBuilder(app)
+ dimensionsComponent = dimensionsBuilder.buildDimensions(parameters)
+ progressDialog.progressValue += 1
+
+ progressDialog.hide()
+ except:
+ if ui:
+ ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
+
+ def getStepsRequired(self):
+ return 3 + (1 if parameters.generateBlanks else 0) + (1 if parameters.generateDimensions else 0)
+
+
+class GuitarEngineDestroyHandler(adsk.core.CommandEventHandler):
+ def __init__(self):
+ super().__init__()
+
+ def notify(self, args):
+ eventArgs = adsk.core.CommandEventArgs.cast(args)
+
+ commandHandlers.clear()
+ uiManager.resetControls()
+
+class GuitarEngineInputChangedCommandHandler(adsk.core.InputChangedEventHandler):
+ def __init__(self):
+ super().__init__()
+
+ def notify(self, args):
+ eventArgs = adsk.core.InputChangedEventArgs.cast(args)
+
+ # Check the value of the check box.
+ changedInput = eventArgs.input
+
+ if (changedInput.id == "fretboardStyle"):
+ uiManager.onFretboardStyleChanged()
+ elif (changedInput.id == "createFretCuts"):
+ uiManager.onCreateFretCutsChanged()
+ elif (changedInput.id == 'createFilletRadius'):
+ uiManager.onCreateFilletRadiusChanged()
+ elif (changedInput.id == 'createEndCurve'):
+ uiManager.onCreateEndCurveChanged()
+ elif (changedInput.id == 'createBlindFrets'):
+ uiManager.onCreateBlindFretsChanged()
+ elif (changedInput.id == 'createFretMarkers'):
+ uiManager.onCreateFretMarkersChanged()
+ elif (changedInput.id == 'pickupBridge'):
+ uiManager.onPickupBridgeChanged()
+ elif (changedInput.id == 'generateOnlyFretboard'):
+ uiManager.onGenerateOnlyFretboardChanged()
+ elif (changedInput.id == 'fretNumber' or changedInput.id == 'scaleLength'):
+ uiManager.recalculateFretboardLength()
+ else:
+ pass
\ No newline at end of file
diff --git a/GuitarEngineUI.py b/GuitarEngineUI.py
new file mode 100644
index 0000000..6e3d283
--- /dev/null
+++ b/GuitarEngineUI.py
@@ -0,0 +1,259 @@
+import adsk.core, adsk.fusion, adsk.cam, traceback, math
+from math import sqrt
+from .ParameterValues import ParameterValues
+from .UIElements import UIElements
+
+class UIManager:
+
+ def __init__(self, app, ui, parameters: ParameterValues):
+ self.app = app
+ self.ui = ui
+ self.parameters = parameters
+
+ def createUIElements(self, inputs: adsk.core.CommandInputs):
+
+ self.createTabs(inputs)
+ self.addGeneralControls()
+ self.addFretboardControls()
+ self.addHeadstockControls()
+ self.addPickupControls()
+ self.addInfoControls()
+ self.setInitialVisibility()
+
+ def createTabs(self, inputs: adsk.core.CommandInputs):
+ UIElements.tabGeneral = inputs.addTabCommandInput('general', 'General')
+ UIElements.tabFretboard = inputs.addTabCommandInput('fretboard', 'Fretboard')
+ UIElements.tabHeadstock = inputs.addTabCommandInput('headstock', 'Headstock')
+ UIElements.tabPickups = inputs.addTabCommandInput('pickups', 'Pickups')
+ UIElements.tabInfo = inputs.addTabCommandInput('info', 'Info')
+
+ def addFloatValueControl(self, name: str, description: str, tab: adsk.core.TabCommandInput):
+ UIElements.floatValueControls[name] = tab.addValueInput(name, description, self.parameters.units, adsk.core.ValueInput.createByReal(float(getattr(self.parameters, name))))
+
+ def addBoolValueControl(self, name: str, description: str, tab: adsk.core.TabCommandInput):
+ UIElements.boolValueControls[name] = tab.addBoolValueInput(name, description, True, '', bool(getattr(self.parameters, name)))
+
+ def addIntSpinnerControl(self, name: str, description: str, min: int, max: int, tab: adsk.core.TabCommandInput):
+ UIElements.intSpinnerControls[name] = tab.addIntegerSpinnerCommandInput(name, description, min, max, 1, int(getattr(self.parameters, name)))
+
+ def addFloatSpinnerControl(self, name: str, description: str, type: str, min: float, max: float, step: float, tab: adsk.core.TabCommandInput):
+ UIElements.floatSpinnerControls[name] = tab.addFloatSpinnerCommandInput(name, description, type, min, max, step, float(getattr(self.parameters, name)))
+
+ def addDropdownControl(self, name: str, description: str, tab: adsk.core.TabCommandInput):
+ newControl = tab.addDropDownCommandInput(name, description, adsk.core.DropDownStyles.TextListDropDownStyle)
+ UIElements.dropdownControls[name] = newControl
+ return newControl
+
+ def addGeneralControls(self):
+
+ tabInputs = UIElements.tabGeneral.children
+
+ imgInput = tabInputs.addImageCommandInput('fretboardImage', '', 'Resources/guitarEngine.png')
+
+ self.addIntSpinnerControl('stringCount', 'Number of Strings', 4, 12, tabInputs)
+ self.addIntSpinnerControl('fretNumber', 'Number of Frets', 12, 36, tabInputs)
+ self.addFloatValueControl('scaleLength', 'Scale Length', tabInputs)
+ self.addFloatValueControl('neckPocketLength', 'Neck Pocket Length', tabInputs)
+ self.addFloatValueControl('bodyLength', 'Body Length', tabInputs)
+ self.addFloatValueControl('bodyWidth', 'Body Width', tabInputs)
+ self.addFloatValueControl('bodyThickness', 'Body Thickness', tabInputs)
+ self.addFloatValueControl('neckThickness', 'Neck Thickness', tabInputs)
+ self.addFloatValueControl('firstFretThickness', 'First Fret Thickness', tabInputs)
+ self.addFloatValueControl('twelfthfretThickness', 'Twelfth Fret Thickness', tabInputs)
+
+ tabInputs.addTextBoxCommandInput('fullWidth_textBox', '', "
", 1, True)
+
+ self.addBoolValueControl('generateOnlyFretboard', 'Generate Fretboard Only?', tabInputs)
+ self.addBoolValueControl('generateBlanks', 'Generate Guitar Blanks?', tabInputs)
+ self.addBoolValueControl('generateDimensions', 'Generate Guitar Dimensions?', tabInputs)
+
+ def addFretboardControls(self):
+
+ tabInputs = UIElements.tabFretboard.children
+
+ fretboardStyle = self.addDropdownControl('fretboardStyle', 'Fretboard Style', tabInputs)
+ fretboardStyle.listItems.add('Straight Radius', (self.parameters.fretboardStyle == "Straight Radius"))
+ fretboardStyle.listItems.add('Compound Radius', (self.parameters.fretboardStyle == "Compound Radius"))
+ fretboardStyle.listItems.add('Flat/No Radius', (self.parameters.fretboardStyle == "Flat/No Radius"))
+
+ self.addFloatValueControl('radius', 'Radius', tabInputs)
+ self.addFloatValueControl('nutRadius', 'Nut Radius', tabInputs)
+ self.addFloatValueControl('endRadius', 'End Radius', tabInputs)
+
+ tabInputs.addTextBoxCommandInput('fullWidth_textBox', '', "
", 1, True)
+
+ #Fretboard length is calculated on change of fret number, we still want to show the value though.
+ self.addFloatValueControl('fretboardLength', 'Fretboard Length', tabInputs)
+ UIElements.floatValueControls['fretboardLength'].isEnabled = False
+
+ self.addFloatValueControl('fretboardLengthOffset', 'Fretboard Length Offset', tabInputs)
+ self.addFloatValueControl('fretboardHeight', 'Fretboard Height', tabInputs)
+ self.addFloatValueControl('bridgeStringSpacing', 'Bridge String Spacing', tabInputs)
+ self.addFloatValueControl('nutStringSpacing', 'Nut String Spacing', tabInputs)
+ self.addFloatValueControl('nutLength', 'Nut Length', tabInputs)
+ self.addFloatValueControl('endLength', 'End Length', tabInputs)
+ self.addFloatValueControl('nutSlotWidth', 'Nut Slot Width', tabInputs)
+ self.addFloatValueControl('nutSlotDepth', 'Nut Slot Depth', tabInputs)
+ self.addBoolValueControl('createFilletRadius', 'Create Fillet Radius?', tabInputs)
+ self.addFloatValueControl('filletRadius', 'Fillet Radius', tabInputs)
+ self.addBoolValueControl('createEndCurve', 'Create End Curve?', tabInputs)
+ self.addFloatValueControl('endCurve', 'End Curve', tabInputs)
+ self.addBoolValueControl('extensionVisible', 'Extension Visible?', tabInputs)
+
+ fretCutsGroup = tabInputs.addGroupCommandInput('fretCuts', 'Fret Cuts')
+ fretCutsGroup.isExpanded = True
+ fretCutsInputs = fretCutsGroup.children
+
+ self.addBoolValueControl('createFretCuts', 'Create Fret Cuts?', fretCutsInputs)
+ self.addFloatValueControl('tangWidth', 'Tang Width', fretCutsInputs)
+ self.addFloatValueControl('tangDepth', 'Tang Depth', fretCutsInputs)
+ self.addBoolValueControl('createBlindFrets', 'Create Blind Frets?', fretCutsInputs)
+ self.addFloatValueControl('blindFretInset', 'Blind Fret Inset', fretCutsInputs)
+
+ markerCutsGroup = tabInputs.addGroupCommandInput('markerCuts', 'Fret Marker Cuts')
+ markerCutsGroup.isExpanded = True
+ markerCutsInputs = markerCutsGroup.children
+
+ self.addBoolValueControl('createFretMarkers', 'Create Fret Markers?', markerCutsInputs)
+ self.addFloatValueControl('markerDiameter', 'Marker Diameter', markerCutsInputs)
+ self.addFloatValueControl('markerDepth', 'Marker Depth', markerCutsInputs)
+ self.addFloatValueControl('markerSpacing', 'Marker Spacing', markerCutsInputs)
+
+ def addHeadstockControls(self):
+
+ tabInputs = UIElements.tabHeadstock.children
+
+ headstockStyle = self.addDropdownControl('headstockStyle', 'Headstock Style', tabInputs)
+ headstockStyle.listItems.add('Straight In-line', (self.parameters.headstockStyle == "Straight In-line"))
+ headstockStyle.listItems.add('Symmetrical', (self.parameters.headstockStyle == "Symmetrical"))
+
+ tabInputs.addTextBoxCommandInput('fullWidth_textBox', '', 'Notice: Symmetrical only supports 6 strings.
', 1, True)
+
+ self.addFloatValueControl('headstockLength', 'Headstock Length', tabInputs)
+ self.addFloatValueControl('headstockWidth', 'Headstock Width', tabInputs)
+ self.addFloatValueControl('headstockThickness', 'Headstock Thickness', tabInputs)
+ self.addFloatValueControl('nutToPost', 'Nut To Post', tabInputs)
+ self.addFloatValueControl('machinePostHoleDiameter', 'Machine Post Hole Diameter', tabInputs)
+ self.addFloatValueControl('machinePostDiameter', 'Machine Post Diameter', tabInputs)
+ self.addFloatValueControl('machinePostHoleSpacing', 'Machine Post Hole Spacing', tabInputs)
+
+ def addPickupControls(self):
+
+ tabInputs = UIElements.tabPickups.children
+
+ pickupNeck = self.addDropdownControl('pickupNeck', 'Neck Pickup', tabInputs)
+ pickupNeck.listItems.add('Single-Coil', (self.parameters.pickupNeck == "Single-Coil"))
+ pickupNeck.listItems.add('Humbucker', (self.parameters.pickupNeck == "Humbucker"))
+ pickupNeck.listItems.add('None', (self.parameters.pickupNeck == "None"))
+
+ pickupMiddle = self.addDropdownControl('pickupMiddle', 'Middle Pickup', tabInputs)
+ pickupMiddle.listItems.add('Single-Coil', (self.parameters.pickupMiddle == "Single-Coil"))
+ pickupMiddle.listItems.add('Humbucker', (self.parameters.pickupMiddle == "Humbucker"))
+ pickupMiddle.listItems.add('None', (self.parameters.pickupMiddle == "None"))
+
+ pickupBridge = self.addDropdownControl('pickupBridge', 'Bridge Pickup', tabInputs)
+ pickupBridge.listItems.add('Single-Coil', (self.parameters.pickupBridge == "Single-Coil"))
+ pickupBridge.listItems.add('Humbucker', (self.parameters.pickupBridge == "Humbucker"))
+
+ self.addFloatSpinnerControl('bridgePickupAngle', 'Bridge Pickup Angle', 'deg', 0, 20, 1, tabInputs)
+ self.addFloatValueControl('neckSpacing', 'Neck Spacing', tabInputs)
+ self.addFloatValueControl('bridgeSpacing', 'Bridge Spacing', tabInputs)
+
+ singleCoilGroup = tabInputs.addGroupCommandInput('singleCoilGroup', 'Single-Coil')
+ singleCoilGroup.isExpanded = True
+ singleCoilGroupInputs = singleCoilGroup.children
+ self.addFloatValueControl('singleCoilLength', 'Single-Coil Length', singleCoilGroupInputs)
+ self.addFloatValueControl('singleCoilWidth', 'Single-Coil Width', singleCoilGroupInputs)
+ self.addFloatValueControl('singleCoilDepth', 'Single-Coil Depth', singleCoilGroupInputs)
+
+ humbuckerGroup = tabInputs.addGroupCommandInput('humbuckerGroup', 'Humbucker')
+ humbuckerGroup.isExpanded = True
+ humbuckerGroupInputs = humbuckerGroup.children
+
+ self.addFloatValueControl('humbuckerLength', 'Humbucker Length', humbuckerGroupInputs)
+ self.addFloatValueControl('humbuckerWidth', 'Humbucker Width', humbuckerGroupInputs)
+ self.addFloatValueControl('humbuckerDepth', 'Humbucker Depth', humbuckerGroupInputs)
+ self.addFloatValueControl('humbuckerFillet', 'Humbucker Corner Radius', humbuckerGroupInputs)
+ self.addFloatValueControl('pickupCavityMountLength', 'Length of pickup cavity', humbuckerGroupInputs)
+ self.addFloatValueControl('pickupCavityMountTabWidth', 'Width of pickup cavity rout', humbuckerGroupInputs)
+
+ def addInfoControls(self):
+ tabInputs = UIElements.tabInfo.children
+
+ message = ''
+ tabInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 10, True)
+
+ message = ''
+ tabInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 10, True)
+
+ message = ''
+ tabInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 3, True)
+
+ def setInitialVisibility(self):
+
+ self.onFretboardStyleChanged()
+ self.onCreateFretCutsChanged()
+ self.onCreateFilletRadiusChanged()
+ self.onCreateEndCurveChanged()
+ self.onCreateBlindFretsChanged()
+ self.onCreateFretMarkersChanged()
+ self.onPickupBridgeChanged()
+ self.onGenerateOnlyFretboardChanged()
+
+ def onFretboardStyleChanged(self):
+ UIElements.floatValueControls['radius'].isVisible = (UIElements.dropdownControls['fretboardStyle'].selectedItem.name == "Straight Radius")
+ UIElements.floatValueControls['nutRadius'].isVisible = (UIElements.dropdownControls['fretboardStyle'].selectedItem.name == "Compound Radius")
+ UIElements.floatValueControls['endRadius'].isVisible = (UIElements.dropdownControls['fretboardStyle'].selectedItem.name == "Compound Radius")
+
+ def onCreateFretCutsChanged(self):
+ UIElements.floatValueControls['tangWidth'].isEnabled = UIElements.boolValueControls['createFretCuts'].value
+ UIElements.floatValueControls['tangDepth'].isEnabled = UIElements.boolValueControls['createFretCuts'].value
+
+ def onCreateFilletRadiusChanged(self):
+ UIElements.floatValueControls['filletRadius'].isEnabled = UIElements.boolValueControls['createFilletRadius'].value
+
+ def onCreateEndCurveChanged(self):
+ UIElements.floatValueControls['endCurve'].isEnabled = UIElements.boolValueControls['createEndCurve'].value
+
+ def onCreateBlindFretsChanged(self):
+ UIElements.floatValueControls['blindFretInset'].isEnabled = UIElements.boolValueControls['createBlindFrets'].value
+
+ def onCreateFretMarkersChanged(self):
+ UIElements.floatValueControls['markerDiameter'].isEnabled = UIElements.boolValueControls['createFretMarkers'].value
+ UIElements.floatValueControls['markerDepth'].isEnabled = UIElements.boolValueControls['createFretMarkers'].value
+ UIElements.floatValueControls['markerSpacing'].isEnabled = UIElements.boolValueControls['createFretMarkers'].value
+
+ def onPickupBridgeChanged(self):
+ UIElements.floatSpinnerControls['bridgePickupAngle'].isVisible = (UIElements.dropdownControls['pickupBridge'].selectedItem.name == "Single-Coil")
+
+ def recalculateFretboardLength(self):
+
+ fretCount = UIElements.intSpinnerControls['fretNumber'].value + 1 #Leave a full frets worth of space at the end of the fretboard
+ scaleLength = UIElements.floatValueControls['scaleLength'].value
+
+ newFretboardLength = round(scaleLength - (scaleLength/(2**(fretCount/12))), 3)
+
+ UIElements.floatValueControls['fretboardLength'].value = newFretboardLength
+
+ def onGenerateOnlyFretboardChanged(self):
+ if UIElements.boolValueControls['generateOnlyFretboard'].value:
+ UIElements.boolValueControls['generateBlanks'].isEnabled = False
+ UIElements.boolValueControls['generateBlanks'].value = False
+ UIElements.boolValueControls['generateDimensions'].isEnabled = False
+ UIElements.boolValueControls['generateDimensions'].value = False
+ else:
+ UIElements.boolValueControls['generateBlanks'].isEnabled = True
+ UIElements.boolValueControls['generateDimensions'].isEnabled = True
+
+ def resetControls(self):
+ UIElements.tabGeneral = None
+ UIElements.tabFretboard = None
+ UIElements.tabHeadstock = None
+ UIElements.tabPickups = None
+ UIElements.tabInfo = None
+
+ UIElements.floatValueControls = {}
+ UIElements.boolValueControls = {}
+ UIElements.intSpinnerControls = {}
+ UIElements.floatSpinnerControls = {}
+ UIElements.dropdownControls = {}
\ No newline at end of file
diff --git a/Modules/simplejson/__init__.py b/Modules/simplejson/__init__.py
new file mode 100644
index 0000000..2e3b838
--- /dev/null
+++ b/Modules/simplejson/__init__.py
@@ -0,0 +1,584 @@
+r"""JSON (JavaScript Object Notation) is a subset of
+JavaScript syntax (ECMA-262 3rd edition) used as a lightweight data
+interchange format.
+
+:mod:`simplejson` exposes an API familiar to users of the standard library
+:mod:`marshal` and :mod:`pickle` modules. It is the externally maintained
+version of the :mod:`json` library contained in Python 2.6, but maintains
+compatibility back to Python 2.5 and (currently) has significant performance
+advantages, even without using the optional C extension for speedups.
+
+Encoding basic Python object hierarchies::
+
+ >>> import simplejson as json
+ >>> json.dumps(['foo', {'bar': ('baz', None, 1.0, 2)}])
+ '["foo", {"bar": ["baz", null, 1.0, 2]}]'
+ >>> print(json.dumps("\"foo\bar"))
+ "\"foo\bar"
+ >>> print(json.dumps(u'\u1234'))
+ "\u1234"
+ >>> print(json.dumps('\\'))
+ "\\"
+ >>> print(json.dumps({"c": 0, "b": 0, "a": 0}, sort_keys=True))
+ {"a": 0, "b": 0, "c": 0}
+ >>> from simplejson.compat import StringIO
+ >>> io = StringIO()
+ >>> json.dump(['streaming API'], io)
+ >>> io.getvalue()
+ '["streaming API"]'
+
+Compact encoding::
+
+ >>> import simplejson as json
+ >>> obj = [1,2,3,{'4': 5, '6': 7}]
+ >>> json.dumps(obj, separators=(',',':'), sort_keys=True)
+ '[1,2,3,{"4":5,"6":7}]'
+
+Pretty printing::
+
+ >>> import simplejson as json
+ >>> print(json.dumps({'4': 5, '6': 7}, sort_keys=True, indent=' '))
+ {
+ "4": 5,
+ "6": 7
+ }
+
+Decoding JSON::
+
+ >>> import simplejson as json
+ >>> obj = [u'foo', {u'bar': [u'baz', None, 1.0, 2]}]
+ >>> json.loads('["foo", {"bar":["baz", null, 1.0, 2]}]') == obj
+ True
+ >>> json.loads('"\\"foo\\bar"') == u'"foo\x08ar'
+ True
+ >>> from simplejson.compat import StringIO
+ >>> io = StringIO('["streaming API"]')
+ >>> json.load(io)[0] == 'streaming API'
+ True
+
+Specializing JSON object decoding::
+
+ >>> import simplejson as json
+ >>> def as_complex(dct):
+ ... if '__complex__' in dct:
+ ... return complex(dct['real'], dct['imag'])
+ ... return dct
+ ...
+ >>> json.loads('{"__complex__": true, "real": 1, "imag": 2}',
+ ... object_hook=as_complex)
+ (1+2j)
+ >>> from decimal import Decimal
+ >>> json.loads('1.1', parse_float=Decimal) == Decimal('1.1')
+ True
+
+Specializing JSON object encoding::
+
+ >>> import simplejson as json
+ >>> def encode_complex(obj):
+ ... if isinstance(obj, complex):
+ ... return [obj.real, obj.imag]
+ ... raise TypeError('Object of type %s is not JSON serializable' %
+ ... obj.__class__.__name__)
+ ...
+ >>> json.dumps(2 + 1j, default=encode_complex)
+ '[2.0, 1.0]'
+ >>> json.JSONEncoder(default=encode_complex).encode(2 + 1j)
+ '[2.0, 1.0]'
+ >>> ''.join(json.JSONEncoder(default=encode_complex).iterencode(2 + 1j))
+ '[2.0, 1.0]'
+
+Using simplejson.tool from the shell to validate and pretty-print::
+
+ $ echo '{"json":"obj"}' | python -m simplejson.tool
+ {
+ "json": "obj"
+ }
+ $ echo '{ 1.2:3.4}' | python -m simplejson.tool
+ Expecting property name: line 1 column 3 (char 2)
+
+Parsing multiple documents serialized as JSON lines (newline-delimited JSON)::
+
+ >>> import simplejson as json
+ >>> def loads_lines(docs):
+ ... for doc in docs.splitlines():
+ ... yield json.loads(doc)
+ ...
+ >>> sum(doc["count"] for doc in loads_lines('{"count":1}\n{"count":2}\n{"count":3}\n'))
+ 6
+
+Serializing multiple objects to JSON lines (newline-delimited JSON)::
+
+ >>> import simplejson as json
+ >>> def dumps_lines(objs):
+ ... for obj in objs:
+ ... yield json.dumps(obj, separators=(',',':')) + '\n'
+ ...
+ >>> ''.join(dumps_lines([{'count': 1}, {'count': 2}, {'count': 3}]))
+ '{"count":1}\n{"count":2}\n{"count":3}\n'
+
+"""
+from __future__ import absolute_import
+__version__ = '3.17.2'
+__all__ = [
+ 'dump', 'dumps', 'load', 'loads',
+ 'JSONDecoder', 'JSONDecodeError', 'JSONEncoder',
+ 'OrderedDict', 'simple_first', 'RawJSON'
+]
+
+__author__ = 'Bob Ippolito '
+
+from decimal import Decimal
+
+from .errors import JSONDecodeError
+from .raw_json import RawJSON
+from .decoder import JSONDecoder
+from .encoder import JSONEncoder, JSONEncoderForHTML
+def _import_OrderedDict():
+ import collections
+ try:
+ return collections.OrderedDict
+ except AttributeError:
+ from . import ordered_dict
+ return ordered_dict.OrderedDict
+OrderedDict = _import_OrderedDict()
+
+def _import_c_make_encoder():
+ try:
+ from ._speedups import make_encoder
+ return make_encoder
+ except ImportError:
+ return None
+
+_default_encoder = JSONEncoder(
+ skipkeys=False,
+ ensure_ascii=True,
+ check_circular=True,
+ allow_nan=True,
+ indent=None,
+ separators=None,
+ encoding='utf-8',
+ default=None,
+ use_decimal=True,
+ namedtuple_as_object=True,
+ tuple_as_array=True,
+ iterable_as_array=False,
+ bigint_as_string=False,
+ item_sort_key=None,
+ for_json=False,
+ ignore_nan=False,
+ int_as_string_bitcount=None,
+)
+
+def dump(obj, fp, skipkeys=False, ensure_ascii=True, check_circular=True,
+ allow_nan=True, cls=None, indent=None, separators=None,
+ encoding='utf-8', default=None, use_decimal=True,
+ namedtuple_as_object=True, tuple_as_array=True,
+ bigint_as_string=False, sort_keys=False, item_sort_key=None,
+ for_json=False, ignore_nan=False, int_as_string_bitcount=None,
+ iterable_as_array=False, **kw):
+ """Serialize ``obj`` as a JSON formatted stream to ``fp`` (a
+ ``.write()``-supporting file-like object).
+
+ If *skipkeys* is true then ``dict`` keys that are not basic types
+ (``str``, ``int``, ``long``, ``float``, ``bool``, ``None``)
+ will be skipped instead of raising a ``TypeError``.
+
+ If *ensure_ascii* is false (default: ``True``), then the output may
+ contain non-ASCII characters, so long as they do not need to be escaped
+ by JSON. When it is true, all non-ASCII characters are escaped.
+
+ If *allow_nan* is false, then it will be a ``ValueError`` to
+ serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``)
+ in strict compliance of the original JSON specification, instead of using
+ the JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``). See
+ *ignore_nan* for ECMA-262 compliant behavior.
+
+ If *indent* is a string, then JSON array elements and object members
+ will be pretty-printed with a newline followed by that string repeated
+ for each level of nesting. ``None`` (the default) selects the most compact
+ representation without any newlines.
+
+ If specified, *separators* should be an
+ ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')``
+ if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most
+ compact JSON representation, you should specify ``(',', ':')`` to eliminate
+ whitespace.
+
+ *encoding* is the character encoding for str instances, default is UTF-8.
+
+ *default(obj)* is a function that should return a serializable version
+ of obj or raise ``TypeError``. The default simply raises ``TypeError``.
+
+ If *use_decimal* is true (default: ``True``) then decimal.Decimal
+ will be natively serialized to JSON with full precision.
+
+ If *namedtuple_as_object* is true (default: ``True``),
+ :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
+ as JSON objects.
+
+ If *tuple_as_array* is true (default: ``True``),
+ :class:`tuple` (and subclasses) will be encoded as JSON arrays.
+
+ If *iterable_as_array* is true (default: ``False``),
+ any object not in the above table that implements ``__iter__()``
+ will be encoded as a JSON array.
+
+ If *bigint_as_string* is true (default: ``False``), ints 2**53 and higher
+ or lower than -2**53 will be encoded as strings. This is to avoid the
+ rounding that happens in Javascript otherwise. Note that this is still a
+ lossy operation that will not round-trip correctly and should be used
+ sparingly.
+
+ If *int_as_string_bitcount* is a positive number (n), then int of size
+ greater than or equal to 2**n or lower than or equal to -2**n will be
+ encoded as strings.
+
+ If specified, *item_sort_key* is a callable used to sort the items in
+ each dictionary. This is useful if you want to sort items other than
+ in alphabetical order by key. This option takes precedence over
+ *sort_keys*.
+
+ If *sort_keys* is true (default: ``False``), the output of dictionaries
+ will be sorted by item.
+
+ If *for_json* is true (default: ``False``), objects with a ``for_json()``
+ method will use the return value of that method for encoding as JSON
+ instead of the object.
+
+ If *ignore_nan* is true (default: ``False``), then out of range
+ :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as
+ ``null`` in compliance with the ECMA-262 specification. If true, this will
+ override *allow_nan*.
+
+ To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
+ ``.default()`` method to serialize additional types), specify it with
+ the ``cls`` kwarg. NOTE: You should use *default* or *for_json* instead
+ of subclassing whenever possible.
+
+ """
+ # cached encoder
+ if (not skipkeys and ensure_ascii and
+ check_circular and allow_nan and
+ cls is None and indent is None and separators is None and
+ encoding == 'utf-8' and default is None and use_decimal
+ and namedtuple_as_object and tuple_as_array and not iterable_as_array
+ and not bigint_as_string and not sort_keys
+ and not item_sort_key and not for_json
+ and not ignore_nan and int_as_string_bitcount is None
+ and not kw
+ ):
+ iterable = _default_encoder.iterencode(obj)
+ else:
+ if cls is None:
+ cls = JSONEncoder
+ iterable = cls(skipkeys=skipkeys, ensure_ascii=ensure_ascii,
+ check_circular=check_circular, allow_nan=allow_nan, indent=indent,
+ separators=separators, encoding=encoding,
+ default=default, use_decimal=use_decimal,
+ namedtuple_as_object=namedtuple_as_object,
+ tuple_as_array=tuple_as_array,
+ iterable_as_array=iterable_as_array,
+ bigint_as_string=bigint_as_string,
+ sort_keys=sort_keys,
+ item_sort_key=item_sort_key,
+ for_json=for_json,
+ ignore_nan=ignore_nan,
+ int_as_string_bitcount=int_as_string_bitcount,
+ **kw).iterencode(obj)
+ # could accelerate with writelines in some versions of Python, at
+ # a debuggability cost
+ for chunk in iterable:
+ fp.write(chunk)
+
+
+def dumps(obj, skipkeys=False, ensure_ascii=True, check_circular=True,
+ allow_nan=True, cls=None, indent=None, separators=None,
+ encoding='utf-8', default=None, use_decimal=True,
+ namedtuple_as_object=True, tuple_as_array=True,
+ bigint_as_string=False, sort_keys=False, item_sort_key=None,
+ for_json=False, ignore_nan=False, int_as_string_bitcount=None,
+ iterable_as_array=False, **kw):
+ """Serialize ``obj`` to a JSON formatted ``str``.
+
+ If ``skipkeys`` is false then ``dict`` keys that are not basic types
+ (``str``, ``int``, ``long``, ``float``, ``bool``, ``None``)
+ will be skipped instead of raising a ``TypeError``.
+
+ If *ensure_ascii* is false (default: ``True``), then the output may
+ contain non-ASCII characters, so long as they do not need to be escaped
+ by JSON. When it is true, all non-ASCII characters are escaped.
+
+ If ``check_circular`` is false, then the circular reference check
+ for container types will be skipped and a circular reference will
+ result in an ``OverflowError`` (or worse).
+
+ If ``allow_nan`` is false, then it will be a ``ValueError`` to
+ serialize out of range ``float`` values (``nan``, ``inf``, ``-inf``) in
+ strict compliance of the JSON specification, instead of using the
+ JavaScript equivalents (``NaN``, ``Infinity``, ``-Infinity``).
+
+ If ``indent`` is a string, then JSON array elements and object members
+ will be pretty-printed with a newline followed by that string repeated
+ for each level of nesting. ``None`` (the default) selects the most compact
+ representation without any newlines. For backwards compatibility with
+ versions of simplejson earlier than 2.1.0, an integer is also accepted
+ and is converted to a string with that many spaces.
+
+ If specified, ``separators`` should be an
+ ``(item_separator, key_separator)`` tuple. The default is ``(', ', ': ')``
+ if *indent* is ``None`` and ``(',', ': ')`` otherwise. To get the most
+ compact JSON representation, you should specify ``(',', ':')`` to eliminate
+ whitespace.
+
+ ``encoding`` is the character encoding for bytes instances, default is
+ UTF-8.
+
+ ``default(obj)`` is a function that should return a serializable version
+ of obj or raise TypeError. The default simply raises TypeError.
+
+ If *use_decimal* is true (default: ``True``) then decimal.Decimal
+ will be natively serialized to JSON with full precision.
+
+ If *namedtuple_as_object* is true (default: ``True``),
+ :class:`tuple` subclasses with ``_asdict()`` methods will be encoded
+ as JSON objects.
+
+ If *tuple_as_array* is true (default: ``True``),
+ :class:`tuple` (and subclasses) will be encoded as JSON arrays.
+
+ If *iterable_as_array* is true (default: ``False``),
+ any object not in the above table that implements ``__iter__()``
+ will be encoded as a JSON array.
+
+ If *bigint_as_string* is true (not the default), ints 2**53 and higher
+ or lower than -2**53 will be encoded as strings. This is to avoid the
+ rounding that happens in Javascript otherwise.
+
+ If *int_as_string_bitcount* is a positive number (n), then int of size
+ greater than or equal to 2**n or lower than or equal to -2**n will be
+ encoded as strings.
+
+ If specified, *item_sort_key* is a callable used to sort the items in
+ each dictionary. This is useful if you want to sort items other than
+ in alphabetical order by key. This option takes precendence over
+ *sort_keys*.
+
+ If *sort_keys* is true (default: ``False``), the output of dictionaries
+ will be sorted by item.
+
+ If *for_json* is true (default: ``False``), objects with a ``for_json()``
+ method will use the return value of that method for encoding as JSON
+ instead of the object.
+
+ If *ignore_nan* is true (default: ``False``), then out of range
+ :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized as
+ ``null`` in compliance with the ECMA-262 specification. If true, this will
+ override *allow_nan*.
+
+ To use a custom ``JSONEncoder`` subclass (e.g. one that overrides the
+ ``.default()`` method to serialize additional types), specify it with
+ the ``cls`` kwarg. NOTE: You should use *default* instead of subclassing
+ whenever possible.
+
+ """
+ # cached encoder
+ if (not skipkeys and ensure_ascii and
+ check_circular and allow_nan and
+ cls is None and indent is None and separators is None and
+ encoding == 'utf-8' and default is None and use_decimal
+ and namedtuple_as_object and tuple_as_array and not iterable_as_array
+ and not bigint_as_string and not sort_keys
+ and not item_sort_key and not for_json
+ and not ignore_nan and int_as_string_bitcount is None
+ and not kw
+ ):
+ return _default_encoder.encode(obj)
+ if cls is None:
+ cls = JSONEncoder
+ return cls(
+ skipkeys=skipkeys, ensure_ascii=ensure_ascii,
+ check_circular=check_circular, allow_nan=allow_nan, indent=indent,
+ separators=separators, encoding=encoding, default=default,
+ use_decimal=use_decimal,
+ namedtuple_as_object=namedtuple_as_object,
+ tuple_as_array=tuple_as_array,
+ iterable_as_array=iterable_as_array,
+ bigint_as_string=bigint_as_string,
+ sort_keys=sort_keys,
+ item_sort_key=item_sort_key,
+ for_json=for_json,
+ ignore_nan=ignore_nan,
+ int_as_string_bitcount=int_as_string_bitcount,
+ **kw).encode(obj)
+
+
+_default_decoder = JSONDecoder(encoding=None, object_hook=None,
+ object_pairs_hook=None)
+
+
+def load(fp, encoding=None, cls=None, object_hook=None, parse_float=None,
+ parse_int=None, parse_constant=None, object_pairs_hook=None,
+ use_decimal=False, namedtuple_as_object=True, tuple_as_array=True,
+ **kw):
+ """Deserialize ``fp`` (a ``.read()``-supporting file-like object containing
+ a JSON document as `str` or `bytes`) to a Python object.
+
+ *encoding* determines the encoding used to interpret any
+ `bytes` objects decoded by this instance (``'utf-8'`` by
+ default). It has no effect when decoding `str` objects.
+
+ *object_hook*, if specified, will be called with the result of every
+ JSON object decoded and its return value will be used in place of the
+ given :class:`dict`. This can be used to provide custom
+ deserializations (e.g. to support JSON-RPC class hinting).
+
+ *object_pairs_hook* is an optional function that will be called with
+ the result of any object literal decode with an ordered list of pairs.
+ The return value of *object_pairs_hook* will be used instead of the
+ :class:`dict`. This feature can be used to implement custom decoders
+ that rely on the order that the key and value pairs are decoded (for
+ example, :func:`collections.OrderedDict` will remember the order of
+ insertion). If *object_hook* is also defined, the *object_pairs_hook*
+ takes priority.
+
+ *parse_float*, if specified, will be called with the string of every
+ JSON float to be decoded. By default, this is equivalent to
+ ``float(num_str)``. This can be used to use another datatype or parser
+ for JSON floats (e.g. :class:`decimal.Decimal`).
+
+ *parse_int*, if specified, will be called with the string of every
+ JSON int to be decoded. By default, this is equivalent to
+ ``int(num_str)``. This can be used to use another datatype or parser
+ for JSON integers (e.g. :class:`float`).
+
+ *parse_constant*, if specified, will be called with one of the
+ following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
+ can be used to raise an exception if invalid JSON numbers are
+ encountered.
+
+ If *use_decimal* is true (default: ``False``) then it implies
+ parse_float=decimal.Decimal for parity with ``dump``.
+
+ To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
+ kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead
+ of subclassing whenever possible.
+
+ """
+ return loads(fp.read(),
+ encoding=encoding, cls=cls, object_hook=object_hook,
+ parse_float=parse_float, parse_int=parse_int,
+ parse_constant=parse_constant, object_pairs_hook=object_pairs_hook,
+ use_decimal=use_decimal, **kw)
+
+
+def loads(s, encoding=None, cls=None, object_hook=None, parse_float=None,
+ parse_int=None, parse_constant=None, object_pairs_hook=None,
+ use_decimal=False, **kw):
+ """Deserialize ``s`` (a ``str`` or ``unicode`` instance containing a JSON
+ document) to a Python object.
+
+ *encoding* determines the encoding used to interpret any
+ :class:`bytes` objects decoded by this instance (``'utf-8'`` by
+ default). It has no effect when decoding :class:`unicode` objects.
+
+ *object_hook*, if specified, will be called with the result of every
+ JSON object decoded and its return value will be used in place of the
+ given :class:`dict`. This can be used to provide custom
+ deserializations (e.g. to support JSON-RPC class hinting).
+
+ *object_pairs_hook* is an optional function that will be called with
+ the result of any object literal decode with an ordered list of pairs.
+ The return value of *object_pairs_hook* will be used instead of the
+ :class:`dict`. This feature can be used to implement custom decoders
+ that rely on the order that the key and value pairs are decoded (for
+ example, :func:`collections.OrderedDict` will remember the order of
+ insertion). If *object_hook* is also defined, the *object_pairs_hook*
+ takes priority.
+
+ *parse_float*, if specified, will be called with the string of every
+ JSON float to be decoded. By default, this is equivalent to
+ ``float(num_str)``. This can be used to use another datatype or parser
+ for JSON floats (e.g. :class:`decimal.Decimal`).
+
+ *parse_int*, if specified, will be called with the string of every
+ JSON int to be decoded. By default, this is equivalent to
+ ``int(num_str)``. This can be used to use another datatype or parser
+ for JSON integers (e.g. :class:`float`).
+
+ *parse_constant*, if specified, will be called with one of the
+ following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
+ can be used to raise an exception if invalid JSON numbers are
+ encountered.
+
+ If *use_decimal* is true (default: ``False``) then it implies
+ parse_float=decimal.Decimal for parity with ``dump``.
+
+ To use a custom ``JSONDecoder`` subclass, specify it with the ``cls``
+ kwarg. NOTE: You should use *object_hook* or *object_pairs_hook* instead
+ of subclassing whenever possible.
+
+ """
+ if (cls is None and encoding is None and object_hook is None and
+ parse_int is None and parse_float is None and
+ parse_constant is None and object_pairs_hook is None
+ and not use_decimal and not kw):
+ return _default_decoder.decode(s)
+ if cls is None:
+ cls = JSONDecoder
+ if object_hook is not None:
+ kw['object_hook'] = object_hook
+ if object_pairs_hook is not None:
+ kw['object_pairs_hook'] = object_pairs_hook
+ if parse_float is not None:
+ kw['parse_float'] = parse_float
+ if parse_int is not None:
+ kw['parse_int'] = parse_int
+ if parse_constant is not None:
+ kw['parse_constant'] = parse_constant
+ if use_decimal:
+ if parse_float is not None:
+ raise TypeError("use_decimal=True implies parse_float=Decimal")
+ kw['parse_float'] = Decimal
+ return cls(encoding=encoding, **kw).decode(s)
+
+
+def _toggle_speedups(enabled):
+ from . import decoder as dec
+ from . import encoder as enc
+ from . import scanner as scan
+ c_make_encoder = _import_c_make_encoder()
+ if enabled:
+ dec.scanstring = dec.c_scanstring or dec.py_scanstring
+ enc.c_make_encoder = c_make_encoder
+ enc.encode_basestring_ascii = (enc.c_encode_basestring_ascii or
+ enc.py_encode_basestring_ascii)
+ scan.make_scanner = scan.c_make_scanner or scan.py_make_scanner
+ else:
+ dec.scanstring = dec.py_scanstring
+ enc.c_make_encoder = None
+ enc.encode_basestring_ascii = enc.py_encode_basestring_ascii
+ scan.make_scanner = scan.py_make_scanner
+ dec.make_scanner = scan.make_scanner
+ global _default_decoder
+ _default_decoder = JSONDecoder(
+ encoding=None,
+ object_hook=None,
+ object_pairs_hook=None,
+ )
+ global _default_encoder
+ _default_encoder = JSONEncoder(
+ skipkeys=False,
+ ensure_ascii=True,
+ check_circular=True,
+ allow_nan=True,
+ indent=None,
+ separators=None,
+ encoding='utf-8',
+ default=None,
+ )
+
+def simple_first(kv):
+ """Helper function to pass to item_sort_key to sort simple
+ elements to the top, then container elements.
+ """
+ return (isinstance(kv[1], (list, dict, tuple)), kv[0])
diff --git a/Modules/simplejson/compat.py b/Modules/simplejson/compat.py
new file mode 100644
index 0000000..5fc1412
--- /dev/null
+++ b/Modules/simplejson/compat.py
@@ -0,0 +1,34 @@
+"""Python 3 compatibility shims
+"""
+import sys
+if sys.version_info[0] < 3:
+ PY3 = False
+ def b(s):
+ return s
+ try:
+ from cStringIO import StringIO
+ except ImportError:
+ from StringIO import StringIO
+ BytesIO = StringIO
+ text_type = unicode
+ binary_type = str
+ string_types = (basestring,)
+ integer_types = (int, long)
+ unichr = unichr
+ reload_module = reload
+else:
+ PY3 = True
+ if sys.version_info[:2] >= (3, 4):
+ from importlib import reload as reload_module
+ else:
+ from imp import reload as reload_module
+ def b(s):
+ return bytes(s, 'latin1')
+ from io import StringIO, BytesIO
+ text_type = str
+ binary_type = bytes
+ string_types = (str,)
+ integer_types = (int,)
+ unichr = chr
+
+long_type = integer_types[-1]
diff --git a/Modules/simplejson/decoder.py b/Modules/simplejson/decoder.py
new file mode 100644
index 0000000..7f0b056
--- /dev/null
+++ b/Modules/simplejson/decoder.py
@@ -0,0 +1,400 @@
+"""Implementation of JSONDecoder
+"""
+from __future__ import absolute_import
+import re
+import sys
+import struct
+from .compat import PY3, unichr
+from .scanner import make_scanner, JSONDecodeError
+
+def _import_c_scanstring():
+ try:
+ from ._speedups import scanstring
+ return scanstring
+ except ImportError:
+ return None
+c_scanstring = _import_c_scanstring()
+
+# NOTE (3.1.0): JSONDecodeError may still be imported from this module for
+# compatibility, but it was never in the __all__
+__all__ = ['JSONDecoder']
+
+FLAGS = re.VERBOSE | re.MULTILINE | re.DOTALL
+
+def _floatconstants():
+ if sys.version_info < (2, 6):
+ _BYTES = '7FF80000000000007FF0000000000000'.decode('hex')
+ nan, inf = struct.unpack('>dd', _BYTES)
+ else:
+ nan = float('nan')
+ inf = float('inf')
+ return nan, inf, -inf
+
+NaN, PosInf, NegInf = _floatconstants()
+
+_CONSTANTS = {
+ '-Infinity': NegInf,
+ 'Infinity': PosInf,
+ 'NaN': NaN,
+}
+
+STRINGCHUNK = re.compile(r'(.*?)(["\\\x00-\x1f])', FLAGS)
+BACKSLASH = {
+ '"': u'"', '\\': u'\\', '/': u'/',
+ 'b': u'\b', 'f': u'\f', 'n': u'\n', 'r': u'\r', 't': u'\t',
+}
+
+DEFAULT_ENCODING = "utf-8"
+
+def py_scanstring(s, end, encoding=None, strict=True,
+ _b=BACKSLASH, _m=STRINGCHUNK.match, _join=u''.join,
+ _PY3=PY3, _maxunicode=sys.maxunicode):
+ """Scan the string s for a JSON string. End is the index of the
+ character in s after the quote that started the JSON string.
+ Unescapes all valid JSON string escape sequences and raises ValueError
+ on attempt to decode an invalid string. If strict is False then literal
+ control characters are allowed in the string.
+
+ Returns a tuple of the decoded string and the index of the character in s
+ after the end quote."""
+ if encoding is None:
+ encoding = DEFAULT_ENCODING
+ chunks = []
+ _append = chunks.append
+ begin = end - 1
+ while 1:
+ chunk = _m(s, end)
+ if chunk is None:
+ raise JSONDecodeError(
+ "Unterminated string starting at", s, begin)
+ end = chunk.end()
+ content, terminator = chunk.groups()
+ # Content is contains zero or more unescaped string characters
+ if content:
+ if not _PY3 and not isinstance(content, unicode):
+ content = unicode(content, encoding)
+ _append(content)
+ # Terminator is the end of string, a literal control character,
+ # or a backslash denoting that an escape sequence follows
+ if terminator == '"':
+ break
+ elif terminator != '\\':
+ if strict:
+ msg = "Invalid control character %r at"
+ raise JSONDecodeError(msg, s, end)
+ else:
+ _append(terminator)
+ continue
+ try:
+ esc = s[end]
+ except IndexError:
+ raise JSONDecodeError(
+ "Unterminated string starting at", s, begin)
+ # If not a unicode escape sequence, must be in the lookup table
+ if esc != 'u':
+ try:
+ char = _b[esc]
+ except KeyError:
+ msg = "Invalid \\X escape sequence %r"
+ raise JSONDecodeError(msg, s, end)
+ end += 1
+ else:
+ # Unicode escape sequence
+ msg = "Invalid \\uXXXX escape sequence"
+ esc = s[end + 1:end + 5]
+ escX = esc[1:2]
+ if len(esc) != 4 or escX == 'x' or escX == 'X':
+ raise JSONDecodeError(msg, s, end - 1)
+ try:
+ uni = int(esc, 16)
+ except ValueError:
+ raise JSONDecodeError(msg, s, end - 1)
+ end += 5
+ # Check for surrogate pair on UCS-4 systems
+ # Note that this will join high/low surrogate pairs
+ # but will also pass unpaired surrogates through
+ if (_maxunicode > 65535 and
+ uni & 0xfc00 == 0xd800 and
+ s[end:end + 2] == '\\u'):
+ esc2 = s[end + 2:end + 6]
+ escX = esc2[1:2]
+ if len(esc2) == 4 and not (escX == 'x' or escX == 'X'):
+ try:
+ uni2 = int(esc2, 16)
+ except ValueError:
+ raise JSONDecodeError(msg, s, end)
+ if uni2 & 0xfc00 == 0xdc00:
+ uni = 0x10000 + (((uni - 0xd800) << 10) |
+ (uni2 - 0xdc00))
+ end += 6
+ char = unichr(uni)
+ # Append the unescaped character
+ _append(char)
+ return _join(chunks), end
+
+
+# Use speedup if available
+scanstring = c_scanstring or py_scanstring
+
+WHITESPACE = re.compile(r'[ \t\n\r]*', FLAGS)
+WHITESPACE_STR = ' \t\n\r'
+
+def JSONObject(state, encoding, strict, scan_once, object_hook,
+ object_pairs_hook, memo=None,
+ _w=WHITESPACE.match, _ws=WHITESPACE_STR):
+ (s, end) = state
+ # Backwards compatibility
+ if memo is None:
+ memo = {}
+ memo_get = memo.setdefault
+ pairs = []
+ # Use a slice to prevent IndexError from being raised, the following
+ # check will raise a more specific ValueError if the string is empty
+ nextchar = s[end:end + 1]
+ # Normally we expect nextchar == '"'
+ if nextchar != '"':
+ if nextchar in _ws:
+ end = _w(s, end).end()
+ nextchar = s[end:end + 1]
+ # Trivial empty object
+ if nextchar == '}':
+ if object_pairs_hook is not None:
+ result = object_pairs_hook(pairs)
+ return result, end + 1
+ pairs = {}
+ if object_hook is not None:
+ pairs = object_hook(pairs)
+ return pairs, end + 1
+ elif nextchar != '"':
+ raise JSONDecodeError(
+ "Expecting property name enclosed in double quotes",
+ s, end)
+ end += 1
+ while True:
+ key, end = scanstring(s, end, encoding, strict)
+ key = memo_get(key, key)
+
+ # To skip some function call overhead we optimize the fast paths where
+ # the JSON key separator is ": " or just ":".
+ if s[end:end + 1] != ':':
+ end = _w(s, end).end()
+ if s[end:end + 1] != ':':
+ raise JSONDecodeError("Expecting ':' delimiter", s, end)
+
+ end += 1
+
+ try:
+ if s[end] in _ws:
+ end += 1
+ if s[end] in _ws:
+ end = _w(s, end + 1).end()
+ except IndexError:
+ pass
+
+ value, end = scan_once(s, end)
+ pairs.append((key, value))
+
+ try:
+ nextchar = s[end]
+ if nextchar in _ws:
+ end = _w(s, end + 1).end()
+ nextchar = s[end]
+ except IndexError:
+ nextchar = ''
+ end += 1
+
+ if nextchar == '}':
+ break
+ elif nextchar != ',':
+ raise JSONDecodeError("Expecting ',' delimiter or '}'", s, end - 1)
+
+ try:
+ nextchar = s[end]
+ if nextchar in _ws:
+ end += 1
+ nextchar = s[end]
+ if nextchar in _ws:
+ end = _w(s, end + 1).end()
+ nextchar = s[end]
+ except IndexError:
+ nextchar = ''
+
+ end += 1
+ if nextchar != '"':
+ raise JSONDecodeError(
+ "Expecting property name enclosed in double quotes",
+ s, end - 1)
+
+ if object_pairs_hook is not None:
+ result = object_pairs_hook(pairs)
+ return result, end
+ pairs = dict(pairs)
+ if object_hook is not None:
+ pairs = object_hook(pairs)
+ return pairs, end
+
+def JSONArray(state, scan_once, _w=WHITESPACE.match, _ws=WHITESPACE_STR):
+ (s, end) = state
+ values = []
+ nextchar = s[end:end + 1]
+ if nextchar in _ws:
+ end = _w(s, end + 1).end()
+ nextchar = s[end:end + 1]
+ # Look-ahead for trivial empty array
+ if nextchar == ']':
+ return values, end + 1
+ elif nextchar == '':
+ raise JSONDecodeError("Expecting value or ']'", s, end)
+ _append = values.append
+ while True:
+ value, end = scan_once(s, end)
+ _append(value)
+ nextchar = s[end:end + 1]
+ if nextchar in _ws:
+ end = _w(s, end + 1).end()
+ nextchar = s[end:end + 1]
+ end += 1
+ if nextchar == ']':
+ break
+ elif nextchar != ',':
+ raise JSONDecodeError("Expecting ',' delimiter or ']'", s, end - 1)
+
+ try:
+ if s[end] in _ws:
+ end += 1
+ if s[end] in _ws:
+ end = _w(s, end + 1).end()
+ except IndexError:
+ pass
+
+ return values, end
+
+class JSONDecoder(object):
+ """Simple JSON decoder
+
+ Performs the following translations in decoding by default:
+
+ +---------------+-------------------+
+ | JSON | Python |
+ +===============+===================+
+ | object | dict |
+ +---------------+-------------------+
+ | array | list |
+ +---------------+-------------------+
+ | string | str, unicode |
+ +---------------+-------------------+
+ | number (int) | int, long |
+ +---------------+-------------------+
+ | number (real) | float |
+ +---------------+-------------------+
+ | true | True |
+ +---------------+-------------------+
+ | false | False |
+ +---------------+-------------------+
+ | null | None |
+ +---------------+-------------------+
+
+ It also understands ``NaN``, ``Infinity``, and ``-Infinity`` as
+ their corresponding ``float`` values, which is outside the JSON spec.
+
+ """
+
+ def __init__(self, encoding=None, object_hook=None, parse_float=None,
+ parse_int=None, parse_constant=None, strict=True,
+ object_pairs_hook=None):
+ """
+ *encoding* determines the encoding used to interpret any
+ :class:`str` objects decoded by this instance (``'utf-8'`` by
+ default). It has no effect when decoding :class:`unicode` objects.
+
+ Note that currently only encodings that are a superset of ASCII work,
+ strings of other encodings should be passed in as :class:`unicode`.
+
+ *object_hook*, if specified, will be called with the result of every
+ JSON object decoded and its return value will be used in place of the
+ given :class:`dict`. This can be used to provide custom
+ deserializations (e.g. to support JSON-RPC class hinting).
+
+ *object_pairs_hook* is an optional function that will be called with
+ the result of any object literal decode with an ordered list of pairs.
+ The return value of *object_pairs_hook* will be used instead of the
+ :class:`dict`. This feature can be used to implement custom decoders
+ that rely on the order that the key and value pairs are decoded (for
+ example, :func:`collections.OrderedDict` will remember the order of
+ insertion). If *object_hook* is also defined, the *object_pairs_hook*
+ takes priority.
+
+ *parse_float*, if specified, will be called with the string of every
+ JSON float to be decoded. By default, this is equivalent to
+ ``float(num_str)``. This can be used to use another datatype or parser
+ for JSON floats (e.g. :class:`decimal.Decimal`).
+
+ *parse_int*, if specified, will be called with the string of every
+ JSON int to be decoded. By default, this is equivalent to
+ ``int(num_str)``. This can be used to use another datatype or parser
+ for JSON integers (e.g. :class:`float`).
+
+ *parse_constant*, if specified, will be called with one of the
+ following strings: ``'-Infinity'``, ``'Infinity'``, ``'NaN'``. This
+ can be used to raise an exception if invalid JSON numbers are
+ encountered.
+
+ *strict* controls the parser's behavior when it encounters an
+ invalid control character in a string. The default setting of
+ ``True`` means that unescaped control characters are parse errors, if
+ ``False`` then control characters will be allowed in strings.
+
+ """
+ if encoding is None:
+ encoding = DEFAULT_ENCODING
+ self.encoding = encoding
+ self.object_hook = object_hook
+ self.object_pairs_hook = object_pairs_hook
+ self.parse_float = parse_float or float
+ self.parse_int = parse_int or int
+ self.parse_constant = parse_constant or _CONSTANTS.__getitem__
+ self.strict = strict
+ self.parse_object = JSONObject
+ self.parse_array = JSONArray
+ self.parse_string = scanstring
+ self.memo = {}
+ self.scan_once = make_scanner(self)
+
+ def decode(self, s, _w=WHITESPACE.match, _PY3=PY3):
+ """Return the Python representation of ``s`` (a ``str`` or ``unicode``
+ instance containing a JSON document)
+
+ """
+ if _PY3 and isinstance(s, bytes):
+ s = str(s, self.encoding)
+ obj, end = self.raw_decode(s)
+ end = _w(s, end).end()
+ if end != len(s):
+ raise JSONDecodeError("Extra data", s, end, len(s))
+ return obj
+
+ def raw_decode(self, s, idx=0, _w=WHITESPACE.match, _PY3=PY3):
+ """Decode a JSON document from ``s`` (a ``str`` or ``unicode``
+ beginning with a JSON document) and return a 2-tuple of the Python
+ representation and the index in ``s`` where the document ended.
+ Optionally, ``idx`` can be used to specify an offset in ``s`` where
+ the JSON document begins.
+
+ This can be used to decode a JSON document from a string that may
+ have extraneous data at the end.
+
+ """
+ if idx < 0:
+ # Ensure that raw_decode bails on negative indexes, the regex
+ # would otherwise mask this behavior. #98
+ raise JSONDecodeError('Expecting value', s, idx)
+ if _PY3 and not isinstance(s, str):
+ raise TypeError("Input string must be text, not bytes")
+ # strip UTF-8 bom
+ if len(s) > idx:
+ ord0 = ord(s[idx])
+ if ord0 == 0xfeff:
+ idx += 1
+ elif ord0 == 0xef and s[idx:idx + 3] == '\xef\xbb\xbf':
+ idx += 3
+ return self.scan_once(s, idx=_w(s, idx).end())
diff --git a/Modules/simplejson/encoder.py b/Modules/simplejson/encoder.py
new file mode 100644
index 0000000..7ea172e
--- /dev/null
+++ b/Modules/simplejson/encoder.py
@@ -0,0 +1,722 @@
+"""Implementation of JSONEncoder
+"""
+from __future__ import absolute_import
+import re
+from operator import itemgetter
+# Do not import Decimal directly to avoid reload issues
+import decimal
+from .compat import unichr, binary_type, text_type, string_types, integer_types, PY3
+def _import_speedups():
+ try:
+ from . import _speedups
+ return _speedups.encode_basestring_ascii, _speedups.make_encoder
+ except ImportError:
+ return None, None
+c_encode_basestring_ascii, c_make_encoder = _import_speedups()
+
+from .decoder import PosInf
+from .raw_json import RawJSON
+
+ESCAPE = re.compile(r'[\x00-\x1f\\"]')
+ESCAPE_ASCII = re.compile(r'([\\"]|[^\ -~])')
+HAS_UTF8 = re.compile(r'[\x80-\xff]')
+ESCAPE_DCT = {
+ '\\': '\\\\',
+ '"': '\\"',
+ '\b': '\\b',
+ '\f': '\\f',
+ '\n': '\\n',
+ '\r': '\\r',
+ '\t': '\\t',
+}
+for i in range(0x20):
+ #ESCAPE_DCT.setdefault(chr(i), '\\u{0:04x}'.format(i))
+ ESCAPE_DCT.setdefault(chr(i), '\\u%04x' % (i,))
+
+FLOAT_REPR = repr
+
+def encode_basestring(s, _PY3=PY3, _q=u'"'):
+ """Return a JSON representation of a Python string
+
+ """
+ if _PY3:
+ if isinstance(s, bytes):
+ s = str(s, 'utf-8')
+ elif type(s) is not str:
+ # convert an str subclass instance to exact str
+ # raise a TypeError otherwise
+ s = str.__str__(s)
+ else:
+ if isinstance(s, str) and HAS_UTF8.search(s) is not None:
+ s = unicode(s, 'utf-8')
+ elif type(s) not in (str, unicode):
+ # convert an str subclass instance to exact str
+ # convert a unicode subclass instance to exact unicode
+ # raise a TypeError otherwise
+ if isinstance(s, str):
+ s = str.__str__(s)
+ else:
+ s = unicode.__getnewargs__(s)[0]
+ def replace(match):
+ return ESCAPE_DCT[match.group(0)]
+ return _q + ESCAPE.sub(replace, s) + _q
+
+
+def py_encode_basestring_ascii(s, _PY3=PY3):
+ """Return an ASCII-only JSON representation of a Python string
+
+ """
+ if _PY3:
+ if isinstance(s, bytes):
+ s = str(s, 'utf-8')
+ elif type(s) is not str:
+ # convert an str subclass instance to exact str
+ # raise a TypeError otherwise
+ s = str.__str__(s)
+ else:
+ if isinstance(s, str) and HAS_UTF8.search(s) is not None:
+ s = unicode(s, 'utf-8')
+ elif type(s) not in (str, unicode):
+ # convert an str subclass instance to exact str
+ # convert a unicode subclass instance to exact unicode
+ # raise a TypeError otherwise
+ if isinstance(s, str):
+ s = str.__str__(s)
+ else:
+ s = unicode.__getnewargs__(s)[0]
+ def replace(match):
+ s = match.group(0)
+ try:
+ return ESCAPE_DCT[s]
+ except KeyError:
+ n = ord(s)
+ if n < 0x10000:
+ #return '\\u{0:04x}'.format(n)
+ return '\\u%04x' % (n,)
+ else:
+ # surrogate pair
+ n -= 0x10000
+ s1 = 0xd800 | ((n >> 10) & 0x3ff)
+ s2 = 0xdc00 | (n & 0x3ff)
+ #return '\\u{0:04x}\\u{1:04x}'.format(s1, s2)
+ return '\\u%04x\\u%04x' % (s1, s2)
+ return '"' + str(ESCAPE_ASCII.sub(replace, s)) + '"'
+
+
+encode_basestring_ascii = (
+ c_encode_basestring_ascii or py_encode_basestring_ascii)
+
+class JSONEncoder(object):
+ """Extensible JSON encoder for Python data structures.
+
+ Supports the following objects and types by default:
+
+ +-------------------+---------------+
+ | Python | JSON |
+ +===================+===============+
+ | dict, namedtuple | object |
+ +-------------------+---------------+
+ | list, tuple | array |
+ +-------------------+---------------+
+ | str, unicode | string |
+ +-------------------+---------------+
+ | int, long, float | number |
+ +-------------------+---------------+
+ | True | true |
+ +-------------------+---------------+
+ | False | false |
+ +-------------------+---------------+
+ | None | null |
+ +-------------------+---------------+
+
+ To extend this to recognize other objects, subclass and implement a
+ ``.default()`` method with another method that returns a serializable
+ object for ``o`` if possible, otherwise it should call the superclass
+ implementation (to raise ``TypeError``).
+
+ """
+ item_separator = ', '
+ key_separator = ': '
+
+ def __init__(self, skipkeys=False, ensure_ascii=True,
+ check_circular=True, allow_nan=True, sort_keys=False,
+ indent=None, separators=None, encoding='utf-8', default=None,
+ use_decimal=True, namedtuple_as_object=True,
+ tuple_as_array=True, bigint_as_string=False,
+ item_sort_key=None, for_json=False, ignore_nan=False,
+ int_as_string_bitcount=None, iterable_as_array=False):
+ """Constructor for JSONEncoder, with sensible defaults.
+
+ If skipkeys is false, then it is a TypeError to attempt
+ encoding of keys that are not str, int, long, float or None. If
+ skipkeys is True, such items are simply skipped.
+
+ If ensure_ascii is true, the output is guaranteed to be str
+ objects with all incoming unicode characters escaped. If
+ ensure_ascii is false, the output will be unicode object.
+
+ If check_circular is true, then lists, dicts, and custom encoded
+ objects will be checked for circular references during encoding to
+ prevent an infinite recursion (which would cause an OverflowError).
+ Otherwise, no such check takes place.
+
+ If allow_nan is true, then NaN, Infinity, and -Infinity will be
+ encoded as such. This behavior is not JSON specification compliant,
+ but is consistent with most JavaScript based encoders and decoders.
+ Otherwise, it will be a ValueError to encode such floats.
+
+ If sort_keys is true, then the output of dictionaries will be
+ sorted by key; this is useful for regression tests to ensure
+ that JSON serializations can be compared on a day-to-day basis.
+
+ If indent is a string, then JSON array elements and object members
+ will be pretty-printed with a newline followed by that string repeated
+ for each level of nesting. ``None`` (the default) selects the most compact
+ representation without any newlines. For backwards compatibility with
+ versions of simplejson earlier than 2.1.0, an integer is also accepted
+ and is converted to a string with that many spaces.
+
+ If specified, separators should be an (item_separator, key_separator)
+ tuple. The default is (', ', ': ') if *indent* is ``None`` and
+ (',', ': ') otherwise. To get the most compact JSON representation,
+ you should specify (',', ':') to eliminate whitespace.
+
+ If specified, default is a function that gets called for objects
+ that can't otherwise be serialized. It should return a JSON encodable
+ version of the object or raise a ``TypeError``.
+
+ If encoding is not None, then all input strings will be
+ transformed into unicode using that encoding prior to JSON-encoding.
+ The default is UTF-8.
+
+ If use_decimal is true (default: ``True``), ``decimal.Decimal`` will
+ be supported directly by the encoder. For the inverse, decode JSON
+ with ``parse_float=decimal.Decimal``.
+
+ If namedtuple_as_object is true (the default), objects with
+ ``_asdict()`` methods will be encoded as JSON objects.
+
+ If tuple_as_array is true (the default), tuple (and subclasses) will
+ be encoded as JSON arrays.
+
+ If *iterable_as_array* is true (default: ``False``),
+ any object not in the above table that implements ``__iter__()``
+ will be encoded as a JSON array.
+
+ If bigint_as_string is true (not the default), ints 2**53 and higher
+ or lower than -2**53 will be encoded as strings. This is to avoid the
+ rounding that happens in Javascript otherwise.
+
+ If int_as_string_bitcount is a positive number (n), then int of size
+ greater than or equal to 2**n or lower than or equal to -2**n will be
+ encoded as strings.
+
+ If specified, item_sort_key is a callable used to sort the items in
+ each dictionary. This is useful if you want to sort items other than
+ in alphabetical order by key.
+
+ If for_json is true (not the default), objects with a ``for_json()``
+ method will use the return value of that method for encoding as JSON
+ instead of the object.
+
+ If *ignore_nan* is true (default: ``False``), then out of range
+ :class:`float` values (``nan``, ``inf``, ``-inf``) will be serialized
+ as ``null`` in compliance with the ECMA-262 specification. If true,
+ this will override *allow_nan*.
+
+ """
+
+ self.skipkeys = skipkeys
+ self.ensure_ascii = ensure_ascii
+ self.check_circular = check_circular
+ self.allow_nan = allow_nan
+ self.sort_keys = sort_keys
+ self.use_decimal = use_decimal
+ self.namedtuple_as_object = namedtuple_as_object
+ self.tuple_as_array = tuple_as_array
+ self.iterable_as_array = iterable_as_array
+ self.bigint_as_string = bigint_as_string
+ self.item_sort_key = item_sort_key
+ self.for_json = for_json
+ self.ignore_nan = ignore_nan
+ self.int_as_string_bitcount = int_as_string_bitcount
+ if indent is not None and not isinstance(indent, string_types):
+ indent = indent * ' '
+ self.indent = indent
+ if separators is not None:
+ self.item_separator, self.key_separator = separators
+ elif indent is not None:
+ self.item_separator = ','
+ if default is not None:
+ self.default = default
+ self.encoding = encoding
+
+ def default(self, o):
+ """Implement this method in a subclass such that it returns
+ a serializable object for ``o``, or calls the base implementation
+ (to raise a ``TypeError``).
+
+ For example, to support arbitrary iterators, you could
+ implement default like this::
+
+ def default(self, o):
+ try:
+ iterable = iter(o)
+ except TypeError:
+ pass
+ else:
+ return list(iterable)
+ return JSONEncoder.default(self, o)
+
+ """
+ raise TypeError('Object of type %s is not JSON serializable' %
+ o.__class__.__name__)
+
+ def encode(self, o):
+ """Return a JSON string representation of a Python data structure.
+
+ >>> from simplejson import JSONEncoder
+ >>> JSONEncoder().encode({"foo": ["bar", "baz"]})
+ '{"foo": ["bar", "baz"]}'
+
+ """
+ # This is for extremely simple cases and benchmarks.
+ if isinstance(o, binary_type):
+ _encoding = self.encoding
+ if (_encoding is not None and not (_encoding == 'utf-8')):
+ o = text_type(o, _encoding)
+ if isinstance(o, string_types):
+ if self.ensure_ascii:
+ return encode_basestring_ascii(o)
+ else:
+ return encode_basestring(o)
+ # This doesn't pass the iterator directly to ''.join() because the
+ # exceptions aren't as detailed. The list call should be roughly
+ # equivalent to the PySequence_Fast that ''.join() would do.
+ chunks = self.iterencode(o, _one_shot=True)
+ if not isinstance(chunks, (list, tuple)):
+ chunks = list(chunks)
+ if self.ensure_ascii:
+ return ''.join(chunks)
+ else:
+ return u''.join(chunks)
+
+ def iterencode(self, o, _one_shot=False):
+ """Encode the given object and yield each string
+ representation as available.
+
+ For example::
+
+ for chunk in JSONEncoder().iterencode(bigobject):
+ mysocket.write(chunk)
+
+ """
+ if self.check_circular:
+ markers = {}
+ else:
+ markers = None
+ if self.ensure_ascii:
+ _encoder = encode_basestring_ascii
+ else:
+ _encoder = encode_basestring
+ if self.encoding != 'utf-8' and self.encoding is not None:
+ def _encoder(o, _orig_encoder=_encoder, _encoding=self.encoding):
+ if isinstance(o, binary_type):
+ o = text_type(o, _encoding)
+ return _orig_encoder(o)
+
+ def floatstr(o, allow_nan=self.allow_nan, ignore_nan=self.ignore_nan,
+ _repr=FLOAT_REPR, _inf=PosInf, _neginf=-PosInf):
+ # Check for specials. Note that this type of test is processor
+ # and/or platform-specific, so do tests which don't depend on
+ # the internals.
+
+ if o != o:
+ text = 'NaN'
+ elif o == _inf:
+ text = 'Infinity'
+ elif o == _neginf:
+ text = '-Infinity'
+ else:
+ if type(o) != float:
+ # See #118, do not trust custom str/repr
+ o = float(o)
+ return _repr(o)
+
+ if ignore_nan:
+ text = 'null'
+ elif not allow_nan:
+ raise ValueError(
+ "Out of range float values are not JSON compliant: " +
+ repr(o))
+
+ return text
+
+ key_memo = {}
+ int_as_string_bitcount = (
+ 53 if self.bigint_as_string else self.int_as_string_bitcount)
+ if (_one_shot and c_make_encoder is not None
+ and self.indent is None):
+ _iterencode = c_make_encoder(
+ markers, self.default, _encoder, self.indent,
+ self.key_separator, self.item_separator, self.sort_keys,
+ self.skipkeys, self.allow_nan, key_memo, self.use_decimal,
+ self.namedtuple_as_object, self.tuple_as_array,
+ int_as_string_bitcount,
+ self.item_sort_key, self.encoding, self.for_json,
+ self.ignore_nan, decimal.Decimal, self.iterable_as_array)
+ else:
+ _iterencode = _make_iterencode(
+ markers, self.default, _encoder, self.indent, floatstr,
+ self.key_separator, self.item_separator, self.sort_keys,
+ self.skipkeys, _one_shot, self.use_decimal,
+ self.namedtuple_as_object, self.tuple_as_array,
+ int_as_string_bitcount,
+ self.item_sort_key, self.encoding, self.for_json,
+ self.iterable_as_array, Decimal=decimal.Decimal)
+ try:
+ return _iterencode(o, 0)
+ finally:
+ key_memo.clear()
+
+
+class JSONEncoderForHTML(JSONEncoder):
+ """An encoder that produces JSON safe to embed in HTML.
+
+ To embed JSON content in, say, a script tag on a web page, the
+ characters &, < and > should be escaped. They cannot be escaped
+ with the usual entities (e.g. &) because they are not expanded
+ within