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

    Entering components

    Scheduled Pinned Locked Moved Developers' Forum
    7 Posts 3 Posters 1.2k Views 3 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
      ben.doherty
      last edited by

      Hi, This seems really simple, so hopefully it is!

      I want to loop through all the instances of a component in a model, then loop through it's entities and find a face that has a special material (lets say kryptonite).

      From looking at the API it seems that Groups have a .entities, but ComponentInstances don't.

      Any hints on how is it done?

      Back story *(ignore this if you aren't too bothered about the application of this)*I'm analysing an appartment block. There are 8 or so appartment types, each is placed and named according to it's position, so one might be 'floor 5 appt 7'. There is a critical window that I need to test using the method outlined in the Taking pictures with cameras thread.

      My plan so far is to take a copy of each face and put it onto a layer, run the test for each window, and then delete them all. Essentially leaving the model untouched.

      1 Reply Last reply Reply Quote 0
      • B Offline
        ben.doherty
        last edited by

        I've actually cracked this. I found an old thread that explained it. I'll post it up in a bit when I finish it

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

          @ben.doherty said:

          From looking at the API it seems that Groups have a .entities, but ComponentInstances don't.

          Any hints on how is it done?

          With ComponentInstances you need to access its ComponentDefinition - that has .entities.

          Btw, Groups and Images also have definitions, you iterate them when you iterate model.definitions. Which is why ComponentDefinition has .group? and .Image?

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

          1 Reply Last reply Reply Quote 0
          • B Offline
            ben.doherty
            last edited by

            So here's the solution I came to. I'm sure that there are better ways to do this, but this was quick, and it worked. I suppose in the future adding a method to the vector class instead of making an instance method would be neater etc.

            [as I see it] Feature instances can't be entered, but their definitions can be. That means that you can find the face that you need to access, but it'll be at the origin. the Instance does have a transform, so if you apply that transform to the new object then you can make it be in the same place as the instance.
            But wait! you can't transform a face, but you can transform a group, so just throw the face into a group and transform that.

            Any raises on that? it doesn't seem too elegant, but it does the job.

            #module Voyeur
            #module FaceMaker
            
            if( not file_loaded?("makeTheFaces.rb") )
            
                # This will add a separator to the menu, but only once
                add_separator_to_menu("Voyeur")
                
                plugins_menu = UI.menu("Plugins")
                voyeur_menu = plugins_menu.add_submenu("Voyeur")
                voyeur_menu.add_item("make analysis faces") { makeAnalysisFaces }
            end
            
              def toP3d(vec)
                return Geom;;Point3d.new(vec.x,vec.y,vec.z)
              end
              
              def vertToVec(aVertex)
                unless aVertex == nil
                  pos = aVertex.position
                  theVec = Geom;;Vector3d.new(pos.x,pos.y,pos.z)
                  return theVec 
                end
              end
              def scaleVec(vec,scalar)
                return Geom;;Vector3d.new(vec.x * scalar, vec.y * scalar, vec.z * scalar)
              end
              
              def makeAnalysisFaces
                
                mod = Sketchup.active_model
                ent = mod.entities
                sel = mod.selection
                
                analysisLayer = mod.layers.add 'analysis'
                
                ent.each{ |e|
                  if e.is_a? Sketchup;;ComponentInstance
                    e.definition.entities.each { |newE|
                      if ((newE.is_a? Sketchup;;Face) and (newE.material != nil))
                        #puts newE.material.name
                        verts  = newE.vertices
                        normal = Geom;;Vector3d.new(newE.normal).normalize
                        offsetFactor = 3000.mm
                        offset = scaleVec(normal, offsetFactor)
                        newPoints = []
                        for i in (0...verts.length)
                          pvec = vertToVec(verts[i])
                          newPoints[i] = toP3d(pvec + offset)
                          #ent.add_cpoint newPoints[i]
                        end
                        tempGroup = ent.add_group
                        face = tempGroup.entities.add_face newPoints
                        #puts "#{e.name}'s transform matrix"
                        #puts e.transformation.to_a
                        tempGroup.transformation = e.transformation
                        tempGroup.set_attribute "analysisInfo", "apptType",   e.definition.name
                        tempGroup.set_attribute "analysisInfo", "apptNumber", e.name
                        tempGroup.layer = analysisLayer 
                      end       #if newE.is_a? Sketchup;;Face
                     }          #e.definition.entities.each
                  end           #if e.is_a
                }               #ent.each
              end               #makeAnalysisFaces
            #end
            #end
            

            I am having lots of trouble with modules though, if I ask the ruby console for Voyeur::FaceMaker::instance_methods it gives me back a list of the methods as I'd expect, but if I say Voyeur::FaceMaker.makeAnalysisFaces it throws a #<NoMethodError.... any idea how to fix that? Currently I've just taken the module stuff out, which seems like bad karma.

            1 Reply Last reply Reply Quote 0
            • Dan RathbunD Offline
              Dan Rathbun
              last edited by

              I also think you missed the Geom::Point3d.offset method

              
                          for i in (0...verts.length)
                            pvec = vertToVec(verts[i])
                            newPoints[i] = toP3d(pvec + offset)
                            #ent.add_cpoint newPoints[i]
                          end
              
              

              can become:

              
                          for i in (0...verts.length)
                            newPoints[i] = verts[i].position.offset( scaleVec )
                            #ent.add_cpoint newPoints[i]
                          end
              
              

              I'm not here much anymore.

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                @ben.doherty said:

                I suppose in the future adding a method to the vector class instead of making an instance method would be neater etc.

                
                >   def toP3d(vec)
                >     return Geom;;Point3d.new(vec.x,vec.y,vec.z)
                >   end
                > 
                

                Done already (in a way.)
                See the API method: Geom::Vector3d#to_a

                Also do not overlook (it's easy; the online API is not organized at that well,) that the API extended the Ruby baseclass Array to be compatible with both Geom::Vector3d and Geom::Point3d classes.
                See, (API left nav) Base Classes: Array

                What the API does NOT explain well (and you won't know unless you read the API topic thread,) is:

                Geom::Point3d.new( *args )
                *args can accept an Array argument or literal as the 1st arg (the rest are then ignored.)
                Ex:
                Geom::Point3d.new( [1,2,3 )]
                Geom::Point3d.new( vec.to_a )

                Geom::Vector3d.new( *args )
                *args can accept an Array argument or literal as the 1st arg (the rest are then ignored.)
                Ex:
                Geom::Vector3d.new( [1,2,3 )]
                Geom::Vector3d.new( pt.to_a )

                Neither class can directly accept each other as arguments; you must use the .to_a method on the argument.


                So to convert Vertex to Vector3d, is simply:
                Geom::Vector3d.new( vertex.position.to_a )


                In addition to scale a vector, you can use:
                vector.length=vector.length*scaler
                or use the vector.transform! method:
                vector.transform! Geom::Transformation.scaling(scalar)

                For a new scaled vector:
                vector2=vector1.clone
                vector2.length=vector1.length*scaler
                or use the vector.transform method:
                vector2=vector1.transform Geom::Transformation.scaling(scalar)

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • Dan RathbunD Offline
                  Dan Rathbun
                  last edited by

                  @ben.doherty said:

                  I am having lots of trouble with modules though, if I ask the ruby console for Voyeur::FaceMaker::instance_methods it gives me back a list of the methods as I'd expect, but if I say Voyeur::FaceMaker.makeAnalysisFaces it throws a #<NoMethodError.... any idea how to fix that?

                  moved to it's OWN topic thread, so folks can find it easier:

                  See: [info] Using Ruby Modules

                  I'm not here much anymore.

                  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