1 from meshpy.common import MeshInfoBase, dump_array
2 import meshpy._tetgen as internals
3
4
5 -class MeshInfo(internals.MeshInfo, MeshInfoBase):
7 """Set a list of simple, single-polygon factes. Unlike :meth:`set_facets_ex`,
8 :meth:`set_facets` does not allow hole and only lets you use a single
9 polygon per facet.
10
11 :param facets: a list of facets, where each facet is a single
12 polygons, represented by a list of point indices.
13 :param markers: Either None or a list of integers of the same
14 length as *facets*. Each integer is the facet marker assigned
15 to its corresponding facet.
16
17 :note: When the above says "list", any repeatable iterable
18 also accepted instead.
19 """
20
21 if markers:
22 assert len(markers) == len(facets)
23
24 self.facets.resize(len(facets))
25
26 for i, vlist in enumerate(facets):
27 facet = self.facets[i]
28 polys = facet.polygons
29 polys.resize(1)
30 poly = facet.polygons[0]
31 poly.vertices.resize(len(vlist))
32 for j, pt_idx in enumerate(vlist):
33 poly.vertices[j] = pt_idx
34
35 if markers:
36 self.facet_markers.setup()
37 for i, mark in enumerate(markers):
38 self.facet_markers[i] = mark
39
40 - def set_facets_ex(self, facets, facet_holestarts=None, markers=None):
41 """Set a list of complicated factes. Unlike :meth:`set_facets`,
42 :meth:`set_facets_ex` allows holes and multiple polygons per
43 facet.
44
45 :param facets: a list of facets, where each facet is a list
46 of polygons, and each polygon is represented by a list
47 of point indices.
48 :param facet_holestarts: Either None or a list of hole starting points
49 for each facet. Each facet may have several hole starting points.
50 The mesh generator starts "eating" a hole into the facet at each
51 starting point and continues until it hits a polygon specified
52 in this facet's record in *facets*.
53 :param markers: Either None or a list of integers of the same
54 length as *facets*. Each integer is the facet marker assigned
55 to its corresponding facet.
56
57 :note: When the above says "list", any repeatable iterable
58 also accepted instead.
59 """
60
61 if markers:
62 assert len(markers) == len(facets)
63 if facet_holestarts is not None:
64 assert len(facet_holestarts) == len(facets)
65
66 self.facets.resize(len(facets))
67 for i_facet, poly_list in enumerate(facets):
68 facet = self.facets[i_facet]
69 polys = facet.polygons
70
71 polys.resize(len(poly_list))
72 for i_poly, vertex_list in enumerate(poly_list):
73 poly = facet.polygons[i_poly]
74
75 poly.vertices.resize(len(vertex_list))
76 for i_point, point in enumerate(vertex_list):
77 poly.vertices[i_point] = point
78
79 if facet_holestarts is not None:
80 hole_list = facet_holestarts[i_facet]
81 facet_holes = facet.holes
82 facet_holes.resize(len(hole_list))
83 for i_hole, hole_start in enumerate(hole_list):
84 for i_coordinate, co_value in enumerate(hole_start):
85 facet_holes[i_hole, i_coordinate] = co_value
86
87 if markers:
88 self.facet_markers.setup()
89 for i, mark in enumerate(markers):
90 self.facet_markers[i] = mark
91
93 for name in ["points"]:
94 dump_array(name, getattr(self, name))
95 for ifacet, facet in enumerate(self.faces):
96 print "facet %d:" % ifacet
97 for ipolygon, polygon in enumerate(facet.polygons):
98 print " polygon %d: vertices [%s]" % \
99 (ipolygon, ",".join(str(vi) for vi in polygon.vertices))
100
102 import pyvtk
103 vtkelements = pyvtk.VtkData(
104 pyvtk.UnstructuredGrid(
105 self.points,
106 tetra=self.elements),
107 "Mesh")
108 vtkelements.tofile(filename)
109
111 self.elements.resize(len(elements))
112
113 for i, element in enumerate(elements):
114 self.elements[i] = element
115
117 self.element_volumes.setup()
118
119 for i in xrange(len(self.element_volumes)):
120 if i in element_constraints:
121 self.element_volumes[i] = element_constraints[i]
122 else:
123 self.element_volumes[i] = -1
124
125
127 - def __init__(self, switches, **kwargs):
128 internals.Options.__init__(self)
129 if len(switches) == 0:
130 from warnings import warn
131 warn("Recommend non-empty 'switches' for crash-free meshing")
132 self.parse_switches(switches)
133 self.quiet = 1
134
135 for k, v in kwargs.iteritems():
136 try:
137 getattr(self, k)
138 except AttributeError:
139 raise ValueError("invalid option: %s" % k)
140 else:
141 setattr(self, k, v)
142
143
145 mesh = MeshInfo()
146
147
148 try:
149 import locale
150 except ImportError:
151 have_locale = False
152 else:
153 have_locale = True
154 prev_num_locale = locale.getlocale(locale.LC_NUMERIC)
155 locale.setlocale(locale.LC_NUMERIC, "C")
156
157 try:
158 internals.tetrahedralize(options, mesh_info, mesh)
159 finally:
160
161 if have_locale:
162 locale.setlocale(locale.LC_NUMERIC, prev_num_locale)
163
164 return mesh
165
166
167 -def build(mesh_info, options=Options("pq"), verbose=False,
168 attributes=False, volume_constraints=False, max_volume=None,
169 diagnose=False, insert_points=None):
170 if not verbose:
171 options.quiet = 1
172
173 if insert_points is not None:
174 options.insertaddpoints = 1
175
176 if attributes:
177 options.regionattrib = 1
178 if volume_constraints:
179 options.varvolume = 1
180 if max_volume:
181 options.fixedvolume = 1
182 options.maxvolume = max_volume
183 if diagnose:
184 options.diagnose = 1
185
186 return tetrahedralize(mesh_info, options)
187