How Profiles in sketch are Index?

How Profiles in sketch are Index?

design_kunalp
Explorer Explorer
716 Views
3 Replies
Message 1 of 4

How Profiles in sketch are Index?

design_kunalp
Explorer
Explorer

I am Not good at programming only basic.

I am trying to extrude profile from sketch. 

 

sketch might be created by sketchLines && sketchCircles or by using DXF/CVS files data.

problem I faced is profile generated on same/identical sketch are index randomly every time I use Script.

maybe because sketch is defined in X-Y coordinate but sketching on yZConstructionPlane/Different Plane.

 

firstly, I thought Profile Indexing based on position from origin. then I thought based on Area of profile, small area index 0 to next. Both time there were two profiles at same distance from origin or have same area property. I didn't get any workaround for this.

 

it's like circle with two chords with same distance and normal to each other.Profile_Indexing_issue.png

 

 

This will also help me with generating standard aluminum profiles but as I know their C/S area I find profile to extrude by inspecting their Area.

 

 

 

#Author- Kunal_Panchal
#Description- Aluminium Profiles Data form MiniTec

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

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        ui.messageBox("Addin By Kunal Panchal",'Aluminium Profiles',0,2)

        design = adsk.fusion.Design.cast(app.activeProduct)
        design.designType = adsk.fusion.DesignTypes.ParametricDesignType
        
        # Get import manager
        importManager = app.importManager
        
        # Get root component
        rootComp = design.rootComponent

        #sketches
        sketches = rootComp.sketches
        #sketch = sketches.add(app.activeProduct)

        #Getting User Inputs
        (Profile, cancelled) = ui.inputBox( "Profile Code:",'MiniTec Aluminium Profile')
        (Length, cancelled) = ui.inputBox( 'Length In MM:','Profile Length')
        Length = float(Length)/10

        #Removed Conditional Statements to simplify code but it gives following data.
        DXF_File = 'directory to dxffile'
        Profile_Code = 'Name of part Created'
        ExtrudedArea = 7.56 #Cross Section Area of Profile in cm^2 

        #Create DXF
        dxfOptions = importManager.createDXF2DImportOptions(DXF_File, rootComp.yZConstructionPlane)
        dxfOptions.isViewFit = True
        # Import dxf file to root component
        importManager.importToTarget(dxfOptions, rootComp)

        #Find Sketch to Extrude
        sketch_avi = sketches.count
        sketch = design.rootComponent.sketches.item(sketch_avi-1)
        extrudes = rootComp.features.extrudeFeatures
        extrudedist = adsk.core.ValueInput.createByReal(Length)

        #To find Profile that Need to Extrude
        Area = []
        profile_avi = sketch.profiles.count
        for i in range(0,profile_avi):
            Inspect_Profile = sketch.profiles.item(i)
            areaProps = Inspect_Profile.areaProperties()
            area = areaProps.area
            Area.append(round(area, 2))
            #ui.messageBox(str(Area)) #For Debugging/Calculating area of each profile avilable in sketch

        prof = sketch.profiles.item(Area.index(ExtrudedArea))
        extrude = extrudes.addSimple(prof, extrudedist, adsk.fusion.FeatureOperations.NewBodyFeatureOperation)
        body1 = extrude.bodies.item(0)
        body1.name = Profile_Code
        ui.messageBox(Profile_Code+' Created','MiniTec Profile',0,2)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))

 

 

I their another way to optimize this and again if I know how profile are index, I don't need to inspect profiles in loop. 

0 Likes
Accepted solutions (2)
717 Views
3 Replies
Replies (3)
Message 2 of 4

kandennti
Mentor
Mentor
Accepted solution

Hi @design_kunalp .

 

There are many possible ways to do this, but why not find a profile that matches the area?

・・・
        extrudedist = adsk.core.ValueInput.createByReal(Length)

        # Get Profile to Extrude
        profs = get_profiles_by_area(
            sketch,
            ExtrudedArea
        )
        if len(profs) < 1:
            return

        # Create Extrude
        prof: adsk.fusion.Profile = None
        for prof in profs:
            extrude: adsk.fusion.ExtrudeFeature = extrudes.addSimple(
                prof,
                extrudedist,
                adsk.fusion.FeatureOperations.NewBodyFeatureOperation
            )
            extrude.bodies.item(0).name = Profile_Code

        ui.messageBox(Profile_Code+' Created','MiniTec Profile',0,2)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def get_profiles_by_area(
    sketch: adsk.fusion.Sketch,
    targetArea: float,
    tolerance: float = 0.001,
) -> list[adsk.fusion.Profile]:

    if sketch.profiles.count < 1:
        return []

    profs = []
    prof: adsk.fusion.Profile = None
    for prof in sketch.profiles:
        areaProps: adsk.fusion.AreaProperties = prof.areaProperties()
        print(areaProps.area)
        if abs(targetArea - areaProps.area) < tolerance:
            profs.append(prof)

    return profs
Message 3 of 4

kandennti
Mentor
Mentor
Accepted solution

If you know that they are the two smallest Areas in the profile, sort by Area and push out only two.

 

・・・
        extrudedist = adsk.core.ValueInput.createByReal(Length)

        # Get list of profiles sorted by Area
        profs = sorted(sketch.profiles, key =lambda x: x.areaProperties().area)

        # Create Extrude
        extrude: adsk.fusion.ExtrudeFeature = extrudes.addSimple(
            lst_to_objs(profs[:2]),
            extrudedist,
            adsk.fusion.FeatureOperations.NewBodyFeatureOperation
        )
        body: adsk.fusion.BRepBody = None
        for body in extrude.bodies:
            body.name = Profile_Code

        ui.messageBox(Profile_Code+' Created','MiniTec Profile',0,2)
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def lst_to_objs(
    profs: list[adsk.fusion.Profile]
) -> adsk.core.ObjectCollection:

    objs: adsk.core.ObjectCollection = adsk.core.ObjectCollection.create()
    [objs.add(p) for p in profs]

    return objs
Message 4 of 4

sylvain_boyer6TGNB
Enthusiast
Enthusiast

I am in the same situation and the solution above was helpful. However it failed with large profiles, extruding the voids of my profile.
I used the code snippet but modified it a little bit to use the perimeter of the profile rather the area.