Compare commits

..

71 Commits
master ... v2.3

Author SHA1 Message Date
whitequark
7c1ca46076 Bump version to 2.3. 2016-12-24 02:09:48 +00:00
whitequark
9c30f7858f README: update Linux dependencies. 2016-12-13 09:58:10 +00:00
Elvira Khabirova
6802a12a52 Fix crash when trying to import not .dxf or .dwg files 2016-11-27 15:17:46 +00:00
whitequark
99d6f1f5b5 DXF: Fix export of wireframe as 3D DXF.
Before this commit, polylines got flattened but all other entities
got exported with the proper Z coordinate. After this commit, all
entities are exported with proper Z coordinate.

Also, instead of exporting LWPOLYLINE (2d only), POLYLINE (2d/3d)
is exported; as a bonus it is more compatible with 3rd party
software, since it is older.
2016-11-26 08:29:21 +00:00
whitequark
ece7630624 Fix detection of transparent meshes.
SSurface::TriangulateInto first populates the mesh with triangles
that have no color, and then paints them, which confused the code
that detects if a mesh is transparent into thinking that all of them
are; and that broke the "draw back faces in red" feature, since it
is disabled for transparent meshes.
2016-11-18 11:02:19 +00:00
whitequark
82746b6171 Fix a crash when adding a symmetric constraint on a line.
This is the same problem as in a2c97fc.
2016-11-16 02:19:09 +00:00
whitequark
74d8621f53 OS X: fix another out-of-bounds TW.META access.
See also e1d6dac.
2016-11-05 17:06:56 +00:00
whitequark
0b2fc34de1 Update CHANGELOG. 2016-11-02 10:22:17 +00:00
whitequark
25febd82ed TTF: use metrics of 'A' to determine cap height.
SolveSpace 2.0 used the height of 'A' (i.e. cap height) to determine
the reference height.
SolveSpace 2.1 completely broke that during transition to Freetype,
and used something more or less random, by using FT_Set_Char_Size
with units_per_EM.
SolveSpace 2.2 attempted to fix that, but also used something more
or less random, by using FT_Request_Size with "unit" values.

Turns out that Freetype actually doesn't have a concept of cap height
at all. It is possible to extract it from the TT_OS2 table that is
present in some TrueType fonts, but it is not present in Microsoft
fonts (the msttcorefonts ones), and for those Linux fonts in which
it is present it doesn't appear very reliable.

So instead, use the height of 'A' instead, like version 2.0 did.
This has the advantage that it is quite bulletproof, and also matches
exactly what the old files are measured against.

One downside is that fonts without an 'A' glyph would not render.
We can deal with that when it becomes a problem.
2016-11-02 09:00:44 +00:00
whitequark
d809d4122f TTF: actually use CID as GID when CID-to-GID mapping is absent. 2016-11-02 09:00:27 +00:00
whitequark
2e1c7a6701 TTF: only call FT_Request_Size once after loading. 2016-11-02 09:00:16 +00:00
whitequark
4fad67d721 OS X: don't crash in GetSaveFile() if default extension is invalid. 2016-10-25 09:59:52 +00:00
whitequark
a2c97fcd46 Fix a crash when adding a symmetric constraint on two points.
The crash was introduced in e2e91672; I have not noticed that some
of the code relies on past-the-size entities in GW.GS being empty.
2016-10-25 09:58:24 +00:00
whitequark
c4ad073d1b Bump version to 2.2. 2016-10-17 02:07:14 +00:00
whitequark
0f3879e37c Debian: remove in-tree packaging.
The package is now maintained by the Debian Science team at:
https://anonscm.debian.org/git/debian-science/packages/solvespace.git
2016-10-17 02:07:14 +00:00
EvilSpirit
05d9c0fab9 Try to re-solve groups that fail rank test.
Sometimes, after a large change in a sketch, constraints that are
geometrically fine may still cause the rank test to fail. One way
this can happen is VectorsParallel() pivoting wrong due to the big
move, converging anyways but ending up singular. It would then
re-pivot correctly on the new solution when you re-solve, making
this a transient error. This is visible when dragging the arm in
the jansen-asm.slvs example.

After this commit, if the rank test fails, equations are regenerated
the Jacobian is rewritten, and the rank test is retried, which
prevents these transient errors from interfering with dragging.

The problem described above was invisible before c011444, as rank
test was only performed before solving.
2016-10-14 00:40:06 +00:00
Evil-Spirit
bc43365eff Write params if system is solved as REDUNDANT_OKAY.
A system solved as REDUNDANT_OKAY is still solved correctly,
even if the UI would consider this an error, in case that
g->allowRedundant==false. So there's no reason to discard this
solution; we might find it useful if a system loses a degree of
freedom while dragging, or to avoid regeneration after redundant
constraints are allowed.

This commit also reverts commit 3ff236c, as that is not necessary
anymore.
2016-10-14 00:34:35 +00:00
whitequark
8a96ca894c OS X: map the backspace key to the "Delete" function.
Apple hardware does not have a discrete Delete key, so Backspace
is used for deleting stuff instead.
2016-10-12 19:43:09 +00:00
whitequark
dde6030533 OS X: set scroller knob style to light.
On newer OS X versions the scrollbar is overlaid on the window
contents, so a black know is invisible.
2016-10-12 19:25:07 +00:00
whitequark
b8abf698c9 OS X: don't remap OK in message boxes to Escape.
The platform convention is to use Return.
2016-10-12 19:08:25 +00:00
whitequark
f6eb079d41 OS X: revert "sort out window visibility and focus."
This reverts commit 1dba594949.

Turns out the old behavior was more appropriate for OS X.
2016-10-12 19:08:16 +00:00
whitequark
adca3cd253 GTK: use 3DConnexion button 0 instead of SI_APP_FIT_BUTTON.
The libspnav library doesn't even define SI_APP_FIT_BUTTON, which
appears to be Windows-specific functionality, perhaps a physical
button remapped with some logic. Just use 0 instead, since that
seems always safe.
2016-10-11 13:57:09 +00:00
whitequark
33c3fd5fce Update CHANGELOG. 2016-10-10 23:43:35 +00:00
EvilSpirit
f2007326b4 Don't draw edges and outlines while dragging an entity.
This is far too slow for realtime dragging, and results in assemblies
falling apart (e.g. jansen-asm from the examples).
2016-10-10 21:32:25 +00:00
whitequark
02b7e24812 Fix a handle leak in TtfFontList::PlotString. 2016-10-10 21:18:03 +00:00
whitequark
1a5047550d Normalize the string returned by Extension() to lowercase.
This would otherwise break code that branches on the extension,
such as that after 06a188cc.
2016-10-10 20:53:16 +00:00
whitequark
5e28b35f2b OS X: correctly parse output of otool -D.
In the past this relied on otool -XD not printing the name of
the library itself, only the install name, but that doesn't work
anymore as of 10.12.
2016-10-10 19:57:11 +00:00
whitequark
19e77e7866 Mark group dirty when clicking "allow redundant constraints" link.
Otherwise, the now-valid constraint will not become satisfied.
2016-10-10 17:45:56 +00:00
whitequark
e1d6dac87a OS X: fix out-of-bounds TW.META access.
For some reason OS X can post pointer events far outside the window
rect, so be defensive here.
2016-10-10 12:26:13 +00:00
whitequark
4c022f8d79 Win32: add proper Unicode support to message boxes.
Before this commit, for every non-ASCII character, a replacement
character was also printed.
2016-10-09 21:55:10 +00:00
whitequark
bbd106044b DXF: update to use Unicode-aware file open routines on Windows. 2016-10-09 20:56:02 +00:00
whitequark
359b13bd62 GTK: show files with uppercase extensions in file open dialog.
The Windows dialog does that automatically, but the GTK one doesn't.
So this is useful for Windows interop.
2016-10-09 16:19:33 +00:00
whitequark
513f55f7d4 Travis: update brew installation instructions.
The `brew upgrade` is no longer needed as Travis updated the
versions in their image.
2016-10-09 13:37:58 +00:00
whitequark
bbf8610c57 Make translate/rotate groups inherit the "suppress solid model" option. 2016-10-09 13:29:04 +00:00
whitequark
dc0eed8322 Get rid of the MAX_SELECTED restriction in GroupSelection(). 2016-08-13 05:22:09 +00:00
whitequark
ca150aeda1 Update CHANGELOG. 2016-08-13 05:21:34 +00:00
EvilSpirit
4d2c773ee6 DXF export: always declare layers before using them.
Before this commit, the #s001-active-grp layer was not declared,
and this broke some external software, such as Inkscape.
See https://bugs.launchpad.net/inkscape/+bug/1472429 for details.
2016-08-13 04:28:14 +00:00
EvilSpirit
0b997e4c17 Forcibly show the current group once we start a drawing operation 2016-08-13 03:43:44 +00:00
EvilSpirit
bfef091ac9 Do not clear selection during operations that don't need it.
Specifically, during "Align View onto Workplane" when we are locked
in workplane (in which case it always aligns onto that workplane).
2016-08-13 03:32:02 +00:00
whitequark
bcd43c7c24 Update libdxfrw. 2016-08-13 02:24:14 +00:00
whitequark
4fae03d105 Unbreak TTF metrics.
In 2.0, the distance between the points in the TTF request specified
cap height. In 2.1, that was accidentally changed to some arbitrary
value near cap height instead, due to a 72pt factor mess-up.
This commit restores the old behavior.
2016-08-01 12:31:34 +00:00
whitequark
c0f5a31401 When snapping constraints to grid, snap the reference point. 2016-07-19 15:14:51 +00:00
whitequark
5af252eaf1 Multiply constraint values by scale when pasting with transformation. 2016-07-19 12:14:28 +00:00
whitequark
61904280a3 GTK: make Space Navigator actually work.
Before this commit, no events would actually be received.
2016-07-19 08:27:11 +00:00
EvilSpirit
51f3d7e438 Fix the "Show degrees of freedom" command.
Before this commit, it never highlighted anything at all.
It was broken when chord tolerance calculation was overhauled.
2016-06-29 17:01:59 +00:00
whitequark
561b2797e8 Don't crash when changing the autosave interval. 2016-06-23 11:59:04 +00:00
whitequark
5525303946 Do not remove autosave after successfully opening file.
If SolveSpace crashes after the open, or hangs and is forcibly
killed, data would be lost. (I lost my data.) Instead, remove
autosave only in two cases: right after a successful save, or right
after a save is declined. This should be completely safe.
2016-06-23 11:59:01 +00:00
whitequark
7f6c774bf5 Update changelog for 2.2. 2016-06-23 11:58:54 +00:00
whitequark
fd255364b3 Show "Paste" context menu item even when only constraints are copied. 2016-06-23 11:58:29 +00:00
whitequark
478973eb3c OS X: fix typo in build system. 2016-06-20 13:42:40 +00:00
Thomas Buck
8fd572d449 OS X: add 3Dconnexion device support. 2016-06-20 13:42:40 +00:00
whitequark
7b82ff68e1 Unix: also install the SolveSpace desktop icon in the xpm format.
This is required by e.g. Debian guidelines.
2016-06-16 02:51:10 +00:00
whitequark
7fc2033c9b Update debian/copyright. 2016-06-16 02:45:20 +00:00
whitequark
ff9a8284b4 OS X: find frameworks last.
Before this commit, any available libpng or libfreetype would be
picked, e.g. from Mono.framework. After, homebrew and MacPorts
are prioritized.
2016-06-13 04:15:55 +00:00
whitequark
c25e4c8973 OS X: sort out window visibility and focus. 2016-06-13 02:08:28 +04:00
whitequark
dce906465d Add CHANGELOG.md. 2016-06-11 22:30:26 +00:00
whitequark
53e5e0eb90 Fix copyright. 2016-06-11 22:29:58 +00:00
whitequark
ce656ef7c6 Fix disabling of autoconstrainter via Ctrl. 2016-06-11 22:28:02 +00:00
whitequark
fb2f32eb72 Three.js: correctly handle browser zoom.
Before this commit, controls went wild on zoom ratios other than 1:1,
and the rendering wasn't too good either.
2016-06-11 20:45:57 +00:00
EvilSpirit
917a7b93ce Load actual factory default, not saved style, when requested. 2016-06-11 20:45:57 +00:00
EvilSpirit
c838158e04 DXF, DWG: allow undoing an import. 2016-06-11 20:28:02 +00:00
whitequark
17f7a7b467 Unbreak importing files in the same directory as current file.
This commit fixes a bug introduced in commit 0d7aa0a1.
2016-06-11 20:27:00 +00:00
whitequark
e78edd9b94 Cocoa: allow dismissing Message/Error NSAlerts using Escape key. 2016-06-11 20:26:51 +00:00
whitequark
d13e29cdaf GTK: clip any editors instead of resizing GraphicsWindow.
Such resizing may well get us past OpenGL's maximum texture size
and break rendering.
2016-06-11 20:26:12 +00:00
whitequark
daee939714 Reimplement e129755d properly.
Before this commit, quitting through menu would bring up the dialog
twice when declining to save the file.
2016-06-11 20:26:01 +00:00
whitequark
44c152ccd0 Fix glyph for U+0454 є in vector font. 2016-06-11 20:24:51 +00:00
whitequark
dfc218c452 Allow copying and pasting constraints. 2016-06-11 20:23:44 +00:00
whitequark
9fc60a0c00 Cocoa: fix massive memory leak. 2016-06-11 20:23:16 +00:00
whitequark
f3e36f593b GTK: intercept the Tab key and run MNU_SHOW_TEXT_WND. 2016-06-11 20:23:09 +00:00
whitequark
b62375b554 Rename "Browser" to "Property Browser".
Also, rename confusing "Show Text Window" menu item.
2016-06-11 20:22:41 +00:00
whitequark
056d3bfa30 Properly fix workplane name overlapping workplane border.
A previous attempt to fix this was done in 0128b8679. However, it was
not rigorous. The added offset was dependent on font size and it
introduced an error into edit control positioning. Further, it is
irrelevant to non-workplanes.

After this commit, the workplane drawing code adds a fixed offset
instead. Also, the "tab" is enlarged to not overlap with #XY etc.
2016-06-11 20:22:24 +00:00
614 changed files with 11362 additions and 122616 deletions

14
.gitattributes vendored
View File

@ -1,10 +1,22 @@
# .gitattributes for SolveSpace
# Set default behaviour, in case users don't have core.autocrlf set.
* text=auto
# Explicitly declare text files we want to always be normalized and converted
# to native line endings on checkout.
*.cpp text
*.h text
*.txt text
# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf
# Denote all files that are truly binary and should not be modified.
*.gz binary
*.ico binary
*.jpg binary
*.lib binary
*.png binary
*.slvs binary
# end .gitattributes

View File

@ -1,18 +0,0 @@
### System information
SolveSpace version: (e.g. 3.0~3dd2fc00; go to Help → About...)
Operating system: (e.g. Debian testing)
### Expected behavior
What should have happened?
### Actual behavior
What actually happened?
### Additional information
For bugs, please attach a savefile that shows the problematic behavior.
You can attach `.slvs` files by archiving them into a `.zip` first.

5
.gitignore vendored
View File

@ -1,8 +1,6 @@
/CMakeCache.txt
/build*/
/test/**/*.diff.*
/test/**/*.curr.*
*.trace
*.trace # OpenGL apitrace files
/debian/tmp/
/debian/*.log
/debian/*.substvars
@ -12,4 +10,3 @@
/debian/libslvs1/
/debian/libslvs1-dev/
/obj-*/
/*.slvs

13
.gitmodules vendored
View File

@ -5,18 +5,9 @@
[submodule "extlib/libpng"]
path = extlib/libpng
url = https://github.com/glennrp/libpng
[submodule "extlib/freetype"]
path = extlib/freetype
[submodule "extlib/libfreetype"]
path = extlib/libfreetype
url = http://git.sv.nongnu.org/r/freetype/freetype2.git
[submodule "extlib/libdxfrw"]
path = extlib/libdxfrw
url = https://github.com/solvespace/libdxfrw.git
[submodule "extlib/pixman"]
path = extlib/pixman
url = https://github.com/solvespace/pixman
[submodule "extlib/cairo"]
path = extlib/cairo
url = https://github.com/solvespace/cairo
[submodule "extlib/angle"]
path = extlib/angle
url = https://github.com/solvespace/angle

View File

@ -4,7 +4,6 @@ os:
- osx
sudo: required
dist: trusty
osx_image: xcode8.2
install:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis/install-debian.sh; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/install-macos.sh; fi
@ -21,9 +20,3 @@ deploy:
repo: solvespace/solvespace
tags: true
condition: "$TRAVIS_OS_NAME == osx"
notifications:
irc:
channels:
- "chat.freenode.net#solvespace"
use_notice: true
skip_join: true

View File

@ -4,10 +4,5 @@ if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=D
mkdir build
cd build
# We build without the GUI until Travis updates to an Ubuntu version with GTK 3.22.
cmake .. -DCMAKE_C_COMPILER=clang-3.9 -DCMAKE_CXX_COMPILER=clang++-3.9 \
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
-DENABLE_GUI=OFF \
-DENABLE_SANITIZERS=ON
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE
make VERBOSE=1
make test_solvespace

View File

@ -5,5 +5,10 @@ if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=D
mkdir build
cd build
cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 -DCMAKE_BUILD_TYPE=$BUILD_TYPE ..
make VERBOSE=1
make test_solvespace
if ! make VERBOSE=1; then
echo "Sigh, transient build failure. Retrying..."
if ! make VERBOSE=1; then
echo "Okay, this is probably an actual bug."
exit 1
fi
fi

View File

@ -1,10 +1,7 @@
#!/bin/sh -xe
wget -O - http://apt.llvm.org/llvm-snapshot.gpg.key|sudo apt-key add -
sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test
sudo add-apt-repository -y 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.9 main'
sudo apt-get update -qq
sudo apt-get install -q -y \
cmake cmake-data libpng12-dev zlib1g-dev libjson0-dev libfontconfig1-dev \
libgtkmm-3.0-dev libpangomm-1.4-dev libcairo2-dev libgl1-mesa-dev libglu-dev \
libfreetype6-dev dpkg-dev libstdc++-5-dev clang-3.9 clang++-3.9 lcov
libgtkmm-2.4-dev libpangomm-1.4-dev libgl1-mesa-dev libglu-dev libglew-dev \
libfreetype6-dev dpkg-dev

View File

@ -1,4 +1,3 @@
#!/bin/sh -xe
brew update
brew install freetype cairo

View File

@ -1,82 +1,6 @@
Changelog
=========
3.0
---
New sketch features:
* Extrude, lathe, translate and rotate groups can now use the "assembly"
boolean operation, to increase performance.
* Translate and rotate groups can create n-dimensional arrays using
the "difference" and "assembly" boolean operations.
* A new sketch in workplane group can be created based on existing workplane.
* TTF text request has two additional points on the right side, which allow
constraining the width of text.
* Image requests can now be created, similar to TTF text requests.
This replaces the "style → background image" feature.
* Irrelevant points (e.g. arc center point) are not counted when estimating
the bounding box used to compute chord tolerance.
* When adding a constraint which has a label and is redundant with another
constraint, the constraint is added as a reference, avoiding an error.
* Datum points can be copied and pasted.
New constraint features:
* When dragging an arc or rectangle point, it will be automatically
constrained to other points with a click.
* When selecting a constraint, the requests it constraints can be selected
in the text window.
* When selecting an entity, the constraints applied to it can be selected
in the text window.
New export/import features:
* Three.js: allow configuring projection for exported model, and initially
use the current viewport projection.
* Wavefront OBJ: a material file is exported alongside the model, containing
mesh color information.
* DXF/DWG: 3D DXF files are imported as construction entities, in 3d.
New rendering features:
* The "Show/hide hidden lines" button is now a tri-state button that allows
showing all lines (on top of shaded mesh), stippling occluded lines
or not drawing them at all.
* The "Show/hide outlines" button is now independent from "Show/hide edges".
New measurement/analysis features:
* New command for measuring total length of selected entities,
"Analyze → Measure Perimeter".
* New command for measuring center of mass, with live updates as the sketch
changes, "Analyze → Center of Mass".
* When selecting a point and a line, projected distance to to current
workplane is displayed.
Other new features:
* New command-line interface, for batch exporting and more.
* New link to match the on-screen size of the sketch with its actual size,
"view → set to full scale".
* When zooming to fit, constraints are also considered.
* When clicking on an entity that shares a place with other entities,
the entity from the current group is selected.
* When dragging an entity that shares a place with other entities,
the entity from a request is selected. For example, dragging a point on
a face of an extrusion coincident with the source sketch plane will
drag the point from the source sketch.
* In expressions, numbers can contain the digit group separator, "_".
* The "=" key is bound to "Zoom In", like "+" key.
* The numpad decimal separator key is bound to "." regardless of locale.
* On Windows, full-screen mode is implemented.
Bugs fixed:
* A point in 3d constrained to any line whose length is free no longer
causes the line length to collapse.
* Curve-line constraints (in 3d), parallel constraints (in 3d), and
same orientation constraints are more robust.
* Adding some constraints (vertical, midpoint, etc) twice errors out
immediately, instead of later and in a confusing way.
* Constraining a newly placed point to a hovered entity does not cause
spurious changes in the sketch.
* Points highlighted with "Analyze → Show Degrees of Freedom" are drawn
on top of all other geometry.
2.3
---

View File

@ -1,12 +1,5 @@
# cmake configuration
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR)
message(FATAL_ERROR
"In-tree builds are not supported; please perform an out-of-tree build:\n"
" rm -rf CMakeCache.txt CMakeFiles/\n"
" mkdir build && cd build && cmake ..")
endif()
cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR)
cmake_policy(VERSION 3.1.0)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
@ -14,6 +7,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
include(CheckIncludeFile)
# for /MT on MSVC
set(CMAKE_USER_MAKE_RULES_OVERRIDE
"${CMAKE_SOURCE_DIR}/cmake/c_flag_overrides.cmake")
@ -30,218 +25,29 @@ include(GetGitCommitHash)
# set(GIT_COMMIT_HASH 0000000000000000000000000000000000000000)
project(solvespace)
set(solvespace_VERSION_MAJOR 3)
set(solvespace_VERSION_MINOR 0)
set(solvespace_VERSION_MAJOR 2)
set(solvespace_VERSION_MINOR 3)
string(SUBSTRING "${GIT_COMMIT_HASH}" 0 8 solvespace_GIT_HASH)
set(ENABLE_GUI ON CACHE BOOL
"Whether the graphical interface is enabled (command line interface always is)")
set(ENABLE_TESTS ON CACHE BOOL
"Whether the test suite will be built and run")
set(ENABLE_COVERAGE OFF CACHE BOOL
"Whether code coverage information will be collected")
set(ENABLE_SANITIZERS OFF CACHE BOOL
"Whether to enable Clang's AddressSanitizer and UndefinedBehaviorSanitizer")
set(OPENGL 2 CACHE STRING "OpenGL version to use (one of: 1 2)")
set(EXECUTABLE_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${CMAKE_BINARY_DIR}/bin)
if(NOT CMAKE_C_COMPILER_ID STREQUAL CMAKE_CXX_COMPILER_ID)
message(FATAL_ERROR "C and C++ compilers should be supplied by the same vendor")
if(NOT WIN32 AND NOT APPLE)
set(GUI gtk2 CACHE STRING "GUI toolkit to use (one of: gtk2 gtk3)")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0)
# GCC 4.8/4.9 ship with broken but present <regex>. meh.
message(FATAL_ERROR "GCC 5.0+ is required")
endif()
endif()
# common compiler flags
if(MINGW)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
if(TRIPLE STREQUAL "i686-w64-mingw32")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -msse2")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse2")
endif()
endif()
if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux" OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed ${CMAKE_EXE_LINKER_FLAGS}")
endif()
if(ENABLE_SANITIZERS)
if(NOT CMAKE_CXX_COMPILER_ID MATCHES "Clang")
message(FATAL_ERROR "Sanitizers are only available when using Clang/Clang++")
endif()
set(SANITIZE_FLAGS "-O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fsanitize=address,integer")
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-sanitize-recover=integer")
# We assume IEEE floats, which means DIV/0 is defined; but ubsan doesn't do so by default.
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-sanitize=float-divide-by-zero")
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-sanitize=unsigned-integer-overflow")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}")
endif()
# dependencies
message(STATUS "Using in-tree libdxfrw")
add_subdirectory(extlib/libdxfrw)
if(WIN32)
include(FindVendoredPackage)
include(AddVendoredSubdirectory)
find_vendored_package(Freetype freetype
WITH_ZLIB OFF
WITH_BZip2 OFF
WITH_PNG OFF
WITH_HarfBuzz OFF
FREETYPE_LIBRARY freetype
FREETYPE_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/freetype/include)
find_vendored_package(ZLIB zlib
ZLIB_LIBRARY zlibstatic
ZLIB_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/zlib)
list(APPEND ZLIB_INCLUDE_DIR ${CMAKE_BINARY_DIR}/extlib/zlib)
find_vendored_package(PNG libpng
SKIP_INSTALL_ALL ON
PNG_LIBRARY png_static
PNG_PNG_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/libpng)
list(APPEND PNG_PNG_INCLUDE_DIR ${CMAKE_BINARY_DIR}/extlib/libpng)
message(STATUS "Using in-tree pixman")
add_vendored_subdirectory(extlib/pixman)
set(PIXMAN_FOUND YES)
set(PIXMAN_LIBRARY pixman)
set(PIXMAN_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/pixman/pixman)
list(APPEND PIXMAN_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/extlib/pixman/pixman)
message(STATUS "Using in-tree cairo")
add_vendored_subdirectory(extlib/cairo)
set(CAIRO_FOUND YES)
set(CAIRO_LIBRARIES cairo)
set(CAIRO_INCLUDE_DIRS ${CMAKE_SOURCE_DIR}/extlib/cairo/src)
list(APPEND CAIRO_INCLUDE_DIRS ${CMAKE_BINARY_DIR}/extlib/cairo/src)
if(ENABLE_GUI)
if(OPENGL STREQUAL "2")
message(STATUS "Using in-tree ANGLE")
set(ANGLE_STATIC ON CACHE INTERNAL "")
set(ANGLE_ENABLE_D3D9 ON CACHE INTERNAL "")
set(ANGLE_ENABLE_D3D11 ON CACHE INTERNAL "")
set(ANGLE_ENABLE_OPENGL OFF CACHE INTERNAL "")
set(ANGLE_ENABLE_ESSL OFF CACHE INTERNAL "")
set(ANGLE_ENABLE_GLSL OFF CACHE INTERNAL "")
set(ANGLE_ENABLE_HLSL ON CACHE INTERNAL "")
add_vendored_subdirectory(extlib/angle)
set(OPENGL_LIBRARIES EGL GLESv2)
set(OPENGL_INCLUDE_DIR ${CMAKE_SOURCE_DIR}/extlib/angle/include)
else()
find_package(OpenGL REQUIRED)
endif()
if(MSVC AND ${CMAKE_SIZEOF_VOID_P} EQUAL 4)
message(STATUS "Using prebuilt SpaceWare")
set(SPACEWARE_FOUND TRUE)
set(SPACEWARE_INCLUDE_DIR
"${CMAKE_SOURCE_DIR}/extlib/si")
set(SPACEWARE_LIBRARIES
"${CMAKE_SOURCE_DIR}/extlib/si/siapp.lib")
endif()
endif()
elseif(APPLE)
set(CMAKE_FIND_FRAMEWORK LAST)
find_package(ZLIB REQUIRED)
find_package(PNG REQUIRED)
find_package(Freetype REQUIRED)
find_library(CAIRO_LIBRARIES cairo REQUIRED)
find_path(CAIRO_INCLUDE_DIRS cairo.h PATH_SUFFIXES cairo)
if(ENABLE_GUI)
find_package(OpenGL REQUIRED)
find_library(APPKIT_LIBRARY AppKit REQUIRED)
endif()
else() # Linux and compatible systems
find_package(PkgConfig REQUIRED)
find_package(Backtrace)
find_package(SpaceWare)
find_package(ZLIB REQUIRED)
find_package(PNG REQUIRED)
find_package(Freetype REQUIRED)
pkg_check_modules(CAIRO REQUIRED cairo)
if(ENABLE_GUI)
find_package(OpenGL REQUIRED)
pkg_check_modules(FONTCONFIG REQUIRED fontconfig)
pkg_check_modules(JSONC REQUIRED json-c)
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0>=3.16 pangomm-1.4 x11)
endif()
endif()
if(ENABLE_COVERAGE)
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU)
find_program(GCOV gcov)
elseif(CMAKE_CXX_COMPILER_ID MATCHES Clang)
find_program(LLVM_COV llvm-cov)
if(LLVM_COV)
set(GCOV ${CMAKE_CURRENT_BINARY_DIR}/llvm-gcov.sh)
file(WRITE ${GCOV} "#!/bin/sh -e\n${LLVM_COV} gcov $*")
execute_process(COMMAND chmod +x ${GCOV})
endif()
endif()
find_program(LCOV lcov)
find_program(GENHTML genhtml)
if(NOT GCOV OR NOT LCOV OR NOT GENHTML)
message(FATAL_ERROR "gcov/llvm-cov and lcov are required for producing coverage reports")
endif()
endif()
find_program(XGETTEXT xgettext)
find_program(MSGINIT msginit)
find_program(MSGMERGE msgmerge)
if(XGETTEXT AND MSGINIT AND MSGMERGE)
set(HAVE_GETTEXT TRUE)
else()
message(WARNING "Gettext not found, translations will not be updated")
set(HAVE_GETTEXT FALSE)
endif()
# solvespace-only compiler flags
# compiler
if(WIN32)
add_definitions(
-D_CRT_SECURE_NO_DEPRECATE
-D_CRT_SECURE_NO_WARNINGS
-D_SCL_SECURE_NO_WARNINGS
-DWINVER=0x0601
-D_WIN32_WINNT=0x0601
-D_WIN32_WINNT=0x500
-D_WIN32_IE=_WIN32_WINNT
-DISOLATION_AWARE_ENABLED
-DWIN32
-DWIN32_LEAN_AND_MEAN
-DUNICODE
-D_UNICODE
-DNOMINMAX
-D_USE_MATH_DEFINES)
-D_UNICODE)
endif()
if(MSVC)
@ -249,56 +55,141 @@ if(MSVC)
# they have their own __inline; this breaks `static inline` functions.
# We do not want to care and so we fix this with a definition.
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline")
# Same for the (C99) __func__ special variable; we use it only in C++ code.
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /D__func__=__FUNCTION__")
# We rely on these /we flags. They correspond to the GNU-style flags below as
# follows: /w4062=-Wswitch
set(WARNING_FLAGS "${WARNING_FLAGS} /we4062")
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
if(CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang)
set(WARNING_FLAGS "-Wall -Wextra -Wno-unused-parameter")
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(WARNING_FLAGS "${WARNING_FLAGS} -Wfloat-conversion")
endif()
# We rely on these -Werror flags.
set(WARNING_FLAGS "${WARNING_FLAGS} -Werror=switch")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${WARNING_FLAGS}")
endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
if(MINGW)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static-libgcc")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc -static-libstdc++")
endif()
if(APPLE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed ${CMAKE_EXE_LINKER_FLAGS}")
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed ${CMAKE_EXE_LINKER_FLAGS}")
endif()
if(SANITIZE)
if(NOT (CMAKE_C_COMPILER_ID STREQUAL Clang AND CMAKE_CXX_COMPILER_ID STREQUAL Clang))
message(ERROR "Sanitizers are only available in Clang/Clang++")
endif()
set(SANITIZE_FLAGS "-O1 -fno-omit-frame-pointer -fno-optimize-sibling-calls")
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fsanitize=address,undefined,integer")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}")
endif()
# dependencies
find_package(OpenGL REQUIRED)
message(STATUS "Using in-tree libdxfrw")
add_subdirectory(extlib/libdxfrw)
if(WIN32)
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -l0")
endif()
# Configure Freetype first. If done later, it will notice that
# zlib is available, try to use it and promptly break on MSVC
# in a very obscure way. Given that the only use of zlib, bzip2
# and png support is in support for extremely obsolete Unix fonts,
# we don't care.
find_package(Freetype)
if(ENABLE_COVERAGE)
if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
message(FATAL_ERROR "Code coverage is only available on GCC and Clang")
if(NOT FREETYPE_FOUND)
message(STATUS "Using in-tree libfreetype")
add_subdirectory(extlib/libfreetype EXCLUDE_FROM_ALL)
set(FREETYPE_LIBRARY
freetype)
set(FREETYPE_INCLUDE_DIRS
"${CMAKE_SOURCE_DIR}/extlib/libfreetype/include")
find_package(Freetype REQUIRED)
endif()
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(FATAL_ERROR "Code coverage produces reliable results only on Debug builds")
find_package(ZLIB)
if(NOT ZLIB_FOUND)
message(STATUS "Using in-tree zlib")
add_subdirectory(extlib/zlib EXCLUDE_FROM_ALL)
message(STATUS "Using in-tree libpng")
set(ZLIB_LIBRARY
zlibstatic)
set(ZLIB_INCLUDE_DIR
"${CMAKE_SOURCE_DIR}/extlib/zlib"
"${CMAKE_BINARY_DIR}/extlib/zlib")
find_package(ZLIB REQUIRED)
endif()
# With -fexceptions, every call becomes a branch. While technically accurate,
# this is not useful for us.
set(COVERAGE_FLAGS -fno-exceptions --coverage)
set(COVERAGE_LIBRARY --coverage)
find_package(PNG)
if(NOT PNG_FOUND)
message(STATUS "Using in-tree libpng")
set(SKIP_INSTALL_ALL
ON)
add_subdirectory(extlib/libpng EXCLUDE_FROM_ALL)
set(PNG_LIBRARY
png16_static)
set(PNG_PNG_INCLUDE_DIR
"${CMAKE_SOURCE_DIR}/extlib/libpng"
"${CMAKE_BINARY_DIR}/extlib/libpng")
find_package(PNG REQUIRED)
endif()
if(NOT MINGW)
message(STATUS "Using prebuilt SpaceWare")
set(SPACEWARE_FOUND TRUE)
set(SPACEWARE_INCLUDE_DIR
"${CMAKE_SOURCE_DIR}/extlib/si")
set(SPACEWARE_LIBRARIES
"${CMAKE_SOURCE_DIR}/extlib/si/siapp.lib")
endif()
elseif(APPLE)
set(CMAKE_FIND_FRAMEWORK LAST)
find_package(PNG REQUIRED)
find_package(Freetype REQUIRED)
find_library(APPKIT_LIBRARY AppKit REQUIRED)
else() # Linux and compatible systems
find_package(SpaceWare)
# Use freedesktop's pkg-config to locate everything.
find_package(PkgConfig REQUIRED)
pkg_check_modules(ZLIB REQUIRED zlib)
pkg_check_modules(PNG REQUIRED libpng)
pkg_check_modules(FONTCONFIG REQUIRED fontconfig)
pkg_check_modules(JSONC REQUIRED json-c)
pkg_check_modules(GLEW REQUIRED glew)
pkg_check_modules(FREETYPE REQUIRED freetype2)
set(HAVE_GTK TRUE)
if(GUI STREQUAL "gtk3")
set(HAVE_GTK3 TRUE)
pkg_check_modules(GTKMM REQUIRED gtkmm-3.0 pangomm-1.4 x11)
elseif(GUI STREQUAL "gtk2")
set(HAVE_GTK2 TRUE)
pkg_check_modules(GTKMM REQUIRED gtkmm-2.4 pangomm-1.4 x11)
else()
message(FATAL_ERROR "GUI unrecognized: ${GUI}")
endif()
endif()
# components
add_subdirectory(res)
add_subdirectory(tools)
add_subdirectory(src)
add_subdirectory(exposed)
if(ENABLE_TESTS)
add_subdirectory(test)
endif()
if(CMAKE_BUILD_TYPE STREQUAL "Release" OR CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
add_subdirectory(bench)
else()
message(STATUS "Benchmarking disabled in debug builds.")
endif()

View File

@ -1,250 +0,0 @@
Contributing to SolveSpace
==========================
Contributing bug reports
------------------------
Bug reports are always welcome! When reporting a bug, please include the following:
* The version of SolveSpace (use Help → About...);
* The operating system;
* The save file that reproduces the incorrect behavior, or, if trivial or impossible,
instructions for reproducing it.
GitHub does not allow attaching `*.slvs` files, but it does allow attaching `*.zip` files,
so any savefiles should first be archived.
Contributing code
-----------------
SolveSpace is written in C++, and currently targets all compilers compliant with C++11.
This includes GCC 5 and later, Clang 3.3 and later, and Visual Studio 12 (2013) and later.
### High-level conventions
#### Portability
SolveSpace aims to consist of two general parts: a fully portable core, and platform-specific
UI and support code. Anything outside of `src/platform/` should only use standard C++11,
and rely on `src/platform/unixutil.cpp` and `src/platform/w32util.cpp` to interact with
the OS where this cannot be done through the C++11 standard library.
#### Libraries
SolveSpace primarily relies on the C++11 STL. STL has well-known drawbacks, but is also
widely supported, used, and understood. SolveSpace also includes a fair amount of use of
bespoke containers List and IdList; these provide STL iterators, and can be used when
convenient, such as when reusing other code.
One notable departure here is the STL I/O threads. SolveSpace does not use STL I/O threads
for two reasons: (i) the interface is borderline unusable, and (ii) on Windows it is not
possible to open files with Unicode paths through STL.
When using external libraries (other than to access platform features), the libraries
should satisfy the following conditions:
* Portable, and preferably not interacting with the platform at all;
* Can be included as a CMake subproject, to facilitate Windows, Android, etc. builds;
* Use a license less restrictive than GPL (BSD/MIT, Apache2, MPL, etc.)
#### String encoding
Internally, SolveSpace exclusively stores and uses UTF-8 for all purposes; any `std::string`
may be assumed to be encoded in UTF-8. On Windows, UTF-8 strings are converted to and from
wide strings at the boundary; see [UTF-8 Everywhere][utf8] for details.
[utf8]: http://utf8everywhere.org/
#### String formatting
For string formatting, a wrapper around `sprintf`, `ssprintf`, is used. A notable
pitfall when using it is trying to pass an `std::string` argument without first converting
it to a C string with `.c_str()`.
#### Filesystem access
For filesystem access, the C standard library is used. The `ssfopen` and `ssremove`
wrappers are provided that accept UTF-8 encoded paths.
#### Assertions
To ensure that internal invariants hold, the `ssassert` function is used, e.g.
`ssassert(!isFoo, "Unexpected foo condition");`. Unlike the standard `assert` function,
the `ssassert` function is always enabled, even in release builds. It is more valuable
to discover a bug through a crash than to silently generate incorrect results, and crashes
do not result in losing more than a few minutes of work thanks to the autosave feature.
### Use of C++ features
The conventions described in this section should be used for all new code, but there is a lot
of existing code in SolveSpace that does not use them. This is fine; don't touch it if it works,
but if you need to modify it anyway, might as well modernize it.
#### Exceptions
Exceptions are not used primarily because SolveSpace's testsuite uses measurement
of branch coverage, important for the critical parts such as the geometric kernel.
Every function call with exceptions enabled introduces a branch, making branch coverage
measurement useless.
#### Operator overloading
Operator overloading is not used primarily for historical reasons. Instead, method such
as `Plus` are used.
#### Member visibility
Member visibility is not used for implementation hiding. Every member field and function
is `public`.
#### Constructors
Constructors are not used for initialization, chiefly because indicating an error
in a constructor would require throwing an exception, nor does it use constructors for
blanket zero-initialization because of the performance impact of doing this for common
POD classes like `Vector`.
Instances can be zero-initialized using the aggregate-initialization syntax, e.g. `Foo foo = {};`.
This zero-initializes the POD members and default-initializes the non-POD members, generally
being an equivalent of `memset(&foo, 0, sizeof(foo));` but compatible with STL containers.
#### Input- and output-arguments
Functions accepting an input argument take it either by-value (`Vector v`) or
by-const-reference (`const Vector &v`). Generally, passing by-value is safer as the value
cannot be aliased by something else, but passing by-const-reference is faster, as a copy is
eliminated. Small values should always be passed by-value, and otherwise functions that do not
capture pointers into their arguments should take them by-const-reference. Use your judgement.
Functions accepting an output argument always take it by-pointer (`Vector *v`). This makes
it immediately visible at the call site as it is seen that the address is taken. Arguments
are never passed by-reference, except when needed for interoperability with STL, etc.
#### Iteration
`foreach`-style iteration is preferred for both STL and `List`/`IdList` containers as it indicates
intent clearly, as opposed to `for`-style.
#### Const correctness
Functions that do not mutate `this` should be marked as `const`; when iterating a collection
without mutating any of its elements, `for(const Foo &elem : collection)` is preferred to indicate
the intent.
### Coding style
Code is formatted by the following rules:
* Code is indented using 4 spaces, with no trailing spaces, and lines are wrapped
at 100 columns;
* Braces are placed at the end of the line with the declaration or control flow statement;
* Braces are used with every control flow statement, even if there is only one statement
in the body;
* There is no space after control flow keywords (`if`, `while`, etc.);
* Identifiers are formatted in camel case; variables start with a lowercase letter
(`exampleVariable`) and functions start with an uppercase letter (`ExampleFunction`).
For example:
```c++
std::string SolveSpace::Dirname(std::string filename) {
int slash = filename.rfind(PATH_SEP);
if(slash >= 0) {
return filename.substr(0, slash);
}
return "";
}
```
Debugging code
--------------
SolveSpace releases are throughly tested but sometimes they contain crash
bugs anyway. The reason for such crashes can be determined only if the executable
was built with debug information.
### Debugging a released version
The Linux distributions usually include separate debug information packages.
On a Debian derivative (e.g. Ubuntu), these can be installed with:
apt-get install solvespace-dbg
The macOS releases include the debug information, and no further action
is needed.
The Windows releases include the debug information on the GitHub
[release downloads page](https://github.com/solvespace/solvespace/releases).
### Debugging a custom build
If you are building SolveSpace yourself on a Unix-like platform,
configure or re-configure SolveSpace to produce a debug build, and
then re-build it:
cd build
cmake .. -DCMAKE_BUILD_TYPE=Debug [other cmake args...]
make
If you are building SolveSpace yourself using the Visual Studio IDE,
select Debug from the Solution Configurations list box on the toolbar,
and build the solution.
### Debugging with gdb
gdb is a debugger that is mostly used on Linux. First, run SolveSpace
under debugging:
gdb [path to solvespace executable]
(gdb) run
Then, reproduce the crash. After the crash, attach the output in
the console, as well as output of the following gdb commands to
a bug report:
(gdb) backtrace
(gdb) info locals
If the crash is not easy to reproduce, please generate a core file,
which you can use to resume the debugging session later, and provide
any other information that is requested:
(gdb) generate-core-file
This will generate a large file called like `core.1234` in the current
directory; it can be later re-loaded using `gdb --core core.1234`.
### Debugging with lldb
lldb is a debugger that is mostly used on macOS. First, run SolveSpace
under debugging:
lldb [path to solvespace executable]
(lldb) run
Then, reproduce the crash. After the crash, attach the output in
the console, as well as output of the following gdb commands to
a bug report:
(lldb) backtrace all
(lldb) frame variable
If the crash is not easy to reproduce, please generate a core file,
which you can use to resume the debugging session later, and provide
any other information that is requested:
(lldb) process save-core "core"
This will generate a large file called `core` in the current
directory; it can be later re-loaded using `lldb -c core`.
### Debugging GUI-related bugs on Linux
There are several environment variables available that make crashes
earlier and errors more informative. Before running SolveSpace, run
the following commands in your shell:
export G_DEBUG=fatal_warnings
export LIBGL_DEBUG=1
export MESA_DEBUG=1

View File

@ -9,10 +9,10 @@ This repository contains the source code of [SolveSpace][], a parametric
Installation
------------
### macOS (>=10.6 64-bit), Windows (>=Vista 32-bit)
### Mac OS X (>=10.6 64-bit), Debian (>=jessie) and Ubuntu (>=trusty)
Binary packages for macOS and Windows are available via
[GitHub releases][rel].
Binary packages for Mac OS X and Debian derivatives are available
via [GitHub releases][rel].
[rel]: https://github.com/solvespace/solvespace/releases
@ -25,14 +25,14 @@ Building on Linux
### Building for Linux
You will need CMake, zlib, libpng, cairo, freetype. To build the GUI, you will need
fontconfig, gtkmm 3.0 (version 3.16 or later), pangomm 1.4, OpenGL and OpenGL GLU, and
optionally, the Space Navigator client library.
You will need CMake, libpng, zlib, json-c, fontconfig, freetype, gtkmm 2.4,
pangomm 1.4, OpenGL, OpenGL GLU and OpenGL GLEW, and optionally, the Space Navigator
client library.
On a Debian derivative (e.g. Ubuntu) these can be installed with:
apt-get install cmake zlib1g-dev libpng-dev libcairo2-dev libfreetype6-dev
apt-get install libjson-c-dev libfontconfig1-dev libgtkmm-3.0-dev libpangomm-1.4-dev \
libgl-dev libglu-dev libspnav-dev
apt-get install libpng12-dev libjson-c-dev libfreetype6-dev \
libfontconfig1-dev libgtkmm-2.4-dev libpangomm-1.4-dev \
libgl-dev libglu-dev libglew-dev libspnav-dev cmake
Before building, check out the necessary submodules:
@ -42,20 +42,19 @@ After that, build SolveSpace as following:
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake ..
make
sudo make install
The graphical interface is built as `build/bin/solvespace`, and the command-line interface
is built as `build/bin/solvespace-cli`. It is possible to build only the command-line interface
by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation.
A fully functional port to GTK3 is available, but not recommended
for use due to bugs in this toolkit.
### Building for Windows
You will need CMake and a Windows cross-compiler.
You will need CMake, a Windows cross-compiler, and Wine with binfmt support.
On a Debian derivative (e.g. Ubuntu) these can be installed with:
apt-get install cmake mingw-w64
apt-get install cmake mingw-w64 wine-binfmt
Before building, check out the necessary submodules:
@ -65,31 +64,27 @@ After that, build 32-bit SolveSpace as following:
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake \
-DCMAKE_BUILD_TYPE=Release
make
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake ..
make solvespace
Or, build 64-bit SolveSpace as following:
mkdir build
cd build
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake \
-DCMAKE_BUILD_TYPE=Release
make
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake ..
make solvespace
The graphical interface is built as `build/bin/solvespace.exe`, and the command-line interface
is built as `build/bin/solvespace-cli.exe`.
The application is built as `build/src/solvespace.exe`.
Space Navigator support will not be available.
Building on macOS
-----------------
Building on Mac OS X
--------------------
You will need XCode tools, CMake, libpng and Freetype. To build tests, you
will need cairo. Assuming you use
You will need XCode tools, CMake, libpng and Freetype. Assuming you use
[homebrew][], these can be installed with:
brew install cmake libpng freetype cairo
brew install cmake libpng freetype
XCode has to be installed via AppStore; it requires a free Apple ID.
@ -101,28 +96,26 @@ After that, build SolveSpace as following:
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake ..
make
The application is built in `build/bin/solvespace.app`, the graphical interface executable
is `build/bin/solvespace.app/Contents/MacOS/solvespace`, and the command-line interface executable
is `build/bin/solvespace.app/Contents/MacOS/solvespace-cli`.
The app bundle is built in `build/src/solvespace.app`.
[homebrew]: http://brew.sh/
Building on Windows
-------------------
You will need [git][gitwin], [cmake][cmakewin] and Visual C++.
You will need [cmake][cmakewin] and Visual C++.
### Building with Visual Studio IDE
### GUI build
Check out the git submodules. Create a directory `build` in
the source tree and point cmake-gui to the source tree and that directory.
Press "Configure" and "Generate", then open `build\solvespace.sln` with
Visual C++ and build it.
### Building with Visual Studio in a command prompt
### Command-line build
First, ensure that git and cl (the Visual C++ compiler driver) are in your
`%PATH%`; the latter is usually done by invoking `vcvarsall.bat` from your
@ -131,10 +124,10 @@ Visual Studio install. Then, run the following in cmd or PowerShell:
git submodule update --init
mkdir build
cd build
cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
cmake .. -G "NMake Makefiles"
nmake
### Building with MinGW
### MSVC build
It is also possible to build SolveSpace using [MinGW][mingw], though
Space Navigator support will be disabled.
@ -145,19 +138,12 @@ in bash:
git submodule update --init
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
cmake ..
make
[gitwin]: https://git-scm.com/download/win
[cmakewin]: http://www.cmake.org/download/#latest
[mingw]: http://www.mingw.org/
Contributing
------------
See the [guide for contributors](CONTRIBUTING.md) for the best way to file issues, contribute code,
and debug SolveSpace.
License
-------

View File

@ -1,4 +1,4 @@
version: 3.0.{build}
version: 2.2.{build}
clone_depth: 1
before_build:
- git submodule update --init
@ -6,25 +6,23 @@ before_build:
- cd build
- set tag=x%APPVEYOR_REPO_TAG_NAME%
- if %tag:~,2% == xv (set BUILD_TYPE=RelWithDebInfo) else (set BUILD_TYPE=Debug)
- cmake -G"Visual Studio 12" -T v120 ..
- cmake -G"Visual Studio 12" -T v120_xp -DCMAKE_BUILD_TYPE=%BUILD_TYPE% ..
build_script:
- msbuild "src\solvespace.vcxproj" /verbosity:minimal /property:Configuration=%BUILD_TYPE% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
- msbuild "src\solvespace-cli.vcxproj" /verbosity:minimal /property:Configuration=%BUILD_TYPE% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
- msbuild "test\solvespace-testsuite.vcxproj" /verbosity:minimal /property:Configuration=%BUILD_TYPE% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
test_script:
- bin\%BUILD_TYPE%\solvespace-testsuite.exe
artifacts:
- path: build\bin\%BUILD_TYPE%\solvespace.exe
- path: build\src\Debug\solvespace.exe
name: solvespace.exe
- path: build\bin\%BUILD_TYPE%\solvespace-cli.exe
name: solvespace-cli.exe
- path: build\bin\%BUILD_TYPE%\solvespace.pdb
- path: build\src\Debug\solvespace.pdb
name: solvespace.pdb
- path: build\src\RelWithDebInfo\solvespace.exe
name: solvespace.exe
- path: build\src\RelWithDebInfo\solvespace.pdb
name: solvespace.pdb
deploy:
- provider: GitHub
auth_token:
secure: P9/pf2nM+jlWKe7pCjMp41HycBNP/+5AsmE/TETrDUoBOa/9WFHelqdVFrbRn9IC
description: ""
artifact: solvespace.exe,solvespace-cli.exe,solvespace.pdb
artifact: solvespace.exe
on:
appveyor_repo_tag: true

View File

@ -1,17 +0,0 @@
# benchmark runner
foreach(pkg_config_lib CAIRO)
include_directories(${${pkg_config_lib}_INCLUDE_DIRS})
link_directories(${${pkg_config_lib}_LIBRARY_DIRS})
endforeach()
add_executable(solvespace-benchmark
harness.cpp
$<TARGET_PROPERTY:resources,EXTRA_SOURCES>)
target_link_libraries(solvespace-benchmark
solvespace-core
solvespace-headless)
add_dependencies(solvespace-benchmark
resources)

View File

@ -1,78 +0,0 @@
//-----------------------------------------------------------------------------
// Our harness for running benchmarks.
//
// Copyright 2016 whitequark
//-----------------------------------------------------------------------------
#include "solvespace.h"
static bool RunBenchmark(std::function<void()> setupFn,
std::function<bool()> benchFn,
std::function<void()> teardownFn,
size_t minIter = 5, double minTime = 5.0) {
// Warmup
setupFn();
if(!benchFn()) {
fprintf(stderr, "Benchmark failed\n");
return false;
}
teardownFn();
// Benchmark
size_t iter = 0;
double time = 0.0;
while(iter < minIter || time < minTime) {
setupFn();
auto testStartTime = std::chrono::steady_clock::now();
benchFn();
auto testEndTime = std::chrono::steady_clock::now();
teardownFn();
std::chrono::duration<double> testTime = testEndTime - testStartTime;
time += testTime.count();
iter += 1;
}
// Report
fprintf(stdout, "Iterations: %zd\n", iter);
fprintf(stdout, "Time: %.3f s\n", time);
fprintf(stdout, "Per iter.: %.3f s\n", time / (double)iter);
return true;
}
int main(int argc, char **argv) {
std::vector<std::string> args = InitPlatform(argc, argv);
std::string mode;
Platform::Path filename;
if(args.size() == 3) {
mode = args[1];
filename = Platform::Path::From(args[2]);
} else {
fprintf(stderr, "Usage: %s [mode] [filename]\n", args[0].c_str());
fprintf(stderr, "Mode can be one of: load.\n");
return 1;
}
bool result = false;
if(mode == "load") {
result = RunBenchmark(
[] {
SS.Init();
},
[&] {
if(!SS.LoadFromFile(filename))
return false;
SS.AfterNewFile();
return true;
},
[] {
SK.Clear();
SS.Clear();
});
} else {
fprintf(stderr, "Unknown mode \"%s\"\n", mode.c_str());
}
return (result == true ? 0 : 1);
}

View File

@ -1,10 +0,0 @@
# Equivalent to add_subdirectory(... EXCLUDE_FROM_ALL), but also disables
# all warnings.
include(DisableWarnings)
function(add_vendored_subdirectory PATH)
disable_warnings()
add_subdirectory(${PATH} EXCLUDE_FROM_ALL)
endfunction()

View File

@ -1,15 +0,0 @@
# Disables all warnings on MSVC and GNU-compatible compilers.
function(disable_warnings)
if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -w" PARENT_SCOPE)
elseif(CMAKE_C_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W0" PARENT_SCOPE)
endif()
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w" PARENT_SCOPE)
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W0" PARENT_SCOPE)
endif()
endfunction()

View File

@ -1,54 +0,0 @@
# Find the given library in the system locations, or build in-tree if not found.
#
# Arguments:
# PKG_NAME - name of the package as passed to find_package
# PKG_PATH - name of the source tree relative to extlib/
#
# The rest of the arguments are VARIABLE VALUE pairs. If the library is not found,
# every VARIABLE will be set to VALUE and find_package will be rerun with the REQUIRED flag.
# Regardless of where the library was found, only the specfied VARIABLEs that start with
# ${PKG_NAME} will be set in the parent scope.
#
# All warnings in the in-tree package are disabled.
include(DisableWarnings)
function(find_vendored_package PKG_NAME PKG_PATH)
find_package(${PKG_NAME})
set(cfg_name)
foreach(item ${ARGN})
if(NOT cfg_name)
set(cfg_name ${item})
else()
set(${cfg_name} ${item} CACHE INTERNAL "")
set(cfg_name)
endif()
endforeach()
disable_warnings()
string(TOUPPER ${PKG_NAME} VAR_NAME)
if(NOT ${VAR_NAME}_FOUND)
message(STATUS "Using in-tree ${PKG_PATH}")
set(${VAR_NAME}_IN_TREE YES CACHE INTERNAL "")
add_subdirectory(extlib/${PKG_PATH} EXCLUDE_FROM_ALL)
find_package(${PKG_NAME} REQUIRED)
elseif(${VAR_NAME}_IN_TREE)
add_subdirectory(extlib/${PKG_PATH} EXCLUDE_FROM_ALL)
endif()
# Now put everything we just discovered into the cache.
set(cfg_name)
foreach(item ${ARGN} ${VAR_NAME}_FOUND)
if(NOT cfg_name)
set(cfg_name ${item})
else()
if(cfg_name MATCHES "^${VAR_NAME}")
set(${cfg_name} "${${cfg_name}}" CACHE INTERNAL "")
endif()
set(cfg_name)
endif()
endforeach()
endfunction()

View File

@ -13,11 +13,11 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleVersion</key>
<string>${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH}</string>
<string>${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}</string>
<key>CFBundleShortVersionString</key>
<string>${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}</string>
<key>NSHumanReadableCopyright</key>
<string>© 2008-2016 Jonathan Westhues and other authors</string>
<string>© 2008-2015 Jonathan Westhues and other authors</string>
<key>NSPrincipalClass</key>
<string>NSApplication</string>
<key>NSMainNibFile</key>

View File

@ -1,15 +1,13 @@
set(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_NAME Windows)
set(TRIPLE i686-w64-mingw32)
SET(TRIPLE i686-w64-mingw32)
set(CMAKE_C_COMPILER ${TRIPLE}-gcc)
set(CMAKE_CXX_COMPILER ${TRIPLE}-g++)
set(CMAKE_RC_COMPILER ${TRIPLE}-windres)
SET(CMAKE_C_COMPILER ${TRIPLE}-gcc)
SET(CMAKE_CXX_COMPILER ${TRIPLE}-g++)
SET(CMAKE_RC_COMPILER ${TRIPLE}-windres)
set(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE})
SET(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(ENV{PKG_CONFIG_LIBDIR} /usr/${TRIPLE}/lib/pkgconfig)

View File

@ -1,15 +1,13 @@
set(CMAKE_SYSTEM_NAME Windows)
SET(CMAKE_SYSTEM_NAME Windows)
set(TRIPLE x86_64-w64-mingw32)
SET(TRIPLE x86_64-w64-mingw32)
set(CMAKE_C_COMPILER ${TRIPLE}-gcc)
set(CMAKE_CXX_COMPILER ${TRIPLE}-g++)
set(CMAKE_RC_COMPILER ${TRIPLE}-windres)
SET(CMAKE_C_COMPILER ${TRIPLE}-gcc)
SET(CMAKE_CXX_COMPILER ${TRIPLE}-g++)
SET(CMAKE_RC_COMPILER ${TRIPLE}-windres)
set(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE})
SET(CMAKE_FIND_ROOT_PATH /usr/${TRIPLE})
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(ENV{PKG_CONFIG_LIBDIR} /usr/${TRIPLE}/lib/pkgconfig)

View File

@ -5,13 +5,18 @@
*
* Copyright 2008-2013 Jonathan Westhues.
*---------------------------------------------------------------------------*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef WIN32
# include <windows.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#include <slvs.h>
@ -31,7 +36,7 @@ static void *CheckMalloc(size_t n)
* An example of a constraint in 3d. We create a single group, with some
* entities and constraints.
*---------------------------------------------------------------------------*/
void Example3d()
void Example3d(void)
{
/* This will contain a single group, which will arbitrarily number 1. */
Slvs_hGroup g = 1;
@ -83,7 +88,7 @@ void Example3d()
* along the reference frame's xy plane. In a second group, we create some
* entities in that group and dimension them.
*---------------------------------------------------------------------------*/
void Example2d()
void Example2d(void)
{
Slvs_hGroup g;
double qw, qx, qy, qz;
@ -249,7 +254,7 @@ void Example2d()
}
}
int main()
int main(void)
{
sys.param = CheckMalloc(50*sizeof(sys.param[0]));
sys.entity = CheckMalloc(50*sizeof(sys.entity[0]));

@ -1 +0,0 @@
Subproject commit 6fbcce0938caaccdbea44d826759aa2e587fe2f7

@ -1 +0,0 @@
Subproject commit d4724ee921c4fa399ccbd0019c3d6917452e0ffd

@ -1 +0,0 @@
Subproject commit 069083cccd73d1d68da68116c8d050bb62cdfe0e

@ -1 +1 @@
Subproject commit 6f362317bf3f176b613be48512a88b78125c79f4
Subproject commit 8f958955f54668c142ded760dc951ffd16d9c71b

1
extlib/libfreetype Submodule

@ -0,0 +1 @@
Subproject commit 44accb9e2e5b00696cf50a869b68afa2ce3dd389

@ -1 +1 @@
Subproject commit e9c3d83d5a04835806287f1e8c0f2d3a962d6673
Subproject commit 5b6a6f914b734f38d3ea96d70bfc67acd8b47414

@ -1 +0,0 @@
Subproject commit 5561dfc3f7e992454076ff3f10a0554c6b407e19

@ -1 +1 @@
Subproject commit 2fa463bacfff79181df1a5270fb67cc679a53e71
Subproject commit 50893291621658f355bc5b4d450a8d06a563053d

View File

@ -1,232 +0,0 @@
# First, set up registration functions for the kinds of resources we handle.
set(resource_root ${CMAKE_CURRENT_SOURCE_DIR}/)
set(resource_list)
if(WIN32)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/win32/versioninfo.rc.in
${CMAKE_CURRENT_BINARY_DIR}/win32/versioninfo.rc)
set(rc_file ${CMAKE_CURRENT_BINARY_DIR}/resources.rc)
file(WRITE ${rc_file} "// Autogenerated; do not edit\n")
file(APPEND ${rc_file} "#include <windows.h>\n")
file(APPEND ${rc_file} "#include \"${CMAKE_CURRENT_BINARY_DIR}/win32/versioninfo.rc\"\n")
function(add_resource name)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name})
if(${ARGC} GREATER 1)
set(id ${ARGV1})
else()
string(REPLACE ${resource_root} "" id ${source})
endif()
if(${ARGC} GREATER 2)
set(type ${ARGV2})
else()
set(type RCDATA)
endif()
file(SHA512 "${source}" hash)
file(APPEND ${rc_file} "${id} ${type} \"${source}\" // ${hash}\n")
# CMake doesn't track file dependencies across directories, so we force
# a reconfigure (which changes the RC file because of the hash above)
# every time a resource is changed.
set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${source}")
endfunction()
elseif(APPLE)
set(app_resource_dir ${CMAKE_BINARY_DIR}/bin/solvespace.app/Contents/Resources)
set(cli_resource_dir ${CMAKE_BINARY_DIR}/res)
function(add_resource name)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name})
set(target_app ${app_resource_dir}/${name})
set(target_cli ${cli_resource_dir}/${name})
set(resource_list "${resource_list};${target_app};${target_cli}" PARENT_SCOPE)
get_filename_component(target_app_dir ${target_app} DIRECTORY)
get_filename_component(target_cli_dir ${target_cli} DIRECTORY)
add_custom_command(
OUTPUT ${target_app} ${target_cli}
COMMAND ${CMAKE_COMMAND} -E make_directory ${target_app_dir}
COMMAND ${CMAKE_COMMAND} -E copy ${source} ${target_app}
COMMAND ${CMAKE_COMMAND} -E make_directory ${target_cli_dir}
COMMAND ${CMAKE_COMMAND} -E copy ${source} ${target_cli}
COMMENT "Copying resource ${name}"
DEPENDS ${source}
VERBATIM)
endfunction()
function(add_xib name)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name})
get_filename_component(basename ${name} NAME_WE)
set(target ${app_resource_dir}/${basename}.nib)
set(resource_list "${resource_list};${target}" PARENT_SCOPE)
add_custom_command(
OUTPUT ${target}
COMMAND ${CMAKE_COMMAND} -E make_directory ${app_resource_dir}
COMMAND ibtool --errors --warnings --notices --output-format human-readable-text
--compile ${target} ${source}
COMMENT "Building Interface Builder file ${name}"
DEPENDS ${source}
VERBATIM)
endfunction()
function(add_iconset name)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name})
get_filename_component(basename ${name} NAME_WE)
set(target ${app_resource_dir}/${basename}.icns)
set(resource_list "${resource_list};${target}" PARENT_SCOPE)
add_custom_command(
OUTPUT ${target}
COMMAND ${CMAKE_COMMAND} -E make_directory ${app_resource_dir}
COMMAND iconutil -c icns -o ${target} ${source}
COMMENT "Building icon set ${name}"
DEPENDS ${source}
VERBATIM)
endfunction()
else() # Unix
include(GNUInstallDirs)
set(app_resource_dir ${CMAKE_BINARY_DIR}/res)
function(add_resource name)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${name})
set(target ${app_resource_dir}/${name})
set(resource_list "${resource_list};${target}" PARENT_SCOPE)
get_filename_component(target_dir ${target} DIRECTORY)
add_custom_command(
OUTPUT ${target}
COMMAND ${CMAKE_COMMAND} -E make_directory ${target_dir}
COMMAND ${CMAKE_COMMAND} -E copy ${source} ${target}
COMMENT "Copying resource ${name}"
DEPENDS ${source}
VERBATIM)
get_filename_component(name_dir ${name} DIRECTORY)
install(FILES ${source}
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/solvespace/${name_dir})
endfunction()
endif()
function(add_resources)
foreach(name ${ARGN})
add_resource(${name})
set(resource_list "${resource_list}" PARENT_SCOPE)
endforeach()
endfunction()
# Second, register all resources.
if(WIN32)
add_resource(win32/icon.ico 4000 ICON)
add_resource(win32/manifest.xml 2 RT_MANIFEST)
elseif(APPLE)
add_iconset (cocoa/AppIcon.iconset)
add_xib (cocoa/MainMenu.xib)
add_xib (cocoa/SaveFormatAccessory.xib)
else()
add_resource(freedesktop/solvespace-48x48.png)
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/freedesktop/solvespace.desktop.in
${CMAKE_CURRENT_BINARY_DIR}/freedesktop/solvespace.desktop)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/freedesktop/solvespace.desktop
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
foreach(SIZE 16x16 24x24 32x32 48x48)
install(FILES freedesktop/solvespace-${SIZE}.png
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/apps
RENAME solvespace.png)
install(FILES freedesktop/solvespace-${SIZE}.png
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/mimetypes
RENAME application.x-solvespace.png)
endforeach()
foreach(SIZE 16x16 24x24 32x32 48x48)
install(FILES freedesktop/solvespace-${SIZE}.xpm
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps)
endforeach()
endif()
add_resources(
banner.txt
icons/graphics-window/angle.png
icons/graphics-window/arc.png
icons/graphics-window/assemble.png
icons/graphics-window/bezier.png
icons/graphics-window/circle.png
icons/graphics-window/construction.png
icons/graphics-window/equal.png
icons/graphics-window/extrude.png
icons/graphics-window/horiz.png
icons/graphics-window/image.png
icons/graphics-window/in3d.png
icons/graphics-window/lathe.png
icons/graphics-window/length.png
icons/graphics-window/line.png
icons/graphics-window/ontoworkplane.png
icons/graphics-window/other-supp.png
icons/graphics-window/parallel.png
icons/graphics-window/perpendicular.png
icons/graphics-window/pointonx.png
icons/graphics-window/point.png
icons/graphics-window/rectangle.png
icons/graphics-window/ref.png
icons/graphics-window/same-orientation.png
icons/graphics-window/sketch-in-3d.png
icons/graphics-window/sketch-in-plane.png
icons/graphics-window/step-rotate.png
icons/graphics-window/step-translate.png
icons/graphics-window/symmetric.png
icons/graphics-window/tangent-arc.png
icons/graphics-window/text.png
icons/graphics-window/trim.png
icons/graphics-window/vert.png
icons/text-window/constraint.png
icons/text-window/edges.png
icons/text-window/faces.png
icons/text-window/occluded-visible.png
icons/text-window/occluded-stippled.png
icons/text-window/occluded-invisible.png
icons/text-window/mesh.png
icons/text-window/normal.png
icons/text-window/outlines.png
icons/text-window/point.png
icons/text-window/shaded.png
icons/text-window/workplane.png
locales.txt
locales/en_US.po
locales/uk_UA.po
fonts/unifont.hex.gz
fonts/private/0-check-false.png
fonts/private/1-check-true.png
fonts/private/2-radio-false.png
fonts/private/3-radio-true.png
fonts/private/4-stipple-dot.png
fonts/private/5-stipple-dash-long.png
fonts/private/6-stipple-dash.png
fonts/private/7-stipple-zigzag.png
fonts/unicode.lff.gz
shaders/imesh.frag
shaders/imesh.vert
shaders/imesh_point.frag
shaders/imesh_point.vert
shaders/imesh_tex.frag
shaders/imesh_texa.frag
shaders/imesh_tex.vert
shaders/mesh.frag
shaders/mesh.vert
shaders/mesh_fill.frag
shaders/mesh_fill.vert
shaders/edge.frag
shaders/edge.vert
shaders/outline.vert
threejs/three-r76.js.gz
threejs/hammer-2.0.8.js.gz
threejs/SolveSpaceControls.js)
# Third, distribute the resources.
add_custom_target(resources
DEPENDS ${resource_list})
if(WIN32)
set_property(TARGET resources PROPERTY EXTRA_SOURCES ${rc_file})
endif()

View File

@ -1 +0,0 @@
SolveSpace!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 819 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 686 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 454 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 710 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 801 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 739 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 920 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 620 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 512 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 480 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 511 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 412 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 916 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 531 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 418 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 413 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 673 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 871 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 411 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 666 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 784 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 575 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 515 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 557 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 703 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 683 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 639 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 345 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 539 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 365 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 394 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 403 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 462 B

View File

@ -1,4 +0,0 @@
# This file lists the ISO locale codes (ISO 639-1/ISO 3166-1), Windows LCIDs,
# and human-readable names for every culture supported by SolveSpace.
en-US,0409,English (US)
uk-UA,0422,Українська

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,35 +0,0 @@
//-----------------------------------------------------------------------------
// Edge rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
const float feather = 0.5;
uniform vec4 color;
uniform float pixel;
uniform float width;
uniform float patternLen;
uniform float patternScale;
uniform sampler2D pattern;
varying vec3 fragLoc;
void main() {
// lookup distance texture
vec4 v = texture2D(pattern, vec2(fragLoc.z / patternScale, 0.0));
// decode distance value
float val = dot(v, vec4(1.0, 1.0 / 255.0, 1.0 / 65025.0, 1.0 / 160581375.0));
// calculate cap
float dist = length(vec2(val * patternScale / (patternLen * width) + abs(fragLoc.x), fragLoc.y));
// perform antialising
float k = smoothstep(1.0 - 2.0 * feather * pixel / (width + feather * pixel), 1.0, abs(dist));
// perfrom alpha-test
if(k == 1.0) discard;
// write resulting color
gl_FragColor = vec4(color.rgb, color.a * (1.0 - k));
}

View File

@ -1,41 +0,0 @@
//-----------------------------------------------------------------------------
// Edge rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
const float feather = 0.5;
attribute vec3 pos;
attribute vec3 loc;
attribute vec3 tan;
uniform mat4 modelview;
uniform mat4 projection;
uniform float width;
uniform float pixel;
varying vec3 fragLoc;
void main() {
// get camera direction from modelview matrix
vec3 dir = vec3(modelview[0].z, modelview[1].z, modelview[2].z);
// calculate line contour extension basis for constant width and caps
vec3 norm = normalize(cross(tan, dir));
norm = normalize(norm - dir * dot(dir, norm));
vec3 perp = normalize(cross(dir, norm));
// calculate line extension width considering antialiasing
float ext = width + feather * pixel;
// extend line contour
vec3 vertex = pos;
vertex += ext * loc.x * normalize(perp);
vertex += ext * loc.y * normalize(norm);
// write fragment location for calculating caps and antialiasing
fragLoc = loc;
// transform resulting vertex with modelview and projection matrices
gl_Position = projection * modelview * vec4(vertex, 1.0);
}

View File

@ -1,12 +0,0 @@
//-----------------------------------------------------------------------------
// Indexed Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec4 color;
uniform sampler2D texture;
void main() {
if(texture2D(texture, gl_FragCoord.xy / 32.0).a < 0.5) discard;
gl_FragColor = color;
}

View File

@ -1,13 +0,0 @@
//-----------------------------------------------------------------------------
// Indexed Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
attribute vec3 pos;
uniform mat4 modelview;
uniform mat4 projection;
void main() {
gl_Position = projection * modelview * vec4(pos, 1.0);
}

View File

@ -1,17 +0,0 @@
//-----------------------------------------------------------------------------
// Point rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
const float feather = 0.5;
uniform vec4 color;
uniform float pixel;
uniform float width;
varying vec2 fragLoc;
void main() {
// Rectangular points
gl_FragColor = color;
}

View File

@ -1,38 +0,0 @@
//-----------------------------------------------------------------------------
// Point rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
const float feather = 0.5;
attribute vec3 pos;
attribute vec2 loc;
uniform mat4 modelview;
uniform mat4 projection;
uniform float width;
uniform float pixel;
varying vec2 fragLoc;
void main() {
// get camera vectors from modelview matrix
vec3 u = vec3(modelview[0].x, modelview[1].x, modelview[2].x);
vec3 v = vec3(modelview[0].y, modelview[1].y, modelview[2].y);
// calculate point contour extension basis for constant width and caps
// calculate point extension width considering antialiasing
float ext = width + feather * pixel;
// extend point contour
vec3 vertex = pos;
vertex += ext * loc.x * normalize(u);
vertex += ext * loc.y * normalize(v);
// write fragment location for calculating caps and antialiasing
fragLoc = loc;
// transform resulting vertex with modelview and projection matrices
gl_Position = projection * modelview * vec4(vertex, 1.0);
}

View File

@ -1,13 +0,0 @@
//-----------------------------------------------------------------------------
// Indexed Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec4 color;
uniform sampler2D texture;
varying vec2 fragTex;
void main() {
gl_FragColor = texture2D(texture, fragTex) * color;
}

View File

@ -1,17 +0,0 @@
//-----------------------------------------------------------------------------
// Indexed Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
attribute vec3 pos;
attribute vec2 tex;
uniform mat4 modelview;
uniform mat4 projection;
varying vec2 fragTex;
void main() {
fragTex = tex;
gl_Position = projection * modelview * vec4(pos, 1.0);
}

View File

@ -1,13 +0,0 @@
//-----------------------------------------------------------------------------
// Indexed Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec4 color;
uniform sampler2D texture;
varying vec2 fragTex;
void main() {
gl_FragColor = vec4(color.rgb, color.a * texture2D(texture, fragTex).TEX_ALPHA);
}

View File

@ -1,26 +0,0 @@
//-----------------------------------------------------------------------------
// Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec3 lightDir0;
uniform vec3 lightDir1;
uniform float lightInt0;
uniform float lightInt1;
uniform float ambient;
varying vec3 fragNormal;
varying vec4 fragColor;
void main() {
vec3 result = fragColor.xyz * ambient;
vec3 normal = normalize(fragNormal);
float light0 = clamp(dot(lightDir0, normal), 0.0, 1.0) * lightInt0 * (1.0 - ambient);
result += fragColor.rgb * light0;
float light1 = clamp(dot(lightDir1, normal), 0.0, 1.0) * lightInt1 * (1.0 - ambient);
result += fragColor.rgb * light1;
gl_FragColor = vec4(result, fragColor.a);
}

View File

@ -1,21 +0,0 @@
//-----------------------------------------------------------------------------
// Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
attribute vec3 pos;
attribute vec3 nor;
attribute vec4 col;
uniform mat4 modelview;
uniform mat4 projection;
varying vec3 fragNormal;
varying vec4 fragColor;
void main() {
fragNormal = vec3(modelview * vec4(nor, 0.0));
fragColor = col;
gl_Position = projection * modelview * vec4(pos, 1.0);
}

View File

@ -1,12 +0,0 @@
//-----------------------------------------------------------------------------
// Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
uniform vec4 color;
uniform sampler2D texture;
void main() {
if(texture2D(texture, gl_FragCoord.xy / 32.0).TEX_ALPHA < 0.5) discard;
gl_FragColor = color;
}

View File

@ -1,13 +0,0 @@
//-----------------------------------------------------------------------------
// Mesh rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
attribute vec3 pos;
uniform mat4 modelview;
uniform mat4 projection;
void main() {
gl_Position = projection * modelview * vec4(pos, 1.0);
}

View File

@ -1,60 +0,0 @@
//-----------------------------------------------------------------------------
// Outline rendering shader
//
// Copyright 2016 Aleksey Egorov
//-----------------------------------------------------------------------------
const int EMPHASIZED_AND_CONTOUR = 0;
const int EMPHASIZED_WITHOUT_CONTOUR = 1;
const int CONTOUR_ONLY = 2;
const float feather = 0.5;
attribute vec3 pos;
attribute vec4 loc;
attribute vec3 tan;
attribute vec3 nol;
attribute vec3 nor;
uniform mat4 modelview;
uniform mat4 projection;
uniform float width;
uniform float pixel;
uniform int mode;
varying vec3 fragLoc;
void main() {
// get camera direction from modelview matrix
vec3 dir = vec3(modelview[0].z, modelview[1].z, modelview[2].z);
// perform outline visibility test
float ldot = dot(nol, dir);
float rdot = dot(nor, dir);
bool isOutline = (ldot > -1e-6) == (rdot < 1e-6) ||
(rdot > -1e-6) == (ldot < 1e-6);
bool isTagged = loc.w > 0.5;
float visible = float((mode == CONTOUR_ONLY && isOutline) ||
(mode == EMPHASIZED_AND_CONTOUR && (isOutline || isTagged)) ||
(mode == EMPHASIZED_WITHOUT_CONTOUR && isTagged && !isOutline));
// calculate line contour extension basis for constant width and caps
vec3 norm = normalize(cross(tan, dir));
norm = normalize(norm - dir * dot(dir, norm));
vec3 perp = normalize(cross(dir, norm));
// calculate line extension width considering antialiasing
float ext = (width + feather * pixel) * visible;
// extend line contour
vec3 vertex = pos;
vertex += ext * loc.x * normalize(perp);
vertex += ext * loc.y * normalize(norm);
// write fragment location for calculating caps and antialiasing
fragLoc = vec3(loc);
// transform resulting vertex with modelview and projection matrices
gl_Position = projection * modelview * vec4(vertex, 1.0);
}

View File

@ -1,505 +0,0 @@
window.devicePixelRatio = window.devicePixelRatio || 1;
SolvespaceCamera = function(renderWidth, renderHeight, scale, up, right, offset) {
THREE.Camera.call(this);
this.type = 'SolvespaceCamera';
this.renderWidth = renderWidth;
this.renderHeight = renderHeight;
this.zoomScale = scale; /* Avoid namespace collision w/ THREE.Object.scale */
this.up = up;
this.right = right;
this.offset = offset;
this.depthBias = 0;
this.updateProjectionMatrix();
};
SolvespaceCamera.prototype = Object.create(THREE.Camera.prototype);
SolvespaceCamera.prototype.constructor = SolvespaceCamera;
SolvespaceCamera.prototype.updateProjectionMatrix = function() {
var temp = new THREE.Matrix4();
var offset = new THREE.Matrix4().makeTranslation(this.offset.x, this.offset.y, this.offset.z);
// Convert to right handed- do up cross right instead.
var n = new THREE.Vector3().crossVectors(this.up, this.right);
var rotate = new THREE.Matrix4().makeBasis(this.right, this.up, n);
rotate.transpose();
/* FIXME: At some point we ended up using row-major.
THREE.js wants column major. Scale/depth correct unaffected b/c diagonal
matrices remain the same when transposed. makeTranslation also makes
a column-major matrix. */
/* TODO: If we want perspective, we need an additional matrix
here which will modify w for perspective divide. */
var scale = new THREE.Matrix4().makeScale(2 * this.zoomScale / this.renderWidth,
2 * this.zoomScale / this.renderHeight, this.zoomScale / 30000.0);
temp.multiply(scale);
temp.multiply(rotate);
temp.multiply(offset);
this.projectionMatrix.copy(temp);
};
SolvespaceCamera.prototype.NormalizeProjectionVectors = function() {
/* After rotating, up and right may no longer be orthogonal.
However, their cross product will produce the correct
rotated plane, and we can recover an orthogonal basis. */
var n = new THREE.Vector3().crossVectors(this.right, this.up);
this.up = new THREE.Vector3().crossVectors(n, this.right);
this.right.normalize();
this.up.normalize();
};
SolvespaceCamera.prototype.rotate = function(right, up) {
var oldRight = new THREE.Vector3().copy(this.right).normalize();
var oldUp = new THREE.Vector3().copy(this.up).normalize();
this.up.applyAxisAngle(oldRight, up);
this.right.applyAxisAngle(oldUp, right);
this.NormalizeProjectionVectors();
}
SolvespaceCamera.prototype.offsetProj = function(right, up) {
var shift = new THREE.Vector3(right * this.right.x + up * this.up.x,
right * this.right.y + up * this.up.y,
right * this.right.z + up * this.up.z);
this.offset.add(shift);
}
/* Calculate the offset in terms of up and right projection vectors
that will preserve the world coordinates of the current mouse position after
the zoom. */
SolvespaceCamera.prototype.zoomTo = function(x, y, delta) {
// Get offset components in world coordinates, in terms of up/right.
var projOffsetX = this.offset.dot(this.right);
var projOffsetY = this.offset.dot(this.up);
/* Remove offset before scaling so, that mouse position changes
proportionally to the model and independent of current offset. */
var centerRightI = x/this.zoomScale - projOffsetX;
var centerUpI = y/this.zoomScale - projOffsetY;
var zoomFactor;
/* Zoom 20% every 100 delta. */
if(delta < 0) {
zoomFactor = (-delta * 0.002 + 1);
}
else if(delta > 0) {
zoomFactor = (delta * (-1.0/600.0) + 1)
}
else {
return;
}
this.zoomScale = this.zoomScale * zoomFactor;
var centerRightF = x/this.zoomScale - projOffsetX;
var centerUpF = y/this.zoomScale - projOffsetY;
this.offset.addScaledVector(this.right, centerRightF - centerRightI);
this.offset.addScaledVector(this.up, centerUpF - centerUpI);
}
SolvespaceControls = function(object, domElement) {
var _this = this;
this.object = object;
this.domElement = ( domElement !== undefined ) ? domElement : document;
var threePan = new Hammer.Pan({event : 'threepan', pointers : 3, enable : false});
var panAfterTap = new Hammer.Pan({event : 'panaftertap', enable : false});
this.touchControls = new Hammer.Manager(domElement, {
recognizers: [
[Hammer.Pinch, { enable: true }],
[Hammer.Pan],
[Hammer.Tap],
]
});
this.touchControls.add(threePan);
this.touchControls.add(panAfterTap);
var changeEvent = {
type: 'change'
};
var startEvent = {
type: 'start'
};
var endEvent = {
type: 'end'
};
var _changed = false;
var _mouseMoved = false;
//var _touchPoints = new Array();
var _offsetPrev = new THREE.Vector2(0, 0);
var _offsetCur = new THREE.Vector2(0, 0);
var _rotatePrev = new THREE.Vector2(0, 0);
var _rotateCur = new THREE.Vector2(0, 0);
// Used during touch events.
var _rotateOrig = new THREE.Vector2(0, 0);
var _offsetOrig = new THREE.Vector2(0, 0);
var _prevScale = 1.0;
this.handleEvent = function(event) {
if (typeof this[event.type] == 'function') {
this[event.type](event);
}
}
function mousedown(event) {
event.preventDefault();
event.stopPropagation();
switch (event.button) {
case 0:
_rotateCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
_rotatePrev.copy(_rotateCur);
document.addEventListener('mousemove', mousemove, false);
document.addEventListener('mouseup', mouseup, false);
break;
case 2:
_offsetCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
_offsetPrev.copy(_offsetCur);
document.addEventListener('mousemove', mousemove, false);
document.addEventListener('mouseup', mouseup, false);
break;
default:
break;
}
}
function wheel( event ) {
event.preventDefault();
/* FIXME: Width and height might not be supported universally, but
can be calculated? */
var box = _this.domElement.getBoundingClientRect();
object.zoomTo(event.clientX - box.width/2 - box.left,
-(event.clientY - box.height/2 - box.top), event.deltaY);
_changed = true;
}
function mousemove(event) {
switch (event.button) {
case 0:
_rotateCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
var diff = new THREE.Vector2().subVectors(_rotateCur, _rotatePrev)
.multiplyScalar(1 / object.zoomScale);
object.rotate(-0.3 * Math.PI / 180 * diff.x * object.zoomScale,
-0.3 * Math.PI / 180 * diff.y * object.zoomScale);
_changed = true;
_rotatePrev.copy(_rotateCur);
break;
case 2:
_mouseMoved = true;
_offsetCur.set(event.screenX / window.devicePixelRatio,
event.screenY / window.devicePixelRatio);
var diff = new THREE.Vector2().subVectors(_offsetCur, _offsetPrev)
.multiplyScalar(1 / object.zoomScale);
object.offsetProj(diff.x, -diff.y);
_changed = true;
_offsetPrev.copy(_offsetCur)
break;
}
}
function mouseup(event) {
/* TODO: Opera mouse gestures will intercept this event, making it
possible to have multiple mousedown events consecutively without
a corresponding mouseup (so multiple viewports can be rotated/panned
simultaneously). Disable mouse gestures for now. */
event.preventDefault();
event.stopPropagation();
document.removeEventListener('mousemove', mousemove);
document.removeEventListener('mouseup', mouseup);
_this.dispatchEvent(endEvent);
}
function pan(event) {
/* neWcur - prev does not necessarily equal (cur + diff) - prev.
Floating point is not associative. */
touchDiff = new THREE.Vector2(event.deltaX, event.deltaY);
_rotateCur.addVectors(_rotateOrig, touchDiff);
incDiff = new THREE.Vector2().subVectors(_rotateCur, _rotatePrev)
.multiplyScalar(1 / object.zoomScale);
object.rotate(-0.3 * Math.PI / 180 * incDiff.x * object.zoomScale,
-0.3 * Math.PI / 180 * incDiff.y * object.zoomScale);
_changed = true;
_rotatePrev.copy(_rotateCur);
}
function panstart(event) {
/* TODO: Dynamically enable pan function? */
_rotateOrig.copy(_rotateCur);
}
function pinchstart(event) {
_prevScale = event.scale;
}
function pinch(event) {
/* FIXME: Width and height might not be supported universally, but
can be calculated? */
var box = _this.domElement.getBoundingClientRect();
/* 16.6... pixels chosen heuristically... matches my touchpad. */
if (event.scale < _prevScale) {
object.zoomTo(event.center.x - box.width/2 - box.left,
-(event.center.y - box.height/2 - box.top), 100/6.0);
_changed = true;
} else if (event.scale > _prevScale) {
object.zoomTo(event.center.x - box.width/2 - box.left,
-(event.center.y - box.height/2 - box.top), -100/6.0);
_changed = true;
}
_prevScale = event.scale;
}
/* A tap will enable panning/disable rotate. */
function tap(event) {
panAfterTap.set({enable : true});
_this.touchControls.get('pan').set({enable : false});
}
function panaftertap(event) {
touchDiff = new THREE.Vector2(event.deltaX, event.deltaY);
_offsetCur.addVectors(_offsetOrig, touchDiff);
incDiff = new THREE.Vector2().subVectors(_offsetCur, _offsetPrev)
.multiplyScalar(1 / object.zoomScale);
object.offsetProj(incDiff.x, -incDiff.y);
_changed = true;
_offsetPrev.copy(_offsetCur);
}
function panaftertapstart(event) {
_offsetOrig.copy(_offsetCur);
}
function panaftertapend(event) {
panAfterTap.set({enable : false});
_this.touchControls.get('pan').set({enable : true});
}
function contextmenu(event) {
event.preventDefault();
}
this.update = function() {
if (_changed) {
_this.dispatchEvent(changeEvent);
_changed = false;
}
}
this.domElement.addEventListener('mousedown', mousedown, false);
this.domElement.addEventListener('wheel', wheel, false);
this.domElement.addEventListener('contextmenu', contextmenu, false);
/* Hammer.on wraps addEventListener */
// Rotate
this.touchControls.on('pan', pan);
this.touchControls.on('panstart', panstart);
// Zoom
this.touchControls.on('pinch', pinch);
this.touchControls.on('pinchstart', pinchstart);
//Pan
this.touchControls.on('tap', tap);
this.touchControls.on('panaftertapstart', panaftertapstart);
this.touchControls.on('panaftertap', panaftertap);
this.touchControls.on('panaftertapend', panaftertapend);
}
SolvespaceControls.prototype = Object.create(THREE.EventDispatcher.prototype);
SolvespaceControls.prototype.constructor = SolvespaceControls;
solvespace = function(obj, params) {
var scene, edgeScene, camera, edgeCamera, renderer;
var geometry, controls, material, mesh, edges;
var width, height, scale, offset, projRight, projUp;
var directionalLightArray = [];
if (typeof params === "undefined" || !("width" in params)) {
width = window.innerWidth;
} else {
width = params.width;
}
if (typeof params === "undefined" || !("height" in params)) {
height = window.innerHeight;
} else {
height = params.height;
}
if (typeof params === "undefined" || !("scale" in params)) {
scale = 5;
} else {
scale = params.scale;
}
if (typeof params === "undefined" || !("offset" in params)) {
offset = new THREE.Vector3(0, 0, 0);
} else {
offset = params.offset;
}
if (typeof params === "undefined" || !("projUp" in params)) {
projUp = new THREE.Vector3(0, 1, -1);
} else {
projUp = params.projUp;
}
if (typeof params === "undefined" || !("projRight" in params)) {
projRight = new THREE.Vector3(1, 0, -1);
} else {
projRight = params.projRight;
}
domElement = init();
lightUpdate();
render();
return domElement;
function init() {
scene = new THREE.Scene();
edgeScene = new THREE.Scene();
camera = new SolvespaceCamera(width, height, scale, projUp, projRight, offset);
camera.NormalizeProjectionVectors();
mesh = createMesh(obj);
scene.add(mesh);
edges = createEdges(obj);
edgeScene.add(edges);
for (var i = 0; i < obj.lights.d.length; i++) {
var lightColor = new THREE.Color(obj.lights.d[i].intensity,
obj.lights.d[i].intensity, obj.lights.d[i].intensity);
var directionalLight = new THREE.DirectionalLight(lightColor, 1);
directionalLight.position.set(obj.lights.d[i].direction[0],
obj.lights.d[i].direction[1], obj.lights.d[i].direction[2]);
directionalLightArray.push(directionalLight);
scene.add(directionalLight);
}
var lightColor = new THREE.Color(obj.lights.a, obj.lights.a, obj.lights.a);
var ambientLight = new THREE.AmbientLight(lightColor.getHex());
scene.add(ambientLight);
renderer = new THREE.WebGLRenderer({ antialias: true});
renderer.setSize(width * window.devicePixelRatio, height * window.devicePixelRatio);
renderer.autoClear = false;
renderer.domElement.style =
"width: " + width + "px;" +
"height: " + height + "px;";
controls = new SolvespaceControls(camera, renderer.domElement);
controls.addEventListener("change", render);
controls.addEventListener("change", lightUpdate);
animate();
return renderer.domElement;
}
function animate() {
requestAnimationFrame(animate);
controls.update();
}
function render() {
var context = renderer.getContext();
camera.updateProjectionMatrix();
renderer.clear();
context.depthRange(0.1, 1);
renderer.render(scene, camera);
context.depthRange(0.1-(2/60000.0), 1-(2/60000.0));
renderer.render(edgeScene, camera);
}
function lightUpdate() {
var changeBasis = new THREE.Matrix4();
// The original light positions were in camera space.
// Project them into standard space using camera's basis
// vectors (up, target, and their cross product).
n = new THREE.Vector3().crossVectors(camera.up, camera.right);
changeBasis.makeBasis(camera.right, camera.up, n);
for (var i = 0; i < 2; i++) {
var newLightPos = changeBasis.applyToVector3Array(
[obj.lights.d[i].direction[0], obj.lights.d[i].direction[1],
obj.lights.d[i].direction[2]]);
directionalLightArray[i].position.set(newLightPos[0],
newLightPos[1], newLightPos[2]);
}
}
function createMesh(meshObj) {
var geometry = new THREE.Geometry();
var materialIndex = 0;
var materialList = [];
var opacitiesSeen = {};
for (var i = 0; i < meshObj.points.length; i++) {
geometry.vertices.push(new THREE.Vector3(meshObj.points[i][0],
meshObj.points[i][1], meshObj.points[i][2]));
}
for (var i = 0; i < meshObj.faces.length; i++) {
var currOpacity = ((meshObj.colors[i] & 0xFF000000) >>> 24) / 255.0;
if (opacitiesSeen[currOpacity] === undefined) {
opacitiesSeen[currOpacity] = materialIndex;
materialIndex++;
materialList.push(new THREE.MeshLambertMaterial({
vertexColors: THREE.FaceColors,
opacity: currOpacity,
transparent: true,
side: THREE.DoubleSide
}));
}
geometry.faces.push(new THREE.Face3(meshObj.faces[i][0],
meshObj.faces[i][1], meshObj.faces[i][2],
[new THREE.Vector3(meshObj.normals[i][0][0],
meshObj.normals[i][0][1], meshObj.normals[i][0][2]),
new THREE.Vector3(meshObj.normals[i][1][0],
meshObj.normals[i][1][1], meshObj.normals[i][1][2]),
new THREE.Vector3(meshObj.normals[i][2][0],
meshObj.normals[i][2][1], meshObj.normals[i][2][2])],
new THREE.Color(meshObj.colors[i] & 0x00FFFFFF),
opacitiesSeen[currOpacity]));
}
geometry.computeBoundingSphere();
return new THREE.Mesh(geometry, new THREE.MultiMaterial(materialList));
}
function createEdges(meshObj) {
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial();
for (var i = 0; i < meshObj.edges.length; i++) {
geometry.vertices.push(new THREE.Vector3(meshObj.edges[i][0][0],
meshObj.edges[i][0][1], meshObj.edges[i][0][2]),
new THREE.Vector3(meshObj.edges[i][1][0],
meshObj.edges[i][1][1], meshObj.edges[i][1][2]));
}
geometry.computeBoundingSphere();
return new THREE.LineSegments(geometry, material);
}
};

Binary file not shown.

Binary file not shown.

View File

@ -1,29 +0,0 @@
1 VERSIONINFO
FILEVERSION ${solvespace_VERSION_MAJOR},${solvespace_VERSION_MINOR},0,0
PRODUCTVERSION ${solvespace_VERSION_MAJOR},${solvespace_VERSION_MINOR},0,0
FILEFLAGSMASK 0
FILEFLAGS 0
FILEOS VOS_NT_WINDOWS32
FILETYPE VFT_APP
FILESUBTYPE 0
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "04090000"
BEGIN
VALUE "CompanyName", "The SolveSpace authors"
VALUE "ProductName", "SolveSpace"
VALUE "ProductVersion", "${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH}"
VALUE "FileDescription", "SolveSpace, a parametric 2d/3d CAD"
VALUE "FileVersion", "${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}~${solvespace_GIT_HASH}"
VALUE "OriginalFilename", "solvespace.exe"
VALUE "InternalName", "solvespace"
VALUE "LegalCopyright", "(c) 2008-2016 Jonathan Westhues and other authors"
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 0
END
END

View File

@ -1,12 +1,31 @@
# global
include(GNUInstallDirs)
# configuration
include_directories(
${OPENGL_INCLUDE_DIR}
${PNG_INCLUDE_DIRS}
${FREETYPE_INCLUDE_DIRS})
link_directories(
${PNG_LIBRARY_DIRS}
${FREETYPE_LIBRARY_DIRS})
add_definitions(
${PNG_CFLAGS_OTHER})
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/built
${CMAKE_CURRENT_BINARY_DIR})
if(SPACEWARE_FOUND)
include_directories(
${SPACEWARE_INCLUDE_DIR})
endif()
set(HAVE_SPACEWARE ${SPACEWARE_FOUND})
set(HAVE_GTK ${GTKMM_FOUND})
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
${CMAKE_CURRENT_BINARY_DIR}/config.h)
@ -14,15 +33,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
if(WIN32)
set(util_SOURCES
platform/w32util.cpp)
win32/w32util.cpp)
else()
set(util_SOURCES
platform/unixutil.cpp)
endif()
if(APPLE)
set(util_LIBRARIES
${APPKIT_LIBRARY})
unix/unixutil.cpp)
endif()
# libslvs
@ -33,12 +47,10 @@ set(libslvs_SOURCES
expr.cpp
constraint.cpp
constrainteq.cpp
system.cpp
platform/platform.cpp)
system.cpp)
set(libslvs_HEADERS
solvespace.h
platform/platform.h)
solvespace.h)
add_library(slvs SHARED
${libslvs_SOURCES}
@ -52,9 +64,6 @@ target_compile_definitions(slvs
target_include_directories(slvs
PUBLIC ${CMAKE_SOURCE_DIR}/include)
target_link_libraries(slvs
${util_LIBRARIES})
set_target_properties(slvs PROPERTIES
PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/include/slvs.h
VERSION ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}
@ -66,87 +75,195 @@ if(NOT WIN32)
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()
# solvespace dependencies
# generated files
include_directories(
${OPENGL_INCLUDE_DIR}
${ZLIB_INCLUDE_DIR}
${PNG_PNG_INCLUDE_DIR}
${FREETYPE_INCLUDE_DIRS}
${CAIRO_INCLUDE_DIRS})
# `$<TARGET_FILE:tool>` allows us to use binfmt support on Linux
# without special-casing anything; running `tool.exe` would succeed
# but unlike Windows, Linux does not have the machinery to map
# an invocation of `tool` to an executable `tool.exe` in $PATH.
if(SPACEWARE_FOUND)
include_directories(
${SPACEWARE_INCLUDE_DIR})
endif()
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)
if(OPENGL STREQUAL 2)
set(gl_SOURCES
render/gl2shader.cpp
render/rendergl2.cpp)
elseif(OPENGL STREQUAL 1)
set(gl_SOURCES
render/rendergl1.cpp)
else()
message(FATAL_ERROR "Unsupported OpenGL version ${OPENGL}")
endif()
file(GLOB icons ${CMAKE_CURRENT_SOURCE_DIR}/icons/*.png)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h
COMMAND $<TARGET_FILE:png2c>
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h
${icons}
DEPENDS png2c ${icons}
VERBATIM)
file(GLOB chars ${CMAKE_CURRENT_SOURCE_DIR}/fonts/private/*.png)
list(SORT chars)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/bitmapfont.table.h
COMMAND $<TARGET_FILE:unifont2c>
${CMAKE_CURRENT_BINARY_DIR}/generated/bitmapfont.table.h
${CMAKE_CURRENT_SOURCE_DIR}/fonts/unifont-8.0.01.hex.gz
${chars}
DEPENDS unifont2c
${CMAKE_CURRENT_SOURCE_DIR}/fonts/unifont-8.0.01.hex.gz
${chars}
VERBATIM)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/vectorfont.table.h
COMMAND $<TARGET_FILE:lff2c>
${CMAKE_CURRENT_BINARY_DIR}/generated/vectorfont.table.h
${CMAKE_CURRENT_SOURCE_DIR}/fonts/unicode.lff.gz
DEPENDS lff2c
${CMAKE_CURRENT_SOURCE_DIR}/fonts/unicode.lff.gz
VERBATIM)
set(generated_HEADERS
${CMAKE_CURRENT_BINARY_DIR}/generated/vectorfont.table.h
${CMAKE_CURRENT_BINARY_DIR}/generated/bitmapfont.table.h
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h)
set(generated_SOURCES
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp)
# platform dependencies
if(WIN32)
set(platform_SOURCES
platform/w32main.cpp
${gl_SOURCES})
win32/w32main.cpp
win32/resource.rc)
set(platform_LIBRARIES
comctl32
${SPACEWARE_LIBRARIES})
comctl32)
elseif(APPLE)
add_compile_options(
add_definitions(
-fobjc-arc)
set(platform_SOURCES
platform/cocoamain.mm
render/rendergl.cpp
${gl_SOURCES})
cocoa/cocoamain.mm
unix/gloffscreen.cpp)
set(platform_XIBS
cocoa/MainMenu.xib
cocoa/SaveFormatAccessory.xib)
set(platform_ICONS
cocoa/AppIcon.iconset)
set(platform_RESOURCES
unix/solvespace-48x48.png)
set(platform_BUNDLED_LIBS
${PNG_LIBRARIES}
${FREETYPE_LIBRARIES})
else()
set(platform_SOURCES
platform/gtkmain.cpp
render/rendergl.cpp
${gl_SOURCES})
set(platform_LIBRARIES
${SPACEWARE_LIBRARIES})
${APPKIT_LIBRARY})
elseif(HAVE_GTK)
include_directories(
${GTKMM_INCLUDE_DIRS}
${JSONC_INCLUDE_DIRS}
${FONTCONFIG_INCLUDE_DIRS}
${GLEW_INCLUDE_DIRS})
foreach(pkg_config_lib GTKMM JSONC FONTCONFIG)
include_directories(${${pkg_config_lib}_INCLUDE_DIRS})
link_directories(${${pkg_config_lib}_LIBRARY_DIRS})
list(APPEND platform_LIBRARIES ${${pkg_config_lib}_LIBRARIES})
endforeach()
link_directories(
${GTKMM_LIBRARY_DIRS}
${JSONC_LIBRARY_DIRS}
${FONTCONFIG_LIBRARY_DIRS}
${GLEW_LIBRARY_DIRS})
add_definitions(
${GTKMM_CFLAGS_OTHER}
${JSONC_CFLAGS_OTHER}
${FONTCONFIG_CFLAGS_OTHER}
${GLEW_CFLAGS_OTHER})
set(platform_SOURCES
gtk/gtkmain.cpp
unix/gloffscreen.cpp)
set(platform_LIBRARIES
${GTKMM_LIBRARIES}
${JSONC_LIBRARIES}
${FONTCONFIG_LIBRARIES}
${GLEW_LIBRARIES})
endif()
set(every_platform_SOURCES
platform/w32main.cpp
platform/gtkmain.cpp
platform/cocoamain.mm)
set(platform_BUNDLED_RESOURCES)
# solvespace library
foreach(xib ${platform_XIBS})
get_filename_component(nib ${xib} NAME_WE)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${xib})
set(target ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources/${nib}.nib)
list(APPEND platform_BUNDLED_RESOURCES ${target})
set(solvespace_core_HEADERS
add_custom_command(
OUTPUT ${target}
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources
COMMAND ibtool --errors --warnings --notices
--output-format human-readable-text --compile
${target} ${source}
COMMENT "Building Interface Builder file ${xib}"
DEPENDS ${xib}
VERBATIM)
endforeach()
foreach(icon ${platform_ICONS})
get_filename_component(name ${icon} NAME_WE)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${icon})
set(target ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources/${name}.icns)
list(APPEND platform_BUNDLED_RESOURCES ${target})
add_custom_command(
OUTPUT ${target}
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources
COMMAND iconutil -c icns -o ${target} ${source}
COMMENT "Building icon set ${icon}"
DEPENDS ${source}
VERBATIM)
endforeach()
foreach(res ${platform_RESOURCES})
get_filename_component(name ${res} NAME)
set(source ${CMAKE_CURRENT_SOURCE_DIR}/${res})
set(target ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources/${name})
list(APPEND platform_BUNDLED_RESOURCES ${target})
add_custom_command(
OUTPUT ${target}
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources
COMMAND ${CMAKE_COMMAND} -E copy ${source} ${target}
COMMENT "Copying resource file ${res}"
DEPENDS ${res}
VERBATIM)
endforeach()
foreach(lib ${platform_BUNDLED_LIBS})
get_filename_component(name ${lib} NAME)
set(target ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/MacOS/${name})
list(APPEND platform_BUNDLED_RESOURCES ${target})
add_custom_command(
OUTPUT ${target}
COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/solvespace.app/Contents/Resources
COMMAND ${CMAKE_COMMAND} -E copy ${lib} ${target}
COMMENT "Bundling shared library ${lib}"
DEPENDS ${lib}
VERBATIM)
endforeach()
# solvespace executable
set(solvespace_HEADERS
config.h
dsc.h
expr.h
polygon.h
sketch.h
solvespace.h
ui.h
platform/platform.h
render/render.h
render/gl2shader.h
srf/surface.h)
set(solvespace_core_SOURCES
set(solvespace_SOURCES
bsp.cpp
clipboard.cpp
confscreen.cpp
@ -163,6 +280,7 @@ set(solvespace_core_SOURCES
expr.cpp
file.cpp
generate.cpp
glhelper.cpp
graphicswin.cpp
group.cpp
groupmesh.cpp
@ -170,10 +288,9 @@ set(solvespace_core_SOURCES
mesh.cpp
modify.cpp
mouse.cpp
polyline.cpp
polygon.cpp
resource.cpp
request.cpp
solvespace.cpp
style.cpp
system.cpp
textscreens.cpp
@ -183,9 +300,6 @@ set(solvespace_core_SOURCES
undoredo.cpp
util.cpp
view.cpp
platform/platform.cpp
render/render.cpp
render/render2d.cpp
srf/boolean.cpp
srf/curve.cpp
srf/merge.cpp
@ -195,213 +309,98 @@ set(solvespace_core_SOURCES
srf/surfinter.cpp
srf/triangulate.cpp)
set(solvespace_core_gl_SOURCES
solvespace.cpp)
add_library(solvespace-core STATIC
add_executable(solvespace WIN32 MACOSX_BUNDLE
${libslvs_HEADERS}
${libslvs_SOURCES}
${util_SOURCES}
${solvespace_core_HEADERS}
${solvespace_core_SOURCES})
target_link_libraries(solvespace-core
dxfrw
${util_LIBRARIES}
${ZLIB_LIBRARY}
${PNG_LIBRARY}
${FREETYPE_LIBRARY}
${Backtrace_LIBRARIES})
target_compile_options(solvespace-core
PRIVATE ${COVERAGE_FLAGS})
# solvespace translations
if(HAVE_GETTEXT)
set(inputs
${solvespace_core_SOURCES}
${solvespace_core_HEADERS}
${every_platform_SOURCES})
set(templ_po ${CMAKE_CURRENT_BINARY_DIR}/../res/messages.po)
set(output_pot ${CMAKE_CURRENT_SOURCE_DIR}/../res/messages.pot)
set(output_po ${CMAKE_CURRENT_SOURCE_DIR}/../res/locales/en_US.po)
file(GLOB locale_pos ${CMAKE_CURRENT_SOURCE_DIR}/../res/locales/*.po)
string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
gen_output_pot ${output_pot})
string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
gen_output_po ${output_po})
string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
gen_locale_pos "${locale_pos}")
add_custom_command(
OUTPUT ${gen_output_pot}
COMMAND ${XGETTEXT}
--language=C++
--keyword --keyword=_ --keyword=N_ --keyword=C_:2,1c --keyword=CN_:2,1c
--force-po --width=100 --sort-by-file
--package-name=SolveSpace
--package-version=${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}
"--copyright-holder=the PACKAGE authors"
--msgid-bugs-address=whitequark@whitequark.org
--from-code=utf-8 --output=${gen_output_pot} ${inputs}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${gen_output_pot} ${output_pot}
DEPENDS ${inputs}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Extracting translations"
VERBATIM)
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/../res/locales)
# en_US is a bit special; we pre-fill the msgstrs from msgids, instead of (as would normally
# happen) leaving them empty.
add_custom_command(
OUTPUT ${gen_output_po}
COMMAND ${MSGINIT}
--locale=en_US --no-translator
--output=${templ_po} --input=${gen_output_pot}
COMMAND ${MSGMERGE}
--force-po --no-fuzzy-matching
--output=${gen_output_po} ${output_po} ${templ_po}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${gen_output_po} ${output_po}
DEPENDS ${gen_output_pot}
COMMENT "Updating en_US translations"
VERBATIM)
foreach(locale_po ${locale_pos})
string(REPLACE ${CMAKE_SOURCE_DIR} ${CMAKE_BINARY_DIR}
gen_locale_po ${locale_po})
get_filename_component(locale_name ${locale_po} NAME_WE)
if(locale_name STREQUAL "en_US")
continue()
endif()
add_custom_command(
OUTPUT ${gen_locale_po}
COMMAND ${MSGMERGE}
--no-fuzzy-matching
--output=${gen_locale_po} ${locale_po} ${gen_output_pot}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${gen_locale_po} ${locale_po}
DEPENDS ${gen_output_pot}
COMMENT "Updating ${locale_name} translations"
VERBATIM)
endforeach()
add_custom_target(solvespace-translations
DEPENDS ${gen_output_pot} ${gen_output_po} ${gen_locale_pos})
endif()
# solvespace graphical executable
if(ENABLE_GUI)
add_executable(solvespace WIN32 MACOSX_BUNDLE
${solvespace_core_gl_SOURCES}
${platform_SOURCES}
$<TARGET_PROPERTY:resources,EXTRA_SOURCES>)
${platform_BUNDLED_RESOURCES}
${generated_SOURCES}
${generated_HEADERS}
${solvespace_HEADERS}
${solvespace_SOURCES})
add_dependencies(solvespace
resources)
target_link_libraries(solvespace
solvespace-core
target_link_libraries(solvespace
dxfrw
${OPENGL_LIBRARIES}
${platform_LIBRARIES}
${COVERAGE_LIBRARY})
${PNG_LIBRARIES}
${ZLIB_LIBRARIES}
${FREETYPE_LIBRARIES}
${platform_LIBRARIES})
if(MSVC)
if(WIN32 AND NOT MINGW)
set_target_properties(solvespace PROPERTIES
LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /INCREMENTAL:NO /OPT:REF")
endif()
LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO")
endif()
# solvespace headless library
set(headless_SOURCES
platform/headless.cpp
render/rendercairo.cpp)
add_library(solvespace-headless STATIC EXCLUDE_FROM_ALL
${solvespace_core_gl_SOURCES}
${headless_SOURCES})
target_compile_definitions(solvespace-headless
PRIVATE -DHEADLESS)
target_include_directories(solvespace-headless
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
target_link_libraries(solvespace-headless
solvespace-core
${CAIRO_LIBRARIES})
target_compile_options(solvespace-headless
PRIVATE ${COVERAGE_FLAGS})
# solvespace command-line executable
add_executable(solvespace-cli
platform/climain.cpp
$<TARGET_PROPERTY:resources,EXTRA_SOURCES>)
target_link_libraries(solvespace-cli
solvespace-core
solvespace-headless)
add_dependencies(solvespace-cli
resources)
if(MSVC)
set_target_properties(solvespace-cli PROPERTIES
LINK_FLAGS "/INCREMENTAL:NO /OPT:REF")
if(SPACEWARE_FOUND)
target_link_libraries(solvespace
${SPACEWARE_LIBRARIES})
endif()
# solvespace unix package
if(NOT (WIN32 OR APPLE))
if(ENABLE_GUI)
install(TARGETS solvespace
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
install(TARGETS solvespace-cli
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
# solvespace macOS package
if(APPLE)
set(bundle solvespace)
set(bundle_bin ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app/Contents/MacOS)
add_custom_command(TARGET solvespace POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:solvespace-cli> ${bundle_bin}
COMMENT "Bundling executable solvespace-cli"
VERBATIM)
set(fixups)
foreach(lib ${platform_BUNDLED_LIBS})
get_filename_component(name ${lib} NAME)
execute_process(COMMAND otool -D ${lib}
OUTPUT_VARIABLE canonical_lib OUTPUT_STRIP_TRAILING_WHITESPACE)
string(REGEX REPLACE "^.+:\n" "" canonical_lib ${canonical_lib})
add_custom_command(TARGET ${bundle} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy ${lib} ${bundle_bin}/${name}
add_custom_command(TARGET solvespace POST_BUILD
COMMAND install_name_tool -change ${canonical_lib} @executable_path/${name}
$<TARGET_FILE:${bundle}>
COMMAND install_name_tool -change ${canonical_lib} @executable_path/${name}
$<TARGET_FILE:solvespace-cli>
COMMENT "Bundling shared library ${lib}"
$<TARGET_FILE:solvespace>
COMMENT "Fixing up rpath for dylib ${name}"
VERBATIM)
endforeach()
add_custom_command(OUTPUT ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg
COMMAND ${CMAKE_COMMAND} -E remove ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg
COMMAND hdiutil create -srcfolder ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app
${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg
set(bundle solvespace)
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${bundle}.dmg
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/${bundle}.dmg
COMMAND hdiutil create -srcfolder ${CMAKE_CURRENT_BINARY_DIR}/${bundle}.app
${CMAKE_BINARY_DIR}/${bundle}.dmg
DEPENDS $<TARGET_FILE:${bundle}>
COMMENT "Building ${bundle}.dmg"
VERBATIM)
add_custom_target(${bundle}-dmg ALL
DEPENDS ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg)
DEPENDS ${CMAKE_BINARY_DIR}/${bundle}.dmg)
endif()
if(NOT WIN32)
install(TARGETS solvespace
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
BUNDLE DESTINATION .)
endif()
install(FILES unix/solvespace.desktop
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/applications)
foreach(SIZE 16x16 24x24 32x32 48x48)
install(FILES unix/solvespace-${SIZE}.png
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/apps
RENAME solvespace.png)
install(FILES unix/solvespace-${SIZE}.png
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/icons/hicolor/${SIZE}/mimetypes
RENAME application.x-solvespace.png)
endforeach()
foreach(SIZE 16x16 24x24 32x32 48x48)
install(FILES unix/solvespace-${SIZE}.xpm
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pixmaps/)
endforeach()
# valgrind
add_custom_target(solvespace-valgrind
valgrind
--tool=memcheck
--verbose
--track-fds=yes
--log-file=vg.%p.out
--num-callers=50
--error-limit=no
--read-var-info=yes
--leak-check=full
--leak-resolution=high
--show-reachable=yes
--track-origins=yes
--malloc-fill=0xac
--free-fill=0xde
$<TARGET_FILE:solvespace>)

Some files were not shown because too many files have changed in this diff Show More