diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index ead5bd3ad9..e961902bf2 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -101,6 +101,9 @@ The Axom project release numbers follow [Semantic Versioning](http://semver.org/ internal `quest::internal::read_*_mesh()`/`logger_init()` helpers are now declared only when Axom is configured with MPI. Serial code that passed the placeholder `MPI_COMM_SELF` explicitly should drop the argument. - We can now configure Axom without MPI when some of its dependencies were configured with MPI. +- Quest: Status-returning reader/writer operations in `C2CReader`, `MFEMReader`, `ProEReader`, + `STEPReader`, `STLReader`, `STLWriter`, and their parallel variants are now marked `[[nodiscard]]`. + Callers that previously ignored returned status values must check them to avoid compiler diagnostics. ### Fixed - MIR/Bump: `MergeCoordsetPoints` now only emits its node-merge `SLIC_INFO` when MIR `verbose` is enabled on the Conduit options passed through ELVIRA. diff --git a/src/axom/quest/examples/containment_driver.cpp b/src/axom/quest/examples/containment_driver.cpp index c1f4b9e5ca..14a9bfa165 100644 --- a/src/axom/quest/examples/containment_driver.cpp +++ b/src/axom/quest/examples/containment_driver.cpp @@ -110,7 +110,8 @@ class ContainmentDriver AXOM_ANNOTATE_SCOPE("load stl"); quest::STLReader reader; reader.setFileName(inputFile); - reader.read(); + const int read_status = reader.read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load STL file '" << inputFile << "'."); // Create surface mesh m_surfaceMesh.reset(new UMesh(3, mint::TRIANGLE)); diff --git a/src/axom/quest/examples/quest_bvh_two_pass.cpp b/src/axom/quest/examples/quest_bvh_two_pass.cpp index dc4fe4afb3..28b6a3d642 100644 --- a/src/axom/quest/examples/quest_bvh_two_pass.cpp +++ b/src/axom/quest/examples/quest_bvh_two_pass.cpp @@ -375,7 +375,8 @@ int main(int argc, char** argv) { axom::quest::STLReader reader; reader.setFileName(args.file_name); - reader.read(); + const int read_status = reader.read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load STL file '" << args.file_name << "'."); // Get surface mesh surface_mesh.reset(new UMesh(3, mint::TRIANGLE)); diff --git a/src/axom/quest/examples/quest_proe_bbox.cpp b/src/axom/quest/examples/quest_proe_bbox.cpp index 5bffa39b1e..04e1491fa6 100644 --- a/src/axom/quest/examples/quest_proe_bbox.cpp +++ b/src/axom/quest/examples/quest_proe_bbox.cpp @@ -141,7 +141,8 @@ int main(int argc, char** argv) // To keep all tets, do not set a TetPred. // Read in the file. - reader.read(); + const int read_status = reader.read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load Pro/E file '" << args.file_name << "'."); // Get surface mesh UMesh mesh(3, axom::mint::TET); diff --git a/src/axom/quest/examples/quest_step_file.cpp b/src/axom/quest/examples/quest_step_file.cpp index 6f89d8964a..3cef185725 100644 --- a/src/axom/quest/examples/quest_step_file.cpp +++ b/src/axom/quest/examples/quest_step_file.cpp @@ -1103,11 +1103,12 @@ int main(int argc, char** argv) constexpr bool extract_trimmed_surface = true; axom::mint::UnstructuredMesh mesh(3, axom::mint::TRIANGLE); - stepReader.getTriangleMesh(&mesh, - deflection, - angular_deflection, - relative_deflection, - extract_trimmed_surface); + const int triangulation_status = stepReader.getTriangleMesh(&mesh, + deflection, + angular_deflection, + relative_deflection, + extract_trimmed_surface); + SLIC_ERROR_IF(triangulation_status != 0, "Failed to triangulate the trimmed STEP model."); #ifdef AXOM_USE_MPI if(validate_model && !validate_triangle_mesh(mesh)) @@ -1129,7 +1130,8 @@ int main(int argc, char** argv) else { axom::quest::STLWriter writer(output_file, true); - writer.write(&mesh); + const int write_status = writer.write(&mesh); + SLIC_ERROR_IF(write_status != 0, "Failed to write STL file '" << output_file << "'."); } SLIC_INFO(axom::fmt::format(axom::utilities::locale(), @@ -1154,11 +1156,12 @@ int main(int argc, char** argv) constexpr bool extract_trimmed_surface = false; axom::mint::UnstructuredMesh mesh(3, axom::mint::TRIANGLE); - stepReader.getTriangleMesh(&mesh, - deflection, - angular_deflection, - relative_deflection, - extract_trimmed_surface); + const int triangulation_status = stepReader.getTriangleMesh(&mesh, + deflection, + angular_deflection, + relative_deflection, + extract_trimmed_surface); + SLIC_ERROR_IF(triangulation_status != 0, "Failed to triangulate the untrimmed STEP model."); #ifdef AXOM_USE_MPI if(validate_model && !validate_triangle_mesh(mesh)) @@ -1180,7 +1183,8 @@ int main(int argc, char** argv) else { axom::quest::STLWriter writer(output_file, true); - writer.write(&mesh); + const int write_status = writer.write(&mesh); + SLIC_ERROR_IF(write_status != 0, "Failed to write STL file '" << output_file << "'."); } SLIC_INFO( diff --git a/src/axom/quest/io/C2CReader.cpp b/src/axom/quest/io/C2CReader.cpp index f4aec2df2c..0811c135e0 100644 --- a/src/axom/quest/io/C2CReader.cpp +++ b/src/axom/quest/io/C2CReader.cpp @@ -22,13 +22,11 @@ #include #include -namespace axom -{ -namespace quest +namespace axom::quest { namespace { -c2c::LengthUnit toC2CLengthUnit(utilities::LengthUnit unit) +constexpr c2c::LengthUnit toC2CLengthUnit(utilities::LengthUnit unit) { switch(unit) { @@ -82,7 +80,7 @@ bool C2CReader::hasValidExtension(const std::string& filename) int C2CReader::read() { - SLIC_WARNING_IF(m_fileName.empty(), "Missing a filename in C2CReader::read()"); + SLIC_WARNING_ROOT_IF(m_fileName.empty(), "Missing a filename in C2CReader::read()"); // Always clear prior results so callers never observe stale curves after a failed read this->clear(); @@ -104,7 +102,7 @@ C2CReader::ResultType C2CReader::readInternal(const std::string& filename, Curve { if(!hasValidExtension(filename)) { - SLIC_WARNING(axom::fmt::format("{} is not a valid c2c file", filename)); + SLIC_WARNING_ROOT(axom::fmt::format("{} is not a valid c2c file", filename)); return ResultType::Failure; } @@ -119,11 +117,11 @@ C2CReader::ResultType C2CReader::readInternal(const std::string& filename, Curve } catch(const std::exception& e) { - SLIC_WARNING(axom::fmt::format("Failed to read c2c file '{}': {}", filename, e.what())); + SLIC_WARNING_ROOT(axom::fmt::format("Failed to read c2c file '{}': {}", filename, e.what())); } catch(...) { - SLIC_WARNING(axom::fmt::format("Failed to read c2c file '{}'", filename)); + SLIC_WARNING_ROOT(axom::fmt::format("Failed to read c2c file '{}'", filename)); } return ResultType::Failure; @@ -135,10 +133,10 @@ C2CReader::ResultType C2CReader::readAssembly(const std::string& filename, Curve std::string assemblyDir; utilities::filesystem::getDirName(assemblyDir, filename); - SLIC_INFO(fmt::format("Loading assembly with {} pieces", assembly.getNumEntries())); + SLIC_INFO_ROOT(fmt::format("Loading assembly with {} pieces", assembly.getNumEntries())); // Make an initial guess at the number of curves we may need. - const int contoursPerFileGuess = 6; + constexpr int contoursPerFileGuess = 6; CurveArray assemblyCurves; assemblyCurves.reserve(assembly.getNumEntries() * contoursPerFileGuess); @@ -172,7 +170,7 @@ C2CReader::ResultType C2CReader::readContour(const std::string& filename, CurveA c2c::Contour contour = c2c::parseContour(filename); const c2c::LengthUnit c2cLengthUnit = toC2CLengthUnit(m_lengthUnit); - SLIC_INFO(fmt::format("Loading contour with {} pieces", contour.getPieces().size())); + SLIC_INFO_ROOT(fmt::format("Loading contour with {} pieces", contour.getPieces().size())); inputCurves.reserve(inputCurves.size() + contour.getPieces().size()); @@ -199,7 +197,7 @@ C2CReader::ResultType C2CReader::readContour(const std::string& filename, CurveA const int degree = static_cast(nkts - npts - 1); if(degree < 0) { - SLIC_WARNING( + SLIC_WARNING_ROOT( fmt::format("Invalid contour file '{}': computed negative NURBS degree for piece " "{} (npts={}, nkts={})", filename, @@ -211,7 +209,7 @@ C2CReader::ResultType C2CReader::readContour(const std::string& filename, CurveA if(npts <= degree) { - SLIC_WARNING( + SLIC_WARNING_ROOT( fmt::format("Invalid contour file '{}': piece {} has too few control points for degree " "(degree={}, npts={}, nkts={})", filename, @@ -229,7 +227,7 @@ C2CReader::ResultType C2CReader::readContour(const std::string& filename, CurveA if(!knotvec.isValid(true)) { - SLIC_WARNING( + SLIC_WARNING_ROOT( fmt::format("Invalid contour file '{}': piece {} converted to an invalid NURBS knot vector " "(degree={}).", filename, @@ -244,7 +242,7 @@ C2CReader::ResultType C2CReader::readContour(const std::string& filename, CurveA { if(static_cast(nurbsData.weights.size()) != controlPoints.size()) { - SLIC_WARNING( + SLIC_WARNING_ROOT( fmt::format("Invalid contour file '{}': piece {} has {} weights for {} control points", filename, piece_index, @@ -304,8 +302,7 @@ void C2CReader::log() ++index; } - SLIC_INFO(sstr.str()); + SLIC_INFO_ROOT(sstr.str()); } -} // end namespace quest -} // end namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/C2CReader.hpp b/src/axom/quest/io/C2CReader.hpp index 4d164a6c7e..7b0f8d9554 100644 --- a/src/axom/quest/io/C2CReader.hpp +++ b/src/axom/quest/io/C2CReader.hpp @@ -21,9 +21,7 @@ #include #include -namespace axom -{ -namespace quest +namespace axom::quest { /* * \class C2CReader @@ -38,6 +36,7 @@ class C2CReader using NURBSCurve = axom::primal::NURBSCurve; using CurveArray = axom::Array; using CurveArrayView = axom::ArrayView; + using ConstCurveArrayView = axom::ArrayView; enum class ResultType { @@ -67,7 +66,7 @@ class C2CReader * * \return 0 for a successful read; non-zero otherwise */ - virtual int read(); + [[nodiscard]] virtual int read(); /// \brief Utility function to log details about the read in file virtual void log(); @@ -78,6 +77,7 @@ class C2CReader * \return A view that contains the curves. */ CurveArrayView getCurvesView() { return m_nurbsData.view(); } + ConstCurveArrayView getCurvesView() const { return m_nurbsData.view(); } protected: /*! @@ -88,7 +88,7 @@ class C2CReader * * \return Success on success, Failure otherwise. */ - ResultType readInternal(const std::string& filename, CurveArray& inputCurves); + [[nodiscard]] ResultType readInternal(const std::string& filename, CurveArray& inputCurves); /*! * \brief Internal helper for reading a contour file. @@ -98,7 +98,7 @@ class C2CReader * * \return Success on success, Failure otherwise. */ - ResultType readContour(const std::string& filename, CurveArray& inputCurves); + [[nodiscard]] ResultType readContour(const std::string& filename, CurveArray& inputCurves); /*! * \brief Internal helper for reading an assembly file. @@ -108,7 +108,7 @@ class C2CReader * * \return Success on success, Failure otherwise. */ - ResultType readAssembly(const std::string& filename, CurveArray& inputCurves); + [[nodiscard]] ResultType readAssembly(const std::string& filename, CurveArray& inputCurves); protected: std::string m_fileName; @@ -116,5 +116,4 @@ class C2CReader CurveArray m_nurbsData; }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/MFEMReader.cpp b/src/axom/quest/io/MFEMReader.cpp index 4587f794cb..fdf4880dad 100644 --- a/src/axom/quest/io/MFEMReader.cpp +++ b/src/axom/quest/io/MFEMReader.cpp @@ -47,7 +47,7 @@ int read_mfem(const std::string& fileName, { if(!axom::utilities::filesystem::pathExists(fileName)) { - SLIC_WARNING(axom::fmt::format("Cannot open the provided MFEM mesh file '{}'", fileName)); + SLIC_WARNING_ROOT(axom::fmt::format("Cannot open the provided MFEM mesh file '{}'", fileName)); return MFEMReader::READ_FAILED; } @@ -59,7 +59,7 @@ int read_mfem(const std::string& fileName, if(mesh->Dimension() != 1 || mesh->SpaceDimension() != 2) { - SLIC_WARNING( + SLIC_WARNING_ROOT( axom::fmt::format("Mesh must have dimension 1 and spatial dimension 2. The supplied mesh " "is dimension {} with spatial dimension {}.", mesh->Dimension(), @@ -72,7 +72,7 @@ int read_mfem(const std::string& fileName, const auto* fec = fes != nullptr ? fes->FEColl() : nullptr; if(nodes == nullptr || fes == nullptr || fec == nullptr) { - SLIC_WARNING("Mesh does not have a valid nodes grid function"); + SLIC_WARNING_ROOT("Mesh does not have a valid nodes grid function"); return MFEMReader::READ_FAILED; } @@ -105,7 +105,7 @@ int read_mfem(const std::string& fileName, mesh->NURBSext->GetPatchDofs(patchId, dofs); if(dofs.Size() <= 0) { - SLIC_WARNING( + SLIC_WARNING_ROOT( axom::fmt::format("MFEM patch {} has no DOFs; cannot extract NURBS curve.", patchId)); return {}; } @@ -205,7 +205,7 @@ int read_mfem(const std::string& fileName, mesh->NURBSext->GetPatchKnotVectors(patchId, kvs); if(kvs.Size() < 1 || kvs[0] == nullptr) { - SLIC_WARNING( + SLIC_WARNING_ROOT( axom::fmt::format("MFEM patch {} has no valid knot vector; cannot extract NURBS curve.", patchId)); return MFEMReader::READ_FAILED; @@ -213,7 +213,7 @@ int read_mfem(const std::string& fileName, const mfem::KnotVector& kv0 = *kvs[0]; if(kv0.Size() <= 0) { - SLIC_WARNING( + SLIC_WARNING_ROOT( axom::fmt::format("MFEM patch {} has an empty knot vector; cannot extract NURBS curve.", patchId)); return MFEMReader::READ_FAILED; @@ -224,7 +224,8 @@ int read_mfem(const std::string& fileName, const primal::KnotVector kv(knots_view, kv0.GetOrder(), SkipTag {}); if(!kv.isValid(true)) { - SLIC_WARNING(axom::fmt::format("MFEM patch {} has an invalid knot vector: {}", patchId, kv)); + SLIC_WARNING_ROOT( + axom::fmt::format("MFEM patch {} has an invalid knot vector: {}", patchId, kv)); return MFEMReader::READ_FAILED; } @@ -262,7 +263,7 @@ int read_mfem(const std::string& fileName, const bool is_bernstein = dynamic_cast(fec) != nullptr; if(!is_bernstein) { - SLIC_WARNING(axom::fmt::format( + SLIC_WARNING_ROOT(axom::fmt::format( "Non-NURBS meshes must define their nodes in the positive Bernstein basis " "(mfem::H1Pos_FECollection). Got FECollection '{}'.", fec->Name())); @@ -298,7 +299,7 @@ int read_mfem(const std::string& fileName, return MFEMReader::READ_SUCCESS; } -} // end namespace internal +} // namespace internal int MFEMReader::read(CurveArray& curves) { @@ -308,7 +309,7 @@ int MFEMReader::read(CurveArray& curves) int MFEMReader::read(CurveArray& curves, axom::Array& attributes) { - SLIC_WARNING_IF(m_fileName.empty(), "Missing a filename in MFEMReader::read()"); + SLIC_WARNING_ROOT_IF(m_fileName.empty(), "Missing a filename in MFEMReader::read()"); curves.clear(); attributes.clear(); @@ -337,7 +338,7 @@ int MFEMReader::read(CurvedPolygonArray& curvedPolygons) int MFEMReader::read(CurvedPolygonArray& curvedPolygons, axom::Array& attributes) { - SLIC_WARNING_IF(m_fileName.empty(), "Missing a filename in MFEMReader::read()"); + SLIC_WARNING_ROOT_IF(m_fileName.empty(), "Missing a filename in MFEMReader::read()"); curvedPolygons.clear(); attributes.clear(); @@ -363,4 +364,4 @@ int MFEMReader::read(CurvedPolygonArray& curvedPolygons, axom::Array& attri return ret; } -} // end namespace axom::quest +} // namespace axom::quest diff --git a/src/axom/quest/io/MFEMReader.hpp b/src/axom/quest/io/MFEMReader.hpp index 5bedf3aada..f2ce6b1bdb 100644 --- a/src/axom/quest/io/MFEMReader.hpp +++ b/src/axom/quest/io/MFEMReader.hpp @@ -20,9 +20,7 @@ #include #include -namespace axom -{ -namespace quest +namespace axom::quest { /* * \class MFEMReader @@ -52,7 +50,7 @@ class MFEMReader * * \return READ_SUCCESS for a successful read; READ_FAILED (non-zero) otherwise */ - int read(CurveArray& curves); + [[nodiscard]] int read(CurveArray& curves); /*! * \brief Read the contour file provided by \a setFileName() @@ -64,7 +62,7 @@ class MFEMReader * * \return READ_SUCCESS for a successful read; READ_FAILED (non-zero) otherwise */ - int read(CurveArray& curves, axom::Array& attributes); + [[nodiscard]] int read(CurveArray& curves, axom::Array& attributes); /*! * \brief Read the contour file provided by \a setFileName() @@ -76,7 +74,7 @@ class MFEMReader * * \return READ_SUCCESS for a successful read; READ_FAILED (non-zero) otherwise */ - int read(CurvedPolygonArray& curvedPolygons); + [[nodiscard]] int read(CurvedPolygonArray& curvedPolygons); /*! * \brief Read the contour file provided by \a setFileName() @@ -90,11 +88,10 @@ class MFEMReader * * \return READ_SUCCESS for a successful read; READ_FAILED (non-zero) otherwise */ - int read(CurvedPolygonArray& curvedPolygons, axom::Array& attributes); + [[nodiscard]] int read(CurvedPolygonArray& curvedPolygons, axom::Array& attributes); protected: std::string m_fileName; }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/PC2CReader.cpp b/src/axom/quest/io/PC2CReader.cpp index aeac88ed7a..991d59a3ee 100644 --- a/src/axom/quest/io/PC2CReader.cpp +++ b/src/axom/quest/io/PC2CReader.cpp @@ -13,9 +13,7 @@ #include "axom/core.hpp" #include "axom/slic.hpp" -namespace axom -{ -namespace quest +namespace axom::quest { namespace { @@ -128,5 +126,4 @@ bool PC2CReader::bcast_bool(bool value) return static_cast(intValue); } -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/PC2CReader.hpp b/src/axom/quest/io/PC2CReader.hpp index 1c17a9d103..9210189eaf 100644 --- a/src/axom/quest/io/PC2CReader.hpp +++ b/src/axom/quest/io/PC2CReader.hpp @@ -17,9 +17,7 @@ #include "mpi.h" -namespace axom -{ -namespace quest +namespace axom::quest { class PC2CReader : public C2CReader @@ -28,7 +26,7 @@ class PC2CReader : public C2CReader PC2CReader() = delete; PC2CReader(MPI_Comm comm); - virtual ~PC2CReader() = default; + ~PC2CReader() override = default; /*! * \brief Reads in a C2C file to all ranks in the associated communicator @@ -36,7 +34,7 @@ class PC2CReader : public C2CReader * \note Rank 0 reads in the C2C mesh file and broadcasts to the other ranks * \return status set to zero on success; non-zero otherwise */ - int read() final override; + [[nodiscard]] int read() final override; private: /// MPI broadcasts an integer from rank 0 and returns the value to all ranks @@ -78,7 +76,7 @@ class PC2CReader : public C2CReader { // since the data is contiguous, we can cast the start of the data to a double* const int numVals = arr.size() * value_type::DIMENSION; - double* dataPtr = (numVals > 0) ? arr[0].data() : nullptr; + double* dataPtr = !arr.empty() ? arr[0].data() : nullptr; MPI_Bcast(dataPtr, numVals, axom::mpi_traits::type, 0, m_comm); } } @@ -92,5 +90,4 @@ class PC2CReader : public C2CReader DISABLE_MOVE_AND_ASSIGNMENT(PC2CReader); }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/PProEReader.cpp b/src/axom/quest/io/PProEReader.cpp index f053f59290..549d29e725 100644 --- a/src/axom/quest/io/PProEReader.cpp +++ b/src/axom/quest/io/PProEReader.cpp @@ -6,9 +6,7 @@ #include "axom/quest/io/PProEReader.hpp" -namespace axom -{ -namespace quest +namespace axom::quest { namespace { @@ -20,10 +18,7 @@ constexpr int READER_FAILED = -1; PProEReader::PProEReader(MPI_Comm comm) : m_comm(comm) { MPI_Comm_rank(m_comm, &m_my_rank); } //------------------------------------------------------------------------------ -PProEReader::~PProEReader() -{ - // Auto-generated destructor stub -} +PProEReader::~PProEReader() = default; //------------------------------------------------------------------------------ int PProEReader::read() @@ -46,11 +41,11 @@ int PProEReader::read() MPI_Bcast(&m_num_tets, 1, axom::mpi_traits::type, 0, m_comm); MPI_Bcast(&m_nodes[0], m_num_nodes * 3, MPI_DOUBLE, 0, m_comm); MPI_Bcast(&m_tets[0], m_num_tets * 4, MPI_INT, 0, m_comm); - } // END if + } else { MPI_Bcast(&rc, 1, axom::mpi_traits::type, 0, m_comm); - } // END else + } break; default: @@ -69,11 +64,9 @@ int PProEReader::read() MPI_Bcast(&m_nodes[0], m_num_nodes * 3, MPI_DOUBLE, 0, m_comm); MPI_Bcast(&m_tets[0], m_num_tets * 4, MPI_INT, 0, m_comm); } - - } // END switch + } return (rc); } -} // end namespace quest -} // end namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/PProEReader.hpp b/src/axom/quest/io/PProEReader.hpp index 2a7241f7a1..d99b84b056 100644 --- a/src/axom/quest/io/PProEReader.hpp +++ b/src/axom/quest/io/PProEReader.hpp @@ -12,9 +12,7 @@ #include "mpi.h" -namespace axom -{ -namespace quest +namespace axom::quest { class PProEReader : public ProEReader { @@ -22,7 +20,7 @@ class PProEReader : public ProEReader PProEReader() = delete; PProEReader(MPI_Comm comm); - virtual ~PProEReader(); + ~PProEReader() override; /*! * \brief Reads in a Pro/E file to all ranks in the associated communicator. @@ -30,7 +28,7 @@ class PProEReader : public ProEReader * \note Rank 0 reads in the Pro/E mesh file and broadcasts to the other ranks. * \return status set to zero on success; set to a non-zero value otherwise. */ - int read() final override; + [[nodiscard]] int read() final override; private: MPI_Comm m_comm {MPI_COMM_NULL}; @@ -40,5 +38,4 @@ class PProEReader : public ProEReader DISABLE_MOVE_AND_ASSIGNMENT(PProEReader); }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/PSTEPReader.cpp b/src/axom/quest/io/PSTEPReader.cpp index dd3940b60f..15c64d6f66 100644 --- a/src/axom/quest/io/PSTEPReader.cpp +++ b/src/axom/quest/io/PSTEPReader.cpp @@ -1,8 +1,6 @@ #include "axom/quest/io/PSTEPReader.hpp" -namespace axom -{ -namespace quest +namespace axom::quest { namespace { @@ -321,5 +319,4 @@ bool PSTEPReader::bcast_bool(bool value) return static_cast(intValue); } -} // end namespace quest -} // end namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/PSTEPReader.hpp b/src/axom/quest/io/PSTEPReader.hpp index 5954cf9b50..bc0f8e94ad 100644 --- a/src/axom/quest/io/PSTEPReader.hpp +++ b/src/axom/quest/io/PSTEPReader.hpp @@ -17,9 +17,7 @@ #include "mpi.h" -namespace axom -{ -namespace quest +namespace axom::quest { /* @@ -53,7 +51,7 @@ class PSTEPReader : public STEPReader * \param validate_model When true, runs OpenCascade BRep validation on rank 0 * \return 0 on success on all ranks, non-zero otherwise */ - int read(bool validate_model) override; + [[nodiscard]] int read(bool validate_model) override; /*! * \brief Generates a triangulated representation of the STEP file as a Mint unstructured triangle mesh. @@ -72,11 +70,11 @@ class PSTEPReader : public STEPReader * * The mesh is constructed on rank 0 and is then broadcast to the other ranks. */ - int getTriangleMesh(axom::mint::UnstructuredMesh* mesh, - double linear_deflection = 0.1, - double angular_deflection = 0.5, - bool is_relative = false, - bool trimmed = true) override; + [[nodiscard]] int getTriangleMesh(axom::mint::UnstructuredMesh* mesh, + double linear_deflection = 0.1, + double angular_deflection = 0.5, + bool is_relative = false, + bool trimmed = true) override; private: /// MPI broadcasts an integer from rank 0 and returns the value to all ranks @@ -158,16 +156,16 @@ class PSTEPReader : public STEPReader { // handles 1D or 2D array of primal::Point // since the data is contiguous, we cast the values to a 1D ArrayView - constexpr static int POINT_DIM = value_type::DIMENSION; + static constexpr int POINT_DIM = value_type::DIMENSION; const int numVals = arr.size() * POINT_DIM; double* dataPtr = nullptr; if constexpr(ARR_DIM == 1) // 1D array of points { - dataPtr = (arr.size() > 0) ? arr[0].data() : nullptr; + dataPtr = !arr.empty() ? arr[0].data() : nullptr; } else if constexpr(ARR_DIM == 2) // 2D array of points { - dataPtr = (arr.size() > 0) ? &arr(0, 0)[0] : nullptr; + dataPtr = !arr.empty() ? &arr(0, 0)[0] : nullptr; } axom::ArrayView flatView(dataPtr, numVals); bcast_data(flatView); @@ -187,5 +185,4 @@ class PSTEPReader : public STEPReader DISABLE_MOVE_AND_ASSIGNMENT(PSTEPReader); }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/PSTLReader.cpp b/src/axom/quest/io/PSTLReader.cpp index 174625b4d0..eff9d5f599 100644 --- a/src/axom/quest/io/PSTLReader.cpp +++ b/src/axom/quest/io/PSTLReader.cpp @@ -6,9 +6,7 @@ #include "axom/quest/io/PSTLReader.hpp" -namespace axom -{ -namespace quest +namespace axom::quest { namespace { @@ -20,10 +18,7 @@ constexpr int READER_FAILED = -1; PSTLReader::PSTLReader(MPI_Comm comm) : m_comm(comm) { MPI_Comm_rank(m_comm, &m_my_rank); } //------------------------------------------------------------------------------ -PSTLReader::~PSTLReader() -{ - // TODO Auto-generated destructor stub -} +PSTLReader::~PSTLReader() = default; //------------------------------------------------------------------------------ int PSTLReader::read() @@ -44,11 +39,11 @@ int PSTLReader::read() { MPI_Bcast(&m_num_nodes, 1, axom::mpi_traits::type, 0, m_comm); MPI_Bcast(&m_nodes[0], m_num_nodes * 3, MPI_DOUBLE, 0, m_comm); - } // END if + } else { MPI_Bcast(&rc, 1, MPI_INT, 0, m_comm); - } // END else + } break; default: @@ -65,11 +60,9 @@ int PSTLReader::read() m_nodes.resize(m_num_nodes * 3); MPI_Bcast(&m_nodes[0], m_num_nodes * 3, MPI_DOUBLE, 0, m_comm); } - - } // END switch + } return (rc); } -} // end namespace quest -} // end namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/PSTLReader.hpp b/src/axom/quest/io/PSTLReader.hpp index 58c6c377b7..18a50bf966 100644 --- a/src/axom/quest/io/PSTLReader.hpp +++ b/src/axom/quest/io/PSTLReader.hpp @@ -12,9 +12,7 @@ #include "mpi.h" -namespace axom -{ -namespace quest +namespace axom::quest { class PSTLReader : public STLReader { @@ -22,7 +20,7 @@ class PSTLReader : public STLReader PSTLReader() = delete; PSTLReader(MPI_Comm comm); - virtual ~PSTLReader(); + ~PSTLReader() override; /*! * \brief Reads in an STL file to all ranks in the associated communicator. @@ -30,7 +28,7 @@ class PSTLReader : public STLReader * \note Rank 0 reads in the STL mesh file and broadcasts to the other ranks. * \return status set to zero on success; set to a non-zero value otherwise. */ - int read() final override; + [[nodiscard]] int read() final override; private: MPI_Comm m_comm {MPI_COMM_NULL}; @@ -40,5 +38,4 @@ class PSTLReader : public STLReader DISABLE_MOVE_AND_ASSIGNMENT(PSTLReader); }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/ProEReader.cpp b/src/axom/quest/io/ProEReader.cpp index 45c7d5c2e6..a87ce99ece 100644 --- a/src/axom/quest/io/ProEReader.cpp +++ b/src/axom/quest/io/ProEReader.cpp @@ -19,14 +19,12 @@ //------------------------------------------------------------------------------ // ProEReader Implementation //------------------------------------------------------------------------------ -namespace axom +namespace axom::quest { -namespace quest -{ -ProEReader::ProEReader() : m_fileName(""), m_num_nodes(0), m_num_tets(0) { } +ProEReader::ProEReader() = default; //------------------------------------------------------------------------------ -ProEReader::~ProEReader() { this->clear(); } +ProEReader::~ProEReader() = default; //------------------------------------------------------------------------------ void ProEReader::clear() @@ -53,7 +51,7 @@ int ProEReader::read() if(!ifs.is_open()) { - SLIC_WARNING("Cannot open the provided Pro/E file [" << m_fileName << "]"); + SLIC_WARNING_ROOT("Cannot open the provided Pro/E file [" << m_fileName << "]"); return (-1); } @@ -197,5 +195,4 @@ void ProEReader::getMesh(axom::mint::UnstructuredMesh* mesh) } } -} // end namespace quest -} // end namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/ProEReader.hpp b/src/axom/quest/io/ProEReader.hpp index d1f0c0421f..e5dcd4f4cb 100644 --- a/src/axom/quest/io/ProEReader.hpp +++ b/src/axom/quest/io/ProEReader.hpp @@ -13,12 +13,10 @@ #include "axom/primal/geometry/BoundingBox.hpp" // C/C++ includes -#include // for std::string -#include // for std::vector +#include +#include -namespace axom -{ -namespace quest +namespace axom::quest { /*! * \class ProEReader @@ -53,8 +51,8 @@ namespace quest class ProEReader { public: - constexpr static int NUM_NODES_PER_TET = 4; - constexpr static int NUM_COMPS_PER_NODE = 3; + static constexpr int NUM_NODES_PER_TET = 4; + static constexpr int NUM_COMPS_PER_NODE = 3; using Point3D = primal::Point; using BBox3D = primal::BoundingBox; /*! \brief Specify tets to keep. @@ -81,19 +79,19 @@ class ProEReader * \brief Sets the name of the file to read. * \param [in] fileName the name of the file to read. */ - void setFileName(const std::string& fileName) { m_fileName = fileName; }; + void setFileName(const std::string& fileName) { m_fileName = fileName; } /*! * \brief Returns the number of nodes of the mesh. * \return numNodes the number of nodes. */ - int getNumNodes() const { return static_cast(m_num_nodes); }; + int getNumNodes() const { return static_cast(m_num_nodes); } /*! * \brief Returns the number of tetrahedra of the mesh * \return numTets the number of tetrahedra. */ - int getNumTets() const { return static_cast(m_num_tets); }; + int getNumTets() const { return static_cast(m_num_tets); } /*! * \brief Clears all internal data-structures @@ -105,7 +103,7 @@ class ProEReader * \pre path to input file has been set by calling `setFileName()` * \return status set to zero on success; set to a non-zero value otherwise. */ - virtual int read(); + [[nodiscard]] virtual int read(); /// \name Set tetrahedron predicate to read mesh subset /// @{ @@ -139,8 +137,8 @@ class ProEReader protected: std::string m_fileName; - axom::IndexType m_num_nodes; - axom::IndexType m_num_tets; + axom::IndexType m_num_nodes {0}; + axom::IndexType m_num_tets {0}; std::vector m_nodes; std::vector m_tets; @@ -161,5 +159,4 @@ class ProEReader DISABLE_MOVE_AND_ASSIGNMENT(ProEReader); }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/STEPReader.cpp b/src/axom/quest/io/STEPReader.cpp index 7326c3728b..53ee5709f2 100644 --- a/src/axom/quest/io/STEPReader.cpp +++ b/src/axom/quest/io/STEPReader.cpp @@ -58,9 +58,7 @@ #include -namespace axom -{ -namespace quest +namespace axom::quest { namespace internal { @@ -222,18 +220,18 @@ class StepFileProcessor const double sq_dist = axom::primal::squared_distance(my_val, other_val); squared_sum += sq_dist; - SLIC_WARNING_IF(m_verbose && sq_dist > sq_tol, - axom::fmt::format("Distance between surfaces at evaluated param " - "({},{}) exceeded tolerance {}.\n" - "Point on my surface {}; Point on other surface " - "{}; Squared distance {} (running sum {})", - u, - v, - sq_tol, - my_val, - other_val, - sq_dist, - squared_sum)); + SLIC_WARNING_ROOT_IF(m_verbose && sq_dist > sq_tol, + axom::fmt::format("Distance between surfaces at evaluated param " + "({},{}) exceeded tolerance {}.\n" + "Point on my surface {}; Point on other surface " + "{}; Squared distance {} (running sum {})", + u, + v, + sq_tol, + my_val, + other_val, + sq_dist, + squared_sum)); } } @@ -243,30 +241,30 @@ class StepFileProcessor /// Logs some information about the patch void printSurfaceInfo() const { - SLIC_INFO(axom::fmt::format("Patch is periodic in u: {}", m_surface->IsUPeriodic())); - SLIC_INFO(axom::fmt::format("Patch is periodic in v: {}", m_surface->IsVPeriodic())); + SLIC_INFO_ROOT(axom::fmt::format("Patch is periodic in u: {}", m_surface->IsUPeriodic())); + SLIC_INFO_ROOT(axom::fmt::format("Patch is periodic in v: {}", m_surface->IsVPeriodic())); // Print control points { const auto patch_control_points = extractControlPoints(); - SLIC_INFO(axom::fmt::format("Patch control points ({} x {}): {}", - patch_control_points.shape()[0], - patch_control_points.shape()[1], - patch_control_points)); + SLIC_INFO_ROOT(axom::fmt::format("Patch control points ({} x {}): {}", + patch_control_points.shape()[0], + patch_control_points.shape()[1], + patch_control_points)); } // Print weights (if the surface is rational) if(const bool isRational = m_surface->IsURational() || m_surface->IsVRational(); isRational) { const auto patch_weights = extractWeights(); - SLIC_INFO(axom::fmt::format("Patch weights ({} x {}): {}", - patch_weights.shape()[0], - patch_weights.shape()[1], - patch_weights)); + SLIC_INFO_ROOT(axom::fmt::format("Patch weights ({} x {}): {}", + patch_weights.shape()[0], + patch_weights.shape()[1], + patch_weights)); } else { - SLIC_INFO("Patch is polynomial (uniform weights)"); + SLIC_INFO_ROOT("Patch is polynomial (uniform weights)"); } } @@ -527,17 +525,17 @@ class StepFileProcessor const double sq_dist = axom::primal::squared_distance(my_val, other_val); squared_sum += sq_dist; - SLIC_WARNING_IF(m_verbose && sq_dist > sq_tol, - axom::fmt::format("Distance between curves at evaluated param {} " - "exceeded tolerance {}.\n" - "Point on my curve {}; Point on other curve {}; " - "Squared distance {} (running sum {})", - val, - sq_tol, - my_val, - other_val, - sq_dist, - squared_sum)); + SLIC_WARNING_ROOT_IF( + m_verbose && sq_dist > sq_tol, + axom::fmt::format( + "Distance between curves at evaluated param {} exceeded tolerance {}.\n" + "Point on my curve {}; Point on other curve {}; Squared distance {} (running sum {})", + val, + sq_tol, + my_val, + other_val, + sq_dist, + squared_sum)); } return squared_sum <= sq_tol; @@ -686,7 +684,7 @@ class StepFileProcessor int patchIndex = 0; for(TopExp_Explorer ex(m_shape, TopAbs_FACE); ex.More(); ex.Next(), ++patchIndex) { - SLIC_DEBUG_IF(m_verbose, "*** Processing patch " << patchIndex); + SLIC_DEBUG_ROOT_IF(m_verbose, "*** Processing patch " << patchIndex); const TopoDS_Face& face = TopoDS::Face(ex.Current()); opencascade::handle surface = BRep_Tool::Surface(face); @@ -720,19 +718,19 @@ class StepFileProcessor opencascade::handle::DownCast(surface); const bool withinThreshold = patchProcessor.compareToSurface(origSurface, 25); - SLIC_WARNING_IF(!withinThreshold, - axom::fmt::format("[Patch {}] Patch geometry was not " - "within threshold after clamping.", - patchIndex, - patches[patchIndex])); + SLIC_WARNING_ROOT_IF(!withinThreshold, + axom::fmt::format("[Patch {}] Patch geometry was not within " + "threshold after clamping.\n Patch data: {}.", + patchIndex, + patches[patchIndex])); } } else { const std::string surfaceType = surface->DynamicType()->Name(); - SLIC_WARNING(fmt::format("Skipping patch {} with non-BSpline surface type: '{}'", - patchIndex, - surfaceType)); + SLIC_WARNING_ROOT(fmt::format("Skipping patch {} with non-BSpline surface type: '{}'", + patchIndex, + surfaceType)); } } } @@ -797,7 +795,7 @@ class StepFileProcessor } if(!sstr.str().empty()) { - SLIC_INFO(prefix << "\n" << sstr.str()); + SLIC_INFO_ROOT(prefix << "\n" << sstr.str()); } }; @@ -875,11 +873,12 @@ class StepFileProcessor auto expandedPatchBbox = patchBbox; expandedPatchBbox.scale(1. + 1e-3); - SLIC_INFO_IF(m_verbose, - axom::fmt::format("[Patch {}]: BBox in parametric space: {}; expanded BBox {}", - patchIndex, - patchBbox, - expandedPatchBbox)); + SLIC_INFO_ROOT_IF( + m_verbose, + axom::fmt::format("[Patch {}]: BBox in parametric space: {}; expanded BBox {}", + patchIndex, + patchBbox, + expandedPatchBbox)); int wireIndex = 0; for(TopExp_Explorer wireExp(faceExp.Current(), TopAbs_WIRE); wireExp.More(); @@ -896,11 +895,11 @@ class StepFileProcessor if(m_verbose) { BRepAdaptor_Curve curveAdaptor(edge); - SLIC_INFO(axom::fmt::format("[Patch {} Wire {} Edge {}] Curve type: '{}'", - patchIndex, - wireIndex, - edgeIndex, - curveTypeMap[curveAdaptor.GetType()])); + SLIC_INFO_ROOT(axom::fmt::format("[Patch {} Wire {} Edge {}] Curve type: '{}'", + patchIndex, + wireIndex, + edgeIndex, + curveTypeMap[curveAdaptor.GetType()])); } Standard_Real first, last; @@ -934,12 +933,12 @@ class StepFileProcessor patch.addTrimmingCurve(curve); - SLIC_INFO_IF(m_verbose, - axom::fmt::format("[Patch {} Wire {} Edge {}] Added curve: {}", - patchIndex, - wireIndex, - edgeIndex, - curve)); + SLIC_INFO_ROOT_IF(m_verbose, + axom::fmt::format("[Patch {} Wire {} Edge {}] Added curve: {}", + patchIndex, + wireIndex, + edgeIndex, + curve)); // Check to ensure that curve did not change geometrically after making non-periodic if(originalCurvePeriodic) @@ -947,12 +946,13 @@ class StepFileProcessor opencascade::handle origCurve = Geom2dConvert::CurveToBSplineCurve(parametricCurve); const bool withinThreshold = curveProcessor.compareToCurve(origCurve, 25); - SLIC_WARNING_IF(!withinThreshold, - axom::fmt::format("[Patch {} Wire {} Edge {}] Trimming curve was not " - "within threshold after clamping.", - patchIndex, - wireIndex, - edgeIndex)); + SLIC_WARNING_ROOT_IF( + !withinThreshold, + axom::fmt::format("[Patch {} Wire {} Edge {}] Trimming curve was not " + "within threshold after clamping.", + patchIndex, + wireIndex, + edgeIndex)); } // TODO: Check that curve control points are within UV patch after adjusting periodicity @@ -1018,8 +1018,8 @@ class StepFileProcessor } m_loadStatus = LoadStatus::SUCCESS; - SLIC_INFO_IF(m_verbose, - axom::fmt::format("Successfully read the STEP file with {} roots", numRoots)); + SLIC_INFO_ROOT_IF(m_verbose, + axom::fmt::format("Successfully read the STEP file with {} roots", numRoots)); return nurbsShape; } @@ -1084,8 +1084,8 @@ class PatchTriangulator if(triangulation.IsNull()) { - SLIC_WARNING(axom::fmt::format("Error: Triangulation could not be generated for patch {}", - patchIndex)); + SLIC_WARNING_ROOT( + axom::fmt::format("Error: Triangulation could not be generated for patch {}", patchIndex)); continue; } @@ -1161,7 +1161,7 @@ class PatchTriangulator if(triangulation.IsNull()) { - SLIC_WARNING( + SLIC_WARNING_ROOT( axom::fmt::format("Error: Triangulation could not be generated for untrimmed patch {}", patchIndex)); break; @@ -1211,7 +1211,7 @@ class PatchTriangulator bool m_deflectionIsRelative; }; -} // end namespace internal +} // namespace internal std::string STEPReader::getFileUnits() const { return m_stepProcessor->getFileUnits(); } @@ -1470,7 +1470,7 @@ axom::primal::BoundingBox STEPReader::getBRepBoundingBox(bool useTria { if(!m_stepProcessor->isLoaded()) { - SLIC_WARNING("Cannot compute bounding box until calling STEPReader::read()"); + SLIC_WARNING_ROOT("Cannot compute bounding box until calling STEPReader::read()"); return axom::primal::BoundingBox {}; } @@ -1566,13 +1566,13 @@ int STEPReader::getTriangleMesh(axom::mint::UnstructuredMeshisLoaded()) { - SLIC_WARNING("Cannot triangulate model until calling STEPReader::read()"); + SLIC_WARNING_ROOT("Cannot triangulate model until calling STEPReader::read()"); return 1; } if(!mesh) { - SLIC_WARNING("Passed in mesh instance was null. Skipping triangulation"); + SLIC_WARNING_ROOT("Passed in mesh instance was null. Skipping triangulation"); return 1; } @@ -1593,5 +1593,4 @@ int STEPReader::getTriangleMesh(axom::mint::UnstructuredMesh #include -namespace axom -{ -namespace quest +namespace axom::quest { namespace internal { @@ -59,7 +57,7 @@ class STEPReader * \param[in] validate Adds validation tests on the model, when true * \return 0 for a successful read; non-zero otherwise */ - virtual int read(bool validate); + [[nodiscard]] virtual int read(bool validate); std::string getFileUnits() const; @@ -67,7 +65,7 @@ class STEPReader const PatchArray& getPatchArray() const { return m_patches; } /// Get the number of patches in the read file - int numPatches() { return m_patches.size(); } + int numPatches() const { return m_patches.size(); } /*! * \brief Returns a 0-based patch id per entry in \a getPatchArray() @@ -112,11 +110,11 @@ class STEPReader * otherwise, we triangulate the untrimmed patches. The latter is mostly to aid * in understanding the model's patches and is not generally useful. */ - virtual int getTriangleMesh(axom::mint::UnstructuredMesh* mesh, - double linear_deflection = 0.1, - double angular_deflection = 0.5, - bool is_relative = false, - bool trimmed = true); + [[nodiscard]] virtual int getTriangleMesh(axom::mint::UnstructuredMesh* mesh, + double linear_deflection = 0.1, + double angular_deflection = 0.5, + bool is_relative = false, + bool trimmed = true); protected: // open cascade does not appear to offer a direct way to get the number of patches @@ -133,5 +131,4 @@ class STEPReader IndexArray m_patchOriginallyPeriodic_v; }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/STLReader.cpp b/src/axom/quest/io/STLReader.cpp index 0a321fb191..c5bcc115c9 100644 --- a/src/axom/quest/io/STLReader.cpp +++ b/src/axom/quest/io/STLReader.cpp @@ -16,21 +16,19 @@ namespace { -const std::size_t BINARY_HEADER_SIZE = 80; // bytes -const std::size_t BINARY_TRI_SIZE = 50; // bytes +constexpr std::size_t BINARY_HEADER_SIZE = 80; // bytes +constexpr std::size_t BINARY_TRI_SIZE = 50; // bytes } // namespace //------------------------------------------------------------------------------ // STLReader Implementation //------------------------------------------------------------------------------ -namespace axom +namespace axom::quest { -namespace quest -{ -STLReader::STLReader() : m_fileName(""), m_num_nodes(0), m_num_faces(0) { } +STLReader::STLReader() = default; //------------------------------------------------------------------------------ -STLReader::~STLReader() { this->clear(); } +STLReader::~STLReader() = default; //------------------------------------------------------------------------------ void STLReader::clear() @@ -54,7 +52,7 @@ bool STLReader::isAsciiFormat() const if(!ifs.is_open()) { /* short-circuit */ - SLIC_WARNING("Cannot open the provided STL file [" << m_fileName << "]"); + SLIC_WARNING_ROOT("Cannot open the provided STL file [" << m_fileName << "]"); return false; } @@ -62,8 +60,8 @@ bool STLReader::isAsciiFormat() const ifs.seekg(0, ifs.end); std::int32_t fileSize = static_cast(ifs.tellg()); - const int totalHeaderSize = (BINARY_HEADER_SIZE + sizeof(std::int32_t)); - if(fileSize < totalHeaderSize) + constexpr int TOTAL_HEADER_SIZE = BINARY_HEADER_SIZE + sizeof(std::int32_t); + if(fileSize < TOTAL_HEADER_SIZE) { return true; } @@ -79,11 +77,11 @@ bool STLReader::isAsciiFormat() const } // Check if the size matches our expectation - int expectedBinarySize = totalHeaderSize + (numTris * BINARY_TRI_SIZE); + const int EXPECTED_BINARY_SIZE = TOTAL_HEADER_SIZE + (numTris * BINARY_TRI_SIZE); ifs.close(); - return (fileSize != expectedBinarySize); + return (fileSize != EXPECTED_BINARY_SIZE); } //------------------------------------------------------------------------------ @@ -93,7 +91,7 @@ int STLReader::readAsciiSTL() if(!ifs.is_open()) { - SLIC_WARNING("Cannot open the provided STL file [" << m_fileName << "]"); + SLIC_WARNING_ROOT("Cannot open the provided STL file [" << m_fileName << "]"); return (-1); } @@ -156,7 +154,7 @@ int STLReader::readBinarySTL() std::ifstream ifs(m_fileName.c_str(), std::ios::in | std::ios::binary); if(!ifs.is_open()) { - SLIC_WARNING("Cannot open the provided STL file [" << m_fileName << "]"); + SLIC_WARNING_ROOT("Cannot open the provided STL file [" << m_fileName << "]"); return (-1); } @@ -251,5 +249,4 @@ void STLReader::getMesh(axom::mint::UnstructuredMesh* mesh) } } -} // end namespace quest -} // end namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/STLReader.hpp b/src/axom/quest/io/STLReader.hpp index dc56deafb4..90583762e8 100644 --- a/src/axom/quest/io/STLReader.hpp +++ b/src/axom/quest/io/STLReader.hpp @@ -15,9 +15,7 @@ #include // for std::string #include // for std::vector -namespace axom -{ -namespace quest +namespace axom::quest { /*! * \class STLReader @@ -31,37 +29,31 @@ namespace quest class STLReader { public: - /*! - * \brief Constructor. - */ + /// \brief Constructor STLReader(); - /*! - * \brief Destructor. - */ + /// \brief Destructor virtual ~STLReader(); /*! * \brief Sets the name of the file to read. * \param [in] fileName the name of the file to read. */ - void setFileName(const std::string& fileName) { m_fileName = fileName; }; + void setFileName(const std::string& fileName) { m_fileName = fileName; } /*! * \brief Returns the number of nodes of the surface mesh. * \return numNodes the number of nodes. */ - int getNumNodes() const { return static_cast(m_num_nodes); }; + int getNumNodes() const { return static_cast(m_num_nodes); } /*! * \brief Returns the number of faces of the surface mesh. * \return numFaces the number of faces. */ - int getNumFaces() const { return static_cast(m_num_faces); }; + int getNumFaces() const { return static_cast(m_num_faces); } - /*! - * \brief Clears all internal data-structures - */ + /// \brief Clears all internal data-structures void clear(); /*! @@ -69,7 +61,7 @@ class STLReader * \pre path to input file has been set by calling `setFileName()` * \return status set to zero on success; set to a non-zero value otherwise. */ - virtual int read(); + [[nodiscard]] virtual int read(); /*! * \brief Stores the STL data in the supplied unstructured mesh object. @@ -96,19 +88,19 @@ class STLReader * \brief Reads an ascii-encoded STL file into memory * \note The filename should be set with STLReader::setFileName() */ - int readAsciiSTL(); + [[nodiscard]] int readAsciiSTL(); /*! * \brief Reads a binary-encoded STL file into memory * \note The filename should be set with STLReader::setFileName() */ - int readBinarySTL(); + [[nodiscard]] int readBinarySTL(); protected: std::string m_fileName; - axom::IndexType m_num_nodes; - axom::IndexType m_num_faces; + axom::IndexType m_num_nodes {0}; + axom::IndexType m_num_faces {0}; std::vector m_nodes; @@ -117,5 +109,4 @@ class STLReader DISABLE_MOVE_AND_ASSIGNMENT(STLReader); }; -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/STLWriter.cpp b/src/axom/quest/io/STLWriter.cpp index f236581b7c..7684009069 100644 --- a/src/axom/quest/io/STLWriter.cpp +++ b/src/axom/quest/io/STLWriter.cpp @@ -13,9 +13,7 @@ #include #include -namespace axom -{ -namespace quest +namespace axom::quest { namespace internal { @@ -45,7 +43,7 @@ void writeTriangle(std::ofstream& out, bool binary, double coords[3][3], const N } // The attribute is sometimes used as colors. Set bits to white. // See https://en.wikipedia.org/wiki/STL_(file_format). - const std::uint16_t attr = 0x7fff; + constexpr std::uint16_t attr = 0x7fff; out.write(reinterpret_cast(n32), 3 * sizeof(float32)); out.write(reinterpret_cast(coords32[0]), 3 * sizeof(float32)); out.write(reinterpret_cast(coords32[1]), 3 * sizeof(float32)); @@ -64,11 +62,10 @@ void writeTriangle(std::ofstream& out, bool binary, double coords[3][3], const N } } -} // end namespace internal +} // namespace internal STLWriter::STLWriter(const std::string& filename, bool binary) - : m_mesh(nullptr) - , m_fileName(filename) + : m_fileName(filename) , m_binary(binary) { } @@ -121,7 +118,7 @@ int STLWriter::write(const mint::Mesh* mesh) using VectorType = axom::primal::Vector; SLIC_ERROR_IF(mesh == nullptr, "mesh pointer is null!"); - SLIC_ERROR_IF(m_fileName.length() <= 0, "STL filename is empty!"); + SLIC_ERROR_IF(m_fileName.empty(), "STL filename is empty!"); SLIC_ERROR_IF(mesh->getDimension() < 2 || mesh->getDimension() > 3, "Input mesh is not 2D/3D."); // Save mesh pointer @@ -143,7 +140,7 @@ int STLWriter::write(const mint::Mesh* mesh) // Fill with spaces memset(header, ' ', sizeof(std::uint8_t) * STL_HEADER_SIZE); // Copy in string (without terminator) - const char* msg = "STL Binary File Written By Axom"; + constexpr char msg[] = "STL Binary File Written By Axom"; memcpy(header, msg, strlen(msg)); out.write(reinterpret_cast(header), STL_HEADER_SIZE); @@ -233,5 +230,4 @@ int write_stl(const mint::Mesh* mesh, const std::string& filename, bool binary) return w.write(mesh); } -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/io/STLWriter.hpp b/src/axom/quest/io/STLWriter.hpp index 416efa3e32..519193fdd0 100644 --- a/src/axom/quest/io/STLWriter.hpp +++ b/src/axom/quest/io/STLWriter.hpp @@ -13,9 +13,7 @@ #include -namespace axom -{ -namespace quest +namespace axom::quest { /*! * \class STLWriter @@ -70,7 +68,7 @@ class STLWriter * \pre path to input file has been set by calling `setFileName()` * \return status set to zero on success; set to a non-zero value otherwise. */ - int write(const mint::Mesh* mesh); + [[nodiscard]] int write(const mint::Mesh* mesh); // The following members are protected (unless using CUDA) #if !defined(__CUDACC__) @@ -105,7 +103,6 @@ class STLWriter * * \return 0 on success; non-zero otherwise. */ -int write_stl(const mint::Mesh* mesh, const std::string& filename, bool binary = false); +[[nodiscard]] int write_stl(const mint::Mesh* mesh, const std::string& filename, bool binary = false); -} // namespace quest -} // namespace axom +} // namespace axom::quest diff --git a/src/axom/quest/tests/quest_c2c_reader.cpp b/src/axom/quest/tests/quest_c2c_reader.cpp index 7dee8bcccd..4c9c15b715 100644 --- a/src/axom/quest/tests/quest_c2c_reader.cpp +++ b/src/axom/quest/tests/quest_c2c_reader.cpp @@ -135,7 +135,7 @@ TEST(quest_c2c_reader, basic_read) quest::C2CReader reader; reader.setFileName(fileName); - reader.read(); + ASSERT_EQ(0, reader.read()); reader.log(); } @@ -147,7 +147,7 @@ TEST(quest_c2c_reader, interpolate_circle) quest::C2CReader reader; reader.setFileName(fileName); - reader.read(); + ASSERT_EQ(0, reader.read()); reader.log(); constexpr int DIM = 2; @@ -224,7 +224,7 @@ TEST(quest_c2c_reader, interpolate_square) quest::C2CReader reader; reader.setFileName(fileName); - reader.read(); + ASSERT_EQ(0, reader.read()); reader.log(); constexpr int DIM = 2; @@ -261,7 +261,7 @@ TEST(quest_c2c_reader, interpolate_spline) quest::C2CReader reader; reader.setFileName(fileName); - reader.read(); + ASSERT_EQ(0, reader.read()); reader.log(); constexpr int DIM = 2; diff --git a/src/axom/quest/tests/quest_gwn_methods.cpp b/src/axom/quest/tests/quest_gwn_methods.cpp index 24d16026ca..e3f5b8172d 100644 --- a/src/axom/quest/tests/quest_gwn_methods.cpp +++ b/src/axom/quest/tests/quest_gwn_methods.cpp @@ -277,7 +277,7 @@ void check_step_file_evaluation() // Get a triangulation of the shape axom::mint::UnstructuredMesh tri_mesh(3, axom::mint::TRIANGLE); - step_reader.getTriangleMesh(&tri_mesh, 0.01, 0.5); + ASSERT_EQ(step_reader.getTriangleMesh(&tri_mesh, 0.01, 0.5), 0); // Get bounding box of the shape axom::primal::BoundingBox shape_bbox = step_reader.getBRepBoundingBox(); diff --git a/src/axom/quest/tests/quest_meshtester.cpp b/src/axom/quest/tests/quest_meshtester.cpp index fb1c601a27..0cbfdf9f72 100644 --- a/src/axom/quest/tests/quest_meshtester.cpp +++ b/src/axom/quest/tests/quest_meshtester.cpp @@ -339,7 +339,7 @@ TEST(quest_mesh_tester, surfacemesh_self_intersection_ondisk) // read in the test file into a Mesh quest::STLReader reader; reader.setFileName(tfname); - reader.read(); + ASSERT_EQ(reader.read(), 0); // Get surface mesh UMesh* surface_mesh = new UMesh(3, mint::TRIANGLE); @@ -463,7 +463,7 @@ TEST(quest_mesh_tester, surfacemesh_watertight_ondisk) // Read in the test file into a Mesh quest::STLReader reader; reader.setFileName(tfname); - reader.read(); + ASSERT_EQ(reader.read(), 0); // Get surface mesh UMesh* surface_mesh = new UMesh(3, mint::TRIANGLE); diff --git a/src/axom/quest/tests/quest_step_reader.cpp b/src/axom/quest/tests/quest_step_reader.cpp index 84cab98891..7cf0bdc68a 100644 --- a/src/axom/quest/tests/quest_step_reader.cpp +++ b/src/axom/quest/tests/quest_step_reader.cpp @@ -204,7 +204,7 @@ void runStepFileTest(const std::string& stepFile, double deflection = 0.1) } mint::UnstructuredMesh triMesh(3, mint::TRIANGLE); - stepReader.getTriangleMesh(&triMesh, deflection); + ASSERT_EQ(0, stepReader.getTriangleMesh(&triMesh, deflection)); MiniTriangleGWN3D triEval; triEval.preprocess(triMesh); diff --git a/src/examples/radiuss_tutorial/lesson_01/README.md b/src/examples/radiuss_tutorial/lesson_01/README.md index 86397edf04..3851829caf 100644 --- a/src/examples/radiuss_tutorial/lesson_01/README.md +++ b/src/examples/radiuss_tutorial/lesson_01/README.md @@ -195,7 +195,8 @@ TriangleMesh makeTriangleMesh(const std::string& stl_mesh_path) { auto reader = std::make_unique(); reader->setFileName(stl_mesh_path); - reader->read(); + const int read_status = reader->read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load STL file '" << stl_mesh_path << "'."); reader->getMesh(surface_mesh.get()); } diff --git a/src/examples/radiuss_tutorial/lesson_01/load_stl_mesh.cpp b/src/examples/radiuss_tutorial/lesson_01/load_stl_mesh.cpp index 7b8a761366..9001477351 100644 --- a/src/examples/radiuss_tutorial/lesson_01/load_stl_mesh.cpp +++ b/src/examples/radiuss_tutorial/lesson_01/load_stl_mesh.cpp @@ -117,7 +117,8 @@ TriangleMesh makeTriangleMesh(const std::string& stl_mesh_path) { auto reader = std::make_unique(); reader->setFileName(stl_mesh_path); - reader->read(); + const int read_status = reader->read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load STL file '" << stl_mesh_path << "'."); reader->getMesh(surface_mesh.get()); } diff --git a/src/examples/radiuss_tutorial/lesson_02/naive_self_intersections.cpp b/src/examples/radiuss_tutorial/lesson_02/naive_self_intersections.cpp index e4a18efe70..89e64d2a22 100644 --- a/src/examples/radiuss_tutorial/lesson_02/naive_self_intersections.cpp +++ b/src/examples/radiuss_tutorial/lesson_02/naive_self_intersections.cpp @@ -161,7 +161,8 @@ TriangleMesh makeTriangleMesh(const std::string& stl_mesh_path, double weldThres auto reader = std::make_unique(); reader->setFileName(stl_mesh_path); - reader->read(); + const int read_status = reader->read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load STL file '" << stl_mesh_path << "'."); reader->getMesh(surface_mesh); timer.stop(); diff --git a/src/examples/radiuss_tutorial/lesson_03/device_self_intersections.cpp b/src/examples/radiuss_tutorial/lesson_03/device_self_intersections.cpp index 1619485c42..07feb2c98f 100644 --- a/src/examples/radiuss_tutorial/lesson_03/device_self_intersections.cpp +++ b/src/examples/radiuss_tutorial/lesson_03/device_self_intersections.cpp @@ -202,7 +202,8 @@ TriangleMesh makeTriangleMesh(const std::string& stl_mesh_path, double weldThres auto reader = std::make_unique(); reader->setFileName(stl_mesh_path); - reader->read(); + const int read_status = reader->read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load STL file '" << stl_mesh_path << "'."); reader->getMesh(surface_mesh); timer.stop(); diff --git a/src/examples/radiuss_tutorial/lesson_04/device_spatial_indexes.cpp b/src/examples/radiuss_tutorial/lesson_04/device_spatial_indexes.cpp index 2b36218eef..c8e32d2dbe 100644 --- a/src/examples/radiuss_tutorial/lesson_04/device_spatial_indexes.cpp +++ b/src/examples/radiuss_tutorial/lesson_04/device_spatial_indexes.cpp @@ -188,7 +188,8 @@ TriangleMesh makeTriangleMesh(const std::string& stl_mesh_path, double weldThres auto reader = std::make_unique(); reader->setFileName(stl_mesh_path); - reader->read(); + const int read_status = reader->read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load STL file '" << stl_mesh_path << "'."); reader->getMesh(surface_mesh); timer.stop(); diff --git a/src/tools/mesh_converter.cpp b/src/tools/mesh_converter.cpp index 7af4f8f928..c1ac3870ec 100644 --- a/src/tools/mesh_converter.cpp +++ b/src/tools/mesh_converter.cpp @@ -248,7 +248,10 @@ bool loadProe(const std::string& filename, TetMesh& slam_mesh, bool dump_debug_m axom::quest::ProEReader reader; reader.setFileName(filename); - reader.read(); + if(reader.read() != 0) + { + return false; + } SLIC_INFO(axom::fmt::format(axom::utilities::locale(), "Input mesh has {:L} vertices and {:L} tets", reader.getNumNodes(), diff --git a/src/tools/mesh_tester.cpp b/src/tools/mesh_tester.cpp index a5d0c1b418..fccc0c0604 100644 --- a/src/tools/mesh_tester.cpp +++ b/src/tools/mesh_tester.cpp @@ -651,7 +651,8 @@ int main(int argc, char** argv) AXOM_ANNOTATE_SCOPE("load stl mesh"); auto reader = std::make_unique(); reader->setFileName(params.stlInput); - reader->read(); + const int read_status = reader->read(); + SLIC_ERROR_IF(read_status != 0, "Failed to load STL file '" << params.stlInput << "'."); reader->getMesh(surface_mesh); }