IsoCurve Script

IsoCurve Script

OrhunUnal
Contributor Contributor
146 Views
0 Replies
Message 1 of 1

IsoCurve Script

OrhunUnal
Contributor
Contributor

 

I created IsoCurve script using ChatGPT, for now it works only on NURBS surfaces and the number of points of the generated curve is too much due to the number of spans of the surface.

IsoCurve Script

import adsk.core, adsk.fusion, adsk.cam, traceback

def create_isocurve(context):
    ui = None
    try:
        # Get Fusion 360 application and user interface
        app = adsk.core.Application.get()
        ui = app.userInterface
        design = app.activeProduct
        rootComp = design.rootComponent
        sketches = rootComp.sketches

        # Ask user to select a face
        ui.messageBox("Please select a face on the surface.")
        selection = ui.selectEntity("Select a surface face", "Faces")
        selected_face = adsk.fusion.BRepFace.cast(selection.entity)

        if not selected_face:
            ui.messageBox("No face selected.")
            return

        # Get the surface geometry of the face
        surface = selected_face.geometry
        if not isinstance(surface, adsk.core.Surface):
            ui.messageBox("Selected face is not a parametric surface.")
            return

        # Get the evaluator and parametric range
        evaluator = surface.evaluator
        param_range = evaluator.parametricRange()
        u_min, u_max = param_range.minPoint.x, param_range.maxPoint.x
        v_min, v_max = param_range.minPoint.y, param_range.maxPoint.y

        # Normalize and denormalize functions
        def normalize(value, min_val, max_val):
            return (value - min_val) / (max_val - min_val) if max_val != min_val else 0.0

        def denormalize(norm_value, min_val, max_val):
            return norm_value * (max_val - min_val) + min_val

        # Ask user for isocurve parameter
        param_input = ui.inputBox(
            "Enter the isocurve parameter value (Normalized Range: U: 0.0-1.0 or V: 0.0-1.0):",
            "Isocurve Parameter",
            "0.5"
        )

        if not param_input:
            ui.messageBox("Parameter value is invalid or was canceled.")
            return

        normalized_parameter = float(param_input[0])  # Fix: Access first element

        # Get user input for U or V direction
        direction_input = ui.inputBox("Enter the direction (u or v):", "Isocurve Direction", "u")

        if not direction_input:
            ui.messageBox("Direction value is invalid or was canceled.")
            return

        direction = direction_input[0].lower()

        if direction not in ['u', 'v']:
            ui.messageBox("Invalid direction. Please enter 'u' or 'v'.")
            return

        # Convert back to actual U/V parameter range
        if direction == 'u':
            actual_parameter = denormalize(normalized_parameter, u_min, u_max)
            degree = surface.degreeU  # Get U direction degree
        else:
            actual_parameter = denormalize(normalized_parameter, v_min, v_max)
            degree = surface.degreeV  # Get V direction degree

        if degree is None:
            ui.messageBox("The selected surface does not have a valid degree for the chosen direction.")
            return

        # Generate points for the isocurve
        num_points = max(degree + 1, 15)  # Ensure enough points for smooth curve
        start, end = 0.0, 1.0
        t_values = [start + (end - start) * i / (num_points - 1) for i in range(num_points)]
        curve_points = []

        for t in t_values:
            if direction == 'u':
                success, point = evaluator.getPointAtParameter(adsk.core.Point2D.create(actual_parameter, denormalize(t, v_min, v_max)))
            else:
                success, point = evaluator.getPointAtParameter(adsk.core.Point2D.create(denormalize(t, u_min, u_max), actual_parameter))

            if success:
                curve_points.append(adsk.core.Point3D.create(point.x, point.y, point.z))
            else:
                ui.messageBox("Failed to evaluate point at parameter. Ensure the parameter value is valid for the surface.")
                return

        # Ask user for spline type (shortened input)
        spline_type_input = ui.inputBox("Enter spline type (F for fitted, C for control):", "Spline Type", "f")

        if not spline_type_input:
            ui.messageBox("Spline type value is invalid or was canceled.")
            return

        spline_type_short = spline_type_input[0].lower()  # Get the first character

        # Convert short input to full type
        if spline_type_short == "f":
            spline_type = "fitted"
        elif spline_type_short == "c":
            spline_type = "control"
        else:
            ui.messageBox("Invalid input. Using 'fitted' as default.")
            spline_type = "fitted"

        # Create a sketch on the default XY plane
        sketch_plane = rootComp.xYConstructionPlane
        sketch = sketches.add(sketch_plane)

        # Convert curve points to ObjectCollection
        spline_points = adsk.core.ObjectCollection.create()
        for point in curve_points:
            spline_points.add(point)

        # Convert ObjectCollection to a Python list for control splines
        control_point_list = list(curve_points)  # FIX: No need for .cast()

        # Add spline to the sketch
        if spline_type == "control":
            sketch.sketchCurves.sketchControlPointSplines.add(control_point_list, degree)  # FIXED
        else:
            sketch.sketchCurves.sketchFittedSplines.add(spline_points)

        ui.messageBox(f"Isocurve created successfully as a {spline_type} spline.")

    except Exception as e:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

create_isocurve(None)

 

Also I created script for getting information about surface degree and span count

import adsk.core, adsk.fusion, adsk.cam, traceback

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        design = app.activeProduct

        if not design:
            ui.messageBox('No active Fusion 360 design.')
            return

        # Get the current selection
        selected_entities = ui.activeSelections

        if selected_entities.count != 1:
            ui.messageBox('Please select exactly one surface before running the script.')
            return

        selected_face = selected_entities.item(0).entity

        # Verify the selected entity is a face
        if not isinstance(selected_face, adsk.fusion.BRepFace):
            ui.messageBox('The selected entity is not a face.')
            return

        geom = selected_face.geometry

        # Ensure the selected face is a NURBS surface
        if not isinstance(geom, adsk.core.NurbsSurface):
            ui.messageBox('The selected face is not a NURBS surface.')
            return

        # Get degree and span count
        uDegree = geom.degreeU
        vDegree = geom.degreeV
        uControlPoints = geom.controlPointCountU
        vControlPoints = geom.controlPointCountV

        # Calculate span count
        uSpanCount = uControlPoints - uDegree
        vSpanCount = vControlPoints - vDegree

        # Display the results
        msg = f"""Surface Details:
        - U-Direction Degree: {uDegree}
        - V-Direction Degree: {vDegree}
        - U-Direction Control Points: {uControlPoints}
        - V-Direction Control Points: {vControlPoints}
        - U-Direction Span Count: {uSpanCount}
        - V-Direction Span Count: {vSpanCount}"""
        ui.messageBox(msg, 'Surface Degree and Span Count')

    except Exception as e:
        if ui:
            ui.messageBox(f'Failed: {traceback.format_exc()}')

 

0 Likes
147 Views
0 Replies
Replies (0)