[solved] Move outside container but keep Placement and Rotation?

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
edwilliams16
Veteran
Posts: 3111
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: [solved] Move outside container but keep Placement and Rotation?

Post by edwilliams16 »

@dprojects
I think the recipe for the global placement is straightforward enough:

Code: Select all

gpl = App.Placement()
for obj in [panelFaceXY, container, container001, container002]: # containers listed from leaf to root
    gpl = obj.Placement * gpl
or if you prefer

Code: Select all

gpl = App.Placement()
for obj in [container002, container001, container, panelFaceXY]: # containers listed from root to leaf
    gpl = gpl * obj.Placement

If you read my blog article, it works exactly the same way as compounded rotations. https://blog.freecad.org/2023/01/16/the ... n-freecad/

Master the algebra of rotation/placements and you can quickly figure this out for yourself. There is also the Macro I pointed out (which is more complicated than necessary after the introduction of the getSelectionEx('',0) option). https://github.com/FreeCAD/FreeCAD-macr ... nt.FCMacro
User avatar
dprojects
Posts: 721
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: [solved] Move outside container but keep Placement and Rotation?

Post by dprojects »

edwilliams16 wrote: Fri Jan 20, 2023 9:52 pm getSelectionEx('',0) option
I think this looks the best to deal with global placement, you don't have to calculate anything and you don't need to take care of any order.
This works with selection but this can be adopted to work with any object, it is possible to do.
But the problem with this solution it is not reliable to me right now. It is not documented and because I didn't test it in many possible scenarios. I mean nested LinkGroups, Linking, Clones, Cubes, Pad with AttachmentOffset and also with raw Sketches move.

Make a note the Placement "wrong multiplication variation" was working fine with some examples but not working with others. So, for now I will stay with separate rotation calculation, even if it is disgusting ;-) For sure in the future I will create something with adopt the getSelectionEx('',0) or Placement multiplications, but need to test it well and make sure this is what I want.

Many times I went through the use of FreeCAD functions, which turned out to work differently than I imagined.

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
edwilliams16
Veteran
Posts: 3111
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: [solved] Move outside container but keep Placement and Rotation?

Post by edwilliams16 »

dprojects wrote: Fri Jan 20, 2023 10:10 pm
But the problem with this solution it is not reliable to me right now. It is not documented and because I didn't test it in many possible scenarios. I mean nested LinkGroups, Linking, Clones, Cubes, Pad with AttachmentOffset and also with raw Sketches move.
If you can find a case where it actually doesn't work, bring it up. It will be a serious bug.
Make a note the Placement "wrong multiplication variation" was working fine with some examples but not working with others.
It will work if and only if the placements commute. With either successive translations or successive rotations around the same axis, the result doesn't depend on the order.

A test case should involve rotations around different axes.
edwilliams16
Veteran
Posts: 3111
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: [solved] Move outside container but keep Placement and Rotation?

Post by edwilliams16 »

BTW, from https://forum.freecadweb.org/viewtopic. ... 45#p352145 this useful code shows the tree to leaf hierarchy of container objects

Code: Select all

for sel in Gui.Selection.getSelectionEx("",0):
	# sel.Object is the top parent object
	print(sel.Object.Name)
	for subname in sel.SubElementNames:
		print('\t' + subname)
		
		# getSubObjectList() split the subname with dots to obtain all
		# sub-objects in the path, including the top parent
		
		for obj in sel.Object.getSubObjectList(subname):
			print ('\t\t' + obj.Name)
outputting, for instance:

Code: Select all

container002
	container001.container.panelFaceXY.Vertex5
		container002
		container001
		container
		panelFaceXY
on selecting Vertex 5 of panelFaceXY - which would give the Placements to multiply together if you were doing it by hand.
edwilliams16
Veteran
Posts: 3111
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: [solved] Move outside container but keep Placement and Rotation?

Post by edwilliams16 »

Compare global placement direct and by multiplying up placements - they agree

Code: Select all

sel = Gui.Selection.getSelectionEx('',0)[0]
path = sel.SubElementNames[0]
shp = sel.Object.getSubObject(path)
gpl1 = shp.Placement
gpl = App.Placement()
for obj in sel.Object.getSubObjectList(path):
    gpl = gpl * obj.Placement

print(f'shp.Placement = {gpl1}')
print(f'gpl = {gpl}')
print(f'Same? {gpl.isSame(gpl1, 1E-7)}')
User avatar
dprojects
Posts: 721
Joined: Mon Mar 06, 2017 6:02 pm
Location: Poland
Contact:

Re: [solved] Move outside container but keep Placement and Rotation?

Post by dprojects »

edwilliams16 wrote: Sat Jan 21, 2023 1:12 am Compare global placement direct and by multiplying up placements - they agree

Code: Select all

sel = Gui.Selection.getSelectionEx('',0)[0]
path = sel.SubElementNames[0]
shp = sel.Object.getSubObject(path)
gpl1 = shp.Placement
gpl = App.Placement()
for obj in sel.Object.getSubObjectList(path):
    gpl = gpl * obj.Placement

print(f'shp.Placement = {gpl1}')
print(f'gpl = {gpl}')
print(f'Same? {gpl.isSame(gpl1, 1E-7)}')
You have knowledge but the problem is, the knowledge is not transformed into simple FreeCAD API.
Here is my proposal to improve: https://forum.freecadweb.org/viewtopic. ... 49#p654949

Thanks
Darek
github.com/dprojects

workbench for woodworking is available at: github.com/dprojects/Woodworking
Post Reply