Compare commits
71 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
7c1ca46076 | ||
![]() |
9c30f7858f | ||
![]() |
6802a12a52 | ||
![]() |
99d6f1f5b5 | ||
![]() |
ece7630624 | ||
![]() |
82746b6171 | ||
![]() |
74d8621f53 | ||
![]() |
0b2fc34de1 | ||
![]() |
25febd82ed | ||
![]() |
d809d4122f | ||
![]() |
2e1c7a6701 | ||
![]() |
4fad67d721 | ||
![]() |
a2c97fcd46 | ||
![]() |
c4ad073d1b | ||
![]() |
0f3879e37c | ||
![]() |
05d9c0fab9 | ||
![]() |
bc43365eff | ||
![]() |
8a96ca894c | ||
![]() |
dde6030533 | ||
![]() |
b8abf698c9 | ||
![]() |
f6eb079d41 | ||
![]() |
adca3cd253 | ||
![]() |
33c3fd5fce | ||
![]() |
f2007326b4 | ||
![]() |
02b7e24812 | ||
![]() |
1a5047550d | ||
![]() |
5e28b35f2b | ||
![]() |
19e77e7866 | ||
![]() |
e1d6dac87a | ||
![]() |
4c022f8d79 | ||
![]() |
bbd106044b | ||
![]() |
359b13bd62 | ||
![]() |
513f55f7d4 | ||
![]() |
bbf8610c57 | ||
![]() |
dc0eed8322 | ||
![]() |
ca150aeda1 | ||
![]() |
4d2c773ee6 | ||
![]() |
0b997e4c17 | ||
![]() |
bfef091ac9 | ||
![]() |
bcd43c7c24 | ||
![]() |
4fae03d105 | ||
![]() |
c0f5a31401 | ||
![]() |
5af252eaf1 | ||
![]() |
61904280a3 | ||
![]() |
51f3d7e438 | ||
![]() |
561b2797e8 | ||
![]() |
5525303946 | ||
![]() |
7f6c774bf5 | ||
![]() |
fd255364b3 | ||
![]() |
478973eb3c | ||
![]() |
8fd572d449 | ||
![]() |
7b82ff68e1 | ||
![]() |
7fc2033c9b | ||
![]() |
ff9a8284b4 | ||
![]() |
c25e4c8973 | ||
![]() |
dce906465d | ||
![]() |
53e5e0eb90 | ||
![]() |
ce656ef7c6 | ||
![]() |
fb2f32eb72 | ||
![]() |
917a7b93ce | ||
![]() |
c838158e04 | ||
![]() |
17f7a7b467 | ||
![]() |
e78edd9b94 | ||
![]() |
d13e29cdaf | ||
![]() |
daee939714 | ||
![]() |
44c152ccd0 | ||
![]() |
dfc218c452 | ||
![]() |
9fc60a0c00 | ||
![]() |
f3e36f593b | ||
![]() |
b62375b554 | ||
![]() |
056d3bfa30 |
30
.gitattributes
vendored
|
@ -1,10 +1,22 @@
|
||||||
|
# .gitattributes for SolveSpace
|
||||||
|
|
||||||
|
# Set default behaviour, in case users don't have core.autocrlf set.
|
||||||
* text=auto
|
* text=auto
|
||||||
*.cpp text
|
|
||||||
*.h text
|
# Explicitly declare text files we want to always be normalized and converted
|
||||||
*.txt text
|
# to native line endings on checkout.
|
||||||
*.gz binary
|
*.cpp text
|
||||||
*.ico binary
|
*.h text
|
||||||
*.jpg binary
|
*.txt text
|
||||||
*.lib binary
|
|
||||||
*.png binary
|
# Declare files that will always have CRLF line endings on checkout.
|
||||||
*.slvs binary
|
*.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
|
||||||
|
|
||||||
|
# end .gitattributes
|
||||||
|
|
18
.github/ISSUE_TEMPLATE.md
vendored
|
@ -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
|
@ -1,8 +1,6 @@
|
||||||
/CMakeCache.txt
|
/CMakeCache.txt
|
||||||
/build*/
|
/build*/
|
||||||
/test/**/*.diff.*
|
*.trace # OpenGL apitrace files
|
||||||
/test/**/*.curr.*
|
|
||||||
*.trace
|
|
||||||
/debian/tmp/
|
/debian/tmp/
|
||||||
/debian/*.log
|
/debian/*.log
|
||||||
/debian/*.substvars
|
/debian/*.substvars
|
||||||
|
@ -12,4 +10,3 @@
|
||||||
/debian/libslvs1/
|
/debian/libslvs1/
|
||||||
/debian/libslvs1-dev/
|
/debian/libslvs1-dev/
|
||||||
/obj-*/
|
/obj-*/
|
||||||
/*.slvs
|
|
||||||
|
|
13
.gitmodules
vendored
|
@ -5,18 +5,9 @@
|
||||||
[submodule "extlib/libpng"]
|
[submodule "extlib/libpng"]
|
||||||
path = extlib/libpng
|
path = extlib/libpng
|
||||||
url = https://github.com/glennrp/libpng
|
url = https://github.com/glennrp/libpng
|
||||||
[submodule "extlib/freetype"]
|
[submodule "extlib/libfreetype"]
|
||||||
path = extlib/freetype
|
path = extlib/libfreetype
|
||||||
url = http://git.sv.nongnu.org/r/freetype/freetype2.git
|
url = http://git.sv.nongnu.org/r/freetype/freetype2.git
|
||||||
[submodule "extlib/libdxfrw"]
|
[submodule "extlib/libdxfrw"]
|
||||||
path = extlib/libdxfrw
|
path = extlib/libdxfrw
|
||||||
url = https://github.com/solvespace/libdxfrw.git
|
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
|
|
||||||
|
|
|
@ -4,7 +4,6 @@ os:
|
||||||
- osx
|
- osx
|
||||||
sudo: required
|
sudo: required
|
||||||
dist: trusty
|
dist: trusty
|
||||||
osx_image: xcode8.2
|
|
||||||
install:
|
install:
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis/install-debian.sh; fi
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./.travis/install-debian.sh; fi
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/install-macos.sh; fi
|
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then ./.travis/install-macos.sh; fi
|
||||||
|
@ -21,9 +20,3 @@ deploy:
|
||||||
repo: solvespace/solvespace
|
repo: solvespace/solvespace
|
||||||
tags: true
|
tags: true
|
||||||
condition: "$TRAVIS_OS_NAME == osx"
|
condition: "$TRAVIS_OS_NAME == osx"
|
||||||
notifications:
|
|
||||||
irc:
|
|
||||||
channels:
|
|
||||||
- "chat.freenode.net#solvespace"
|
|
||||||
use_notice: true
|
|
||||||
skip_join: true
|
|
||||||
|
|
|
@ -4,10 +4,5 @@ if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=D
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
# We build without the GUI until Travis updates to an Ubuntu version with GTK 3.22.
|
cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE
|
||||||
cmake .. -DCMAKE_C_COMPILER=clang-3.9 -DCMAKE_CXX_COMPILER=clang++-3.9 \
|
|
||||||
-DCMAKE_BUILD_TYPE=$BUILD_TYPE \
|
|
||||||
-DENABLE_GUI=OFF \
|
|
||||||
-DENABLE_SANITIZERS=ON
|
|
||||||
make VERBOSE=1
|
make VERBOSE=1
|
||||||
make test_solvespace
|
|
||||||
|
|
|
@ -5,5 +5,10 @@ if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=D
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 -DCMAKE_BUILD_TYPE=$BUILD_TYPE ..
|
cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 -DCMAKE_BUILD_TYPE=$BUILD_TYPE ..
|
||||||
make VERBOSE=1
|
if ! make VERBOSE=1; then
|
||||||
make test_solvespace
|
echo "Sigh, transient build failure. Retrying..."
|
||||||
|
if ! make VERBOSE=1; then
|
||||||
|
echo "Okay, this is probably an actual bug."
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
|
@ -1,10 +1,7 @@
|
||||||
#!/bin/sh -xe
|
#!/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 update -qq
|
||||||
sudo apt-get install -q -y \
|
sudo apt-get install -q -y \
|
||||||
cmake cmake-data libpng12-dev zlib1g-dev libjson0-dev libfontconfig1-dev \
|
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 \
|
libgtkmm-2.4-dev libpangomm-1.4-dev libgl1-mesa-dev libglu-dev libglew-dev \
|
||||||
libfreetype6-dev dpkg-dev libstdc++-5-dev clang-3.9 clang++-3.9 lcov
|
libfreetype6-dev dpkg-dev
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
#!/bin/sh -xe
|
#!/bin/sh -xe
|
||||||
|
|
||||||
brew update
|
brew update
|
||||||
brew install freetype cairo
|
|
||||||
|
|
76
CHANGELOG.md
|
@ -1,82 +1,6 @@
|
||||||
Changelog
|
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
|
2.3
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|
367
CMakeLists.txt
|
@ -1,12 +1,5 @@
|
||||||
# cmake configuration
|
# 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_minimum_required(VERSION 3.1.0 FATAL_ERROR)
|
||||||
cmake_policy(VERSION 3.1.0)
|
cmake_policy(VERSION 3.1.0)
|
||||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
|
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 11)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
set(CMAKE_CXX_STANDARD_REQUIRED YES)
|
||||||
|
|
||||||
|
include(CheckIncludeFile)
|
||||||
|
|
||||||
# for /MT on MSVC
|
# for /MT on MSVC
|
||||||
set(CMAKE_USER_MAKE_RULES_OVERRIDE
|
set(CMAKE_USER_MAKE_RULES_OVERRIDE
|
||||||
"${CMAKE_SOURCE_DIR}/cmake/c_flag_overrides.cmake")
|
"${CMAKE_SOURCE_DIR}/cmake/c_flag_overrides.cmake")
|
||||||
|
@ -30,218 +25,29 @@ include(GetGitCommitHash)
|
||||||
# set(GIT_COMMIT_HASH 0000000000000000000000000000000000000000)
|
# set(GIT_COMMIT_HASH 0000000000000000000000000000000000000000)
|
||||||
|
|
||||||
project(solvespace)
|
project(solvespace)
|
||||||
set(solvespace_VERSION_MAJOR 3)
|
set(solvespace_VERSION_MAJOR 2)
|
||||||
set(solvespace_VERSION_MINOR 0)
|
set(solvespace_VERSION_MINOR 3)
|
||||||
string(SUBSTRING "${GIT_COMMIT_HASH}" 0 8 solvespace_GIT_HASH)
|
string(SUBSTRING "${GIT_COMMIT_HASH}" 0 8 solvespace_GIT_HASH)
|
||||||
|
|
||||||
set(ENABLE_GUI ON CACHE BOOL
|
if(NOT WIN32 AND NOT APPLE)
|
||||||
"Whether the graphical interface is enabled (command line interface always is)")
|
set(GUI gtk2 CACHE STRING "GUI toolkit to use (one of: gtk2 gtk3)")
|
||||||
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")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
|
# compiler
|
||||||
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
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_definitions(
|
add_definitions(
|
||||||
-D_CRT_SECURE_NO_DEPRECATE
|
-D_CRT_SECURE_NO_DEPRECATE
|
||||||
-D_CRT_SECURE_NO_WARNINGS
|
-D_CRT_SECURE_NO_WARNINGS
|
||||||
-D_SCL_SECURE_NO_WARNINGS
|
-D_SCL_SECURE_NO_WARNINGS
|
||||||
-DWINVER=0x0601
|
-D_WIN32_WINNT=0x500
|
||||||
-D_WIN32_WINNT=0x0601
|
|
||||||
-D_WIN32_IE=_WIN32_WINNT
|
-D_WIN32_IE=_WIN32_WINNT
|
||||||
-DISOLATION_AWARE_ENABLED
|
-DISOLATION_AWARE_ENABLED
|
||||||
-DWIN32
|
-DWIN32
|
||||||
-DWIN32_LEAN_AND_MEAN
|
-DWIN32_LEAN_AND_MEAN
|
||||||
-DUNICODE
|
-DUNICODE
|
||||||
-D_UNICODE
|
|
||||||
-DNOMINMAX
|
-DNOMINMAX
|
||||||
-D_USE_MATH_DEFINES)
|
-D_UNICODE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
|
@ -249,56 +55,141 @@ if(MSVC)
|
||||||
# they have their own __inline; this breaks `static inline` functions.
|
# they have their own __inline; this breaks `static inline` functions.
|
||||||
# We do not want to care and so we fix this with a definition.
|
# We do not want to care and so we fix this with a definition.
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /Dinline=__inline")
|
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()
|
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")
|
set(WARNING_FLAGS "-Wall -Wextra -Wno-unused-parameter")
|
||||||
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
|
||||||
set(WARNING_FLAGS "${WARNING_FLAGS} -Wfloat-conversion")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 ${WARNING_FLAGS}")
|
||||||
endif()
|
|
||||||
# We rely on these -Werror flags.
|
|
||||||
set(WARNING_FLAGS "${WARNING_FLAGS} -Werror=switch")
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${WARNING_FLAGS}")
|
if(MINGW)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS}")
|
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)
|
if(WIN32)
|
||||||
set(CMAKE_RC_FLAGS "${CMAKE_RC_FLAGS} -l0")
|
# Configure Freetype first. If done later, it will notice that
|
||||||
endif()
|
# 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 FREETYPE_FOUND)
|
||||||
if(NOT (CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR
|
message(STATUS "Using in-tree libfreetype")
|
||||||
CMAKE_CXX_COMPILER_ID MATCHES "Clang"))
|
|
||||||
message(FATAL_ERROR "Code coverage is only available on GCC and Clang")
|
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()
|
endif()
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
|
find_package(ZLIB)
|
||||||
message(FATAL_ERROR "Code coverage produces reliable results only on Debug builds")
|
|
||||||
|
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()
|
endif()
|
||||||
|
|
||||||
# With -fexceptions, every call becomes a branch. While technically accurate,
|
find_package(PNG)
|
||||||
# this is not useful for us.
|
|
||||||
set(COVERAGE_FLAGS -fno-exceptions --coverage)
|
if(NOT PNG_FOUND)
|
||||||
set(COVERAGE_LIBRARY --coverage)
|
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()
|
endif()
|
||||||
|
|
||||||
# components
|
# components
|
||||||
|
|
||||||
add_subdirectory(res)
|
add_subdirectory(tools)
|
||||||
add_subdirectory(src)
|
add_subdirectory(src)
|
||||||
add_subdirectory(exposed)
|
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()
|
|
||||||
|
|
250
CONTRIBUTING.md
|
@ -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
|
|
76
README.md
|
@ -9,10 +9,10 @@ This repository contains the source code of [SolveSpace][], a parametric
|
||||||
Installation
|
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
|
Binary packages for Mac OS X and Debian derivatives are available
|
||||||
[GitHub releases][rel].
|
via [GitHub releases][rel].
|
||||||
|
|
||||||
[rel]: https://github.com/solvespace/solvespace/releases
|
[rel]: https://github.com/solvespace/solvespace/releases
|
||||||
|
|
||||||
|
@ -25,14 +25,14 @@ Building on Linux
|
||||||
|
|
||||||
### Building for Linux
|
### Building for Linux
|
||||||
|
|
||||||
You will need CMake, zlib, libpng, cairo, freetype. To build the GUI, you will need
|
You will need CMake, libpng, zlib, json-c, fontconfig, freetype, gtkmm 2.4,
|
||||||
fontconfig, gtkmm 3.0 (version 3.16 or later), pangomm 1.4, OpenGL and OpenGL GLU, and
|
pangomm 1.4, OpenGL, OpenGL GLU and OpenGL GLEW, and optionally, the Space Navigator
|
||||||
optionally, the Space Navigator client library.
|
client library.
|
||||||
On a Debian derivative (e.g. Ubuntu) these can be installed with:
|
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 libpng12-dev libjson-c-dev libfreetype6-dev \
|
||||||
apt-get install libjson-c-dev libfontconfig1-dev libgtkmm-3.0-dev libpangomm-1.4-dev \
|
libfontconfig1-dev libgtkmm-2.4-dev libpangomm-1.4-dev \
|
||||||
libgl-dev libglu-dev libspnav-dev
|
libgl-dev libglu-dev libglew-dev libspnav-dev cmake
|
||||||
|
|
||||||
Before building, check out the necessary submodules:
|
Before building, check out the necessary submodules:
|
||||||
|
|
||||||
|
@ -42,20 +42,19 @@ After that, build SolveSpace as following:
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
cmake ..
|
||||||
make
|
make
|
||||||
sudo make install
|
sudo make install
|
||||||
|
|
||||||
The graphical interface is built as `build/bin/solvespace`, and the command-line interface
|
A fully functional port to GTK3 is available, but not recommended
|
||||||
is built as `build/bin/solvespace-cli`. It is possible to build only the command-line interface
|
for use due to bugs in this toolkit.
|
||||||
by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation.
|
|
||||||
|
|
||||||
### Building for Windows
|
### 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:
|
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:
|
Before building, check out the necessary submodules:
|
||||||
|
|
||||||
|
@ -65,31 +64,27 @@ After that, build 32-bit SolveSpace as following:
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake \
|
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake ..
|
||||||
-DCMAKE_BUILD_TYPE=Release
|
make solvespace
|
||||||
make
|
|
||||||
|
|
||||||
Or, build 64-bit SolveSpace as following:
|
Or, build 64-bit SolveSpace as following:
|
||||||
|
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake \
|
cmake -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw64.cmake ..
|
||||||
-DCMAKE_BUILD_TYPE=Release
|
make solvespace
|
||||||
make
|
|
||||||
|
|
||||||
The graphical interface is built as `build/bin/solvespace.exe`, and the command-line interface
|
The application is built as `build/src/solvespace.exe`.
|
||||||
is built as `build/bin/solvespace-cli.exe`.
|
|
||||||
|
|
||||||
Space Navigator support will not be available.
|
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
|
You will need XCode tools, CMake, libpng and Freetype. Assuming you use
|
||||||
will need cairo. Assuming you use
|
|
||||||
[homebrew][], these can be installed with:
|
[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.
|
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
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
cmake ..
|
||||||
make
|
make
|
||||||
|
|
||||||
The application is built in `build/bin/solvespace.app`, the graphical interface executable
|
The app bundle is built in `build/src/solvespace.app`.
|
||||||
is `build/bin/solvespace.app/Contents/MacOS/solvespace`, and the command-line interface executable
|
|
||||||
is `build/bin/solvespace.app/Contents/MacOS/solvespace-cli`.
|
|
||||||
|
|
||||||
[homebrew]: http://brew.sh/
|
[homebrew]: http://brew.sh/
|
||||||
|
|
||||||
Building on Windows
|
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
|
Check out the git submodules. Create a directory `build` in
|
||||||
the source tree and point cmake-gui to the source tree and that directory.
|
the source tree and point cmake-gui to the source tree and that directory.
|
||||||
Press "Configure" and "Generate", then open `build\solvespace.sln` with
|
Press "Configure" and "Generate", then open `build\solvespace.sln` with
|
||||||
Visual C++ and build it.
|
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
|
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
|
`%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
|
git submodule update --init
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=Release
|
cmake .. -G "NMake Makefiles"
|
||||||
nmake
|
nmake
|
||||||
|
|
||||||
### Building with MinGW
|
### MSVC build
|
||||||
|
|
||||||
It is also possible to build SolveSpace using [MinGW][mingw], though
|
It is also possible to build SolveSpace using [MinGW][mingw], though
|
||||||
Space Navigator support will be disabled.
|
Space Navigator support will be disabled.
|
||||||
|
@ -145,19 +138,12 @@ in bash:
|
||||||
git submodule update --init
|
git submodule update --init
|
||||||
mkdir build
|
mkdir build
|
||||||
cd build
|
cd build
|
||||||
cmake .. -DCMAKE_BUILD_TYPE=Release
|
cmake ..
|
||||||
make
|
make
|
||||||
|
|
||||||
[gitwin]: https://git-scm.com/download/win
|
|
||||||
[cmakewin]: http://www.cmake.org/download/#latest
|
[cmakewin]: http://www.cmake.org/download/#latest
|
||||||
[mingw]: http://www.mingw.org/
|
[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
|
License
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
|
20
appveyor.yml
|
@ -1,4 +1,4 @@
|
||||||
version: 3.0.{build}
|
version: 2.2.{build}
|
||||||
clone_depth: 1
|
clone_depth: 1
|
||||||
before_build:
|
before_build:
|
||||||
- git submodule update --init
|
- git submodule update --init
|
||||||
|
@ -6,25 +6,23 @@ before_build:
|
||||||
- cd build
|
- cd build
|
||||||
- set tag=x%APPVEYOR_REPO_TAG_NAME%
|
- set tag=x%APPVEYOR_REPO_TAG_NAME%
|
||||||
- if %tag:~,2% == xv (set BUILD_TYPE=RelWithDebInfo) else (set BUILD_TYPE=Debug)
|
- 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:
|
build_script:
|
||||||
- msbuild "src\solvespace.vcxproj" /verbosity:minimal /property:Configuration=%BUILD_TYPE% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll"
|
- 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:
|
artifacts:
|
||||||
- path: build\bin\%BUILD_TYPE%\solvespace.exe
|
- path: build\src\Debug\solvespace.exe
|
||||||
name: solvespace.exe
|
name: solvespace.exe
|
||||||
- path: build\bin\%BUILD_TYPE%\solvespace-cli.exe
|
- path: build\src\Debug\solvespace.pdb
|
||||||
name: solvespace-cli.exe
|
name: solvespace.pdb
|
||||||
- path: build\bin\%BUILD_TYPE%\solvespace.pdb
|
- path: build\src\RelWithDebInfo\solvespace.exe
|
||||||
|
name: solvespace.exe
|
||||||
|
- path: build\src\RelWithDebInfo\solvespace.pdb
|
||||||
name: solvespace.pdb
|
name: solvespace.pdb
|
||||||
deploy:
|
deploy:
|
||||||
- provider: GitHub
|
- provider: GitHub
|
||||||
auth_token:
|
auth_token:
|
||||||
secure: P9/pf2nM+jlWKe7pCjMp41HycBNP/+5AsmE/TETrDUoBOa/9WFHelqdVFrbRn9IC
|
secure: P9/pf2nM+jlWKe7pCjMp41HycBNP/+5AsmE/TETrDUoBOa/9WFHelqdVFrbRn9IC
|
||||||
description: ""
|
description: ""
|
||||||
artifact: solvespace.exe,solvespace-cli.exe,solvespace.pdb
|
artifact: solvespace.exe
|
||||||
on:
|
on:
|
||||||
appveyor_repo_tag: true
|
appveyor_repo_tag: true
|
||||||
|
|
|
@ -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)
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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()
|
|
|
@ -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()
|
|
|
@ -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()
|
|
|
@ -13,11 +13,11 @@
|
||||||
<key>CFBundlePackageType</key>
|
<key>CFBundlePackageType</key>
|
||||||
<string>APPL</string>
|
<string>APPL</string>
|
||||||
<key>CFBundleVersion</key>
|
<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>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}</string>
|
<string>${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}</string>
|
||||||
<key>NSHumanReadableCopyright</key>
|
<key>NSHumanReadableCopyright</key>
|
||||||
<string>© 2008-2016 Jonathan Westhues and other authors</string>
|
<string>© 2008-2015 Jonathan Westhues and other authors</string>
|
||||||
<key>NSPrincipalClass</key>
|
<key>NSPrincipalClass</key>
|
||||||
<string>NSApplication</string>
|
<string>NSApplication</string>
|
||||||
<key>NSMainNibFile</key>
|
<key>NSMainNibFile</key>
|
||||||
|
|
|
@ -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_C_COMPILER ${TRIPLE}-gcc)
|
||||||
set(CMAKE_CXX_COMPILER ${TRIPLE}-g++)
|
SET(CMAKE_CXX_COMPILER ${TRIPLE}-g++)
|
||||||
set(CMAKE_RC_COMPILER ${TRIPLE}-windres)
|
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_PROGRAM NEVER)
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
|
||||||
set(ENV{PKG_CONFIG_LIBDIR} /usr/${TRIPLE}/lib/pkgconfig)
|
|
||||||
|
|
|
@ -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_C_COMPILER ${TRIPLE}-gcc)
|
||||||
set(CMAKE_CXX_COMPILER ${TRIPLE}-g++)
|
SET(CMAKE_CXX_COMPILER ${TRIPLE}-g++)
|
||||||
set(CMAKE_RC_COMPILER ${TRIPLE}-windres)
|
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_PROGRAM NEVER)
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
|
||||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
|
||||||
|
|
||||||
set(ENV{PKG_CONFIG_LIBDIR} /usr/${TRIPLE}/lib/pkgconfig)
|
|
||||||
|
|
|
@ -5,13 +5,18 @@
|
||||||
*
|
*
|
||||||
* Copyright 2008-2013 Jonathan Westhues.
|
* Copyright 2008-2013 Jonathan Westhues.
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
# include <config.h>
|
||||||
|
#endif
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
# include <windows.h>
|
# include <windows.h>
|
||||||
#endif
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#ifdef HAVE_STDINT_H
|
||||||
|
# include <stdint.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <slvs.h>
|
#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
|
* An example of a constraint in 3d. We create a single group, with some
|
||||||
* entities and constraints.
|
* entities and constraints.
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
void Example3d()
|
void Example3d(void)
|
||||||
{
|
{
|
||||||
/* This will contain a single group, which will arbitrarily number 1. */
|
/* This will contain a single group, which will arbitrarily number 1. */
|
||||||
Slvs_hGroup g = 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
|
* along the reference frame's xy plane. In a second group, we create some
|
||||||
* entities in that group and dimension them.
|
* entities in that group and dimension them.
|
||||||
*---------------------------------------------------------------------------*/
|
*---------------------------------------------------------------------------*/
|
||||||
void Example2d()
|
void Example2d(void)
|
||||||
{
|
{
|
||||||
Slvs_hGroup g;
|
Slvs_hGroup g;
|
||||||
double qw, qx, qy, qz;
|
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.param = CheckMalloc(50*sizeof(sys.param[0]));
|
||||||
sys.entity = CheckMalloc(50*sizeof(sys.entity[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
|
|
@ -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()
|
|
|
@ -1 +0,0 @@
|
||||||
SolveSpace!
|
|
Before Width: | Height: | Size: 819 B |
Before Width: | Height: | Size: 686 B |
Before Width: | Height: | Size: 454 B |
Before Width: | Height: | Size: 710 B |
Before Width: | Height: | Size: 801 B |
Before Width: | Height: | Size: 739 B |
Before Width: | Height: | Size: 920 B |
Before Width: | Height: | Size: 620 B |
Before Width: | Height: | Size: 418 B |
Before Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 512 B |
Before Width: | Height: | Size: 401 B |
Before Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 511 B |
Before Width: | Height: | Size: 412 B |
Before Width: | Height: | Size: 916 B |
Before Width: | Height: | Size: 531 B |
Before Width: | Height: | Size: 427 B |
Before Width: | Height: | Size: 394 B |
Before Width: | Height: | Size: 596 B |
Before Width: | Height: | Size: 418 B |
Before Width: | Height: | Size: 413 B |
Before Width: | Height: | Size: 673 B |
Before Width: | Height: | Size: 597 B |
Before Width: | Height: | Size: 507 B |
Before Width: | Height: | Size: 871 B |
Before Width: | Height: | Size: 411 B |
Before Width: | Height: | Size: 515 B |
Before Width: | Height: | Size: 666 B |
Before Width: | Height: | Size: 784 B |
Before Width: | Height: | Size: 575 B |
Before Width: | Height: | Size: 515 B |
Before Width: | Height: | Size: 557 B |
Before Width: | Height: | Size: 703 B |
Before Width: | Height: | Size: 683 B |
Before Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 639 B |
Before Width: | Height: | Size: 345 B |
Before Width: | Height: | Size: 539 B |
Before Width: | Height: | Size: 365 B |
Before Width: | Height: | Size: 733 B |
Before Width: | Height: | Size: 394 B |
Before Width: | Height: | Size: 403 B |
Before Width: | Height: | Size: 462 B |
|
@ -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,Українська
|
|
1812
res/locales/en_US.po
1650
res/locales/uk_UA.po
1613
res/messages.pot
|
@ -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));
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
|
@ -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);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -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
|
|
|
@ -1,12 +1,31 @@
|
||||||
|
# global
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
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(
|
include_directories(
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}
|
${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
|
${CMAKE_CURRENT_SOURCE_DIR}/built
|
||||||
${CMAKE_CURRENT_BINARY_DIR})
|
${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
|
if(SPACEWARE_FOUND)
|
||||||
|
include_directories(
|
||||||
|
${SPACEWARE_INCLUDE_DIR})
|
||||||
|
endif()
|
||||||
|
|
||||||
set(HAVE_SPACEWARE ${SPACEWARE_FOUND})
|
set(HAVE_SPACEWARE ${SPACEWARE_FOUND})
|
||||||
|
set(HAVE_GTK ${GTKMM_FOUND})
|
||||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
${CMAKE_CURRENT_BINARY_DIR}/config.h)
|
||||||
|
|
||||||
|
@ -14,15 +33,10 @@ configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(util_SOURCES
|
set(util_SOURCES
|
||||||
platform/w32util.cpp)
|
win32/w32util.cpp)
|
||||||
else()
|
else()
|
||||||
set(util_SOURCES
|
set(util_SOURCES
|
||||||
platform/unixutil.cpp)
|
unix/unixutil.cpp)
|
||||||
endif()
|
|
||||||
|
|
||||||
if(APPLE)
|
|
||||||
set(util_LIBRARIES
|
|
||||||
${APPKIT_LIBRARY})
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# libslvs
|
# libslvs
|
||||||
|
@ -33,12 +47,10 @@ set(libslvs_SOURCES
|
||||||
expr.cpp
|
expr.cpp
|
||||||
constraint.cpp
|
constraint.cpp
|
||||||
constrainteq.cpp
|
constrainteq.cpp
|
||||||
system.cpp
|
system.cpp)
|
||||||
platform/platform.cpp)
|
|
||||||
|
|
||||||
set(libslvs_HEADERS
|
set(libslvs_HEADERS
|
||||||
solvespace.h
|
solvespace.h)
|
||||||
platform/platform.h)
|
|
||||||
|
|
||||||
add_library(slvs SHARED
|
add_library(slvs SHARED
|
||||||
${libslvs_SOURCES}
|
${libslvs_SOURCES}
|
||||||
|
@ -52,9 +64,6 @@ target_compile_definitions(slvs
|
||||||
target_include_directories(slvs
|
target_include_directories(slvs
|
||||||
PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
PUBLIC ${CMAKE_SOURCE_DIR}/include)
|
||||||
|
|
||||||
target_link_libraries(slvs
|
|
||||||
${util_LIBRARIES})
|
|
||||||
|
|
||||||
set_target_properties(slvs PROPERTIES
|
set_target_properties(slvs PROPERTIES
|
||||||
PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/include/slvs.h
|
PUBLIC_HEADER ${CMAKE_SOURCE_DIR}/include/slvs.h
|
||||||
VERSION ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}
|
VERSION ${solvespace_VERSION_MAJOR}.${solvespace_VERSION_MINOR}
|
||||||
|
@ -66,87 +75,195 @@ if(NOT WIN32)
|
||||||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# solvespace dependencies
|
# generated files
|
||||||
|
|
||||||
include_directories(
|
# `$<TARGET_FILE:tool>` allows us to use binfmt support on Linux
|
||||||
${OPENGL_INCLUDE_DIR}
|
# without special-casing anything; running `tool.exe` would succeed
|
||||||
${ZLIB_INCLUDE_DIR}
|
# but unlike Windows, Linux does not have the machinery to map
|
||||||
${PNG_PNG_INCLUDE_DIR}
|
# an invocation of `tool` to an executable `tool.exe` in $PATH.
|
||||||
${FREETYPE_INCLUDE_DIRS}
|
|
||||||
${CAIRO_INCLUDE_DIRS})
|
|
||||||
|
|
||||||
if(SPACEWARE_FOUND)
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated)
|
||||||
include_directories(
|
|
||||||
${SPACEWARE_INCLUDE_DIR})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(OPENGL STREQUAL 2)
|
file(GLOB icons ${CMAKE_CURRENT_SOURCE_DIR}/icons/*.png)
|
||||||
set(gl_SOURCES
|
add_custom_command(
|
||||||
render/gl2shader.cpp
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp
|
||||||
render/rendergl2.cpp)
|
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h
|
||||||
elseif(OPENGL STREQUAL 1)
|
COMMAND $<TARGET_FILE:png2c>
|
||||||
set(gl_SOURCES
|
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.cpp
|
||||||
render/rendergl1.cpp)
|
${CMAKE_CURRENT_BINARY_DIR}/generated/icons.h
|
||||||
else()
|
${icons}
|
||||||
message(FATAL_ERROR "Unsupported OpenGL version ${OPENGL}")
|
DEPENDS png2c ${icons}
|
||||||
endif()
|
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)
|
if(WIN32)
|
||||||
set(platform_SOURCES
|
set(platform_SOURCES
|
||||||
platform/w32main.cpp
|
win32/w32main.cpp
|
||||||
${gl_SOURCES})
|
win32/resource.rc)
|
||||||
|
|
||||||
set(platform_LIBRARIES
|
set(platform_LIBRARIES
|
||||||
comctl32
|
comctl32)
|
||||||
${SPACEWARE_LIBRARIES})
|
|
||||||
elseif(APPLE)
|
elseif(APPLE)
|
||||||
add_compile_options(
|
add_definitions(
|
||||||
-fobjc-arc)
|
-fobjc-arc)
|
||||||
|
|
||||||
set(platform_SOURCES
|
set(platform_SOURCES
|
||||||
platform/cocoamain.mm
|
cocoa/cocoamain.mm
|
||||||
render/rendergl.cpp
|
unix/gloffscreen.cpp)
|
||||||
${gl_SOURCES})
|
|
||||||
|
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
|
set(platform_BUNDLED_LIBS
|
||||||
${PNG_LIBRARIES}
|
${PNG_LIBRARIES}
|
||||||
${FREETYPE_LIBRARIES})
|
${FREETYPE_LIBRARIES})
|
||||||
else()
|
|
||||||
set(platform_SOURCES
|
|
||||||
platform/gtkmain.cpp
|
|
||||||
render/rendergl.cpp
|
|
||||||
${gl_SOURCES})
|
|
||||||
|
|
||||||
set(platform_LIBRARIES
|
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)
|
link_directories(
|
||||||
include_directories(${${pkg_config_lib}_INCLUDE_DIRS})
|
${GTKMM_LIBRARY_DIRS}
|
||||||
link_directories(${${pkg_config_lib}_LIBRARY_DIRS})
|
${JSONC_LIBRARY_DIRS}
|
||||||
list(APPEND platform_LIBRARIES ${${pkg_config_lib}_LIBRARIES})
|
${FONTCONFIG_LIBRARY_DIRS}
|
||||||
endforeach()
|
${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()
|
endif()
|
||||||
|
|
||||||
set(every_platform_SOURCES
|
set(platform_BUNDLED_RESOURCES)
|
||||||
platform/w32main.cpp
|
|
||||||
platform/gtkmain.cpp
|
|
||||||
platform/cocoamain.mm)
|
|
||||||
|
|
||||||
# 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
|
dsc.h
|
||||||
expr.h
|
expr.h
|
||||||
polygon.h
|
polygon.h
|
||||||
sketch.h
|
sketch.h
|
||||||
solvespace.h
|
solvespace.h
|
||||||
ui.h
|
ui.h
|
||||||
platform/platform.h
|
|
||||||
render/render.h
|
|
||||||
render/gl2shader.h
|
|
||||||
srf/surface.h)
|
srf/surface.h)
|
||||||
|
|
||||||
set(solvespace_core_SOURCES
|
set(solvespace_SOURCES
|
||||||
bsp.cpp
|
bsp.cpp
|
||||||
clipboard.cpp
|
clipboard.cpp
|
||||||
confscreen.cpp
|
confscreen.cpp
|
||||||
|
@ -163,6 +280,7 @@ set(solvespace_core_SOURCES
|
||||||
expr.cpp
|
expr.cpp
|
||||||
file.cpp
|
file.cpp
|
||||||
generate.cpp
|
generate.cpp
|
||||||
|
glhelper.cpp
|
||||||
graphicswin.cpp
|
graphicswin.cpp
|
||||||
group.cpp
|
group.cpp
|
||||||
groupmesh.cpp
|
groupmesh.cpp
|
||||||
|
@ -170,10 +288,9 @@ set(solvespace_core_SOURCES
|
||||||
mesh.cpp
|
mesh.cpp
|
||||||
modify.cpp
|
modify.cpp
|
||||||
mouse.cpp
|
mouse.cpp
|
||||||
polyline.cpp
|
|
||||||
polygon.cpp
|
polygon.cpp
|
||||||
resource.cpp
|
|
||||||
request.cpp
|
request.cpp
|
||||||
|
solvespace.cpp
|
||||||
style.cpp
|
style.cpp
|
||||||
system.cpp
|
system.cpp
|
||||||
textscreens.cpp
|
textscreens.cpp
|
||||||
|
@ -183,9 +300,6 @@ set(solvespace_core_SOURCES
|
||||||
undoredo.cpp
|
undoredo.cpp
|
||||||
util.cpp
|
util.cpp
|
||||||
view.cpp
|
view.cpp
|
||||||
platform/platform.cpp
|
|
||||||
render/render.cpp
|
|
||||||
render/render2d.cpp
|
|
||||||
srf/boolean.cpp
|
srf/boolean.cpp
|
||||||
srf/curve.cpp
|
srf/curve.cpp
|
||||||
srf/merge.cpp
|
srf/merge.cpp
|
||||||
|
@ -195,213 +309,98 @@ set(solvespace_core_SOURCES
|
||||||
srf/surfinter.cpp
|
srf/surfinter.cpp
|
||||||
srf/triangulate.cpp)
|
srf/triangulate.cpp)
|
||||||
|
|
||||||
set(solvespace_core_gl_SOURCES
|
add_executable(solvespace WIN32 MACOSX_BUNDLE
|
||||||
solvespace.cpp)
|
${libslvs_HEADERS}
|
||||||
|
${libslvs_SOURCES}
|
||||||
add_library(solvespace-core STATIC
|
|
||||||
${util_SOURCES}
|
${util_SOURCES}
|
||||||
${solvespace_core_HEADERS}
|
${platform_SOURCES}
|
||||||
${solvespace_core_SOURCES})
|
${platform_BUNDLED_RESOURCES}
|
||||||
|
${generated_SOURCES}
|
||||||
|
${generated_HEADERS}
|
||||||
|
${solvespace_HEADERS}
|
||||||
|
${solvespace_SOURCES})
|
||||||
|
|
||||||
target_link_libraries(solvespace-core
|
target_link_libraries(solvespace
|
||||||
dxfrw
|
dxfrw
|
||||||
${util_LIBRARIES}
|
${OPENGL_LIBRARIES}
|
||||||
${ZLIB_LIBRARY}
|
${PNG_LIBRARIES}
|
||||||
${PNG_LIBRARY}
|
${ZLIB_LIBRARIES}
|
||||||
${FREETYPE_LIBRARY}
|
${FREETYPE_LIBRARIES}
|
||||||
${Backtrace_LIBRARIES})
|
${platform_LIBRARIES})
|
||||||
|
|
||||||
target_compile_options(solvespace-core
|
if(WIN32 AND NOT MINGW)
|
||||||
PRIVATE ${COVERAGE_FLAGS})
|
set_target_properties(solvespace PROPERTIES
|
||||||
|
LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO")
|
||||||
# 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()
|
endif()
|
||||||
|
|
||||||
# solvespace graphical executable
|
if(SPACEWARE_FOUND)
|
||||||
|
|
||||||
if(ENABLE_GUI)
|
|
||||||
add_executable(solvespace WIN32 MACOSX_BUNDLE
|
|
||||||
${solvespace_core_gl_SOURCES}
|
|
||||||
${platform_SOURCES}
|
|
||||||
$<TARGET_PROPERTY:resources,EXTRA_SOURCES>)
|
|
||||||
|
|
||||||
add_dependencies(solvespace
|
|
||||||
resources)
|
|
||||||
|
|
||||||
target_link_libraries(solvespace
|
target_link_libraries(solvespace
|
||||||
solvespace-core
|
${SPACEWARE_LIBRARIES})
|
||||||
${OPENGL_LIBRARIES}
|
|
||||||
${platform_LIBRARIES}
|
|
||||||
${COVERAGE_LIBRARY})
|
|
||||||
|
|
||||||
if(MSVC)
|
|
||||||
set_target_properties(solvespace PROPERTIES
|
|
||||||
LINK_FLAGS "/MANIFEST:NO /SAFESEH:NO /INCREMENTAL:NO /OPT:REF")
|
|
||||||
endif()
|
|
||||||
endif()
|
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")
|
|
||||||
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)
|
if(APPLE)
|
||||||
set(bundle solvespace)
|
set(fixups)
|
||||||
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)
|
|
||||||
|
|
||||||
foreach(lib ${platform_BUNDLED_LIBS})
|
foreach(lib ${platform_BUNDLED_LIBS})
|
||||||
get_filename_component(name ${lib} NAME)
|
get_filename_component(name ${lib} NAME)
|
||||||
|
|
||||||
execute_process(COMMAND otool -D ${lib}
|
execute_process(COMMAND otool -D ${lib}
|
||||||
OUTPUT_VARIABLE canonical_lib OUTPUT_STRIP_TRAILING_WHITESPACE)
|
OUTPUT_VARIABLE canonical_lib OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||||
string(REGEX REPLACE "^.+:\n" "" canonical_lib ${canonical_lib})
|
string(REGEX REPLACE "^.+:\n" "" canonical_lib ${canonical_lib})
|
||||||
add_custom_command(TARGET ${bundle} POST_BUILD
|
add_custom_command(TARGET solvespace POST_BUILD
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy ${lib} ${bundle_bin}/${name}
|
|
||||||
COMMAND install_name_tool -change ${canonical_lib} @executable_path/${name}
|
COMMAND install_name_tool -change ${canonical_lib} @executable_path/${name}
|
||||||
$<TARGET_FILE:${bundle}>
|
$<TARGET_FILE:solvespace>
|
||||||
COMMAND install_name_tool -change ${canonical_lib} @executable_path/${name}
|
COMMENT "Fixing up rpath for dylib ${name}"
|
||||||
$<TARGET_FILE:solvespace-cli>
|
|
||||||
COMMENT "Bundling shared library ${lib}"
|
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
endforeach()
|
endforeach()
|
||||||
|
|
||||||
add_custom_command(OUTPUT ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg
|
set(bundle solvespace)
|
||||||
COMMAND ${CMAKE_COMMAND} -E remove ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg
|
add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/${bundle}.dmg
|
||||||
COMMAND hdiutil create -srcfolder ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app
|
COMMAND ${CMAKE_COMMAND} -E remove ${CMAKE_BINARY_DIR}/${bundle}.dmg
|
||||||
${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg
|
COMMAND hdiutil create -srcfolder ${CMAKE_CURRENT_BINARY_DIR}/${bundle}.app
|
||||||
|
${CMAKE_BINARY_DIR}/${bundle}.dmg
|
||||||
DEPENDS $<TARGET_FILE:${bundle}>
|
DEPENDS $<TARGET_FILE:${bundle}>
|
||||||
COMMENT "Building ${bundle}.dmg"
|
COMMENT "Building ${bundle}.dmg"
|
||||||
VERBATIM)
|
VERBATIM)
|
||||||
|
|
||||||
add_custom_target(${bundle}-dmg ALL
|
add_custom_target(${bundle}-dmg ALL
|
||||||
DEPENDS ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg)
|
DEPENDS ${CMAKE_BINARY_DIR}/${bundle}.dmg)
|
||||||
endif()
|
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>)
|
||||||
|
|