Script for Dimensioning STP file
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
Hi,
I started working on scripts to automate the dimensioning of STP files as they don't come with Design History. For this I chose to option to select a face and give all the dimensions of the features. But I am facing an issue and if someone could help that would be really appreciated as I am not a python expert and using ChatGPT to solve the same but nothing happening.
So my code works to an extend in dimensioning, and this is how it works.
I will select a face and generate a place offset 0, and standardized sketch is projected to that plane which the program dimensions.
but when it comes to dimensioning the position of the arcs and circles, if the STP file I have is far from the origin as in the picture below, the dimension for the the position of circle is starting from a point that is outside the sketch.
Upon troubleshooting, I found that this point was created by the origin. Since the part is inclined a bit, its projecting a line to point point at which a line from origin intersect perpendicular to the line from part. the only option from me is to move the origin around and get dimensions which sometimes is not perfect.
Can someone please help me to rectify this so that all the dimensions start from the generated sketch itself like this.
If anyone can share a different way I can achieve what I am trying to do in here, that would be amazing!!!
Please find the code below:
import adsk, adsk.core, adsk.fusion, traceback
# Fusion 360 application and UI objects
app = adsk.core.Application.get()
ui = app.userInterface
# Global variables for add-in setup
WORKSPACE_ID = 'FusionSolidEnvironment'
TOOLBARTAB_ID = "ToolsTab"
TOOLBARPANEL_ID = "InspectPanel"
CMD_ID = "STP Dimension Adder"
_handlers = []
def create_offset_plane(selected_face, root_comp):
try:
# Create a construction plane at 0 offset from the selected face
plane_input = root_comp.constructionPlanes.createInput()
plane_input.setByOffset(selected_face, adsk.core.ValueInput.createByReal(0))
return root_comp.constructionPlanes.add(plane_input)
except Exception as e:
# Log the error for debugging
adsk.core.Application.get().userInterface.messageBox(f"Failed to create offset plane: {str(e)}")
return None
def is_duplicate_dimension(existing_dimensions, point_one, point_two):
for dimension in existing_dimensions:
if dimension.objectType == adsk.fusion.SketchDimension.classType():
if dimension.parameter.isDriven:
continue
if (dimension.startPoint.geometry.isEqualTo(point_one) and
dimension.endPoint.geometry.isEqualTo(point_two)) or (
dimension.startPoint.geometry.isEqualTo(point_two) and
dimension.endPoint.geometry.isEqualTo(point_one)):
return True
return False
def find_corner_point(sketch):
corner_point = None
min_distance = float('inf') # Start with a large number
# Iterate through all sketch points to find the corner point
for sketchPoint in sketch.sketchPoints:
distance = sketchPoint.geometry.vectorTo(sketch.originPoint.geometry).length
if distance < min_distance:
min_distance = distance
corner_point = sketchPoint
return corner_point
def add_dimensions_to_sketch(sketch, selected_face):
try:
# Get the existing dimensions in the sketch
existing_dimensions = sketch.sketchDimensions
# Find a corner point of the sketch
corner_point = find_corner_point(sketch)
# Iterate over each edge of the selected face
for edge in selected_face.edges:
geometry = edge.geometry
if geometry.curveType == adsk.core.Curve3DTypes.Line3DCurveType:
# Handle line edges
startPoint = edge.startVertex.geometry
endPoint = edge.endVertex.geometry
sktStartPoint = sketch.modelToSketchSpace(startPoint)
sktEndPoint = sketch.modelToSketchSpace(endPoint)
sketchLine = sketch.sketchCurves.sketchLines.addByTwoPoints(sktStartPoint, sktEndPoint)
sketch.areDimensionsShown = True
midPoint = adsk.core.Point3D.create(
(startPoint.x + endPoint.x) / 2,
(startPoint.y + endPoint.y) / 2,
(startPoint.z + endPoint.z) / 2
)
try:
if not is_duplicate_dimension(existing_dimensions, sktStartPoint, sktEndPoint):
sketch.sketchDimensions.addDistanceDimension(
sketchLine.startSketchPoint,
sketchLine.endSketchPoint,
adsk.fusion.DimensionOrientations.AlignedDimensionOrientation,
midPoint
)
except RuntimeError as e:
pass # Suppress the error message related to over-constraint
elif geometry.curveType == adsk.core.Curve3DTypes.Circle3DCurveType:
# Handle circular edges
circle = edge.geometry
centerPoint = sketch.modelToSketchSpace(circle.center)
radius = circle.radius
# Find the closest sketch point to the circle center
closest_point = None
min_distance = float('inf')
for sketchPoint in sketch.sketchPoints:
distance = sketchPoint.geometry.vectorTo(centerPoint).length
if distance < min_distance:
min_distance = distance
closest_point = sketchPoint
if closest_point:
# Determine orientation based on relative positions
if abs(closest_point.geometry.x - centerPoint.x) > abs(closest_point.geometry.y - centerPoint.y):
# Horizontal dimension
orientation = adsk.fusion.DimensionOrientations.HorizontalDimensionOrientation
else:
# Vertical dimension
orientation = adsk.fusion.DimensionOrientations.VerticalDimensionOrientation
# Add distance dimension to the closest point on line
sketch.sketchDimensions.addDistanceDimension(
closest_point,
corner_point, # Adjust this to fit your specific sketch setup
orientation,
adsk.core.Point3D.create(
(closest_point.geometry.x + corner_point.geometry.x) / 2,
(closest_point.geometry.y + corner_point.geometry.y) / 2,
0
)
)
# Add radial dimension
sketchCircle = sketch.sketchCurves.sketchCircles.addByCenterRadius(centerPoint, radius)
sketch.areDimensionsShown = True
sketch.sketchDimensions.addRadialDimension(
sketchCircle,
adsk.core.Point3D.create(
centerPoint.x + radius,
centerPoint.y,
centerPoint.z
)
)
elif geometry.curveType == adsk.core.Curve3DTypes.Arc3DCurveType:
# Handle arc edges
arc = edge.geometry
centerPoint = sketch.modelToSketchSpace(arc.center)
startPoint = sketch.modelToSketchSpace(arc.startPoint)
endPoint = sketch.modelToSketchSpace(arc.endPoint)
radius = arc.radius
startAngle = arc.startAngle
endAngle = arc.endAngle
sketchArc = sketch.sketchCurves.sketchArcs.addByCenterStartSweep(centerPoint, startPoint, endAngle - startAngle)
sketch.areDimensionsShown = True
sketch.sketchDimensions.addRadialDimension(
sketchArc,
adsk.core.Point3D.create(
centerPoint.x + radius,
centerPoint.y,
centerPoint.z
)
)
except Exception as e:
adsk.core.Application.get().userInterface.messageBox(f"Error in add_dimensions_to_sketch: {str(e)}")
class scriptExecuteHandler(adsk.core.CommandCreatedEventHandler):
def __init__(self):
super().__init__()
def notify(self, eventArgs: adsk.core.CommandCreatedEventArgs) -> None:
try:
# Your main script logic goes here
app = adsk.core.Application.get()
ui = app.userInterface
design = app.activeProduct
# Get the root component of the active design
root_comp = design.rootComponent
# Get all selected entities (faces) from the user's selection
selected_entities = ui.activeSelections
selected_faces = []
# Filter and collect selected faces
for selection in selected_entities:
if isinstance(selection.entity, adsk.fusion.BRepFace):
selected_faces.append(selection.entity)
# Check if faces are selected
if selected_faces:
# Create a new offset plane at 0 offset from the selected face
offset_plane = create_offset_plane(selected_faces[0], root_comp)
if offset_plane:
# Create a new sketch on the offset plane
sketches = root_comp.sketches
sketch = sketches.add(offset_plane)
# Add dimensions to the sketch based on the selected face
add_dimensions_to_sketch(sketch, selected_faces[0])
except Exception as e:
ui.messageBox(f"Error in scriptExecuteHandler.notify(): {str(e)}")
def run(context):
global _handlers
cmdDef = ui.commandDefinitions.itemById(CMD_ID)
if not cmdDef:
cmdDef = ui.commandDefinitions.addButtonDefinition(CMD_ID, CMD_ID, CMD_ID, ".\\")
onCommandCreated = scriptExecuteHandler()
cmdDef.commandCreated.add(onCommandCreated)
_handlers.append(onCommandCreated)
workspace = ui.workspaces.itemById(WORKSPACE_ID)
toolbar_tab = workspace.toolbarTabs.itemById(TOOLBARTAB_ID)
panel = toolbar_tab.toolbarPanels.itemById(TOOLBARPANEL_ID)
control = panel.controls.addCommand(cmdDef)
control.isPromoted = True
def stop(context):
global _handlers
_handlers = []
try:
ui.commandDefinitions.itemById(CMD_ID).deleteMe()
except:
pass
workspace = ui.workspaces.itemById(WORKSPACE_ID)
toolbar_tab = workspace.toolbarTabs.itemById(TOOLBARTAB_ID)
panel = toolbar_tab.toolbarPanels.itemById(TOOLBARPANEL_ID)
try:
panel.controls.itemById(CMD_ID).deleteMe()
except:
pass
# Entry point of Fusion 360 script
if __name__ == '__main__':
app = adsk.core.Application.get()
ui = app.userInterface
if ui:
# Prompt the user to run the script
ui.messageBox('Click OK to run the script.')
try:
run(None)
except Exception as e:
adsk.core.Application.get().userInterface.messageBox(f"Unhandled exception: {str(e)}")