Commit Graph

23 Commits (457ff78849564cbe6da22f608230f76041770cf4)

Author SHA1 Message Date
EvilSpirit bbca4cc224 Rewrite declarations of form f(void) as f().
In C++ there is no difference and newly added functions are all
declared as f(), so this brings back consistency.
2016-05-20 12:43:20 +00:00
whitequark febe0f5282 Rename the old "Import / Assemble" feature to "Link / Assemble".
This better reflects what it does and avoids clashes with the new
DXF import feature.
2016-05-07 05:27:54 +00:00
whitequark c17f1160dc Allow snapping constraint labels to grid.
This is pretty much the only way to get a sketch with tidily placed
dimensions.
2016-04-23 04:38:32 +00:00
EvilSpirit e74ccb3010 Perform grid fitting on the builtin vector font.
Grid fitting is performed only on glyph boundaries, since glyphs
include curves converted to pwl, which would be mangled by per-point
grid fitting.

Grid fitting is only performed when the plane in which text is
laid out is parallel to the viewing plane.

Grid fitting is only performed when rendering for display; there
are no devices with dpi low enough for grid fitting to become
profitable, and in any case we cannot predict what the dpi would
be anyway.
2016-04-16 04:19:14 +00:00
EvilSpirit d1a2eb6d18 Allow rendering hidden solid edges using a distinct style.
Before this change, the two buttons "Show/hide shaded model" (S) and
"Show/hide hidden lines" (H) resulted in drawing the following
elements in the following styles:

  Button | Non-occluded | Non-occluded |  Occluded   |   Occluded
  state  | solid edges  |   entities   | solid edges |   entities
 --------+--------------+--------------+-------------+--------------
  !S !H  |              |              | solid-edge  | entity style
 --------+              |              +-------------+--------------
   S !H  |              |              |         invisible
 --------+  solid-edge  | entity style +-------------+--------------
  !S  H  |              |              |             |
 --------+              |              | solid-edge  | entity style
   S  H  |              |              |             |
 --------+--------------+--------------+-------------+--------------

After this change, they are drawn as follows:

  Button | Non-occluded | Non-occluded |  Occluded   |   Occluded
  state  | solid edges  |   entities   | solid edges |   entities
 --------+--------------+--------------+-------------+--------------
  !S !H  |              |              | solid-edge  | entity style
 --------+              |              +-------------+--------------
   S !H  |              |              |         invisible
 --------+  solid-edge  | entity style +-------------+--------------
  !S  H  |              |              |             |
 --------+              |              | hidden-edge |  stippled¹
   S  H  |              |              |             |
 --------+--------------+--------------+-------------+--------------

  ¹ entity style, but the stipple parameters taken from hidden-edge

In SolveSpace's true WYSIWYG tradition, the 2d view export follows
the rendered view exactly.

Also, it is now possible to edit the stipple parameters of built-in
styles, so that by changing the hidden-edge style to non-stippled
it is possible to regain the old behavior.
2016-04-15 21:53:08 +00:00
EvilSpirit 73f28b9731 Make normals and workplanes non-stylable.
This does not seem to have any useful application, and it can
result in odd misrenderings with some styles.
2016-04-08 10:12:28 +00:00
EvilSpirit 3d334d153d Disable autoconstrainer while Ctrl is held. 2016-04-08 09:51:10 +00:00
whitequark 6e56b00b9a Don't perform hit testing if we haven't painted the graphics window.
This change is quite subtle. The goal is to improve responsiveness
of highlighting even further. To understand this change you need
to keep in mind that Windows and Gtk have dramatically different
behavior for paint (WM_PAINT in Windows, expose in Gtk) and
mouse move events.

In Windows, WM_PAINT and WM_MOUSEMOVE, unless sent explicitly,
are synthesized: WM_MOUSEMOVE is delivered when there are no other
messages and the current cursor position doesn't match the remembered
one, and WM_PAINT is delivered when there are no other messages,
even WM_MOUSEMOVE. This is pretty clever because it doesn't swamp
programs that are slow to process either of those events with even
more of them, ensuring they remain responsive.

In Gtk, expose events are delivered at the end of the frame whenever
there is an invalid view, and every single mouse move that happened
will result in a separate event.

If mouse move events are handled quickly, then the behavior is
identical in either case:
  * process mouse move event
    * perform hit testing
    * invalidate view
  * no more events to process!
    * there are invalid views
      * repaint

If, however, mouse move events are handled slower, then the behavior
diverges. With Gtk:
  * process mouse move event
    * perform hit testing (slow)
      * while this happens, ten more mouse move events are added
    * invalidate view
  * end of frame!
    * there are invalid views
      * repaint
  * process mouse move event...
As a result, the Gtk-hosted UI hopelessly lags behind user input.
This is very irritating.

With Windows:
  * process mouse move event
    * perform hit testing (slow)
      * while this happens, mouse was moved
    * invalidate view
  * process mouse move event...
As a result, the Windows-hosted UI never repaints while the mouse
is moved. This is also very irritating.

Commit HEAD^ has fixed the problems with Gtk-based UI by making
hit testing so fast that mouse move events never quite overflow
the queue. There's still a barely noticeable lag but it's better.

However, the problems with Windows remained because while the queue
doesn't *overflow* with the faster hit testing code, it doesn't go
*empty* either! Thus we still don't repaint.

This commit builds on top of HEAD^ and makes it so that we don't
actually hit test anything if we haven't painted the result of
the previous hit test already. This fixes the problem on Windows
but also helps Gtk a little bit.

Curiously, the Cocoa-based UI never suffered from any of these
problems. To my understanding (it's somewhat underdocumented), it
processes mouse moves like Windows, but paints like Gtk.
2016-03-07 16:03:20 +00:00
whitequark bda2835e9f Cache bounding boxes.
This results in massive performance improvements for hit testing.
Files with very large amounts of entities (e.g. [1]) inflict
a delay of several seconds between moving the pointer and
highlighting an entity in commit HEAD^^^, whereas in this commit
the delay is barely perceptible.

[1]: http://solvespace.com/forum.pl?action=viewthread&parent=872
2016-03-05 16:48:56 +00:00
EvilSpirit e99eedd7a3 Check entity bounding box before hit testing edges. 2016-03-05 16:48:56 +00:00
EvilSpirit 96344c85a6 Eliminate DEFAULT_TEXT_HEIGHT from drawing code.
Instead, query the text height for constraint style.
2016-03-05 12:02:13 +00:00
whitequark c9648805ea Allow generating groups in arbitrary order. 2016-02-19 10:23:24 +00:00
whitequark 29ad1acdfe Enable and mollify -Wunused-variable.
In my (whitequark's) experience this warning tends to expose
copy-paste errors with a high SNR, so making a few fragments
slightly less symmetric is worth it.

Also mollify -Wlogical-op-parentheses while we're at it.
2016-02-14 14:29:47 +00:00
whitequark d43bd93060 Only consider groups until active when checking for solver failure.
After commit 2f734d9, inactive groups are no longer regenerated
for trivial changes, e.g. changing parameters, so it's possible to
switch to an earlier group and work on it without incurring
the computational (slowdown) and cognitive (annoyance by red
background) overhead of later groups failing to solve.

However, if a group--any group anywhere--was not solved OK,
the interface reacted accordingly, which diminished usefulness of
the change, especially given that, if we have groups A and B with
B depending on A, if B is broken by a change in A and we activate A
and fix it, B will not be regenerated.

After this commit, only active groups are considered when deciding
if generating the entire sketch would fail.
2016-02-14 14:09:36 +00:00
EvilSpirit 89eb208660 Use a separate value of chord tolerance for exporting.
Before this commit, a single chord tolerance was used for both
displaying and exporting geometry. Moreover, this chord tolerance
was specified in screen pixels, and as such depended on zoom level.
This was inconvenient: exporting geometry with a required level of
precision required awkward manipulations of viewport. Moreover,
since some operations, e.g. mesh watertightness checking, were done
on triangle meshes which are generated differently depending on
the zoom level, these operations could report wildly different
and quite confusing results depending on zoom level.

The chord tolerance for display and export pursue completely distinct
goals: display chord tolerance should be set high enough to achieve
both fast regeneration and legible rendering, whereas export chord
tolerance should be set to match the dimension tolerance of
the fabrication process.

This commit introduces two distinct chord tolerances: a display
and an export one. Both chord tolerances are absolute and expressed
in millimeters; this is inappropriate for display purposes but
will be fixed in the next commits.

After exporting, the geometry is redrawn with the chord tolerance
configured for the export and an overlay message is displayed;
pressing Esc clears the message and returns the display back to
normal.
2016-02-13 16:16:47 +00:00
whitequark 45f056c852 Replace all ZERO and memset with C++11 brace-initialization.
This will allow us to use non-POD classes inside these objects
in future and is otherwise functionally equivalent, as well
as more concise.

Note that there are some subtleties with handling of
brace-initialization. Specifically:

On aggregates (e.g. simple C-style structures) using an empty
brace-initializer zero-initializes the aggregate, i.e. it makes
all members zero.

On non-aggregates an empty brace-initializer calls the default
constructor. And if the constructor doesn't explicitly initialize
the members (which the auto-generated constructor doesn't) then
the members will be constructed but otherwise uninitialized.

So, what is an aggregate class? To quote the C++ standard
(C++03 8.5.1 §1):

An aggregate is an array or a class (clause 9) with no
user-declared constructors (12.1), no private or protected
non-static data members (clause 11), no base classes (clause 10),
and no virtual functions (10.3).

In SolveSpace, we only have to handle the case of base classes;
Constraint and Entity have those. Thus, they had to gain a default
constructor that does nothing but initializes the members to zero.
2016-01-13 06:45:16 +00:00
whitequark 5e7c7fce7e Rename RgbColor to RgbaColor. 2015-07-10 15:59:12 +03:00
whitequark 75a3936b64 Add support for transparent solids.
Some extra code is necessary to determine that the back faces
should not be drawn in red for transparent solids. It is expected
that the user will first ensure that the shell is watertight
and then set the opacity; back faces are still drawn if
the opacity is exactly 1.

The savefile format is changed backwards-compatibly by stashing
the alpha value in uppermost byte of 4-byte hex color value
in Surface and Triangle clauses. The existing files have 00
in the high byte, so RgbColor::FromPackedInt treats that
as "opaque".
2015-07-10 15:59:12 +03:00
whitequark 69c509064c Automatically add horz/vert constraints to lines if close enough. 2015-07-10 15:59:12 +03:00
whitequark 2c39f259db Add a GTK2/3 port.
In principle, GTK3 is the way forward, and GTK2 is officially
deprecated, though still maintained. In practice however, GTK3
is often unbearably buggy; e.g. on my system, combo boxes
don't ever roll up in GTK3 windows. So I have added support
for both.

This required a few minor changes to the core, namely:
  * GTK wants to know beforehand whether a menu item is a check
    menu item or a regular one.
  * GTK doesn't give us an easy way to execute something after
    any event is processed, so an explicit idle timer is added.
    This is a no-op on Win32.
  * A few function signatures were const'ed, since GTK expects
    immutable strings when converting to Glib::ustring.
2015-07-10 15:59:12 +03:00
whitequark c5364fe7a8 Trim trailing whitespace. 2015-07-10 15:59:11 +03:00
whitequark 14690e6e42 Work around poor line rendering with Intel Mesa-based drivers.
However, don't use ssglLineWidth for UI drawing operations.
These only draw horizontal or vertical lines that don't need to
be antialiased, and thus don't require the workaround. In fact
the workaround would make them thicker than needed.
2015-07-05 06:20:25 +03:00
Daniel Richard G 0a24cf40f0 Moved most of the source into a src/ subdirectory
The SolveSpace top-level directory was getting a bit cluttered, so
following the example of numerous other free-software projects, we move the
main application source into a subdirectory and adjust the build systems
accordingly.

Also, got rid of the obj/ directory in favor of creating it on the fly in
Makefile.msvc.
2013-11-19 18:17:32 -05:00