Align sketch with face

Need help, or want to share a macro? Post here!
Forum rules
Be nice to others! Respect the FreeCAD code of conduct!
Post Reply
User avatar
Roy_043
Veteran
Posts: 8552
Joined: Thu Dec 27, 2018 12:28 pm

Align sketch with face

Post by Roy_043 »

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?
jaisejames
Posts: 384
Joined: Sat Sep 24, 2016 6:51 am

Re: Align sketch with face

Post by jaisejames »

vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Align sketch with face

Post by vocx »

Roy_043 wrote: Fri May 22, 2020 12:37 pm 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.
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.
User avatar
Roy_043
Veteran
Posts: 8552
Joined: Thu Dec 27, 2018 12:28 pm

Re: Align sketch with face

Post by Roy_043 »

@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.
User avatar
Roy_043
Veteran
Posts: 8552
Joined: Thu Dec 27, 2018 12:28 pm

Re: Align sketch with face

Post by Roy_043 »

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.
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Align sketch with face

Post by vocx »

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:
Neither Part nor Arch are used, so you should not import them.
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.
User avatar
Roy_043
Veteran
Posts: 8552
Joined: Thu Dec 27, 2018 12:28 pm

Re: Align sketch with face

Post by Roy_043 »

vocx wrote: Sun May 24, 2020 5:50 pm Neither Part nor Arch are used, so you should not import them.
Thanks for checking. Fixed!
vocx
Veteran
Posts: 5197
Joined: Thu Oct 18, 2018 9:18 pm

Re: Align sketch with face

Post by vocx »

Roy_043 wrote: Sun May 24, 2020 7:57 pm Thanks for checking. Fixed!
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.
User avatar
Roy_043
Veteran
Posts: 8552
Joined: Thu Dec 27, 2018 12:28 pm

Re: Align sketch with face

Post by Roy_043 »

Right, I am still in 'Lisp mode'.
Fixed that + added reset of window placement + tried to improve the recompute.
Post Reply