44#include <pxr/base/gf/matrix4f.h>
45#include <pxr/base/vt/array.h>
46#include <pxr/base/vt/types.h>
47#include <pxr/usd/sdf/types.h>
48#include <pxr/usd/usdGeom/primvarsAPI.h>
49#include <pxr/usd/usdGeom/subset.h>
50#include <pxr/usd/usdShade/materialBindingAPI.h>
51#include <pxr/usd/usdShade/tokens.h>
52#include <pxr/usd/usdSkel/bindingAPI.h>
63static const pxr::TfToken
st(
"st", pxr::TfToken::Immortal);
74 const pxr::UsdShadeMaterialBindingAPI api = pxr::UsdShadeMaterialBindingAPI(prim);
80 pxr::UsdShadeMaterial mtl;
81 switch (mtl_purpose) {
83 mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->full);
86 mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->preview);
90 mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->preview);
93 mtl = api.ComputeBoundMaterial(pxr::UsdShadeTokens->allPurpose);
104 pxr::UsdStageRefPtr stage,
107 if (!(stage && bmain && ob)) {
117 for (
const auto item : mat_index_map.
items()) {
124 pxr::UsdPrim prim = stage->GetPrimAtPath(item.key);
125 pxr::UsdShadeMaterial usd_mat(prim);
129 &
LOG,
"Couldn't construct USD material from prim %s", item.key.GetAsString().c_str());
137 assigned_mat = mat_reader.
add_material(usd_mat, !have_import_hook);
141 "Couldn't create Blender material from USD material %s",
142 item.key.GetAsString().c_str());
154 if (have_import_hook) {
166 CLOG_WARN(&
LOG,
"Couldn't assign material %s", item.key.GetAsString().c_str());
188 is_initial_load_ =
true;
192 Mesh *read_mesh = this->read_mesh(mesh,
params,
nullptr);
194 is_initial_load_ =
false;
195 if (read_mesh != mesh) {
199 readFaceSetsSample(bmain, mesh, motionSampleTime);
201 if (mesh_prim_.GetPointsAttr().ValueMightBeTimeVarying() ||
202 mesh_prim_.GetNormalsAttr().ValueMightBeTimeVarying() ||
203 mesh_prim_.GetVelocitiesAttr().ValueMightBeTimeVarying() ||
204 mesh_prim_.GetCreaseSharpnessesAttr().ValueMightBeTimeVarying() ||
205 mesh_prim_.GetCreaseLengthsAttr().ValueMightBeTimeVarying() ||
206 mesh_prim_.GetCreaseIndicesAttr().ValueMightBeTimeVarying() ||
207 mesh_prim_.GetCornerSharpnessesAttr().ValueMightBeTimeVarying() ||
208 mesh_prim_.GetCornerIndicesAttr().ValueMightBeTimeVarying())
210 is_time_varying_ =
true;
213 if (is_time_varying_) {
218 pxr::TfToken subdivScheme;
219 mesh_prim_.GetSubdivisionSchemeAttr().Get(&subdivScheme, motionSampleTime);
221 if (subdivScheme == pxr::UsdGeomTokens->catmullClark) {
243 mesh_prim_.GetFaceVertexIndicesAttr().Get(&face_indices_, motionSampleTime);
244 mesh_prim_.GetFaceVertexCountsAttr().Get(&face_counts_, motionSampleTime);
245 mesh_prim_.GetPointsAttr().Get(&positions_, motionSampleTime);
247 const pxr::UsdGeomPrimvarsAPI primvarsAPI(mesh_prim_);
254 if (primvar.HasValue()) {
255 primvar.ComputeFlattened(&normals_, motionSampleTime);
256 normal_interpolation_ = primvar.GetInterpolation();
259 mesh_prim_.GetNormalsAttr().Get(&normals_, motionSampleTime);
260 normal_interpolation_ = mesh_prim_.GetNormalsInterpolation();
263 return positions_.size() != existing_mesh->
verts_num ||
264 face_counts_.size() != existing_mesh->
faces_num ||
265 face_indices_.size() != existing_mesh->
corners_num;
268bool USDMeshReader::read_faces(
Mesh *mesh)
const
275 for (
int i = 0;
i < face_counts_.size();
i++) {
276 const int face_size = face_counts_[
i];
278 face_offsets[
i] = loop_index;
283 if (is_left_handed_) {
284 int loop_end_index = loop_index + (face_size - 1);
285 for (
int f = 0; f < face_size; ++f, ++loop_index) {
286 corner_verts[loop_index] = face_indices_[loop_end_index - f];
290 for (
int f = 0; f < face_size; ++f, ++loop_index) {
291 corner_verts[loop_index] = face_indices_[loop_index];
297 const OffsetIndices<int>
faces = mesh->faces();
302 [&](
const IndexRange part,
const bool ok_so_far) {
303 bool current_faces_ok = ok_so_far;
305 for (const int i : part) {
306 const IndexRange face_range = faces[i];
307 const Set<int, 32> used_verts(corner_verts.slice(face_range));
308 current_faces_ok = current_faces_ok && used_verts.size() == face_range.size();
311 return current_faces_ok;
313 std::logical_and<>());
320 if (is_initial_load_) {
321 const char *message =
N_(
322 "Invalid face data detected for mesh '%s'. Automatic correction will be used, but some "
323 "data will most likely be lost");
324 const std::string prim_path = this->prim_path().GetAsString();
337 mesh->tag_topology_changed();
342void USDMeshReader::read_uv_data_primvar(
Mesh *mesh,
343 const pxr::UsdGeomPrimvar &primvar,
344 const double motionSampleTime)
346 const StringRef primvar_name(
347 pxr::UsdGeomPrimvar::StripPrimvarsName(primvar.GetName()).GetString());
349 const pxr::VtVec2fArray usd_uvs = get_primvar_array<pxr::GfVec2f>(primvar, motionSampleTime);
350 if (usd_uvs.empty()) {
354 const pxr::TfToken varying_type = primvar.GetInterpolation();
356 pxr::UsdGeomTokens->vertex,
357 pxr::UsdGeomTokens->faceVarying,
358 pxr::UsdGeomTokens->varying));
360 if ((varying_type == pxr::UsdGeomTokens->faceVarying && usd_uvs.size() != mesh->
corners_num) ||
361 (varying_type == pxr::UsdGeomTokens->vertex && usd_uvs.size() != mesh->
verts_num) ||
362 (varying_type == pxr::UsdGeomTokens->varying && usd_uvs.size() != mesh->
verts_num))
366 "USD Import: UV attribute value '%s' count inconsistent with interpolation type",
367 primvar.GetName().GetText());
371 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
372 bke::SpanAttributeWriter<float2> uv_data = attributes.lookup_or_add_for_write_only_span<
float2>(
378 "USD Import: couldn't add UV attribute '%s'",
379 primvar.GetBaseName().GetText());
383 if (varying_type == pxr::UsdGeomTokens->faceVarying) {
384 if (is_left_handed_) {
386 const OffsetIndices
faces = mesh->faces();
387 for (
const int i :
faces.index_range()) {
388 const IndexRange face =
faces[
i];
390 const int rev_index = face.
last(j);
391 uv_data.span[face.
start() + j] =
float2(usd_uvs[rev_index][0], usd_uvs[rev_index][1]);
396 for (
int i = 0;
i < uv_data.span.size(); ++
i) {
397 uv_data.span[
i] =
float2(usd_uvs[
i][0], usd_uvs[
i][1]);
403 const Span<int> corner_verts = mesh->corner_verts();
405 for (
int i = 0;
i < uv_data.span.size(); ++
i) {
407 int vi = corner_verts[
i];
408 uv_data.span[
i] =
float2(usd_uvs[vi][0], usd_uvs[vi][1]);
415void USDMeshReader::read_subdiv()
420 pxr::TfToken uv_smooth;
421 mesh_prim_.GetFaceVaryingLinearInterpolationAttr().Get(&uv_smooth);
423 if (uv_smooth == pxr::UsdGeomTokens->
all) {
426 else if (uv_smooth == pxr::UsdGeomTokens->cornersOnly) {
429 else if (uv_smooth == pxr::UsdGeomTokens->cornersPlus1) {
432 else if (uv_smooth == pxr::UsdGeomTokens->cornersPlus2) {
435 else if (uv_smooth == pxr::UsdGeomTokens->boundaries) {
438 else if (uv_smooth == pxr::UsdGeomTokens->none) {
442 pxr::TfToken boundary_smooth;
443 mesh_prim_.GetInterpolateBoundaryAttr().Get(&boundary_smooth);
445 if (boundary_smooth == pxr::UsdGeomTokens->edgeOnly) {
448 else if (boundary_smooth == pxr::UsdGeomTokens->edgeAndCorner) {
453void USDMeshReader::read_vertex_creases(
Mesh *mesh,
const double motionSampleTime)
455 pxr::VtIntArray usd_corner_indices;
456 if (!mesh_prim_.GetCornerIndicesAttr().Get(&usd_corner_indices, motionSampleTime)) {
460 pxr::VtFloatArray usd_corner_sharpnesses;
461 if (!mesh_prim_.GetCornerSharpnessesAttr().Get(&usd_corner_sharpnesses, motionSampleTime)) {
466 if (usd_corner_indices.empty() || usd_corner_sharpnesses.empty()) {
471 if (usd_corner_indices.size() > mesh->
verts_num) {
473 &
LOG,
"Too many vertex creases for mesh %s", this->prim_path().GetAsString().c_str());
477 if (usd_corner_indices.size() != usd_corner_sharpnesses.size()) {
479 "Vertex crease and sharpness count mismatch for mesh %s",
480 this->prim_path().GetAsString().c_str());
484 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
485 bke::SpanAttributeWriter creases = attributes.lookup_or_add_for_write_only_span<
float>(
487 creases.span.fill(0.0f);
489 Span<int> corner_indices =
Span(usd_corner_indices.cdata(), usd_corner_indices.size());
490 Span<float> corner_sharpnesses =
Span(usd_corner_sharpnesses.cdata(),
491 usd_corner_sharpnesses.size());
493 for (
size_t i = 0;
i < corner_indices.
size();
i++) {
494 const float crease = settings_->blender_stage_version_prior_44 ?
495 corner_sharpnesses[
i] :
497 creases.span[corner_indices[
i]] = std::clamp(crease, 0.0f, 1.0f);
502void USDMeshReader::read_edge_creases(
Mesh *mesh,
const double motionSampleTime)
504 pxr::VtArray<int> usd_crease_lengths;
505 pxr::VtArray<int> usd_crease_indices;
506 pxr::VtArray<float> usd_crease_sharpness;
507 mesh_prim_.GetCreaseLengthsAttr().Get(&usd_crease_lengths, motionSampleTime);
508 mesh_prim_.GetCreaseIndicesAttr().Get(&usd_crease_indices, motionSampleTime);
509 mesh_prim_.GetCreaseSharpnessesAttr().Get(&usd_crease_sharpness, motionSampleTime);
512 if (usd_crease_lengths.empty() || usd_crease_indices.empty() || usd_crease_sharpness.empty()) {
517 if (usd_crease_lengths.size() != usd_crease_sharpness.size()) {
519 "Edge crease and sharpness count mismatch for mesh %s",
520 this->prim_path().GetAsString().c_str());
525 using EdgeMap = VectorSet<OrderedEdge,
528 DefaultHash<OrderedEdge>,
529 DefaultEquality<OrderedEdge>,
530 SimpleVectorSetSlot<OrderedEdge, int>,
532 Span<int2> edges = mesh->edges();
534 edge_map.reserve(edges.
size());
537 edge_map.add(edges[
i]);
540 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
541 bke::SpanAttributeWriter creases = attributes.lookup_or_add_for_write_only_span<
float>(
543 creases.span.fill(0.0f);
545 Span<int> crease_lengths =
Span(usd_crease_lengths.cdata(), usd_crease_lengths.size());
546 Span<int> crease_indices =
Span(usd_crease_indices.cdata(), usd_crease_indices.size());
547 Span<float> crease_sharpness =
Span(usd_crease_sharpness.cdata(), usd_crease_sharpness.size());
549 size_t index_start = 0;
550 for (
size_t i = 0;
i < crease_lengths.
size();
i++) {
551 const int length = crease_lengths[
i];
556 "Edge crease length %d is invalid for mesh %s",
558 this->prim_path().GetAsString().c_str());
562 if (index_start +
length > crease_indices.
size()) {
564 "Edge crease lengths are out of bounds for mesh %s",
565 this->prim_path().GetAsString().c_str());
569 float crease = settings_->blender_stage_version_prior_44 ?
570 crease_sharpness[
i] :
572 crease = std::clamp(crease, 0.0f, 1.0f);
573 for (
size_t j = 0; j <
length - 1; j++) {
574 const int v1 = crease_indices[index_start + j];
575 const int v2 = crease_indices[index_start + j + 1];
576 const int edge_i = edge_map.index_of_try({v1,
v2});
581 creases.span[edge_i] = crease;
590void USDMeshReader::read_velocities(
Mesh *mesh,
const double motionSampleTime)
592 pxr::VtVec3fArray velocities;
593 mesh_prim_.GetVelocitiesAttr().Get(&velocities, motionSampleTime);
595 if (!velocities.empty()) {
596 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
597 bke::SpanAttributeWriter<float3> velocity =
600 Span<pxr::GfVec3f> usd_data(velocities.cdata(), velocities.size());
601 velocity.span.copy_from(usd_data.cast<
float3>());
606void USDMeshReader::process_normals_vertex_varying(
Mesh *mesh)
608 if (normals_.empty()) {
612 if (normals_.size() != mesh->
verts_num) {
614 "Vertex varying normals count mismatch for mesh '%s'",
615 this->prim_path().GetAsString().c_str());
621 *mesh, {
reinterpret_cast<float3 *
>(normals_.data()),
int64_t(normals_.size())});
624void USDMeshReader::process_normals_face_varying(
Mesh *mesh)
const
626 if (normals_.empty()) {
633 &
LOG,
"Loop normal count mismatch for mesh '%s'", this->prim_path().GetAsString().c_str());
639 const OffsetIndices
faces = mesh->faces();
640 for (
const int i :
faces.index_range()) {
641 const IndexRange face =
faces[
i];
643 const int corner = face.
start() + j;
645 int usd_index = face.
start();
646 if (is_left_handed_) {
647 usd_index += face.
size() - 1 - j;
653 corner_normals[corner] = detail::convert_value<pxr::GfVec3f, float3>(normals_[usd_index]);
660void USDMeshReader::process_normals_uniform(
Mesh *mesh)
const
662 if (normals_.empty()) {
667 if (normals_.size() != mesh->
faces_num) {
669 "Uniform normal count mismatch for mesh '%s'",
670 this->prim_path().GetAsString().c_str());
676 const OffsetIndices
faces = mesh->faces();
677 for (
const int i :
faces.index_range()) {
678 for (
const int corner :
faces[
i]) {
679 corner_normals[corner] = detail::convert_value<pxr::GfVec3f, float3>(normals_[
i]);
686void USDMeshReader::read_mesh_sample(ImportSettings *settings,
688 const double motionSampleTime,
696 MutableSpan<float3> vert_positions = mesh->vert_positions_for_write();
698 mesh->tag_positions_changed();
700 read_vertex_creases(mesh, motionSampleTime);
704 if (!read_faces(mesh)) {
707 read_edge_creases(mesh, motionSampleTime);
709 if (normal_interpolation_ == pxr::UsdGeomTokens->faceVarying) {
710 process_normals_face_varying(mesh);
712 else if (normal_interpolation_ == pxr::UsdGeomTokens->uniform) {
713 process_normals_uniform(mesh);
719 normal_interpolation_ == pxr::UsdGeomTokens->vertex)
721 process_normals_vertex_varying(mesh);
729 read_velocities(mesh, motionSampleTime);
734void USDMeshReader::read_custom_data(
const ImportSettings *settings,
736 const double motionSampleTime,
743 pxr::UsdGeomPrimvarsAPI pv_api = pxr::UsdGeomPrimvarsAPI(mesh_prim_);
744 std::vector<pxr::UsdGeomPrimvar> primvars = pv_api.GetPrimvarsWithValues();
746 pxr::TfToken active_color_name;
747 pxr::TfToken active_uv_set_name;
750 for (
const pxr::UsdGeomPrimvar &pv : primvars) {
751 const pxr::SdfValueTypeName type = pv.GetTypeName();
752 if (!type.IsArray()) {
756 const pxr::TfToken varying_type = pv.GetInterpolation();
757 const pxr::TfToken name = pxr::UsdGeomPrimvar::StripPrimvarsName(pv.GetPrimvarName());
761 if (!new_mesh && primvar_varying_map_.contains(name) && !primvar_varying_map_.lookup(name)) {
766 if (
ELEM(name,
"velocity")) {
771 pxr::SdfValueTypeNames->StringArray,
772 pxr::SdfValueTypeNames->QuatdArray,
773 pxr::SdfValueTypeNames->QuathArray))
786 active_color_name = name;
794 else if (
ELEM(varying_type,
795 pxr::UsdGeomTokens->vertex,
796 pxr::UsdGeomTokens->faceVarying,
797 pxr::UsdGeomTokens->varying) &&
805 active_uv_set_name = name;
807 this->read_uv_data_primvar(mesh, pv, motionSampleTime);
819 if (!primvar_varying_map_.contains(name)) {
820 bool might_be_time_varying = pv.ValueMightBeTimeVarying();
821 primvar_varying_map_.add(name, might_be_time_varying);
822 if (might_be_time_varying) {
823 is_time_varying_ =
true;
828 if (!active_color_name.IsEmpty()) {
833 if (!active_uv_set_name.IsEmpty()) {
836 if (layer_index > -1) {
843void USDMeshReader::assign_facesets_to_material_indices(
double motionSampleTime,
844 MutableSpan<int> material_indices,
845 blender::Map<pxr::SdfPath, int> *r_mat_map)
847 if (r_mat_map ==
nullptr) {
857 const std::vector<pxr::UsdGeomSubset> subsets = pxr::UsdGeomSubset::GetAllGeomSubsets(
861 if (!subsets.empty()) {
862 for (
const pxr::UsdGeomSubset &subset : subsets) {
863 pxr::UsdPrim subset_prim = subset.GetPrim();
864 pxr::UsdShadeMaterial subset_mtl = utils::compute_bound_material(subset_prim,
865 import_params_.mtl_purpose);
870 pxr::SdfPath subset_mtl_path = subset_mtl.GetPath();
871 if (subset_mtl_path.IsEmpty()) {
875 pxr::TfToken element_type;
876 subset.GetElementTypeAttr().Get(&element_type, motionSampleTime);
877 if (element_type != pxr::UsdGeomTokens->face) {
879 "UsdGeomSubset '%s' uses unsupported elementType: %s",
880 subset_prim.GetName().GetText(),
881 element_type.GetText());
885 const int mat_idx = r_mat_map->
lookup_or_add(subset_mtl_path, 1 + current_mat++);
886 const int max_element_idx = std::max(0,
int(material_indices.
size() - 1));
889 subset.GetIndicesAttr().Get(&
indices, motionSampleTime);
891 int bad_element_count = 0;
892 for (
const int element_idx :
indices.AsConst()) {
893 const int safe_element_idx = std::clamp(element_idx, 0, max_element_idx);
894 bad_element_count += (safe_element_idx != element_idx) ? 1 : 0;
895 material_indices[safe_element_idx] = mat_idx - 1;
898 if (bad_element_count > 0) {
900 "UsdGeomSubset '%s' contains invalid indices; material assignment may be "
901 "incorrect (%d were out of range)",
902 subset_prim.GetName().GetText(),
909 pxr::UsdShadeMaterial mtl = utils::compute_bound_material(prim_, import_params_.mtl_purpose);
911 pxr::SdfPath mtl_path = mtl.GetPath();
913 if (!mtl_path.IsEmpty()) {
914 r_mat_map->
add(mtl.GetPath(), 1);
920void USDMeshReader::readFaceSetsSample(Main *bmain,
Mesh *mesh,
const double motionSampleTime)
922 if (!import_params_.import_materials) {
926 blender::Map<pxr::SdfPath, int> mat_map;
928 bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
929 bke::SpanAttributeWriter<int> material_indices = attributes.lookup_or_add_for_write_span<
int>(
931 this->assign_facesets_to_material_indices(motionSampleTime, material_indices.span, &mat_map);
932 material_indices.finish();
934 if (this->settings_->mat_name_to_mat.is_empty()) {
937 utils::assign_materials(
938 bmain, object_, mat_map, this->import_params_, this->prim_.GetStage(), *
this->settings_);
941Mesh *USDMeshReader::read_mesh(
Mesh *existing_mesh,
942 const USDMeshReadParams
params,
945 mesh_prim_.GetOrientationAttr().Get(&orientation_);
946 if (orientation_ == pxr::UsdGeomTokens->leftHanded) {
947 is_left_handed_ =
true;
950 Mesh *active_mesh = existing_mesh;
951 bool new_mesh =
false;
956 ImportSettings settings;
957 settings.read_flag |=
params.read_flags;
959 if (topology_changed(existing_mesh,
params.motion_sample_time)) {
962 existing_mesh, positions_.size(), 0, face_counts_.size(), face_indices_.size());
966 &settings, active_mesh,
params.motion_sample_time, new_mesh || is_initial_load_);
972 if (active_mesh->
faces_num != 0 && import_params_.import_materials) {
973 blender::Map<pxr::SdfPath, int> mat_map;
974 bke::MutableAttributeAccessor attributes = active_mesh->attributes_for_write();
975 bke::SpanAttributeWriter<int> material_indices =
977 assign_facesets_to_material_indices(
978 params.motion_sample_time, material_indices.span, &mat_map);
979 material_indices.finish();
983 if (import_params_.validate_meshes) {
994 const char **r_err_str)
997 Mesh *new_mesh = read_mesh(existing_mesh,
params, r_err_str);
999 if (new_mesh != existing_mesh) {
1013 pxr::UsdSkelBindingAPI skel_api(
prim_);
1015 if (pxr::UsdSkelSkeleton skel = skel_api.GetInheritedSkeleton()) {
1016 return skel.GetPath();
1022std::optional<XformResult> USDMeshReader::get_local_usd_xform(
const float time)
const
1024 if (!import_params_.import_skeletons || prim_.IsInstanceProxy()) {
1031 pxr::UsdSkelBindingAPI skel_api = pxr::UsdSkelBindingAPI(prim_);
1032 if (pxr::UsdAttribute xf_attr = skel_api.GetGeomBindTransformAttr()) {
1033 if (xf_attr.HasAuthoredValue()) {
1034 pxr::GfMatrix4d bind_xf;
1035 if (skel_api.GetGeomBindTransformAttr().Get(&bind_xf)) {
1040 return XformResult(pxr::GfMatrix4f(bind_xf),
true);
1045 "%s: Couldn't compute geom bind transform for %s",
1047 prim_.GetPath().GetAsString().c_str());
1051 return USDXformReader::get_local_usd_xform(time);
void BKE_id_attributes_default_color_set(struct ID *id, std::optional< blender::StringRef > name)
void BKE_id_attributes_active_color_set(struct ID *id, std::optional< blender::StringRef > name)
CustomData interface, see also DNA_customdata_types.h.
void CustomData_set_layer_render_index(CustomData *data, eCustomDataType type, int n)
int CustomData_get_named_layer_index(const CustomData *data, eCustomDataType type, blender::StringRef name)
void CustomData_set_layer_active_index(CustomData *data, eCustomDataType type, int n)
General operations, lookup, etc. for materials.
void BKE_object_material_assign_single_obdata(Main *bmain, Object *ob, Material *ma, short act)
Mesh * BKE_mesh_new_nomain_from_template(const Mesh *me_src, int verts_num, int edges_num, int faces_num, int corners_num)
bool BKE_mesh_validate(Mesh *mesh, bool do_verbose, bool cddata_check_mask)
void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob)
Mesh * BKE_mesh_add(Main *bmain, const char *name)
General operations, lookup, etc. for blender objects.
Object * BKE_object_add_only_object(Main *bmain, int type, const char *name) ATTR_RETURNS_NONNULL
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
#define BLI_STATIC_ASSERT(a, msg)
#define CLOG_WARN(clg_ref,...)
@ SUBSURF_BOUNDARY_SMOOTH_ALL
@ SUBSURF_BOUNDARY_SMOOTH_PRESERVE_CORNERS
struct ModifierData ModifierData
@ MOD_MESHSEQ_READ_ATTRIBUTES
struct SubsurfModifierData SubsurfModifierData
@ SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_AND_JUNCTIONS
@ SUBSURF_UV_SMOOTH_PRESERVE_CORNERS
@ SUBSURF_UV_SMOOTH_PRESERVE_BOUNDARIES
@ SUBSURF_UV_SMOOTH_PRESERVE_CORNERS_JUNCTIONS_AND_CONCAVE
Object is a sort of wrapper for general info.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
constexpr int64_t last(const int64_t n=0) const
constexpr int64_t size() const
constexpr int64_t start() const
constexpr IndexRange index_range() const
void add_new(const Key &key, const Value &value)
constexpr int64_t size() const
constexpr void copy_from(Span< T > values) const
constexpr int64_t size() const
constexpr IndexRange index_range() const
bool add(const Key &key, const Value &value)
ItemIterator items() const &
Value & lookup_or_add(const Key &key, const Value &value)
bool contains(const Key &key) const
void add_cache_modifier()
void add_subdiv_modifier()
Material * add_material(const pxr::UsdShadeMaterial &usd_material, bool read_usd_preview=true) const
void read_object_data(Main *bmain, double motionSampleTime) override
pxr::SdfPath get_skeleton_path() const
void read_geometry(bke::GeometrySet &geometry_set, USDMeshReadParams params, const char **r_err_str) override
void create_object(Main *bmain) override
bool topology_changed(const Mesh *existing_mesh, double motionSampleTime) override
const USDImportParams & import_params_
ReportList * reports() const
bool all(VecOp< bool, D >) RET
VectorSet< OrderedEdge, 16, DefaultProbingStrategy, DefaultHash< OrderedEdge >, DefaultEquality< OrderedEdge >, SimpleVectorSetSlot< OrderedEdge, int >, GuardedAllocator > EdgeMap
BLI_INLINE float sharpness_to_crease(float sharpness)
void mesh_calc_edges(Mesh &mesh, bool keep_existing_edges, bool select_new_edges)
void mesh_set_custom_normals_from_verts(Mesh &mesh, MutableSpan< float3 > vert_normals)
void mesh_set_custom_normals(Mesh &mesh, MutableSpan< float3 > corner_normals)
void read_custom_data(const std::string &iobject_full_name, const ICompoundProperty &prop, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss)
static pxr::UsdShadeMaterial compute_bound_material(const pxr::UsdPrim &prim, eUSDMtlPurpose mtl_purpose)
static void assign_materials(Main *bmain, Object *ob, const blender::Map< pxr::SdfPath, int > &mat_index_map, const USDImportParams ¶ms, pxr::UsdStageRefPtr stage, const ImportSettings &settings)
void import_mesh_skel_bindings(Object *mesh_obj, const pxr::UsdPrim &prim, ReportList *reports)
void build_material_map(const Main *bmain, blender::Map< std::string, Material * > &r_mat_map)
Material * find_existing_material(const pxr::SdfPath &usd_mat_path, const USDImportParams ¶ms, const blender::Map< std::string, Material * > &mat_map, const blender::Map< pxr::SdfPath, Material * > &usd_path_to_mat)
USDMeshReadParams create_mesh_read_params(const double motion_sample_time, const int read_flags)
@ USD_MTL_PURPOSE_PREVIEW
std::string make_safe_name(const StringRef name, bool allow_unicode)
void import_blendshapes(Main *bmain, Object *mesh_obj, const pxr::UsdPrim &prim, ReportList *reports, const bool import_anim)
std::optional< eCustomDataType > convert_usd_type_to_blender(const pxr::SdfValueTypeName usd_type)
void read_generic_mesh_primvar(Mesh *mesh, const pxr::UsdGeomPrimvar &primvar, const double motionSampleTime, const bool is_left_handed)
@ USD_MTL_NAME_COLLISION_MAKE_UNIQUE
Value parallel_reduce(IndexRange range, int64_t grain_size, const Value &identity, const Function &function, const Reduction &reduction)
VecBase< float, 2 > float2
PythonProbingStrategy<> DefaultProbingStrategy
VecBase< float, 3 > float3
static const pxr::TfToken st("st", pxr::TfToken::Immortal)
static const pxr::TfToken normalsPrimvar("normals", pxr::TfToken::Immortal)
const pxr::TfToken displayColor("displayColor", pxr::TfToken::Immortal)
void replace_mesh(Mesh *mesh, GeometryOwnershipType ownership=GeometryOwnershipType::Owned)
Mesh * get_mesh_for_write()
blender::Map< std::string, Material * > mat_name_to_mat
blender::Set< pxr::SdfPath > mat_import_hook_sources
blender::Map< pxr::SdfPath, Material * > usd_path_to_mat_for_hook
blender::Map< pxr::SdfPath, Material * > usd_path_to_mat