Add offset options to Draft PathArray (#8295)

* Add offset options to Draft PathArray

Allows user to specify a starting and ending offset to items in Draft PathArrays.

* [Draft] path array offset

---------

Co-authored-by: Roy-043 <info@b-k-g.nl>
This commit is contained in:
BHennen
2023-03-11 08:54:25 -06:00
committed by GitHub
parent fff0f535dd
commit 0f4acc55be
3 changed files with 77 additions and 4 deletions

View File

@@ -112,6 +112,8 @@ class PathArray(gui_base_original.Modifier):
tan_vector = App.Vector(1, 0, 0)
force_vertical = False
vertical_vector = App.Vector(0, 0, 1)
start_offset = 0.0
end_offset = 0.0
use_link = self.use_link
_edge_list_str = list()
@@ -134,6 +136,8 @@ class PathArray(gui_base_original.Modifier):
_cmd += "tan_vector=" + DraftVecUtils.toString(tan_vector) + ", "
_cmd += "force_vertical=" + str(force_vertical) + ", "
_cmd += "vertical_vector=" + vertical_vector_str + ", "
_cmd += "start_offset=" + str(start_offset) + ", "
_cmd += "end_offset=" + str(end_offset) + ", "
_cmd += "use_link=" + str(use_link)
_cmd += ")"

View File

@@ -57,6 +57,7 @@ def make_path_array(base_object, path_object, count=4,
tan_vector=App.Vector(1, 0, 0),
force_vertical=False,
vertical_vector=App.Vector(0, 0, 1),
start_offset=0.0, end_offset=0.0,
use_link=True):
"""Make a Draft PathArray object.
@@ -140,6 +141,14 @@ def make_path_array(base_object, path_object, count=4,
It will force this vector to be the vertical direction
when `force_vertical` is `True`.
start_offset: float, optional
It defaults to 0.0.
It is the length from the start of the path to the first copy.
end_offset: float, optional
It defaults to 0.0.
It is the length from the end of the path to the last copy.
use_link: bool, optional
It defaults to `True`, in which case the copies are `App::Link`
elements. Otherwise, the copies are shape copies which makes
@@ -266,6 +275,24 @@ def make_path_array(base_object, path_object, count=4,
_err(translate("draft","Wrong input: must be a vector."))
return None
_msg("start_offset: {}".format(start_offset))
try:
utils.type_check([(start_offset, (int, float))],
name=_name)
except TypeError:
_err(translate("draft","Wrong input: must be a number."))
return None
start_offset = float(start_offset)
_msg("end_offset: {}".format(end_offset))
try:
utils.type_check([(end_offset, (int, float))],
name=_name)
except TypeError:
_err(translate("draft","Wrong input: must be a number."))
return None
end_offset = float(end_offset)
use_link = bool(use_link)
_msg("use_link: {}".format(use_link))
@@ -288,6 +315,8 @@ def make_path_array(base_object, path_object, count=4,
new_obj.TangentVector = tan_vector
new_obj.ForceVertical = force_vertical
new_obj.VerticalVector = vertical_vector
new_obj.StartOffset = start_offset
new_obj.EndOffset = end_offset
if App.GuiUp:
if use_link:

View File

@@ -124,6 +124,14 @@ class PathArray(DraftLink):
It defaults to `False`.
If it is `True`, and `AlignMode` is `'Original'` or `'Tangent'`,
it will use the vector in `VerticalVector` as the `Z` axis.
StartOffset: float
It defaults to 0.0.
It is the length from the start of the path to the first copy.
EndOffset: float
It defaults to 0.0.
It is the length from the end of the path to the last copy.
"""
def __init__(self, obj):
@@ -255,6 +263,22 @@ class PathArray(DraftLink):
obj.AlignMode = ['Original', 'Frenet', 'Tangent']
obj.AlignMode = 'Original'
if "StartOffset" not in properties:
_tip = QT_TRANSLATE_NOOP("App::Property","Length from the start of the path to the first copy.")
obj.addProperty("App::PropertyLength",
"StartOffset",
"Alignment",
_tip)
obj.StartOffset = 0.0
if "EndOffset" not in properties:
_tip = QT_TRANSLATE_NOOP("App::Property","Length from the end of the path to the last copy.")
obj.addProperty("App::PropertyLength",
"EndOffset",
"Alignment",
_tip)
obj.EndOffset = 0.0
# The Align property must be attached after other align properties
# so that onChanged works properly
if "Align" not in properties:
@@ -304,7 +328,9 @@ class PathArray(DraftLink):
obj.ExtraTranslation,
obj.Align, obj.AlignMode,
obj.ForceVertical,
obj.VerticalVector)
obj.VerticalVector,
obj.StartOffset.Value,
obj.EndOffset.Value)
self.buildShape(obj, array_placement, copy_placements)
self.props_changed_clear()
@@ -410,7 +436,8 @@ _PathArray = PathArray
def placements_on_path(shapeRotation, pathwire, count, xlate, align,
mode="Original", forceNormal=False,
normalOverride=None):
normalOverride=None,
startOffset=0.0, endOffset=0.0):
"""Calculate the placements of a shape along a given path.
Copies will be distributed evenly.
@@ -434,9 +461,22 @@ def placements_on_path(shapeRotation, pathwire, count, xlate, align,
cdist += e.Length
ends.append(cdist)
step = cdist / (count if DraftGeomUtils.isReallyClosed(pathwire) else count - 1)
if startOffset > (cdist - 1e-6):
_wrn(translate("draft", "Start Offset too large for path length. Using zero instead."))
start = 0
else:
start = startOffset
if endOffset > (cdist - start - 1e-6):
_wrn(translate("draft", "End Offset too large for path length minus Start Offset. Using zero instead."))
end = 0
else:
end = endOffset
cdist = cdist - start - end
step = cdist / (count if (DraftGeomUtils.isReallyClosed(pathwire) and not (start or end)) else count - 1)
remains = 0
travel = 0
travel = start
placements = []
for i in range(0, count):