This evolved from a discussion in the Help area.
viewtopic.php?f=5&t=8637
Inkscape uses groups to implement layers. In the last post of the thread above there is an example where group/ungroup results in a different render order depending on the presence or absence of a second Inkscape layer. It wasn't clear to me what SVG has to say about the render order of objects in a group once that group is ungrouped. Should they return to their original positions, or is their render order only defined with respect to the other members of that group?
Also in that thread I wondered if layer behavior might not be made SVG compliant by dropping Layer tags as invisible objects into the object stack. For instance, it might be a single pixel which is fully transparent. Other SVG applications should render such an SVG document correctly, yet it would retain the Inkscape layer information.
Layers vs. groups
Re: Layers vs. groups
Answering the comment in the previous topic:
That's a different issue discussed in an earlier forum topic (a limitation of the 'fake layers with groups' implementation of layers) and fully compliant to the SVG spec (see also bug #171627):
Since layers are just regular SVG groups, you cannot group objects across layers and still keep them on their original layers: they all have to be moved into the new group which will be on one of the layers. Inkscape does not keep a special history (to track for each object in which group and layer it had ever been) that would allow to restore an object to the originating layer (possibly also including its stack order position within that layer) when you ungroup a group with objects that might have been - at some point of the editing history - on a different layer. Just imagine how that would blow up the file size since it obviously would have to stored for each object and group in the SVG file itself.
Summary: Inkscape implements (or simulates, depending on your POV ;-) ) layers (in 'Inkscape SVG' documents) with groups - the interaction of groups and layers might change once the official SVG specification has a standardized syntax for layers as part of the document structure.
mathog wrote:My point being that the Inkscape layers change the render order of the pieces following a group/ungroup operation. I'm not sure that that is SVG compliant. It might be, I just don't know. In the second case, given that SVG does not have a layers concept, shouldn't the ungrouped pieces have reverted to their original positions, even though those were in a layer different from the group?
That's a different issue discussed in an earlier forum topic (a limitation of the 'fake layers with groups' implementation of layers) and fully compliant to the SVG spec (see also bug #171627):
Since layers are just regular SVG groups, you cannot group objects across layers and still keep them on their original layers: they all have to be moved into the new group which will be on one of the layers. Inkscape does not keep a special history (to track for each object in which group and layer it had ever been) that would allow to restore an object to the originating layer (possibly also including its stack order position within that layer) when you ungroup a group with objects that might have been - at some point of the editing history - on a different layer. Just imagine how that would blow up the file size since it obviously would have to stored for each object and group in the SVG file itself.
Summary: Inkscape implements (or simulates, depending on your POV ;-) ) layers (in 'Inkscape SVG' documents) with groups - the interaction of groups and layers might change once the official SVG specification has a standardized syntax for layers as part of the document structure.
Last edited by ~suv on Sun Feb 13, 2011 4:34 am, edited 1 time in total.
Re: Layers vs. groups
From the earlier thread:
Inkscape can and does make use of namespaces (sodipodi, inkscape) [1] to store attributes with objects (as intended in XML based languages).
[1] see also Inkscape SVG vs. Plain SVG in the Inkscape wiki (might be slightly outdated with regard to the listed attributes)
IMHO layers need to be container elements (similar to groups).mathog wrote:One could even store layer boundaries by inserting nonpainting named objects at the appropriate positions in the object sequence.
Invisible pixels - like web bugs?mathog wrote:Also in that thread I wondered if layer behavior might not be made SVG compliant by dropping Layer tags as invisible objects into the object stack. For instance, it might be a single pixel which is fully transparent. Other SVG applications should render such an SVG document correctly, yet it would retain the Inkscape layer information.
Inkscape can and does make use of namespaces (sodipodi, inkscape) [1] to store attributes with objects (as intended in XML based languages).
[1] see also Inkscape SVG vs. Plain SVG in the Inkscape wiki (might be slightly outdated with regard to the listed attributes)
Re: Layers vs. groups
Here's an alternative proposal filed in the bug tracker (though I don't know if it had been discussed in the inkscape-devel mailing list):
- Bug #516580 in Inkscape: “improvement: group over several layers”
Instead of layer containers or inserting layer boundaries, it proposes to make layer membership an attribute of each object. I don't know though how one would implement any concept of stack order based on layers without requiring intensive calculations every time the canvas gets repainted to determine paint order based on both the implicit drawing order and special attributes of each (nested) group and object.
Re: Layers vs. groups
~suv wrote:Here's an alternative proposal filed in the bug tracker (though I don't know if it had been discussed in the inkscape-devel mailing list):
- Bug #516580 in Inkscape: “improvement: group over several layers”
Instead of layer containers or inserting layer boundaries, it proposes to make layer membership an attribute of each object. I don't know though how one would implement any concept of stack order based on layers without requiring intensive calculations every time the canvas gets repainted to determine paint order based on both the implicit drawing order and special attributes of each (nested) group and object.
The SVG group is defined in terms of rendering order. However, there is a common usage for grouping in the composition of drawings where changing the rendering order is very much not desired, and that is what 516580 is about. This is when the sole purpose of the grouping is to align and distribute replicated objects in X and Y, with no intention of altering Z, including and especially across layers. These operations can sort of be accomplished in Inkscape by selecting and not grouping, but it becomes exceedingly difficult to do this on a large set of objects. In terms of replication I suppose one could place the base 3 objects into a defs group (making them not render), and then replicate by creating instances where the def is drawn.
But that is going to shift the drawing order in Z from replica to replica, which may be visible if the replicas overlap.
For instance, imagine an object composed of 3 elements {A,B,C}. The objects must be drawn in that order. We make a replica of it, but want {A',B',C'} to be at the same draw levels as {A,B,C}. SVG cannot draw objects A and A' at the same level. The closest it can do is render
A,A',B,B',C,C' and that implies 3 groups {A,A'}, {B,B'}, {C,C'}, but this is grouped the wrong way, it isn't possible to move Object with respect to Object'. If we make {A,B,C} a def and then cause it to be drawn twice by other objects the draw order would be A,B,C,A',B'',C' - which isn't the desired draw order.
I don't see a simple way around this without modifying SVG to support some sort of "interleave" option for containers. Where interleaved_group{group1, group2, ... } causes the elements in the contained groups to be rendered g1:1, g2:1, ...gN:1, g1:2,g2:2, etc. This probably only makes sense for exact replicas though, if the groups differ, interleave may not have a clear meaning. If SVG itself does not support this Inkscape could still support the operations (and write the objects interleaved into the SVG file), but the accompanying group information wouldn't be compatible and would be lost.
Re: Layers vs. groups
Another way to think of this is that the current SVG "g" is "group (in Z)", and the missing SVG container type might be called "gxy" which would be "group (in XY)". The render order relative to objects outside the container would be the same, but the render order of the objects inside the container is different.
Re: Layers vs. groups
As mentioned in Grouping and Layers (and linked to in bug #516580), requests for grouping across layers often turn out to be requests for named selection sets for the current session:mathog wrote:However, there is a common usage for grouping in the composition of drawings where changing the rendering order is very much not desired, and that is what 516580 is about. This is when the sole purpose of the grouping is to align and distribute replicated objects in X and Y, with no intention of altering Z, including and especially across layers. These operations can sort of be accomplished in Inkscape by selecting and not grouping, but it becomes exceedingly difficult to do this on a large set of objects.
- Bug #170286 in Inkscape: “sets (named selections)”
Do you know other vector drawing applications, which implement such a concept of 'interleaved containers' (which then no longer are containers)? It might also be of interest to search the mailing list archives of the SVG working group about any ideas/drafts discussed related to implementing layers or other structuring elements, as well as whether alternatives to the painters model are considered for SVG 2.0. SVG 1.1/1.2/2.0 Requirements says no ("SVG should attempt to preserve a default painter's rendering model.")mathog wrote:I don't see a simple way around this without modifying SVG to support some sort of "interleave" option for containers.
As far as I understand, it doesn't. And even if Inkscape would implement it, in the end - unless Inkscape uses a different painting order and a custom native file format - doesn't it boil down to an option to automatically reshuffle the stack order within or across some or all container elements (groups, layers, nested <svg> elements) based on (private) object attributes which define mandatory relations to other objects?mathog wrote:If SVG itself does not support this (…)
Re: Layers vs. groups
~suv wrote:IMHO layers need to be container elements (similar to groups).
Probably that is how it will eventually enter the specification. I'm not sure that it needs to be done that way, it depends what one wants layers to be able to do. If they just represent bump stops, effectively hints to applications to keep objects in separate render regions a simpler object would suffice. If that's all they do, then removing them doesn't do anything - the image will render the same. If the idea is to be able to apply "lock", "do not show" and the like to all of the objects within the group, and have that override the equivalent value on those objects, and have that respected in the final render, than the container is clearly the better way to go.
~suv wrote:Invisible pixels - like web bugs?mathog wrote:Also in that thread I wondered if layer behavior might not be made SVG compliant by dropping Layer tags as invisible objects into the object stack. For instance, it might be a single pixel which is fully transparent. Other SVG applications should render such an SVG document correctly, yet it would retain the Inkscape layer information.
Ick, that wasn't the model I was shooting for! Web bugs do something on end user viewers, the layer objects would only do something in an SVG editor like Inkscape. It was just a way to smuggle layer information into a standard file so that it doesn't interfere with rendering elsewhere.
Re: Layers vs. groups
~suv wrote:Do you know other vector drawing applications, which implement such a concept of 'interleaved containers' (which then no longer are containers)?mathog wrote:I don't see a simple way around this without modifying SVG to support some sort of "interleave" option for containers.
Nope, wish I did. For instance, CorelDraw, at least the old version I have on one machine, has the same ABCA'B'C' draw order for a replicated 3 member group as does Inkscape. I don't see interleaved render ordering as a "container violation" though, it is more of an alternate merge operation. The default, and apparently only option for "draw (group1, group2)", is concatenate. Interleave(group1, group2) would emit all the same objects, just in a different order. There is plenty of precedent for such things, programs with "side by side" diff formats (xxdiff), SIMD operations like _mm_unpacklo_ps, and so forth.
Re: Layers vs. groups
How hard would it be to give an object an inkscape specific attribute called, e.g. "label", that does not affect the appearance of the svg, or the group membership, and is settable in perhaps the object properties dialog box, nicely out of the way for most of the time? Then perhaps if one wanted to select across groups one could search for all objects with label attribute of "1" or "fred" : ) etc.
It seems that many users need only this much more functionality, although clearly it would not address mathog's problem...
It seems that many users need only this much more functionality, although clearly it would not address mathog's problem...
Your mind is what you think it is.
Re: Layers vs. groups
Already there.druban wrote:How hard would it be to give an object an inkscape specific attribute called, e.g. "label", that does not affect the appearance of the svg, or the group membership, and is settable in perhaps the object properties dialog box
That's the missing part: in 'Edt > Find…' you can't search the content of attributes (except in the 'style' one), only for their presence (bug #456180).druban wrote:Then perhaps if one wanted to select across groups one could search for all objects with label attribute of "1" or "fred" : ) etc.
Re: Layers vs. groups
On mulling this over further I think I have a better explanation for why some things in SVG (and other graphics programs) look like bugs. Basically it comes down to (my) psychology of drawing versus the methods of drawing allowed by SVG.
When I compose a drawing I tend to think of the objects as being thin flat pieces viewed from above. That is, as if they were physical objects, and I will call this the physical model. All the pieces have the same thickness - something like colored shapes cut out of the same thickness plastic sheet. My drawing is assembled by placing these on a surface. Order front to back has a physical meaning, because each piece has a real (x,y,z) and z is the position of the object up from the surface. If it sits directly on the surface z is 1, if it sits on another piece, z is 2, and so forth. So I am thinking in 3 dimensions, or maybe more accurately, something like 2.1 dimensions, since z doesn't have the same dimension as x or y. If I set up layers it is equivalent to placing a large clear plastic sheet well above the first, and placing more pieces on it. SVG has a completely different model, where its Z (capitalized to distinguish it) represents the drawing order. So long as nothing overlaps there is no difference in the scene rendering between the two models. However, in the physical model when two pieces with the same z overlap in x,y there is a collision. SVG has no collisions because no two objects have the same Z. Collisions may need special attention to produce the desired drawing. Some of the collision cases are: 1. overlap is not allowed (as in a representation of physical objects, where they cannot occupy the same space), 2. overlap is allowed but requires some sort of fusion (as in the two overlapping pieces must be fused into a single piece, as in two overlapping circles with an edge become a figure 8 shaped piece with an edge), 3. overlap is allowed and no special operations are needed (both are 100% opaque and the same color, so the same render results in either drawing order). In order to implement the physical model would require a set of rules for finding and handling collisions. Finding them is actually not that difficult a task, since every object has {x,y,z} coordinates and a bounding box the overlaps may be located efficiently. (These sorts of methods are in common use in 3D modeling programs, where collision cannot be ignored.) Setting up the rules for handling the collisions is complex, although for many things it would be good enough to classify a collision between two objects with different rendering properties as an error, and specify fusion operations for those with compatible rendering properties.
There are a lot of advantages to the physical model. The main one is that, since it corresponds to the way real world objects behave, it is pretty much hardwired into our brains. Sliding one object into another on a flat surface results in a collision, it does not result in one gliding over the other. Placing two washers next to each other on a flat surface places them at the same level, and so forth. In terms of selection in the user interface there are also some advantages - there are built in layers (not the grouping type of layer, physical layers) which do not need to be named to be seen. So one could define operations like "select within this box on layer 2" to select objects which are largely buried and otherwise difficult to "grab".
In any case, from the physical model one can derive an SVG description which will render correctly. It may (and probably will) require some processing to resolve the collisions, but it is possible, and it results in a mapping of z->Z. Conversely it is not generally possible to derive the physical model from the SVG description, since there may not be a unique mapping of Z->z. So to implement an SVG editor which is compatible with the physical model, and could save and read compatible SVG files, the underlying objects and their {x,y,z} values must be smuggled into the file, and in a form where the extra information does not blow up a compliant SVG renderer. When such an SVG editor reads an SVG file without the smuggled information it can try to derive z from Z, essentially by "dropping" the objects onto the render surface and keeping track of their depth, subject to the constraint that the SVG derived from the derived physical model must be the same as the original. I suspect that would be fairly difficult to do, and I doubt that there is in every case a unique physical model that would be compatible with that rendering.
When I compose a drawing I tend to think of the objects as being thin flat pieces viewed from above. That is, as if they were physical objects, and I will call this the physical model. All the pieces have the same thickness - something like colored shapes cut out of the same thickness plastic sheet. My drawing is assembled by placing these on a surface. Order front to back has a physical meaning, because each piece has a real (x,y,z) and z is the position of the object up from the surface. If it sits directly on the surface z is 1, if it sits on another piece, z is 2, and so forth. So I am thinking in 3 dimensions, or maybe more accurately, something like 2.1 dimensions, since z doesn't have the same dimension as x or y. If I set up layers it is equivalent to placing a large clear plastic sheet well above the first, and placing more pieces on it. SVG has a completely different model, where its Z (capitalized to distinguish it) represents the drawing order. So long as nothing overlaps there is no difference in the scene rendering between the two models. However, in the physical model when two pieces with the same z overlap in x,y there is a collision. SVG has no collisions because no two objects have the same Z. Collisions may need special attention to produce the desired drawing. Some of the collision cases are: 1. overlap is not allowed (as in a representation of physical objects, where they cannot occupy the same space), 2. overlap is allowed but requires some sort of fusion (as in the two overlapping pieces must be fused into a single piece, as in two overlapping circles with an edge become a figure 8 shaped piece with an edge), 3. overlap is allowed and no special operations are needed (both are 100% opaque and the same color, so the same render results in either drawing order). In order to implement the physical model would require a set of rules for finding and handling collisions. Finding them is actually not that difficult a task, since every object has {x,y,z} coordinates and a bounding box the overlaps may be located efficiently. (These sorts of methods are in common use in 3D modeling programs, where collision cannot be ignored.) Setting up the rules for handling the collisions is complex, although for many things it would be good enough to classify a collision between two objects with different rendering properties as an error, and specify fusion operations for those with compatible rendering properties.
There are a lot of advantages to the physical model. The main one is that, since it corresponds to the way real world objects behave, it is pretty much hardwired into our brains. Sliding one object into another on a flat surface results in a collision, it does not result in one gliding over the other. Placing two washers next to each other on a flat surface places them at the same level, and so forth. In terms of selection in the user interface there are also some advantages - there are built in layers (not the grouping type of layer, physical layers) which do not need to be named to be seen. So one could define operations like "select within this box on layer 2" to select objects which are largely buried and otherwise difficult to "grab".
In any case, from the physical model one can derive an SVG description which will render correctly. It may (and probably will) require some processing to resolve the collisions, but it is possible, and it results in a mapping of z->Z. Conversely it is not generally possible to derive the physical model from the SVG description, since there may not be a unique mapping of Z->z. So to implement an SVG editor which is compatible with the physical model, and could save and read compatible SVG files, the underlying objects and their {x,y,z} values must be smuggled into the file, and in a form where the extra information does not blow up a compliant SVG renderer. When such an SVG editor reads an SVG file without the smuggled information it can try to derive z from Z, essentially by "dropping" the objects onto the render surface and keeping track of their depth, subject to the constraint that the SVG derived from the derived physical model must be the same as the original. I suspect that would be fairly difficult to do, and I doubt that there is in every case a unique physical model that would be compatible with that rendering.