Repository navigation
Conversation
gonzalocasas
left a comment
There was a problem hiding this comment.
This one is a bit tricky, I would say that the real problem is in compas itself, and it should actually be handled there. Which makes this a potentially problematic workaround, because if compas core ever fixes this, this might misbehave (or in the best case, just do extra work).
Since there's probably not an easy and quick way to change this in compas (note that there are some draft PRs open to tackle this), I guess it's fine to keep the workaround here, but it should be rather strictly marked as such
| if not has_scale: | ||
| # No resize at all - Shape.transform (== frame.transform) already does | ||
| # exactly the right thing here: moves the point, rotates the axes. | ||
| geometry.transform(translation * rotation) |
There was a problem hiding this comment.
Why recompose the matrix, which incurs into additional computing, instead of passing the original transformation if scale will be ignored anyway?
| if not hasattr(geometry, "frame"): | ||
| # Not a Shape (e.g. a Point/Mesh/Polyline, transformed via its own raw | ||
| # coordinates) - unlike Shape, these support a general affine `.transform()` | ||
| # including scale directly (Shape is the one deliberate exception - see its | ||
| # own docstring above), so the full delta can just be applied as-is. | ||
| geometry.transform(transformation) | ||
| return |
There was a problem hiding this comment.
this is a very weird way to check if this is a shape or not, why not an isinstance of the correct super-class of Shape?
642ebe6 to
e320641
Compare
Shape.transform() (the base for Box/Sphere/...) only ever applies to the shape's frame and explicitly does not support scale, so applying a TransformControls scale-mode gizmo drag straight to geometry.transform() silently dropped the resize's effect on frame.point, and applying only the rigid (translation * rotation) part of the delta - as the old code path effectively did - could land the object's pivot a full grid unit away from where the gizmo showed it for a real-world resize amount. _apply_transform_with_scale now decomposes the incoming delta and, for a Shape being resized, applies the FULL delta (translation and scale together) to frame.point while only the rotation part goes to the frame's axes, then resizes via Shape.scale(). Non-Shape geometry (Point/Mesh/ Polyline) isn't scale-blind the way Shape is, so it keeps getting the full delta applied directly via its own .transform(). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
e320641 to
6aae427
Compare
Summary
Shape.transform()(the base for Box/Sphere/...) applies only to the shape's frame and ignores scale. A scale-mode TransformControls drag therefore lost the resize's effect onframe.point, and the object's pivot could end up a full grid unit away from where the gizmo showed it.Inbox._apply_transform_with_scalenow decomposes the delta. For aShapeit applies the full delta (translation + scale) toframe.pointand only the rotation to the frame axes, then resizes viaShape.scale(). Non-Shape geometry (Point/Mesh/Polyline) keeps getting the full delta through its own.transform().Stacked on #58 (WebSocket max frame size); merge that first. Frontend counterpart: compas-dev/compas_threejs_ts#33.
Test plan
pytest(newtests/test_object_transform_scale.py)🤖 Generated with Claude Code