<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Aligning component Origin to Body in Fusion API and Scripts Forum</title>
    <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10292507#M8943</link>
    <description>&lt;P&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/8795735"&gt;@corijn&lt;/a&gt;&amp;nbsp;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Changed to use the getPrincipalAxes method to create a Minimal Box.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-E05D2232-BCD2-4588-8C1A-9FC766AAFA41" target="_blank" rel="noopener"&gt;https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-E05D2232-BCD2-4588-8C1A-9FC766AAFA41&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;# Fusion360API Python script
import adsk.core, adsk.fusion, traceback

def run(context):
    ui = adsk.core.UserInterface.cast(None)
    try:
        app :adsk.fusion.Application = adsk.core.Application.get()
        ui = app.userInterface
        des :adsk.fusion.Design = app.activeProduct

        # select body
        msg :str = 'Select Body'
        selFiltter :str = 'Bodies'
        sel :adsk.core.Selection = selectEnt(msg ,selFiltter)
        if not sel: return

        # get OrientedBoundingBox3D
        body = sel.entity
        bBox :adsk.core.OrientedBoundingBox3D = getBoundingBox(body)

        # Confirmation
        initBoundingBox(body, bBox)

        # show info
        unitsMgr = des.unitsManager
        defLenUnit = unitsMgr.defaultLengthUnits
        covUnit = unitsMgr.convert(1, unitsMgr.internalUnits, defLenUnit)

        ui.messageBox('{}\nlength:{:.3f}{}\nwidth:{:.3f}{}\nheight:{:.3f}{}'.format(
            body.name,
            covUnit * bBox.length, defLenUnit,
            covUnit * bBox.width, defLenUnit,
            covUnit * bBox.height, defLenUnit,
        ))

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def getBoundingBox(
    body :adsk.fusion.BRepBody) -&amp;gt; adsk.core.OrientedBoundingBox3D:

    # get vecter3D
    prop :adsk.fusion.PhysicalProperties = body.physicalProperties
    _, xAxis, yAxis, _ = prop.getPrincipalAxes()

    # get MeasureManager
    app :adsk.fusion.Application = adsk.core.Application.get()
    measMgr :adsk.core.MeasureManager = app.measureManager

    return measMgr.getOrientedBoundingBox(body, yAxis, xAxis)


def selectEnt(
        msg :str, 
        filtterStr :str) -&amp;gt; adsk.core.Selection :

    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        sel = ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None


def initBoundingBox(
    body :adsk.fusion.BRepBody,
    bBox :adsk.core.OrientedBoundingBox3D):

    # brepBody
    tmpMgr :adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get()
    bRepBox = tmpMgr.createBox(bBox)

    # get comp
    app :adsk.fusion.Application = adsk.core.Application.get()
    des :adsk.fusion.Design = app.activeProduct
    root :adsk.fusion.Component = des.rootComponent

    # add body
    box = adsk.fusion.BRepBody.cast(None)
    if des.designType == adsk.fusion.DesignTypes.DirectDesignType:
        box = root.bRepBodies.add(bRepBox)
        box.opacity = 0.5
    else:
        baseFeatures = root.features.baseFeatures
        baseFeature = baseFeatures.add()
        baseFeature.startEdit()

        try:
            box = root.bRepBodies.add(bRepBox, baseFeature)
            box.opacity = 0.5
        except:
            pass
        finally:
            baseFeature.finishEdit()&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The initBoundingBox function is for confirmation, so please delete it if you do not need it.&lt;/P&gt;</description>
    <pubDate>Wed, 05 May 2021 14:59:57 GMT</pubDate>
    <dc:creator>kandennti</dc:creator>
    <dc:date>2021-05-05T14:59:57Z</dc:date>
    <item>
      <title>Aligning component Origin to Body</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10287382#M8940</link>
      <description>&lt;P&gt;I'm running into edge cases with my Bill of Material script where a the body of a component was drawn at an angle, making the origin's axis alignment not match the actual board alignment. Simplest way to put it would be I have bodies that were created at 45 degree angles, not rotated to 45 degree angles as a component. This means their bounding box is completely off. See attached screenshot. Not even a recalculated "closest fitting bounding box" fixes this if the reference coordinate system is misaligned.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'd like to programmatically fix this when my BOM script runs. I'd imagine something like calculating surface normal vectors for all faces, picking the one with the largest surface area, then transforming the body by that vector, then transforming&amp;nbsp; the component to the reverse, effectively keeping things in place but rotating the origin.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;I'm a bit too green with Fusion's Python API so perhaps somebody can point me in the right direction for this?&lt;/P&gt;&lt;DIV&gt;&amp;nbsp;&lt;/DIV&gt;</description>
      <pubDate>Mon, 03 May 2021 16:28:15 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10287382#M8940</guid>
      <dc:creator>corijn</dc:creator>
      <dc:date>2021-05-03T16:28:15Z</dc:date>
    </item>
    <item>
      <title>Re: Aligning component Origin to Body</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10288480#M8941</link>
      <description>&lt;P&gt;Hi&amp;nbsp;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/8795735"&gt;@corijn&lt;/a&gt;&amp;nbsp;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Although it does not the Minimal Box, we have created a sample to get a BoundingBox with the orientation of the origin of the component to which the selected body belongs.&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;# Fusion360API Python script
import adsk.core, adsk.fusion, traceback

def run(context):
    ui = adsk.core.UserInterface.cast(None)
    try:
        app :adsk.fusion.Application = adsk.core.Application.get()
        ui = app.userInterface
        des :adsk.fusion.Design = app.activeProduct

        # select body
        msg :str = 'Select Body'
        selFiltter :str = 'Bodies'
        sel :adsk.core.Selection = selectEnt(msg ,selFiltter)
        if not sel: return

        # get OrientedBoundingBox3D
        body = sel.entity
        bBox :adsk.core.OrientedBoundingBox3D = getBoundingBox(body)

        # show info
        unitsMgr = des.unitsManager
        defLenUnit = unitsMgr.defaultLengthUnits
        covUnit = unitsMgr.convert(1, unitsMgr.internalUnits, defLenUnit)

        ui.messageBox('{}\nlength:{:.3f}{}\nwidth:{:.3f}{}\nheight:{:.3f}{}'.format(
            body.name,
            covUnit * bBox.length, defLenUnit,
            covUnit * bBox.width, defLenUnit,
            covUnit * bBox.height, defLenUnit,
        ))

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def getBoundingBox(
    body :adsk.fusion.BRepBody) -&amp;gt; adsk.core.OrientedBoundingBox3D:

    # get occ
    occ :adsk.fusion.Occurrence = body.assemblyContext

    # get Vector3D
    mat :adsk.core.Matrix3D = adsk.core.Matrix3D.create()
    if occ:
        mat = occ.transform

    _, xAxis, yAxis, _ = mat.getAsCoordinateSystem()

    # get MeasureManager
    app :adsk.fusion.Application = adsk.core.Application.get()
    measMgr :adsk.core.MeasureManager = app.measureManager

    return measMgr.getOrientedBoundingBox(body, yAxis, xAxis)


def selectEnt(
        msg :str, 
        filtterStr :str) -&amp;gt; adsk.core.Selection :

    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        sel = ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Tue, 04 May 2021 03:35:06 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10288480#M8941</guid>
      <dc:creator>kandennti</dc:creator>
      <dc:date>2021-05-04T03:35:06Z</dc:date>
    </item>
    <item>
      <title>Re: Aligning component Origin to Body</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10292265#M8942</link>
      <description>&lt;P&gt;Hi, thanks for your response. I tried it out but it seems to be doing the same thing: it's using the assembly context/orientation of the component. I would need to extract that Vector3D (xAxis, yAxis) from the body itself, by analyzing its geometry. Something like comparing edge or surface orientations and deriving a useable axis alignment from those. Your example does show the use of:&lt;/P&gt;&lt;PRE&gt;measMgr.getOrientedBoundingBox(body, yAxis, xAxis)&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;which is part of what I'm looking for....&lt;/P&gt;</description>
      <pubDate>Wed, 05 May 2021 13:37:41 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10292265#M8942</guid>
      <dc:creator>corijn</dc:creator>
      <dc:date>2021-05-05T13:37:41Z</dc:date>
    </item>
    <item>
      <title>Re: Aligning component Origin to Body</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10292507#M8943</link>
      <description>&lt;P&gt;&lt;a href="https://forums.autodesk.com/t5/user/viewprofilepage/user-id/8795735"&gt;@corijn&lt;/a&gt;&amp;nbsp;.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;Changed to use the getPrincipalAxes method to create a Minimal Box.&lt;/P&gt;
&lt;P&gt;&lt;A href="https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-E05D2232-BCD2-4588-8C1A-9FC766AAFA41" target="_blank" rel="noopener"&gt;https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-E05D2232-BCD2-4588-8C1A-9FC766AAFA41&lt;/A&gt;&amp;nbsp;&lt;/P&gt;
&lt;LI-CODE lang="python"&gt;# Fusion360API Python script
import adsk.core, adsk.fusion, traceback

def run(context):
    ui = adsk.core.UserInterface.cast(None)
    try:
        app :adsk.fusion.Application = adsk.core.Application.get()
        ui = app.userInterface
        des :adsk.fusion.Design = app.activeProduct

        # select body
        msg :str = 'Select Body'
        selFiltter :str = 'Bodies'
        sel :adsk.core.Selection = selectEnt(msg ,selFiltter)
        if not sel: return

        # get OrientedBoundingBox3D
        body = sel.entity
        bBox :adsk.core.OrientedBoundingBox3D = getBoundingBox(body)

        # Confirmation
        initBoundingBox(body, bBox)

        # show info
        unitsMgr = des.unitsManager
        defLenUnit = unitsMgr.defaultLengthUnits
        covUnit = unitsMgr.convert(1, unitsMgr.internalUnits, defLenUnit)

        ui.messageBox('{}\nlength:{:.3f}{}\nwidth:{:.3f}{}\nheight:{:.3f}{}'.format(
            body.name,
            covUnit * bBox.length, defLenUnit,
            covUnit * bBox.width, defLenUnit,
            covUnit * bBox.height, defLenUnit,
        ))

    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


def getBoundingBox(
    body :adsk.fusion.BRepBody) -&amp;gt; adsk.core.OrientedBoundingBox3D:

    # get vecter3D
    prop :adsk.fusion.PhysicalProperties = body.physicalProperties
    _, xAxis, yAxis, _ = prop.getPrincipalAxes()

    # get MeasureManager
    app :adsk.fusion.Application = adsk.core.Application.get()
    measMgr :adsk.core.MeasureManager = app.measureManager

    return measMgr.getOrientedBoundingBox(body, yAxis, xAxis)


def selectEnt(
        msg :str, 
        filtterStr :str) -&amp;gt; adsk.core.Selection :

    try:
        app = adsk.core.Application.get()
        ui = app.userInterface
        sel = ui.selectEntity(msg, filtterStr)
        return sel
    except:
        return None


def initBoundingBox(
    body :adsk.fusion.BRepBody,
    bBox :adsk.core.OrientedBoundingBox3D):

    # brepBody
    tmpMgr :adsk.fusion.TemporaryBRepManager = adsk.fusion.TemporaryBRepManager.get()
    bRepBox = tmpMgr.createBox(bBox)

    # get comp
    app :adsk.fusion.Application = adsk.core.Application.get()
    des :adsk.fusion.Design = app.activeProduct
    root :adsk.fusion.Component = des.rootComponent

    # add body
    box = adsk.fusion.BRepBody.cast(None)
    if des.designType == adsk.fusion.DesignTypes.DirectDesignType:
        box = root.bRepBodies.add(bRepBox)
        box.opacity = 0.5
    else:
        baseFeatures = root.features.baseFeatures
        baseFeature = baseFeatures.add()
        baseFeature.startEdit()

        try:
            box = root.bRepBodies.add(bRepBox, baseFeature)
            box.opacity = 0.5
        except:
            pass
        finally:
            baseFeature.finishEdit()&lt;/LI-CODE&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;The initBoundingBox function is for confirmation, so please delete it if you do not need it.&lt;/P&gt;</description>
      <pubDate>Wed, 05 May 2021 14:59:57 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10292507#M8943</guid>
      <dc:creator>kandennti</dc:creator>
      <dc:date>2021-05-05T14:59:57Z</dc:date>
    </item>
    <item>
      <title>Re: Aligning component Origin to Body</title>
      <link>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10292545#M8944</link>
      <description>&lt;P&gt;Fantastic! I have been googling so much but this GetPrincipalAxes is the perfect solution, no need to iterate the mesh vertices myself! Thank you very much!&lt;/P&gt;</description>
      <pubDate>Wed, 05 May 2021 15:16:29 GMT</pubDate>
      <guid>https://forums.autodesk.com/t5/fusion-api-and-scripts-forum/aligning-component-origin-to-body/m-p/10292545#M8944</guid>
      <dc:creator>corijn</dc:creator>
      <dc:date>2021-05-05T15:16:29Z</dc:date>
    </item>
  </channel>
</rss>

