From 2ac92f01e46c4e324ed148c4951ec9841d376087 Mon Sep 17 00:00:00 2001 From: Stephen Boddy Date: Thu, 16 Jul 2026 04:02:57 +0100 Subject: [PATCH] Fix missing silhouette on curved analytic column/pile faces Circular-profile IfcColumn/IfcPile elements produce a genuine analytic cylindrical BRep face (via BRepPrimAPI_MakePrism), not a tessellated facet. The edge classification/extraction pipeline is edge-identity-based end to end, but a smooth surface's silhouette is synthesized by HLR on the fly and has no corresponding pre-existing edge to bucket, so it was silently dropped once any edge in the product had been classified. Add a face-level pass that includes any non-planar face directly in the outline bucket, giving HLR's per-face OutLine reconstruction a face identity to correlate against. Purely additive: diffing the whole test scene's output before and after shows only the two previously-missing tangent lines appear, nothing else changes. Generated with the assistance of an AI coding tool. Co-Authored-By: Claude Sonnet 5 --- src/serializers/SvgSerializer.cpp | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index f8fb64fa0c..2a4cb9c2b4 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -1436,6 +1436,29 @@ void SvgSerializer::write(const geometry_data& data) { } BBcls.Add(bucket_it->second, cls_edge); } + + // Non-planar faces (e.g. a real analytic cylindrical wall from a + // circular-profile column/pile, swept via BRepPrimAPI_MakePrism rather than + // faceted) have a silhouette that HLR synthesizes on the fly -- it is not a + // pre-existing topological edge, so the edge-only loop above can never bucket + // it. OutLineVCompound(S) correlates a curved face's silhouette by the + // identity of the originating *face*, not any edge, so add the non-planar + // face itself into the outline bucket alongside whatever edges it already + // contributed (top/bottom/seam), giving HLR's per-face OutLine reconstruction + // something to match against. + for (TopExp_Explorer fexp(*compound_to_hlr, TopAbs_FACE); fexp.More(); fexp.Next()) { + const TopoDS_Face& f = TopoDS::Face(fexp.Current()); + if (BRep_Tool::Surface(f)->DynamicType() != STANDARD_TYPE(Geom_Plane)) { + std::string name = edge_style_class_name(edge_style_class::outline); + auto bucket_it = classified_edge_buckets.find(name); + if (bucket_it == classified_edge_buckets.end()) { + TopoDS_Compound c; + BBcls.MakeCompound(c); + bucket_it = classified_edge_buckets.emplace(name, c).first; + } + BBcls.Add(bucket_it->second, f); + } + } } if (is_floor_plan_) {