forked from orbingol/NURBS-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtessellate.py
189 lines (139 loc) · 5.91 KB
/
tessellate.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
"""
.. module:: tessellate
:platform: Unix, Windows
:synopsis: Provides tessellation classes for surface triangulation
.. moduleauthor:: Onur Rauf Bingol <orbingol@gmail.com>
"""
import abc
from .exceptions import GeomdlException
from . import _tessellate as tsl
from ._utilities import add_metaclass, export
# Add some aliases
make_triangle_mesh = tsl.make_triangle_mesh
make_quad_mesh = tsl.make_quad_mesh
polygon_triangulate = tsl.polygon_triangulate
surface_tessellate = tsl.surface_tessellate
surface_trim_tessellate = tsl.surface_trim_tessellate
@add_metaclass(abc.ABCMeta)
class AbstractTessellate(object):
""" Abstract base class for tessellation algorithms. """
def __init__(self, **kwargs):
self._tsl_func = None
self._vertices = []
self._faces = []
self._arguments = dict()
@property
def vertices(self):
""" Vertex objects generated after tessellation.
:getter: Gets the vertices
:type: elements.AbstractEntity
"""
return self._vertices
@property
def faces(self):
""" Objects generated after tessellation.
:getter: Gets the faces
:type: elements.AbstractEntity
"""
return self._faces
@property
def arguments(self):
""" Arguments passed to the tessellation function.
This property allows customization of the tessellation algorithm, and mainly designed to allow users to pass
additional arguments to the tessellation function or change the behavior of the algorithm at runtime. This
property can be thought as a way to input and store extra data for the tessellation functionality.
:getter: Gets the tessellation arguments (as a dict)
:setter: Sets the tessellation arguments (as a dict)
"""
return self._arguments
@arguments.setter
def arguments(self, value):
if not isinstance(value, dict):
raise GeomdlException("Tessellation arguments must be a dict object")
self._arguments = value
@arguments.deleter
def arguments(self):
self._arguments = dict()
def reset(self):
""" Clears stored vertices and faces. """
self._vertices[:] = []
self._faces[:] = []
def is_tessellated(self):
""" Checks if vertices and faces are generated.
:return: tessellation status
:rtype: bool
"""
return all((self.vertices, self.faces))
@abc.abstractmethod
def tessellate(self, points, **kwargs):
""" Abstract method for the implementation of the tessellation algorithm.
This algorithm should update :py:attr:`~vertices` and :py:attr:`~faces` properties.
.. note::
This is an abstract method and it must be implemented in the subclass.
:param points: points to be tessellated
"""
pass
@export
class TriangularTessellate(AbstractTessellate):
""" Triangular tessellation algorithm for surfaces. """
def __init__(self, **kwargs):
super(TriangularTessellate, self).__init__(**kwargs)
self._tsl_func = tsl.make_triangle_mesh
def tessellate(self, points, **kwargs):
""" Applies triangular tessellation.
This function does not check if the points have already been tessellated.
Keyword Arguments:
* ``size_u``: number of points on the u-direction
* ``size_v``: number of points on the v-direction
:param points: array of points
:type points: list, tuple
"""
# Call parent function
super(TriangularTessellate, self).tessellate(points, **kwargs)
# Apply default triangular mesh generator function
self._vertices, self._faces = self._tsl_func(points, **kwargs)
@export
class TrimTessellate(AbstractTessellate):
""" Triangular tessellation algorithm for trimmed surfaces. """
def __init__(self, **kwargs):
super(TrimTessellate, self).__init__(**kwargs)
self._tsl_func = tsl.make_triangle_mesh
self._tsl_trim_func = tsl.surface_trim_tessellate
def tessellate(self, points, **kwargs):
""" Applies triangular tessellation w/ trimming curves.
Keyword Arguments:
* ``size_u``: number of points on the u-direction
* ``size_v``: number of points on the v-direction
:param points: array of points
:type points: list, tuple
"""
# Call parent function
super(TrimTessellate, self).tessellate(points, **kwargs)
# Get trims from the keyword arguments
trims = kwargs.pop('trims', [])
# Update sense if it is not set
for trim in trims:
if trim.opt_get('reversed') is None:
trim.opt = ['reversed', 0] # always trim the enclosed area by the curve
# Apply default triangular mesh generator function with trimming customization
self._vertices, self._faces = self._tsl_func(points, trims=trims, tessellate_func=self._tsl_trim_func,
tessellate_args=self.arguments, **kwargs)
@export
class QuadTessellate(AbstractTessellate):
""" Quadrilateral tessellation algorithm for surfaces. """
def __init__(self, **kwargs):
super(QuadTessellate, self).__init__(**kwargs)
self._tsl_func = tsl.make_quad_mesh
def tessellate(self, points, **kwargs):
""" Applies quadrilateral tessellation.
This function does not check if the points have already been tessellated.
Keyword Arguments:
* ``size_u``: number of points on the u-direction
* ``size_v``: number of points on the v-direction
:param points: array of points
:type points: list, tuple
"""
# Call parent function
super(QuadTessellate, self).tessellate(points, **kwargs)
# Apply default triangular mesh generator function
self._vertices, self._faces = self._tsl_func(points, **kwargs)