Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds untrimmed NURBS patches to primal #1470

Merged
merged 28 commits into from
Dec 6, 2024
Merged

Conversation

jcs15c
Copy link
Contributor

@jcs15c jcs15c commented Nov 12, 2024

Summary

  • This PR is a feature
  • It adds a NURBSPatch class to primal. NURBSPatch has the following features, along with relevant tests:
    • Construictors from arrays of points (optionally weights) and either the degree or knot vector
    • Evaluation/Derivative methods
    • Knot insertion
    • Patch subdivision/Bezier extraction
  • It also enhances the Bezier extraction method of NURBSCurve to be more efficient, performing the knot insertion in place to avoid repeated calculations.
    • An extra test has been added to primal_nurbs_curve.cpp to test a currently unchecked edge case.
  • Minor bug-fixes in NURBSCurve and KnotVector

Additional Changes

  • Rework the KnotVector and NURBSCurve classes to be more tolerant of parameters slightly outside the range of the knots.

@jcs15c jcs15c added enhancement New feature or request Primal Issues related to Axom's 'primal component labels Nov 12, 2024
@jcs15c jcs15c requested a review from kennyweiss November 12, 2024 18:51
@jcs15c jcs15c self-assigned this Nov 12, 2024
@jcs15c jcs15c marked this pull request as ready for review November 12, 2024 20:55
Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @jcs15c for this great new feature w/ comprehensive tests!

Comment on lines +1735 to +1737
evaluateFirstDerivatives(u, v, eval, Du, Dv);

return VectorType::cross_product(Du, Dv);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there cases where the derivative is not defined, e.g. near cusps? If so, what will the normal be?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible that one or both derivatives are zero, in which case the normal would be zero too. That doesn't mean that the surface itself doesn't have a normal there (like for a corner of a degenerate triangular patch), but the normal with respect to this parameterization is zero. Accounting for all the relevant edge cases is tricky, and I haven't worked out a consistent system for that yet.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to add a note? Or perhaps later when the edge cases are more worked out?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Couldn't hurt to add a comment here, although it isn't like returning a zero vector is itself incorrect. For a simple cusp on a 2D curve, the tangent vector at the point of the cusp really is just continuously zero, and although I have less intuition for the 3D case, I'm fairly sure that's the case there too. Even though the direction of the tangent/normal vector changes depending on the direction of approach, the magnitude goes to zero regardless. In my experience, the more pressing issue is when you need to take a unit normal vector at a point like that, since that genuinely is always going to be discontinuous at the cusp. This is a bit troublesome with the current primal::Vector implementation, which returns something like (1,0,0) by default if the norm is zero.

As an example of how I've dealt with these geometric/unit vectors before, the 2D winding number classes need to know tangent vectors at endpoints, and in those cases I manually iterated over control points until I found a pair that correctly defined a geometric tangent vector. That doesn't strictly help with the cusp case, but in 2D you could imagine splitting the curve at the point of discontinuity and handling each half that way.

Copy link
Member

@kennyweiss kennyweiss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the updates!

Copy link
Contributor

@bmhan12 bmhan12 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

One thing missing is NURBSPatch.hpp should be added to the list of headers in primal/CMakeLists.txt

@jcs15c
Copy link
Contributor Author

jcs15c commented Dec 6, 2024

I made a few extra changes to the KnotVector class and the NURBS objects to make them more tolerant of input parameter values that are slightly outside of the range of the knot values, which happens surprisingly often with floating point arithmetic. These checks for "slightly outside the range" are handled by the KnotVector::isValidParameter method, which is the only place where the exact value of this numerical tolerance is kept.

In the future, it might be desirable to give NURBS curves and surfaces the ability to extrapolate beyond their knot spans slightly, as is naturally the case for the analogous Bezier objects, but that's a comparatively computationally expensive procedure compared to simple clamping to handle floating point errors. This is also why I don't think it's necessary to expose this tolerance parameter to a user, and to some extent, I prefer the idea of all instances of these objects using the same tolerance level.

@kennyweiss What do you think of this as a solution?

@kennyweiss
Copy link
Member

I made a few extra changes to the KnotVector class and the NURBS objects to make them more tolerant of input parameter

@kennyweiss What do you think of this as a solution?

Thanks @jcs15c -- I think this is a reasonable and sufficient solution for now. If we need to extrapolate at parametric points near the boundary in the future, it should be easy to add that capability (at the expense of some additional computational work, as you mentioned).

@jcs15c jcs15c merged commit 56c8787 into develop Dec 6, 2024
13 checks passed
@jcs15c jcs15c deleted the feature/spainhour/nurbs_patches branch December 6, 2024 23:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request Primal Issues related to Axom's 'primal component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants