sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    How do you make individual components

    Scheduled Pinned Locked Moved Plugins
    12 Posts 5 Posters 1.4k Views 5 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • B Offline
      Brendon5374
      last edited by

      Here is something I have edited for myself from cab.rb from the ruby libray. I end up with panels, a complete cabinet, etc. But when I point the cursor at the object in sketchup, there are no individual components. No individual pieces of timber I can point to, move around., resize, etc. How do I make this script come up with a left panel that is a component and not part of the whole entity.

      When I use the menu without the plugin I draw the dimensions, push/pull, select all, and "make component". Then I do the same over again. I get what I want then. How can I get the same result doing a plugin script?

      I don't know the ettiquette here, so sorry if pasting all this is wrong. But here goes:

      require 'sketchup.rb'
      #-----------------------------------------------------------------------------
      def create_cab

      prompts = ["Cabinet Width", "Cabinet Height", "Cabinet Depth","With Kick?"]
      values = [100.cm, 100.cm, 60.cm , 10.cm ]
      thick = 1.6.cm  #<----panel thickness
      results = inputbox prompts, values, "Cabinet Dimensions"
      width, height, depth, kick = results
      if (kick <= 0.0.cm)
         then kick = 0.01.cm
      end
      

      #-----------------------------------------------------------------------------
      model = Sketchup.active_model
      model.start_operation "Create Cab"
      entities = model.active_entities
      group = entities.add_group
      entities = group.entities

      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 thick
      
      
      
      x = width-thick
      rs=[]   #right panel
      rs[0] = [x, depth, kick]
      rs[1] = [x, depth, height-thick]
      rs[2] = [x, thick, height-thick]
      rs[3] = [x, thick, kick]
      rs_base = entities.add_face rs
      rs_base.pushpull thick
      
      
      
      
      rp=[]   #rear panel
      rp[0] = [0, depth, kick]
      rp[1] = [0, depth+thick, kick]
      rp[2] = [0, depth+thick, height-thick]
      rp[3] = [0, depth, height-thick]
      rp_base = entities.add_face rp
      rp_base.pushpull -width
      
      top=[]   #top 
      top[0] = [thick, 10.cm, height-thick]
      top[1] = [thick, 0+thick, height-thick]
      top[2] = [thick, 0+thick, height-thick-thick]
      top[3] = [thick, 10.cm, height-thick-thick]
      top_base = entities.add_face top
      top_base.pushpull width-thick-thick
      
      
      
      top=[]   #top 
      top[0] = [thick, depth-10.cm, height-thick]
      top[1] = [thick, depth, height-thick]
      top[2] = [thick, depth, height-thick-thick]
      top[3] = [thick, depth-10.cm, height-thick-thick]
      top_base = entities.add_face top
      top_base.pushpull width-thick-thick
      
      
      
      btm=[]   #bottom shelf
      btm[0] = [thick, thick, kick+thick]
      btm[1] = [thick, depth, kick+thick]
      btm[2] = [thick, depth, kick+0]
      btm[3] = [thick, thick, kick+0]
      btm_base = entities.add_face btm
      btm_base.pushpull width-thick-thick
      
      
      
      
      
      kickf=[]   #kicktoe panel front
      kickf[0] = [0, 4.cm, 0]
      kickf[1] = [0, 4.cm+thick, 0]
      kickf[2] = [0, 4.cm+thick, kick]
      kickf[3] = [0, 4.cm, kick]
      kickf_base = entities.add_face kickf 
      kickf_base.pushpull -width
      
      
      kickb=[]   #kicktoe panel back
      kickb[0] = [0, depth-4.cm, 0]
      kickb[1] = [0, depth-4.cm-thick, 0]
      kickb[2] = [0, depth-4.cm-thick, kick]
      kickb[3] = [0, depth-4.cm, kick]
      kickb_base = entities.add_face kickb 
      kickb_base.pushpull -width
      

      #-----------------------------------------------------------------------------
      view = model.active_view
      view.zoom_extents
      #-----------------------------------------------------------------------------
      prompts = ["Door Height", "Top Rail Width", "Bottom Rail Width", "Stile Width" ]
      values = [100.cm, 10.cm, 10.cm, 3.3.cm]
      results = inputbox prompts, values, "Door Frame Dimensions"
      height, top, btm, sw = results
      #----------------------------------Do Left Door
      ld=[] #left style, left door
      ld[0] = [0, 0, kick]
      ld[1] = [0, 0, height]
      ld[2] = [0, thick, height]
      ld[3] = [0, thick, kick]
      ld_base = entities.add_face ld
      ld_base.pushpull -sw

      x = width/2-sw
      ld=[]    #right style, left door
      ld[0] = [x, 0, kick]
      ld[1] = [x, 0, height]
      ld[2] = [x, thick, height]
      ld[3] = [x, thick, kick]
      ld_base = entities.add_face ld 
      ld_base.pushpull -sw
      
      x = sw
      ld=[]    #top rail, left door
      ld[0] = [x, 0, height-top]
      ld[1] = [x, thick,height-top]
      ld[2] = [x, thick, height]
      ld[3] = [x, 0, height]
      ld_base = entities.add_face ld
      ld_base.pushpull width/2-sw-sw
      
      x = sw
      ld=[]    #btm rail, left door
      ld[0] = [x, 0, kick]
      ld[1] = [x, 0, kick+btm]
      ld[2] = [x, thick, kick+btm]
      ld[3] = [x, thick, kick]
      ld_base = entities.add_face ld 
      ld_base.pushpull width/2-sw-sw
      
      x = sw
      ld=[]    #glazing panel, left door
      ld[0] = [x, thick/2, height-top]
      ld[1] = [x, thick, height-top]
      ld[2] = [x, thick, kick+btm]
      ld[3] = [x, thick/2, kick+btm]
      ld_base = entities.add_face ld 
      ld_base.material = Sketchup::Color.new (236,201, 101)
      ld_base.material.alpha = 0.7 
      ld_base.pushpull width/2-sw-sw
      

      #----------------------------------- Do Right Door
      x = width/2+sw
      ld=[] #left style, right door
      ld[0] = [x, 0, kick]
      ld[1] = [x, 0, height]
      ld[2] = [x, thick, height]
      ld[3] = [x, thick, kick]
      ld_base = entities.add_face ld
      ld_base.pushpull sw

      x = width-sw
      ld=[]    #right style, right door
      ld[0] = [x, 0, kick]
      ld[1] = [x, 0, height]
      ld[2] = [x, thick, height]
      ld[3] = [x, thick, kick]
      ld_base = entities.add_face ld 
      ld_base.pushpull -sw
      
      x = width-sw
      ld=[]    #top rail, right door
      ld[0] = [x, 0, height-top]
      ld[1] = [x, thick,height-top]
      ld[2] = [x, thick, height]
      ld[3] = [x, 0, height]
      ld_base = entities.add_face ld
      ld_base.pushpull width/2-sw-sw
      
      x = width-sw
      ld=[]    #btm rail, right door
      ld[0] = [x, 0, kick]
      ld[1] = [x, 0, kick+btm]
      ld[2] = [x, thick, kick+btm]
      ld[3] = [x, thick, kick]
      ld_base = entities.add_face ld 
      ld_base.pushpull width/2-sw-sw
      
      x = width-sw
      ld=[]    #glazing panel, right door
      ld[0] = [x, thick/2, height-top]
      ld[1] = [x, thick, height-top]
      ld[2] = [x, thick, kick+btm]
      ld[3] = [x, thick/2, kick+btm]
      ld_base = entities.add_face ld 
      ld_base.material = Sketchup::Color.new (236,201, 101)
      ld_base.material.alpha = 0.7 
      ld_base.pushpull width/2-sw-sw
      

      #-----------------------------------------------------------------------------
      prompts = ["Counter Top Height", "Thickness", "Reveal"]
      values = [100.cm, 3.3.cm, 1.cm]
      results = inputbox prompts, values, "Countertop Optional"
      height, th, reveal = results

      top=[]   #countertop 
      top[0] = [0, thick, height]
      top[1] = [0, thick, height+reveal]
      top[2] = [0, 0, height+reveal]
      top[3] = [0, 0, height+th]
      top[4] = [0, depth, height+th]
      top[5] = [0, depth, height]
      top_base = entities.add_face top
      top_base.pushpull -width
      

      #-----------------------------------------------------------------------------
      model.commit_operation
      end
      #-----------------------------------------------------------------------------
      if( not file_loaded?("Cab.rb") )
      add_separator_to_menu("Plugins")
      UI.menu("Plugins").add_item("Cab") { create_cab }
      end
      #-----------------------------------------------------------------------------
      file_loaded("cab.rb")

      1 Reply Last reply Reply Quote 0
      • thomthomT Offline
        thomthom
        last edited by

        I'm having a quick look at it.

        However, when posting code, please wrap it in Code tags to the formatting is preserved. And when posting whole scripts like this you might as well just post the .rb file itself.

        Thomas Thomassen — SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 Reply Last reply Reply Quote 0
        • thomthomT Offline
          thomthom
          last edited by

          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_group

          Here you are creating a group. You must do this for each object you want and add the entities to that group.

          Thomas Thomassen — SketchUp Monkey & Coding addict
          List of my plugins and link to the CookieWare fund

          1 Reply Last reply Reply Quote 0
          • Dave RD Offline
            Dave R
            last edited by

            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
            

            ?

            Etaoin Shrdlu

            %

            (THERE'S NO PLACE LIKE)

            G28 X0.0 Y0.0 Z0.0

            M30

            %

            1 Reply Last reply Reply Quote 0
            • thomthomT Offline
              thomthom
              last edited by

              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.

              Thomas Thomassen — SketchUp Monkey & Coding addict
              List of my plugins and link to the CookieWare fund

              1 Reply Last reply Reply Quote 0
              • Dave RD Offline
                Dave R
                last edited by

                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.

                Etaoin Shrdlu

                %

                (THERE'S NO PLACE LIKE)

                G28 X0.0 Y0.0 Z0.0

                M30

                %

                1 Reply Last reply Reply Quote 0
                • B Offline
                  Brendon5374
                  last edited by

                  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 thick

                  to 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.

                  1 Reply Last reply Reply Quote 0
                  • D Offline
                    Doi
                    last edited by

                    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:
                    console.PNG

                    I know it'll be something really simple - it usually is 😕

                    Thanks in advance

                    1 Reply Last reply Reply Quote 0
                    • TIGT Offline
                      TIG Moderator
                      last edited by

                      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...
                      
                      

                      🤓

                      TIG

                      1 Reply Last reply Reply Quote 0
                      • D Offline
                        Doi
                        last edited by

                        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:
                        Console02.PNG

                        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! 💚

                        1 Reply Last reply Reply Quote 0
                        • TIGT Offline
                          TIG Moderator
                          last edited by

                          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")
                          

                          TIG

                          1 Reply Last reply Reply Quote 0
                          • D Offline
                            Doi
                            last edited by

                            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!

                            1 Reply Last reply Reply Quote 0
                            • 1 / 1
                            • First post
                              Last post
                            Buy SketchPlus
                            Buy SUbD
                            Buy WrapR
                            Buy eBook
                            Buy Modelur
                            Buy Vertex Tools
                            Buy SketchCuisine
                            Buy FormFonts

                            Advertisement