-
-
Notifications
You must be signed in to change notification settings - Fork 458
Expand file tree
/
Copy pathdiffutils.py
More file actions
139 lines (103 loc) · 4.95 KB
/
Copy pathdiffutils.py
File metadata and controls
139 lines (103 loc) · 4.95 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
import re
from pyrevit.coreutils.logger import get_logger
from pyrevit.coreutils import reverse_dict, get_str_hash
from pyrevit import DB
from pyrevit.compat import get_elementid_value_func
logger = get_logger(__name__)
type_param_exclude_list = ['Type', 'Type Name', 'Type Id', 'Family',
'Family Name', 'Family and Type']
domain_param_exclude_list = ['Workset', 'Edited by', 'Design Option',
'Drawn By', 'Level', 'Comments',
'Copyright', 'Image']
custom_attrs = {DB.TextNote: ['LeaderCount', 'LeaderLeftAttachment',
'LeaderRightAttachment', 'Text'],
DB.Dimension: ['Above', 'Below', 'Prefix', 'Suffix',
'ValueOverride', 'AreSegmentsEqual',
'NumberOfSegments']}
class DiffResults:
def __init__(self):
self.processed_params = set()
self.rvt_element_types = set()
self.diff_elements = []
def cleanup_repr_str(repr_str):
repr_str = repr_str.strip('\n,\r')
return re.sub(' +', ' ', repr_str)
def element_hash(rvt_element, include_type=False, diff_results=None):
def param_hash(param):
repr_str = '{} {}'.format(unicode(param.Definition.Name).ljust(30),
param.AsValueString())
if diff_results:
diff_results.processed_params.add(param.Definition.Name)
return get_str_hash(cleanup_repr_str(repr_str))
def attribute_hash(el, attribute):
try:
repr_str = unicode(getattr(el, attribute))
except Exception as hash_err:
logger.debug('Error reading attribute: '
'{} form element {} with id: {} | {}'
.format(attribute, el, el.Id, hash_err))
return ''
if diff_results:
diff_results.processed_params.add(attribute)
return get_str_hash(cleanup_repr_str(repr_str))
sorted_params = sorted(rvt_element.Parameters,
key=lambda x: x.Definition.Name)
if diff_results:
diff_results.rvt_element_types.add(type(rvt_element))
hash_value = ''
for parameter in sorted_params:
if parameter.Definition.Name not in domain_param_exclude_list:
if include_type:
hash_value += param_hash(parameter)
elif parameter.Definition.Name not in type_param_exclude_list:
hash_value += param_hash(parameter)
if type(rvt_element) in custom_attrs:
for el_attr in custom_attrs[type(rvt_element)]:
hash_value += attribute_hash(rvt_element, el_attr)
return get_str_hash(hash_value)
def element_hash_dict(element_list, include_type=False, diff_results=None):
get_elementid_value = get_elementid_value_func()
return {get_elementid_value(el.Id): element_hash(el, include_type, diff_results)
for el in element_list}
def compare(element_a, element_b, compare_types=False, diff_results=None):
return element_hash(element_a,
compare_types,
diff_results) == element_hash(element_b,
compare_types,
diff_results)
def compare_elmnt_sets(elementset_a, elementset_b,
compare_types=False, diff_results=None):
dict_a = element_hash_dict(elementset_a, compare_types, diff_results)
hash_list_a = sorted(dict_a.values())
dict_b = element_hash_dict(elementset_b, compare_types, diff_results)
hash_list_b = sorted(dict_b.values())
if hash_list_a == hash_list_b:
return True
elif diff_results:
rdict_a = reverse_dict(dict_a)
rdict_b = reverse_dict(dict_b)
for el_hash in set(hash_list_a) ^ set(hash_list_b):
if el_hash in rdict_a:
for el_id in rdict_a[el_hash]:
diff_results.diff_elements.append(DB.ElementId(el_id))
if el_hash in rdict_b:
for el_id in rdict_b[el_hash]:
diff_results.diff_elements.append(DB.ElementId(el_id))
return False
def compare_views(doc, view_a, view_b, compare_types=False, diff_results=None):
view_a_elmts = DB.FilteredElementCollector(doc)\
.OwnedByView(view_a.Id)\
.WhereElementIsNotElementType()\
.ToElements()
view_b_elmts = DB.FilteredElementCollector(doc)\
.OwnedByView(view_b.Id)\
.WhereElementIsNotElementType()\
.ToElements()
# pick the detail elements only
det_elmts_a = [el for el in view_a_elmts if el.ViewSpecific]
det_elmts_b = [el for el in view_b_elmts if el.ViewSpecific]
# compare and return result
return compare_elmnt_sets(det_elmts_a,
det_elmts_b,
compare_types,
diff_results)