# -*- coding: utf-8 -*- """ Compute the difference between two shapes. Additions are marked red, removals are marked green. Both original parts will be half transparent. The volume of the additions and removals are printed in the console. """ from __future__ import unicode_literals __Name__ = 'Highlight Difference' __Comment__ = 'Compute the difference between two shapes' __Author__ = 'galou and other contributors' __Version__ = '2.2.0' __Date__ = '2021-07-01' __License__ = 'CC0-1.0' __Web__ = 'https://freecadweb.org/wiki/Macro_HighlightDifference' __Wiki__ = 'https://freecadweb.org/wiki/Macro_HighlightDifference' __Icon__ = 'HighlightDifference.svg' __Help__ = 'Select two objects and run' __Status__ = 'Production' __Requires__ = 'FreeCAD V0.17+' __Communication__ = 'https://github.com/FreeCAD/FreeCAD-macros/issues/' __Files__ = 'HighlightDifference.svg' from PySide import QtCore # FreeCAD's special PySide! from PySide.QtGui import QMessageBox # FreeCAD's special PySide! import FreeCAD as app import FreeCADGui as gui PREFERENCE_PATH = 'User parameter:BaseApp/Preferences/Mod/HighlightDifference' def error_dialog(msg): """Create a simple dialog QMessageBox with an error message.""" app.Console.PrintError(msg + '\n') diag = QMessageBox(QMessageBox.Icon.Critical, 'Error in macro highlight_difference', msg) diag.setWindowModality(QtCore.Qt.ApplicationModal) diag.exec_() def load_and_save_settings(): param_change = 'change_transparency' param_transparency = 'transparency' p = app.ParamGet(PREFERENCE_PATH) change_transparency = p.GetBool(param_change, True) transparency = p.GetInt(param_transparency, 80) p.SetBool(param_change, change_transparency) p.SetInt(param_transparency, transparency) return change_transparency, transparency def main(): if len(gui.Selection.getSelection()) < 2: error_dialog('Select two objects') return object_a = gui.Selection.getSelection()[0] object_b = gui.Selection.getSelection()[1] try: shape_a = object_a.Shape shape_b = object_b.Shape label_a = object_a.Label label_b = object_b.Label except AttributeError: error_dialog('No suitable objects selected, select two objects\n') return shape_addition = shape_a.cut(shape_b) if shape_addition.Volume < 1e-6: app.Console.PrintMessage('No addition from {} to {}\n'.format( label_a, label_b)) else: app.Console.PrintMessage( 'Volume of the addition from {} to {}: {}\n'.format( label_a, label_b, shape_addition.Volume)) shape_removal = shape_b.cut(shape_a) if shape_removal.Volume < 1e-6: app.Console.PrintMessage('No removal from {} to {}\n'.format( label_a, label_b)) else: app.Console.PrintMessage( 'Volume of the removal from {} to {}: {}\n'.format( label_a, label_b, shape_removal.Volume)) if (shape_addition.Volume < 1e-6) and (shape_removal.Volume < 1e-6): app.Console.PrintMessage('{} and {} have the same shape\n'.format( label_a, label_b)) added = app.ActiveDocument.addObject('Part::Feature') added.Label = 'Addition ({} − {})'.format(label_a, label_b) added.Shape = shape_addition added.ViewObject.ShapeColor = (1.0, 0.0, 0.0, 1.0) removed = app.ActiveDocument.addObject('Part::Feature') removed.Label = 'Removal ({} − {})'.format(label_b, label_a) removed.Shape = shape_removal removed.ViewObject.ShapeColor = (0.0, 0.5, 0.0, 1.0) change_transparency, transparency = load_and_save_settings() if change_transparency: try: object_a.ViewObject.Transparency = transparency object_b.ViewObject.Transparency = transparency except AttributeError: pass if __name__ == '__main__': main()