How do you make individual components
-
I see.
The reason you're not getting any components are because you are not creating any.
You must explicitly create a group or component and add the entities to it.
You are doing it once in the script:
group = entities.add_group
http://code.google.com/apis/sketchup/docs/ourdoc/entities.html#add_groupHere you are creating a group. You must do this for each object you want and add the entities to that group.
-
I looked at the link Thomas but I didn't see the answer. If you want to make a component instead of a group, would you replace
group = entities.add_group
with
component = entities.add_component
?
-
To to create a component you first need to create a component definition and add the entities to it. Then place instances of that definitions
entities.add_instance
.I deliberately just explained groups as they are more straight forward. So that Brendon could see the concept of creating isolated geometry via Ruby.
-
Thanks Thomas.
I was just asking because I downloaded Dan's revision of box.rb and was wondering about changing it to make components instead of groups. I was thinking that it might be a tool to speed up some of my drawing processes but in thinking about it, I decided it will just replace one operation with another.
Thanks again.
-
Thank you Thomas and Dave for your replies. I was pretty sure there had to be more script for each piece (object). I'm not too familar with the syntax. And reading all this is daunting for me. Basically, I was just cannabalizing open files to suit my purpose; and beyond what I understood from doing that, I'm a bit lost when off the beaten track. I read the links you gave, and I tried, but came up lacking.
I do not know what to put with say,
ls=[] #left panel
ls[0] = [0, depth, kick]
ls[1] = [0, depth, height-thick]
ls[2] = [0, thick, height-thick]
ls[3] = [0, thick, kick]
ls_base = entities.add_face ls
ls_base.pushpull thickto turn it into a component. I pasted every line you gave, this way and that- front and back. But I couldn't figure it. Monkey see-monkey do, has it limits. ha ha.
-
Hi,
My first post, so before anything else, hello
A bit of background on my component issue...
I have a model that I have 'inherited' (approximately 130 buildings) that need to be cleaned up - basically lots of unconnected entities, and components with materials applied to the back face etc. I have thrown together a quick and dirty script to fix these issues (I was a little surprised at how easy it was to fix all that; ruby is very nice to use)
Where things have gone a little screwy, is when I try to re-create the individual components.All my searching keeps pointing me back to the API documentation, which is fine, but I must not be interpreting it correctly, and am now just going round in circles?..
The basic process I am trying to do is:
temp_group = exploded_entities.add_group adjusted_component = temp_group.to_component
The API docs state that calling the explode method on a ComponentInstancewill return an Entitiesobject. I read this as an Entities container (array?) filled with the individual Entityobjects that make up the building - the Entities container class is the only one with the add_group method!?
Functionally I am able to access the exploded building as expected, as I said above the clean up steps work no worries, what I am finding is that the exploded_entities object is of type Array and as such throws a no method error when calling add_group?Here is the code in question:
# output working component puts e.typename + "; " + compname if exploded_component = e.explode puts "Exploded into; " + exploded_component.class.to_s # parse component entities exploded_component.each do |ce| ...fixing stuff here end #end do #re-create component temp_group = exploded_component.add_group adj_component = temp_group.to_component puts "Recreated; " + adj_component.name puts "Total Faces; " + totalfaces.to_s + ";;Adjusted; " + adjusted.to_s
Here is the console output:
I know it'll be something really simple - it usually is
Thanks in advance
-
When you explode a ComponentInstance it returns an Array of Entities NOT an 'Entities' object.
There are several ways to get available 'entities'
Sketchup.active_model.entities
ALL model's entities
Sketchup.active_model.active_entities
accessible entities in this 'edit' session - if not edit it is == previous example
definition.entites
the entities in the definition
group.entities
the entities in the group.
The
add_...
methods apply to Entities.
So to add a group to the model use
new_group=Sketchup.active_model.entities.add_group()
then get that group's entities and add to them
new_group.entities.add_cpoint([1,2,3])
So in your case let's assume the grouped building is done something like this...
### we have already somehow got an array of the required 'bits'... group=Sketchup.active_model.entities.add_group(an_array_of_entities) ### this method can lead to Bugsplats BUT with the recent SUp MR it seems more stable ### now you have group in the model that holds the 'bits'... inst=group.to_component defn=inst.definition defn.name="defn_name" defn.decription="defn_desc" ### you could then erase the 'inst' and reinsert an new one if needed, or just transform! it to anew location etc...
-
Hi TIG,
thanks for the clarification, it is nice to know I wasn't completely lost and was heading down the right track in one of my circular attempts - when I encountered an "All entities must have a common parent" error I went back to my initial attempt for my first post...
The current issue now seems to be that my exploded_entities need a reference to their 'parent' before being added to the group, yet I thought this is what add_group/to_component process was doing? From what I understand from the API, you must have a Component Instance first, then use it to create the Component Definition - then multiple Instances can be created under the Definition?
Using your example, my code becomes:
orig_entities = Sketchup.active_model.entities ### Note; there is (correctly) no difference between calling .entities, or .active_entities here ... #re-create component temp_group = orig_entities.add_group(exploded_component) adj_component = temp_group.to_component adj_definition = adj_component adj_definition.name= orig_definition.name adj_definition.description= orig_definition.description
The console throws:
Line 42 is the temp_group = orig_entities.add_group(exploded_component) method call.
If it helps, here is the entire script:
require 'sketchup.rb' # # # def parsecomponents # containers adjustedcomps = Sketchup;;Entities.new # data model = Sketchup.active_model orig_entities = model.entities layers = model.layers unattached_layer = layers.add "Unattached Elements" #anything that ends up here to be deleted... puts "Starting-----------------------------" orig_entities.each do |e| case e when Sketchup;;ComponentInstance totalfaces = 0 adjusted = 0 orig_definition = e.definition orig_transform = e.transformation # output working component puts e.typename + "; " + orig_definition.name if exploded_component = e.explode puts "Exploded into; " + exploded_component.class.to_s # parse component entities exploded_component.each do |ce| # swap material if required if ce.is_a? Sketchup;;Face totalfaces += 1 if !ce.material && ce.back_material ce.material= ce.back_material ce.back_material= nil adjusted += 1 end #end if end #end if end #end do #re-create component temp_group = Sketchup.active_model.entities.add_group(exploded_component) adj_component = temp_group.to_component adj_definition = adj_component adj_definition.name= orig_definition.name adj_definition.description= orig_definition.description puts "Recreated; " + adj_definition.name puts "Total Faces; " + totalfaces.to_s + ";;Adjusted; " + adjusted.to_s else UI.messagebox "Failed to Explode Component!" end else # anything other than a component is not wanted... e.layer= unattached_layer puts e.typename + " moved to Unattached Layer!" end # end case end # end do puts puts "Completed----------------------" end # end parsecomponents ########################################### if(file_loaded("swapmaterials02.rb")) menu = UI.menu("Plugins"); menu.add_item("Parse Model") {parsecomponents} end #------------------------------------------ file_loaded("swapmaterials02.rb")
Cheers Doi!
-
Try this...
require 'sketchup.rb' # # # def parsecomponents # containers ###adjustedcomps = Sketchup;;Entities.new ###NOT USED LATER ??? # data model = Sketchup.active_model # model.start_operation("parsecomponents") ### SEE BELOW...*** orig_entities = model.entities layers = model.layers ###??? unattached_layer = layers.add "Unattached Elements" #anything that ends up here to be deleted... ??? puts "Starting-----------------------------" orig_entities.to_a.each do |e| ### NOTE HOW I MADE IT AN array FOR SAFETY if e.class == Sketchup;;ComponentInstance ### PROBABLY EASIER THAN class ??? totalfaces = 0 adjusted = 0 orig_definition = e.definition orig_transform = e.transformation # output working component puts e.typename + "; " + orig_definition.name if exploded_component = e.explode ### THIS IS AN array puts "Exploded into; " + exploded_component.class.to_s # parse component entities exploded_component.each do |ce| # swap material if required if ce.is_a? Sketchup;;Face totalfaces += 1 if !ce.material && ce.back_material ce.material= ce.back_material ce.back_material= nil adjusted += 1 end #end if end #end if end #end do #re-create component temp_group = orig_entities.add_group(exploded_component) ### ADD it were it was adj_component = temp_group.to_component adj_definition = adj_component.definition ##### POINT TO THE DEFN !!!!! # name=orig_definition.name ### USED below*** adj_definition.name= orig_definition.name ##### THIS will add [1] to the end as the original exists adj_definition.description= orig_definition.description puts "Recreated; " + adj_definition.name puts "Total Faces; " + totalfaces.to_s + ";;Adjusted; " + adjusted.to_s ### YOU COULD remove the original definition too... ### neeeds start/commit ### *** # orig_definition.name = orig_definition.name+rand.to_s ### rename temporarily # orig_definition.entities.erase_entites(orig_definition.entities) # adj_definition.name = name ### the orig_defn is now emppty and will go from the browser after the 'commit' *** ### the new definition has it's name else UI.messagebox "Failed to Explode Component!" end else # anything other than a component is not wanted... e.layer= unattached_layer puts e.typename + " moved to Unattached Layer!" ### alternatively ADD erase! HERE AND AVOID layer COMPLICATIONS # e.erase! if e.valid? # puts e.to_s+" ERASED." ### valid? traps if you delete an edge that had aface that's then not available to erase next! end # end IF ### end # end do puts puts "Completed----------------------" # model.commit_operation ###*** end # end parsecomponents ########################################### if(file_loaded("swapmaterials02.rb")) menu = UI.menu("Plugins"); menu.add_item("Parse Model") {parsecomponents} end #------------------------------------------ file_loaded("swapmaterials02.rb")
BUT to be honest I think you are making it overly complicated, as you can edit the definition's contents directly thus
require 'sketchup.rb' def parsecomponents model = Sketchup.active_model model.start_operation("parsecomponents",true) ### makes it undobale ents = model.entities puts "Starting-----------------------------" ents.to_a.each{|e| if e.class == Sketchup;;ComponentInstance totalfaces = 0 adjusted = 0 defn = e.definition begin defn.entities.each{|e| if e.class==Sketchup;;Face totalfaces += 1 if !e.material && e.back_material e.material= e.back_material e.back_material= nil adjusted += 1 end #end if end #end if } rescue UI.messagebox "Failed to Edit Component!" end#begin else # anything other than a component is not wanted... e.erase! if e.valid? puts e.to_s+" ERASED." end # end IF ### } puts "Recreated; " + defn.name puts "Total Faces; " + totalfaces.to_s + "; Adjusted; " + adjusted.to_s puts "Completed----------------------" model.commit_operation end # end parsecomponents ########################################### if(file_loaded("swapmaterials02.rb")) menu = UI.menu("Plugins"); menu.add_item("Parse Model") {parsecomponents} end #------------------------------------------ file_loaded("swapmaterials02.rb")
-
Wow TIG,
thank you so much! Both edits work a treat , but yes yours is definitely more succinct - I have always had issues with my code being a tad too verbose, and possibly missing the trees for the forest...
After my previous post, I was thinking it did seem odd that I wasn't working directly with the definition, but I'm sure I would never have found it without the help
Thanks again - now onto the next tweak...
Cheers,
Doi!
Advertisement