USD Import: USD Shapes Support #104707
@ -382,6 +382,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
|
||||
const bool import_materials = RNA_boolean_get(op->ptr, "import_materials");
|
||||
const bool import_meshes = RNA_boolean_get(op->ptr, "import_meshes");
|
||||
const bool import_volumes = RNA_boolean_get(op->ptr, "import_volumes");
|
||||
const bool import_shapes = RNA_boolean_get(op->ptr, "import_shapes");
|
||||
|
||||
const bool import_subdiv = RNA_boolean_get(op->ptr, "import_subdiv");
|
||||
|
||||
@ -443,6 +444,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
|
||||
.import_materials = import_materials,
|
||||
.import_meshes = import_meshes,
|
||||
.import_volumes = import_volumes,
|
||||
.import_shapes = import_shapes,
|
||||
.import_subdiv = import_subdiv,
|
||||
.import_instance_proxies = import_instance_proxies,
|
||||
.create_collection = create_collection,
|
||||
@ -488,6 +490,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
|
||||
uiItemR(col, ptr, "import_materials", 0, NULL, ICON_NONE);
|
||||
uiItemR(col, ptr, "import_meshes", 0, NULL, ICON_NONE);
|
||||
uiItemR(col, ptr, "import_volumes", 0, NULL, ICON_NONE);
|
||||
uiItemR(col, ptr, "import_shapes", 0, NULL, ICON_NONE);
|
||||
uiItemR(box, ptr, "prim_path_mask", 0, NULL, ICON_NONE);
|
||||
uiItemR(box, ptr, "scale", 0, NULL, ICON_NONE);
|
||||
|
||||
@ -577,6 +580,7 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
|
||||
RNA_def_boolean(ot->srna, "import_materials", true, "Materials", "");
|
||||
RNA_def_boolean(ot->srna, "import_meshes", true, "Meshes", "");
|
||||
RNA_def_boolean(ot->srna, "import_volumes", true, "Volumes", "");
|
||||
RNA_def_boolean(ot->srna, "import_shapes", true, "Shapes", "");
|
||||
|
||||
RNA_def_boolean(ot->srna,
|
||||
"import_subdiv",
|
||||
|
@ -83,6 +83,7 @@ set(SRC
|
||||
intern/usd_reader_mesh.cc
|
||||
intern/usd_reader_nurbs.cc
|
||||
intern/usd_reader_prim.cc
|
||||
intern/usd_reader_shape.cc
|
||||
intern/usd_reader_stage.cc
|
||||
intern/usd_reader_volume.cc
|
||||
intern/usd_reader_xform.cc
|
||||
@ -111,6 +112,7 @@ set(SRC
|
||||
intern/usd_reader_mesh.h
|
||||
intern/usd_reader_nurbs.h
|
||||
intern/usd_reader_prim.h
|
||||
intern/usd_reader_shape.h
|
||||
intern/usd_reader_stage.h
|
||||
intern/usd_reader_volume.h
|
||||
intern/usd_reader_xform.h
|
||||
|
245
source/blender/io/usd/intern/usd_reader_shape.cc
Normal file
@ -0,0 +1,245 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
CharlesWardlaw marked this conversation as resolved
|
||||
* Copyright 2023 Nvidia. All rights reserved. */
|
||||
|
||||
#include "BKE_lib_id.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_object.h"
|
||||
|
||||
#include "DNA_cachefile_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
The comment says the header is added The comment says the header is added `for FILE_MAX`, but `FILE_MAX` isn't used here. Make sure the headers included here are actually necessary.
Charles Wardlaw
commented
Removed. Removed.
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "WM_api.h"
|
||||
|
||||
#include "usd_reader_shape.h"
|
||||
|
||||
#include <pxr/usd/usdGeom/capsule.h>
|
||||
#include <pxr/usd/usdGeom/cone.h>
|
||||
#include <pxr/usd/usdGeom/cube.h>
|
||||
#include <pxr/usd/usdGeom/cylinder.h>
|
||||
#include <pxr/usd/usdGeom/sphere.h>
|
||||
#include <pxr/usdImaging/usdImaging/capsuleAdapter.h>
|
||||
#include <pxr/usdImaging/usdImaging/coneAdapter.h>
|
||||
#include <pxr/usdImaging/usdImaging/cubeAdapter.h>
|
||||
#include <pxr/usdImaging/usdImaging/cylinderAdapter.h>
|
||||
#include <pxr/usdImaging/usdImaging/sphereAdapter.h>
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
||||
USDShapeReader::USDShapeReader(const pxr::UsdPrim &prim,
|
||||
const USDImportParams &import_params,
|
||||
const ImportSettings &settings)
|
||||
: USDGeomReader(prim, import_params, settings)
|
||||
{
|
||||
}
|
||||
|
||||
void USDShapeReader::create_object(Main *bmain, double /*motionSampleTime*/)
|
||||
{
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Change this to Change this to `/*motionSampleTime*/` in the function arguments
Charles Wardlaw
commented
Changed. Changed.
|
||||
Mesh *mesh = BKE_mesh_add(bmain, name_.c_str());
|
||||
object_ = BKE_object_add_only_object(bmain, OB_MESH, name_.c_str());
|
||||
object_->data = mesh;
|
||||
}
|
||||
|
||||
void USDShapeReader::read_object_data(Main *bmain, double motionSampleTime)
|
||||
{
|
||||
Mesh *mesh = (Mesh *)object_->data;
|
||||
Mesh *read_mesh = this->read_mesh(
|
||||
mesh, motionSampleTime, import_params_.mesh_read_flag, nullptr);
|
||||
|
||||
if (read_mesh != mesh) {
|
||||
BKE_mesh_nomain_to_mesh(read_mesh, mesh, object_);
|
||||
if (is_time_varying()) {
|
||||
USDGeomReader::add_cache_modifier();
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
This isn't true anymore, this logic with This isn't true anymore, this logic with `mesh->flag` can be removed.
Charles Wardlaw
commented
Removed. Removed.
|
||||
}
|
||||
}
|
||||
|
||||
USDXformReader::read_object_data(bmain, motionSampleTime);
|
||||
}
|
||||
|
||||
template<typename Adapter>
|
||||
void USDShapeReader::read_values(const double motionSampleTime,
|
||||
pxr::VtVec3fArray &positions,
|
||||
pxr::VtIntArray &face_indices,
|
||||
pxr::VtIntArray &face_counts) const
|
||||
{
|
||||
Adapter adapter;
|
||||
pxr::VtValue points_val = adapter.GetPoints(prim_, motionSampleTime);
|
||||
|
||||
if (points_val.IsHolding<pxr::VtVec3fArray>()) {
|
||||
positions = points_val.Get<pxr::VtVec3fArray>();
|
||||
}
|
||||
|
||||
pxr::VtValue topology_val = adapter.GetTopology(prim_, pxr::SdfPath(), motionSampleTime);
|
||||
|
||||
if (topology_val.IsHolding<pxr::HdMeshTopology>()) {
|
||||
const pxr::HdMeshTopology &topology = topology_val.Get<pxr::HdMeshTopology>();
|
||||
face_counts = topology.GetFaceVertexCounts();
|
||||
face_indices = topology.GetFaceVertexIndices();
|
||||
}
|
||||
}
|
||||
|
||||
bool USDShapeReader::read_mesh_values(double motionSampleTime,
|
||||
pxr::VtVec3fArray &positions,
|
||||
pxr::VtIntArray &face_indices,
|
||||
pxr::VtIntArray &face_counts) const
|
||||
{
|
||||
if (prim_.IsA<pxr::UsdGeomCapsule>()) {
|
||||
read_values<pxr::UsdImagingCapsuleAdapter>(
|
||||
motionSampleTime, positions, face_indices, face_counts);
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Looks like this is missing clang format here Looks like this is missing clang format here
Charles Wardlaw
commented
Reformatted file. Reformatted file.
|
||||
return true;
|
||||
}
|
||||
|
||||
if (prim_.IsA<pxr::UsdGeomCylinder>()) {
|
||||
read_values<pxr::UsdImagingCylinderAdapter>(
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
No need for these separate boolean variables IMO, just put the check directly inside the if statements. No need for these separate boolean variables IMO, just put the check directly inside the if statements.
Charles Wardlaw
commented
Changed. Changed.
|
||||
motionSampleTime, positions, face_indices, face_counts);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (prim_.IsA<pxr::UsdGeomCone>()) {
|
||||
read_values<pxr::UsdImagingConeAdapter>(
|
||||
motionSampleTime, positions, face_indices, face_counts);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (prim_.IsA<pxr::UsdGeomCube>()) {
|
||||
read_values<pxr::UsdImagingCubeAdapter>(
|
||||
motionSampleTime, positions, face_indices, face_counts);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (prim_.IsA<pxr::UsdGeomSphere>()) {
|
||||
read_values<pxr::UsdImagingSphereAdapter>(
|
||||
motionSampleTime, positions, face_indices, face_counts);
|
||||
return true;
|
||||
}
|
||||
|
||||
WM_reportf(RPT_ERROR,
|
||||
"Unhandled Gprim type: %s (%s)",
|
||||
prim_.GetTypeName().GetText(),
|
||||
prim_.GetPath().GetText());
|
||||
return false;
|
||||
}
|
||||
|
||||
Mesh *USDShapeReader::read_mesh(struct Mesh *existing_mesh,
|
||||
Hans Goudey
commented
`struct Mesh` -> `Mesh`
|
||||
double motionSampleTime,
|
||||
int /*read_flag*/,
|
||||
const char ** /*err_str*/)
|
||||
{
|
||||
pxr::VtIntArray face_indices;
|
||||
pxr::VtIntArray face_counts;
|
||||
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
No need for the struct keyword in C++ code No need for the struct keyword in C++ code
Charles Wardlaw
commented
Removed. Removed.
|
||||
if (!prim_) {
|
||||
return existing_mesh;
|
||||
}
|
||||
|
||||
/* Should have a good set of data by this point-- copy over. */
|
||||
Mesh *active_mesh = mesh_from_prim(existing_mesh, motionSampleTime, face_indices, face_counts);
|
||||
if (active_mesh == existing_mesh) {
|
||||
return existing_mesh;
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Suggestion here so the reader has fewer things to keep track of at the same time:
Suggestion here so the reader has fewer things to keep track of at the same time:
```
Mesh *active_mesh = mesh_from_prim(existing_mesh, motionSampleTime, face_indices, face_counts);
if (active_mesh == existing_mesh) {
return existing_mesh;
}
MutableSpan<MPoly> polys = active_mesh->polys_for_write();
MutableSpan<MLoop> loops = active_mesh->loops_for_write();
const char should_smooth = prim_.IsA<pxr::UsdGeomCube>() ? 0 : ME_SMOOTH;
int loop_index = 0;
for (int i = 0; i < face_counts.size(); i++) {
const int face_size = face_counts[i];
MPoly &poly = polys[i];
poly.loopstart = loop_index;
poly.totloop = face_size;
/* Don't smooth-shade cubes; we're not worrying about sharpness for Gprims. */
poly.flag |= should_smooth;
for (int f = 0; f < face_size; ++f, ++loop_index) {
loops[loop_index].v = face_indices[loop_index];
}
}
BKE_mesh_calc_edges(active_mesh, false, false);
return active_mesh;
```
|
||||
}
|
||||
|
||||
MutableSpan<MPoly> polys = active_mesh->polys_for_write();
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Declare Declare `loop_index` at the smallest scope possible, right above the `for (int i = 0; i < face_counts.size(); i++) {` loop.
|
||||
MutableSpan<MLoop> loops = active_mesh->loops_for_write();
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Same here with the unused arguments Same here with the unused arguments
Charles Wardlaw
commented
Changed. Changed.
|
||||
|
||||
const char should_smooth = prim_.IsA<pxr::UsdGeomCube>() ? 0 : ME_SMOOTH;
|
||||
|
||||
int loop_index = 0;
|
||||
for (int i = 0; i < face_counts.size(); i++) {
|
||||
const int face_size = face_counts[i];
|
||||
|
||||
MPoly &poly = polys[i];
|
||||
poly.loopstart = loop_index;
|
||||
poly.totloop = face_size;
|
||||
|
||||
/* Don't smooth-shade cubes; we're not worrying about sharpness for Gprims. */
|
||||
poly.flag |= should_smooth;
|
||||
|
||||
for (int f = 0; f < face_size; ++f, ++loop_index) {
|
||||
loops[loop_index].v = face_indices[loop_index];
|
||||
}
|
||||
}
|
||||
|
||||
BKE_mesh_calc_edges(active_mesh, false, false);
|
||||
return active_mesh;
|
||||
}
|
||||
|
||||
Mesh *USDShapeReader::mesh_from_prim(Mesh *existing_mesh,
|
||||
double motionSampleTime,
|
||||
pxr::VtIntArray &face_indices,
|
||||
pxr::VtIntArray &face_counts) const
|
||||
{
|
||||
pxr::VtVec3fArray positions;
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Why do you need to calculate the edges if you didn't change anything above? Why do you need to calculate the edges if you didn't change anything above?
Charles Wardlaw
commented
mesh_from_prim() does not calculate edges; I deferred their calculation to this spot. mesh_from_prim() does not calculate edges; I deferred their calculation to this spot.
Hans Goudey
commented
Yes, but my point is, shouldn't it be in the Yes, but my point is, shouldn't it be in the `if (active_mesh != existing_mesh) {` where the corner vertices are actually set? Otherwise it looks like it's calculating edges unnecessarily.
Charles Wardlaw
commented
No, because No, because `active_mesh` was created by `mesh_from_prim()` which does not calculate the edges. They need to be calculated either way.
|
||||
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
No need to tag normals dirty on a new mesh. You aren't changing the positions here anyway, so it's not the correct update tag if any was actually needed. No need to tag normals dirty on a new mesh. You aren't changing the positions here anyway, so it's not the correct update tag if any was actually needed.
Charles Wardlaw
commented
Seems to be fine now without-- removed. Seems to be fine now without-- removed.
|
||||
if (!read_mesh_values(motionSampleTime, positions, face_indices, face_counts)) {
|
||||
return existing_mesh;
|
||||
}
|
||||
|
||||
const bool poly_counts_match = existing_mesh ? face_counts.size() == existing_mesh->totpoly :
|
||||
false;
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Clang format! Clang format!
Charles Wardlaw
commented
Reformatted file. Reformatted file.
|
||||
const bool position_counts_match = existing_mesh ? positions.size() == existing_mesh->totvert :
|
||||
false;
|
||||
|
||||
Mesh *active_mesh = nullptr;
|
||||
if (!position_counts_match || !poly_counts_match) {
|
||||
active_mesh = BKE_mesh_new_nomain_from_template(
|
||||
existing_mesh, positions.size(), 0, 0, face_indices.size(), face_counts.size());
|
||||
}
|
||||
else {
|
||||
active_mesh = existing_mesh;
|
||||
}
|
||||
|
||||
MutableSpan<float3> vert_positions = active_mesh->vert_positions_for_write();
|
||||
|
||||
for (int i = 0; i < positions.size(); i++) {
|
||||
vert_positions[i][0] = positions[i][0];
|
||||
vert_positions[i][1] = positions[i][1];
|
||||
vert_positions[i][2] = positions[i][2];
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
For consistency, change the For consistency, change the `verts` name to `vert_positions`
Charles Wardlaw
commented
Changed. Changed.
|
||||
}
|
||||
|
||||
return active_mesh;
|
||||
}
|
||||
|
||||
bool USDShapeReader::is_time_varying()
|
||||
{
|
||||
if (prim_.IsA<pxr::UsdGeomCapsule>()) {
|
||||
pxr::UsdGeomCapsule geom(prim_);
|
||||
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
|
||||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
|
||||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
|
||||
}
|
||||
|
||||
if (prim_.IsA<pxr::UsdGeomCylinder>()) {
|
||||
pxr::UsdGeomCylinder geom(prim_);
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Same here with the no need for separate variables Same here with the no need for separate variables
Charles Wardlaw
commented
Removed. Removed.
|
||||
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
|
||||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
|
||||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
|
||||
}
|
||||
|
||||
if (prim_.IsA<pxr::UsdGeomCone>()) {
|
||||
pxr::UsdGeomCone geom(prim_);
|
||||
return (geom.GetAxisAttr().ValueMightBeTimeVarying() ||
|
||||
geom.GetHeightAttr().ValueMightBeTimeVarying() ||
|
||||
geom.GetRadiusAttr().ValueMightBeTimeVarying());
|
||||
}
|
||||
|
||||
if (prim_.IsA<pxr::UsdGeomCube>()) {
|
||||
pxr::UsdGeomCube geom(prim_);
|
||||
return geom.GetSizeAttr().ValueMightBeTimeVarying();
|
||||
}
|
||||
|
||||
if (prim_.IsA<pxr::UsdGeomSphere>()) {
|
||||
pxr::UsdGeomSphere geom(prim_);
|
||||
return geom.GetRadiusAttr().ValueMightBeTimeVarying();
|
||||
}
|
||||
|
||||
WM_reportf(RPT_ERROR,
|
||||
"Unhandled Gprim type: %s (%s)",
|
||||
prim_.GetTypeName().GetText(),
|
||||
prim_.GetPath().GetText());
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace blender::io::usd
|
62
source/blender/io/usd/intern/usd_reader_shape.h
Normal file
@ -0,0 +1,62 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Missing license header Missing license header
Charles Wardlaw
commented
Added. Added.
|
||||
* Copyright 2023 Nvidia. All rights reserved. */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "usd.h"
|
||||
#include "usd_reader_geom.h"
|
||||
#include "usd_reader_xform.h"
|
||||
#include <pxr/usd/usdGeom/gprim.h>
|
||||
|
||||
struct Mesh;
|
||||
|
||||
namespace blender::io::usd {
|
||||
|
||||
/*
|
||||
* Read USDGeom primitive shapes as Blender Meshes. This class uses the same adapter functions
|
||||
* as the GL viewport to generate geometry for each of the supported types.
|
||||
*/
|
||||
class USDShapeReader : public USDGeomReader {
|
||||
private:
|
||||
/* Template required to read mesh information out of Shape prims,
|
||||
* as each prim type has a separate subclass. */
|
||||
template<typename Adapter>
|
||||
void read_values(double motionSampleTime,
|
||||
pxr::VtVec3fArray &positions,
|
||||
pxr::VtIntArray &face_indices,
|
||||
pxr::VtIntArray &face_counts) const;
|
||||
|
||||
/* Wrapper for the templated method read_values, calling the correct template
|
||||
* instantiation based on the introspected prim type. */
|
||||
bool read_mesh_values(double motionSampleTime,
|
||||
pxr::VtVec3fArray &positions,
|
||||
pxr::VtIntArray &face_indices,
|
||||
pxr::VtIntArray &face_counts) const;
|
||||
|
||||
/* Read the pxr:UsdGeomMesh values and convert them to a Blender Mesh,
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Clang format! Please configure your editor to format when you save the file, it will save everyone's time. Clang format! Please configure your editor to format when you save the file, it will save everyone's time.
Charles Wardlaw
commented
Reformatted file. Reformatted file.
|
||||
* also returning face_indices and counts for further loop processing. */
|
||||
Mesh *mesh_from_prim(Mesh *existing_mesh,
|
||||
double motionSampleTime,
|
||||
pxr::VtIntArray &face_indices,
|
||||
pxr::VtIntArray &face_counts) const;
|
||||
|
||||
public:
|
||||
USDShapeReader(const pxr::UsdPrim &prim,
|
||||
const USDImportParams &import_params,
|
||||
const ImportSettings &settings);
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
No need for these struct keywords in C++ code, even headers. No need for these struct keywords in C++ code, even headers.
Charles Wardlaw
commented
Removed. Removed.
Charles Wardlaw
commented
Removed. Removed.
|
||||
|
||||
void create_object(Main *bmain, double /*motionSampleTime*/) override;
|
||||
void read_object_data(Main *bmain, double motionSampleTime) override;
|
||||
Mesh *read_mesh(Mesh *existing_mesh,
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
`struct Mesh` -> `Mesh`
|
||||
double motionSampleTime,
|
||||
int /*read_flag*/,
|
||||
CharlesWardlaw marked this conversation as resolved
Hans Goudey
commented
Consistency: Consistency: `/* existing_mesh */` -> `/*existing_mesh*/`, etc.
Charles Wardlaw
commented
Changed. Changed.
|
||||
const char ** /*err_str*/) override;
|
||||
bool is_time_varying();
|
||||
|
||||
virtual bool topology_changed(const Mesh * /*existing_mesh*/, double /*motionSampleTime*/)
|
||||
{
|
||||
return false;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace blender::io::usd
|
@ -9,6 +9,7 @@
|
||||
#include "usd_reader_mesh.h"
|
||||
#include "usd_reader_nurbs.h"
|
||||
#include "usd_reader_prim.h"
|
||||
#include "usd_reader_shape.h"
|
||||
#include "usd_reader_volume.h"
|
||||
#include "usd_reader_xform.h"
|
||||
|
||||
@ -16,9 +17,14 @@
|
||||
#include <pxr/usd/usd/primRange.h>
|
||||
#include <pxr/usd/usdGeom/camera.h>
|
||||
#include <pxr/usd/usdGeom/curves.h>
|
||||
#include <pxr/usd/usdGeom/capsule.h>
|
||||
#include <pxr/usd/usdGeom/cone.h>
|
||||
#include <pxr/usd/usdGeom/cube.h>
|
||||
#include <pxr/usd/usdGeom/cylinder.h>
|
||||
#include <pxr/usd/usdGeom/mesh.h>
|
||||
#include <pxr/usd/usdGeom/nurbsCurves.h>
|
||||
#include <pxr/usd/usdGeom/scope.h>
|
||||
#include <pxr/usd/usdGeom/sphere.h>
|
||||
#include <pxr/usd/usdGeom/xform.h>
|
||||
#include <pxr/usd/usdShade/material.h>
|
||||
|
||||
@ -57,8 +63,18 @@ bool USDStageReader::valid() const
|
||||
return stage_;
|
||||
}
|
||||
|
||||
bool USDStageReader::is_primitive_prim(const pxr::UsdPrim &prim) const
|
||||
{
|
||||
return (prim.IsA<pxr::UsdGeomCapsule>() || prim.IsA<pxr::UsdGeomCylinder>() ||
|
||||
prim.IsA<pxr::UsdGeomCone>() || prim.IsA<pxr::UsdGeomCube>() ||
|
||||
prim.IsA<pxr::UsdGeomSphere>());
|
||||
}
|
||||
|
||||
USDPrimReader *USDStageReader::create_reader_if_allowed(const pxr::UsdPrim &prim)
|
||||
{
|
||||
if (params_.import_shapes && is_primitive_prim(prim)) {
|
||||
return new USDShapeReader(prim, params_, settings_);
|
||||
}
|
||||
if (params_.import_cameras && prim.IsA<pxr::UsdGeomCamera>()) {
|
||||
return new USDCameraReader(prim, params_, settings_);
|
||||
}
|
||||
@ -91,6 +107,9 @@ USDPrimReader *USDStageReader::create_reader_if_allowed(const pxr::UsdPrim &prim
|
||||
|
||||
USDPrimReader *USDStageReader::create_reader(const pxr::UsdPrim &prim)
|
||||
{
|
||||
if (is_primitive_prim(prim)) {
|
||||
return new USDShapeReader(prim, params_, settings_);
|
||||
}
|
||||
if (prim.IsA<pxr::UsdGeomCamera>()) {
|
||||
return new USDCameraReader(prim, params_, settings_);
|
||||
}
|
||||
|
@ -100,6 +100,12 @@ class USDStageReader {
|
||||
* toggled off.
|
||||
*/
|
||||
bool include_by_purpose(const pxr::UsdGeomImageable &imageable) const;
|
||||
|
||||
/*
|
||||
* Returns true if the specified UsdPrim is a UsdGeom primitive,
|
||||
* procedural shape, such as UsdGeomCube.
|
||||
*/
|
||||
bool is_primitive_prim(const pxr::UsdPrim &prim) const;
|
||||
};
|
||||
|
||||
}; // namespace blender::io::usd
|
||||
|
@ -66,6 +66,7 @@ struct USDImportParams {
|
||||
bool import_materials;
|
||||
bool import_meshes;
|
||||
bool import_volumes;
|
||||
bool import_shapes;
|
||||
char prim_path_mask[1024];
|
||||
bool import_subdiv;
|
||||
bool import_instance_proxies;
|
||||
|
Missing license header
Added.