STL export: objects end up in different locations - how to maintain origins?

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
0xCoto
Posts: 26
Joined: Wed Aug 10, 2022 3:56 pm

STL export: objects end up in different locations - how to maintain origins?

Post by 0xCoto »

I have the following Python code which takes a STEP file and exports each object as a separate STL file. It also exports an STL containing everything ("model.stl"):

Code: Select all

def step2stl(step_file="model.step", clear=True):
    doc = FreeCAD.newDocument("Unnamed")

    # Delete pre-existing STL files
    dir_name = "data"
    test = os.listdir(dir_name)

    for item in test:
        if item.endswith(".stl"):
            os.remove(os.path.join(dir_name, item))

    # Empty out tmp directory
    if clear:
        dir = "data/tmp"
        if os.path.exists(dir):
            shutil.rmtree(dir)
        os.makedirs(dir)

    # Import STEP file
    Import.insert("data/" + step_file, "Unnamed")

    obj_list = []
    for obj in FreeCAD.ActiveDocument.Objects:
        if hasattr(obj, "Shape"):
            obj_list.append(obj.Name)

    __objs__ = []
    for object in obj_list:
        __objs__.append(FreeCAD.getDocument("Unnamed").getObject(str(object)))

    Mesh.export(__objs__, "data/tmp/model.stl")

    del __objs__

    for object in obj_list:
        __objs__ = []
        if object.startswith("Part"):
            __objs__.append(FreeCAD.getDocument("Unnamed").getObject(str(object)))

        Mesh.export(__objs__, "data/" + str(object) + ".stl")

        del __objs__
However, in some cases like this one (STEP import):

Image

There is a different origin associated with each object, and if I export each STL separately, and then import them one by one, I get this offset:

Image

This happens with both the GUI fashion of importing and exporting, as well as the scripting way. Is there a way to tell FreeCAD to convert everything so that it uses a single global origin, so that my exported STL files remain intact (just like I nicely see it on FreeCAD's interface when I import the STEP file)?
jbi
Posts: 117
Joined: Sun Apr 24, 2016 3:28 pm

Re: STL export: objects end up in different locations - how to maintain origins?

Post by jbi »

I think you have to transform the geometry

Code: Select all

newbody=body.transformGeometry(body.Placement.toMatrix())
afterwards you can export this newbody.
Maybe transformShape is also working, but you have to check yourself (just check the Placement after transform, should be the origin)
User avatar
onekk
Veteran
Posts: 6146
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: STL export: objects end up in different locations - how to maintain origins?

Post by onekk »

Problem with STL is that is a triangulation (a shape made of triangles) so it is simply a bunch of vertexes that form the "shape".

You have two places that FC (FreeCAD) use to determine where to show your solid:

1) "Shape" property
2) "Placement" property

Probably the exporter use the Shape property.

You could consolidate both in "Shape" property use the advice above that will create a new solid.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
0xCoto
Posts: 26
Joined: Wed Aug 10, 2022 3:56 pm

Re: STL export: objects end up in different locations - how to maintain origins?

Post by 0xCoto »

jbi wrote: Sat Aug 13, 2022 8:37 am I think you have to transform the geometry

Code: Select all

newbody=body.transformGeometry(body.Placement.toMatrix())
afterwards you can export this newbody.
Maybe transformShape is also working, but you have to check yourself (just check the Placement after transform, should be the origin)
Thanks, I think I got the idea, but how exactly would I implement this transformation to the last part of the code? I tried a few ways but it seems like I need to handle the shape/part/object in a specific class/type?

Code: Select all

# Import STEP file
Import.insert("data/" + step_file, "Unnamed")

# Export full model as a single STL
obj_list = []
for obj in FreeCAD.ActiveDocument.Objects:
    if str(obj) == "<Part::PartFeature>":
        obj_list.append(obj)

def getObj(object):
    return FreeCAD.getDocument("Unnamed").getObject(str(object.Name))

__objs__ = list(map(getObj, obj_list))
Mesh.export(__objs__, "data/tmp/model.stl")

# Export each object as a separate STL
for object in obj_list:
    if object.Name.startswith("Part"):
        ### I guess the transform should take place here somehow? ###
        obj = FreeCAD.getDocument("Unnamed").getObject(str(object.Name))
        Mesh.export([obj], "data/" + str(object.Name) + ".stl")
jbi
Posts: 117
Joined: Sun Apr 24, 2016 3:28 pm

Re: STL export: objects end up in different locations - how to maintain origins?

Post by jbi »

Code: Select all

# Import STEP file
Import.insert("data/" + step_file, "Unnamed")

# Export full model as a single STL
obj_list = []
for obj in FreeCAD.ActiveDocument.Objects:
    if str(obj) == "<Part::PartFeature>":
        obj_list.append(obj)

def getObj(object):
    return FreeCAD.getDocument("Unnamed").getObject(str(object.Name))

__objs__ = list(map(getObj, obj_list))
Mesh.export(__objs__, "data/tmp/model.stl")

# Export each object as a separate STL
for object in obj_list:
    orig=FreeCAD.activeDocument().getObject(str(object.Name)) #changed to active document instead of FreeCAD.getDocument("Unnamed")
    transformed=orig.Shape.transformGeometry(orig.Placement.toMatrix())
    filename= "data/" + str(object.Name) + ".stl")
    transformed.exportStl(filename,0.1) #second parameter is deviation tolerance // don't know how to do it with Mesh.export()
I have changed the last few lines. But it is untested. If you need to use Mesh.export() someone else with deeper knowledge of the document objects should have a look.
Generally you make it for everybody far more interesting (and for you much more likely to get helped) if you provide a model with your post.
0xCoto
Posts: 26
Joined: Wed Aug 10, 2022 3:56 pm

Re: STL export: objects end up in different locations - how to maintain origins?

Post by 0xCoto »

jbi wrote: Sat Aug 13, 2022 5:52 pm I have changed the last few lines. But it is untested. If you need to use Mesh.export() someone else with deeper knowledge of the document objects should have a look.
I've attached the file (Wifi_Antenna.step). Looks like I'm getting the following error:

Code: Select all

Traceback (most recent call last):
  File "/home/apostolos/Desktop/api/solver_api.py", line 990, in <module>
    step2stl(step_file, clear=clear)
  File "/home/apostolos/Desktop/api/solver_api.py", line 54, in step2stl
    transformed=orig.Shape.transformGeometry(orig.Placement.toMatrix())
Part.OCCError: Geom_TrimmedCurve::parameters out of range
I also tested against a different model (attached, dipole.stp - which doesn't have any issues with multiple origins etc.), and this one seems to run, but it seems to have messed with the distances a bit.

Before (original model):
Image

After running the script:
Image
Attachments
dipole.step
(13.64 KiB) Downloaded 19 times
Wifi_Antenna.step
(456.51 KiB) Downloaded 11 times
User avatar
onekk
Veteran
Posts: 6146
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: STL export: objects end up in different locations - how to maintain origins?

Post by onekk »

Your screenshot seems to reveal that some recomputing is missing from the first image (blue marks on the icons).

Plus I don't know if STL is supporting multiple objects per file, as usually a STL file will contain a single triangulation.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
0xCoto
Posts: 26
Joined: Wed Aug 10, 2022 3:56 pm

Re: STL export: objects end up in different locations - how to maintain origins?

Post by 0xCoto »

onekk wrote: Sat Aug 13, 2022 10:21 pm Your screenshot seems to reveal that some recomputing is missing from the first image (blue marks on the icons).
I simply created the two cylinders in FreeCAD, positioned them and exported the file as STEP. I re-opened, and the model looks fine (never really paid attention to the blue marks since most of my CAD processing and STL exporting has worked OK).
onekk wrote: Sat Aug 13, 2022 10:21 pm Plus I don't know if STL is supporting multiple objects per file, as usually a STL file will contain a single triangulation.
If you select all objects and use File -> Export -> STL, it creates an STL file containing both objects as a single "object"/triangulation:
Image

Still not sure how to fix the origin problem though. :(
edwilliams16
Veteran
Posts: 3107
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: STL export: objects end up in different locations - how to maintain origins?

Post by edwilliams16 »

When I opened your WiFi_antenna.step file:
1) There's a recomputing problem. It never comes to a final answer.
2) Body001 and Shell001 appear to be identical and both are shells, not solid objects.

It seems that should be fixed first.
Post Reply