How to select everything touching a bounding box?
-
Well,
My last foray into asking a question in this forum went so well that I think I'll give it another shotI am trying to write a script to draw something that I once drew by hand so that I can parameterize it, tweak the parameters, and see what I get for results. One of the things I did by hand was to select a bunch of drawing elements (lines, arcs, faces, etc...) by dragging my mouse from right to left (and bottom to top) across my drawing. I would then either move or rotate the bunch of things.
How can I accomplish something similar from a Ruby script? Basically, I would like to select everything to the right of some plane that is parallel to the Y-Z plane (i.e. at some offset x from the Y-Z plane.)
I suppose I could iterate through all of the entities in my drawing and look at some indication of the minimum and maximum coordinates and if both x coordinates are greater than "x", I could add that entity to my selection list. But what happens when, tomorrow, I decide that my selection criteria is no longer parallel to the Y-Z plane, but is parallel to some arbitrary plane?
What I probably want to do is to write a support function to do this for me. But, usually when I have an idea for a support function like this, I find out that somebody else already has a much more full-featured solution to my tiny problem (witness Chris Fullmer's shape bender tool).
Has anybody already solved this problem? Can I use your solution? Can you point me in a good direction to get started?
Thanks again...
--wpd
-
I'm not entirely sure I understand the problem, but here is my take on what I think you are asking.
If it was a simple shape like a box, or sphere, all loose, connected geometry, you could:
Take all entities in the model and make an array (I'll call it called all_ents)
Make an array of all_ents[0].all_connected
Then subtract that array of elemtents from the all_ents array.That will give you an array of entities in the other object in the model.
Does that even begin to get at what you are trying to figure out?
re-reading your question, I'm not sure that is really what you are looking for. How about a diagram?
Chris
-
Hi Chris,
What I am trying to do, for example, is to select everything to the right of x=10. With the GUI, I would zoom out to see everything, choose the select tool, press the mouse button and draw a box around everything to the right of X=10. (Of course, in the GUI, I probably wouldn't know exactly where x=10 was, but by looking at my model, I would know that I wanted to selected everything to the right of some particular feature in my model.)Then I might want to rotate all of those entities. Or I might want to move them a little to the right. Or I might want to delete them...
I'm just trying to figure out how to do programatically what is very easy and intuitive when using the GUI.
Does that make more sense yet?
--wpd
-
I think that helps. I don't understand the workflow very well, but that's not for me to question I suppose!
What about making a tool (a true "tool", which is more complex than just a standard script in SU in my opinion, it lets you interact with the mouse, which is important). So what bout a true tool so you could activate your script, then make it s the first click defines the xyz coordinate to use as the base. Then the 2nd click defines the vector (direction to select from you first point.
Or you could greatly simplify it if you made it so that it always select "to the right" of your model. Then just a single click to define the x=?? position, and then iterate through all entities to figure out which ones should be selected.
Or to avoid using the "tool" class in SketchUp (which might be a good idea on your first version of the script, until you get it worked out), you could find the x=?? point by forcing the user to have a selection made when they run the script. then the script would just iterate though the model.selection to find the max x position, and use that to define where to start selecting from. I think this option (though less robust) might b a good way to start the script. Then once its working, try the version above and add the tool class and make it so the user can define X with a mouse click. Then when that is working, go for the full blown version with two clicks (2 clicks is exponentially harder because you will be implementing SU's inferenceing engine, which might be easy once you understand it, but I still have NO clue how to get it working correctly).
Does that get closer to answering the real question?
-
I think that you are mistaking me for somebody who knows a lot more than I do
I want to do something much simpler than what you have described. To give a (ficticious, but concrete example), suppose I had a script in which I had drawn a bunch of lines, arcs, faces, etc... In that script, I would like to select every entity that exists to the right of the plane defined by x=1. Then I would like to rotate all of those entities by 10 degrees (about the Y axis).
I think that I need to start by grabbing a hold of all of the entities that exist to the right of x=1.
I'm just not sure how to do that.
It seems like this would be a good candidate for a helper method.
It seems like somebody has probably already figured out how to do this and may have even published the helper method.
If not (to both), then I think I just need to iterate through all of the entities in my model, keep track of which ones start or end at x > 10, select them or add them to a group, and then rotate, move, delete, or do whatever I want to do to that selection/group.
--wpd
-
I doubt that anyone has published a helper method to do exactly what you are looking for. But you have the logic correct. First clear the selection (in case the user has something selected). Then search through all entities and find the ones on the wrong side of x. Then add all those to the selection set.
` model = Sketchup.active_model
ents = model.active_entities
sel = model.selection
sel.clear!ents.each do |e|
if e is on the wrong side of x- Add your code here
sel.add e
end
end`Everything in that "your code ghoes here" part needs to decide what type of entity is being looked at and then you have to specify how to determine if that entity is on the wrong side of x. To simplify it, you could just look at the bounding box of each entity and determins if the center of the bounding box is on the wrong side of x. If it is, then add it. That would be the simplest way and would look something like this:
if e.bounds.center[0] > my_x sel.add e end
Chris
I guess I pretty much wrote the whole thing, so I might as well just finish it up. Here is a whole little snippet of working code:
` model = Sketchup.active_model
ents = model.active_entities
sel = model.selection
sel.clear
my_x = 0.0ents.each do |e|
if e.bounds.center[0] > my_x
sel.add e
end
end`
Advertisement