4f75bb8b07
Add IGES v5.3 export for B-Rep models with: - Entity mapping: Point(116), Line(110), Circular Arc(100), B-Spline Curve(126), Plane(108), B-Spline Surface(128), Vertex(502), Edge(504), Loop(508), Face(510), Shell(514), Manifold Solid B-Rep(186) - Auto-detection of circular arcs (degree-2 NURBS with isosceles control triangle) and planes (1x1 degree surfaces) - Fixed 80-column IGES format with S/G/D/P/T sections - Header-only format_utils.h for IGES/STEP number formatting New files: - include/vde/foundation/format_utils.h - include/vde/brep/iges_export.h - src/brep/iges_export.cpp - tests/brep/test_iges_export.cpp
60 lines
1.8 KiB
C++
60 lines
1.8 KiB
C++
#pragma once
|
|
#include "vde/core/point.h"
|
|
#include <string>
|
|
#include <sstream>
|
|
#include <iomanip>
|
|
#include <cmath>
|
|
#include <cstdio>
|
|
|
|
namespace vde::foundation {
|
|
|
|
/// Format double with adequate precision for CAD (12 significant digits)
|
|
inline std::string fmt_double(double v, int precision = 12) {
|
|
if (std::isnan(v)) return "0.0";
|
|
if (std::isinf(v)) return v > 0 ? "1e30" : "-1e30";
|
|
std::ostringstream ss;
|
|
ss << std::setprecision(precision) << std::scientific << v;
|
|
std::string s = ss.str();
|
|
// Ensure always has exponent sign (e.g., "1.0e+00" not "1.0e00")
|
|
auto epos = s.find('e');
|
|
if (epos != std::string::npos) {
|
|
if (epos + 1 < s.size() && s[epos + 1] != '-' && s[epos + 1] != '+') {
|
|
s.insert(epos + 1, "+");
|
|
}
|
|
}
|
|
return s;
|
|
}
|
|
|
|
/// Format for IGES: uses D exponent
|
|
inline std::string fmt_iges_real(double v) {
|
|
auto s = fmt_double(v, 12);
|
|
auto pos = s.find('e');
|
|
if (pos != std::string::npos) s[pos] = 'D';
|
|
return s;
|
|
}
|
|
|
|
/// Format a Point3D as comma-separated reals
|
|
inline std::string fmt_point(const core::Point3D& p, bool use_d = false) {
|
|
auto fmt = use_d ? fmt_iges_real : fmt_double;
|
|
return fmt(p.x()) + "," + fmt(p.y()) + "," + fmt(p.z());
|
|
}
|
|
|
|
/// Pad a string to exactly 72 characters with spaces
|
|
inline std::string pad72(const std::string& s) {
|
|
std::string result = s;
|
|
if (result.size() > 72) result.resize(72);
|
|
result.resize(72, ' ');
|
|
return result;
|
|
}
|
|
|
|
/// Format an IGES section line: data + section marker (80 columns total)
|
|
inline std::string format_iges_line(const std::string& data, char section_char, int seq) {
|
|
std::string line = pad72(data);
|
|
char seq_buf[9];
|
|
std::snprintf(seq_buf, sizeof(seq_buf), "%c%07d", section_char, seq);
|
|
line += std::string(seq_buf);
|
|
return line + "\n";
|
|
}
|
|
|
|
} // namespace vde::foundation
|