From 0553c319dcb1d288c0320a4a8dfc7ba0f2695036 Mon Sep 17 00:00:00 2001 From: jzwar Date: Mon, 26 Jun 2023 15:23:28 +0200 Subject: [PATCH] Slight changes - deleted helpers --- cpp/splinepy/py/py_knot_insertion_matrix.hpp | 8 +- cpp/splinepy/splines/bspline.hpp | 16 +- .../helpers/extract_bezier_patches.hpp | 147 +++++++++++------- 3 files changed, 106 insertions(+), 65 deletions(-) diff --git a/cpp/splinepy/py/py_knot_insertion_matrix.hpp b/cpp/splinepy/py/py_knot_insertion_matrix.hpp index 2354118b7..eb8c2d324 100644 --- a/cpp/splinepy/py/py_knot_insertion_matrix.hpp +++ b/cpp/splinepy/py/py_knot_insertion_matrix.hpp @@ -5,7 +5,7 @@ #include "pybind11/numpy.h" #include "pybind11/pybind11.h" -#include "splinepy/splines/helpers.hpp" +#include "splinepy/splines/helpers/extract_bezier_patches.hpp" #include "splinepy/utils/print.hpp" /// @brief @@ -457,9 +457,9 @@ py::tuple BezierExtractionMatrices(const py::list& old_kvs, // Lastly, compute the bezier extraction points, that correspond to the global // matrix. const auto& list_of_ids = - splines::ExtractBezierPatchIDs(degrees_ptr, - n_patches_per_dimension.data(), - n_para_dims); + splines::helpers::ExtractBezierPatchIDs(degrees_ptr, + n_patches_per_dimension.data(), + n_para_dims); const std::size_t n_patches = list_of_ids.size(); const std::size_t n_ctps_per_patch = list_of_ids[0].size(); py::array_t bezier_ctps_ids(n_ctps_per_patch * n_patches); diff --git a/cpp/splinepy/splines/bspline.hpp b/cpp/splinepy/splines/bspline.hpp index 4fce1f443..e04c744db 100644 --- a/cpp/splinepy/splines/bspline.hpp +++ b/cpp/splinepy/splines/bspline.hpp @@ -3,14 +3,14 @@ // SplineLib #include -#include -#include -#include -#include -#include -#include -#include -#include +#include "splinepy/explicit/splinelib/b_spline_extern.hpp" +#include "splinepy/proximity/proximity.hpp" +#include "splinepy/splines/helpers/basis_functions.hpp" +#include "splinepy/splines/helpers/extract.hpp" +#include "splinepy/splines/helpers/extract_bezier_patches.hpp" +#include "splinepy/splines/helpers/properties.hpp" +#include "splinepy/splines/helpers/scalar_type_wrapper.hpp" +#include "splinepy/splines/splinepy_base.hpp" namespace splinepy::splines { diff --git a/cpp/splinepy/splines/helpers/extract_bezier_patches.hpp b/cpp/splinepy/splines/helpers/extract_bezier_patches.hpp index bf4774ce5..2112586b4 100644 --- a/cpp/splinepy/splines/helpers/extract_bezier_patches.hpp +++ b/cpp/splinepy/splines/helpers/extract_bezier_patches.hpp @@ -1,11 +1,82 @@ #pragma once -#include -#include -#include +#include +#include + +#include "splinepy/splines/bezier.hpp" +#include "splinepy/splines/rational_bezier.hpp" +#include "splinepy/splines/splinepy_base.hpp" namespace splinepy::splines::helpers { +template +std::vector> +ExtractBezierPatchIDs(const IndexingType* degrees, + const int* n_patches_per_para_dim, + const int& para_dim) { + // Check for type + static_assert(std::is_integral_v, + "Unsupported type for ExtractBezierPatchIDs"); + // Number of total patches and ctps per patch + int n_total_patches = n_patches_per_para_dim[0]; + IndexingType n_ctps_per_patch = degrees[0] + 1; + + // Offsets for start values of individual patches + std::vector bezier_index_offsets{}; + bezier_index_offsets.reserve(para_dim); + bezier_index_offsets.push_back(1); + for (int i_para_dim{1}; i_para_dim < para_dim; i_para_dim++) { + n_total_patches *= n_patches_per_para_dim[i_para_dim]; + n_ctps_per_patch *= degrees[i_para_dim] + 1; + bezier_index_offsets.push_back(bezier_index_offsets[i_para_dim - 1] + * (degrees[i_para_dim - 1] + 1)); + } + + // Init return values + std::vector> list_of_id_lists(n_total_patches); + for (int i_patch{}; i_patch < n_total_patches; i_patch++) { + // Determine internal postitions in local coord system + std::vector patch_ctp_id_offsets{}; + patch_ctp_id_offsets.reserve(para_dim); + int ii{i_patch}; + // Determine the parameter wise ids of the patch (i.e. the + // patch-coordinates) and calculate the required index offsets + for (int i{}; i < para_dim; i++) { + // ID in spline coordinate system of current patch + const int patch_coord = static_cast(ii % n_patches_per_para_dim[i]); + ii -= patch_coord; + ii /= n_patches_per_para_dim[i]; + // Coordinate offset of the control points indices + patch_ctp_id_offsets.push_back(patch_coord * degrees[i]); + } + + // Init vectors required for initialization + std::vector& ids = list_of_id_lists[i_patch]; + ids.reserve(n_ctps_per_patch); + + // Extract relevant coordinates + for (int i_local_id{}; i_local_id < static_cast(n_ctps_per_patch); + i_local_id++) { + int global_id{}; + int n_ctps_in_previous_layers{1}; + // Determine index of local point in global spline + for (int i_para_dim{}; i_para_dim < para_dim; i_para_dim++) { + // First id in local system + const int local_id = (i_local_id / bezier_index_offsets[i_para_dim]) + % (degrees[i_para_dim] + 1); + // Add patch offsets + global_id += (local_id + patch_ctp_id_offsets[i_para_dim]) + * n_ctps_in_previous_layers; + // Multiply to index offset + n_ctps_in_previous_layers *= + n_patches_per_para_dim[i_para_dim] * degrees[i_para_dim] + 1; + } + ids.push_back(global_id); + } + } + return list_of_id_lists; +} + /// extract patches and returns SplinepyBase. /// located in a separate file to avoid cirular dependency template @@ -30,14 +101,6 @@ auto ExtractBezierPatches(SplineType& input) { degrees[i_p] = static_cast( input.GetParameterSpace().GetDegrees()[i_p].Get()); } - std::array bezier_index_offsets{}; - bezier_index_offsets[0] = 1; - std::size_t n_ctps_per_patch = degrees[0] + 1; - for (std::size_t i{1}; i < para_dim; i++) { - bezier_index_offsets[i] = - bezier_index_offsets[i - 1] * (degrees[i - 1] + 1); - n_ctps_per_patch *= degrees[i] + 1; - } std::array n_patches_per_para_dim{}; std::array n_ctps_per_para_dim{}; @@ -60,12 +123,24 @@ auto ExtractBezierPatches(SplineType& input) { input.InsertKnot(splinelib::Dimension{i_p_dim}, knot_vector_ref[i_knot]); } } + // Auxiliary function + const auto& ControlPointVector = [&](const int& id) { + if constexpr (is_rational) { + return input.GetWeightedVectorSpace()[splinelib::Index{id}]; + } else { + return input.GetVectorSpace()[splinelib::Index{id}]; + } + }; + + // Retrieve id information + const std::vector>& ids = + ExtractBezierPatchIDs(degrees.data(), + n_patches_per_para_dim.data(), + para_dim); // Number of total patches - int n_total_patches = n_patches_per_para_dim[0]; - for (std::size_t i_para_dim{1}; i_para_dim < para_dim; i_para_dim++) { - n_total_patches *= n_patches_per_para_dim[i_para_dim]; - } + const int n_total_patches = ids.size(); + const int n_ctps_per_patch = ids[0].size(); // Init return value std::vector> bezier_list{}; @@ -73,19 +148,6 @@ auto ExtractBezierPatches(SplineType& input) { // Loop over the individual patches for (int i_patch{}; i_patch < n_total_patches; i_patch++) { - // Determine internal postitions in local coord system - std::array patch_ctp_id_offsets{}; - int ii{i_patch}; - // Determine the parameter wise ids of the patch (i.e. the - // patch-coordinates) and calculate the required index offsets - for (int i{}; i < para_dim; i++) { - // ID in spline coordinate system of current patch - const int patch_coord = static_cast(ii % n_patches_per_para_dim[i]); - ii -= patch_coord; - ii /= n_patches_per_para_dim[i]; - // Coordinate offset of the control points indices - patch_ctp_id_offsets[i] = patch_coord * degrees[i]; - } // Init vectors required for initialization std::vector ctps; @@ -94,33 +156,11 @@ auto ExtractBezierPatches(SplineType& input) { if constexpr (is_rational) { weights.reserve(n_ctps_per_patch); } + const auto& local_ids = ids[i_patch]; // Extract relevant coordinates - for (std::size_t i_local_id{}; i_local_id < n_ctps_per_patch; - i_local_id++) { - int global_id{}; - int n_ctps_in_previous_layers{1}; - // Determine index of local point in global spline - for (std::size_t i_para_dim{}; i_para_dim < para_dim; i_para_dim++) { - // First id in local system - const int local_id = (i_local_id / bezier_index_offsets[i_para_dim]) - % (degrees[i_para_dim] + 1); - // Add patch offsets - global_id += (local_id + patch_ctp_id_offsets[i_para_dim]) - * n_ctps_in_previous_layers; - // Multiply to index offset - n_ctps_in_previous_layers *= n_ctps_per_para_dim[i_para_dim]; - } - - // Alias to facilitate access to control points - const auto& ControlPointVector = [&](const int& id) { - if constexpr (is_rational) { - return input.GetWeightedVectorSpace()[splinelib::Index{id}]; - } else { - return input.GetVectorSpace()[splinelib::Index{id}]; - } - }; - + for (int i_local_id{}; i_local_id < n_ctps_per_patch; i_local_id++) { + const std::size_t global_id = local_ids[i_local_id]; // Retrieve Control Point PointType point{}; // Check if scalar (double instead of array) @@ -141,6 +181,7 @@ auto ExtractBezierPatches(SplineType& input) { } ctps.push_back(point); } + // Create Spline and add it to list if constexpr (is_rational) { bezier_list.push_back(std::make_shared(