Fix: Prevent NURBS .obj importer from setting invalid degree/order
Default behavior in most edit mode operators is to adjust the order if there is not enough points/knots to support it. If the degree is incorrectly encoded in the file, import should update it to avoid generating an invalid NURBS curve. Pull Request: https://projects.blender.org/blender/blender/pulls/138374
This commit is contained in:
committed by
Hans Goudey
parent
fbb659c4c5
commit
87d04eadd4
@@ -73,10 +73,18 @@ Object *CurveFromGeometry::create_curve_object(Main *bmain, const OBJImportParam
|
||||
return obj;
|
||||
}
|
||||
|
||||
static int8_t get_valid_nurbs_degree(const NurbsElement &element)
|
||||
{
|
||||
/* Use max(1, min()) to avoid undefined clamp behavior when curve_indices.size() == 0 */
|
||||
const int degree = std::max(1, std::min<int>(element.degree, element.curv_indices.size() - 1));
|
||||
return degree + 1 > std::numeric_limits<int8_t>::max() ? std::numeric_limits<int8_t>::max() - 1 :
|
||||
int8_t(degree);
|
||||
}
|
||||
|
||||
void CurveFromGeometry::create_nurbs(Curve *curve, const OBJImportParams &import_params)
|
||||
{
|
||||
const NurbsElement &nurbs_geometry = curve_geometry_.nurbs_element_;
|
||||
const int degree = nurbs_geometry.degree;
|
||||
const int8_t degree = get_valid_nurbs_degree(nurbs_geometry);
|
||||
Nurb *nurb = static_cast<Nurb *>(curve->nurb.first);
|
||||
|
||||
nurb->type = CU_NURBS;
|
||||
@@ -87,8 +95,7 @@ void CurveFromGeometry::create_nurbs(Curve *curve, const OBJImportParams &import
|
||||
nurb->pntsu = 0;
|
||||
/* Total points = pntsu * pntsv. */
|
||||
nurb->pntsv = 1;
|
||||
nurb->orderu = nurb->orderv = (nurbs_geometry.degree + 1 > SHRT_MAX) ? 4 :
|
||||
nurbs_geometry.degree + 1;
|
||||
nurb->orderu = nurb->orderv = degree + 1;
|
||||
nurb->resolu = nurb->resolv = curve->resolu;
|
||||
|
||||
nurb->flagu = this->detect_knot_mode(import_params,
|
||||
@@ -136,7 +143,7 @@ void CurveFromGeometry::create_nurbs(Curve *curve, const OBJImportParams &import
|
||||
}
|
||||
|
||||
short CurveFromGeometry::detect_knot_mode(const OBJImportParams &import_params,
|
||||
const int degree,
|
||||
const int8_t degree,
|
||||
const Span<int> indices,
|
||||
const Span<float> knots,
|
||||
const float2 range)
|
||||
@@ -170,7 +177,7 @@ short CurveFromGeometry::detect_knot_mode(const OBJImportParams &import_params,
|
||||
* the parameters should have at least (degree+1) values on each end,
|
||||
* and their values should match curve range. */
|
||||
bool do_endpoints = false;
|
||||
int order = degree + 1;
|
||||
const int8_t order = degree + 1;
|
||||
if (knots.size() >= order * 2) {
|
||||
do_endpoints = true;
|
||||
for (int i = 0; i < order; ++i) {
|
||||
|
||||
@@ -45,7 +45,7 @@ class CurveFromGeometry : NonMovable, NonCopyable {
|
||||
void create_nurbs(Curve *curve, const OBJImportParams &import_params);
|
||||
|
||||
short detect_knot_mode(const OBJImportParams &import_params,
|
||||
int degree,
|
||||
int8_t degree,
|
||||
Span<int> indices,
|
||||
Span<float> knots,
|
||||
float2 range);
|
||||
|
||||
Reference in New Issue
Block a user