mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
ifcviewer: move section-plane mutators into ViewportCore (#84-y)
addSectionPlaneAtSurface (camera-facing auto-flip + kMaxSectionPlanes cap check), removeSectionPlane, and clearSectionPlanes all move to ViewportCore. ViewportWindow keeps tiny forwarders so the section tool's input handlers (still VW) call through without seeing the move. Each method now calls host_->requestFrame() in place of the isExposed() + requestUpdate() gate, which means the section tool path becomes the next piece that could exercise the WebViewportHost: a click-to-add over WebGPU will work as soon as the host is wired, without further core-side changes.
This commit is contained in:
@@ -5268,3 +5268,52 @@ void ViewportCore::render() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ===========================================================================
|
||||
// Section planes (#84-y)
|
||||
// ===========================================================================
|
||||
|
||||
bool ViewportCore::addSectionPlaneAtSurface(const Eigen::Vector3f& point,
|
||||
const Eigen::Vector3f& normal,
|
||||
float visual_radius) {
|
||||
if (int(section_planes_.size()) >= kMaxSectionPlanes) {
|
||||
Log::warn() << "[wgpu section] cap reached (" << kMaxSectionPlanes
|
||||
<< " planes)";
|
||||
return false;
|
||||
}
|
||||
Eigen::Vector3f n = normal;
|
||||
if (n.squaredNorm() < 1e-8f) return false;
|
||||
n.normalize();
|
||||
// Auto-flip the normal so the camera-facing half gets cut away.
|
||||
const Eigen::Vector3f eye = orbitEye(camera_target_, camera_distance_,
|
||||
camera_yaw_deg_, camera_pitch_deg_);
|
||||
const Eigen::Vector3f eye_dir = eye - point;
|
||||
if (n.dot(eye_dir) < 0.0f) n = -n;
|
||||
|
||||
SectionPlane p;
|
||||
p.n = n;
|
||||
p.origin = point;
|
||||
p.d = -n.dot(point);
|
||||
p.visual_radius = (visual_radius > 0.0f) ? visual_radius : 1.0f;
|
||||
section_planes_.push_back(p);
|
||||
Log::info()
|
||||
<< "[wgpu section] added plane #" << section_planes_.size() - 1
|
||||
<< " origin=(" << point.x() << "," << point.y() << "," << point.z() << ")"
|
||||
<< " normal=(" << n.x() << "," << n.y() << "," << n.z() << ")";
|
||||
host_->requestFrame();
|
||||
return true;
|
||||
}
|
||||
|
||||
void ViewportCore::removeSectionPlane(int index) {
|
||||
if (index < 0 || index >= int(section_planes_.size())) return;
|
||||
section_planes_.erase(section_planes_.begin() + index);
|
||||
Log::info() << "[wgpu section] removed plane " << index;
|
||||
host_->requestFrame();
|
||||
}
|
||||
|
||||
void ViewportCore::clearSectionPlanes() {
|
||||
if (section_planes_.empty()) return;
|
||||
section_planes_.clear();
|
||||
Log::info() << "[wgpu section] cleared all planes";
|
||||
host_->requestFrame();
|
||||
}
|
||||
|
||||
@@ -355,6 +355,23 @@ public:
|
||||
void finalizeScreenshotCapture(WGPUBuffer capture_buffer,
|
||||
std::uint32_t padded_bpr);
|
||||
|
||||
// ---- Section planes (#84-y) -------------------------------------------
|
||||
//
|
||||
// Append a section plane at the supplied surface hit, with a normal
|
||||
// auto-flipped toward the camera so the first click reveals the
|
||||
// surface the user just clicked. `visual_radius` controls the
|
||||
// overlay gizmo size; <= 0 falls back to 1 m. Returns false when
|
||||
// the kMaxSectionPlanes cap is already reached.
|
||||
bool addSectionPlaneAtSurface(const Eigen::Vector3f& point,
|
||||
const Eigen::Vector3f& normal,
|
||||
float visual_radius);
|
||||
|
||||
// Remove a single section plane by index (no-op when out of range).
|
||||
void removeSectionPlane(int index);
|
||||
|
||||
// Drop every section plane. No-op when none are active.
|
||||
void clearSectionPlanes();
|
||||
|
||||
// ---- Render loop (#84-x) ----------------------------------------------
|
||||
//
|
||||
// Encode one frame: acquire the swapchain texture, run cull (parallel
|
||||
|
||||
@@ -969,51 +969,13 @@ void ViewportWindow::toggleSectionTool() {
|
||||
if (isExposed()) requestUpdate();
|
||||
}
|
||||
|
||||
bool ViewportWindow::addSectionPlaneAtSurface(const Eigen::Vector3f& point,
|
||||
const Eigen::Vector3f& normal,
|
||||
float visual_radius) {
|
||||
if (int(section_planes_.size()) >= kMaxSectionPlanes) {
|
||||
std::fprintf(stderr, "[warn] [wgpu section] cap reached (%d planes)\n",
|
||||
kMaxSectionPlanes);
|
||||
return false;
|
||||
}
|
||||
Eigen::Vector3f n = normal;
|
||||
if (n.squaredNorm() < 1e-8f) return false;
|
||||
n.normalize();
|
||||
// Auto-flip the normal so the camera-facing half gets cut away — that
|
||||
// way the first click always reveals the surface the user just clicked.
|
||||
const Eigen::Vector3f eye = orbitEye(camera_target_, camera_distance_,
|
||||
camera_yaw_deg_, camera_pitch_deg_);
|
||||
const Eigen::Vector3f eye_dir = eye - point;
|
||||
if (n.dot(eye_dir) < 0.0f) n = -n;
|
||||
|
||||
SectionPlane p;
|
||||
p.n = n;
|
||||
p.origin = point;
|
||||
p.d = -n.dot(point);
|
||||
p.visual_radius = (visual_radius > 0.0f) ? visual_radius : 1.0f;
|
||||
section_planes_.push_back(p);
|
||||
Log::info().noquote().nospace()
|
||||
<< "[wgpu section] added plane #" << section_planes_.size() - 1
|
||||
<< " origin=(" << point.x() << "," << point.y() << "," << point.z() << ")"
|
||||
<< " normal=(" << n.x() << "," << n.y() << "," << n.z() << ")";
|
||||
if (isExposed()) requestUpdate();
|
||||
return true;
|
||||
bool ViewportWindow::addSectionPlaneAtSurface(const Eigen::Vector3f& point, const Eigen::Vector3f& normal, float visual_radius) {
|
||||
return core_.addSectionPlaneAtSurface(point, normal, visual_radius);
|
||||
}
|
||||
|
||||
void ViewportWindow::removeSectionPlane(int index) {
|
||||
if (index < 0 || index >= int(section_planes_.size())) return;
|
||||
section_planes_.erase(section_planes_.begin() + index);
|
||||
Log::info().noquote() << "[wgpu section] removed plane" << index;
|
||||
if (isExposed()) requestUpdate();
|
||||
}
|
||||
void ViewportWindow::removeSectionPlane(int index) { core_.removeSectionPlane(index); }
|
||||
|
||||
void ViewportWindow::clearSectionPlanes() {
|
||||
if (section_planes_.empty()) return;
|
||||
section_planes_.clear();
|
||||
Log::info() << "[wgpu section] cleared all planes";
|
||||
if (isExposed()) requestUpdate();
|
||||
}
|
||||
void ViewportWindow::clearSectionPlanes() { core_.clearSectionPlanes(); }
|
||||
|
||||
void ViewportWindow::setOverlayLines(
|
||||
const std::vector<OverlayRenderer::LineGroup>& groups) {
|
||||
|
||||
Reference in New Issue
Block a user