080776930f
- 08_3d_print: Complete SDF→marching cubes→STL pipeline with mesh stats (volume, bounding box) and both binary + ASCII STL exports - 09_brep_fab: Fabrication-oriented B-Rep modeling: box→shell→STEP+GLB with AP214 header preview - python_examples/sdf_optimize_demo.py: SDF parameter optimization from point clouds with analytic gradient descent - Update examples/CMakeLists.txt to include new subdirectories - Add __pycache__/ to .gitignore
118 lines
5.7 KiB
C++
118 lines
5.7 KiB
C++
/// \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 <vde/brep/modeling.h>
|
||
#include <vde/brep/step_export.h>
|
||
#include <vde/foundation/io_gltf.h>
|
||
#include <vde/core/aabb.h>
|
||
|
||
#include <iostream>
|
||
#include <iomanip>
|
||
|
||
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;
|
||
}
|