Bifrost Geometry Editing
A Bifrost Geometry is built on top of a Bifrost Object.
Reading the content of a Bifrost Geometry is simply navigating the Bifrost Geo Properties, however, modifying Geo Properties may entail extra data copies due to value semantics.
In this section we present how data copies can be reduced by extracting
Geo Properties before editing them.
Geo Property Getters and Setters
There are various Geo Property getters and setters available from the Geometry SDK, refer to the file sdk/include/Bifrost/Geometry/GeoProperty.h
from your installation's SDK include directory.
C++ examples of using the getters such as Bifrost::Geometry::getDataGeoPropValues<>
and Bifrost::Geometry::getRangeGeoPropIndices
can be found in your installation's SDK example directories sdk/examples/MeshArea
, sdk/examples/ObjWriter
, and others. Getters do not imply a data copy of managed types stored as Amino::Ptr
. Only the reference count of the Amino::Ptr
to the data is incremented.
Replacing a Geo Property is achieved through setters such as Bifrost::Geometry::setDataGeoPropValues
. A C++ example can be found in your installation's SDK example test directory of sdk/examples/SimpleNUBSCurve
. Setters simply create or replace the existing Geo Property. If the replaced Geo Property is an Amino::Ptr
managed data type then its reference count is decremented and the Geo Property is released if its reference count falls to 0.
Modifying Geo Properties
Getters will increment the reference count of an Amino::Ptr
managed type. The reference count of the returned Amino::Ptr
will be greater or equal to 2: at least one reference due to the Bifrost Geometry Object holding the Geo Property and one from the getter's returned data.
Geo Property modifications involve the use of Amino::Ptr::toMutable()
to obtain write access to the data. If the reference count of the Amino::Ptr
managed Geo Property is greater than or equal to 2, calling Amino::Ptr::toMutable()
will trigger a true copy. To minimize data copies, the Bifrost Geometry SDK provides functionality to extract a Geo Property and its data. The extraction preserves the reference count of the Geo Property by removing it from the Bifrost Geometry object that holds it.
Note that if a Geo Property is only held by one Bifrost Geometry object and is not being accessed by other code, its reference count is one. In this case, modifications can be made in place without triggering any data copies when using Amino::Ptr::toMutable()
.
C++ examples of using the guards are provided in your installation's SDK example directories sdk/examples/TwistDeformer
and sdk/examples/MeshWeldUV
. The examples use Bifrost::Geometry::createDataGeoPropGuard
and Bifrost::Geometry::createRangeGuard
. Below, we outline the usage of Bifrost::Geometry::createDataGeoPropGuard
.
// Assuming that we have as input a modifiable Bifrost Geometry mesh object...
void scale_positions( Bifrost::Object & io_mesh, float scale){
// Returns the extracted Bifrost::Geometry::DataGeoPropertyGuard<> that reflects the
// structure of a Data Geo Property.
// The Data Geo Property was extracted from io_mesh input.
// Amino::Ptr::toMutable() was applied to the extracted Data Geo Property.
auto positions = Bifrost::Geometry::createDataGeoPropGuard<Bifrost::Math::float3>(
io_mesh, Bifrost::Geometry::sPointPosition);
assert(positions);
// Iterate over the positions (Bifrost::Math::float3)
// Note: .data() accesses the data array of the Data Geo Property
for (auto& position : positions.data()) {
position.x *= scale;
position.y *= scale;
position.z *= scale;
}
// RAII in action! Nothing to do to set the Data Geo Property.
// The guard will go out of scope and set back the Data Geo Property
// on the input/output Bifrost::Object
}