How to use a Component to provide a generic face?

I’ve been using a component definition to generate various solids that I move with a transform and instantiate. I wanted to do this for extruding a face, but am having problems.

For solids, I define a component that creates a face and pushpull’s it into a solid. I then add_instance the definition with a transform to put it where I want it.

What I tried to do to extrude a face was to make a component that just makes a face (add_face). I then add_instance it with a transform. I then try a followme on it to extrude, but the instance doesn’t seem to be a vanilla face anymore. I now see it as a “ComponentInstance”, not real surprising. I tried various ways of extracting the raw face but can’t. Any guidance on how to extrude it? Code below. Thanks.

  def self.create_component_definition_molding()
    @componentDefinitionMolding=@definitions.add "molding"
    moldingFace = @componentDefinitionMolding.entities.add_face [0, 0, 0], [1, 0, 0], [3, 0, 2],[8,0,4],[8,0,5],[7,0,5],[0,0,2],[0,0,0]
  end

  # Draw top/trim molding
  # Create a molding face
  self.create_component_definition_molding()
  @transform=Geom::Transformation.new([128,18,94])
  moldingFace=@entities.add_instance(@componentDefinitionMolding,@transform)
  UI.messagebox("moldingFace type: " + moldingFace.typename)
  # Create the extrusion path
  path = @entities.add_edges [128,18,94],[128,6.75,94],[0,6.75,94]
  # Extrude the molding along the rectangular path
  moldingFace.explode.entities[0].face[0].followme path     (line 426)

This results in:

Error:NoMethodError: undefined method entities' for #<Array:0x0000000cc55c90>> C:/users/gkd/sketchuprubyscripts/shelfUnitAnthony.1.rb:426:inmodule:Shelving
C:/users/gkd/sketchuprubyscripts/shelfUnitAnthony.1.rb:12:in `<top (required)>’

:in `load' :in `' SketchUp:1:in `eval'

Update: Looks like you can’t “explode” in place, since changing the last line to the 2 below seems to work as expected:

  array=moldingFace.explode
  array[0].followme path

Explode returns an Array of Entity objects. You can’t run entities on that array since there is no entities method on Arrays.

This should work:

moldingFace.explode.find { |e| e.is_a?(Sketchup::Face) }.followme path

It also iterates the Entity objects returned by the explosion to find the one that is a face regardless of its index. However I would not use the variable name “moldingFace” for something that isn’t a face but a ComponentInstance.

1 Like

Works great. I see what’s going on now. Thanks.

Also, a question on extruding. The lower left corner of my face was at 128,18,94 after the transform. I then extruded with a path that had a Z coordinate of the lower left corner of the transformed face. I thought I had to match the lower left corner, but it seems it doesn’t matter. I changed the path’s Z coordinates to 0, and it still worked as expected. Is that because Sketchup knew I was extruding normal to the face (in the XY plane, since all Z values were equal)? What if I wanted to extrude with a path that had different Z values? What happens if I extrude with a path that doesn’t start with a point on the face? Any pointers to more detailed documentation on extruding? Thanks.

You can play around with the Follow Me tool in Sketchup to better understand how it works. If you’re only extruding along a single line you can also use pushpull.

Some further scripting experiments cleared things up. Here are my new “rules to extrude by”:

  • As expected, drawn faces have their normal based on the right hand rule: ccw vertex’d face -> normal out.
  • Looks like extruding starts from the initial face, and then travels parallel to the path.
  • So, probably clearer to actually start the extrusion path from any point on the face.
  • And probably clearer to use a face point that is more interesting in the final solid.
  • If not using a path coincident with a face vertex, or later transform’ing the extruded solid, should delete the path by looping through edge.erase!'s so no longer visible.