Reading out origins of nested components
-
As the title says, I want to read out the origins of components, nested within other components. And as far as I can tell that task is not as trivial as it sounds. While searching and googling for something to answer my questions I only stumbled upon this:
https://groups.google.com/forum/#!topic/sketchupruby/nM4hRA2ioDIHere an exact description of what I want to do:
I have a bunch of components, which I can put together with guides. Per request I need a plugin that can check whether those guides are properly aligned. So ideally to do this I need a list of all origins of all according guides, then I can check all the distances and if everything is okay I will end up with a neat array full of pairs of (nearly) matching coordinates. Given I'd find a guide that has no other guide close, I'd have found some stray components. Working with that list once I'd get it is easy and I already have a solution for that.In short, I need the origins of nested and replicated guide components. There are 2 problems:
- The nested components have only 1 ComponentInstance name, regardless of how often I copy the parent component. This makes sense when reading the topic I linked above, however it also makes it exceedingly hard to even get a grip on those things I need the origin from.
- If I get a grip on them, I can't just go and read out the origin because the results will always be completely wrong, that is the given origin will be in relation to the parent, not to the global origin. The results would be right if I could read out the origins while in the context of the parent, which however is not possible because the Ruby API only offers the possibility to close active groups/components, not to open them.
I do have some ideas how I could still get to where I want to be, the only problem being that those ideas all would end in a plugin which would eat a lot of resources and time for a task that is actually rather simple.
Ideas:
- Copy the whole model, break down all components except for the guides, and read out the origins, afterwards delete all geometry that has been created in the process.
Very well possible and I also tried it. It should be obvious though that this takes rather long thanks to exploding almost every component in the model. - Fetch all guides that are present in the model, take a look at the parents and find out in which geometrical relation the guides are. Then extrapolate all needed origins by calculating them with the relation we got and the origins of all parents.
This should be more resource efficent, would need a rather excessive amount of code to work with scalable components though. And I have scalable components. - By making a copy of the model and making all components unique I could get a grip on the locations of all needed guides. This would be much more resource efficient and I wouldn't need to calculate the origins, however I'd still have the problem that the given origin would be wrong as it would be in relation to the parent.
So, anything I've overseen which would make this task easier? Any good ideas?
PS: Why do I get the origin in relation to the parent when I directly fetch the ComponentInstance.transformation.origin while not being in any edit mode, while I get the origin in relation to the global origin while I'm in the edit mode of the parent? Shouldn't it be right the other way around? Doesn't seem to make any sense to me, so if anyone could satisfy my curiousity as to why it is that way I'd be grateful as well.
-
All entities inside a component or group have xyz's relative to the component or group origin. So you have to apply the parent transformation. As you go down each level, the transformation becomes the product of all the transformation of the levels above.
This code will return a messagebox with all the names and origins of components in the selection. To test, enter Real_World_XYZ.main in the Ruby Console after loading. It would be simple to limit search to guide name.
module Real_World_XYZ def self.main mod=Sketchup.active_model sel=mod.selection sel.grep(Sketchup;;ComponentInstance).each{|tci| @msg="#{tci.definition.name} at #{tci.transformation.origin}\n" e=tci.definition.entities;t=tci.transformation; self.recurse(e,t) UI.messagebox @msg,MB_MULTILINE } end def self.recurse(ents,tran) ents.grep(Sketchup;;ComponentInstance).each{|ci| @msg+="#{ci.definition.name} at #{ci.transformation.origin.transform(tran)}\n" e=ci.definition.entities; t = tran*ci.transformation; self.recurse(e,t) } end end
-
I was wondering if there was a way to do it without going through all parent origins as I feared that might become very complicated, I didn't think about doing it like that (recurse) though. Your solution is right on the spot! Also I didn't knew about the grep method yet, so thanks for that as well.
Advertisement