Skip to content

Commit 47c0225

Browse files
authored
Merge pull request #15 from lottilotte/joined_from-fill
Join curves and surface from fill with 4 curves
2 parents 969c336 + 87ce76c commit 47c0225

File tree

10 files changed

+176
-3
lines changed

10 files changed

+176
-3
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## Unreleased
99

1010
### Added
11+
* Added `compas_occ.geometry.NurbsCurve.join`.
12+
* Added `compas_occ.geometry.NurbsCurve.joined`.
1113

1214
### Changed
15+
* Extend `compas_occ.geometry.OCCNurbsSurface.from_fill` with up to 4 input curves.
1316

1417
### Removed
1518

375 KB
Loading
373 KB
Loading
484 KB
Loading

docs/examples/curve_joining.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from compas.geometry import Point
2+
from compas.geometry import Polyline
3+
from compas_occ.geometry import OCCNurbsCurve
4+
from compas_view2.app import App
5+
6+
points1 = [Point(0, 0, 0), Point(1, 1, 0), Point(3, 0, 0)]
7+
points2 = [Point(3, 0, 0), Point(4, -2, 0), Point(5, 0, 0)]
8+
9+
curve1 = OCCNurbsCurve.from_interpolation(points1)
10+
curve2 = OCCNurbsCurve.from_interpolation(points2)
11+
12+
joined = curve1.joined(curve2)
13+
curve1.join(curve2)
14+
15+
# ==============================================================================
16+
# Visualisation
17+
# ==============================================================================
18+
19+
view = App()
20+
21+
view.add(Polyline(curve1.locus()), linewidth=3, linecolor=(1, 0, 0))
22+
view.add(Polyline(curve2.locus()), linewidth=3, linecolor=(0, 1, 0))
23+
view.add(Polyline(joined.locus()), linewidth=3, linecolor=(0, 0, 1))
24+
25+
view.run()

docs/examples/curve_joining.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
********************************************************************************
2+
Curve Joining
3+
********************************************************************************
4+
5+
.. figure:: /_images/example_curve_joining_separate.png
6+
:figclass: figure
7+
:class: figure-img img-fluid
8+
9+
.. figure:: /_images/example_curve_joining_joined.png
10+
:figclass: figure
11+
:class: figure-img img-fluid
12+
13+
.. literalinclude:: curve_joining.py
14+
:language: python

docs/examples/surface_from_fill.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
2+
from compas.geometry import NurbsCurve
3+
from compas.geometry import NurbsSurface
4+
5+
6+
from compas.geometry import Point
7+
from compas.geometry import Polyline
8+
9+
from compas_view2.app import App
10+
11+
points1 = [Point(0, -10, 0), Point(1, -8, 0), Point(-1, -6, 0), Point(0, -4, 0)]
12+
points2 = [Point(5, -10, 0), Point(4, -8, 0), Point(6, -6, 0), Point(5, -4, 0)]
13+
14+
nurbscurve1 = NurbsCurve.from_interpolation(points1)
15+
nurbscurve2 = NurbsCurve.from_interpolation(points2)
16+
17+
nurbssurface_2curves = NurbsSurface.from_fill(nurbscurve1, nurbscurve2)
18+
19+
points3 = [Point(0, 0, 0), Point(1, 2, 0), Point(-1, 4, 0), Point(0, 6, 0)]
20+
points4 = [Point(0, 6, 0), Point(3, 6, -1), Point(5, 6, 0)]
21+
points5 = [Point(5, 6, 0), Point(4, 2, 0), Point(5, 0, 0)]
22+
points6 = [Point(5, 0, 0), Point(2, -1, 1), Point(0, 0, 0)]
23+
24+
nurbscurve3 = NurbsCurve.from_interpolation(points3)
25+
nurbscurve4 = NurbsCurve.from_interpolation(points4)
26+
nurbscurve5 = NurbsCurve.from_interpolation(points5)
27+
nurbscurve6 = NurbsCurve.from_interpolation(points6)
28+
29+
nurbssurface_4curves = NurbsSurface.from_fill(nurbscurve3, nurbscurve4, nurbscurve5, nurbscurve6, style='curved')
30+
31+
32+
# ==============================================================================
33+
# Visualisation
34+
# ==============================================================================
35+
36+
view = App()
37+
38+
view.add(Polyline(nurbscurve1.locus()), linewidth=3, linecolor=(1, 0, 0))
39+
view.add(Polyline(nurbscurve2.locus()), linewidth=3, linecolor=(0, 1, 0))
40+
41+
view.add(Polyline(nurbscurve3.locus()), linewidth=3, linecolor=(1, 0, 0))
42+
view.add(Polyline(nurbscurve4.locus()), linewidth=3, linecolor=(0, 1, 0))
43+
view.add(Polyline(nurbscurve5.locus()), linewidth=3, linecolor=(1, 0, 1))
44+
view.add(Polyline(nurbscurve6.locus()), linewidth=3, linecolor=(0, 0, 1))
45+
46+
view.add(nurbssurface_2curves.to_mesh(nu=10))
47+
view.add(nurbssurface_4curves.to_mesh(nu=10))
48+
49+
view.run()
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
********************************************************************************
2+
Surface From Fill
3+
********************************************************************************
4+
5+
.. figure:: /_images/example_surface_from_fill.png
6+
:figclass: figure
7+
:class: figure-img img-fluid
8+
9+
.. literalinclude:: surface_from_fill.py
10+
:language: python

src/compas_occ/geometry/curves/nurbs.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
from OCC.Core.Geom import Geom_BSplineCurve
2121
from OCC.Core.GeomAPI import GeomAPI_Interpolate
22+
from OCC.Core.GeomConvert import GeomConvert_CompCurveToBSplineCurve
2223

2324
from .curve import OCCCurve
2425

@@ -493,3 +494,45 @@ def segmented(self, u, v, precision=1e-3):
493494
copy = self.copy()
494495
copy.segment(u, v, precision)
495496
return copy
497+
498+
def join(self, curve, precision=1e-4):
499+
"""Modifies this curve by joining it with another curve.
500+
501+
Parameters
502+
----------
503+
curve : :class:`OCCNurbsCurve`
504+
The curve to join.
505+
precision : float, optional
506+
Tolerance for continuity and multiplicity.
507+
508+
Returns
509+
-------
510+
None
511+
512+
"""
513+
converter = GeomConvert_CompCurveToBSplineCurve(self.occ_curve)
514+
success = converter.Add(curve.occ_curve, precision)
515+
if success:
516+
self.occ_curve = converter.BSplineCurve()
517+
518+
def joined(self, curve, precision=1e-4):
519+
"""Returns a new curve that is the result of joining this curve with another.
520+
521+
Parameters
522+
----------
523+
curve : :class:`OCCNurbsCurve`
524+
The curve to join.
525+
precision : float, optional
526+
Tolerance for continuity and multiplicity.
527+
528+
Returns
529+
-------
530+
:class:`OCCNurbsCurve` | None
531+
532+
"""
533+
copy = self.copy()
534+
converter = GeomConvert_CompCurveToBSplineCurve(self.occ_curve)
535+
success = converter.Add(curve.occ_curve, precision)
536+
if success:
537+
copy.occ_curve = converter.BSplineCurve()
538+
return copy

src/compas_occ/geometry/surfaces/nurbs.py

Lines changed: 32 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,9 @@
1616

1717
from OCC.Core.Geom import Geom_BSplineSurface
1818
from OCC.Core.GeomFill import GeomFill_BSplineCurves
19+
from OCC.Core.GeomFill import GeomFill_StretchStyle
1920
from OCC.Core.GeomFill import GeomFill_CoonsStyle
21+
from OCC.Core.GeomFill import GeomFill_CurvedStyle
2022

2123
from .surface import OCCSurface
2224

@@ -354,21 +356,48 @@ def from_step(cls, filepath):
354356
raise NotImplementedError
355357

356358
@classmethod
357-
def from_fill(cls, curve1, curve2):
358-
"""Construct a NURBS surface from the infill between two NURBS curves.
359+
def from_fill(cls, curve1, curve2, curve3=None, curve4=None, style='stretch'):
360+
"""Construct a NURBS surface from the infill between two, three or four contiguous NURBS curves.
359361
360362
Parameters
361363
----------
362364
curve1 : :class:`~compas_occ.geometry.OCCNurbsCurve`
363365
curve2 : :class:`~compas_occ.geometry.OCCNurbsCurve`
366+
curve3 : :class:`~compas_occ.geometry.OCCNurbsCurve`, optional.
367+
curve4 : :class:`~compas_occ.geometry.OCCNurbsCurve`, optional.
368+
style : Literal['stretch', 'coons', 'curved'], optional.
369+
370+
* ``'stretch'`` produces the flattest patch.
371+
* ``'curved'`` produces a rounded patch.
372+
* ``'coons'`` is between stretch and coons.
373+
374+
Raises
375+
------
376+
ValueError
377+
If the fill style is not supported.
364378
365379
Returns
366380
-------
367381
:class:`OCCNurbsSurface`
368382
369383
"""
384+
385+
if style == 'stretch':
386+
style = GeomFill_StretchStyle
387+
elif style == 'coons':
388+
style = GeomFill_CoonsStyle
389+
elif style == 'curved':
390+
style = GeomFill_CurvedStyle
391+
else:
392+
ValueError('Scheme is not supported')
393+
370394
surface = cls()
371-
occ_fill = GeomFill_BSplineCurves(curve1.occ_curve, curve2.occ_curve, GeomFill_CoonsStyle)
395+
if curve3 and curve4:
396+
occ_fill = GeomFill_BSplineCurves(curve1.occ_curve, curve2.occ_curve, curve3.occ_curve, curve4.occ_curve, style)
397+
elif curve3:
398+
occ_fill = GeomFill_BSplineCurves(curve1.occ_curve, curve2.occ_curve, curve3.occ_curve, style)
399+
else:
400+
occ_fill = GeomFill_BSplineCurves(curve1.occ_curve, curve2.occ_curve, style)
372401
surface.occ_surface = occ_fill.Surface()
373402
return surface
374403

0 commit comments

Comments
 (0)