Transform geometry within comonent or sub-components

I’d like to do a transform, i.e. move/rotate bare geometry that is inside a component, or in it’s sub components.
(Creating new geometry is not an option).

I’m barely able to get the geometry grouped (I understand that is what is needed for the transform?). Unless I can move/rotate the geometry without grouping/making a component… !?

I’ve tried various different ways, and got all kinds of odd geometry appearing in the wrong places… Sketchup crashed a few times. In the following code it creates a group… but the group is sorta still related to the selected component, so if I delete the group, the component is not selectable…

My problem must be related to what I’ve read here and there, that the elements to be grouped must be in:
Sketchup.active_model.active_entities, and I guess the sub-geometry is not considered part of that? Maybe I need to copy the geometry out somehow, group it, and put it back in!? (what a mess :slight_smile: ).

def make_grouped
  entities = Sketchup.active_model.selection
  ents_array = Array.new
  entities.each { |ent|
    ent.definition.entities.each { |ent|
      ents_array.push ent  
    }
  }
  new_group = Sketchup.active_model.active_entities.add_group(ents_array)
end

See Class: Sketchup::Entities — SketchUp Ruby API Documentation

# Apply the same Transformation to  all entities in a Group
tr = Geom::Transformation.rotation([0, 0, 0], X_AXIS, 90.degrees)
grp.entities.transform_entities(tr, grp.entities.to_a)

# Apply the same Transformation to all model entities
entities = Sketchup.active_model.entities
entities.transform_entities(tr, entities.to_a)

Or to re-use a bit if your example:

ent.definition.entities.transform_entities(tr, ent.definition.entities.to_a)

Thanks Jim.
That works great on geometry in a component.

Now I’m trying to apply that on geometry that is in a few sub-components that are in various locations in a component. And what I’ve come up with isn’t working very well… Something in how I am defining the origin is not correct? It’s rotating every component differently and not with each of their axis, but some invisible axis in different locations for each one…

def rotate_90
  entities = Sketchup.active_model.selection
  entities.each { |ent|

    ent.definition.entities.each { |sub_ent| 
      if sub_ent.is_a?(Sketchup::ComponentInstance)
        origin = sub_ent.transformation.origin
        vector = sub_ent.transformation.xaxis
        tr = Geom::Transformation.rotation(origin, vector, -90.degrees)
        sub_ent.definition.entities.transform_entities(tr, sub_ent.definition.entities.to_a)
      end
    } 
  }
end

[quote=“Yoni, post:3, topic:37927”]
tr = Geom::Transformation.rotation(origin, vector, -90.degrees)
[/quote] relate to the instance.
You want to transform the definition’s entities, so something like:

tr = Geom::Transformation.rotation(ORIGIN, X_AXIS, -90.degrees)

Where the capitalized Constants relate to the model OR within the component definition’s internal axes…
If you have multiple instances of the same definition, then the definition’s contents will rotated more than once !

Thanks Tig,
Using the constants seems to work, and yes, with multiple instances of the same definition I’m getting extra rotations… Would there be an “easy” way out of the extra rotations?

Is there documentation about the ORIGIN constant? It’s quite confusing that the constants aren’t quite constant, but rather change according to their context. I guess it’s sort of like __FILE__ ?

Try adding this code in instead…

defns = [] ### to store processed definitions
tr = Geom::Transformation.rotation(ORIGIN, X_AXIS, -90.degrees)
ent.definition.entities.grep(Sketchup::ComponentInstance).each { |e|
  ### grep filters for just that kind of entity
  defn = e.definition
  next if  defns.include?(defn) 
  ### only process ONE instance of any definition
  defns << defn
  ### remember processed definition
  defn.entities.transform_entities(tr, defn.entities.to_a)
  ### transform the definition's entities once...
}
1 Like

If the examples above are used on drawing elements that are nested inside a grouped object, then transformation constructor arguments would be relative to the local coordinate system. For example: a rotation performed in a chain of nested transformations that results in an overall mirror would result in the vector being in the reverse direction relative to the user. If performing a translation (i.e. linear movement), directions and distances in the local coordinate system are affected by the chain of nested transformation rotations and scale factors (and any mirroring).