FreeCAD

Форк
0
/
make_orthoarray.py 
494 строки · 17.3 Кб
1
# ***************************************************************************
2
# *   (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de>           *
3
# *                                                                         *
4
# *   This file is part of the FreeCAD CAx development system.              *
5
# *                                                                         *
6
# *   This program is free software; you can redistribute it and/or modify  *
7
# *   it under the terms of the GNU Lesser General Public License (LGPL)    *
8
# *   as published by the Free Software Foundation; either version 2 of     *
9
# *   the License, or (at your option) any later version.                   *
10
# *   for detail see the LICENCE text file.                                 *
11
# *                                                                         *
12
# *   FreeCAD is distributed in the hope that it will be useful,            *
13
# *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
# *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
# *   GNU Library General Public License for more details.                  *
16
# *                                                                         *
17
# *   You should have received a copy of the GNU Library General Public     *
18
# *   License along with FreeCAD; if not, write to the Free Software        *
19
# *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  *
20
# *   USA                                                                   *
21
# *                                                                         *
22
# ***************************************************************************
23
"""Provides functions to create orthogonal 2D and 3D Array objects."""
24
## @package make_orthoarray
25
# \ingroup draftmake
26
# \brief Provides functions to create orthogonal 2D and 3D Arrays.
27

28
## \addtogroup draftmake
29
# @{
30
import FreeCAD as App
31
import draftutils.utils as utils
32
import draftmake.make_array as make_array
33

34
from draftutils.messages import _wrn, _err
35
from draftutils.translate import translate
36

37

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),
42
                      n_x=2,
43
                      n_y=2,
44
                      n_z=1,
45
                      use_link=True):
46
    """Create an orthogonal array from the given object.
47

48
    This is a simple wrapper of the `draftmake.make_array.make_array`
49
    function to be used by the different orthogonal arrays.
50

51
    - `make_ortho_array`
52
    - `make_ortho_array2d`, no Z direction
53
    - `make_rect_array`, strictly rectangular
54
    - `make_rect_array2d`, strictly rectangular, no Z direction
55

56
    This function has no error checking, nor does it display messages.
57
    This should be handled by the subfunctions that use this one.
58
    """
59
    _name = "_make_ortho_array"
60

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,
64
                                    use_link=use_link)
65
    return new_obj
66

67

68
def _are_vectors(v_x, v_y, v_z=None, name="Unknown"):
69
    """Check that the vectors are numbers."""
70
    try:
71
        if v_z:
72
            utils.type_check([(v_x, (int, float, App.Vector)),
73
                              (v_y, (int, float, App.Vector)),
74
                              (v_z, (int, float, App.Vector))],
75
                             name=name)
76
        else:
77
            utils.type_check([(v_x, (int, float, App.Vector)),
78
                              (v_y, (int, float, App.Vector))],
79
                             name=name)
80
    except TypeError:
81
        _err(translate("draft","Wrong input: must be a number or vector."))
82
        return False, v_x, v_y, v_z
83

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."))
93

94
    return True, v_x, v_y, v_z
95

96

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."""
99
    try:
100
        if n_z:
101
            utils.type_check([(n_x, int),
102
                              (n_y, int),
103
                              (n_z, int)], name=name)
104
        else:
105
            utils.type_check([(n_x, int),
106
                              (n_y, int)], name=name)
107
    except TypeError:
108
        _err(translate("draft","Wrong input: must be an integer number."))
109
        return False, n_x, n_y, n_z
110

111
    if n_x < 1:
112
        _wrn(translate("draft","Input: number of elements must be at least 1. It is set to 1."))
113
        n_x = 1
114
    if n_y < 1:
115
        _wrn(translate("draft","Input: number of elements must be at least 1. It is set to 1."))
116
        n_y = 1
117
    if n_z and n_z < 1:
118
        _wrn(translate("draft","Input: number of elements must be at least 1. It is set to 1."))
119
        n_z = 1
120

121
    return True, n_x, n_y, n_z
122

123

124
def _are_numbers(d_x, d_y, d_z=None, name="Unknown"):
125
    """Check that the numbers are numbers."""
126
    try:
127
        if d_z:
128
            utils.type_check([(d_x, (int, float)),
129
                              (d_y, (int, float)),
130
                              (d_z, (int, float))], name=name)
131
        else:
132
            utils.type_check([(d_x, (int, float)),
133
                              (d_y, (int, float))], name=name)
134
    except TypeError:
135
        _err(translate("draft","Wrong input: must be a number."))
136
        return False, d_x, d_y, d_z
137

138
    return True, d_x, d_y, d_z
139

140

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)
144
    if not found:
145
        _err(translate("draft","Wrong input: base_object not in document."))
146

147
    return found, base_object
148

149

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),
154
                     n_x=2,
155
                     n_y=2,
156
                     n_z=1,
157
                     use_link=True):
158
    """Create an orthogonal array from the given object.
159

160
    Parameters
161
    ----------
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.
168

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.
172

173
        By default:
174
        ::
175
            v_x = App.Vector(10, 0, 0)
176
            v_y = App.Vector(0, 10, 0)
177
            v_z = App.Vector(0, 0, 10)
178

179
        Given that this is a vectorial displacement
180
        the next object can appear displaced in one, two or three axes
181
        at the same time.
182

183
        For example
184
        ::
185
            v_x = App.Vector(10, 5, 0)
186

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.
189

190
        A traditional "rectangular" array is obtained when
191
        the displacement vector only has its corresponding component,
192
        like in the default case.
193

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
197
        to be zero.
198

199
        For example
200
        ::
201
            v_x = 15
202
            v_y = 10
203
            v_z = 1
204
        becomes
205
        ::
206
            v_x = App.Vector(15, 0, 0)
207
            v_y = App.Vector(0, 10, 0)
208
            v_z = App.Vector(0, 0, 1)
209

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
213
        at least 1.
214

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.
218

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.
225

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.
230

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.
234

235
    Returns
236
    -------
237
    Part::FeaturePython
238
        A scripted object of type `'Array'`.
239
        Its `Shape` is a compound of the copies of the original object.
240

241
    None
242
        If there is a problem it will return `None`.
243

244
    See Also
245
    --------
246
    make_ortho_array2d, make_rect_array, make_rect_array2d, make_polar_array,
247
    make_circular_array, make_path_array, make_point_array
248
    """
249
    _name = "make_ortho_array"
250

251
    found, base_object = _find_object_in_doc(base_object,
252
                                             doc=App.activeDocument())
253
    if not found:
254
        return None
255

256
    ok, v_x, v_y, v_z = _are_vectors(v_x, v_y, v_z, name=_name)
257
    if not ok:
258
        return None
259

260
    ok, n_x, n_y, n_z = _are_integers(n_x, n_y, n_z, name=_name)
261
    if not ok:
262
        return None
263

264
    use_link = bool(use_link)
265

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,
269
                                use_link=use_link)
270
    return new_obj
271

272

273
def make_ortho_array2d(base_object,
274
                       v_x=App.Vector(10, 0, 0),
275
                       v_y=App.Vector(0, 10, 0),
276
                       n_x=2,
277
                       n_y=2,
278
                       use_link=True):
279
    """Create a 2D orthogonal array from the given object.
280

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.
284

285
    Parameters
286
    ----------
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.
293

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`.
298

299
    n_x, n_y: int, optional
300
        Number of elements
301
        in the corresponding X and Y directions.
302
        See `make_ortho_array`.
303

304
    use_link: bool, optional
305
        If it is `True`, create `App::Link` array.
306
        See `make_ortho_array`.
307

308
    Returns
309
    -------
310
    Part::FeaturePython
311
        A scripted object of type `'Array'`.
312
        Its `Shape` is a compound of the copies of the original object.
313

314
    None
315
        If there is a problem it will return `None`.
316

317
    See Also
318
    --------
319
    make_ortho_array, make_rect_array, make_rect_array2d, make_polar_array,
320
    make_circular_array, make_path_array, make_point_array
321
    """
322
    _name = "make_ortho_array2d"
323

324
    found, base_object = _find_object_in_doc(base_object,
325
                                             doc=App.activeDocument())
326
    if not found:
327
        return None
328

329
    ok, v_x, v_y, __ = _are_vectors(v_x, v_y, v_z=None, name=_name)
330
    if not ok:
331
        return None
332

333
    ok, n_x, n_y, __ = _are_integers(n_x, n_y, n_z=None, name=_name)
334
    if not ok:
335
        return None
336

337
    use_link = bool(use_link)
338

339
    new_obj = _make_ortho_array(base_object,
340
                                v_x=v_x, v_y=v_y,
341
                                n_x=n_x, n_y=n_y,
342
                                use_link=use_link)
343
    return new_obj
344

345

346
def make_rect_array(base_object,
347
                    d_x=10,
348
                    d_y=10,
349
                    d_z=10,
350
                    n_x=2,
351
                    n_y=2,
352
                    n_z=1,
353
                    use_link=True):
354
    """Create a rectangular array from the given object.
355

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.
360

361
    Parameters
362
    ----------
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.
369

370
    d_x, d_y, d_z: Base::Vector3, optional
371
        Displacement of elements in the corresponding X, Y, and Z directions.
372

373
    n_x, n_y, n_z: int, optional
374
        Number of elements in the corresponding X, Y, and Z directions.
375

376
    use_link: bool, optional
377
        If it is `True`, create `App::Link` array.
378
        See `make_ortho_array`.
379

380
    Returns
381
    -------
382
    Part::FeaturePython
383
        A scripted object of type `'Array'`.
384
        Its `Shape` is a compound of the copies of the original object.
385

386
    None
387
        If there is a problem it will return `None`.
388

389
    See Also
390
    --------
391
    make_ortho_array, make_ortho_array2d, make_rect_array2d, make_polar_array,
392
    make_circular_array, make_path_array, make_point_array
393
    """
394
    _name = "make_rect_array"
395

396
    found, base_object = _find_object_in_doc(base_object,
397
                                             doc=App.activeDocument())
398
    if not found:
399
        return None
400

401
    ok, d_x, d_y, d_z = _are_numbers(d_x, d_y, d_z, name=_name)
402
    if not ok:
403
        return None
404

405
    ok, n_x, n_y, n_z = _are_integers(n_x, n_y, n_z, _name)
406
    if not ok:
407
        return None
408

409
    use_link = bool(use_link)
410

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),
415
                                n_x=n_x,
416
                                n_y=n_y,
417
                                n_z=n_z,
418
                                use_link=use_link)
419
    return new_obj
420

421

422
def make_rect_array2d(base_object,
423
                      d_x=10,
424
                      d_y=10,
425
                      n_x=2,
426
                      n_y=2,
427
                      use_link=True):
428
    """Create a 2D rectangular array from the given object.
429

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.
435

436
    Parameters
437
    ----------
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.
444

445
    d_x, d_y: Base::Vector3, optional
446
        Displacement of elements in the corresponding X and Y directions.
447

448
    n_x, n_y: int, optional
449
        Number of elements in the corresponding X and Y directions.
450

451
    use_link: bool, optional
452
        If it is `True`, create `App::Link` array.
453
        See `make_ortho_array`.
454

455
    Returns
456
    -------
457
    Part::FeaturePython
458
        A scripted object of type `'Array'`.
459
        Its `Shape` is a compound of the copies of the original object.
460

461
    None
462
        If there is a problem it will return `None`.
463

464
    See Also
465
    --------
466
    make_ortho_array, make_ortho_array2d, make_rect_array, make_polar_array,
467
    make_circular_array, make_path_array, make_point_array
468
    """
469
    _name = "make_rect_array2d"
470

471
    found, base_object = _find_object_in_doc(base_object,
472
                                             doc=App.activeDocument())
473
    if not found:
474
        return None
475

476
    ok, d_x, d_y, __ = _are_numbers(d_x, d_y, d_z=None, name=_name)
477
    if not ok:
478
        return None
479

480
    ok, n_x, n_y, __ = _are_integers(n_x, n_y, n_z=None, name=_name)
481
    if not ok:
482
        return None
483

484
    use_link = bool(use_link)
485

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),
489
                                n_x=n_x,
490
                                n_y=n_y,
491
                                use_link=use_link)
492
    return new_obj
493

494
## @}
495

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.