Skip to content

Commit

Permalink
Slight changes - deleted helpers
Browse files Browse the repository at this point in the history
  • Loading branch information
jzwar committed Jun 26, 2023
1 parent 010545e commit 0553c31
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 65 deletions.
8 changes: 4 additions & 4 deletions cpp/splinepy/py/py_knot_insertion_matrix.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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<int> bezier_ctps_ids(n_ctps_per_patch * n_patches);
Expand Down
16 changes: 8 additions & 8 deletions cpp/splinepy/splines/bspline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
// SplineLib
#include <Sources/Splines/b_spline.hpp>

#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>
#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 {

Expand Down
147 changes: 94 additions & 53 deletions cpp/splinepy/splines/helpers/extract_bezier_patches.hpp
Original file line number Diff line number Diff line change
@@ -1,11 +1,82 @@
#pragma once

#include <splinepy/splines/bezier.hpp>
#include <splinepy/splines/rational_bezier.hpp>
#include <splinepy/splines/splinepy_base.hpp>
#include <array>
#include <type_traits>

#include "splinepy/splines/bezier.hpp"
#include "splinepy/splines/rational_bezier.hpp"
#include "splinepy/splines/splinepy_base.hpp"

namespace splinepy::splines::helpers {

template<typename IndexingType>
std::vector<std::vector<int>>
ExtractBezierPatchIDs(const IndexingType* degrees,
const int* n_patches_per_para_dim,
const int& para_dim) {
// Check for type
static_assert(std::is_integral_v<IndexingType>,
"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<std::size_t> 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<std::vector<int>> 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<std::size_t> 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<int>(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<int>& 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<int>(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<bool as_base = false, typename SplineType>
Expand All @@ -30,14 +101,6 @@ auto ExtractBezierPatches(SplineType& input) {
degrees[i_p] = static_cast<std::size_t>(
input.GetParameterSpace().GetDegrees()[i_p].Get());
}
std::array<std::size_t, para_dim> 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<int, para_dim> n_patches_per_para_dim{};
std::array<int, para_dim> n_ctps_per_para_dim{};

Expand All @@ -60,32 +123,31 @@ 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<std::vector<int>>& 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<std::shared_ptr<ReturnVectorValueType>> bezier_list{};
bezier_list.reserve(n_total_patches);

// 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<std::size_t, para_dim> 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<int>(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<PointType> ctps;
Expand All @@ -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)
Expand All @@ -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<ReturnType>(
Expand Down

0 comments on commit 0553c31

Please sign in to comment.