/// \file 09_brep_fab/main.cpp /// \brief Fabrication-oriented B-Rep modeling: box → shell → STEP + GLB export /// /// Demonstrates a typical design-for-manufacturing workflow using boundary /// representation (B-Rep). The part is exported both to STEP (AP214, for /// CAM/CNC) and to GLB (for quick 3D preview in any viewer). #include #include #include #include #include #include using namespace vde::brep; using namespace vde::foundation; using namespace vde::core; // ═══════════════════════════════════════════════════════════════════════ // Main — B-Rep Fabrication // ═══════════════════════════════════════════════════════════════════════ int main() { std::cout << std::fixed << std::setprecision(3); std::cout << "╔══════════════════════════════════╗\n" << "║ B-Rep Fabrication ║\n" << "╚══════════════════════════════════╝\n\n"; // ── Step 1: Base solid box ─────────────────────────────────────── // // External dimensions: 100 × 50 × 30 mm (typical enclosure part) double w = 100.0, h = 50.0, d = 30.0; auto part = make_box(w, h, d); AABB3D bb_raw = part.bounds(); std::cout << "Step 1: make_box(" << w << ", " << h << ", " << d << ")\n" << " volume: " << w * h * d << " mm³ (raw)\n" << " bbox: (" << bb_raw.min().x() << ", " << bb_raw.min().y() << ", " << bb_raw.min().z() << ") → (" << bb_raw.max().x() << ", " << bb_raw.max().y() << ", " << bb_raw.max().z() << ")\n"; // ── Step 2: Shell to a thin-walled enclosure ───────────────────── // // face_id = -1 → closed shell (no openings, hollow interior) // thickness = 2.0 mm → typical for injection-moulded / 3D-printed parts const double wall_thickness = 2.0; part = shell(part, -1, wall_thickness); AABB3D bb_shell = part.bounds(); std::cout << "\nStep 2: shell(face_id=-1, thickness=" << wall_thickness << ")\n" << " faces: " << part.num_faces() << "\n" << " edges: " << part.num_edges() << "\n" << " bbox: (" << bb_shell.min().x() << ", " << bb_shell.min().y() << ", " << bb_shell.min().z() << ") → (" << bb_shell.max().x() << ", " << bb_shell.max().y() << ", " << bb_shell.max().z() << ")\n"; // ── Step 3: Export to STEP for CAM ──────────────────────────────── // // AP214 format is the standard exchange format for CNC machining, // 5-axis milling, sheet-metal bending, and coordinate measurement. std::cout << "\nStep 3: Export STEP (AP214)\n"; const char* step_path = "output_fab.stp"; export_step_file(step_path, {part}); // Show the raw STEP header for verification std::string step_str = export_step({part}); // Find the end of the header section auto header_end = step_str.find("FILE_SCHEMA"); if (header_end != std::string::npos) { header_end = step_str.find("ENDSEC;", header_end); } size_t preview_len = std::min(header_end + 6, step_str.size()); if (preview_len > 0 && preview_len < step_str.size()) { std::cout << " → " << step_path << " (" << step_str.size() << " chars)\n"; std::cout << " Header excerpt:\n" << step_str.substr(0, preview_len) << "\n ...\n"; } else { std::cout << " → " << step_path << " (" << step_str.size() << " chars)\n"; } // ── Step 4: Export to GLB for 3D preview ───────────────────────── std::cout << "\nStep 4: Export GLB for visualization\n"; const char* glb_path = "output_fab.glb"; const int tess_res = 32; // segments per curved edge if (write_brep_gltf(glb_path, part, tess_res)) { std::cout << " → " << glb_path << " (tessellation level " << tess_res << ")\n"; std::cout << " Open in: gltf-viewer.donmccurdy.com, blender, three.js editor\n"; } else { std::cerr << " ✗ Failed to write " << glb_path << "\n"; return 1; } // ── Summary ────────────────────────────────────────────────────── std::cout << "\n╔══════════════════════════════════════════╗\n" << "║ Export Summary ║\n" << "╠══════════════════════════════════════════╣\n" << "║ B-Rep → STEP (CAM/CNC) ✓ ║\n" << "║ B-Rep → GLB (Preview) ✓ ║\n" << "╚══════════════════════════════════════════╝\n"; std::cout << "\nDone.\n"; return 0; }