mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 14:41:25 +00:00
ifcviewer-full: 1-pt laser, 2-pt XYZ + perpendicular, sharper visuals
Length tool's 1-pt laser is now hybrid:
- On any surface, a coplanar BFS finds the connected face patch
around the click and projects its vertices into the surface
tangent basis to get an exact bounding-box extent. Stops at
the face edge by construction — no overshoot into adjacent
geometry like the previous tangent-raycast did.
- On near-horizontal surfaces (|n.z| > 0.85, i.e. floors and
ceilings) it additionally fires one raycast in +n to the
opposing surface — so a single floor click reports X extent +
Y extent + ceiling height.
- Bars are labelled by their dominant world axis (X/Y/Z) instead
of "vertical/horizontal", which reads cleanly on either kind
of surface.
The 2-pt readout now draws the world-space XYZ stair-step (red ΔX,
green ΔY, blue ΔZ) with each leg labelled, and a dashed
perpendicular line whenever the two picks landed on near-parallel
surfaces — useful for measuring across walls.
To support multiple line styles per frame, OverlayRenderer's
setOverlayLines takes std::vector<LineGroup> instead of a single
inline style; each group has its own color/halo/width and an
optional dash period. The line shader gained v_along_px +
u_dash_period uniforms (screen-space dashes), and both line and
point shaders now use a sharp step() for the inner→stroke
transition with AA only on the outer halo edge — much crisper than
the previous soft band. Default visual style trimmed: 1.5px lines
(0.5px halo), 6px dots (1px halo), opaque black halo.
Also adds ViewportWindow::raycast(origin, dir, RaycastHit&) — CPU
ray traversal of each model's per-instance BVH followed by
Möller-Trumbore against the candidate meshes' triangles (lazily
read back, cached per call). Used by the floor/ceiling laser path
today and reusable for any future raycast-based feature.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -44,19 +44,21 @@ public:
|
||||
void setHighlightTriangles(const std::vector<float>& world_xyz,
|
||||
float r, float g, float b, float a);
|
||||
|
||||
// Replace the overlay-line list (3 floats per vertex, 2 verts per
|
||||
// segment, world space).
|
||||
//
|
||||
// When stroke_a > 0, every segment is rendered twice — first a wider
|
||||
// (line_width + 2*stroke_extra) stroke pass, then the inner line_width
|
||||
// pass. Most desktop GL drivers clamp glLineWidth at ~1, so the
|
||||
// stroke pass on lines may visually collapse onto the inner; reliable
|
||||
// two-tone outlining will need a screen-space-quad thick-line shader.
|
||||
void setOverlayLines(const std::vector<float>& world_xyz,
|
||||
float r, float g, float b, float a,
|
||||
float line_width,
|
||||
float stroke_r, float stroke_g, float stroke_b, float stroke_a,
|
||||
float stroke_extra);
|
||||
// One stylistic group of line segments rendered through the
|
||||
// outlined / optionally-dashed line shader. Multiple groups in a
|
||||
// single setOverlayLines call let the caller mix solid + dashed +
|
||||
// axis-coloured legs in one frame (e.g. the length tool's white
|
||||
// total line + RGB XYZ stair-step + dashed perpendicular).
|
||||
struct LineGroup {
|
||||
std::vector<float> world_xyz; // 6 floats per segment (a, b)
|
||||
float color[4] = {1, 1, 1, 1}; // inner color
|
||||
float stroke_color[4] = {0, 0, 0, 1}; // outline (0 alpha = no outline)
|
||||
float line_width = 1.5f; // pixels (inner)
|
||||
float stroke_extra = 0.5f; // pixels per side outside inner
|
||||
float dash_period_px = 0.0f; // 0 = solid; else screen-space dash period
|
||||
float dash_on_ratio = 0.6f; // [0..1], used only when period > 0
|
||||
};
|
||||
void setOverlayLines(const std::vector<LineGroup>& groups);
|
||||
|
||||
// Replace the overlay-point list (3 floats per point, world space).
|
||||
// `pixel_size` is the inner-dot diameter in physical pixels.
|
||||
@@ -118,23 +120,19 @@ private:
|
||||
float stroke_extra = 0.0f;
|
||||
};
|
||||
|
||||
// Line bundle: each input segment is CPU-expanded into 6 vertices
|
||||
// (a quad as 2 triangles), each carrying both endpoints and a
|
||||
// (side, along) corner index. The vertex shader projects to screen,
|
||||
// computes the screen-space perpendicular, and offsets accordingly;
|
||||
// the fragment shader uses the interpolated signed perpendicular
|
||||
// distance to discard outside the half-width and to pick inner vs
|
||||
// stroke color. Result: real outlined lines independent of the
|
||||
// driver's glLineWidth clamp.
|
||||
struct LineBundle {
|
||||
GLuint vao = 0;
|
||||
GLuint vbo = 0;
|
||||
size_t vbo_capacity = 0;
|
||||
GLsizei vertex_count = 0;
|
||||
float inner_color[4] = {0, 0, 0, 0};
|
||||
float stroke_color[4] = {0, 0, 0, 0};
|
||||
float line_width = 1.0f;
|
||||
float stroke_extra = 0.0f;
|
||||
// Per-group draw-call record. setOverlayLines populates one of these
|
||||
// per LineGroup, with `first` indexing into a shared expanded-vertex
|
||||
// VBO. At render time we iterate them, set per-group uniforms, and
|
||||
// issue one glDrawArrays each.
|
||||
struct LineDrawCall {
|
||||
float color[4] = {1, 1, 1, 1};
|
||||
float stroke_color[4] = {0, 0, 0, 0};
|
||||
float line_width = 1.5f;
|
||||
float stroke_extra = 0.5f;
|
||||
float dash_period_px = 0.0f;
|
||||
float dash_on_ratio = 0.6f;
|
||||
GLint first = 0;
|
||||
GLsizei count = 0;
|
||||
};
|
||||
|
||||
QOpenGLFunctions_4_5_Core* gl_ = nullptr;
|
||||
@@ -160,6 +158,8 @@ private:
|
||||
GLint u_ln_stroke_extra_ = -1;
|
||||
GLint u_ln_inner_color_ = -1;
|
||||
GLint u_ln_stroke_color_ = -1;
|
||||
GLint u_ln_dash_period_ = -1;
|
||||
GLint u_ln_dash_on_ratio_ = -1;
|
||||
|
||||
// Screen-space rect program (label + HUD backgrounds). Vertex
|
||||
// attribute is vec2 NDC; fragment outputs a uniform color. Drawn
|
||||
@@ -172,7 +172,13 @@ private:
|
||||
|
||||
TriBundle triangles_;
|
||||
PointBundle points_;
|
||||
LineBundle lines_;
|
||||
|
||||
// Lines: one shared VAO/VBO holding the concatenated expanded
|
||||
// vertices of every group; line_draws_ records each group's slice.
|
||||
GLuint vao_lines_ = 0;
|
||||
GLuint vbo_lines_ = 0;
|
||||
size_t vbo_lines_capacity_ = 0;
|
||||
std::vector<LineDrawCall> line_draws_;
|
||||
|
||||
std::vector<Label> labels_;
|
||||
QString hud_text_;
|
||||
|
||||
Reference in New Issue
Block a user