Last active
October 11, 2026 00:31
-
-
Save palaniraja/5fca4260e2df3e489f16009cf9db3336 to your computer and use it in GitHub Desktop.
Freecad macro to diff two step files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import FreeCAD as App | |
| import FreeCADGui as Gui | |
| # colors from HistoryWorkbench addon (RGBA) | |
| Color = tuple[float, float, float, float] | |
| DIFF_FEATURE_TRANSPARENCY: int = 70 | |
| ADDED_COLOR: Color = (0.0, 0.5, 0.0, 1.0) | |
| REMOVED_COLOR: Color = (0.9, 0.0, 0.0, 1.0) | |
| # cyan & orange | |
| OLD_COLOR: Color = (0.0, 0.7, 0.9, 0.0) | |
| NEW_COLOR: Color = (1.0, 0.5, 0.0, 0.5) | |
| # magenta & yellow | |
| OLD_COLOR: Color = (0.8, 0.1, 0.6, 0.0) | |
| NEW_COLOR: Color = (1.0, 0.9, 0.1, 0.5) | |
| # Compatibility check for Qt UI bindings across FreeCAD versions | |
| try: | |
| from PySide2 import QtWidgets | |
| except ImportError: | |
| try: | |
| from PySide6 import QtWidgets | |
| except ImportError: | |
| from PySide import QtGui as QtWidgets | |
| def compare_step_models(): | |
| doc = App.ActiveDocument | |
| if not doc: | |
| QtWidgets.QMessageBox.warning(None, "Error", "No active document open.") | |
| return | |
| # Retrieve selected objects from Tree View | |
| sel = Gui.Selection.getSelection() | |
| if len(sel) != 2: | |
| QtWidgets.QMessageBox.information( | |
| None, | |
| "Selection Required", | |
| "Select exactly TWO objects in the Tree View:\n\n" | |
| "1. First selected = Old STEP\n" | |
| "2. Second selected = New STEP" | |
| ) | |
| return | |
| obj_old = sel[0] | |
| obj_new = sel[1] | |
| # --- 1. Apply Appearance Settings --- | |
| # Old Version: Solid Red = | |
| obj_old.ViewObject.ShapeColor = OLD_COLOR | |
| obj_old.ViewObject.Visibility = True | |
| # New Version: Translucent Green | |
| obj_new.ViewObject.ShapeColor = NEW_COLOR | |
| obj_new.ViewObject.Visibility = True | |
| # 2. move the orignal inside a group for easy visibility toggle | |
| step_group = doc.getObject("Original_STEP_Models") | |
| if not step_group: | |
| step_group = doc.addObject("App::DocumentObjectGroup", "Original_STEP_Models") | |
| # Add the selected objects to the group | |
| step_group.addObject(obj_old) | |
| step_group.addObject(obj_new) | |
| # --- 3. Perform Part Cuts using Shape Copies --- | |
| doc.openTransaction("Compare STEP Models") | |
| # Copy 1: Added Material (New - Old) | |
| base_added = doc.addObject("Part::Feature", "Base_New_Copy") | |
| base_added.Shape = obj_new.Shape.copy() | |
| tool_added = doc.addObject("Part::Feature", "Tool_Old_Copy") | |
| tool_added.Shape = obj_old.Shape.copy() | |
| cut_added = doc.addObject("Part::Cut", "Diff_Added_Material") | |
| cut_added.Base = base_added | |
| cut_added.Tool = tool_added | |
| # Hide intermediate helper copies so tree stays clean | |
| base_added.ViewObject.Visibility = False | |
| tool_added.ViewObject.Visibility = False | |
| # Copy 2: Removed Material (Old - New) | |
| base_removed = doc.addObject("Part::Feature", "Base_Old_Copy") | |
| base_removed.Shape = obj_old.Shape.copy() | |
| tool_removed = doc.addObject("Part::Feature", "Tool_New_Copy") | |
| tool_removed.Shape = obj_new.Shape.copy() | |
| cut_removed = doc.addObject("Part::Cut", "Diff_Removed_Material") | |
| cut_removed.Base = base_removed | |
| cut_removed.Tool = tool_removed | |
| # Hide intermediate helper copies | |
| base_removed.ViewObject.Visibility = False | |
| tool_removed.ViewObject.Visibility = False | |
| # Apply contrasting colors to the diff cuts for easy visual inspection | |
| cut_added.ViewObject.ShapeColor = (0.0, 0.8, 0.0, 0.4) # Green for Added | |
| cut_removed.ViewObject.ShapeColor = (0.9, 0.1, 0.1, 0.8) # Red for Removed | |
| # Keep original objects visible | |
| obj_old.ViewObject.Visibility = True | |
| obj_new.ViewObject.Visibility = True | |
| doc.commitTransaction() | |
| doc.recompute() | |
| # Select both output cuts in the Tree | |
| Gui.Selection.clearSelection() | |
| Gui.Selection.addSelection(cut_added) | |
| Gui.Selection.addSelection(cut_removed) | |
| compare_step_models() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment