Retrieving Global Position of Face or Edge in Nested Components/Groups

Hello everybody,

I’m trying to find a reliable method to retrieve the correct global position of a Face or Edge in SketchUp. Most of the time, the entity is part of the global model, but it can also be nested inside one or more groups or components, which themselves can be nested within other groups or components.

Problem:

  • The Face or Edge is not selected.
  • I cannot rely on user input to select the entity (e.g., using PickHelper).
  • I want to receive the global positioning of a Face or Edge (or the correct transformation).

What I have so far:

Here’s the code I am currently using to handle cases where the Face or Edge is inside a ComponentInstance:

def get_parent_transformation
    
    found_instance = nil

    if !parent.is_a?(Sketchup::Model) && (self.is_a?(Sketchup::Face) || self.is_a?(Sketchup::Edge))
      vertices_local = vertices.map { |vertex| vertex.position }
      instances = parent.instances  
      instances.each do |instance|
        vertices_global = vertices_local.map { |point| point.transform(instance.transformation) }
          match = vertices.each_with_index.all? do |vertex, index|
          vertex_global_position = vertex.position.transform(instance.transformation)
          puts vertex_global_position.distance(vertices_global[index])
          (vertex_global_position.distance(vertices_global[index]) < 0.001)
        end

        if match
          found_instance = instance
          break
        end
      end
    elsif !parent.is_a?(Sketchup::Model) && self.is_a?(Sketchup::ComponentInstance)
        found_instance = find_parent_instance(self)
    end
    if found_instance

      parent_transformation = found_instance.get_parent_transformation * found_instance.transformation
    else
      parent_transformation = Geom::Transformation.new
    end
    parent_transformation
  end

Current Behavior:

  • This code works when the Face or Edge is nested one level deep inside a ComponentInstance.
  • It works by comparing the global and local positions of vertices to determine the correct instance.

Problem I’m Facing:

  • The issue arises when the Face or Edge is nested deeper within multiple levels of ComponentInstances (i.e., a ComponentInstance inside another ComponentInstance).
  • In this case, I’m unsure how to accurately identify which ComponentInstance is the correct parent, especially when there are multiple instances of the same ComponentDefinition.

Question:

How can I reliably determine the correct ComponentInstance (or global positioning) when a Face or Edge is nested deeper inside multiple component hierarchies? Is there a way to ensure that I apply the correct transformations recursively when dealing with complex nesting?

Any insights or suggestions would be greatly appreciated!

I don’t understand. How do you determine which face or edge is of interest?

1 Like

It also appears that your code may be modifying the Face or Edge classes. If so, please do not.
Instead use a Ruby refinement.


This question has been asked and answered multiple times here in this category. Just recently in fact.

A nested entity cannot know which instance path it is that you wish to know the transformation for. Ie, it can be a member of multiple instance paths.

So your code will need to walk the model hierarchy and build an InstancePath array as it goes, and get the transformation from it.

How are you first getting the reference to the edge/face?

The same edge or face can occur any number of times in the model. There can be multiple instances of the same group or component that holds the edge or face. To know the transformation for one specific occurrence of this object, to calculate its global position, you need to know the full path of its parent groups/components up to the model root.

If you are making an exporter that iterates over all content in the model, you can collect this back trace as you are iterating. You can also keep track of the transformation as you iterate.

https://developer.sketchup.com/article-series/traversing-sketchup-model

If you are working on a custom Tool, you can use the PickHelper or InputPoint class to provide either the path or the transformation for you as the user picks the entity.

2 Likes