Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
    Nicolas Silva
    @nical
    err, yes absolutely
    Aaron McLeod
    @agmcleod

    Hey folks, a bit of a follow up to my issue question i posted the other day: nical/lyon#718 Wondering how i can get the same vertices, but when the big square is made up of 4 smaller squares. So an overlapping set of points would remove the points at 5,5.

    https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f3870639c328eebe2abdfb555b8fb4ce

    Nicolas Silva
    @nical
    @agmcleod hi, at a glance, I think that the snippet should render correctly. What do you see when running it ?
    Nicolas Silva
    @nical
    Screenshot from 2021-10-12 17-26-36.png
    Here it is from a quick test with the command line app on the repository
    Screenshot from 2021-10-12 17-28-29.png
    And the wireframe view to see what the tessellation looks like
    Nicolas Silva
    @nical
    Here is the command to run in the cli directory if you want to play around with teh tool: cargo run -- show "M 0 0 5 0 5 5 0 5 M 5 0 10 0 10 5 5 5 M 0 5 5 5 5 10 0 10 M 5 5 10 5 10 10 5 10 M 2 4 4 2 8 6 6 8"
    Aaron McLeod
    @agmcleod
    ah k, i never tried rendering it as i couldnt get the wgpu example working on my computer. Could be i need some config or 3rd party lib installed, just couldnt be bothered. My previous example i just looked at the coordiantes and drew them out on paper. Given im seeing 5,5 as a vertex, my guess was is that it wasnt working as intended.
    Looks like 5,5 may not be in the indices list though
    Nicolas Silva
    @nical
    Right, the vertex gets added regardless of whether it ends up otuside of the final shape. Detecting that it could be removed is a bit complicated so I haven't bothered with it so far.
    maxammann
    @maxammann:matrix.org
    [m]

    Hey, I'm currently working on a map renderer which uses lyon. The vector data contains LineStrings for streets for example. Naively I just went with the StrokeTesselator and draw lines using an SvgBuilder. This works, but there are issues as soon as lines intersect with other lines. For example at streen junctions a line can start ON other lines.

    I supposet hat the StrokeTesselator is not able to handle this. Does anyone know a general approach to rendering streets based on LineStrings? I suppose that some more manual work is required (possibly involving writing a StreetTesselator us using FillTesselator).

    Does anyone have experience with the earcut tesselation algorithm?
    maxammann
    @maxammann:matrix.org
    [m]
    Nicolas Silva
    @nical
    Hi, The way to solve this is to turn the countour of the stroke into a filled path and use a fill tessellator. I you generate contours with consistent winding, then the fill tessellator can render it properly using the non-zero fill rule. That's how most vector graphics renderers deal with even simple strokes due to how quickly you can get them to self-overlap.
    2 replies
    Nicolas Silva
    @nical
    I have writen a tessellator using the ear clipping algorithm (I suppose you are referring to mapbox's ercut which is an implementation of the ear clipping algorithm). It's a very simple algorithm to implement (much much much simpler than monotone polygon tessellation. It also tends to generate nicer geometry (less thin triangles), at the cost of N² complexity (so they quickly become very very slow with complex paths). The algorithm also doesn't deal with self-intersecting paths, If you need to handle that then you probably need to first simplify the polygon using the bentley ottmann algorithm, and finally it doesn't work with polygon with holes. I think that you can extend it to work with holes if you know for example what polygons are outer loops and what polygons are holes.
    1 reply
    maxammann
    @maxammann:matrix.org
    [m]

    One more question about StrokeTesselator: As far as I have seen (see picture above) the StrokeTesselator is only drawing joints between line segements which directly follow. That means if I first draw a line segment (line_to), then move somewhere else (move_to), then move back tot he end of the previous segement (move_to) and then continue drawing (line_to), the tesselator would not add a joint, right?

    In order to be able to do something like that I would need to turn the contour into a filled path (like you said) and then tesselate that.

    maxammann
    @maxammann:matrix.org
    [m]

    Oke in fact the "state-of-the-art" map renderers like maplibre simply overdraw to cover the gaps you see on the picture above.

    Whether this overdrawing "works" is dependant on the zoom level. That means quite a lot of the rendered data is in accurate in maplibre is wrong on certain zoom levels. Its just impossible to see because the streets contours with gaps are soo small or there is a hardcoded limit which does not allow zooming further in :D

    Nicolas Silva
    @nical
    Correct.
    Looking back at your screenshot, If you don't do any transparency then self-overlaps shouldn't be a big issue, you can just render the strokes the way you did with round caps. It should look fine.
    1 reply
    maxammann
    @maxammann:matrix.org
    [m]
    I think for a start "overdrawing" a little bit and sticking with the StrokeTesselator for lines is fine. It would be interesting though to improve on that and switch to the FillTesselator eventually. In fact, Google Maps is more advanced here as it render the width of a street correctly. For example if a street suddenly becomes wider then it also renders that.
    This is only possible with the FillTesselator ofc.
    I think there is still room for improvement for open-source renderer. Even though I'm not sure whether all this data is available in OSM.
    maxammann
    @maxammann:matrix.org
    [m]
    For example something like that is crazy accurate :D
    FuriouZz
    @furiouzs:matrix.org
    [m]
    Hello there 👋 I am looking for to draw a stroke along a path. I am just wondering if it exists an easy way with the lyon API to close the path without merging last points to first ones when the path is closed. Here a gif to see my issue. (The GIF does not loop well, no worry, the jump is not a bug.)
    maxammann
    @maxammann:matrix.org
    [m]
    What do mean with "close the path". In that gif the star looks complete for a split second.
    FuriouZz
    @furiouzs:matrix.org
    [m]
    When I start to fill the stroke along the path, the stroke is filled in two directions.
    FuriouZz
    @furiouzs:matrix.org
    [m]
    Here an example without closing the path. I want the same behavior with the path closed.
    In each vertex, I store a progress between 0-1. Due to the vertex-to-fragment interpolation, my progress is interpolated at the closing segment.
    Nicolas Silva
    @nical
    Hm I'll consider this a bug. Basically when closing, the first two vertices are reused along with their advancement parameter (which is zero), but when someone actually makes use of advancement it's counterproductive since the last edge gets interpolated from "near the end" to zero instead of "near the end"to "the end"
    I'll put up a fix for this but unfortunately i might have to wait for a few weeks as I'm going on vacation.
    FuriouZz
    @furiouzs:matrix.org
    [m]
    That's what I have noticed by logging advancement. I can check your code and see if I can do a PR. The issue is in the StrokeTessellator ?
    Nicolas Silva
    @nical
    Yes, basically we keep track of the first points https://github.com/nical/lyon/blob/master/crates/tessellation/src/stroke.rs#L577 so that at the end we can close or generate the first cap and edge properly. The EndpointData here stores a bunch of vertex IDs which end up being reused at the end, and for advancement to look right we should use the stored vertex ids for the beginning of the curve and create new ones for the end of the curve even if they are at the same position.
    I re-wrote the stroke tessellator on the master branch and haven't published it yet, if you want something on crates.io soon you may want to fix the stroke tessellator that is on the 0.17 branch https://github.com/nical/lyon/blob/0.17/crates/tessellation/src/stroke.rs#L263 The idea is similar but the code looks a bit different
    If you propose a fix on the 0.17 branch I can publish a 0.17.11 version with it sooner than what's on master
    FuriouZz
    @furiouzs:matrix.org
    [m]
    I already use the version on the master branch in my own project. I created my own InvertedWinding struct, but I saw that you created one plus a couple of issues related to.
    I may have a look.
    FuriouZz
    @furiouzs:matrix.org
    [m]
    I have found where to change endpoints here by using self.next_endpoint_id().
    for the first and the second
    FuriouZz
    @furiouzs:matrix.org
    [m]
    But I am not really sure to understand how to add two new vertices. Vertex are created by self.output.add_stroke_vertex via self.tessellate_join. Ideally I want to duplicate one of these edges
    http://chrsmsln.com/stroke3.png
    I will continue to investigate or I can wait the end of your vacation to have more inputs.
    FuriouZz
    @furiouzs:matrix.org
    [m]
    I finally succeeded to add a stroke and to have a result close to what expected. Yellow means 1 and Red means 0. https://chrsmsln.com/add_stroke.webp
    There is the overlap to resolve and fix the progress (I tricked by using the endpoint id instead of advancement).
    I was thinking, maybe advancement() and side() can considered as texcoords where U indicates the positive or negative side (0-1) and V indicates the progress along the stroke.
    Nicolas Silva
    @nical
    I just had a bit of time to look into this and put together nical/lyon#784 which I think should make things look more like what you want (on the master branch). I haven't thoroughly tested it yet though, I'll hopefully have some time to test/finish it in the next few days.
    FuriouZz
    @furiouzs:matrix.org
    [m]
    I will have a look @nical thanks
    FuriouZz
    @furiouzs:matrix.org
    [m]
    I suggested a fix, to have the proper vertex side
    I am using vertex.side() as uv.x and vertex.advancement() / max as uv.y.
    The result sounds fine: https://capture.chrsmsln.com/rExov8