Assembly 4 workbench

Discussion about the development of the Assembly workbench.
leoheck
Veteran
Posts: 1084
Joined: Tue Mar 13, 2018 5:56 pm
Location: Coffee shop

Re: Assembly 4 workbench

Post by leoheck »

NEW Question:

Does Asm4 or Freecad has something to list linked files, or to export the current file together with the linked files to a folder folder?

I want to share an Assembly file with online, but I have to keep other subassemblies files togueter.

Also, I have a bunch of files in the same folder... so this would help this process of sharing and organizing the design files.
leoheck
Veteran
Posts: 1084
Joined: Tue Mar 13, 2018 5:56 pm
Location: Coffee shop

Re: Assembly 4 workbench

Post by leoheck »

Zolko wrote:
Zolko, how do I get a file path of a App::Link object with python? Is it possible?
User avatar
Zolko
Veteran
Posts: 1993
Joined: Mon Dec 17, 2018 10:02 am

Re: Assembly 4 workbench

Post by Zolko »

leoheck wrote: Sat Oct 01, 2022 6:48 pm how do I get a file path of a App::Link object with python? Is it possible?
I don't know. You can get the document like this:

Code: Select all

Link.LinkedObject.Document.Name
There is probably a way to get the file path of the document, but I've never used it.
try the Assembly4 workbench for FreCAD
install with Tools > Addon Manager > Assembly4 — tutorials here and here
leoheck
Veteran
Posts: 1084
Joined: Tue Mar 13, 2018 5:56 pm
Location: Coffee shop

Re: Assembly 4 workbench

Post by leoheck »

Got it, the right reference to what you said is this one. However it does not have the file path.

Code: Select all

[link].getLinkedObject().Document.Name
The tooltip over the value in the Linked Object property shows the info I want. Just don't know how to get it.
Screenshot-20221002221525-616x244.png
Screenshot-20221002221525-616x244.png (29.83 KiB) Viewed 1457 times
leoheck
Veteran
Posts: 1084
Joined: Tue Mar 13, 2018 5:56 pm
Location: Coffee shop

Re: Assembly 4 workbench

Post by leoheck »

Ah, this solves my issue.

Code: Select all

[link].getLinkedObject().Document.FileName
leoheck
Veteran
Posts: 1084
Joined: Tue Mar 13, 2018 5:56 pm
Location: Coffee shop

Re: Assembly 4 workbench

Post by leoheck »

I could solve my issue of having a list of linked files with this code

Code: Select all

def find_linked_files():
    linked_files = []

    def list_files(obj):

        if obj == None:
            return

        if obj.TypeId == "App::Link":
            filename = obj.getLinkedObject().Document.FileName
            linked_files.append(filename)
            list_files(obj.LinkedObject)

        # Navigate on objects inside a folders
        if obj.TypeId == 'App::DocumentObjectGroup' or obj.TypeId == 'App::Part':
            for objname in obj.getSubObjects():
                subobj = obj.Document.getObject(objname[0:-1])
                list_files(subobj)

    for obj in (FreeCAD.ActiveDocument.Objects):
        list_files(obj)

    return linked_files

linked_files = find_linked_files()
for filename in sorted(set(linked_files)):
    print(filename)
Result on the console of this project that I am using to test.

Code: Select all

/home/lheck/Documents/diy-pcb-cnc/ASSembly.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/8mmx300_rod.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/8mmx500_rod.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Board4electronics.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Drill_bit.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FDM/Big_Corner/Big_Corner.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FDM/Emergency_button_case.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FDM/LSW_support_Y.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FDM/LSW_support_Z.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FDM/Light.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FDM/NEMA17_support.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/2020_V-slot_Al_extrusion/2020x450_V_slot_profile.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/2020_V-slot_Al_extrusion/2020x490_V_slot_profile.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/Corner/2020_corner_bracket.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/Coupling/Beam-coupling-8mm-5mm.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/Electrical Switches/EmergencyButton_LAY37.fcstd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/KFL08/KFL08.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/KP08/KP08.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/NEMA/NEMA_17_with_connector.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/SC8UU/SC8UU.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/SHF08/SHF08.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/SK08/SK08.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/Slot_T_nuts/Slot_T_nuts.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/T8_housing_bracket/T8_housing_bracket.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/T8_leadscrew/T8_leadscrew_350mm.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/T8_leadscrew/T8_leadscrew_500mm.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/FreeCAD-library/T8_screw_nut/Anti_backlash_nut/T8_antibacklash_nut_simplified.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Mototool.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Plate_03.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Plate_04.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Plate_05.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Side_wood.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Spacer_20.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Steel L-Bracket for NEMA 17.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Timing_belt_GT2.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Timing_pulley_GT2_20.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/Timing_pulley_GT2_60.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/step/Arduino_CNC_shield.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/step/Fuente_12V_10A.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/step/Green_indicator.FCStd
/home/lheck/Documents/diy-pcb-cnc/cad/step/Limit_SW_PCB.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/3D-printed_corner.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Base.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Bed_bottom.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Bed_full.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Bed_top.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Corner.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Electronics.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Emergency.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Green.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/SW_X.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/SW_Y.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/SW_Z.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Vertical_frame_XZ.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/XZ.FCStd
/home/lheck/Documents/diy-pcb-cnc/sub-assemblies/Z_axis.FCStd
User avatar
Kunda1
Veteran
Posts: 13233
Joined: Thu Jan 05, 2017 9:03 pm

Re: Assembly 4 workbench

Post by Kunda1 »

This is great @leoheck!
Alone you go faster. Together we go farther
Please mark thread [Solved]
Want to contribute back to FC? Checkout:
#lowhangingfruit | Use the Source, Luke. | How to Help FreeCAD | How to report FC bugs and features
leoheck
Veteran
Posts: 1084
Joined: Tue Mar 13, 2018 5:56 pm
Location: Coffee shop

Re: Assembly 4 workbench

Post by leoheck »

Kunda1 wrote: Mon Oct 03, 2022 11:38 am This is great @leoheck!
Thanks. Check this version here, then.

It generates a list of unique files OR a tree to explore the hierarchy of files.

Code: Select all

# Needs
# pip install anytree

def list_files(tree=0, relative_path=1):

    import os
    from anytree import Node, RenderTree

    def find_linked_files(relative_path=1):

        def find_files(obj, root_dirpath, level=0, relative_path=1, parent_node=None, parent_filepath=None):

            if obj == None:
                return

            filepath = obj.getLinkedObject().Document.FileName
            if relative_path:
                filepath = os.path.relpath(filepath, root_dirpath)

            if obj.TypeId == "App::Link":

                indexes_of_current_level = [idx for idx, s in enumerate(linked_files_level) if str(level) in str(s)]
                linked_files_at_current_level = [linked_files[idx] for idx in indexes_of_current_level]

                if not any(filepath in s for s in linked_files_at_current_level):

                    if filepath != parent_filepath:
                        linked_files.append(filepath)
                        linked_files_level.append(level)
                        node = Node(filepath, parent=parent_node)
                        find_files(obj.LinkedObject, root_dirpath, level+1, relative_path=relative_path, parent_node=node, parent_filepath=filepath)

            # Navigate on objects inside a folders
            if obj.TypeId == 'App::DocumentObjectGroup' or obj.TypeId == 'App::Part':
                for objname in obj.getSubObjects():
                    subobj = obj.Document.getObject(objname[0:-1])
                    find_files(subobj, root_dirpath, level, relative_path=relative_path, parent_node=parent_node, parent_filepath=filepath)

        linked_files = []
        linked_files_level = []
        level=0

        filepath = FreeCAD.ActiveDocument.FileName
        root_dirpath = os.path.dirname(filepath)
        if relative_path:
            filepath = os.path.relpath(filepath, root_dirpath)

        linked_files.append(filepath)
        linked_files_level.append(level)
        file_tree = Node(filepath)

        for obj in (FreeCAD.ActiveDocument.Objects):
            find_files(obj, root_dirpath, level=level, relative_path=relative_path, parent_node=file_tree, parent_filepath=filepath)

        return linked_files, linked_files_level, file_tree

    linked_files, linked_files_level, file_tree = find_linked_files(relative_path=relative_path)

    if not tree: # uniq
        for filepath in set(linked_files):
            print(filepath)
    else: # show tree
        for pre, fill, node in RenderTree(file_tree):
            print("%s%s" % (pre, node.name))

list_files(tree=1, relative_path=1)
And this is how you run it:

Code: Select all

# Shows a tree, using relative paths
list_files(tree=1, relative_path=1) 

# Present the list of files, absolute names, so it is easier to reuse the filepaths
list_files(tree=0, relative_path=0)
list_files(tree=0, relative_path=1) # It can be relative to the root path, too.
I put the code here too: https://gist.github.com/leoheck/0933ca6 ... 0e2a4f811b
project4
Posts: 234
Joined: Fri Jul 12, 2013 12:53 pm

Re: Assembly 4 workbench

Post by project4 »

Zolko,

I see the issue that require close/reopen of the newly created files still exist.
I just tried to create a model file from an existing STEP file, saved it and tried to import it into an assembly.
The part is shown with "unknown" name in the opened list.

Do you know where does it come from in the code so I could look on it?
Maybe all that should be done is setting some variables after save, something that is probably done in open logic?

I'll need to create many models based on existing STEP files, so I prefer to fix that issue once and for all.

Thanks.
User avatar
onekk
Veteran
Posts: 3746
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Assembly 4 workbench

Post by onekk »

project4 wrote: Sun Oct 09, 2022 11:07 am ....
I think that is not a proper issue.

When you create a new file, it has no name until you save it.

From this "fact" derive the "unnamed" name that you see in the treeview.

As FCStd files are "compressed directories" I think that is a design choice, and is not specific to Assembly4 WB.


So probably a newly created Assembly4 file until saved has no idea of where it will be until saved (You could even decide to save in some strange places) so probably it will not know how to set correct path to external files.

Better to ask probably on another forum as it is not a thing that depends on Zolko code.

I don't know if asking main FC developers to modify the "new file" behaviour to ask for a name when creating and save and reopen it "on the fly" will solve your problem or not.

Regards

Carlo D.
My English and Italian material about FreeCAD https://github.com/onekk/freecad-doc.
My Blog: https://onekk-maker.blogspot.com/

See on GitHub how to fund development

For Scripting courses, customized FC Design and Scripting job PM me.
Post Reply