Commit: 6adbae02ef5dc20ed6ef062f9c08d813adb514f8 Author: Michael A. Kowalski Date: Fri Oct 9 22:01:06 2020 -0400 Branches: usd-importer-T81257 https://developer.blender.org/rB6adbae02ef5dc20ed6ef062f9c08d813adb514f8
USD importer: added logic to read normals. =================================================================== M source/blender/editors/io/io_usd.c M source/blender/io/usd/intern/usd_reader_mesh.cc 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 9f39057b0e1..f6c8062e96c 100644 --- a/source/blender/editors/io/io_usd.c +++ b/source/blender/editors/io/io_usd.c @@ -269,6 +269,8 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) const bool import_uvs = RNA_boolean_get(op->ptr, "import_uvs"); + const bool import_normals = RNA_boolean_get(op->ptr, "import_normals"); + const float scale = RNA_float_get(op->ptr, "scale"); const bool debug = RNA_boolean_get(op->ptr, "debug"); @@ -279,7 +281,7 @@ static int wm_usd_import_exec(bContext *C, wmOperator *op) ED_object_mode_set(C, OB_MODE_OBJECT); } - struct USDImportParams params = {import_uvs, scale, debug}; + struct USDImportParams params = {import_uvs, import_normals, scale, debug}; bool ok = USD_import(C, filename, ¶ms, as_background_job); @@ -300,6 +302,7 @@ static void wm_usd_import_draw(bContext *UNUSED(C), wmOperator *op) col = uiLayoutColumn(box, true); uiItemR(col, ptr, "import_uvs", 0, NULL, ICON_NONE); + uiItemR(col, ptr, "import_normals", 0, NULL, ICON_NONE); uiItemR(col, ptr, "debug", 0, NULL, ICON_NONE); } @@ -325,6 +328,8 @@ void WM_OT_usd_import(wmOperatorType *ot) RNA_def_boolean(ot->srna, "import_uvs", true, "uvs", "When checked, import mesh uvs."); + RNA_def_boolean(ot->srna, "import_normals", true, "normals", "When checked, import mesh normals."); + RNA_def_float( ot->srna, "scale", diff --git a/source/blender/io/usd/intern/usd_reader_mesh.cc b/source/blender/io/usd/intern/usd_reader_mesh.cc index c5780c496fe..173293e929d 100644 --- a/source/blender/io/usd/intern/usd_reader_mesh.cc +++ b/source/blender/io/usd/intern/usd_reader_mesh.cc @@ -47,6 +47,8 @@ struct MeshSampleData { pxr::VtVec2fArray uv_values; pxr::VtArray<int> uv_indices; pxr::TfToken uv_interpolation; + pxr::VtArray<pxr::GfVec3f> normals; + pxr::TfToken normals_interpolation; bool y_up; bool reverse_vert_order; @@ -196,6 +198,116 @@ static void read_mpolys(Mesh *mesh, const MeshSampleData &mesh_data) /* TODO(makowalski): Possibly check for invalid geometry. */ } +static void process_no_normals(Mesh *mesh) +{ + /* Absense of normals in the USD mesh is interpreted as 'smooth'. */ + BKE_mesh_calc_normals(mesh); +} + +static void process_loop_normals(Mesh *mesh, const MeshSampleData &mesh_data) +{ + if (!mesh) { + return; + } + + size_t loop_count = mesh_data.normals.size(); + + if (loop_count == 0) { + process_no_normals(mesh); + return; + } + + if (loop_count != mesh->totloop) { + std::cerr << "WARNING: loop normal count mismatch." << std::endl; + process_no_normals(mesh); + return; + } + + float(*lnors)[3] = static_cast<float(*)[3]>( + MEM_malloc_arrayN(loop_count, sizeof(float[3]), "USD::FaceNormals")); + + for (int i = 0; i < loop_count; ++i) { + + if (mesh_data.y_up) + { + blender::io::usd::copy_zup_from_yup(lnors[i], mesh_data.normals[i].data()); + } + else { + lnors[i][0] = mesh_data.normals[i].data()[0]; + lnors[i][1] = mesh_data.normals[i].data()[1]; + lnors[i][2] = mesh_data.normals[i].data()[2]; + } + + if (mesh_data.reverse_vert_order) { + lnors[i][0] = -lnors[i][0]; + lnors[i][1] = -lnors[i][1]; + lnors[i][2] = -lnors[i][2]; + } + } + + mesh->flag |= ME_AUTOSMOOTH; + BKE_mesh_set_custom_normals(mesh, lnors); + + MEM_freeN(lnors); +} + +static void process_vertex_normals(Mesh *mesh, const MeshSampleData &mesh_data) +{ + if (!mesh) { + return; + } + + size_t normals_count = mesh_data.normals.size(); + if (normals_count == 0) { + std::cerr << "WARNING: vertex normal count mismatch." << std::endl; + process_no_normals(mesh); + return; + } + + float(*vnors)[3] = static_cast<float(*)[3]>( + MEM_malloc_arrayN(normals_count, sizeof(float[3]), "USD::VertexNormals")); + + for (int i = 0; i < normals_count; ++i) { + + if (mesh_data.y_up) + { + blender::io::usd::copy_zup_from_yup(vnors[i], mesh_data.normals[i].data()); + } + else { + vnors[i][0] = mesh_data.normals[i].data()[0]; + vnors[i][1] = mesh_data.normals[i].data()[1]; + vnors[i][2] = mesh_data.normals[i].data()[2]; + } + + if (mesh_data.reverse_vert_order) { + vnors[i][0] = -vnors[i][0]; + vnors[i][1] = -vnors[i][1]; + vnors[i][2] = -vnors[i][2]; + } + } + + mesh->flag |= ME_AUTOSMOOTH; + BKE_mesh_set_custom_normals_from_vertices(mesh, vnors); + MEM_freeN(vnors); +} + +static void process_normals(Mesh *mesh, const MeshSampleData &mesh_data) +{ + if (!mesh || mesh_data.normals.empty() ) { + process_no_normals(mesh); + return; + } + + if (mesh_data.normals_interpolation == pxr::UsdGeomTokens->faceVarying) { + process_loop_normals(mesh, mesh_data); /* 'vertex normals' in Houdini. */ + } else if (mesh_data.normals_interpolation == pxr::UsdGeomTokens->vertex) { + process_vertex_normals(mesh, mesh_data); /* 'point normals' in Houdini. */ + } else { + process_no_normals(mesh); + } +} + + namespace blender::io::usd { UsdMeshReader::UsdMeshReader(const pxr::UsdPrim &prim, const USDImporterContext &context) @@ -261,7 +373,15 @@ Mesh *UsdMeshReader::read_mesh(Mesh *existing_mesh, } read_mpolys(new_mesh, mesh_data); - BKE_mesh_calc_normals(new_mesh); + + if (this->context_.import_params.import_normals) { + mesh_.GetNormalsAttr().Get(&mesh_data.normals, time); + mesh_data.normals_interpolation = mesh_.GetNormalsInterpolation(); + + process_normals(new_mesh, mesh_data); + } else { + process_no_normals(new_mesh); + } } /* TODO(makowalski): Handle case where topology hasn't changed. */ diff --git a/source/blender/io/usd/usd.h b/source/blender/io/usd/usd.h index 9dadbb1c02b..c72952dd0bf 100644 --- a/source/blender/io/usd/usd.h +++ b/source/blender/io/usd/usd.h @@ -56,6 +56,7 @@ bool USD_export(struct bContext *C, struct USDImportParams { bool import_uvs; + bool import_normals; float scale; bool debug; }; _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs