Draft: clean up code, PEP8, and docstrings for Array class

Added author of the `CircularArray` array type, "M. G. Berberich"
(berberic2) or "rynn" in the forum.
This commit is contained in:
vocx-fc
2020-05-26 00:17:26 -05:00
committed by Yorik van Havre
parent d93e8518b0
commit ca9cfc6804

View File

@@ -1,7 +1,8 @@
# ***************************************************************************
# * Copyright (c) 2009, 2010 Yorik van Havre <yorik@uncreated.net> *
# * Copyright (c) 2009, 2010 Ken Cline <cline@frii.com> *
# * Copyright (c) 2020 FreeCAD Developers *
# * Copyright (c) 2019, M G Berberich (berberic2, rynn) *
# * Copyright (c) 2020 Eliud Cabrera Castillo <e.cabrera-castillo@tum.de> *
# * *
# * This program is free software; you can redistribute it and/or modify *
# * it under the terms of the GNU Lesser General Public License (LGPL) *
@@ -20,124 +21,179 @@
# * USA *
# * *
# ***************************************************************************
"""This module provides the object code for the Draft Array object.
"""Provides the object code for the Draft Array object.
The `Array` class currently handles three types of arrays,
orthogonal, polar, and circular. In the future, probably they should be
split in separate classes so that they are easier to manage.
"""
## @package array
# \ingroup DRAFT
# \brief This module provides the object code for the Draft Array object.
# \brief Provides the object code for the Draft Array object.
import math
from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD as App
import DraftVecUtils
from draftutils.utils import get_param
from draftobjects.draftlink import DraftLink
class Array(DraftLink):
"The Draft Array object"
"""The Draft Array object.
def __init__(self,obj):
To Do
-----
The `Array` class currently handles three types of arrays,
orthogonal, polar, and circular. In the future, probably they should be
split in separate classes so that they are easier to manage.
"""
def __init__(self, obj):
super(Array, self).__init__(obj, "Array")
def attach(self, obj):
_tip = "The base object that must be duplicated"
obj.addProperty("App::PropertyLink", "Base",
"Objects", QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyLink",
"Base",
"Objects",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "The type of array to create"
obj.addProperty("App::PropertyEnumeration", "ArrayType",
"Draft", QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyEnumeration",
"ArrayType",
"Draft",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "The axis (e.g. DatumLine) overriding Axis/Center"
obj.addProperty("App::PropertyLinkGlobal", "AxisReference",
"Objects", QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyLinkGlobal",
"AxisReference",
"Objects",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "The axis direction"
obj.addProperty("App::PropertyVector", "Axis",
"Parameters", QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyVector",
"Axis",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Number of copies in X direction"
obj.addProperty("App::PropertyInteger", "NumberX",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyInteger",
"NumberX",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Number of copies in Y direction"
obj.addProperty("App::PropertyInteger", "NumberY",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyInteger",
"NumberY",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Number of copies in Z direction"
obj.addProperty("App::PropertyInteger", "NumberZ",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyInteger",
"NumberZ",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Number of copies"
obj.addProperty("App::PropertyInteger", "NumberPolar",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyInteger",
"NumberPolar",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Distance and orientation of intervals in X direction"
obj.addProperty("App::PropertyVectorDistance", "IntervalX",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyVectorDistance",
"IntervalX",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Distance and orientation of intervals in Y direction"
obj.addProperty("App::PropertyVectorDistance", "IntervalY",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyVectorDistance",
"IntervalY",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Distance and orientation of intervals in Z direction"
obj.addProperty("App::PropertyVectorDistance", "IntervalZ",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyVectorDistance",
"IntervalZ",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Distance and orientation of intervals in Axis direction"
obj.addProperty("App::PropertyVectorDistance", "IntervalAxis",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyVectorDistance",
"IntervalAxis",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Center point"
obj.addProperty("App::PropertyVectorDistance", "Center",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyVectorDistance",
"Center",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Angle to cover with copies"
obj.addProperty("App::PropertyAngle", "Angle",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyAngle",
"Angle",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Distance between copies in a circle"
obj.addProperty("App::PropertyDistance", "RadialDistance",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyDistance",
"RadialDistance",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Distance between circles"
obj.addProperty("App::PropertyDistance", "TangentialDistance",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyDistance",
"TangentialDistance",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "number of circles"
obj.addProperty("App::PropertyInteger", "NumberCircles",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyInteger",
"NumberCircles",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "number of circles"
obj.addProperty("App::PropertyInteger", "Symmetry",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyInteger",
"Symmetry",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = "Specifies if copies must be fused (slower)"
obj.addProperty("App::PropertyBool", "Fuse",
"Parameters",QT_TRANSLATE_NOOP("App::Property", _tip))
obj.addProperty("App::PropertyBool",
"Fuse",
"Parameters",
QT_TRANSLATE_NOOP("App::Property", _tip))
obj.Fuse = False
if self.use_link:
obj.addProperty("App::PropertyInteger","Count","Draft",'')
obj.addProperty("App::PropertyBool","ExpandArray","Draft",
QT_TRANSLATE_NOOP("App::Property","Show array element as children object"))
_tip = "Number of elements in the array, read only"
obj.addProperty("App::PropertyInteger",
"Count",
"Draft",
QT_TRANSLATE_NOOP("App::Property", _tip))
_tip = ("Show the individual array elements "
"(only for Link arrays)")
obj.addProperty("App::PropertyBool",
"ExpandArray",
"Draft",
QT_TRANSLATE_NOOP("App::Property", _tip))
obj.ExpandArray = False
obj.ArrayType = ['ortho','polar','circular']
obj.ArrayType = ['ortho', 'polar', 'circular']
obj.NumberX = 1
obj.NumberY = 1
obj.NumberZ = 1
obj.NumberPolar = 1
obj.IntervalX = App.Vector(1,0,0)
obj.IntervalY = App.Vector(0,1,0)
obj.IntervalZ = App.Vector(0,0,1)
obj.IntervalX = App.Vector(1, 0, 0)
obj.IntervalY = App.Vector(0, 1, 0)
obj.IntervalZ = App.Vector(0, 0, 1)
obj.Angle = 360
obj.Axis = App.Vector(0,0,1)
obj.Axis = App.Vector(0, 0, 1)
obj.RadialDistance = 1.0
obj.TangentialDistance = 1.0
obj.NumberCircles = 2
@@ -145,12 +201,14 @@ class Array(DraftLink):
super(Array, self).attach(obj)
def linkSetup(self,obj):
def linkSetup(self, obj):
"""Set up the object as a link object."""
super(Array, self).linkSetup(obj)
obj.configLinkProperty(ElementCount='Count')
obj.setPropertyStatus('Count','Hidden')
obj.setPropertyStatus('Count', 'Hidden')
def onChanged(self,obj,prop):
def onChanged(self, obj, prop):
"""Execute when a property is changed."""
super(Array, self).onChanged(obj, prop)
if prop == "AxisReference":
if obj.AxisReference:
@@ -160,76 +218,98 @@ class Array(DraftLink):
obj.setEditorMode("Center", 0)
obj.setEditorMode("Axis", 0)
def execute(self,obj):
def execute(self, obj):
"""Execture when the object is created or recomputed."""
if obj.Base:
pl = obj.Placement
axis = obj.Axis
center = obj.Center
if hasattr(obj,"AxisReference") and obj.AxisReference:
if hasattr(obj.AxisReference,"Placement"):
axis = obj.AxisReference.Placement.Rotation * App.Vector(0,0,1)
if hasattr(obj, "AxisReference") and obj.AxisReference:
if hasattr(obj.AxisReference, "Placement"):
axis = obj.AxisReference.Placement.Rotation * App.Vector(0, 0, 1)
center = obj.AxisReference.Placement.Base
else:
raise TypeError("AxisReference has no Placement attribute. Please select a different AxisReference.")
_info = ("'AxisReference' has no 'Placement' property. "
"Please select a different object to use as "
"reference.")
raise TypeError(_info)
if obj.ArrayType == "ortho":
pls = self.rectArray(obj.Base.Placement,obj.IntervalX,obj.IntervalY,
obj.IntervalZ,obj.NumberX,obj.NumberY,obj.NumberZ)
pls = self.rectArray(obj.Base.Placement,
obj.IntervalX,
obj.IntervalY,
obj.IntervalZ,
obj.NumberX,
obj.NumberY,
obj.NumberZ)
elif obj.ArrayType == "polar":
av = obj.IntervalAxis if hasattr(obj, "IntervalAxis") else None
pls = self.polarArray(obj.Base.Placement,
center, obj.Angle.Value,
obj.NumberPolar, axis, av)
elif obj.ArrayType == "circular":
pls = self.circArray(obj.Base.Placement,obj.RadialDistance,obj.TangentialDistance,
axis,center,obj.NumberCircles,obj.Symmetry)
else:
av = obj.IntervalAxis if hasattr(obj,"IntervalAxis") else None
pls = self.polarArray(obj.Base.Placement,center,obj.Angle.Value,obj.NumberPolar,axis,av)
pls = self.circArray(obj.Base.Placement,
obj.RadialDistance,
obj.TangentialDistance,
axis, center,
obj.NumberCircles, obj.Symmetry)
return super(Array, self).buildShape(obj, pl, pls)
def rectArray(self,pl,xvector,yvector,zvector,xnum,ynum,znum):
def rectArray(self, pl, xvector, yvector, zvector, xnum, ynum, znum):
"""Determine the placements where the rectangular copies will be."""
base = [pl.copy()]
for xcount in range(xnum):
currentxvector=App.Vector(xvector).multiply(xcount)
if not xcount==0:
currentxvector = App.Vector(xvector).multiply(xcount)
if not xcount == 0:
npl = pl.copy()
npl.translate(currentxvector)
base.append(npl)
for ycount in range(ynum):
currentyvector=App.Vector(currentxvector)
currentyvector=currentyvector.add(App.Vector(yvector).multiply(ycount))
if not ycount==0:
currentyvector = App.Vector(currentxvector)
currentyvector = currentyvector.add(App.Vector(yvector).multiply(ycount))
if not ycount == 0:
npl = pl.copy()
npl.translate(currentyvector)
base.append(npl)
for zcount in range(znum):
currentzvector=App.Vector(currentyvector)
currentzvector=currentzvector.add(App.Vector(zvector).multiply(zcount))
if not zcount==0:
currentzvector = App.Vector(currentyvector)
currentzvector = currentzvector.add(App.Vector(zvector).multiply(zcount))
if not zcount == 0:
npl = pl.copy()
npl.translate(currentzvector)
base.append(npl)
return base
def circArray(self,pl,rdist,tdist,axis,center,cnum,sym):
def circArray(self, pl, rdist, tdist, axis, center, cnum, sym):
"""Determine the placements where the circular copies will be."""
sym = max(1, sym)
lead = (0,1,0)
if axis.x == 0 and axis.z == 0: lead = (1,0,0)
lead = (0, 1, 0)
if axis.x == 0 and axis.z == 0:
lead = (1, 0, 0)
direction = axis.cross(App.Vector(lead)).normalize()
base = [pl.copy()]
for xcount in range(1, cnum):
rc = xcount*rdist
rc = xcount * rdist
c = 2 * rc * math.pi
n = math.floor(c / tdist)
n = int(math.floor(n / sym) * sym)
if n == 0: continue
if n == 0:
continue
angle = 360.0/n
for ycount in range(0, n):
npl = pl.copy()
trans = App.Vector(direction).multiply(rc)
npl.translate(trans)
npl.rotate(npl.Rotation.inverted().multVec(center-trans), axis, ycount*angle)
npl.rotate(npl.Rotation.inverted().multVec(center-trans),
axis, ycount * angle)
base.append(npl)
return base
def polarArray(self,spl,center,angle,num,axis,axisvector):
#print("angle ",angle," num ",num)
def polarArray(self, spl, center, angle, num, axis, axisvector):
"""Determine the placements where the polar copies will be."""
# print("angle ",angle," num ",num)
spin = App.Placement(App.Vector(), spl.Rotation)
pl = App.Placement(spl.Base, App.Rotation())
center = center.sub(spl.Base)