Align sketch with face
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Be nice to others! Respect the FreeCAD code of conduct!
Align sketch with face
I am trying to align a sketch with the face of a wall, but have a hard time understanding the Axis and Rotation logic of the sketch. Are there any resources explaining this? Or perhaps some examples?
-
- Posts: 384
- Joined: Sat Sep 24, 2016 6:51 am
Re: Align sketch with face
Do you mean the properties that appear in the property editor?
The display is a bit strange to grasp because internally the rotation is handled through quaternions. The best you could do is use Part_Attachment to position the sketch on the face, and let the program automatically calculate the Axis and Angle, and all those values.
See also Placement, and Tutorial_custom_placing_of_windows_and_doors.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
Re: Align sketch with face
@jaisejames
Thanks I'll have a go with that example.
@vocx
My goal is to create a macro to automate the steps described in Tutorial_custom_placing_of_windows_and_doors.
Thanks I'll have a go with that example.
@vocx
My goal is to create a macro to automate the steps described in Tutorial_custom_placing_of_windows_and_doors.
Re: Align sketch with face
Ultimately the example was too hard to understand for me. I have used a matrix solution instead:
Code: Select all
import FreeCAD as App
import FreeCADGui as Gui
def WinFix():
errorMessage = "Selection error: Selection must contain exactly one window and one planar wall face\n"
selLst = Gui.Selection.getSelectionEx()
if len(selLst) != 2:
App.Console.PrintMessage(errorMessage)
return
objGui = selLst[0]
if objGui.Object.Proxy.__module__ == "ArchWindow":
win = objGui.Object
walGui = selLst[1]
wal = walGui.Object
else:
win = selLst[1].Object
walGui = objGui
wal = walGui.Object
if win.Proxy.__module__ != "ArchWindow":
App.Console.PrintMessage(errorMessage)
return
if wal.Proxy.__module__ != "ArchWall":
App.Console.PrintMessage(errorMessage)
return
if not walGui.HasSubObjects:
App.Console.PrintMessage(errorMessage)
return
if len(walGui.SubObjects) != 1:
App.Console.PrintMessage(errorMessage)
return
face = walGui.SubObjects[0]
# if not type(face.Surface) is Part.Plane:
if not face.Surface.isPlanar():
App.Console.PrintMessage(errorMessage)
return
ske = win.Base
if not ske.isDerivedFrom("Sketcher::SketchObject"):
App.Console.PrintMessage(errorMessage)
return
Gui.Selection.clearSelection()
# https://forum.freecadweb.org/viewtopic.php?t=420
# Calculate u, v and w vectors and t (=translation) vector.
w = face.normalAt(0, 0)
v = App.Vector(0.0, 0.0, 1.0)
u = v.cross(w)
# c = face.CenterOfMass
# t = App.Vector(c.x, c.y, ske.Placement.Base.z)
b = face.BoundBox
# Calculate 2 out of 4 possible bottom vectors:
xA = App.Vector(b.XMax - b.XMin, b.YMax - b.YMin, 0.0).normalize() # BL to TR.
xB = App.Vector(b.XMax - b.XMin, b.YMin - b.YMax, 0.0).normalize() # TL to BR.
# Compare u vector with bottom vectors to position t at left edge of face (t.z calculated later):
if u.isEqual(xA, 1e-6):
t = App.Vector(b.XMin, b.YMin, 0)
elif u.isEqual(xA.negative(), 1e-6):
t = App.Vector(b.XMax, b.YMax, 0)
elif u.isEqual(xB, 1e-6):
t = App.Vector(b.XMin, b.YMax, 0)
else:
t = App.Vector(b.XMax, b.YMin, 0)
m = App.Matrix(
u.x, v.x, w.x, t.x,
u.y, v.y, w.y, t.y,
u.z, v.z, w.z, ske.Placement.Base.z + win.Placement.Base.z,
0.0, 0.0, 0.0, 1.0)
ske.Placement = App.Placement(m)
win.Placement = App.Placement() # Reset win placement.
win.Normal = w.negative()
oldHosts = win.Hosts
win.Hosts = [wal]
# Avoid recomputing whole doc (works if there are no other windows in oldHosts):
for host in oldHosts:
host.touch() # Required!
host.recompute(True)
ske.recompute(True)
win.recompute(True)
wal.recompute(True)
return
Last edited by Roy_043 on Sun May 24, 2020 8:48 pm, edited 2 times in total.
Re: Align sketch with face
Neither Part nor Arch are used, so you should not import them.Roy_043 wrote: ↑Sun May 24, 2020 2:04 pm Ultimately the example was too hard to understand for me. I have used a matrix solution instead:
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
Re: Align sketch with face
Also, please notice that standard indentation in Python is 4 spaces. Using two spaces makes the code crowded and a bit unreadable. Python relies on whitespace to be readable. I think I've read the standard in Ruby or one of those languages is 2, but that's too little in the opinion of Python.
Always add the important information to your posts if you need help. Also see Tutorials and Video tutorials.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
To support the documentation effort, and code development, your donation is appreciated: liberapay.com/FreeCAD.
Re: Align sketch with face
Right, I am still in 'Lisp mode'.
Fixed that + added reset of window placement + tried to improve the recompute.
Fixed that + added reset of window placement + tried to improve the recompute.