ArcCurve to a specific layer (in the API)

This is an API technical question which I did not directly figure out…

Say, I have an ArcCurve which I would like to put on a specific layer (tag), i.e. different from Layer0 or Untagged.

ArcCurve is inherited like this:
ArcCurve < Curve < Entity < Object

In contrast Edge is inherited like this:
Edge < DrawingElement < Entity < Object

Now, according to the API documentation DrawingElement contains
the layer method to set/retrieve the layer (tag) information.
From this I would tend to conclude that I cannot set an ArcCurve (or Curve for that matter) to a specific layer (tag).

However, from the UI I have no problem selecting an ArcCurve and assign it to a particular layer (tag).

Where does my logic fail?
Or is there some way to assign an ArcCurve to a specific layer (tag)?

(1) You do not “put” SketchUp objects “on” layers. This is why their name was changed to tag.
People kept thinking of SketchUp layers as geometric containers. They are not.

They always were nothing but property sets of display behaviors, that could be shared by any object regardless of it’s place in the model’s group / component hiearchy.


(2) It is normally asking for trouble to associate any primitives (edges, faces, circles, curves, arccurves, polylines, etc.) with any layer/tag except “Layer0”/“untagged”.

All that said, … the usual exception for the rule is you need to export the model to another format whose exporter uses SketchUp layer/tags to organize, convert or treat such “tagged” objects in a particular way, so as to have the exported objects be correct for the external application.


The API docstring for the Sketchup::ArcCurve class explicitly gives you the answer …

However, keep in mind that all Curves in SketchUp are really edges with some extra data attached to them. When you use the API to draw a Curve or ArcCurve, you are really drawing edges.

… SO, …

my_curve.edges.each {|edge| edge.layer= some_layer_object }

Thank you Dan, but - as I tried to emphasize - this was meant as a purely technical question. :grinning:
I believe I fully understand the layer/tag issues (including how it is recommended to use those), so maybe I should have worded my question differently?

So the basic question really was:
Why is it that I can alter an ArcCurve (treating it as one single object) layer/tag directly from the UI but not from the API?

I was wondering if there was something that I had overlooked here. Apparently, this is not so.

For the record, in my particular use - where I import to Sketchup from other databases - I use layers/tags or names to add information to the objects being imported from databases.

Again, thanks for responding.

The UI will assign the layer/tag to all the edges in the curve. Similar to how it will assign the layer/tag to all selected entities. A curve is just an abstraction, an entity not a drawingelement. Layers/tags are assigned to drawingelements.

1 Like

I guess in the “background” all UI command executing several code to achieve its goal…
(as tt_su wrote above while I typed)

It is common that the Ruby API breaks a GUI operation down into more basic steps.

1 Like

Yes, of course.

But is this particular case it made me wonder whether I had overlooked something important!
(Which happens from time to time, I must admit!)

I am very happy there is a place like this to check one’s understanding.
Thanks everyone!

I suggest that you overlooked the explanation in the Sketchup::ArcCurve class’ YARD docstring.

And more, it’s superclass Sketchup::Curve also makes it clear …

The Curve class is used by SketchUp to unite a series of Edge objects into one conceptual entity. Since SketchUp is a surface modeler, all circles, arcs, and arbitrary curves are really just edges that are bound together in sequence.

What I’m trying to get at is that SketchUp’ API uses the inheritance model, which means that much of the shared functionality is defined in superclasses and passed down to the subclasses.

As you noticed, the layer/tag assignment method is defined in Sketchup::Drawingelement so cannot be passed down to curves because their classes do not have Sketchup::Drawingelement in their ancestral lineage.

If you look at the API classes and study them a bit, you’ll notice that only sublcass objects of Sketchup::Drawingelement can be direct members of any Sketchup::Entities collection.

Other classes deriving from Sketchup::Entity are either collection classes or helper classes (ie, things that don’t exist by themselves, and can only be used via accessing a property of something else. The loop objects for a face, for example.)
There are also classes derived directly from Object that are not (generally) things that are saved into the .skp file’s data, but are used by the application or used upon the model and it’s data (ie, the various abstract observer class objects.)

Anyway … back to inheritance. So since the curve classes are helper classes they cannot inherit the assignment for a tag/layer. But you can use a refinement if you wish and refine only your use of the two curve classes, like so …

module JoNoS
  module RefinedCurves
    refine Sketchup::Curve do
      def layer=(layer)
        self.edges.each {|edge| edge.layer= layer }
      end
    end
  end
end

… and then in your plugin file(s), you can do …

require File.join(__dir__,"refined_curves.rb")

module JoNoS
  module SomePlugin

    using RefinedCurves

    # Example method ...
    def set_curve_layer(curve,new_layer)
      curve.layer= new_layer
    end

  end
end

For more examples and explanation of Ruby refinements see the primer …


However, as Thomas explained recently in another topic, curves are just made up of individual edges, that each can have their own layer/tag assignment. They could be assigned to look like a rainbow.


You should likely use AttributeDictionary objects instead to add information (if possible.)

They can be attached to the model, any subclass of SkecthUp::Entity, even layer objects themselves or the Layers collection instead of individual layers. (Attaching to the collection does not run risk that a user would delete the data if they delete a layer/tag.)

1 Like

Thanks a lot Dan, for a most informative answer!
I need to digest this a little the coming days. Thanks again!

1 Like