Skip to content

Commit

Permalink
Draft: advanced indexing in Skip for Array
Browse files Browse the repository at this point in the history
syntax aligned with Part_CompoundFilter syntax. With the extension that
index patterns can be intermixed with manual enumeration in a matlab style:
	[1, 3:6:2] -> [1. 3, 5]
  • Loading branch information
davidosterberg committed Feb 13, 2021
1 parent 5097167 commit c99905e
Showing 1 changed file with 51 additions and 24 deletions.
75 changes: 51 additions & 24 deletions src/Mod/Draft/draftobjects/array.py
Expand Up @@ -35,6 +35,7 @@
# @{
import math
import json
import re
from PySide.QtCore import QT_TRANSLATE_NOOP

import FreeCAD as App
Expand Down Expand Up @@ -389,29 +390,6 @@ def show_and_hide(self, obj, prop):
"NumberPolar", "Angle", "IntervalAxis"):
obj.setPropertyStatus(pr, "Hidden")

def parse_skip_list(self, obj):
"""
Parses obj.Skip as a list of integers.
The reason for parsing this ourselves instead of using PropertyIntegerList
is so that we can handle failure silently
"""
try:
skip_list_raw = json.loads(obj.Skip)
except json.decoder.JSONDecodeError:
return []

if not isinstance(skip_list_raw, list):
return []

skip_list = []

for s in skip_list_raw:
if isinstance(s, int):
skip_list.append(s)

return skip_list


def execute(self, obj):
"""Execture when the object is created or recomputed."""
if not obj.Base:
Expand All @@ -432,7 +410,7 @@ def execute(self, obj):
"reference.")
raise TypeError(_info)

skip_list = self.parse_skip_list(obj)
skip_list = parse_skip_list(obj.Skip)

if obj.ArrayType == "ortho":
pls = rect_placements(obj.Base.Placement,
Expand Down Expand Up @@ -577,4 +555,53 @@ def circ_placements(base_placement,

return placements


def parse_skip_list(skip_expression):
"""
Parses a skip expression (as found in obj.Skip) as a list of integers.
The reason for parsing this ourselves instead of using PropertyIntegerList
is so that we can handle failure silently, and support more advanced indexing.
Syntax:
========
Skip expressions are expanded in a matlab like way
Example 1: skip_expression = 1:5
Will be expanded to [1, 2, 3, 4, 5]
Example 2: skip_expression = [2:5, 9]
Will be expanded to [2, 3, 4, 5, 9]
Example 3: skip_expression = [1, 3:2:7, 9]
Will be expanded to [1, 3, 5, 7, 9]
"""

matches = re.finditer(r"(?P<A>\d+):(?P<B>\d+)(:(?P<C>\d+))*", skip_expression)

skip_list = []
for m in matches:
d = m.groupdict()
d = {k:None if d[k] is None else int(d[k]) for k in d}
if d['C']:
skip_list.extend(range(d['A'], d['B'], d['C']))
else:
skip_list.extend(range(d['A'], d['B']))
skip_expression = skip_expression.replace(m.group(), '-0.1') # hack: we use a float as a marker in order have valid json, but not a valid index.

try:
skip_list_raw = json.loads(skip_expression)
except json.decoder.JSONDecodeError:
return skip_list

if not isinstance(skip_list_raw, list):
return skip_list

for s in skip_list_raw:
if isinstance(s, int):
skip_list.append(s)

return skip_list

## @}

0 comments on commit c99905e

Please sign in to comment.