How to attach Sketchup::Text to Sketchup::ComponentInstance


#1

Hi guys,

I want to iterate through scene, find all ComponentInstances of definiton X and conditionally label them with dimensions here and there based on some magic business logic to be determined yet.

How can I add label to, say, a middle point of CompoentInstance? Sketchup.active_model.entities.add_text is not sufficient, because the label doesn’t move when I move the instance (it is not glued to it?). All I could figure out is make the instance into a group and add_text to that group, but that does not seem like good idea because it clutters the object tree with unnecessary group.

Please help!


#2

Long known issue in the Ruby API.

In the C API the latest version (6.0) released with SketchUp 2018, has the ability to set the connection to objects via an InstancePath instance.

Not sure if the Ruby API’s Sketchup::Text#point= method was updated as well.

(The docs do not mention that it was updated. And then again, normally Ruby methods using an equal sign generally should only take 1 argument, and if they need to take more, usually they must be wrapped in an array.)

So you could try it in SU2018 Ruby …

leader = Sketchup.active_model.entities.add_text("Some text", point, vector)
leader.point= [ point, Sketchup::InstancePath::new([comp_inst]) ]

… and if you get an ArgumentError or a TypeError then likely it has not yet been updated to leverage the new C side functionality.


If you know C, you could write a little C extension to create a Ruby binding to call the C side function ?

ping @thomthom


#3

The APIs have not been updated to handle InstancePath (or array representation). We have tickets logged for that though.

I’m not sure if the C API expose anything useful for this…


#4

Thank you for your replies! I did not try the C api yet, so far I just attached it to component group. The only issue left is that group’s boundbox gets enlarged to include label’s dimensions.


#5

It sure looks like the following C API method sets the connection point …

SU_RESULT SUTextSetPoint (SUTextRef text, const struct SUPoint3D *point, SUInstancePathRef path)

Sets the connection point of a text object. A text’s connection point can be set in a few different ways. In the simplest form a connection point can be set to an arbitrary point in space by providing a non-null SUPoint3D and an invalid SUInstancePathRef. The more complex forms to connect the point to a position on an entity in the model by providing a valid SUInstancePathRef which refers to an existing model entity. In the more complex forms the input SUPoint3D must be non-null for all connectable entity types except for vertices and guide points, in which case the SUPoint3D argument may be null as it will be ignored. It should be noted that when changing a text’s connection point the other point may need to be adjusted as well. Users may want to verify the other connection point after setting this one.

I think that the “other point” referred to above is meant for when dealing with dimensions, and may be a doc mistake. (I don’t see any need for type casting between dimension text and leader text. It may be that the doc should refer to the start point of the leader vector that may need to be also adjusted.)


The above function goes along with this one …

SU_RESULT SUTextGetPoint (SUTextRef text, struct SUPoint3D *point, SUInstancePathRef *path)


And BTW, all these C API SUTextRef object functions are new for SU2018, C API ver 6.0.


#6

Ah - yes. There was a lot of additions to the C API for SU2018. I’d actually not noticed the SUTextRef myself.
That being said - you currently cannot use the C API to make model changes. It’s read only (experimental).
(Nothing prevents you from trying to modify the model, but you’ll gonna be messing up the undo stack and most likely crash eventually.)


#7

Oh,… no operation function yet, similar to rb_protect() and siblings ?

And, BTW, access to Text leader connection points is one of the oldest Ruby API requests. It comes up every year it seems (as it has here in this thread.)
Add to that access to and control of font metrics for both Text and Dimensions.


#8

rb_protect doesn’t relate to model operations. It’s just a mechanism from preventing Ruby exceptions from jumping out of the current stack.

But for model changes inside of the SketchUp client an active undo operation is required for things to be done properly. So the C API will need something similar to the Ruby API’s model.start_operation.

In a standalone use of the C API, then operations are not needed. (And standalone usage of the C API is the only supported usage right now.)


#9

I know, I did say similar.

Really? I could think that there might be situations where you add geometry and such, and then test something, and may need to “undo” or backtrack.

What would a C coder need to do in this case ? Start all over again and toss out all the changes they made ?


#10

Undo operations are entirely for the end user within the SketchUp client. When using standalone C API to author SKP files you don’t have an end user like that.


#11

You’re just stating the obvious and not answering the real question.


#12

Sorry, I didn’t what you meant by “test something” to which undo operation would solve anything.

But after a fresh night’s sleep I presume you meant using it as a transaction construct, like databases, where you can roll back in case one of your model modifying function calls would fail?

If that wasn’t what you mean, could you provide an example?


#13

… yes exactly what I meant. :cookie:

It might be “expensive” and time consuming to have to abandon the attempt, destroy all the objects in memory and start over again. (I can see coders writing a bunch of temporary SKP files at strategic times to get around this. Which makes a chore of cleaning up any unused files later.)