github Open-Cascade-SAS/OCCT V8_0_0_beta1

pre-release3 hours ago

Open Cascade is delighted to announce the release of Open CASCADE Technology version 8.0.0 Beta 1 to the public.

Overview

Version 8.0.0-beta1 marks the feature-freeze milestone on the road to OCCT 8.0.0. It incorporates 41 changes since 8.0.0-rc5, bringing the cumulative total of improvements and fixes since 7.9.0 to over 500 changes. The Beta cycle is dominated by two large automated quality sweeps and one major NCollection / BRepGraph overhaul.

The Beta phase signals that 8.0.0 is feature-complete: no further functional or API changes are planned before the final release. The remaining work is documentation polish, sample-folder modernization to reflect the new project layout and workflows, and - only if surfaced during the Beta soak - targeted fixes for critical bugs or regressions.

Final 8.0.0 release is planned for May 7, 2026, contingent on a stable, regression-free Beta cycle.

This release focuses on:

  • NCollection size_t API migration #1212: Size() now returns size_t across maps, sequences, arrays, and lists; Length() retains the legacy int-returning contract - this is the single most impactful migration item in 8.0.0
  • NCollection_LinearVector #1212, #1244: New contiguous flat-buffer dynamic array with Standard::Reallocate-based growth; NCollection_DynamicArray rebuilt on top of it; NCollection_Vector deprecated; NCollection_BasePointerVector removed entirely
  • BRepGraph editor consolidation #1212, #1237: BuilderView retired; EditorView (with a dedicated EditorView_Setters.cxx) becomes the single mutation surface, owning both structural Add/Remove and field-level Mut*() RAII operations with automatic generation propagation
  • Two-tier mesh storage #1212: New BRepGraph_MeshCache and BRepGraph_MeshView separate algorithm-derived caches from persistent (definition) triangulations; freshness keyed on FaceDef.OwnGen
  • Shader-based infinite grid #1223: V3d rectangular and circular grids unified onto a single shader path with infinite extent, background mode, sub-pixel AA, arbitrary gp_Ax3 privileged plane, and matrix-derived pan/rotate compensation - no Graphic3d_Camera API change required
  • Selection through group flipping #1219: New Graphic3d_Flipper brings flip-aware BVH bounds and frustum overlap testing in line with OpenGl_Flipper rendering, fixing missed clicks on AIS_TextLabel/PrsDim_Dimension after camera rotation
  • BVH-accelerated polyhedra interference #924: New IntPatch_PolyhedronBVH (BVH_PrimitiveSet<double, 3> + BVH_LinearBuilder) and IntPatch_BVHTraversal replace pairwise triangle scanning in IntPatch_InterferencePolyhedron::Interference() - O(log n) queries replace linear search
  • Shape Healing robustness #1227, #1247: Replacement-chain leaf resolution, cycle rejection, and DFS in-flight guards eliminate stack overflows and edge multiplication on shapes with shared sub-shapes
  • -Werror enabled in Linux/macOS CI #1209: GitHub Actions configure step now sets -Werror -Wzero-as-null-pointer-constant plus a curated allow-list of -Wno-error=... suppressions, locking in a clean warning baseline
  • Two large Clang-Tidy automated sweeps #1207, #1245: Round 1 focused on emplace_back/empty()/= default; round 2 (clang-tidy 22.1.3) is a codebase-wide sweep applying braces-around-statements, nullptr, override, =default/=delete, and redundant-init removal

What is a Beta Release

A Beta release is a feature-freeze tag on the master branch. All planned 8.0.0 features and APIs are present and stable; the remaining cycle is dedicated to documentation, samples, and regression-only fixes. Unlike Release Candidates - which still admit small targeted features - the Beta gate is intentionally narrow: only critical defects or regressions surfaced during the Beta soak are eligible for cherry-pick before the final release.


What's New in OCCT 8.0.0-beta1

Foundation Classes

NCollection Modernization (Major) #1212

PR #1212 is a single change that touches the entire NCollection layer. Highlights:

  • Size() migration to size_t: Across NCollection_Map, NCollection_DataMap, NCollection_IndexedMap, NCollection_IndexedDataMap, NCollection_Sequence, NCollection_Array1, NCollection_Array2, NCollection_List (and the underlying NCollection_BaseMap/NCollection_BaseSequence/NCollection_BaseList), Size() now returns size_t. The legacy int-returning accessor is preserved as Length(). int overloads of ReSize()/BeginResize()/EndResize() delegate through a shared NbBucketsFromInt() helper with a negative-input guard. The same PR sweeps Size() -> Length() across all call sites in TKG2d, TKG3d, TKMath, TKMesh, TKBO, TKOffset, TKShHealing, TKTopAlgo, TKBRep, TKService, TKV3d, TKOpenGl, TKMeshVS, TKDE*, TKXCAF, TKXSBase, TKLCAF, TKStd, and Draw harness wherever the count fed an int-typed API or progress scope.

  • New NCollection_LinearVector: Contiguous flat-buffer dynamic array. Uses Standard::Reallocate-based growth for trivially copyable types and move-construction for non-trivial types. The header carries a documented iterator-invalidation contract.

  • NCollection_DynamicArray rebuilt: Now a LinearVector<T*> of fixed-size blocks with power-of-two block sizing and precomputed shift/mask for O(1) indexed access. Old block-pointer indirection layer is gone.

  • NCollection_BasePointerVector removed: Superseded by NCollection_LinearVector. No backward-compatibility shim.

  • NCollection_BaseMap::Statistics removed: Unused.

  • NCollection_IncAllocator lock-free fast path: Switched to std::shared_mutex plus CAS bump allocation on an atomic AvailableSize. Exclusive lock is taken only for new-block allocation and free-list reordering - existing block allocations now proceed without contention.

  • NCollection_BaseMap iterator rework: New forward findFirst() helper eliminates negative-bucket arithmetic; iterator state unified under size_t.

  • <cstddef> include added to NCollection_Primes.hxx: Clean-build fix for size_t resolution on platforms that did not implicitly include it.

  • GTest coverage: New NCollection_DynamicArray_Test.cxx and NCollection_LinearVector_Test.cxx covering construction, growth, iterator invalidation, move semantics, and Resize patterns.

Other NCollection Improvements

  • NCollection_LinearVector extended #1244: Added size+value constructor and Resize(size, value) overload. Migrated many std::vector usages across TKMath/TKMesh/TKBO/TKBRep/visualization to NCollection_LinearVector, including BVH array plumbing - removing the conditional STL-vs-OCCT branches that previously cluttered those paths.

  • NCollection_Vector deprecated #1230: All in-tree usages migrated to NCollection_DynamicArray. The class continues to compile under a deprecation warning.

  • NCollection_Array1/Array2 zero-based constructors and size_t resize #1236: New zero-based constructors (allocation + buffer-reuse wrapping). size_t-based Resize() overloads. NCollection_Array1 resize logic refactored into a shared implementation. Dedicated GTest coverage included.

Foundation Improvements

  • Robust unit-conversion error handling #1201: Units_Measurement and Units::Convert() now print the name of the unknown unit when conversion fails. Units::Convert() no longer crashes when the first unit is unknown. UnitsAPI documentation strings corrected (non-existent unit type "millimeter" replaced with "mm").

  • Standard_DEPRECATED_STD macro #1241: New macro in Standard_Macro.hxx expanding to standard [[deprecated("...")]] (or empty under OCCT_NO_DEPRECATED). Used by GCE2d_* alias headers; restores compiler compatibility while preserving deprecation warnings.

Modeling Data

BRepGraph - Editor Consolidation and Mesh Cache (Major)

The same PR #1212 rewrites the BRepGraph mutation surface:

  • EditorView replaces BuilderView #1212: The BuilderView API is removed (BRepGraph_BuilderView.cxx/.hxx deleted). EditorView (BRepGraph_EditorView.cxx/.hxx, plus BRepGraph_EditorView_Mut.cxx) becomes the single programmatic mutation surface, owning both structural creation (Add*/Remove*) and field-level RAII-scoped mutation (Mut*()) with automatic OwnGen and SubtreeGen propagation.

  • Dedicated BRepGraph_EditorView_Setters.cxx #1242: A new file adds typed setters that replace direct field writes in tests. Used together with GenOps::RemoveRef; mutation-gen tests adopt MarkDirty(). BRepGraphInc_ReverseIndex gains incremental bind/unbind helpers, eliminating full rebuilds in many editor operations. BRepGraph_Copy and BRepGraph_Transform extended with CopyNode/TransformNode, plus optional mesh-copy/transform support.

  • BRepGraph_MeshCache and BRepGraph_MeshView #1212: Two-tier mesh storage separating algorithm-derived caches from persistent definition triangulations. Freshness is keyed on FaceDef.OwnGen; cache writes do not mutate the model. The invalidation contract is documented inline - which mutations bump Face.OwnGen and how markRepModified closes the loop for Surface and Triangulation reps.

  • New iterators #1212: BRepGraph_RefsIterator (generic flat ref scan with RefTraits dispatch) and BRepGraph_ReverseIterator (typed parent-traversal wrappers over reverse-index vectors).

  • RefId entity model rework #1212: Inline refs replaced with typed RefId vectors. New OccurrenceRef type and Kind::Occurrence=7. BRepGraphInc_WireExplorer now requires a VertexRefLookup parameter.

  • Layer/usage renames #1212: BRepGraph_ParamLayer -> BRepGraph_LayerParam, BRepGraph_RegularityLayer -> BRepGraph_LayerRegularity, BRepGraphInc_Usage -> BRepGraphInc_Instance.

  • Roots API #1212: RootNodeIds() replaced by RootProductIds() returning product roots only.

  • uint32_t ID migration #1229: Node, ref, and rep ID types - and many count-returning APIs - migrated from int to uint32_t/size_t (history indices). Loops reworked from raw integer indexing to typed-id iteration (Start(), IsValid(), range-for) across both production code and tests. Compaction test coverage expanded with a bounding-box preservation assertion.

  • Builder lifecycle clean-up #1237: BRepGraph_Builder::Perform() is replaced with BRepGraph_Builder::Add(). New BRepGraph::Clear() is the canonical rebuild boundary. Product/occurrence editing renamed: AddAssembly -> CreateEmptyProduct, AddOccurrence -> LinkProducts; occurrence mutation moves under Editor().Occurrences(). Inline docs and a large GTest set updated.

  • Comprehensive new GTest set #1212: NCollection_DynamicArray_Test, NCollection_LinearVector_Test, BRepGraph_Fuzz_Test, BRepGraph_Iterator_Test, BRepGraph_LayerIterator_Test, BRepGraph_MeshCache_Test, BRepGraph_MutGuard_Test, BRepGraph_ReplaceVertex_Test, BRepGraph_ReverseIterator_Test, BRepGraph_ScenarioMatrix_Test, BRepGraph_TypedIdDispatch_Test, BRepGraph_WireExplorer_Test. PR #1242 adds a BRepGraphInc_Test.cxx.

  • MSVC fallback hardening #1246: BRepGraphInc_Storage visitors made explicit on the "unsupported id type" branch to silence MSVC control-path warnings; BRepGraph_NodeId::Invalid() used in place of integer literals where appropriate. Several Size() calls revised back to Extent()/Length() where they fed Message_ProgressScope (which expects int).

Other Modeling Data

  • TopExp_Explorer::Clear() allocation churn fix #1195: The previous Reallocate(0)/Reallocate(N) cycle in Clear() caused unnecessary heap traffic in hot iteration paths. The fix resets live TopoDS_Iterator slots in place from myStackTop down to 0 and keeps the array allocation, so subsequent reuse skips reallocation. Covered by a new GTest exercising nested iteration and reinitialization (post-RC5 stack-refactor regression gate).

Modeling Algorithms

Bug Fixes (High-Impact)

  • Stack overflow / edge multiplication in shape healing with shared sub-shapes #1227: Replacement chains in ShapeBuild_ReShape could form cycles when the same TShape was rewritten more than once via differently-oriented entry points, causing recursive descent loops and exponential edge expansion. Fix introduces:

    • ValueLeaf() - replacement-chain leaf resolution
    • Cycle rejection on Replace()
    • DFS in-flight guards against recursive descent loops
    • Quadratic wire-fixing cost reduction
    • Progress cancellation checkpoints across ShapeFix routines
  • Shape replacement regression follow-up #1247: Targeted fixes for regressions surfaced by the cycle-handling change above.

  • Null-context crash in ShapeUpgrade_FaceDivide::Perform() #1203: Lazy initialization of the ShapeBuild_ReShape context when none is supplied; covered by serial and parallel-execution GTests.

  • Crash in BRepFill_PipeShell::MakeSolid() #1224: IsSameOriented() now iterates over face edges and selects one present in the shell's edge->faces map, with a Contains guard before FindFromKey() to prevent invalid map access. Local naming (theFace, theShell, anEdgeFaceMap) updated to OCCT conventions.

  • Cylinder-cylinder tangent-along-line case #1228: When two cylinders are tangent along a line, the analytical intersection produces an invalid restriction point (an algorithmic limitation of the analytical approach). Patch ensures the implicit-implicit intersection algorithm is used in this case.

  • Degenerate thin-solid detection #1231: FillSameDomainFaces now uses the parent solid (not the shell) for Same-Domain face mapping, eliminating misclassification of degenerate thin solids.

  • 3D cycling detection in IntWalk_PWalking #1226: New 3D-distance-based closure check marks an intersection line as closed when the walker returns near the starting point, forcing early termination and re-adding the first point to close the polyline.

  • GeomFill_ConstrainedFilling and GeomFill_CoonsAlgPatch correctness fixes #922: Fixed bug where law functions were silently discarded due to Func() being called instead of SetFunc() in Init(). Corrected parameter usage in CoonsAlgPatch::Value() for proper variable assignment in curve evaluation.

Performance

  • BVH-accelerated polyhedra interference #924: Introduces two new classes:
    • IntPatch_PolyhedronBVH: Wraps IntPatch_Polyhedron as a BVH_PrimitiveSet<double, 3> built with BVH_LinearBuilder. Stores a reference to the polyhedron (no data copy) and maintains an index mapping to track triangle reordering during BVH construction.
    • IntPatch_BVHTraversal: Dual-tree traversal yielding candidate triangle pairs.
    • IntPatch_InterferencePolyhedron::Interference() refactored on top of these for O(log n) queries replacing linear search. A new IntPatch_PolyhedronBVH_Test.cxx GTest covers the new path.
    • Triangle-pair container migrated to NCollection_DynamicArray in a follow-up commit.

Mesh

  • BRepMesh_BaseMeshAlgo node registration #940: Used-node binding moved from initDataStructure() to registerNode() to ensure consistent tracking of all nodes (the earlier code missed nodes inserted later in the algorithm). New GTest suite validates internal vertex handling in mesh triangulation.

Visualization

Shader-Based Infinite Grid (Major) #1223

Both V3d_RectangularGrid and V3d_CircularGrid now go through a unified shader path. The classical CPU O(NxM) vertex rebuild on every parameter/camera/plane change is gone. New capabilities:

  • Infinite extent with sub-pixel line antialiasing via fwidth-based AA
  • Per-axis Nyquist fade - once a grid period fits inside a single pixel, that axis fades to zero instead of smearing into a bright haze at grazing angles. Uses smoothstep(1.0, 2.0, fwidth).
  • Lines vs points modes - lines mode uses max() of per-axis alphas; points mode uses the product so only intersections light up
  • Background (sky-plane) mode that pins gl_FragDepth to 1.0 - 1e-5
  • Bounded clipping (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 rather than a binary staircase at the clipping edge
  • Stable-reference rebasing - the 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 fract() arguments bounded at far world offsets without changing the visible line pattern
  • Arbitrary gp_Ax3 privileged plane via uPlaneOrigin/uPlaneX/uPlaneY/uPlaneN uniforms. Plane intersection uses intersectPlane() with a normalized direction, 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.
  • Matrix-derived pan/rotate compensation in background mode - derived from the view-matrix delta currentView * refView^-1 captured at GridDisplay(); no Graphic3d_Camera API change required
Aspect layer
  • New 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() falls back to Scale() when ScaleY is zero. IsCircular() shorthand for AngularDivisions() > 0. IsBounded() / IsArc() report active clipping.
  • Aspect_RectangularGrid extended with SizeX/SizeY/ZOffset. Aspect_CircularGrid extended with Radius/ZOffset/AngleStart/AngleEnd and IsArc(). Snap math is unchanged.
  • Graphic3d_CView::GridDisplay(Aspect_GridParams, gp_Ax3) and GridErase() virtuals added with no-op defaults.
OpenGL plumbing
  • New 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.
  • New 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.
  • renderGrid() runs between renderScene() and renderTrihedron() in the non-immediate draw pass; myGridVao released in ReleaseGlResources.
V3d layer
  • V3d_View::GridDisplay(params) / GridDisplay(params, plane) / GridErase are thin pass-throughs; the single-argument overload uses V3d_Viewer::PrivilegedPlane().
  • V3d_RectangularGrid / V3d_CircularGrid rewritten: nested RectangularGridStructure/CircularGridStructure, myGroup, DefineLines, DefinePoints, and all myCur* caching flags removed. Display()/Erase()/UpdateDisplay() now call syncViews() which builds an Aspect_GridParams from the existing grid state and broadcasts it over V3d_Viewer::DefinedViews().
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 retained and now drive the shader path.
  • New tests/v3d/grid/ group: ortho, persp, inf_pan, inf_rotate, inf_plane, rect_shader, circ_shader, rect_points, inf_options, bounded_rect, bounded_circ. Registered in tests/v3d/grids.list.
  • Two new GTests: Aspect_GridParams_Test.cxx (defaults, round-trip, copy, EffectiveScaleY fallback, RotationAngle round-trip, AngularDivisions/IsCircular toggle, DrawMode round-trip) and Aspect_Grid_Bounds_Test.cxx (SizeX/SizeY/Radius/ArcRange).
Behaviour notes
  • V3d_RectangularGrid is unbounded by default (SizeX = SizeY = 0). The previous behaviour of capping to 0.5 * DefaultViewSize() is available via explicit SetSizeX/SetSizeY.
  • Aspect_GDM_Points is now rendered as shader dots at intersections through uDrawMode, not as the old CPU point markers. Applications that depended on point markers as individually selectable entities should present them through a dedicated AIS object.
  • Grids no longer rely on Graphic3d_Structure view affinity. Views added to the viewer after V3d_Viewer::ActivateGrid() must trigger a re-broadcast (Grid()->Display() or re-activate) to pick up the grid.
  • The shader requires GL 3.2 / GLES 3.0 (uses gl_VertexID and gl_FragDepth). Older driver/profile combinations will not see grid rendering.

Selection

  • Selection through group-level flipping #1219: AIS_TextLabel and PrsDim_Dimension use Graphic3d_Group::SetFlippingOptions so labels stay upright relative to the camera. The selection pipeline previously computed BVH boxes and frustums in unflipped local coordinates - once the camera rotated past the flipping threshold, clicks on the on-screen label missed.

    • New Graphic3d_Flipper: CPU-side analogue of OpenGl_Flipper carrying the reference plane and reproducing the render-time flip matrix. Each flip branch is a 180-degree rotation involution, so the matrix is self-inverse - using T_flip directly is valid in inverse contexts.
    • Graphic3d_CStructure gains HasGroupFlipping()/SetGroupFlipping(); reset in Graphic3d_Structure::clear().
    • Graphic3d_Group::Flipper() and a myFlipper member populated from OpenGl_Group::SetFlippingOptions(true,...). The render-side OpenGl_Flipper element is still emitted for the push/pop bracket; myFlipper persists across the matching SetFlippingOptions(false,...) call so the selection side can see that the group contains flipped geometry.
    • Select3D_SensitiveEntity::Flipper()/SetFlippingOptions() so sensitive entities can carry the same flipping metadata used by selection traversal; included in DumpJson.
    • SelectMgr_SensitiveEntitySet tracks myNbEntityWithFlipping in Append()/Remove(); HasEntityWithFlipping() exposes it to the viewer selector.
    • SelectMgr_SelectableObjectSet::appropriateSubset() routes presentations with HasGroupFlipping() to the 3d-persistent BVH subset (same as transform persistence).
    • BVHBuilderAdaptorPersistent merges flipping and transform-persistence loops into a single pass: for each group with a Flipper or TransformPersistence, build its local bbox, apply the flip (if any), then apply TransformPersistence (if any), then add the resulting box to the object bbox; object-level TransformPersistence is applied once to the merged box. Note: for the rare case of object-level + group-level TransformPersistence, the application order differs from the prior code (object-TP now runs after group-TP contributions are added). Common cases are behaviour-preserving.
    • SelectMgr_ViewerSelector::traverseObject() bypasses the root/per-node overlap early-outs when the entity set contains flipped sensitives, and folds the flip matrix into aInvFlippingAndPers = T_flip * aInvSensTrsf before computeFrustum() and checkOverlap().
    • The object's Transformation() is folded into aMVForFlip via Graphic3d_TransformUtils::Convert<double> so the isReversedX/Y/Z decision agrees with OpenGl_Flipper::Render() which uses WorldView * ModelWorld.
    • Known limitation: group-level Graphic3d_Group::Transformation() is still not folded in on the selection side because the sensitive entity does not carry a reference to its host group - only affects consumers that give the flipping group its own non-identity gp_Trsf (uncommon in stock OCCT). A TODO in Graphic3d_Flipper::Compute and SelectMgr_ViewerSelector marks the deferred follow-up.
  • Polyline selection inclusion test fixes #1222: Two long-standing bugs in SelectMgr_TriangularFrustumSet fixed:

    • OverlapsBox(min, max, bool* theInside) - the corner-edge isIntersectBoundary heuristic produced false "fully inside" answers whenever an AABB was large enough that its 12 edges did not cross the polyline but its interior did not lie inside either. Rewrite: first probe every frustum for any overlap; if none, return false. Otherwise, project the 8 AABB corners onto the frustum near plane and apply a ray-cast inside test against the original polyline loop. If any corner projects outside, clear theInside; else leave it untouched. The near-plane coplanarity assumption is guaranteed by Build(), which derives every near vertex from myBuilder->ProjectPntOnViewPlane(x, y, 0.0).
    • OverlapsPoint(const gp_Pnt&) - previously a stub returning false, silently making strict-inclusion polyline selection of Select3D_SensitiveTriangle/SensitivePoly/SensitiveTriangulation/SensitivePrimitiveArray/MeshVS_CommonSensitiveEntity/MeshVS_SensitiveQuad impossible (those types call theMgr.OverlapsPoint(...) on each vertex in strict-inclusion mode; a blanket false meant nothing was ever picked). Now delegates to the same near-plane projection + ray-cast test, so strict inclusion works for all these sensitive types in polyline mode.
    • Covered by a new Draw test tests/vselect/bugs/bug_polyline_inclusion (no GTest because constructing a working TriangularFrustumSet requires a configured Graphic3d_Camera + viewport).
  • Select3D_SensitivePrimitiveArray::GetVertex accessor #1221: Returns the three vertex positions of the triangle at the given index as std::array<NCollection_Vec3<float>, 3>. Downstream consumers can query triangulation geometry of a picked primitive array without re-walking the underlying Graphic3d_Buffer/Graphic3d_IndexBuffer. Uses the existing file-local getTriIndices helper and the private getPosVec3 member, keeping the implementation a pure accessor.

AIS_ColorScale Rendering

  • Triangle winding fix #1220: Swap the last two vertex indices in the second triangle of each color-scale rectangle so the two triangles share the same diagonal with consistent CCW orientation. Earlier indexing (v+1, v+2, v+3) built two overlapping triangles with opposite winding, producing visible seams and dropped vertices under back-face culling.

  • Face-culling completion #1225: Switched the rectangle helper from manual triangle edges to Graphic3d_ArrayOfPrimitives::AddQuadTriangleEdges() while preserving the top/bottom color layout. Picks up the upstream patch revision from Kirill Gavrilov (commit 9b8c624...). Pixel-check Draw regression tests/v3d/colorscale/colorscale_faceculling added.

IVtk

  • Pixel tolerance via IVtk picker #1204: Removed the dead IVtkTools_ShapePicker::SetTolerance(float)/GetTolerance() API and the unused stored tolerance value. New SetPixelTolerance(int)/PixelTolerance() const on IVtkTools_ShapePicker and IVtkOCC_ShapePickerAlgo forward to SelectMgr_ViewerSelector. IVtkOCC_ViewerSelector no longer caches tolerance fields locally; all Pick() overloads apply myTolerances.Tolerance() on every pick.

Data Exchange

  • Crash in XSControl_Reader::OneShape() #1216: TransferRoots()/TransferList() now allow appending null TopoDS_Shape results (matching TransferEntity() behaviour). OneShape() skips null shapes when building the result compound. Transfer loops modernised: parameter renames (start -> theStart, list -> theList, TR -> aTransferReader), size_t iteration variables, removal of the obsolete ShapeExtend_Explorer STU empty-shape filter (now uniformly handled by appending null shapes and skipping in OneShape()).

  • Segfault in CheckSRRReversesNAUO #1215: Added null-checks around SDR->Definition().PropertyDefinition() before extracting ProductDefinition() for both rep1/pd1 and rep2/pd2 paths.

  • PMI measurement conversion factor #1218: STEPCAF dimension-value conversion extended to recognize StepRepr_ReprItemAndLengthMeasureWithUnitAndQRI and StepRepr_ReprItemAndPlaneAngleMeasureWithUnitAndQRI. Regression test bug33095 extended to validate scaling between m and mm.

  • STEPControl_Writer::SetShapeFixParameters() overload #1235: Additional convenience overload introduced as part of the QADraw migration.

Build and Configuration

  • -Werror enabled in Linux/macOS CI #1209: CMAKE_CXX_FLAGS in the shared GitHub Action configure-occt now includes -Werror -Wzero-as-null-pointer-constant plus a curated allow-list (-Wno-unknown-warning-option, -Wno-error=array-bounds, -Wno-error=maybe-uninitialized, -Wno-error=stringop-overflow, -Wno-deprecated-declarations, -Wno-error=cast-function-type-mismatch). Specific defensive code changes accompanying the flag flip:

    • MathRoot_Trig.hxx: aNZer = std::min<size_t>(aPoly.NbRoots, aZer.size()) defensive clamp before reading roots
    • Poly_MergeNodesTool::PushLastElement: std::min(theNbNodes, 4) clamp before std::sort over a Vec4
    • StepData_EnumTool::AddDefinition: char text[80] = {0} zero-initialisation
    • IGESData_IGESWriter::DirPart: added && i < 8 bound on the short-label copy loop
    • VrmlData_Node VRMLDATA_LCOMPARE: 0L -> nullptr
    • TObj_Persistence macro: (const TObj_Persistence*)0 -> static_cast<const TObj_Persistence*>(nullptr)
    • FlexLexer.h: std::ostream* new_out = 0 -> nullptr
  • Conditional vtkRenderingGL2PSOpenGL2 linkage #1214: vtkRenderingGL2PSOpenGL2 is now appended to USED_TOOLKITS_BY_CURRENT_PROJECT only when the target exists, for both namespaced (VTK 9) and legacy (VTK 7/8) names. Required because the module is omitted on Android/iOS and when building VTK with GLES.

Testing

  • Windows ARM64 master validation #1213: Promoted the Windows ARM64 build/test workflow from the IR branch to master (deleted from build-and-test-multiplatform.yml, added to master-validation.yml).

  • QADraw -> GTest migration (round 1) #1235: Removed multiple legacy DRAW test scripts and several QABugs DRAW command implementations. New GTest suites cover the migrated regressions across ModelingData, ModelingAlgorithms, FoundationClasses, DataExchange, and ApplicationFramework.

  • QADraw -> GTest migration (round 2) #1243: Additional GTests covering historical regressions (intersection, projection, pipe shell, boolean ops, fillet, distances, gp transforms, string hashing). Legacy Tcl tests and corresponding QADraw commands removed from QABugs_*.cxx.

  • Reference data refresh for migration to new station #1248: Adjusted faulties/warnings in IGES and STEP tests to reflect updated results. Tolerance values corrected in multiple shape-validation tests. Expected label counts and properties realigned. HLR and offset error messages refined for consistency. GLTF and STEP metadata checks updated to revised reference sizes/values. Improvements cases updated with TODO removals.

Coding Quality (Two Large Sweeps)

  • Clang-Tidy round 1 #1207 (contributed by JIJINBEI): Focused on:

    • push_back(T(...)) -> emplace_back(...)
    • size() == 0 / size() != 0 -> empty() / !empty()
    • Trivial constructors/destructors -> = default
    • Removal of redundant (void) parameter lists
  • Clang-Tidy round 2 (codebase-wide sweep) #1245 (clang-tidy 22.1.3). Most of the diff comes from readability-braces-around-statements adding explicit { / } to single-statement if/else/loop bodies across .cxx and .pxx files. Other applied checks:

    • modernize-deprecated-headers
    • modernize-redundant-void-arg
    • modernize-use-bool-literals
    • modernize-use-equals-default, modernize-use-equals-delete
    • modernize-use-nullptr, modernize-use-override
    • performance-avoid-endl, performance-move-constructor-init
    • readability-delete-null-pointer, readability-redundant-control-flow, readability-redundant-declaration, readability-redundant-function-ptr-dereference, readability-redundant-member-init, readability-redundant-string-init, readability-static-accessed-through-instance
  • MSVC warning sweep #1246: Follow-up to PR #1212. Various Size() calls switched to Extent()/Length() (int-returning) where they fed Message_ProgressScope. BRepGraphInc_Storage visitors made explicit on the unsupported-id-type fallback to silence MSVC C4715. BRepGraph_NodeId::Invalid() used in place of integer literals; duplicate Standard_EXPORT removed; loop variable rename in tests.

Documentation

  • Typo fixes #1234: BSplCLib_MultDistribution ("mutiplicities" -> "multiplicities"), QABugs_20.cxx ("syncronization" -> "synchronization"), QABugs_19.cxx output strings, STEP rendering properties comments ("applyed" -> "applied").

Migration Guide

Size() Now Returns size_t - Read This First

This is the single most impactful migration item in 8.0.0. Across NCollection_Map, NCollection_DataMap, NCollection_IndexedMap, NCollection_IndexedDataMap, NCollection_Sequence, NCollection_Array1, NCollection_Array2, and NCollection_List:

  • Size() now returns size_t (was Standard_Integer / int)
  • Length() continues to return int - it is the legacy accessor you should use whenever the count must feed int-typed APIs (Message_ProgressScope, indexing arithmetic against int loop counters, format strings, function signatures expecting Standard_Integer)

Symptoms you may see

// Before - compiled cleanly
const Standard_Integer aCount = aMap.Size();  // implicit narrowing, accepted by older code

// After - compiler may warn or (under -Werror, now CI-enforced) reject
const Standard_Integer aCount = aMap.Size();  // -Wnarrowing / -Wsign-compare
// Before - compiled
Message_ProgressScope aPS(theProgress, "Processing", aSeq.Size());  // int parameter

// After - pass the int accessor instead
Message_ProgressScope aPS(theProgress, "Processing", aSeq.Length());
// Before - mixed-type loop
for (int i = 0; i < aMap.Size(); ++i) { ... }  // signed/unsigned compare

// After - use Length() to keep int semantics, OR switch the loop counter to size_t
for (int i = 0; i < aMap.Length(); ++i) { ... }
// or
for (size_t i = 0; i < aMap.Size(); ++i) { ... }

Mechanical migration rule

Use site Before After
Pass to an int-typed API (progress scope, function expecting Standard_Integer, format %d) c.Size() c.Length()
Compare against an int loop counter c.Size() c.Length()
Use as an unsigned count in arithmetic / pass to a size_t API c.Size() c.Size() (no change; gain size_t semantics)
Capacity reservations on STL/size_t APIs c.Size() c.Size() (no change)

When in doubt, prefer Length() for backward compatibility - it preserves the historical type contract. Use Size() only when you actively want size_t semantics.

int overloads still work

ReSize(), BeginResize(), EndResize(), and friends retain their int-taking overloads. They now delegate through a shared NbBucketsFromInt() helper that guards against negative inputs.

NCollection_Vector Deprecated - Migrate to NCollection_DynamicArray

#1230

// Before
#include <NCollection_Vector.hxx>
NCollection_Vector<TopoDS_Shape> aVec;

// After
#include <NCollection_DynamicArray.hxx>
NCollection_DynamicArray<TopoDS_Shape> aVec;

NCollection_Vector continues to compile under a deprecation warning. NCollection_DynamicArray is now backed by NCollection_LinearVector<T*> of fixed-size blocks with O(1) indexed access via precomputed shift/mask.

For new code that does not require stable element addresses across growth, prefer NCollection_LinearVector<T> directly - it is contiguous, uses Standard::Reallocate, and matches std::vector's memory model.

NCollection_BasePointerVector Removed

#1212

Replace with NCollection_LinearVector<T*>. No backward-compatibility shim is provided.

BRepGraph: BuilderView -> EditorView

#1212, #1237, #1242

BuilderView is removed. All programmatic mutation goes through EditorView.

// Before
auto aBuilder = aGraph.BuilderView();
aBuilder.SomeMutation(...);

// After
auto aEditor = aGraph.EditorView();
aEditor.SomeMutation(...);
// Field-level RAII mutation:
{
  auto aMut = aEditor.Mut<FaceDef>(aFaceId);
  aMut->SomeField = aValue;
} // OwnGen / SubtreeGen propagated automatically here

BRepGraph builder lifecycle

// Before
BRepGraph_Builder aBuilder(aGraph, aShape);
aBuilder.Perform();

// After
BRepGraph_Builder aBuilder(aGraph, aShape);
aBuilder.Add();           // one-shot add
// or
aGraph.Clear();           // canonical rebuild boundary
aBuilder.Add();

Product/occurrence renames

Before After
AddAssembly CreateEmptyProduct
AddOccurrence LinkProducts
occurrence mutation directly on view Editor().Occurrences()

Layer / usage renames

Before After
BRepGraph_ParamLayer BRepGraph_LayerParam
BRepGraph_RegularityLayer BRepGraph_LayerRegularity
BRepGraphInc_Usage BRepGraphInc_Instance

Roots API

RootNodeIds() is removed. Use RootProductIds(), which returns product roots only.

BRepGraphInc_WireExplorer

Now requires a VertexRefLookup parameter as part of the RefId entity model rework.

V3d Grids: Unbounded by Default

#1223

V3d_RectangularGrid is now unbounded by default (SizeX = SizeY = 0). To restore the historical "capped to 0.5 * DefaultViewSize()" behaviour, call SetSizeX(...)/SetSizeY(...) explicitly.

Aspect_GDM_Points is now rendered as shader dots at intersections rather than CPU point markers. Applications that depended on point markers being individually selectable must present them through a dedicated AIS object.

Grids no longer rely on Graphic3d_Structure view affinity. Views added to the viewer after V3d_Viewer::ActivateGrid() must trigger a re-broadcast (Grid()->Display() or re-activate) to pick up the grid.

The shader requires GL 3.2 / GLES 3.0 (uses gl_VertexID and gl_FragDepth). Older driver/profile combinations will not see grid rendering.

IVtk: SetTolerance(float) Removed

#1204

// Before
aPicker->SetTolerance(2.0f);
const float aTol = aPicker->GetTolerance();

// After
aPicker->SetPixelTolerance(2);
const Standard_Integer aTol = aPicker->PixelTolerance();

The new API forwards directly to SelectMgr_ViewerSelector and is applied on every Pick() (the previous local cache is gone).

Standard_DEPRECATED_STD Macro

#1241

If you maintain downstream code that defines its own deprecation macros conflicting with OCCT's, note the new Standard_DEPRECATED_STD(...) form, which expands to standard [[deprecated("...")]] and respects OCCT_NO_DEPRECATED. Existing Standard_DEPRECATED(...) continues to work; Standard_DEPRECATED_STD is preferred for new alias headers.

Downstream Builds Adopting -Werror

If you mirror the OCCT CI flags downstream (-Werror -Wzero-as-null-pointer-constant), you may surface latent issues that the OCCT codebase has now cleaned up. The defensive patterns applied in PR #1209 are a useful template:

  • Bound-clamp before std::sort / array reads even when the bound looks redundant
  • Zero-initialise stack buffers (char text[80] = {0})
  • Add an explicit && i < N bound on copy loops where N matches the destination capacity
  • Replace (T*)0 / 0L literals with nullptr / static_cast<T*>(nullptr) in macros and default arguments

Removed Functionality (since 8.0.0-rc5)

Item Commit Replacement
BRepGraph_BuilderView #1212 BRepGraph_EditorView
NCollection_BasePointerVector #1212 NCollection_LinearVector<T*>
NCollection_BaseMap::Statistics #1212 (unused; no replacement)
BRepGraph::RootNodeIds() #1212 RootProductIds()
BRepGraph_Builder::Perform() #1237 BRepGraph_Builder::Add() (+ BRepGraph::Clear())
IVtkTools_ShapePicker::SetTolerance(float) / GetTolerance() #1204 SetPixelTolerance(int) / PixelTolerance()
IVtkOCC_ViewerSelector cached tolerance fields #1204 myTolerances.Tolerance() applied per Pick()
Legacy CPU V3d grid presentation pipeline (RectangularGridStructure/CircularGridStructure, myCur* caches, DefineLines/DefinePoints) #1223 Shader-based grid (single path)
V3d_RectangularGrid default-bounded behaviour #1223 Unbounded by default; explicit SetSizeX/SetSizeY to bound

Deprecated Functionality (since 8.0.0-rc5)

Item Commit Replacement
NCollection_Vector #1230 NCollection_DynamicArray (or NCollection_LinearVector for new code)

Performance Improvements Summary

  • BVH-based polyhedra interference #924: O(log n) dual-tree traversal replaces pairwise triangle scans; BVH_LinearBuilder-based construction
  • Lock-free NCollection_IncAllocator #1212: std::shared_mutex + CAS bump allocation; exclusive lock taken only on new-block allocation
  • NCollection_DynamicArray power-of-two block sizing #1212: O(1) indexing via precomputed shift/mask
  • Shader grid path #1223: Eliminates O(NxM) CPU vertex rebuilds on every grid/camera change
  • Incremental BRepGraph reverse-index updates #1242: Avoids full rebuilds in many editor operations
  • TopExp_Explorer::Clear() allocation reuse #1195: In-place iterator reset removes Reallocate(0)/Reallocate(N) churn
  • Quadratic wire-fixing cost reduction in ShapeFix #1227

Beta Phase Plan

The remainder of the cycle to May 7, 2026 is dedicated to:

  1. Documentation: User-facing docs, migration guide refinements, README and module docs polish.
  2. Sample folder modernization: Update samples/ to reflect the 8.0.0 project layout, the new BRepGraph/EditorView APIs, the shader-grid vgrid invocations, and the Length()/Size() distinction in NCollection containers.
  3. Critical-bug-only changes: Only regressions or critical defects surfaced during the Beta soak are eligible for cherry-pick. No new features, refactors, or non-critical fixes are planned.

If the Beta soak is stable and no regressions are detected, the final 8.0.0 release tag will be cut on May 7, 2026 with no further code changes.


Acknowledgments

We thank all contributors who helped make this release possible through their code contributions, bug reports, and testing.

New Contributors

Full Changelog: V8_0_0_rc5...V8_0_0_beta1

Don't miss a new OCCT release

NewReleases is sending notifications on new releases.