So I have a question that seams really easy (probably a brain fart on my end) but I just cant find the answer and its driving me crazy! I’m new to Ruby coding and still haven’t figured out all the details.
So I have created 2 components with ruby from 2 groups using the .to_component method. This works fine. So now I want to create a new component and add the 2 existing components into the new one, the new component should have no entities inside it, only the 2 existing components. I cant seam to figure out how to create a component without using the .to_component method. Any ideas?
You can create new empty component definitions with Sketchup::DefinitionList#add and then add geometry directly into it’s entities collection. Lastly add an instance of that new definition to whatever entities collection you desire (the model’s or some other definition’s entities collection.)
So if the 2 instances you are creating will always be your code’s creations then you’ve been doing it butt-backward. First create the empty parent definition. Then the child definitions. Add instances of the children to the parent’s entities collection, then add an instance of the parent to the model at some level.
@DanRathbun thank you for your input! I’ll try it out next week when I’'m back home. Have I understod it correctly that I would have to add a new definition to the model.definitions (new_comp) and then add the other components (comp_A & comp_B) to the new components entities and lastly add a instance off the newly created component (new_comp) to the model? Wouldn’t that create 2 copies of comp_A & comp_B? The original ones and the new ones in the new_comp?
@nnijmeijer appreciate your input as well. Currently enjoying some time in the southern part of your wonderful country!
Well I had said that IF you were creating instance A and instance B … then you might as well just create them as component definitions (instead of going through the group paradigm,) in which case no there would not be 2 copies of each.
But IF you are wanting to encapsulate existing instances in a component, then as I said in the 2nd post above, this has been discussed multiple times with multiple code snippets already posted. (See the category search link in that post.)
Hey again @DanRathbun
So I got a version of the code working but only when using the .to_component method. I just can’t seem to understand how to do it “The Correct” way that you showed above. I wrote a bit of code that doesn’t work ( and is obviously incorrect) but “should” work the way I understand it. I created two new definitions, one Cube component and one Main component that should envelop two instances of the cubes. Can you or anyone else give me a hint of where my code is flawed, and how to correct it?
model = Sketchup.active_model
entities = model.active_entities
definitions = model.definitions
definitions.purge_unused #Just to make sure there are no existing definitions i the model
main = definitions.add "Main_comp"
cube = definitions.add "Cube_comp"
x = 1000.mm
pts = [
[0,0,0],
[x,0,0],
[x,x,0],
[0,x,0]
]
face = cube.entities.add_face(pts)
face.reverse!
face.pushpull(x)
main.entities.add_instance(cube,[0,x,0])
main.entities.add_instance(cube,[x,x,0])
entities.add_instance(main,[0,0,0])
The garbage collector here is aggressive about empty definitions. If you want to keep it “alive” you have to put something in it immediately! So, simple rearrange your code lines order… and it “should” work
model = Sketchup.active_model
entities = model.active_entities
definitions = model.definitions
definitions.purge_unused
x = 1000.mm
pts = [
[0,0,0],
[x,0,0],
[x,x,0],
[0,x,0]
]
cube = definitions.add "Cube_comp"
face = cube.entities.add_face(pts)
face.reverse!
face.pushpull(x)
main = definitions.add "Main_comp"
main.entities.add_instance(cube,[0,x,0])
main.entities.add_instance(cube,[x,x,0])
entities.add_instance(main,[0,0,0])
@dezmo THANK YOU! You have no idea how long I’ve been scratching my head trying to figure out why it wouldn’t work. So if you don’t use a newly created definition right away and but something in it SketchUp deletes it? I guess it kind of makes sense thought, this way the model wont have a bunch of empty components associated with it.
Once again thank you, and thanks to @DanRathbun for giving a excellent explanation on the use of definitions.
Yes, also the same for groups (as they are just a special type of component.)
And in the olden days before the API had a method to delete a specific definition from the definitions list, coders could delete all the entities of a definition and SketchUp would “clean it up” by dereferencing it so it was marked for garbage collection.
In the near future this “clean up” may seem even more aggressive as SketchUp updates to Ruby 3 which is advertised to be 3 times faster than Ruby 2.
It’s not the Ruby garbage collector. It’s SkechUp that cleans up between operations. Since the sample code wasn’t wrapped inside of model.start/commit_operation it meant that every call to a method that modified the model could trigger this. This cleanup is suspended between model.start/commit_operation.
Interesting… Seams that I managed to create a rather specific senario were my code failed because if i wrap my previously posted code with a model.start_operation and a model.commit_operation it runs just fine. Thanks for helping to clear up my problem @tt_su
model = Sketchup.active_model
entities = model.active_entities
definitions = model.definitions
definitions.purge_unused #Just to make sure there are no existing definitions i the model
model.start_operation("Test",true)
main = definitions.add "Main_comp"
cube = definitions.add "Cube_comp"
x = 1000.mm
pts = [
[0,0,0],
[x,0,0],
[x,x,0],
[0,x,0]
]
face = cube.entities.add_face(pts)
face.reverse!
face.pushpull(x)
main.entities.add_instance(cube,[0,x,0])
main.entities.add_instance(cube,[x,x,0])
entities.add_instance(main,[0,0,0])
model.commit_operation