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: 3192
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Discussion on placement

Post by edwilliams16 »

zardozer wrote: Thu Jun 10, 2021 1:12 am
Btw, you can expose Placement on a basefeature in a body. You have to right-click on the properties panel and select 'show all'. Why it's not exposed by default, I'm not sure.
Forgot all about that. Sigh.

Finding the coordinate vector to subtract off the BaseFeature Placement is a case type statement

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()
        
User avatar
onekk
Veteran
Posts: 6222
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Discussion on placement

Post by onekk »

From what I have seen, the placement property is related to the object to to the Shape.

Or to be more precise, each objects has his "position", for primitives there is the "build position", the "reference point" that is not "copied" when you do copy or duplicate a "shape".

You could hardcode this "position" if you make it in another way, saying supplying the vertex and create a BREP representation, is such case, as you state the "absolute vertex" coordinates it will be "copied" as they are "stored in the shape itself".

When dealing say with boolean operation, the resulting object has it's own "reference point" that is (0,0,0), but it take the relative position to (0,0,0) using placement properties of the "generating" objects.

I usually find this behaviour very useful, as you could simply create an object and place his "reference" point in a "definite position" to be more easy to place them in the ifnal assembly.

As a little example, i Create a Bolt and then place the (0,0,0) of the Bolt at center of the shaft and just under the head, so I could reuse the placemente properties of the "boring cylinders" as placement property of the "bolts" when the object is assembled, correcting programmatically the "boring cyclinders" placement to make a "proper cut" of the final body.

As with STL file, the format is not "very smart" as it is simply not much mor than a "bunch of vertex coordinates".

I consider STL only the "final format" to use when 3D printing, as as an interchange format is not holding relevant data, if you make a cylinder in STL you could guess the diameter and the heigth using the bounding box data, but for a more complex form it is not immediate to obtain lenghts and other measures.

Sorry if this post is not adding much to the discussion, a part from my personal use of the peculiar way FreeCAD store the "reference position" of an object.

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/
drmacro
Veteran
Posts: 9009
Joined: Sun Mar 02, 2014 4:35 pm

Re: Discussion on placement

Post by drmacro »

At this point it is clear how to get the info required to reposition something.

But I would still like to understand the logic or reason adding a component to a container overrides user specified repositioning to a position that is clearly not what the user has specified.

And, if this is some sort requirement of a Body and if there is a way to override the override.

And (I need to check this is true, think this is what I saw the other day...) why does a step component stay put? Seems it should work the same for all components whatever the source.
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
drmacro
Veteran
Posts: 9009
Joined: Sun Mar 02, 2014 4:35 pm

Re: Discussion on placement

Post by drmacro »

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
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
User avatar
onekk
Veteran
Posts: 6222
Joined: Sat Jan 17, 2015 7:48 am
Contact:

Re: Discussion on placement

Post by onekk »

I think, that is only a guess that adding an object to a container will reset his placement property.

What type of container you are talking about, I've seen this "reset" when copying the "object.Shape" or the "TopoShape" to be more precise, as the Placement is a property of the "data" part and is not "copied".

I think that speaking of "primitives" is a understandable behaviour, when dealing with solids that are subject to boolean operation is another way.

It resemble the way "colors" are not preserved as they are applied to the "whole" container (a compaound in my case), and the individual colors of the "components" of the container are not applied, but they are present in the "elements of the container", they are simply "overridden" by the property of the "high gerarchy" element (the container).

But when dealing with compound placement is preserved, only the "compound" placemente could be added to the "element" placement

Code: Select all

import FreeCAD
from FreeCAD import Rotation, Vector
import Part


ROT0 = Rotation(0,0,0)


dsp1 = Vector(10,10,0)

obj1 = Part.makeBox(10,20,10)
obj1.Placement = FreeCAD.Placement(dsp1, ROT0)

#Part.show(obj1, "box")

dsp2 = dsp1 + Vector(5, 10, 5)

obj2 = Part.makeCylinder(2,15)
obj2.Placement = FreeCAD.Placement(dsp2, ROT0)

#Part.show(obj2, "cyl")

obj3 = obj1.fuse(obj2).removeSplitter()

Part.show(obj3, "fusion")

print(obj3.Placement)


As you can see the Placement of obj3 is:

Code: Select all

Placement [Pos=(0,0,0), Yaw-Pitch-Roll=(0,0,0)]

But this is something you know (pass me the example as a more articulated discussion, maybe in case someone more skilled will read this thread).

now there is no way to revert to the "standard" placement of the "primitives" (cylinder and box), but this behaviour is well know and I think "what you want" as a fusion has "his own life".

Having doing so in scripting is not exposing anymore the "components", using Gui you have the "fusion object" that contains the two "document object" of the primitives with the related placement that are "exposed and readable".

Maybe this is the Gui implementation that is "exposing too much" to the user, and maybe a fusion object will be better to be a "single solid" instead of exposing the "elements".

This is "one of the possible ways" to do things, but at the end, once acquired the "normal way" of FreeCAD, it is not a big problem.

But if you speak of Body, you are talking of a Part Design component?

Sorry for Bothering but I've not perfectly clear the "problem core"


EDIT: I've seen your post, it remain to see how the position is stored in the original "object", in other word if the "original object" has a Placement property different from:

Code: Select all

Placement [Pos=(0,0,0), Yaw-Pitch-Roll=(0,0,0)]
If it has a Placement properties, this Property is resetted, so the problem will be "is this behaviour correct" or "when added to a Body the explicit user placement property has to be preserved or not"

Maybe analyzing the sourced code will make some light on the "addtoBody" method.

From my user point of view if not specified I will be wanting that the explicit Placement property will be respected so i could model the components in a separate way and add then to the body to be treated like a "whole part", but I don't know enough Part Design to argue about the decision taken in the developing phase.


Hope to have "centered the problem", if not sorry.

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/
drmacro
Veteran
Posts: 9009
Joined: Sun Mar 02, 2014 4:35 pm

Re: Discussion on placement

Post by drmacro »

I have looked at the Position object of an STL and STEP components.

It appears the issue is the the way the two formats handle the global and local coordinate system.

In the case of the STL file the LCS and GCS are the same. So, a point in the STL file that is vector vA is at GCS vector vA. (i.e. the position object of the point is set to GCS origin. Thus, why the inverse of vA moves it to the origin. But, the position object is now set -vA.)

In the case of STEP the position object vector vB is set to the offset from GCS origin (establishing the LCS of the component). So, setting vB to 0.0 moves the LCS to GCS origin.

So, when the moved STL component is dropped into a Body, it's position object is use to set it relative to the Body LCS making the BaseFeature appear to back in it's original location. (and, in fact, it sets the position object back to the origin [even the yaw-pitch-roll value is returned to 0 if it has been modified])

In the STEP file this does not happen and it remains where the user expects.

Is would appear all the data of the STL file would need to be processed to adjust the data and set the position object to the desired location (for example to the origin).
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
edwilliams16
Veteran
Posts: 3192
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Discussion on placement

Post by edwilliams16 »

So far it seems that STEP import is the only outlier - retaining its placement when made a BaseFeature. Is this parametric? That is, what happens if you change the placement after you created the BaseFeature? If you want to base multiple bodies on the same imported object, how does that work?

This all seems reminiscent of whether vertex coordinates do or do not include the effect of the enclosing placement in https://forum.freecadweb.org/viewtopic. ... a5#p225497 Not consistent there either...

It's clearly an equal amount of work for the user (or the user's macro) to adjust the Placement before or after import into a BaseFeature, so we are discussing consistency and the mental model of what is happening and maybe the amount of computer cycles required, but not the effort the user has to put in.
drmacro
Veteran
Posts: 9009
Joined: Sun Mar 02, 2014 4:35 pm

Re: Discussion on placement

Post by drmacro »

edwilliams16 wrote: Thu Jun 10, 2021 5:18 pm So far it seems that STEP import is the only outlier - retaining its placement when made a BaseFeature. Is this parametric? That is, what happens if you change the placement after you created the BaseFeature? If you want to base multiple bodies on the same imported object, how does that work?
IGES is the same as STL, it moves when dropped in a Body.
This all seems reminiscent of whether vertex coordinates do or do not include the effect of the enclosing placement in https://forum.freecadweb.org/viewtopic. ... a5#p225497 Not consistent there either...

It's clearly an equal amount of work for the user (or the user's macro) to adjust the Placement before or after import into a BaseFeature, so we are discussing consistency and the mental model of what is happening and maybe the amount of computer cycles required, but not the effort the user has to put in.
I suppose you could recommend the workflow to be: drop it in a Body, then move it.

The whole concept makes FreeCAD look/feel like a hack tool. There shouldn't be caveats about moving things. The user moved it, it stays moved.
Now, if there is a benefit to it working that way then explaining to a user why they need to take special steps for particular types of input maybe it's more palatable.

Clearly the STL and IGES format don't handle placement in the terms FreeCAD expects. But, the import should make accommodation (IMO).

"My STL or IGES file is off in never-never-land how do I fix it" is a VERY common question.
Star Trek II: The Wrath of Khan: Spock: "...His pattern indicates two-dimensional thinking."
edwilliams16
Veteran
Posts: 3192
Joined: Thu Sep 24, 2020 10:31 pm
Location: Hawaii
Contact:

Re: Discussion on placement

Post by edwilliams16 »

It is not just imports. If you make something in the Part workbench and make it a BaseFeature then it it doesn't bring in its placement either.

I don't know about IGES, but the result of bringing in an STL and making it a solid results in a Part::Feature object, just like a Part primitive.
This does reduce the number of places the code would need to be changed, but gives an opportunity to break models in the middle of the tree. (Like make an object in Part Design, slice it in two in Part, make two BaseFeatures and continue in Part Design. I've done this several times. This might still work OK - it might not.)

BW, I'm not wedded to the current behavior - I agree 'move first then make a body' is a bit more intuitive than 'make body then move'. But for me, I'd go for consistent behavior as first priority.
zardozer
Posts: 49
Joined: Sat Nov 07, 2020 2:35 am

Re: Discussion on placement

Post by zardozer »

drmacro wrote: Thu Jun 10, 2021 9:12 pm
IGES is the same as STL, it moves when dropped in a Body.


"My STL or IGES file is off in never-never-land how do I fix it" is a VERY common question.
Hmm, maybe I'm missing something, but don't a lot of STEP files also exhibit the 'moves back to original location' problem?

I'm attaching this random STEP I downloaded from GrabCAD. Let's say you import it, and it results in a Part container with four parts in it: Correct Thread, Correct Thread001, Correct Thread002, Correct Thread003.

Let's say you want to move Correct Thread002 so that the circular part is centered on the global origin, and you want to edit it using a Part Design Body. When you make the Part Design Body, its origin matches the global origin. You drag the Correct Thread002 outside the Part container, then you transform it to be at the origin. Now if you take that transformed part and drag it into the Part Design Body to make a basefeature, it pops back to its original location.

So what you can do now is "show all" in the basefeature's properties, then set its placement to be the same numbers as when you first transformed the part. But you don't get to use the Transform UI for basefeatures. Basically, the basefeature doesn't retain the transformation of the part.

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.
Attachments
Correct Thread.STEP.zip
(874.06 KiB) Downloaded 42 times
Post Reply