mirror of
https://github.com/Open-Cascade-SAS/OCCT.git
synced 2026-05-10 09:30:48 +08:00
The classical V3d_RectangularGrid / V3d_CircularGrid path generated all grid
lines on the CPU into a Graphic3d_Structure and recomputed them whenever any
parameter, the camera, or the privileged plane moved. Dense grids paid an
O(NxM) vertex rebuild per interaction and were effectively capped in extent;
there was no way to draw an infinite grid, a background (sky-plane) grid, or
a grid with sub-pixel line antialiasing.
This change promotes a shader-based grid to the single rendering path for
both rectangular and circular grids. Classical API, snap math and the vgrid
Draw command are preserved; only the presentation pipeline moves under the
shader.
Aspect layer:
- Add Aspect_GridParams: POD carrying shader-only appearance knobs (color,
origin, Scale, ScaleY, LineThickness, RotationAngle, AngularDivisions,
IsBackground, IsDrawAxis, IsInfinity, DrawMode, SizeX/SizeY, Radius,
AngleStart/AngleEnd). EffectiveScaleY() returns ScaleY when non-zero and
Scale() otherwise; IsCircular() is shorthand for AngularDivisions() > 0;
IsBounded() / IsArc() report active clipping.
- Extend Aspect_RectangularGrid with SizeX/SizeY/ZOffset fields and
accessors; extend Aspect_CircularGrid with Radius/ZOffset/AngleStart/
AngleEnd and IsArc(). Snap math is unchanged.
- Add Graphic3d_CView::GridDisplay(Aspect_GridParams, gp_Ax3) and GridErase()
virtuals with no-op defaults; include Aspect_GridParams.hxx and gp_Ax3.hxx
from Graphic3d_CView.hxx.
Shader (Graphic3d_ShaderManager::getGridProgram):
- Full-screen triangle unprojected per-fragment to world-space Near/Far
points, ray-plane intersection against an arbitrary plane supplied through
uPlaneOrigin / uPlaneX / uPlaneY / uPlaneN uniforms. Per-fragment unproject
avoids perspective-divide nonlinearity that plagues varying-based rays.
- Helper intersectPlane() uses a normalized direction for the parallel test,
so GRID_PARALLEL_EPS = 1e-6 is a dimensionless |sin(angle)| threshold
(~5.7e-5 deg) that stays scale-invariant under any world-depth range.
- gridLines2d / gridLines1d: fwidth-based AA plus per-axis Nyquist fade
(smoothstep(1.0, 2.0, fwidth)). Once a grid period fits inside a single
pixel, that axis fades to zero instead of smearing into a bright haze at
grazing angles. Lines mode uses max() of per-axis alphas; points mode
uses the product so only intersections light up.
- Bounded work area (rectangular SizeX/SizeY, circular Radius, optional arc
range): hard discard and smoothstep endpoint are both extended by
fwidth(coord), giving a single-screen-pixel AA transition instead of a
binary staircase at the clipping edge.
- Stable-reference rebasing for the rectangular grid: CPU unprojects the
screen center to the plane every frame and uploads the plane-local hit as
uStableRefLocal + uHasStableRef. The shader subtracts
floor(ref * scale) / scale before fract(), keeping the fract() argument
bounded at far world offsets without changing the visible line pattern.
- Branch on uGridType (0 = rectangular, 1 = circular). Circular path uses
polar coords (length, atan2) scaled by uScaleX and uAngularScale;
plane-local X/Y axis colouring is applied uniformly in both modes so the
red/green/blue cardinal lines stay straight.
- uDrawMode switches lines vs points (Aspect_GDM_Points); uIsBackground
pins gl_FragDepth to 1.0 - 1e-5 for the sky-plane look. Explicit GL 3.2 /
GLES 3.0 version headers; requires gl_VertexID and gl_FragDepth.
OpenGL plumbing:
- Add OpenGl_ShaderManager::BindGridProgram(): lazy Create + cache, routed
through bindProgramWithState so the standard OCCT matrix uniforms
(occProjectionMatrix, occWorldViewMatrix, occModelWorldMatrix and their
inverses, occViewport) are pushed onto the grid program every bind.
myGridProgram is nullified in clear() so context resets release the
compiled program.
- Add OpenGl_View::GridDisplay / GridErase overrides and private
renderGrid(). The renderer binds a dedicated VAO (core-profile safe) and
saves/restores program, depth test / func / mask, blend enable,
blend-func-separate, and depth-clamp. ProjectionState / WorldViewState are
push/pop-guarded. Original ZNear/ZFar/ProjType are captured before any
mutation so a mid-function ZFitAll cannot clobber user-set vzrange on
restore.
- Background-mode pan/rotate compensation is derived from the view-matrix
delta (currentView * refView^-1) captured at GridDisplay(); no public
Graphic3d_Camera API change is needed.
- Compute the plane-local stable reference in renderGrid via
Graphic3d_TransformUtils::UnProject on the viewport center; upload
uStableRefLocal / uHasStableRef alongside the other uniforms.
- Insert renderGrid() between renderScene() and renderTrihedron() in the
non-immediate draw pass; release myGridVao in ReleaseGlResources.
V3d layer:
- Add V3d_View::GridDisplay(params) / GridDisplay(params, plane) / GridErase
as thin pass-throughs; the single-argument overload uses
V3d_Viewer::PrivilegedPlane().
- Rewrite V3d_RectangularGrid and V3d_CircularGrid: drop the nested
RectangularGridStructure / CircularGridStructure classes, myGroup,
DefineLines, DefinePoints, and all myCur* caching flags. Display() /
Erase() / UpdateDisplay() now call syncViews() which builds an
Aspect_GridParams from the Aspect_{Rectangular,Circular}Grid state
(XStep/YStep -> Scale/ScaleY, RadiusStep -> Scale, DivisionNumber ->
AngularDivisions, XOrigin/YOrigin/OffSet -> Origin, RotationAngle ->
RotationAngle, SizeX/SizeY/Radius/ArcRange -> bounds, DrawMode)
and broadcasts it over V3d_Viewer::DefinedViews(). Snap math in
Aspect_RectangularGrid / Aspect_CircularGrid is untouched.
- V3d_RectangularGrid is unbounded by default (SizeX = SizeY = 0). The grid
renderer honours an explicit SetSizeX / SetSizeY to activate in-shader
clipping with AA edges; applications that want the old bounded behaviour
set the size explicitly.
Draw / tests:
- vgrid Draw command gains -type {rect|circ|inf|infinite}, -color R G B,
-scale N, -lineThickness T, -background {0|1}, -drawAxis {0|1},
-inf {0|1}. Existing -origin, -step, -rotAngle, -zoffset, -size, -radius,
-mode flags are retained and now drive the shader path.
- tests/v3d/grid/ (new group) adds ortho, persp, inf_pan, inf_rotate,
inf_plane, rect_shader, circ_shader, rect_points, inf_options,
bounded_rect, bounded_circ Draw regressions covering background mode,
matrix-derived pan/rotate stability, non-XY privileged planes,
anisotropic rectangular cells, polar divisions, points draw mode, and
in-shader bounded clipping. Registered in tests/v3d/grids.list.
- Add src/Visualization/TKService/GTests/Aspect_GridParams_Test.cxx covering
defaults, round-trip, copy, EffectiveScaleY fallback, RotationAngle
round-trip, AngularDivisions / IsCircular toggle, and DrawMode round-trip.
- Add src/Visualization/TKService/GTests/Aspect_Grid_Bounds_Test.cxx
covering SizeX/SizeY/Radius/ArcRange on the base grid classes.
Behaviour notes:
- V3d_RectangularGrid and V3d_CircularGrid no longer rely on
Graphic3d_Structure view affinity, so new views added to the viewer after
V3d_Viewer::ActivateGrid() must trigger a re-broadcast (call
Grid()->Display() on the viewer or re-activate) to pick up the grid.
- Aspect_GDM_Points is now rendered as dots at grid intersections through
uDrawMode (not as the old CPU point markers). Applications that depended
on point markers as selectable entities should present them through a
dedicated AIS object.
- V3d_RectangularGrid is unbounded by default; the old behaviour of
capping to 0.5 * DefaultViewSize() is available via an explicit
SetSizeX / SetSizeY call.
- Aspect_GridParams::Origin is a plane-local offset; the plane itself is
supplied as a gp_Ax3 (defaults to V3d_Viewer::PrivilegedPlane()).