In the attached model, there is a tree of 3 groups. Call the innermost g1, the parent instance g2 and the outermost g3. g2 is scaled to twice its original size. A dimension dim is attached to g1 in g2
Now, going from now open groups to opening each one, I create a vector of dim.start[1] and dim.end[1] and print its length. The results are:
dim.start[1].vector_to(dim.end[1]).length
139mm
dim.start[1].vector_to(dim.end[1]).length
139mm
dim.start[1].vector_to(dim.end[1]).length
278mm
dim.start[1].vector_to(dim.end[1]).length
278mm
So before I open the scaled group, the length, according to the positions is 139 and afterwards it is 278. Now, even if the positions are not supposed to be in model space, isn’t it logical that when outside of the group context the length will be 278 and inside it’ll be 139?
What should I do to fix this anomaly? Note that when I scale g1 (the inner group), this doesn’t happen. When I scale g3, the same effect happens (even though I’d expect the length to change from 139 to 278 when I open g3)
I’m seeing the same results. Assuming that;
dim = Sketchup.active_model.entities[0].entities[0].entities[1]
When I check the start points at the most outer and inner levels of edit mode I observe:
Outer:
dim.start[1]
(153mm, 0mm, 139mm)
Inner:
dim.start[1]
(112.004929mm, 10mm, 288mm)
Not only is a scale change occurring, but a translate as well (y value from 0 to 10 mm). It appears that when in edit mode on nested grouped objects, the transformation(s) are being applied.
To make it clear, the most confusing part is the dimension measures at 139 when the group is not open (they is, in the global context) and 278 when the group is open
When I first worked with the Sketchup API, I reached the same conclusion. I thought that a grouped object would simply consist of links or pointers (i.e. the definition) to the loose drawing elements that would retain their world coordinates. Sketchup’s approach simplifies the implementation of component instances, where a common component definition can be reused at multiple positions and orientations with a transformation matrix unique to the instance. That requires that the drawing elements in the definition be in local coordinates relative to the transformation’s origin position. The transformation matrix associated with the grouped object determines the grouped object’s position, orientation, and scaling. I believe that same approach can be used in OpenGL to reduce graphics card memory useage. Now as to why the positions change when edit mode, I suppose when in edit mode, the current edit context establishes temporary coordinate system relative to the existing transformations.
I think the Sketchup internals have more context than what the API provides. Normalizing the coordinates, so they are always relative to the parent is a tricky business that requires opening and closing groups (pasted the code below). The API should be much simpler to use than that. I’m not drawing these elements, I just want to reason about them
NOTE: this method is added to Group and ComponentInstance
def transformation2
undo = 0
selection = self.model.selection.map(&:itself)
begin
while !self.model.active_path.nil? && self.model.active_path.include?(self)
# this self is open. this causes sketchup to return the unit transformation for it, and parents while
# the edit_tranfrom is the comulative transform (to the model space)
self.model.close_active
undo += 1
end
t = self.transformation
if self.parent.entities == self.model.active_entities
# self belongs to the current/active entities collection.
# Here SketchUp for some reason transforms the coordinates to model space before returning it.
# Transform it back to the logical and consistent local coordinate space.
# Transformations and other coordinates (Point3d and Vector3d) requires different methods for applying transformations.
t *= self.model.edit_transform.inverse
end
t
ensure
undo.times {Sketchup.undo}
self.model.selection.add(selection)
end
end