Bug in glued_to?

I have an interesting bug in my app when inserting a component (window) onto another component (wall) the component is usually glued to the component (wall). Occasionally however the component (window) somehow ends up glued to a face inside the wall component. I can’t see how this is possible because that seems to be illegal.

Is this a SketchUp bug or am I missing something?

OK saving the model does set the glued_to to nil. This really bugs me. (I was going to post the model).

What I’m trying to do is find all components that are glued_to a particular component.

This is what I had but it wasn’t returning components that were incorrectly glued to a face in the component.

def get_glued_instances
  co = self.parent.entities.grep(Sketchup::ComponentInstance).find_all { |c| c.glued_to == self}
  return co
end

This works but still doesn’t seem right because there could be potentially more than one instance of a definition, although in my particular situation there won’t be.

def get_glued_instances
  co = self.parent.entities.grep(Sketchup::ComponentInstance).find_all { |c| (c.glued_to == self) || (c.glued_to !=nil && c.glued_to.parent == self.definition && c.parent != self.definition)}
  return co
end

Why would gluing to a FACE be illegal, when the Sketchup::Face class itself has a #get_glued_instances() method ?

Currently, in order for the built-in “cuts opening” feature to work, the cutting component must be glued directly to a face (this means inside a group or component,) the component must have been drawn correctly lying upon the XY cutting plane, and it’s snapto behavior setting set to anything other than none.

I’m “purty” sure we’ve complained about this over the years and have asked for cutting components that will cut multiple faces. (Ie, great for doors and windows, bolts, etc.) This would imply (I hope) gluing to the “outside” of a component.

Anyhow, … I have a Refinement project I play with from time to time, and it has the same refinement methods you show. We’ve discussed this in the past and some of us may have posted our refinement methods in those threads.

_EDIT: Evidence your thread on the subject 2 full years ago: Find faces component 'lays' on - #12 by Neil_Burkholder

So for the Sketchup::ComponentDefinition class refinement I have a whole bunch of “get_glued_… whatever” methods to find internally glued instances that are almost verbatim what you have shown here, except they refine the definition instead of accessing it via self.parent.


The API docs are incorrect in that they do not state that the return classes for Sketchup::ComponentInstance#glued_to() can also be (in addition to nil and Sketchup::Face,) Sketchup::Group, Sketchup::ComponentInstance and Sketchup::Image.

This also implies that the Sketchup::ComponentInstance#glued_to=() can accept all these same classes as the object argument for assignement (or deassignment in the case of nil.)

FYI, it has been requested for a long time that Sketchup::Group get a behavior and these two gluing methods.

You are correct except for the fact that a component can only be glued to a face in the same parent context as itself. The behavior I’m seeing is that the component is glued to a face inside another component. That is the ‘illegal’ behavior I’m talking about. In this case when the model is saved the glued_to of the windows component goes to nil. The correct behavior would be that the window component would be glued to the porch component rather than a face inside the porch.

Thanks for putting that class together. I understand about refinements. Shame on me for procrastinating so long to implement them.

I thought I could solve the issue by doing something like this:

def fix_gluing_problems
  d = Sketchup.active_model.definitions
  num_prob = 0
  d.each {|cdef| 
    cdef.instances.each {|c| 
    if c.glued_to != nil && c.glued_to.parent != c.parent then
      c.glued_to = c.glued_to.parent
    end       
    }
  }
  return num_prob.to_s + ' gluing problems fixed'
end

However I get this error:

Error: #<ArgumentError: wrong type - expected Sketchup::Face>

It seems like there is an API error that doesn’t allow you to specify another component to glue to, only a face.

Apparently not.

Okay, I stand corrected as to the assignment method.

This is not a bug for the assignment, it’s just one of those features that is implemented for interactive use but not exposed to the API (yet.) Suggest opening a request in the tracker.

For the other bug try to see if you can nail down the “occasions” (ie reproducible example) when this mis-gluing happens. Is the face at some acute angle to the camera when this happens? Is there an undesired inference active at the time? What is the snapto behavior for the component ? … etc.
If you can file a separate issue on this bug.

OK did that.

It reliably happens when I snap to the corner of the two faces, but only if the edged in the component are hidden. Note that when snapping at the corner the face glued to is whichever face the mouse is over.
gluing bug.skp (17.4 KB)

This appears to be a GUI error rather than an API error. So I don’t think it would be welcome in the API issue tracker.

Please note that this is a tracker for the SketchUp and LayOut APIs only.

@thomthom Where should this get filed ?

@Neil_Burkholder So what do you need to do ? Use a observer and set the edges visible during the component placement, and reset them hidden afterward ?

I’m not exactly sure. For now I’m telling customers that if a component doesn’t cut out properly delete it and re-insert it. Since this is an edge case it works fine and rarely is a problem. I’m happy to finally have pinpointed the source of the bug. I’ve also implemented the code above to detect such situations and still handle the cutout. Unfortunately this doesn’t work if the user saves the model, because then the glued_to is set to nil. For my use case this isn’t a huge deal because my extension is designed to be a visualization tool and many times models are discarded when done rather than saving them.

A quick and dirty fix would be to set Hidden Geometry to false, and then back to true after inserting the component. I couldn’t find how to do that in the API though.

1 Like
Sketchup.active_model.rendering_options["DrawHidden"]=true

Sketchup.active_model.rendering_options["DrawHidden"]=false
1 Like

… and the ol’ toggle (but it does not tell you what the setting was or is) …

Sketchup.send_action("viewShowHidden:")

Ok I implemented that using observers. Now I find out that in some cases showing hidden geometry, before inserting the component doesn’t fix the issue. I guess I’ll leave it for now. I’ve wasted enough of time.

1 Like

Any non-APi related issues, report that to SketchUp support.

I have imported a png image to plot from. It was glued to XY. They don’t always glue to XY, but sometimes seem to automatically. Why would it do that? Am I doing it myself without realising? The only way I know to glue is right context click and I didn’t do that.

This is a real problem for me. Currently I can’t find anyway to glue a component to another component using the API.

Here is a gif showing why it is a problem.

Can anyone suggest a work around?

The API .glued_to is a method associated with a face, not a component instance or group.
Although manually adding a gluing component might glue it onto a face beneath it inside a container, it cannot be replicated in code…

The .glued_to might return an instance or group, but there’s no equivalent method to set the gluing, unless it’s a face, and then you do need to check that the face is oriented sensibly on the instance.definition gluing-plane, otherwise very weird results can happen…

You could add the window instance directly into the shed’s entities, and glue it there, but only onto a face, checking orientation etc… of course the definition of that shed component then has a window in all instances, so you might want to invoke make_unique too ?

The SketchUp core very much supports gluing to another instance, but the API doesn’t. You may be able to glue to a face and then group that face and then turn the group to a component and then swap out the definition, but it’s a lot of extra steps and may be fragile.

1 Like

Layman’s suggestion that may be a workaround:
If you position a ‘Glue to’ component A to a face inside the group or component B that you would like A to glue to… Then cut A inside B > close B > paste A in place outside.
I’m not sure how that would / could be done in Ruby but A will stick to B in the end, not directly to its face inside. This odd workflow works in plain SketchUp.