Announcements
Attention for Customers without Multi-Factor Authentication or Single Sign-On - OTP Verification rolls out April 2025. Read all about it here.

InternalValidationError when creating construction plane

Tim.Overbye
Explorer

InternalValidationError when creating construction plane

Tim.Overbye
Explorer
Explorer

Howdy,

 

I have a script to generate a half sphere and place holes in its surface randomly. It works fine for the first 10-20 holes then throws an error.

Failed:
Traceback (most recent call last):
  File "C:/Users/Tim/AppData/Roaming/Autodesk/Autodesk Fusion 360/API/Scripts/Star_form/Star_form.py", line 111, in run
    workplane = rootComp.constructionPlanes.add(workplaneinput)
  File "C:/Users/Tim/AppData/Local/Autodesk/webdeploy/production/6783e6b71d33852e05099c507cf8d926394ea32c/Api/Python/packages\adsk\fusion.py", line 12795, in add
    return _fusion.ConstructionPlanes_add(self, input)
RuntimeError: 2 : InternalValidationError : data_->execute(&obj, apiName) && obj

 

I'd appreciate any help, the full code is below.

 

 

#Author-
#Description-

from tkinter.messagebox import NO
import adsk.core, adsk.fusion, adsk.cam, traceback

import math

import random

id = 300*0.1
wall_thickness = 2 * 0.1


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

        doc = app.documents.add(adsk.core.DocumentTypes.FusionDesignDocumentType)
        design = app.activeProduct

        # Get the root component of the active design.
        rootComp = design.rootComponent

        # Create a new sketch on the xy plane.
        sketches = rootComp.sketches
        xyPlane = rootComp.xYConstructionPlane
        sketch = sketches.add(xyPlane)

        # Draw arcs.

        arc = sketch.sketchCurves.sketchArcs
        arc1 = arc.addByCenterStartSweep(adsk.core.Point3D.create(0, 0, 0), adsk.core.Point3D.create(id/2, 0, 0),math.pi)
        arc2 = arc.addByCenterStartSweep(adsk.core.Point3D.create(0, 0, 0), adsk.core.Point3D.create(id/2 + wall_thickness, 0, 0),math.pi)

        # Draw lines to close arcs.
        lines = sketch.sketchCurves.sketchLines
        line_1 = lines.addByTwoPoints(adsk.core.Point3D.create(id/2, 0, 0), adsk.core.Point3D.create(id/2 + wall_thickness, 0, 0))
        line_2 = lines.addByTwoPoints(adsk.core.Point3D.create(-id/2, 0, 0), adsk.core.Point3D.create(-id/2 - wall_thickness, 0, 0))

        # Draw center line to use as the axis of revolution.
        lines = sketch.sketchCurves.sketchLines
        axisLine = lines.addByTwoPoints(adsk.core.Point3D.create(-1, 0, 0), adsk.core.Point3D.create(1, 0, 0))

        # Get the profile defined by the circle.
        prof = sketch.profiles.item(0)

        # Create an revolution input to be able to define the input needed for a revolution
        # while specifying the profile and that a new body is to be created
        revolves = rootComp.features.revolveFeatures
        revInput = revolves.createInput(prof, axisLine, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)

        # Define that the extent is an angle of pi to get half of a sphere.
        angle = adsk.core.ValueInput.createByReal(math.pi)
        revInput.setAngleExtent(False, angle)

        # Create the extrusion.
        ext = revolves.add(revInput)
            
        body = ext.bodies[0]
        target_face = None

        # Create hole on body
        
        basesketch = rootComp.sketches.add(rootComp.xYConstructionPlane)
        basesketch.isVisible = False

        r = id/2 + wall_thickness

        # randomply place pt on half sphere
        for i in range(100):
                    # Get face
            for face in body.faces:
                surface = adsk.core.Sphere.cast(face.geometry)

                if (surface and math.fabs(surface.radius - (id/2 + wall_thickness)) < 1.0e-6 ):
                    target_face = face


            phi = random.random() * math.pi * 2.0
            theta = random.random() * math.pi*0.5

            x = r * math.sin(theta) * math.cos(phi)
            y = r * math.sin(theta) * math.sin(phi)
            z = r * math.cos(theta)

            # Create hole based on a point

            pt = adsk.core.Point3D.create(x, y, z)
            basesketchpoint = basesketch.sketchPoints.add(pt)


            if(target_face):

                # Create plane tangent to sphere
                
                workplaneinput = rootComp.constructionPlanes.createInput()  
                workplaneinput.setByTangentAtPoint(target_face, basesketchpoint)

                workplane = rootComp.constructionPlanes.add(workplaneinput)

                # Create hole
                holeinput = rootComp.features.holeFeatures.createSimpleInput(adsk.core.ValueInput.createByString('1 cm'))
                holeinput.setPositionByPoint(workplane, pt)
                holeinput.setDistanceExtent(adsk.core.ValueInput.createByReal(10))
                rootComp.features.holeFeatures.add(holeinput)
                
                # Hide workplane
                workplane.isLightBulbOn = False



    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))
0 Likes
Reply
Accepted solutions (1)
448 Views
4 Replies
Replies (4)

kandennti
Mentor
Mentor

Hi @Tim.Overbye .

 

I haven't checked the reason in detail, but it seems that sometimes the sketch point is not on the surface.

I'm sure there are better ways to do this, but you might want to make sure they are on the surface.

・・・
            if(target_face):
                # Check if the point is on the surface.
                if not isPointOnSurface(target_face, basesketchpoint):
                    continue

                # Create plane tangent to sphere
                workplaneinput = rootComp.constructionPlanes.createInput()  
                workplaneinput.setByTangentAtPoint(target_face, basesketchpoint)
・・・
def isPointOnSurface(
    target_face: adsk.fusion.BRepFace,
    basesketchpoint: adsk.fusion.SketchPoin,
    tolerance: float = 0.0001) -> bool:

    try:
        app: adsk.core.Application = adsk.core.Application.get()
        measMgr: adsk.core.MeasureManager = app.measureManager

        res: adsk.core.MeasureResults = measMgr.measureMinimumDistance(
            target_face,
            basesketchpoint
        )

        if res.value > tolerance:
            return False

        return True
    except:
        return False

 

0 Likes

Tim.Overbye
Explorer
Explorer

Thanks, I tried what you suggested but it didn't solve the problem.

 

I'm still not sure what the problem was but I got it working by creating all the construction planes in a single batch and then doing all the holes in a separate batch. I think the problem was related to using the object's surface after modifying it.

1 Like

BrianEkins
Mentor
Mentor
Accepted solution

I looked into this a bit and believe it is some kind of bug with Fusion.  I captured the XYZ coordinates from a failed run and then used those to test with.  It consistently failed on the last point, but I can interactively create a construction plane using that point.  What's especially weird is if I reordered the last point that failed to any other location in the point set, it was successful.

 

I would recommend another approach to do what you're doing that should be much faster to process and I think simpler too. You can use the functionality supported by the TemporaryBRep Object. I presented a class on this at Autodesk University a few years ago and that material is available here.

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
1 Like

Tim.Overbye
Explorer
Explorer

Thanks, I switched to the TemporaryBRep Object approach and everything's working now and significantly faster.

1 Like