@sdmitch said:
What defines a good or bad pairing?
No overlap when moved center to center. Where 'center' is center of paired face.
@sdmitch said:
What defines a good or bad pairing?
No overlap when moved center to center. Where 'center' is center of paired face.
You know, I've yet to solve the problem of adding an image to a post? Never-mind...it pays to actually look at the screen staring you in the face...doh!! These are all individual groups. Here is a correctly paired and moved (face center to face center) pair followed by an incorrect pairing...Ignore the purple dot and odd selection coloring, they are not germane.
Thus far I've found 13 pairings that fail for obvious reasons:
I will continue to test at least until I figure a way to code, detect and fix.
@sdmitch said:
No, it can be negative. The sign of 'z' of the product of the two vectors you are using to determine the angle_between should be the sign of the angle of rotation.
Very good to know. I just built a 3d grid of nine boxes to see how many bad pairs I can find. Anything on a diagonal path is bad so far. That arrangement seems like it should be all of the possible pairings but I'm not yet confident enough to bet the farm on it.
@sdmitch said:
So you would like to specify the "face" on the "moved" object which is to be "paired" with a specified face on the "fixed" object?
Pretty much. As part of the existing code I already know the orientation of the two object BB faces. And have written code for opposite? so I know when things are amiss. The rotate90 code is also written. I'm now pondering the code between. And wondering if rotation will always be positive.
When I say face in this instance I'm speaking of the side of a bounding box and not a SU face. My problem stems from a naive assumption on my part, that the closest pair of faces of two objects would be what I think of as 'opposing', i.e. right with left, top with bottom and so on. Only a second or two of visualization would show that this is not so. Right may easily pair with front, rear with left and similar. Needless to say this does not lead to good result.
So the obvious solution is to rotate the object into 'paired' alignment. My problem is that I'm having trouble thinking of such a solution. Clearly the un-aligned would have to be rotated to match the target but what does that imply? I mean it is obvious that right would have to rotate to become rear in order to match up with front...and I suppose that means a rotation around the z-axis assuming normal orientation. Seems like it would always be a single 90Β° right or left(around the given axis).
So the sledgehammer approach is to map out each possible rotation and apply it. Which leads me to ask is the a better solution?
As is often the case the problem is simpleβcode in question works much better if properly invoked:
pk = HSM_Picker.new()
mod.select_tool(pk)
Thanks all, sorry for the stupidity
@thomthom said:
@hsmyers said:
@thomthom said:
What is the value you get from .best_picked?
That should only return an entity - so I wouldn't expect @@picks.length to work. (Unless you accidentally picked an edge - in which case you are getting the length of the edge.)
Don't know, will find out...oh the joys of print statements!
Try the debugger: https://github.com/SketchUp/sketchup-ruby-debugger
I prefer RubyMine for debugging: http://forums.sketchup.com/t/please-help-me-to-setup-de-debugger-on-rubymine-for-mac/289
Hmmm...haven't used any, could be interesting...
@thomthom said:
What is the value you get from .best_picked?
That should only return an entity - so I wouldn't expect @@picks.length to work. (Unless you accidentally picked an edge - in which case you are getting the length of the edge.)
Don't know, will find out...oh the joys of print statements!
Back to debugging... The following appears to run without errorβor actually without doing anything other than returning "[]"!
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
SKETCHUP_CONSOLE.clear
class HSM_Picker
@@picks = []
def activate
@@picks = []
Sketchup.set_status_text('Select an object', SB_PROMPT)
end
def deactivate(view)
view.invalidate
end
def onLButtonUp(_flags, x, y, view)
ph = view.pick_helper
ph.do_pick(x, y)
@@picks << ph.best_picked
if @@picks.length == 2
p 'done'
Sketchup.active_model.select_tool(nil)
end
end
def onCancel(_flag, _view)
Sketchup.send_action('selectSelectionTool;')
end
def picks
@@picks
end
end # class HSM_Picker
pk = HSM_Picker.new()
ets = pk.picks
Implication clearly being that I don't know what I'm doing (certainly true!) So once again begging for clues here... In line with previous I had expected
ph.do_pick(x, y)
to politely wait for the user to make a selection (or two) and then be available for interrogation but I fear that may have been naive. My initial understanding ( or miss in this case ) is often warped by my expectations based on years of building APIs more sigh
@sdmitch said:
In the API the ph = view.pick_helper statement does not does not have variables passed to it. Taking off the (x,y) made it work for me.
class HSM_Picker
> def activate
> @@picks = []
> Sketchup.set_status_text('Select an object', SB_PROMPT)
> end
>
> def deactivate(view)
> view.invalidate
> end
>
> def onLButtonUp(_flags, x, y, view)
> ph = view.pick_helper
> ph.do_pick(x, y)
> @@picks << ph.best_picked
> if @@picks.length == 2
> p 'done'
> Sketchup.active_model.select_tool(nil)
> end
> end
>
> def onCancel(_flag, _view)
> Sketchup.send_action('selectSelectionTool;')
> end
> end # class HSM_Picker
> Sketchup.active_model.select_tool HSM_Picker.new
Ah! On such screw-ups as this are founded the bugs that plague us! Much and many thanks sir.
@thomthom said:
Can you elaborate to what didn't work and what you expected to see happening?
Never having used PickHelper, I really didn't have any expectations other than a vague notion of some indication that the code was in control of the 'pick' process but I saw no such indication during testing. I noticed that what I was printing to the console didn't appear which suggests an error of some sort...which I foolishly failed to save, I clear the console with each run head slap I'm not even all that clear on how I should integrate what I need with the tool under developmentβroll it into the tool or separate class within?
I'm trying to allow the user to pick two objects with the intent to align the second selection with the first. I'll allow embroidery regarding axis and points later. With that in mind I thought this was a good chance to use PickHelper. So I created a small class as follows:
class HSM_Picker
def activate
@@picks = []
Sketchup.set_status_text('Select an object', SB_PROMPT)
end
def deactivate(view)
view.invalidate
end
def onLButtonUp(_flags, x, y, view)
ph = view.pick_helper(x, y)
ph.do_pick(x, y)
@@picks << ph.best_picked
if @@picks.length == 2
p 'done'
Sketchup.active_model.select_tool(nil)
end
end
def onCancel(_flag, _view)
Sketchup.send_action('selectSelectionTool;')
end
end # class HSM_Picker
This for reasons unknown to me does not work. In my effort to debug I wrote the following snippet in the console:
x = y = 0
view = mod.active_view
ph = view.pick_helper(x, y)
ph.do_pick(x, y)
best_entity = ph.best_picked
As you might guess this did not work either.
So what am I doing wrong? Efforts to amend my abysmal ignorance will be deeply appreciated!!
@sdmitch said:
@hsmyers said:
how about closest pair of points?
Since you are only dealing with two objects, it shouldn't matter which is sel[0] or sel[1]
To find the closest corners of two objects
mod = Sketchup.active_model
> .
> .
> .
> UI.messagebox "Obj0 Cor#{m} to Obj1 Cor#{n} is #{Sketchup.format_length(md)}"
>
Thank you for the snippet!
You are correct excepting that the tool in question will move one of the two objects such that the opposing face centers are touching plus or minus an offset. Sorry for the grossly incomplete spec My plan (very fluid and quite murky ) is take the first selection as the moving object and the second as the fixed object. I've some notion about non-parallel faces requiring ( optionally ) an rotational adjustment. However it's my goal to keep things as simple as possible. My usage is to stack components together to assemble the model much like one would in actuality. Hex nuts, lock washer on threaded rod etc.
Additionally, there is the self-educational aspect of solving the which selection is on first This tool already has four options and looks to acquire one or more in the future. So it seems prudent to solve this now to make ready for the unforeseen. 'Sides any excuse to cut code!!
@dan rathbun said:
@hsmyers said:
I'll be using the faces from the bounding box of each object.
Bounding Boxes are virtual geometric "helper" objects that do not have faces.
True but it is easy enough to construct the necessary 'face' and then derive the center. I should have been more clear. Hmmmm...that said, how about closest pair of points? A sorted list of 64 lengths? Or is the something less sledgehammerish?
@unknownuser said:
@hsmyers said:
How do I reliably tell first selection from second? Currently it's the simple minded
@sel[0]
and@sel[1]
as first and second where@sel
results fromSketchup.active_model.entities.selection
.You will need to implement a
[%(#BF0000)[SelectionObserver]](http://www.sketchup.com/intl/en/developer/docs/ourdoc/selectionobserver)
subclass.
Ah! A little bit deeper into the tool pool...splash!! Thanks for the tip and the correction Any ideas on the revised question?
Imagine two selected objects. I'd like to determine the closest pairing of one face from each. I'll be using the faces from the bounding box of each object. My goal is to move one from the BB center to it's opposing BB center, but that is later and I've cobbled code to do so. What I'm currently doing is a distance from CP to origin and then comparing the two. It works some times and fails the rest of the time. This may be influenced by a second problem and that has to do with selection. How do I reliably tell first selection from second? Currently it's the simple minded @sel[0] and @sel[1] as first and second where @sel decends from Sketchup.active_mode.entities.selection.
In sum, I'd like to know how to:
Will bake cookies!!
@thomthom said:
model.tools.push_tool(tool) model.tools.pop_tool
http://www.sketchup.com/intl/en/developer/docs/ourdoc/tools#push_tool
My thanks...and off to read the fine manual (err...what manual?) again
I'd like to come back from using my tool with the previous cursor restored or lacking that switch to the nil cursor. I realize this implies a switch back to the previous tool selected. Is there some ruby API way to accomplish this?
@jim said:
However, the .stl export does work. What's better is that FreeCAD does not need to be running to convert a .step to .stl. The FreeCAD Python API can be used to convert the file and a plugin can be made to import .step as an .stl from SketchUp.
Slight improvement, tested and working:
# step2stl.py
FREECAD = 'C;\\Program Files\\FreeCAD 0.15\\bin'
import sys
sys.path.append(FREECAD)
import FreeCAD
import Part
part = Part.read(str(sys.argv[1]))
part.exportStl(str(sys.argv[2]))
Late to the dance, but just ran into the problem => Thanks Jim !!
@dan rathbun said:
Then you'll need to follow:
http://extensions.sketchup.com/en/developer_center/ew_developer#rbz
I've read through same and I plan to do so again more thoroughly again after I get this next layer of magic nailed down. I think I now understand the two file format well enough to give it a spin in a bit but am momentarily busy prepping prototype parts for shapeways. Its been tool, prototype, tool, proto in a kind of recursive spiral! Need one for the other and round about we go...
@tig said:
Get some others recent Extensions to see how it's done by them...
e.g. some of my recent ones like "LayerWatcher"...
Cool!! I will