17 curve.set_control_points(control_points);
18 curve.set_knots(knots);
19 std::vector<int> unused;
20 for (
int i = 0; i <
V.rows(); ++i)
24 Eigen::MatrixXd point =
V.block(b, 0, 1,
dim);
25 auto t =
curve.approximate_inverse_evaluate(point);
26 double distance = (point -
curve.evaluate(t)).norm();
30 logger().error(
"Could not find a valid t for deducing spline parametrization. Distance: {}, point: {}, {}", distance, point(0), point(1));
38 if (unused.size() > 0)
49 logger().info(
"Number of useful boundary nodes in spline parametrization: {}",
node_ids_.size());
55 curve.set_control_points(control_points);
60 newV.block(b, 0, 1,
dim) = new_val;
66 assert(!mesh_changed);
68 bool boundary_changed =
false;
69 for (
int i = 0; i <
node_ids_.size(); ++i)
73 boundary_points.block(i, 0, 1,
dim) = new_point;
75 double difference = (old_point - new_point).norm();
76 if (difference > 1e-4)
78 boundary_changed =
true;
84 auto new_curve =
curve.fit(t_params, boundary_points,
curve.get_control_points().rows(),
curve.get_knots());
85 control_points = new_curve.get_control_points();
89 control_points =
curve.get_control_points();
95 grad_control_points.setZero(
curve.get_control_points().size());
96 nanospline::BSpline<double, 1, 3> curve_;
97 curve_.set_knots(
curve.get_knots());
99 for (
int i = 0; i <
curve.get_control_points().rows(); ++i)
101 Eigen::MatrixXd indicator = Eigen::MatrixXd::Zero(
curve.get_control_points().rows(), 1);
103 curve_.set_control_points(indicator);
107 for (
int k = 0; k <
dim; ++k)
108 grad_control_points(i *
dim + k) += grad_boundary(b *
dim + k) * basis_val;
115 nanospline::BSpline<double, 2, 3>
curve;
116 curve.set_control_points(control_points);
117 auto val =
curve.evaluate(t_parameter);
119 grad = (point -
val) / distance;
124 nanospline::BSpline<double, 2, 3>
curve;
125 curve.set_control_points(control_points);
131 nanospline::BSpline<double, 2, 3>
curve;
132 curve.set_control_points(control_points);
141 patch.set_control_grid(control_points);
142 patch.set_knots_u(knots_u);
143 patch.set_knots_v(knots_v);
145 std::vector<int> unused;
146 for (
int i = 0; i <
V.rows(); ++i)
150 Eigen::MatrixXd point =
V.block(b, 0, 1,
dim);
151 auto uv =
patch.approximate_inverse_evaluate(point, 5, 5, 0, 1, 0, 1, 30);
152 assert(uv.size() == 2);
153 double distance = (point -
patch.evaluate(uv(0), uv(1))).norm();
157 logger().error(
"Could not find a valid uv for deducing spline parametrization. Distance: {}", distance);
165 if (unused.size() > 0)
176 logger().info(
"Number of useful boundary nodes in spline parametrization: {}",
node_ids_.size());
181 assert(!mesh_changed);
183 bool boundary_changed =
false;
184 for (
int i = 0; i <
node_ids_.size(); ++i)
188 assert(uv.size() == 2);
189 auto old_point =
patch.evaluate(uv(0), uv(1));
191 boundary_points.block(i, 0, 1,
dim) = new_point;
192 uv_params.row(i) = uv;
193 double difference = (old_point - new_point).norm();
194 if (difference > 1e-4)
196 boundary_changed =
true;
199 if (boundary_changed)
202 auto new_patch =
patch.fit(uv_params, boundary_points,
patch.get_knots_u().size() - 1 - 3,
patch.get_knots_v().size() - 1 - 3,
patch.get_knots_u(),
patch.get_knots_v());
203 control_points = new_patch.get_control_grid();
207 control_points =
patch.get_control_grid();
215 patch.set_control_grid(control_points);
220 assert(uv.size() == 2);
221 auto new_val =
patch.evaluate(uv(0), uv(1));
222 newV.block(b, 0, 1,
dim) = new_val;
229 grad_control_points.setZero(
patch.get_control_grid().size());
231 for (
int i = 0; i <
patch.get_control_grid().rows(); ++i)
233 nanospline::BSplinePatch<double, 3, 3, 3> patch_;
234 patch_.set_knots_u(
patch.get_knots_u());
235 patch_.set_knots_v(
patch.get_knots_v());
236 Eigen::MatrixXd indicator = Eigen::MatrixXd::Zero(
patch.get_control_grid().rows(), 3);
237 indicator.row(i) = Eigen::VectorXd::Ones(3);
238 patch_.set_control_grid(indicator);
243 assert(uv.size() == 2);
244 auto basis_val = patch_.evaluate(uv(0), uv(1))(0);
245 for (
int k = 0; k <
dim; ++k)
246 grad_control_points(i *
dim + k) += grad_boundary(b *
dim + k) * basis_val;
251 void BSplineParametrization3D::gradient(
const Eigen::MatrixXd &point,
const Eigen::MatrixXd &control_points,
const Eigen::MatrixXd &uv_parameter,
const double distance, Eigen::MatrixXd &grad)
253 assert(uv_parameter.size() == 2);
254 nanospline::BSplinePatch<double, 3, 3, 3>
patch;
255 patch.set_control_grid(control_points);
256 auto val =
patch.evaluate(uv_parameter(0), uv_parameter(1));
258 grad = (point -
val) / distance;
263 assert(uv_parameter.size() == 2);
264 nanospline::BSplinePatch<double, 3, 3, 3>
patch;
265 patch.set_control_grid(control_points);
266 val =
patch.evaluate(uv_parameter(0), uv_parameter(1));
271 assert(uv_parameter.size() == 2);
272 nanospline::BSplinePatch<double, 3, 3, 3>
patch;
273 patch.set_control_grid(control_points);
274 deriv_u =
patch.evaluate_derivative_u(uv_parameter(0), uv_parameter(1));
275 deriv_v =
patch.evaluate_derivative_v(uv_parameter(0), uv_parameter(1));
void derivative_wrt_params(const Eigen::VectorXd &grad_boundary, Eigen::VectorXd &grad_control_points) override
BSplineParametrization2D(const Eigen::MatrixXd &control_points, const Eigen::MatrixXd &knots, const Eigen::MatrixXd &V)
void reparametrize(const Eigen::MatrixXd &control_points, Eigen::MatrixXd &newV) override
static void eval(const Eigen::MatrixXd &control_points, const double t, Eigen::MatrixXd &val)
std::vector< int > node_ids_
static void deriv(const Eigen::MatrixXd &control_points, const double t, Eigen::MatrixXd &val)
nanospline::BSpline< double, 2, 3 > curve
static void gradient(const Eigen::MatrixXd &point, const Eigen::MatrixXd &control_points, const double t_parameter, const double distance, Eigen::MatrixXd &grad)
void get_parameters(const Eigen::MatrixXd &V, Eigen::MatrixXd &control_points, const bool mesh_changed) override
std::map< int, double > node_id_to_t_
static void gradient(const Eigen::MatrixXd &point, const Eigen::MatrixXd &control_points, const Eigen::MatrixXd &uv_parameter, const double distance, Eigen::MatrixXd &grad)
static void deriv(const Eigen::MatrixXd &control_points, const Eigen::MatrixXd &uv_parameter, Eigen::MatrixXd &deriv_u, Eigen::MatrixXd &deriv_v)
std::map< int, Eigen::MatrixXd > node_id_to_param_
void get_parameters(const Eigen::MatrixXd &V, Eigen::MatrixXd &control_points, const bool mesh_changed) override
static void eval(const Eigen::MatrixXd &control_points, const Eigen::MatrixXd &uv_parameter, Eigen::MatrixXd &val)
std::vector< int > node_ids_
BSplineParametrization3D(const Eigen::MatrixXd &control_points, const Eigen::MatrixXd &knots_u, const Eigen::MatrixXd &knots_v, const Eigen::MatrixXd &V)
nanospline::BSplinePatch< double, 3, 3, 3 > patch
void derivative_wrt_params(const Eigen::VectorXd &grad_boundary, Eigen::VectorXd &grad_control_points) override
void reparametrize(const Eigen::MatrixXd &control_points, Eigen::MatrixXd &newV) override
spdlog::logger & logger()
Retrieves the current logger.
void log_and_throw_error(const std::string &msg)