Fix Collada exporter skipping App::Link geometry (#27974)

* Fix Collada exporter skipping App::Link geometry

Resolve App::Link objects recursively during export so referenced
geometry is included in the .dae output while preserving link placement.

* Arch: Fix Collada export for App::Link objects

The Collada exporter skipped geometry for App::Link instances because
it only handled objects directly present in the document.

This change resolves Link objects using getLinkedObject() and exports
their referenced geometry while applying the placement of the exporting
instance.

The original App::Part expansion behavior is preserved.

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* Arch: fix placement handling for App::Link and primitives in Collada export

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

* final change

* [pre-commit.ci] auto fixes from pre-commit.com hooks

for more information, see https://pre-commit.ci

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Gaurang-2005
2026-03-08 17:31:54 +00:00
committed by GitHub
co-authored by pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
parent 88940fb375
commit 11dd9d8870
+36 -6
View File
@@ -169,6 +169,23 @@ def read(filename):
FreeCAD.Gui.SendMsgToActiveView("ViewFit")
def get_global_placement(obj):
"""
Compute the global placement of an object by accumulating
placements from its parent containers.
"""
pl = obj.Placement
parent = obj.getParentGeoFeatureGroup()
while parent:
if hasattr(parent, "Placement"):
pl = parent.Placement.multiply(pl)
parent = parent.getParentGeoFeatureGroup()
return pl
def export(
exports: list[FreeCAD.DocumentObject],
filename: str,
@@ -219,21 +236,34 @@ def export(
addgroups=True,
)
objects = Arch.pruneIncluded(objects, strict=True)
for obj in objects:
is_link = obj.isDerivedFrom("App::Link")
if is_link:
real_obj = obj.getLinkedObject(True)
else:
real_obj = obj
if is_link:
global_pl = get_global_placement(obj)
elif hasattr(obj, "getGlobalPlacement"):
global_pl = obj.getGlobalPlacement()
else:
global_pl = obj.Placement
findex = np.array([])
m: Optional[Mesh.Mesh] = None
if obj.isDerivedFrom("Part::Feature"):
if real_obj.isDerivedFrom("Part::Feature"):
FreeCAD.Console.PrintMessage(
f'Exporting shape of object {obj.Name} ("{obj.Label}")' + "\n"
)
new_shape = obj.Shape.copy()
new_shape.Placement = obj.getGlobalPlacement()
m = Mesh.Mesh(triangulate(new_shape))
elif obj.isDerivedFrom("Mesh::Feature"):
shape = real_obj.Shape.copy()
shape.Placement = global_pl
m = Mesh.Mesh(triangulate(shape))
elif real_obj.isDerivedFrom("Mesh::Feature"):
FreeCAD.Console.PrintMessage(
f'Exporting mesh of object {obj.Name} ("{obj.Label}")' + "\n"
)
m = obj.Mesh
m = real_obj.Mesh.copy()
m.transform(global_pl.toMatrix())
elif obj.isDerivedFrom("App::Part"):
for child in obj.OutList:
objects.append(child)