Inkscape.org
Beyond the Basics Transform a Group leaving the stroke widths intact
  1. #1
    Eric Woodcock Eric Woodcock @EricWoodcock

    Hello,

    I'm including a document (rectexample1.svg) that contains a group which contains a rectangle in its turn. My actual document is much more complicated than this, of course: I've simplified this as far as possible to still demonstrate my problem.

    The effect that I'm trying to achieve is to shrink the group horizontally so that its horizontal size shrinks. But the stroke widths of the group contents must all remain exactly as they are before shrinking. 

    So I select the group, grab the right resize handle and move the handle leftward. When I do this, I find that the widths of the horizontal strokes of the rectangle have become much thinner than the vertical strokes. The file after the transformation is rectexample2.svg. Cf. the image enclosed, the parts highlighted in blue.

    The culprit is within the group: My shrinking action has added a "transform" attribute to the group which the renderer applies to the stroke of the group's content. Cf. the image enclosed, the XML editor and the parts highlighted in red. 

    What i would need is that Inkscape doesn't add a "transform" attribute to the group but instead recalculates the positions and the widths of the group contents, recursively if necessary. 

    I've tried to configure just that in my preferences, cf. the image enclosed, the preferences window and the parts highlighted in violet:

    • I've UNset the option "Scale stroke width" and
    • I've set  the option "Store transformation" to "optimized". The tooltip for "Optimized" explains that Inkscape would then apply transformations "without adding a transform attribute". Unfortunately, as you can see, Inkscape still DOES add a transform attribute to groups.  


    So how do I achieve my effect? I need Inkscape to preserve the stroke width of all the group contents, recursively if needed, when I scale the group.

    To re-iterate, my actual problem is considerably more complicated than 1 rectangle in 1 group, so "just simply select every member of the group instead of the group as a whole and then transform that" isn't really feasible for me. 

    Rectexample2
    Rectexample
    Rectexample1
  2. #2
    COD COD @COD
    *

    I reported a bug concerning something similar to this. Somewhat related but your issue is quite different because I was using preserved transform behavior. 

    https://gitlab.com/inkscape/inbox/-/issues/10896

    I think the root cause of this is that Inkscape doesn't use "vector-effect="non-scaling-stroke". Not sure why Inkscape doesn't utilize this SVG feature.

    I would report it as a bug. Link to my original bug report in your report.  

    Maybe some of the more experienced users here will come up with an idea. 

    Could you ungroup then regroup after scaling?

    Thanks for posting this because I always assumed that when the optimized behavior is used that it would never apply a transform. It should simply recalculate the path data. If it was a group of objects, it would do so recursively. Guess not!

  3. #3
    Paddy_CAD Paddy_CAD @Paddy_CAD
    *

    My workaround is to ungroup and group [shift+ctrl+g] [ctrl+g] after scaling.

    This is long standing behaviour. I'm not sure if it's an Inkscape bug or a feature of the svg specification. In your example, the horizontal lines are thickened and the vertical lines are thinned, which tells me that you squeezed the horizontal more than the vertical. Strangely, line widths are preserved if you scale proportionally.

    Edit: I see that @COD suggested the same while I dallied.

  4. #4
    COD COD @COD

    Paddy
    I just took a wild guess about the solution. I always used preserved transform behavior becuase I don't want Inkscape to apply the math on the path data because of accumulated rounding errors that Inkscape will create. 

    Technically it is not a bug - its just that Inkscape is simply not taking advantage of the SVG vector-effect="non-scaling-stroke feature. Not sure why. It could be that the Cairo graphics library doesn't handle that feature. It could be that vector effect is not standard SVG.

    To make you even more crazy - the solution we both suggested is wrong even though it works!  When you ungroup, the ungrouped paths are supposed to be changed to the original groups stroke width. In this case, the group's stroke width is ignored. Go figure!

     

  5. #5
    Eric Woodcock Eric Woodcock @EricWoodcock
    *

    @Paddy_CAD

    Yes, this is long-standing behaviour: I can go back to Inkscape 0.92, and I've found out now that they already have this behaviour of recalculating paths etc. but using "transform"s for groups. 

    I recently ran into a similar problem: I had a group containing groups containing groups … containing paths, and I needed to double the stroke width of each contained path. Different stroke widths were involved in different subgroups.

    So I selected the outermost group,  and in the Fill and Stroke pane, set the units for the Stroke size field to "percent" and entered "200" into the value field. I expected that Inkscape would now go through that  group recursively and double each stroke size it encountered, but no dice. 

    Maybe this is a general philosophy and all of Inkscape hasn't implemented the concept of recursively traversing groups and doing things to group elements, no matter what things.

    BTW, I asked the copilot of my Edge browser how to solve the latter problem, and it instantly replied, ‘So you need a little Python program for that. Here's the program. Change the names of the input and output files to your names where the comments tell you to.’ And the program was correct and idiomatic (I'm neither a Python nor an SVG buff, but I know enough to be able to verify  simple code that I get shown).

    Well, yes of course, using a tiny helper program is one way of getting things done, but it's not what you have in mind when you work with an application such as Inkscape. 

  6. #6
    COD COD @COD

    I thought I had this all figured out when comes to transform behavior of preserved vs optimised. Guess not. 
    Another example of my confusion:  https://gitlab.com/inkscape/inbox/-/issues/11626

    This one confused me even more: https://gitlab.com/inkscape/inkscape/-/issues/5446

  7. #7
    Eric Woodcock Eric Woodcock @EricWoodcock

    So, would an extension be a way out of this?

    The extension would take any group, extract and delete the "transform" attribute and then modify the paths of its children according to that attribute, recursively if needed. 

    If a child was a group that had a "transform" attribute in its turn, it would have to join the transforms, which I would suppose without knowing the details to be a matrix multiplication. 

  8. #8
    COD COD @COD

    I use an extension called "Apply Transform" that will take an individual path and apply the transform to the path data. Only used it a few times so I don't know if it will do so recursively on a group of paths. 

    Not even sure where I downloaded that extension. Let me go look. 

    https://github.com/Klowner/inkscape-applytransforms

     

  9. #9
    Eric Woodcock Eric Woodcock @EricWoodcock

    Thanks a bunch!! This extension seems to be an excellent step towards where I need to go.

    AFAICS, it does traverse the groups recursively and combine the transfoms it encounters.

    At one point of the code, it seems to fiddle with the stroke widths in some way, but if I simply cut that out so that the stroke widths all stay just as they are which is fine … …

    I'll report back.

  10. #10
    COD COD @COD

    Most likely during your grouping and scaling them a style was applied to change the stoke width of the entire group. I suspect that was a cludge fix to the way the transform behavior works. 

    I don't think Apply Transform extension will remove that. You can verify that by using the XML editor for the group and simply delete that style. Just do it before you use the extension. 

    Sucks you got to go through hoops like this to actually overcome what in my opinion is a bug. 

    Just thankful that you pointed this out to me for future reference. 

  11. #11
    inklinea inklinea @inklinea⛰️

    This extension simulates the group / ungroup, move a couple of pixels then move back trick.

    It is usually successful in forcing Inkscape to internally recalculate paths, baking in the transforms.

    https://inkscape.org/ca/forums/extensions/ink-flatten-work-in-progress/

    Just another option.

Inkscape Inkscape.org Inkscape Forum Beyond the Basics Transform a Group leaving the stroke widths intact