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

Surface from Net of Curves Node (Gordon Surface) #4183

Merged
merged 39 commits into from
Jul 4, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
8e449b1
Preparations for Gordon nurbs surfaces.
portnov Jun 24, 2021
c30432b
Minor tunings.
portnov Jun 24, 2021
a72c02d
Experiments.
portnov Jun 25, 2021
3fac45f
On degree elevation.
portnov Jun 25, 2021
263db21
Tunes.
portnov Jun 25, 2021
058665d
Some debug.
portnov Jun 26, 2021
688f49f
Some api for Bezier curves.
portnov Jun 26, 2021
e27a635
On curves intersection.
portnov Jun 27, 2021
92ced42
Initial implementation of "Intersect NURBS curves" node.
portnov Jun 27, 2021
164dc65
Tuning.
portnov Jun 27, 2021
138d7de
Initial implementation of Gordon Surface node.
portnov Jun 27, 2021
8bba576
icon.
portnov Jun 27, 2021
6783d39
Native implementation for "Interpolate nurbs surface" node.
portnov Jun 27, 2021
42977e8
Update documentation.
portnov Jun 27, 2021
b5c7a40
"Intersect curves" documentation.
portnov Jun 27, 2021
e4a9d3b
Simple reparametrization option.
portnov Jun 28, 2021
c89b7f3
Fixes.
portnov Jun 28, 2021
73cd215
Knotvector accuracy parameter.
portnov Jun 29, 2021
2dda048
Add a check.
portnov Jun 29, 2021
a69bd07
Add checks.
portnov Jun 29, 2021
4140e33
Fix in "intersect curves".
portnov Jun 29, 2021
e4eb738
Start "Gordon surface" documentation.
portnov Jun 29, 2021
d6c19d2
Icon.
portnov Jun 29, 2021
b898c9f
Update documentation.
portnov Jun 29, 2021
e164612
First implementation of knot removal.
portnov Jun 29, 2021
7129742
Some checks.
portnov Jun 29, 2021
e7a8a69
On knots precision.
portnov Jul 1, 2021
c556821
Knotvector insert / remove testing.
portnov Jul 2, 2021
e30503b
Minor api change.
portnov Jul 2, 2021
ccce1b2
Minor changes.
portnov Jul 2, 2021
c7d9145
skip failing test for now.
portnov Jul 2, 2021
aae102a
Change according to https://github.com/orbingol/NURBS-Python/issues/135
portnov Jul 3, 2021
4c5ae00
Fix tests.
portnov Jul 4, 2021
107b9bf
Remove debug prints.
portnov Jul 4, 2021
d7a9269
Skip a test for now.
portnov Jul 4, 2021
ff97788
Add examples to the documentation.
portnov Jul 4, 2021
c4b16a9
Add a note.
portnov Jul 4, 2021
cc9c1d7
Logging.
portnov Jul 4, 2021
6e4ec18
Some code documentation.
portnov Jul 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ Paramters

This node has the following paramters:

* **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