Add Chromium-only Blender WebEngine parity work
This commit is contained in:
224
blender-5.2.0/extern/opensubdiv-source/documentation/vtr_overview.rst
vendored
Normal file
224
blender-5.2.0/extern/opensubdiv-source/documentation/vtr_overview.rst
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
..
|
||||
Copyright 2013 Pixar
|
||||
|
||||
Licensed under the terms set forth in the LICENSE.txt file available at
|
||||
https://opensubdiv.org/license.
|
||||
|
||||
|
||||
Vtr Overview
|
||||
------------
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
:backlinks: none
|
||||
|
||||
Vectorized Topology Representation (Vtr)
|
||||
========================================
|
||||
|
||||
*Vtr* consists of a suite of classes that collectively provide an intermediate
|
||||
representation of topology that supports efficient refinement.
|
||||
|
||||
*Vtr* is intended for internal use only and is currently accessed through the
|
||||
*Far* layer by the `Far::TopologyRefiner <far_overview.html>`__, which assembles
|
||||
these *Vtr* classes to meet the topological and refinement needs of the *Far*
|
||||
layer. What follows is therefore more intended to provide insite into the
|
||||
underlying architecture than to describe particular usage. For documentation
|
||||
more relevant to direct usage, proceed to the *Far* section previously noted.
|
||||
|
||||
*Vtr* is vectorized in that its topological data is stored more as a collection of
|
||||
vectors of primitive elements rather than as the faces, vertices and edges that
|
||||
make up many other topological representations. It is essentially a
|
||||
structure-of-arrays (SOA) approach to topology in contrast to the more common
|
||||
array-of-structures pattern found in many other topological representations.
|
||||
Vtr's use of vectors allows it to be fairly efficient in its use of memory and
|
||||
similarly efficient to refine, but the topology is fixed once defined.
|
||||
|
||||
*Vtr* classes are purely topological. They are even more independent of the
|
||||
representation of vertices, faces, etc. than Hbr in that they are not even
|
||||
parameterized by an interface to such components. So the same set of Vtr
|
||||
objects can eventually be used to serve more than one representation of these
|
||||
components. The primary requirement is that a mesh be expressable as an
|
||||
indexable set (i.e. a vector or array) of vertices, edges and faces. The index
|
||||
of a component uniquely identifies it and properties are retrieved by referring
|
||||
to it by index.
|
||||
|
||||
It's worth qualifying the term "topological" here and elsewhere -- we generally
|
||||
refer to "topology" as "subdivision topology" rather than "mesh topology". A
|
||||
subdivision hierarchy is impacted by the presence of semi-sharp creasing, as
|
||||
the subdivision rules change in response to that creasing. So subdivision
|
||||
topology includes the sharpness values assigned to edges and vertices that
|
||||
affect the semi-sharp creasing.
|
||||
|
||||
The two primary classes in *Vtr* consist of:
|
||||
|
||||
* `Vtr::Level <#vtrlevel>`__ - a class representing complete vertex topology
|
||||
for a level
|
||||
* `Vtr::Refinement <#vtrrefinement>`__ - a class mapping a parent *Vtr::Level*
|
||||
to a child level
|
||||
|
||||
Others exist to represent the following:
|
||||
|
||||
* selection and appropriate tagging of components for sparse refinement
|
||||
* divergence of face-varying topology from the vertex topology
|
||||
* mapping between face-varying topology at successive levels
|
||||
* common low-level utilities, e.g. simple array classes
|
||||
|
||||
|
||||
Vtr::Level
|
||||
==========
|
||||
|
||||
*Vtr::Level* is a complete topological description of a subdivision level, with the
|
||||
topological relations, sharpness values and component tags all stored in
|
||||
vectors (literally std::vectors, but easily changed via typedefs). There are no
|
||||
classes or objects for the mesh component types (i.e. faces, edges and
|
||||
vertices) but simply an integer index to identify each. It can be viewed as a
|
||||
structure-of-arrays representation of the topology: any property related to a
|
||||
particular component is stored in an array and accessible using the index
|
||||
identifying that component. So with no classes the for the components, its
|
||||
difficult to say what constitutes a "vertex" or a "face": they are each the sum
|
||||
of all the fields scattered amongst the many vectors included.
|
||||
|
||||
*Level* represents a single level of a potential hierarchy and is capable of
|
||||
representing the complete base mesh. There are no members that relate data in
|
||||
one level to any other, either below or above. As such, any *Level* can be
|
||||
used as the base level for a new subdivision hierarchy (potentially more than
|
||||
one). All relationships between separate levels are maintained in the
|
||||
`Vtr::Refinement <#vtrrefinement>`__ class.
|
||||
|
||||
Topological Relationships
|
||||
*************************
|
||||
|
||||
*Level* requires the definition of and associations between a fixed set of
|
||||
indexable components for all three component types, i.e. an explicit edge list
|
||||
in addition to the expected set of vertices and faces. There are no explicit
|
||||
component objects in the representation, only an integer index (*Vtr::Index*)
|
||||
identifying each component within the set and data associated with that
|
||||
component in the various vectors.
|
||||
|
||||
The topology is stored as six sets of incident relations between the components:
|
||||
two each for the two other component types incident each component type, i.e.:
|
||||
|
||||
* for each face, its incident vertices and incident edges
|
||||
* for each edge, its incident vertices and incident faces
|
||||
* for each vertex, its incident edges and incident faces
|
||||
|
||||
The collection of incidence relations is a vectorized variation of AIF (the
|
||||
"Adjacency and Incidence Framework"). The set of these six incidence relations
|
||||
is not minimal (only four are required, but that set excludes the most desired
|
||||
face-vertex relation) but all six are kept and maintained to facilitate faster
|
||||
refinement. While the sizes of several vectors are directly proportional to the
|
||||
number of vertices, edges or faces to which the data is associated, the sizes
|
||||
of some of the vectors for these relations is more cumulative and so additional
|
||||
vectors of offsets is required (typical of the face-vertex list commonly used
|
||||
as the minimal definition of mesh topology).
|
||||
|
||||
Vectors for the sharpness values associated with crease edges and corner
|
||||
vertices are included (and so sized according to the number of edges and
|
||||
vertices), along with additional tags for the components that may be helpful to
|
||||
refinement (i.e. the type of subdivision Rule associated with each vertex).
|
||||
|
||||
A *Level* is really just a container for data in a subdivision level, and so
|
||||
its public methods are primarily to access that data. Modification of the data
|
||||
is protected and only made available to classes that are intended to construct
|
||||
*Levels*: currently the *Far* factory class that is responsible for building the
|
||||
base level, and the `Vtr::Refinement <#vtrrefinement>`__ class that constructs
|
||||
subsequent levels during refinement.
|
||||
|
||||
Memory Efficiency
|
||||
*****************
|
||||
|
||||
One of the advantages in storing data in what is essentially a
|
||||
structure-of-arrays, rather than the array-of-structures more typical of
|
||||
topological representations, is that we can be more selective about memory
|
||||
usage in some cases. Particularly in the case of uniform refinement, when the
|
||||
data in subsequent levels is typically 4x its predecessor, we can minimize what
|
||||
we either generate or keep around at each level. For instance, if only a
|
||||
face-list is required at the finest level, we only need to generate one of the
|
||||
six topological relations: the vertices incident each face. When we do keep
|
||||
*Levels* around in memory (as is the case with the `Far::TopologyRefiner
|
||||
<far_overview.html>`__) we do have do have the opportunity to prune what is not
|
||||
strictly necessary after the refinement. Just as with construction, whatever
|
||||
classes are privileged to construct a *Level* are likely those that will be
|
||||
privileged to prune its contents when needed.
|
||||
|
||||
The current implementation of Level is far from optimal though -- there are
|
||||
opportunities for improvement. After one level of subdivision, the
|
||||
faces in a Level will be either all quads or tris. Having specializations
|
||||
for these cases and using the more general case in support of N-sided faces
|
||||
for the base level only is one possibility. Levels also allocate dozens of
|
||||
vectors in which to store all data. Since these vectors are of fixed size
|
||||
once created, they could be aggregated by partitioning one or a smaller
|
||||
number of larger block of memory into the desired pieces. The desire to
|
||||
make some of these improvements is part of why Vtr is not directly exposed
|
||||
for public use and instead exposed via Far.
|
||||
|
||||
|
||||
Vtr::Refinement
|
||||
===============
|
||||
|
||||
While `Vtr::Level <#vtrlevel>`__ contains the topology for each subdivision level,
|
||||
*Vtr::Refinement* is responsible for creating a new level via refinement of an
|
||||
existing one, and for maintaining the relationships between the components in
|
||||
the parent and child levels. So a simplified view of a subdivision hierarchy
|
||||
with *Vtr* is a set of *Levels* with a *Refinement* between each
|
||||
successive pair.
|
||||
|
||||
.. image:: images/vtr_refinement.1.png
|
||||
:align: center
|
||||
:target: images/vtr_refinement.1.png
|
||||
|
||||
|
||||
*Refinement* is a friend of *Level* and will populate a child level from
|
||||
a parent given a set of refinement parameters. Aside from parameters related
|
||||
to data or depth, there are two kinds of refinement supported: uniform and
|
||||
sparse. The latter sparse refinement requires selection of an arbitrary set of
|
||||
components -- any dependent or *"neighboring"* components that are required for
|
||||
the limit will be automatically included. So feature-adaptive refinement is
|
||||
just one form of this selective sparse refinement, the criteria being the
|
||||
topological features of interest (creases and extra-ordinary vertices). The
|
||||
intent is to eventually provide more flexibility to facilitate the refinement
|
||||
of particular regions of interest or more dynamic/adaptive needs.
|
||||
|
||||
*Refinement* has also been subclassed according to the type of topological
|
||||
split being performed, i.e. splitting all faces into quads or tris via the
|
||||
*QuadRefinement* and *TriRefinement* subclasses. As noted with *Vtr::Level*,
|
||||
there is further room for improvement in memory and/or performance here by
|
||||
combining more optimal specializations for both *Refinement* and *Level* --
|
||||
with consideration of separating the uniform and sparse cases.
|
||||
|
||||
Parent-child and child-parent relationships
|
||||
*******************************************
|
||||
|
||||
While *Refinement* populates a new child *Level* as part of its refinement
|
||||
operation, it also accumulates the relationships between the parent and child
|
||||
level (and as with *Level*, this data is stored in vectors indexable by the
|
||||
components).
|
||||
|
||||
The associations between components in the two levels was initially only
|
||||
uni-directional: child components were associated with incident components
|
||||
of a parent component based on the parent components topology, so we had a
|
||||
parent-to-child mapping (one to many). Storing the reverse child-to-parent
|
||||
mapping was avoided to reduce memory (particularly in the case of uniform
|
||||
refinement) as it often was not necessary, but a growing need for it,
|
||||
particularly in the case of sparse feature-adaptive refinement, lead to it
|
||||
being included.
|
||||
|
||||
Data flexibility
|
||||
****************
|
||||
|
||||
One of the advantages of the structure-of-arrays representation in both
|
||||
*Level* and *Refinement* is that we can make more dynamic choices about what
|
||||
type of data we choose to allocate and use based on needs. For instance, we can
|
||||
choose between maintaining the parent-child or child-parent mapping in
|
||||
*Refinement*, or both if needed, and we can remove one if no longer
|
||||
necessary. An active example of this is uniform refinement: if we only require
|
||||
the face-vertex list at the finest subdivision level, there is no need to
|
||||
generate a complete topological description of that level (as would be required
|
||||
of more traditional representations), and given that level is 4x the magnitude
|
||||
of its parent, the savings are considerable.
|
||||
|
||||
Currently there is nothing specific to a subdivision scheme in the refinement
|
||||
other than the type of topological splitting to apply. The refinement does
|
||||
subdivide sharpness values for creasing, but that too is independent of scheme.
|
||||
Tags were added to the base level that are propagated through the refinement
|
||||
and these too are dependent on the scheme, but are applied externally.
|
||||
Reference in New Issue
Block a user