How to transform InputPoint to local coordinate system?
-
@tt_su said:
If you are interested in InputPoint.position to be in the local coordinates then transforming it with model.edit_transform.inverse is the way to go.
If you want to pick positions inside of nested component, say the user picks an edge vertex inside a group and you want to get the position relative to that edge's parent group then you want InputPoint.transformation.inverse.
A part of my problem I guess is that I the edit_transform does not help me unless the user has navigated all the way down in the tree so that the surface to be modified is considered the local scope. I only ran into the problem when I used my drilling tool to arbitrarily drill holes in faces without making sure that the group containing the face was open for editing. (From a theoretical point of view, I am well aware of the fact that it may not be desirable to allow a part to be edited unless the part is 'opened'). However, I wanted to see if there was another way. As you pointed out, the InputPoint.transformation just gave me a relative transformation, so whenever I added lines using that transformation, they had a chance to be added in a different spot as they are supposed to be added relative to the group they are added in and not relative to the feature that InputPoint used for its navigation. (It worked fine as long as I clicked on faces directly as InputPoint had no choice by to find the transformation of the actual face. The problem became apparent when I used features outside the group to guide the mouse.
Anyway, this information was very helpful and I learned a lot more than I originally asked for and I hope that we leave a trail that others may find useful. (I tried to google this problem for a good hour before I asked, that's why I am a little more elaborate than for a simple question )
regards,
Stefan -
@tt_su said:
If you are interested in InputPoint.position to be in the local coordinates then transforming it with model.edit_transform.inverse is the way to go.
If you want to pick positions inside of nested component, say the user picks an edge vertex inside a group and you want to get the position relative to that edge's parent group then you want InputPoint.transformation.inverse.
I noticed that InputPoint.transformation is bugged and does not always return the real transformation (instead it may return the tr identity). So I now rely on Pickhelper, but this is a pity in many simple case where you don't care which group or component the picked elements belong to.
Fredo
-
@fredo6 said:
I noticed that InputPoint.transformation is bugged and does not always return the real transformation (instead it may return the tr identity). So I now rely on Pickhelper, but this is a pity in many simple case where you don't care which group or component the picked elements belong to.
Can you produce a reproducible example?
-
@tt_su said:
Can you produce a reproducible example?
No problem, but that's not a problem with the model.
In the example below (SU14), I just hover the mouse over a component containing other components.
ip.pick view, x, y
puts "tr = #{ip.transformation.to_a}"I also show the all_picked value of a parallel ph.do_pick
As you can see, there are cases where the transformation of the input point is the Identity.
Fredo
-
Got the code snipped you used? (Fully working Tool)
With your model and this snippet I wasn't able to reproduce it.<span class="syntaxdefault"><br />class InputTool<br /><br /> def initialize<br /> </span><span class="syntaxkeyword">@</span><span class="syntaxdefault">ip </span><span class="syntaxkeyword">=</span><span class="syntaxdefault"> Sketchup</span><span class="syntaxkeyword">;;</span><span class="syntaxdefault">InputPoint</span><span class="syntaxkeyword">.new<br /></span><span class="syntaxdefault"> end<br /><br /> def onLButtonDown</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">flgas</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> x</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> y</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> view</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> </span><span class="syntaxkeyword">@</span><span class="syntaxdefault">ip</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">pick</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">view</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> x</span><span class="syntaxkeyword">,</span><span class="syntaxdefault"> y</span><span class="syntaxkeyword">)<br /></span><span class="syntaxdefault"> puts </span><span class="syntaxstring">"Position; #{@ip.position}"<br /></span><span class="syntaxdefault"> puts </span><span class="syntaxstring">"Edge; #{@ip.edge}"<br /></span><span class="syntaxdefault"> puts </span><span class="syntaxstring">"Face; #{@ip.face}"<br /></span><span class="syntaxdefault"> puts </span><span class="syntaxstring">"Vertex; #{@ip.vertex}"<br /></span><span class="syntaxdefault"> puts </span><span class="syntaxstring">"Depth; #{@ip.depth}"<br /></span><span class="syntaxdefault"> puts </span><span class="syntaxstring">"Transformation; #{@ip.transformation.to_a}"<br /></span><span class="syntaxdefault"> end<br /><br />end<br /><br />Sketchup</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">active_model</span><span class="syntaxkeyword">.</span><span class="syntaxdefault">select_tool</span><span class="syntaxkeyword">(</span><span class="syntaxdefault">InputTool</span><span class="syntaxkeyword">.new)<br /></span><span class="syntaxdefault"> </span>
-
Thomthom,
This happens from time to time, in general when you have embedded groups or component, and possibly when they are remote inferencing within the group or component. Maybe this is also due to moving the mouse fast when hovering over the group / component.
However it happens frequently enough, and on various models, that I did renounce to use ip.transformation and switch to PickHelper for this type of information. This is fine, but the only issue I noticed is that sometime InputPoint and PickHelper are themselves desynchronized, that is, InputPoint will pick something under the mouse (not remote) and Pickhelper won't. Usually, I set the precision of Pickhelper.do_pick to 5 to get similar results.
Fredo
-
When you get identity transformation, did you check the depth? Maybe the position of IP is coming from an inferred point and therefore isn't coming from inside the group/component you click on?
-
@tt_su said:
When you get identity transformation, did you check the depth? Maybe the position of IP is coming from an inferred point and therefore isn't coming from inside the group/component you click on?
That was exactly the problem that I was having initially which prompted me to ask my question. The only reliable way that I found to solve this was to use a combination of InputPoint and PickHelper.
InputPoint will give the face that I am looking for and I iterate through the results from PickHelper until I find the same face. PickHelper will always return the correct transformation for the face, but InputPoint may (as you pointed out) return the transformation of something else. The design of InputPoint is a little limited for what one may want to do. InputPoint can return a face and an edge at the same time, but if those two entities belong to different groups, the transformation returned by InputPoint will obviously never be able to apply to both entities at the same time.It might be desirable to extend InputPoint so that it can return the transformation for each of the different entities that it can refer to. Or at least add a note to the documentation that the transformation might not be useful for all referenced entities.
regards,
Stefan -
@f94sbu said:
It might be desirable to extend InputPoint so that it can return the transformation for each of the different entities that it can refer to. Or at least add a note to the documentation that the transformation might not be useful for all referenced entities.
The purpose of InputPoint isn't to pick entities, that's why there is differences between the PickHelper.
The fact that is returns a face, edge, or vertex is simply meta data to indicate what it gets the position from.
Are you trying to pick an entity and at the same time get a 3d position? Can you explain the use case for this?
-
@tt_su said:
@f94sbu said:
It might be desirable to extend InputPoint so that it can return the transformation for each of the different entities that it can refer to. Or at least add a note to the documentation that the transformation might not be useful for all referenced entities.
The purpose of InputPoint isn't to pick entities, that's why there is differences between the PickHelper.
The fact that is returns a face, edge, or vertex is simply meta data to indicate what it gets the position from.
Are you trying to pick an entity and at the same time get a 3d position? Can you explain the use case for this?
It took me a while to understand the difference between PickHelper and InputPoint, and your explanations were very helpful. The documentation was rather vague as it mostly described the two as 'similar' but did not go into depth of the difference.
This is the use case:
I have created a 'drilling' tool that allows you to drill holes through objects. I am using Sketchup for mechanical construction and I needed a way to place (and track) screw holes in my model. The usage of the tool is rather simple, just click a face and the tool will ask you which drill size you want to use (and an optional depth for blind holes). The tool will then create a circle on the face (centered around the click), push the cut surface through the object and then it records the center by placing a cross (2 edges) in the center of the circle. The drill size used is also assigned as an attribute to one of the edges so that I can iterate through the model at a later time (during G-code generation) to generate G-code for drilling the holes. The purpose of the cross is to have an anchor for the hole when you want to line things up (such as screws or objects with corresponding holes). Most of the time, matching holes will be of different sizes as one hole is sized for the screw and the other is sized smaller to use a tap to create threads in it. (That's why I don't rely on Sketchup's ability to snap the two holes together.)Also, if I have added a hole to an object and I want to drill the corresponding hole, all I need to do is to add a guide that is perpendicular to the hole by grabbing a perpendicular edge and then snap the guide with the center of the cross.
To accomplish the above I needed to get the following things to work:
- To push the hole through, I obviously needed to get the face to modify, but I also need to get this in the local coordinates of the face as I am adding entities to the same group/component as the face it self, otherwise I would just add a cylinder, not a hole, and it is desirable tha the holes move with the component if I rearrange things
- To know which 3d coordinate to use, I need to get the 3d coordinate that the user clicked on, but this needs to be snapped to whatever guide that the user used. As often place holes referenced from other holes, I need to make sure that the 3d point is snapped correctly. Most of the time, I create the guides without caring about which group that is open for editing. The transformation returned by InputPoint will be from the guide which is often different from the transformation of the group that I will be modifying.
PickHelper gives me all that I need (picked face and translation) except that it does not tell me the 3d coordinate that was snapped from the mouse x,y. Thats what I need to use InputPoint for. I guess I could disregard the face returned from InputPoint, I just added a comparison between the face from InputPoint and the leaf in PickHelper to make sure that they are equal in case something goes wrong and PickHelper does not pick the same face as InputPoint snapped to. I guess this is unlikely (impossible) and I have not yet seen them to be different, but I just felt it was a good safeguard.
So short answer I guess would be, Yes I need to pick an entity at the same time as I am picking a (snapped) 3d position
I would not be surprised if the 'problem' fredo described is related to what you described about InputPoint. InputPoint may have used several entities to snap its position and as it is not possible to tell which of them that was the origin for the transformation in InputPoint, the transformation in InputPoint is most of the time too ambiguous to be used for editing or adding entities.
-
In your case that you describe I would have used construction lines and construction points for the markers - instead of edges. This is because edges might "stick" to other geometry while construction doesn't.
You can aid your pick helper by adding an attribute to the construction geometry so when you do your pick you can use this to get the position of the construction point.Since InputPoint infer from many source I'm not sure we can provide transformations in the same manner as the pick_helper. I think that even the native tools sometimes use both in combination - but you need to beware that "picking" results can differ.
As for the docs, yes, there are much to be improved. For PickHelper I spent a lot of time trying to work out what it actually did. The description is poor and it's function is overloaded as it let you pick entities as well as "virtual" points and segments.
I didn't fully grasp it until I visualized what a pick looked like:
http://www.thomthom.net/thoughts/2013/01/pickhelper-a-visual-guide/ -
@tt_su said:
In your case that you describe I would have used construction lines and construction points for the markers - instead of edges. This is because edges might "stick" to other geometry while construction doesn't.
You can aid your pick helper by adding an attribute to the construction geometry so when you do your pick you can use this to get the position of the construction point.Since InputPoint infer from many source I'm not sure we can provide transformations in the same manner as the pick_helper. I think that even the native tools sometimes use both in combination - but you need to beware that "picking" results can differ.
As for the docs, yes, there are much to be improved. For PickHelper I spent a lot of time trying to work out what it actually did. The description is poor and it's function is overloaded as it let you pick entities as well as "virtual" points and segments.
I didn't fully grasp it until I visualized what a pick looked like:
http://www.thomthom.net/thoughts/2013/01/pickhelper-a-visual-guide/Thanks for the link, it is very helpful. When I first saw it I just didn't understand that I needed to use PickHelper
I thought about using clines but the drawback is that they disappear when I globally delete all guides. (Using Edit->Delete guides). The geometry that I create are created inside the hole to make sure that they don't stick to other things, but this cannot be avoided 100% obviously. (Edit: I just realized that I can make the crossing edges a group when I create them.)
I don't think it is a good idea to provide multiple transformations in InputPoint (now when I understand the logic behind InputPoint and PickHelper) and now I have started to think of the translation in InputPoint is highly unreliable as it is not possible to know from which entity it was derived.
-
We are working on getting a better developer site up and running, something that should aid in improving our docs.
-
@unknownuser said:
Postby tt_su » Tue Mar 18, 2014 8:08 am
When you get identity transformation, did you check the depth? Maybe the position of IP is coming from an inferred point and therefore isn't coming from inside the group/component you click on?
The bug reported by Freddo a few messages above seems to be related to inference points indeed. I always get the identity from ip.transformation when the position of the cursor is along an inference line.
Besides that, along inference lines, the ip.depth equals 0 and the ip.degree_of_freedom equals 1 independent whether a face was picked by the InputPoint or not.
Even along inference lines, the InputPoint position seems to be correct.
Update: Along inference lines, the InputPoint position seems to be the position of the point on the inference line and not of the cursor position.Ronaldo
Advertisement