sketchucation logo sketchucation
    • Login
    1. Home
    2. gbabcock
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info
    G
    Offline
    • Profile
    • Following 0
    • Followers 0
    • Topics 2
    • Posts 14
    • Groups 1

    gbabcock

    @gbabcock

    10
    Reputation
    1
    Profile views
    14
    Posts
    0
    Followers
    0
    Following
    Joined
    Last Online

    gbabcock Unfollow Follow
    registered-users

    Latest posts made by gbabcock

    • RE: Find the global position of a Vertex in a Group/Component

      @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

      posted in Developers' Forum
      G
      gbabcock
    • RE: Find the global position of a Vertex in a Group/Component

      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" }
      
      posted in Developers' Forum
      G
      gbabcock
    • RE: Find the global position of a Vertex in a Group/Component

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

      posted in Developers' Forum
      G
      gbabcock
    • RE: Find the global position of a Vertex in a Group/Component

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

      posted in Developers' Forum
      G
      gbabcock
    • RE: Find the global position of a Vertex in a Group/Component

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

      posted in Developers' Forum
      G
      gbabcock
    • RE: Find the global position of a Vertex in a Group/Component

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

      posted in Developers' Forum
      G
      gbabcock
    • RE: Find the global position of a Vertex in a Group/Component

      @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

      posted in Developers' Forum
      G
      gbabcock
    • RE: Find the global position of a Vertex in a Group/Component

      @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

      posted in Developers' Forum
      G
      gbabcock
    • RE: Find the global position of a Vertex in a Group/Component

      jessejames, thats not quite what I was after, but thanks for the post!

      thomthom, thanks for the feedback. I'll check out PickHelper in any case, sounds interesting.

      BTW, the code snippet I posted does work, I was testing it last night, and it doesn't traverse the model. The only caveat was that I had to use group.make_unique on copies of groups due to the bug discussed on this forum.

      Glenn

      posted in Developers' Forum
      G
      gbabcock
    • Find the global position of a Vertex in a Group/Component

      Being new to this, I've been searching around to find a way to get the global position of a vertex when it is in an unopened group, or even worse when it is in a nested group. I found a lot of good info in this forum, and learned that you need the Point3d of the vertex AND the Transformations of the parent Group(s) and/or Component(s). The problem is how to get the parents starting from an edge without walking the entire Group/Component/Model from the top-down.

      The SU API seems to be very top-down oriented, and it is not intuitive how you walk up the hierarchy. Assuming that this is correct?:

      HIERARCHY
      === Model
      ====== DefinitionList
      ========= ComponentDefinitions
      ============ ComponentInstances #collection of Group or Components Instances
      ============ Entities
      ============ ComponentDefinitions
      =============== ComponentInstances #collection of Group or Components Instances
      =============== Entities

      If so, then if you start with an edge (or face) in a Group/Component you can do this:

      • edge.parent #returns ComponentDefinition
      • edge.parent.instances[0] #returns first ComponentInstance of ComponentDefinition, a Group or Component
      • edge.parent.instances[0].parent #returns the next level ComponentDefinition or the Model
        Now you have the hierarchy of Groups/Components, and can easily access their Transformations!

      I've been messing around with this for the SketchyFFD and Position_Explorer plugins, but didn't come across this solution, so I thought I would post it for the group's opinion and/or entertainment πŸ˜‰.

      #call with ent=a face or an edge
      #returns an array of Point3d objects that equal the global position of the vertices	
      #currently only gets the first ComponentInstance, works for Group, but Components may have many instances
      def getGlobalPosition(ent) 
      	g_pos=[] #array to store global positions of vertices
      
      	#get local position of vertices
      	ent.vertices.each_with_index{|vert,i|
      		g_pos[i]=vert.position
      	}
      
      	#get the parent
      	p=ent.parent
      
      	#while the parent is a group or component
      	while p.is_a? Sketchup;;ComponentDefinition
      		#get the group/component transformation
      		grp=p.instances[0]
      		grp_t=grp.transformation
      
      		#apply the group transformation to the stored position of the vertices
      		g_pos.each{|g|
      			g=g.transform! grp_t
      		}
      		
      		#get the next parent in the hierarchy
      		p=p.instances[0].parent
      	end	
      	return g_pos
      end
      

      Make sense?

      This performs reasonably well, does anyone know a faster way?

      Thanks,
      Glenn

      posted in Developers' Forum
      G
      gbabcock