This changes all the lambdas to have explicit captures, since the use of
implicit captures has led to some memory errors, especially segfaults in
the right-click menu.
I'm not 100% sure that the code is correct anyway - it really needs auditing
to ensure all referenced values are still valid when the menu item is clicked
(e.g. can you change stuff with keyboard shortcuts while the context menu is
visible?), but it should at least be *more* correct!
This was incorrectly capturing `r` by reference and using it after it left
its scope. Changed to capture by value, and also explicitly capture `this`
in case we were accidentally capturing any other scope variables by reference.
Fixes#571
* Limit u,v range between 0 and 1 in Newton. Fixes issue #471
* Change the math for projecting a point onto a plane to work better with non-orthogonal U,V derivatives in several places. Fixes#472.
See:
https://github.com/solvespace/solvespace/issues/92#issuecomment-567831112
The problem was first introduced here:
dabd57847e
and later "fixed" here:
f324477dd0
by setting the stack size to /STACK:33554432
Solvespace now starts up even with /STACK:554432
According to this:
https://en.cppreference.com/w/cpp/language/value_initialization
```
"2) if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor; "
```
So removing the `{}` should leave both the `System` and `TextWindow` class instances properly initialized.
A warning found with /W4 by MSVC 2019 (Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314)
is an actual bug. How does the SpaceMouse (I do not have one) work at all when the global `hSpaceWareDriverClass` is NULL?!
.\src\platform\guiwin.cpp(1392,34): warning C4459: declaration of 'hSpaceWareDriverClass' hides global declaration
.\src\platform\guiwin.cpp(1389,13): message : see declaration of 'SolveSpace::Platform::hSpaceWareDriverClass'
Found with /W4 by MSVC 2019 (Microsoft (R) C/C++ Optimizing Compiler Version 19.24.28314)
A bunch of implicit casts 'double' to 'float' and one 'int64_t' to 'unsigned'.
.\src\platform\guiwin.cpp(1237): warning C4701: potentially uninitialized local variable 'cursorName' used
.\src\platform\guiwin.cpp(1237): warning C4703: potentially uninitialized local pointer variable 'cursorName' used
.\src\solvespace.cpp(805,30): warning C4456: declaration of 'gs' hides previous local declaration
.\src\solvespace.cpp(715,17): message : see declaration of 'gs'
.\src\solvespace.cpp(849,47): warning C4456: declaration of 'e' hides previous local declaration
.\src\solvespace.cpp(847,29): message : see declaration of 'e'
.\src\render\render.h(288,51): warning C4458: declaration of 'camera' hides class member
.\src\render\render.h(271,17): message : see declaration of 'SolveSpace::SurfaceRenderer::camera'
.\src\render\render.h(289,57): warning C4458: declaration of 'lighting' hides class member
.\src\render\render.h(272,17): message : see declaration of 'SolveSpace::SurfaceRenderer::lighting'
GetIdent is called from an UI event callback, at which point there
might well not be an active GL context. Before this commit, that
would return a NULL pointer and result in a crash.
Before this commit, certain fonts (e.g. Terminus) would appear in
the selector but cause a crash (assertion failure) if they are used.
After this commit, we make sure all preconditions are met before
showing a font there.
Also, improve error reporting to always print font filename.
This was originally changed in 74aa80b6, but the fix broke stipping
because it incorrectly changed the logic. Revert that, and just make
the textures smaller instead.
Before this commit, resizing the property browser would cut off
the rows at the bottom, or else add black space, until next refresh.
This could be perhaps more elegantly done by adding an onResize event
but given that each of them would be followed by onRender anyway, it
seems there's no benefit to adding onResize.
As I understand it, both glGetError() and glFinish() are serializing
and blockig, so it makes more sense to call them at the same time.
glFlush() does not block.
Since Catalina or earlier this no longer causes artifacts when Cocoa
controls are overlaid on a GL layer. Conversely, offscreen rendering
is very slow, especially on HiDPI screens.
Co-Authored-By: Koen Schmeets <hello@koenschmeets.nl>
When drawing the graphics window, we flush it twice: once to draw
the geometry, and another time to draw the UI overlay (toolbar,
selection marquee, and FPS counter). Calling glFinish() each time
is (on most platforms) just pointlessly slow, but on macOS Catalina,
without offscreen rendering, it causes the toolbar to flicker.
Instead of calling glFinish() twice per frame in that case, call
glFlush() twice and then glFinish() once we really are done.
Union and difference are optimized by replacing the expression
(!inShell && !inFace)
which is equivqlent to
(!inShell && !inSame && !inOpp)
with
outSide
which is equivalent, since SShell::Class::OUTSIDE is the only remaining possibility.
Per the OpenGL documentation:
> GL_INVALID_VALUE may be generated if level is greater than
> log2(max), where max is the returned value of GL_MAX_TEXTURE_SIZE.
Although we always passed `log2(max) + 1` as `level`, for some reason
none of the GL implementations we run on ever returned an error.
It also appears there is a bug in ANGLE that crashes the process
instead in this case if the C++ runtime performs bound checks on
vector::operator[]=.
Was getting segfaults near here with another patch since removed from the branch.
Moving these assignments after the memfree means they still have
useful data when debugging a crash in memfree.
Allows distancing users from the internal "elem" member.
Add Get() and operator[].
Replace direct references to elem.
Make elem and elemsAllocated private in IdList/List.
In other words, Ctrl inverts the normal action of LMB. It is already
possible to deselect entities through the context menu, but that
can be very awkward on laptop touchpads with a crowded sketch; with
Ctrl, a misclick is easily corrected without moving cursor at all.
This means that automatically added H/V constraints now will never
cause the sketch to become overconstrained, which currently makes
that feature almost unusable.
It makes no sense to solve by substitution (therefore weakening rank
check) in SolveRank(), since that's the whole point of SolveRank().
In addition, because SolveRank() is currently always called right
after AddConstraint(), forceDofCheck would always be true anyway.
In addition, it makes no sense to have TestRankForGroup() dependent
on the result of the previous solve. (For SolveGroup(), solving by
substitution after we know that rank test succeeds makes dragging
points much faster.)
Clarify the name of the command, as the old name is not strictly
correct. E.g. consider a vertical line with a midpoint constraint to
origin has 1 DOF, but 2 highlights are shown. Conversely, a single
datum point has 2 DOF, but 1 highlight is shown.
Supported metric units: km, m, cm, mm, µm, nm.
Supported USCS units: in, mil, µin.
Also, use the newly introduced unit formatting machinery in tools for
measuring perimeter, area and volume, so that e.g. volume is not
displayed in millions of cubic millimeters.
It's not very obvious if the extrusion failed because in a later
group, the solid (by default) uses a very dark gray color that blends
into the black background.
This needs to be done separately because, while we already warn on
broken polygons in workplanes, many more groups can be extruded, e.g.
the canonical way (for now) to mirror a group is to use a rotation,
and that doesn't get checked for closed contour, since most rotations
won't get extruded.
MSVC has a long history of value initialization bugs, and this one is
no exception. In this case, when some MSVC versions (at least up to
2013) are instructed to value-initialize a non-POD class with
a compiler generated non-trivial constructor, it does not zero out
the POD members.
Its only use was in a context where it was completely equivalent to
MemFree, so just use that instead, and keep the temporary heap as
purely an arena allocator, that could use something like bump
pointer.
This is useful in niche cases, like making angular measurement tools.
Also, use simpler and more principled code for numeric precision
while editing constraints: don't special-case angles, but use up to
10 digits after the decimal point for everything.
This is currently necessary to get repeatable results when exporting
assemblies as a part of a batch process, since the mesh geometry in
imported files is not regenerated for export.
Also, mark not just curves, but also points and normals derived from
construction requests as construction.
Also, don't always mark arc center point as construction just to
exclude it from chord tolerance bounding box calculation; instead,
special-case it there.
If a sketch has a "minor" problem, such as being self-intersecting,
this can cause considerably confusion in subsequent groups, yet is
not indicated in the group list.
This commit makes the "err" yellow in such cases. Note that the
indication may not change immediately when a change leading to
trouble is made, since the dependent groups are not recalculated
on all changes.
By setting WINVER=0x0501 (Windows XP) in CMakeLists.txt and adding a few
missing defines in guiwin.cpp and configuring OPENGL=1 in CMake
Solvespace (3.0~25b6eba1) compiles and works perfectly on Windows XP.
Tested with MinGW GCC-6.3.0-1
Before this commit it would prompt for top left and bottom left
corner, neither of which was what in fact was being used. Those two
specific points cannot be used because of the way equations are
written, so instead change that to top left and bottom right, which
is more convenient anyway.
This fixes an elusive GTK issue where tooltips would be spuriously
displayed, and makes tooltips behave nicer on Windows.
Unfortunately the macOS code is unchanged as the macOS tooltip
implementation seems seriously broken in ways I do not understand.
After this commit, if the target system does have modern OpenGL
drivers installed, ANGLE is configured to use them, bypassing most
translation (shaders still have to be translated from ESSL to GLSL).
If there are no OpenGL drivers, such as if the graphics drivers were
installed via Windows Update, DirectX translation is still used. This
results in a very noticeable startup delay and minor performance
degradation.
In addition it is no longer necessary to build with -DOPENGL=1 to be
able to run the binary in wine; everything works out of the box.
Before, wine's incomplete HLSL translator would crash.
This change required renaming the variable `texture` in shaders,
since it shadows the Core GLSL function with the same name, and ANGLE
translates texture2D() calls to texture() calls.
It is not clear why this code was added (I don't remember) and
the normal parent-child relationship should be sufficient for
the task of keeping property browser on top of the main window.
With SetWindowPos(hwnd, HWND_TOPMOST) though, the property browser
window stays on top of *anything*, even if the user switches to
an entirely different application.
This function showed up surprisingly high on a CPU time profile
when the GUI was unresponsive "doing things". Removed a duplicated
difference in the not-equal case, and switched to abs and a single compare
instead of two compares with a negation. It seems to have moved the
function further down in the profile.
Ubuntu 18.04 uses GTKMM 3.22.2-2, which doesn't support native file chooser.
Commit bc3e09edbf checks if native file chooser
is available, but the result is overridden with a hardcoded define,
probably for debugging.
Removing the debugging code fixes build on Ubuntu 18.04.
Before this commit, if the sketch contain no entities with starting
points off of the axis of revolution, the revolution may fail, which
manifests as the face normals being inverted. The code at the top of
MakeFromRevolutionOf() takes the furthest point from the axis,
projects it on that axis to get a vector. In this case that vector
is essentially zero length except for rounding errors.
After this commit, instead of only considering start points of
beziers, all control points are considered.
Fix by @phkahler.
We plan to use flatbuffers in the future for the next generation of
the .slvs file format, so flatbuffers are built unconditionally; and
the Q3DO exporter itself is tiny.
Before this commit, the default font chosen for TTF text is Arial
(chosen by the basename of arial.ttf), which isn't present on most
Linux systems, and cannot be redistributed. After this commit, it is
replaced with Bitstream Vera Sans, which can be. Existing files
are not affected.
The font name in the TTF file was artificially modified to add
the (built-in) suffix, which will need to be done if more built-in
fonts are added.
Modifying the original entities instead of deleting them, retains the
original associated constraints. This makes creating rounded rectangles
a lot easier.
This serves two purposes.
First, we want to (some day) convert these messages into a less
obtrustive form, something like toaster notifications, such that they
don't interrupt workflow as harshly. That would, of course, be
nonblocking.
Second, some platforms, like Emscripten, do not support nested event
loops, and it's not possible to display a modal dialog on them
synchronously.
When making this commit, I've reviewed all Error() and Message()
calls to ensure that only some of the following is true for all
of them:
* The call is followed a break or return statement that exits
an UI entry point (e.g. an MenuX function);
* The call is followed by cleanup (in fact, in this case the new
behavior is better, since even with a synchronous modal dialog
we have to be reentrant);
* The message is an informational message only and nothing
unexpected will happen if the operation proceeds in background.
In general, all Error() calls already satisfied the above conditions,
although in some cases I changed control flow aroudn them to more
clearly show that. The Message() calls that didn't satisfy these
conditions were reworked into an asynchronous form.
There are three explicit RunModal() calls left that need to be
reworked into an async form.
We have a lot of classes with virtual functions but no virtual
destructor, mostly under render/. While this is not a problem
due to how our hierarchy is structured, some versions of clang
warn about this on the delete statement inside shared_ptr.
We could add a virtual destructor, but adding final qualifiers
expresses intent better, is generally more efficient (since it allows
devirtualizing most virtual calls in render/), and solves
the potential problem clang is warning us about.
We currently support MSVC 2013, and MSVC 2013 has weird bugs around
std::unique_ptr; the one we hit is Connect ID 858243. You can't
actually open the bug report anymore because Microsoft has shut down
Microsoft Connect. We probably shouldn't support a compiler so old
its bugtracker doesn't exist anymore, but there isn't any very good
reason to use unique_ptr for TimerRef either, so let's change that
for the time being.
This commit removes Platform::Window::Redraw function, and rewrites
its uses to run on timer events. Most UI toolkits have obscure issues
with recursive event handling loops, and Emscripten is purely event-
driven and cannot handle imperative redraws at all.
As a part of this change, the Platform::Timer::WindUp function
is split into three to make the interpretation of its argument
less magical. The new functions are RunAfter (a regular timeout,
setTimeout in browser terms), RunAfterNextFrame (an animation
request, requestAnimationFrame in browser terms), and
RunAfterProcessingEvents (a request to run something after all
events for the current frame are processed, used for coalescing
expensive operations in face of input event queues).
This commit changes two uses of Redraw(): the AnimateOnto() and
ScreenStepDimGo() functions. The latter was actually broken in that
on small sketches, it would run very quickly and not animate
the dimension change at all; this has been fixed.
While we're at it, get rid of unused Platform::Window::NativePtr
function as well.
This commit fixes two issues that cause issues in WebGL:
* Non-power-of-two textures must wrap as GL_CLAMP_TO_EDGE.
This breaks non-power-of-two textures.
* Render calls with zero primitives should not be issued.
This just causes warning spam.
The code in LoadStringFromGzip was attempting to perform an unaligned
access using memcpy, but it cast the source to a pointer with
alignment requirements larger than 1, which, under optimizations,
reintroduced the original issue.
This is to address MSVC warnings.
This commit changes a few configuration fields to use double instead
of float. There doesn't seem to be any reason these use float except
for the legacy Windows code using float for saved configuration.
Changing their type to double improves consistency.
This commit merges all ad-hoc file dialog code, such as the feature
where dialogs remember last location and format, and exposes it
through a common interface.
This commit also significantly improves Gtk dialog handling code.
This commit changes the awfully specific code for dialogs with
messages duplicated three times to go through a generic interface.
It also fixes some issues with the way translated messages
were parameterized.
This commit removes the custom message dialog box used on Windows,
for several reasons. First, it was the last element not respecting
HiDPI displays. Second, other OSes do not easily provide this much
control over rendering default message boxes, and both Gnome and
macOS frown upon non-standard renderings such as those; so the custom
rendering was already not used on the other OSes.
This commit mostly just changes the settings code to be in line with
the rest of the platform abstractions, although it also fixes some
settings names to be consistent with others, and uses native bool
types where applicable.
This commit also makes settings-related operations much less
wasteful, not that it should matter.
This commit removes a large amount of code partially duplicated
between the text and the graphics windows, and opens the path to
having more than one model window on screen at any given time,
as well as simplifies platform work.
This commit also adds complete support for High-DPI device pixel
ratio. It adds support for font scale factor (a fractional factor
on top of integral device pixel ratio) on the platform side, but not
on the application side.
This commit also adds error checking to all Windows API calls
(within the abstracted code) and fixes a significant number of
misuses and non-future-proof uses of Windows API.
This commit also makes uses of Windows API idiomatic, e.g. using
the built-in vertical scroll bar, native tooltips, control
subclassing instead of hooks in the global dispatch loop, and so on.
It reinstates tooltip support and removes menu-related hacks.
This commit removes a large amount of redundant code that needed
to be kept in sync between platforms and also makes it much easier
to add new menu-related functionality since little to no platform
code needs to be altered anymore.
This commit also greatly improves code locality in context menu
handling by allowing context menu click handlers to be closures.
This commit temporarily introduces a SetMainMenu API, which is rather
hacky but only necessary until an abstraction for windows is added.
We should make good use of in-place member initialization. Many
new classes have constructors that effectively do nothing but
default-initialize POD members, and when adding new members,
it is very easy to miss initializing them. With in-place
initialization, the code is more compact, the diffs are nicer,
and it's harder to miss them.
This commit only converts render/ and platform/ to use in-place
member initialization, since there was a bug in CairoRenderer,
but we should convert the entire codebase.
This changes the assertion failure behavior to be the same in debug
and release builds: to show the complete failure message, and
to offer to restart the application or defer to Windows Error
Reporting to generate a backtrace. Contrary to popular belief,
WER is not useless, and since SolveSpace publishes pdb files,
WER-generated reports can be symbolized.
This commit also addresses the long-standing problem where showing
a dialog on fatal error would re-enter the application code, thus
causing another error or a crash that is more fatal than the current
one.
According to the C standard all preprocessor definitions starting
with an underscore are reserved for standard and implementation use,
so don't use those. Also, sort and unique include directives.
windowBits of 16 means "decode gzip header" and "use window size
from zlib header". For some reason, this results in a window size
that is too small on OpenBSD. Instead, use maximum window size
explicitly, since there is no downside for doing so.
Since font sizes in SolveSpace are specified in terms of cap height,
we need U+0041 to determine cap height. Some fonts lack it; in
that case, we assume that cap height is the same as the size we've
requested. This avoids a crash, at the cost of completely wrong
(although consistent) metrics; I do not really know of a better way.
There was a copy rule that copied the locale from the source
to the binary directory, and also a regeneration rule that used
the locale in the binary directory as a temporary file.
Rename the target for the latter.
To reproduce:
* New sketch;
* Create two redundant constraints, with second being automatically
marked as reference;
* Switch one of these to non-reference;
* Allow redundant constraints;
* All new constraints with labels created as reference, even
if that specific degree of freedom is not constrained yet.
Before this commit, if the source group of a step rotate/translate
group is forced to triangle mesh, the UI would show that the step
rotate/translate group is also forced to triangle mesh, but the group
would in fact contain NURBS surfaces.
glibc defines a CHAR_WIDTH macro in limits.h since about 6.3.*.
This is apparently added as a part of ISO TS 18661-1:2014, which
I cannot read because it is not publicly available, and which covers
some sort of floating-point extensions. This is one of those changes
that should never have been done yet here we are.
This commit updates a *lot* of rather questionable path handling
logic to be robust. Specifically:
* All path operations go through Platform::Path.
* All ad-hoc path handling functions are removed, together with
PATH_SEP. This removes code that was in platform-independent
parts, but had platform-dependent behavior.
* Group::linkFileRel is removed; only an absolute path is stored
in Group::linkFile. However, only Group::linkFileRel is saved,
with the relative path calculated on the fly, from the filename
passed into SaveToFile. This eliminates dependence on global
state, and makes it unnecessary to have separare code paths
for saved and not yet saved files.
* In a departure from previous practice, functions with
platform-independent code but platform-dependent behavior
are all grouped under platform/. This makes it easy to grep
for functions with platform-dependent behavior.
* Similarly, new (GUI-independent) code for all platforms is added
in the same platform.cpp file, guarded with #ifs. It turns out
that implementations for different platforms had a lot of shared
code that tended to go out of sync.
Extrustion top and bottom faces require a normal to be present.
Before this commit, the normal is always taken from the assembled
loop; if the loop could not be assembled (i.e. the loop is broken
or not coplanar) the normal will be (0,0,0), which breaks the sketch.
Also, loops are not generated when generating the sketch
to determine its bounding box.
This may result in spuriously broken sketches when e.g. undoing
a change that has broken a loop.
After this commit, loops are generated when generating for bounding
box, and if the loop could not be assembled, then the workplane
normal is used. This still results in failures when there is
no workplane, but those cases should be quite pathological.
Before this commit, a same orientation constraint created with
a workplane selected would only remove 2 of 3 DOFs. After
this commit, it properly removes all 3 DOFs.
Before this commit, lathe groups had three DOFs, which of course
could not actually move. After this commit, lathe groups have
zero DOFs, as expected.
This bug was introduced in commit 6dced80.
Before this commit, DoLater would be run as an idle callback,
which (depending on system performance) could either result in
a half-regenerated sketch being displayed, with only the dragged
entity updated, or no regeneration whatsoever during the drag.
After this commit, the GTK behavior matches macOS and Win32 ones.
Hiding the menu bar was only supported on macOS, and it is inherently
troublesome to port because keyboard accelerators on Win32 and GTK
are inherently dependent on the menu bar being visible.
On top of that, it's not clear how to bring it back if it's hidden
by accident.
Before this commit, when a point is constrained to an entity (point,
circle, arc of circle or line segment) by clicking on it,
the resulting constraint is not necessarily satisfied, and the next
regeneration may place the newly constrained point somewhere other
than the intended position. After this commit, the parameters
are modified to satisfy the constraint.
Commit f5485cb and its ancestors add a parameter to some constraints.
This parameter must be materialized and assigned a non-zero value via
ModifyToSatisfy for the solver library to not make unnecessary
changes to the sketch during the initial generation. For this, we
represent it explicitly instead of using hc.param(0), such that
the materialized constraint does not conflict with any user-defined
ones.
This commit follows 41365c5, which enabled export of Z coordinate
by using POLYLINE instead of LWPOLYLINE. After this commit, only
the AcDb2dPolyline/AcDb2dVertex are used when exporting flat views,
which may improve compatibility with 2d design packages.
The existing code is horrible and needlessly platform-dependent.
Even worse, it causes a freeze on GTK. Instead of propping that up
with a few more crutches, just fix the root cause.
The somewhat confusingly named set_has_alpha() function does not
affect whether alpha can be used during rendering to the area.
Rather, it affects whether alpha will be used when composing
the contents of the area with the window underneath it.
Before this commit, if any rendering mode except "show all occluded"
is enabled, points can be highlighted for corresponding to a DOF
after "Analyze → Degrees of Freedom" but then promptly occluded,
which is confusing.
We want to suppress accelerators but still get input to (at least)
the window where the editor is opened. It's no harm to permit input
to other windows, but it is bad to route all of it to the editor,
since color chooser depends on being able to receive input.
So, what we do is add modal grab to the *overlay*, which has
the editor and the underlay widget, route all events as usual
to children, and just force the key events to go to the editor,
since otherwise they would still propagate up for some reason.
Before this commit, the first time NewFrame() is called,
the background color would not be filled, leading to interference
with whatever the GUI toolkit decided to put there.