Need some development help.
-
I don't want to be a recursive idiot (though I am) and need some help solving a problem.
Problem is I have all these nested components and they are named foo.
I need to remove all component instances named foo from their parents and place them in their own new component named foobar. I had some embarrassing failures at this and it is clearly over my head. I can use some pro suggestions/solutions and I am thinking a ruby script is the way to go as I can hardly maintain my sanity doing this much work manually. -
@skastafari said:
I don't want to be a recursive idiot (though I am) and need some help solving a problem.
Problem is I have all these nested components and they are named foo.
I need to remove all component instances named foo from their parents and place them in their own new component named foobar. I had some embarrassing failures at this and it is clearly over my head. I can use some pro suggestions/solutions and I am thinking a ruby script is the way to go as I can hardly maintain my sanity doing this much work manually.Maybe this will help.
@mod = Sketchup.active_model @ent = @mod.active_entities @sel = @mod.selection cntrs = @sel.grep(Sketchup;;ComponentInstance) for cntr in cntrs cde=cntr.definition.entities foos = cde.grep(Sketchup;;ComponentInstance).select{|ci|ci.definition.name=='foo'} foos.each{|f|tr=cntr.transformation*f.transformation; fb = @ent.add_instance(f.definition,tr); fb.definition.name='_foobar_' if Sketchup.version.to_i>=14 fb.definition.name='foobar' f.erase! } end
-
Okay, awesome. Thank you sdmitch. This definitely opens some doors for me. I did have some unexpected results. I wanted to get the foos out of their homes and into the foobar (for some nightlife), but instead my foos turned into foobars. (I have a hard time typing this without laughing a little.) I see how you got the transform for the foos which is important to keep their location the same once in the foobar, but after that I got lost. I really just want my foobar to be populated with foos. If I get this right there should be just one foobar.
-
How about a simple manual way of doing it...
If you want to keep the component definition [or any instances of it] named 'foo-container':
then add an instance of it [you need at least two], select it and right-click > context-menu > make unique; now it's named 'foo-container#1'; in Entity Info rename it as 'foobar' - there will be the original 'foo-container' left - if you don't want it delete it...If you do NOT want to keep component definition [or any instances of it] named 'foo-container':
simply select it and rename it 'foobar' in Entity Info - any instances will rename, there will be no 'foo-container' anymore ! The 'foobar' will be full of 'foos'...If you really want to do this 'in code' you can replicate the above steps in the API quite simply...
-
Okay to be honest, I am not sure there really is a manual way to acheive this result easily, as it would require you to enter each parent container simultaneously. I struggled with the fact that in SU you must first enter into a component in order to select a subcomponent, however the act of entering or exiting a component resets your selection set. I will always prefer to spend my time learning something useful as opposed to doing something laborious. Which is why I came here. So here is what I have been doing to learn from sdmitch's example and here is how I understand it currently, though I may be wrong.
@mod = Sketchup.active_model [highlight=#ffff00:3b775s2t]Gets a handle on current model also saves tedious typing[/highlight:3b775s2t]
@ent = @mod.active_entities [highlight=#ffff00:3b775s2t]Gets a handle on entities currently in the model[/highlight:3b775s2t]
@sel = @mod.selection [highlight=#ffff00:3b775s2t]Targets entities within the current selection set, though I have to admit I left this out[/highlight:3b775s2t]
cntrs = @sel.grep(Sketchup::ComponentInstance) [highlight=#ffff00:3b775s2t]This iterates the components in the selection and I think it is here mostly to get into the parent components containers[/highlight:3b775s2t]
for cntr in cntrs [highlight=#ffff00:3b775s2t]Here some logic, I believe cntr is a placeholder for future transforms to objects returned from above iteration. The fact that it appears undefined makes me believe it is part of recursive process.[/highlight:3b775s2t]
cde=cntr.definition.entities [highlight=#ffff00:3b775s2t]I think this is both a shortcut and a way to define cntr without error to prepare for next line[/highlight:3b775s2t]
foos = cde.grep(Sketchup::ComponentInstance).select{|ci|ci.definition.name=='foo'} [highlight=#ffff00:3b775s2t]Where we find and grab all the foos with yet another iteration[/highlight:3b775s2t]
foos.each{|f|tr=cntr.transformation*f.transformation; [highlight=#ffff00:3b775s2t]This is where I start to get lost, or should I say go splat? I do understand this is where we get transform data from though.[/highlight:3b775s2t]
fb = @ent.add_instance(f.definition,tr); [highlight=#ffff00:3b775s2t]Here is where I start to have a problem, we do need to put the foos outside their original container and into a new container called foobar but...[/highlight:3b775s2t]
fb.definition.name='foobar' if Sketchup.version.to_i>=14 [highlight=#ffff00:3b775s2t]we are doing it from within foos.each which is how I think my foos got turned into foobars[/highlight:3b775s2t]
fb.definition.name='foobar'
f.erase! [highlight=#ffff00:3b775s2t]Here we just clean up the original foos, bang they are gone while simultaneously redefining the components they were in, very powerful and hugely time saving.[/highlight:3b775s2t]
}
endThen, I wrapped this in def fooBar so I could test and, I am way closer to a solution then I was on my own. I am very grateful for this help. Sorry I am not much use to others here in this forum, it is difficult for me to write when I am still just learning to read. This really is another language for me. If it takes me 30 days to finish this solution on my own, it will be better than spending 30 days clicking on component after component all day, and I will have learned a lot in the process. Thank you for your help everyone. Sorry if I am a bother.
-
I now see your issue.
There are several component definitions containing instances of the 'foo' definition.I think there are still some issues to consider...
Assuming that you want to extract every 'foo' from their current 'home' definition, and add them all into a 'new definition', you'll need to decide on a few things...When extracting a 'foo' instance it could cause that definition to vanish IF it's the only entity it had - is this anticipated...
When extracting each 'foo' instance do you want to retain its current location within its current definition 'home' and replicate this within the 'new definition': then where does the instance of the 'new definition' need to go ?
-
"I now see your issue.
There are several component definitions containing instances of the 'foo' definition."
Yes, getting the foo out of it's home, as to redefine its home without foos is equally important."When extracting a 'foo' instance it could cause that definition to vanish IF it's the only entity it had - is this anticipated..."
I had not anticipated this. I see, a foo removed from now empty container = nothing garbage collector. A foo should always be either in it's parent home, or possibly loose in the scene perhaps we must first gather all loose foos into their own parent component?"When extracting each 'foo' instance do you want to retain its current location within its current definition 'home' and replicate this within the 'new definition': then where does the instance of the 'new definition' need to go ?"
Yes, keeping it's current location in the world is very important. I do see the possible issue locating the new foobar component. It does seem like we need a reference to locate the foobar so as to maintain the foos in their current location. Possible to get a vector to origin from perhaps bounds to locate?TIG, I love how you make me feel like I am about to get "learned" from the schoolmaster master right now.
I included an example here of a very simplified but typical scenario I will need to solve thousands of times in the next 6 months or to eternity for all I know. I really appreciate the help. I am already thinking about this clearer than I was just a day ago.
-
-
Wow! okay. This is totally awesome. This is quite a few levels above what I am capable of writing. This may take me like a week just to figure out. Sdmitch, you have saved me hundreds of hours of treachery. I want to buy you a beer, but I think you deserve a whole keg. This is way better then what I was plugging away at. Tig had got me thinking in the right direction about what I was trying for better ideas, and I had a feeling bounds was the answer to locating the foobar. I changed line 65 to some regex (=~/^[Ff]oo/) I learned from Tig back in the day to solve for a couple foos that were made unique and I left out the selection bits. This should be the example to anyone trying to get components out of their parents and gathered into their own.
I want to thank the community here for being so awesome and living up to the name Sketchucation. I have learned so much from guys like Dan Rathbun, Thom Thom, TIG, sdmitch and too many others to list.
Thanks & Cheers!
Advertisement