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",
92 if (attribute.is_empty()) {
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)
128 const VArraySpan velocity = *points->attributes().lookup<
float3>(
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
Span< NewT > constexpr cast() 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)
const USDExportParams & export_params
const pxr::SdfPath usd_path
const pxr::UsdStageRefPtr stage