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 <noreply@anthropic.com>
This commit is contained in:
Stephen Boddy
2026-07-16 04:02:57 +01:00
parent 2e9e75c7bd
commit 2ac92f01e4
+23
View File
@@ -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_) {