[Bf-blender-cvs] [50a30043283] universal-scene-description: USD Import: support reading USD shapes.
Michael Kowalski
noreply at git.blender.org
Mon Oct 17 21:12:37 CEST 2022
Commit: 50a300432838d8f731bf567d6914fff5fc140080
Author: Michael Kowalski
Date: Mon Oct 17 15:11:42 2022 -0400
Branches: universal-scene-description
https://developer.blender.org/rB50a300432838d8f731bf567d6914fff5fc140080
USD Import: support reading USD shapes.
Added readers for importing USD shapes (capsule, cylinder,
cone, cube and sphere) as meshes. Implemented by Charles
Wardlaw.
===================================================================
M source/blender/editors/io/io_usd.c
M source/blender/io/usd/CMakeLists.txt
M source/blender/io/usd/intern/usd_capi_import.cc
A source/blender/io/usd/intern/usd_reader_shape.cc
A source/blender/io/usd/intern/usd_reader_shape.h
M source/blender/io/usd/intern/usd_reader_stage.cc
M source/blender/io/usd/intern/usd_reader_stage.h
M source/blender/io/usd/usd.h
===================================================================
diff --git a/source/blender/editors/io/io_usd.c b/source/blender/editors/io/io_usd.c
index ca0df20a45e..0998fc77b01 100644
--- a/source/blender/editors/io/io_usd.c
+++ b/source/blender/editors/io/io_usd.c
@@ -1060,6 +1060,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
const bool import_blendshapes = RNA_boolean_get(op->ptr, "import_blendshapes");
const bool import_volumes = RNA_boolean_get(op->ptr, "import_volumes");
const bool import_skeletons = RNA_boolean_get(op->ptr, "import_skeletons");
+ const bool import_shapes = RNA_boolean_get(op->ptr, "import_shapes");
const bool import_subdiv = RNA_boolean_get(op->ptr, "import_subdiv");
@@ -1144,7 +1145,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op)
.scale_light_radius = scale_light_radius,
.create_background_shader = create_background_shader,
.mtl_name_collision_mode = mtl_name_collision_mode,
- .attr_import_mode = attr_import_mode};
+ .attr_import_mode = attr_import_mode,
+ .import_shapes = import_shapes};
const bool ok = USD_import(C, filename, ¶ms, as_background_job);
@@ -1169,6 +1171,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op)
uiItemR(col, ptr, "import_blendshapes", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "import_volumes", 0, NULL, ICON_NONE);
uiItemR(col, ptr, "import_skeletons", 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);
uiItemR(box, ptr, "apply_unit_conversion_scale", 0, NULL, ICON_NONE);
@@ -1267,6 +1270,7 @@ void WM_OT_usd_import(struct wmOperatorType *ot)
RNA_def_boolean(ot->srna, "import_blendshapes", true, "Blend Shapes", "");
RNA_def_boolean(ot->srna, "import_volumes", true, "Volumes", "");
RNA_def_boolean(ot->srna, "import_skeletons", true, "Skeletons", "");
+ RNA_def_boolean(ot->srna, "import_shapes", true, "USD Shapes", "");
RNA_def_boolean(ot->srna,
"import_subdiv",
diff --git a/source/blender/io/usd/CMakeLists.txt b/source/blender/io/usd/CMakeLists.txt
index 4a77bb32544..28cbf158a01 100644
--- a/source/blender/io/usd/CMakeLists.txt
+++ b/source/blender/io/usd/CMakeLists.txt
@@ -74,6 +74,7 @@ set(SRC
intern/usd_reader_camera.cc
intern/usd_reader_curve.cc
intern/usd_reader_geom.cc
+ intern/usd_reader_shape.cc
intern/usd_reader_instance.cc
intern/usd_reader_light.cc
intern/usd_reader_material.cc
@@ -114,6 +115,7 @@ set(SRC
intern/usd_reader_camera.h
intern/usd_reader_curve.h
intern/usd_reader_geom.h
+ intern/usd_reader_shape.h
intern/usd_reader_instance.h
intern/usd_reader_light.h
intern/usd_reader_material.h
@@ -179,6 +181,7 @@ endif()
# Source: https://github.com/PixarAnimationStudios/USD/blob/master/BUILDING.md#linking-whole-archives
if(WIN32)
target_link_libraries(bf_usd INTERFACE ${USD_LIBRARIES})
+ target_compile_options(bf_usd PRIVATE /w34101)
elseif(APPLE)
target_link_libraries(bf_usd INTERFACE -Wl,-force_load ${USD_LIBRARIES})
elseif(UNIX)
diff --git a/source/blender/io/usd/intern/usd_capi_import.cc b/source/blender/io/usd/intern/usd_capi_import.cc
index 1d005f92116..791ddc351e8 100644
--- a/source/blender/io/usd/intern/usd_capi_import.cc
+++ b/source/blender/io/usd/intern/usd_capi_import.cc
@@ -339,6 +339,7 @@ static void report_job_duration(const ImportJobData *data)
std::cout << '\n';
}
+
static void import_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
ImportJobData *data = static_cast<ImportJobData *>(customdata);
diff --git a/source/blender/io/usd/intern/usd_reader_shape.cc b/source/blender/io/usd/intern/usd_reader_shape.cc
new file mode 100644
index 00000000000..92597c290ee
--- /dev/null
+++ b/source/blender/io/usd/intern/usd_reader_shape.cc
@@ -0,0 +1,218 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2021 Tangent Animation. 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"
+#include "DNA_object_types.h"
+#include "DNA_space_types.h" /* for FILE_MAX */
+#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)
+{
+ 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) {
+ /* FIXME: after 2.80; `mesh->flag` isn't copied by #BKE_mesh_nomain_to_mesh() */
+ /* read_mesh can be freed by BKE_mesh_nomain_to_mesh(), so get the flag before that happens. */
+ uint16_t autosmooth = (read_mesh->flag & ME_AUTOSMOOTH);
+ BKE_mesh_nomain_to_mesh(read_mesh, mesh, object_, &CD_MASK_MESH, true);
+ mesh->flag |= autosmooth;
+
+ if (is_time_varying()) {
+ USDGeomReader::add_cache_modifier();
+ }
+ }
+
+ 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)
+{
+ pxr::VtValue meshPoints = Adapter::GetMeshPoints(prim_, motionSampleTime);
+ positions = meshPoints.Get<pxr::VtArray<pxr::GfVec3f>>();
+ pxr::HdMeshTopology meshTopologyValue = Adapter::GetMeshTopology().Get<pxr::HdMeshTopology>();
+ face_counts = meshTopologyValue.GetFaceVertexCounts();
+ face_indices = meshTopologyValue.GetFaceVertexIndices();
+}
+
+struct Mesh *USDShapeReader::read_mesh(struct Mesh *existing_mesh,
+ double motionSampleTime,
+ int read_flag,
+ const char **err_str)
+{
+ if (!prim_) {
+ return existing_mesh;
+ }
+
+ pxr::VtVec3fArray positions;
+ pxr::VtIntArray face_indices;
+ pxr::VtIntArray face_counts;
+
+ Mesh *active_mesh = existing_mesh;
+
+ const bool is_capsule = prim_.IsA<pxr::UsdGeomCapsule>();
+ const bool is_cylinder = prim_.IsA<pxr::UsdGeomCylinder>();
+ const bool is_cone = prim_.IsA<pxr::UsdGeomCone>();
+ const bool is_cube = prim_.IsA<pxr::UsdGeomCube>();
+ const bool is_sphere = prim_.IsA<pxr::UsdGeomSphere>();
+
+ if (is_capsule) {
+ read_values<pxr::UsdImagingCapsuleAdapter>(motionSampleTime, positions, face_indices, face_counts);
+ }
+ else if (is_cylinder) {
+ read_values<pxr::UsdImagingCylinderAdapter>(motionSampleTime, positions, face_indices, face_counts);
+ }
+ else if (is_cone) {
+ read_values<pxr::UsdImagingConeAdapter>(motionSampleTime, positions, face_indices, face_counts);
+ }
+ else if (is_cube) {
+ read_values<pxr::UsdImagingCubeAdapter>(motionSampleTime, positions, face_indices, face_counts);
+ }
+ else if (is_sphere) {
+ read_values<pxr::UsdImagingSphereAdapter>(motionSampleTime, positions, face_indices, face_counts);
+ }
+ else {
+ WM_reportf(RPT_ERROR,
+ "Unhandled Gprim type: %s (%s)",
+ prim_.GetTypeName().GetText(),
+ prim_.GetPath().GetText());
+ return existing_mesh;
+ }
+
+ /* Should be guaranteed to have a good set of data by this point-- copy over. */
+ const bool position_counts_match = active_mesh ? positions.size() == active_mesh->totvert :
+ false;
+ const bool poly_counts_match = active_mesh ? face_counts.size() == active_mesh->totpoly : false;
+
+ 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());
+ }
+
+ for (int i = 0; i < positions.size(); i++) {
+ MVert &mvert = active_mesh->mvert[i];
+ mvert.co[0] = positions[i][0];
+ mvert.co[1] = positions[i][1];
+ mvert.co[2] = positions[i][2];
+ }
+
+ MPoly *mpolys = active_mesh->mpoly;
+ MLoop *mloops = active_mesh->mloop;
+
+ int loop_index = 0;
+
+ if (!poly_counts_match) {
+ for (int i = 0; i < face_counts.size(); i++) {
+ const int face_size = face_counts[i];
+
+ MPoly &poly = mpolys[i];
+ poly.loopstart = loop_index;
+ poly.totloop = face_size;
+ poly.mat_nr = 0;
+
+ /* Don't smooth-shade cubes; we're not worrying about sharpness for Gprims. */
+ poly.flag |= is_cube ? 0 : ME_SMOOTH;
+
+ for (int f = 0; f < face_size; ++f, ++loop_index) {
+ mloops[loop_index].v = face_indices[loop_index];
+ }
+ }
+ }
+
+ BKE_mesh_calc_edges(active_mesh, false, false);
+ BKE_mesh_normals_tag_dirty(active_mesh);
+
+ return active_mesh;
+}
+
+bool USDShapeReader::is_time_varying()
+{
+ bool result;
+
+ const bool is_capsule = prim_.IsA<pxr::UsdGeomCapsule>();
+ const bool is_cylinder = prim_.IsA
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list