Script for Dimensioning STP file

sidharthbabu8
Explorer

Script for Dimensioning STP file

sidharthbabu8
Explorer
Explorer

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.

sidharthbabu8_0-1719598227531.png

sidharthbabu8_1-1719598358733.png

 

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.

sidharthbabu8_2-1719598563047.png

 

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)}")

 

 

0 Likes
Replies (0)