Skip to content

Commit

Permalink
Merge pull request #4183 from nortikin/gordon_nurbs
Browse files Browse the repository at this point in the history
Surface from Net of Curves Node (Gordon Surface)
  • Loading branch information
portnov authored Jul 4, 2021
2 parents 165a9bf + 6e4ec18 commit 95102d4
Show file tree
Hide file tree
Showing 24 changed files with 2,332 additions and 245 deletions.
1 change: 1 addition & 0 deletions docs/nodes/curve/curve_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ Curves
catenary_curve
bezier_fit
circlify
intersect_curves
intersect_curve_plane
extremes
interpolate_frame
Expand Down
97 changes: 97 additions & 0 deletions docs/nodes/curve/intersect_curves.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
Intersect NURBS Curves
======================

Dependencies
------------

This node requires either SciPy_ library, or FreeCAD_ libraries to work.

.. _SciPy: https://scipy.org/
.. _FreeCAD: https://www.freecadweb.org/

Functionality
-------------

This node tries to find all intersections of provided Curve objects. This node
can work only with NURBS or NURBS-like curves.

Inputs
------

This node has the following inputs:

* **Curve1**. The first curve. This input is mandatory.
* **Curve2**. The second curve. This input is mandatory.

Parameters
----------

This node has the following parameters:

* **Implementation**. Implementation of numeric algorithm to be used. The
available options are:

* **FreeCAD**. Use implementation from FreeCAD_ library. This option is
available when FreeCAD library is installed.
* **SciPy**. Use implementation based on SciPy_ library. This option is
available when SciPy library is installed.

In general, FreeCAD implementation is considered to be faster, more precise,
and better tested. However, it does not allow one to control intersection
tolerances, while SciPy implementation does.

By default, the first available implementation is used.

* **Matching**. This defines how lists of input curves are matched. The
available options are:

* **Longest**. The node will use input lists in parallel: first curve from
the first list with first curve from the second list, then second curve
from first list with second curve from the second list, and so on. In case
two lists have different lengths, in the shortest one, the last curve will
be repeated as many times as required to match lengths.

* **Cross**. The node will use input lists in "each-to-each" mode: first
curve from first list with each curve from the second list, then second
curve from first list with each curve from the second list, and so on.

The default option is **Longest**.

* **Find single intersection**. If checked, the node will search only one
intersection for each pair of input curves. Otherwise, it will search for all
intersections. Checked by default.
* **Curves do intersect**. If checked, then the node will fail if two curves do
not intersect. Otherwise, it will just output empty list of intersections.
Unchecked by default.
* **Split by row**. This parameter is available only when **Matching**
parameter is set to **Cross**. If checked, the node will output a separate
list of intersections for each curve from the first list. Otherwise, the node
will output a single flat list with all intersections of each curve with
each. Checked by default.
* **Precision**. This parameter is available in the N panel only, and only when
**Implementation** parameter is set to **SciPy**. This defines the allowed
tolerance of numeric method - the maximum allowed distance between curves,
which is considered as intersection. The default value is 0.001.
* **Numeric method**. This parameter is available in the N panel only, and only when
**Implementation** parameter is set to **SciPy**. This defines numeric method
to be used. The available options are: Nelder-Mead, L-BFGS-B, SLSQP, Powell,
Trust-Cosntr.

Outputs
-------

This node has the following output:

* **Intersections**. The list of intersection points.

Example of Usage
----------------

Find three intersections of two curves:

.. image:: https://user-images.githubusercontent.com/284644/123548323-c3281580-d77d-11eb-83fb-8216aad82d0f.png

Find twelve intersections of two series of curves:

.. image:: https://user-images.githubusercontent.com/284644/123548414-24e87f80-d77e-11eb-86aa-348b6c7c0322.png

131 changes: 131 additions & 0 deletions docs/nodes/surface/gordon_surface.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
NURBS Surface from Curves Net
=============================

Functionaltiy
-------------

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:

* All input curves must be NURBS or NURBS-like. More specifically, only
non-rational curves are supported - i.e., without weights (or all weights
equal).
* All U-curves must have "the same" direction; all V-curves must also have "the
same" direction.
* There must be N curves along one direction, and M curves along another
direction, which must exactly intersect at `N x M` points.
* Intersection points must be located evenly in parameter spaces of curves. For
example, V-Curve `C_v` must intersect all U-curves `C_u` at the same value of
U parameter. In other words, intersection points must be located so that
given curves would represent iso-curves of some surface, along U and V
directions correspondingly.
* U-curves must be ordered along direction of V-curves, and vice versa. For
example, if U-curve `C_u1` intersects V-curve `C_v` at `v = v1`, and another
U-curve C_u2 intersects the same V-curve `C_v` at `v = v2`, and `v1 < v2`,
then in input curves list, `C_u1` must be provided before `C_u2`.

If some of these requirements are not met exactly, then the resulting surface
will pass through the curves only approximately.

If intersections of your curves are located arbitrarily in parameter spaces of
curves, the node can try to reparametrize curves in order to make intersections
located "even" in parameter spaces. Note that reparametrization algorithm is
somewhat rude, so it can produce unwanted additional control points, and/or
create "bad" parametrization of resulting surface. In some cases, it is
possible to get a better parametrization by manually removing excessive knots.

To clear the issue of intersections location in parameter space, let's draw some pictures.

Good parametrization: (first number is parameter of U-curve at the intersection
point, the second number is parameter of V-curve at the intersection point):

.. image:: https://user-images.githubusercontent.com/284644/123667069-394a7c00-d853-11eb-86dd-4b7b79bbb827.png

Note that when you move from left to right, U value is changing by the same
amount at all U-curves. And when you move from bottom to top, V-value is
changing by the same amount at all V-curves.

"Bad" parametrization:

.. image:: https://user-images.githubusercontent.com/284644/123667108-44051100-d853-11eb-9f68-52529b2278d8.png

Inputs
------

This node has the following inputs:

* **CurvesU**. Set of curves along U direction. This input is mandatory. At
least two U-curves is required to build a proper surface.
* **CurvesV**. Set of curves along V direction. This input is mandatory. At
least two V-curves is required to build a proper surface.
* **T1**. This input is available and mandatory when **Explicit T values**
parameter is checked. For each U-curve, this input should contain a list of T
parameter values, at which this curve intersects V-curves.
* **T2**. This input is available and mandatory when **Explicit T values**
parameter is checked. For each V-curve, this input should contain a list of T
parameter values, at which this curve intersects U-curves.
* **Intersections**. Intersection points of curves. For each U-curve, this
input must contain a list of points (in 3D space), where this curve
intersects V-curves. This input is mandatory.

Parameters
----------

This node has the following parameters:

* **Explicit T values**. If checked, the node expects the user to provide T
parameter values of curve intersections in **T1** and **T2** inputs. In this
case, the node will try to automatically reparametrize input curves in order
to make intersection points located "evenly" in curve's parameter space (see
illustrations above). If not checked, the node will calculate T values of
intersections according to **Metric** parameter. Unchecked by default.
* **Metric**. This node is available in the N panel only, and only when
**Explicit T values** parameter is not checked. This defines the metric,
which the node should use to calculate T values of curve intersections, when
they are not provided by user. The available options are:

* Manhattan
* Euclidian
* Points (just number of points from the beginning)
* Chebyshev
* Centripetal (square root of Euclidian distance).

The default option is Points. In most cases, this option gives the best results.
* **Knotvector accuracy**. This parameter is available in the N panel only.
Number of decimal digits (after decimal point), to which the node should
round values in resulting surface's knot vectors. More decimal digits will
give more exact results, but can produce a number of knots / control points
located very close to each other, most of them being just an artefact of
floating-point precision issues. The default value is 4.

Outputs
-------

This node has the following output:

* **Surface**. The resulting NURBS surface.

Examples of usage
-----------------

.. image:: https://user-images.githubusercontent.com/284644/123552408-71888680-d78f-11eb-92b7-904edc5a53bb.png

.. image:: https://user-images.githubusercontent.com/284644/124376217-4e923100-dcbf-11eb-8a50-4c4f2e21442f.png

There are some other examples at github's PR page: https://github.com/nortikin/sverchok/pull/4183
32 changes: 29 additions & 3 deletions docs/nodes/surface/interpolate_nurbs_surface.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ Interpolate NURBS Surface
Dependencies
------------

This node requires Geomdl_ library to work.
This node can optionally use Geomdl_ library to work.

.. _Geomdl: https://onurraufbingol.com/NURBS-Python/

Expand Down Expand Up @@ -45,8 +45,34 @@ Parameters

This node has the following parameters:

* **Centripetal**. This defines whether the node will use centripetal
interpolation method. Unchecked by default.
* **Implementation**. This defines the implementation of NURBS mathematics to
be used. The available options are:

* **Geomdl**. Use Geomdl_ library. This option is available only when Geomdl
package is installed.
* **Sverchok**. Use built-in Sverchok implementation.

In general (with large nuber of control points), built-in implementation
should be faster; but Geomdl implementation is better tested.
The default option is **Geomdl**, when it is available; otherwise, built-in
implementation is used.

* **Centripetal**. This parameter is only available when **Implementation**
parameter is set to **Geomdl**. Defines whether the node will use
centripetal interpolation method. Unchecked by default.
* **Metric**. This parameter is available only when **Implementation**
parameter is set to **Sverchok**. This defines the metric used to calculate
surface's U, V parameter values corresponding to specified points. The
available values are:

* Manhattan
* Euclidian
* Points (just number of points from the beginning)
* Chebyshev
* Centripetal (square root of Euclidian distance).

The default value is Euclidian.

* **Input mode**. The available values are:

* **Single list**. The node expects a flat list of points for each surface.
Expand Down
1 change: 1 addition & 0 deletions docs/nodes/surface/surface_index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Surface
nurbs_loft
nurbs_sweep
nurbs_birail
gordon_surface
intersect_curve_surface
nearest_point
ortho_project
Expand Down
2 changes: 2 additions & 0 deletions index.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
SvReparametrizeCurveNode
SvExSurfaceBoundaryNode
---
SvIntersectNurbsCurvesNode
SvExNearestPointOnCurveNode
SvExOrthoProjectCurveNode
SvExCurveEndpointsNode
Expand Down Expand Up @@ -132,6 +133,7 @@
SvNurbsLoftNode
SvNurbsSweepNode
SvNurbsBirailNode
SvGordonSurfaceNode
SvDeconstructSurfaceNode
---
SvExQuadsToNurbsNode
Expand Down
Loading

0 comments on commit 95102d4

Please sign in to comment.