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 = '

Guitar Engine
by Brad Anderson Jr

Fusion 360 Luthiers Facebook Group
' - tab5ChildInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 10, True) - - message = '
Please report any issues to the
Guitar Engine Github Repository
' - tab5ChildInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 10, True) - - message = '
If you would like to support the development of Guitar Engine
please follow this link. Thank you!
' - 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 = '

Guitar Engine
by Brad Anderson Jr

Fusion 360 Luthiers Facebook Group
' + tabInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 10, True) + + message = '
Please report any issues to the
Guitar Engine Github Repository
' + tabInputs.addTextBoxCommandInput('fullWidth_textBox', '', message, 10, True) + + message = '
If you would like to support the development of Guitar Engine
please follow this link. Thank you!
' + 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