Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Solution to components drifting when scaling entire project?

9 REPLIES 9
SOLVED
Reply
Message 1 of 10
awilliamwright
446 Views, 9 Replies

Solution to components drifting when scaling entire project?

Now, I know WHY this is happening. When I scale a complex project (which has components all over with many instanced copies), some components drift and move incorrectly, so that after the scale the entire project is broken and scattered. I know this is partly because of component-specific origins being out of sync with the project origin, or because I use the "move" tool too much, whatever the case.

 

However, is there a way to trick Fusion into avoiding this problem? There's no point in picking on me for using "bad practices" or any of that nonsense. The deed is done, I'm not changing my workflow regardless, let's move on past that. But is there way to write a script to bypass this issue? Even if all it can do is move the decimal around?

9 REPLIES 9
Message 2 of 10
kandennti
in reply to: awilliamwright

Hi @awilliamwright .

 

I did not understand the meaning of what you see as the problem.

Could you please attach as simple as possible f3d/f3z data that is reproducible?

Message 3 of 10
awilliamwright
in reply to: kandennti

 I attached a simple project that shows the error, where components drift after scaling. The beam instances were simply move/copied, the slat instances were component-pattern copied, but they both drift in the same way.

Message 4 of 10
kandennti
in reply to: awilliamwright

@awilliamwright .

 

Thanks for attaching the model.
I was able to confirm the phenomenon.

 

I think that the scaled criteria is always done at the origin of the component to which it belongs, so it does not get to the desired state.

 

I feel this is probably a Fusion360 specification.
It may be possible with the API to create a body that does not follow changes, only the result.

Message 5 of 10
kandennti
in reply to: awilliamwright

@awilliamwright .

 

Now that we know the cause of the misalignment, we created a script.

 

When the script is run, a dialog box appears to enter the scaling ratio, so enter any number.

# Fusion360API Python script

import traceback
import adsk.core as core
import adsk.fusion as fusion

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

        msg = '\n'.join(
            [
                'Scales all displayed bodies at once.',
                'Enter the scaling ratio.',
            ]
        )

        scale, res = ui.inputBox(
            msg,
            'scaling',
            '0.75',
        )

        if res:
            return

        if not is_float(scale):
            return

        exec_occurrence_show_bodies_scaling(
            float(scale)
        )

        ui.messageBox('Done')

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


def exec_occurrence_show_bodies_scaling(
    scale: float
) -> None:

    bodyLst: list = get_show_bodies()
    occLst: list = get_occ_list_by_bodies(bodyLst)

    move_occs(occLst, scale)

    app: core.Application = core.Application.get()
    des: fusion.Design = app.activeProduct
    des.snapshots.add()

    exec_scaling(bodyLst, scale)


def get_unique_bodies(
    bodyLst: list,
) -> list:

    dict = {}

    body: fusion.BRepBody = None
    for body in bodyLst:

        dict.setdefault(
            body.parentComponent.entityToken,
            body,
        )

    return list(dict.values())


def exec_scaling(
    bodyLst: list,
    scale: float,
) -> None:

    app: core.Application = core.Application.get()
    des: fusion.Design = app.activeProduct
    root: fusion.Component = des.rootComponent

    bodyLstUnique = get_unique_bodies(bodyLst)
    rootBodyLst = [b for b in bodyLst if b.parentComponent == root]
    bodyLstUnique.extend(rootBodyLst)

    objs: core.ObjectCollection = core.ObjectCollection.create()
    [objs.add(occ) for occ in bodyLstUnique]

    scaleFeats: fusion.ScaleFeatures = root.features.scaleFeatures
    scaleIpt: fusion.ScaleFeatureInput = scaleFeats.createInput(
        objs,
        root.originConstructionPoint,
        core.ValueInput.createByReal(scale),
    )
    scaleFeats.add(scaleIpt)


def move_occs(
    occLst: list,
    scale: float,
) -> None:

    occ: fusion.Occurrence = None
    for occ in occLst:
        mat: core.Matrix3D = occ.transform2.copy()
        origin, xAxis, yAxis, zAxis = mat.getAsCoordinateSystem()
        ary = origin.asArray()
        ary = [v * scale for v in ary]
        origin.setWithArray(ary)
        mat.setWithCoordinateSystem(origin, xAxis, yAxis, zAxis)
        occ.transform2 = mat


def get_occ_list_by_bodies(
    bodyLst: list
) -> list:

    app: core.Application = core.Application.get()
    des: fusion.Design = app.activeProduct
    root: fusion.Component = des.rootComponent

    dict = {}

    body: fusion.BRepBody = None
    for body in bodyLst:
        if body.parentComponent == root:
            continue

        occ: fusion.Occurrence = body.assemblyContext
        dict.setdefault(
            occ.entityToken,
            occ,
        )

    return list(dict.values())


def get_show_bodies() -> list:
    app: core.Application = core.Application.get()
    des: fusion.Design = app.activeProduct
    root: fusion.Component = des.rootComponent

    bodyLst = root.findBRepUsingPoint(
        core.Point3D.create(0,0,0),
        fusion.BRepEntityTypes.BRepBodyEntityType,
        10000000000,
        True,
    )

    return [b for b in bodyLst]


def is_float(
    txt: str
) -> bool:

    try:
        float(txt)
        return True
    except ValueError:
        return False

 

 

The position of the component (occurrence) is moved in advance to be in the proper position after scaling.

1.png

 

It is possible that this may not work, as I just checked with the attached data.

Message 6 of 10
awilliamwright
in reply to: kandennti

Well, either way, thank you so much for taking the time to put that together. I really appreciate that effort, because I'm very green with script writing!

 

So, I am able to get the script to work myself for simpler projects, but when I try and use it on the complex project I'm working on, it doesn't work. Oddly, it shuffles some components around but doesn't scale anything. It's very mysterious. Even stranger, if I click "revert position" after running the script, all the components snap back to where they're supposed to go (but nothing was scaled).

 

The first screenshot is of component drift with the script, the second screenshot is component drift using regular scaling.

 

mysterious drifting of components when using scaling scriptmysterious drifting of components when using scaling scriptcomponent drift when using regular scalingcomponent drift when using regular scaling

Message 7 of 10

Hi Mr AWilliamWright,

... scaling components/bodies is one thing ... but in most complex (parametric) models are operations like offset to face, construction planes, sketch's dims, etc., which are not easily scalable. Well, to be precise, they also could be, but under the condition that the design process considers such function/requirements and follows very strict (and costly) design rules.
However, there is always a ray of Sunny Sun Shinning, ... although it might be on a different Planet.
In your case, the hope is on the Planet called DirectModeling. The good thing is that it is not that far ... just a click away.
Convert (save the original first) your design to DM mode and apply the global scale. All should come out great ... I hope  😉.

Regards
MichaelT

MichaelT
Message 8 of 10
kandennti
in reply to: awilliamwright

@awilliamwright .

 

Excellent work.

 

I could certainly see cases where it would not work for data with more complex components.

After consulting with others on the Japanese forum, I learned that exporting with SAT and re-importing will make it component-independent.
(In the case of Step and Iges, the component relationship is maintained.)


Probably the easiest way is to export/import and scale with SAT.

Message 9 of 10
awilliamwright
in reply to: kandennti

I would agree. 

What I finally got to work was to export/import as a STEP, then do a move/copy of the bodies. That was the only way to not only clear the component relationships but also “flatten” all the instances and mirrors. It makes the project a giant mess of bodies (almost 2000), but it works. 

Message 10 of 10
MichaelT_123
in reply to: kandennti

Hi Kondennti-San,

You are a One-Of-The-Kind F360 Scripter. I don't think another one on this Planet matches your skill and proficiency.


Regarding the hard subject.
Understanding the difference between scaling real Design Geometry and scaling Design is essential.
Apart from the visible topology of objects (which can be sent to e.g. 3D printer), the latter contains intangible elements. Let's call them designs intents, which are not easily scalable or not at all.
The attached file demonstrates some trivial cases.
It is also worth pointing... to some dangers.
As designs with scaled elements can be nested in more complex assemblies, their design intents might become unsynchronized. When successively used as references, they may lead to excruciating head-scratching by consecutive drafters 🤕.
... so use scaling sparingly and certainly ... not frivolously!

 

DesignScaling_G.png


Regards
MichaelT

 

P.S.
Yes, the CAD system can possess full scalability, … but the more complex it is more difficult it is to achieve such functionality.

P.S. II

I re-edited, replaced term "draftsmen" with "drafters" as ... Artificial Intelligence warned me ... politely at this stage that:

Some readers may find the term draftsmen non-inclusive. If you don’t mean to specify gender in this context, a different term may be more effective.

 

MichaelT

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators