14#include <pxr/base/vt/array.h>
15#include <pxr/usd/usdGeom/points.h>
16#include <pxr/usd/usdGeom/primvarsAPI.h>
30 const pxr::UsdGeomPoints usd_points = pxr::UsdGeomPoints::Define(stage,
usd_path);
32 pxr::VtArray<pxr::GfVec3f> usd_positions;
33 usd_positions.assign(positions.
begin(), positions.
end());
35 pxr::UsdAttribute attr_positions = usd_points.CreatePointsAttr(pxr::VtValue(),
true);
36 if (!attr_positions.HasValue()) {
37 attr_positions.Set(usd_positions, pxr::UsdTimeCode::Default());
41 if (!radii.is_empty()) {
42 pxr::VtArray<float> usd_widths;
43 usd_widths.resize(radii.size());
44 for (
const int i : radii.index_range()) {
45 usd_widths[i] = radii[i] * 2.0f;
48 pxr::UsdAttribute attr_widths = usd_points.CreateWidthsAttr(pxr::VtValue(),
true);
49 if (!attr_widths.HasValue()) {
50 attr_widths.Set(usd_widths, pxr::UsdTimeCode::Default());
55 this->write_velocities(points, usd_points, timecode);
56 this->write_custom_data(points, usd_points, timecode);
58 const pxr::UsdPrim usd_prim = usd_points.GetPrim();
59 this->set_extents(usd_prim, timecode);
65 switch (blender_domain) {
67 return pxr::UsdGeomTokens->varying;
75 const pxr::UsdGeomPoints &usd_points,
76 const pxr::UsdTimeCode timecode)
81 if (!pv_interp || !pv_type) {
84 "Attribute '%s' (Blender domain %d, type %d) cannot be converted to USD",
96 const pxr::TfToken pv_name(
98 const pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(usd_points);
100 pxr::UsdGeomPrimvar pv_attr = pv_api.CreatePrimvar(pv_name, *pv_type, *pv_interp);
106void USDPointsWriter::write_custom_data(
const PointCloud *points,
107 const pxr::UsdGeomPoints &usd_points,
108 const pxr::UsdTimeCode timecode)
110 const bke::AttributeAccessor attributes = points->
attributes();
112 attributes.foreach_attribute([&](
const bke::AttributeIter &iter) {
115 ELEM(iter.name,
"position",
"radius",
"id",
"velocity"))
120 this->write_generic_data(iter, usd_points, timecode);
124void USDPointsWriter::write_velocities(
const PointCloud *points,
125 const pxr::UsdGeomPoints &usd_points,
126 const pxr::UsdTimeCode timecode)
130 if (velocity.is_empty()) {
134 Span<pxr::GfVec3f>
data = velocity.cast<pxr::GfVec3f>();
135 pxr::VtArray<pxr::GfVec3f> usd_velocities;
136 usd_velocities.assign(
data.begin(),
data.end());
138 pxr::UsdAttribute attr_vel = usd_points.CreateVelocitiesAttr(pxr::VtValue(),
true);
139 if (!attr_vel.HasValue()) {
140 attr_vel.Set(usd_velocities, pxr::UsdTimeCode::Default());
146void USDPointsWriter::set_extents(
const pxr::UsdPrim &prim,
const pxr::UsdTimeCode timecode)
148 pxr::UsdGeomBoundable boundable(prim);
150 pxr::VtArray<pxr::GfVec3f> extent;
151 pxr::UsdGeomBoundable::ComputeExtentFromPlugins(boundable, timecode, &extent);
153 pxr::UsdAttribute attr_extent = boundable.CreateExtentAttr(pxr::VtValue(),
true);
154 if (!attr_extent.HasValue()) {
155 attr_extent.Set(extent, pxr::UsdTimeCode::Default());
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
struct PointCloud PointCloud
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between and object coordinate space Combine Create a color from its and value channels Color Retrieve a color attribute
constexpr const T * end() const
constexpr const T * begin() const
constexpr const char * c_str() const
eCustomDataType data_type
GAttributeReader get() const
const pxr::SdfPath & usd_path() const
ReportList * reports() const
pxr::UsdTimeCode get_export_time_code() const
pxr::UsdUtilsSparseValueWriter usd_value_writer_
const USDExporterContext usd_export_context_
virtual void do_write(HierarchyContext &context) override
bool attribute_name_is_anonymous(const StringRef name)
std::string make_safe_name(const std::string &name, bool allow_unicode)
void copy_blender_attribute_to_primvar(const GVArray &attribute, const eCustomDataType data_type, const pxr::UsdTimeCode timecode, const pxr::UsdGeomPrimvar &primvar, pxr::UsdUtilsSparseValueWriter &value_writer)
static std::optional< pxr::TfToken > convert_blender_domain_to_usd(const bke::AttrDomain blender_domain, bool is_bezier)
std::optional< pxr::SdfValueTypeName > convert_blender_type_to_usd(const eCustomDataType blender_type, bool use_color3f_type)
VecBase< float, 3 > float3
const USDExportParams & export_params