Repository navigation
MeshData: build attributes from mdspans - #23
Merged
Merged
Conversation
- MeshAttribute is constructed from a rank-1 or rank-2 (components x elements) mdspan of any arithmetic type, layout and accessor; it derives component_count()/count() from the shape and stores column-major float (element-major memory). Data is private: data(), view(), view<D>(). - MeshData::add_attribute takes an mdspan; the flat-range overload is a thin adapter and rejects sizes that are not a multiple of the component count. - Fix view extents order ((components, count), not (count, components)); view() is always valid (possibly empty), view<D>() is optional. - Scalar extraction uses zipper: row(component) or colwise().norm() (previously rowwise squared norm over the wrong axis). - mesh_conversion passes OBJ vertex/triangle matrices as mdspans directly. - Property: Vec3Value min uses numeric_limits::lowest() (min() is the smallest positive float). - Point zipper.wrap at refactor/defer-mdspan-accessor (zipper#41) for const as_mdspan().
zipper#41 now honors mdspan layouts (incl. layout_stride) and accessors, so the hand-written copy loop and memcpy fast path become a zipper cast assignment. Adds a strided (interleaved buffer) input test.
- Store values in a zipper column-major matrix (components x count) per element type, held in a variant; component_count()/count() come from the matrix instead of separately kept counters. - Input keeps its type, widened to float/double/int32/uint32 (e.g. uint8 -> uint32); type()/holds<T>()/view<T[, D]>()/visit(f) replace the float-only data()/view(). - RoleBinding records its own component count and converts non-float attributes into its float buffer (also used for scalar component and magnitude extraction); raw_data() returns const float *, and is_converted() reports whether it points at a copy.
Attribute values are plain data, not a linear-algebra matrix: use zipper's DataArray (no arithmetic semantics) instead of ColVectors. Bindings still wrap views in MatrixBase for the float conversion and magnitudes. Note DataArray's LeftMajor = true is row-major, so column-major storage is DataArray_<T, dextents<2>, false>.
Replace the nested conditional_t with a trait specialized per supported input type (float, double, signed/unsigned integers up to 32 bits); its missing ::type for other types drives an AttributeValue concept that constrains the MeshAttribute constructor and MeshData::add_attribute instead of a static_assert.
- MeshAttribute::view<T, D>() and RoleBinding::view<T, D>() return std::expected<view, ViewError> (Unbound / WrongType / WrongComponentCount, with the actual type and component count). - RoleBinding no longer converts to float: it views the whole attribute, a selected component (strided view, no copy), or the magnitude (derived attribute; float stays float, other types become double). type() and visit(f) expose the bound values in their own type. - VulkanMeshDrawable converts to float at upload (contiguous float data is uploaded in place); normalize_mesh computes in float from any type.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on
feature/controls-model. Depends on mtao/zipper#41, which is now merged.subprojects/zipper.wrapis back onmain.Changes
MeshAttributebuilt from an mdspan. It takes a rank-1 mdspan (one scalar per element) or a rank-2 mdspan with extents(components, elements), with any arithmetic type, layout (includinglayout_stride) or accessor. Values are stored in a column-major zipperDataArray(plain data with no arithmetic semantics), which is the only source of the shape:component_count()andcount()read it, so there are no separately kept counters.float,double,int32oruint32, held in astd::variant. Narrower integers widen to the 32-bit type of the same sign (e.g.uint8becomesuint32). Access is throughtype(),holds<T>(),view<T>()/view<T, D>()(std::optional, empty on a type or component-count mismatch) andvisit(f). The conversion goes through a zippercast<T>().MeshAttribute::view<T, D>()andRoleBinding::view<T, D>()returnstd::expected<view, ViewError>. The error says whether the binding wasUnbound, the values have theWrongType(with the actual stored type), or the view had theWrongComponentCount(with the actual count).RoleBindingviews either the whole attribute, one selected component (a strided view into the attribute, with no copy), or the per-element magnitude. The magnitude is computed into a derived attribute:floatstaysfloat, and other types becomedouble.type()andvisit(f)expose the bound values in their own type.VulkanMeshDrawableuploads contiguousfloatbindings in place and converts anything else into a staging buffer.normalize_meshworks in float from any stored type.MeshData::add_attribute(name, domain, mdspan)rejects shapes with 0 or more than 255 components. The flat contiguous-range overload is now a thin adapter, and it rejects data whose length isn't a multiple of the component count. Before, such data was added with only a warning.(components, count). Scalar extraction now uses zipper:row(component)for one component andcolwise().norm()for the magnitude. The previous code used a squaredrowwise()norm, which reduced over the wrong axis.mesh_conversionpasses the OBJ vertex and triangle matrices directly viaas_mdspan(), which removesflatten_columns.Property::Vec3Value::minusesnumeric_limits<float>::lowest().min()is the smallest positive float, so negative values were blocked.Tests
mesh_attribute_from_mdspancovers column- and row-major input, type preservation (double,int32, anduint8widened touint32),view<T, D>, rejection of bad shapes, and strided (interleaved-buffer) input.role_binding_keeps_attribute_typecovers adoubleposition binding viewing the attribute in place, a strideduint32component view, adoublemagnitude, andvisit().role_binding_viewchecks eachViewErrorreason.scalar_binding_magnitude.meson test: 13/13 suites pass.test_scene_graph: 476 assertions in 58 test cases.