dprojects / Woodworking

This is Woodworking workbench for FreeCAD
MIT License
200 stars 17 forks source link

use placement/Support for jointTenon #28

Closed kervel closed 7 months ago

kervel commented 11 months ago

Hello,

I tried to use the jointTenon (and i had to change the code a bit so that tenon height and width are a bit different for my case). I found the tenons to be not as robust as they could be. I think it would be better to use placement/Support for tenons.

The following code does this more or less:

    for o in selection:

        objRef = MagicPanels.getReference(selection[i])
        subs = FreeCADGui.Selection.getSelectionEx()[i].SubObjects
        i = i + 1

        for objFace in subs:
            vertexes = objFace.Vertexes
            vertexNames = []
            for vtx in vertexes:
                for idx, v2 in enumerate(objRef.Shape.Vertexes):
                    if vtx.isSame(v2):
                        vertexNames.append(f'Vertex{idx + 1}')

            [ faceType, eAll, eThick, eShort, eLong ] = MagicPanels.getFaceEdges(objRef, objFace)

            if len(eLong) > 0:
                edge = eLong[0]
            elif len(eShort) > 0:
                edge = eShort[0]
            elif len(eThick) > 0:
                edge = eThick[0]
            sizes = MagicPanels.getSizes(objRef)
            sizes.sort()
            thick = sizes[0]
            jointSize = thick / 3 ## tenon width is 1/3 of the width of the shape
            jointHeight = 30
            size = edge.Length - (7) * 2 ## i use 7mm for the tenon offset
            Length = size
            Width = jointSize
            Height = jointHeight
            oo, ox, oy, of = vertexes[0], vertexes[2], vertexes[1], vertexes[3]
            no, nx, ny, nf = vertexNames[0], vertexNames[2], vertexNames[1], vertexNames[3]
            z_axis_relative = ox.Point.sub(oo.Point).cross(oy.Point.sub(oo.Point))
            com_relative = objRef.Shape.CenterOfMass.sub(oo.Point)
            if (z_axis_relative.dot(com_relative) > 0):
                oo, ox, oy, of = of, ox, oy, oo ## the tenon would overlap with the object, so we need to point at the other side
                no, nx, ny, nf = nf, nx, ny, no
            joint = FreeCAD.ActiveDocument.addObject("Part::Box","tenon")

            if oo.distToShape(ox)[0] == edge.Length:
                print("case1")
                joint.Width, joint.Height, joint.Length = jointSize, jointHeight, size
                joint.AttachmentOffset.Base = (7, jointSize, 0)
            else:
                print(f"case2 {oo.distToShape(ox)[0]} {edge.Length}")
                joint.Length, joint.Height, joint.Width = jointSize, jointHeight, size
                joint.AttachmentOffset.Base = (jointSize, 7, 0)

            joint.Support = [(objRef, (no, nx, ny))]
            joint.MapMode = 'OXY'
            #MagicPanels.setContainerPlacement(joint, x, y, z, 0, "center")
            MagicPanels.moveToFirst([ joint ], objRef)

i don't know if this would work perfectly in all cases, but at least for me it results in more robust tenons that are easier to tweak afterwards, and that move together with the panel on which they were made

dprojects commented 11 months ago
      size = edge.Length - (7) * 2 ## i use 7mm for the tenon offset

I have error: "name 'edge' is not defined"

i don't know if this would work perfectly in all cases

For sure it is not good solution to hard-code offset. This might be great for personal specific situation but normally should not be done with this way. I would rather recommend to use spreadsheet with custom settings.

I think, in the future, I will add spreadsheet with custom setting and some tools will be reading this spreadsheet. So, there might be entry for tenon size and offset. If there will not be entry for tenon this should work as default.

I will keep this issue open to this time I will cover the customization little more. Thanks for the code sample and this issue.

kervel commented 11 months ago

Hi,

sorry bout the error, i redacted the code a bit for brevity. The "edge" came unmodified from your code. I absolutely agree with not having to hardcode the tenon width / offset / .... I just did this example to see if using support rather than absolute position would yield an improvement.

I now did my model with this, and while it is very convenient to have your tenons stick with the panels they are attached to, it seems to impact the performance a bit too when moving panels if you have a lot of tenons.

A spreadsheet would be cool, but i think a task panel would maybe also be good (i see that in the woodworking bench there are not really task panels so i guess you are not too fond of them). For instance, i now choose the orientation of the tenon based on the longest edge (using the existing code). However, sometimes, i need a tenon on a square face. Then there is no "longest edge" and my tenon frequently ends up having the wrong orientation. So a task window with a "flip tenon" checkbox or button would i think make sense, and in the same window one could also edit tenon width depth and offset.

Frank

dprojects commented 11 months ago

i think a task panel would maybe also be good

The jointTenon tool is intended to be some kind of "quick shot". However, this might be good idea to extend this tool with extra window similar to, for example magicMove and some other tools. You could have "add" button with default settings but at any time you would be able to edit those defaults. I need to think about it.

However, I was thinking about settings spreadsheet long time ago. This would be some kind of spreadsheet added via button with default settings (separate icon that create default spreadsheet ready to edit). Next step would be adjust workbench to respect settings from this spreadsheet if there is such entry. I think it would be nice powerful approach and also this would solve the custom values.

dprojects commented 7 months ago

Hello again, I tested your code after edit and it works fine. However, I decided to add new option to magicDowels tool. I guess this approach gives more flexibility, you can change any option for tenon, size, sink, number of tenons and offsets...

Here is the video: Tenons with magicDowels

Regarding second issue. I think bounding should be option not automatic. Non-bounding modeling gives more flexibility, in my opinion. Maybe in the future I will add "bound feature" and this will be bounding and unbounding on demand.

Feel free to reopen this issue or create another one, Thanks !