View Issue Details

IDProjectCategoryView StatusLast Update
0003473DraftBugpublic2018-07-02 17:08
ReporterTheMarkster Assigned Toyorik  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionfixed 
Product Version0.17 
Fixed in Version0.18 
Summary0003473: Draft.array() and Draft.makeArray() not accepting z vector and z number parameters
DescriptionReported on forum here:
https://forum.freecadweb.org/viewtopic.php?f=22&t=28611&sid=a15235a1de099a8ea65ad5d907f1d6f6

In the wiki:

Draft Array

it states:

array (objectslist,xvector,yvector,xnum,ynum,[zvector,znum]) 

can be used to create an array object in python, but calls to array() will fail if more than 5 parameters are used (in other words, if zvector and znum parameters are used).

The error reported is that Draft.array() takes only 5 parameters, not 7.

The wiki also provides information on the Draft.makeArray() parametric version of the function, but does not suggest zvector and znum parameters can be used with that function, but if only the x and y parameters are used to create the parametric array object, in the data tab there are options for modifying the IntervalZ and NumberZ properties.

My guess is somebody forgot to add the necessary code to provide for the zvector and znum parameters for Draft.array() and Draft.makeArray() and also the Draft.makeArray() wiki was not updated to reflect the ability to use z parameters.

The fix is to add the necessary code Draft.array() and Draft.makeArray() so that these 2 functions will accept 7 parameters. I propose the following code changes. First, modify Draft.array() so that it looks like this:

def array(objectslist,arg1,arg2,arg3,arg4=None,arg5=None,arg6=None):
    '''array(objectslist,xvector,yvector,xnum,ynum) or 
    array(objectslist,xvector,yvector,zvector,xnum,ynum,znum) for rectangular array, or
    array(objectslist,center,totalangle,totalnum) for polar array: Creates an array
    of the objects contained in list (that can be an object or a list of objects)
    with, in case of rectangular array, xnum of iterations in the x direction
    at xvector distance between iterations, and same for y and z directions with yvector,
    zvector, ynum, and znum. In case of polar array, center is a vector, 
    totalangle is the angle
    to cover (in degrees) and totalnum is the number of objects, including the original.

    This function creates an array of independent objects. Use makeArray() to create a
    parametric array object.'''

    def rectArray(objectslist,xvector,yvector,xnum,ynum):
        typecheck([(xvector,Vector), (yvector,Vector), (xnum,int), (ynum,int)], "rectArray")
        if not isinstance(objectslist,list): objectslist = [objectslist]
        for xcount in range(xnum):
            currentxvector=Vector(xvector).multiply(xcount)
            if not xcount==0:
                move(objectslist,currentxvector,True)
            for ycount in range(ynum):
                currentxvector=FreeCAD.Base.Vector(currentxvector)
                currentyvector=currentxvector.add(Vector(yvector).multiply(ycount))
                if not ycount==0:
                    move(objectslist,currentyvector,True)
#new function to handle the extra z parameters
    def rectArray2(objectslist,xvector,yvector,zvector,xnum,ynum,znum):
        typecheck([(xvector,Vector), (yvector,Vector), (zvector,Vector),(xnum,int), (ynum,int),(znum,int)], "rectArray2")
        if not isinstance(objectslist,list): objectslist = [objectslist]
        for xcount in range(xnum):
            currentxvector=Vector(xvector).multiply(xcount)
            if not xcount==0:
                move(objectslist,currentxvector,True)
            for ycount in range(ynum):
                currentxvector=FreeCAD.Base.Vector(currentxvector)
                currentyvector=currentxvector.add(Vector(yvector).multiply(ycount))
                if not ycount==0:
                    move(objectslist,currentyvector,True)
                for zcount in range(znum):
                    currentzvector=currentyvector.add(Vector(zvector).multiply(zcount))
                    if not zcount==0:
                        move(objectslist,currentzvector,True)
    def polarArray(objectslist,center,angle,num):
        typecheck([(center,Vector), (num,int)], "polarArray")
        if not isinstance(objectslist,list): objectslist = [objectslist]
        fraction = float(angle)/num
        for i in range(num):
            currangle = fraction + (i*fraction)
            rotate(objectslist,currangle,center,copy=True)
#now also check for additional parameters arg5 and arg6
    if arg6:
        rectArray2(objectslist,arg1,arg2,arg3,arg4,arg5,arg6)
    elif arg4:
        rectArray(objectslist,arg1,arg2,arg3,arg4)
    else:
        polarArray(objectslist,arg1,arg2,arg3)

Next, modify Draft.makeArray() to this:

def makeArray(baseobject,arg1,arg2,arg3,arg4=None,arg5=None,arg6=None,name="Array"):
    '''makeArray(object,xvector,yvector,xnum,ynum,[name]) or alternatively 
    makeArray(object,xvector,yvector,zvector,xnum,ynum,znum,[name]) for rectangular  
    array, makeArray(object,center,totalangle,totalnum,[name]) for polar array: 
    Creates an array of the given object
    with, in case of rectangular array, xnum of iterations in the x direction
    at xvector distance between iterations, and same for y and z directions with yvector
    zvector, ynum, and znum. In case of polar array, center is a vector, totalangle 
    is the angle to cover (in degrees) and totalnum is the number of objects, including 
    the original. The result is a parametric Draft Array.'''
    obj = FreeCAD.ActiveDocument.addObject("Part::FeaturePython",name)
    _Array(obj)
    obj.Base = baseobject
    if arg6:
        obj.ArrayType = "ortho"
        obj.IntervalX = arg1
        obj.IntervalY = arg2
        obj.IntervalZ = arg3
        obj.NumberX = arg4
        obj.NumberY = arg5
        obj.NumberZ = arg6
    elif arg4:
        obj.ArrayType = "ortho"
        obj.IntervalX = arg1
        obj.IntervalY = arg2
        obj.NumberX = arg3
        obj.NumberY = arg4
    else:
        obj.ArrayType = "polar"
        obj.Center = arg1
        obj.Angle = arg2
        obj.NumberPolar = arg3
    if gui:
        _ViewProviderDraftArray(obj.ViewObject)
        baseobject.ViewObject.hide()
        formatObject(obj,obj.Base)
        if len(obj.Base.ViewObject.DiffuseColor) > 1:
            FreeCAD.ActiveDocument.recompute()
            obj.ViewObject.Proxy.resetColors(obj.ViewObject)
        select(obj)
    return obj

I do not believe any of the proposed changes would break any existing scripts that make use only of the x and y parameters.

The wiki will need to be updated for makeArray() to show the new z parameters are available.
Steps To ReproduceRun this macro to reproduce the error.

import FreeCAD, Draft
reload(Draft)
if not App.ActiveDocument:
    App.newDocument("Unnamed")
box = App.ActiveDocument.addObject("Part::Box","Box")
box.Length=1
box.Width=1
box.Height=1
spacing = 2
xv = App.Vector(spacing,0,0)
yv = App.Vector(0,spacing,0)
zv = App.Vector(0,0,spacing)
ary = Draft.array(box,xv,yv,zv,2,4,6) #fails here
#ary = Draft.array(box,xv,yv,2,4) #this works
#ary = Draft.makeArray(box,xv,yv,2,4) #this works
#ary = Draft.makeArray(box,xv,yv,zv,2,4,6) #fails here
App.activeDocument().recompute()
Additional InformationOS: Windows 10
Word size of OS: 64-bit
Word size of FreeCAD: 64-bit
Version: 0.17.13519 (Git)
Build type: Release
Branch: releases/FreeCAD-0-17
Hash: 1a8b868018f45ea486c0023fdbfeb06febc1fb89
Python version: 2.7.14
Qt version: 4.8.7
Coin version: 4.0.0a
OCC version: 7.2.0
Locale: English/UnitedStates (en_US)
Tags#tobeclosed
FreeCAD Information

Activities

Kunda1

2018-05-14 01:20

administrator   ~0011250

@yorik please weigh in on this Draft ticket at your convenience

TheMarkster

2018-05-17 23:16

reporter   ~0011256

added a pull request

https://github.com/FreeCAD/FreeCAD/pull/1460

Let me know if I did anything wrong as I'm new to github.

Kunda1

2018-05-30 23:25

administrator   ~0011312

@yorik this ticket wasn't closed even though the PR was merged. Is there anything left?

ref:
https://github.com/FreeCAD/FreeCAD/commit/e74a18f09c84c8a46f87a52fdab484e5ca897a58
https://github.com/FreeCAD/FreeCAD/commit/f9212edc6d030a090aff4d40a5b58055c3c9b128
https://github.com/FreeCAD/FreeCAD/commit/e0ef642d248422ea4e97060b180163f6f2c8f9ec

TheMarkster

2018-05-31 04:18

reporter   ~0011323

Today I added another pull request related to this same issue. Z Interval is being set to 0,0,0 by default, which should be 0,0,1. The user can easily change the property, so it's very minor, but as it is with the default value no z-axis objects are being added (or at least if they're being added they're all going to the z=0 placement).

https://github.com/FreeCAD/FreeCAD/pull/1486

Kunda1

2018-06-20 15:13

administrator   ~0011455

@yorik please weigh in at your convenience, thanks

yorik

2018-07-02 17:08

administrator   ~0011479

This is solved already (forgot which commit unfortunately)

Issue History

Date Modified Username Field Change
2018-05-12 23:22 TheMarkster New Issue
2018-05-14 01:20 Kunda1 Note Added: 0011250
2018-05-17 23:16 TheMarkster Note Added: 0011256
2018-05-30 23:25 Kunda1 Note Added: 0011312
2018-05-30 23:26 Kunda1 Tag Attached: #tobeclosed
2018-05-31 04:18 TheMarkster Note Added: 0011323
2018-06-20 15:13 Kunda1 Note Added: 0011455
2018-07-02 17:08 yorik Note Added: 0011479
2018-07-02 17:08 yorik Assigned To => yorik
2018-07-02 17:08 yorik Status new => closed
2018-07-02 17:08 yorik Resolution open => fixed
2018-07-02 17:08 yorik Fixed in Version => 0.18