Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

display exact circles/arcs whenever possible #195

Closed
wpwrak opened this issue Feb 10, 2017 · 9 comments
Closed

display exact circles/arcs whenever possible #195

wpwrak opened this issue Feb 10, 2017 · 9 comments

Comments

@wpwrak
Copy link
Contributor

wpwrak commented Feb 10, 2017

This is an enhancement request. Right now, arcs and circles (and maybe splines as well) are drawn with a relatively large chord tolerance, which often results in significant visual differences between the ideal arc and the polygon displayed.

Reducing the chord tolerance (for better accuracy) has a major computational impact and is therefore often not advisable.

These deviations cause numerous inconveniences:

  • they can suggest mistakes while everything is correct. E.g., in the picture below, the point in the selection is coincident with the lower arc, though it looks as if it wasn't properly attached to anything:
    chord-off
  • they can mask mistakes, e.g., arcs that should overlap but by mistake don't. The visual difference can be easily explained away by chord tolerance, even if there's an error in the design (which may reveal itself much later). Thus, the designer is deprived of important clues that would help to spot mistakes.
  • the polygons of overlapping arcs of different length will typically not look the same, which is at least confusing, and can lead to the above misinterpretations.

However, drawing an arc with pixel accuracy is not something that should be particularly difficult, especially if it is parallel to the display plane (i.e., it's circular, not elliptical). So instead of drawing inaccurate chords, SolveSpace could detect when it could just draw an exact circle or arc, and then invoke the corresponding graphics primitive.

I understand that this may cause divergence from solids/meshes (which inevitably have to use chords), and that, when switching to polygons is necessary, e.g., when tilting the plane, the transition may be unexpected, but I think all these issues are minor compared to the risk of poorly approximated arcs causing design errors to be introduced already in the 2D phase.

@whitequark
Copy link
Contributor

Right now, arcs and circles (and maybe splines as well) are drawn with a relatively large chord tolerance, which often results in significant visual differences between the ideal arc and the polygon displayed.

They are drawn with the chord tolerance that you've specified in settings, which is as small as you set it.

However, drawing an arc with pixel accuracy is not something that should be particularly difficult, especially if it is parallel to the display plane (i.e., it's circular, not elliptical). So instead of drawing inaccurate chords, SolveSpace could detect when it could just draw an exact circle or arc, and then invoke the corresponding graphics primitive.

This doesn't make any sense. There is no graphical primitive for a circle or an arc in OpenGL, just triangles. Regardless of what you do, you have to choose some chord tolerance (perhaps corresponding to one pixel), and then convert a circle or an arc into piecewise linear representation.

and that, when switching to polygons is necessary, e.g., when tilting the plane, the transition may be unexpected, but I think all these issues are minor

I don't think these are minor issues. In particular, implementing this would require regeneration of the entire sketch, at least, every time you zoom in, and perhaps once you zoom out, to avoid having way too many edges. That is also a nontrivial computational cost.

@wpwrak
Copy link
Contributor Author

wpwrak commented Feb 10, 2017

The problem with setting a significantly smaller chord tolerance is that SolveSpace becomes extremely slow, probably since the chord tolerance also affects mesh operations. I guess having separate chord tolerances for arcs display and meshes could accomplish what I'm after.

Please let me be clear about the objective: the principal issue is that sloppily drawn geometry causes the designer to develop a sloppy mindset, which causes mistakes that could have been avoided. What I'm looking for is to remove the cause for that sloppiness, preferably without having to redesign the human condition at large :-) Now, I don't know the internal workings of SolveSpace nearly well enough to be able to tell how exactly this should be implemented. So I'm merely making suggestions based on things I'm familiar with.

Regarding primitives, I don't known OpenGL, but a quick search yielded https://www.opengl.org/discussion_boards/showthread.php/167955-drawing-a-smooth-circle mentioning gluDisk. https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPartialDisk.xml looks useful. Is that prohibitively expensive ?

implementing this would require regeneration of the entire sketch

So the arc/polygon is precomputed and stored in OpenGL (I'm thinking "display lists" here. Not sure if that's still something people use.) ? If this is so (and the primitives are not issued for each screen refresh), perhaps arc/polygons could then be put in a separate display list, and you'd only regenerate that one when the zoom level changes. I'm assuming here that the expensive bit are mesh operations while the rest is fairly cheap.

@whitequark
Copy link
Contributor

Regarding primitives, I don't known OpenGL, but a quick search yielded https://www.opengl.org/discussion_boards/showthread.php/167955-drawing-a-smooth-circle mentioning gluDisk. https://www.khronos.org/registry/OpenGL-Refpages/gl2.1/xhtml/gluPartialDisk.xml looks useful. Is that prohibitively expensive ?

That's only useful in immediate mode, not when drawing in OpenGL 2.

@whitequark
Copy link
Contributor

So the arc/polygon is precomputed and stored in OpenGL (I'm thinking "display lists" here. Not sure if that's still something people use.) ?

More or less. Display lists specifically are useless but we have a similar data structure.

If this is so (and the primitives are not issued for each screen refresh), perhaps arc/polygons could then be put in a separate display list, and you'd only regenerate that one when the zoom level changes. I'm assuming here that the expensive bit are mesh operations while the rest is fairly cheap.

Yes. But the issue is that regenerating edges alone can be costly too.

@Evil-Spirit
Copy link
Collaborator

@whitequark, @wpwrak We can easily make perfect primitives just using bezier representation and geometry shaders https://www.khronos.org/opengl/wiki/Geometry_Shader. But this require OpenGL 3.2.

@whitequark
Copy link
Contributor

I don't think OpenGL 3.2 is an option.

@marthinwurer
Copy link

Why is OpenGL 3+ not an option?

@whitequark
Copy link
Contributor

We already require 3+, the problem was with 3.2 specifically. But now that I think about it again, we can gracefully degrade on pre-3.2 OpenGL to the current rendering, and use a much nicer one when geometry shaders are available.

@whitequark
Copy link
Contributor

This is a duplicate of #295 (exactly 100 higher, heh) and the correct solution (or at least realistically implementable one) is described in #295 (comment), so I'm closing this in favor of that issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants