-
Notifications
You must be signed in to change notification settings - Fork 233
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
Surface from Net of Curves Node (Gordon Surface) #4183
Conversation
@rendetto initial implementation of "NURBS Surface from Curves Net" node is more or less ready. It still lacks documentation, and there may be some tunings... but you may already try it from this branch. |
The following is the most trivial approach to removing this restriction. Given a curve and a set of T-values at which it has intersections with other curves from the net, reparametrize the curve so that intersection points will be located evenly in curve's parameter space. """
in curve_in C
out curve_out C
"""
from sverchok.data_structure import zip_long_repeat, ensure_nesting_level
from sverchok.utils.curve import SvCurve
from sverchok.utils.curve.nurbs import SvNurbsCurve
def process(curve):
t_values = [0.2, 0.3, 0.7, 0.8]
t_min, t_max = curve.get_u_bounds()
t_values = [t_min] + t_values + [t_max]
segments = []
for t1, t2 in zip(t_values, t_values[1:]):
segment = curve.cut_segment(t1, t2, rescale=True)
segments.append(segment)
result = segments[0]
for segment in segments[1:]:
result = result.concatenate(segment)
return result
curve_out = []
for curve in curve_in:
c = process(curve)
curve_out.append(c) note: this approach creates a number of additional control points. |
Great work! I did a simple test - 4x4 straight Bezier curves - forming a simple 4x4 grid. Found a funny thing - when I use SciPy for calculating intersections the resulting Gordon have 9x9 control vertices and the U and V knot vectors are (0, 0, 0, 0, 0.5, 0.5, 0.5, 1, 1, 1, 1). |
Well, as here you're using FreeCad implementation, there is nothing I can do. FreeCad's For original Gordon algorithm, it is required, that intersections are located "evenly" in curve's parameter spaces. I.e. one U-curve intersects all V-curves at the same T parameters of those V-curves. If this restriction is not met exactly, then the generated surface will be only "approximately" Gordon surface. I've just pushed updates to "Intersect curves" and "gordon surface" nodes: Intersection node outputs T values of intersection points, and Gordon node can consume them. If you provide these T values of intersections, Gordon node will automatically reparametrize curves so that in new parametric space intersection would occur "evenly". This reparametrization algorithm is somewhat rude, so it can produce unwanted additional control points, or create "bad" parametrization of resulting surface. But it works for my example :)
|
Does "evenly" means like placing 5 sections exactly at (0.0, 0.25, 0.5 ,0.75 1.0) if the paths are defined in (0.0, 1.0)? |
Woh, interesting. Please post console output here. |
Can you share blend file? |
adapted from Geomdl.
I tested the Explicit T values on my test file. Now the surface goes through the sections really well, but there is brake in the internal continuity. I used the "zebra" matcap to illustrate the effect. Maybe there is no way to interpolate the sections so perfect and in the same time to maintain the initial degree and control points structure of the source curves. Nevertheless I like the initial result being really tight on the contour curves and in the same time identical to the source curves structure and degree. In many cases that's more important than interpolating exactly through the sections. I wanted to compare this particular setup as being identical to the Birail case. Mainly because I have it set with the Birail node where I get somewhat better (but again not exact) interpolation of the sections. The curious thing with the Birail node is that the best result is achieved using exactly 5 VSections(an equal number to the source curves in V direction) as control parameter and everything above created somewhat bigger deviation (but better parametrization regarding the initial placement of the sections). |
AFAIK there is a way, but it's too complicated for me to implement in nearest future :) |
Wow, it will be great if you implement it at some point in time. One method I know of is implemented in the TiGL library and also adapted for python in CurvesWB in FreeCAD - but it's a reparametrization method and also produces lots of control points. It's smooth but sometimes the resulting surface can get really wavy. |
As far as I understand, it is possible to do reparametrization as follows:
I did not dig into TiGL / FreeCAD implementation, but I suspect that they use the same general approach. It looks simple when described in general words, but it involves quite significant amounts of mathematics :) The good thing about this approach is that it uses smooth interpolation. My current approach, in turn, is much simpler, but it uses picewise-linear interpolation:
|
Thanks a lot. I'll do a search on those topics. As for TiGL, this is the paper I know of https://arxiv.org/pdf/1810.10795.pdf . Hope you can find it useful in some way. |
Interesting. It uses the following approach:
So yes, this is smooth reparametrization, i.e. it preserves curvature continuity; but the resulting surface follows given curves only approximately, while passing exactly through intersection points. Though I think approximation precision should be adjustable, so by some setting you should be able to have a "precise enough" surface. |
The control it gives is by ramping up some precision tolerance value and a target maximum of control points (which could be not the best approach since you can never get exactly what you want). The "precise enough" result can work in certain cases, but when the goal is high precision/quality surface modelling it hits its limits because of the oscillation and the unpredictable control vertices structure/degree/knot vector. Also it could be a real disaster, but that I guess is a matter of source curves distribution. |
By the way, I'm not sure at this scale, but it looks like you have curve intersection point very near of "even" T parameter value. Due to cut-and-join approach I described above, this leads to two rows of control points very near one another. |
It's not just near - the sections touch the paths precisely at the provided T values. I was assuming that this is the way to construct the curve net. But there are no coincident control points at the left part where the zebra is zig-zag-ing. I guess the continuity break comes from the knot multiplicity there. If you increase the Mesh Viewer density this break becomes even clearer. |
I investigated this issue for a while. It seems, with current implementation of reparametrization, it is not possible to automatically have smooth continuity every time. In some cases it is possible to achieve good results by "manually" removing excessive knots. In current state of this branch, you can pass result of Gordon node through Formula node with the following formula: |
refs #3603
Given a net of intersecting curves, this node generates a surface which passes
through all given curves.
A net of curves is two sets of curves, one set along one direction and one set
along another. One set of curves is called "U-curves" (curves along U
direction) and another set of curves is called "V-curves" (curves along V
direction).
Apart of curves grid, this node requires intersection points of curves provided
explictly. Intersection points can be calculated by use of "Intersect NURBS
curves" node. Note: that node uses numeric algorithms to calculate
intersections, so it can fail to find intersections, or give imprecise results.
So, if you have intersection points in advance, it's better to use them.
This node generates a NURBS surface from NURBS curves according to algorithm
known as "Gordon Surface".
Gordon surface algorithm has a number of restrictions:
N x M
points.C_v
must intersect all U-curvesC_u
at the same value of U parameter.C_u1
intersects V-curveC_v
atv = v1
, and another U-curveC_u2
intersects the same V-curveC_v
atv = v2
, andv1 < v2
, then in input curves list,C_u1
must be provided beforeC_u2
.One relatively easy way to build a correct curves net is to draw a number of Bezier curves, which intersect exactly at their node points.
Planned developments:
Preflight checklist
Put an x letter in each brackets when you're done this item: