With Snap to Grid on, a move of objects on one perspective plane at
different depths applied the snap correction only to the objects at the
first object's depth, and every other object moved by the pointer's
offset read at its own depth. Those objects left the grid and lost their
spacing.
Every object on the first object's plane now moves by that object's
plane offset plus the correction, so the edge of the joint bounds nearer
a gridline lands on it and the objects keep their spacing. A selection
at one depth snaps as before, and objects on other planes keep their own
offset.
Commands whose `id` or `ids` the shared check in Session::execute does not
read still parsed them with id_param/ids_param, which drop anything that is
not a non-negative integer, and then acted on the selection or the current
layer. `object.blend.make {"ids": 3}` blended the selection,
`object.envelope.makeWithWarp {"ids": [2, "x"]}` warped the selection,
`graph.setData {"id": "2"}` changed the selected graph and
`layer.newSublayer {"parent": "2"}` added a sublayer to the current layer.
- cmd::named_ids and cmd::named_id read `ids`/`id` as targets does: a value
that is not an object id, or an unresolved step reference, is an error.
- The symbol and brush, Live Paint, Shape Builder and Image Trace, blend,
envelope and mesh, perspective, Liquify, Puppet Warp and graph helpers use
them in place of the lenient readers.
- layer.clippingMask.toggle checks `id`, and layer.newSublayer checks
`parent`, with checked_id before falling back to the highlighted row or the
current layer.
Homography::then_after returned products whose entries could overflow to
infinity or become NaN. A move, transform or grid reproject of type or a
symbol instance whose stored projection has large finite entries stored such
a product, and the type was then drawn flat, since a projection that is not
finite reads as none.
- Homography::checked_then_after returns None when an entry of the product
is not finite.
- project_node composes each type and symbol instance projection with it and
returns false, leaving the object as it is, when one would not be finite;
moves and transforms in perspective and Define Perspective Grid with
reproject then return the horizon error and leave the document unchanged.
- transform_map, attach_homography and size_homography return None for such
a product.
- Edit Text returns the horizon error, and does not enter isolation mode,
when the type cannot be shown flat where it is drawn.
perspective.move takes constrain: true instead of a plane-space
direction. For each object, the command snaps the move to the nearest
axis or 45-degree diagonal of that object's own plane, so a selection on
several planes keeps every object on a line of its plane. The tool sends
the raw pointer with the flag.
On a diagonal, Snap to Grid now moves along the diagonal by the nearer
per-axis correction, so that edge lands on its gridline.
perspective.move takes an optional constrain: [dx, dy], a plane-space
direction. For an in-plane move, Snap to Grid's correction is projected
onto that direction, so a move the Shift key constrains to a plane axis
or a 45-degree diagonal stays on that line when an object edge lies near
a gridline. The Perspective Selection tool sends the direction for
Shift moves and copies. Moves without the param behave as before.