FreeCAD-macros
144 строки · 5.2 Кб
1# -*- coding: utf-8 -*-
2
3from __future__ import unicode_literals
4
5__Name__ = 'Highlight Common parts'
6__Comment__ = 'Compute the common parts between selected shapes'
7__Author__ = 'JMG, galou and other contributors'
8__Version__ = '2.3.2'
9__Date__ = '2021-07-01'
10__License__ = 'CC0-1.0'
11__Web__ = 'https://freecadweb.org/wiki/Macro_HighlightCommon'
12__Wiki__ = 'https://freecadweb.org/wiki/Macro_HighlightCommon'
13__Icon__ = 'HighlightCommon.png'
14__Help__ = 'Select at least two objects and run'
15__Status__ = 'Production'
16__Requires__ = 'FreeCAD V0.17+'
17__Communication__ = 'https://github.com/FreeCAD/FreeCAD-macros/issues/'
18__Files__ = 'HighlightCommon.png'
19
20from PySide.QtGui import QMessageBox # FreeCAD's special PySide!
21
22import FreeCAD as app
23import FreeCADGui as gui
24
25
26PREFERENCE_PATH = 'User parameter:BaseApp/Preferences/Mod/HighlightCommon'
27
28
29def load_and_save_settings():
30param_change = 'change_transparency'
31param_transparency = 'transparency'
32p = app.ParamGet(PREFERENCE_PATH)
33change_transparency = p.GetBool(param_change, True)
34transparency = p.GetInt(param_transparency, 80)
35p.SetBool(param_change, change_transparency)
36p.SetInt(param_transparency, transparency)
37return change_transparency, transparency
38
39
40def main():
41# Store active doc in case it may change during run.
42doc = app.activeDocument()
43
44if doc is None:
45return
46
47change_transparency, transparency = load_and_save_settings()
48
49colli_grp = None # Group object to group collisions.
50colli_max = 0 # Maximum collision volume.
51
52# Open a transaction in undo pile.
53doc.openTransaction('Seeking collisions')
54
55objectsToEnumerate = gui.Selection.getSelection()
56if len(objectsToEnumerate) < 2:
57objectsToEnumerate = doc.Objects
58
59# Ensure list of unique objects.
60object_list = []
61for obj in objectsToEnumerate:
62if ((obj not in object_list)
63and hasattr(obj, 'Shape')
64and hasattr(obj, 'getGlobalPlacement')
65and hasattr(obj, 'Label')):
66object_list.append(obj)
67
68# Going through selected objects (object A).
69for i, object_a in enumerate(object_list):
70shape_a = object_a.Shape.copy()
71shape_a.Placement = object_a.getGlobalPlacement()
72label_a = object_a.Label
73
74# Making selected objects transparent.
75if change_transparency:
76try:
77object_a.ViewObject.Transparency = transparency
78except AttributeError:
79pass
80
81# Comparing object A with all
82# following ones in the list (object B).
83for object_b in object_list[(i + 1):]:
84
85shape_b = object_b.Shape.copy()
86shape_b.Placement = object_b.getGlobalPlacement()
87label_b = object_b.Label
88common = shape_a.common(shape_b)
89
90# Making selected objects transparent.
91if change_transparency:
92try:
93object_b.ViewObject.Transparency = transparency
94except AttributeError:
95pass
96
97# If object A & object B have a collision
98# display a message with collision volume and
99# add a new representative shape in the group.
100if common.Volume > 1e-6:
101app.Console.PrintMessage(
102'Volume of the intersection between {} and {}: {:.3f} mm³\n'.format(
103label_a,
104label_b,
105common.Volume))
106colli_max = common.Volume if common.Volume > colli_max else colli_max
107if not colli_grp:
108# Create group if it doesn't already exist.
109colli_grp = doc.addObject('App::DocumentObjectGroup',
110'Collisions')
111intersection_object = doc.addObject(
112'Part::Feature')
113intersection_object.Label = '{} - {}'.format(
114label_a, label_b)
115intersection_object.Shape = common
116intersection_object.ViewObject.ShapeColor = (1.0, 0.0, 0.0, 1.0)
117colli_grp.addObject(intersection_object)
118else:
119# If no collision, just inform the user.
120app.Console.PrintMessage(
121'No intersection between {} and {}\n'.format(
122label_a,
123label_b))
124
125# If collisions have been found, commit the undo transaction and
126# give a summary (count + max value) to the user.
127if colli_grp:
128doc.commitTransaction()
129app.Console.PrintMessage(
130'{} collision(s) found between selected objects\nMaximum collision: {:.3f} mm³\n'.format(
131len(colli_grp.Group),
132colli_max))
133doc.recompute()
134else:
135# If no collision has been found, just inform the user about it.
136doc.abortTransaction()
137if len(object_list) >= 2:
138app.Console.PrintWarning('No collision found between selected objects\n')
139else:
140app.Console.PrintWarning('No suitable objects selected, select at least two objects\n')
141
142
143if __name__ == '__main__':
144main()
145