sketchucation logo sketchucation
    • 登入
    Oops, your profile's looking a bit empty! To help us tailor your experience, please fill in key details like your SketchUp version, skill level, operating system, and more. Update and save your info on your profile page today!
    🔌 Smart Spline | Fluid way to handle splines for furniture design and complex structures. Download

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

    已排程 已置頂 已鎖定 已移動 Developers' Forum
    25 貼文 6 Posters 5.4k 瀏覽 6 Watching
    正在載入更多貼文
    • 從舊到新
    • 從新到舊
    • 最多點贊
    回覆
    • 在新貼文中回覆
    登入後回覆
    此主題已被刪除。只有擁有主題管理權限的使用者可以查看。
    • J 離線
      jessejames
      最後由 編輯

      @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 條回覆 最後回覆 回覆 引用 0
      • AdamBA 離線
        AdamB
        最後由 編輯

        @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 條回覆 最後回覆 回覆 引用 0
        • thomthomT 離線
          thomthom
          最後由 編輯

          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 條回覆 最後回覆 回覆 引用 0
          • G 離線
            gbabcock
            最後由 編輯

            @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 條回覆 最後回覆 回覆 引用 0
            • G 離線
              gbabcock
              最後由 編輯

              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 條回覆 最後回覆 回覆 引用 0
              • thomthomT 離線
                thomthom
                最後由 編輯

                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 條回覆 最後回覆 回覆 引用 0
                • G 離線
                  gbabcock
                  最後由 編輯

                  @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 條回覆 最後回覆 回覆 引用 0
                  • D 離線
                    dburdick
                    最後由 編輯

                    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 條回覆 最後回覆 回覆 引用 0
                    • thomthomT 離線
                      thomthom
                      最後由 編輯

                      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 條回覆 最後回覆 回覆 引用 0
                      • K 離線
                        kwalkerman
                        最後由 編輯

                        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 條回覆 最後回覆 回覆 引用 0
                        • 1
                        • 2
                        • 2 / 2
                        • 第一個貼文
                          最後的貼文
                        Buy SketchPlus
                        Buy SUbD
                        Buy WrapR
                        Buy eBook
                        Buy Modelur
                        Buy Vertex Tools
                        Buy SketchCuisine
                        Buy FormFonts

                        Advertisement