mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-18 19:30:25 +00:00
ifcviewer: add section-plane clipping plumbing
Adds a clip-plane pipeline used by the upcoming section tool:
- Up to 8 SectionPlane{n, d} entries, AND-combined as
fragment-shader discard against world position. Main and pick
fragment shaders both honour the planes, so cut areas are
neither drawn nor selectable.
- Main vertex shader now passes v_world_pos through.
- Pick FBO grows two attachments (RGB32F world position, RGB16F
world normal) and the pick shader writes both alongside the
object id. pickSurfaceAt() does a single readback of all
three. Existing pickObjectAt() still works unchanged for
callers that just want the id.
- addSectionPlaneAtSurface(point, normal) auto-flips the normal
toward the camera so the first click immediately cuts the
camera-facing half.
No UI yet — that's the next commit (gizmo, drag, K shortcut).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -172,6 +172,30 @@ public:
|
||||
void setSelectedObjectId(uint32_t id);
|
||||
uint32_t pickObjectAt(int x, int y);
|
||||
|
||||
// Extended pick: returns the object id, world-space hit point, and
|
||||
// world-space surface normal at (x, y). Renders the same pick pass as
|
||||
// pickObjectAt but reads back from two extra color attachments
|
||||
// (world_pos in RGB32F, world_normal in RGB16F). Returns false if the
|
||||
// click missed all geometry; the out-params are then untouched.
|
||||
bool pickSurfaceAt(int x, int y,
|
||||
uint32_t& object_id_out,
|
||||
QVector3D& world_pos_out,
|
||||
QVector3D& world_normal_out);
|
||||
|
||||
// Section planes — fragment-shader clipping with up to MaxSectionPlanes
|
||||
// active. Each plane clips the half-space dot(n, p) + d > 0. addSection-
|
||||
// PlaneAtSurface auto-flips the normal toward the camera so the first
|
||||
// click immediately cuts away the camera-facing side.
|
||||
static constexpr int MaxSectionPlanes = 8;
|
||||
struct SectionPlane {
|
||||
QVector3D n; // unit world-space normal
|
||||
float d; // -dot(n, p) for some p on the plane
|
||||
};
|
||||
int sectionPlaneCount() const { return int(section_planes_.size()); }
|
||||
bool addSectionPlaneAtSurface(const QVector3D& point, const QVector3D& normal);
|
||||
void removeSectionPlane(int index);
|
||||
void clearSectionPlanes();
|
||||
|
||||
void setCamera(float tx, float ty, float tz, float dist, float yaw, float pitch);
|
||||
void setBenchmarkFrames(int n);
|
||||
QString cameraString() const;
|
||||
@@ -356,9 +380,15 @@ private:
|
||||
// Per-model GPU data
|
||||
std::unordered_map<uint32_t, ModelGpuData> models_gpu_;
|
||||
|
||||
// Pick framebuffer
|
||||
// Pick framebuffer. Three color attachments:
|
||||
// 0: R32UI — object_id
|
||||
// 1: RGB32F — world position at hit
|
||||
// 2: RGB16F — world normal at hit (already flipped for reflections in
|
||||
// the vertex shader)
|
||||
GLuint pick_fbo_ = 0;
|
||||
GLuint pick_color_tex_ = 0;
|
||||
GLuint pick_pos_tex_ = 0;
|
||||
GLuint pick_normal_tex_ = 0;
|
||||
GLuint pick_depth_rbo_ = 0;
|
||||
int pick_width_ = 0;
|
||||
int pick_height_ = 0;
|
||||
@@ -467,6 +497,13 @@ private:
|
||||
// Selection
|
||||
uint32_t selected_object_id_ = 0;
|
||||
|
||||
// Active section planes. Uploaded as uniform array each frame to the
|
||||
// main + pick programs; capped at MaxSectionPlanes.
|
||||
std::vector<SectionPlane> section_planes_;
|
||||
// Push the current plane list into a freshly-bound program. No-op if
|
||||
// the program does not declare u_clip_count / u_clip_planes.
|
||||
void uploadClipPlaneUniforms(GLuint program);
|
||||
|
||||
// FPS smoothing
|
||||
int frame_count_ = 0;
|
||||
float accumulated_time_ = 0.0f;
|
||||
|
||||
Reference in New Issue
Block a user