Fix sibling component intersections in fused CAD exports (#939)#1384
Conversation
PR RemindersThis PR has changes in
This is an automated reminder from CI |
…y intersect and remove farfield
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1384 +/- ##
==========================================
- Coverage 73.21% 73.19% -0.03%
==========================================
Files 324 324
Lines 28556 28594 +38
==========================================
+ Hits 20908 20928 +20
- Misses 7648 7666 +18
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
…ild-relations-for-fused-iges-exports
|
Thank you for that really cool fix. Looks very good. I also tried some configs and everything worked as intended. |
Maybe. Its still used in examples, unit tests and, most critically, in the duct and control surface code. I suppose we could remove it, but I suggest as part of a separate issue. What do you think?
boolean_operations/CFuseShapes.cpp:#include "CFuseShapes.h"
boolean_operations/CFuseShapes.cpp:CFuseShapes::CFuseShapes(const PNamedShape parent, const ListPNamedShape &childs)
boolean_operations/CFuseShapes.cpp:CFuseShapes::~CFuseShapes()
boolean_operations/CFuseShapes.cpp:const PNamedShape CFuseShapes::NamedShape()
boolean_operations/CFuseShapes.cpp:CFuseShapes::operator PNamedShape()
boolean_operations/CFuseShapes.cpp:const ListPNamedShape &CFuseShapes::Intersections()
boolean_operations/CFuseShapes.cpp:const ListPNamedShape &CFuseShapes::TrimmedChilds()
boolean_operations/CFuseShapes.cpp:const PNamedShape CFuseShapes::TrimmedParent()
boolean_operations/CFuseShapes.cpp:void CFuseShapes::Perform()
boolean_operations/CFuseShapes.cpp:void CFuseShapes::Clear()
boolean_operations/CFuseShapes.cpp:void CFuseShapes::DoFuse()
boolean_operations/CFuseShapes.h: * @brief CFuseShapes Implement a fuse, where the childs are fused with the parent
boolean_operations/CFuseShapes.h:class CFuseShapes
boolean_operations/CFuseShapes.h: TIGL_EXPORT CFuseShapes(const PNamedShape parent, const ListPNamedShape& childs);
boolean_operations/CFuseShapes.h: TIGL_EXPORT virtual ~CFuseShapes();
control_devices/CCPACSControlSurfaces.cpp: fusedBoxes = CFuseShapes(fusedBoxes, childs);
control_devices/CCPACSControlSurfaces.cpp: fusedBoxes = CFuseShapes(fusedBoxes, childs);
ducts/CCPACSDuctAssembly.cpp:#include "CFuseShapes.h"
ducts/CCPACSDuctAssembly.cpp: tool = CFuseShapes(parentDuct, childDucts); |
Description
Fixes #939.
Fused IGES/STEP/BRep exports of a full aircraft only considered CPACS parent-child relationships when fusing components. Sibling components that geometrically intersect one another but not through their shared parent (e.g. a horizontal and vertical tailplane that both attach to the fuselage and also intersect each other near the tail) were never fused against each
other. Their overlap region showed up as unfused/internal geometry in the exported solid.
An initial fix made the fusing algorithm consider all sibling components pairwise instead of only parent-child pairs, but this still fused them one pair at a time (running result + next component). That incremental approach cannot correctly resolve a genuine mutual/triple intersection between three or more components meeting in the same region (fuselage + HTP + VTP all overlapping near the tail) - it produced a self-intersecting solid with missing faces once tested against a more realistic geometry.
This PR replaces the incremental pairwise fuse with a single n-ary BRepAlgoAPI_Fuse operation over all aircraft components at once (CTiglFusePlane::Perform()), which resolves mutual intersections between any number of components consistently in one pass. A proper TopoDS_SOLID is rebuilt from the operation's result, and per-component face names are propagated for exporters and TiGLCreator picking.
The pairwise intersection-curve computation (used only for the seam overlay in exports and in TiGLCreator's fused-aircraft view, not for the fused solid itself) was reworked so each curve is trimmed against every other component, avoiding stray untrimmed seam wires. This computation is also now performed lazily, only when a caller actually requests it via Intersections(), instead of unconditionally inside Perform() - this alone roughly halves the regression test's runtime and speeds up every other caller that only needs the fused solid. The overlay in TiGLCreator was removed to make the fused visualization faster.
How Has This Been Tested?
tests/integrationtests/testSiblingComponentFuse.cppwith a realistic test geometry wherefuselage, HTP and VTP all pairwise intersect near the tail. The test checks that the fused shape is topologically valid and has no internal/buried faces.
aircraft fused (slow)" draw action
Screenshots, that help to understand the changes(if applicabl
Checklist for PR Author:
ChangeLog.mdupdatedDisclaimer: Parts of this PR were developed with the assistance
(Anthropic's AI coding agent). I have reviewed, tested, and manu
all changes myself before submitting.
Differences in fuse behavior on main and the pr branch
C23 from digital hangar is missing tailplane after fuse
On main:
Both versions aren't correct
D250-TF-2040 from digital hangar
On main (or more precisely on 1388 crash when usind draw fused aircraft triangulation #1389)
Similar issue on main but not on this branch for D250-TFLH2-MHEP-2040 from digital hangar.
I suggest to merge this. From the randomly selected CPACS files the behavior on this branch seems more robust. The C23 has issues both on main and on this branch. This should be examined as part of a separate issue.