23
"""Provides functions to create orthogonal 2D and 3D Array objects."""
31
import draftutils.utils as utils
32
import draftmake.make_array as make_array
34
from draftutils.messages import _wrn, _err
35
from draftutils.translate import translate
38
def _make_ortho_array(base_object,
39
v_x=App.Vector(10, 0, 0),
40
v_y=App.Vector(0, 10, 0),
41
v_z=App.Vector(0, 0, 10),
46
"""Create an orthogonal array from the given object.
48
This is a simple wrapper of the `draftmake.make_array.make_array`
49
function to be used by the different orthogonal arrays.
52
- `make_ortho_array2d`, no Z direction
53
- `make_rect_array`, strictly rectangular
54
- `make_rect_array2d`, strictly rectangular, no Z direction
56
This function has no error checking, nor does it display messages.
57
This should be handled by the subfunctions that use this one.
59
_name = "_make_ortho_array"
61
new_obj = make_array.make_array(base_object,
62
arg1=v_x, arg2=v_y, arg3=v_z,
63
arg4=n_x, arg5=n_y, arg6=n_z,
68
def _are_vectors(v_x, v_y, v_z=None, name="Unknown"):
69
"""Check that the vectors are numbers."""
72
utils.type_check([(v_x, (int, float, App.Vector)),
73
(v_y, (int, float, App.Vector)),
74
(v_z, (int, float, App.Vector))],
77
utils.type_check([(v_x, (int, float, App.Vector)),
78
(v_y, (int, float, App.Vector))],
81
_err(translate("draft","Wrong input: must be a number or vector."))
82
return False, v_x, v_y, v_z
84
if not isinstance(v_x, App.Vector):
85
v_x = App.Vector(v_x, 0, 0)
86
_wrn(translate("draft","Input: single value expanded to vector."))
87
if not isinstance(v_y, App.Vector):
88
v_y = App.Vector(0, v_y, 0)
89
_wrn(translate("draft","Input: single value expanded to vector."))
90
if v_z and not isinstance(v_z, App.Vector):
91
v_z = App.Vector(0, 0, v_z)
92
_wrn(translate("draft","Input: single value expanded to vector."))
94
return True, v_x, v_y, v_z
97
def _are_integers(n_x, n_y, n_z=None, name="Unknown"):
98
"""Check that the numbers are integers, with minimum value of 1."""
101
utils.type_check([(n_x, int),
103
(n_z, int)], name=name)
105
utils.type_check([(n_x, int),
106
(n_y, int)], name=name)
108
_err(translate("draft","Wrong input: must be an integer number."))
109
return False, n_x, n_y, n_z
112
_wrn(translate("draft","Input: number of elements must be at least 1. It is set to 1."))
115
_wrn(translate("draft","Input: number of elements must be at least 1. It is set to 1."))
118
_wrn(translate("draft","Input: number of elements must be at least 1. It is set to 1."))
121
return True, n_x, n_y, n_z
124
def _are_numbers(d_x, d_y, d_z=None, name="Unknown"):
125
"""Check that the numbers are numbers."""
128
utils.type_check([(d_x, (int, float)),
130
(d_z, (int, float))], name=name)
132
utils.type_check([(d_x, (int, float)),
133
(d_y, (int, float))], name=name)
135
_err(translate("draft","Wrong input: must be a number."))
136
return False, d_x, d_y, d_z
138
return True, d_x, d_y, d_z
141
def _find_object_in_doc(base_object, doc=None):
142
"""Check that a document is available and the object exists."""
143
found, base_object = utils.find_object(base_object, doc=doc)
145
_err(translate("draft","Wrong input: base_object not in document."))
147
return found, base_object
150
def make_ortho_array(base_object,
151
v_x=App.Vector(10, 0, 0),
152
v_y=App.Vector(0, 10, 0),
153
v_z=App.Vector(0, 0, 10),
158
"""Create an orthogonal array from the given object.
162
base_object: Part::Feature or str
163
Any of object that has a `Part::TopoShape` that can be duplicated.
164
This means most 2D and 3D objects produced with any workbench.
165
If it is a string, it must be the `Label` of that object.
166
Since a label is not guaranteed to be unique in a document,
167
it will use the first object found with this label.
169
v_x, v_y, v_z: Base::Vector3, optional
170
The vector indicating the vector displacement between two elements
171
in the specified orthogonal direction X, Y, Z.
175
v_x = App.Vector(10, 0, 0)
176
v_y = App.Vector(0, 10, 0)
177
v_z = App.Vector(0, 0, 10)
179
Given that this is a vectorial displacement
180
the next object can appear displaced in one, two or three axes
185
v_x = App.Vector(10, 5, 0)
187
means that the next element in the X direction will be displaced
188
10 mm in X, 5 mm in Y, and 0 mm in Z.
190
A traditional "rectangular" array is obtained when
191
the displacement vector only has its corresponding component,
192
like in the default case.
194
If these values are entered as single numbers instead
195
of vectors, the single value is expanded into a vector
196
of the corresponding direction, and the other components are assumed
206
v_x = App.Vector(15, 0, 0)
207
v_y = App.Vector(0, 10, 0)
208
v_z = App.Vector(0, 0, 1)
210
n_x, n_y, n_z: int, optional
211
The number of copies in the specified orthogonal direction X, Y, Z.
212
This number includes the original object, therefore, it must be
215
The values of `n_x` and `n_y` default to 2,
216
while `n_z` defaults to 1.
217
This means the array is a planar array by default.
219
use_link: bool, optional
220
It defaults to `True`.
221
If it is `True` the produced copies are not `Part::TopoShape` copies,
222
but rather `App::Link` objects.
223
The Links repeat the shape of the original `base_object` exactly,
224
and therefore the resulting array is more memory efficient.
226
Also, when `use_link` is `True`, the `Fuse` property
227
of the resulting array does not work; the array doesn't
228
contain separate shapes, it only has the original shape repeated
229
many times, so there is nothing to fuse together.
231
If `use_link` is `False` the original shape is copied many times.
232
In this case the `Fuse` property is able to fuse
233
all copies into a single object, if they touch each other.
238
A scripted object of type `'Array'`.
239
Its `Shape` is a compound of the copies of the original object.
242
If there is a problem it will return `None`.
246
make_ortho_array2d, make_rect_array, make_rect_array2d, make_polar_array,
247
make_circular_array, make_path_array, make_point_array
249
_name = "make_ortho_array"
251
found, base_object = _find_object_in_doc(base_object,
252
doc=App.activeDocument())
256
ok, v_x, v_y, v_z = _are_vectors(v_x, v_y, v_z, name=_name)
260
ok, n_x, n_y, n_z = _are_integers(n_x, n_y, n_z, name=_name)
264
use_link = bool(use_link)
266
new_obj = _make_ortho_array(base_object,
267
v_x=v_x, v_y=v_y, v_z=v_z,
268
n_x=n_x, n_y=n_y, n_z=n_z,
273
def make_ortho_array2d(base_object,
274
v_x=App.Vector(10, 0, 0),
275
v_y=App.Vector(0, 10, 0),
279
"""Create a 2D orthogonal array from the given object.
281
This works the same as `make_ortho_array`.
282
The Z component is ignored so it only considers vector displacements
283
in X and Y directions.
287
base_object: Part::Feature or str
288
Any of object that has a `Part::TopoShape` that can be duplicated.
289
This means most 2D and 3D objects produced with any workbench.
290
If it is a string, it must be the `Label` of that object.
291
Since a label is not guaranteed to be unique in a document,
292
it will use the first object found with this label.
294
v_x, v_y: Base::Vector3, optional
295
Vectorial displacement of elements
296
in the corresponding X and Y directions.
297
See `make_ortho_array`.
299
n_x, n_y: int, optional
301
in the corresponding X and Y directions.
302
See `make_ortho_array`.
304
use_link: bool, optional
305
If it is `True`, create `App::Link` array.
306
See `make_ortho_array`.
311
A scripted object of type `'Array'`.
312
Its `Shape` is a compound of the copies of the original object.
315
If there is a problem it will return `None`.
319
make_ortho_array, make_rect_array, make_rect_array2d, make_polar_array,
320
make_circular_array, make_path_array, make_point_array
322
_name = "make_ortho_array2d"
324
found, base_object = _find_object_in_doc(base_object,
325
doc=App.activeDocument())
329
ok, v_x, v_y, __ = _are_vectors(v_x, v_y, v_z=None, name=_name)
333
ok, n_x, n_y, __ = _are_integers(n_x, n_y, n_z=None, name=_name)
337
use_link = bool(use_link)
339
new_obj = _make_ortho_array(base_object,
346
def make_rect_array(base_object,
354
"""Create a rectangular array from the given object.
356
This function wraps around `make_ortho_array`
357
to produce strictly rectangular arrays, in which
358
the displacement vectors `v_x`, `v_y`, and `v_z`
359
only have their respective components in X, Y, and Z.
363
base_object: Part::Feature or str
364
Any of object that has a `Part::TopoShape` that can be duplicated.
365
This means most 2D and 3D objects produced with any workbench.
366
If it is a string, it must be the `Label` of that object.
367
Since a label is not guaranteed to be unique in a document,
368
it will use the first object found with this label.
370
d_x, d_y, d_z: Base::Vector3, optional
371
Displacement of elements in the corresponding X, Y, and Z directions.
373
n_x, n_y, n_z: int, optional
374
Number of elements in the corresponding X, Y, and Z directions.
376
use_link: bool, optional
377
If it is `True`, create `App::Link` array.
378
See `make_ortho_array`.
383
A scripted object of type `'Array'`.
384
Its `Shape` is a compound of the copies of the original object.
387
If there is a problem it will return `None`.
391
make_ortho_array, make_ortho_array2d, make_rect_array2d, make_polar_array,
392
make_circular_array, make_path_array, make_point_array
394
_name = "make_rect_array"
396
found, base_object = _find_object_in_doc(base_object,
397
doc=App.activeDocument())
401
ok, d_x, d_y, d_z = _are_numbers(d_x, d_y, d_z, name=_name)
405
ok, n_x, n_y, n_z = _are_integers(n_x, n_y, n_z, _name)
409
use_link = bool(use_link)
411
new_obj = _make_ortho_array(base_object,
412
v_x=App.Vector(d_x, 0, 0),
413
v_y=App.Vector(0, d_y, 0),
414
v_z=App.Vector(0, 0, d_z),
422
def make_rect_array2d(base_object,
428
"""Create a 2D rectangular array from the given object.
430
This function wraps around `make_ortho_array`,
431
to produce strictly rectangular arrays, in which
432
the displacement vectors `v_x` and `v_y`
433
only have their respective components in X and Y.
434
The Z component is ignored.
438
base_object: Part::Feature or str
439
Any of object that has a `Part::TopoShape` that can be duplicated.
440
This means most 2D and 3D objects produced with any workbench.
441
If it is a string, it must be the `Label` of that object.
442
Since a label is not guaranteed to be unique in a document,
443
it will use the first object found with this label.
445
d_x, d_y: Base::Vector3, optional
446
Displacement of elements in the corresponding X and Y directions.
448
n_x, n_y: int, optional
449
Number of elements in the corresponding X and Y directions.
451
use_link: bool, optional
452
If it is `True`, create `App::Link` array.
453
See `make_ortho_array`.
458
A scripted object of type `'Array'`.
459
Its `Shape` is a compound of the copies of the original object.
462
If there is a problem it will return `None`.
466
make_ortho_array, make_ortho_array2d, make_rect_array, make_polar_array,
467
make_circular_array, make_path_array, make_point_array
469
_name = "make_rect_array2d"
471
found, base_object = _find_object_in_doc(base_object,
472
doc=App.activeDocument())
476
ok, d_x, d_y, __ = _are_numbers(d_x, d_y, d_z=None, name=_name)
480
ok, n_x, n_y, __ = _are_integers(n_x, n_y, n_z=None, name=_name)
484
use_link = bool(use_link)
486
new_obj = _make_ortho_array(base_object,
487
v_x=App.Vector(d_x, 0, 0),
488
v_y=App.Vector(0, d_y, 0),