sketchucation logo sketchucation
    • Login
    ๐Ÿ›ฃ๏ธ Road Profile Builder | Generate roads, curbs and pavements easily Download

    Find the global position of a Vertex in a Group/Component

    Scheduled Pinned Locked Moved Developers' Forum
    25 Posts 6 Posters 4.8k Views 6 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.
    • thomthomT Offline
      thomthom
      last edited by

      I'd avoid making groups unique. I some times get models made by others where groups have been used as components. Provided the groups have not been made unique I can still recover them, by using Selection Toys.

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

      1 Reply Last reply Reply Quote 0
      • G Offline
        gbabcock
        last edited by

        @thomthom said:

        What was your testcase? With group or components? Did you try with scaled instances as well?

        I tested Groups, nested Groups, scaled Groups, rotated Groups, translated Groups, Group copies, Components (single only). Works for all of them.

        I've updated my Position Explorer tool, see attached. I'll post the update in the Plugins forum.

        @thomthom said:

        Which one was that?

        http://forums.sketchucation.com/viewtopic.php?f=180&t=14062&p=105782

        Glenn


        Position Explorer 13 Feb 2010

        Glenn

        1 Reply Last reply Reply Quote 0
        • G Offline
          gbabcock
          last edited by

          @thomthom said:

          I'd avoid making groups unique. I some times get models made by others where groups have been used as components. Provided the groups have not been made unique I can still recover them, by using Selection Toys.

          So how do I work around the bug? If I make a copy of a group and immediately try to get it's position I get the original's transformation.

          Glenn

          Glenn

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

            @unknownuser said:

            #returns an array of Point3d objects that equal the global position of the vertices in an edge
            #currently only gets the first parent instance, components may have many instances

            You're not dealing with components with many instances? You only pick the first instance?

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

            1 Reply Last reply Reply Quote 0
            • G Offline
              gbabcock
              last edited by

              @thomthom said:

              You're not dealing with components with many instances? You only pick the first instance?

              I am, I just haven't gotten that far with the tool yet!

              Glenn

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

                @gbabcock said:

                @thomthom said:

                You're not dealing with components with many instances? You only pick the first instance?

                I am, I just haven't gotten that far with the tool yet!

                Well, that is a key major problem. Getting the correct instance. It's why traversing the parent won't work, as you only get the definition, but no way of getting the right instance.
                If you make components work, then you make groups with group copies work. They are the same thing under the hood.

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

                1 Reply Last reply Reply Quote 0
                • G Offline
                  gbabcock
                  last edited by

                  Thanks, that's helpful. I'll play around with that.

                  Glenn

                  1 Reply Last reply Reply Quote 0
                  • G Offline
                    gbabcock
                    last edited by

                    @thomthom said:

                    Well, that is a key major problem. Getting the correct instance...

                    OK, I see now. It's not a true hierarchy, since an element (vertex, face, edge, etc.) can be in more than one instance. Parent only gets you the Definition, with no way to get the correct Instance, as you said.

                    Thanks for helping me understand!

                    Glenn

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

                      Only way is to map the whole model, going from Model and up. Which is just a brute force way to do it. ๐Ÿ˜•

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

                      1 Reply Last reply Reply Quote 0
                      • J Offline
                        jessejames
                        last edited by

                        @thomthom said:

                        SU changes the co-ordiates when you open a group/component. When a group or component is open SU returns global co-ordinates for the entities in that context.

                        It seems Tim Toady is more prevalent that i had originally feared! ๐Ÿ˜ฎ

                        PS: Before some hot shot notices i made a mistake in accessing the origin using

                        collection..transformation[-1]
                        

                        Since the transformation is a 16 element array an NOT a 4 element array of 4 element sub arrays that code will only return the last float.

                        Always sleep with a loaded gun under your pillow!

                        1 Reply Last reply Reply Quote 0
                        • AdamBA Offline
                          AdamB
                          last edited by

                          @thomthom said:

                          Only way is to map the whole model, going from Model and up. Which is just a brute force way to do it. ๐Ÿ˜•

                          Not really true. Its certainly non-trivial but LightUp does it ๐Ÿ˜„. ie LightUp needs to find the transform of every instance of a Component called PointLightSource. Clearly starting at the top and walking down is "one way" buts its incredibly inefficient. Better is to get each instance (trivial) then work your way back up concatenating transforms as you go - and dealing with the fact that there can be many instances of Components as thomthom points out. Took a fair amount of head scratching but its all in lightcache.rb if you want to take a butchers.

                          Its invoked by list = LightCache.flat(LightCache.walk(ent, ent.transformation)) which gives you back a list of transforms.

                          Adam

                          Developer of LightUp Click for website

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

                            Very interesting Adam. I'm glad to be proven wrong.

                            I will for sure poke about that code of yours. Is it ok with you if I adapt it to a generic method and add it to my generic library shared between my plugins?

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

                            1 Reply Last reply Reply Quote 0
                            • G Offline
                              gbabcock
                              last edited by

                              @adamb said:

                              Clearly starting at the top and walking down is "one way" buts its incredibly inefficient. Better is to get each instance (trivial) then work your way back up concatenating transforms as you go - and dealing with the fact that there can be many instances of Components as thomthom points out. Adam

                              Exactly what I'm trying to do! Thanks, Adam, I'll check this out.

                              Glenn

                              1 Reply Last reply Reply Quote 0
                              • G Offline
                                gbabcock
                                last edited by

                                OK, I think I'm getting a clearer picture now. โ— Let me sum it up to make sure.

                                Since we can have multiple instances of a Group/Component, there is a One-to-Many relationship between a Vertex and Transformations:

                                Vertex->ComponentDefinition->ComponentInstances->ComponentInstance->Transformation

                                model.jpg
                                Therefore, to get the global position of a Vertex you need BOTH the Vertex (which is in ComponentDefinition) AND the specific ComponentInstance you are evaluating. From there you can walk UP the hierarchy of ComponentInstances and get their Transformations to apply to the Vertex.

                                So in Ruby we have:
                                Sketchup.active_model #top of model
                                Sketchup.active_model.definitions #returns DefinitionList
                                Sketchup.active_model.definitions[n] #returns ComponentDefinition[n] from array
                                Sketchup.active_model.definitions[n].instances[n] #returns ComponentInstance[n] from array

                                You can get a quick picture of this in SU with:

                                Sketchup.active_model.definitions.each {|definition| puts "#{definition} contains #{definition.instances}\n" }
                                

                                Glenn

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

                                  Adam, that code returns the transformation of all the copies of that instance? But no way to track back a single path to the model, like you get with PickHelper?

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

                                  1 Reply Last reply Reply Quote 0
                                  • G Offline
                                    gbabcock
                                    last edited by

                                    @gbabcock said:

                                    From there you can walk UP the hierarchy of ComponentInstances

                                    Well, not quite... ๐Ÿ˜•

                                    The Parent of a ComponentInstance is a ComponentDefinition, which can exist in more than one ComponentInstance (for example, if you have multiple instances of a Component that has nested Components). So you can't even walk up the hierarchy of ComponentInstances. ๐Ÿ˜ก

                                    But walking down works well! My use case is where I have selected a Group/Component (but not opened it) and need the global position of every Vertex. With limited testing performed, this code seems to give an accurate position report:

                                    #get vertices
                                    def Start
                                    	#get vertices
                                    	verts=[] #initialize vertices array
                                    	trans_h=[] #initialize transformation array use to store hierarchy of transformations
                                    	verts=createVerticesArray(sel,trans_h,verts)
                                    end
                                    
                                    def createVerticesArray(sel,trans_h,verts)
                                    	sel.each{|ent|
                                    		if (ent.is_a? Sketchup;;Group) || (ent.is_a? Sketchup;;ComponentInstance)
                                    			trans_h.push(ent.transformation) #push the Group/Component tranformation onto the array
                                    			ents=ent.definition.entities #get the entities in this Group/Component instance
                                    			verts=createVerticesArray(ents, trans_h, verts) #recurse
                                    		elsif (ent.is_a? Sketchup;;Edge)
                                    			ent.vertices.each{|vert| #begin analysis of vertices in this edge
                                    					puts vert if @debugFFD
                                    				#get global position of the vertex by applying the hierarchy of transformations
                                    				v_gpos=vert.position #returns local Point3d position of vertex
                                    					puts v_gpos if @debugFFD
                                    				flat_t=flatten(trans_h) #get the flattened transformation for the hierarchy
                                    					puts flat_t if @debugFFD
                                    				v_gpos.transform! flat_t #transform the vertex to get the global position
                                    				vert.set_attribute("vert","gpos",v_gpos)
                                    				verts.push(vert)
                                    			}		
                                    		end
                                    	}
                                    	#verts now contains redundant verts. remove duplicates.
                                    	verts.uniq!			
                                    	return verts
                                    end
                                    
                                    #thanks to Adam for the idea!
                                    def flatten(trans_h) #returns a flattened transformation from an array of transformations for the instance hierarchy
                                    	flat_t=Geom;;Transformation.new #create an entity transformation object
                                    	
                                    	#apply the hierarchy of transformations to the entity transformation
                                    	trans_h.each{|t|
                                    		flat_t=flat_t* t
                                    	}
                                    	return flat_t
                                    end
                                    
                                    

                                    It performs well too, though I'm sure it could be improved. I have used it on a component with ~8400 entities and 1720 vertices, and get the results back in 0.25 seconds consistently.

                                    Glenn

                                    Glenn

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

                                      Interesting thread. I'm trying to do figure out how to apply transformations to SU mesh objects for exporting. The object.transform! method seems to only perform rotation and scaling but not translation (e.g. the delta movement along the x, y, and z axis). I see that the transform matrix does indeed contain the translation values in the last row (row 4) of the matrix. Why doesn't the transform! method also perform the translation? Is this a bug or a feature?

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

                                        Never had any problems with translation and .tranform!.
                                        Maybe post a code snippet? (though in a new thread - as we're moving towards a new topic)

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

                                        1 Reply Last reply Reply Quote 0
                                        • K Offline
                                          kwalkerman
                                          last edited by

                                          one small correction to the code posted by Glenn: after calling createVerticesArray on line 14, add the line:

                                          trans_h.pop

                                          otherwise, if there are multiple sub-components in the entities collection, you will take into account the transformation of any entity that came before.

                                          Otherwise, great code, very useful.

                                          Thanks!

                                          --
                                          Karen

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

                                          Advertisement