Discussion on placement

Have some feature requests, feedback, cool stuff to share, or want to know where FreeCAD is going? This is the place.
Forum rules
Be nice to others! Read the FreeCAD code of conduct!
edwilliams16
Veteran
Posts: 3180
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Discussion on placement

Post by edwilliams16 »

zardozer wrote: Fri Jun 11, 2021 1:39 am
Note also that even if you try to transform it so that circular part is 'centered' at origin, you'll have to tweak that x coordinate by some fractional amount to get it to be as close to the real center as possible. So there's no automatic, mathematically calculated way to set that center, it's just tweak, zoom in, tweak, measure, etc.
My macro above will do that for you. Put the object in a PartDesign Body, select the circular edge and run the Macro. It will place the origin at the center of the circle. Choose a vertex and it will make it the origin. Choose a line and it will use the center of the line. Choose a face and it will use the CG of the face. Double click to select the body and it will use its CG. I’ve only tested on a few objects, so I may have missed some case in which case it will do nothing.
zardozer
Posts: 49
Joined: Sat Nov 07, 2020 2:35 am

Re: Discussion on placement

Post by zardozer »

edwilliams16 wrote: Fri Jun 11, 2021 1:53 am
My macro above will do that for you. Put the object in a PartDesign Body, select the circular edge and run the Macro. It will place the origin at the center of the circle. Choose a vertex and it will make it the origin. Choose a line and it will use the center of the line. Choose a face and it will use the CG of the face. Double click to select the body and it will use its CG. I’ve only tested on a few objects, so I may have missed some case in which case it will do nothing.
Cool, thanks for doing this. I'll test it soon.
User avatar
onekk
Veteran
Posts: 6208
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Discussion on placement

Post by onekk »

I think that consistency is important, but if the behaviour is linked to the lack of proper data in the original format or not, maybe the "importer" could be more smart or dumb to ask the user what he want?

STL have no concept of position, is a mesh so the informations are only vertexes, so the only way i see, is when importing a STL to a draw maybe the importer will ask the user if he want to "relocate the mesh" and "cristallize this relocation" in the final "solid".

Same for other formats, asking the user what way FreeCAD has to import the file, (about the "base position"), in other world if the solid has to be placed somewhere and that "position" will led to a Vector(0,0,0), Rotation(0,0,0) (so simplify things).

Maybe setting some "default behaviour" in Preferences, so the user is not forced to "click every time the same buttons" when importing things.

I think that in this case the "consistency" will be improved, but nothing will be broken, as existent FCStd files will be not affected.

If a user modify the "standard behaviour" is his responsability to know what he is doing and the only thing that a developer/documenter could do is to explain the behaviour clearly in the documentation, maybe giving technical infos about why these choices has to be made.

a sort of:

Warning: STL (IGES or whatever is the problematic fomrat) files don't hold an "absolute position" so if you choose a different position from the origin this "relocation", "translation" or whatever you want to call will be "hardcoded" in the resulting solid.

What do you think about a similar behaviour.

Regards

Carlo D.
GitHub page: https://github.com/onekk/freecad-doc.
- In deep articles on FreeCAD.
- Learning how to model with scripting.
- Various other stuffs.

Blog: https://okkmkblog.wordpress.com/
edwilliams16
Veteran
Posts: 3180
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Discussion on placement

Post by edwilliams16 »

drmacro wrote: Thu Jun 10, 2021 2:32 pm To add to the "why doesn't it stay where it's put" comments... :mrgreen:

When dropped into a Body:
  • STL, converted to shape, to solid. Moves back to original position
  • IGES, back to original position
  • STEP, stays put
In my one and only test of step import, it didn't work like this. Changing the placement of the imported step object had no effect on the location of the BaseFeature - just like STL imports or Part objects. I assume you have an example where it behaves differently - in which case there's more complexity here.
Attachments
stl-import-placement-Body001.step
(6.37 KiB) Downloaded 47 times
step-import-test.FCStd
(7.09 KiB) Downloaded 45 times
drmacro
Veteran
Posts: 8984
Joined: Sun Mar 02, 2014 4:35 pm

Re: Discussion on placement

Post by drmacro »

It is the object and description of the process I produced behaviour with in this thread:
https://forum.freecadweb.org/viewtopic.php?f=3&t=59212

The STEP file: C38-81.STEP here: https://www.thingiverse.com/thing:4073910/files
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
drmacro
Veteran
Posts: 8984
Joined: Sun Mar 02, 2014 4:35 pm

Re: Discussion on placement

Post by drmacro »

And, I just realized while tinkering with that file...

I had always moved the object, then dropped it in the Body.

It turns out that just dropping it in a Body moves it to the origin...

Haven't thought that through yet...working on something else ATM. :roll:
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
mario52
Veteran
Posts: 4692
Joined: Wed May 16, 2012 2:13 pm

Re: Discussion on placement

Post by mario52 »

hi

for Shape, Mesh and Points use this wmayer snippet

this center the object in BoundBox center = 0,0,0 (not work with certain position of the object, just example test)

enjoy

Code: Select all

selt = Gui.Selection.getSelectionEx()

objs = FreeCADGui.Selection.getSelection()

if hasattr(objs[0], "Shape"):
    print("Shape")
    s = objs[0].Shape
    bbCenter = s.BoundBox.Center
    objs[0].Placement.Base = FreeCAD.Vector(-bbCenter[0], -bbCenter[1], -bbCenter[2])
    ## your macro code for shape .. here
    print(bbCenter)
elif hasattr(objs[0], "Mesh"):      # upgrade with wmayer thanks #http://forum.freecadweb.org/viewtopic.php?f=13&t=22331
    print("Mesh")
    s = objs[0].Mesh
    bbCenter = s.BoundBox.Center
    print(bbCenter)
    objs[0].Placement.Base = FreeCAD.Vector(-bbCenter[0], -bbCenter[1], -bbCenter[2])
    print(s.Placement)
elif hasattr(objs[0], "Points"):
    print("Points")
    s = objs[0].Points
    bbCenter = s.BoundBox.Center
    print(bbCenter)
    objs[0].Placement.Base = FreeCAD.Vector(-bbCenter[0], -bbCenter[1], -bbCenter[2])
    print(s.Placement)
print("_____________________")



mario
Maybe you need a special feature, go into Macros_recipes and Code_snippets, Topological_data_scripting.
My macros on Gist.github here complete macros Wiki and forum.
edwilliams16
Veteran
Posts: 3180
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Discussion on placement

Post by edwilliams16 »

Ah yes - this is where we started. The difference is that the C38 file imports as a set of objects in a container. My simpler example just imports an object. It seems that uniformly if you just drop an object into a Body it loses its placement.
drmacro
Veteran
Posts: 8984
Joined: Sun Mar 02, 2014 4:35 pm

Re: Discussion on placement

Post by drmacro »

edwilliams16 wrote: Thu Jun 10, 2021 2:59 am ...
Something on these lines could be extended and bullet-proofed:
EDIT Dealt with Face and 3D selections.
I'm not sure I've covered all the cases of interest.

Code: Select all

selt = Gui.Selection.getSelectionEx()
if len(selt) != 1:
    print('Select one vertex, edge or object')
else:
    sel = selt[0]
    if sel.HasSubObjects:
        selected = sel.SubObjects[0] 
        if selected.ShapeType == 'Vertex':
            shift = selected.Point
        elif selected.ShapeType == 'Edge':
            if selected.Curve.TypeId == 'Part::GeomCircle':    #circles and arcs
                 shift = selected.Curve.Center
            elif selected.Curve.TypeId == 'Part::GeomLine':
                shift = (selected.valueAt(selected.FirstParameter) + selected.valueAt(selected.LastParameter))/2 # mid-point
            else:
                shift = App.Vector(0, 0, 0)  # bail and do nothing
        elif selected.ShapeType == 'Face':
            shift = selected.CenterOfMass #center of face
        else:
            shift = App.Vector(0, 0, 0)  # bail and do nothing
    else:
        if sel.ObjectName[0:11] == 'BaseFeature':
            if sel.Object.Shape.ShapeType == 'Solid':
                shift = sel.Object.Shape.CenterOfMass
            elif sel.Object.Shape.ShapeType == 'Compound':
                shift = sel.Object.Shape.SubShapes[0].CenterOfMass
            #more cases?
            else:
                shift = App.Vector(0, 0, 0)  # bail and do nothing                
        else:
            shift = App.Vector(0, 0, 0)  # bail and do nothing
#print(f'Shift = {shift}')
base = App.ActiveDocument.getObject(sel.ObjectName).Placement
base.move(-shift)
App.ActiveDocument.recompute()
        
Started thinking about this some more.

It would appear there may be need to actually add options to the import that would allow the actual data being imported to be modified as it's imported to adjust the data so the placement was FreeCAD-ified .

Since that appeared a bit beyond my grasp at this point, I decided to have a think and look at the code above.

The first thing is it works fine for a solid like a STEP import. I.e. a step file has a concept of arcs, circles, etc. so you can select an arc which represents a hole that you might want on the identity and the code works fine.

But, in an STL file, that's been converted to a solid, it is tessellated.

So, one could select 3 vertexes or 3 edges that represent the circumference of a hole and use the calculated center to align the hole on the identity.

I'm guessing this calculation is available on call somewhere in FreeCAD already...anybody know where that might be?
I dug around in ..src/Mod/Draft/draftgeoutils/ to no avail, but, could have missed the obvious. :oops:

(Yes, I'm sure I could figure out the trig...but, I'm happy to be lazy and not recreate the wheel. :mrgreen: )
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
edwilliams16
Veteran
Posts: 3180
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Discussion on placement

Post by edwilliams16 »

drmacro wrote: Sun Jun 13, 2021 6:27 pm

It would appear there may be need to actually add options to the import that would allow the actual data being imported to be modified as it's imported to adjust the data so the placement was FreeCAD-ified .
It seemed to me that trying to mess with the placement during the import wasn't the way to go. It isn't clear you would really know what placement you wanted until you've already imported and looked at the model. Better to separate the procedure IMO.
drmacro wrote: Sun Jun 13, 2021 6:27 pm I'm guessing this calculation is available on call somewhere in FreeCAD already...anybody know where that might be?
I dug around in ..src/Mod/Draft/draftgeoutils/ to no avail, but, could have missed the obvious. :oops:

(Yes, I'm sure I could figure out the trig...but, I'm happy to be lazy and not recreate the wheel. :mrgreen: )
The math is easy enough. I'll write a case that given three vertices will move the origin to the circumcenter.
Post Reply