1. User selects face of part
2. User runs macro
3. Part is rotated so that the selected face is coincident to the XY plane. The normal vector for the face should be (0,0,-1) so that the Z vertices of the part are all >= 0.
The method I tried is to create a rotation object using the normal vector of the selected face and the vector (0,0,-1). The problem with this method is that the rotation always returns the values relative to the nearest axis ( i.e. all values are < 180) but the part placement is based on the absolute or total rotation of the part. If the part has a rotation of 0,0,0 then it works fine, otherwise the rotation is wrong.
Here's a small example that demonstrates the problem. Any ideas? Maybe this should be done with a rotation matrix
Code: Select all
# Make a box
obj = App.ActiveDocument.addObject("Part::Box","Box")
App.ActiveDocument.recompute()
# Create a vector facing down (-Z)
vec1 = App.Vector(0,0,-1)
FreeCAD.Console.PrintMessage("Vector 1: " + str(vec1) + '\n')
# The goal is to rotate the part so that the top face is on the bottom
# Basically the box must rotate 180 degrees
# Face 5 is the top and should have a normal vector equal to: (0,0,1)
vec2 = obj.Shape.Faces[5].normalAt(0,0)
FreeCAD.Console.PrintMessage("Vector 2: " + str(vec2) + '\n')
# Create a rotation object from the two vectors.
rot1 = App.Rotation(vec1,vec2)
FreeCAD.Console.PrintMessage("Rotation 1: " + str(rot1.toEuler()) + '\n')
# Get the part origin
org1 = obj.Placement.Base
FreeCAD.Console.PrintMessage("Base: " + str(org1) + '\n')
# Create the placement object
pla1 = App.Placement(org1,rot1)
FreeCAD.Console.PrintMessage("Placement 1: " + str(pla1) + '\n')
# Set the placement of the box
obj.Placement = pla1
## The box rotates sucessfully i.e. the normal of face 5 is now (0,0,-1)
FreeCAD.Console.PrintMessage("\n")
# Now rotate the box back to the original using the same methodology
vec3 = App.Vector(0,0,1)
FreeCAD.Console.PrintMessage("Vector 3: " + str(vec3) + '\n')
vec4 = obj.Shape.Faces[5].normalAt(0,0)
FreeCAD.Console.PrintMessage("Vector 4: " + str(vec4) + '\n')
rot2 = App.Rotation(vec3,vec4)
FreeCAD.Console.PrintMessage("Rotation 2: " + str(rot2.toEuler()) + '\n')
pla2 = App.Placement(org1,rot2)
FreeCAD.Console.PrintMessage("Placement 2: " + str(pla2) + '\n')
obj.Placement = pla2
## The box does not rotate because the rotation is the same as the placement???
Platform: 64-bit
Version: 0.14.3426 (Git)
Branch: master
Hash: 380dfcff0954c1c6e683b64fe82817f0812c12c7
Python version: 2.7.3
Qt version: 4.8.2
Coin version: 3.1.3
SoQt version: 1.5.0
OCC version: 6.7.0