Fix T103354: Author extents on UsdGeomMesh #104676
|
@ -5,12 +5,15 @@
|
|||
#include "usd_writer_material.h"
|
||||
|
||||
#include <pxr/base/tf/stringUtils.h>
|
||||
#include <pxr/usd/usdGeom/bboxCache.h>
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BLI_assert.h"
|
||||
|
||||
#include "DNA_mesh_types.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
/* TfToken objects are not cheap to construct, so we do it once. */
|
||||
namespace usdtokens {
|
||||
/* Materials */
|
||||
|
@ -149,4 +152,37 @@ bool USDAbstractWriter::mark_as_instance(const HierarchyContext &context, const
|
|||
return true;
|
||||
}
|
||||
|
||||
void USDAbstractWriter::author_extent(const pxr::UsdTimeCode timecode, pxr::UsdGeomBoundable &prim)
|
||||
{
|
||||
/* Compute the bounds for a boundable prim, and author the result as the extent attribute.
|
||||
*
|
||||
* Although this method works for any boundable prim, it is preferred to use Blender's own
|
||||
* cached bounds when possible.
|
||||
*
|
||||
* This method does not author the extentsHint attribute, which is also important to provide.
|
||||
* Whereas the extent attribute can only be authored on prims inheriting from UsdGeomBoundable,
|
||||
* an extentsHint can be provided on any prim, including scopes. This extentsHint should be
|
||||
* authored on every prim in a hierarchy being exported.
|
||||
wave marked this conversation as resolved
|
||||
*
|
||||
* Note that this hint is only useful when importing or inspecting layers, and should not be
|
||||
* taken into account when computing extents during export.
|
||||
*
|
||||
* TODO: also provide method for authoring extentsHint on every prim in a hierarchy.
|
||||
*/
|
||||
|
||||
/* do not use any existing extentsHint that may authored, instead recompute the extent when authoring it */
|
||||
const bool useExtentsHint = false;
|
||||
const pxr::TfTokenVector includedPurposes{pxr::UsdGeomTokens->default_};
|
||||
pxr::UsdGeomBBoxCache bboxCache(timecode, includedPurposes, useExtentsHint);
|
||||
pxr::GfBBox3d bounds = bboxCache.ComputeLocalBound(prim.GetPrim());
|
||||
if (pxr::GfBBox3d() == bounds) {
|
||||
/* This will occur, for example, if a mesh does not have any vertices. */
|
||||
WM_reportf(RPT_ERROR, "USD Export: no bounds could be computed for %s", prim.GetPrim().GetName().GetText());
|
||||
return;
|
||||
}
|
||||
|
||||
pxr::VtArray<pxr::GfVec3f> extent{ (pxr::GfVec3f)bounds.GetRange().GetMin(), (pxr::GfVec3f)bounds.GetRange().GetMax() };
|
||||
prim.CreateExtentAttr().Set(extent);
|
||||
}
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include <pxr/usd/usd/stage.h>
|
||||
#include <pxr/usd/usdShade/material.h>
|
||||
#include <pxr/usd/usdUtils/sparseValueWriter.h>
|
||||
#include <pxr/usd/usdGeom/boundable.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
|
@ -67,6 +68,8 @@ class USDAbstractWriter : public AbstractHierarchyWriter {
|
|||
* Reference the original data instead of writing a copy.
|
||||
*/
|
||||
virtual bool mark_as_instance(const HierarchyContext &context, const pxr::UsdPrim &prim);
|
||||
|
||||
virtual void author_extent(const pxr::UsdTimeCode timecode, pxr::UsdGeomBoundable &prim);
|
||||
};
|
||||
|
||||
} // namespace blender::io::usd
|
||||
|
|
|
@ -62,6 +62,8 @@ void USDHairWriter::do_write(HierarchyContext &context)
|
|||
colors.push_back(pxr::GfVec3f(cache[0]->col));
|
||||
curves.CreateDisplayColorAttr(pxr::VtValue(colors));
|
||||
}
|
||||
|
||||
this->author_extent(timecode, curves);
|
||||
}
|
||||
|
||||
bool USDHairWriter::check_is_animated(const HierarchyContext & /*context*/) const
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include <pxr/usd/usdGeom/mesh.h>
|
||||
#include <pxr/usd/usdGeom/primvarsAPI.h>
|
||||
#include <pxr/usd/usdGeom/bboxCache.h>
|
||||
#include <pxr/usd/usdShade/material.h>
|
||||
#include <pxr/usd/usdShade/materialBindingAPI.h>
|
||||
|
||||
|
@ -247,6 +248,15 @@ void USDGenericMeshWriter::write_mesh(HierarchyContext &context, Mesh *mesh)
|
|||
if (usd_export_context_.export_params.export_materials) {
|
||||
assign_materials(context, usd_mesh, usd_mesh_data.face_groups);
|
||||
}
|
||||
|
||||
/* Blender grows its bounds cache to cover animated meshes, so only author once. */
|
||||
float bound_min[3];
|
||||
float bound_max[3];
|
||||
INIT_MINMAX(bound_min, bound_max);
|
||||
BKE_mesh_minmax(mesh, bound_min, bound_max);
|
||||
pxr::VtArray<pxr::GfVec3f> extent{ pxr::GfVec3f{ bound_min[0], bound_min[1], bound_min[2]},
|
||||
pxr::GfVec3f{ bound_max[0], bound_max[1], bound_max[2]} };
|
||||
usd_mesh.CreateExtentAttr().Set(extent);
|
||||
}
|
||||
|
||||
static void get_vertices(const Mesh *mesh, USDMeshData &usd_mesh_data)
|
||||
|
|
Loading…
Reference in New Issue
Since this situation doesn't seem to abort the export itself, I think
RPT_WARNING
would be more suitable here.