Or an alternative, but less preferred method (cut perpendicular to face):
As far as I know, there is no easy (or difficult) way to obtain this affect. Especially when you take into account that not all hole cutting components are rectangular.
It isn’t normal behavior. I’ve had this happen to me before and wanted to report it as some bug. But after saving and reopening the file to report, there was nothing there anymore showing the distortion. The issue had healed itself by saving the file. And I wasn’t able to reproduce the distortion to report. But it’s certainly not a feature.
Hmmm… I missed that part. The ‘healing’ that occurs, is that the component is actually moved to match the plane of the face. Interesting!!! Not bad if that’s what you actually wanted.
It seems that a validity check is done when saving.
I can’t see any use for this feature, although others might, who knows.
As for it being a bug, if it happens enough to others as well and it can be reproduced, certainly. Then yes, report it.
So… It seems to me that there should be a way to check if gluing the component will cause it to move. Or maybe even a feature to test a face, or an array of faces, and see if their planes are valid to glue the component to? It seems there is no possible way of getting the hole-cutting face of a component. I understand it’s not really a face, but its seems like there should be a way to figure out where the cutting will take place, or has taken place.
model = Sketchup.active_model
entities = model.active_entities
face = entities.grep(Sketchup::Face).first
instances = entities.grep(Sketchup::ComponentInstance)
# Assumes the instances are in the same Entities collection as the faces.
instances.each { |instance|
point = instance.transformation.origin
# The classify_point check is a very naive check to see if the origin of
# the instance is actually on the face and not just on the plane.
# You might have to tweak that to your conditions - like allowing the point
# to be on the vertices and edges.
if point.on_plane?(face.plane) && face.classify_point(point) == Sketchup::Face::PointInside
puts "Gluing #{instance} to #{face}"
instance.glued_to = face
end
}
I see. Check first to see if the origin is on the face. then check the zaxis.
Now that part is solved.
I still have no way of know the dimentions of the cut hole. Currently I just create additional instances of the component. This works alright except for two things.
For complex components you end up with a lot of geometry.
The glass gets less translucent because of the additional copies.
In my building creator extension I can control the shape and size so know where to cut the hole, but with user supplied components there’s no way to know.
One more question (this should be the last). If I check a component and the Z-axis is aligned with the plane of the face, but the component origin is not on the face, how can I calculate the distance between the face and the origin? On a normal wall this would be the wall thickness. And one more: how do I transform the component to move that distance? Basically I need to move the component to be on the face.
Geom::Point3d#vector_to()
returns a new vector object between the point argument and the point itself.
The distance will be returned by the vector object’s length() instance method.
(But you do not really need it to move the component. You can test a vector if it is NOT of zero length via it’s valid?() instance method. See the example below that does this and only creates an undoable operation if the test is true.)