micahpearlman / MonkSVG

SVG parsing framework in C++
BSD 3-Clause "New" or "Revised" License
79 stars 19 forks source link

Multiple shapes in one path not drawn correctly #7

Open lukelutman opened 12 years ago

lukelutman commented 12 years ago

The tesselation used by MonkSVG fails unless all of the subpaths in a path are touching. The three red squares are touching, so tesselation works properly and all three squares appear. The two blue squares are not touching, so tessellation fails and only the square closest to the top left appears (source order doesn't matter).

Here's an svg file that demonstrates the problem: test.svg

Here's the correct rendering (as viewed in Safari or Xcode): Correct

Here's what it looks like when rendered by MonkSVG: Incorrect

micahpearlman commented 12 years ago

Well the tessellator in MonkVG expects all vgPaths to never have two paths that aren't overlapping. I'm pretty sure the OpenVG spec specifies that, but I would need to do a bit more reading. I'm surprised that SVG would allow that as most tessellators can't handle that case -- but again I would have to look at that more. MonkVG uses the opengl glu tessellator to generate the the triangle mesh from the 2d contours and so MonkVG is limited to what it can do. Perhaps an offline tool can be used to separate non-overlapping sub paths -- but again I'm very surprised that is valid SVG.

david-a-campbell commented 11 years ago

This may be a problem with the parsing. I noticed that there is an issue where only the first group of items inside the svg tags are displayed. If it has subgroups all the subgroups will be displayed as well. But any group after that doesnt get displayed. I bet if you move the last square into the group with the others it will be displayed.

micahpearlman commented 11 years ago

Ok, I've seen this issue before and it is an issue with the tessellation library (gluTess) used in MonkVG. It cannot handle multiple unconnected contours that aren't overlapping (it can handle holes because a hole will overlap, but not the case you are showing). Nothing I can really do about that other then:

01) Check if that condition exists in MonkSVG after every "Z -- Closed Path -- onPathClose". Problem is it potentially very time intensive and still potentially inaccurate because I can think of cases where a simple AABB overlap case wouldn't work. But, I guess it could be implemented and allow the user to turn it on or off. 02) Write a whole new tesseleator. Probably not going to happen anytime soon.

It would be awesome if you could implement and donate to the project solution 1 (with the ability to turn if on/off programmatically). Basically:

01) Keep track off all closed paths within a "onPathBegin/onPathEnd". 02) At on "onPathEnd" Calculate all the AABBs of all the sub-paths and see if the overlap. Any non-overlapping AABBs make into there own paths. You will need a lot of tracking logic because you can have two different pair groups of AABBs that overlap within the pairs but not overlap each other. There is also the case that you can have a non-convex path and it would appear to overlap with the AABB test but not actually render properly. Ughh…

On Jun 3, 2013, at 11:07 AM, W1ngy notifications@github.com wrote:

This may be a problem with the parsing. I noticed that there is an issue where only the first group of items inside the svg tags are displayed. If it has subgroups all the subgroups will be displayed as well. But any group after that doesnt get displayed. I bet if you move the last square into the group with the others it will be displayed.

— Reply to this email directly or view it on GitHub.

gerchicov commented 10 years ago

If you can't fix it then why not to split path tag programmatically into a several paths without unlinked segments