Rich's Seed Eco-Home Design Software
SUPER ALIGN!
I had AI make for me an alignment tool in FreeCAD 1.0 so that it can align a folder of objects with objects, or other folder of objects, so compound objects don't have to be created. Compound objects prevent the editing of component objects that are baked in. Super Align allows for the alignment of folders without creating these compounds.
Instructions:
Run Macro:
-Click Macro > 📝 Macros... -Copy and Paste the code below in the macro window -Highlight all the code -Click Macro > Execute Macro
A window with a red button that says Align! should appear
-Click on the 3D view tab below to get pack to your project.
The Align! window should be there. You can minimize it and dock it to other windows.
-Click a point, edge, or face on your movable object -On Mac command Click a point, edge, or face on your fixed object -Click Align!
Macro Code: import FreeCAD as App import FreeCADGui as Gui from PySide import QtGui, QtCore
def get_parent_container(obj):
"""Find container (Part/Group) one level up, or return obj itself."""
for container in App.ActiveDocument.Objects:
if hasattr(container, 'Group') and obj in container.Group:
return container
return obj
def super_align():
sel_ex = Gui.Selection.getSelectionEx()
if len(sel_ex) != 2:
print("❌ Ctrl+click point/edge/face on MOVABLE, then FIXED")
return
# Store visibility states
original_vis = {}
for obj in App.ActiveDocument.Objects:
if hasattr(obj, 'Visibility'):
original_vis[obj.Name] = obj.Visibility
# Get parents (container or object itself)
movable_parent = get_parent_container(sel_ex[0].Object)
fixed_parent = get_parent_container(sel_ex[1].Object)
print(f"MOVABLE: '{movable_parent.Label}' → FIXED: '{fixed_parent.Label}'")
# Get movable objects (whole container or single)
if hasattr(movable_parent, 'Group') and movable_parent.Group:
movable_objects = list(movable_parent.Group)
else:
movable_objects = [movable_parent]
# Get subelement positions
def get_sub_pos(sub_ex):
sub_obj = sub_ex.SubObjects[0]
if hasattr(sub_obj, 'Point'):
return sub_obj.Point
elif hasattr(sub_obj, 'CenterOfMass'):
return sub_obj.CenterOfMass
else:
# Bounding box center
bb = sub_obj.BoundBox
return App.Vector((bb.XMin+bb.XMax)/2, (bb.YMin+bb.YMax)/2, (bb.ZMin+bb.ZMax)/2)
movable_pos = get_sub_pos(sel_ex[0])
fixed_pos = get_sub_pos(sel_ex[1])
offset = fixed_pos - movable_pos
print(f"📐 Incremental offset: {offset.x:.1f}, {offset.y:.1f}, {offset.z:.1f}")
# INCREMENTAL ALIGNMENT (preserves relative positions)
aligned_count = 0
for obj in movable_objects:
if hasattr(obj, 'Placement'):
new_base = obj.Placement.Base + offset
obj.Placement = App.Placement(new_base, obj.Placement.Rotation)
aligned_count += 1
# Restore visibility
for name, vis in original_vis.items():
obj = App.ActiveDocument.getObject(name)
if obj and hasattr(obj, 'Visibility'):
obj.Visibility = vis
Gui.Selection.clearSelection()
Gui.Selection.addSelection(movable_parent)
print(f"✅ INCREMENTALLY aligned {aligned_count} objects!")
- CREATE REFINED DOCKED PANEL
mw = Gui.getMainWindow() dock = QtGui.QDockWidget("Super Align", mw) dock.setObjectName("SuperAlignDock") dock.setFeatures(QtGui.QDockWidget.DockWidgetMovable |
QtGui.QDockWidget.DockWidgetFloatable |
QtGui.QDockWidget.DockWidgetClosable)
widget = QtGui.QWidget() layout = QtGui.QVBoxLayout(widget)
- BIGGER TITLE
title = QtGui.QLabel("Super Align") title.setStyleSheet("font-weight: bold; font-size: 20px; color: #2E8B57; padding: 5px;") layout.addWidget(title)
- INSTRUCTIONS (small text under title)
instructions = QtGui.QLabel(""" • Select point/edge/face on movable object • Select point/edge/face on fixed object • Click Align! """) instructions.setStyleSheet("font-size: 10px; color: #666; padding: 2px; margin: 0px;") instructions.setWordWrap(True) layout.addWidget(instructions)
- THINNER ALIGN BUTTON
align_btn = QtGui.QPushButton("Align!") align_btn.setToolTip("Ctrl-click movable point/edge/face → Ctrl-click fixed → Align!") align_btn.clicked.connect(super_align) align_btn.setStyleSheet("""
QPushButton {
font-weight: bold;
min-height: 25px;
max-height: 25px;
background-color: #FF6B6B;
border-radius: 5px;
}
""") layout.addWidget(align_btn)
widget.setLayout(layout) dock.setWidget(widget) mw.addDockWidget(QtCore.Qt.RightDockWidgetArea, dock) dock.show()
print("✅ Super Align REFINED panel ready!")