[GSOC 2023] Progress on perspective transformation | Haiku Project

I think that folding everything into a single layers stack has the peril of making the reuse of shared elements and its relationships too abstract and difficult to follow, specially if you open an icon from its HVIF version, where all the names are stripped.

The way the UI is distributed now has the virtue of showing to a good degree the internal logic of the format, where things that exist once (but can be reused many times) are showed only once in a specific list.
The only one that I will get rid of and integrate into the shapes list is the Transformer list, because they are always specific to each shape, thereā€™s just two of them and it takes up a fixed, mostly empty space that could be used to have more room for the other lists.
The other lists contain shareable elements so I think they must be kept.

That said, having the shapes list shown in this way, with all the linked paths, styles and transforms next to each shape or layer could be a good complement to better grasp the structure of an icon at a glance, even if a bit redundant.

I always thought that the ā€œThings should be done as simple as possibleā€ principle has an implied continuation that has to be taken very seriously, that is: ā€œā€¦but never more simple than possibleā€.
Iā€™m sure everyone has some example in mind about something that was simple enough, but was made more complicated in an attempt to simplify it too much, at times for cost reducing reasons in physical products , other times taking to the extreme some UI trends (gestures for absolutely everything, hiding scrollbars, flat UIs), but I digress.

I try my best to only suggest things that make sense directly inside Icon-O-Matic in the context of creating efficient icons :man_mechanic: :balance_scale: :feather:

I did already go a couple of times through the route of prototyping something in WonderBrush and exporting it in SVG to load it in Icon-O-Matic, but it ended up being more cumbersome.
Either the icon ended up more bloated as every element became a different path because WonderBrush doesnā€™t do path reuse, or I had to redo practically everything again and it made more sense to do it directly in Icon-O-Matic from the start.
The only things that were still useful were to do some perspective transformation, which is about to get solved, and to trace something from a bitmap image, mostly solved with the recently implemented reference layers.
True however, a new way to use WonderBrush has opened up now with reference layers, that is prototyping in a more relaxed way, exporting as a bitmap, and tracing directly in Icon-O-Matic with all its native advantages.

Regarding layers, they are just a way of organizing things, a mere UI convenience to select at once a group of shapes, they could be called ā€œlayerā€, ā€œgroupā€ or something else.

It even crossed my mind to suggest that layers could be discarded once the icon is exported to HVIF, as it happens with names. But given that the data about which shapes have been moved or transformed together will have to be preserved in some way, it didnā€™t made much sense, because they will be just a way of exposing something that is already happening internally, no?

At least that is the concept of layers I had in mind, something simple integrated directly in the shapes hierarchy, no layer masks, no blending modesā€¦

No problem. As long as a bunch of shapes can be transformed at once in an filesize efficient way, I donā€™t mind having to select them manually, Iā€™m a happy mouse :cheese: :mouse2:

Ok, thatā€™s right, step by step.
Cā€™mon, lets advance :saluting_face: :smile:

2 Likes

Image previews of the layers, shapes, paths and styles would help somewhat with that problem. Except for all the time it would take to implement. Ah, dreams, dreams. But yes, that redesign would make interpreting HVIF files even more difficult. Hope you have the source IOM file available, or your going to be stuck with reverse engineering!

Looks like your idea and my idea of layers match. Layers are a grouping of shapes. They also act similarly to shapes in that you can apply transformers to a whole layer as if they were just another shape. No layer masks, blending modes, etc.

Now it remains to figure out whether it would be more space-efficient to preserve layer data in the HVIF or to list the transformers applied to each shape individuallyā€¦ (except we donā€™t actually need to figure that out. Weā€™re just dreaming.)

If I ever get around to it, it would probably look like letting transformers be shared among multiple shapes, similar to how paths and styles are.

Wait, enlighten me, how are perspective transformations useful? Given all the limitations they currently have, I have no idea :sweat_smile:. Currently, they canā€™t be applied to multiple shapes at a time. It would be really space-inefficient to apply the same perspective transformation to each shape individually one at a time. The only use I can think of is applying perspective transformations to reference images, though I canā€™t imagine that coming up all that often.

Maybe I should get around to letting transformers be shared among multiple shapes? Though thatā€™s a rather large project all by itself.

2 Likes

Extraneous data, like layer information, names, etc, could be stored in a separate ā€œprojectā€ file. The generated HVIF file should be kept ā€œcleanā€, to mantain its small size. Like a Photoshop file, and then the generated bitmap of the picture.

Icon-O-Matic already stores that in its own file format (shape names and various other things). And hvif is clearly an export format in the GUI and normally not used to store the icons anywhere but their final use in resource files. So thatā€™s one thing we donā€™t need to invent, itā€™s already there

2 Likes

I think it is more complex than that. The icon style and design language we use is partially originated from the existing features and dimitations in Icon-O-Matic. But, lately, there have been a lot of icons based on SVG imports.

And so the definition of ā€œspace efficientā€ varies a lot, depending on what you look at. Some extra features in HVIF may help make SVG imports more compact if the importer makes use of them, but makes handmade HVIF larger. Or maype the opposite: provide great optimizations for handmade icons, but be too high level for the SVG files to make efficient use of.

So, which cases do we optimize for? Or do we open opportunities for a new style of icons?

Ah yes, good point. I never quite thought about the fact that a lot of icons are imported from SVGs and that therefore we should make sure the icon format handles imported SVGs reasonably well.

1 Like

Is there already a translator that can convert SVG to hvif/icon-o-matic format? Would that be more in line with the OS philosophy?

Iā€™d say the philosophy is ā€œwhatever is convenientā€. In this case, since the only user of the icon-o-matic format is icon-o-matic itself, a translator from SVG to icon-o-matic would be of no use to anyone else. Translation from SVG to HVIF may sound useful at first, but, what are applications going to do with the resulting HVIF file? The only thing you can dois rendering it to a bitmap to show it on screen. So, why not use a translator that will do that directly? And we indeed have one that does it.

Sometimes it is not even possible to convert an SVG to Icon-O-Matic or HVIF format simply because the image is too complex and has more shapes or paths than the HVIF format allows.

The Icon-O-Matic and HVIF formats are not good target formats for a translator. They are too specific.

Translators in the other direction might be useful, if there were more apps that knew hoz to import SVG files. But there arenā€™t that many of these yet, either.

2 Likes

In the end that will be the most sensible approach, as we could make a clean separation between it and the simple organizational nature of layers/groups.
Also, this will let the task be divided in two more easily approachable tickets, and opens the possibility of having one or the other, as the two things can be useful by themselves.

Butā€¦ you mean transformations, right? :sweat_smile:
Though, now that I think, classifying geometric transformations as a Transformer can be more intuitive for the user (transformation, transformer), it will make good use of a UI space that is sitting mostly empty all of the time (the Transformers list), and making Contours and Strokes also shared can have a positive impact in filesize, even if a small oneā€¦ hmmmā€¦ :thinking:

Hmmmā€¦
:thinking:

It was better than having to guess the correct perspective.
It was neutral in terms of filesize because it had to be done to things that, anyways, consisted in multiple paths.
It is more or less the same as (is going to be :face_holding_back_tears:) doing a perspective transformation directly to the paths inside Icon-O-Matic.

Indeed, Stippi himself had planned it that way for that all these years ago. The code had a shell of a perspective transformation and a more complete version of an affine transformation. So, the list as Stippi intended goes something like ā€œContour,ā€ ā€œStroke,ā€ ā€œPerspective,ā€ and ā€œTransformation.ā€ Now that, ā€œTransformationā€ā€¦ It should probably be renamed to ā€œAffine.ā€

1 Like

Cube in perspective
Finally, gradients follow the perspective transformation. Now itā€™s time to clean up the code. Afterwards, Iā€™ll need to make sure saving works and iron out various other bugs.

12 Likes

It all starts to feel like Inception, the movie.
But we are just dreaming, arenā€™t we? :relieved:
Are we? :face_with_spiral_eyes:
:melting_face:

1 Like

progress
Hereā€™s an interesting problem Iā€™ve come across: how do you detect invalid perspective transforms like the one shown above? Icon-O-Matic should not try rendering these shapes since AGG likes getting into infinite loops drawing them.

The shape is somewhat interesting, though. Itā€™s the DiskUsage icon, turned into a fractal. Hereā€™s another image showing the fractal in higher resolution.
progress2

Edit: The fractal comes from the fact that reference images tile themselves. Disabling that, the image is mostly blank.

1 Like

Possible solution would be to update agg code, agg version 2.6.1 has many improvements, also uses permissive license.

This link has agg-2.6.1.tar.gz version: Releases Ā· aggeom/agg-2.6 Ā· GitHub

Here the reasons for creating the agg-2.6.1 version: https://github.com/conan-io/conan-center-index/pull/16865

Debian project uses agg version 2.6.1, explanation in link: https://metadata.ftp-master.debian.org/changelogs//main/a/agg/agg_2.6.1-r134+dfsg1-2_changelog

3 Likes

Ah yes, Iā€™ve been wishing for AGG 2.6 as well. That versionā€™s perspective transformation is more fully fleshed out. I believe this was the version Stippi wanted as well when he wrote the shell of the perspective transformer all those years ago. Unfortunately, Iā€™m going to guess that upgrading our version of AGG would require a lot of work to fix whatever breaks as a result. Without the upgrade, Iā€™ll likely be forced to make some changes to AGG myself.

1 Like

I thin it would be a much better idea to update. I donā€™t think there are too many API changes between 2.4 and 2.6? At least it seems worth trying.

Diverging our version of AGG further than it already is from upstream sounds like a bad idea.

5 Likes

Determining precisely how our version of AGG has diverged may be important; weā€™ve fixed a number of bugs (including crashes, memory faults, etc.) over the years, and we would have to check carefully that upstream has these same fixes, or contribute them back, before switching.

Then again, ā€œupstreamā€ looks pretty inactive anywayā€¦

AGG 2.7.0 r138 (svn):
Notice this commit:
[r134] by jhorigan

  • Update library revision from 2.6.0 to 2.7.0

Note: Iā€™ve compiled an updated AGG 2.7.0 with existing Haikuport patches merged successfully. So, we can import newer patches from this point.

Exactly it is important to import the patches, the version of AGG 2.7.0 [r138] (svn) has patches from 2021, already AGG 2.6.1 based on [r132] (github) has patches from 2023, which are different structure improvements. In practice the svn repository has the latest patches in chunks, so I opened a ticket on github to add the changes to the AGG 2.6.1 repository: Add changes and fixes from svn repository version [r138] to your repository Ā· Issue #6 Ā· aggeom/agg-2.6 Ā· GitHub

4 Likes