From d72eba8039c52f5e8d3ab36ec2d8a7598dfd578b Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Fri, 9 Oct 2020 15:10:22 -0400 Subject: [PATCH 001/113] Create intersection curves from existing ones. When a plane coinsides with a seam we need to copy that trim curve. The existing curve belongs to the original shell surfaces and an intersection is otherwise not found. Fixes #540. --- src/srf/surface.h | 1 + src/srf/surfinter.cpp | 50 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/srf/surface.h b/src/srf/surface.h index ba4414a2..393be4aa 100644 --- a/src/srf/surface.h +++ b/src/srf/surface.h @@ -342,6 +342,7 @@ public: void GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const; bool CoincidentWithPlane(Vector n, double d) const; bool CoincidentWith(SSurface *ss, bool sameNormal) const; + bool ContainsPlaneCurve(SCurve *sc) const; bool IsExtrusion(SBezier *of, Vector *along) const; bool IsCylinder(Vector *axis, Vector *center, double *r, Vector *start, Vector *finish) const; diff --git a/src/srf/surfinter.cpp b/src/srf/surfinter.cpp index ddcbad23..1e4fb396 100644 --- a/src/srf/surfinter.cpp +++ b/src/srf/surfinter.cpp @@ -313,6 +313,38 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, inters.Clear(); lv.Clear(); } else { + if((degm == 1 && degn == 1) || (b->degm == 1 && b->degn == 1)) { + // we should only be here if just one surface is a plane because the + // plane-plane case was already handled above. Need to check the other + // nonplanar surface for trim curves that lie in the plane and are not + // already trimming both surfaces. This happens when we cut a Lathe shell + // on one of the seams for example. + // This also seems necessary to merge some coincident surfaces. + SSurface *splane, *sext; + SShell *shext; + if(degm == 1 && degn == 1) { // this and other checks assume coplanar ctrl pts. + splane = this; + sext = b; + shext = agnstB; + } else { + splane = b; + sext = this; + shext = agnstA; + } + SCurve *sc; + for(sc = shext->curve.First(); sc; sc = shext->curve.NextAfter(sc)) { + if(sc->source == SCurve::Source::INTERSECTION) continue; + if(!sc->isExact) continue; + if((sc->surfA != sext->h) && (sc->surfB != sext->h)) continue; + // we have a curve belonging to the curved surface and not the plane. + // does it lie completely in the plane? + if(splane->ContainsPlaneCurve(sc)) { + SBezier bezier = sc->exact; + AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into); + } + } + } + // Try intersecting the surfaces numerically, by a marching algorithm. // First, we find all the intersections between a surface and the // boundary of the other surface. @@ -505,6 +537,24 @@ bool SSurface::CoincidentWithPlane(Vector n, double d) const { return true; } +//----------------------------------------------------------------------------- +// Does a planar surface contain a curve? Does the curve lie completely in plane? +//----------------------------------------------------------------------------- +bool SSurface::ContainsPlaneCurve(SCurve *sc) const { + if(degm != 1 || degn != 1) return false; + if(!sc->isExact) return false; // we don't handle those (yet?) + + Vector p = ctrl[0][0]; + Vector n = NormalAt(0, 0).WithMagnitude(1); + double d = n.Dot(p); + + // check all control points on the curve + for(int i=0; i<= sc->exact.deg; i++) { + if(fabs(n.Dot(sc->exact.ctrl[i]) - d) > LENGTH_EPS) return false; + } + return true; +} + //----------------------------------------------------------------------------- // In our shell, find all surfaces that are coincident with the prototype // surface (with same or opposite normal, as specified), and copy all of From 3ea8ebfaf57ab061f18f2838f6599d10a339d59b Mon Sep 17 00:00:00 2001 From: ruevs Date: Fri, 16 Oct 2020 16:54:21 +0300 Subject: [PATCH 002/113] Win32: Fix "File|Open...", "Save" and "Save As" when a command line argument is used. `GetSaveFileNameA` `OPENFILENAMEA` does not like UNC ( "\\\\?\\C:\\..." ) file prefixes in `lpstrFile`. Work around it by not `Expand`-ing parameters passed on the command line too early. The only user visible change is that "File|Open Recent" will show items as they were passed instead of expanded to full path for example: "..\..\NURBSTests\Intersection2.slvs" Fixes: https://github.com/solvespace/solvespace/issues/622 --- src/platform/entrygui.cpp | 2 +- src/platform/platform.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/entrygui.cpp b/src/platform/entrygui.cpp index 30fd4438..397831ac 100644 --- a/src/platform/entrygui.cpp +++ b/src/platform/entrygui.cpp @@ -21,7 +21,7 @@ int main(int argc, char** argv) { dbp("Only the first file passed on command line will be opened."); } - SS.Load(Platform::Path::From(args.back()).Expand(/*fromCurrentDirectory=*/true)); + SS.Load(Platform::Path::From(args.back())); } Platform::RunGui(); diff --git a/src/platform/platform.cpp b/src/platform/platform.cpp index a0809821..f025c861 100644 --- a/src/platform/platform.cpp +++ b/src/platform/platform.cpp @@ -401,7 +401,7 @@ FILE *OpenFile(const Platform::Path &filename, const char *mode) { ssassert(filename.raw.length() == strlen(filename.raw.c_str()), "Unexpected null byte in middle of a path"); #if defined(WIN32) - return _wfopen(Widen(filename.Expand().raw).c_str(), Widen(mode).c_str()); + return _wfopen(Widen(filename.Expand(/*fromCurrentDirectory=*/true).raw).c_str(), Widen(mode).c_str()); #else return fopen(filename.raw.c_str(), mode); #endif From 6558cb9ebe3eae7a64d427002a1755ee4fcce222 Mon Sep 17 00:00:00 2001 From: ruevs Date: Fri, 16 Oct 2020 23:35:40 +0300 Subject: [PATCH 003/113] Fix crash in solvespace-cli `window` is a `nullptr` with guinone.cpp - avoid dereferencing it. Fixes: https://github.com/solvespace/solvespace/issues/567 --- src/draw.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/draw.cpp b/src/draw.cpp index db2f33e5..1dabd75b 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -305,9 +305,16 @@ void GraphicsWindow::GroupSelection() { Camera GraphicsWindow::GetCamera() const { Camera camera = {}; - window->GetContentSize(&camera.width, &camera.height); - camera.pixelRatio = window->GetDevicePixelRatio(); - camera.gridFit = (window->GetDevicePixelRatio() == 1); + if(window) { + window->GetContentSize(&camera.width, &camera.height); + camera.pixelRatio = window->GetDevicePixelRatio(); + camera.gridFit = (window->GetDevicePixelRatio() == 1); + } else { // solvespace-cli + camera.width = 297.0; // A4? Whatever... + camera.height = 210.0; + camera.pixelRatio = 1.0; + camera.gridFit = camera.pixelRatio == 1.0; + } camera.offset = offset; camera.projUp = projUp; camera.projRight = projRight; From 0288c0a98b139dfb57acf99d6303d44a75fa5929 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Fri, 16 Oct 2020 21:11:42 +0200 Subject: [PATCH 004/113] Travis: add windows target Mimic the appveyor cfg without the artifact deployment. Also upgrade to Visual Studio 2017/v141 toolset. --- .travis.yml | 5 +++++ .travis/build-windows.sh | 16 ++++++++++++++++ .travis/install-windows.sh | 3 +++ 3 files changed, 24 insertions(+) create mode 100755 .travis/build-windows.sh create mode 100755 .travis/install-windows.sh diff --git a/.travis.yml b/.travis.yml index 1c90474b..76f5ef1a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,6 +12,11 @@ jobs: dist: bionic install: ./.travis/install-debian.sh script: ./.travis/build-debian.sh + - stage: test + name: "Windows Visual Studio 2017" + os: windows + install: ./.travis/install-windows.sh + script: ./.travis/build-windows.sh - stage: deploy name: "OSX" os: osx diff --git a/.travis/build-windows.sh b/.travis/build-windows.sh new file mode 100755 index 00000000..e7502e6b --- /dev/null +++ b/.travis/build-windows.sh @@ -0,0 +1,16 @@ +#!/bin/sh -xe + +MSBUILD_PATH="c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin" +export PATH=$MSBUILD_PATH:$PATH + +if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=Debug; fi + +mkdir build +cd build +cmake .. -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=$BUILD_TYPE + +MSBuild.exe "src/solvespace.vcxproj" +MSBuild.exe "src/solvespace-cli.vcxproj" +MSBuild.exe "test/solvespace-testsuite.vcxproj" + +bin/$BUILD_TYPE/solvespace-testsuite.exe diff --git a/.travis/install-windows.sh b/.travis/install-windows.sh new file mode 100755 index 00000000..738d67dd --- /dev/null +++ b/.travis/install-windows.sh @@ -0,0 +1,3 @@ +#!/bin/sh -xe + +git submodule update --init From 91684fe6f4a44e11dfd75a88d87d30e5f8f043bf Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sat, 17 Oct 2020 17:05:10 +0200 Subject: [PATCH 005/113] Add macOS travis config, fix issue in CMakeLists.txt causing macOS build to break --- .travis.yml | 36 +++++++++++++++++++++-- .travis/build-macos.sh | 2 +- .travis/install-macos.sh | 4 +-- .travis/sign-macos.sh | 63 ++++++++++++++++++++++++++++++++++++++++ CMakeLists.txt | 9 +++--- 5 files changed, 102 insertions(+), 12 deletions(-) create mode 100644 .travis/sign-macos.sh diff --git a/.travis.yml b/.travis.yml index 76f5ef1a..792d7c26 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,6 +6,36 @@ jobs: - stage: deploy name: Snap arm64 include: + - stage: test + name: macOS + os: osx + osx_image: xcode11.2 + install: "./.travis/install-macos.sh" + script: "./.travis/build-macos.sh" + deploy: + provider: releases + api_key: + secure: 3PAqaWQTsHKKuItoZnIm7KJkCE/IHjrGtQMvdjabmVr9F/X3nuRYCdhvlSwU6z1N/UIiUso5jDc/qYOxbBnDfXiu2HihW9USaPLLrQoMQHxqAr62Hks1ESMo/rCrYPdqzFBdEbkuP6GqwxXyUDhnvDwXzmqSzhcotEUwiuRnvcTnlf29WT4D0Gz8gEwIkkiMN9msH8mabvd5SkmaBFd+Z7elXn6DpTxZSHRhX8QCW7681pdq424H4qbArIB+I9ccHbS+Cbh8kKBcd/hNX1tFK4SdaUYyywonrWhgPHZzZ8oj0dRGvY19+ZnTJisQmUjiJQDglUeJ+p5RIcUHOnUjM/Io/jWdA78W9Vn0gpjX5F2iBfm0UcSyXwf9dXDFnm9pOCnFjJ1Cv4wxWlRvUXcQxv9hb00cyHYEhzPJRmNUu/DF45caOHYvLADwd0d3UPrfblXpjTPxpDxHHl3QuXQLeERiGsZOg5N6kg0coUO0p60JDdDHrxjiLXDsD8Oe9FMxIfZd6y+hfsQWLFSDyWqod+F4rmROsRdsJaAC8EliRCxBp/jLY8/ntFLAKCwRP57z46wXWe65yOENOErSDZvbrPZbNOm7whX4GsTozfE1dy+3lcsOq+jth3LbyQHuDRNW2/oKtWfOeQ1H+8W+WP1GRpyIOHzClSgMe/k3n7E60Ls= + skip_cleanup: true + file: build/bin/SolveSpace.dmg + on: + repo: vespakoen/solvespace + tags: true + - stage: deploy + name: macOS + os: osx + osx_image: xcode11.2 + install: "./.travis/install-macos.sh" + script: "./.travis/build-macos.sh && ./.travis/sign-macos.sh" + deploy: + provider: releases + api_key: + secure: 3PAqaWQTsHKKuItoZnIm7KJkCE/IHjrGtQMvdjabmVr9F/X3nuRYCdhvlSwU6z1N/UIiUso5jDc/qYOxbBnDfXiu2HihW9USaPLLrQoMQHxqAr62Hks1ESMo/rCrYPdqzFBdEbkuP6GqwxXyUDhnvDwXzmqSzhcotEUwiuRnvcTnlf29WT4D0Gz8gEwIkkiMN9msH8mabvd5SkmaBFd+Z7elXn6DpTxZSHRhX8QCW7681pdq424H4qbArIB+I9ccHbS+Cbh8kKBcd/hNX1tFK4SdaUYyywonrWhgPHZzZ8oj0dRGvY19+ZnTJisQmUjiJQDglUeJ+p5RIcUHOnUjM/Io/jWdA78W9Vn0gpjX5F2iBfm0UcSyXwf9dXDFnm9pOCnFjJ1Cv4wxWlRvUXcQxv9hb00cyHYEhzPJRmNUu/DF45caOHYvLADwd0d3UPrfblXpjTPxpDxHHl3QuXQLeERiGsZOg5N6kg0coUO0p60JDdDHrxjiLXDsD8Oe9FMxIfZd6y+hfsQWLFSDyWqod+F4rmROsRdsJaAC8EliRCxBp/jLY8/ntFLAKCwRP57z46wXWe65yOENOErSDZvbrPZbNOm7whX4GsTozfE1dy+3lcsOq+jth3LbyQHuDRNW2/oKtWfOeQ1H+8W+WP1GRpyIOHzClSgMe/k3n7E60Ls= + skip_cleanup: true + file: build/bin/SolveSpace.dmg + on: + repo: vespakoen/solvespace + tags: true - stage: test name: "Debian" os: linux @@ -40,9 +70,9 @@ jobs: arch: amd64 dist: bionic addons: - snaps: - - name: snapcraft - confinement: classic + snaps: + - name: snapcraft + confinement: classic script: ./.travis/build-snap.sh deploy: - provider: script diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh index b87e2fdb..4629442b 100755 --- a/.travis/build-macos.sh +++ b/.travis/build-macos.sh @@ -5,5 +5,5 @@ if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=D mkdir build cd build cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. -make VERBOSE=1 +make make test_solvespace diff --git a/.travis/install-macos.sh b/.travis/install-macos.sh index 792126ca..0c6a6e7c 100755 --- a/.travis/install-macos.sh +++ b/.travis/install-macos.sh @@ -1,5 +1,3 @@ #!/bin/sh -xe -brew update -brew install freetype cairo -git submodule update --init +git submodule update --init \ No newline at end of file diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh new file mode 100644 index 00000000..cf4ec073 --- /dev/null +++ b/.travis/sign-macos.sh @@ -0,0 +1,63 @@ +#!/bin/sh -xe + +cd build + +app="bin/SolveSpace.app" +dmg="bin/SolveSpace.dmg" +bundle_id="com.solvespace.solvespace" + +# get the signing certificate (this is the Developer ID:Application: Your Name, exported to a p12 file, then converted to base64, e.g.: cat ~/Desktop/certificate.p12 | base64 | pbcopy) +echo $MACOS_CERTIFICATE_P12 | base64 --decode > certificate.p12 + +# create a keychain +security create-keychain -p secret build.keychain +security default-keychain -s build.keychain +security unlock-keychain -p secret build.keychain + +# import the key +security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PASSWORD -T /usr/bin/codesign + +security set-key-partition-list -S apple-tool:,apple: -s -k secret build.keychain +#security set-keychain-settings -t 3600 -u build.keychain + +# check if all is good +security find-identity -v + +# sign the .app +codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${app}" + +# create the .dmg from the signed .app +hdiutil create -srcfolder "${app}" "${dmg}" + +# sign the .dmg +codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f "${dmg}" + +# notarize and store request uuid in variable +notarize_uuid=$(xcrun altool --notarize-app --primary-bundle-id "${bundle_id}" --username "${MACOS_APPSTORE_USERNAME}" --password "${MACOS_APPSTORE_APP_PASSWORD}" --file "${dmg}" 2>&1 | grep RequestUUID | awk '{print $3'}) + +# wait a bit so we don't get errors during checking +sleep 5 + +success=0 +for (( ; ; )) +do + echo "Checking progress..." + progress=$(xcrun altool --notarization-info "${notarize_uuid}" -u "${MACOS_APPSTORE_USERNAME}" -p "${MACOS_APPSTORE_APP_PASSWORD}" 2>&1) + echo "${progress}" + + if [ $? -ne 0 ] || [[ "${progress}" =~ "Invalid" ]] ; then + echo "Error with notarization. Exiting" + break + fi + + if [[ "${progress}" =~ "success" ]]; then + success=1 + break + else + echo "Not completed yet. Sleeping for 10 seconds" + fi + sleep 10 +done + +# staple +xcrun stapler staple $app \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 40071be4..836c58a0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,6 +22,10 @@ set(CMAKE_USER_MAKE_RULES_OVERRIDE set(CMAKE_USER_MAKE_RULES_OVERRIDE_CXX "${CMAKE_SOURCE_DIR}/cmake/cxx_flag_overrides.cmake") +if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") +endif() + # project # NOTE TO PACKAGERS: The embedded git commit hash is critical for rapid bug triage when the builds @@ -69,7 +73,6 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU") endif() # common compiler flags - include(CheckCXXCompilerFlag) set(FILE_PREFIX_MAP "-ffile-prefix-map=${CMAKE_CURRENT_SOURCE_DIR}=.") @@ -109,10 +112,6 @@ if(ENABLE_OPENMP) 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() From e42aa0fac42af16b7c23472d49f6a1232e7f29c3 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sun, 18 Oct 2020 10:50:02 +0200 Subject: [PATCH 006/113] Update .travis.yml for macOS build Update .travis.yml for macOS build Add executable permission on sign-macos.sh script --- .travis.yml | 24 ++++-------------------- .travis/sign-macos.sh | 12 ++++-------- 2 files changed, 8 insertions(+), 28 deletions(-) mode change 100644 => 100755 .travis/sign-macos.sh diff --git a/.travis.yml b/.travis.yml index 792d7c26..b6a5ebf0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,11 +15,11 @@ jobs: deploy: provider: releases api_key: - secure: 3PAqaWQTsHKKuItoZnIm7KJkCE/IHjrGtQMvdjabmVr9F/X3nuRYCdhvlSwU6z1N/UIiUso5jDc/qYOxbBnDfXiu2HihW9USaPLLrQoMQHxqAr62Hks1ESMo/rCrYPdqzFBdEbkuP6GqwxXyUDhnvDwXzmqSzhcotEUwiuRnvcTnlf29WT4D0Gz8gEwIkkiMN9msH8mabvd5SkmaBFd+Z7elXn6DpTxZSHRhX8QCW7681pdq424H4qbArIB+I9ccHbS+Cbh8kKBcd/hNX1tFK4SdaUYyywonrWhgPHZzZ8oj0dRGvY19+ZnTJisQmUjiJQDglUeJ+p5RIcUHOnUjM/Io/jWdA78W9Vn0gpjX5F2iBfm0UcSyXwf9dXDFnm9pOCnFjJ1Cv4wxWlRvUXcQxv9hb00cyHYEhzPJRmNUu/DF45caOHYvLADwd0d3UPrfblXpjTPxpDxHHl3QuXQLeERiGsZOg5N6kg0coUO0p60JDdDHrxjiLXDsD8Oe9FMxIfZd6y+hfsQWLFSDyWqod+F4rmROsRdsJaAC8EliRCxBp/jLY8/ntFLAKCwRP57z46wXWe65yOENOErSDZvbrPZbNOm7whX4GsTozfE1dy+3lcsOq+jth3LbyQHuDRNW2/oKtWfOeQ1H+8W+WP1GRpyIOHzClSgMe/k3n7E60Ls= + secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true file: build/bin/SolveSpace.dmg on: - repo: vespakoen/solvespace + repo: solvespace/solvespace tags: true - stage: deploy name: macOS @@ -30,11 +30,11 @@ jobs: deploy: provider: releases api_key: - secure: 3PAqaWQTsHKKuItoZnIm7KJkCE/IHjrGtQMvdjabmVr9F/X3nuRYCdhvlSwU6z1N/UIiUso5jDc/qYOxbBnDfXiu2HihW9USaPLLrQoMQHxqAr62Hks1ESMo/rCrYPdqzFBdEbkuP6GqwxXyUDhnvDwXzmqSzhcotEUwiuRnvcTnlf29WT4D0Gz8gEwIkkiMN9msH8mabvd5SkmaBFd+Z7elXn6DpTxZSHRhX8QCW7681pdq424H4qbArIB+I9ccHbS+Cbh8kKBcd/hNX1tFK4SdaUYyywonrWhgPHZzZ8oj0dRGvY19+ZnTJisQmUjiJQDglUeJ+p5RIcUHOnUjM/Io/jWdA78W9Vn0gpjX5F2iBfm0UcSyXwf9dXDFnm9pOCnFjJ1Cv4wxWlRvUXcQxv9hb00cyHYEhzPJRmNUu/DF45caOHYvLADwd0d3UPrfblXpjTPxpDxHHl3QuXQLeERiGsZOg5N6kg0coUO0p60JDdDHrxjiLXDsD8Oe9FMxIfZd6y+hfsQWLFSDyWqod+F4rmROsRdsJaAC8EliRCxBp/jLY8/ntFLAKCwRP57z46wXWe65yOENOErSDZvbrPZbNOm7whX4GsTozfE1dy+3lcsOq+jth3LbyQHuDRNW2/oKtWfOeQ1H+8W+WP1GRpyIOHzClSgMe/k3n7E60Ls= + secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true file: build/bin/SolveSpace.dmg on: - repo: vespakoen/solvespace + repo: solvespace/solvespace tags: true - stage: test name: "Debian" @@ -47,22 +47,6 @@ jobs: os: windows install: ./.travis/install-windows.sh script: ./.travis/build-windows.sh - - stage: deploy - name: "OSX" - os: osx - osx_image: xcode8.3 - install: ./.travis/install-macos.sh - # the awk command is a workaround for https://github.com/travis-ci/travis-ci/issues/4704. - script: ./.travis/build-macos.sh | awk '/.{0,32}/ {print $0}' - deploy: - provider: releases - api_key: - secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= - skip_cleanup: true - file: build/SolveSpace.dmg - on: - repo: solvespace/solvespace - tags: true - &deploy-snap stage: deploy name: Snap amd64 diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh old mode 100644 new mode 100755 index cf4ec073..e5e76232 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -2,7 +2,7 @@ cd build -app="bin/SolveSpace.app" +# app="bin/SolveSpace.app" dmg="bin/SolveSpace.dmg" bundle_id="com.solvespace.solvespace" @@ -23,18 +23,14 @@ security set-key-partition-list -S apple-tool:,apple: -s -k secret build.keychai # check if all is good security find-identity -v -# sign the .app -codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${app}" - -# create the .dmg from the signed .app -hdiutil create -srcfolder "${app}" "${dmg}" - # sign the .dmg -codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f "${dmg}" +codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${dmg}" # notarize and store request uuid in variable notarize_uuid=$(xcrun altool --notarize-app --primary-bundle-id "${bundle_id}" --username "${MACOS_APPSTORE_USERNAME}" --password "${MACOS_APPSTORE_APP_PASSWORD}" --file "${dmg}" 2>&1 | grep RequestUUID | awk '{print $3'}) +echo $notarize_uuid + # wait a bit so we don't get errors during checking sleep 5 From 408128a138df29974a193580438058a5d0fee16b Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sat, 17 Oct 2020 14:05:29 -0400 Subject: [PATCH 007/113] Avoid zero tangnet vectors on degenerate NURBS edges. Fixes #652 --- src/srf/ratpoly.cpp | 8 +++++++- src/srf/surface.h | 2 +- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/srf/ratpoly.cpp b/src/srf/ratpoly.cpp index 8e43367d..05ccd038 100644 --- a/src/srf/ratpoly.cpp +++ b/src/srf/ratpoly.cpp @@ -332,7 +332,7 @@ Vector SSurface::PointAt(double u, double v) const { return num; } -void SSurface::TangentsAt(double u, double v, Vector *tu, Vector *tv) const { +void SSurface::TangentsAt(double u, double v, Vector *tu, Vector *tv, bool retry) const { Vector num = Vector::From(0, 0, 0), num_u = Vector::From(0, 0, 0), num_v = Vector::From(0, 0, 0); @@ -364,6 +364,12 @@ void SSurface::TangentsAt(double u, double v, Vector *tu, Vector *tv) const { *tv = ((num_v.ScaledBy(den)).Minus(num.ScaledBy(den_v))); *tv = tv->ScaledBy(1.0/(den*den)); + + // Tangent is zero at sungularities like the north pole. Move away a bit and retry. + if(tv->Equals(Vector::From(0,0,0)) && retry) + TangentsAt(u+(0.5-u)*0.00001, v, tu, tv, false); + if(tu->Equals(Vector::From(0,0,0)) && retry) + TangentsAt(u, v+(0.5-v)*0.00001, tu, tv, false); } Vector SSurface::NormalAt(Point2d puv) const { diff --git a/src/srf/surface.h b/src/srf/surface.h index 393be4aa..ff8aa0f2 100644 --- a/src/srf/surface.h +++ b/src/srf/surface.h @@ -335,7 +335,7 @@ public: void PointOnCurve(const SBezier *curve, double *up, double *vp); Vector PointAt(double u, double v) const; Vector PointAt(Point2d puv) const; - void TangentsAt(double u, double v, Vector *tu, Vector *tv) const; + void TangentsAt(double u, double v, Vector *tu, Vector *tv, bool retry=true) const; Vector NormalAt(Point2d puv) const; Vector NormalAt(double u, double v) const; bool LineEntirelyOutsideBbox(Vector a, Vector b, bool asSegment) const; From 05487020436d8bf450d92c7c979add67be1c22fb Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 19 Oct 2020 11:24:37 +0200 Subject: [PATCH 008/113] macOS CI fixes --- .travis/build-macos.sh | 4 ++-- .travis/sign-macos.sh | 9 +++++++-- src/CMakeLists.txt | 10 ---------- 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh index 4629442b..3e861deb 100755 --- a/.travis/build-macos.sh +++ b/.travis/build-macos.sh @@ -4,6 +4,6 @@ if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=D mkdir build cd build -cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.7 -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. -make +cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. +make -j2 make test_solvespace diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh index e5e76232..da90ec21 100755 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -2,7 +2,7 @@ cd build -# app="bin/SolveSpace.app" +app="bin/SolveSpace.app" dmg="bin/SolveSpace.dmg" bundle_id="com.solvespace.solvespace" @@ -18,11 +18,16 @@ security unlock-keychain -p secret build.keychain security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PASSWORD -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple: -s -k secret build.keychain -#security set-keychain-settings -t 3600 -u build.keychain # check if all is good security find-identity -v +# sign the .app +codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${app}" + +# create the .dmg from the signed .app +hdiutil create -srcfolder "${app}" "${dmg}" + # sign the .dmg codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${dmg}" diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1b6d9005..fd8359f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -410,14 +410,4 @@ if(APPLE) COMMAND ${CMAKE_COMMAND} -E copy $ ${bundle_bin} COMMENT "Bundling executable solvespace-cli" VERBATIM) - - add_custom_command(OUTPUT ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg - COMMAND ${CMAKE_COMMAND} -E remove ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg - COMMAND hdiutil create -srcfolder ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app - ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg - DEPENDS solvespace - COMMENT "Building ${bundle}.dmg" - VERBATIM) - add_custom_target(${bundle}-dmg ALL - DEPENDS ${EXECUTABLE_OUTPUT_PATH}/${bundle}.dmg) endif() From b12bcc5889ced49b9d7a7c60dff2b97cca4fa334 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sun, 18 Oct 2020 17:05:02 -0400 Subject: [PATCH 009/113] Fix some IDF file curves. --- src/importidf.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/importidf.cpp b/src/importidf.cpp index c1e2e331..c9ce7ec6 100644 --- a/src/importidf.cpp +++ b/src/importidf.cpp @@ -241,7 +241,6 @@ static void MakeBeziersForArcs(SBezierList *sbl, Vector center, Vector pa, Vecto if(angle == 360.0) { thetaa = 0; thetab = 2*PI; - dtheta = 2*PI; } else { Point2d c2 = center.Project2d(u, v); Point2d pa2 = (pa.Project2d(u, v)).Minus(c2); @@ -249,8 +248,9 @@ static void MakeBeziersForArcs(SBezierList *sbl, Vector center, Vector pa, Vecto thetaa = atan2(pa2.y, pa2.x); thetab = atan2(pb2.y, pb2.x); - dtheta = thetab - thetaa; } + dtheta = angle * PI/180; + int i, n; if(dtheta > (3*PI/2 + 0.01)) { n = 4; From b28499ea483098402a9b3ddff8d694778bcf28b9 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Mon, 19 Oct 2020 13:57:37 -0400 Subject: [PATCH 010/113] initial support (disabled) for keepout regions in IDF files. --- src/importidf.cpp | 97 ++++++++++++++++++++++++++++------------------- 1 file changed, 59 insertions(+), 38 deletions(-) diff --git a/src/importidf.cpp b/src/importidf.cpp index c9ce7ec6..1789e5cc 100644 --- a/src/importidf.cpp +++ b/src/importidf.cpp @@ -236,18 +236,15 @@ static void MakeBeziersForArcs(SBezierList *sbl, Vector center, Vector pa, Vecto Vector u = q.RotationU(), v = q.RotationV(); double r = pa.Minus(center).Magnitude(); - double thetaa, thetab, dtheta; + double theta, dtheta; if(angle == 360.0) { - thetaa = 0; - thetab = 2*PI; + theta = 0; } else { Point2d c2 = center.Project2d(u, v); Point2d pa2 = (pa.Project2d(u, v)).Minus(c2); - Point2d pb2 = (pb.Project2d(u, v)).Minus(c2); - thetaa = atan2(pa2.y, pa2.x); - thetab = atan2(pb2.y, pb2.x); + theta = atan2(pa2.y, pa2.x); } dtheta = angle * PI/180; @@ -266,17 +263,17 @@ static void MakeBeziersForArcs(SBezierList *sbl, Vector center, Vector pa, Vecto for(i = 0; i < n; i++) { double s, c; - c = cos(thetaa); - s = sin(thetaa); + c = cos(theta); + s = sin(theta); // The start point of the curve, and the tangent vector at // that start point. Vector p0 = center.Plus(u.ScaledBy( r*c)).Plus(v.ScaledBy(r*s)), t0 = u.ScaledBy(-r*s). Plus(v.ScaledBy(r*c)); - thetaa += dtheta; + theta += dtheta; - c = cos(thetaa); - s = sin(thetaa); + c = cos(theta); + s = sin(theta); Vector p2 = center.Plus(u.ScaledBy( r*c)).Plus(v.ScaledBy(r*s)), t2 = u.ScaledBy(-r*s). Plus(v.ScaledBy(r*c)); @@ -335,6 +332,7 @@ bool LinkIDF(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *s double board_thickness = 10.0; double scale = 1.0; //mm + bool topEntities, bottomEntities; Quaternion normal = Quaternion::From(Vector::From(1,0,0), Vector::From(0,1,0)); hEntity hnorm = newNormal(el, &entityCount, normal); @@ -347,6 +345,7 @@ bool LinkIDF(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *s for(std::string line; getline( stream, line ); ) { if (line.find(".END_") == 0) { section = none; + curve = -1; } switch (section) { case none: @@ -356,6 +355,10 @@ bool LinkIDF(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *s } else if (line.find(".BOARD_OUTLINE") == 0) { section = board_outline; record_number = 1; +// no keepouts for now - they should also be shown as construction? +// } else if (line.find(".ROUTE_KEEPOUT") == 0) { +// section = routing_keepout; +// record_number = 1; } else if(line.find(".DRILLED_HOLES") == 0) { section = drilled_holes; record_number = 1; @@ -375,11 +378,23 @@ bool LinkIDF(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *s } } break; - + + case routing_keepout: case board_outline: if (record_number == 2) { - board_thickness = std::stod(line) * scale; - dbp("IDF board thickness: %lf", board_thickness); + if(section == board_outline) { + topEntities = true; + bottomEntities = true; + board_thickness = std::stod(line) * scale; + dbp("IDF board thickness: %lf", board_thickness); + } else if (section == routing_keepout) { + topEntities = false; + bottomEntities = false; + if(line.find("TOP") == 0 || line.find("BOTH") == 0) + topEntities = true; + if(line.find("BOTTOM") == 0 || line.find("BOTH") == 0) + bottomEntities = true; + } } else { // records 3+ are lines, arcs, and circles std::vector values = splitString(line); if(values.size() != 4) continue; @@ -391,36 +406,43 @@ bool LinkIDF(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *s Vector pTop = Vector::From(x,y,board_thickness); if(c != curve) { // start a new curve curve = c; - hprev = newPoint(el, &entityCount, point, /*visible=*/false); - hprevTop = newPoint(el, &entityCount, pTop, /*visible=*/false); + if (bottomEntities) + hprev = newPoint(el, &entityCount, point, /*visible=*/false); + if (topEntities) + hprevTop = newPoint(el, &entityCount, pTop, /*visible=*/false); pprev = point; pprevTop = pTop; } else { - // create a bezier for the extrusion - if (ang == 0) { - // straight lines - SBezier sb = SBezier::From(pprev, point); - sbl.l.Add(&sb); - } else if (ang != 360.0) { - // Arcs - Vector c = ArcCenter(pprev, point, ang); - MakeBeziersForArcs(&sbl, c, pprev, point, normal, ang); - } else { - // circles - MakeBeziersForArcs(&sbl, point, pprev, pprev, normal, ang); + if(section == board_outline) { + // create a bezier for the extrusion + if (ang == 0) { + // straight lines + SBezier sb = SBezier::From(pprev, point); + sbl.l.Add(&sb); + } else if (ang != 360.0) { + // Arcs + Vector c = ArcCenter(pprev, point, ang); + MakeBeziersForArcs(&sbl, c, pprev, point, normal, ang); + } else { + // circles + MakeBeziersForArcs(&sbl, point, pprev, pprev, normal, ang); + } } // next create the entities // only curves and points at circle centers will be visible bool vis = (ang == 360.0); - hEntity hp = newPoint(el, &entityCount, point, /*visible=*/vis); - CreateEntity(el, &entityCount, hprev, hp, hnorm, pprev, point, ang); - pprev = point; - hprev = hp; - hp = newPoint(el, &entityCount, pTop, /*visible=*/vis); - CreateEntity(el, &entityCount, hprevTop, hp, hnorm, pprevTop, pTop, ang); - pprevTop = pTop; - hprevTop = hp; - + if (bottomEntities) { + hEntity hp = newPoint(el, &entityCount, point, /*visible=*/vis); + CreateEntity(el, &entityCount, hprev, hp, hnorm, pprev, point, ang); + pprev = point; + hprev = hp; + } + if (topEntities) { + hEntity hp = newPoint(el, &entityCount, pTop, /*visible=*/vis); + CreateEntity(el, &entityCount, hprevTop, hp, hnorm, pprevTop, pTop, ang); + pprevTop = pTop; + hprevTop = hp; + } } } break; @@ -428,7 +450,6 @@ bool LinkIDF(const Platform::Path &filename, EntityList *el, SMesh *m, SShell *s case other_outline: case routing_outline: case placement_outline: - case routing_keepout: case via_keepout: case placement_group: break; From 8e7416f3fdb184e7f951be16d376207a475002d9 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Tue, 20 Oct 2020 09:39:26 +0200 Subject: [PATCH 011/113] Travis: Build improvements and fixes (#751) - Add OpenMP to macOS build - Use as many cores as possible in CI - Update travis osx image to xcode12.2 - Ignore .vscode folder - In `.travis/sign-macos.sh`, only create keychain when `CI` variable is present - Only run macOS deploy stage when a tag is pushed --- .gitignore | 1 + .travis.yml | 14 +++----------- .travis/build-debian.sh | 2 +- .travis/build-macos.sh | 26 +++++++++++++++++++++----- .travis/build-windows.sh | 6 +++--- .travis/install-macos.sh | 1 + .travis/sign-macos.sh | 24 +++++++++++++----------- CMakeLists.txt | 22 ++++++++++++++++++++-- src/drawentity.cpp | 10 +++++++--- src/mouse.cpp | 28 ++++++++++++++-------------- src/solvespace.h | 2 +- 11 files changed, 85 insertions(+), 51 deletions(-) diff --git a/.gitignore b/.gitignore index 5301e142..4f76b266 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,4 @@ /debian/libslvs1-dev/ /obj-*/ /*.slvs +.vscode/ diff --git a/.travis.yml b/.travis.yml index b6a5ebf0..d6ac1209 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,22 +9,14 @@ jobs: - stage: test name: macOS os: osx - osx_image: xcode11.2 + osx_image: xcode12.2 install: "./.travis/install-macos.sh" script: "./.travis/build-macos.sh" - deploy: - provider: releases - api_key: - secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= - skip_cleanup: true - file: build/bin/SolveSpace.dmg - on: - repo: solvespace/solvespace - tags: true - stage: deploy + if: tag IS present name: macOS os: osx - osx_image: xcode11.2 + osx_image: xcode12.2 install: "./.travis/install-macos.sh" script: "./.travis/build-macos.sh && ./.travis/sign-macos.sh" deploy: diff --git a/.travis/build-debian.sh b/.travis/build-debian.sh index bb678daf..007bf805 100755 --- a/.travis/build-debian.sh +++ b/.travis/build-debian.sh @@ -7,5 +7,5 @@ cd build cmake .. \ -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ -DENABLE_SANITIZERS=ON -make VERBOSE=1 +make -j$(nproc) VERBOSE=1 make test_solvespace diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh index 3e861deb..31c182b5 100755 --- a/.travis/build-macos.sh +++ b/.travis/build-macos.sh @@ -1,9 +1,25 @@ #!/bin/sh -xe -if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=Debug; fi +if echo $TRAVIS_TAG | grep ^v; then + BUILD_TYPE=RelWithDebInfo +else + BUILD_TYPE=Debug +fi -mkdir build +mkdir build || true cd build -cmake -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. -make -j2 -make test_solvespace + +LLVM_PREFIX=$(brew --prefix llvm@9) +export CC="${LLVM_PREFIX}/bin/clang" +export CXX="${CC}++" +export LDFLAGS="-L${LLVM_PREFIX}/lib -Wl,-rpath,${LLVM_PREFIX}/lib" \ +export CFLAGS="-I${LLVM_PREFIX}/include" +export CPPFLAGS="-I${LLVM_PREFIX}/include" + +cmake \ + -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 \ + -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. \ + -DENABLE_OPENMP=ON + +cmake --build . --config $BUILD_TYPE +make -j$(nproc) test_solvespace diff --git a/.travis/build-windows.sh b/.travis/build-windows.sh index e7502e6b..9cbc3897 100755 --- a/.travis/build-windows.sh +++ b/.travis/build-windows.sh @@ -9,8 +9,8 @@ mkdir build cd build cmake .. -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -MSBuild.exe "src/solvespace.vcxproj" -MSBuild.exe "src/solvespace-cli.vcxproj" -MSBuild.exe "test/solvespace-testsuite.vcxproj" +MSBuild.exe "src/solvespace.vcxproj" -maxcpucount +MSBuild.exe "src/solvespace-cli.vcxproj" -maxcpucount +MSBuild.exe "test/solvespace-testsuite.vcxproj" -maxcpucount bin/$BUILD_TYPE/solvespace-testsuite.exe diff --git a/.travis/install-macos.sh b/.travis/install-macos.sh index 0c6a6e7c..d4817455 100755 --- a/.travis/install-macos.sh +++ b/.travis/install-macos.sh @@ -1,3 +1,4 @@ #!/bin/sh -xe +brew install llvm@9 git submodule update --init \ No newline at end of file diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh index da90ec21..6c0fd1b5 100755 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -6,21 +6,23 @@ app="bin/SolveSpace.app" dmg="bin/SolveSpace.dmg" bundle_id="com.solvespace.solvespace" -# get the signing certificate (this is the Developer ID:Application: Your Name, exported to a p12 file, then converted to base64, e.g.: cat ~/Desktop/certificate.p12 | base64 | pbcopy) -echo $MACOS_CERTIFICATE_P12 | base64 --decode > certificate.p12 +if [ "$CI" = "true" ]; then + # get the signing certificate (this is the Developer ID:Application: Your Name, exported to a p12 file, then converted to base64, e.g.: cat ~/Desktop/certificate.p12 | base64 | pbcopy) + echo $MACOS_CERTIFICATE_P12 | base64 --decode > certificate.p12 -# create a keychain -security create-keychain -p secret build.keychain -security default-keychain -s build.keychain -security unlock-keychain -p secret build.keychain + # create a keychain + security create-keychain -p secret build.keychain + security default-keychain -s build.keychain + security unlock-keychain -p secret build.keychain -# import the key -security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PASSWORD -T /usr/bin/codesign + # import the key + security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PASSWORD -T /usr/bin/codesign -security set-key-partition-list -S apple-tool:,apple: -s -k secret build.keychain + security set-key-partition-list -S apple-tool:,apple: -s -k secret build.keychain -# check if all is good -security find-identity -v + # check if all is good + security find-identity -v +fi # sign the .app codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${app}" diff --git a/CMakeLists.txt b/CMakeLists.txt index 836c58a0..ed4f673c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -106,9 +106,27 @@ if(ENABLE_LTO) endif() if(ENABLE_OPENMP) - include(FindOpenMP) - if(OpenMP_FOUND) + if(APPLE) + # OpenMP does not work with the default Apple llvm/clang++ + # Install a more recent version using Homebrew (version 11.0.0 which is the next available tag on homebrew at this time crashed): + # "brew install llvm@9" + # and set the right compiler flags using: + # LLVM_PREFIX=$(brew --prefix llvm@9) + # export CC="${LLVM_PREFIX}/bin/clang" + # export CXX="${CC}++" + # export LDFLAGS="-L${LLVM_PREFIX}/lib -Wl,-rpath,${LLVM_PREFIX}/lib" \ + # export CFLAGS="-I${LLVM_PREFIX}/include" + # export CPPFLAGS="-I${LLVM_PREFIX}/include" + set(OpenMP_CXX_FLAGS "-fopenmp=libomp") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + message(STATUS "found OpenMP, compiling with flags: " ${OpenMP_CXX_FLAGS} ) + else() + find_package( OpenMP REQUIRED ) + include(FindOpenMP) + if(OPENMP_FOUND) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + message(STATUS "found OpenMP, compiling with flags: " ${OpenMP_CXX_FLAGS} ) + endif() endif() endif() diff --git a/src/drawentity.cpp b/src/drawentity.cpp index d6797661..fab40713 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -315,9 +315,13 @@ void Entity::ComputeInterpolatingSpline(SBezierList *sbl, bool periodic) const { } else { // The wrapping would work, except when n = 1 and everything // wraps to zero... - if(i > 0) bm.A[i][i - 1] = eq.x; - /**/ bm.A[i][i] = eq.y; - if(i < (n-1)) bm.A[i][i + 1] = eq.z; + if(i > 0) { + bm.A[i][i - 1] = eq.x; + } + bm.A[i][i] = eq.y; + if(i < (n-1)) { + bm.A[i][i + 1] = eq.z; + } } } bm.Solve(); diff --git a/src/mouse.cpp b/src/mouse.cpp index 7f90a8a3..699f3e26 100644 --- a/src/mouse.cpp +++ b/src/mouse.cpp @@ -624,24 +624,24 @@ void GraphicsWindow::MouseRightUp(double x, double y) { } if(gs.withEndpoints > 0) { menu->AddItem(_("Select Edge Chain"), - [this]() { MenuEdit(Command::SELECT_CHAIN); }); + []() { MenuEdit(Command::SELECT_CHAIN); }); } if(gs.constraints == 1 && gs.n == 0) { Constraint *c = SK.GetConstraint(gs.constraint[0]); if(c->HasLabel() && c->type != Constraint::Type::COMMENT) { menu->AddItem(_("Toggle Reference Dimension"), - []() { Constraint::MenuConstrain(Command::REFERENCE); }); + []() { Constraint::MenuConstrain(Command::REFERENCE); }); } if(c->type == Constraint::Type::ANGLE || - c->type == Constraint::Type::EQUAL_ANGLE) + c->type == Constraint::Type::EQUAL_ANGLE) { menu->AddItem(_("Other Supplementary Angle"), - []() { Constraint::MenuConstrain(Command::OTHER_ANGLE); }); + []() { Constraint::MenuConstrain(Command::OTHER_ANGLE); }); } } if(gs.constraintLabels > 0 || gs.points > 0) { menu->AddItem(_("Snap to Grid"), - [this]() { MenuEdit(Command::SNAP_TO_GRID); }); + []() { MenuEdit(Command::SNAP_TO_GRID); }); } if(gs.points == 1 && gs.point[0].isFromRequest()) { @@ -714,7 +714,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) { } if(gs.entities == gs.n) { menu->AddItem(_("Toggle Construction"), - [this]() { MenuRequest(Command::CONSTRUCTION); }); + []() { MenuRequest(Command::CONSTRUCTION); }); } if(gs.points == 1) { @@ -748,28 +748,28 @@ void GraphicsWindow::MouseRightUp(double x, double y) { menu->AddSeparator(); if(LockedInWorkplane()) { menu->AddItem(_("Cut"), - [this]() { MenuClipboard(Command::CUT); }); + []() { MenuClipboard(Command::CUT); }); menu->AddItem(_("Copy"), - [this]() { MenuClipboard(Command::COPY); }); + []() { MenuClipboard(Command::COPY); }); } } else { menu->AddItem(_("Select All"), - [this]() { MenuEdit(Command::SELECT_ALL); }); + []() { MenuEdit(Command::SELECT_ALL); }); } if((!SS.clipboard.r.IsEmpty() || !SS.clipboard.c.IsEmpty()) && LockedInWorkplane()) { menu->AddItem(_("Paste"), - [this]() { MenuClipboard(Command::PASTE); }); + []() { MenuClipboard(Command::PASTE); }); menu->AddItem(_("Paste Transformed..."), - [this]() { MenuClipboard(Command::PASTE_TRANSFORM); }); + []() { MenuClipboard(Command::PASTE_TRANSFORM); }); } if(itemsSelected) { menu->AddItem(_("Delete"), - [this]() { MenuClipboard(Command::DELETE); }); + []() { MenuClipboard(Command::DELETE); }); menu->AddSeparator(); menu->AddItem(_("Unselect All"), - [this]() { MenuEdit(Command::UNSELECT_ALL); }); + []() { MenuEdit(Command::UNSELECT_ALL); }); } // If only one item is selected, then it must be the one that we just // selected from the hovered item; in which case unselect all and hovered @@ -785,7 +785,7 @@ void GraphicsWindow::MouseRightUp(double x, double y) { if(itemsSelected) { menu->AddSeparator(); menu->AddItem(_("Zoom to Fit"), - [this]() { MenuView(Command::ZOOM_TO_FIT); }); + []() { MenuView(Command::ZOOM_TO_FIT); }); } menu->PopUp(); diff --git a/src/solvespace.h b/src/solvespace.h index 1157723a..d0fde5f5 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -513,7 +513,7 @@ public: GraphicsWindow GW; // The state for undo/redo - typedef struct { + typedef struct UndoState { IdList group; List
groupOrder; IdList request; From 3af8127e8f3d6afb6231fc021005eabd196d75fc Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Tue, 20 Oct 2020 14:38:34 +0200 Subject: [PATCH 012/113] macOS: add NSOpenGLPFADoubleBuffer to NSOpenGLPixelFormatAttribute --- src/platform/guimac.mm | 1 + 1 file changed, 1 insertion(+) diff --git a/src/platform/guimac.mm b/src/platform/guimac.mm index 0f0997c4..5aa7f054 100644 --- a/src/platform/guimac.mm +++ b/src/platform/guimac.mm @@ -371,6 +371,7 @@ MenuBarRef GetOrCreateMainMenu(bool *unique) { - (id)initWithFrame:(NSRect)frameRect { NSOpenGLPixelFormatAttribute attrs[] = { + NSOpenGLPFADoubleBuffer, NSOpenGLPFAColorSize, 24, NSOpenGLPFADepthSize, 24, 0 From 9d2641a5dec60277a0f6da5e8e40ea54eb336b04 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Tue, 20 Oct 2020 14:14:49 +0200 Subject: [PATCH 013/113] Travis: update travis and macos build configs - Fixing warnings in .travis.yml - Enable building on all cores for macOS build - Quote variables --- .travis.yml | 36 +++++++++++++++++++----------------- .travis/build-macos.sh | 2 +- .travis/sign-macos.sh | 2 +- 3 files changed, 21 insertions(+), 19 deletions(-) diff --git a/.travis.yml b/.travis.yml index d6ac1209..d11a77ed 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,3 +1,5 @@ +os: linux +dist: xenial language: c git: submodules: false @@ -7,23 +9,23 @@ jobs: name: Snap arm64 include: - stage: test - name: macOS + name: macOS test os: osx osx_image: xcode12.2 - install: "./.travis/install-macos.sh" - script: "./.travis/build-macos.sh" + install: ".travis/install-macos.sh" + script: ".travis/build-macos.sh" - stage: deploy if: tag IS present - name: macOS + name: macOS deploy os: osx osx_image: xcode12.2 - install: "./.travis/install-macos.sh" - script: "./.travis/build-macos.sh && ./.travis/sign-macos.sh" + install: ".travis/install-macos.sh" + script: ".travis/build-macos.sh && .travis/sign-macos.sh" deploy: provider: releases - api_key: + token: secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= - skip_cleanup: true + cleanup: false file: build/bin/SolveSpace.dmg on: repo: solvespace/solvespace @@ -32,13 +34,13 @@ jobs: name: "Debian" os: linux dist: bionic - install: ./.travis/install-debian.sh - script: ./.travis/build-debian.sh + install: .travis/install-debian.sh + script: .travis/build-debian.sh - stage: test name: "Windows Visual Studio 2017" os: windows - install: ./.travis/install-windows.sh - script: ./.travis/build-windows.sh + install: .travis/install-windows.sh + script: .travis/build-windows.sh - &deploy-snap stage: deploy name: Snap amd64 @@ -49,17 +51,17 @@ jobs: snaps: - name: snapcraft confinement: classic - script: ./.travis/build-snap.sh + script: .travis/build-snap.sh deploy: - provider: script - script: sudo ./.travis/deploy-snap.sh edge - skip_cleanup: true + script: sudo .travis/deploy-snap.sh edge + cleanup: false on: branch: master tags: false - provider: script - script: sudo ./.travis/deploy-snap.sh edge,beta - skip_cleanup: true + script: sudo .travis/deploy-snap.sh edge,beta + cleanup: false on: branch: master tags: true diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh index 31c182b5..a9f39c4f 100755 --- a/.travis/build-macos.sh +++ b/.travis/build-macos.sh @@ -21,5 +21,5 @@ cmake \ -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. \ -DENABLE_OPENMP=ON -cmake --build . --config $BUILD_TYPE +cmake --build . --config $BUILD_TYPE -- -j$(nproc) make -j$(nproc) test_solvespace diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh index 6c0fd1b5..6a379b53 100755 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -16,7 +16,7 @@ if [ "$CI" = "true" ]; then security unlock-keychain -p secret build.keychain # import the key - security import certificate.p12 -k build.keychain -P $MACOS_CERTIFICATE_PASSWORD -T /usr/bin/codesign + security import certificate.p12 -k build.keychain -P "${MACOS_CERTIFICATE_PASSWORD}" -T /usr/bin/codesign security set-key-partition-list -S apple-tool:,apple: -s -k secret build.keychain From 2be2e428d36f83d5b8ce383456f6dd42f91d71a0 Mon Sep 17 00:00:00 2001 From: ZHOU You Date: Mon, 28 Sep 2020 13:15:34 +0800 Subject: [PATCH 014/113] Chinese translation added. --- res/CMakeLists.txt | 1 + res/locales.txt | 1 + res/locales/zh_CN.mo | Bin 0 -> 30647 bytes res/locales/zh_CN.po | 1773 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 1775 insertions(+) create mode 100644 res/locales/zh_CN.mo create mode 100644 res/locales/zh_CN.po diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index 3783f242..5969039b 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -256,6 +256,7 @@ add_resources( locales/fr_FR.po locales/uk_UA.po locales/ru_RU.po + locales/zh_CN.po fonts/unifont.hex.gz fonts/private/0-check-false.png fonts/private/1-check-true.png diff --git a/res/locales.txt b/res/locales.txt index 9a3f102d..0f4fab16 100644 --- a/res/locales.txt +++ b/res/locales.txt @@ -5,3 +5,4 @@ en-US,0409,English (US) fr-FR,040C,Français ru-RU,0419,Русский uk-UA,0422,Українська +zh-CN,0804,简体中文 diff --git a/res/locales/zh_CN.mo b/res/locales/zh_CN.mo new file mode 100644 index 0000000000000000000000000000000000000000..75f043babf759f10c7b88d0eba88c059a2fb1529 GIT binary patch literal 30647 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, 2020. +# +msgid "" +msgstr "" +"Project-Id-Version: SolveSpace 3.0\n" +"Report-Msgid-Bugs-To: whitequark@whitequark.org\n" +"POT-Creation-Date: 2020-09-21 09:28+0200\n" +"PO-Revision-Date: 2020-09-28 12:42+0800\n" +"Last-Translator: lomatus@163.com\n" +"Language-Team: none\n" +"Language: zh_CN\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Generator: Poedit 2.4.1\n" + +#: clipboard.cpp:274 +msgid "" +"Cut, paste, and copy work only in a workplane.\n" +"\n" +"Activate one with Sketch -> In Workplane." +msgstr "" +"仅在工作平面中剪切、粘贴和复制工作。\n" +"\n" +"使用\"工作平面中的草图 -+\"激活一个。" + +#: clipboard.cpp:291 +msgid "Clipboard is empty; nothing to paste." +msgstr "剪贴板为空;没有要粘贴的内容。" + +#: clipboard.cpp:338 +msgid "Number of copies to paste must be at least one." +msgstr "要粘贴的副本数必须至少为 1 个。" + +#: clipboard.cpp:354 textscreens.cpp:783 +msgid "Scale cannot be zero." +msgstr "缩放不能为零。" + +#: clipboard.cpp:396 +msgid "Select one point to define origin of rotation." +msgstr "选择一个点以定义旋转原点。" + +#: clipboard.cpp:408 +msgid "Select two points to define translation vector." +msgstr "选择两个点来定义转换向量。" + +#: clipboard.cpp:418 +msgid "" +"Transformation is identity. So all copies will be exactly on top of each " +"other." +msgstr "转换就是标识,因此所有的复制在彼此之上。" + +#: clipboard.cpp:422 +msgid "Too many items to paste; split this into smaller pastes." +msgstr "要粘贴的项目太多; 请把他们拆分。" + +#: clipboard.cpp:427 +msgid "No workplane active." +msgstr "没有工作平面处于活动状态。" + +#: confscreen.cpp:410 +msgid "Bad format: specify coordinates as x, y, z" +msgstr "格式错误:将坐标指定为 x、y、z" + +#: confscreen.cpp:420 style.cpp:659 textscreens.cpp:805 +msgid "Bad format: specify color as r, g, b" +msgstr "格式错误:将颜色指定为 r、g、b" + +#: confscreen.cpp:446 +msgid "" +"The perspective factor will have no effect until you enable View -> Use " +"Perspective Projection." +msgstr "在启用\"视图 -= 使用透视投影\"之前,透视因子将不起作用。" + +#: confscreen.cpp:459 confscreen.cpp:469 +#, c-format +msgid "Specify between 0 and %d digits after the decimal." +msgstr "在十进制之后指定 0 和 %d 数字之间。" + +#: confscreen.cpp:481 +msgid "Export scale must not be zero!" +msgstr "输出比例不能为零!" + +#: confscreen.cpp:493 +msgid "Cutter radius offset must not be negative!" +msgstr "刀具半径偏移不能为负数!" + +#: confscreen.cpp:547 +msgid "Bad value: autosave interval should be positive" +msgstr "坏值:自动保存间隔应为正" + +#: confscreen.cpp:550 +msgid "Bad format: specify interval in integral minutes" +msgstr "格式错误:以整数分钟为单位指定间隔" + +#: constraint.cpp:12 +msgctxt "constr-name" +msgid "pts-coincident" +msgstr "点约束" + +#: constraint.cpp:13 +msgctxt "constr-name" +msgid "pt-pt-distance" +msgstr "点点间距" + +#: constraint.cpp:14 +msgctxt "constr-name" +msgid "pt-line-distance" +msgstr "线长" + +#: constraint.cpp:15 +msgctxt "constr-name" +msgid "pt-plane-distance" +msgstr "平面具体" + +#: constraint.cpp:16 +msgctxt "constr-name" +msgid "pt-face-distance" +msgstr "面间距" + +#: constraint.cpp:17 +msgctxt "constr-name" +msgid "proj-pt-pt-distance" +msgstr "点点距离" + +#: constraint.cpp:18 +msgctxt "constr-name" +msgid "pt-in-plane" +msgstr "点在面" + +#: constraint.cpp:19 +msgctxt "constr-name" +msgid "pt-on-line" +msgstr "点在线" + +#: constraint.cpp:20 +msgctxt "constr-name" +msgid "pt-on-face" +msgstr "点在面" + +#: constraint.cpp:21 +msgctxt "constr-name" +msgid "eq-length" +msgstr "长度相同" + +#: constraint.cpp:22 +msgctxt "constr-name" +msgid "eq-length-and-pt-ln-dist" +msgstr "长度相等且点在距离" + +#: constraint.cpp:23 +msgctxt "constr-name" +msgid "eq-pt-line-distances" +msgstr "点线距离相等" + +#: constraint.cpp:24 +msgctxt "constr-name" +msgid "length-ratio" +msgstr "长度比率" + +#: constraint.cpp:25 +msgctxt "constr-name" +msgid "length-difference" +msgstr "长度不同" + +#: constraint.cpp:26 +msgctxt "constr-name" +msgid "symmetric" +msgstr "对称的" + +#: constraint.cpp:27 +msgctxt "constr-name" +msgid "symmetric-h" +msgstr "水平对称" + +#: constraint.cpp:28 +msgctxt "constr-name" +msgid "symmetric-v" +msgstr "纵向对称" + +#: constraint.cpp:29 +msgctxt "constr-name" +msgid "symmetric-line" +msgstr "线对称" + +#: constraint.cpp:30 +msgctxt "constr-name" +msgid "at-midpoint" +msgstr "在中点" + +#: constraint.cpp:31 +msgctxt "constr-name" +msgid "horizontal" +msgstr "水平约束" + +#: constraint.cpp:32 +msgctxt "constr-name" +msgid "vertical" +msgstr "垂直约束" + +#: constraint.cpp:33 +msgctxt "constr-name" +msgid "diameter" +msgstr "直径约束" + +#: constraint.cpp:34 +msgctxt "constr-name" +msgid "pt-on-circle" +msgstr "圆点约束" + +#: constraint.cpp:35 +msgctxt "constr-name" +msgid "same-orientation" +msgstr "相同原点" + +#: constraint.cpp:36 +msgctxt "constr-name" +msgid "angle" +msgstr "角度约束" + +#: constraint.cpp:37 +msgctxt "constr-name" +msgid "parallel" +msgstr "平行约束" + +#: constraint.cpp:38 +msgctxt "constr-name" +msgid "arc-line-tangent" +msgstr "弧切线" + +#: constraint.cpp:39 +msgctxt "constr-name" +msgid "cubic-line-tangent" +msgstr "立方体切线" + +#: constraint.cpp:40 +msgctxt "constr-name" +msgid "curve-curve-tangent" +msgstr "曲线间切线" + +#: constraint.cpp:41 +msgctxt "constr-name" +msgid "perpendicular" +msgstr "垂直约束" + +#: constraint.cpp:42 +msgctxt "constr-name" +msgid "eq-radius" +msgstr "等于半径" + +#: constraint.cpp:43 +msgctxt "constr-name" +msgid "eq-angle" +msgstr "等于角度" + +#: constraint.cpp:44 +msgctxt "constr-name" +msgid "eq-line-len-arc-len" +msgstr "等于线长或弧长" + +#: constraint.cpp:45 +msgctxt "constr-name" +msgid "lock-where-dragged" +msgstr "锁定位置" + +#: constraint.cpp:46 +msgctxt "constr-name" +msgid "comment" +msgstr "备注" + +#: constraint.cpp:171 +msgid "" +"Bad selection for distance / diameter constraint. This constraint can apply " +"to:\n" +"\n" +" * two points (distance between points)\n" +" * a line segment (length)\n" +" * two points and a line segment or normal (projected distance)\n" +" * a workplane and a point (minimum distance)\n" +" * a line segment and a point (minimum distance)\n" +" * a plane face and a point (minimum distance)\n" +" * a circle or an arc (diameter)\n" +msgstr "" +"距离/直径约束的选择错误。此约束可应用于:\n" +"\n" +"* 两点(点之间的距离)\n" +" * 线段(长度)\n" +" * 两个点和线段或法线(投影距离)\n" +" * 工作平面和点(最小距离)\n" +" * 线段和点(最小距离)\n" +" * 平面面和点(最小距离)\n" +" * 圆或弧(直径)\n" + +#: constraint.cpp:224 +msgid "" +"Bad selection for on point / curve / plane constraint. This constraint can " +"apply to:\n" +"\n" +" * two points (points coincident)\n" +" * a point and a workplane (point in plane)\n" +" * a point and a line segment (point on line)\n" +" * a point and a circle or arc (point on curve)\n" +" * a point and a plane face (point on face)\n" +msgstr "" +"点 / 曲线 / 平面约束的选定方法错误。此约束可应用于:\n" +"\n" +"* 两点(点重合)\n" +" * 一个点和一个工作平面(平面中点)\n" +" * 点和线段(点在线)\n" +" * 一个点和一个圆或圆(曲线上的点)\n" +" * 点和平面面(点在脸上)\n" + +#: constraint.cpp:286 +msgid "" +"Bad selection for equal length / radius constraint. This constraint can " +"apply to:\n" +"\n" +" * two line segments (equal length)\n" +" * two line segments and two points (equal point-line distances)\n" +" * a line segment and two points (equal point-line distances)\n" +" * a line segment, and a point and line segment (point-line distance " +"equals length)\n" +" * four line segments or normals (equal angle between A,B and C,D)\n" +" * three line segments or normals (equal angle between A,B and B,C)\n" +" * two circles or arcs (equal radius)\n" +" * a line segment and an arc (line segment length equals arc length)\n" +msgstr "" +"等长度/半径约束的选定方法错误。此约束可应用于:\n" +"\n" +"* 两个线段(相等长度)\n" +" * 两个线段和两个点(相等的点线距离)\n" +" * 线段和两个点(相等的点线距离)\n" +" * 线段和点段和线段(点线距离等于长度)\n" +" * 四条线段或法线(A、B 和 C、D 之间的等角)\n" +" * 三条线段或法线(A、B 和 B、C 之间的等角)\n" +" * 两个圆或圆(相等半径)\n" +" * 线段和圆弧(线段长度等于弧长)\n" + +#: constraint.cpp:325 +msgid "" +"Bad selection for length ratio constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +msgstr "" +"长度比率约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个线段\n" + +#: constraint.cpp:342 +msgid "" +"Bad selection for length difference constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments\n" +msgstr "" +"长度差异约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个线段\n" + +#: constraint.cpp:368 +msgid "" +"Bad selection for at midpoint constraint. This constraint can apply to:\n" +"\n" +" * a line segment and a point (point at midpoint)\n" +" * a line segment and a workplane (line's midpoint on plane)\n" +msgstr "" +"中点约束的选定方法错误。此约束可应用于:\n" +"\n" +"* 线段和点(点在中点)\n" +" * 线段和工作平面(平面上的线中点)\n" + +#: constraint.cpp:426 +msgid "" +"Bad selection for symmetric constraint. This constraint can apply to:\n" +"\n" +" * two points or a line segment (symmetric about workplane's coordinate " +"axis)\n" +" * line segment, and two points or a line segment (symmetric about line " +"segment)\n" +" * workplane, and two points or a line segment (symmetric about " +"workplane)\n" +msgstr "" +"对称约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个点或线段(与工作平面的坐标轴对称)\n" +" * 线段,和两个点或线段(对称的线段)\n" +" * 工作平面和两个点或线段(工作平面对称)\n" + +#: constraint.cpp:440 +msgid "" +"A workplane must be active when constraining symmetric without an explicit " +"symmetry plane." +msgstr "在没有显式对称平面约束对称时,工作平面必须处于活动状态。" + +#: constraint.cpp:470 +msgid "" +"Activate a workplane (with Sketch -> In Workplane) before applying a " +"horizontal or vertical constraint." +msgstr "在应用水平或垂直约束之前,激活工作平面(使用草图 -= 在工作平面中)。" + +#: constraint.cpp:483 +msgid "" +"Bad selection for horizontal / vertical constraint. This constraint can " +"apply to:\n" +"\n" +" * two points\n" +" * a line segment\n" +msgstr "" +"水平/垂直约束的选择错误。此约束可应用于:\n" +"\n" +"• 两点\n" +" • 线段\n" + +#: constraint.cpp:504 +msgid "" +"Bad selection for same orientation constraint. This constraint can apply " +"to:\n" +"\n" +" * two normals\n" +msgstr "" +"同一方向约束的选择错误。此约束可应用于:\n" +"\n" +"• 两个法线\n" + +#: constraint.cpp:554 +msgid "Must select an angle constraint." +msgstr "必须选择角度约束。" + +#: constraint.cpp:567 +msgid "Must select a constraint with associated label." +msgstr "必须选择具有关联标签的约束。" + +#: constraint.cpp:578 +msgid "" +"Bad selection for angle constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"角度约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个线段\n" +" * 线段和法线\n" +" • 两个法线\n" + +#: constraint.cpp:635 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "切线弧和线段必须共享一个端点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:659 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"切线立方段和线段必须共享终结点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:669 +msgid "Curve-curve tangency must apply in workplane." +msgstr "曲线曲线切线必须应用于工作平面。" + +#: constraint.cpp:687 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "曲线必须共享一个终结点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:696 +msgid "" +"Bad selection for parallel / tangent constraint. This constraint can apply " +"to:\n" +"\n" +" * two line segments (parallel)\n" +" * a line segment and a normal (parallel)\n" +" * two normals (parallel)\n" +" * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" +msgstr "" +"平行/切线约束的选择错误。此约束可应用于:\n" +"\n" +"* 两条线段(平行)\n" +" * 线段和法线(平行)\n" +" * 两个法线(平行)\n" +" * 共享端点的两条线段、弧线或贝塞尔(切线)\n" + +#: constraint.cpp:714 +msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"垂直约束的选择错误。此约束可应用于:\n" +"\n" +"* 两个线段\n" +" * 线段和法线\n" +" • 两个法线\n" + +#: constraint.cpp:729 +msgid "" +"Bad selection for lock point where dragged constraint. This constraint can " +"apply to:\n" +"\n" +" * a point\n" +msgstr "" +"拖动约束的锁点选择错误。此约束可应用于:\n" +"\n" +"• 一点\n" + +#: constraint.cpp:740 +msgid "click center of comment text" +msgstr "单击注释文本的中心" + +#: export.cpp:19 +msgid "" +"No solid model present; draw one with extrudes and revolves, or use Export " +"2d View to export bare lines and curves." +msgstr "" +"不存在实体模型;使用拉伸和旋转绘制一个,或使用导出 2d 视图导出裸线和曲线。" + +#: export.cpp:61 +msgid "" +"Bad selection for export section. Please select:\n" +"\n" +" * nothing, with an active workplane (workplane is section plane)\n" +" * a face (section plane through face)\n" +" * a point and two line segments (plane through point and parallel to " +"lines)\n" +msgstr "" +"导出部分的选择错误。请选择:\n" +"\n" +"* 无,带活动工作平面(工作平面为剖面平面)\n" +" * 脸(通过面的剖面)\n" +" * 一个点和两个线段(平面穿过点和平行线)\n" + +#: export.cpp:822 +msgid "Active group mesh is empty; nothing to export." +msgstr "活动组网格为空;没有要导出的。" + +#: exportvector.cpp:337 +msgid "freehand lines were replaced with continuous lines" +msgstr "徒手线替换为连续线" + +#: exportvector.cpp:339 +msgid "zigzag lines were replaced with continuous lines" +msgstr "锯齿线替换为连续线" + +#: exportvector.cpp:593 +msgid "" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" +msgstr "绘图的某些方面没有 DXF 等效项,并且未导出:\n" + +#: exportvector.cpp:839 +msgid "" +"PDF page size exceeds 200 by 200 inches; many viewers may reject this file." +msgstr "PDF 页面大小超过 200 英寸或 200 英寸;许多查看器可能会拒绝此文件。" + +#: file.cpp:44 group.cpp:91 +msgctxt "group-name" +msgid "sketch-in-plane" +msgstr "平面草图" + +#: file.cpp:62 +msgctxt "group-name" +msgid "#references" +msgstr "#参考" + +#: file.cpp:549 +msgid "" +"Unrecognized data in file. This file may be corrupt, or from a newer version " +"of the program." +msgstr "未识别文件内数据。该文件可能损坏,或使用新版本应用程序尝试打开。" + +#: file.cpp:849 +msgctxt "title" +msgid "Missing File" +msgstr "文件丢失" + +#: file.cpp:850 +#, c-format +msgctxt "dialog" +msgid "The linked file “%s” is not present." +msgstr "连接的文件不存在:\"%s\"。" + +#: file.cpp:852 +msgctxt "dialog" +msgid "" +"Do you want to locate it manually?\n" +"\n" +"If you decline, any geometry that depends on the missing file will be " +"permanently removed." +msgstr "您是否想手工查找?如果是,所有基于该丢失文件的几何对象将会被全部删除." + +#: file.cpp:855 +msgctxt "button" +msgid "&Yes" +msgstr "是(&Y)" + +#: file.cpp:857 +msgctxt "button" +msgid "&No" +msgstr "否(&N)" + +#: file.cpp:859 +msgctxt "button" +msgid "&Cancel" +msgstr "取消(&C)" + +#: graphicswin.cpp:41 +msgid "&File" +msgstr "文件(&F)" + +#: graphicswin.cpp:42 +msgid "&New" +msgstr "新建(&N)" + +#: graphicswin.cpp:43 +msgid "&Open..." +msgstr "打开(&O)" + +#: graphicswin.cpp:44 +msgid "Open &Recent" +msgstr "打开最近使用(&R)" + +#: graphicswin.cpp:45 +msgid "&Save" +msgstr "保存(&S)" + +#: graphicswin.cpp:46 +msgid "Save &As..." +msgstr "另存为(&A)" + +#: graphicswin.cpp:48 +msgid "Export &Image..." +msgstr "导出图片(&I)" + +#: graphicswin.cpp:49 +msgid "Export 2d &View..." +msgstr "导出2D视图(&V)" + +#: graphicswin.cpp:50 +msgid "Export 2d &Section..." +msgstr "导出2D截面(&S)" + +#: graphicswin.cpp:51 +msgid "Export 3d &Wireframe..." +msgstr "导出3D线框模型(&W)" + +#: graphicswin.cpp:52 +msgid "Export Triangle &Mesh..." +msgstr "导出三角面模型(&M)" + +#: graphicswin.cpp:53 +msgid "Export &Surfaces..." +msgstr "导出表面模型(&S)" + +#: graphicswin.cpp:54 +msgid "Im&port..." +msgstr "导入(&P)" + +#: graphicswin.cpp:57 +msgid "E&xit" +msgstr "退出(&E)" + +#: graphicswin.cpp:60 +msgid "&Edit" +msgstr "编辑(&E)" + +#: graphicswin.cpp:61 +msgid "&Undo" +msgstr "回退(&U)" + +#: graphicswin.cpp:62 +msgid "&Redo" +msgstr "重做(&R)" + +#: graphicswin.cpp:63 +msgid "Re&generate All" +msgstr "重新生成所有(&G)" + +#: graphicswin.cpp:65 +msgid "Snap Selection to &Grid" +msgstr "选择到轴线(&G)" + +#: graphicswin.cpp:66 +msgid "Rotate Imported &90°" +msgstr "旋转导入模型90° (&9)" + +#: graphicswin.cpp:68 +msgid "Cu&t" +msgstr "剪切 (&T)" + +#: graphicswin.cpp:69 +msgid "&Copy" +msgstr "复制 (&C)" + +#: graphicswin.cpp:70 +msgid "&Paste" +msgstr "粘贴 (&P)" + +#: graphicswin.cpp:71 +msgid "Paste &Transformed..." +msgstr "粘贴移动(&T)" + +#: graphicswin.cpp:72 +msgid "&Delete" +msgstr "删除(&D)" + +#: graphicswin.cpp:74 +msgid "Select &Edge Chain" +msgstr "选择边缘约束(&E)" + +#: graphicswin.cpp:75 +msgid "Select &All" +msgstr "选择所有(&A)" + +#: graphicswin.cpp:76 +msgid "&Unselect All" +msgstr "取消全选(&U)" + +#: graphicswin.cpp:78 +msgid "&Line Styles..." +msgstr "线型(&L)" + +#: graphicswin.cpp:79 +msgid "&View Projection..." +msgstr "查看投影...(&V)" + +#: graphicswin.cpp:81 +msgid "Con&figuration..." +msgstr "配置 (&F)" + +#: graphicswin.cpp:84 +msgid "&View" +msgstr "查看 (&V)" + +#: graphicswin.cpp:85 +msgid "Zoom &In" +msgstr "放大(&I)" + +#: graphicswin.cpp:86 +msgid "Zoom &Out" +msgstr "缩小(&O)" + +#: graphicswin.cpp:87 +msgid "Zoom To &Fit" +msgstr "自动缩放(&F)" + +#: graphicswin.cpp:89 +msgid "Align View to &Workplane" +msgstr "切换视图至平面(&W)" + +#: graphicswin.cpp:90 +msgid "Nearest &Ortho View" +msgstr "Ortho视图 (&O)" + +#: graphicswin.cpp:91 +msgid "Nearest &Isometric View" +msgstr "ISO视图 (&I)" + +#: graphicswin.cpp:92 +msgid "&Center View At Point" +msgstr "以点为中心视图 (&C)" + +#: graphicswin.cpp:94 +msgid "Show Snap &Grid" +msgstr "显示捕捉轴线 (&G)" + +#: graphicswin.cpp:95 +msgid "Use &Perspective Projection" +msgstr "使用远景透视(&P)" + +#: graphicswin.cpp:96 +msgid "Dimension &Units" +msgstr "标注单位(&U)" + +#: graphicswin.cpp:97 +msgid "Dimensions in &Millimeters" +msgstr "标注单位 mm (&M)" + +#: graphicswin.cpp:98 +msgid "Dimensions in M&eters" +msgstr "标注单位m (&E)" + +#: graphicswin.cpp:99 +msgid "Dimensions in &Inches" +msgstr "标准单位英寸 (&I)" + +#: graphicswin.cpp:101 +msgid "Show &Toolbar" +msgstr "显示工具条(&T)" + +#: graphicswin.cpp:102 +msgid "Show Property Bro&wser" +msgstr "显示属性浏览器(&W)" + +#: graphicswin.cpp:104 +msgid "&Full Screen" +msgstr "全屏(&F)" + +#: graphicswin.cpp:106 +msgid "&New Group" +msgstr "新组合(&N)" + +#: graphicswin.cpp:107 +msgid "Sketch In &3d" +msgstr "在三维内绘制(&3)" + +#: graphicswin.cpp:108 +msgid "Sketch In New &Workplane" +msgstr "在新工作面绘制(&W)" + +#: graphicswin.cpp:110 +msgid "Step &Translating" +msgstr "移动(&T)" + +#: graphicswin.cpp:111 +msgid "Step &Rotating" +msgstr "旋转(&R)" + +#: graphicswin.cpp:113 +msgid "E&xtrude" +msgstr "挤出(&E)" + +#: graphicswin.cpp:114 +msgid "&Helix" +msgstr "螺旋(&H)" + +#: graphicswin.cpp:115 +msgid "&Lathe" +msgstr "扫略(&L)" + +#: graphicswin.cpp:116 +msgid "Re&volve" +msgstr "旋转(&V)" + +#: graphicswin.cpp:118 +msgid "Link / Assemble..." +msgstr "链接/装配..." + +#: graphicswin.cpp:119 +msgid "Link Recent" +msgstr "连接最近文件" + +#: graphicswin.cpp:121 +msgid "&Sketch" +msgstr "绘图(&S)" + +#: graphicswin.cpp:122 +msgid "In &Workplane" +msgstr "在工作平面(&W)" + +#: graphicswin.cpp:123 +msgid "Anywhere In &3d" +msgstr "在3D的任何位置(&3)" + +#: graphicswin.cpp:125 +msgid "Datum &Point" +msgstr "基准点(&P)" + +#: graphicswin.cpp:126 +msgid "&Workplane" +msgstr "工作面(&W)" + +#: graphicswin.cpp:128 +msgid "Line &Segment" +msgstr "线段(&S)" + +#: graphicswin.cpp:129 +msgid "C&onstruction Line Segment" +msgstr "构造线段(&C)" + +#: graphicswin.cpp:130 +msgid "&Rectangle" +msgstr "矩形(&R)" + +#: graphicswin.cpp:131 +msgid "&Circle" +msgstr "圆线(&C)" + +#: graphicswin.cpp:132 +msgid "&Arc of a Circle" +msgstr "圆弧(&A)" + +#: graphicswin.cpp:133 +msgid "&Bezier Cubic Spline" +msgstr "立方体线的贝塞尔曲线(&B)" + +#: graphicswin.cpp:135 +msgid "&Text in TrueType Font" +msgstr "TrueTyoe字体文字(&T)" + +#: graphicswin.cpp:136 +msgid "&Image" +msgstr "图片(&I)" + +#: graphicswin.cpp:138 +msgid "To&ggle Construction" +msgstr "切换构造(&G)" + +#: graphicswin.cpp:139 +msgid "Tangent &Arc at Point" +msgstr "弧线切线点(&A)" + +#: graphicswin.cpp:140 +msgid "Split Curves at &Intersection" +msgstr "在交叉处拆分曲线(&I)" + +#: graphicswin.cpp:142 +msgid "&Constrain" +msgstr "约束(&C)" + +#: graphicswin.cpp:143 +msgid "&Distance / Diameter" +msgstr "距离/直径(&D)" + +#: graphicswin.cpp:144 +msgid "Re&ference Dimension" +msgstr "参考标注(&F)" + +#: graphicswin.cpp:145 +msgid "A&ngle" +msgstr "角度(&A)" + +#: graphicswin.cpp:146 +msgid "Reference An&gle" +msgstr "参考角度(&G)" + +#: graphicswin.cpp:147 +msgid "Other S&upplementary Angle" +msgstr "其它增补角度(&U)" + +#: graphicswin.cpp:148 +msgid "Toggle R&eference Dim" +msgstr "切换参考标注(&E)" + +#: graphicswin.cpp:150 +msgid "&Horizontal" +msgstr "水平约束(&H)" + +#: graphicswin.cpp:151 +msgid "&Vertical" +msgstr "垂直约束(&V)" + +#: graphicswin.cpp:153 +msgid "&On Point / Curve / Plane" +msgstr "在点线面(&O)" + +#: graphicswin.cpp:154 +msgid "E&qual Length / Radius / Angle" +msgstr "等于/长度/半径/角度(&Q)" + +#: graphicswin.cpp:155 +msgid "Length Ra&tio" +msgstr "长度比例(&T)" + +#: graphicswin.cpp:156 +msgid "Length Diff&erence" +msgstr "长度偏差(&E)" + +#: graphicswin.cpp:157 +msgid "At &Midpoint" +msgstr "在中点(&M)" + +#: graphicswin.cpp:158 +msgid "S&ymmetric" +msgstr "对称(&Y)" + +#: graphicswin.cpp:159 +msgid "Para&llel / Tangent" +msgstr "水平/切线(&L)" + +#: graphicswin.cpp:160 +msgid "&Perpendicular" +msgstr "垂直的(&P)" + +#: graphicswin.cpp:161 +msgid "Same Orient&ation" +msgstr "相同方向(&A)" + +#: graphicswin.cpp:162 +msgid "Lock Point Where &Dragged" +msgstr "锁定点位置(&D)" + +#: graphicswin.cpp:164 +msgid "Comment" +msgstr "备注" + +#: graphicswin.cpp:166 +msgid "&Analyze" +msgstr "分析(&A)" + +#: graphicswin.cpp:167 +msgid "Measure &Volume" +msgstr "测量体积(&V)" + +#: graphicswin.cpp:168 +msgid "Measure A&rea" +msgstr "测量面积(&R)" + +#: graphicswin.cpp:169 +msgid "Measure &Perimeter" +msgstr "测量周长(&P)" + +#: graphicswin.cpp:170 +msgid "Show &Interfering Parts" +msgstr "显示干涉零件(&I)" + +#: graphicswin.cpp:171 +msgid "Show &Naked Edges" +msgstr "显示孤立边(&N)" + +#: graphicswin.cpp:172 +msgid "Show &Center of Mass" +msgstr "显示中心(&C)" + +#: graphicswin.cpp:174 +msgid "Show &Underconstrained Points" +msgstr "显示无效约束点(&U)" + +#: graphicswin.cpp:176 +msgid "&Trace Point" +msgstr "跟踪点(&T)" + +#: graphicswin.cpp:177 +msgid "&Stop Tracing..." +msgstr "停止跟踪(&S)" + +#: graphicswin.cpp:178 +msgid "Step &Dimension..." +msgstr "逐步标注(&D)" + +#: graphicswin.cpp:180 +msgid "&Help" +msgstr "帮助(&H)" + +#: graphicswin.cpp:181 +msgid "&Language" +msgstr "语言(&L)" + +#: graphicswin.cpp:182 +msgid "&Website / Manual" +msgstr "网页/手册(&W)" + +#: graphicswin.cpp:184 +msgid "&About" +msgstr "关于(&A)" + +#: graphicswin.cpp:352 +msgid "(no recent files)" +msgstr "(无文件)" + +#: graphicswin.cpp:360 +#, c-format +msgid "File '%s' does not exist." +msgstr "文件不存在: \"%s\"。" + +#: graphicswin.cpp:721 +msgid "No workplane is active, so the grid will not appear." +msgstr "没有激活的工作面,因此无法显示轴网。" + +#: graphicswin.cpp:730 +msgid "" +"The perspective factor is set to zero, so the view will always be a parallel " +"projection.\n" +"\n" +"For a perspective projection, modify the perspective factor in the " +"configuration screen. A value around 0.3 is typical." +msgstr "" + +#: graphicswin.cpp:809 +msgid "" +"Select a point; this point will become the center of the view on screen." +msgstr "" + +#: graphicswin.cpp:1103 +msgid "No additional entities share endpoints with the selected entities." +msgstr "" + +#: graphicswin.cpp:1121 +msgid "" +"To use this command, select a point or other entity from an linked part, or " +"make a link group the active group." +msgstr "" + +#: graphicswin.cpp:1144 +msgid "" +"No workplane is active. Activate a workplane (with Sketch -> In Workplane) " +"to define the plane for the snap grid." +msgstr "" + +#: graphicswin.cpp:1151 +msgid "" +"Can't snap these items to grid; select points, text comments, or constraints " +"with a label. To snap a line, select its endpoints." +msgstr "" + +#: graphicswin.cpp:1239 +msgid "No workplane selected. Activating default workplane for this group." +msgstr "" + +#: graphicswin.cpp:1242 +msgid "" +"No workplane is selected, and the active group does not have a default " +"workplane. Try selecting a workplane, or activating a sketch-in-new-" +"workplane group." +msgstr "" + +#: graphicswin.cpp:1263 +msgid "" +"Bad selection for tangent arc at point. Select a single point, or select " +"nothing to set up arc parameters." +msgstr "" + +#: graphicswin.cpp:1274 +msgid "click point on arc (draws anti-clockwise)" +msgstr "点击弧线的点(逆时针方向绘制)" + +#: graphicswin.cpp:1275 +msgid "click to place datum point" +msgstr "点击放置基准点" + +#: graphicswin.cpp:1276 +msgid "click first point of line segment" +msgstr "点击线条的起点" + +#: graphicswin.cpp:1278 +msgid "click first point of construction line segment" +msgstr "点击构造线的起点" + +#: graphicswin.cpp:1279 +msgid "click first point of cubic segment" +msgstr "点击立方体的起点" + +#: graphicswin.cpp:1280 +msgid "click center of circle" +msgstr "点击圆弧的中心" + +#: graphicswin.cpp:1281 +msgid "click origin of workplane" +msgstr "点击工作面的原点" + +#: graphicswin.cpp:1282 +msgid "click one corner of rectangle" +msgstr "点击一个矩形倒角" + +#: graphicswin.cpp:1283 +msgid "click top left of text" +msgstr "点击文字左上角" + +#: graphicswin.cpp:1289 +msgid "click top left of image" +msgstr "点击图片左上角" + +#: graphicswin.cpp:1301 +msgid "" +"No entities are selected. Select entities before trying to toggle their " +"construction state." +msgstr "为选中实体,切换构造状态前请先选中实体对象。" + +#: group.cpp:86 +msgctxt "group-name" +msgid "sketch-in-3d" +msgstr "3D草图" + +#: group.cpp:142 +msgid "" +"Bad selection for new sketch in workplane. This group can be created with:\n" +"\n" +" * a point (through the point, orthogonal to coordinate axes)\n" +" * a point and two line segments (through the point, parallel to the " +"lines)\n" +" * a workplane (copy of the workplane)\n" +msgstr "" +"在新工作面内绘图选择失败,该组可以使用:\n" +"\n" +" * 一个点(通过该点,正交至坐标轴)\n" +" * 一个点和二个线段(通过点,绘制平行线至线段)\n" +" * 一个工作面(复制工作面)\n" + +#: group.cpp:154 +msgid "" +"Activate a workplane (Sketch -> In Workplane) before extruding. The sketch " +"will be extruded normal to the workplane." +msgstr "挤出前先激活工作面(草图->在工作面),该草图将由工作面的法线方向挤出。" + +#: group.cpp:163 +msgctxt "group-name" +msgid "extrude" +msgstr "挤出" + +#: group.cpp:168 +msgid "Lathe operation can only be applied to planar sketches." +msgstr "扫略操作仅可用于二维草图。" + +#: group.cpp:179 +msgid "" +"Bad selection for new lathe group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" +"创建扫略组失败,该组可由:\n" +"\n" +" * 一个点和一个线段或法线(围绕坐标轴至线或法线的平行线,通过点)\n" +" * 一个线段(围绕线段)\n" + +#: group.cpp:189 +msgctxt "group-name" +msgid "lathe" +msgstr "扫略" + +#: group.cpp:194 +msgid "Revolve operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:205 +msgid "" +"Bad selection for new revolve group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:217 +msgctxt "group-name" +msgid "revolve" +msgstr "旋转" + +#: group.cpp:222 +msgid "Helix operation can only be applied to planar sketches." +msgstr "" + +#: group.cpp:233 +msgid "" +"Bad selection for new helix group. This group can be created with:\n" +"\n" +" * a point and a line segment or normal (revolved about an axis parallel " +"to line / normal, through point)\n" +" * a line segment (revolved about line segment)\n" +msgstr "" + +#: group.cpp:245 +msgctxt "group-name" +msgid "helix" +msgstr "螺旋" + +#: group.cpp:258 +msgid "" +"Bad selection for new rotation. This group can be created with:\n" +"\n" +" * a point, while locked in workplane (rotate in plane, about that " +"point)\n" +" * a point and a line or a normal (rotate about an axis through the " +"point, and parallel to line / normal)\n" +msgstr "" + +#: group.cpp:271 +msgctxt "group-name" +msgid "rotate" +msgstr "旋转" + +#: group.cpp:282 +msgctxt "group-name" +msgid "translate" +msgstr "移动" + +#: group.cpp:400 +msgid "(unnamed)" +msgstr "(未命名)" + +#: groupmesh.cpp:689 +msgid "not closed contour, or not all same style!" +msgstr "未闭合轮廓,或样式不一致!" + +#: groupmesh.cpp:702 +msgid "points not all coplanar!" +msgstr "点不在相同平面!" + +#: groupmesh.cpp:704 +msgid "contour is self-intersecting!" +msgstr "轮廓自相交!" + +#: groupmesh.cpp:706 +msgid "zero-length edge!" +msgstr "边缘长度为零!" + +#: modify.cpp:254 +msgid "Must be sketching in workplane to create tangent arc." +msgstr "" + +#: modify.cpp:301 +msgid "" +"To create a tangent arc, select a point where two non-construction lines or " +"circles in this group and workplane join." +msgstr "" + +#: modify.cpp:388 +msgid "" +"Couldn't round this corner. Try a smaller radius, or try creating the " +"desired geometry by hand with tangency constraints." +msgstr "" + +#: modify.cpp:597 +msgid "Couldn't split this entity; lines, circles, or cubics only." +msgstr "" + +#: modify.cpp:624 +msgid "Must be sketching in workplane to split." +msgstr "" + +#: modify.cpp:631 +msgid "" +"Select two entities that intersect each other (e.g. two lines/circles/arcs " +"or a line/circle/arc and a point)." +msgstr "" + +#: modify.cpp:736 +msgid "Can't split; no intersection found." +msgstr "无法拆分;未发现较差点。" + +#: mouse.cpp:560 +msgid "Assign to Style" +msgstr "指定样式" + +#: mouse.cpp:576 +msgid "No Style" +msgstr "无样式" + +#: mouse.cpp:579 +msgid "Newly Created Custom Style..." +msgstr "新组样式。" + +#: mouse.cpp:586 +msgid "Group Info" +msgstr "组信息" + +#: mouse.cpp:606 +msgid "Style Info" +msgstr "样式信息" + +#: mouse.cpp:626 +msgid "Select Edge Chain" +msgstr "选择边缘链" + +#: mouse.cpp:632 +msgid "Toggle Reference Dimension" +msgstr "切换参考标注" + +#: mouse.cpp:638 +msgid "Other Supplementary Angle" +msgstr "其它补充角度" + +#: mouse.cpp:643 +msgid "Snap to Grid" +msgstr "捕捉至轴网" + +#: mouse.cpp:652 +msgid "Remove Spline Point" +msgstr "删除样条线的点" + +#: mouse.cpp:687 +msgid "Add Spline Point" +msgstr "增加样条线的点" + +#: mouse.cpp:691 +msgid "Cannot add spline point: maximum number of points reached." +msgstr "无法增加样条线点:超过最大限制。" + +#: mouse.cpp:716 +msgid "Toggle Construction" +msgstr "切换构造" + +#: mouse.cpp:731 +msgid "Delete Point-Coincident Constraint" +msgstr "删除点一致约束" + +#: mouse.cpp:750 +msgid "Cut" +msgstr "剪切" + +#: mouse.cpp:752 +msgid "Copy" +msgstr "复制" + +#: mouse.cpp:756 +msgid "Select All" +msgstr "全选" + +#: mouse.cpp:761 +msgid "Paste" +msgstr "粘贴" + +#: mouse.cpp:763 +msgid "Paste Transformed..." +msgstr "粘贴移动的..." + +#: mouse.cpp:768 +msgid "Delete" +msgstr "删除" + +#: mouse.cpp:771 +msgid "Unselect All" +msgstr "取消全选" + +#: mouse.cpp:778 +msgid "Unselect Hovered" +msgstr "取消覆盖区域的全选" + +#: mouse.cpp:787 +msgid "Zoom to Fit" +msgstr "自动缩放" + +#: mouse.cpp:990 mouse.cpp:1277 +msgid "click next point of line, or press Esc" +msgstr "点击下一个点或取消(ESC)" + +#: mouse.cpp:996 +msgid "" +"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "无法在3D内绘制矩形; 首先,激活工作面,草图->在工作面。" + +#: mouse.cpp:1030 +msgid "click to place other corner of rectangle" +msgstr "点击放置其它矩形倒角" + +#: mouse.cpp:1050 +msgid "click to set radius" +msgstr "点击设置半径" + +#: mouse.cpp:1055 +msgid "" +"Can't draw arc in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "无法在3D空间内绘制弧线,可使用 草图->在工作面 激活工作面。" + +#: mouse.cpp:1074 +msgid "click to place point" +msgstr "点击放置点" + +#: mouse.cpp:1090 +msgid "click next point of cubic, or press Esc" +msgstr "点击下一个点或取消(ESC)" + +#: mouse.cpp:1095 +msgid "" +"Sketching in a workplane already; sketch in 3d before creating new workplane." +msgstr "已经在工作面绘制;在新建工作面前在三维空间绘制。" + +#: mouse.cpp:1111 +msgid "" +"Can't draw text in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "无法在三维空间内绘制文字,可使用 草图->在工作面 激活工作面。" + +#: mouse.cpp:1128 +msgid "click to place bottom right of text" +msgstr "点击文字的右下角放置" + +#: mouse.cpp:1134 +msgid "" +"Can't draw image in 3d; first, activate a workplane with Sketch -> In " +"Workplane." +msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 激活工作面。" + +#: mouse.cpp:1161 +msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" +msgstr "新备注 - 双击编辑" + +#: platform/gui.cpp:85 +msgctxt "file-type" +msgid "SolveSpace models" +msgstr "SolveSpace模型" + +#: platform/gui.cpp:89 +msgctxt "file-type" +msgid "PNG image" +msgstr "PNG图片" + +#: platform/gui.cpp:93 +msgctxt "file-type" +msgid "STL mesh" +msgstr "STL网格" + +#: platform/gui.cpp:94 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "Wavefront OBJ网格" + +#: platform/gui.cpp:95 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "Three.js-网格及查看视图" + +#: platform/gui.cpp:96 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "Three.js-仅网格" + +#: platform/gui.cpp:97 +msgctxt "file-type" +msgid "Q3D Object file" +msgstr "Q3D对象文件" + +#: platform/gui.cpp:98 +msgctxt "file-type" +msgid "VRML text file" +msgstr "VRML文本文件" + +#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116 +msgctxt "file-type" +msgid "STEP file" +msgstr "STEP文件" + +#: platform/gui.cpp:106 +msgctxt "file-type" +msgid "PDF file" +msgstr "PDF文件" + +#: platform/gui.cpp:107 +msgctxt "file-type" +msgid "Encapsulated PostScript" +msgstr "封装好的PostScript" + +#: platform/gui.cpp:108 +msgctxt "file-type" +msgid "Scalable Vector Graphics" +msgstr "SVG矢量图" + +#: platform/gui.cpp:110 platform/gui.cpp:117 +msgctxt "file-type" +msgid "DXF file (AutoCAD 2007)" +msgstr "DXF文件(AutoCAD 2007)" + +#: platform/gui.cpp:111 +msgctxt "file-type" +msgid "HPGL file" +msgstr "HPGL文件" + +#: platform/gui.cpp:112 +msgctxt "file-type" +msgid "G Code" +msgstr "G Code" + +#: platform/gui.cpp:121 +msgctxt "file-type" +msgid "AutoCAD DXF and DWG files" +msgstr "AutoCAD DXF/DWG文件" + +#: platform/gui.cpp:125 +msgctxt "file-type" +msgid "Comma-separated values" +msgstr "逗号分隔数据" + +#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608 +msgid "untitled" +msgstr "未命名" + +#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305 +#: platform/guiwin.cpp:1555 +msgctxt "title" +msgid "Save File" +msgstr "保存文件" + +#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288 +#: platform/guiwin.cpp:1557 +msgctxt "title" +msgid "Open File" +msgstr "打开文件" + +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1368 +msgctxt "button" +msgid "_Cancel" +msgstr "取消_C" + +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 +msgctxt "button" +msgid "_Save" +msgstr "保存_S" + +#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 +msgctxt "button" +msgid "_Open" +msgstr "打开_O" + +#: style.cpp:166 +msgid "" +"Can't assign style to an entity that's derived from another entity; try " +"assigning a style to this entity's parent." +msgstr "无法将样式分配给派生自其他实体的实体;尝试将样式分配给此实体的父级。" + +#: style.cpp:665 +msgid "Style name cannot be empty" +msgstr "样式名称不能为空" + +#: textscreens.cpp:741 +msgid "Can't repeat fewer than 1 time." +msgstr "不能重复少于 1 次。" + +#: textscreens.cpp:745 +msgid "Can't repeat more than 999 times." +msgstr "重复不超过 999 次。" + +#: textscreens.cpp:770 +msgid "Group name cannot be empty" +msgstr "组名称不能为空" + +#: textscreens.cpp:813 +msgid "Opacity must be between zero and one." +msgstr "不透明度必须在零和 1 之间。" + +#: textscreens.cpp:848 +msgid "Radius cannot be zero or negative." +msgstr "半径偏移不能为负数。" + +#: toolbar.cpp:18 +msgid "Sketch line segment" +msgstr "草图线段" + +#: toolbar.cpp:20 +msgid "Sketch rectangle" +msgstr "草图矩形" + +#: toolbar.cpp:22 +msgid "Sketch circle" +msgstr "草图圆" + +#: toolbar.cpp:24 +msgid "Sketch arc of a circle" +msgstr "圆的草图弧线" + +#: toolbar.cpp:26 +msgid "Sketch curves from text in a TrueType font" +msgstr "从 TrueType 字体中的文本中绘制草图曲线" + +#: toolbar.cpp:28 +msgid "Sketch image from a file" +msgstr "从文件中绘制图像" + +#: toolbar.cpp:30 +msgid "Create tangent arc at selected point" +msgstr "在选定点创建切线弧" + +#: toolbar.cpp:32 +msgid "Sketch cubic Bezier spline" +msgstr "草图立方贝塞尔样条" + +#: toolbar.cpp:34 +msgid "Sketch datum point" +msgstr "草图基准点" + +#: toolbar.cpp:36 +msgid "Toggle construction" +msgstr "切换结构" + +#: toolbar.cpp:38 +msgid "Split lines / curves where they intersect" +msgstr "相交的分割线/曲线" + +#: toolbar.cpp:42 +msgid "Constrain distance / diameter / length" +msgstr "约束距离/直径/长度" + +#: toolbar.cpp:44 +msgid "Constrain angle" +msgstr "约束角度" + +#: toolbar.cpp:46 +msgid "Constrain to be horizontal" +msgstr "约束为水平" + +#: toolbar.cpp:48 +msgid "Constrain to be vertical" +msgstr "约束为垂直" + +#: toolbar.cpp:50 +msgid "Constrain to be parallel or tangent" +msgstr "约束为平行或切线" + +#: toolbar.cpp:52 +msgid "Constrain to be perpendicular" +msgstr "约束至垂直" + +#: toolbar.cpp:54 +msgid "Constrain point on line / curve / plane / point" +msgstr "约束点至线/曲线/平面/点" + +#: toolbar.cpp:56 +msgid "Constrain symmetric" +msgstr "对称约束" + +#: toolbar.cpp:58 +msgid "Constrain equal length / radius / angle" +msgstr "约束长/半径/角度相等" + +#: toolbar.cpp:60 +msgid "Constrain normals in same orientation" +msgstr "约束法线在同原点" + +#: toolbar.cpp:62 +msgid "Other supplementary angle" +msgstr "其它补充角度" + +#: toolbar.cpp:64 +msgid "Toggle reference dimension" +msgstr "切换参考标注" + +#: toolbar.cpp:68 +msgid "New group extruding active sketch" +msgstr "新组中挤出当前草图" + +#: toolbar.cpp:70 +msgid "New group rotating active sketch" +msgstr "新组中旋转体当前草图" + +#: toolbar.cpp:72 +msgid "New group step and repeat rotating" +msgstr "新组中逐步重复旋转体" + +#: toolbar.cpp:74 +msgid "New group step and repeat translating" +msgstr "新组中逐步重复移动体" + +#: toolbar.cpp:76 +msgid "New group in new workplane (thru given entities)" +msgstr "在新工作平面创建组(通过指定对象)" + +#: toolbar.cpp:78 +msgid "New group in 3d" +msgstr "在3D中新建组" + +#: toolbar.cpp:80 +msgid "New group linking / assembling file" +msgstr "新组 连接/装配文件" + +#: toolbar.cpp:84 +msgid "Nearest isometric view" +msgstr "ISO视图" + +#: toolbar.cpp:86 +msgid "Align view to active workplane" +msgstr "切换视图至当前工作面" + +#: util.cpp:165 +msgctxt "title" +msgid "Error" +msgstr "错误" + +#: util.cpp:165 +msgctxt "title" +msgid "Message" +msgstr "消息" + +#: util.cpp:170 +msgctxt "button" +msgid "&OK" +msgstr "&OK" + +#: view.cpp:78 +msgid "Scale cannot be zero or negative." +msgstr "缩放不能为零。" + +#: view.cpp:90 view.cpp:99 +msgid "Bad format: specify x, y, z" +msgstr "格式错误: 需指定 x, y, z" From 6b5936b2f6fe8ecff6a09d4c73673f6a31a478f1 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Tue, 20 Oct 2020 11:11:43 -0400 Subject: [PATCH 015/113] remove zh_CN.mo --- res/locales/zh_CN.mo | Bin 30647 -> 0 bytes 1 file changed, 0 insertions(+), 0 deletions(-) delete mode 100644 res/locales/zh_CN.mo diff --git a/res/locales/zh_CN.mo b/res/locales/zh_CN.mo deleted file mode 100644 index 75f043babf759f10c7b88d0eba88c059a2fb1529..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30647 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 Date: Wed, 14 Oct 2020 20:27:56 -0400 Subject: [PATCH 016/113] Add vertexes to curve intersection list in addition to surface intersections. Sometimes a vertex can be used to split a curve where surface intersections can't. Those unsplit curves can cause boolean failures. --- src/srf/boolean.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 47 insertions(+), 3 deletions(-) diff --git a/src/srf/boolean.cpp b/src/srf/boolean.cpp index b0b175da..7789b8de 100644 --- a/src/srf/boolean.cpp +++ b/src/srf/boolean.cpp @@ -20,6 +20,32 @@ void SShell::MakeFromIntersectionOf(SShell *a, SShell *b) { MakeFromBoolean(a, b, SSurface::CombineAs::INTERSECTION); } +// We will be inserting existing verticies into curves to split them +// todo: this is only using the ends of exact curves, and it is only +// using them to split existing curves, not new intersections. +// It resolves some issues but we could do better. We will need to +// reorder things so the surface intersection curves exist prior to +// splitting any curves at all in order to have their verticies too. +// Better still would be to get curve/surface intersection to work +// more reliably at the edges - maybe do curve/curve tests as part +// of the curve-surface intersection test. +static void FindVertsOnCurve(List *l, const SCurve *curve, SShell *sh) { + for(auto sc : sh->curve) { + if(!sc.isExact) continue; + for(int i=0; i<2; i++) { + Vector pt = sc.exact.ctrl[ i==0 ? 0 : sc.exact.deg ]; + double t; + curve->exact.ClosestPointTo(pt, &t, /*must converge=*/ false); + double d = pt.Minus(curve->exact.PointAt(t)).Magnitude(); + if((t>LENGTH_EPS) && (t<(1.0-LENGTH_EPS)) && (d < LENGTH_EPS)) { + SInter inter; + inter.p = pt; + l->Add(&inter); + } + } + } +} + //----------------------------------------------------------------------------- // Take our original pwl curve. Wherever an edge intersects a surface within // either agnstA or agnstB, split the piecewise linear element. Then refine @@ -35,12 +61,19 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, ret = *this; ret.pts = {}; + // First find any vertex that lies on our curve. + List vertpts = {}; + if(agnstA) + FindVertsOnCurve(&vertpts, this, agnstA); + if(agnstB) + FindVertsOnCurve(&vertpts, this, agnstB); + const SCurvePt *p = pts.First(); ssassert(p != NULL, "Cannot split an empty curve"); SCurvePt prev = *p; ret.pts.Add(p); p = pts.NextAfter(p); - + for(; p; p = pts.NextAfter(p)) { List il = {}; @@ -100,12 +133,22 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, pi->p = (pi->srf)->PointAt(puv); } il.RemoveTagged(); + } + // Now add any vertex that is on this segment + const Vector lineStart = prev.p; + const Vector lineDirection = (p->p).Minus(prev.p); + for(auto vtx : vertpts) { + double t = (vtx.p.Minus(lineStart)).DivProjected(lineDirection); + if((0.0 < t) && (t < 1.0)) { + il.Add(&vtx); + } + } + if(!il.IsEmpty()) { + SInter *pi; // And now sort them in order along the line. Note that we must // do that after refining, in case the refining would make two // points switch places. - const Vector lineStart = prev.p; - const Vector lineDirection = (p->p).Minus(prev.p); std::sort(il.begin(), il.end(), [&](const SInter &a, const SInter &b) { double ta = (a.p.Minus(lineStart)).DivProjected(lineDirection); double tb = (b.p.Minus(lineStart)).DivProjected(lineDirection); @@ -133,6 +176,7 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, ret.pts.Add(p); prev = *p; } + vertpts.Clear(); return ret; } From f3f33d3f2692a8e7b3551ee7469997c05176d10e Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Tue, 20 Oct 2020 17:31:26 +0200 Subject: [PATCH 017/113] Travis: optimize macOS deploy build - Turns on the -DENABLE_LTO flag during deploy - Turns off the -DENABLE_OPENMP flag during test --- .travis/build-macos.sh | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh index a9f39c4f..aca078f1 100755 --- a/.travis/build-macos.sh +++ b/.travis/build-macos.sh @@ -1,14 +1,9 @@ #!/bin/sh -xe -if echo $TRAVIS_TAG | grep ^v; then - BUILD_TYPE=RelWithDebInfo -else - BUILD_TYPE=Debug -fi - mkdir build || true cd build +OSX_TARGET="10.9" LLVM_PREFIX=$(brew --prefix llvm@9) export CC="${LLVM_PREFIX}/bin/clang" export CXX="${CC}++" @@ -16,10 +11,19 @@ export LDFLAGS="-L${LLVM_PREFIX}/lib -Wl,-rpath,${LLVM_PREFIX}/lib" \ export CFLAGS="-I${LLVM_PREFIX}/include" export CPPFLAGS="-I${LLVM_PREFIX}/include" -cmake \ - -DCMAKE_OSX_DEPLOYMENT_TARGET=10.9 \ - -DCMAKE_BUILD_TYPE=$BUILD_TYPE .. \ - -DENABLE_OPENMP=ON +if echo $TRAVIS_TAG | grep ^v; then + BUILD_TYPE=RelWithDebInfo + cmake \ + -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_TARGET}" \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. \ + -DENABLE_OPENMP=ON \ + -DENABLE_LTO=ON +else + BUILD_TYPE=Debug + cmake \ + -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_TARGET}" \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. +fi -cmake --build . --config $BUILD_TYPE -- -j$(nproc) +cmake --build . --config "${BUILD_TYPE}" -- -j$(nproc) make -j$(nproc) test_solvespace From 8a2e77d035ebe1ec9ab4c5a67e4792d002ae4aca Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Wed, 21 Oct 2020 00:07:32 +0200 Subject: [PATCH 018/113] CMake: fix LTO on Linux LTO/IPO with non-Intel compilers on Linux requires policy CMP0069 to be set to NEW. Set it explicitly until cmake_minimum_required is raised to >= 3.9 Also explicitly check whether the current environment actually supports IPO. --- CMakeLists.txt | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index ed4f673c..736d8727 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,11 @@ cmake_minimum_required(VERSION 3.7.2 FATAL_ERROR) if(NOT CMAKE_VERSION VERSION_LESS 3.11.0) cmake_policy(VERSION 3.11.0) endif() +if(NOT CMAKE_VERSION VERSION_LESS 3.9) + # LTO/IPO with non-Intel compilers on Linux requires policy CMP0069 to be set to NEW. + # Set it explicitly until cmake_minimum_required is raised to >= 3.9. + cmake_policy(SET CMP0069 NEW) +endif() set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") set(CMAKE_CXX_STANDARD 11) @@ -102,6 +107,8 @@ if(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" OR CMAKE_SYSTEM_PROCESSOR STREQUAL "X8 endif() if(ENABLE_LTO) + include(CheckIPOSupported) + check_ipo_supported() set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE) endif() From b3cd92899e61052db356d01e5f2d7c654d75f23d Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Wed, 21 Oct 2020 21:13:49 +0200 Subject: [PATCH 019/113] Travis: release macOS and Windows edge builds - Fixes windows build type - Revert `cleanup: false` back to `skip_cleanup: true` - Waits 10 seconds to get notarize_uuid for macOS since it would sometimes fail --- .travis.yml | 45 +++++++++++++++++++++++++++++++++------- .travis/build-macos.sh | 2 +- .travis/build-windows.sh | 21 +++++++++++++------ .travis/sign-macos.sh | 2 +- 4 files changed, 55 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index d11a77ed..2d02dd98 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,21 +15,29 @@ jobs: install: ".travis/install-macos.sh" script: ".travis/build-macos.sh" - stage: deploy - if: tag IS present name: macOS deploy + if: (NOT type IN (pull_request)) AND (branch = master) os: osx osx_image: xcode12.2 install: ".travis/install-macos.sh" - script: ".travis/build-macos.sh && .travis/sign-macos.sh" + script: ".travis/build-macos.sh release && .travis/sign-macos.sh" + before_deploy: + - git config --local user.name "solvespace-cd" + - git config --local user.email "no-reply@solvespace.com" + - export TRAVIS_TAG=${TRAVIS_TAG:-edge} + - git tag $TRAVIS_TAG deploy: provider: releases token: secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= - cleanup: false + skip_cleanup: true + prerelease: true + overwrite: true + name: ${TRAVIS_TAG:-edge} + body: $TRAVIS_COMMIT_MESSAGE file: build/bin/SolveSpace.dmg on: repo: solvespace/solvespace - tags: true - stage: test name: "Debian" os: linux @@ -37,10 +45,33 @@ jobs: install: .travis/install-debian.sh script: .travis/build-debian.sh - stage: test - name: "Windows Visual Studio 2017" + name: "Windows Visual Studio 2017 test" os: windows install: .travis/install-windows.sh script: .travis/build-windows.sh + - stage: deploy + name: "Windows Visual Studio 2017 deploy" + os: windows + install: .travis/install-windows.sh + script: .travis/build-windows.sh release + before_deploy: + - git config --local user.name "solvespace-cd" + - git config --local user.email "no-reply@solvespace.com" + - export TRAVIS_TAG=${TRAVIS_TAG:-edge} + - git tag $TRAVIS_TAG + deploy: + provider: releases + token: + secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= + skip_cleanup: true + draft: true + prerelease: true + overwrite: true + name: ${TRAVIS_TAG:-edge} + body: $TRAVIS_COMMIT_MESSAGE + file: build/bin/RelWithDebInfo/solvespace.exe + on: + repo: solvespace/solvespace - &deploy-snap stage: deploy name: Snap amd64 @@ -55,13 +86,13 @@ jobs: deploy: - provider: script script: sudo .travis/deploy-snap.sh edge - cleanup: false + skip_cleanup: true on: branch: master tags: false - provider: script script: sudo .travis/deploy-snap.sh edge,beta - cleanup: false + skip_cleanup: true on: branch: master tags: true diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh index aca078f1..d8868a66 100755 --- a/.travis/build-macos.sh +++ b/.travis/build-macos.sh @@ -11,7 +11,7 @@ export LDFLAGS="-L${LLVM_PREFIX}/lib -Wl,-rpath,${LLVM_PREFIX}/lib" \ export CFLAGS="-I${LLVM_PREFIX}/include" export CPPFLAGS="-I${LLVM_PREFIX}/include" -if echo $TRAVIS_TAG | grep ^v; then +if [ "$1" == "release" ]; then BUILD_TYPE=RelWithDebInfo cmake \ -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_TARGET}" \ diff --git a/.travis/build-windows.sh b/.travis/build-windows.sh index 9cbc3897..f66b6cd4 100755 --- a/.travis/build-windows.sh +++ b/.travis/build-windows.sh @@ -3,14 +3,23 @@ MSBUILD_PATH="c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin" export PATH=$MSBUILD_PATH:$PATH -if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=Debug; fi - mkdir build cd build -cmake .. -G "Visual Studio 15 2017 Win64" -DCMAKE_BUILD_TYPE=$BUILD_TYPE -MSBuild.exe "src/solvespace.vcxproj" -maxcpucount -MSBuild.exe "src/solvespace-cli.vcxproj" -maxcpucount -MSBuild.exe "test/solvespace-testsuite.vcxproj" -maxcpucount +if [ "$1" == "release" ]; then + BUILD_TYPE=RelWithDebInfo + cmake \ + -G "Visual Studio 15 2017 Win64" \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. \ + -DENABLE_OPENMP=ON \ + -DENABLE_LTO=ON +else + BUILD_TYPE=Debug + cmake \ + -G "Visual Studio 15 2017 Win64" \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. +fi + +cmake --build . --config "${BUILD_TYPE}" -- -maxcpucount bin/$BUILD_TYPE/solvespace-testsuite.exe diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh index 6a379b53..8399e88a 100755 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -39,7 +39,7 @@ notarize_uuid=$(xcrun altool --notarize-app --primary-bundle-id "${bundle_id}" - echo $notarize_uuid # wait a bit so we don't get errors during checking -sleep 5 +sleep 10 success=0 for (( ; ; )) From 32e695bfee6d21ab866780ca69232405fb6e17d9 Mon Sep 17 00:00:00 2001 From: ruevs Date: Wed, 21 Oct 2020 22:16:37 +0300 Subject: [PATCH 020/113] STEP Export: include colors and alpha The implementation may be sub-optimal, since the colour and alpha is defined for each NURBS surface instead of on group level, but the STEP export currently does not represent group structure at all and I am not familiar with the format in order to change this. Fixes: https://github.com/solvespace/solvespace/issues/452 --- src/exportstep.cpp | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/src/exportstep.cpp b/src/exportstep.cpp index d5c9d406..ef50e789 100644 --- a/src/exportstep.cpp +++ b/src/exportstep.cpp @@ -273,9 +273,36 @@ void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) { } fprintf(f, "),#%d,.T.);\n", srfid); - fprintf(f, "\n"); advancedFaces.Add(&advFaceId); + // Export the surface color and transparency + // https://www.cax-if.org/documents/rec_prac_styling_org_v16.pdf sections 4.4.2 4.2.4 etc. + // https://tracker.dev.opencascade.org/view.php?id=31550 + fprintf(f, "#%d=COLOUR_RGB('',%.2f,%.2f,%.2f);\n", ++id, ss->color.redF(), + ss->color.greenF(), ss->color.blueF()); + + fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); + fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", + ++id, id - 2, id - 1); + + fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d));\n", ++id, id - 1); + + /* // This also works but is more verbose. + fprintf(f, "#%d=FILL_AREA_STYLE_COLOUR('',#%d);\n", ++id, id - 1); + fprintf(f, "#%d=FILL_AREA_STYLE('',(#%d));\n", ++id, id - 1); + fprintf(f, "#%d=SURFACE_STYLE_FILL_AREA(#%d);\n", ++id, id - 1); + + fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); + fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", ++id, id - 5, id - 1); + + fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d, #%d));\n", ++id, id - 3, id - 1); + */ + + fprintf(f, "#%d=SURFACE_STYLE_USAGE(.BOTH.,#%d);\n", ++id, id - 1); + fprintf(f, "#%d=PRESENTATION_STYLE_ASSIGNMENT((#%d));\n", ++id, id - 1); + fprintf(f, "#%d=STYLED_ITEM('',(#%d),#%d);\n", ++id, id - 1, advFaceId); + fprintf(f, "\n"); + id++; listOfLoops.Clear(); } From aa83681da7765964f37e9fd13d5fcf53ff480141 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Wed, 21 Oct 2020 00:30:03 +0200 Subject: [PATCH 021/113] snap: enable OpenMP and LTO --- pkg/snap/snap/snapcraft.yaml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/snap/snap/snapcraft.yaml b/pkg/snap/snap/snapcraft.yaml index 195a5086..400ea19e 100644 --- a/pkg/snap/snap/snapcraft.yaml +++ b/pkg/snap/snap/snapcraft.yaml @@ -51,6 +51,8 @@ parts: - -DCMAKE_BUILD_TYPE=Release - -DENABLE_TESTS=OFF - -DSNAP=ON + - -DENABLE_OPENMP=ON + - -DENABLE_LTO=ON build-packages: - zlib1g-dev - libpng-dev From 400056cdedd270d4bd741e5438f67d52a2b427e3 Mon Sep 17 00:00:00 2001 From: ruevs Date: Wed, 21 Oct 2020 12:25:53 +0300 Subject: [PATCH 022/113] CMake: Give ENABLE_LTO a default and a description so it shows up in cmake-gui --- CMakeLists.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 736d8727..6430e2a9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -57,6 +57,8 @@ set(ENABLE_SANITIZERS OFF CACHE BOOL "Whether to enable Clang's AddressSanitizer and UndefinedBehaviorSanitizer") set(ENABLE_OPENMP OFF CACHE BOOL "Whether geometric operations will be parallelized using OpenMP") +set(ENABLE_LTO OFF CACHE BOOL + "Whether interprocedural (global) optimizations are enabled") set(OPENGL 3 CACHE STRING "OpenGL version to use (one of: 1 3)") From 0761339ec96a5c5e8936c2cc8fad8e04b757062d Mon Sep 17 00:00:00 2001 From: ruevs Date: Thu, 22 Oct 2020 09:59:35 +0300 Subject: [PATCH 023/113] STEP Export: include colors and alpha Make the color export work in KiCAD and Horison EDA which do not support transparency. Fixes: https://github.com/solvespace/solvespace/issues/452 https://github.com/solvespace/solvespace/pull/763 --- src/exportstep.cpp | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/src/exportstep.cpp b/src/exportstep.cpp index ef50e789..91585226 100644 --- a/src/exportstep.cpp +++ b/src/exportstep.cpp @@ -281,22 +281,21 @@ void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) { fprintf(f, "#%d=COLOUR_RGB('',%.2f,%.2f,%.2f);\n", ++id, ss->color.redF(), ss->color.greenF(), ss->color.blueF()); +/* // This works in Kisters 3DViewStation but not in KiCAD and Horison EDA, + // it seems they do not support transparency so use the more verbose one below fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", ++id, id - 2, id - 1); - fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d));\n", ++id, id - 1); +*/ - /* // This also works but is more verbose. - fprintf(f, "#%d=FILL_AREA_STYLE_COLOUR('',#%d);\n", ++id, id - 1); - fprintf(f, "#%d=FILL_AREA_STYLE('',(#%d));\n", ++id, id - 1); - fprintf(f, "#%d=SURFACE_STYLE_FILL_AREA(#%d);\n", ++id, id - 1); - - fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); - fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", ++id, id - 5, id - 1); - - fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d, #%d));\n", ++id, id - 3, id - 1); - */ + // This works in Horison EDA but is more verbose. + fprintf(f, "#%d=FILL_AREA_STYLE_COLOUR('',#%d);\n", ++id, id - 1); + fprintf(f, "#%d=FILL_AREA_STYLE('',(#%d));\n", ++id, id - 1); + fprintf(f, "#%d=SURFACE_STYLE_FILL_AREA(#%d);\n", ++id, id - 1); + fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); + fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", ++id, id - 5, id - 1); + fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d, #%d));\n", ++id, id - 3, id - 1); fprintf(f, "#%d=SURFACE_STYLE_USAGE(.BOTH.,#%d);\n", ++id, id - 1); fprintf(f, "#%d=PRESENTATION_STYLE_ASSIGNMENT((#%d));\n", ++id, id - 1); From 0f1ece2b8e76f52cc675c0c3349749eb2e0d9470 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Wed, 21 Oct 2020 16:30:55 -0400 Subject: [PATCH 024/113] Resovle a huge performance regression introduced by commit ab10e38 while still fixing the NURBS issues resolved by that commit with only modest speed penalty. The performance is significantly improved by using bounding box tests on curves prior to doing complex intersection testing. --- src/srf/boolean.cpp | 48 ++++++++++++++++++++++++++++++++------------- src/srf/surface.h | 1 + 2 files changed, 35 insertions(+), 14 deletions(-) diff --git a/src/srf/boolean.cpp b/src/srf/boolean.cpp index 7789b8de..7546b0b9 100644 --- a/src/srf/boolean.cpp +++ b/src/srf/boolean.cpp @@ -20,18 +20,36 @@ void SShell::MakeFromIntersectionOf(SShell *a, SShell *b) { MakeFromBoolean(a, b, SSurface::CombineAs::INTERSECTION); } -// We will be inserting existing verticies into curves to split them -// todo: this is only using the ends of exact curves, and it is only -// using them to split existing curves, not new intersections. -// It resolves some issues but we could do better. We will need to -// reorder things so the surface intersection curves exist prior to -// splitting any curves at all in order to have their verticies too. -// Better still would be to get curve/surface intersection to work -// more reliably at the edges - maybe do curve/curve tests as part -// of the curve-surface intersection test. +void SCurve::GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const { + *ptMax = {VERY_NEGATIVE, VERY_NEGATIVE, VERY_NEGATIVE}; + *ptMin = {VERY_POSITIVE, VERY_POSITIVE, VERY_POSITIVE}; + + for(int i = 0; i <= exact.deg; i++) { + exact.ctrl[i].MakeMaxMin(ptMax, ptMin); + } +} + +// We will be inserting other curve verticies into our curves to split them. +// This is helpful when curved surfaces become tangent along a trim and the +// usual tests for curve-surface intersection don't split the curve at a vertex. +// This is faster than the previous version that split at surface corners and +// handles more buggy cases. It's not clear this is the best way but it works ok. static void FindVertsOnCurve(List *l, const SCurve *curve, SShell *sh) { + + Vector amax, amin; + curve->GetAxisAlignedBounding(&amax, &amin); + for(auto sc : sh->curve) { if(!sc.isExact) continue; + + Vector cmax, cmin; + sc.GetAxisAlignedBounding(&cmax, &cmin); + + if(Vector::BoundingBoxesDisjoint(amax, amin, cmax, cmin)) { + // They cannot possibly intersect, no curves to generate + continue; + } + for(int i=0; i<2; i++) { Vector pt = sc.exact.ctrl[ i==0 ? 0 : sc.exact.deg ]; double t; @@ -63,11 +81,13 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, // First find any vertex that lies on our curve. List vertpts = {}; - if(agnstA) - FindVertsOnCurve(&vertpts, this, agnstA); - if(agnstB) - FindVertsOnCurve(&vertpts, this, agnstB); - + if(isExact) { + if(agnstA) + FindVertsOnCurve(&vertpts, this, agnstA); + if(agnstB) + FindVertsOnCurve(&vertpts, this, agnstB); + } + const SCurvePt *p = pts.First(); ssassert(p != NULL, "Cannot split an empty curve"); SCurvePt prev = *p; diff --git a/src/srf/surface.h b/src/srf/surface.h index ff8aa0f2..54974552 100644 --- a/src/srf/surface.h +++ b/src/srf/surface.h @@ -219,6 +219,7 @@ public: SSurface *GetSurfaceB(SShell *a, SShell *b) const; void Clear(); + void GetAxisAlignedBounding(Vector *ptMax, Vector *ptMin) const; }; // A segment of a curve by which a surface is trimmed: indicates which curve, From c674bc8fb914b990350f9b8c243bff4c307c12b5 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Thu, 22 Oct 2020 10:48:27 -0400 Subject: [PATCH 025/113] Add OpenMP parallel for to SShell::CopyCurvesSplitAgainst --- src/srf/boolean.cpp | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/src/srf/boolean.cpp b/src/srf/boolean.cpp index 7546b0b9..1edf46ed 100644 --- a/src/srf/boolean.cpp +++ b/src/srf/boolean.cpp @@ -201,16 +201,19 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB, } void SShell::CopyCurvesSplitAgainst(bool opA, SShell *agnst, SShell *into) { - SCurve *sc; - for(sc = curve.First(); sc; sc = curve.NextAfter(sc)) { +#pragma omp parallel for + for(int i=0; iMakeCopySplitAgainst(agnst, NULL, surface.FindById(sc->surfA), surface.FindById(sc->surfB)); scn.source = opA ? SCurve::Source::A : SCurve::Source::B; - - hSCurve hsc = into->curve.AddAndAssignId(&scn); - // And note the new ID so that we can rewrite the trims appropriately - sc->newH = hsc; +#pragma omp critical + { + hSCurve hsc = into->curve.AddAndAssignId(&scn); + // And note the new ID so that we can rewrite the trims appropriately + sc->newH = hsc; + } } } From 68b1abf77f5c8858659a51b8bdbf760effb53b66 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Thu, 22 Oct 2020 23:09:17 +0200 Subject: [PATCH 026/113] CMake: use sanitizer flags for internal targets only Previously sanitizer flags were set unconditionally for all code, including that of external libraries. Set them only for targets in src/, tests/ and exposed/. Unfortunately, the linker equivalent to add_compile_options, add_link_options, is only available for CMake version >= 3.13. So add the sanitizer flags manually to each target's linker options. --- CMakeLists.txt | 10 +++------- exposed/CMakeLists.txt | 5 ++++- src/CMakeLists.txt | 19 ++++++++++++++----- test/CMakeLists.txt | 8 ++++++-- 4 files changed, 27 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6430e2a9..9b46e012 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,19 +170,15 @@ if(ENABLE_SANITIZERS) endif() string(REPLACE ";" "," SANITIZE_OPTIONS "${SANITIZE_OPTIONS}") - set(SANITIZE_FLAGS "-O1 -fsanitize=${SANITIZE_OPTIONS}") - set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-sanitize-recover=address,undefined") + set(SANITIZE_FLAGS "-O1;-fsanitize=${SANITIZE_OPTIONS};-fno-sanitize-recover=address,undefined") if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls") + list(APPEND SANITIZE_FLAGS -fno-omit-frame-pointer -fno-optimize-sibling-calls) elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fuse-ld=gold") + list(APPEND SANITIZE_FLAGS -fuse-ld=gold) else() message(FATAL_ERROR "Sanitizers are only available when using GCC or Clang") endif() - - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}") endif() # common dependencies diff --git a/exposed/CMakeLists.txt b/exposed/CMakeLists.txt index bdc3fc39..a70b2c5f 100644 --- a/exposed/CMakeLists.txt +++ b/exposed/CMakeLists.txt @@ -1,3 +1,5 @@ +add_compile_options(${SANITIZE_FLAGS}) + include_directories( ${CMAKE_SOURCE_DIR}/include) @@ -5,4 +7,5 @@ add_executable(CDemo CDemo.c) target_link_libraries(CDemo - slvs) + slvs + ${SANITIZE_FLAGS}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd8359f6..f40b2dee 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,6 +26,10 @@ if(APPLE) ${APPKIT_LIBRARY}) endif() +# sanitizers for all code in src and below + +add_compile_options(${SANITIZE_FLAGS}) + # libslvs set(libslvs_SOURCES @@ -55,7 +59,8 @@ target_include_directories(slvs target_link_libraries(slvs ${util_LIBRARIES} - mimalloc-static) + mimalloc-static + ${SANITIZE_FLAGS}) add_dependencies(slvs mimalloc-static) @@ -225,7 +230,8 @@ target_link_libraries(solvespace-core ${PNG_LIBRARY} ${FREETYPE_LIBRARY} flatbuffers - mimalloc-static) + mimalloc-static + ${SANITIZE_FLAGS}) if(Backtrace_FOUND) target_link_libraries(solvespace-core @@ -332,7 +338,8 @@ if(ENABLE_GUI) solvespace-core ${OPENGL_LIBRARIES} ${platform_LIBRARIES} - ${COVERAGE_LIBRARY}) + ${COVERAGE_LIBRARY} + ${SANITIZE_FLAGS}) if(MSVC) set_target_properties(solvespace PROPERTIES @@ -361,7 +368,8 @@ target_include_directories(solvespace-headless target_link_libraries(solvespace-headless solvespace-core - ${CAIRO_LIBRARIES}) + ${CAIRO_LIBRARIES} + ${SANITIZE_FLAGS}) target_compile_options(solvespace-headless PRIVATE ${COVERAGE_FLAGS}) @@ -375,7 +383,8 @@ if(ENABLE_CLI) target_link_libraries(solvespace-cli solvespace-core - solvespace-headless) + solvespace-headless + ${SANITIZE_FLAGS}) add_dependencies(solvespace-cli resources) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index db812bfa..2382253e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,6 +11,8 @@ if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") add_definitions(-DTEST_BUILD_ON_WINDOWS) endif() +add_compile_options(${SANITIZE_FLAGS}) + # test suite set(testsuite_SOURCES @@ -74,7 +76,8 @@ add_executable(solvespace-testsuite target_link_libraries(solvespace-testsuite solvespace-headless - ${COVERAGE_LIBRARY}) + ${COVERAGE_LIBRARY} + ${SANITIZE_FLAGS}) add_dependencies(solvespace-testsuite resources) @@ -132,7 +135,8 @@ add_executable(solvespace-debugtool target_link_libraries(solvespace-debugtool solvespace-core - solvespace-headless) + solvespace-headless + ${SANITIZE_FLAGS}) add_dependencies(solvespace-debugtool resources) From 70350715267b025f65ff6fc14eb31e557d672cb1 Mon Sep 17 00:00:00 2001 From: ruevs Date: Wed, 21 Oct 2020 16:39:15 +0300 Subject: [PATCH 027/113] Performance optimization of the Vector class Profiling with MSVC 2019 showed that many of the Vector methods are on a critical path (not surprising). They are changed to be inline and unnecessary temporaries are removed. On the example below generate times decreased from 102s. to 64s. At the same time the executable size shrank from 5569536 to 5150208 bytes in release mode (with global optimizations). This should not stop us from working on optimizing inner loops e.g. https://github.com/solvespace/solvespace/issues/759 . [Test model](https://github.com/solvespace/solvespace/files/5414683/PrismConeNURBSNormalsTangents300.zip) --- src/dsc.h | 46 +++++++++++++++++++++++++++++++ src/util.cpp | 78 ---------------------------------------------------- 2 files changed, 46 insertions(+), 78 deletions(-) diff --git a/src/dsc.h b/src/dsc.h index f07d9321..93403bca 100644 --- a/src/dsc.h +++ b/src/dsc.h @@ -155,6 +155,52 @@ inline bool Vector::Equals(Vector v, double tol) const { return dv.MagSquared() < tol*tol; } +inline Vector Vector::From(double x, double y, double z) { + return {x, y, z}; +} + +inline Vector Vector::Plus(Vector b) const { + return {x + b.x, y + b.y, z + b.z}; +} + +inline Vector Vector::Minus(Vector b) const { + return {x - b.x, y - b.y, z - b.z}; +} + +inline Vector Vector::Negated() const { + return {-x, -y, -z}; +} + +inline Vector Vector::Cross(Vector b) const { + return {-(z * b.y) + (y * b.z), (z * b.x) - (x * b.z), -(y * b.x) + (x * b.y)}; +} + +inline double Vector::Dot(Vector b) const { + return (x * b.x + y * b.y + z * b.z); +} + +inline double Vector::MagSquared() const { + return x * x + y * y + z * z; +} + +inline double Vector::Magnitude() const { + return sqrt(x * x + y * y + z * z); +} + +inline Vector Vector::ScaledBy(const double v) const { + return {x * v, y * v, z * v}; +} + +inline void Vector::MakeMaxMin(Vector *maxv, Vector *minv) const { + maxv->x = max(maxv->x, x); + maxv->y = max(maxv->y, y); + maxv->z = max(maxv->z, z); + + minv->x = min(minv->x, x); + minv->y = min(minv->y, y); + minv->z = min(minv->z, z); +} + struct VectorHash { size_t operator()(const Vector &v) const; }; diff --git a/src/util.cpp b/src/util.cpp index f2d33c2d..f14417cc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -428,12 +428,6 @@ Quaternion Quaternion::Mirror() const { } -Vector Vector::From(double x, double y, double z) { - Vector v; - v.x = x; v.y = y; v.z = z; - return v; -} - Vector Vector::From(hParam x, hParam y, hParam z) { Vector v; v.x = SK.GetParam(x)->val; @@ -448,50 +442,6 @@ bool Vector::EqualsExactly(Vector v) const { z == v.z); } -Vector Vector::Plus(Vector b) const { - Vector r; - - r.x = x + b.x; - r.y = y + b.y; - r.z = z + b.z; - - return r; -} - -Vector Vector::Minus(Vector b) const { - Vector r; - - r.x = x - b.x; - r.y = y - b.y; - r.z = z - b.z; - - return r; -} - -Vector Vector::Negated() const { - Vector r; - - r.x = -x; - r.y = -y; - r.z = -z; - - return r; -} - -Vector Vector::Cross(Vector b) const { - Vector r; - - r.x = -(z*b.y) + (y*b.z); - r.y = (z*b.x) - (x*b.z); - r.z = -(y*b.x) + (x*b.y); - - return r; -} - -double Vector::Dot(Vector b) const { - return (x*b.x + y*b.y + z*b.z); -} - double Vector::DirectionCosineWith(Vector b) const { Vector a = this->WithMagnitude(1); b = b.WithMagnitude(1); @@ -629,24 +579,6 @@ Vector Vector::ClosestPointOnLine(Vector p0, Vector dp) const { return this->Plus(n.WithMagnitude(d)); } -double Vector::MagSquared() const { - return x*x + y*y + z*z; -} - -double Vector::Magnitude() const { - return sqrt(x*x + y*y + z*z); -} - -Vector Vector::ScaledBy(double v) const { - Vector r; - - r.x = x * v; - r.y = y * v; - r.z = z * v; - - return r; -} - Vector Vector::WithMagnitude(double v) const { double m = Magnitude(); if(EXACT(m == 0)) { @@ -729,16 +661,6 @@ Vector Vector::ClampWithin(double minv, double maxv) const { return ret; } -void Vector::MakeMaxMin(Vector *maxv, Vector *minv) const { - maxv->x = max(maxv->x, x); - maxv->y = max(maxv->y, y); - maxv->z = max(maxv->z, z); - - minv->x = min(minv->x, x); - minv->y = min(minv->y, y); - minv->z = min(minv->z, z); -} - bool Vector::OutsideAndNotOn(Vector maxv, Vector minv) const { return (x > maxv.x + LENGTH_EPS) || (x < minv.x - LENGTH_EPS) || (y > maxv.y + LENGTH_EPS) || (y < minv.y - LENGTH_EPS) || From 8f509f14527f5f5776788f287f1d90ec446499b1 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sat, 24 Oct 2020 11:08:40 +0200 Subject: [PATCH 028/113] Travis: CI improvements and fixing edge builds (#766) - Fix release notes by using edge deploy provider, see: https://github.com/travis-ci/dpl/pull/1069 - Deploy only on master branch - Move to arm64-graviton2 - Rename debian -> ubuntu - Remove appveyor.yml - Remove redundant deploy stage in build step names - Get rid of bash code in files using sh, and explicitly use bash in sign-macos.sh script - Add missing newline to build-windows.sh - Build x86 for Windows - Enable OpenMP in test builds - Disable sanitizers on macOS test build - Disallow failures on snap build --- .travis.yml | 56 ++++++++++++++----- .travis/build-debian.sh | 11 ---- .travis/build-macos.sh | 16 ++++-- .travis/build-ubuntu.sh | 11 ++++ .travis/build-windows.sh | 28 +++++++--- .../{install-debian.sh => install-ubuntu.sh} | 0 .travis/sign-macos.sh | 2 +- CMakeLists.txt | 6 +- appveyor.yml | 29 ---------- 9 files changed, 89 insertions(+), 70 deletions(-) delete mode 100755 .travis/build-debian.sh create mode 100755 .travis/build-ubuntu.sh rename .travis/{install-debian.sh => install-ubuntu.sh} (100%) delete mode 100644 appveyor.yml diff --git a/.travis.yml b/.travis.yml index 2d02dd98..8444246f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,20 +3,20 @@ dist: xenial language: c git: submodules: false +stages: + - test + - name: deploy + if: (NOT type IN (pull_request)) AND (branch = master) jobs: - allow_failures: - - stage: deploy - name: Snap arm64 include: - stage: test - name: macOS test + name: macOS os: osx osx_image: xcode12.2 install: ".travis/install-macos.sh" script: ".travis/build-macos.sh" - stage: deploy - name: macOS deploy - if: (NOT type IN (pull_request)) AND (branch = master) + name: macOS os: osx osx_image: xcode12.2 install: ".travis/install-macos.sh" @@ -33,24 +33,25 @@ jobs: skip_cleanup: true prerelease: true overwrite: true + edge: true name: ${TRAVIS_TAG:-edge} - body: $TRAVIS_COMMIT_MESSAGE + release_notes: $TRAVIS_COMMIT_MESSAGE file: build/bin/SolveSpace.dmg on: repo: solvespace/solvespace - stage: test - name: "Debian" + name: "Ubuntu" os: linux dist: bionic - install: .travis/install-debian.sh - script: .travis/build-debian.sh + install: .travis/install-ubuntu.sh + script: .travis/build-ubuntu.sh - stage: test - name: "Windows Visual Studio 2017 test" + name: "Windows" os: windows install: .travis/install-windows.sh script: .travis/build-windows.sh - stage: deploy - name: "Windows Visual Studio 2017 deploy" + name: "Windows" os: windows install: .travis/install-windows.sh script: .travis/build-windows.sh release @@ -64,14 +65,37 @@ jobs: token: secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true - draft: true prerelease: true overwrite: true + edge: true name: ${TRAVIS_TAG:-edge} - body: $TRAVIS_COMMIT_MESSAGE + release_notes: $TRAVIS_COMMIT_MESSAGE file: build/bin/RelWithDebInfo/solvespace.exe on: repo: solvespace/solvespace + - stage: deploy + name: "Windows with OpenMP" + os: windows + install: .travis/install-windows.sh + script: .travis/build-windows.sh release openmp + before_deploy: + - git config --local user.name "solvespace-cd" + - git config --local user.email "no-reply@solvespace.com" + - export TRAVIS_TAG=${TRAVIS_TAG:-edge} + - git tag $TRAVIS_TAG + deploy: + provider: releases + token: + secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= + skip_cleanup: true + prerelease: true + overwrite: true + edge: true + name: ${TRAVIS_TAG:-edge} + release_notes: $TRAVIS_COMMIT_MESSAGE + file: build/bin/RelWithDebInfo/solvespace-openmp.exe + on: + repo: solvespace/solvespace - &deploy-snap stage: deploy name: Snap amd64 @@ -98,4 +122,6 @@ jobs: tags: true - <<: *deploy-snap name: Snap arm64 - arch: arm64 + arch: arm64-graviton2 + group: edge + virt: lxd diff --git a/.travis/build-debian.sh b/.travis/build-debian.sh deleted file mode 100755 index 007bf805..00000000 --- a/.travis/build-debian.sh +++ /dev/null @@ -1,11 +0,0 @@ -#!/bin/sh -xe - -if echo $TRAVIS_TAG | grep ^v; then BUILD_TYPE=RelWithDebInfo; else BUILD_TYPE=Debug; fi - -mkdir build -cd build -cmake .. \ - -DCMAKE_BUILD_TYPE=$BUILD_TYPE \ - -DENABLE_SANITIZERS=ON -make -j$(nproc) VERBOSE=1 -make test_solvespace diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh index d8868a66..48623c11 100755 --- a/.travis/build-macos.sh +++ b/.travis/build-macos.sh @@ -11,18 +11,22 @@ export LDFLAGS="-L${LLVM_PREFIX}/lib -Wl,-rpath,${LLVM_PREFIX}/lib" \ export CFLAGS="-I${LLVM_PREFIX}/include" export CPPFLAGS="-I${LLVM_PREFIX}/include" -if [ "$1" == "release" ]; then +if [ "$1" = "release" ]; then BUILD_TYPE=RelWithDebInfo cmake \ -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_TARGET}" \ - -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. \ - -DENABLE_OPENMP=ON \ - -DENABLE_LTO=ON + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ + -DENABLE_OPENMP="ON" \ + -DENABLE_LTO="ON" \ + .. else BUILD_TYPE=Debug - cmake \ + cmake \ -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_TARGET}" \ - -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ + -DENABLE_OPENMP="ON" \ + -DENABLE_SANITIZERS="ON" \ + .. fi cmake --build . --config "${BUILD_TYPE}" -- -j$(nproc) diff --git a/.travis/build-ubuntu.sh b/.travis/build-ubuntu.sh new file mode 100755 index 00000000..4c8f4ea4 --- /dev/null +++ b/.travis/build-ubuntu.sh @@ -0,0 +1,11 @@ +#!/bin/sh -xe + +mkdir build +cd build +cmake \ + -DCMAKE_BUILD_TYPE="Debug" \ + -DENABLE_OPENMP="ON" \ + -DENABLE_SANITIZERS="ON" \ + .. +make -j$(nproc) VERBOSE=1 +make test_solvespace diff --git a/.travis/build-windows.sh b/.travis/build-windows.sh index f66b6cd4..d237d528 100755 --- a/.travis/build-windows.sh +++ b/.travis/build-windows.sh @@ -6,20 +6,34 @@ export PATH=$MSBUILD_PATH:$PATH mkdir build cd build -if [ "$1" == "release" ]; then +if [ "$1" = "release" ]; then + if [ "$2" = "openmp" ]; then + ENABLE_OPENMP="ON" + else + ENABLE_OPENMP="OFF" + fi BUILD_TYPE=RelWithDebInfo cmake \ - -G "Visual Studio 15 2017 Win64" \ - -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. \ - -DENABLE_OPENMP=ON \ - -DENABLE_LTO=ON + -G "Visual Studio 15 2017" \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ + -DENABLE_OPENMP="${ENABLE_OPENMP}" \ + -DENABLE_LTO=ON \ + -DCMAKE_GENERATOR_PLATFORM="Win32" \ + .. else BUILD_TYPE=Debug cmake \ - -G "Visual Studio 15 2017 Win64" \ - -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" .. + -G "Visual Studio 15 2017" \ + -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ + -DENABLE_OPENMP="ON" \ + -DCMAKE_GENERATOR_PLATFORM="Win32" \ + .. fi cmake --build . --config "${BUILD_TYPE}" -- -maxcpucount bin/$BUILD_TYPE/solvespace-testsuite.exe + +if [ "$2" = "openmp" ]; then + mv bin/$BUILD_TYPE/solvespace.exe bin/$BUILD_TYPE/solvespace-openmp.exe +fi diff --git a/.travis/install-debian.sh b/.travis/install-ubuntu.sh similarity index 100% rename from .travis/install-debian.sh rename to .travis/install-ubuntu.sh diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh index 8399e88a..2d50d319 100755 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -1,4 +1,4 @@ -#!/bin/sh -xe +#!/bin/bash -xe cd build diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b46e012..a141e539 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,7 +170,11 @@ if(ENABLE_SANITIZERS) endif() string(REPLACE ";" "," SANITIZE_OPTIONS "${SANITIZE_OPTIONS}") - set(SANITIZE_FLAGS "-O1;-fsanitize=${SANITIZE_OPTIONS};-fno-sanitize-recover=address,undefined") + if (NOT APPLE) + set(SANITIZE_FLAGS "-O1;-fsanitize=${SANITIZE_OPTIONS};-fno-sanitize-recover=address,undefined") + else() + set(SANITIZE_FLAGS "-O1;-fsanitize=${SANITIZE_OPTIONS}") + endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") list(APPEND SANITIZE_FLAGS -fno-omit-frame-pointer -fno-optimize-sibling-calls) diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index e2c632a9..00000000 --- a/appveyor.yml +++ /dev/null @@ -1,29 +0,0 @@ -version: '{build}' -clone_depth: 1 -before_build: - - git submodule update --init - - set tag=x%APPVEYOR_REPO_TAG_NAME% - - if %tag:~,2% == xv (set BUILD_TYPE=RelWithDebInfo) else (set BUILD_TYPE=Debug) - - mkdir build - - cmake -G"Visual Studio 14" -Tv140 -Bbuild -H. -build_script: - - msbuild "build\src\solvespace.vcxproj" /verbosity:minimal /property:Configuration=%BUILD_TYPE% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - - msbuild "build\src\solvespace-cli.vcxproj" /verbosity:minimal /property:Configuration=%BUILD_TYPE% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" - - msbuild "build\test\solvespace-testsuite.vcxproj" /verbosity:minimal /property:Configuration=%BUILD_TYPE% /logger:"C:\Program Files\AppVeyor\BuildAgent\Appveyor.MSBuildLogger.dll" -test_script: - - build\bin\%BUILD_TYPE%\solvespace-testsuite.exe -artifacts: - - path: build\bin\%BUILD_TYPE%\solvespace.exe - name: solvespace.exe - - path: build\bin\%BUILD_TYPE%\solvespace-cli.exe - name: solvespace-cli.exe - - path: build\bin\%BUILD_TYPE%\solvespace.pdb - name: solvespace.pdb -deploy: - - provider: GitHub - auth_token: - secure: P9/pf2nM+jlWKe7pCjMp41HycBNP/+5AsmE/TETrDUoBOa/9WFHelqdVFrbRn9IC - description: "" - artifact: solvespace.exe,solvespace-cli.exe,solvespace.pdb - on: - appveyor_repo_tag: true From da87a680938d3f47549dcf759f8b01b6e321d81b Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sat, 24 Oct 2020 12:11:00 +0200 Subject: [PATCH 029/113] Travis: try fixing deploy secret (sorry, has to happen on master) --- .travis.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8444246f..e1d69df0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,8 +28,7 @@ jobs: - git tag $TRAVIS_TAG deploy: provider: releases - token: - secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= + token: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true prerelease: true overwrite: true @@ -62,8 +61,7 @@ jobs: - git tag $TRAVIS_TAG deploy: provider: releases - token: - secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= + token: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true prerelease: true overwrite: true @@ -85,8 +83,7 @@ jobs: - git tag $TRAVIS_TAG deploy: provider: releases - token: - secure: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= + token: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true prerelease: true overwrite: true From 24720a0024149b169fb9e1996f7860d512f91615 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Sat, 24 Oct 2020 13:09:00 +0200 Subject: [PATCH 030/113] Revert "CMake: use sanitizer flags for internal targets only" This reverts commit 68b1abf77f5c8858659a51b8bdbf760effb53b66. The warnings are valuable and shouldn't be cast aside. As of 8f509f1, we special case macOS and don't set -fno-sanitize-recover to allow CI to succeed. In the future, this could be made stricter again by only suppressing known bugs, which ideally should also be fixed or reported upstream. --- CMakeLists.txt | 12 ++++++++---- exposed/CMakeLists.txt | 5 +---- src/CMakeLists.txt | 19 +++++-------------- test/CMakeLists.txt | 8 ++------ 4 files changed, 16 insertions(+), 28 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a141e539..712c0f23 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,19 +170,23 @@ if(ENABLE_SANITIZERS) endif() string(REPLACE ";" "," SANITIZE_OPTIONS "${SANITIZE_OPTIONS}") + if (NOT APPLE) - set(SANITIZE_FLAGS "-O1;-fsanitize=${SANITIZE_OPTIONS};-fno-sanitize-recover=address,undefined") + set(SANITIZE_FLAGS "-O1 -fsanitize=${SANITIZE_OPTIONS} -fno-sanitize-recover=address,undefined") else() - set(SANITIZE_FLAGS "-O1;-fsanitize=${SANITIZE_OPTIONS}") + set(SANITIZE_FLAGS "-O1 -fsanitize=${SANITIZE_OPTIONS}") endif() if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - list(APPEND SANITIZE_FLAGS -fno-omit-frame-pointer -fno-optimize-sibling-calls) + set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls") elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU") - list(APPEND SANITIZE_FLAGS -fuse-ld=gold) + set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fuse-ld=gold") else() message(FATAL_ERROR "Sanitizers are only available when using GCC or Clang") endif() + + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${SANITIZE_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${SANITIZE_FLAGS}") endif() # common dependencies diff --git a/exposed/CMakeLists.txt b/exposed/CMakeLists.txt index a70b2c5f..bdc3fc39 100644 --- a/exposed/CMakeLists.txt +++ b/exposed/CMakeLists.txt @@ -1,5 +1,3 @@ -add_compile_options(${SANITIZE_FLAGS}) - include_directories( ${CMAKE_SOURCE_DIR}/include) @@ -7,5 +5,4 @@ add_executable(CDemo CDemo.c) target_link_libraries(CDemo - slvs - ${SANITIZE_FLAGS}) + slvs) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index f40b2dee..fd8359f6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -26,10 +26,6 @@ if(APPLE) ${APPKIT_LIBRARY}) endif() -# sanitizers for all code in src and below - -add_compile_options(${SANITIZE_FLAGS}) - # libslvs set(libslvs_SOURCES @@ -59,8 +55,7 @@ target_include_directories(slvs target_link_libraries(slvs ${util_LIBRARIES} - mimalloc-static - ${SANITIZE_FLAGS}) + mimalloc-static) add_dependencies(slvs mimalloc-static) @@ -230,8 +225,7 @@ target_link_libraries(solvespace-core ${PNG_LIBRARY} ${FREETYPE_LIBRARY} flatbuffers - mimalloc-static - ${SANITIZE_FLAGS}) + mimalloc-static) if(Backtrace_FOUND) target_link_libraries(solvespace-core @@ -338,8 +332,7 @@ if(ENABLE_GUI) solvespace-core ${OPENGL_LIBRARIES} ${platform_LIBRARIES} - ${COVERAGE_LIBRARY} - ${SANITIZE_FLAGS}) + ${COVERAGE_LIBRARY}) if(MSVC) set_target_properties(solvespace PROPERTIES @@ -368,8 +361,7 @@ target_include_directories(solvespace-headless target_link_libraries(solvespace-headless solvespace-core - ${CAIRO_LIBRARIES} - ${SANITIZE_FLAGS}) + ${CAIRO_LIBRARIES}) target_compile_options(solvespace-headless PRIVATE ${COVERAGE_FLAGS}) @@ -383,8 +375,7 @@ if(ENABLE_CLI) target_link_libraries(solvespace-cli solvespace-core - solvespace-headless - ${SANITIZE_FLAGS}) + solvespace-headless) add_dependencies(solvespace-cli resources) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 2382253e..db812bfa 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -11,8 +11,6 @@ if(${CMAKE_HOST_SYSTEM_NAME} STREQUAL "Windows") add_definitions(-DTEST_BUILD_ON_WINDOWS) endif() -add_compile_options(${SANITIZE_FLAGS}) - # test suite set(testsuite_SOURCES @@ -76,8 +74,7 @@ add_executable(solvespace-testsuite target_link_libraries(solvespace-testsuite solvespace-headless - ${COVERAGE_LIBRARY} - ${SANITIZE_FLAGS}) + ${COVERAGE_LIBRARY}) add_dependencies(solvespace-testsuite resources) @@ -135,8 +132,7 @@ add_executable(solvespace-debugtool target_link_libraries(solvespace-debugtool solvespace-core - solvespace-headless - ${SANITIZE_FLAGS}) + solvespace-headless) add_dependencies(solvespace-debugtool resources) From 5fbb1b8f53322f4a29d86839fe88d3fd2a1fe897 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sun, 25 Oct 2020 17:59:52 +0100 Subject: [PATCH 031/113] Travis: remove old secrets from .travis.yml --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index e1d69df0..1655b7f5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,6 @@ jobs: - git tag $TRAVIS_TAG deploy: provider: releases - token: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true prerelease: true overwrite: true @@ -61,7 +60,6 @@ jobs: - git tag $TRAVIS_TAG deploy: provider: releases - token: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true prerelease: true overwrite: true @@ -83,7 +81,6 @@ jobs: - git tag $TRAVIS_TAG deploy: provider: releases - token: dDlkIawHcODlW9B/20/cQCtzeoocvs0hKuNngRKXKqzXLWTRq33oq/B7+39tAixWbmv6exTpijiKrRNFiSCW5Z4iwHLwaRD4XJznxw63e/Hus/dxg2Tvqx7XFpkCz8mT1Z+gZQE5YxAngeZPpI/sZbZtF1UO3yH5eLeeokZ15p26ZskQUPoYuzrTgTzYL3XfpG3F+20rNBawH1ycsCTVD/08/n31d2m3CrKAsbW7er92ek6w4fzKr7NW8WeXjrPJETVpw5fQg1Od3pRGW8dPQaJcvKQEogMp8Mm0ETYd0qigg89/giBz7QwOgmAWQ4dH+DfZH4Ojl//127QztBolMvyDMQBykWrtJoGcij05sT6K2IJr2FHeUBO12MAEdjiVvhQj3DtTzjPiZAHHDBSLWxLKWWhlhHE4pq7g1MQhqXkaAHI2BLNzwLmaowbMT0bECf9yfz6xx18h6XPQFX44oOktraobVALFlyHqeKa8zdcUt22LF6uAL1m5dxL0tny3eXCIPE4UH/RZgua/cHV9G3cUvKQa/QnFSLRhvWVSbGB+7YsHouBJcsUOOW1gmd5442XuC7mpppccRldh+GSxUk6TBJRAx7TeQ0ybDUaoco9MUqp2twv3KreR2+8Q12PDaAhfQVNEGdF3wTm1sShImjCN4VN3eSLlBEbve1QRQXM= skip_cleanup: true prerelease: true overwrite: true From 57f8b37270cbbf2d83fea918c6ae3761ecdf9deb Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sun, 25 Oct 2020 19:44:30 +0100 Subject: [PATCH 032/113] Travis: skip build if tag is edge, staple to the .dmg --- .travis.yml | 1 + .travis/sign-macos.sh | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 1655b7f5..17e5b569 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,6 +3,7 @@ dist: xenial language: c git: submodules: false +if: tag != edge stages: - test - name: deploy diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh index 2d50d319..df111ddb 100755 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -63,4 +63,4 @@ do done # staple -xcrun stapler staple $app \ No newline at end of file +xcrun stapler staple "${dmg}" \ No newline at end of file From 5388e10649b51ec9a66cd88741d76a4f4817a000 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sun, 25 Oct 2020 21:00:40 +0100 Subject: [PATCH 033/113] Travis: use force to overwrite tag --- .travis.yml | 12 +++--------- .travis/sign-macos.sh | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/.travis.yml b/.travis.yml index 17e5b569..e9f6680a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -26,7 +26,7 @@ jobs: - git config --local user.name "solvespace-cd" - git config --local user.email "no-reply@solvespace.com" - export TRAVIS_TAG=${TRAVIS_TAG:-edge} - - git tag $TRAVIS_TAG + - git tag --force $TRAVIS_TAG deploy: provider: releases skip_cleanup: true @@ -36,8 +36,6 @@ jobs: name: ${TRAVIS_TAG:-edge} release_notes: $TRAVIS_COMMIT_MESSAGE file: build/bin/SolveSpace.dmg - on: - repo: solvespace/solvespace - stage: test name: "Ubuntu" os: linux @@ -58,7 +56,7 @@ jobs: - git config --local user.name "solvespace-cd" - git config --local user.email "no-reply@solvespace.com" - export TRAVIS_TAG=${TRAVIS_TAG:-edge} - - git tag $TRAVIS_TAG + - git tag --force $TRAVIS_TAG deploy: provider: releases skip_cleanup: true @@ -68,8 +66,6 @@ jobs: name: ${TRAVIS_TAG:-edge} release_notes: $TRAVIS_COMMIT_MESSAGE file: build/bin/RelWithDebInfo/solvespace.exe - on: - repo: solvespace/solvespace - stage: deploy name: "Windows with OpenMP" os: windows @@ -79,7 +75,7 @@ jobs: - git config --local user.name "solvespace-cd" - git config --local user.email "no-reply@solvespace.com" - export TRAVIS_TAG=${TRAVIS_TAG:-edge} - - git tag $TRAVIS_TAG + - git tag --force $TRAVIS_TAG deploy: provider: releases skip_cleanup: true @@ -89,8 +85,6 @@ jobs: name: ${TRAVIS_TAG:-edge} release_notes: $TRAVIS_COMMIT_MESSAGE file: build/bin/RelWithDebInfo/solvespace-openmp.exe - on: - repo: solvespace/solvespace - &deploy-snap stage: deploy name: Snap amd64 diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh index df111ddb..3c047711 100755 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -46,7 +46,7 @@ for (( ; ; )) do echo "Checking progress..." progress=$(xcrun altool --notarization-info "${notarize_uuid}" -u "${MACOS_APPSTORE_USERNAME}" -p "${MACOS_APPSTORE_APP_PASSWORD}" 2>&1) - echo "${progress}" + # echo "${progress}" if [ $? -ne 0 ] || [[ "${progress}" =~ "Invalid" ]] ; then echo "Error with notarization. Exiting" From 7292c32e6f89dcc550ec45161e4f387c1e6c95f1 Mon Sep 17 00:00:00 2001 From: ruevs Date: Sun, 25 Oct 2020 23:53:42 +0200 Subject: [PATCH 034/113] Performance: inline the Bernstein functions This is another small profiling driven optimization. Moving the initialization of `const double *c` as part of the definition also helps with the generated assembler. --- src/srf/ratpoly.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/src/srf/ratpoly.cpp b/src/srf/ratpoly.cpp index 05ccd038..46180a55 100644 --- a/src/srf/ratpoly.cpp +++ b/src/srf/ratpoly.cpp @@ -13,8 +13,7 @@ // and convergence should be fast by now. #define RATPOLY_EPS (LENGTH_EPS/(1e2)) -static double Bernstein(int k, int deg, double t) -{ +static inline double Bernstein(int k, int deg, double t) { // indexed by [degree][k][exponent] static const double bernstein_coeff[4][4][4] = { { { 1.0,0.0,0.0,0.0 }, { 1.0,0.0,0.0,0.0 }, { 1.0,0.0,0.0,0.0 }, { 1.0,0.0,0.0,0.0 } }, @@ -22,21 +21,18 @@ static double Bernstein(int k, int deg, double t) { { 1.0,-2.0,1.0,0.0 }, { 0.0,2.0,-2.0,0.0 },{ 0.0,0.0,1.0,0.0 }, { 0.0,0.0,0.0,0.0 } }, { { 1.0,-3.0,3.0,-1.0 },{ 0.0,3.0,-6.0,3.0 },{ 0.0,0.0,3.0,-3.0}, { 0.0,0.0,0.0,1.0 } } }; - const double *c; - c = bernstein_coeff[deg][k]; + const double *c = bernstein_coeff[deg][k]; return (((c[3]*t+c[2])*t)+c[1])*t+c[0]; } -static double BernsteinDerivative(int k, int deg, double t) -{ +static inline double BernsteinDerivative(int k, int deg, double t) { static const double bernstein_derivative_coeff[4][4][3] = { { { 0.0,0.0,0.0 }, { 0.0,0.0,0.0 }, { 0.0,0.0,0.0 }, { 0.0,0.0,0.0 } }, { { -1.0,0.0,0.0 }, { 1.0,0.0,0.0 }, { 0.0,0.0,0.0 }, { 0.0,0.0,0.0 } }, { { -2.0,2.0,0.0 }, { 2.0,-4.0,0.0 },{ 0.0,2.0,0.0 }, { 0.0,0.0,0.0 } }, { { -3.0,6.0,-3.0 },{ 3.0,-12.0,9.0 },{ 0.0,6.0,-9.0}, { 0.0,0.0,3.0 } } }; - const double *c; - c = bernstein_derivative_coeff[deg][k]; + const double *c = bernstein_derivative_coeff[deg][k]; return ((c[2]*t)+c[1])*t+c[0]; } From 88b26aabdb6aa4a7b6eb16193216390f600c9f5f Mon Sep 17 00:00:00 2001 From: ruevs Date: Mon, 26 Oct 2020 00:12:29 +0200 Subject: [PATCH 035/113] Update the year in the About dialog --- src/solvespace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solvespace.cpp b/src/solvespace.cpp index d68cedf2..7c30a8f5 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -965,7 +965,7 @@ void SolveSpaceUI::MenuHelp(Command id) { "law. For details, visit http://gnu.org/licenses/\n" "\n" "© 2008-%d Jonathan Westhues and other authors.\n"), -PACKAGE_VERSION, 2019); +PACKAGE_VERSION, 2020); break; default: ssassert(false, "Unexpected menu ID"); From 73bbbdef83c122f64b651ed257d92ad1f66cf93f Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 26 Oct 2020 02:25:42 +0100 Subject: [PATCH 036/113] Travis: include libomp in macOS .app --- .travis/build-macos.sh | 6 ------ .travis/install-macos.sh | 2 +- CMakeLists.txt | 22 +++------------------- src/CMakeLists.txt | 7 ++++++- 4 files changed, 10 insertions(+), 27 deletions(-) diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh index 48623c11..bb4c1e0c 100755 --- a/.travis/build-macos.sh +++ b/.travis/build-macos.sh @@ -4,12 +4,6 @@ mkdir build || true cd build OSX_TARGET="10.9" -LLVM_PREFIX=$(brew --prefix llvm@9) -export CC="${LLVM_PREFIX}/bin/clang" -export CXX="${CC}++" -export LDFLAGS="-L${LLVM_PREFIX}/lib -Wl,-rpath,${LLVM_PREFIX}/lib" \ -export CFLAGS="-I${LLVM_PREFIX}/include" -export CPPFLAGS="-I${LLVM_PREFIX}/include" if [ "$1" = "release" ]; then BUILD_TYPE=RelWithDebInfo diff --git a/.travis/install-macos.sh b/.travis/install-macos.sh index d4817455..457dd5d4 100755 --- a/.travis/install-macos.sh +++ b/.travis/install-macos.sh @@ -1,4 +1,4 @@ #!/bin/sh -xe -brew install llvm@9 +brew install libomp git submodule update --init \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 712c0f23..ad23d983 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -115,27 +115,11 @@ if(ENABLE_LTO) endif() if(ENABLE_OPENMP) - if(APPLE) - # OpenMP does not work with the default Apple llvm/clang++ - # Install a more recent version using Homebrew (version 11.0.0 which is the next available tag on homebrew at this time crashed): - # "brew install llvm@9" - # and set the right compiler flags using: - # LLVM_PREFIX=$(brew --prefix llvm@9) - # export CC="${LLVM_PREFIX}/bin/clang" - # export CXX="${CC}++" - # export LDFLAGS="-L${LLVM_PREFIX}/lib -Wl,-rpath,${LLVM_PREFIX}/lib" \ - # export CFLAGS="-I${LLVM_PREFIX}/include" - # export CPPFLAGS="-I${LLVM_PREFIX}/include" - set(OpenMP_CXX_FLAGS "-fopenmp=libomp") + find_package( OpenMP REQUIRED ) + include(FindOpenMP) + if(OPENMP_FOUND) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") message(STATUS "found OpenMP, compiling with flags: " ${OpenMP_CXX_FLAGS} ) - else() - find_package( OpenMP REQUIRED ) - include(FindOpenMP) - if(OPENMP_FOUND) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - message(STATUS "found OpenMP, compiling with flags: " ${OpenMP_CXX_FLAGS} ) - endif() endif() endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index fd8359f6..1a46e246 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -404,10 +404,15 @@ endif() if(APPLE) set(bundle SolveSpace) set(bundle_bin ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app/Contents/MacOS) - + set(bundle_resources ${EXECUTABLE_OUTPUT_PATH}/${bundle}.app/Contents/Resources/lib) + execute_process( + COMMAND mkdir -p ${bundle_resources} + COMMAND cp -p /usr/local/opt/libomp/lib/libomp.dylib ${bundle_resources}/libomp.dylib + ) add_custom_command(TARGET solvespace POST_BUILD COMMAND ${CMAKE_COMMAND} -E make_directory ${bundle_bin} COMMAND ${CMAKE_COMMAND} -E copy $ ${bundle_bin} + COMMAND install_name_tool -change /usr/local/opt/libomp/lib/libomp.dylib "@executable_path/../Resources/lib/libomp.dylib" ${bundle_bin}/${bundle} COMMENT "Bundling executable solvespace-cli" VERBATIM) endif() From 3694c9b3eee5a2acc25457e07fde4bc05ca29a53 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 26 Oct 2020 03:38:32 +0100 Subject: [PATCH 037/113] Travis: sign libomp.dylib --- .travis/sign-macos.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis/sign-macos.sh b/.travis/sign-macos.sh index 3c047711..c23dab99 100755 --- a/.travis/sign-macos.sh +++ b/.travis/sign-macos.sh @@ -2,6 +2,7 @@ cd build +openmp="bin/SolveSpace.app/Contents/Resources/lib/libomp.dylib" app="bin/SolveSpace.app" dmg="bin/SolveSpace.dmg" bundle_id="com.solvespace.solvespace" @@ -24,6 +25,9 @@ if [ "$CI" = "true" ]; then security find-identity -v fi +# sign openmp +codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${openmp}" + # sign the .app codesign -s "${MACOS_DEVELOPER_ID}" --timestamp --options runtime -f --deep "${app}" From 7e99ba0096d2c6042ab006c12ef47b8353df6618 Mon Sep 17 00:00:00 2001 From: ruevs Date: Wed, 28 Oct 2020 00:21:23 +0200 Subject: [PATCH 038/113] UI: Fix the Property Browser window scrollbar - Scrolling with the scrollbar now works properly. - Do not scroll with the mouse wheel while an edit field is active in the property browser. Fixes: https://github.com/solvespace/solvespace/issues/782 --- src/textwin.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/textwin.cpp b/src/textwin.cpp index 131e12e9..900a8242 100644 --- a/src/textwin.cpp +++ b/src/textwin.cpp @@ -252,8 +252,8 @@ void TextWindow::Init() { MouseLeave(); return true; } else if(event.type == MouseEvent::Type::SCROLL_VERT) { - window->SetScrollbarPosition(window->GetScrollbarPosition() - - LINE_HEIGHT / 2 * event.scrollDelta); + ScrollbarEvent(window->GetScrollbarPosition() - + LINE_HEIGHT / 2 * event.scrollDelta); } return false; }; @@ -1130,7 +1130,7 @@ void TextWindow::MouseLeave() { void TextWindow::ScrollbarEvent(double newPos) { if(window->IsEditorVisible()) { - window->SetScrollbarPosition(scrollPos); + // An edit field is active. Do not move the scrollbar. return; } @@ -1140,6 +1140,7 @@ void TextWindow::ScrollbarEvent(double newPos) { if(newPos != scrollPos) { scrollPos = (int)newPos; + window->SetScrollbarPosition(scrollPos); window->Invalidate(); } } From 6c4b075eefa2b026a9f860d5484957c09fe109f4 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Tue, 27 Oct 2020 19:29:24 -0400 Subject: [PATCH 039/113] Increase MAX_UNDO to 100 --- src/solvespace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solvespace.h b/src/solvespace.h index d0fde5f5..e8eeddc9 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -530,7 +530,7 @@ public: style.Clear(); } } UndoState; - enum { MAX_UNDO = 16 }; + enum { MAX_UNDO = 100 }; typedef struct { UndoState d[MAX_UNDO]; int cnt; From eadeac44f05d16ffea6d2009b928fb4c4ce13fa4 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Tue, 27 Oct 2020 19:37:30 -0400 Subject: [PATCH 040/113] use VERY_NEGATIVE and VERY_POSITIVE instead of numeric values which is some cases were 1e-10 instead of -1e10 --- src/srf/surface.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/srf/surface.cpp b/src/srf/surface.cpp index 3e97bb21..815aedad 100644 --- a/src/srf/surface.cpp +++ b/src/srf/surface.cpp @@ -507,9 +507,9 @@ void SShell::MakeFromExtrusionOf(SBezierLoopSet *sbls, Vector t0, Vector t1, Rgb Vector n = sbls->normal.ScaledBy(-1); Vector u = n.Normal(0), v = n.Normal(1); Vector orig = sbls->point; - double umax = 1e-10, umin = 1e10; + double umax = VERY_NEGATIVE, umin = VERY_POSITIVE; sbls->GetBoundingProjd(u, orig, &umin, &umax); - double vmax = 1e-10, vmin = 1e10; + double vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE; sbls->GetBoundingProjd(v, orig, &vmin, &vmax); // and now fix things up so that all u and v lie between 0 and 1 orig = orig.Plus(u.ScaledBy(umin)); @@ -663,9 +663,9 @@ void SShell::MakeFromHelicalRevolutionOf(SBezierLoopSet *sbls, Vector pt, Vector Vector n = sbls->normal.ScaledBy(-1); Vector u = n.Normal(0), v = n.Normal(1); Vector orig = sbls->point; - double umax = 1e-10, umin = 1e10; + double umax = VERY_NEGATIVE, umin = VERY_POSITIVE; sbls->GetBoundingProjd(u, orig, &umin, &umax); - double vmax = 1e-10, vmin = 1e10; + double vmax = VERY_NEGATIVE, vmin = VERY_POSITIVE; sbls->GetBoundingProjd(v, orig, &vmin, &vmax); // and now fix things up so that all u and v lie between 0 and 1 orig = orig.Plus(u.ScaledBy(umin)); From 8a3e5b4d56b644808b4378a1f068486151a69ab2 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Wed, 28 Oct 2020 14:17:48 -0400 Subject: [PATCH 041/113] Don't do numeric surface intersections if an exact curve has been copied. We don't want 2 overlapping but different sets of PWLs. --- src/srf/surfinter.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/srf/surfinter.cpp b/src/srf/surfinter.cpp index 1e4fb396..0a827761 100644 --- a/src/srf/surfinter.cpp +++ b/src/srf/surfinter.cpp @@ -331,6 +331,7 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, sext = this; shext = agnstA; } + bool foundExact = false; SCurve *sc; for(sc = shext->curve.First(); sc; sc = shext->curve.NextAfter(sc)) { if(sc->source == SCurve::Source::INTERSECTION) continue; @@ -341,8 +342,14 @@ void SSurface::IntersectAgainst(SSurface *b, SShell *agnstA, SShell *agnstB, if(splane->ContainsPlaneCurve(sc)) { SBezier bezier = sc->exact; AddExactIntersectionCurve(&bezier, b, agnstA, agnstB, into); + foundExact = true; } } + // if we found at lest one of these we don't want to do the numerical + // intersection as well. Sometimes it will also find the same curve but + // with different PWLs and the polygon will fail to assemble. + if(foundExact) + return; } // Try intersecting the surfaces numerically, by a marching algorithm. From ef7e2c7ec2722f509d60b5650fc3f3acdc625afa Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Wed, 28 Oct 2020 18:26:19 +0100 Subject: [PATCH 042/113] README: Add Travis & Snap Store badges --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 295f25fe..b8ffbb6a 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,8 @@ SolveSpace ========== +[![Build Status](https://travis-ci.com/solvespace/solvespace.svg?branch=master)](https://travis-ci.com/solvespace/solvespace) +[![solvespace](https://snapcraft.io/solvespace/badge.svg)](https://snapcraft.io/solvespace) +[![solvespace](https://snapcraft.io/solvespace/trending.svg?name=0)](https://snapcraft.io/solvespace) This repository contains the source code of [SolveSpace][], a parametric 2d/3d CAD. From 078fb99cfa52fbf86edc41303e490d79abd30a15 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Wed, 28 Oct 2020 19:51:46 +0100 Subject: [PATCH 043/113] add logo in heading --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b8ffbb6a..a7f82bc5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +SolveSpace Logo + SolveSpace ========== [![Build Status](https://travis-ci.com/solvespace/solvespace.svg?branch=master)](https://travis-ci.com/solvespace/solvespace) From d973405c8c71ab807622c809b88e745fda8ddffb Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Wed, 28 Oct 2020 19:53:18 +0100 Subject: [PATCH 044/113] adjust logo size --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a7f82bc5..44e14f20 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -SolveSpace Logo +SolveSpace Logo SolveSpace ========== From 6ff8db93e83d06926d182c4d9d66874667ae2cb8 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Fri, 30 Oct 2020 13:21:26 -0400 Subject: [PATCH 045/113] Use zOrder for selections within the same group --- src/draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/draw.cpp b/src/draw.cpp index 1dabd75b..5370d1ed 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -352,7 +352,7 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToSelect() { Group *g = SK.GetGroup(hg); if(g->order > activeGroup->order) continue; - if(bestOrder != -1 && (bestOrder >= g->order || bestZIndex > hov.zIndex)) continue; + if(bestOrder != -1 && (bestOrder > g->order || bestZIndex > hov.zIndex)) continue; bestOrder = g->order; bestZIndex = hov.zIndex; sel = hov.selection; @@ -382,7 +382,7 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToDrag() { Group *g = SK.GetGroup(hg); if(g->order > activeGroup->order) continue; - if(bestOrder != -1 && (bestOrder >= g->order || bestZIndex > hov.zIndex)) continue; + if(bestOrder != -1 && (bestOrder > g->order || bestZIndex > hov.zIndex)) continue; bestOrder = g->order; bestZIndex = hov.zIndex; sel = hov.selection; From 953c472897b081d0c438302f650559a429bae52b Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 2 Nov 2020 23:10:16 +0100 Subject: [PATCH 046/113] Travis: add clean edge script --- .travis.yml | 7 +++++++ .travis/remove-edge.sh | 23 +++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100755 .travis/remove-edge.sh diff --git a/.travis.yml b/.travis.yml index e9f6680a..4d796af7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,10 +6,17 @@ git: if: tag != edge stages: - test + - name: clean + if: (NOT type IN (pull_request)) AND (branch = master) - name: deploy if: (NOT type IN (pull_request)) AND (branch = master) jobs: include: + - stage: clean + name: Remove Github Release + os: linux + dist: bionic + script: .travis/remove-edge.sh - stage: test name: macOS os: osx diff --git a/.travis/remove-edge.sh b/.travis/remove-edge.sh new file mode 100755 index 00000000..4321ff58 --- /dev/null +++ b/.travis/remove-edge.sh @@ -0,0 +1,23 @@ +#!/bin/sh -xe + +sudo apt-get update -qq +sudo apt-get -y install jq + +old_release=$(curl \ + -H "Accept: application/vnd.github.v3+json" \ + https://api.github.com/repos/solvespace/solvespace/releases/tags/edge \ + | jq -r ".url") + +if [ -z "$old_release" ]; then + curl \ + -X DELETE \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token $GITHUB_TOKEN" \ + "$old_release" +fi + +curl \ + -X DELETE \ + -H "Accept: application/vnd.github.v3+json" \ + -H "Authorization: token $GITHUB_TOKEN" \ + https://api.github.com/repos/solvespace/solvespace/git/refs/tags/edge From 5945d556a6c373e863672b8bc355c48122de26c2 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Fri, 6 Nov 2020 19:12:52 -0500 Subject: [PATCH 047/113] Add end marker to text window and increase max rows. --- src/textwin.cpp | 11 +++++++++++ src/ui.h | 2 +- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/textwin.cpp b/src/textwin.cpp index 900a8242..e243825c 100644 --- a/src/textwin.cpp +++ b/src/textwin.cpp @@ -338,11 +338,22 @@ void TextWindow::ClearScreen() { rows = 0; } +// This message was addded when someone had too many fonts for the text window +// Scrolling seemed to be broken, but was actaully at the MAX_ROWS. +static const char* endString = " **** End of Text Screen ****"; + void TextWindow::Printf(bool halfLine, const char *fmt, ...) { if(!canvas) return; if(rows >= MAX_ROWS) return; + if(rows >= MAX_ROWS-2 && (fmt != endString)) { + // twice due to some half-row issues on resizing + Printf(halfLine, endString); + Printf(halfLine, endString); + return; + } + va_list vl; va_start(vl, fmt); diff --git a/src/ui.h b/src/ui.h index b44d566b..a7984102 100644 --- a/src/ui.h +++ b/src/ui.h @@ -179,7 +179,7 @@ public: enum { MAX_COLS = 100, MIN_COLS = 45, - MAX_ROWS = 2000 + MAX_ROWS = 4000 }; typedef struct { From d0876d5f43f8e4663b0743e426babaa59fb57013 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sat, 7 Nov 2020 21:54:47 +0100 Subject: [PATCH 048/113] Update README.md (by @nii236) --- README.md | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 44e14f20..394e33dc 100644 --- a/README.md +++ b/README.md @@ -104,8 +104,9 @@ by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation. ### Building for Windows -You will need the usual build tools, CMake, a Windows cross-compiler, and flatc. -On a Debian derivative (e.g. Ubuntu) these can be installed with: +Ubuntu will require 20.04 or above. Cross-compiling with WSL is also confirmed to work. + +You will need the usual build tools, CMake, a Windows cross-compiler, and flatc. On a Debian derivative (e.g. Ubuntu) these can be installed with: apt-get install git build-essential cmake mingw-w64 libflatbuffers-dev @@ -115,16 +116,7 @@ Before building, check out the project and the necessary submodules: cd solvespace git submodule update --init -After that, build 32-bit SolveSpace as following: - - mkdir build - cd build - cmake .. -DCMAKE_TOOLCHAIN_FILE=../cmake/Toolchain-mingw32.cmake \ - -DCMAKE_BUILD_TYPE=Release \ - -DFLATC=$(which flatc) - make - -Or, build 64-bit SolveSpace as following: +Build 64-bit SolveSpace with the following: mkdir build cd build From 6c2b967790b4554021b5f0fa8f16236456f95cbb Mon Sep 17 00:00:00 2001 From: Jason Lenz Date: Thu, 12 Nov 2020 14:11:28 -0600 Subject: [PATCH 049/113] Use recent flatbuffers commit to solve compiling issue on OpenBSD --- extlib/flatbuffers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extlib/flatbuffers b/extlib/flatbuffers index f73d205b..de1f0342 160000 --- a/extlib/flatbuffers +++ b/extlib/flatbuffers @@ -1 +1 @@ -Subproject commit f73d205bc7536991e620d3027a711e713a789967 +Subproject commit de1f0342c86fc00955f6047937fac05e56b9b54c From 142252ddf8b9fdf22cf59a2eb4ba5b726d741f54 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Mon, 16 Nov 2020 20:40:27 -0500 Subject: [PATCH 050/113] Add z distance checking to entity picking. Fixes issue 521 --- src/draw.cpp | 10 ++++++++++ src/render/render.cpp | 17 +++++++++++------ src/render/render.h | 3 ++- src/ui.h | 1 + 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/draw.cpp b/src/draw.cpp index 5370d1ed..0a21c198 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -342,6 +342,8 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToSelect() { Group *activeGroup = SK.GetGroup(SS.GW.activeGroup); int bestOrder = -1; int bestZIndex = 0; + double bestDepth = VERY_POSITIVE; + for(const Hover &hov : hoverList) { hGroup hg = {}; if(hov.selection.entity.v != 0) { @@ -353,8 +355,11 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToSelect() { Group *g = SK.GetGroup(hg); if(g->order > activeGroup->order) continue; if(bestOrder != -1 && (bestOrder > g->order || bestZIndex > hov.zIndex)) continue; + // we have hov.zIndex is >= best and hov.group is >= best (but not > active group) + if(hov.depth > bestDepth && bestOrder == g->order && bestZIndex == hov.zIndex) continue; bestOrder = g->order; bestZIndex = hov.zIndex; + bestDepth = hov.depth; sel = hov.selection; } return sel; @@ -370,6 +375,8 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToDrag() { Group *activeGroup = SK.GetGroup(SS.GW.activeGroup); int bestOrder = -1; int bestZIndex = 0; + double bestDepth = VERY_POSITIVE; + for(const Hover &hov : hoverList) { hGroup hg = {}; if(hov.selection.entity.v != 0) { @@ -383,6 +390,8 @@ GraphicsWindow::Selection GraphicsWindow::ChooseFromHoverToDrag() { Group *g = SK.GetGroup(hg); if(g->order > activeGroup->order) continue; if(bestOrder != -1 && (bestOrder > g->order || bestZIndex > hov.zIndex)) continue; + // we have hov.zIndex is >= best and hov.group is >= best (but not > active group) + if(hov.depth > bestDepth && bestOrder == g->order && bestZIndex == hov.zIndex) continue; bestOrder = g->order; bestZIndex = hov.zIndex; sel = hov.selection; @@ -439,6 +448,7 @@ void GraphicsWindow::HitTestMakeSelection(Point2d mp) { Hover hov = {}; hov.distance = canvas.minDistance; hov.zIndex = canvas.maxZIndex; + hov.depth = canvas.minDepth; hov.selection.entity = e.h; hoverList.Add(&hov); } diff --git a/src/render/render.cpp b/src/render/render.cpp index ca2a26eb..89434c2d 100644 --- a/src/render/render.cpp +++ b/src/render/render.cpp @@ -343,9 +343,10 @@ void UiCanvas::DrawBitmapText(const std::string &str, int x, int y, RgbaColor co // A canvas that performs picking against drawn geometry. //----------------------------------------------------------------------------- -void ObjectPicker::DoCompare(double distance, int zIndex, int comparePosition) { +void ObjectPicker::DoCompare(double depth, double distance, int zIndex, int comparePosition) { if(distance > selRadius) return; if((zIndex == maxZIndex && distance < minDistance) || (zIndex > maxZIndex)) { + minDepth = depth; minDistance = distance; maxZIndex = zIndex; position = comparePosition; @@ -372,10 +373,10 @@ void ObjectPicker::DoQuad(const Vector &a, const Vector &b, const Vector &c, con bool insideQuad = (minNegative == VERY_NEGATIVE || maxPositive == VERY_POSITIVE); if(insideQuad) { - DoCompare(0.0, zIndex, comparePosition); + DoCompare(0, 0.0, zIndex, comparePosition); } else { double distance = std::min(fabs(minNegative), fabs(maxPositive)); - DoCompare(distance, zIndex, comparePosition); + DoCompare(0, distance, zIndex, comparePosition); } } @@ -384,7 +385,8 @@ void ObjectPicker::DrawLine(const Vector &a, const Vector &b, hStroke hcs) { Point2d ap = camera.ProjectPoint(a); Point2d bp = camera.ProjectPoint(b); double distance = point.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true); - DoCompare(distance - stroke->width / 2.0, stroke->zIndex); + double depth = 0.5 * (camera.ProjectPoint3(a).z + camera.ProjectPoint3(b).z) ; + DoCompare(depth, distance - stroke->width / 2.0, stroke->zIndex); } void ObjectPicker::DrawEdges(const SEdgeList &el, hStroke hcs) { @@ -393,7 +395,8 @@ void ObjectPicker::DrawEdges(const SEdgeList &el, hStroke hcs) { Point2d ap = camera.ProjectPoint(e.a); Point2d bp = camera.ProjectPoint(e.b); double distance = point.DistanceToLine(ap, bp.Minus(ap), /*asSegment=*/true); - DoCompare(distance - stroke->width / 2.0, stroke->zIndex, e.auxB); + double depth = 0.5 * (camera.ProjectPoint3(e.a).z + camera.ProjectPoint3(e.b).z) ; + DoCompare(depth, distance - stroke->width / 2.0, stroke->zIndex, e.auxB); } } @@ -423,7 +426,8 @@ void ObjectPicker::DrawQuad(const Vector &a, const Vector &b, const Vector &c, c void ObjectPicker::DrawPoint(const Vector &o, Canvas::hStroke hcs) { Stroke *stroke = strokes.FindById(hcs); double distance = point.DistanceTo(camera.ProjectPoint(o)) - stroke->width / 2; - DoCompare(distance, stroke->zIndex); + double depth = camera.ProjectPoint3(o).z; + DoCompare(depth, distance, stroke->zIndex); } void ObjectPicker::DrawPolygon(const SPolygon &p, hFill hcf) { @@ -445,6 +449,7 @@ void ObjectPicker::DrawPixmap(std::shared_ptr pm, } bool ObjectPicker::Pick(const std::function &drawFn) { + minDepth = VERY_POSITIVE; minDistance = VERY_POSITIVE; maxZIndex = INT_MIN; diff --git a/src/render/render.h b/src/render/render.h index b1692f13..9601a5e7 100644 --- a/src/render/render.h +++ b/src/render/render.h @@ -232,6 +232,7 @@ public: double selRadius = 0.0; // Picking state. double minDistance = 0.0; + double minDepth = 1e10; int maxZIndex = 0; uint32_t position = 0; @@ -257,7 +258,7 @@ public: const Point2d &ta, const Point2d &tb, hFill hcf) override; void InvalidatePixmap(std::shared_ptr pm) override {} - void DoCompare(double distance, int zIndex, int comparePosition = 0); + void DoCompare(double depth, double distance, int zIndex, int comparePosition = 0); void DoQuad(const Vector &a, const Vector &b, const Vector &c, const Vector &d, int zIndex, int comparePosition = 0); diff --git a/src/ui.h b/src/ui.h index a7984102..8bdd701c 100644 --- a/src/ui.h +++ b/src/ui.h @@ -727,6 +727,7 @@ public: public: int zIndex; double distance; + double depth; Selection selection; }; From 5a3f45ed2a88298c2d9c2dd5f03ee12c97adcf23 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Tue, 17 Nov 2020 21:17:24 -0500 Subject: [PATCH 051/113] ran make translate_solvespace. cleaned out some obsolete strings in en_US.po --- res/locales/de_DE.po | 94 +++++++-------- res/locales/en_US.po | 266 +++++++------------------------------------ res/locales/fr_FR.po | 117 +++++++++---------- res/locales/ru_RU.po | 85 +++++++------- res/locales/uk_UA.po | 109 +++++++++--------- res/locales/zh_CN.po | 67 ++++++----- res/messages.pot | 99 ++++++++-------- 7 files changed, 331 insertions(+), 506 deletions(-) diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po index fb4f19b4..bf858b1f 100644 --- a/res/locales/de_DE.po +++ b/res/locales/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-09-21 09:28+0200\n" +"POT-Creation-Date: 2020-11-17 20:50-0500\n" "PO-Revision-Date: 2018-07-19 06:55+0000\n" "Last-Translator: Reini Urban \n" "Language-Team: none\n" @@ -597,8 +597,7 @@ msgstr "Zickzacklinien wurden mit durchgehenden Linien ersetzt" #: exportvector.cpp:593 msgid "" -"Some aspects of the drawing have no DXF equivalent and " -"were not exported:\n" +"Some aspects of the drawing have no DXF equivalent and were not exported:\n" msgstr "" "Teile der Zeichnung haben keine Entsprechung in DXF und wurden nicht " "exportiert:\n" @@ -628,18 +627,18 @@ msgstr "" "Nicht erkannte Daten in der Datei. Diese Datei könnte beschädigt sein oder " "von einer neueren Version des Programms stammen." -#: file.cpp:849 +#: file.cpp:859 msgctxt "title" msgid "Missing File" msgstr "Fehlende Datei" -#: file.cpp:850 +#: file.cpp:860 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "Die verlinkte Datei “%s” fehlt." -#: file.cpp:852 +#: file.cpp:862 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -648,20 +647,20 @@ msgid "" "permanently removed." msgstr "" "Möchten Sie sie selber auswählen?\n" -"Falls Sie ablehnen, wird jegliche mit der fehlenden Datei " -"verknüpfte Geometrie verworfen." +"Falls Sie ablehnen, wird jegliche mit der fehlenden Datei verknüpfte " +"Geometrie verworfen." -#: file.cpp:855 +#: file.cpp:865 msgctxt "button" msgid "&Yes" msgstr "&Ja" -#: file.cpp:857 +#: file.cpp:867 msgctxt "button" msgid "&No" msgstr "&Nein" -#: file.cpp:859 +#: file.cpp:869 msgctxt "button" msgid "&Cancel" msgstr "&Abbrechen" @@ -1371,19 +1370,19 @@ msgstr "Versetzen" msgid "(unnamed)" msgstr "unbenannt" -#: groupmesh.cpp:689 +#: groupmesh.cpp:708 msgid "not closed contour, or not all same style!" msgstr "Kontur nicht geschlossen, oder kein einheitlicher Linientyp!" -#: groupmesh.cpp:702 +#: groupmesh.cpp:721 msgid "points not all coplanar!" msgstr "Punkte sind nicht alle koplanar!" -#: groupmesh.cpp:704 +#: groupmesh.cpp:723 msgid "contour is self-intersecting!" msgstr "Kontur überschneidet sich selbst!" -#: groupmesh.cpp:706 +#: groupmesh.cpp:725 msgid "zero-length edge!" msgstr "Kante mit Länge Null!" @@ -1593,102 +1592,107 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEUER KOMMENTAR -- DOPPELKLICKEN ZUM BEARBEITEN" -#: platform/gui.cpp:85 +#: platform/gui.cpp:85 platform/gui.cpp:89 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace-Modelle" -#: platform/gui.cpp:89 +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "" + +#: platform/gui.cpp:94 msgctxt "file-type" msgid "PNG image" msgstr "PNG-Datei" -#: platform/gui.cpp:93 +#: platform/gui.cpp:98 msgctxt "file-type" msgid "STL mesh" msgstr "STL-Netz" -#: platform/gui.cpp:94 +#: platform/gui.cpp:99 msgctxt "file-type" msgid "Wavefront OBJ mesh" msgstr "Wavefront OBJ-Netz" -#: platform/gui.cpp:95 +#: platform/gui.cpp:100 msgctxt "file-type" msgid "Three.js-compatible mesh, with viewer" msgstr "Three.js-kompatibles Netz, mit Ansicht" -#: platform/gui.cpp:96 +#: platform/gui.cpp:101 msgctxt "file-type" msgid "Three.js-compatible mesh, mesh only" msgstr "Three.js-kompatibles Netz, nur Netz" -#: platform/gui.cpp:97 +#: platform/gui.cpp:102 msgctxt "file-type" msgid "Q3D Object file" msgstr "Q3D Objektdatei" -#: platform/gui.cpp:98 +#: platform/gui.cpp:103 msgctxt "file-type" msgid "VRML text file" msgstr "VRML Textdatei" -#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116 +#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "STEP file" msgstr "STEP-Datei" -#: platform/gui.cpp:106 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "PDF file" msgstr "PDF-Datei" -#: platform/gui.cpp:107 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "Eingebettetes Postscript" -#: platform/gui.cpp:108 +#: platform/gui.cpp:113 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "Skalierbare Vektorgrafik" -#: platform/gui.cpp:110 platform/gui.cpp:117 +#: platform/gui.cpp:115 platform/gui.cpp:122 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "DXF-Datei (AutoCAD 2007)" -#: platform/gui.cpp:111 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "HPGL file" msgstr "HPGL-Datei" -#: platform/gui.cpp:112 +#: platform/gui.cpp:117 msgctxt "file-type" msgid "G Code" msgstr "G-Code" -#: platform/gui.cpp:121 +#: platform/gui.cpp:126 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "AutoCAD DXF- und DWG-Dateien" -#: platform/gui.cpp:125 +#: platform/gui.cpp:130 msgctxt "file-type" msgid "Comma-separated values" msgstr "Werte durch Komma getrennt (CSV)" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 msgid "untitled" msgstr "unbenannt" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305 +#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 #: platform/guiwin.cpp:1555 msgctxt "title" msgid "Save File" msgstr "Datei speichern" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288 +#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 #: platform/guiwin.cpp:1557 msgctxt "title" msgid "Open File" @@ -1709,16 +1713,6 @@ msgctxt "button" msgid "_Open" msgstr "" -# solvespace.cpp:557 -msgctxt "title" -msgid "(new sketch)" -msgstr "(Neue Skizze)" - -#: solvespace.cpp:564 -msgctxt "title" -msgid "Property Browser" -msgstr "Attribut-Browser" - #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1904,6 +1898,15 @@ msgstr "Der Maßstab kann nicht Null oder negativ sein." msgid "Bad format: specify x, y, z" msgstr "Ungültiges Format: geben Sie x, y, z ein" +# solvespace.cpp:557 +#~ msgctxt "title" +#~ msgid "(new sketch)" +#~ msgstr "(Neue Skizze)" + +#~ msgctxt "title" +#~ msgid "Property Browser" +#~ msgstr "Attribut-Browser" + #~ msgid "Specify between 0 and 8 digits after the decimal." #~ msgstr "Geben Sie 0 bis 8 Ziffern nach dem Dezimalzeichen an." @@ -2016,4 +2019,3 @@ msgstr "Ungültiges Format: geben Sie x, y, z ein" #~ msgctxt "button" #~ msgid "_No" #~ msgstr "_Nein" - diff --git a/res/locales/en_US.po b/res/locales/en_US.po index 45b60995..485950f4 100644 --- a/res/locales/en_US.po +++ b/res/locales/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-09-21 09:28+0200\n" +"POT-Creation-Date: 2020-11-17 20:50-0500\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -607,18 +607,18 @@ msgstr "" "Unrecognized data in file. This file may be corrupt, or from a newer version " "of the program." -#: file.cpp:849 +#: file.cpp:859 msgctxt "title" msgid "Missing File" msgstr "Missing File" -#: file.cpp:850 +#: file.cpp:860 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "The linked file “%s” is not present." -#: file.cpp:852 +#: file.cpp:862 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -631,17 +631,17 @@ msgstr "" "If you decline, any geometry that depends on the missing file will be " "permanently removed." -#: file.cpp:855 +#: file.cpp:865 msgctxt "button" msgid "&Yes" msgstr "&Yes" -#: file.cpp:857 +#: file.cpp:867 msgctxt "button" msgid "&No" msgstr "&No" -#: file.cpp:859 +#: file.cpp:869 msgctxt "button" msgid "&Cancel" msgstr "&Cancel" @@ -1350,19 +1350,19 @@ msgstr "translate" msgid "(unnamed)" msgstr "(unnamed)" -#: groupmesh.cpp:689 +#: groupmesh.cpp:708 msgid "not closed contour, or not all same style!" msgstr "not closed contour, or not all same style!" -#: groupmesh.cpp:702 +#: groupmesh.cpp:721 msgid "points not all coplanar!" msgstr "points not all coplanar!" -#: groupmesh.cpp:704 +#: groupmesh.cpp:723 msgid "contour is self-intersecting!" msgstr "contour is self-intersecting!" -#: groupmesh.cpp:706 +#: groupmesh.cpp:725 msgid "zero-length edge!" msgstr "zero-length edge!" @@ -1564,102 +1564,107 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT" -#: platform/gui.cpp:85 +#: platform/gui.cpp:85 platform/gui.cpp:89 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace models" -#: platform/gui.cpp:89 +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "IDF circuit board" + +#: platform/gui.cpp:94 msgctxt "file-type" msgid "PNG image" msgstr "PNG image" -#: platform/gui.cpp:93 +#: platform/gui.cpp:98 msgctxt "file-type" msgid "STL mesh" msgstr "STL mesh" -#: platform/gui.cpp:94 +#: platform/gui.cpp:99 msgctxt "file-type" msgid "Wavefront OBJ mesh" msgstr "Wavefront OBJ mesh" -#: platform/gui.cpp:95 +#: platform/gui.cpp:100 msgctxt "file-type" msgid "Three.js-compatible mesh, with viewer" msgstr "Three.js-compatible mesh, with viewer" -#: platform/gui.cpp:96 +#: platform/gui.cpp:101 msgctxt "file-type" msgid "Three.js-compatible mesh, mesh only" msgstr "Three.js-compatible mesh, mesh only" -#: platform/gui.cpp:97 +#: platform/gui.cpp:102 msgctxt "file-type" msgid "Q3D Object file" msgstr "Q3D Object file" -#: platform/gui.cpp:98 +#: platform/gui.cpp:103 msgctxt "file-type" msgid "VRML text file" msgstr "VRML text file" -#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116 +#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "STEP file" msgstr "STEP file" -#: platform/gui.cpp:106 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "PDF file" msgstr "PDF file" -#: platform/gui.cpp:107 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "Encapsulated PostScript" -#: platform/gui.cpp:108 +#: platform/gui.cpp:113 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "Scalable Vector Graphics" -#: platform/gui.cpp:110 platform/gui.cpp:117 +#: platform/gui.cpp:115 platform/gui.cpp:122 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "DXF file (AutoCAD 2007)" -#: platform/gui.cpp:111 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "HPGL file" msgstr "HPGL file" -#: platform/gui.cpp:112 +#: platform/gui.cpp:117 msgctxt "file-type" msgid "G Code" msgstr "G Code" -#: platform/gui.cpp:121 +#: platform/gui.cpp:126 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "AutoCAD DXF and DWG files" -#: platform/gui.cpp:125 +#: platform/gui.cpp:130 msgctxt "file-type" msgid "Comma-separated values" msgstr "Comma-separated values" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 msgid "untitled" msgstr "untitled" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305 +#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 #: platform/guiwin.cpp:1555 msgctxt "title" msgid "Save File" msgstr "Save File" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288 +#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 #: platform/guiwin.cpp:1557 msgctxt "title" msgid "Open File" @@ -1680,16 +1685,6 @@ msgctxt "button" msgid "_Open" msgstr "_Open" -#: solvespace.cpp:557 -msgctxt "title" -msgid "(new sketch)" -msgstr "(new sketch)" - -#: solvespace.cpp:564 -msgctxt "title" -msgid "Property Browser" -msgstr "Property Browser" - #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1873,193 +1868,10 @@ msgstr "Scale cannot be zero or negative." msgid "Bad format: specify x, y, z" msgstr "Bad format: specify x, y, z" -#~ msgid "" -#~ "Some aspects of the drawing have no DWG equivalent and were not " -#~ "exported:\n" -#~ msgstr "" -#~ "Some aspects of the drawing have no DWG equivalent and were not " -#~ "exported:\n" - -#~ msgctxt "file-type" -#~ msgid "DWG file (AutoCAD 2000)" -#~ msgstr "DWG file (AutoCAD 2000)" - -#~ msgid "Specify between 0 and 8 digits after the decimal." -#~ msgstr "Specify between 0 and 8 digits after the decimal." - -#~ msgid "Show Degrees of &Freedom" -#~ msgstr "Show Degrees of &Freedom" - -#~ msgid "click to place bottom left of text" -#~ msgstr "click to place bottom left of text" - -#~ msgid "Do you want to save the changes you made to the new sketch?" -#~ msgstr "Do you want to save the changes you made to the new sketch?" - -#~ msgid "Your changes will be lost if you don't save them." -#~ msgstr "Your changes will be lost if you don't save them." - -#~ msgctxt "button" -#~ msgid "Save" -#~ msgstr "Save" - -#~ msgctxt "button" -#~ msgid "Cancel" -#~ msgstr "Cancel" - -#~ msgctxt "button" -#~ msgid "Don't Save" -#~ msgstr "Don't Save" - -#~ msgid "An autosave file is available for this project." -#~ msgstr "An autosave file is available for this project." - -#~ msgid "Do you want to load the autosave file instead?" -#~ msgstr "Do you want to load the autosave file instead?" - -#~ msgctxt "button" -#~ msgid "Load" -#~ msgstr "Load" - -#~ msgctxt "button" -#~ msgid "Don't Load" -#~ msgstr "Don't Load" - -#~ msgid "" -#~ "Do you want to locate it manually?\n" -#~ "If you select “No”, any geometry that depends on the missing file will be " -#~ "removed." -#~ msgstr "" -#~ "Do you want to locate it manually?\n" -#~ "If you select “No”, any geometry that depends on the missing file will be " -#~ "removed." - -#~ msgctxt "button" -#~ msgid "Yes" -#~ msgstr "Yes" - -#~ msgctxt "button" -#~ msgid "No" -#~ msgstr "No" - -#~ msgctxt "button" -#~ msgid "OK" -#~ msgstr "OK" +#~ msgctxt "title" +#~ msgid "(new sketch)" +#~ msgstr "(new sketch)" #~ msgctxt "title" #~ msgid "Property Browser" #~ msgstr "Property Browser" - -#~ msgid "_Cancel" -#~ msgstr "_Cancel" - -#~ msgid "_Open" -#~ msgstr "_Open" - -#~ msgid "" -#~ "The file has changed since it was last saved.\n" -#~ "\n" -#~ "Do you want to save the changes?" -#~ msgstr "" -#~ "The file has changed since it was last saved.\n" -#~ "\n" -#~ "Do you want to save the changes?" - -#~ msgctxt "title" -#~ msgid "Modified File" -#~ msgstr "Modified File" - -#~ msgctxt "button" -#~ msgid "Do_n't Save" -#~ msgstr "Do_n't Save" - -#~ msgid "" -#~ "An autosave file is available for this project.\n" -#~ "\n" -#~ "Do you want to load the autosave file instead?" -#~ msgstr "" -#~ "An autosave file is available for this project.\n" -#~ "\n" -#~ "Do you want to load the autosave file instead?" - -#~ msgctxt "title" -#~ msgid "Autosave Available" -#~ msgstr "Autosave Available" - -#~ msgctxt "button" -#~ msgid "_Load autosave" -#~ msgstr "_Load autosave" - -#~ msgctxt "button" -#~ msgid "Do_n't Load" -#~ msgstr "Do_n't Load" - -#~ msgctxt "button" -#~ msgid "_Yes" -#~ msgstr "_Yes" - -#~ msgctxt "button" -#~ msgid "_No" -#~ msgstr "_No" - -#~ msgid "SolveSpace models" -#~ msgstr "SolveSpace models" - -#~ msgid "PNG file" -#~ msgstr "PNG file" - -#~ msgid "STL mesh" -#~ msgstr "STL mesh" - -#~ msgid "Wavefront OBJ mesh" -#~ msgstr "Wavefront OBJ mesh" - -#~ msgid "Three.js-compatible mesh, with viewer" -#~ msgstr "Three.js-compatible mesh, with viewer" - -#~ msgid "Three.js-compatible mesh, mesh only" -#~ msgstr "Three.js-compatible mesh, mesh only" - -#~ msgid "STEP file" -#~ msgstr "STEP file" - -#~ msgid "PDF file" -#~ msgstr "PDF file" - -#~ msgid "Encapsulated PostScript" -#~ msgstr "Encapsulated PostScript" - -#~ msgid "Scalable Vector Graphics" -#~ msgstr "Scalable Vector Graphics" - -#~ msgid "DXF file (AutoCAD 2007)" -#~ msgstr "DXF file (AutoCAD 2007)" - -#~ msgid "HPGL file" -#~ msgstr "HPGL file" - -#~ msgid "G Code" -#~ msgstr "G Code" - -#~ msgid "AutoCAD DXF and DWG files" -#~ msgstr "AutoCAD DXF and DWG files" - -#~ msgid "Comma-separated values" -#~ msgstr "Comma-separated values" - -#~ msgid "" -#~ "Select two entities that intersect each other (e.g. two lines or two " -#~ "circles or a circle and a line)." -#~ msgstr "" -#~ "Select two entities that intersect each other (e.g. two lines or two " -#~ "circles or a circle and a line)." - -#~ msgid "Show Menu &Bar" -#~ msgstr "Show Menu &Bar" - -#~ msgctxt "group-name" -#~ msgid "link" -#~ msgstr "link" - -#~ msgid "Scale must not be zero or negative!" -#~ msgstr "Scale must not be zero or negative!" diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po index 6b643f26..8bea1a9f 100644 --- a/res/locales/fr_FR.po +++ b/res/locales/fr_FR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-09-21 09:28+0200\n" +"POT-Creation-Date: 2020-11-17 20:50-0500\n" "PO-Revision-Date: 2018-07-14 06:12+0000\n" "Last-Translator: whitequark \n" "Language-Team: none\n" @@ -624,18 +624,18 @@ msgstr "" "Données non reconnues dans le fichier. Ce fichier peut être corrompu ou " "depuis une version plus récente du programme." -#: file.cpp:849 +#: file.cpp:859 msgctxt "title" msgid "Missing File" msgstr "Fichier manquant" -#: file.cpp:850 +#: file.cpp:860 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "" -#: file.cpp:852 +#: file.cpp:862 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -644,17 +644,17 @@ msgid "" "permanently removed." msgstr "" -#: file.cpp:855 +#: file.cpp:865 msgctxt "button" msgid "&Yes" msgstr "" -#: file.cpp:857 +#: file.cpp:867 msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:859 +#: file.cpp:869 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1363,19 +1363,19 @@ msgstr "translation" msgid "(unnamed)" msgstr "(sans nom)" -#: groupmesh.cpp:689 +#: groupmesh.cpp:708 msgid "not closed contour, or not all same style!" msgstr "contour non fermé ou tout n'est pas du même style!" -#: groupmesh.cpp:702 +#: groupmesh.cpp:721 msgid "points not all coplanar!" msgstr "les points ne sont pas tous coplanaires!" -#: groupmesh.cpp:704 +#: groupmesh.cpp:723 msgid "contour is self-intersecting!" msgstr "le contour s'entrecroise!" -#: groupmesh.cpp:706 +#: groupmesh.cpp:725 msgid "zero-length edge!" msgstr "arête de longueur nulle!" @@ -1578,102 +1578,107 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NOUVEAU COMMENTAIRE - DOUBLE-CLIQUE POUR EDITER" -#: platform/gui.cpp:85 +#: platform/gui.cpp:85 platform/gui.cpp:89 msgctxt "file-type" msgid "SolveSpace models" msgstr "" -#: platform/gui.cpp:89 +#: platform/gui.cpp:90 msgctxt "file-type" -msgid "PNG image" -msgstr "" - -#: platform/gui.cpp:93 -msgctxt "file-type" -msgid "STL mesh" +msgid "IDF circuit board" msgstr "" #: platform/gui.cpp:94 msgctxt "file-type" -msgid "Wavefront OBJ mesh" -msgstr "" - -#: platform/gui.cpp:95 -msgctxt "file-type" -msgid "Three.js-compatible mesh, with viewer" -msgstr "" - -#: platform/gui.cpp:96 -msgctxt "file-type" -msgid "Three.js-compatible mesh, mesh only" -msgstr "" - -#: platform/gui.cpp:97 -msgctxt "file-type" -msgid "Q3D Object file" +msgid "PNG image" msgstr "" #: platform/gui.cpp:98 msgctxt "file-type" +msgid "STL mesh" +msgstr "" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "Q3D Object file" +msgstr "" + +#: platform/gui.cpp:103 +msgctxt "file-type" msgid "VRML text file" msgstr "" -#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116 +#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "STEP file" msgstr "" -#: platform/gui.cpp:106 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "PDF file" msgstr "" -#: platform/gui.cpp:107 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "" -#: platform/gui.cpp:108 +#: platform/gui.cpp:113 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "" -#: platform/gui.cpp:110 platform/gui.cpp:117 +#: platform/gui.cpp:115 platform/gui.cpp:122 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "" -#: platform/gui.cpp:111 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "HPGL file" msgstr "" -#: platform/gui.cpp:112 +#: platform/gui.cpp:117 msgctxt "file-type" msgid "G Code" msgstr "" -#: platform/gui.cpp:121 +#: platform/gui.cpp:126 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "" -#: platform/gui.cpp:125 +#: platform/gui.cpp:130 msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 msgid "untitled" msgstr "sans nom" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305 +#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 #: platform/guiwin.cpp:1555 msgctxt "title" msgid "Save File" msgstr "Sauver fichier" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288 +#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 #: platform/guiwin.cpp:1557 msgctxt "title" msgid "Open File" @@ -1694,16 +1699,6 @@ msgctxt "button" msgid "_Open" msgstr "" -#: solvespace.cpp:557 -msgctxt "title" -msgid "(new sketch)" -msgstr "(nouveau dessin)" - -#: solvespace.cpp:564 -msgctxt "title" -msgid "Property Browser" -msgstr "Navigateur de propriété" - #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1888,6 +1883,14 @@ msgstr "L'échelle ne peut pas être zéro ou négative." msgid "Bad format: specify x, y, z" msgstr "Mauvais format: Spécifiez x, y, z" +#~ msgctxt "title" +#~ msgid "(new sketch)" +#~ msgstr "(nouveau dessin)" + +#~ msgctxt "title" +#~ msgid "Property Browser" +#~ msgstr "Navigateur de propriété" + #~ msgid "Specify between 0 and 8 digits after the decimal." #~ msgstr "Spécifiez entre 0 et 8 chiffres après la virgule." diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po index 95a3a94e..aa6078ee 100644 --- a/res/locales/ru_RU.po +++ b/res/locales/ru_RU.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-09-21 09:28+0200\n" +"POT-Creation-Date: 2020-11-17 20:50-0500\n" "PO-Revision-Date: 2017-04-21 10:29+0700\n" "Last-Translator: evilspirit@evilspirit.org\n" "Language-Team: EvilSpirit\n" @@ -615,18 +615,18 @@ msgstr "" "Некоторые данные из этого файла не распознаны. Возможно, файл поврежден или " "создан в более новой версии программы" -#: file.cpp:849 +#: file.cpp:859 msgctxt "title" msgid "Missing File" msgstr "Файл Отсутствует" -#: file.cpp:850 +#: file.cpp:860 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "" -#: file.cpp:852 +#: file.cpp:862 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -638,17 +638,17 @@ msgstr "" "Если вы ответите \"Нет\", то вся геометрия, которая зависит от " "отсутствующего файла будет удалена." -#: file.cpp:855 +#: file.cpp:865 msgctxt "button" msgid "&Yes" msgstr "Да" -#: file.cpp:857 +#: file.cpp:867 msgctxt "button" msgid "&No" msgstr "Нет" -#: file.cpp:859 +#: file.cpp:869 msgctxt "button" msgid "&Cancel" msgstr "Отменить" @@ -1366,19 +1366,19 @@ msgstr "линейный-массив" msgid "(unnamed)" msgstr "(без имени)" -#: groupmesh.cpp:689 +#: groupmesh.cpp:708 msgid "not closed contour, or not all same style!" msgstr "незамкнутый контур или несовпадение стилей!" -#: groupmesh.cpp:702 +#: groupmesh.cpp:721 msgid "points not all coplanar!" msgstr "не все точки лежат в одной плоскости!" -#: groupmesh.cpp:704 +#: groupmesh.cpp:723 msgid "contour is self-intersecting!" msgstr "контур имеет самопересечения!" -#: groupmesh.cpp:706 +#: groupmesh.cpp:725 msgid "zero-length edge!" msgstr "вырожденный отрезок!" @@ -1581,102 +1581,107 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ" -#: platform/gui.cpp:85 +#: platform/gui.cpp:85 platform/gui.cpp:89 msgctxt "file-type" msgid "SolveSpace models" msgstr "проекты SolveSpace" -#: platform/gui.cpp:89 +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "" + +#: platform/gui.cpp:94 msgctxt "file-type" msgid "PNG image" msgstr "PNG изображение" -#: platform/gui.cpp:93 +#: platform/gui.cpp:98 msgctxt "file-type" msgid "STL mesh" msgstr "STL полигональная сетка" -#: platform/gui.cpp:94 +#: platform/gui.cpp:99 msgctxt "file-type" msgid "Wavefront OBJ mesh" msgstr "Wavefront OBJ полигональная сетка" -#: platform/gui.cpp:95 +#: platform/gui.cpp:100 msgctxt "file-type" msgid "Three.js-compatible mesh, with viewer" msgstr "Three.js-совместимая полигональная сетка с просмторщиком" -#: platform/gui.cpp:96 +#: platform/gui.cpp:101 msgctxt "file-type" msgid "Three.js-compatible mesh, mesh only" msgstr "Three.js-совместимая полигональная сетка" -#: platform/gui.cpp:97 +#: platform/gui.cpp:102 msgctxt "file-type" msgid "Q3D Object file" msgstr "" -#: platform/gui.cpp:98 +#: platform/gui.cpp:103 msgctxt "file-type" msgid "VRML text file" msgstr "" -#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116 +#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "STEP file" msgstr "STEP файл" -#: platform/gui.cpp:106 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "PDF file" msgstr "PDF документ" -#: platform/gui.cpp:107 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "Encapsulated PostScript" -#: platform/gui.cpp:108 +#: platform/gui.cpp:113 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "SVG изображение" -#: platform/gui.cpp:110 platform/gui.cpp:117 +#: platform/gui.cpp:115 platform/gui.cpp:122 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "DXF файл (AutoCAD 2007)" -#: platform/gui.cpp:111 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "HPGL file" msgstr "HPGL файл" -#: platform/gui.cpp:112 +#: platform/gui.cpp:117 msgctxt "file-type" msgid "G Code" msgstr "G Code" -#: platform/gui.cpp:121 +#: platform/gui.cpp:126 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "AutoCAD DXF и DWG файлы" -#: platform/gui.cpp:125 +#: platform/gui.cpp:130 msgctxt "file-type" msgid "Comma-separated values" msgstr "CSV файлы (значения, разделенные запятой)" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 msgid "untitled" msgstr "без имени" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305 +#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 #: platform/guiwin.cpp:1555 msgctxt "title" msgid "Save File" msgstr "Сохранить Файл" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288 +#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 #: platform/guiwin.cpp:1557 msgctxt "title" msgid "Open File" @@ -1697,16 +1702,6 @@ msgctxt "button" msgid "_Open" msgstr "" -#: solvespace.cpp:557 -msgctxt "title" -msgid "(new sketch)" -msgstr "(новый проект)" - -#: solvespace.cpp:564 -msgctxt "title" -msgid "Property Browser" -msgstr "Браузер" - #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1890,6 +1885,14 @@ msgstr "Масштабный коэффициент не может быть н msgid "Bad format: specify x, y, z" msgstr "Неверный формат: введите данные как x, y, z" +#~ msgctxt "title" +#~ msgid "(new sketch)" +#~ msgstr "(новый проект)" + +#~ msgctxt "title" +#~ msgid "Property Browser" +#~ msgstr "Браузер" + #~ msgid "Specify between 0 and 8 digits after the decimal." #~ msgstr "Введите число от 0 до 8." diff --git a/res/locales/uk_UA.po b/res/locales/uk_UA.po index d4c052d1..e9870664 100644 --- a/res/locales/uk_UA.po +++ b/res/locales/uk_UA.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-09-21 09:28+0200\n" +"POT-Creation-Date: 2020-11-17 20:50-0500\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: appsoft@ua.fm\n" "Language-Team: OpenOrienteeringUkraine\n" @@ -498,18 +498,18 @@ msgid "" "of the program." msgstr "" -#: file.cpp:849 +#: file.cpp:859 msgctxt "title" msgid "Missing File" msgstr "" -#: file.cpp:850 +#: file.cpp:860 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "" -#: file.cpp:852 +#: file.cpp:862 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -518,17 +518,17 @@ msgid "" "permanently removed." msgstr "" -#: file.cpp:855 +#: file.cpp:865 msgctxt "button" msgid "&Yes" msgstr "" -#: file.cpp:857 +#: file.cpp:867 msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:859 +#: file.cpp:869 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1189,19 +1189,19 @@ msgstr "" msgid "(unnamed)" msgstr "" -#: groupmesh.cpp:689 +#: groupmesh.cpp:708 msgid "not closed contour, or not all same style!" msgstr "" -#: groupmesh.cpp:702 +#: groupmesh.cpp:721 msgid "points not all coplanar!" msgstr "" -#: groupmesh.cpp:704 +#: groupmesh.cpp:723 msgid "contour is self-intersecting!" msgstr "" -#: groupmesh.cpp:706 +#: groupmesh.cpp:725 msgid "zero-length edge!" msgstr "" @@ -1388,102 +1388,107 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" -#: platform/gui.cpp:85 +#: platform/gui.cpp:85 platform/gui.cpp:89 msgctxt "file-type" msgid "SolveSpace models" msgstr "" -#: platform/gui.cpp:89 +#: platform/gui.cpp:90 msgctxt "file-type" -msgid "PNG image" -msgstr "" - -#: platform/gui.cpp:93 -msgctxt "file-type" -msgid "STL mesh" +msgid "IDF circuit board" msgstr "" #: platform/gui.cpp:94 msgctxt "file-type" -msgid "Wavefront OBJ mesh" -msgstr "" - -#: platform/gui.cpp:95 -msgctxt "file-type" -msgid "Three.js-compatible mesh, with viewer" -msgstr "" - -#: platform/gui.cpp:96 -msgctxt "file-type" -msgid "Three.js-compatible mesh, mesh only" -msgstr "" - -#: platform/gui.cpp:97 -msgctxt "file-type" -msgid "Q3D Object file" +msgid "PNG image" msgstr "" #: platform/gui.cpp:98 msgctxt "file-type" +msgid "STL mesh" +msgstr "" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "Q3D Object file" +msgstr "" + +#: platform/gui.cpp:103 +msgctxt "file-type" msgid "VRML text file" msgstr "" -#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116 +#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "STEP file" msgstr "" -#: platform/gui.cpp:106 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "PDF file" msgstr "" -#: platform/gui.cpp:107 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "" -#: platform/gui.cpp:108 +#: platform/gui.cpp:113 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "" -#: platform/gui.cpp:110 platform/gui.cpp:117 +#: platform/gui.cpp:115 platform/gui.cpp:122 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "" -#: platform/gui.cpp:111 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "HPGL file" msgstr "" -#: platform/gui.cpp:112 +#: platform/gui.cpp:117 msgctxt "file-type" msgid "G Code" msgstr "" -#: platform/gui.cpp:121 +#: platform/gui.cpp:126 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "" -#: platform/gui.cpp:125 +#: platform/gui.cpp:130 msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 msgid "untitled" msgstr "" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305 +#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 #: platform/guiwin.cpp:1555 msgctxt "title" msgid "Save File" msgstr "" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288 +#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 #: platform/guiwin.cpp:1557 msgctxt "title" msgid "Open File" @@ -1504,16 +1509,6 @@ msgctxt "button" msgid "_Open" msgstr "" -#: solvespace.cpp:557 -msgctxt "title" -msgid "(new sketch)" -msgstr "" - -#: solvespace.cpp:564 -msgctxt "title" -msgid "Property Browser" -msgstr "" - #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " diff --git a/res/locales/zh_CN.po b/res/locales/zh_CN.po index 4d2d2d41..a2e1b454 100644 --- a/res/locales/zh_CN.po +++ b/res/locales/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-09-21 09:28+0200\n" +"POT-Creation-Date: 2020-11-17 20:50-0500\n" "PO-Revision-Date: 2020-09-28 12:42+0800\n" "Last-Translator: lomatus@163.com\n" "Language-Team: none\n" @@ -576,18 +576,18 @@ msgid "" "of the program." msgstr "未识别文件内数据。该文件可能损坏,或使用新版本应用程序尝试打开。" -#: file.cpp:849 +#: file.cpp:859 msgctxt "title" msgid "Missing File" msgstr "文件丢失" -#: file.cpp:850 +#: file.cpp:860 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "连接的文件不存在:\"%s\"。" -#: file.cpp:852 +#: file.cpp:862 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -596,17 +596,17 @@ msgid "" "permanently removed." msgstr "您是否想手工查找?如果是,所有基于该丢失文件的几何对象将会被全部删除." -#: file.cpp:855 +#: file.cpp:865 msgctxt "button" msgid "&Yes" msgstr "是(&Y)" -#: file.cpp:857 +#: file.cpp:867 msgctxt "button" msgid "&No" msgstr "否(&N)" -#: file.cpp:859 +#: file.cpp:869 msgctxt "button" msgid "&Cancel" msgstr "取消(&C)" @@ -1276,19 +1276,19 @@ msgstr "移动" msgid "(unnamed)" msgstr "(未命名)" -#: groupmesh.cpp:689 +#: groupmesh.cpp:708 msgid "not closed contour, or not all same style!" msgstr "未闭合轮廓,或样式不一致!" -#: groupmesh.cpp:702 +#: groupmesh.cpp:721 msgid "points not all coplanar!" msgstr "点不在相同平面!" -#: groupmesh.cpp:704 +#: groupmesh.cpp:723 msgid "contour is self-intersecting!" msgstr "轮廓自相交!" -#: groupmesh.cpp:706 +#: groupmesh.cpp:725 msgid "zero-length edge!" msgstr "边缘长度为零!" @@ -1475,102 +1475,107 @@ msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "新备注 - 双击编辑" -#: platform/gui.cpp:85 +#: platform/gui.cpp:85 platform/gui.cpp:89 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace模型" -#: platform/gui.cpp:89 +#: platform/gui.cpp:90 +msgctxt "file-type" +msgid "IDF circuit board" +msgstr "" + +#: platform/gui.cpp:94 msgctxt "file-type" msgid "PNG image" msgstr "PNG图片" -#: platform/gui.cpp:93 +#: platform/gui.cpp:98 msgctxt "file-type" msgid "STL mesh" msgstr "STL网格" -#: platform/gui.cpp:94 +#: platform/gui.cpp:99 msgctxt "file-type" msgid "Wavefront OBJ mesh" msgstr "Wavefront OBJ网格" -#: platform/gui.cpp:95 +#: platform/gui.cpp:100 msgctxt "file-type" msgid "Three.js-compatible mesh, with viewer" msgstr "Three.js-网格及查看视图" -#: platform/gui.cpp:96 +#: platform/gui.cpp:101 msgctxt "file-type" msgid "Three.js-compatible mesh, mesh only" msgstr "Three.js-仅网格" -#: platform/gui.cpp:97 +#: platform/gui.cpp:102 msgctxt "file-type" msgid "Q3D Object file" msgstr "Q3D对象文件" -#: platform/gui.cpp:98 +#: platform/gui.cpp:103 msgctxt "file-type" msgid "VRML text file" msgstr "VRML文本文件" -#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116 +#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "STEP file" msgstr "STEP文件" -#: platform/gui.cpp:106 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "PDF file" msgstr "PDF文件" -#: platform/gui.cpp:107 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "封装好的PostScript" -#: platform/gui.cpp:108 +#: platform/gui.cpp:113 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "SVG矢量图" -#: platform/gui.cpp:110 platform/gui.cpp:117 +#: platform/gui.cpp:115 platform/gui.cpp:122 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "DXF文件(AutoCAD 2007)" -#: platform/gui.cpp:111 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "HPGL file" msgstr "HPGL文件" -#: platform/gui.cpp:112 +#: platform/gui.cpp:117 msgctxt "file-type" msgid "G Code" msgstr "G Code" -#: platform/gui.cpp:121 +#: platform/gui.cpp:126 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "AutoCAD DXF/DWG文件" -#: platform/gui.cpp:125 +#: platform/gui.cpp:130 msgctxt "file-type" msgid "Comma-separated values" msgstr "逗号分隔数据" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 msgid "untitled" msgstr "未命名" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305 +#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 #: platform/guiwin.cpp:1555 msgctxt "title" msgid "Save File" msgstr "保存文件" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288 +#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 #: platform/guiwin.cpp:1557 msgctxt "title" msgid "Open File" diff --git a/res/messages.pot b/res/messages.pot index 8ea9c85b..7f025001 100644 --- a/res/messages.pot +++ b/res/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-09-21 09:28+0200\n" +"POT-Creation-Date: 2020-11-17 20:50-0500\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -477,18 +477,18 @@ msgstr "" msgid "Unrecognized data in file. This file may be corrupt, or from a newer version of the program." msgstr "" -#: file.cpp:849 +#: file.cpp:859 msgctxt "title" msgid "Missing File" msgstr "" -#: file.cpp:850 +#: file.cpp:860 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "" -#: file.cpp:852 +#: file.cpp:862 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -496,17 +496,17 @@ msgid "" "If you decline, any geometry that depends on the missing file will be permanently removed." msgstr "" -#: file.cpp:855 +#: file.cpp:865 msgctxt "button" msgid "&Yes" msgstr "" -#: file.cpp:857 +#: file.cpp:867 msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:859 +#: file.cpp:869 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1160,19 +1160,19 @@ msgstr "" msgid "(unnamed)" msgstr "" -#: groupmesh.cpp:689 +#: groupmesh.cpp:708 msgid "not closed contour, or not all same style!" msgstr "" -#: groupmesh.cpp:702 +#: groupmesh.cpp:721 msgid "points not all coplanar!" msgstr "" -#: groupmesh.cpp:704 +#: groupmesh.cpp:723 msgid "contour is self-intersecting!" msgstr "" -#: groupmesh.cpp:706 +#: groupmesh.cpp:725 msgid "zero-length edge!" msgstr "" @@ -1350,102 +1350,107 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" -#: platform/gui.cpp:85 +#: platform/gui.cpp:85 platform/gui.cpp:89 msgctxt "file-type" msgid "SolveSpace models" msgstr "" -#: platform/gui.cpp:89 +#: platform/gui.cpp:90 msgctxt "file-type" -msgid "PNG image" -msgstr "" - -#: platform/gui.cpp:93 -msgctxt "file-type" -msgid "STL mesh" +msgid "IDF circuit board" msgstr "" #: platform/gui.cpp:94 msgctxt "file-type" -msgid "Wavefront OBJ mesh" -msgstr "" - -#: platform/gui.cpp:95 -msgctxt "file-type" -msgid "Three.js-compatible mesh, with viewer" -msgstr "" - -#: platform/gui.cpp:96 -msgctxt "file-type" -msgid "Three.js-compatible mesh, mesh only" -msgstr "" - -#: platform/gui.cpp:97 -msgctxt "file-type" -msgid "Q3D Object file" +msgid "PNG image" msgstr "" #: platform/gui.cpp:98 msgctxt "file-type" +msgid "STL mesh" +msgstr "" + +#: platform/gui.cpp:99 +msgctxt "file-type" +msgid "Wavefront OBJ mesh" +msgstr "" + +#: platform/gui.cpp:100 +msgctxt "file-type" +msgid "Three.js-compatible mesh, with viewer" +msgstr "" + +#: platform/gui.cpp:101 +msgctxt "file-type" +msgid "Three.js-compatible mesh, mesh only" +msgstr "" + +#: platform/gui.cpp:102 +msgctxt "file-type" +msgid "Q3D Object file" +msgstr "" + +#: platform/gui.cpp:103 +msgctxt "file-type" msgid "VRML text file" msgstr "" -#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116 +#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "STEP file" msgstr "" -#: platform/gui.cpp:106 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "PDF file" msgstr "" -#: platform/gui.cpp:107 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "" -#: platform/gui.cpp:108 +#: platform/gui.cpp:113 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "" -#: platform/gui.cpp:110 platform/gui.cpp:117 +#: platform/gui.cpp:115 platform/gui.cpp:122 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "" -#: platform/gui.cpp:111 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "HPGL file" msgstr "" -#: platform/gui.cpp:112 +#: platform/gui.cpp:117 msgctxt "file-type" msgid "G Code" msgstr "" -#: platform/gui.cpp:121 +#: platform/gui.cpp:126 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "" -#: platform/gui.cpp:125 +#: platform/gui.cpp:130 msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 msgid "untitled" msgstr "" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305 +#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 #: platform/guiwin.cpp:1555 msgctxt "title" msgid "Save File" msgstr "" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288 +#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 #: platform/guiwin.cpp:1557 msgctxt "title" msgid "Open File" From 1b2d47cd8603b017de1b715c84502d57ed0fc860 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Wed, 18 Nov 2020 10:53:14 +0100 Subject: [PATCH 052/113] Travis: deploy tagged commits & edge tagging fixes With the recent Travis changes, we prevented the deploy stage from running for tagged commits as branch=tag for tagged commits. Fix this by also running deploy for tagged commits. Furthermore, clean up .travis.yml by pulling the edge tagging logic into a separate script. A logic change is introduced to prevent git tag --force being run on set tags as this would turn annotated tags into lightweight tags. --- .travis.yml | 20 ++++---------------- .travis/tag-edge.sh | 8 ++++++++ 2 files changed, 12 insertions(+), 16 deletions(-) create mode 100755 .travis/tag-edge.sh diff --git a/.travis.yml b/.travis.yml index 4d796af7..b9f64899 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ stages: - name: clean if: (NOT type IN (pull_request)) AND (branch = master) - name: deploy - if: (NOT type IN (pull_request)) AND (branch = master) + if: (NOT type IN (pull_request)) AND (branch = master OR tag IS present) jobs: include: - stage: clean @@ -29,11 +29,7 @@ jobs: osx_image: xcode12.2 install: ".travis/install-macos.sh" script: ".travis/build-macos.sh release && .travis/sign-macos.sh" - before_deploy: - - git config --local user.name "solvespace-cd" - - git config --local user.email "no-reply@solvespace.com" - - export TRAVIS_TAG=${TRAVIS_TAG:-edge} - - git tag --force $TRAVIS_TAG + before_deploy: source .travis/tag-edge.sh deploy: provider: releases skip_cleanup: true @@ -59,11 +55,7 @@ jobs: os: windows install: .travis/install-windows.sh script: .travis/build-windows.sh release - before_deploy: - - git config --local user.name "solvespace-cd" - - git config --local user.email "no-reply@solvespace.com" - - export TRAVIS_TAG=${TRAVIS_TAG:-edge} - - git tag --force $TRAVIS_TAG + before_deploy: source .travis/tag-edge.sh deploy: provider: releases skip_cleanup: true @@ -78,11 +70,7 @@ jobs: os: windows install: .travis/install-windows.sh script: .travis/build-windows.sh release openmp - before_deploy: - - git config --local user.name "solvespace-cd" - - git config --local user.email "no-reply@solvespace.com" - - export TRAVIS_TAG=${TRAVIS_TAG:-edge} - - git tag --force $TRAVIS_TAG + before_deploy: source .travis/tag-edge.sh deploy: provider: releases skip_cleanup: true diff --git a/.travis/tag-edge.sh b/.travis/tag-edge.sh new file mode 100755 index 00000000..8ce6a194 --- /dev/null +++ b/.travis/tag-edge.sh @@ -0,0 +1,8 @@ +#!/bin/sh -xe + +if [ -z "$TRAVIS_TAG" ]; then + git config --local user.name "solvespace-cd" + git config --local user.email "no-reply@solvespace.com" + export TRAVIS_TAG="edge" + git tag --force $TRAVIS_TAG +fi From 898fb6f4f5624fda29707713d6b7e21cdd152c31 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Wed, 18 Nov 2020 15:27:35 +0100 Subject: [PATCH 053/113] Travis: deploy tagged & master commits to GitHub Our implicit deploy conditions were previously only met by untagged commits on master. As the stage conditions filter everything except branch = master and tagged commits, we can just use all_branches: true to also deploy tagged builds. Also clean up the snap deploy sections. --- .travis.yml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b9f64899..0681bf2b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -39,6 +39,8 @@ jobs: name: ${TRAVIS_TAG:-edge} release_notes: $TRAVIS_COMMIT_MESSAGE file: build/bin/SolveSpace.dmg + on: + all_branches: true - stage: test name: "Ubuntu" os: linux @@ -65,6 +67,8 @@ jobs: name: ${TRAVIS_TAG:-edge} release_notes: $TRAVIS_COMMIT_MESSAGE file: build/bin/RelWithDebInfo/solvespace.exe + on: + all_branches: true - stage: deploy name: "Windows with OpenMP" os: windows @@ -80,6 +84,8 @@ jobs: name: ${TRAVIS_TAG:-edge} release_notes: $TRAVIS_COMMIT_MESSAGE file: build/bin/RelWithDebInfo/solvespace-openmp.exe + on: + all_branches: true - &deploy-snap stage: deploy name: Snap amd64 @@ -95,14 +101,10 @@ jobs: - provider: script script: sudo .travis/deploy-snap.sh edge skip_cleanup: true - on: - branch: master - tags: false - provider: script script: sudo .travis/deploy-snap.sh edge,beta skip_cleanup: true on: - branch: master tags: true - <<: *deploy-snap name: Snap arm64 From bcb8cd2c03259f382cd15d6a4497b3fa7a8ebba6 Mon Sep 17 00:00:00 2001 From: ruevs Date: Wed, 18 Nov 2020 17:04:36 +0200 Subject: [PATCH 054/113] Fix unsequenced modification and access warnings. Found by clang 11. They are a potential problem. [ 21%] Building CXX object src/CMakeFiles/solvespace-core.dir/exportstep.cpp.obj .\src\exportstep.cpp:293:61: warning: unsequenced modification and access to 'id' [-Wunsequenced] fprintf(f, "#%d=FILL_AREA_STYLE_COLOUR('',#%d);\n", ++id, id - 1); ^ ~~ .\src\exportstep.cpp:294:56: warning: unsequenced modification and access to 'id' [-Wunsequenced] fprintf(f, "#%d=FILL_AREA_STYLE('',(#%d));\n", ++id, id - 1); ^ ~~ .\src\exportstep.cpp:295:59: warning: unsequenced modification and access to 'id' [-Wunsequenced] fprintf(f, "#%d=SURFACE_STYLE_FILL_AREA(#%d);\n", ++id, id - 1); ^ ~~ .\src\exportstep.cpp:297:98: warning: unsequenced modification and access to 'id' [-Wunsequenced] fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", ++id, id - 5, id - 1); ^ ~~ .\src\exportstep.cpp:298:64: warning: unsequenced modification and access to 'id' [-Wunsequenced] fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d, #%d));\n", ++id, id - 3, id - 1); ^ ~~ .\src\exportstep.cpp:300:62: warning: unsequenced modification and access to 'id' [-Wunsequenced] fprintf(f, "#%d=SURFACE_STYLE_USAGE(.BOTH.,#%d);\n", ++id, id - 1); ^ ~~ .\src\exportstep.cpp:301:67: warning: unsequenced modification and access to 'id' [-Wunsequenced] fprintf(f, "#%d=PRESENTATION_STYLE_ASSIGNMENT((#%d));\n", ++id, id - 1); ^ ~~ .\src\exportstep.cpp:302:56: warning: unsequenced modification and access to 'id' [-Wunsequenced] fprintf(f, "#%d=STYLED_ITEM('',(#%d),#%d);\n", ++id, id - 1, advFaceId); ^ ~~ 8 warnings generated. --- src/exportstep.cpp | 32 +++++++++++++++++++++----------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/exportstep.cpp b/src/exportstep.cpp index 91585226..db42dc08 100644 --- a/src/exportstep.cpp +++ b/src/exportstep.cpp @@ -282,24 +282,34 @@ void StepFileWriter::ExportSurface(SSurface *ss, SBezierList *sbl) { ss->color.greenF(), ss->color.blueF()); /* // This works in Kisters 3DViewStation but not in KiCAD and Horison EDA, - // it seems they do not support transparency so use the more verbose one below + // it seems they do not support transparency so use the more verbose one below fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); + ++id; fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", - ++id, id - 2, id - 1); - fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d));\n", ++id, id - 1); + id, id - 2, id - 1); + ++id; + fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d));\n", id, id - 1); */ // This works in Horison EDA but is more verbose. - fprintf(f, "#%d=FILL_AREA_STYLE_COLOUR('',#%d);\n", ++id, id - 1); - fprintf(f, "#%d=FILL_AREA_STYLE('',(#%d));\n", ++id, id - 1); - fprintf(f, "#%d=SURFACE_STYLE_FILL_AREA(#%d);\n", ++id, id - 1); + ++id; + fprintf(f, "#%d=FILL_AREA_STYLE_COLOUR('',#%d);\n", id, id - 1); + ++id; + fprintf(f, "#%d=FILL_AREA_STYLE('',(#%d));\n", id, id - 1); + ++id; + fprintf(f, "#%d=SURFACE_STYLE_FILL_AREA(#%d);\n", id, id - 1); fprintf(f, "#%d=SURFACE_STYLE_TRANSPARENT(%.2f);\n", ++id, 1.0 - ss->color.alphaF()); - fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", ++id, id - 5, id - 1); - fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d, #%d));\n", ++id, id - 3, id - 1); + ++id; + fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n", id, id - 5, id - 1); + ++id; + fprintf(f, "#%d=SURFACE_SIDE_STYLE('',(#%d, #%d));\n", id, id - 3, id - 1); - fprintf(f, "#%d=SURFACE_STYLE_USAGE(.BOTH.,#%d);\n", ++id, id - 1); - fprintf(f, "#%d=PRESENTATION_STYLE_ASSIGNMENT((#%d));\n", ++id, id - 1); - fprintf(f, "#%d=STYLED_ITEM('',(#%d),#%d);\n", ++id, id - 1, advFaceId); + ++id; + fprintf(f, "#%d=SURFACE_STYLE_USAGE(.BOTH.,#%d);\n", id, id - 1); + ++id; + fprintf(f, "#%d=PRESENTATION_STYLE_ASSIGNMENT((#%d));\n", id, id - 1); + ++id; + fprintf(f, "#%d=STYLED_ITEM('',(#%d),#%d);\n", id, id - 1, advFaceId); fprintf(f, "\n"); id++; From 427a29abb26d4c00c8ab7b885283c135be720889 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Wed, 18 Nov 2020 21:43:08 +0100 Subject: [PATCH 055/113] Travis: build snaps in LXD containers With arm64-graviton2 now providing full VM virtualization, LXD containers can be used to build snaps on all architectures. This is beneficial for us as having snapcraft manage the whole build environment is likely to yield better/more consistent results than running the builds on the Travis images directly. --- .travis.yml | 10 ++++++---- .travis/build-snap.sh | 3 +-- .travis/deploy-snap.sh | 2 +- .travis/install-snap.sh | 6 ++++++ 4 files changed, 14 insertions(+), 7 deletions(-) create mode 100755 .travis/install-snap.sh diff --git a/.travis.yml b/.travis.yml index 0681bf2b..a692aa77 100644 --- a/.travis.yml +++ b/.travis.yml @@ -91,18 +91,20 @@ jobs: name: Snap amd64 os: linux arch: amd64 - dist: bionic + dist: focal addons: snaps: - name: snapcraft confinement: classic + - name: lxd + install: .travis/install-snap.sh script: .travis/build-snap.sh deploy: - provider: script - script: sudo .travis/deploy-snap.sh edge + script: .travis/deploy-snap.sh edge skip_cleanup: true - provider: script - script: sudo .travis/deploy-snap.sh edge,beta + script: .travis/deploy-snap.sh edge,beta skip_cleanup: true on: tags: true @@ -110,4 +112,4 @@ jobs: name: Snap arm64 arch: arm64-graviton2 group: edge - virt: lxd + virt: vm diff --git a/.travis/build-snap.sh b/.travis/build-snap.sh index 634e01c4..665e5614 100755 --- a/.travis/build-snap.sh +++ b/.travis/build-snap.sh @@ -1,4 +1,3 @@ #!/bin/sh -xe -sudo apt-get update -sudo ./pkg/snap/build.sh --destructive-mode +./pkg/snap/build.sh --use-lxd diff --git a/.travis/deploy-snap.sh b/.travis/deploy-snap.sh index 91674a7c..9cbab5b1 100755 --- a/.travis/deploy-snap.sh +++ b/.travis/deploy-snap.sh @@ -4,5 +4,5 @@ channels="$1" echo "$SNAP_TOKEN" | snapcraft login --with - for snap in ./pkg/snap/*.snap; do - snapcraft push "$snap" --release "$channels" + snapcraft upload "$snap" --release "$channels" done diff --git a/.travis/install-snap.sh b/.travis/install-snap.sh new file mode 100755 index 00000000..e10a91da --- /dev/null +++ b/.travis/install-snap.sh @@ -0,0 +1,6 @@ +#!/bin/sh -xe + +sudo /snap/bin/lxd waitready +sudo /snap/bin/lxd init --auto +sudo chgrp travis /var/snap/lxd/common/lxd/unix.socket +mkdir -p "$TRAVIS_BUILD_DIR/snaps-cache" From 942bf3f35409ac58b3f2bc90144dea67a96f6200 Mon Sep 17 00:00:00 2001 From: ruevs Date: Fri, 13 Nov 2020 23:46:33 +0200 Subject: [PATCH 056/113] Remove Q3DO export. It was added in 3a3a2755b as a potential way to export colorful meshes to Horizon EDA but ended up being supported only by SolveSpace. Since no software can consume the exported q3do files the feature is superfluous. See https://github.com/solvespace/solvespace/issues/795 for details. --- .gitmodules | 6 ----- .travis/install-ubuntu.sh | 2 +- CHANGELOG.md | 3 ++- CMakeLists.txt | 11 -------- README.md | 6 ++--- extlib/flatbuffers | 1 - extlib/q3d | 1 - pkg/snap/snap/snapcraft.yaml | 2 +- src/CMakeLists.txt | 3 --- src/export.cpp | 50 ------------------------------------ src/platform/gui.cpp | 1 - src/solvespace.h | 1 - 12 files changed, 7 insertions(+), 80 deletions(-) delete mode 160000 extlib/flatbuffers delete mode 160000 extlib/q3d diff --git a/.gitmodules b/.gitmodules index 51193203..71384a1a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -20,12 +20,6 @@ [submodule "extlib/angle"] path = extlib/angle url = https://github.com/solvespace/angle -[submodule "extlib/flatbuffers"] - path = extlib/flatbuffers - url = https://github.com/google/flatbuffers -[submodule "extlib/q3d"] - path = extlib/q3d - url = https://github.com/q3k/q3d [submodule "extlib/mimalloc"] path = extlib/mimalloc url = https://github.com/microsoft/mimalloc diff --git a/.travis/install-ubuntu.sh b/.travis/install-ubuntu.sh index fb20fffa..53f88b27 100755 --- a/.travis/install-ubuntu.sh +++ b/.travis/install-ubuntu.sh @@ -7,4 +7,4 @@ sudo apt-get install -q -y \ libfontconfig1-dev libgtkmm-3.0-dev libpangomm-1.4-dev libgl-dev \ libgl-dev libglu-dev libspnav-dev -git submodule update --init extlib/libdxfrw extlib/flatbuffers extlib/q3d extlib/mimalloc +git submodule update --init extlib/libdxfrw extlib/mimalloc diff --git a/CHANGELOG.md b/CHANGELOG.md index f3faa478..a7a40327 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,7 +53,8 @@ New export/import features: * 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. - * Q3D: [Q3D](https://github.com/q3k/q3d/) triangle meshes can now be + * [ADDED 2019-02-25](https://github.com/solvespace/solvespace/pull/384) and [REMOVED 2020-11-13](https://github.com/solvespace/solvespace/issues/795): + Q3D: [Q3D](https://github.com/q3k/q3d/) triangle meshes can now be exported. This format allows to easily hack on triangle mesh data created in SolveSpace, supports colour information and is more space efficient than most other formats. diff --git a/CMakeLists.txt b/CMakeLists.txt index ad23d983..6cdca35c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,17 +182,6 @@ endif() message(STATUS "Using in-tree libdxfrw") add_subdirectory(extlib/libdxfrw) -message(STATUS "Using in-tree flatbuffers") -set(FLATBUFFERS_BUILD_FLATLIB ON CACHE BOOL "") -set(FLATBUFFERS_BUILD_FLATC ON CACHE BOOL "") -set(FLATBUFFERS_BUILD_FLATHASH OFF CACHE BOOL "") -set(FLATBUFFERS_BUILD_TESTS OFF CACHE BOOL "") -add_subdirectory(extlib/flatbuffers EXCLUDE_FROM_ALL) - -message(STATUS "Using in-tree q3d") -add_subdirectory(extlib/q3d) -set(Q3D_INCLUDE_DIR ${CMAKE_BINARY_DIR}/extlib/q3d) - message(STATUS "Using in-tree mimalloc") set(MI_OVERRIDE OFF CACHE BOOL "") set(MI_BUILD_SHARED OFF CACHE BOOL "") diff --git a/README.md b/README.md index 394e33dc..cbeb89f5 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ Before building, check out the project and the necessary submodules: git clone https://github.com/solvespace/solvespace cd solvespace - git submodule update --init extlib/libdxfrw extlib/flatbuffers extlib/q3d extlib/mimalloc + git submodule update --init extlib/libdxfrw extlib/mimalloc After that, build SolveSpace as following: @@ -108,7 +108,7 @@ Ubuntu will require 20.04 or above. Cross-compiling with WSL is also confirmed t You will need the usual build tools, CMake, a Windows cross-compiler, and flatc. On a Debian derivative (e.g. Ubuntu) these can be installed with: - apt-get install git build-essential cmake mingw-w64 libflatbuffers-dev + apt-get install git build-essential cmake mingw-w64 Before building, check out the project and the necessary submodules: @@ -182,7 +182,7 @@ Before building, check out the project and the necessary submodules: git clone https://github.com/solvespace/solvespace cd solvespace - git submodule update --init extlib/libdxfrw extlib/flatbuffers extlib/q3d extlib/mimalloc + git submodule update --init extlib/libdxfrw extlib/mimalloc After that, build SolveSpace as following: diff --git a/extlib/flatbuffers b/extlib/flatbuffers deleted file mode 160000 index de1f0342..00000000 --- a/extlib/flatbuffers +++ /dev/null @@ -1 +0,0 @@ -Subproject commit de1f0342c86fc00955f6047937fac05e56b9b54c diff --git a/extlib/q3d b/extlib/q3d deleted file mode 160000 index 880db1d3..00000000 --- a/extlib/q3d +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 880db1d34706778f216a2308fd82a9a3adacb314 diff --git a/pkg/snap/snap/snapcraft.yaml b/pkg/snap/snap/snapcraft.yaml index 400ea19e..5fe5f7be 100644 --- a/pkg/snap/snap/snapcraft.yaml +++ b/pkg/snap/snap/snapcraft.yaml @@ -45,7 +45,7 @@ parts: snapcraftctl set-version "$version" git describe --exact-match HEAD && grade="stable" || grade="devel" snapcraftctl set-grade "$grade" - git submodule update --init extlib/libdxfrw extlib/flatbuffers extlib/q3d extlib/mimalloc + git submodule update --init extlib/libdxfrw extlib/mimalloc configflags: - -DCMAKE_INSTALL_PREFIX=/usr - -DCMAKE_BUILD_TYPE=Release diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 1a46e246..d6b13523 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,7 +80,6 @@ include_directories( ${PNG_PNG_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS} - ${Q3D_INCLUDE_DIR} ${MIMALLOC_INCLUDE_DIR}) if(Backtrace_FOUND) @@ -214,7 +213,6 @@ add_library(solvespace-core STATIC ${solvespace_core_SOURCES}) add_dependencies(solvespace-core - q3d_header mimalloc-static) target_link_libraries(solvespace-core @@ -224,7 +222,6 @@ target_link_libraries(solvespace-core ${ZLIB_LIBRARY} ${PNG_LIBRARY} ${FREETYPE_LIBRARY} - flatbuffers mimalloc-static) if(Backtrace_FOUND) diff --git a/src/export.cpp b/src/export.cpp index e0c6182c..f5649b68 100644 --- a/src/export.cpp +++ b/src/export.cpp @@ -843,8 +843,6 @@ void SolveSpaceUI::ExportMeshTo(const Platform::Path &filename) { ExportMeshAsObjTo(f, fMtl, m); fclose(fMtl); - } else if(filename.HasExtension("q3do")) { - ExportMeshAsQ3doTo(f, m); } else if(filename.HasExtension("js") || filename.HasExtension("html")) { SOutlineList *e = &(SK.GetGroup(SS.GW.activeGroup)->displayOutlines); @@ -898,54 +896,6 @@ void SolveSpaceUI::ExportMeshAsStlTo(FILE *f, SMesh *sm) { } } -//----------------------------------------------------------------------------- -// Export the mesh as a Q3DO (https://github.com/q3k/q3d) file. -//----------------------------------------------------------------------------- - -#include "q3d_object_generated.h" -void SolveSpaceUI::ExportMeshAsQ3doTo(FILE *f, SMesh *sm) { - flatbuffers::FlatBufferBuilder builder(1024); - double s = SS.exportScale; - - // Create a material for every colour used, keep note of triangles belonging to color/material. - std::map, RgbaColorCompare> materials; - std::map>, RgbaColorCompare> materialTriangles; - for (const STriangle &t : sm->l) { - auto color = t.meta.color; - if (materials.find(color) == materials.end()) { - auto name = builder.CreateString(ssprintf("Color #%02x%02x%02x%02x", color.red, color.green, color.blue, color.alpha)); - auto co = q3d::CreateColor(builder, color.red, color.green, color.blue, color.alpha); - auto mo = q3d::CreateMaterial(builder, name, co); - materials.emplace(color, mo); - } - - Vector faceNormal = t.Normal(); - auto a = q3d::Vector3((float)(t.a.x/s), (float)(t.a.y/s), (float)(t.a.z/s)); - auto b = q3d::Vector3((float)(t.b.x/s), (float)(t.b.y/s), (float)(t.b.z/s)); - auto c = q3d::Vector3((float)(t.c.x/s), (float)(t.c.y/s), (float)(t.c.z/s)); - auto fn = q3d::Vector3((float)faceNormal.x, (float)faceNormal.y, (float)faceNormal.x); - auto n1 = q3d::Vector3((float)t.normals[0].x, (float)t.normals[0].y, (float)t.normals[0].z); - auto n2 = q3d::Vector3((float)t.normals[1].x, (float)t.normals[1].y, (float)t.normals[1].z); - auto n3 = q3d::Vector3((float)t.normals[2].x, (float)t.normals[2].y, (float)t.normals[2].z); - auto tri = q3d::CreateTriangle(builder, &a, &b, &c, &fn, &n1, &n2, &n3); - materialTriangles[color].push_back(tri); - } - - // Build all meshes sorted by material. - std::vector> meshes; - for (auto &it : materials) { - auto &mato = it.second; - auto to = builder.CreateVector(materialTriangles[it.first]); - auto mo = q3d::CreateMesh(builder, to, mato); - meshes.push_back(mo); - } - - auto mo = builder.CreateVector(meshes); - auto o = q3d::CreateObject(builder, mo); - q3d::FinishObjectBuffer(builder, o); - fwrite(builder.GetBufferPointer(), builder.GetSize(), 1, f); -} - //----------------------------------------------------------------------------- // Export the mesh as Wavefront OBJ format. This requires us to reduce all the // identical vertices to the same identifier, so do that first. diff --git a/src/platform/gui.cpp b/src/platform/gui.cpp index ff9b2cff..28fded44 100644 --- a/src/platform/gui.cpp +++ b/src/platform/gui.cpp @@ -99,7 +99,6 @@ std::vector MeshFileFilters = { { CN_("file-type", "Wavefront OBJ mesh"), { "obj" } }, { CN_("file-type", "Three.js-compatible mesh, with viewer"), { "html" } }, { CN_("file-type", "Three.js-compatible mesh, mesh only"), { "js" } }, - { CN_("file-type", "Q3D Object file"), { "q3do" } }, { CN_("file-type", "VRML text file"), { "wrl" } }, }; diff --git a/src/solvespace.h b/src/solvespace.h index e8eeddc9..e64a1ab8 100644 --- a/src/solvespace.h +++ b/src/solvespace.h @@ -686,7 +686,6 @@ public: void ExportAsPngTo(const Platform::Path &filename); void ExportMeshTo(const Platform::Path &filename); void ExportMeshAsStlTo(FILE *f, SMesh *sm); - void ExportMeshAsQ3doTo(FILE *f, SMesh *sm); void ExportMeshAsObjTo(FILE *fObj, FILE *fMtl, SMesh *sm); void ExportMeshAsThreeJsTo(FILE *f, const Platform::Path &filename, SMesh *sm, SOutlineList *sol); From bdd2be60412914ad434e132b41a3b41230257d0a Mon Sep 17 00:00:00 2001 From: ruevs Date: Sun, 22 Nov 2020 18:45:50 +0200 Subject: [PATCH 057/113] Translations: Add solvespace.cpp to the translations... ...since it currently contains many relevant strings. --- res/locales/de_DE.po | 285 +++++++++++++++++++++++++++++++----- res/locales/en_US.po | 338 +++++++++++++++++++++++++++++++++++++++---- res/locales/fr_FR.po | 281 ++++++++++++++++++++++++++++++----- res/locales/ru_RU.po | 281 ++++++++++++++++++++++++++++++----- res/locales/uk_UA.po | 265 ++++++++++++++++++++++++++++++--- res/locales/zh_CN.po | 271 +++++++++++++++++++++++++++++++--- res/messages.pot | 262 ++++++++++++++++++++++++++++++--- src/CMakeLists.txt | 3 +- 8 files changed, 1788 insertions(+), 198 deletions(-) diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po index bf858b1f..846861fb 100644 --- a/res/locales/de_DE.po +++ b/res/locales/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-17 20:50-0500\n" +"POT-Creation-Date: 2020-11-22 18:09+0200\n" "PO-Revision-Date: 2018-07-19 06:55+0000\n" "Last-Translator: Reini Urban \n" "Language-Team: none\n" @@ -660,7 +660,7 @@ msgctxt "button" msgid "&No" msgstr "&Nein" -#: file.cpp:869 +#: file.cpp:869 solvespace.cpp:537 msgctxt "button" msgid "&Cancel" msgstr "&Abbrechen" @@ -1592,7 +1592,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEUER KOMMENTAR -- DOPPELKLICKEN ZUM BEARBEITEN" -#: platform/gui.cpp:85 platform/gui.cpp:89 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace-Modelle" @@ -1629,71 +1629,66 @@ msgstr "Three.js-kompatibles Netz, nur Netz" #: platform/gui.cpp:102 msgctxt "file-type" -msgid "Q3D Object file" -msgstr "Q3D Objektdatei" - -#: platform/gui.cpp:103 -msgctxt "file-type" msgid "VRML text file" msgstr "VRML Textdatei" -#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 msgctxt "file-type" msgid "STEP file" msgstr "STEP-Datei" -#: platform/gui.cpp:111 +#: platform/gui.cpp:110 msgctxt "file-type" msgid "PDF file" msgstr "PDF-Datei" -#: platform/gui.cpp:112 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "Eingebettetes Postscript" -#: platform/gui.cpp:113 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "Skalierbare Vektorgrafik" -#: platform/gui.cpp:115 platform/gui.cpp:122 +#: platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "DXF-Datei (AutoCAD 2007)" -#: platform/gui.cpp:116 +#: platform/gui.cpp:115 msgctxt "file-type" msgid "HPGL file" msgstr "HPGL-Datei" -#: platform/gui.cpp:117 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "G Code" msgstr "G-Code" -#: platform/gui.cpp:126 +#: platform/gui.cpp:125 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "AutoCAD DXF- und DWG-Dateien" -#: platform/gui.cpp:130 +#: platform/gui.cpp:129 msgctxt "file-type" msgid "Comma-separated values" msgstr "Werte durch Komma getrennt (CSV)" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 msgid "untitled" msgstr "unbenannt" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1555 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "Datei speichern" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1557 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "Datei öffnen" @@ -1713,6 +1708,237 @@ msgctxt "button" msgid "_Open" msgstr "" +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "Automatische Speicherdatei verfügbar" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:525 +msgctxt "title" +msgid "Modified File" +msgstr "Geänderte Datei" + +#: solvespace.cpp:527 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:530 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:533 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:534 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:536 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +# solvespace.cpp:557 +#: solvespace.cpp:557 +msgctxt "title" +msgid "(new sketch)" +msgstr "(Neue Skizze)" + +#: solvespace.cpp:564 +msgctxt "title" +msgid "Property Browser" +msgstr "Attribut-Browser" + +#: solvespace.cpp:624 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:692 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:740 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:744 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:768 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:784 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:793 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:798 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:813 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:822 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:834 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:854 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:876 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:899 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:929 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:930 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:932 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:933 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:936 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:940 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:943 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:956 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1898,14 +2124,9 @@ msgstr "Der Maßstab kann nicht Null oder negativ sein." msgid "Bad format: specify x, y, z" msgstr "Ungültiges Format: geben Sie x, y, z ein" -# solvespace.cpp:557 -#~ msgctxt "title" -#~ msgid "(new sketch)" -#~ msgstr "(Neue Skizze)" - -#~ msgctxt "title" -#~ msgid "Property Browser" -#~ msgstr "Attribut-Browser" +#~ msgctxt "file-type" +#~ msgid "Q3D Object file" +#~ msgstr "Q3D Objektdatei" #~ msgid "Specify between 0 and 8 digits after the decimal." #~ msgstr "Geben Sie 0 bis 8 Ziffern nach dem Dezimalzeichen an." @@ -1983,10 +2204,6 @@ msgstr "Ungültiges Format: geben Sie x, y, z ein" #~ "\n" #~ "Möchten Sie die Änderungen speichern?" -#~ msgctxt "title" -#~ msgid "Modified File" -#~ msgstr "Geänderte Datei" - #~ msgctxt "button" #~ msgid "Do_n't Save" #~ msgstr "Nicht speichern" @@ -2000,10 +2217,6 @@ msgstr "Ungültiges Format: geben Sie x, y, z ein" #~ "\n" #~ "Wollen Sie die automatisch gespeicherte Datei öffnen?" -#~ msgctxt "title" -#~ msgid "Autosave Available" -#~ msgstr "Automatische Speicherdatei verfügbar" - #~ msgctxt "button" #~ msgid "_Load autosave" #~ msgstr "AutoDatei öffnen" diff --git a/res/locales/en_US.po b/res/locales/en_US.po index 485950f4..dbee8961 100644 --- a/res/locales/en_US.po +++ b/res/locales/en_US.po @@ -2,12 +2,12 @@ # Copyright (C) 2017 the SolveSpace authors # This file is distributed under the same license as the SolveSpace package. # Automatically generated, 2017. -# +# msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-17 20:50-0500\n" +"POT-Creation-Date: 2020-11-22 18:09+0200\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -641,7 +641,7 @@ msgctxt "button" msgid "&No" msgstr "&No" -#: file.cpp:869 +#: file.cpp:869 solvespace.cpp:537 msgctxt "button" msgid "&Cancel" msgstr "&Cancel" @@ -1564,7 +1564,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT" -#: platform/gui.cpp:85 platform/gui.cpp:89 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace models" @@ -1601,71 +1601,66 @@ msgstr "Three.js-compatible mesh, mesh only" #: platform/gui.cpp:102 msgctxt "file-type" -msgid "Q3D Object file" -msgstr "Q3D Object file" - -#: platform/gui.cpp:103 -msgctxt "file-type" msgid "VRML text file" msgstr "VRML text file" -#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 msgctxt "file-type" msgid "STEP file" msgstr "STEP file" -#: platform/gui.cpp:111 +#: platform/gui.cpp:110 msgctxt "file-type" msgid "PDF file" msgstr "PDF file" -#: platform/gui.cpp:112 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "Encapsulated PostScript" -#: platform/gui.cpp:113 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "Scalable Vector Graphics" -#: platform/gui.cpp:115 platform/gui.cpp:122 +#: platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "DXF file (AutoCAD 2007)" -#: platform/gui.cpp:116 +#: platform/gui.cpp:115 msgctxt "file-type" msgid "HPGL file" msgstr "HPGL file" -#: platform/gui.cpp:117 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "G Code" msgstr "G Code" -#: platform/gui.cpp:126 +#: platform/gui.cpp:125 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "AutoCAD DXF and DWG files" -#: platform/gui.cpp:130 +#: platform/gui.cpp:129 msgctxt "file-type" msgid "Comma-separated values" msgstr "Comma-separated values" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 msgid "untitled" msgstr "untitled" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1555 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "Save File" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1557 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "Open File" @@ -1685,6 +1680,297 @@ msgctxt "button" msgid "_Open" msgstr "_Open" +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "Autosave Available" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "An autosave file is available for this sketch." + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "Do you want to load the autosave file instead?" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "&Load autosave" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "Do&n't Load" + +#: solvespace.cpp:525 +msgctxt "title" +msgid "Modified File" +msgstr "Modified File" + +#: solvespace.cpp:527 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "Do you want to save the changes you made to the sketch “%s”?" + +#: solvespace.cpp:530 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "Do you want to save the changes you made to the new sketch?" + +#: solvespace.cpp:533 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "Your changes will be lost if you don't save them." + +#: solvespace.cpp:534 +msgctxt "button" +msgid "&Save" +msgstr "&Save" + +#: solvespace.cpp:536 +msgctxt "button" +msgid "Do&n't Save" +msgstr "Do&n't Save" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "(new sketch)" +msgstr "(new sketch)" + +#: solvespace.cpp:564 +msgctxt "title" +msgid "Property Browser" +msgstr "Property Browser" + +#: solvespace.cpp:624 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." + +#: solvespace.cpp:692 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." + +#: solvespace.cpp:740 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "Constraint must have a label, and must not be a reference dimension." + +#: solvespace.cpp:744 +msgid "Bad selection for step dimension; select a constraint." +msgstr "Bad selection for step dimension; select a constraint." + +#: solvespace.cpp:768 +msgid "The assembly does not interfere, good." +msgstr "The assembly does not interfere, good." + +#: solvespace.cpp:784 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" +"The volume of the solid model is:\n" +"\n" +" %s" + +#: solvespace.cpp:793 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" + +#: solvespace.cpp:798 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." + +#: solvespace.cpp:813 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." + +#: solvespace.cpp:822 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." + +#: solvespace.cpp:834 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." + +#: solvespace.cpp:854 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." + +#: solvespace.cpp:860 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "Bad selection for perimeter; select line segments, arcs, and curves." + +#: solvespace.cpp:876 +msgid "Bad selection for trace; select a single point." +msgstr "Bad selection for trace; select a single point." + +#: solvespace.cpp:899 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "Couldn't write to '%s'" + +#: solvespace.cpp:929 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "The mesh is self-intersecting (NOT okay, invalid)." + +#: solvespace.cpp:930 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "The mesh is not self-intersecting (okay, valid)." + +#: solvespace.cpp:932 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "The mesh has naked edges (NOT okay, invalid)." + +#: solvespace.cpp:933 +msgid "The mesh is watertight (okay, valid)." +msgstr "The mesh is watertight (okay, valid)." + +#: solvespace.cpp:936 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." + +#: solvespace.cpp:940 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" + +#: solvespace.cpp:943 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" + +#: solvespace.cpp:956 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" + #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1868,10 +2154,6 @@ msgstr "Scale cannot be zero or negative." msgid "Bad format: specify x, y, z" msgstr "Bad format: specify x, y, z" -#~ msgctxt "title" -#~ msgid "(new sketch)" -#~ msgstr "(new sketch)" - -#~ msgctxt "title" -#~ msgid "Property Browser" -#~ msgstr "Property Browser" +#~ msgctxt "file-type" +#~ msgid "Q3D Object file" +#~ msgstr "Q3D Object file" diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po index 8bea1a9f..01429138 100644 --- a/res/locales/fr_FR.po +++ b/res/locales/fr_FR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-17 20:50-0500\n" +"POT-Creation-Date: 2020-11-22 18:09+0200\n" "PO-Revision-Date: 2018-07-14 06:12+0000\n" "Last-Translator: whitequark \n" "Language-Team: none\n" @@ -654,7 +654,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 +#: file.cpp:869 solvespace.cpp:537 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1578,7 +1578,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NOUVEAU COMMENTAIRE - DOUBLE-CLIQUE POUR EDITER" -#: platform/gui.cpp:85 platform/gui.cpp:89 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1615,71 +1615,66 @@ msgstr "" #: platform/gui.cpp:102 msgctxt "file-type" -msgid "Q3D Object file" -msgstr "" - -#: platform/gui.cpp:103 -msgctxt "file-type" msgid "VRML text file" msgstr "" -#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 msgctxt "file-type" msgid "STEP file" msgstr "" -#: platform/gui.cpp:111 +#: platform/gui.cpp:110 msgctxt "file-type" msgid "PDF file" msgstr "" -#: platform/gui.cpp:112 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "" -#: platform/gui.cpp:113 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "" -#: platform/gui.cpp:115 platform/gui.cpp:122 +#: platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "" -#: platform/gui.cpp:116 +#: platform/gui.cpp:115 msgctxt "file-type" msgid "HPGL file" msgstr "" -#: platform/gui.cpp:117 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "G Code" msgstr "" -#: platform/gui.cpp:126 +#: platform/gui.cpp:125 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "" -#: platform/gui.cpp:130 +#: platform/gui.cpp:129 msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 msgid "untitled" msgstr "sans nom" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1555 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "Sauver fichier" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1557 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "Ouvrir Fichier" @@ -1699,6 +1694,236 @@ msgctxt "button" msgid "_Open" msgstr "" +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "Sauvegarde automatique existante" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:525 +msgctxt "title" +msgid "Modified File" +msgstr "Fichier modifié" + +#: solvespace.cpp:527 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:530 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:533 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:534 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:536 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "(new sketch)" +msgstr "(nouveau dessin)" + +#: solvespace.cpp:564 +msgctxt "title" +msgid "Property Browser" +msgstr "Navigateur de propriété" + +#: solvespace.cpp:624 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:692 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:740 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:744 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:768 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:784 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:793 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:798 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:813 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:822 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:834 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:854 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:876 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:899 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:929 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:930 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:932 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:933 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:936 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:940 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:943 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:956 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1883,14 +2108,6 @@ msgstr "L'échelle ne peut pas être zéro ou négative." msgid "Bad format: specify x, y, z" msgstr "Mauvais format: Spécifiez x, y, z" -#~ msgctxt "title" -#~ msgid "(new sketch)" -#~ msgstr "(nouveau dessin)" - -#~ msgctxt "title" -#~ msgid "Property Browser" -#~ msgstr "Navigateur de propriété" - #~ msgid "Specify between 0 and 8 digits after the decimal." #~ msgstr "Spécifiez entre 0 et 8 chiffres après la virgule." @@ -1967,18 +2184,10 @@ msgstr "Mauvais format: Spécifiez x, y, z" #~ "\n" #~ "Voulez-vous enregistrer les modifications?" -#~ msgctxt "title" -#~ msgid "Modified File" -#~ msgstr "Fichier modifié" - #~ msgctxt "button" #~ msgid "Do_n't Save" #~ msgstr "_Ne pas sauver" -#~ msgctxt "title" -#~ msgid "Autosave Available" -#~ msgstr "Sauvegarde automatique existante" - #~ msgctxt "button" #~ msgid "_Load autosave" #~ msgstr "_Charger la sauvegarde automatique" diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po index aa6078ee..9f198e43 100644 --- a/res/locales/ru_RU.po +++ b/res/locales/ru_RU.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-17 20:50-0500\n" +"POT-Creation-Date: 2020-11-22 18:09+0200\n" "PO-Revision-Date: 2017-04-21 10:29+0700\n" "Last-Translator: evilspirit@evilspirit.org\n" "Language-Team: EvilSpirit\n" @@ -648,7 +648,7 @@ msgctxt "button" msgid "&No" msgstr "Нет" -#: file.cpp:869 +#: file.cpp:869 solvespace.cpp:537 msgctxt "button" msgid "&Cancel" msgstr "Отменить" @@ -1581,7 +1581,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ" -#: platform/gui.cpp:85 platform/gui.cpp:89 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 msgctxt "file-type" msgid "SolveSpace models" msgstr "проекты SolveSpace" @@ -1618,71 +1618,66 @@ msgstr "Three.js-совместимая полигональная сетка" #: platform/gui.cpp:102 msgctxt "file-type" -msgid "Q3D Object file" -msgstr "" - -#: platform/gui.cpp:103 -msgctxt "file-type" msgid "VRML text file" msgstr "" -#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 msgctxt "file-type" msgid "STEP file" msgstr "STEP файл" -#: platform/gui.cpp:111 +#: platform/gui.cpp:110 msgctxt "file-type" msgid "PDF file" msgstr "PDF документ" -#: platform/gui.cpp:112 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "Encapsulated PostScript" -#: platform/gui.cpp:113 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "SVG изображение" -#: platform/gui.cpp:115 platform/gui.cpp:122 +#: platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "DXF файл (AutoCAD 2007)" -#: platform/gui.cpp:116 +#: platform/gui.cpp:115 msgctxt "file-type" msgid "HPGL file" msgstr "HPGL файл" -#: platform/gui.cpp:117 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "G Code" msgstr "G Code" -#: platform/gui.cpp:126 +#: platform/gui.cpp:125 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "AutoCAD DXF и DWG файлы" -#: platform/gui.cpp:130 +#: platform/gui.cpp:129 msgctxt "file-type" msgid "Comma-separated values" msgstr "CSV файлы (значения, разделенные запятой)" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 msgid "untitled" msgstr "без имени" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1555 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "Сохранить Файл" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1557 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "Открыть Файл" @@ -1702,6 +1697,236 @@ msgctxt "button" msgid "_Open" msgstr "" +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "Автосохранение Доступно" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:525 +msgctxt "title" +msgid "Modified File" +msgstr "Измененный Файл" + +#: solvespace.cpp:527 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:530 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:533 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:534 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:536 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "(new sketch)" +msgstr "(новый проект)" + +#: solvespace.cpp:564 +msgctxt "title" +msgid "Property Browser" +msgstr "Браузер" + +#: solvespace.cpp:624 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:692 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:740 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:744 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:768 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:784 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:793 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:798 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:813 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:822 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:834 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:854 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:876 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:899 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:929 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:930 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:932 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:933 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:936 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:940 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:943 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:956 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1885,14 +2110,6 @@ msgstr "Масштабный коэффициент не может быть н msgid "Bad format: specify x, y, z" msgstr "Неверный формат: введите данные как x, y, z" -#~ msgctxt "title" -#~ msgid "(new sketch)" -#~ msgstr "(новый проект)" - -#~ msgctxt "title" -#~ msgid "Property Browser" -#~ msgstr "Браузер" - #~ msgid "Specify between 0 and 8 digits after the decimal." #~ msgstr "Введите число от 0 до 8." @@ -1970,10 +2187,6 @@ msgstr "Неверный формат: введите данные как x, y, #~ "\n" #~ "Хотите сохранить их?" -#~ msgctxt "title" -#~ msgid "Modified File" -#~ msgstr "Измененный Файл" - #~ msgctxt "button" #~ msgid "Do_n't Save" #~ msgstr "Не Сохранять" @@ -1987,10 +2200,6 @@ msgstr "Неверный формат: введите данные как x, y, #~ "\n" #~ "Хотите загрузить их вместо открываемого файла?" -#~ msgctxt "title" -#~ msgid "Autosave Available" -#~ msgstr "Автосохранение Доступно" - #~ msgctxt "button" #~ msgid "_Load autosave" #~ msgstr "Загрузить Автосохранение" diff --git a/res/locales/uk_UA.po b/res/locales/uk_UA.po index e9870664..cb2cd2df 100644 --- a/res/locales/uk_UA.po +++ b/res/locales/uk_UA.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-17 20:50-0500\n" +"POT-Creation-Date: 2020-11-22 18:09+0200\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: appsoft@ua.fm\n" "Language-Team: OpenOrienteeringUkraine\n" @@ -528,7 +528,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 +#: file.cpp:869 solvespace.cpp:537 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1388,7 +1388,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" -#: platform/gui.cpp:85 platform/gui.cpp:89 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1425,71 +1425,66 @@ msgstr "" #: platform/gui.cpp:102 msgctxt "file-type" -msgid "Q3D Object file" -msgstr "" - -#: platform/gui.cpp:103 -msgctxt "file-type" msgid "VRML text file" msgstr "" -#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 msgctxt "file-type" msgid "STEP file" msgstr "" -#: platform/gui.cpp:111 +#: platform/gui.cpp:110 msgctxt "file-type" msgid "PDF file" msgstr "" -#: platform/gui.cpp:112 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "" -#: platform/gui.cpp:113 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "" -#: platform/gui.cpp:115 platform/gui.cpp:122 +#: platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "" -#: platform/gui.cpp:116 +#: platform/gui.cpp:115 msgctxt "file-type" msgid "HPGL file" msgstr "" -#: platform/gui.cpp:117 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "G Code" msgstr "" -#: platform/gui.cpp:126 +#: platform/gui.cpp:125 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "" -#: platform/gui.cpp:130 +#: platform/gui.cpp:129 msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 msgid "untitled" msgstr "" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1555 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1557 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "" @@ -1509,6 +1504,236 @@ msgctxt "button" msgid "_Open" msgstr "" +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:525 +msgctxt "title" +msgid "Modified File" +msgstr "" + +#: solvespace.cpp:527 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:530 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:533 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:534 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:536 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "(new sketch)" +msgstr "" + +#: solvespace.cpp:564 +msgctxt "title" +msgid "Property Browser" +msgstr "" + +#: solvespace.cpp:624 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:692 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:740 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:744 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:768 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:784 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:793 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:798 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:813 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:822 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:834 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:854 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:876 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:899 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:929 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:930 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:932 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:933 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:936 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:940 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:943 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:956 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " diff --git a/res/locales/zh_CN.po b/res/locales/zh_CN.po index a2e1b454..61984ad3 100644 --- a/res/locales/zh_CN.po +++ b/res/locales/zh_CN.po @@ -2,12 +2,12 @@ # Copyright (C) 2020 the PACKAGE authors # This file is distributed under the same license as the SolveSpace package. # , 2020. -# +# msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-17 20:50-0500\n" +"POT-Creation-Date: 2020-11-22 18:09+0200\n" "PO-Revision-Date: 2020-09-28 12:42+0800\n" "Last-Translator: lomatus@163.com\n" "Language-Team: none\n" @@ -606,7 +606,7 @@ msgctxt "button" msgid "&No" msgstr "否(&N)" -#: file.cpp:869 +#: file.cpp:869 solvespace.cpp:537 msgctxt "button" msgid "&Cancel" msgstr "取消(&C)" @@ -1475,7 +1475,7 @@ msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "新备注 - 双击编辑" -#: platform/gui.cpp:85 platform/gui.cpp:89 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace模型" @@ -1512,71 +1512,66 @@ msgstr "Three.js-仅网格" #: platform/gui.cpp:102 msgctxt "file-type" -msgid "Q3D Object file" -msgstr "Q3D对象文件" - -#: platform/gui.cpp:103 -msgctxt "file-type" msgid "VRML text file" msgstr "VRML文本文件" -#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 msgctxt "file-type" msgid "STEP file" msgstr "STEP文件" -#: platform/gui.cpp:111 +#: platform/gui.cpp:110 msgctxt "file-type" msgid "PDF file" msgstr "PDF文件" -#: platform/gui.cpp:112 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "封装好的PostScript" -#: platform/gui.cpp:113 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "SVG矢量图" -#: platform/gui.cpp:115 platform/gui.cpp:122 +#: platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "DXF文件(AutoCAD 2007)" -#: platform/gui.cpp:116 +#: platform/gui.cpp:115 msgctxt "file-type" msgid "HPGL file" msgstr "HPGL文件" -#: platform/gui.cpp:117 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "G Code" msgstr "G Code" -#: platform/gui.cpp:126 +#: platform/gui.cpp:125 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "AutoCAD DXF/DWG文件" -#: platform/gui.cpp:130 +#: platform/gui.cpp:129 msgctxt "file-type" msgid "Comma-separated values" msgstr "逗号分隔数据" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 msgid "untitled" msgstr "未命名" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1555 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "保存文件" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1557 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "打开文件" @@ -1596,6 +1591,236 @@ msgctxt "button" msgid "_Open" msgstr "打开_O" +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:525 +msgctxt "title" +msgid "Modified File" +msgstr "" + +#: solvespace.cpp:527 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:530 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:533 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:534 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:536 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "(new sketch)" +msgstr "" + +#: solvespace.cpp:564 +msgctxt "title" +msgid "Property Browser" +msgstr "" + +#: solvespace.cpp:624 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This " +"is probably not what you want; hide them by clicking the link at the top of " +"the text window." +msgstr "" + +#: solvespace.cpp:692 +#, c-format +msgid "" +"Can't identify file type from file extension of filename '%s'; try .dxf or ." +"dwg." +msgstr "" + +#: solvespace.cpp:740 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:744 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:768 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:784 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:793 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:798 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:813 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:822 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" + +#: solvespace.cpp:834 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:854 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:876 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:899 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:929 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:930 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:932 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:933 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:936 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:940 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:943 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:956 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try " @@ -1776,3 +2001,7 @@ msgstr "缩放不能为零。" #: view.cpp:90 view.cpp:99 msgid "Bad format: specify x, y, z" msgstr "格式错误: 需指定 x, y, z" + +#~ msgctxt "file-type" +#~ msgid "Q3D Object file" +#~ msgstr "Q3D对象文件" diff --git a/res/messages.pot b/res/messages.pot index 7f025001..8bb0e2ad 100644 --- a/res/messages.pot +++ b/res/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-17 20:50-0500\n" +"POT-Creation-Date: 2020-11-22 18:09+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -506,7 +506,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 +#: file.cpp:869 solvespace.cpp:537 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1350,7 +1350,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" -#: platform/gui.cpp:85 platform/gui.cpp:89 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1387,71 +1387,66 @@ msgstr "" #: platform/gui.cpp:102 msgctxt "file-type" -msgid "Q3D Object file" -msgstr "" - -#: platform/gui.cpp:103 -msgctxt "file-type" msgid "VRML text file" msgstr "" -#: platform/gui.cpp:107 platform/gui.cpp:114 platform/gui.cpp:121 +#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 msgctxt "file-type" msgid "STEP file" msgstr "" -#: platform/gui.cpp:111 +#: platform/gui.cpp:110 msgctxt "file-type" msgid "PDF file" msgstr "" -#: platform/gui.cpp:112 +#: platform/gui.cpp:111 msgctxt "file-type" msgid "Encapsulated PostScript" msgstr "" -#: platform/gui.cpp:113 +#: platform/gui.cpp:112 msgctxt "file-type" msgid "Scalable Vector Graphics" msgstr "" -#: platform/gui.cpp:115 platform/gui.cpp:122 +#: platform/gui.cpp:114 platform/gui.cpp:121 msgctxt "file-type" msgid "DXF file (AutoCAD 2007)" msgstr "" -#: platform/gui.cpp:116 +#: platform/gui.cpp:115 msgctxt "file-type" msgid "HPGL file" msgstr "" -#: platform/gui.cpp:117 +#: platform/gui.cpp:116 msgctxt "file-type" msgid "G Code" msgstr "" -#: platform/gui.cpp:126 +#: platform/gui.cpp:125 msgctxt "file-type" msgid "AutoCAD DXF and DWG files" msgstr "" -#: platform/gui.cpp:130 +#: platform/gui.cpp:129 msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1608 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 msgid "untitled" msgstr "" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1555 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1557 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "" @@ -1471,6 +1466,233 @@ msgctxt "button" msgid "_Open" msgstr "" +#: solvespace.cpp:169 +msgctxt "title" +msgid "Autosave Available" +msgstr "" + +#: solvespace.cpp:170 +msgctxt "dialog" +msgid "An autosave file is available for this sketch." +msgstr "" + +#: solvespace.cpp:171 +msgctxt "dialog" +msgid "Do you want to load the autosave file instead?" +msgstr "" + +#: solvespace.cpp:172 +msgctxt "button" +msgid "&Load autosave" +msgstr "" + +#: solvespace.cpp:174 +msgctxt "button" +msgid "Do&n't Load" +msgstr "" + +#: solvespace.cpp:525 +msgctxt "title" +msgid "Modified File" +msgstr "" + +#: solvespace.cpp:527 +#, c-format +msgctxt "dialog" +msgid "Do you want to save the changes you made to the sketch “%s”?" +msgstr "" + +#: solvespace.cpp:530 +msgctxt "dialog" +msgid "Do you want to save the changes you made to the new sketch?" +msgstr "" + +#: solvespace.cpp:533 +msgctxt "dialog" +msgid "Your changes will be lost if you don't save them." +msgstr "" + +#: solvespace.cpp:534 +msgctxt "button" +msgid "&Save" +msgstr "" + +#: solvespace.cpp:536 +msgctxt "button" +msgid "Do&n't Save" +msgstr "" + +#: solvespace.cpp:557 +msgctxt "title" +msgid "(new sketch)" +msgstr "" + +#: solvespace.cpp:564 +msgctxt "title" +msgid "Property Browser" +msgstr "" + +#: solvespace.cpp:624 +msgid "" +"Constraints are currently shown, and will be exported in the toolpath. This is probably not what " +"you want; hide them by clicking the link at the top of the text window." +msgstr "" + +#: solvespace.cpp:692 +#, c-format +msgid "Can't identify file type from file extension of filename '%s'; try .dxf or .dwg." +msgstr "" + +#: solvespace.cpp:740 +msgid "Constraint must have a label, and must not be a reference dimension." +msgstr "" + +#: solvespace.cpp:744 +msgid "Bad selection for step dimension; select a constraint." +msgstr "" + +#: solvespace.cpp:768 +msgid "The assembly does not interfere, good." +msgstr "" + +#: solvespace.cpp:784 +#, c-format +msgid "" +"The volume of the solid model is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:793 +#, c-format +msgid "" +"\n" +"The volume of current group mesh is:\n" +"\n" +" %s" +msgstr "" + +#: solvespace.cpp:798 +msgid "" +"\n" +"\n" +"Curved surfaces have been approximated as triangles.\n" +"This introduces error, typically of around 1%." +msgstr "" + +#: solvespace.cpp:813 +#, c-format +msgid "" +"The surface area of the selected faces is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:822 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, not coplanar, or self-" +"intersecting." +msgstr "" + +#: solvespace.cpp:834 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:854 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" + +#: solvespace.cpp:860 +msgid "Bad selection for perimeter; select line segments, arcs, and curves." +msgstr "" + +#: solvespace.cpp:876 +msgid "Bad selection for trace; select a single point." +msgstr "" + +#: solvespace.cpp:899 +#, c-format +msgid "Couldn't write to '%s'" +msgstr "" + +#: solvespace.cpp:929 +msgid "The mesh is self-intersecting (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:930 +msgid "The mesh is not self-intersecting (okay, valid)." +msgstr "" + +#: solvespace.cpp:932 +msgid "The mesh has naked edges (NOT okay, invalid)." +msgstr "" + +#: solvespace.cpp:933 +msgid "The mesh is watertight (okay, valid)." +msgstr "" + +#: solvespace.cpp:936 +#, c-format +msgid "" +"\n" +"\n" +"The model contains %d triangles, from %d surfaces." +msgstr "" + +#: solvespace.cpp:940 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" + +#: solvespace.cpp:943 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" + +#: solvespace.cpp:956 +#, c-format +msgid "" +"This is SolveSpace version %s.\n" +"\n" +"For more information, see http://solvespace.com/\n" +"\n" +"SolveSpace is free software: you are free to modify\n" +"and/or redistribute it under the terms of the GNU\n" +"General Public License (GPL) version 3 or later.\n" +"\n" +"There is NO WARRANTY, to the extent permitted by\n" +"law. For details, visit http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues and other authors.\n" +msgstr "" + #: style.cpp:166 msgid "" "Can't assign style to an entity that's derived from another entity; try assigning a style to this " diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d6b13523..4f277f53 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -238,7 +238,8 @@ if(HAVE_GETTEXT) set(inputs ${solvespace_core_SOURCES} ${solvespace_core_HEADERS} - ${every_platform_SOURCES}) + ${every_platform_SOURCES} + ${solvespace_core_gl_SOURCES}) set(templ_po ${CMAKE_CURRENT_BINARY_DIR}/../res/messages.po) From 5137da295a55651fbf6beffaa717dc7552d0024e Mon Sep 17 00:00:00 2001 From: ruevs Date: Sun, 22 Nov 2020 19:58:46 +0200 Subject: [PATCH 058/113] Win32: Mouse wheel zooming always remains properly centered On scroll wheel events convert the mouse coordinates from screen to client area so that scroll wheel zooming remains centered irrespective of the window position. Fixes https://github.com/solvespace/solvespace/issues/806 --- src/platform/guiwin.cpp | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index 43e7a59a..cfa4b7ea 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -907,8 +907,8 @@ public: // Make the mousewheel work according to which window the mouse is // over, not according to which window is active. POINT pt; - pt.x = LOWORD(lParam); - pt.y = HIWORD(lParam); + pt.x = GET_X_LPARAM(lParam); + pt.y = GET_Y_LPARAM(lParam); HWND hWindowUnderMouse; sscheck(hWindowUnderMouse = WindowFromPoint(pt)); if(hWindowUnderMouse && hWindowUnderMouse != h) { @@ -917,6 +917,13 @@ public: break; } + // Convert the mouse coordinates from screen to client area so that + // scroll wheel zooming remains centered irrespective of the window + // position. + ScreenToClient(hWindowUnderMouse, &pt); + event.x = pt.x / pixelRatio; + event.y = pt.y / pixelRatio; + event.type = MouseEvent::Type::SCROLL_VERT; event.scrollDelta = GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? 1 : -1; break; From 08f37deaddff86ccb628b3b61b86a51b2d34b9ed Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sat, 21 Nov 2020 19:16:45 -0500 Subject: [PATCH 059/113] Make better choices of SI units by considering order. --- src/solvespace.cpp | 46 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 36 insertions(+), 10 deletions(-) diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 7c30a8f5..9b3ef9b3 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -341,13 +341,39 @@ static const char *DimToString(int dim) { default: ssassert(false, "Unexpected dimension"); } } -static std::pair SelectSIPrefixMm(int deg) { - if(deg >= 3) return { 3, "km" }; - else if(deg >= 0) return { 0, "m" }; - else if(deg >= -2) return { -2, "cm" }; - else if(deg >= -3) return { -3, "mm" }; - else if(deg >= -6) return { -6, "µm" }; - else return { -9, "nm" }; +static std::pair SelectSIPrefixMm(int ord, int dim) { +// decide what units to use depending on the order of magnitude of the +// measure in meters and the dimmension (1,2,3 lenear, area, volume) + switch(dim) { + case 0: + case 1: + if(ord >= 3) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -2) return { -2, "cm" }; + else if(ord >= -3) return { -3, "mm" }; + else if(ord >= -6) return { -6, "µm" }; + else return { -9, "nm" }; + break; + case 2: + if(ord >= 5) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -2) return { -2, "cm" }; + else if(ord >= -6) return { -3, "mm" }; + else if(ord >= -13) return { -6, "µm" }; + else return { -9, "nm" }; + break; + case 3: + if(ord >= 7) return { 3, "km" }; + else if(ord >= 0) return { 0, "m" }; + else if(ord >= -5) return { -2, "cm" }; + else if(ord >= -11) return { -3, "mm" }; + else return { -6, "µm" }; + break; + default: + dbp ("dimensions over 3 not supported"); + break; + } + return {0, "m"}; } static std::pair SelectSIPrefixInch(int deg) { if(deg >= 0) return { 0, "in" }; @@ -363,14 +389,14 @@ std::string SolveSpaceUI::MmToStringSI(double v, int dim) { } v /= pow((viewUnits == Unit::INCHES) ? 25.4 : 1000, dim); - int vdeg = (int)((log10(fabs(v))) / dim); + int vdeg = (int)(log10(fabs(v))); std::string unit; if(fabs(v) > 0.0) { int sdeg = 0; std::tie(sdeg, unit) = (viewUnits == Unit::INCHES) - ? SelectSIPrefixInch(vdeg) - : SelectSIPrefixMm(vdeg); + ? SelectSIPrefixInch(vdeg/dim) + : SelectSIPrefixMm(vdeg, dim); v /= pow(10.0, sdeg * dim); } int pdeg = (int)ceil(log10(fabs(v) + 1e-10)); From d0d5df1bb852f7a59fe8ae8938940bf9c71e743b Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sun, 22 Nov 2020 17:30:41 -0500 Subject: [PATCH 060/113] Update contour_area test image to match the change in displayed units. --- test/analysis/contour_area/normal.png | Bin 4787 -> 4818 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/test/analysis/contour_area/normal.png b/test/analysis/contour_area/normal.png index 486fcdc4102cb485be2fb3f83264897aada4eeae..3b50df9cdc701d6b1986b47b6f2c0fb7f5543e68 100644 GIT binary patch literal 4818 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 literal 4787 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 JMTgLr{tFoz=urRw From fac093a8b3dc2e226e14840e8872edbdd57ba094 Mon Sep 17 00:00:00 2001 From: Reini Urban Date: Mon, 23 Nov 2020 08:02:32 +0100 Subject: [PATCH 061/113] Translations: update de_DE for the solvespace.cpp changes. Run make -C src translate_solvespace for updated line numbers for the rest. --- res/locales/de_DE.po | 200 +++++++++++++++++++++++++++++-------------- res/locales/en_US.po | 138 ++++++++++++++--------------- res/locales/fr_FR.po | 74 ++++++++-------- res/locales/ru_RU.po | 74 ++++++++-------- res/locales/uk_UA.po | 74 ++++++++-------- res/locales/zh_CN.po | 76 ++++++++-------- res/messages.pot | 74 ++++++++-------- 7 files changed, 391 insertions(+), 319 deletions(-) diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po index 846861fb..795f9220 100644 --- a/res/locales/de_DE.po +++ b/res/locales/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-22 18:09+0200\n" +"POT-Creation-Date: 2020-11-23 11:23+0200\n" "PO-Revision-Date: 2018-07-19 06:55+0000\n" "Last-Translator: Reini Urban \n" "Language-Team: none\n" @@ -660,7 +660,7 @@ msgctxt "button" msgid "&No" msgstr "&Nein" -#: file.cpp:869 solvespace.cpp:537 +#: file.cpp:869 solvespace.cpp:563 msgctxt "button" msgid "&Cancel" msgstr "&Abbrechen" @@ -1320,7 +1320,7 @@ msgstr "" #: group.cpp:217 msgctxt "group-name" msgid "revolve" -msgstr "" +msgstr "Revolve" #: group.cpp:222 msgid "Helix operation can only be applied to planar sketches." @@ -1334,11 +1334,17 @@ msgid "" "to line / normal, through point)\n" " * a line segment (revolved about line segment)\n" msgstr "" +"Ungültige Auswahl für eine neue Helix Gruppe. Diese Gruppe kann erzeugt " +"werden mit:\n" +"\n" +" * einem Punkt und einem Liniensegment oder Normale (gedreht um eine " +"Achse parallel zu Linie / Normale, durch Punkt)\n" +" * einem Liniensegment (gedreht um Liniensegment)\n" #: group.cpp:245 msgctxt "group-name" msgid "helix" -msgstr "" +msgstr "Helix" #: group.cpp:258 msgid "" @@ -1349,12 +1355,12 @@ msgid "" " * a point and a line or a normal (rotate about an axis through the " "point, and parallel to line / normal)\n" msgstr "" -"Ungültige Auswahl für neue Rotation Diese Gruppe kann erstellt werden mit:\n" +"Ungültige Auswahl für neue Rotation. Diese Gruppe kann erstellt werden mit:\n" "\n" -" * einem Punkt in vorgegebener Arbeitsebene (in der Ebene um den Punkt " -"drehen)\n" -" * einem Punkt und einer Linie oder einer Normale (um eine Achse durch " -"den Punkt drehen, parallel zur Linie / Normale)\n" +" * einem Punkt in vorgegebener Arbeitsebene (gedreht in der Ebene um den " +"Punkt)\n" +" * einem Punkt und einer Linie oder einer Normale (gedreht um eine Achse " +"durch den Punkt, parallel zur Linie / Normale)\n" #: group.cpp:271 msgctxt "group-name" @@ -1592,7 +1598,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEUER KOMMENTAR -- DOPPELKLICKEN ZUM BEARBEITEN" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace-Modelle" @@ -1600,7 +1606,7 @@ msgstr "SolveSpace-Modelle" #: platform/gui.cpp:90 msgctxt "file-type" msgid "IDF circuit board" -msgstr "" +msgstr "IDF Leiterplatte" #: platform/gui.cpp:94 msgctxt "file-type" @@ -1677,18 +1683,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "Werte durch Komma getrennt (CSV)" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 msgid "untitled" msgstr "unbenannt" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1562 msgctxt "title" msgid "Save File" msgstr "Datei speichern" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1564 msgctxt "title" msgid "Open File" msgstr "Datei öffnen" @@ -1706,110 +1712,122 @@ msgstr "_Speichern" #: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 msgctxt "button" msgid "_Open" -msgstr "" +msgstr "_Öffnen" #: solvespace.cpp:169 msgctxt "title" msgid "Autosave Available" -msgstr "Automatische Speicherdatei verfügbar" +msgstr "Automatische Sicherungsdatei verfügbar" #: solvespace.cpp:170 msgctxt "dialog" msgid "An autosave file is available for this sketch." -msgstr "" +msgstr "Eine automatische Sicherung ist für diese Skizze verfügbar." #: solvespace.cpp:171 msgctxt "dialog" msgid "Do you want to load the autosave file instead?" -msgstr "" +msgstr "Wollen Sie die automatische Sicherungsdatei stattdessen laden?" #: solvespace.cpp:172 msgctxt "button" msgid "&Load autosave" -msgstr "" +msgstr "AutoDatei &öffnen" #: solvespace.cpp:174 msgctxt "button" msgid "Do&n't Load" -msgstr "" +msgstr "&Nicht laden" -#: solvespace.cpp:525 +#: solvespace.cpp:551 msgctxt "title" msgid "Modified File" msgstr "Geänderte Datei" -#: solvespace.cpp:527 +#: solvespace.cpp:553 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" -msgstr "" +msgstr "Wollen Sie die Änderungen an der Skizze “%s” sichern?" -#: solvespace.cpp:530 +#: solvespace.cpp:556 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" -msgstr "" +msgstr "Wollen Sie die Änderungen an der Skizze sichern?" -#: solvespace.cpp:533 +#: solvespace.cpp:559 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." -msgstr "" +msgstr "Ihre Änderungen werden verworfen, wenn sie nicht abgespeichert werden." -#: solvespace.cpp:534 +#: solvespace.cpp:560 msgctxt "button" msgid "&Save" -msgstr "" +msgstr "&Sichern" -#: solvespace.cpp:536 +#: solvespace.cpp:562 msgctxt "button" msgid "Do&n't Save" -msgstr "" +msgstr "&Verwerfen" # solvespace.cpp:557 -#: solvespace.cpp:557 +#: solvespace.cpp:583 msgctxt "title" msgid "(new sketch)" msgstr "(Neue Skizze)" -#: solvespace.cpp:564 +#: solvespace.cpp:590 msgctxt "title" msgid "Property Browser" msgstr "Attribut-Browser" -#: solvespace.cpp:624 +#: solvespace.cpp:650 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" +"Einschränkungen sind momentan sichtbar und werden exportiert. Das wollen Sie " +"wahrscheinlich nicht. Verstecken Sie sie in dem auf den Link oben im " +"Textfenster klicken." -#: solvespace.cpp:692 +#: solvespace.cpp:718 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" +"Kann den Dateityp der Datei '%s' nicht auf Grund der Dateierweiterung " +"erkennen. Versuchen Sie .dxf oder .dwg." -#: solvespace.cpp:740 +#: solvespace.cpp:766 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" +"Die Einschränkung muss einen Namen haben, und darf keine " +"Referenzdimensionierung sein." -#: solvespace.cpp:744 +#: solvespace.cpp:770 msgid "Bad selection for step dimension; select a constraint." msgstr "" +"Falsche Auswahl für die Schrittdimensionierung. Wählen Sie eine " +"Einschränkung." -#: solvespace.cpp:768 +#: solvespace.cpp:794 msgid "The assembly does not interfere, good." -msgstr "" +msgstr "Der Zusammenbau funktioniert, gut." -#: solvespace.cpp:784 +#: solvespace.cpp:810 #, c-format msgid "" "The volume of the solid model is:\n" "\n" " %s" msgstr "" +"Das Volumen des Modell ist:\n" +"\n" +" %s" -#: solvespace.cpp:793 +#: solvespace.cpp:819 #, c-format msgid "" "\n" @@ -1817,16 +1835,24 @@ msgid "" "\n" " %s" msgstr "" +"\n" +"Das Volumen des Netz der aktiven Gruppe ist:\n" +"\n" +" %s" -#: solvespace.cpp:798 +#: solvespace.cpp:824 msgid "" "\n" "\n" "Curved surfaces have been approximated as triangles.\n" "This introduces error, typically of around 1%." msgstr "" +"\n" +"\n" +"Gekrümmte Flächen wurden als Dreiecksnetz angenähert.\n" +"Das verursacht Fehler, typischerweise um 1%." -#: solvespace.cpp:813 +#: solvespace.cpp:839 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1836,14 +1862,22 @@ msgid "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." msgstr "" +"Die Fläche der ausgewählten Flächen ist:\n" +"\n" +" %s\n" +"\n" +"Kurven wurden als gerade Linienstücke angenähert.\n" +"Das verursacht Fehler, typischerweise um 1%%." -#: solvespace.cpp:822 +#: solvespace.cpp:848 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" +"Diese Gruppe beinhaltet keine korrekt geschlossene 2D Fläche. Sie ist offen, " +"nicht koplanar, oder überschneidet sich selbst." -#: solvespace.cpp:834 +#: solvespace.cpp:860 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1853,8 +1887,14 @@ msgid "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." msgstr "" +"Die Summe der Flächen in dieser Gruppe ist:\n" +"\n" +" %s\n" +"\n" +"Kurven wurden als gerade Linienstücke angenähert.\n" +"Das verursacht Fehler, typischerweise um 1%%." -#: solvespace.cpp:854 +#: solvespace.cpp:880 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1864,45 +1904,54 @@ msgid "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." msgstr "" +"Die Gesamtlänge der ausgwählten Elemente ist:\n" +"\n" +" %s\n" +"\n" +"Kurven wurden als gerade Linienstücke angenähert.\n" +"Das verursacht Fehler, typischerweise um 1%%." -#: solvespace.cpp:860 +#: solvespace.cpp:886 msgid "Bad selection for perimeter; select line segments, arcs, and curves." -msgstr "" +msgstr "Falsche Auswahl für Umfang. Wähle Liniensegmente, Bögen und Kurven." -#: solvespace.cpp:876 +#: solvespace.cpp:902 msgid "Bad selection for trace; select a single point." -msgstr "" +msgstr "Falsche Auswahl für Punkt nachzeichnen. Wähle einen einzelnen Punkt." -#: solvespace.cpp:899 +#: solvespace.cpp:925 #, c-format msgid "Couldn't write to '%s'" -msgstr "" +msgstr "Konnte '%s' nicht schreiben" -#: solvespace.cpp:929 +#: solvespace.cpp:955 msgid "The mesh is self-intersecting (NOT okay, invalid)." -msgstr "" +msgstr "Das Netz schneidet sich selbst: Falsch, ungültig." -#: solvespace.cpp:930 +#: solvespace.cpp:956 msgid "The mesh is not self-intersecting (okay, valid)." -msgstr "" +msgstr "Das Netz schneidet sich nicht: Gut, gültig." -#: solvespace.cpp:932 +#: solvespace.cpp:958 msgid "The mesh has naked edges (NOT okay, invalid)." -msgstr "" +msgstr "Das Netz hat lose Kanten: Falsch, ungültig." -#: solvespace.cpp:933 +#: solvespace.cpp:959 msgid "The mesh is watertight (okay, valid)." -msgstr "" +msgstr "Das Netz hat keine lose Kanten: Gut, gültig." -#: solvespace.cpp:936 +#: solvespace.cpp:962 #, c-format msgid "" "\n" "\n" "The model contains %d triangles, from %d surfaces." msgstr "" +"\n" +"\n" +"Das Modell hat %d Dreiecke, von %d Flächen." -#: solvespace.cpp:940 +#: solvespace.cpp:966 #, c-format msgid "" "%s\n" @@ -1911,8 +1960,13 @@ msgid "" "\n" "Zero problematic edges, good.%s" msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"Keine problematischen Kanten, gut.%s" -#: solvespace.cpp:943 +#: solvespace.cpp:969 #, c-format msgid "" "%s\n" @@ -1921,8 +1975,13 @@ msgid "" "\n" "%d problematic edges, bad.%s" msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematische Kanten, schlecht.%s" -#: solvespace.cpp:956 +#: solvespace.cpp:982 #, c-format msgid "" "This is SolveSpace version %s.\n" @@ -1938,6 +1997,19 @@ msgid "" "\n" "© 2008-%d Jonathan Westhues and other authors.\n" msgstr "" +"Das ist SolveSpace version %s.\n" +"\n" +"Für mehr Information siehe http://solvespace.com/\n" +"\n" +"SolveSpace ist freie Software: Sie steht Ihnen frei sie zu ändern\n" +"und/oder zu vervielfältigen unter der Auflage der GNU\n" +"General Public License (GPL) Version 3 oder späterer Versionen.\n" +"\n" +"Es besteht keinerlei Gewährleistung und Haftung für das Programm, soweit " +"dies gesetzlich zulässig ist.\n" +"Für Details siehe http://gnu.org/licenses/\n" +"\n" +"© 2008-%d Jonathan Westhues und andere.\n" #: style.cpp:166 msgid "" diff --git a/res/locales/en_US.po b/res/locales/en_US.po index dbee8961..01c4b432 100644 --- a/res/locales/en_US.po +++ b/res/locales/en_US.po @@ -2,12 +2,12 @@ # Copyright (C) 2017 the SolveSpace authors # This file is distributed under the same license as the SolveSpace package. # Automatically generated, 2017. -# +# msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-22 18:09+0200\n" +"POT-Creation-Date: 2020-11-23 07:36+0100\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -641,7 +641,7 @@ msgctxt "button" msgid "&No" msgstr "&No" -#: file.cpp:869 solvespace.cpp:537 +#: file.cpp:869 solvespace.cpp:563 msgctxt "button" msgid "&Cancel" msgstr "&Cancel" @@ -1564,7 +1564,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace models" @@ -1649,18 +1649,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "Comma-separated values" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 msgid "untitled" msgstr "untitled" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1562 msgctxt "title" msgid "Save File" msgstr "Save File" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1564 msgctxt "title" msgid "Open File" msgstr "Open File" @@ -1705,48 +1705,48 @@ msgctxt "button" msgid "Do&n't Load" msgstr "Do&n't Load" -#: solvespace.cpp:525 +#: solvespace.cpp:551 msgctxt "title" msgid "Modified File" msgstr "Modified File" -#: solvespace.cpp:527 +#: solvespace.cpp:553 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "Do you want to save the changes you made to the sketch “%s”?" -#: solvespace.cpp:530 +#: solvespace.cpp:556 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "Do you want to save the changes you made to the new sketch?" -#: solvespace.cpp:533 +#: solvespace.cpp:559 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "Your changes will be lost if you don't save them." -#: solvespace.cpp:534 +#: solvespace.cpp:560 msgctxt "button" msgid "&Save" msgstr "&Save" -#: solvespace.cpp:536 +#: solvespace.cpp:562 msgctxt "button" msgid "Do&n't Save" msgstr "Do&n't Save" -#: solvespace.cpp:557 +#: solvespace.cpp:583 msgctxt "title" msgid "(new sketch)" msgstr "(new sketch)" -#: solvespace.cpp:564 +#: solvespace.cpp:590 msgctxt "title" msgid "Property Browser" msgstr "Property Browser" -#: solvespace.cpp:624 +#: solvespace.cpp:650 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " @@ -1756,7 +1756,7 @@ msgstr "" "is probably not what you want; hide them by clicking the link at the top of " "the text window." -#: solvespace.cpp:692 +#: solvespace.cpp:718 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." @@ -1765,19 +1765,19 @@ msgstr "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." -#: solvespace.cpp:740 +#: solvespace.cpp:766 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "Constraint must have a label, and must not be a reference dimension." -#: solvespace.cpp:744 +#: solvespace.cpp:770 msgid "Bad selection for step dimension; select a constraint." msgstr "Bad selection for step dimension; select a constraint." -#: solvespace.cpp:768 +#: solvespace.cpp:794 msgid "The assembly does not interfere, good." msgstr "The assembly does not interfere, good." -#: solvespace.cpp:784 +#: solvespace.cpp:810 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1788,7 +1788,7 @@ msgstr "" "\n" " %s" -#: solvespace.cpp:793 +#: solvespace.cpp:819 #, c-format msgid "" "\n" @@ -1801,7 +1801,7 @@ msgstr "" "\n" " %s" -#: solvespace.cpp:798 +#: solvespace.cpp:824 msgid "" "\n" "\n" @@ -1813,7 +1813,7 @@ msgstr "" "Curved surfaces have been approximated as triangles.\n" "This introduces error, typically of around 1%." -#: solvespace.cpp:813 +#: solvespace.cpp:839 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1830,7 +1830,7 @@ msgstr "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." -#: solvespace.cpp:822 +#: solvespace.cpp:848 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." @@ -1838,70 +1838,70 @@ msgstr "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." -#: solvespace.cpp:834 -#, c-format -msgid "" -"The area of the region sketched in this group is:\n" -"\n" -" %s\n" -"\n" -"Curves have been approximated as piecewise linear.\n" -"This introduces error, typically of around 1%%." -msgstr "" -"The area of the region sketched in this group is:\n" -"\n" -" %s\n" -"\n" -"Curves have been approximated as piecewise linear.\n" -"This introduces error, typically of around 1%%." - -#: solvespace.cpp:854 -#, c-format -msgid "" -"The total length of the selected entities is:\n" -"\n" -" %s\n" -"\n" -"Curves have been approximated as piecewise linear.\n" -"This introduces error, typically of around 1%%." -msgstr "" -"The total length of the selected entities is:\n" -"\n" -" %s\n" -"\n" -"Curves have been approximated as piecewise linear.\n" -"This introduces error, typically of around 1%%." - #: solvespace.cpp:860 +#, c-format +msgid "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"The area of the region sketched in this group is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." + +#: solvespace.cpp:880 +#, c-format +msgid "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." +msgstr "" +"The total length of the selected entities is:\n" +"\n" +" %s\n" +"\n" +"Curves have been approximated as piecewise linear.\n" +"This introduces error, typically of around 1%%." + +#: solvespace.cpp:886 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "Bad selection for perimeter; select line segments, arcs, and curves." -#: solvespace.cpp:876 +#: solvespace.cpp:902 msgid "Bad selection for trace; select a single point." msgstr "Bad selection for trace; select a single point." -#: solvespace.cpp:899 +#: solvespace.cpp:925 #, c-format msgid "Couldn't write to '%s'" msgstr "Couldn't write to '%s'" -#: solvespace.cpp:929 +#: solvespace.cpp:955 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "The mesh is self-intersecting (NOT okay, invalid)." -#: solvespace.cpp:930 +#: solvespace.cpp:956 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "The mesh is not self-intersecting (okay, valid)." -#: solvespace.cpp:932 +#: solvespace.cpp:958 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "The mesh has naked edges (NOT okay, invalid)." -#: solvespace.cpp:933 +#: solvespace.cpp:959 msgid "The mesh is watertight (okay, valid)." msgstr "The mesh is watertight (okay, valid)." -#: solvespace.cpp:936 +#: solvespace.cpp:962 #, c-format msgid "" "\n" @@ -1912,7 +1912,7 @@ msgstr "" "\n" "The model contains %d triangles, from %d surfaces." -#: solvespace.cpp:940 +#: solvespace.cpp:966 #, c-format msgid "" "%s\n" @@ -1927,7 +1927,7 @@ msgstr "" "\n" "Zero problematic edges, good.%s" -#: solvespace.cpp:943 +#: solvespace.cpp:969 #, c-format msgid "" "%s\n" @@ -1942,7 +1942,7 @@ msgstr "" "\n" "%d problematic edges, bad.%s" -#: solvespace.cpp:956 +#: solvespace.cpp:982 #, c-format msgid "" "This is SolveSpace version %s.\n" diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po index 01429138..2295312b 100644 --- a/res/locales/fr_FR.po +++ b/res/locales/fr_FR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-22 18:09+0200\n" +"POT-Creation-Date: 2020-11-23 07:36+0100\n" "PO-Revision-Date: 2018-07-14 06:12+0000\n" "Last-Translator: whitequark \n" "Language-Team: none\n" @@ -654,7 +654,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:537 +#: file.cpp:869 solvespace.cpp:563 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1578,7 +1578,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NOUVEAU COMMENTAIRE - DOUBLE-CLIQUE POUR EDITER" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1663,18 +1663,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 msgid "untitled" msgstr "sans nom" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1562 msgctxt "title" msgid "Save File" msgstr "Sauver fichier" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1564 msgctxt "title" msgid "Open File" msgstr "Ouvrir Fichier" @@ -1719,74 +1719,74 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:525 +#: solvespace.cpp:551 msgctxt "title" msgid "Modified File" msgstr "Fichier modifié" -#: solvespace.cpp:527 +#: solvespace.cpp:553 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:530 +#: solvespace.cpp:556 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:533 +#: solvespace.cpp:559 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:534 +#: solvespace.cpp:560 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:536 +#: solvespace.cpp:562 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:557 +#: solvespace.cpp:583 msgctxt "title" msgid "(new sketch)" msgstr "(nouveau dessin)" -#: solvespace.cpp:564 +#: solvespace.cpp:590 msgctxt "title" msgid "Property Browser" msgstr "Navigateur de propriété" -#: solvespace.cpp:624 +#: solvespace.cpp:650 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" -#: solvespace.cpp:692 +#: solvespace.cpp:718 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" -#: solvespace.cpp:740 +#: solvespace.cpp:766 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:744 +#: solvespace.cpp:770 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:768 +#: solvespace.cpp:794 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:784 +#: solvespace.cpp:810 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1794,7 +1794,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:793 +#: solvespace.cpp:819 #, c-format msgid "" "\n" @@ -1803,7 +1803,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:798 +#: solvespace.cpp:824 msgid "" "\n" "\n" @@ -1811,7 +1811,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:813 +#: solvespace.cpp:839 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1822,13 +1822,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:822 +#: solvespace.cpp:848 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" -#: solvespace.cpp:834 +#: solvespace.cpp:860 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1839,7 +1839,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:854 +#: solvespace.cpp:880 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1850,36 +1850,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:886 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:876 +#: solvespace.cpp:902 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:899 +#: solvespace.cpp:925 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:929 +#: solvespace.cpp:955 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:930 +#: solvespace.cpp:956 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:932 +#: solvespace.cpp:958 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:933 +#: solvespace.cpp:959 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:936 +#: solvespace.cpp:962 #, c-format msgid "" "\n" @@ -1887,7 +1887,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:940 +#: solvespace.cpp:966 #, c-format msgid "" "%s\n" @@ -1897,7 +1897,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:943 +#: solvespace.cpp:969 #, c-format msgid "" "%s\n" @@ -1907,7 +1907,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:982 #, c-format msgid "" "This is SolveSpace version %s.\n" diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po index 9f198e43..c098caaf 100644 --- a/res/locales/ru_RU.po +++ b/res/locales/ru_RU.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-22 18:09+0200\n" +"POT-Creation-Date: 2020-11-23 07:36+0100\n" "PO-Revision-Date: 2017-04-21 10:29+0700\n" "Last-Translator: evilspirit@evilspirit.org\n" "Language-Team: EvilSpirit\n" @@ -648,7 +648,7 @@ msgctxt "button" msgid "&No" msgstr "Нет" -#: file.cpp:869 solvespace.cpp:537 +#: file.cpp:869 solvespace.cpp:563 msgctxt "button" msgid "&Cancel" msgstr "Отменить" @@ -1581,7 +1581,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 msgctxt "file-type" msgid "SolveSpace models" msgstr "проекты SolveSpace" @@ -1666,18 +1666,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "CSV файлы (значения, разделенные запятой)" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 msgid "untitled" msgstr "без имени" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1562 msgctxt "title" msgid "Save File" msgstr "Сохранить Файл" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1564 msgctxt "title" msgid "Open File" msgstr "Открыть Файл" @@ -1722,74 +1722,74 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:525 +#: solvespace.cpp:551 msgctxt "title" msgid "Modified File" msgstr "Измененный Файл" -#: solvespace.cpp:527 +#: solvespace.cpp:553 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:530 +#: solvespace.cpp:556 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:533 +#: solvespace.cpp:559 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:534 +#: solvespace.cpp:560 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:536 +#: solvespace.cpp:562 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:557 +#: solvespace.cpp:583 msgctxt "title" msgid "(new sketch)" msgstr "(новый проект)" -#: solvespace.cpp:564 +#: solvespace.cpp:590 msgctxt "title" msgid "Property Browser" msgstr "Браузер" -#: solvespace.cpp:624 +#: solvespace.cpp:650 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" -#: solvespace.cpp:692 +#: solvespace.cpp:718 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" -#: solvespace.cpp:740 +#: solvespace.cpp:766 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:744 +#: solvespace.cpp:770 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:768 +#: solvespace.cpp:794 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:784 +#: solvespace.cpp:810 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1797,7 +1797,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:793 +#: solvespace.cpp:819 #, c-format msgid "" "\n" @@ -1806,7 +1806,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:798 +#: solvespace.cpp:824 msgid "" "\n" "\n" @@ -1814,7 +1814,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:813 +#: solvespace.cpp:839 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1825,13 +1825,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:822 +#: solvespace.cpp:848 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" -#: solvespace.cpp:834 +#: solvespace.cpp:860 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1842,7 +1842,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:854 +#: solvespace.cpp:880 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1853,36 +1853,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:886 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:876 +#: solvespace.cpp:902 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:899 +#: solvespace.cpp:925 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:929 +#: solvespace.cpp:955 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:930 +#: solvespace.cpp:956 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:932 +#: solvespace.cpp:958 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:933 +#: solvespace.cpp:959 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:936 +#: solvespace.cpp:962 #, c-format msgid "" "\n" @@ -1890,7 +1890,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:940 +#: solvespace.cpp:966 #, c-format msgid "" "%s\n" @@ -1900,7 +1900,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:943 +#: solvespace.cpp:969 #, c-format msgid "" "%s\n" @@ -1910,7 +1910,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:982 #, c-format msgid "" "This is SolveSpace version %s.\n" diff --git a/res/locales/uk_UA.po b/res/locales/uk_UA.po index cb2cd2df..89fd5ac0 100644 --- a/res/locales/uk_UA.po +++ b/res/locales/uk_UA.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-22 18:09+0200\n" +"POT-Creation-Date: 2020-11-23 07:36+0100\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: appsoft@ua.fm\n" "Language-Team: OpenOrienteeringUkraine\n" @@ -528,7 +528,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:537 +#: file.cpp:869 solvespace.cpp:563 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1388,7 +1388,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1473,18 +1473,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 msgid "untitled" msgstr "" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1562 msgctxt "title" msgid "Save File" msgstr "" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1564 msgctxt "title" msgid "Open File" msgstr "" @@ -1529,74 +1529,74 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:525 +#: solvespace.cpp:551 msgctxt "title" msgid "Modified File" msgstr "" -#: solvespace.cpp:527 +#: solvespace.cpp:553 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:530 +#: solvespace.cpp:556 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:533 +#: solvespace.cpp:559 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:534 +#: solvespace.cpp:560 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:536 +#: solvespace.cpp:562 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:557 +#: solvespace.cpp:583 msgctxt "title" msgid "(new sketch)" msgstr "" -#: solvespace.cpp:564 +#: solvespace.cpp:590 msgctxt "title" msgid "Property Browser" msgstr "" -#: solvespace.cpp:624 +#: solvespace.cpp:650 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" -#: solvespace.cpp:692 +#: solvespace.cpp:718 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" -#: solvespace.cpp:740 +#: solvespace.cpp:766 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:744 +#: solvespace.cpp:770 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:768 +#: solvespace.cpp:794 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:784 +#: solvespace.cpp:810 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1604,7 +1604,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:793 +#: solvespace.cpp:819 #, c-format msgid "" "\n" @@ -1613,7 +1613,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:798 +#: solvespace.cpp:824 msgid "" "\n" "\n" @@ -1621,7 +1621,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:813 +#: solvespace.cpp:839 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1632,13 +1632,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:822 +#: solvespace.cpp:848 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" -#: solvespace.cpp:834 +#: solvespace.cpp:860 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1649,7 +1649,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:854 +#: solvespace.cpp:880 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1660,36 +1660,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:886 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:876 +#: solvespace.cpp:902 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:899 +#: solvespace.cpp:925 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:929 +#: solvespace.cpp:955 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:930 +#: solvespace.cpp:956 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:932 +#: solvespace.cpp:958 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:933 +#: solvespace.cpp:959 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:936 +#: solvespace.cpp:962 #, c-format msgid "" "\n" @@ -1697,7 +1697,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:940 +#: solvespace.cpp:966 #, c-format msgid "" "%s\n" @@ -1707,7 +1707,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:943 +#: solvespace.cpp:969 #, c-format msgid "" "%s\n" @@ -1717,7 +1717,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:982 #, c-format msgid "" "This is SolveSpace version %s.\n" diff --git a/res/locales/zh_CN.po b/res/locales/zh_CN.po index 61984ad3..df48341a 100644 --- a/res/locales/zh_CN.po +++ b/res/locales/zh_CN.po @@ -2,12 +2,12 @@ # Copyright (C) 2020 the PACKAGE authors # This file is distributed under the same license as the SolveSpace package. # , 2020. -# +# msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-22 18:09+0200\n" +"POT-Creation-Date: 2020-11-23 07:36+0100\n" "PO-Revision-Date: 2020-09-28 12:42+0800\n" "Last-Translator: lomatus@163.com\n" "Language-Team: none\n" @@ -606,7 +606,7 @@ msgctxt "button" msgid "&No" msgstr "否(&N)" -#: file.cpp:869 solvespace.cpp:537 +#: file.cpp:869 solvespace.cpp:563 msgctxt "button" msgid "&Cancel" msgstr "取消(&C)" @@ -1475,7 +1475,7 @@ msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "新备注 - 双击编辑" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace模型" @@ -1560,18 +1560,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "逗号分隔数据" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 msgid "untitled" msgstr "未命名" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1562 msgctxt "title" msgid "Save File" msgstr "保存文件" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1564 msgctxt "title" msgid "Open File" msgstr "打开文件" @@ -1616,74 +1616,74 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:525 +#: solvespace.cpp:551 msgctxt "title" msgid "Modified File" msgstr "" -#: solvespace.cpp:527 +#: solvespace.cpp:553 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:530 +#: solvespace.cpp:556 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:533 +#: solvespace.cpp:559 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:534 +#: solvespace.cpp:560 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:536 +#: solvespace.cpp:562 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:557 +#: solvespace.cpp:583 msgctxt "title" msgid "(new sketch)" msgstr "" -#: solvespace.cpp:564 +#: solvespace.cpp:590 msgctxt "title" msgid "Property Browser" msgstr "" -#: solvespace.cpp:624 +#: solvespace.cpp:650 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" -#: solvespace.cpp:692 +#: solvespace.cpp:718 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" -#: solvespace.cpp:740 +#: solvespace.cpp:766 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:744 +#: solvespace.cpp:770 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:768 +#: solvespace.cpp:794 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:784 +#: solvespace.cpp:810 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1691,7 +1691,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:793 +#: solvespace.cpp:819 #, c-format msgid "" "\n" @@ -1700,7 +1700,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:798 +#: solvespace.cpp:824 msgid "" "\n" "\n" @@ -1708,7 +1708,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:813 +#: solvespace.cpp:839 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1719,13 +1719,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:822 +#: solvespace.cpp:848 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" -#: solvespace.cpp:834 +#: solvespace.cpp:860 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1736,7 +1736,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:854 +#: solvespace.cpp:880 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1747,36 +1747,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:886 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:876 +#: solvespace.cpp:902 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:899 +#: solvespace.cpp:925 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:929 +#: solvespace.cpp:955 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:930 +#: solvespace.cpp:956 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:932 +#: solvespace.cpp:958 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:933 +#: solvespace.cpp:959 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:936 +#: solvespace.cpp:962 #, c-format msgid "" "\n" @@ -1784,7 +1784,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:940 +#: solvespace.cpp:966 #, c-format msgid "" "%s\n" @@ -1794,7 +1794,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:943 +#: solvespace.cpp:969 #, c-format msgid "" "%s\n" @@ -1804,7 +1804,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:982 #, c-format msgid "" "This is SolveSpace version %s.\n" diff --git a/res/messages.pot b/res/messages.pot index 8bb0e2ad..5a6ef365 100644 --- a/res/messages.pot +++ b/res/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-22 18:09+0200\n" +"POT-Creation-Date: 2020-11-23 07:36+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -506,7 +506,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:537 +#: file.cpp:869 solvespace.cpp:563 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1350,7 +1350,7 @@ msgstr "" msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:479 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1435,18 +1435,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1621 +#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 msgid "untitled" msgstr "" #: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1562 msgctxt "title" msgid "Save File" msgstr "" #: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1564 msgctxt "title" msgid "Open File" msgstr "" @@ -1491,71 +1491,71 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:525 +#: solvespace.cpp:551 msgctxt "title" msgid "Modified File" msgstr "" -#: solvespace.cpp:527 +#: solvespace.cpp:553 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:530 +#: solvespace.cpp:556 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:533 +#: solvespace.cpp:559 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:534 +#: solvespace.cpp:560 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:536 +#: solvespace.cpp:562 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:557 +#: solvespace.cpp:583 msgctxt "title" msgid "(new sketch)" msgstr "" -#: solvespace.cpp:564 +#: solvespace.cpp:590 msgctxt "title" msgid "Property Browser" msgstr "" -#: solvespace.cpp:624 +#: solvespace.cpp:650 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This is probably not what " "you want; hide them by clicking the link at the top of the text window." msgstr "" -#: solvespace.cpp:692 +#: solvespace.cpp:718 #, c-format msgid "Can't identify file type from file extension of filename '%s'; try .dxf or .dwg." msgstr "" -#: solvespace.cpp:740 +#: solvespace.cpp:766 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:744 +#: solvespace.cpp:770 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:768 +#: solvespace.cpp:794 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:784 +#: solvespace.cpp:810 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1563,7 +1563,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:793 +#: solvespace.cpp:819 #, c-format msgid "" "\n" @@ -1572,7 +1572,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:798 +#: solvespace.cpp:824 msgid "" "\n" "\n" @@ -1580,7 +1580,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:813 +#: solvespace.cpp:839 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1591,13 +1591,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:822 +#: solvespace.cpp:848 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, not coplanar, or self-" "intersecting." msgstr "" -#: solvespace.cpp:834 +#: solvespace.cpp:860 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1608,7 +1608,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:854 +#: solvespace.cpp:880 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1619,36 +1619,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:886 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:876 +#: solvespace.cpp:902 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:899 +#: solvespace.cpp:925 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:929 +#: solvespace.cpp:955 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:930 +#: solvespace.cpp:956 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:932 +#: solvespace.cpp:958 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:933 +#: solvespace.cpp:959 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:936 +#: solvespace.cpp:962 #, c-format msgid "" "\n" @@ -1656,7 +1656,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:940 +#: solvespace.cpp:966 #, c-format msgid "" "%s\n" @@ -1666,7 +1666,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:943 +#: solvespace.cpp:969 #, c-format msgid "" "%s\n" @@ -1676,7 +1676,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:982 #, c-format msgid "" "This is SolveSpace version %s.\n" From 8dcb2db6e6b9539e82b7ae8b0fe967914b5f90fc Mon Sep 17 00:00:00 2001 From: ruevs Date: Mon, 23 Nov 2020 12:23:16 +0200 Subject: [PATCH 062/113] Changelog: Describe the "err" indicator in the property browser. --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a7a40327..b302f403 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,8 @@ New sketch features: * "Split Curves at Intersection" can now split curves at point lying on curve, not just at intersection of two curves. * Property browser now shows amount of degrees of freedom in group list. + It also shows a yellow "err" if the sketch has problems (e.g. self + intersecting) that would propagate in subsequent groups. New constraint features: * When dragging an arc or rectangle point, it will be automatically From f2850246fa4f56c9ef080d620d9b7266764dd273 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sat, 21 Nov 2020 12:42:15 +0100 Subject: [PATCH 063/113] Move z-index of construction segments behind normal segments --- src/drawentity.cpp | 7 +++++-- test/constraint/angle/skew.png | Bin 4869 -> 4867 bytes 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/drawentity.cpp b/src/drawentity.cpp index fab40713..d8763360 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -472,13 +472,13 @@ void Entity::Draw(DrawAs how, Canvas *canvas) { int zIndex; if(IsPoint()) { - zIndex = 5; + zIndex = 6; } else if(how == DrawAs::HIDDEN) { zIndex = 2; } else if(group != SS.GW.activeGroup) { zIndex = 3; } else { - zIndex = 4; + zIndex = 5; } hStyle hs; @@ -488,6 +488,9 @@ void Entity::Draw(DrawAs how, Canvas *canvas) { hs.v = Style::NORMALS; } else { hs = Style::ForEntity(h); + if (hs.v == Style::CONSTRUCTION) { + zIndex = 4; + } } Canvas::Stroke stroke = Style::Stroke(hs); diff --git a/test/constraint/angle/skew.png b/test/constraint/angle/skew.png index 97fb0dbf53595dac63eef4b79d78fe3bb110b6cf..92d7577a44f841963122399714b2e8daae3d7690 100644 GIT binary patch delta 2296 zcmY*b3sjQX7CvC0`PRx;rj43*Q!Djq4-GJ1Yce(GmXc;_md*|HF=eTUzf9(gQ);Y# z%15OZWobS@LaijwQhJ!=HL>u4lbIPI6$$AdaIv|w?wYmET4%3)&e^YTe|w!%&L^GE zI)y&|KG1)6_C@Jf;!h*NcZvpj-O~>UGg()cch=Q*I+0hg4Eszfz5f~F;fg~($pLT!>(NyPwDX9fV> zODq84#d93aOBWQFvZy)%C>9;wbr}xF@cf&!3DSw0xoO>`oto-d+$@WK@m{_Zp-!>_^-MGDg04$FJHpF+ zDJoHZ8U_EMRvUpAk;hc|A;{D#0mOkLuwf7sbD{3qale(6im8{~QxFP_-8D#@)=&%R4%&r}B0SB}#%G zmWz@1K}u!y{i#WuZ~s)2t9jb0bV*Vhu07UHRXvEDkiBSGSW`@%Rr%)5cL;hZh0{#S z;RIAC&E11J%&gwh?^pv@>Dr^j@Eu(ODjr63H=xeJu6j05v^{(_7qWXPm|=@1+r4U- zQ#Q9EhuqEjSr77wr2(y1c1ksarv0PX#RaN8ratb!0Rq$x+L%gZWn8maSNZ&{8or@ZqN z-Xo9IQcav9J|pdhQDbR%5rHNrHJzV#>SWH-7=PxKA#E?(j>r!2vQ!;aiB)yoU4FfdD;DE7O&02BT)-Br&cxh`nvX5S0+Y9i z#m``zez8GjLseaUwi8fRcG0MgaD$OK1SZ$Tcq}6VkofmNZ6CYH{hVFwGfq#{KBNg*GX@5fq_?%q7C0$PogjNGg-}o5un3u%AC00MFLr``e zY@zU-KLBSQX!%d5;Gu!u|6IcH`UbQKeU`nUCmJp`x3}YUoWJ&(@%LD?&_ObjUkvQl7j(wF+|2%0A4BF zXW(pn;;!_~%**g=bO5l)-+Bb58+r#stt948*#N6uM-tpmKSYC~e{loXwt@nVTj--i ziOx-StBVO>{F0;{c09tL6E7zArtZfduBZ5(D@6mV3Tyb8;R+Zs*M}MfyiYGr0UmYE znuuF%12!{oS_6rWq$9H9Bnq&K;8KS~4BAlDv!5f37R0^``W1PwSgXsRd9(3&=g5O7 z0<>V#C@ebNC{%B1Ewliilg{uCOC4LWNj?T(VYemm(Z)@~1UkXTY zg|)i#?X8CIV6Q?rmAC6_<38}sc^6MalH=_ct(PK}Bc8w$x&h5EU# zxY4!CC|IF;&7}hTX*Vysocu2+0;y@5cjruEC2-o4RH>gmQL}N!Vz;{@_T&NXv>2t)rjUH5^-@;a6V<_ zd$D%5-BuNaNt4zYl#+fQ$pRmI7CBQvqILa)R=a~%YiyxGkz>qu{hMy$rTw0O?}Nev Jo3|(Y{9iQeT3!GE delta 2234 zcmYjS3pCW-7C$o#lkv(cj~FHDyC{7kZ*h~`Ln>WiJVr9gc)#-H5bM{_q@3r@D|8}m~Kg0pg zaCfbER8vE3wFTg^)W;bB;t&!VQqhA7m3BcCRdpy^!^wvBPs8h#7)&uCJCnIFL$)91bY4p!EK)A$q8j+{mT5p1FNar8{aYx}9=ECA6e2N8=C;UkAfzN{@^B)XO3MB!cv0Ivdb5!Fj|TfNhe3Bnxq z6!Jze+@7QZQ0=!RW*&Y0Kzei{YuuA$pC#q8<$5Cu)QzW{Zk-(qkE<|B6>U-_9mp6>=HUmT;xnccWL+mgp0^6NpPo1Ffkp<_jpqhBA)jU z3M+d)&$u`Yd~Pt;h%t=ihqb!2VT>dXhlK)ObI9sx4dJ-hI(_2>>2=o4+2&nrEUdH0 z@^CY|xzc{XL;#g3qG5FCrQ$Id8QN4l1S^FskotrOG*l>(Iz1;3l~)4l-bx^tNw4{3OKJ zjo6$gWx6(I(IR~C4Q6PB&NpJRBts3}B0t~;ZqqFdB|U($DPQrMNn zm9@;4RJ_Hem9UE2se)%}Oc%oU!6uSZzI%ut2JhP1ndeQ%8F1(l`m!|Dmdaw?Ghr@= z?N6F=me5#{k{NbQqzEq(ClYjS&uUs|y5~IR#i{5pP?^!Mlz0UU_=h5Y^8>y=2bjrl z>u4$0xC@=ifQ*%NQGV=6x`&-ts*!&$gBzmUjN|D&<{ zqxEIJ>DoO`C0;@~r^}HI4WqdL=ob9S2YU@}jv`o2C5HL{>n#KSc5w#PtS1@Ow+0NL zX83+6O;rb4`ZXf$mQvJ@aIbj@9N%CBfK`VORnI!E11NPuWm)qZ?)Z%XfV$c5MYd`T z|G~cg|Ki)G89~a}`{9;~Q=TxO+^-D9YwUwcQ8s_Ax20^pvjJ9BTtCJB0lL&~ZR#&liW}O;u zYJ=Tn3pCXQ>1VsBNs&DGG!HO5w@V37>n428gY~6ZPPScx~DOYL2 zZil&wPlqOr6zviR>208dca)-#nR^vX>B^)4O@9Jl9OOA}OW;^JBhpKj#q)6faoM#8 z&JP?~Sb-6ncbiiVMie%_KQQs|8n=VgK%T@btuq(RZSvl+pNqsu5OG)A4-~cpEf=!f(B}(9RJ6Mt^Fs0PTV&p($>)gld1C_ zvvKZa=bqW+dwfEkkTih!Gkk3KB8B*S{o;vx}q196^hi zBkGtKYqL|Fa^r`#UZ+XEQ=2$TFFe=U*~{(12N-5}-%O05V2J6w>=3;nHC+?WlkYQc z$Mc16TLr%)w{fCKF*3i|gc77@BL3-O0`ATHTl{qiEbUwnwyTG#g^3LosWu@%XA!Nb z+kxzF_tkROfC-Q2C>n)7BA_bOw(?xO;ml?5^Y+ua74KF$iNi;QfaGR%TFabnrRn|>@ zrD;`q=a;crDcnte3MZ-}YQ}P>Z_NW|IiOmTQt&OfFcTLLdwPDpd21xzRTIA!yJaG9 zjpylZtnO|mh}*Vi*9>f_AwK?bfz{)Ua>TYhzs=#_+2yK^*!9a56@wPeaukrQlOAV} JH@ahQ{10wbN5B98 From bb5994ed7080d30f89286cfeb8abfb3fcb0e6721 Mon Sep 17 00:00:00 2001 From: ruevs Date: Mon, 23 Nov 2020 15:15:37 +0200 Subject: [PATCH 064/113] UI: Display "err" in the property browser only if "check sketch for closed contour" ... is enabled. "err" was first introduced in c2c26e95adb to indicate sketches that may cause problems in the subsequent 3D groups. But is makes sense not to display the error if the "check sketch for closed contour" option is turned off. The user obviously does not want to be warned. Based on a suggestion in https://github.com/solvespace/solvespace/issues/819 --- src/textscreens.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/textscreens.cpp b/src/textscreens.cpp index aac27033..07d5cdee 100644 --- a/src/textscreens.cpp +++ b/src/textscreens.cpp @@ -143,7 +143,7 @@ void TextWindow::ShowListOfGroups() { // Link to the errors, if a problem occurred while solving ok ? (warn ? 'm' : (dof > 0 ? 'i' : 's')) : 'x', g->h.v, (&TextWindow::ScreenHowGroupSolved), - ok ? (warn ? "err" : sdof) : "", + ok ? ((warn && SS.checkClosedContour) ? "err" : sdof) : "", ok ? "" : "ERR", // Link to a screen that gives more details on the group g->h.v, (&TextWindow::ScreenSelectGroup), s.c_str()); From 5d173694e7333227e1dc03f4c51d7b1701b67306 Mon Sep 17 00:00:00 2001 From: ruevs Date: Tue, 24 Nov 2020 19:36:26 +0200 Subject: [PATCH 065/113] Win32: Remove sscheck on SetScrollInfo - it returns the scrollbar position ...which can be zero. Fixes: https://github.com/solvespace/solvespace/issues/817 --- src/platform/guiwin.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index cfa4b7ea..5a9f09de 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -1342,7 +1342,7 @@ public: si.nMin = (UINT)(min * SCROLLBAR_UNIT); si.nMax = (UINT)(max * SCROLLBAR_UNIT); si.nPage = (UINT)(pageSize * SCROLLBAR_UNIT); - sscheck(SetScrollInfo(hWindow, SB_VERT, &si, /*redraw=*/TRUE)); + SetScrollInfo(hWindow, SB_VERT, &si, /*redraw=*/TRUE); // Returns scrollbar position } double GetScrollbarPosition() override { @@ -1366,7 +1366,7 @@ public: return; si.nPos = (int)(pos * SCROLLBAR_UNIT); - sscheck(SetScrollInfo(hWindow, SB_VERT, &si, /*redraw=*/TRUE)); + SetScrollInfo(hWindow, SB_VERT, &si, /*redraw=*/TRUE); // Returns scrollbar position // Windows won't synthesize a WM_VSCROLL for us here. if(onScrollbarAdjusted) { From 22dea590778431b80ceef186fe8a23477f937f6e Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Tue, 24 Nov 2020 18:36:35 -0500 Subject: [PATCH 066/113] "Edit newly added dimensions" is now turned on by default. issue826 --- src/solvespace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 9b3ef9b3..acc7162e 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -77,7 +77,7 @@ void SolveSpaceUI::Init() { // Use turntable mouse navigation turntableNav = settings->ThawBool("TurntableNav", false); // Immediately edit dimension - immediatelyEditDimension = settings->ThawBool("ImmediatelyEditDimension", false); + immediatelyEditDimension = settings->ThawBool("ImmediatelyEditDimension", true); // Check that contours are closed and not self-intersecting checkClosedContour = settings->ThawBool("CheckClosedContour", true); // Enable automatic constrains for lines From a2b5d0d45c59b135f8a443e740471ab2cbbf04d9 Mon Sep 17 00:00:00 2001 From: ruevs Date: Wed, 25 Nov 2020 15:51:28 +0200 Subject: [PATCH 067/113] Win32: Remove sscheck on IsWindowVisible and ShowWindow The return value of these functions is not an error code and according to the Win32 API documentation they can not affect `GetLastError`. Calling sscheck on them normally does not fail since it does SetLastError(0) before running the checked expression and only then GetLastError(). However in issue 817 a user discovered that when running "DisplayFusion" software GetLastError does return an error and SolveSpace closes. So while not a strict bug-fix this is a "correctness improvement" for SolveSpace and works around a possible bug in DisplayFusion. Similarly the return value of Reg*** functions is now compared to ERROR_SUCCESS which is zero. Before the sschecks were strictly wrong but did not cause problems for the same reason as above. --- src/platform/guiwin.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index 5a9f09de..d50d24d4 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -183,7 +183,7 @@ public: HKEY GetKey() { if(hKey == NULL) { - sscheck(RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\SolveSpace", 0, NULL, 0, + sscheck(ERROR_SUCCESS == RegCreateKeyExW(HKEY_CURRENT_USER, L"Software\\SolveSpace", 0, NULL, 0, KEY_ALL_ACCESS, NULL, &hKey, NULL)); } return hKey; @@ -191,12 +191,12 @@ public: ~SettingsImplWin32() { if(hKey != NULL) { - sscheck(RegCloseKey(hKey)); + sscheck(ERROR_SUCCESS == RegCloseKey(hKey)); } } void FreezeInt(const std::string &key, uint32_t value) { - sscheck(RegSetValueExW(GetKey(), &Widen(key)[0], 0, + sscheck(ERROR_SUCCESS == RegSetValueExW(GetKey(), &Widen(key)[0], 0, REG_DWORD, (const BYTE *)&value, sizeof(value))); } @@ -212,7 +212,7 @@ public: } void FreezeFloat(const std::string &key, double value) { - sscheck(RegSetValueExW(GetKey(), &Widen(key)[0], 0, + sscheck(ERROR_SUCCESS == RegSetValueExW(GetKey(), &Widen(key)[0], 0, REG_QWORD, (const BYTE *)&value, sizeof(value))); } @@ -231,7 +231,7 @@ public: ssassert(value.length() == strlen(value.c_str()), "illegal null byte in middle of a string setting"); std::wstring valueW = Widen(value); - sscheck(RegSetValueExW(GetKey(), &Widen(key)[0], 0, + sscheck(ERROR_SUCCESS == RegSetValueExW(GetKey(), &Widen(key)[0], 0, REG_SZ, (const BYTE *)&valueW[0], (valueW.length() + 1) * 2)); } @@ -242,7 +242,7 @@ public: if(result == ERROR_SUCCESS && type == REG_SZ) { std::wstring valueW; valueW.resize(length / 2 - 1); - sscheck(RegQueryValueExW(GetKey(), &Widen(key)[0], 0, + sscheck(ERROR_SUCCESS == RegQueryValueExW(GetKey(), &Widen(key)[0], 0, &type, (BYTE *)&valueW[0], &length)); return Narrow(valueW); } @@ -1101,12 +1101,12 @@ public: bool IsVisible() override { BOOL isVisible; - sscheck(isVisible = IsWindowVisible(hWindow)); + isVisible = IsWindowVisible(hWindow); return isVisible == TRUE; } void SetVisible(bool visible) override { - sscheck(ShowWindow(hWindow, visible ? SW_SHOW : SW_HIDE)); + ShowWindow(hWindow, visible ? SW_SHOW : SW_HIDE); } void Focus() override { @@ -1274,7 +1274,7 @@ public: bool IsEditorVisible() override { BOOL visible; - sscheck(visible = IsWindowVisible(hEditor)); + visible = IsWindowVisible(hEditor); return visible == TRUE; } @@ -1316,7 +1316,7 @@ public: sscheck(MoveWindow(hEditor, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, /*bRepaint=*/true)); - sscheck(ShowWindow(hEditor, SW_SHOW)); + ShowWindow(hEditor, SW_SHOW); if(!textW.empty()) { sscheck(SendMessageW(hEditor, WM_SETTEXT, 0, (LPARAM)textW.c_str())); sscheck(SendMessageW(hEditor, EM_SETSEL, 0, textW.length())); @@ -1327,7 +1327,7 @@ public: void HideEditor() override { if(!IsEditorVisible()) return; - sscheck(ShowWindow(hEditor, SW_HIDE)); + ShowWindow(hEditor, SW_HIDE); } void SetScrollbarVisible(bool visible) override { From 9390ab02d5e1d921cfaa4e4948082a818d0e8246 Mon Sep 17 00:00:00 2001 From: ruevs Date: Mon, 23 Nov 2020 13:52:17 +0200 Subject: [PATCH 068/113] Set the default font for text objects correctly. The default font is BitstreamVeraSans-Roman-builtin.ttf since 94b26ddfac0c, but on Win32 it needs to be `res://fonts/...` URI to work. Fixes: https://github.com/solvespace/solvespace/issues/821 --- src/mouse.cpp | 2 +- src/platform/platform.h | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/mouse.cpp b/src/mouse.cpp index 699f3e26..6c22a0cb 100644 --- a/src/mouse.cpp +++ b/src/mouse.cpp @@ -1117,7 +1117,7 @@ void GraphicsWindow::MouseLeftDown(double mx, double my, bool shiftDown, bool ct AddToPending(hr); Request *r = SK.GetRequest(hr); r->str = "Abc"; - r->font = "BitstreamVeraSans-Roman-builtin.ttf"; + r->font = Platform::embeddedFont; for(int i = 1; i <= 4; i++) { SK.GetEntity(hr.entity(i))->PointForceTo(v); diff --git a/src/platform/platform.h b/src/platform/platform.h index 5664fa21..21c2b2bf 100644 --- a/src/platform/platform.h +++ b/src/platform/platform.h @@ -17,6 +17,12 @@ std::string Narrow(const std::wstring &s); std::wstring Widen(const std::string &s); #endif +#if defined(_WIN32) + const std::string embeddedFont = "res://fonts/BitstreamVeraSans-Roman-builtin.ttf"; +#else // Linux and macOS + const std::string embeddedFont = "BitstreamVeraSans-Roman-builtin.ttf"; +#endif + // A filesystem path, respecting the conventions of the current platform. // Transformation functions return an empty path on error. class Path { From aa78043fa218389d0818b41df43dd184661a0859 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Fri, 27 Nov 2020 14:04:53 +0100 Subject: [PATCH 069/113] Swap vertical and horizontal constraints when rotating 90/270 degrees --- src/clipboard.cpp | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index 011b658d..b02808d0 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -227,7 +227,6 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { MakeSelected(hr.entity(j)); } } - Constraint *cc; for(cc = SS.clipboard.c.First(); cc; cc = SS.clipboard.c.NextAfter(cc)) { Constraint c = {}; @@ -257,7 +256,17 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { case Constraint::Type::DIAMETER: c.valA *= fabs(scale); break; - + case Constraint::Type::HORIZONTAL: + case Constraint::Type::VERTICAL: + // When rotating 90 or 270 degrees, swap the vertical / horizontal constaints + if (theta == PI/2 || theta == PI*1.5) { + if(c.type == Constraint::Type::HORIZONTAL) { + c.type = Constraint::Type::VERTICAL; + } else { + c.type = Constraint::Type::HORIZONTAL; + } + } + break; default: break; } From 6b91ab57784ed9920cc9413adc46f994d23e829e Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sat, 28 Nov 2020 12:27:26 +0100 Subject: [PATCH 070/113] Better rotating --- src/clipboard.cpp | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index b02808d0..f2d2b952 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -245,6 +245,7 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { c.reference = cc->reference; c.disp = cc->disp; c.comment = cc->comment; + bool removeConstraint = false; switch(c.type) { case Constraint::Type::COMMENT: c.disp.offset = c.disp.offset.Plus(trans); @@ -259,21 +260,25 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { case Constraint::Type::HORIZONTAL: case Constraint::Type::VERTICAL: // When rotating 90 or 270 degrees, swap the vertical / horizontal constaints - if (theta == PI/2 || theta == PI*1.5) { + dbp("Remainder: %f", fmod(theta + (PI / 2), PI)); + if (fmod(theta + (PI/2), PI) == 0) { if(c.type == Constraint::Type::HORIZONTAL) { c.type = Constraint::Type::VERTICAL; } else { c.type = Constraint::Type::HORIZONTAL; } + } else if (fmod(theta, PI/2) != 0) { + removeConstraint = true; } break; default: break; } - - hConstraint hc = Constraint::AddConstraint(&c, /*rememberForUndo=*/false); - if(c.type == Constraint::Type::COMMENT) { - MakeSelected(hc); + if (!removeConstraint) { + hConstraint hc = Constraint::AddConstraint(&c, /*rememberForUndo=*/false); + if(c.type == Constraint::Type::COMMENT) { + MakeSelected(hc); + } } } } From b316a8863bfe72f7acebe7124bef10830675157f Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Sat, 28 Nov 2020 13:50:38 +0100 Subject: [PATCH 071/113] Use EXACT for checking theta --- src/clipboard.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index f2d2b952..dbcd1dfa 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -260,8 +260,7 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { case Constraint::Type::HORIZONTAL: case Constraint::Type::VERTICAL: // When rotating 90 or 270 degrees, swap the vertical / horizontal constaints - dbp("Remainder: %f", fmod(theta + (PI / 2), PI)); - if (fmod(theta + (PI/2), PI) == 0) { + if (EXACT(fmod(theta + (PI/2), PI) == 0)) { if(c.type == Constraint::Type::HORIZONTAL) { c.type = Constraint::Type::VERTICAL; } else { From 5fa23189d930fc1cf61404b70e5b274a3ac36f63 Mon Sep 17 00:00:00 2001 From: Maximilian Federle Date: Tue, 8 Dec 2020 18:19:33 +0100 Subject: [PATCH 072/113] CI: Replace Travis with GitHub Actions (#824) Travis's move away from providing unlimited build time to OSS and its inferior developer experience are the reason for this change. The workflows are simple and straightforward, and the build scripts are mostly 1:1 the same we used on Travis. This avoids vendor lock-in as much as possible in case we need to move somewhere else in the future. We introduce two workflows: 1. CD (cd.yml) Runs on: Commits to master, GitHub releases. Does: Run tests, build release assets, update GitHub edge release or release to developer created GitHub release. Builds & uploads snaps to the Snap Store. 2. Test (test.yml) Runs on: Every commit except those on master and v* tagged ones. I.e. PRs and other branches. Does: Run tests only. Creating a release is now an explicit operation. On the Travis workflow, pushing a tag that begins with "v" will lead to the automatic creation of an associated GitHub release. On GHA, creating a GitHub release by hand will trigger the CD-workflow to build & upload the release assets. Other differences to Travis: - Windows builds on Visual Studio 16 2019 instead of Visual Studio 15 2017. - Snap builds run in docker containers, not directly on the build host. - Snap arm64 builds on amd64 via QEMU user emulation. This is slower than what Travis gave us and should be changed when/if GHA offers ARM64 build runners. - GHA retains build artifacts for 90 days by default. Required secrets: - MACOS_CERTIFICATE_PASSWORD - MACOS_CERTIFICATE_P12 - MACOS_APPSTORE_APP_PASSWORD - MACOS_APPSTORE_USERNAME - MACOS_DEVELOPER_ID - SNAPSTORE_LOGIN Discussion: https://github.com/solvespace/solvespace/issues/807 PR: https://github.com/solvespace/solvespace/pull/824 Fixes #807 --- {.travis => .github/scripts}/build-macos.sh | 0 {.travis => .github/scripts}/build-snap.sh | 0 {.travis => .github/scripts}/build-ubuntu.sh | 0 {.travis => .github/scripts}/build-windows.sh | 7 +- {.travis => .github/scripts}/install-macos.sh | 0 {.travis => .github/scripts}/install-snap.sh | 0 .../scripts}/install-ubuntu.sh | 0 .../scripts}/install-windows.sh | 0 {.travis => .github/scripts}/sign-macos.sh | 0 .github/workflows/cd.yml | 240 ++++++++++++++++++ .github/workflows/test.yml | 41 +++ .travis.yml | 115 --------- .travis/deploy-snap.sh | 8 - .travis/remove-edge.sh | 23 -- .travis/tag-edge.sh | 8 - README.md | 2 +- 16 files changed, 284 insertions(+), 160 deletions(-) rename {.travis => .github/scripts}/build-macos.sh (100%) rename {.travis => .github/scripts}/build-snap.sh (100%) rename {.travis => .github/scripts}/build-ubuntu.sh (100%) rename {.travis => .github/scripts}/build-windows.sh (79%) rename {.travis => .github/scripts}/install-macos.sh (100%) rename {.travis => .github/scripts}/install-snap.sh (100%) rename {.travis => .github/scripts}/install-ubuntu.sh (100%) rename {.travis => .github/scripts}/install-windows.sh (100%) rename {.travis => .github/scripts}/sign-macos.sh (100%) create mode 100644 .github/workflows/cd.yml create mode 100644 .github/workflows/test.yml delete mode 100644 .travis.yml delete mode 100755 .travis/deploy-snap.sh delete mode 100755 .travis/remove-edge.sh delete mode 100755 .travis/tag-edge.sh diff --git a/.travis/build-macos.sh b/.github/scripts/build-macos.sh similarity index 100% rename from .travis/build-macos.sh rename to .github/scripts/build-macos.sh diff --git a/.travis/build-snap.sh b/.github/scripts/build-snap.sh similarity index 100% rename from .travis/build-snap.sh rename to .github/scripts/build-snap.sh diff --git a/.travis/build-ubuntu.sh b/.github/scripts/build-ubuntu.sh similarity index 100% rename from .travis/build-ubuntu.sh rename to .github/scripts/build-ubuntu.sh diff --git a/.travis/build-windows.sh b/.github/scripts/build-windows.sh similarity index 79% rename from .travis/build-windows.sh rename to .github/scripts/build-windows.sh index d237d528..e81fb2ac 100755 --- a/.travis/build-windows.sh +++ b/.github/scripts/build-windows.sh @@ -1,8 +1,5 @@ #!/bin/sh -xe -MSBUILD_PATH="c:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin" -export PATH=$MSBUILD_PATH:$PATH - mkdir build cd build @@ -14,7 +11,7 @@ if [ "$1" = "release" ]; then fi BUILD_TYPE=RelWithDebInfo cmake \ - -G "Visual Studio 15 2017" \ + -G "Visual Studio 16 2019" \ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ -DENABLE_OPENMP="${ENABLE_OPENMP}" \ -DENABLE_LTO=ON \ @@ -23,7 +20,7 @@ if [ "$1" = "release" ]; then else BUILD_TYPE=Debug cmake \ - -G "Visual Studio 15 2017" \ + -G "Visual Studio 16 2019" \ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \ -DENABLE_OPENMP="ON" \ -DCMAKE_GENERATOR_PLATFORM="Win32" \ diff --git a/.travis/install-macos.sh b/.github/scripts/install-macos.sh similarity index 100% rename from .travis/install-macos.sh rename to .github/scripts/install-macos.sh diff --git a/.travis/install-snap.sh b/.github/scripts/install-snap.sh similarity index 100% rename from .travis/install-snap.sh rename to .github/scripts/install-snap.sh diff --git a/.travis/install-ubuntu.sh b/.github/scripts/install-ubuntu.sh similarity index 100% rename from .travis/install-ubuntu.sh rename to .github/scripts/install-ubuntu.sh diff --git a/.travis/install-windows.sh b/.github/scripts/install-windows.sh similarity index 100% rename from .travis/install-windows.sh rename to .github/scripts/install-windows.sh diff --git a/.travis/sign-macos.sh b/.github/scripts/sign-macos.sh similarity index 100% rename from .travis/sign-macos.sh rename to .github/scripts/sign-macos.sh diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml new file mode 100644 index 00000000..4cf7ab40 --- /dev/null +++ b/.github/workflows/cd.yml @@ -0,0 +1,240 @@ +name: CD + +on: + push: + branches: + - master + release: + types: + - created + +jobs: + test_ubuntu: + runs-on: ubuntu-18.04 + name: Test Ubuntu + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-ubuntu.sh + - name: Build & Test + run: .github/scripts/build-ubuntu.sh + + test_windows: + runs-on: windows-2019 + name: Test Windows + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-windows.sh + shell: bash + - name: Build & Test + run: .github/scripts/build-windows.sh + shell: bash + + test_macos: + runs-on: macos-latest + name: Test macOS + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-macos.sh + - name: Build & Test + run: .github/scripts/build-macos.sh + + build_release_windows: + needs: [test_ubuntu, test_windows, test_macos] + name: Build Release Windows + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-windows.sh + shell: bash + - name: Build & Test + run: .github/scripts/build-windows.sh release + shell: bash + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: windows + path: build/bin/RelWithDebInfo/solvespace.exe + + build_release_windows_openmp: + needs: [test_ubuntu, test_windows, test_macos] + name: Build Release Windows (OpenMP) + runs-on: windows-2019 + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-windows.sh + shell: bash + - name: Build & Test + run: .github/scripts/build-windows.sh release openmp + shell: bash + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: windows-openmp + path: build/bin/RelWithDebInfo/solvespace-openmp.exe + + build_release_macos: + needs: [test_ubuntu, test_windows, test_macos] + name: Build Release macOS + runs-on: macos-latest + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-macos.sh + - name: Build & Test + run: .github/scripts/build-macos.sh release + - name: Sign Build + run: .github/scripts/sign-macos.sh + env: + MACOS_CERTIFICATE_PASSWORD: ${{ secrets.MACOS_CERTIFICATE_PASSWORD }} + MACOS_CERTIFICATE_P12: ${{ secrets.MACOS_CERTIFICATE_P12 }} + MACOS_APPSTORE_APP_PASSWORD: ${{ secrets.MACOS_APPSTORE_APP_PASSWORD }} + MACOS_APPSTORE_USERNAME: ${{ secrets.MACOS_APPSTORE_USERNAME }} + MACOS_DEVELOPER_ID: ${{ secrets.MACOS_DEVELOPER_ID }} + - name: Upload artifact + uses: actions/upload-artifact@v2 + with: + name: macos + path: build/bin/SolveSpace.dmg + + deploy_snap_amd64: + needs: [test_ubuntu, test_windows, test_macos] + name: Deploy AMD64 Snap + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v2 + - name: Set Up Source + run: rsync --filter=":- .gitignore" -r ./ pkg/snap/solvespace-snap-src + - name: Build Snap + id: build + uses: diddlesnaps/snapcraft-multiarch-action@v1 + with: + path: pkg/snap + - name: Upload & Release to Edge + if: github.event_name == 'push' + uses: snapcore/action-publish@v1 + with: + store_login: ${{ secrets.SNAPSTORE_LOGIN }} + snap: ${{ steps.build.outputs.snap }} + release: edge + - name: Upload & Release to Beta + Edge + if: github.event_name == 'release' + uses: snapcore/action-publish@v1 + with: + store_login: ${{ secrets.SNAPSTORE_LOGIN }} + snap: ${{ steps.build.outputs.snap }} + release: edge,beta + + deploy_snap_arm64: + needs: [test_ubuntu, test_windows, test_macos] + name: Deploy ARM64 Snap + runs-on: ubuntu-latest + steps: + - uses: docker/setup-qemu-action@v1 + - uses: actions/checkout@v2 + - name: Set Up Source + run: rsync --filter=":- .gitignore" -r ./ pkg/snap/solvespace-snap-src + - name: Build Snap + id: build + uses: diddlesnaps/snapcraft-multiarch-action@v1 + with: + path: pkg/snap + architecture: arm64 + - name: Upload & Release to Edge + if: github.event_name == 'push' + uses: snapcore/action-publish@v1 + with: + store_login: ${{ secrets.SNAPSTORE_LOGIN }} + snap: ${{ steps.build.outputs.snap }} + release: edge + - name: Upload & Release to Beta + Edge + if: github.event_name == 'release' + uses: snapcore/action-publish@v1 + with: + store_login: ${{ secrets.SNAPSTORE_LOGIN }} + snap: ${{ steps.build.outputs.snap }} + release: edge,beta + + update_edge_release: + name: Update Edge Release + needs: [build_release_windows, build_release_windows_openmp, build_release_macos] + if: always() && github.event_name == 'push' + runs-on: ubuntu-latest + outputs: + upload_url: ${{ steps.create_release.outputs.upload_url }} + steps: + - name: Delete Old Edge Release + uses: dev-drprasad/delete-tag-and-release@v0.1.2 + with: + delete_release: true + tag_name: edge + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Create New Edge Release + id: create_release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: edge + release_name: Edge + prerelease: true + draft: false + body: ${{ github.event.head_commit.message }} + + upload_release_assets: + name: Upload Release Assets + needs: [build_release_windows, build_release_windows_openmp, build_release_macos, update_edge_release] + if: always() + runs-on: ubuntu-latest + steps: + - name: Download All Workflow Artifacts + uses: actions/download-artifact@v2 + - name: Get Release Upload URL + id: get_upload_url + env: + event_name: ${{ github.event_name }} + event: ${{ toJson(github.event) }} + edge_upload_url: ${{ needs.update_edge_release.outputs.upload_url }} + run: | + if [ "$event_name" = "release" ]; then + upload_url=$(echo "$event" | jq -r ".release.upload_url") + else + upload_url="$edge_upload_url" + fi + echo "::set-output name=upload_url::$upload_url" + echo "Upload URL: $upload_url" + - name: Upload solvespace.exe + uses: actions/upload-release-asset@v1 + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.get_upload_url.outputs.upload_url }} + asset_path: windows/solvespace.exe + asset_name: solvespace.exe + asset_content_type: binary/octet-stream + - name: Upload solvespace-openmp.exe + uses: actions/upload-release-asset@v1 + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.get_upload_url.outputs.upload_url }} + asset_path: windows-openmp/solvespace-openmp.exe + asset_name: solvespace-openmp.exe + asset_content_type: binary/octet-stream + - name: Upload SolveSpace.dmg + uses: actions/upload-release-asset@v1 + continue-on-error: true + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.get_upload_url.outputs.upload_url }} + asset_path: macos/SolveSpace.dmg + asset_name: SolveSpace.dmg + asset_content_type: binary/octet-stream diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 00000000..71b82886 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,41 @@ +name: Test + +on: + push: + branches-ignore: + - master + tags-ignore: + - v* + +jobs: + test_ubuntu: + runs-on: ubuntu-18.04 + name: Test Ubuntu + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-ubuntu.sh + - name: Build & Test + run: .github/scripts/build-ubuntu.sh + + test_windows: + runs-on: windows-2019 + name: Test Windows + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-windows.sh + shell: bash + - name: Build & Test + run: .github/scripts/build-windows.sh + shell: bash + + test_macos: + runs-on: macos-latest + name: Test macOS + steps: + - uses: actions/checkout@v2 + - name: Install Dependencies + run: .github/scripts/install-macos.sh + - name: Build & Test + run: .github/scripts/build-macos.sh diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index a692aa77..00000000 --- a/.travis.yml +++ /dev/null @@ -1,115 +0,0 @@ -os: linux -dist: xenial -language: c -git: - submodules: false -if: tag != edge -stages: - - test - - name: clean - if: (NOT type IN (pull_request)) AND (branch = master) - - name: deploy - if: (NOT type IN (pull_request)) AND (branch = master OR tag IS present) -jobs: - include: - - stage: clean - name: Remove Github Release - os: linux - dist: bionic - script: .travis/remove-edge.sh - - stage: test - name: macOS - os: osx - osx_image: xcode12.2 - install: ".travis/install-macos.sh" - script: ".travis/build-macos.sh" - - stage: deploy - name: macOS - os: osx - osx_image: xcode12.2 - install: ".travis/install-macos.sh" - script: ".travis/build-macos.sh release && .travis/sign-macos.sh" - before_deploy: source .travis/tag-edge.sh - deploy: - provider: releases - skip_cleanup: true - prerelease: true - overwrite: true - edge: true - name: ${TRAVIS_TAG:-edge} - release_notes: $TRAVIS_COMMIT_MESSAGE - file: build/bin/SolveSpace.dmg - on: - all_branches: true - - stage: test - name: "Ubuntu" - os: linux - dist: bionic - install: .travis/install-ubuntu.sh - script: .travis/build-ubuntu.sh - - stage: test - name: "Windows" - os: windows - install: .travis/install-windows.sh - script: .travis/build-windows.sh - - stage: deploy - name: "Windows" - os: windows - install: .travis/install-windows.sh - script: .travis/build-windows.sh release - before_deploy: source .travis/tag-edge.sh - deploy: - provider: releases - skip_cleanup: true - prerelease: true - overwrite: true - edge: true - name: ${TRAVIS_TAG:-edge} - release_notes: $TRAVIS_COMMIT_MESSAGE - file: build/bin/RelWithDebInfo/solvespace.exe - on: - all_branches: true - - stage: deploy - name: "Windows with OpenMP" - os: windows - install: .travis/install-windows.sh - script: .travis/build-windows.sh release openmp - before_deploy: source .travis/tag-edge.sh - deploy: - provider: releases - skip_cleanup: true - prerelease: true - overwrite: true - edge: true - name: ${TRAVIS_TAG:-edge} - release_notes: $TRAVIS_COMMIT_MESSAGE - file: build/bin/RelWithDebInfo/solvespace-openmp.exe - on: - all_branches: true - - &deploy-snap - stage: deploy - name: Snap amd64 - os: linux - arch: amd64 - dist: focal - addons: - snaps: - - name: snapcraft - confinement: classic - - name: lxd - install: .travis/install-snap.sh - script: .travis/build-snap.sh - deploy: - - provider: script - script: .travis/deploy-snap.sh edge - skip_cleanup: true - - provider: script - script: .travis/deploy-snap.sh edge,beta - skip_cleanup: true - on: - tags: true - - <<: *deploy-snap - name: Snap arm64 - arch: arm64-graviton2 - group: edge - virt: vm diff --git a/.travis/deploy-snap.sh b/.travis/deploy-snap.sh deleted file mode 100755 index 9cbab5b1..00000000 --- a/.travis/deploy-snap.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -e - -channels="$1" -echo "$SNAP_TOKEN" | snapcraft login --with - - -for snap in ./pkg/snap/*.snap; do - snapcraft upload "$snap" --release "$channels" -done diff --git a/.travis/remove-edge.sh b/.travis/remove-edge.sh deleted file mode 100755 index 4321ff58..00000000 --- a/.travis/remove-edge.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/sh -xe - -sudo apt-get update -qq -sudo apt-get -y install jq - -old_release=$(curl \ - -H "Accept: application/vnd.github.v3+json" \ - https://api.github.com/repos/solvespace/solvespace/releases/tags/edge \ - | jq -r ".url") - -if [ -z "$old_release" ]; then - curl \ - -X DELETE \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token $GITHUB_TOKEN" \ - "$old_release" -fi - -curl \ - -X DELETE \ - -H "Accept: application/vnd.github.v3+json" \ - -H "Authorization: token $GITHUB_TOKEN" \ - https://api.github.com/repos/solvespace/solvespace/git/refs/tags/edge diff --git a/.travis/tag-edge.sh b/.travis/tag-edge.sh deleted file mode 100755 index 8ce6a194..00000000 --- a/.travis/tag-edge.sh +++ /dev/null @@ -1,8 +0,0 @@ -#!/bin/sh -xe - -if [ -z "$TRAVIS_TAG" ]; then - git config --local user.name "solvespace-cd" - git config --local user.email "no-reply@solvespace.com" - export TRAVIS_TAG="edge" - git tag --force $TRAVIS_TAG -fi diff --git a/README.md b/README.md index cbeb89f5..a367bcb9 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ SolveSpace ========== -[![Build Status](https://travis-ci.com/solvespace/solvespace.svg?branch=master)](https://travis-ci.com/solvespace/solvespace) +[![Build Status](https://github.com/solvespace/solvespace/workflows/CD/badge.svg)](https://github.com/solvespace/solvespace/actions) [![solvespace](https://snapcraft.io/solvespace/badge.svg)](https://snapcraft.io/solvespace) [![solvespace](https://snapcraft.io/solvespace/trending.svg?name=0)](https://snapcraft.io/solvespace) From f5086b62ccace2eb756fea97b2e250524af4ad14 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Fri, 4 Dec 2020 23:27:16 +0100 Subject: [PATCH 073/113] Analyze | Stop Tracing (Ctrl+Shift+S) saves CSV only if a point is being traced This avoids confusion with "Ctrl+Shift+S" being used as "Save As..." shortcut on some platforms. --- src/solvespace.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/solvespace.cpp b/src/solvespace.cpp index acc7162e..cc89fed0 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -904,6 +904,9 @@ void SolveSpaceUI::MenuAnalyze(Command id) { break; case Command::STOP_TRACING: { + if (SS.traced.point == Entity::NO_ENTITY) { + break; + } Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); dialog->AddFilters(Platform::CsvFileFilters); dialog->ThawChoices(settings, "Trace"); From a8b8a347c1a9e98de55047715662308ab89efc0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Sun, 22 Mar 2020 23:20:54 +0100 Subject: [PATCH 074/113] Make Path::SetExtension("") not include a dot --- src/platform/platform.cpp | 6 ++++-- test/core/path/test.cpp | 1 + 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/platform/platform.cpp b/src/platform/platform.cpp index f025c861..00854131 100644 --- a/src/platform/platform.cpp +++ b/src/platform/platform.cpp @@ -185,8 +185,10 @@ Path Path::WithExtension(std::string ext) const { if(dot != std::string::npos) { withExt.raw.erase(dot); } - withExt.raw += "."; - withExt.raw += ext; + if(!ext.empty()) { + withExt.raw += "."; + withExt.raw += ext; + } return withExt; } diff --git a/test/core/path/test.cpp b/test/core/path/test.cpp index 92639564..86accf1f 100644 --- a/test/core/path/test.cpp +++ b/test/core/path/test.cpp @@ -83,6 +83,7 @@ TEST_CASE(extension) { } TEST_CASE(with_extension) { + CHECK_EQ_STR(Path::From("foo.bar").WithExtension("").raw, "foo"); CHECK_EQ_STR(Path::From("foo.bar").WithExtension("baz").raw, "foo.baz"); CHECK_EQ_STR(Path::From("foo").WithExtension("baz").raw, "foo.baz"); } From e59186a413f90dd4dd60e4d59a53abcb649cde0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=BD=D0=B0=D0=B1?= Date: Sat, 21 Mar 2020 19:37:14 +0100 Subject: [PATCH 075/113] Suggest sensible defaults in file dialogs Went through first the diff of the referenced commit, then all instances of "Create(Open|Save)FileDialog"; added SuggestFilename() calls where a default exists This has been previously removed in 6b5db5897155ca9bdc5daa3e791c07723a6b7d9c Closes #538 --- src/file.cpp | 5 ++++- src/platform/gui.h | 1 + src/platform/guigtk.cpp | 4 ++++ src/platform/guimac.mm | 4 ++++ src/platform/guiwin.cpp | 4 ++++ src/solvespace.cpp | 7 +++++++ 6 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/file.cpp b/src/file.cpp index acb931f0..f36e49b3 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -904,11 +904,13 @@ try_again: } else if(linkMap.count(g.linkFile) == 0) { dbp("Missing file for group: %s", g.name.c_str()); // The file was moved; prompt the user for its new location. - switch(LocateImportedFile(g.linkFile.RelativeTo(saveFile), canCancel)) { + const auto linkFileRelative = g.linkFile.RelativeTo(saveFile); + switch(LocateImportedFile(linkFileRelative, canCancel)) { case Platform::MessageDialog::Response::YES: { Platform::FileDialogRef dialog = Platform::CreateOpenFileDialog(SS.GW.window); dialog->AddFilters(Platform::SolveSpaceModelFileFilters); dialog->ThawChoices(settings, "LinkSketch"); + dialog->SuggestFilename(linkFileRelative); if(dialog->RunModal()) { dialog->FreezeChoices(settings, "LinkSketch"); linkMap[g.linkFile] = dialog->GetFilename(); @@ -985,6 +987,7 @@ bool SolveSpaceUI::ReloadLinkedImage(const Platform::Path &saveFile, Platform::FileDialogRef dialog = Platform::CreateOpenFileDialog(SS.GW.window); dialog->AddFilters(Platform::RasterFileFilters); dialog->ThawChoices(settings, "LinkImage"); + dialog->SuggestFilename(filename->RelativeTo(saveFile)); if(dialog->RunModal()) { dialog->FreezeChoices(settings, "LinkImage"); *filename = dialog->GetFilename(); diff --git a/src/platform/gui.h b/src/platform/gui.h index 7b2cdf5a..1608a6f2 100644 --- a/src/platform/gui.h +++ b/src/platform/gui.h @@ -356,6 +356,7 @@ public: virtual Platform::Path GetFilename() = 0; virtual void SetFilename(Platform::Path path) = 0; + virtual void SuggestFilename(Platform::Path path) = 0; virtual void AddFilter(std::string name, std::vector extensions) = 0; void AddFilter(const FileFilter &filter); diff --git a/src/platform/guigtk.cpp b/src/platform/guigtk.cpp index cd5d0b8d..0c857df7 100644 --- a/src/platform/guigtk.cpp +++ b/src/platform/guigtk.cpp @@ -1246,6 +1246,10 @@ public: gtkChooser->set_filename(path.raw); } + void SuggestFilename(Platform::Path path) override { + SetFilename(path.WithExtension("")); // TODO + } + void AddFilter(std::string name, std::vector extensions) override { Glib::RefPtr gtkFilter = Gtk::FileFilter::create(); Glib::ustring desc; diff --git a/src/platform/guimac.mm b/src/platform/guimac.mm index 5aa7f054..97897364 100644 --- a/src/platform/guimac.mm +++ b/src/platform/guimac.mm @@ -1274,6 +1274,10 @@ public: nsPanel.nameFieldStringValue = Wrap(path.FileStem()); } + void SuggestFilename(Platform::Path path) override { + SetFilename(path.WithExtension("")); + } + void FreezeChoices(SettingsRef settings, const std::string &key) override { settings->FreezeString("Dialog_" + key + "_Folder", [nsPanel.directoryURL.absoluteString UTF8String]); diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index d50d24d4..cc930775 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -1582,6 +1582,10 @@ public: wcsncpy(filenameWC, Widen(path.raw).c_str(), sizeof(filenameWC) / sizeof(wchar_t) - 1); } + void SuggestFilename(Platform::Path path) override { + SetFilename(Platform::Path::From(path.FileStem())); + } + void AddFilter(std::string name, std::vector extensions) override { std::string desc, patterns; for(auto extension : extensions) { diff --git a/src/solvespace.cpp b/src/solvespace.cpp index cc89fed0..55f6dedd 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -627,6 +627,7 @@ void SolveSpaceUI::MenuFile(Command id) { Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); dialog->AddFilters(Platform::RasterFileFilters); dialog->ThawChoices(settings, "ExportImage"); + dialog->SuggestFilename(SS.saveFile); if(dialog->RunModal()) { dialog->FreezeChoices(settings, "ExportImage"); SS.ExportAsPngTo(dialog->GetFilename()); @@ -638,6 +639,7 @@ void SolveSpaceUI::MenuFile(Command id) { Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); dialog->AddFilters(Platform::VectorFileFilters); dialog->ThawChoices(settings, "ExportView"); + dialog->SuggestFilename(SS.saveFile); if(!dialog->RunModal()) break; dialog->FreezeChoices(settings, "ExportView"); @@ -661,6 +663,7 @@ void SolveSpaceUI::MenuFile(Command id) { Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); dialog->AddFilters(Platform::Vector3dFileFilters); dialog->ThawChoices(settings, "ExportWireframe"); + dialog->SuggestFilename(SS.saveFile); if(!dialog->RunModal()) break; dialog->FreezeChoices(settings, "ExportWireframe"); @@ -672,6 +675,7 @@ void SolveSpaceUI::MenuFile(Command id) { Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); dialog->AddFilters(Platform::VectorFileFilters); dialog->ThawChoices(settings, "ExportSection"); + dialog->SuggestFilename(SS.saveFile); if(!dialog->RunModal()) break; dialog->FreezeChoices(settings, "ExportSection"); @@ -683,6 +687,7 @@ void SolveSpaceUI::MenuFile(Command id) { Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); dialog->AddFilters(Platform::MeshFileFilters); dialog->ThawChoices(settings, "ExportMesh"); + dialog->SuggestFilename(SS.saveFile); if(!dialog->RunModal()) break; dialog->FreezeChoices(settings, "ExportMesh"); @@ -694,6 +699,7 @@ void SolveSpaceUI::MenuFile(Command id) { Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); dialog->AddFilters(Platform::SurfaceFileFilters); dialog->ThawChoices(settings, "ExportSurfaces"); + dialog->SuggestFilename(SS.saveFile); if(!dialog->RunModal()) break; dialog->FreezeChoices(settings, "ExportSurfaces"); @@ -910,6 +916,7 @@ void SolveSpaceUI::MenuAnalyze(Command id) { Platform::FileDialogRef dialog = Platform::CreateSaveFileDialog(SS.GW.window); dialog->AddFilters(Platform::CsvFileFilters); dialog->ThawChoices(settings, "Trace"); + dialog->SetFilename(SS.saveFile); if(dialog->RunModal()) { dialog->FreezeChoices(settings, "Trace"); From 640a1b913af7a749d83a94a06ee0a6663696480f Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Wed, 9 Dec 2020 20:46:20 -0500 Subject: [PATCH 076/113] Use good default filenames on Linux/GTK --- src/platform/guigtk.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/platform/guigtk.cpp b/src/platform/guigtk.cpp index 0c857df7..287515eb 100644 --- a/src/platform/guigtk.cpp +++ b/src/platform/guigtk.cpp @@ -1247,7 +1247,7 @@ public: } void SuggestFilename(Platform::Path path) override { - SetFilename(path.WithExtension("")); // TODO + gtkChooser->set_current_name(path.FileStem()+"."+GetExtension()); } void AddFilter(std::string name, std::vector extensions) override { From 681a50db26e200758423053b091cc7d9481380b7 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Thu, 10 Dec 2020 11:20:22 +0100 Subject: [PATCH 077/113] Run Test CI for pull requests --- .github/workflows/test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 71b82886..27462aef 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -1,6 +1,9 @@ name: Test on: + pull_request: + branches: + - master push: branches-ignore: - master From 2939abf5f876a7454e0afbc06b32c888989b6546 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 23 Nov 2020 22:11:14 +0100 Subject: [PATCH 078/113] Improve zooming with trackpad and scrollwheel On macOS actual scroll delta is used for the zoom amount. On Windows WHEEL_DELTA is used to allow smooth scrolling if supported. Shift+Scroll is added for 10x finer zooming. --- CHANGELOG.md | 1 + src/mouse.cpp | 22 ++++++++++++++-------- src/platform/guigtk.cpp | 4 ++-- src/platform/guimac.mm | 7 +++---- src/platform/guiwin.cpp | 2 +- src/textwin.cpp | 15 ++++++++++++--- src/ui.h | 2 +- 7 files changed, 34 insertions(+), 19 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b302f403..8447d0ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -113,6 +113,7 @@ Other new features: that are shortcuts to the respective configuration screens. * New cmake build options using -DENABLE_OPENMP=yes and -DENABLE_LTO=yes to enable support for multi-threading and link-time optimization. + * "Shift+Scroll" for ten times finer zoom. Bugs fixed: * Fixed broken --view options for command line thumbnail image creation. diff --git a/src/mouse.cpp b/src/mouse.cpp index 6c22a0cb..729c8ee2 100644 --- a/src/mouse.cpp +++ b/src/mouse.cpp @@ -877,7 +877,6 @@ bool GraphicsWindow::ConstrainPointByHovered(hEntity pt, const Point2d *projecte bool GraphicsWindow::MouseEvent(Platform::MouseEvent event) { using Platform::MouseEvent; - double width, height; window->GetContentSize(&width, &height); @@ -918,7 +917,7 @@ bool GraphicsWindow::MouseEvent(Platform::MouseEvent event) { break; case MouseEvent::Type::SCROLL_VERT: - this->MouseScroll(event.x, event.y, (int)event.scrollDelta); + this->MouseScroll(event.x, event.y, event.shiftDown ? event.scrollDelta / 10 : event.scrollDelta); break; case MouseEvent::Type::LEAVE: @@ -1472,18 +1471,25 @@ void GraphicsWindow::EditControlDone(const std::string &s) { } } -void GraphicsWindow::MouseScroll(double x, double y, int delta) { +void GraphicsWindow::MouseScroll(double x, double y, double delta) { double offsetRight = offset.Dot(projRight); double offsetUp = offset.Dot(projUp); double righti = x/scale - offsetRight; double upi = y/scale - offsetUp; - if(delta > 0) { - scale *= 1.2; - } else if(delta < 0) { - scale /= 1.2; - } else return; + // The default zoom factor is 1.2x for one scroll wheel click (delta==1). + // To support smooth scrolling where scroll wheel events come in increments + // smaller (or larger) than 1 we do: + // scale *= exp(ln(1.2) * delta); + // to ensure that the same total scroll delta always results in the same + // total zoom irrespective of in how many increments the zoom was applied. + // For example if we scroll a total delta of a+b in two events vs. one then + // scale * e^a * e^b == scale * e^(a+b) + // while + // scale * a * b != scale * (a+b) + // So this constant is ln(1.2) = 0.1823216 to make the default zoom 1.2x + scale *= exp(0.1823216 * delta); double rightf = x/scale - offsetRight; double upf = y/scale - offsetUp; diff --git a/src/platform/guigtk.cpp b/src/platform/guigtk.cpp index 287515eb..e8113ed2 100644 --- a/src/platform/guigtk.cpp +++ b/src/platform/guigtk.cpp @@ -472,7 +472,7 @@ protected: } bool process_pointer_event(MouseEvent::Type type, double x, double y, - guint state, guint button = 0, int scroll_delta = 0) { + guint state, guint button = 0, double scroll_delta = 0) { MouseEvent event = {}; event.type = type; event.x = x; @@ -536,7 +536,7 @@ protected: } bool on_scroll_event(GdkEventScroll *gdk_event) override { - int delta; + double delta; if(gdk_event->delta_y < 0 || gdk_event->direction == GDK_SCROLL_UP) { delta = 1; } else if(gdk_event->delta_y > 0 || gdk_event->direction == GDK_SCROLL_DOWN) { diff --git a/src/platform/guimac.mm b/src/platform/guimac.mm index 97897364..b2b07a8b 100644 --- a/src/platform/guimac.mm +++ b/src/platform/guimac.mm @@ -554,7 +554,9 @@ MenuBarRef GetOrCreateMainMenu(bool *unique) { MouseEvent event = [self convertMouseEvent:nsEvent]; event.type = MouseEvent::Type::SCROLL_VERT; - event.scrollDelta = [nsEvent deltaY]; + + bool isPrecise = [nsEvent hasPreciseScrollingDeltas]; + event.scrollDelta = [nsEvent scrollingDeltaY] / (isPrecise ? 50 : 5); if(receiver->onMouseEvent) { receiver->onMouseEvent(event); @@ -975,9 +977,6 @@ public: if(GetScrollbarPosition() == pos) return; [nsScroller setDoubleValue:(pos / (ssView.scrollerMax - ssView.scrollerMin))]; - if(onScrollbarAdjusted) { - onScrollbarAdjusted(pos); - } } void Invalidate() override { diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index cc930775..ebd2667b 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -925,7 +925,7 @@ public: event.y = pt.y / pixelRatio; event.type = MouseEvent::Type::SCROLL_VERT; - event.scrollDelta = GET_WHEEL_DELTA_WPARAM(wParam) > 0 ? 1 : -1; + event.scrollDelta = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA; break; case WM_MOUSELEAVE: diff --git a/src/textwin.cpp b/src/textwin.cpp index e243825c..3e339226 100644 --- a/src/textwin.cpp +++ b/src/textwin.cpp @@ -252,8 +252,18 @@ void TextWindow::Init() { MouseLeave(); return true; } else if(event.type == MouseEvent::Type::SCROLL_VERT) { - ScrollbarEvent(window->GetScrollbarPosition() - - LINE_HEIGHT / 2 * event.scrollDelta); + if (event.scrollDelta == 0) { + return true; + } + if (abs(event.scrollDelta) < 0.2) { + if (event.scrollDelta > 0) { + event.scrollDelta = 0.2; + } else { + event.scrollDelta = -0.2; + } + } + double offset = LINE_HEIGHT / 2 * event.scrollDelta; + ScrollbarEvent(window->GetScrollbarPosition() - offset); } return false; }; @@ -1148,7 +1158,6 @@ void TextWindow::ScrollbarEvent(double newPos) { int bottom = top[rows-1] + 2; newPos = min((int)newPos, bottom - halfRows); newPos = max((int)newPos, 0); - if(newPos != scrollPos) { scrollPos = (int)newPos; window->SetScrollbarPosition(scrollPos); diff --git a/src/ui.h b/src/ui.h index 8bdd701c..6563a144 100644 --- a/src/ui.h +++ b/src/ui.h @@ -825,7 +825,7 @@ public: void MouseLeftDoubleClick(double x, double y); void MouseMiddleOrRightDown(double x, double y); void MouseRightUp(double x, double y); - void MouseScroll(double x, double y, int delta); + void MouseScroll(double x, double y, double delta); void MouseLeave(); bool KeyboardEvent(Platform::KeyboardEvent event); void EditControlDone(const std::string &s); From cac3aae0c7d43413897490859b7d2518efd64c31 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sun, 13 Dec 2020 16:06:26 -0500 Subject: [PATCH 079/113] remove the CLA and commercial licensing text. --- CONTRIBUTING.md | 6 +++--- README.md | 4 +--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4caf715b..aee8bb59 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,11 +14,11 @@ Bug reports are always welcome! When reporting a bug, please include the followi GitHub does not allow attaching `*.slvs` files, but it does allow attaching `*.zip` files, so any savefiles should first be archived. -Signing the CLA +Licensing --------------- -To contribute code, translations, artwork, or other resources to SolveSpace, it is necessary to -sign a [Contributor License Agreement](https://cla-assistant.io/solvespace/solvespace). +SolveSpace is licensed under the GPLv3 and any contributions must be made available +under the terms of that license. Contributing translations ------------------------- diff --git a/README.md b/README.md index a367bcb9..098f1f07 100644 --- a/README.md +++ b/README.md @@ -254,6 +254,4 @@ and debug SolveSpace. License ------- -SolveSpace is distributed under the terms of the [GPL v3 license](COPYING.txt). It is possible -to license SolveSpace for use in a commercial application; to do so, -[contact](http://solvespace.com/contact.pl) the developers. +SolveSpace is distributed under the terms of the [GPL v3 license](COPYING.txt). From 4275fb120265460c910d3ffcf0e1f7cf67e7b1fe Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Wed, 16 Dec 2020 19:04:18 +0100 Subject: [PATCH 080/113] Fix snap to grid not working in some situations --- src/graphicswin.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/graphicswin.cpp b/src/graphicswin.cpp index 5aed9663..33bb708d 100644 --- a/src/graphicswin.cpp +++ b/src/graphicswin.cpp @@ -1175,10 +1175,7 @@ void GraphicsWindow::MenuEdit(Command id) { } // Regenerate, with these points marked as dragged so that they // get placed as close as possible to our snap grid. - SS.GW.ClearPending(); - SS.GW.ClearSelection(); - SS.GW.Invalidate(); break; } From f343bbc4f4290df88165a13ad97684719d3fbca3 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 21 Dec 2020 16:02:37 +0100 Subject: [PATCH 081/113] Fix marquee selection when the view is rotated away from the working plane --- src/draw.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/draw.cpp b/src/draw.cpp index 0a21c198..ccaeb961 100644 --- a/src/draw.cpp +++ b/src/draw.cpp @@ -207,8 +207,8 @@ void GraphicsWindow::MakeSelected(Selection *stog) { //----------------------------------------------------------------------------- void GraphicsWindow::SelectByMarquee() { Point2d marqueePoint = ProjectPoint(orig.marqueePoint); - BBox marqueeBBox = BBox::From(Vector::From(marqueePoint.x, marqueePoint.y, -1), - Vector::From(orig.mouse.x, orig.mouse.y, 1)); + BBox marqueeBBox = BBox::From(Vector::From(marqueePoint.x, marqueePoint.y, VERY_NEGATIVE), + Vector::From(orig.mouse.x, orig.mouse.y, VERY_POSITIVE)); Entity *e; for(e = SK.entity.First(); e; e = SK.entity.NextAfter(e)) { From 0e5a246a7030043e56d1bbed917a09582362f887 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 21 Dec 2020 16:03:18 +0100 Subject: [PATCH 082/113] Fix normal selection with marquee --- src/drawentity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drawentity.cpp b/src/drawentity.cpp index d8763360..4ccd228b 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -64,7 +64,7 @@ BBox Entity::GetOrGenerateScreenBBox(bool *hasBBox) { Vector proj = SS.GW.ProjectPoint3(PointGetNum()); screenBBox = BBox::From(proj, proj); } else if(IsNormal()) { - Vector proj = SK.GetEntity(point[0])->PointGetNum(); + Vector proj = SS.GW.ProjectPoint3(SK.GetEntity(point[0])->PointGetNum()); screenBBox = BBox::From(proj, proj); } else if(!sbl->l.IsEmpty()) { Vector first = SS.GW.ProjectPoint3(sbl->l[0].ctrl[0]); From 679e2b920236892132d80bb3934fd8d98615ec02 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Mon, 21 Dec 2020 16:03:42 +0100 Subject: [PATCH 083/113] Fix an off-by-one error that missed the last point when generating screen bounding boxes --- src/drawentity.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/drawentity.cpp b/src/drawentity.cpp index 4ccd228b..6260f0dc 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -70,7 +70,7 @@ BBox Entity::GetOrGenerateScreenBBox(bool *hasBBox) { Vector first = SS.GW.ProjectPoint3(sbl->l[0].ctrl[0]); screenBBox = BBox::From(first, first); for(auto &sb : sbl->l) { - for(int i = 0; i < sb.deg; ++i) { screenBBox.Include(SS.GW.ProjectPoint3(sb.ctrl[i])); } + for(int i = 0; i <= sb.deg; ++i) { screenBBox.Include(SS.GW.ProjectPoint3(sb.ctrl[i])); } } } else ssassert(false, "Expected entity to be a point or have beziers"); From 96958f466395148ee7f0a252222a2a27e7345c22 Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Tue, 22 Dec 2020 14:09:31 +0100 Subject: [PATCH 084/113] Fix paste transformed not correcting tangent arcs when mirrored (#833) --- src/clipboard.cpp | 31 ++++++++++-- src/constraint.cpp | 119 +++++++++++++++++++++++++-------------------- src/sketch.h | 3 ++ 3 files changed, 97 insertions(+), 56 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index dbcd1dfa..d43ec458 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -245,18 +245,41 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { c.reference = cc->reference; c.disp = cc->disp; c.comment = cc->comment; - bool removeConstraint = false; + bool dontAddConstraint = false; switch(c.type) { case Constraint::Type::COMMENT: c.disp.offset = c.disp.offset.Plus(trans); break; - case Constraint::Type::PT_PT_DISTANCE: case Constraint::Type::PT_LINE_DISTANCE: case Constraint::Type::PROJ_PT_DISTANCE: case Constraint::Type::DIAMETER: c.valA *= fabs(scale); break; + case Constraint::Type::ARC_LINE_TANGENT: { + Entity *line = SK.GetEntity(c.entityB), + *arc = SK.GetEntity(c.entityA); + if(line->type == Entity::Type::ARC_OF_CIRCLE) { + swap(line, arc); + } + Constraint::ConstrainArcLineTangent(&c, line, arc); + break; + } + case Constraint::Type::CUBIC_LINE_TANGENT: { + Entity *line = SK.GetEntity(c.entityB), + *cubic = SK.GetEntity(c.entityA); + if(line->type == Entity::Type::CUBIC) { + swap(line, cubic); + } + Constraint::ConstrainCubicLineTangent(&c, line, cubic); + break; + } + case Constraint::Type::CURVE_CURVE_TANGENT: { + Entity *eA = SK.GetEntity(c.entityA), + *eB = SK.GetEntity(c.entityB); + Constraint::ConstrainCurveCurveTangent(&c, eA, eB); + break; + } case Constraint::Type::HORIZONTAL: case Constraint::Type::VERTICAL: // When rotating 90 or 270 degrees, swap the vertical / horizontal constaints @@ -267,13 +290,13 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { c.type = Constraint::Type::HORIZONTAL; } } else if (fmod(theta, PI/2) != 0) { - removeConstraint = true; + dontAddConstraint = true; } break; default: break; } - if (!removeConstraint) { + if (!dontAddConstraint) { hConstraint hc = Constraint::AddConstraint(&c, /*rememberForUndo=*/false); if(c.type == Constraint::Type::COMMENT) { MakeSelected(hc); diff --git a/src/constraint.cpp b/src/constraint.cpp index a66f6d36..2acc2115 100644 --- a/src/constraint.cpp +++ b/src/constraint.cpp @@ -127,6 +127,66 @@ hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) { Entity::NO_ENTITY, Entity::NO_ENTITY, /*other=*/false, /*other2=*/false); } +void Constraint::ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc) { + Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), + l1 = SK.GetEntity(line->point[1])->PointGetNum(); + Vector a1 = SK.GetEntity(arc->point[1])->PointGetNum(), + a2 = SK.GetEntity(arc->point[2])->PointGetNum(); + if(l0.Equals(a1) || l1.Equals(a1)) { + c->other = false; + } else if(l0.Equals(a2) || l1.Equals(a2)) { + c->other = true; + } else { + Error(_("The tangent arc and line segment must share an " + "endpoint. Constrain them with Constrain -> " + "On Point before constraining tangent.")); + return; + } +} + +void Constraint::ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic) { + Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), + l1 = SK.GetEntity(line->point[1])->PointGetNum(); + Vector as = cubic->CubicGetStartNum(), + af = cubic->CubicGetFinishNum(); + + if(l0.Equals(as) || l1.Equals(as)) { + c->other = false; + } else if(l0.Equals(af) || l1.Equals(af)) { + c->other = true; + } else { + Error(_("The tangent cubic and line segment must share an " + "endpoint. Constrain them with Constrain -> " + "On Point before constraining tangent.")); + return; + } +} + +void Constraint::ConstrainCurveCurveTangent(Constraint *c, Entity *eA, Entity *eB) { + Vector as = eA->EndpointStart(), + af = eA->EndpointFinish(), + bs = eB->EndpointStart(), + bf = eB->EndpointFinish(); + if(as.Equals(bs)) { + c->other = false; + c->other2 = false; + } else if(as.Equals(bf)) { + c->other = false; + c->other2 = true; + } else if(af.Equals(bs)) { + c->other = true; + c->other2 = false; + } else if(af.Equals(bf)) { + c->other = true; + c->other2 = true; + } else { + Error(_("The curves must share an endpoint. Constrain them " + "with Constrain -> On Point before constraining " + "tangent.")); + return; + } +} + void Constraint::MenuConstrain(Command id) { Constraint c = {}; c.group = SS.GW.activeGroup; @@ -617,50 +677,22 @@ void Constraint::MenuConstrain(Command id) { c.entityA = gs.vector[0]; c.entityB = gs.vector[1]; } else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) { - Entity *line = SK.GetEntity(gs.entity[0]); - Entity *arc = SK.GetEntity(gs.entity[1]); + Entity *line = SK.GetEntity(gs.entity[0]), + *arc = SK.GetEntity(gs.entity[1]); if(line->type == Entity::Type::ARC_OF_CIRCLE) { swap(line, arc); } - Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), - l1 = SK.GetEntity(line->point[1])->PointGetNum(); - Vector a1 = SK.GetEntity(arc->point[1])->PointGetNum(), - a2 = SK.GetEntity(arc->point[2])->PointGetNum(); - - if(l0.Equals(a1) || l1.Equals(a1)) { - c.other = false; - } else if(l0.Equals(a2) || l1.Equals(a2)) { - c.other = true; - } else { - Error(_("The tangent arc and line segment must share an " - "endpoint. Constrain them with Constrain -> " - "On Point before constraining tangent.")); - return; - } + ConstrainArcLineTangent(&c, line, arc); c.type = Type::ARC_LINE_TANGENT; c.entityA = arc->h; c.entityB = line->h; } else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) { - Entity *line = SK.GetEntity(gs.entity[0]); - Entity *cubic = SK.GetEntity(gs.entity[1]); + Entity *line = SK.GetEntity(gs.entity[0]), + *cubic = SK.GetEntity(gs.entity[1]); if(line->type == Entity::Type::CUBIC) { swap(line, cubic); } - Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), - l1 = SK.GetEntity(line->point[1])->PointGetNum(); - Vector as = cubic->CubicGetStartNum(), - af = cubic->CubicGetFinishNum(); - - if(l0.Equals(as) || l1.Equals(as)) { - c.other = false; - } else if(l0.Equals(af) || l1.Equals(af)) { - c.other = true; - } else { - Error(_("The tangent cubic and line segment must share an " - "endpoint. Constrain them with Constrain -> " - "On Point before constraining tangent.")); - return; - } + ConstrainCubicLineTangent(&c, line, cubic); c.type = Type::CUBIC_LINE_TANGENT; c.entityA = cubic->h; c.entityB = line->h; @@ -671,24 +703,7 @@ void Constraint::MenuConstrain(Command id) { } Entity *eA = SK.GetEntity(gs.entity[0]), *eB = SK.GetEntity(gs.entity[1]); - Vector as = eA->EndpointStart(), - af = eA->EndpointFinish(), - bs = eB->EndpointStart(), - bf = eB->EndpointFinish(); - if(as.Equals(bs)) { - c.other = false; c.other2 = false; - } else if(as.Equals(bf)) { - c.other = false; c.other2 = true; - } else if(af.Equals(bs)) { - c.other = true; c.other2 = false; - } else if(af.Equals(bf)) { - c.other = true; c.other2 = true; - } else { - Error(_("The curves must share an endpoint. Constrain them " - "with Constrain -> On Point before constraining " - "tangent.")); - return; - } + ConstrainCurveCurveTangent(&c, eA, eB); c.type = Type::CURVE_CURVE_TANGENT; c.entityA = eA->h; c.entityB = eB->h; diff --git a/src/sketch.h b/src/sketch.h index 869e0b6f..83773749 100644 --- a/src/sketch.h +++ b/src/sketch.h @@ -790,6 +790,9 @@ public: static hConstraint TryConstrain(Constraint::Type type, hEntity ptA, hEntity ptB, hEntity entityA, hEntity entityB = Entity::NO_ENTITY, bool other = false, bool other2 = false); + static void ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc); + static void ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic); + static void ConstrainCurveCurveTangent(Constraint *c, Entity *eA, Entity *eB); }; class hEquation { From 14e837a45f599b9b2a8a28d8628f96490b593c24 Mon Sep 17 00:00:00 2001 From: ruevs Date: Tue, 22 Dec 2020 20:33:58 +0200 Subject: [PATCH 085/113] Clean up paste transformed and constrain operations a bit. --- src/clipboard.cpp | 21 ++++++--------------- src/constraint.cpp | 15 +++++++++------ 2 files changed, 15 insertions(+), 21 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index d43ec458..6e83aa34 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -257,27 +257,18 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { c.valA *= fabs(scale); break; case Constraint::Type::ARC_LINE_TANGENT: { - Entity *line = SK.GetEntity(c.entityB), - *arc = SK.GetEntity(c.entityA); - if(line->type == Entity::Type::ARC_OF_CIRCLE) { - swap(line, arc); - } - Constraint::ConstrainArcLineTangent(&c, line, arc); + Constraint::ConstrainArcLineTangent(&c, SK.GetEntity(c.entityB), + SK.GetEntity(c.entityA)); break; } case Constraint::Type::CUBIC_LINE_TANGENT: { - Entity *line = SK.GetEntity(c.entityB), - *cubic = SK.GetEntity(c.entityA); - if(line->type == Entity::Type::CUBIC) { - swap(line, cubic); - } - Constraint::ConstrainCubicLineTangent(&c, line, cubic); + Constraint::ConstrainCubicLineTangent(&c, SK.GetEntity(c.entityB), + SK.GetEntity(c.entityA)); break; } case Constraint::Type::CURVE_CURVE_TANGENT: { - Entity *eA = SK.GetEntity(c.entityA), - *eB = SK.GetEntity(c.entityB); - Constraint::ConstrainCurveCurveTangent(&c, eA, eB); + Constraint::ConstrainCurveCurveTangent(&c, SK.GetEntity(c.entityA), + SK.GetEntity(c.entityB)); break; } case Constraint::Type::HORIZONTAL: diff --git a/src/constraint.cpp b/src/constraint.cpp index 2acc2115..7b3c3eb4 100644 --- a/src/constraint.cpp +++ b/src/constraint.cpp @@ -128,10 +128,15 @@ hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) { } void Constraint::ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc) { + if(line->type == Entity::Type::ARC_OF_CIRCLE) { + swap(line, arc); + } + Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), l1 = SK.GetEntity(line->point[1])->PointGetNum(); Vector a1 = SK.GetEntity(arc->point[1])->PointGetNum(), a2 = SK.GetEntity(arc->point[2])->PointGetNum(); + if(l0.Equals(a1) || l1.Equals(a1)) { c->other = false; } else if(l0.Equals(a2) || l1.Equals(a2)) { @@ -145,6 +150,10 @@ void Constraint::ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *ar } void Constraint::ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic) { + if(line->type == Entity::Type::CUBIC) { + swap(line, cubic); + } + Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), l1 = SK.GetEntity(line->point[1])->PointGetNum(); Vector as = cubic->CubicGetStartNum(), @@ -679,9 +688,6 @@ void Constraint::MenuConstrain(Command id) { } else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) { Entity *line = SK.GetEntity(gs.entity[0]), *arc = SK.GetEntity(gs.entity[1]); - if(line->type == Entity::Type::ARC_OF_CIRCLE) { - swap(line, arc); - } ConstrainArcLineTangent(&c, line, arc); c.type = Type::ARC_LINE_TANGENT; c.entityA = arc->h; @@ -689,9 +695,6 @@ void Constraint::MenuConstrain(Command id) { } else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) { Entity *line = SK.GetEntity(gs.entity[0]), *cubic = SK.GetEntity(gs.entity[1]); - if(line->type == Entity::Type::CUBIC) { - swap(line, cubic); - } ConstrainCubicLineTangent(&c, line, cubic); c.type = Type::CUBIC_LINE_TANGENT; c.entityA = cubic->h; From 440ea554c904c7336afba50ac30b839ac463b882 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sun, 20 Dec 2020 20:55:00 -0500 Subject: [PATCH 086/113] Add menu checkbox Dim Solid for Sketch Groups. Makes shadowing the solid optional for sketch in 2d/3d groups. Handy for making dimensioned drawings by putting dims in their own group. #834 --- src/graphicswin.cpp | 11 +++++++++++ src/groupmesh.cpp | 3 ++- src/solvespace.cpp | 1 + src/ui.h | 3 +++ 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/graphicswin.cpp b/src/graphicswin.cpp index 33bb708d..d368c321 100644 --- a/src/graphicswin.cpp +++ b/src/graphicswin.cpp @@ -92,6 +92,7 @@ const MenuEntry Menu[] = { { 1, N_("&Center View At Point"), Command::CENTER_VIEW, F|4, KN, mView }, { 1, NULL, Command::NONE, 0, KN, NULL }, { 1, N_("Show Snap &Grid"), Command::SHOW_GRID, '>', KC, mView }, +{ 1, N_("Dim Solid for Sketch Groups"), Command::DIM_SOLID_MODEL, 0, KC, mView }, { 1, N_("Use &Perspective Projection"), Command::PERSPECTIVE_PROJ, '`', KC, mView }, { 1, N_("Dimension &Units"), Command::NONE, 0, KN, NULL }, { 2, N_("Dimensions in &Millimeters"), Command::UNITS_MM, 0, KR, mView }, @@ -312,6 +313,8 @@ void GraphicsWindow::PopulateMainMenu() { if(Menu[i].cmd == Command::SHOW_GRID) { showGridMenuItem = menuItem; + } else if(Menu[i].cmd == Command::DIM_SOLID_MODEL) { + dimSolidModelMenuItem = menuItem; } else if(Menu[i].cmd == Command::PERSPECTIVE_PROJ) { perspectiveProjMenuItem = menuItem; } else if(Menu[i].cmd == Command::SHOW_TOOLBAR) { @@ -406,6 +409,7 @@ void GraphicsWindow::Init() { showTextWindow = true; showSnapGrid = false; + dimSolidModel = true; context.active = false; toolbarHovered = Command::NONE; @@ -722,6 +726,12 @@ void GraphicsWindow::MenuView(Command id) { } break; + case Command::DIM_SOLID_MODEL: + SS.GW.dimSolidModel = !SS.GW.dimSolidModel; + SS.GW.EnsureValidActives(); + SS.GW.Invalidate(/*clearPersistent=*/true); + break; + case Command::PERSPECTIVE_PROJ: SS.usePerspectiveProj = !SS.usePerspectiveProj; SS.GW.EnsureValidActives(); @@ -923,6 +933,7 @@ void GraphicsWindow::EnsureValidActives() { showTextWndMenuItem->SetActive(SS.GW.showTextWindow); showGridMenuItem->SetActive(SS.GW.showSnapGrid); + dimSolidModelMenuItem->SetActive(SS.GW.dimSolidModel); perspectiveProjMenuItem->SetActive(SS.usePerspectiveProj); showToolbarMenuItem->SetActive(SS.showToolbar); fullScreenMenuItem->SetActive(SS.GW.window->IsFullScreen()); diff --git a/src/groupmesh.cpp b/src/groupmesh.cpp index 2d509aea..f1041d63 100644 --- a/src/groupmesh.cpp +++ b/src/groupmesh.cpp @@ -569,7 +569,8 @@ void Group::DrawMesh(DrawMeshAs how, Canvas *canvas) { if(!SS.GW.showShaded) { fillFront.layer = Canvas::Layer::DEPTH_ONLY; } - if(type == Type::DRAWING_3D || type == Type::DRAWING_WORKPLANE) { + if((type == Type::DRAWING_3D || type == Type::DRAWING_WORKPLANE) + && SS.GW.dimSolidModel) { fillFront.color = Style::Color(Style::DIM_SOLID); } Canvas::hFill hcfFront = canvas->GetFill(fillFront); diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 55f6dedd..0b746f22 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -1018,6 +1018,7 @@ void SolveSpaceUI::Clear() { GW.openRecentMenu = NULL; GW.linkRecentMenu = NULL; GW.showGridMenuItem = NULL; + GW.dimSolidModelMenuItem = NULL; GW.perspectiveProjMenuItem = NULL; GW.showToolbarMenuItem = NULL; GW.showTextWndMenuItem = NULL; diff --git a/src/ui.h b/src/ui.h index 6563a144..026d57de 100644 --- a/src/ui.h +++ b/src/ui.h @@ -80,6 +80,7 @@ enum class Command : uint32_t { ZOOM_OUT, ZOOM_TO_FIT, SHOW_GRID, + DIM_SOLID_MODEL, PERSPECTIVE_PROJ, ONTO_WORKPLANE, NEAREST_ORTHO, @@ -532,6 +533,7 @@ public: Platform::MenuRef linkRecentMenu; Platform::MenuItemRef showGridMenuItem; + Platform::MenuItemRef dimSolidModelMenuItem; Platform::MenuItemRef perspectiveProjMenuItem; Platform::MenuItemRef showToolbarMenuItem; Platform::MenuItemRef showTextWndMenuItem; @@ -803,6 +805,7 @@ public: DrawOccludedAs drawOccludedAs; bool showSnapGrid; + bool dimSolidModel; void DrawSnapGrid(Canvas *canvas); void AddPointToDraggedList(hEntity hp); From 222c80e4c132f6d1fa1bc0a293660f65874a683f Mon Sep 17 00:00:00 2001 From: Koen Schmeets Date: Tue, 29 Dec 2020 20:09:10 +0100 Subject: [PATCH 087/113] Add OpenMP debug information to conf screen (#869) * Add OpenMP debug information to conf screen * Revert casing and whitespace in CMakeLists.txt * Remove unnecessary comment src/CMakeLists.txt --- CMakeLists.txt | 1 - src/CMakeLists.txt | 3 ++- src/confscreen.cpp | 8 ++++++++ 3 files changed, 10 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6cdca35c..12948781 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,7 +116,6 @@ endif() if(ENABLE_OPENMP) find_package( OpenMP REQUIRED ) - include(FindOpenMP) if(OPENMP_FOUND) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") message(STATUS "found OpenMP, compiling with flags: " ${OpenMP_CXX_FLAGS} ) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 4f277f53..45dab944 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -80,7 +80,8 @@ include_directories( ${PNG_PNG_INCLUDE_DIR} ${FREETYPE_INCLUDE_DIRS} ${CAIRO_INCLUDE_DIRS} - ${MIMALLOC_INCLUDE_DIR}) + ${MIMALLOC_INCLUDE_DIR} + ${OpenMP_CXX_INCLUDE_DIRS}) if(Backtrace_FOUND) include_directories( diff --git a/src/confscreen.cpp b/src/confscreen.cpp index 07c42b74..c7e2815a 100644 --- a/src/confscreen.cpp +++ b/src/confscreen.cpp @@ -5,6 +5,9 @@ // Copyright 2008-2013 Jonathan Westhues. //----------------------------------------------------------------------------- #include "solvespace.h" +#if defined(_OPENMP) +#include +#endif void TextWindow::ScreenChangeLightDirection(int link, uint32_t v) { SS.TW.ShowEditControl(8, ssprintf("%.2f, %.2f, %.2f", CO(SS.lightDir[v]))); @@ -389,6 +392,11 @@ void TextWindow::ShowConfiguration() { Printf(false, " %Ft renderer %E%s", gl_renderer); Printf(false, " %Ft version %E%s", gl_version); } + + #if defined(_OPENMP) + Printf(false, " %FtOpenMP enabled"); + Printf(false, " %Ft threads %E%d", omp_get_max_threads()); + #endif } bool TextWindow::EditControlDoneForConfiguration(const std::string &s) { From 3e3ccdca8d6c66080078c46c274cbde645f43cf4 Mon Sep 17 00:00:00 2001 From: ruevs Date: Fri, 8 Jan 2021 21:30:31 +0200 Subject: [PATCH 088/113] Revert "Clean up paste transformed and constrain operations a bit." This reverts commit 14e837a45f599b9b2a8a28d8628f96490b593c24. Fixes a regression described here: https://github.com/solvespace/solvespace/issues/875 --- src/clipboard.cpp | 21 +++++++++++++++------ src/constraint.cpp | 15 ++++++--------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/src/clipboard.cpp b/src/clipboard.cpp index 6e83aa34..d43ec458 100644 --- a/src/clipboard.cpp +++ b/src/clipboard.cpp @@ -257,18 +257,27 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) { c.valA *= fabs(scale); break; case Constraint::Type::ARC_LINE_TANGENT: { - Constraint::ConstrainArcLineTangent(&c, SK.GetEntity(c.entityB), - SK.GetEntity(c.entityA)); + Entity *line = SK.GetEntity(c.entityB), + *arc = SK.GetEntity(c.entityA); + if(line->type == Entity::Type::ARC_OF_CIRCLE) { + swap(line, arc); + } + Constraint::ConstrainArcLineTangent(&c, line, arc); break; } case Constraint::Type::CUBIC_LINE_TANGENT: { - Constraint::ConstrainCubicLineTangent(&c, SK.GetEntity(c.entityB), - SK.GetEntity(c.entityA)); + Entity *line = SK.GetEntity(c.entityB), + *cubic = SK.GetEntity(c.entityA); + if(line->type == Entity::Type::CUBIC) { + swap(line, cubic); + } + Constraint::ConstrainCubicLineTangent(&c, line, cubic); break; } case Constraint::Type::CURVE_CURVE_TANGENT: { - Constraint::ConstrainCurveCurveTangent(&c, SK.GetEntity(c.entityA), - SK.GetEntity(c.entityB)); + Entity *eA = SK.GetEntity(c.entityA), + *eB = SK.GetEntity(c.entityB); + Constraint::ConstrainCurveCurveTangent(&c, eA, eB); break; } case Constraint::Type::HORIZONTAL: diff --git a/src/constraint.cpp b/src/constraint.cpp index 7b3c3eb4..2acc2115 100644 --- a/src/constraint.cpp +++ b/src/constraint.cpp @@ -128,15 +128,10 @@ hConstraint Constraint::ConstrainCoincident(hEntity ptA, hEntity ptB) { } void Constraint::ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *arc) { - if(line->type == Entity::Type::ARC_OF_CIRCLE) { - swap(line, arc); - } - Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), l1 = SK.GetEntity(line->point[1])->PointGetNum(); Vector a1 = SK.GetEntity(arc->point[1])->PointGetNum(), a2 = SK.GetEntity(arc->point[2])->PointGetNum(); - if(l0.Equals(a1) || l1.Equals(a1)) { c->other = false; } else if(l0.Equals(a2) || l1.Equals(a2)) { @@ -150,10 +145,6 @@ void Constraint::ConstrainArcLineTangent(Constraint *c, Entity *line, Entity *ar } void Constraint::ConstrainCubicLineTangent(Constraint *c, Entity *line, Entity *cubic) { - if(line->type == Entity::Type::CUBIC) { - swap(line, cubic); - } - Vector l0 = SK.GetEntity(line->point[0])->PointGetNum(), l1 = SK.GetEntity(line->point[1])->PointGetNum(); Vector as = cubic->CubicGetStartNum(), @@ -688,6 +679,9 @@ void Constraint::MenuConstrain(Command id) { } else if(gs.lineSegments == 1 && gs.arcs == 1 && gs.n == 2) { Entity *line = SK.GetEntity(gs.entity[0]), *arc = SK.GetEntity(gs.entity[1]); + if(line->type == Entity::Type::ARC_OF_CIRCLE) { + swap(line, arc); + } ConstrainArcLineTangent(&c, line, arc); c.type = Type::ARC_LINE_TANGENT; c.entityA = arc->h; @@ -695,6 +689,9 @@ void Constraint::MenuConstrain(Command id) { } else if(gs.lineSegments == 1 && gs.cubics == 1 && gs.n == 2) { Entity *line = SK.GetEntity(gs.entity[0]), *cubic = SK.GetEntity(gs.entity[1]); + if(line->type == Entity::Type::CUBIC) { + swap(line, cubic); + } ConstrainCubicLineTangent(&c, line, cubic); c.type = Type::CUBIC_LINE_TANGENT; c.entityA = cubic->h; From d45e2c4c2e814146a11d261f75a5c091162f77f9 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sat, 9 Jan 2021 12:27:27 -0500 Subject: [PATCH 089/113] Add toolbar icons for Revolve and Helix created by jkrei0 in issue #857. (#878) --- res/CMakeLists.txt | 2 ++ res/icons/graphics-window/helix.png | Bin 0 -> 664 bytes res/icons/graphics-window/revolve.png | Bin 0 -> 680 bytes src/toolbar.cpp | 6 +++++- 4 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 res/icons/graphics-window/helix.png create mode 100644 res/icons/graphics-window/revolve.png diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index 5969039b..e261ba21 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -213,6 +213,7 @@ add_resources( icons/graphics-window/construction.png icons/graphics-window/equal.png icons/graphics-window/extrude.png + icons/graphics-window/helix.png icons/graphics-window/horiz.png icons/graphics-window/image.png icons/graphics-window/in3d.png @@ -227,6 +228,7 @@ add_resources( icons/graphics-window/point.png icons/graphics-window/rectangle.png icons/graphics-window/ref.png + icons/graphics-window/revolve.png icons/graphics-window/same-orientation.png icons/graphics-window/sketch-in-3d.png icons/graphics-window/sketch-in-plane.png diff --git a/res/icons/graphics-window/helix.png b/res/icons/graphics-window/helix.png new file mode 100644 index 0000000000000000000000000000000000000000..4b2cda68d5138d636ffe3af605bf3ad5fbb696a0 GIT binary patch literal 664 zcmV;J0%!e+P)EX>4Tx04R}tkv&MmKpe$iQ>7wRK|6>zWT@g`K~%(1s#pXIrLEAagUO{|(4-+r zad8w}3l4rPRvlcNb#-tR1i=pwCr2km7b)?7NufoI2gm(*ckglc4iM^PrkWiSfT~$W zG8Ppx*;O&{iXi&Yi!p>HX6o_OVj7;~>mEM7-bHwp_qjhukCHPP;1h}Gm~L3a8^kl4 zmd<&fIK+yQLVQjM*<>bR8c}179zB2q?kz3e$>N1AO zrG<}xzHQ**x~0i`z~v4w_@qmQWaB3Q005LpL_t(Y$L*6*4uBvGLutZU z$DMZB`lXpfWWe~+eSs3O!PpGn{IcX{QyhP~ugQ;!)um^_oVGC%|pl9#5G ya?@dzKS=_BHM9GWm%Ozso~J#cO)Q?jTy+59P=<`q9VLJO0000EX>4Tx04R}tkv&MmKpe$iQ>7wRK|6>zWT@g`K~%(1s#pXIrLEAagUO{|(4-+r zad8w}3l4rPRvlcNb#-tR1i=pwCr2km7b)?7NufoI2gm(*ckglc4iM^PrkWiSfT~$W zG8Ppx*;O&{iXi&Yi!p>HX6o_OVj7;~>mEM7-bHwp_qjhukCHPP;1h}Gm~L3a8^kl4 zmd<&fIK+yQLVQjM*<>bR8c}179zB2q?kz3e$>N1AO zrG<}xzHQ**x~0i`z~v4w_@qmQ5(6O!TO8k- zKj~-bp{3(EP{?}f%;u;NP(rTj-yvB50R448=M=iYN}3Tcv89fWa!<%3j>aUbD&0V< zyh1;)`{oG+o$zP|ckmQQ(b>g2T1HC-pp1&v z-AGjgKue~z=|9?m#@a7y-JS6u5&3p`yAdPM1yS7YOJxB>L#`HjK;Z=v_ne2gg`(&H O0000 Date: Sat, 9 Jan 2021 19:41:23 +0200 Subject: [PATCH 090/113] Update ISSUE_TEMPLATE.md (#859) Improve formatting. --- .github/ISSUE_TEMPLATE.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index e3747b22..e9d7df97 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,8 +1,7 @@ ### System information -SolveSpace version: - -Operating system: +- **SolveSpace version:** +- **Operating system:** ### Expected behavior From 82698b19a356ff1338298ec84b8553e3644bc2c2 Mon Sep 17 00:00:00 2001 From: ruevs Date: Sat, 9 Jan 2021 23:11:19 +0200 Subject: [PATCH 091/113] Update the year in the About dialog --- src/solvespace.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 0b746f22..054c4908 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -1001,7 +1001,7 @@ void SolveSpaceUI::MenuHelp(Command id) { "law. For details, visit http://gnu.org/licenses/\n" "\n" "© 2008-%d Jonathan Westhues and other authors.\n"), -PACKAGE_VERSION, 2020); +PACKAGE_VERSION, 2021); break; default: ssassert(false, "Unexpected menu ID"); From 3abfd91e9d0d8276eb5ab5653aa436dbfba889d7 Mon Sep 17 00:00:00 2001 From: ruevs Date: Sat, 9 Jan 2021 23:18:32 +0200 Subject: [PATCH 092/113] Win32: Update the year in the Windows version resource Visible in right-click on solvespace.exe | Properties | Details | Copyright --- res/win32/versioninfo.rc.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/win32/versioninfo.rc.in b/res/win32/versioninfo.rc.in index 0772a39d..e6e90056 100644 --- a/res/win32/versioninfo.rc.in +++ b/res/win32/versioninfo.rc.in @@ -18,7 +18,7 @@ BEGIN 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" + VALUE "LegalCopyright", "(c) 2008-2021 Jonathan Westhues and other authors" END END From 5ef7034de8a14174ec53e027e2636d458b8d5d72 Mon Sep 17 00:00:00 2001 From: ruevs Date: Sun, 10 Jan 2021 00:30:13 +0200 Subject: [PATCH 093/113] README.md: Use the SVG icon with a relative path. (#883) --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 098f1f07..6e575a5d 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -SolveSpace Logo +SolveSpace Logo SolveSpace ========== From 758095adb38179d0cc9415763df7ef774d81db60 Mon Sep 17 00:00:00 2001 From: ruevs Date: Sun, 10 Jan 2021 00:31:25 +0200 Subject: [PATCH 094/113] =?UTF-8?q?Win32:=20Avoid=20the=20"Default=20Beep"?= =?UTF-8?q?=20sound=20in=20"=D0=95rror"=20and=20"Message"=20dialogs=20(#88?= =?UTF-8?q?1)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On Windows SolveSpace 2.3 uses a plain dialog for `SolveSpace::Error` and `SolveSpace::Message` with no icon and no system beep. After the GUI abstraction was reworked this changed to the default system message boxes (using MessageBoxIndirectW) that play the "Default Beep" sound and show red "X" and blue "i" icons respectively. The beep is annoying since the error and message dialogs are used often to show required conditions for constraints, new groups and other behaviors. This disables the beep and uses the SolveSpace icon. Fixes: 719 --- src/platform/guiwin.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index ebd2667b..745720a4 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -1450,7 +1450,10 @@ public: void SetType(Type type) override { switch(type) { case Type::INFORMATION: - style = MB_ICONINFORMATION; + style = MB_USERICON; // Avoid beep + mbp.hInstance = GetModuleHandle(NULL); + mbp.lpszIcon = MAKEINTRESOURCE(4000); // Use SolveSpace icon + // mbp.lpszIcon = IDI_INFORMATION; break; case Type::QUESTION: @@ -1462,7 +1465,10 @@ public: break; case Type::ERROR: - style = MB_ICONERROR; + style = MB_USERICON; // Avoid beep + mbp.hInstance = GetModuleHandle(NULL); + mbp.lpszIcon = MAKEINTRESOURCE(4000); // Use SolveSpace icon + // mbp.lpszIcon = IDI_ERROR; break; } } From bd41485ebecce360baa729567273714caac1df6c Mon Sep 17 00:00:00 2001 From: ruevs Date: Sun, 10 Jan 2021 17:33:26 +0200 Subject: [PATCH 095/113] Correct toolbar height calculation (#885) The toolbar height is `int fudge = 8;` `int h = 32*18 + 3*16 + fudge;` It means 18 icons 32 pixels each and 3 separators 16 pixels each. `32*18 + 3*16 + 8 = 632` `36*16 + 3*16 + 8 = 632` See these correct increases of the toolbar height: https://github.com/ruevs/solvespace/blame/bf4de993cbc752cd063bd7dbaa8ef44b36ec13e4/toolbar.cpp#L97 https://github.com/ruevs/solvespace/blame/fe2ea5d5e1c0a361c78248521fc3cff06ab322a9/toolbar.cpp#L103 https://github.com/ruevs/solvespace/blame/ef5db2132e871e12c667bc2147e94c2cabf37729/src/toolbar.cpp#L112 https://github.com/ruevs/solvespace/blame/ca2aad7fea14b09cd4df39b9a4628781f76624c7/src/toolbar.cpp#L145 And then these incorrect ones: https://github.com/ruevs/solvespace/blame/3e3ccdca8d6c66080078c46c274cbde645f43cf4/src/toolbar.cpp#L156 https://github.com/ruevs/solvespace/blame/master/src/toolbar.cpp#L160 In addition https://github.com/ruevs/solvespace/blob/master/src/drawentity.cpp#L618 the point at which the XYZ axis are shifted right so that they do not overlap with the toolbar is corrected. The original discussion is here: https://github.com/ruevs/solvespace/commit/d45e2c4c2e814146a11d261f75a5c091162f77f9 --- src/drawentity.cpp | 2 +- src/toolbar.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/drawentity.cpp b/src/drawentity.cpp index 6260f0dc..b8e3cbd5 100644 --- a/src/drawentity.cpp +++ b/src/drawentity.cpp @@ -615,7 +615,7 @@ void Entity::Draw(DrawAs how, Canvas *canvas) { double w = 60 - camera.width / 2.0; // Shift the axis to the right if they would overlap with the toolbar. if(SS.showToolbar) { - if(h + 30 > -(34*16 + 3*16 + 8) / 2) + if(h + 30 > -(32*18 + 3*16 + 8) / 2) w += 60; } tail = camera.projRight.ScaledBy(w/s).Plus( diff --git a/src/toolbar.cpp b/src/toolbar.cpp index e6f76732..bf6b59c5 100644 --- a/src/toolbar.cpp +++ b/src/toolbar.cpp @@ -157,7 +157,7 @@ bool GraphicsWindow::ToolbarDrawOrHitTest(int mx, int my, UiCanvas *canvas, // When changing these values, also change the asReference drawing code in drawentity.cpp. int fudge = 8; - int h = 36*16 + 3*16 + fudge; + int h = 32*18 + 3*16 + fudge; int aleft = 0, aright = 66, atop = y+16+fudge/2, abot = y+16-h; bool withinToolbar = From 41c81a71c1c432c2d5ff3342d2a570c19d01727b Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sat, 9 Jan 2021 16:57:38 -0500 Subject: [PATCH 096/113] Override minimum displayed digits as needed to avoid showing zero. --- src/solvespace.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/solvespace.cpp b/src/solvespace.cpp index 054c4908..4e458cf4 100644 --- a/src/solvespace.cpp +++ b/src/solvespace.cpp @@ -331,7 +331,13 @@ const char *SolveSpaceUI::UnitName() { std::string SolveSpaceUI::MmToString(double v) { v /= MmPerUnit(); - return ssprintf("%.*f", UnitDigitsAfterDecimal(), v); + int digits = UnitDigitsAfterDecimal(); + double minimum = 0.5 * pow(10,-digits); + while ((v < minimum) && (v > LENGTH_EPS)) { + digits++; + minimum *= 0.1; + } + return ssprintf("%.*f", digits, v); } static const char *DimToString(int dim) { switch(dim) { From d6c2983c7216d348f5f92f0feb2aa21f4735fc97 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Fri, 15 Jan 2021 14:53:31 -0600 Subject: [PATCH 097/113] Update messages --- res/locales/de_DE.po | 448 ++++++++++++++++++------------------ res/locales/en_US.po | 534 ++++++++++++++++++++++--------------------- res/locales/fr_FR.po | 448 ++++++++++++++++++------------------ res/locales/ru_RU.po | 450 ++++++++++++++++++------------------ res/locales/uk_UA.po | 432 +++++++++++++++++----------------- res/locales/zh_CN.po | 434 ++++++++++++++++++----------------- res/messages.pot | 432 +++++++++++++++++----------------- 7 files changed, 1631 insertions(+), 1547 deletions(-) diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po index 795f9220..82807643 100644 --- a/res/locales/de_DE.po +++ b/res/locales/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-23 11:23+0200\n" +"POT-Creation-Date: 2021-01-15 14:51-0600\n" "PO-Revision-Date: 2018-07-19 06:55+0000\n" "Last-Translator: Reini Urban \n" "Language-Team: none\n" @@ -17,7 +17,7 @@ msgstr "" "X-Generator: Zanata 4.5.0\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -#: clipboard.cpp:274 +#: clipboard.cpp:310 msgid "" "Cut, paste, and copy work only in a workplane.\n" "\n" @@ -28,27 +28,27 @@ msgstr "" "\n" "Aktivieren Sie eine mit Skizze -> In Arbeitsebene" -#: clipboard.cpp:291 +#: clipboard.cpp:327 msgid "Clipboard is empty; nothing to paste." msgstr "Zwischenablage ist leer; es gibt nichts einzufügen." -#: clipboard.cpp:338 +#: clipboard.cpp:374 msgid "Number of copies to paste must be at least one." msgstr "Die Anzahl der einzufügenden Kopien muss mind. 1 sein." -#: clipboard.cpp:354 textscreens.cpp:783 +#: clipboard.cpp:390 textscreens.cpp:783 msgid "Scale cannot be zero." msgstr "Maßstab kann nicht Null sein." -#: clipboard.cpp:396 +#: clipboard.cpp:432 msgid "Select one point to define origin of rotation." msgstr "Wählen Sie einen Punkt, um den Drehmittelpunkt zu definieren." -#: clipboard.cpp:408 +#: clipboard.cpp:444 msgid "Select two points to define translation vector." msgstr "Wählen Sie zwei Punkte, um den Verschiebungsvektor zu definieren." -#: clipboard.cpp:418 +#: clipboard.cpp:454 msgid "" "Transformation is identity. So all copies will be exactly on top of each " "other." @@ -56,25 +56,25 @@ msgstr "" "Die Transformation ist die Identität. Alle Kopien werden deckungsgleich " "übereinanderliegen." -#: clipboard.cpp:422 +#: clipboard.cpp:458 msgid "Too many items to paste; split this into smaller pastes." msgstr "" "Zuviele Objekte zum Einfügen; teilen Sie diese in kleinere " "Einfügeoperationen auf." -#: clipboard.cpp:427 +#: clipboard.cpp:463 msgid "No workplane active." msgstr "Es ist keine Arbeitsebene aktiv." -#: confscreen.cpp:410 +#: confscreen.cpp:418 msgid "Bad format: specify coordinates as x, y, z" msgstr "Ungültiges Format: geben Sie Koordinaten als x, y, z an" -#: confscreen.cpp:420 style.cpp:659 textscreens.cpp:805 +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 msgid "Bad format: specify color as r, g, b" msgstr "Ungültiges Format: geben Sie Farben als r, g, b an" -#: confscreen.cpp:446 +#: confscreen.cpp:454 msgid "" "The perspective factor will have no effect until you enable View -> Use " "Perspective Projection." @@ -82,25 +82,25 @@ msgstr "" "Der Perspektivfaktor wird sich nicht auswirken, bis Sie Ansicht -> " "Perspektive Projektion aktivieren." -#: confscreen.cpp:459 confscreen.cpp:469 +#: confscreen.cpp:467 confscreen.cpp:477 #, c-format msgid "Specify between 0 and %d digits after the decimal." msgstr "Geben Sie 0 bis %d Ziffern nach dem Dezimalzeichen an." -#: confscreen.cpp:481 +#: confscreen.cpp:489 msgid "Export scale must not be zero!" msgstr "Der Exportmaßstab darf nicht Null sein!" -#: confscreen.cpp:493 +#: confscreen.cpp:501 msgid "Cutter radius offset must not be negative!" msgstr "Der Werkzeugradialabstand darf nicht negativ sein!" -#: confscreen.cpp:547 +#: confscreen.cpp:555 msgid "Bad value: autosave interval should be positive" msgstr "" "Ungültiger Wert: Interval für automatisches Speichern muss positiv sein" -#: confscreen.cpp:550 +#: confscreen.cpp:558 msgid "Bad format: specify interval in integral minutes" msgstr "Ungültiges Format: geben Sie das Interval in ganzen Minuten an" @@ -279,7 +279,33 @@ msgctxt "constr-name" msgid "comment" msgstr "Kommentar" -#: constraint.cpp:171 +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" +"Die Bogentangente und das Liniensegment müssen einen gemeinsamen Endpunkt " +"haben. Schränken Sie mit \"Einschränkung / Auf Punkt\" ein, bevor Sie die " +"Tangente einschränken. -> Sc" + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"Die Kurventangente und das Liniensegment müssen einen gemeinsamen Endpunkt " +"haben. Schränken Sie mit \"Einschränkung / Auf Punkt\" ein, bevor Sie die " +"Tangente einschränken. -> Sc" + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" +"Die Kurven müssen einen gemeinsamen Endpunkt haben. Schränken Sie mit " +"\"Einschränkung / Auf Punkt\" ein, bevor Sie die Tangente einschränken. -> Sc" + +#: constraint.cpp:231 msgid "" "Bad selection for distance / diameter constraint. This constraint can apply " "to:\n" @@ -303,7 +329,7 @@ msgstr "" " * eine Seitenfläche und ein Punkt [minimaler Abstand]\n" " * ein Kreis oder ein Bogen [Durchmesser]\n" -#: constraint.cpp:224 +#: constraint.cpp:284 msgid "" "Bad selection for on point / curve / plane constraint. This constraint can " "apply to:\n" @@ -323,7 +349,7 @@ msgstr "" " * einen Punkt und einen Kreis oder Bogen [Punkt auf Kurve]\n" " * einen Punkt und eine Seitenfläche [Punkt auf Fläche]\n" -#: constraint.cpp:286 +#: constraint.cpp:346 msgid "" "Bad selection for equal length / radius constraint. This constraint can " "apply to:\n" @@ -354,7 +380,7 @@ msgstr "" " * ein Liniensegment und ein Bogen [Länge des Liniensegments gleich " "Bogenlänge]\n" -#: constraint.cpp:325 +#: constraint.cpp:385 msgid "" "Bad selection for length ratio constraint. This constraint can apply to:\n" "\n" @@ -365,7 +391,7 @@ msgstr "" "\n" " * zwei Liniensegmente\n" -#: constraint.cpp:342 +#: constraint.cpp:402 msgid "" "Bad selection for length difference constraint. This constraint can apply " "to:\n" @@ -377,7 +403,7 @@ msgstr "" "\n" " * zwei Liniensegmente\n" -#: constraint.cpp:368 +#: constraint.cpp:428 msgid "" "Bad selection for at midpoint constraint. This constraint can apply to:\n" "\n" @@ -391,7 +417,7 @@ msgstr "" " * ein Liniensegment und eine Arbeitsebene [Mittelpunkt der Linie auf " "Ebene]\n" -#: constraint.cpp:426 +#: constraint.cpp:486 msgid "" "Bad selection for symmetric constraint. This constraint can apply to:\n" "\n" @@ -412,7 +438,7 @@ msgstr "" " * eine Arbeitsebene und zwei Punkte oder ein Liniensegment [symmetrisch " "zu Arbeitsebene]\n" -#: constraint.cpp:440 +#: constraint.cpp:500 msgid "" "A workplane must be active when constraining symmetric without an explicit " "symmetry plane." @@ -420,7 +446,7 @@ msgstr "" "Eine Arbeitsebene muss aktiv sein, um die Symmetrie ohne explizite " "Symmetrieebene einzuschränken." -#: constraint.cpp:470 +#: constraint.cpp:530 msgid "" "Activate a workplane (with Sketch -> In Workplane) before applying a " "horizontal or vertical constraint." @@ -428,7 +454,7 @@ msgstr "" "Aktivieren Sie eine Arbeitsebene (mit Skizze -> In Arbeitsebene), bevor Sie " "horizontal oder vertikal einschränken." -#: constraint.cpp:483 +#: constraint.cpp:543 msgid "" "Bad selection for horizontal / vertical constraint. This constraint can " "apply to:\n" @@ -442,7 +468,7 @@ msgstr "" " * zwei Punkte\n" " * ein Liniensegment\n" -#: constraint.cpp:504 +#: constraint.cpp:564 msgid "" "Bad selection for same orientation constraint. This constraint can apply " "to:\n" @@ -454,15 +480,15 @@ msgstr "" "\n" " * zwei Normale\n" -#: constraint.cpp:554 +#: constraint.cpp:614 msgid "Must select an angle constraint." msgstr "Sie müssen einen eingeschränkten Winkel auswählen." -#: constraint.cpp:567 +#: constraint.cpp:627 msgid "Must select a constraint with associated label." msgstr "Sie müssen eine Einschränkung mit zugeordneter Kennzeichnung angeben." -#: constraint.cpp:578 +#: constraint.cpp:638 msgid "" "Bad selection for angle constraint. This constraint can apply to:\n" "\n" @@ -477,38 +503,12 @@ msgstr "" " * ein Liniensegment und eine Normale\n" " * zwei Normale\n" -#: constraint.cpp:635 -msgid "" -"The tangent arc and line segment must share an endpoint. Constrain them with " -"Constrain -> On Point before constraining tangent." -msgstr "" -"Die Bogentangente und das Liniensegment müssen einen gemeinsamen Endpunkt " -"haben. Schränken Sie mit \"Einschränkung / Auf Punkt\" ein, bevor Sie die " -"Tangente einschränken. -> Sc" - -#: constraint.cpp:659 -msgid "" -"The tangent cubic and line segment must share an endpoint. Constrain them " -"with Constrain -> On Point before constraining tangent." -msgstr "" -"Die Kurventangente und das Liniensegment müssen einen gemeinsamen Endpunkt " -"haben. Schränken Sie mit \"Einschränkung / Auf Punkt\" ein, bevor Sie die " -"Tangente einschränken. -> Sc" - -#: constraint.cpp:669 +#: constraint.cpp:701 msgid "Curve-curve tangency must apply in workplane." msgstr "" "Die Kurven-Kurven-Tangente muss in der Arbeitsebene eingeschränkt werden." -#: constraint.cpp:687 -msgid "" -"The curves must share an endpoint. Constrain them with Constrain -> On Point " -"before constraining tangent." -msgstr "" -"Die Kurven müssen einen gemeinsamen Endpunkt haben. Schränken Sie mit " -"\"Einschränkung / Auf Punkt\" ein, bevor Sie die Tangente einschränken. -> Sc" - -#: constraint.cpp:696 +#: constraint.cpp:711 msgid "" "Bad selection for parallel / tangent constraint. This constraint can apply " "to:\n" @@ -527,7 +527,7 @@ msgstr "" " * zwei Liniensegmente, Bögen oder Beziers mit gemeinsamem Endpunkt " "[Tangente]\n" -#: constraint.cpp:714 +#: constraint.cpp:729 msgid "" "Bad selection for perpendicular constraint. This constraint can apply to:\n" "\n" @@ -542,7 +542,7 @@ msgstr "" " * ein Liniensegment und eine Normale\n" " * zwei Normale\n" -#: constraint.cpp:729 +#: constraint.cpp:744 msgid "" "Bad selection for lock point where dragged constraint. This constraint can " "apply to:\n" @@ -554,7 +554,7 @@ msgstr "" "\n" " * einen Punkt\n" -#: constraint.cpp:740 +#: constraint.cpp:755 msgid "click center of comment text" msgstr "Klicken Sie auf die Mitte des Kommentartextes" @@ -660,7 +660,7 @@ msgctxt "button" msgid "&No" msgstr "&Nein" -#: file.cpp:869 solvespace.cpp:563 +#: file.cpp:869 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "&Abbrechen" @@ -826,300 +826,304 @@ msgid "Show Snap &Grid" msgstr "Arbeitsraster anzeigen" #: graphicswin.cpp:95 +msgid "Dim Solid for Sketch Groups" +msgstr "" + +#: graphicswin.cpp:96 msgid "Use &Perspective Projection" msgstr "Perspektivische Projektion" -#: graphicswin.cpp:96 +#: graphicswin.cpp:97 msgid "Dimension &Units" msgstr "Maßeinheit" -#: graphicswin.cpp:97 +#: graphicswin.cpp:98 msgid "Dimensions in &Millimeters" msgstr "Maße in Millimeter" -#: graphicswin.cpp:98 +#: graphicswin.cpp:99 msgid "Dimensions in M&eters" msgstr "Masse in M&etern" -#: graphicswin.cpp:99 +#: graphicswin.cpp:100 msgid "Dimensions in &Inches" msgstr "Maße in Zoll" -#: graphicswin.cpp:101 +#: graphicswin.cpp:102 msgid "Show &Toolbar" msgstr "Werkzeugleiste anzeigen" -#: graphicswin.cpp:102 +#: graphicswin.cpp:103 msgid "Show Property Bro&wser" msgstr "Attributbrowser anzeigen" -#: graphicswin.cpp:104 +#: graphicswin.cpp:105 msgid "&Full Screen" msgstr "Vollbildschirm" -#: graphicswin.cpp:106 +#: graphicswin.cpp:107 msgid "&New Group" msgstr "Neue Gruppe" -#: graphicswin.cpp:107 +#: graphicswin.cpp:108 msgid "Sketch In &3d" msgstr "In 3D skizzieren" -#: graphicswin.cpp:108 +#: graphicswin.cpp:109 msgid "Sketch In New &Workplane" msgstr "In neuer Arbeitsebene skizzieren" -#: graphicswin.cpp:110 +#: graphicswin.cpp:111 msgid "Step &Translating" msgstr "Kopieren und verschieben" -#: graphicswin.cpp:111 +#: graphicswin.cpp:112 msgid "Step &Rotating" msgstr "Kopieren und drehen" -#: graphicswin.cpp:113 +#: graphicswin.cpp:114 msgid "E&xtrude" msgstr "E&xtrudieren" -#: graphicswin.cpp:114 +#: graphicswin.cpp:115 msgid "&Helix" msgstr "&Helix" -#: graphicswin.cpp:115 +#: graphicswin.cpp:116 msgid "&Lathe" msgstr "R&otieren" -#: graphicswin.cpp:116 +#: graphicswin.cpp:117 msgid "Re&volve" msgstr "D&rehen" -#: graphicswin.cpp:118 +#: graphicswin.cpp:119 msgid "Link / Assemble..." msgstr "Verknüpfen / Zusammensetzen" -#: graphicswin.cpp:119 +#: graphicswin.cpp:120 msgid "Link Recent" msgstr "Letzte verknüpfen" -#: graphicswin.cpp:121 +#: graphicswin.cpp:122 msgid "&Sketch" msgstr "&Skizze" -#: graphicswin.cpp:122 +#: graphicswin.cpp:123 msgid "In &Workplane" msgstr "In Arbeitsebene" -#: graphicswin.cpp:123 +#: graphicswin.cpp:124 msgid "Anywhere In &3d" msgstr "Im 3D-Raum" -#: graphicswin.cpp:125 +#: graphicswin.cpp:126 msgid "Datum &Point" msgstr "Bezugspunkt" -#: graphicswin.cpp:126 +#: graphicswin.cpp:127 msgid "&Workplane" msgstr "Arbeits&ebene" -#: graphicswin.cpp:128 +#: graphicswin.cpp:129 msgid "Line &Segment" msgstr "&Linie" -#: graphicswin.cpp:129 +#: graphicswin.cpp:130 msgid "C&onstruction Line Segment" msgstr "K&onstruktionslinie" -#: graphicswin.cpp:130 +#: graphicswin.cpp:131 msgid "&Rectangle" msgstr "&Rechteck" -#: graphicswin.cpp:131 +#: graphicswin.cpp:132 msgid "&Circle" msgstr "&Kreis" -#: graphicswin.cpp:132 +#: graphicswin.cpp:133 msgid "&Arc of a Circle" msgstr "Kreisbogen" -#: graphicswin.cpp:133 +#: graphicswin.cpp:134 msgid "&Bezier Cubic Spline" msgstr "Kubischer &Bezier-Spline" -#: graphicswin.cpp:135 +#: graphicswin.cpp:136 msgid "&Text in TrueType Font" msgstr "&Text in Truetype-Font" -#: graphicswin.cpp:136 +#: graphicswin.cpp:137 msgid "&Image" msgstr "B&ild" -#: graphicswin.cpp:138 +#: graphicswin.cpp:139 msgid "To&ggle Construction" msgstr "Konstruktionselement an/aus" -#: graphicswin.cpp:139 +#: graphicswin.cpp:140 msgid "Tangent &Arc at Point" msgstr "Bogentangente an Punkt" -#: graphicswin.cpp:140 +#: graphicswin.cpp:141 msgid "Split Curves at &Intersection" msgstr "Kurven im Schnittpunkt trennen" -#: graphicswin.cpp:142 +#: graphicswin.cpp:143 msgid "&Constrain" msgstr "&Einschränkung" -#: graphicswin.cpp:143 +#: graphicswin.cpp:144 msgid "&Distance / Diameter" msgstr "Abstand / Durchmesser" -#: graphicswin.cpp:144 +#: graphicswin.cpp:145 msgid "Re&ference Dimension" msgstr "Referenzangabe" -#: graphicswin.cpp:145 +#: graphicswin.cpp:146 msgid "A&ngle" msgstr "Winkel" -#: graphicswin.cpp:146 +#: graphicswin.cpp:147 msgid "Reference An&gle" msgstr "Referenzwinkel" -#: graphicswin.cpp:147 +#: graphicswin.cpp:148 msgid "Other S&upplementary Angle" msgstr "Komplementärwinkel" -#: graphicswin.cpp:148 +#: graphicswin.cpp:149 msgid "Toggle R&eference Dim" msgstr "Referenzangabe ein/aus" -#: graphicswin.cpp:150 +#: graphicswin.cpp:151 msgid "&Horizontal" msgstr "Horizontal" -#: graphicswin.cpp:151 +#: graphicswin.cpp:152 msgid "&Vertical" msgstr "&Vertikal" -#: graphicswin.cpp:153 +#: graphicswin.cpp:154 msgid "&On Point / Curve / Plane" msgstr "Auf Punkt / Kurve / Ebene" -#: graphicswin.cpp:154 +#: graphicswin.cpp:155 msgid "E&qual Length / Radius / Angle" msgstr "Gleicher Abstand / Radius / Winkel" -#: graphicswin.cpp:155 +#: graphicswin.cpp:156 msgid "Length Ra&tio" msgstr "Längenverhältnis" -#: graphicswin.cpp:156 +#: graphicswin.cpp:157 msgid "Length Diff&erence" msgstr "Längendifferenz" -#: graphicswin.cpp:157 +#: graphicswin.cpp:158 msgid "At &Midpoint" msgstr "Auf &Mittelpunkt" -#: graphicswin.cpp:158 +#: graphicswin.cpp:159 msgid "S&ymmetric" msgstr "Symmetrisch" -#: graphicswin.cpp:159 +#: graphicswin.cpp:160 msgid "Para&llel / Tangent" msgstr "Paral&llel / Tangente" -#: graphicswin.cpp:160 +#: graphicswin.cpp:161 msgid "&Perpendicular" msgstr "Rechtwinklig" -#: graphicswin.cpp:161 +#: graphicswin.cpp:162 msgid "Same Orient&ation" msgstr "Gleiche Orientierung" -#: graphicswin.cpp:162 +#: graphicswin.cpp:163 msgid "Lock Point Where &Dragged" msgstr "Punkt an Position fixieren" -#: graphicswin.cpp:164 +#: graphicswin.cpp:165 msgid "Comment" msgstr "Kommentar" -#: graphicswin.cpp:166 +#: graphicswin.cpp:167 msgid "&Analyze" msgstr "&Analyse" -#: graphicswin.cpp:167 +#: graphicswin.cpp:168 msgid "Measure &Volume" msgstr "&Volumen bestimmen" -#: graphicswin.cpp:168 +#: graphicswin.cpp:169 msgid "Measure A&rea" msgstr "Fläche bestimmen" -#: graphicswin.cpp:169 +#: graphicswin.cpp:170 msgid "Measure &Perimeter" msgstr "Umfang bestimmen" -#: graphicswin.cpp:170 +#: graphicswin.cpp:171 msgid "Show &Interfering Parts" msgstr "Überlagernde Teile anzeigen" -#: graphicswin.cpp:171 +#: graphicswin.cpp:172 msgid "Show &Naked Edges" msgstr "Freiliegende Kanten anzeigen" -#: graphicswin.cpp:172 +#: graphicswin.cpp:173 msgid "Show &Center of Mass" msgstr "Massenmittelpunkt anzeigen" -#: graphicswin.cpp:174 +#: graphicswin.cpp:175 msgid "Show &Underconstrained Points" msgstr "&Unterbeschränkte Punkte anzeigen" -#: graphicswin.cpp:176 +#: graphicswin.cpp:177 msgid "&Trace Point" msgstr "Punkt nachzeichnen" -#: graphicswin.cpp:177 +#: graphicswin.cpp:178 msgid "&Stop Tracing..." msgstr "Nachzeichnen beenden" -#: graphicswin.cpp:178 +#: graphicswin.cpp:179 msgid "Step &Dimension..." msgstr "Schrittgröße…" -#: graphicswin.cpp:180 +#: graphicswin.cpp:181 msgid "&Help" msgstr "&Hilfe" -#: graphicswin.cpp:181 +#: graphicswin.cpp:182 msgid "&Language" msgstr "Sprache" -#: graphicswin.cpp:182 +#: graphicswin.cpp:183 msgid "&Website / Manual" msgstr "&Website / Anleitung" -#: graphicswin.cpp:184 +#: graphicswin.cpp:185 msgid "&About" msgstr "Über" -#: graphicswin.cpp:352 +#: graphicswin.cpp:355 msgid "(no recent files)" msgstr "(keine vorhergehenden Dateien)" -#: graphicswin.cpp:360 +#: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." msgstr "" -#: graphicswin.cpp:721 +#: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." msgstr "" "Das Raster wird nicht angezeigt, weil keine Arbeitsebene ausgewählt ist." -#: graphicswin.cpp:730 +#: graphicswin.cpp:740 msgid "" "The perspective factor is set to zero, so the view will always be a parallel " "projection.\n" @@ -1133,20 +1137,20 @@ msgstr "" "Ändern Sie den Faktor für die Perspektivprojektion in der " "Konfigurationsmaske. Ein typischer Wert ist ca. 0,3." -#: graphicswin.cpp:809 +#: graphicswin.cpp:819 msgid "" "Select a point; this point will become the center of the view on screen." msgstr "" "Wählen Sie einen Punkt aus; dieser Punkt wird im Mittelpunkt der " "Bildschirmansicht sein." -#: graphicswin.cpp:1103 +#: graphicswin.cpp:1114 msgid "No additional entities share endpoints with the selected entities." msgstr "" "Die ausgewählten Objekte teilen keine gemeinsamen Endpunkte mit anderen " "Objekten." -#: graphicswin.cpp:1121 +#: graphicswin.cpp:1132 msgid "" "To use this command, select a point or other entity from an linked part, or " "make a link group the active group." @@ -1154,7 +1158,7 @@ msgstr "" "Für diesen Befehl wählen Sie einen Punkt oder ein anderes Objekt von einem " "verknüpften Teil aus, oder aktivieren Sie eine verknüpfte Gruppe." -#: graphicswin.cpp:1144 +#: graphicswin.cpp:1155 msgid "" "No workplane is active. Activate a workplane (with Sketch -> In Workplane) " "to define the plane for the snap grid." @@ -1163,7 +1167,7 @@ msgstr "" "(mit Skizze -> In Arbeitsebene), um die Ebene für das Gitterraster zu " "definieren." -#: graphicswin.cpp:1151 +#: graphicswin.cpp:1162 msgid "" "Can't snap these items to grid; select points, text comments, or constraints " "with a label. To snap a line, select its endpoints." @@ -1172,13 +1176,13 @@ msgstr "" "für Punkte, Textkommentare, oder Einschränkungen mit einer Bezeichnung. Um " "eine Linie auf das Raster auszurichten, wählen Sie deren Endpunkte aus." -#: graphicswin.cpp:1239 +#: graphicswin.cpp:1247 msgid "No workplane selected. Activating default workplane for this group." msgstr "" "Es wurde keine Arbeitsebene ausgewählt. Die Standard-Arbeitsebene für diese " "Gruppe wird aktiviert." -#: graphicswin.cpp:1242 +#: graphicswin.cpp:1250 msgid "" "No workplane is selected, and the active group does not have a default " "workplane. Try selecting a workplane, or activating a sketch-in-new-" @@ -1188,7 +1192,7 @@ msgstr "" "standardmäßige Arbeitsebene. Wählen Sie eine Arbeitsebene aus, oder " "erstellen Sie eine Gruppe in einer neuen Arbeitsebene." -#: graphicswin.cpp:1263 +#: graphicswin.cpp:1271 msgid "" "Bad selection for tangent arc at point. Select a single point, or select " "nothing to set up arc parameters." @@ -1196,48 +1200,48 @@ msgstr "" "Ungültige Auswahl für Bogentangente an Punkt. Wählen Sie einen einzelnen " "Punkt. Um die Bogenparameter anzugeben, wählen Sie nichts aus." -#: graphicswin.cpp:1274 +#: graphicswin.cpp:1282 msgid "click point on arc (draws anti-clockwise)" msgstr "" "Erstellen Sie einen Punkt auf dem Bogen (zeichnet im Gegenuhrzeigersinn)" -#: graphicswin.cpp:1275 +#: graphicswin.cpp:1283 msgid "click to place datum point" msgstr "Klicken Sie, um einen Bezugspunkt zu platzieren" -#: graphicswin.cpp:1276 +#: graphicswin.cpp:1284 msgid "click first point of line segment" msgstr "Klicken Sie auf den ersten Punkt des Liniensegments" -#: graphicswin.cpp:1278 +#: graphicswin.cpp:1286 msgid "click first point of construction line segment" msgstr "Klicken Sie auf den ersten Punkt der Konstruktionslinie" -#: graphicswin.cpp:1279 +#: graphicswin.cpp:1287 msgid "click first point of cubic segment" msgstr "Klicken Sie auf den ersten Punkt der kubischen Linie" -#: graphicswin.cpp:1280 +#: graphicswin.cpp:1288 msgid "click center of circle" msgstr "Klicken Sie auf den Kreismittelpunkt" -#: graphicswin.cpp:1281 +#: graphicswin.cpp:1289 msgid "click origin of workplane" msgstr "Klicken Sie auf den Ursprungspunkt der Arbeitsebene" -#: graphicswin.cpp:1282 +#: graphicswin.cpp:1290 msgid "click one corner of rectangle" msgstr "Klicken Sie auf eine Ecke des Rechtecks" -#: graphicswin.cpp:1283 +#: graphicswin.cpp:1291 msgid "click top left of text" msgstr "Klicken Sie auf die obere linke Ecke des Texts" -#: graphicswin.cpp:1289 +#: graphicswin.cpp:1297 msgid "click top left of image" msgstr "Klicken Sie auf die obere linke Ecke des Bilds" -#: graphicswin.cpp:1301 +#: graphicswin.cpp:1309 msgid "" "No entities are selected. Select entities before trying to toggle their " "construction state." @@ -1376,19 +1380,19 @@ msgstr "Versetzen" msgid "(unnamed)" msgstr "unbenannt" -#: groupmesh.cpp:708 +#: groupmesh.cpp:709 msgid "not closed contour, or not all same style!" msgstr "Kontur nicht geschlossen, oder kein einheitlicher Linientyp!" -#: groupmesh.cpp:721 +#: groupmesh.cpp:722 msgid "points not all coplanar!" msgstr "Punkte sind nicht alle koplanar!" -#: groupmesh.cpp:723 +#: groupmesh.cpp:724 msgid "contour is self-intersecting!" msgstr "Kontur überschneidet sich selbst!" -#: groupmesh.cpp:725 +#: groupmesh.cpp:726 msgid "zero-length edge!" msgstr "Kante mit Länge Null!" @@ -1530,11 +1534,11 @@ msgstr "Aktive deselektieren" msgid "Zoom to Fit" msgstr "Zoom an Bildschirm anpassen" -#: mouse.cpp:990 mouse.cpp:1277 +#: mouse.cpp:989 mouse.cpp:1276 msgid "click next point of line, or press Esc" msgstr "Klicken Sie auf den nächsten Punkt der Linie, oder drücken Sie Esc" -#: mouse.cpp:996 +#: mouse.cpp:995 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1542,15 +1546,15 @@ msgstr "" "Ein Rechteck kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " "Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." -#: mouse.cpp:1030 +#: mouse.cpp:1029 msgid "click to place other corner of rectangle" msgstr "Klicken Sie auf die gegenüberliegende Ecke des Rechtecks" -#: mouse.cpp:1050 +#: mouse.cpp:1049 msgid "click to set radius" msgstr "Klicken Sie, um den Radius festzulegen" -#: mouse.cpp:1055 +#: mouse.cpp:1054 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1558,23 +1562,23 @@ msgstr "" "Ein Kreisbogen kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " "Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." -#: mouse.cpp:1074 +#: mouse.cpp:1073 msgid "click to place point" msgstr "Klicken Sie, um einen Punkt zu platzieren" -#: mouse.cpp:1090 +#: mouse.cpp:1089 msgid "click next point of cubic, or press Esc" msgstr "" "Klicken Sie auf den nächsten Punkt der kubischen Linie, oder drücken Sie Esc" -#: mouse.cpp:1095 +#: mouse.cpp:1094 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" "Eine Arbeitsebene ist bereits aktiv. Skizzieren Sie in 3D, bevor Sie eine " "neue Arbeitsebene erstellen." -#: mouse.cpp:1111 +#: mouse.cpp:1110 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1582,11 +1586,11 @@ msgstr "" "Text kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " "Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." -#: mouse.cpp:1128 +#: mouse.cpp:1127 msgid "click to place bottom right of text" msgstr "Klicken Sie auf die untere rechte Ecke des Texts" -#: mouse.cpp:1134 +#: mouse.cpp:1133 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1594,11 +1598,11 @@ msgstr "" "Das Bild kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " "Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." -#: mouse.cpp:1161 +#: mouse.cpp:1160 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEUER KOMMENTAR -- DOPPELKLICKEN ZUM BEARBEITEN" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace-Modelle" @@ -1683,33 +1687,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "Werte durch Komma getrennt (CSV)" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 msgid "untitled" msgstr "unbenannt" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1562 +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "Datei speichern" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1564 +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "Datei öffnen" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1368 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 msgctxt "button" msgid "_Cancel" msgstr "_Abbrechen" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 msgctxt "button" msgid "_Save" msgstr "_Speichern" -#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 msgctxt "button" msgid "_Open" msgstr "_Öffnen" @@ -1739,49 +1743,49 @@ msgctxt "button" msgid "Do&n't Load" msgstr "&Nicht laden" -#: solvespace.cpp:551 +#: solvespace.cpp:557 msgctxt "title" msgid "Modified File" msgstr "Geänderte Datei" -#: solvespace.cpp:553 +#: solvespace.cpp:559 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "Wollen Sie die Änderungen an der Skizze “%s” sichern?" -#: solvespace.cpp:556 +#: solvespace.cpp:562 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "Wollen Sie die Änderungen an der Skizze sichern?" -#: solvespace.cpp:559 +#: solvespace.cpp:565 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "Ihre Änderungen werden verworfen, wenn sie nicht abgespeichert werden." -#: solvespace.cpp:560 +#: solvespace.cpp:566 msgctxt "button" msgid "&Save" msgstr "&Sichern" -#: solvespace.cpp:562 +#: solvespace.cpp:568 msgctxt "button" msgid "Do&n't Save" msgstr "&Verwerfen" # solvespace.cpp:557 -#: solvespace.cpp:583 +#: solvespace.cpp:589 msgctxt "title" msgid "(new sketch)" msgstr "(Neue Skizze)" -#: solvespace.cpp:590 +#: solvespace.cpp:596 msgctxt "title" msgid "Property Browser" msgstr "Attribut-Browser" -#: solvespace.cpp:650 +#: solvespace.cpp:658 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " @@ -1791,7 +1795,7 @@ msgstr "" "wahrscheinlich nicht. Verstecken Sie sie in dem auf den Link oben im " "Textfenster klicken." -#: solvespace.cpp:718 +#: solvespace.cpp:730 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." @@ -1800,23 +1804,23 @@ msgstr "" "Kann den Dateityp der Datei '%s' nicht auf Grund der Dateierweiterung " "erkennen. Versuchen Sie .dxf oder .dwg." -#: solvespace.cpp:766 +#: solvespace.cpp:778 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" "Die Einschränkung muss einen Namen haben, und darf keine " "Referenzdimensionierung sein." -#: solvespace.cpp:770 +#: solvespace.cpp:782 msgid "Bad selection for step dimension; select a constraint." msgstr "" "Falsche Auswahl für die Schrittdimensionierung. Wählen Sie eine " "Einschränkung." -#: solvespace.cpp:794 +#: solvespace.cpp:806 msgid "The assembly does not interfere, good." msgstr "Der Zusammenbau funktioniert, gut." -#: solvespace.cpp:810 +#: solvespace.cpp:822 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1827,7 +1831,7 @@ msgstr "" "\n" " %s" -#: solvespace.cpp:819 +#: solvespace.cpp:831 #, c-format msgid "" "\n" @@ -1840,7 +1844,7 @@ msgstr "" "\n" " %s" -#: solvespace.cpp:824 +#: solvespace.cpp:836 msgid "" "\n" "\n" @@ -1852,7 +1856,7 @@ msgstr "" "Gekrümmte Flächen wurden als Dreiecksnetz angenähert.\n" "Das verursacht Fehler, typischerweise um 1%." -#: solvespace.cpp:839 +#: solvespace.cpp:851 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1869,7 +1873,7 @@ msgstr "" "Kurven wurden als gerade Linienstücke angenähert.\n" "Das verursacht Fehler, typischerweise um 1%%." -#: solvespace.cpp:848 +#: solvespace.cpp:860 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." @@ -1877,7 +1881,7 @@ msgstr "" "Diese Gruppe beinhaltet keine korrekt geschlossene 2D Fläche. Sie ist offen, " "nicht koplanar, oder überschneidet sich selbst." -#: solvespace.cpp:860 +#: solvespace.cpp:872 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1894,7 +1898,7 @@ msgstr "" "Kurven wurden als gerade Linienstücke angenähert.\n" "Das verursacht Fehler, typischerweise um 1%%." -#: solvespace.cpp:880 +#: solvespace.cpp:892 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1911,36 +1915,36 @@ msgstr "" "Kurven wurden als gerade Linienstücke angenähert.\n" "Das verursacht Fehler, typischerweise um 1%%." -#: solvespace.cpp:886 +#: solvespace.cpp:898 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "Falsche Auswahl für Umfang. Wähle Liniensegmente, Bögen und Kurven." -#: solvespace.cpp:902 +#: solvespace.cpp:914 msgid "Bad selection for trace; select a single point." msgstr "Falsche Auswahl für Punkt nachzeichnen. Wähle einen einzelnen Punkt." -#: solvespace.cpp:925 +#: solvespace.cpp:941 #, c-format msgid "Couldn't write to '%s'" msgstr "Konnte '%s' nicht schreiben" -#: solvespace.cpp:955 +#: solvespace.cpp:971 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "Das Netz schneidet sich selbst: Falsch, ungültig." -#: solvespace.cpp:956 +#: solvespace.cpp:972 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "Das Netz schneidet sich nicht: Gut, gültig." -#: solvespace.cpp:958 +#: solvespace.cpp:974 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "Das Netz hat lose Kanten: Falsch, ungültig." -#: solvespace.cpp:959 +#: solvespace.cpp:975 msgid "The mesh is watertight (okay, valid)." msgstr "Das Netz hat keine lose Kanten: Gut, gültig." -#: solvespace.cpp:962 +#: solvespace.cpp:978 #, c-format msgid "" "\n" @@ -1951,7 +1955,7 @@ msgstr "" "\n" "Das Modell hat %d Dreiecke, von %d Flächen." -#: solvespace.cpp:966 +#: solvespace.cpp:982 #, c-format msgid "" "%s\n" @@ -1966,7 +1970,7 @@ msgstr "" "\n" "Keine problematischen Kanten, gut.%s" -#: solvespace.cpp:969 +#: solvespace.cpp:985 #, c-format msgid "" "%s\n" @@ -1981,7 +1985,7 @@ msgstr "" "\n" "%d problematische Kanten, schlecht.%s" -#: solvespace.cpp:982 +#: solvespace.cpp:998 #, c-format msgid "" "This is SolveSpace version %s.\n" @@ -2145,31 +2149,39 @@ msgid "New group rotating active sketch" msgstr "Neue Gruppe mit rotierter aktiver Skizze" #: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 msgid "New group step and repeat rotating" msgstr "Neue Gruppe mit kopierter gedrehter Skizze" -#: toolbar.cpp:74 +#: toolbar.cpp:78 msgid "New group step and repeat translating" msgstr "Neue Gruppe mit kopierter versetzter Skizze" -#: toolbar.cpp:76 +#: toolbar.cpp:80 msgid "New group in new workplane (thru given entities)" msgstr "" "Neue Gruppe in neuer Arbeitsebene (definiert durch ausgewählte Objekte)" -#: toolbar.cpp:78 +#: toolbar.cpp:82 msgid "New group in 3d" msgstr "Neue Gruppe in 3D" -#: toolbar.cpp:80 +#: toolbar.cpp:84 msgid "New group linking / assembling file" msgstr "Neue Gruppe mit verknüpfter Datei" -#: toolbar.cpp:84 +#: toolbar.cpp:88 msgid "Nearest isometric view" msgstr "Nächste isometrische Ansicht" -#: toolbar.cpp:86 +#: toolbar.cpp:90 msgid "Align view to active workplane" msgstr "Ansicht auf Arbeitsebene ausrichten" diff --git a/res/locales/en_US.po b/res/locales/en_US.po index 01c4b432..9772d574 100644 --- a/res/locales/en_US.po +++ b/res/locales/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-23 07:36+0100\n" +"POT-Creation-Date: 2021-01-15 14:51-0600\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: clipboard.cpp:274 +#: clipboard.cpp:310 msgid "" "Cut, paste, and copy work only in a workplane.\n" "\n" @@ -27,27 +27,27 @@ msgstr "" "\n" "Activate one with Sketch -> In Workplane." -#: clipboard.cpp:291 +#: clipboard.cpp:327 msgid "Clipboard is empty; nothing to paste." msgstr "Clipboard is empty; nothing to paste." -#: clipboard.cpp:338 +#: clipboard.cpp:374 msgid "Number of copies to paste must be at least one." msgstr "Number of copies to paste must be at least one." -#: clipboard.cpp:354 textscreens.cpp:783 +#: clipboard.cpp:390 textscreens.cpp:783 msgid "Scale cannot be zero." msgstr "Scale cannot be zero." -#: clipboard.cpp:396 +#: clipboard.cpp:432 msgid "Select one point to define origin of rotation." msgstr "Select one point to define origin of rotation." -#: clipboard.cpp:408 +#: clipboard.cpp:444 msgid "Select two points to define translation vector." msgstr "Select two points to define translation vector." -#: clipboard.cpp:418 +#: clipboard.cpp:454 msgid "" "Transformation is identity. So all copies will be exactly on top of each " "other." @@ -55,23 +55,23 @@ msgstr "" "Transformation is identity. So all copies will be exactly on top of each " "other." -#: clipboard.cpp:422 +#: clipboard.cpp:458 msgid "Too many items to paste; split this into smaller pastes." msgstr "Too many items to paste; split this into smaller pastes." -#: clipboard.cpp:427 +#: clipboard.cpp:463 msgid "No workplane active." msgstr "No workplane active." -#: confscreen.cpp:410 +#: confscreen.cpp:418 msgid "Bad format: specify coordinates as x, y, z" msgstr "Bad format: specify coordinates as x, y, z" -#: confscreen.cpp:420 style.cpp:659 textscreens.cpp:805 +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 msgid "Bad format: specify color as r, g, b" msgstr "Bad format: specify color as r, g, b" -#: confscreen.cpp:446 +#: confscreen.cpp:454 msgid "" "The perspective factor will have no effect until you enable View -> Use " "Perspective Projection." @@ -79,24 +79,24 @@ msgstr "" "The perspective factor will have no effect until you enable View -> Use " "Perspective Projection." -#: confscreen.cpp:459 confscreen.cpp:469 +#: confscreen.cpp:467 confscreen.cpp:477 #, c-format msgid "Specify between 0 and %d digits after the decimal." msgstr "Specify between 0 and %d digits after the decimal." -#: confscreen.cpp:481 +#: confscreen.cpp:489 msgid "Export scale must not be zero!" msgstr "Export scale must not be zero!" -#: confscreen.cpp:493 +#: confscreen.cpp:501 msgid "Cutter radius offset must not be negative!" msgstr "Cutter radius offset must not be negative!" -#: confscreen.cpp:547 +#: confscreen.cpp:555 msgid "Bad value: autosave interval should be positive" msgstr "Bad value: autosave interval should be positive" -#: confscreen.cpp:550 +#: confscreen.cpp:558 msgid "Bad format: specify interval in integral minutes" msgstr "Bad format: specify interval in integral minutes" @@ -275,7 +275,31 @@ msgctxt "constr-name" msgid "comment" msgstr "comment" -#: constraint.cpp:171 +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." + +#: constraint.cpp:231 msgid "" "Bad selection for distance / diameter constraint. This constraint can apply " "to:\n" @@ -299,7 +323,7 @@ msgstr "" " * a plane face and a point (minimum distance)\n" " * a circle or an arc (diameter)\n" -#: constraint.cpp:224 +#: constraint.cpp:284 msgid "" "Bad selection for on point / curve / plane constraint. This constraint can " "apply to:\n" @@ -319,7 +343,7 @@ msgstr "" " * a point and a circle or arc (point on curve)\n" " * a point and a plane face (point on face)\n" -#: constraint.cpp:286 +#: constraint.cpp:346 msgid "" "Bad selection for equal length / radius constraint. This constraint can " "apply to:\n" @@ -347,7 +371,7 @@ msgstr "" " * two circles or arcs (equal radius)\n" " * a line segment and an arc (line segment length equals arc length)\n" -#: constraint.cpp:325 +#: constraint.cpp:385 msgid "" "Bad selection for length ratio constraint. This constraint can apply to:\n" "\n" @@ -357,7 +381,7 @@ msgstr "" "\n" " * two line segments\n" -#: constraint.cpp:342 +#: constraint.cpp:402 msgid "" "Bad selection for length difference constraint. This constraint can apply " "to:\n" @@ -369,7 +393,7 @@ msgstr "" "\n" " * two line segments\n" -#: constraint.cpp:368 +#: constraint.cpp:428 msgid "" "Bad selection for at midpoint constraint. This constraint can apply to:\n" "\n" @@ -381,7 +405,7 @@ msgstr "" " * a line segment and a point (point at midpoint)\n" " * a line segment and a workplane (line's midpoint on plane)\n" -#: constraint.cpp:426 +#: constraint.cpp:486 msgid "" "Bad selection for symmetric constraint. This constraint can apply to:\n" "\n" @@ -401,7 +425,7 @@ msgstr "" " * workplane, and two points or a line segment (symmetric about " "workplane)\n" -#: constraint.cpp:440 +#: constraint.cpp:500 msgid "" "A workplane must be active when constraining symmetric without an explicit " "symmetry plane." @@ -409,7 +433,7 @@ msgstr "" "A workplane must be active when constraining symmetric without an explicit " "symmetry plane." -#: constraint.cpp:470 +#: constraint.cpp:530 msgid "" "Activate a workplane (with Sketch -> In Workplane) before applying a " "horizontal or vertical constraint." @@ -417,7 +441,7 @@ msgstr "" "Activate a workplane (with Sketch -> In Workplane) before applying a " "horizontal or vertical constraint." -#: constraint.cpp:483 +#: constraint.cpp:543 msgid "" "Bad selection for horizontal / vertical constraint. This constraint can " "apply to:\n" @@ -431,7 +455,7 @@ msgstr "" " * two points\n" " * a line segment\n" -#: constraint.cpp:504 +#: constraint.cpp:564 msgid "" "Bad selection for same orientation constraint. This constraint can apply " "to:\n" @@ -443,15 +467,15 @@ msgstr "" "\n" " * two normals\n" -#: constraint.cpp:554 +#: constraint.cpp:614 msgid "Must select an angle constraint." msgstr "Must select an angle constraint." -#: constraint.cpp:567 +#: constraint.cpp:627 msgid "Must select a constraint with associated label." msgstr "Must select a constraint with associated label." -#: constraint.cpp:578 +#: constraint.cpp:638 msgid "" "Bad selection for angle constraint. This constraint can apply to:\n" "\n" @@ -465,35 +489,11 @@ msgstr "" " * a line segment and a normal\n" " * two normals\n" -#: constraint.cpp:635 -msgid "" -"The tangent arc and line segment must share an endpoint. Constrain them with " -"Constrain -> On Point before constraining tangent." -msgstr "" -"The tangent arc and line segment must share an endpoint. Constrain them with " -"Constrain -> On Point before constraining tangent." - -#: constraint.cpp:659 -msgid "" -"The tangent cubic and line segment must share an endpoint. Constrain them " -"with Constrain -> On Point before constraining tangent." -msgstr "" -"The tangent cubic and line segment must share an endpoint. Constrain them " -"with Constrain -> On Point before constraining tangent." - -#: constraint.cpp:669 +#: constraint.cpp:701 msgid "Curve-curve tangency must apply in workplane." msgstr "Curve-curve tangency must apply in workplane." -#: constraint.cpp:687 -msgid "" -"The curves must share an endpoint. Constrain them with Constrain -> On Point " -"before constraining tangent." -msgstr "" -"The curves must share an endpoint. Constrain them with Constrain -> On Point " -"before constraining tangent." - -#: constraint.cpp:696 +#: constraint.cpp:711 msgid "" "Bad selection for parallel / tangent constraint. This constraint can apply " "to:\n" @@ -511,22 +511,22 @@ msgstr "" " * two normals (parallel)\n" " * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" -#: constraint.cpp:714 -msgid "" -"Bad selection for perpendicular constraint. This constraint can apply to:\n" -"\n" -" * two line segments\n" -" * a line segment and a normal\n" -" * two normals\n" -msgstr "" -"Bad selection for perpendicular constraint. This constraint can apply to:\n" -"\n" -" * two line segments\n" -" * a line segment and a normal\n" -" * two normals\n" - #: constraint.cpp:729 msgid "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" +msgstr "" +"Bad selection for perpendicular constraint. This constraint can apply to:\n" +"\n" +" * two line segments\n" +" * a line segment and a normal\n" +" * two normals\n" + +#: constraint.cpp:744 +msgid "" "Bad selection for lock point where dragged constraint. This constraint can " "apply to:\n" "\n" @@ -537,7 +537,7 @@ msgstr "" "\n" " * a point\n" -#: constraint.cpp:740 +#: constraint.cpp:755 msgid "click center of comment text" msgstr "click center of comment text" @@ -641,7 +641,7 @@ msgctxt "button" msgid "&No" msgstr "&No" -#: file.cpp:869 solvespace.cpp:563 +#: file.cpp:869 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "&Cancel" @@ -807,299 +807,303 @@ msgid "Show Snap &Grid" msgstr "Show Snap &Grid" #: graphicswin.cpp:95 +msgid "Dim Solid for Sketch Groups" +msgstr "Dim Solid for Sketch Groups" + +#: graphicswin.cpp:96 msgid "Use &Perspective Projection" msgstr "Use &Perspective Projection" -#: graphicswin.cpp:96 +#: graphicswin.cpp:97 msgid "Dimension &Units" msgstr "Dimension &Units" -#: graphicswin.cpp:97 +#: graphicswin.cpp:98 msgid "Dimensions in &Millimeters" msgstr "Dimensions in &Millimeters" -#: graphicswin.cpp:98 +#: graphicswin.cpp:99 msgid "Dimensions in M&eters" msgstr "Dimensions in M&eters" -#: graphicswin.cpp:99 +#: graphicswin.cpp:100 msgid "Dimensions in &Inches" msgstr "Dimensions in &Inches" -#: graphicswin.cpp:101 +#: graphicswin.cpp:102 msgid "Show &Toolbar" msgstr "Show &Toolbar" -#: graphicswin.cpp:102 +#: graphicswin.cpp:103 msgid "Show Property Bro&wser" msgstr "Show Property Bro&wser" -#: graphicswin.cpp:104 +#: graphicswin.cpp:105 msgid "&Full Screen" msgstr "&Full Screen" -#: graphicswin.cpp:106 +#: graphicswin.cpp:107 msgid "&New Group" msgstr "&New Group" -#: graphicswin.cpp:107 +#: graphicswin.cpp:108 msgid "Sketch In &3d" msgstr "Sketch In &3d" -#: graphicswin.cpp:108 +#: graphicswin.cpp:109 msgid "Sketch In New &Workplane" msgstr "Sketch In New &Workplane" -#: graphicswin.cpp:110 +#: graphicswin.cpp:111 msgid "Step &Translating" msgstr "Step &Translating" -#: graphicswin.cpp:111 +#: graphicswin.cpp:112 msgid "Step &Rotating" msgstr "Step &Rotating" -#: graphicswin.cpp:113 +#: graphicswin.cpp:114 msgid "E&xtrude" msgstr "E&xtrude" -#: graphicswin.cpp:114 +#: graphicswin.cpp:115 msgid "&Helix" msgstr "&Helix" -#: graphicswin.cpp:115 +#: graphicswin.cpp:116 msgid "&Lathe" msgstr "&Lathe" -#: graphicswin.cpp:116 +#: graphicswin.cpp:117 msgid "Re&volve" msgstr "Re&volve" -#: graphicswin.cpp:118 +#: graphicswin.cpp:119 msgid "Link / Assemble..." msgstr "Link / Assemble..." -#: graphicswin.cpp:119 +#: graphicswin.cpp:120 msgid "Link Recent" msgstr "Link Recent" -#: graphicswin.cpp:121 +#: graphicswin.cpp:122 msgid "&Sketch" msgstr "&Sketch" -#: graphicswin.cpp:122 +#: graphicswin.cpp:123 msgid "In &Workplane" msgstr "In &Workplane" -#: graphicswin.cpp:123 +#: graphicswin.cpp:124 msgid "Anywhere In &3d" msgstr "Anywhere In &3d" -#: graphicswin.cpp:125 +#: graphicswin.cpp:126 msgid "Datum &Point" msgstr "Datum &Point" -#: graphicswin.cpp:126 +#: graphicswin.cpp:127 msgid "&Workplane" msgstr "&Workplane" -#: graphicswin.cpp:128 +#: graphicswin.cpp:129 msgid "Line &Segment" msgstr "Line &Segment" -#: graphicswin.cpp:129 +#: graphicswin.cpp:130 msgid "C&onstruction Line Segment" msgstr "C&onstruction Line Segment" -#: graphicswin.cpp:130 +#: graphicswin.cpp:131 msgid "&Rectangle" msgstr "&Rectangle" -#: graphicswin.cpp:131 +#: graphicswin.cpp:132 msgid "&Circle" msgstr "&Circle" -#: graphicswin.cpp:132 +#: graphicswin.cpp:133 msgid "&Arc of a Circle" msgstr "&Arc of a Circle" -#: graphicswin.cpp:133 +#: graphicswin.cpp:134 msgid "&Bezier Cubic Spline" msgstr "&Bezier Cubic Spline" -#: graphicswin.cpp:135 +#: graphicswin.cpp:136 msgid "&Text in TrueType Font" msgstr "&Text in TrueType Font" -#: graphicswin.cpp:136 +#: graphicswin.cpp:137 msgid "&Image" msgstr "&Image" -#: graphicswin.cpp:138 +#: graphicswin.cpp:139 msgid "To&ggle Construction" msgstr "To&ggle Construction" -#: graphicswin.cpp:139 +#: graphicswin.cpp:140 msgid "Tangent &Arc at Point" msgstr "Tangent &Arc at Point" -#: graphicswin.cpp:140 +#: graphicswin.cpp:141 msgid "Split Curves at &Intersection" msgstr "Split Curves at &Intersection" -#: graphicswin.cpp:142 +#: graphicswin.cpp:143 msgid "&Constrain" msgstr "&Constrain" -#: graphicswin.cpp:143 +#: graphicswin.cpp:144 msgid "&Distance / Diameter" msgstr "&Distance / Diameter" -#: graphicswin.cpp:144 +#: graphicswin.cpp:145 msgid "Re&ference Dimension" msgstr "Re&ference Dimension" -#: graphicswin.cpp:145 +#: graphicswin.cpp:146 msgid "A&ngle" msgstr "A&ngle" -#: graphicswin.cpp:146 +#: graphicswin.cpp:147 msgid "Reference An&gle" msgstr "Reference An&gle" -#: graphicswin.cpp:147 +#: graphicswin.cpp:148 msgid "Other S&upplementary Angle" msgstr "Other S&upplementary Angle" -#: graphicswin.cpp:148 +#: graphicswin.cpp:149 msgid "Toggle R&eference Dim" msgstr "Toggle R&eference Dim" -#: graphicswin.cpp:150 +#: graphicswin.cpp:151 msgid "&Horizontal" msgstr "&Horizontal" -#: graphicswin.cpp:151 +#: graphicswin.cpp:152 msgid "&Vertical" msgstr "&Vertical" -#: graphicswin.cpp:153 +#: graphicswin.cpp:154 msgid "&On Point / Curve / Plane" msgstr "&On Point / Curve / Plane" -#: graphicswin.cpp:154 +#: graphicswin.cpp:155 msgid "E&qual Length / Radius / Angle" msgstr "E&qual Length / Radius / Angle" -#: graphicswin.cpp:155 +#: graphicswin.cpp:156 msgid "Length Ra&tio" msgstr "Length Ra&tio" -#: graphicswin.cpp:156 +#: graphicswin.cpp:157 msgid "Length Diff&erence" msgstr "Length Diff&erence" -#: graphicswin.cpp:157 +#: graphicswin.cpp:158 msgid "At &Midpoint" msgstr "At &Midpoint" -#: graphicswin.cpp:158 +#: graphicswin.cpp:159 msgid "S&ymmetric" msgstr "S&ymmetric" -#: graphicswin.cpp:159 +#: graphicswin.cpp:160 msgid "Para&llel / Tangent" msgstr "Para&llel / Tangent" -#: graphicswin.cpp:160 +#: graphicswin.cpp:161 msgid "&Perpendicular" msgstr "&Perpendicular" -#: graphicswin.cpp:161 +#: graphicswin.cpp:162 msgid "Same Orient&ation" msgstr "Same Orient&ation" -#: graphicswin.cpp:162 +#: graphicswin.cpp:163 msgid "Lock Point Where &Dragged" msgstr "Lock Point Where &Dragged" -#: graphicswin.cpp:164 +#: graphicswin.cpp:165 msgid "Comment" msgstr "Comment" -#: graphicswin.cpp:166 +#: graphicswin.cpp:167 msgid "&Analyze" msgstr "&Analyze" -#: graphicswin.cpp:167 +#: graphicswin.cpp:168 msgid "Measure &Volume" msgstr "Measure &Volume" -#: graphicswin.cpp:168 +#: graphicswin.cpp:169 msgid "Measure A&rea" msgstr "Measure A&rea" -#: graphicswin.cpp:169 +#: graphicswin.cpp:170 msgid "Measure &Perimeter" msgstr "Measure &Perimeter" -#: graphicswin.cpp:170 +#: graphicswin.cpp:171 msgid "Show &Interfering Parts" msgstr "Show &Interfering Parts" -#: graphicswin.cpp:171 +#: graphicswin.cpp:172 msgid "Show &Naked Edges" msgstr "Show &Naked Edges" -#: graphicswin.cpp:172 +#: graphicswin.cpp:173 msgid "Show &Center of Mass" msgstr "Show &Center of Mass" -#: graphicswin.cpp:174 +#: graphicswin.cpp:175 msgid "Show &Underconstrained Points" msgstr "Show &Underconstrained Points" -#: graphicswin.cpp:176 +#: graphicswin.cpp:177 msgid "&Trace Point" msgstr "&Trace Point" -#: graphicswin.cpp:177 +#: graphicswin.cpp:178 msgid "&Stop Tracing..." msgstr "&Stop Tracing..." -#: graphicswin.cpp:178 +#: graphicswin.cpp:179 msgid "Step &Dimension..." msgstr "Step &Dimension..." -#: graphicswin.cpp:180 +#: graphicswin.cpp:181 msgid "&Help" msgstr "&Help" -#: graphicswin.cpp:181 +#: graphicswin.cpp:182 msgid "&Language" msgstr "&Language" -#: graphicswin.cpp:182 +#: graphicswin.cpp:183 msgid "&Website / Manual" msgstr "&Website / Manual" -#: graphicswin.cpp:184 +#: graphicswin.cpp:185 msgid "&About" msgstr "&About" -#: graphicswin.cpp:352 +#: graphicswin.cpp:355 msgid "(no recent files)" msgstr "(no recent files)" -#: graphicswin.cpp:360 +#: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." msgstr "File '%s' does not exist." -#: graphicswin.cpp:721 +#: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." msgstr "No workplane is active, so the grid will not appear." -#: graphicswin.cpp:730 +#: graphicswin.cpp:740 msgid "" "The perspective factor is set to zero, so the view will always be a parallel " "projection.\n" @@ -1113,17 +1117,17 @@ msgstr "" "For a perspective projection, modify the perspective factor in the " "configuration screen. A value around 0.3 is typical." -#: graphicswin.cpp:809 +#: graphicswin.cpp:819 msgid "" "Select a point; this point will become the center of the view on screen." msgstr "" "Select a point; this point will become the center of the view on screen." -#: graphicswin.cpp:1103 +#: graphicswin.cpp:1114 msgid "No additional entities share endpoints with the selected entities." msgstr "No additional entities share endpoints with the selected entities." -#: graphicswin.cpp:1121 +#: graphicswin.cpp:1132 msgid "" "To use this command, select a point or other entity from an linked part, or " "make a link group the active group." @@ -1131,7 +1135,7 @@ msgstr "" "To use this command, select a point or other entity from an linked part, or " "make a link group the active group." -#: graphicswin.cpp:1144 +#: graphicswin.cpp:1155 msgid "" "No workplane is active. Activate a workplane (with Sketch -> In Workplane) " "to define the plane for the snap grid." @@ -1139,7 +1143,7 @@ msgstr "" "No workplane is active. Activate a workplane (with Sketch -> In Workplane) " "to define the plane for the snap grid." -#: graphicswin.cpp:1151 +#: graphicswin.cpp:1162 msgid "" "Can't snap these items to grid; select points, text comments, or constraints " "with a label. To snap a line, select its endpoints." @@ -1147,11 +1151,11 @@ msgstr "" "Can't snap these items to grid; select points, text comments, or constraints " "with a label. To snap a line, select its endpoints." -#: graphicswin.cpp:1239 +#: graphicswin.cpp:1247 msgid "No workplane selected. Activating default workplane for this group." msgstr "No workplane selected. Activating default workplane for this group." -#: graphicswin.cpp:1242 +#: graphicswin.cpp:1250 msgid "" "No workplane is selected, and the active group does not have a default " "workplane. Try selecting a workplane, or activating a sketch-in-new-" @@ -1161,7 +1165,7 @@ msgstr "" "workplane. Try selecting a workplane, or activating a sketch-in-new-" "workplane group." -#: graphicswin.cpp:1263 +#: graphicswin.cpp:1271 msgid "" "Bad selection for tangent arc at point. Select a single point, or select " "nothing to set up arc parameters." @@ -1169,47 +1173,47 @@ msgstr "" "Bad selection for tangent arc at point. Select a single point, or select " "nothing to set up arc parameters." -#: graphicswin.cpp:1274 +#: graphicswin.cpp:1282 msgid "click point on arc (draws anti-clockwise)" msgstr "click point on arc (draws anti-clockwise)" -#: graphicswin.cpp:1275 +#: graphicswin.cpp:1283 msgid "click to place datum point" msgstr "click to place datum point" -#: graphicswin.cpp:1276 +#: graphicswin.cpp:1284 msgid "click first point of line segment" msgstr "click first point of line segment" -#: graphicswin.cpp:1278 +#: graphicswin.cpp:1286 msgid "click first point of construction line segment" msgstr "click first point of construction line segment" -#: graphicswin.cpp:1279 +#: graphicswin.cpp:1287 msgid "click first point of cubic segment" msgstr "click first point of cubic segment" -#: graphicswin.cpp:1280 +#: graphicswin.cpp:1288 msgid "click center of circle" msgstr "click center of circle" -#: graphicswin.cpp:1281 +#: graphicswin.cpp:1289 msgid "click origin of workplane" msgstr "click origin of workplane" -#: graphicswin.cpp:1282 +#: graphicswin.cpp:1290 msgid "click one corner of rectangle" msgstr "click one corner of rectangle" -#: graphicswin.cpp:1283 +#: graphicswin.cpp:1291 msgid "click top left of text" msgstr "click top left of text" -#: graphicswin.cpp:1289 +#: graphicswin.cpp:1297 msgid "click top left of image" msgstr "click top left of image" -#: graphicswin.cpp:1301 +#: graphicswin.cpp:1309 msgid "" "No entities are selected. Select entities before trying to toggle their " "construction state." @@ -1350,19 +1354,19 @@ msgstr "translate" msgid "(unnamed)" msgstr "(unnamed)" -#: groupmesh.cpp:708 +#: groupmesh.cpp:709 msgid "not closed contour, or not all same style!" msgstr "not closed contour, or not all same style!" -#: groupmesh.cpp:721 +#: groupmesh.cpp:722 msgid "points not all coplanar!" msgstr "points not all coplanar!" -#: groupmesh.cpp:723 +#: groupmesh.cpp:724 msgid "contour is self-intersecting!" msgstr "contour is self-intersecting!" -#: groupmesh.cpp:725 +#: groupmesh.cpp:726 msgid "zero-length edge!" msgstr "zero-length edge!" @@ -1498,11 +1502,11 @@ msgstr "Unselect Hovered" msgid "Zoom to Fit" msgstr "Zoom to Fit" -#: mouse.cpp:990 mouse.cpp:1277 +#: mouse.cpp:989 mouse.cpp:1276 msgid "click next point of line, or press Esc" msgstr "click next point of line, or press Esc" -#: mouse.cpp:996 +#: mouse.cpp:995 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1510,15 +1514,15 @@ msgstr "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." -#: mouse.cpp:1030 +#: mouse.cpp:1029 msgid "click to place other corner of rectangle" msgstr "click to place other corner of rectangle" -#: mouse.cpp:1050 +#: mouse.cpp:1049 msgid "click to set radius" msgstr "click to set radius" -#: mouse.cpp:1055 +#: mouse.cpp:1054 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1526,21 +1530,21 @@ msgstr "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." -#: mouse.cpp:1074 +#: mouse.cpp:1073 msgid "click to place point" msgstr "click to place point" -#: mouse.cpp:1090 +#: mouse.cpp:1089 msgid "click next point of cubic, or press Esc" msgstr "click next point of cubic, or press Esc" -#: mouse.cpp:1095 +#: mouse.cpp:1094 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" "Sketching in a workplane already; sketch in 3d before creating new workplane." -#: mouse.cpp:1111 +#: mouse.cpp:1110 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1548,11 +1552,11 @@ msgstr "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." -#: mouse.cpp:1128 +#: mouse.cpp:1127 msgid "click to place bottom right of text" msgstr "click to place bottom right of text" -#: mouse.cpp:1134 +#: mouse.cpp:1133 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1560,11 +1564,11 @@ msgstr "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." -#: mouse.cpp:1161 +#: mouse.cpp:1160 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace models" @@ -1649,33 +1653,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "Comma-separated values" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 msgid "untitled" msgstr "untitled" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1562 +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "Save File" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1564 +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "Open File" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1368 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 msgctxt "button" msgid "_Cancel" msgstr "_Cancel" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 msgctxt "button" msgid "_Save" msgstr "_Save" -#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 msgctxt "button" msgid "_Open" msgstr "_Open" @@ -1705,48 +1709,48 @@ msgctxt "button" msgid "Do&n't Load" msgstr "Do&n't Load" -#: solvespace.cpp:551 +#: solvespace.cpp:557 msgctxt "title" msgid "Modified File" msgstr "Modified File" -#: solvespace.cpp:553 +#: solvespace.cpp:559 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "Do you want to save the changes you made to the sketch “%s”?" -#: solvespace.cpp:556 +#: solvespace.cpp:562 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "Do you want to save the changes you made to the new sketch?" -#: solvespace.cpp:559 +#: solvespace.cpp:565 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "Your changes will be lost if you don't save them." -#: solvespace.cpp:560 +#: solvespace.cpp:566 msgctxt "button" msgid "&Save" msgstr "&Save" -#: solvespace.cpp:562 +#: solvespace.cpp:568 msgctxt "button" msgid "Do&n't Save" msgstr "Do&n't Save" -#: solvespace.cpp:583 +#: solvespace.cpp:589 msgctxt "title" msgid "(new sketch)" msgstr "(new sketch)" -#: solvespace.cpp:590 +#: solvespace.cpp:596 msgctxt "title" msgid "Property Browser" msgstr "Property Browser" -#: solvespace.cpp:650 +#: solvespace.cpp:658 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " @@ -1756,7 +1760,7 @@ msgstr "" "is probably not what you want; hide them by clicking the link at the top of " "the text window." -#: solvespace.cpp:718 +#: solvespace.cpp:730 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." @@ -1765,19 +1769,19 @@ msgstr "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." -#: solvespace.cpp:766 +#: solvespace.cpp:778 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "Constraint must have a label, and must not be a reference dimension." -#: solvespace.cpp:770 +#: solvespace.cpp:782 msgid "Bad selection for step dimension; select a constraint." msgstr "Bad selection for step dimension; select a constraint." -#: solvespace.cpp:794 +#: solvespace.cpp:806 msgid "The assembly does not interfere, good." msgstr "The assembly does not interfere, good." -#: solvespace.cpp:810 +#: solvespace.cpp:822 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1788,7 +1792,7 @@ msgstr "" "\n" " %s" -#: solvespace.cpp:819 +#: solvespace.cpp:831 #, c-format msgid "" "\n" @@ -1801,7 +1805,7 @@ msgstr "" "\n" " %s" -#: solvespace.cpp:824 +#: solvespace.cpp:836 msgid "" "\n" "\n" @@ -1813,7 +1817,7 @@ msgstr "" "Curved surfaces have been approximated as triangles.\n" "This introduces error, typically of around 1%." -#: solvespace.cpp:839 +#: solvespace.cpp:851 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1830,15 +1834,15 @@ msgstr "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." -#: solvespace.cpp:848 -msgid "" -"This group does not contain a correctly-formed 2d closed area. It is open, " -"not coplanar, or self-intersecting." -msgstr "" -"This group does not contain a correctly-formed 2d closed area. It is open, " -"not coplanar, or self-intersecting." - #: solvespace.cpp:860 +msgid "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." +msgstr "" +"This group does not contain a correctly-formed 2d closed area. It is open, " +"not coplanar, or self-intersecting." + +#: solvespace.cpp:872 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1855,7 +1859,7 @@ msgstr "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." -#: solvespace.cpp:880 +#: solvespace.cpp:892 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1872,36 +1876,36 @@ msgstr "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." -#: solvespace.cpp:886 +#: solvespace.cpp:898 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "Bad selection for perimeter; select line segments, arcs, and curves." -#: solvespace.cpp:902 +#: solvespace.cpp:914 msgid "Bad selection for trace; select a single point." msgstr "Bad selection for trace; select a single point." -#: solvespace.cpp:925 +#: solvespace.cpp:941 #, c-format msgid "Couldn't write to '%s'" msgstr "Couldn't write to '%s'" -#: solvespace.cpp:955 +#: solvespace.cpp:971 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "The mesh is self-intersecting (NOT okay, invalid)." -#: solvespace.cpp:956 +#: solvespace.cpp:972 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "The mesh is not self-intersecting (okay, valid)." -#: solvespace.cpp:958 +#: solvespace.cpp:974 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "The mesh has naked edges (NOT okay, invalid)." -#: solvespace.cpp:959 +#: solvespace.cpp:975 msgid "The mesh is watertight (okay, valid)." msgstr "The mesh is watertight (okay, valid)." -#: solvespace.cpp:962 +#: solvespace.cpp:978 #, c-format msgid "" "\n" @@ -1912,39 +1916,39 @@ msgstr "" "\n" "The model contains %d triangles, from %d surfaces." -#: solvespace.cpp:966 -#, c-format -msgid "" -"%s\n" -"\n" -"%s\n" -"\n" -"Zero problematic edges, good.%s" -msgstr "" -"%s\n" -"\n" -"%s\n" -"\n" -"Zero problematic edges, good.%s" - -#: solvespace.cpp:969 -#, c-format -msgid "" -"%s\n" -"\n" -"%s\n" -"\n" -"%d problematic edges, bad.%s" -msgstr "" -"%s\n" -"\n" -"%s\n" -"\n" -"%d problematic edges, bad.%s" - #: solvespace.cpp:982 #, c-format msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" +msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"Zero problematic edges, good.%s" + +#: solvespace.cpp:985 +#, c-format +msgid "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" +msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d problematic edges, bad.%s" + +#: solvespace.cpp:998 +#, c-format +msgid "" "This is SolveSpace version %s.\n" "\n" "For more information, see http://solvespace.com/\n" @@ -2104,30 +2108,38 @@ msgid "New group rotating active sketch" msgstr "New group rotating active sketch" #: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "New group helix from active sketch" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "New group revolve active sketch" + +#: toolbar.cpp:76 msgid "New group step and repeat rotating" msgstr "New group step and repeat rotating" -#: toolbar.cpp:74 +#: toolbar.cpp:78 msgid "New group step and repeat translating" msgstr "New group step and repeat translating" -#: toolbar.cpp:76 +#: toolbar.cpp:80 msgid "New group in new workplane (thru given entities)" msgstr "New group in new workplane (thru given entities)" -#: toolbar.cpp:78 +#: toolbar.cpp:82 msgid "New group in 3d" msgstr "New group in 3d" -#: toolbar.cpp:80 +#: toolbar.cpp:84 msgid "New group linking / assembling file" msgstr "New group linking / assembling file" -#: toolbar.cpp:84 +#: toolbar.cpp:88 msgid "Nearest isometric view" msgstr "Nearest isometric view" -#: toolbar.cpp:86 +#: toolbar.cpp:90 msgid "Align view to active workplane" msgstr "Align view to active workplane" diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po index 2295312b..a6f4c1e8 100644 --- a/res/locales/fr_FR.po +++ b/res/locales/fr_FR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-23 07:36+0100\n" +"POT-Creation-Date: 2021-01-15 14:51-0600\n" "PO-Revision-Date: 2018-07-14 06:12+0000\n" "Last-Translator: whitequark \n" "Language-Team: none\n" @@ -17,7 +17,7 @@ msgstr "" "X-Generator: Zanata 4.4.5\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" -#: clipboard.cpp:274 +#: clipboard.cpp:310 msgid "" "Cut, paste, and copy work only in a workplane.\n" "\n" @@ -27,27 +27,27 @@ msgstr "" "\n" "Activez un plan avec \"Dessin -> Dans plan de travail\"." -#: clipboard.cpp:291 +#: clipboard.cpp:327 msgid "Clipboard is empty; nothing to paste." msgstr "Presse papier vide; rien à coller." -#: clipboard.cpp:338 +#: clipboard.cpp:374 msgid "Number of copies to paste must be at least one." msgstr "Le nombre de copies à coller doit être d'au moins un." -#: clipboard.cpp:354 textscreens.cpp:783 +#: clipboard.cpp:390 textscreens.cpp:783 msgid "Scale cannot be zero." msgstr "L'échelle ne peut pas être zéro." -#: clipboard.cpp:396 +#: clipboard.cpp:432 msgid "Select one point to define origin of rotation." msgstr "Sélectionnez un point pour définir l'origine de la rotation." -#: clipboard.cpp:408 +#: clipboard.cpp:444 msgid "Select two points to define translation vector." msgstr "Sélectionnez deux points pour définir le vecteur de translation." -#: clipboard.cpp:418 +#: clipboard.cpp:454 msgid "" "Transformation is identity. So all copies will be exactly on top of each " "other." @@ -55,23 +55,23 @@ msgstr "" "Transformation identique. Donc, toutes les copies seront exactement les unes " "au-dessus des autres." -#: clipboard.cpp:422 +#: clipboard.cpp:458 msgid "Too many items to paste; split this into smaller pastes." msgstr "Trop d'éléments à coller; Divisez-les en plus petits groupes." -#: clipboard.cpp:427 +#: clipboard.cpp:463 msgid "No workplane active." msgstr "Pas d'espace de travail actif." -#: confscreen.cpp:410 +#: confscreen.cpp:418 msgid "Bad format: specify coordinates as x, y, z" msgstr "Mauvais format: spécifiez les coordonnées comme x, y, z" -#: confscreen.cpp:420 style.cpp:659 textscreens.cpp:805 +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 msgid "Bad format: specify color as r, g, b" msgstr "Mauvais format; spécifiez la couleur comme r, v, b" -#: confscreen.cpp:446 +#: confscreen.cpp:454 msgid "" "The perspective factor will have no effect until you enable View -> Use " "Perspective Projection." @@ -79,26 +79,26 @@ msgstr "" "Le facteur de perspective n'aura aucun effet tant que vous n'aurez pas " "activé \"Affichage -> Utiliser la projection de perspective\"." -#: confscreen.cpp:459 confscreen.cpp:469 +#: confscreen.cpp:467 confscreen.cpp:477 #, c-format msgid "Specify between 0 and %d digits after the decimal." msgstr "" -#: confscreen.cpp:481 +#: confscreen.cpp:489 msgid "Export scale must not be zero!" msgstr "L'échelle d'export ne doit pas être zéro!" -#: confscreen.cpp:493 +#: confscreen.cpp:501 msgid "Cutter radius offset must not be negative!" msgstr "Le décalage du rayon de coupe ne doit pas être négatif!" -#: confscreen.cpp:547 +#: confscreen.cpp:555 msgid "Bad value: autosave interval should be positive" msgstr "" "Mauvaise valeur: l'intervalle d'enregistrement automatique devrait être " "positif" -#: confscreen.cpp:550 +#: confscreen.cpp:558 msgid "Bad format: specify interval in integral minutes" msgstr "Mauvais format: spécifiez un nombre entier de minutes" @@ -277,7 +277,33 @@ msgctxt "constr-name" msgid "comment" msgstr "commentaire" -#: constraint.cpp:171 +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" +"L'arc tangent et le segment de ligne doivent partager un point final. " +"Contraignez-les avec \"Contrainte -> Sur point avant de contraindre la " +"tangente\"." + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"La tangente cubique et le segment de ligne doivent partager un point final. " +"Contraignez-les avec \"Contrainte -> Sur point avant de contraindre la " +"tangente\"." + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" +"Les courbes doivent partager un point final. Contraignez-les avec " +"\"Contrainte -> Sur point avant de contraindre la tangente\"." + +#: constraint.cpp:231 msgid "" "Bad selection for distance / diameter constraint. This constraint can apply " "to:\n" @@ -301,7 +327,7 @@ msgstr "" "    * Une face plane et un point (distance minimale)\n" "    * Un cercle ou un arc (diamètre)\n" -#: constraint.cpp:224 +#: constraint.cpp:284 msgid "" "Bad selection for on point / curve / plane constraint. This constraint can " "apply to:\n" @@ -321,7 +347,7 @@ msgstr "" "    * Un point et un cercle ou un arc (point sur courbe)\n" "    * Un point et une face plane (point sur une face)\n" -#: constraint.cpp:286 +#: constraint.cpp:346 msgid "" "Bad selection for equal length / radius constraint. This constraint can " "apply to:\n" @@ -352,7 +378,7 @@ msgstr "" "    * Un segment de ligne et un arc (la longueur de segment de ligne est " "égale à la longueur d'arc)\n" -#: constraint.cpp:325 +#: constraint.cpp:385 msgid "" "Bad selection for length ratio constraint. This constraint can apply to:\n" "\n" @@ -363,7 +389,7 @@ msgstr "" "\n" "    * Deux segments de ligne\n" -#: constraint.cpp:342 +#: constraint.cpp:402 msgid "" "Bad selection for length difference constraint. This constraint can apply " "to:\n" @@ -375,7 +401,7 @@ msgstr "" "\n" "    * Deux segments de ligne\n" -#: constraint.cpp:368 +#: constraint.cpp:428 msgid "" "Bad selection for at midpoint constraint. This constraint can apply to:\n" "\n" @@ -388,7 +414,7 @@ msgstr "" "    * Un segment de ligne et un point (point au milieu)\n" "    * Un segment de ligne et un plan de travail (point médian dans le plan)\n" -#: constraint.cpp:426 +#: constraint.cpp:486 msgid "" "Bad selection for symmetric constraint. This constraint can apply to:\n" "\n" @@ -409,7 +435,7 @@ msgstr "" "    * Plan de travail, et deux points ou un segment de ligne (symétrique au " "plan de travail)\n" -#: constraint.cpp:440 +#: constraint.cpp:500 msgid "" "A workplane must be active when constraining symmetric without an explicit " "symmetry plane." @@ -417,7 +443,7 @@ msgstr "" "Un plan de travail doit être actif lors d'une contrainte de symétrie sans " "plan de symétrie explicite." -#: constraint.cpp:470 +#: constraint.cpp:530 msgid "" "Activate a workplane (with Sketch -> In Workplane) before applying a " "horizontal or vertical constraint." @@ -425,7 +451,7 @@ msgstr "" "Activez un plan de travail (avec Dessin -> Dans plan de travail) avant " "d'appliquer une contrainte horizontale ou verticale." -#: constraint.cpp:483 +#: constraint.cpp:543 msgid "" "Bad selection for horizontal / vertical constraint. This constraint can " "apply to:\n" @@ -439,7 +465,7 @@ msgstr "" "    * deux points\n" "    * Un segment de ligne\n" -#: constraint.cpp:504 +#: constraint.cpp:564 msgid "" "Bad selection for same orientation constraint. This constraint can apply " "to:\n" @@ -451,15 +477,15 @@ msgstr "" "\n" " * Deux normales\n" -#: constraint.cpp:554 +#: constraint.cpp:614 msgid "Must select an angle constraint." msgstr "Vous devez sélectionner une contrainte d'angle." -#: constraint.cpp:567 +#: constraint.cpp:627 msgid "Must select a constraint with associated label." msgstr "Vous devez sélectionner une contrainte avec une étiquette associée." -#: constraint.cpp:578 +#: constraint.cpp:638 msgid "" "Bad selection for angle constraint. This constraint can apply to:\n" "\n" @@ -474,37 +500,11 @@ msgstr "" "    * Un segment de ligne et une normale\n" "    * Deux normales\n" -#: constraint.cpp:635 -msgid "" -"The tangent arc and line segment must share an endpoint. Constrain them with " -"Constrain -> On Point before constraining tangent." -msgstr "" -"L'arc tangent et le segment de ligne doivent partager un point final. " -"Contraignez-les avec \"Contrainte -> Sur point avant de contraindre la " -"tangente\"." - -#: constraint.cpp:659 -msgid "" -"The tangent cubic and line segment must share an endpoint. Constrain them " -"with Constrain -> On Point before constraining tangent." -msgstr "" -"La tangente cubique et le segment de ligne doivent partager un point final. " -"Contraignez-les avec \"Contrainte -> Sur point avant de contraindre la " -"tangente\"." - -#: constraint.cpp:669 +#: constraint.cpp:701 msgid "Curve-curve tangency must apply in workplane." msgstr "Courbe-Courbe tangence doit s'appliquer dans le plan de travail." -#: constraint.cpp:687 -msgid "" -"The curves must share an endpoint. Constrain them with Constrain -> On Point " -"before constraining tangent." -msgstr "" -"Les courbes doivent partager un point final. Contraignez-les avec " -"\"Contrainte -> Sur point avant de contraindre la tangente\"." - -#: constraint.cpp:696 +#: constraint.cpp:711 msgid "" "Bad selection for parallel / tangent constraint. This constraint can apply " "to:\n" @@ -523,7 +523,7 @@ msgstr "" "    * Deux segments de ligne, des arcs ou des Béziers, qui partagent un " "point final (tangent)\n" -#: constraint.cpp:714 +#: constraint.cpp:729 msgid "" "Bad selection for perpendicular constraint. This constraint can apply to:\n" "\n" @@ -538,7 +538,7 @@ msgstr "" "    * Un segment de ligne et une normale\n" "    * Deux normales\n" -#: constraint.cpp:729 +#: constraint.cpp:744 msgid "" "Bad selection for lock point where dragged constraint. This constraint can " "apply to:\n" @@ -550,7 +550,7 @@ msgstr "" "\n" "    * un point\n" -#: constraint.cpp:740 +#: constraint.cpp:755 msgid "click center of comment text" msgstr "cliquez le centre du texte de commentaire" @@ -654,7 +654,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:563 +#: file.cpp:869 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "" @@ -820,299 +820,303 @@ msgid "Show Snap &Grid" msgstr "Afficher la &grille d'accrochage" #: graphicswin.cpp:95 +msgid "Dim Solid for Sketch Groups" +msgstr "" + +#: graphicswin.cpp:96 msgid "Use &Perspective Projection" msgstr "Utiliser la vue en &Perspective" -#: graphicswin.cpp:96 +#: graphicswin.cpp:97 msgid "Dimension &Units" msgstr "&Unités de dimensions" -#: graphicswin.cpp:97 +#: graphicswin.cpp:98 msgid "Dimensions in &Millimeters" msgstr "Dimensions en &Millimètres" -#: graphicswin.cpp:98 +#: graphicswin.cpp:99 msgid "Dimensions in M&eters" msgstr "Dimensions en &Mètres" -#: graphicswin.cpp:99 +#: graphicswin.cpp:100 msgid "Dimensions in &Inches" msgstr "Dimensions en &Pouces" -#: graphicswin.cpp:101 +#: graphicswin.cpp:102 msgid "Show &Toolbar" msgstr "Affichage &Barre d'outils" -#: graphicswin.cpp:102 +#: graphicswin.cpp:103 msgid "Show Property Bro&wser" msgstr "Affichage du &Navigateur de Propriété" -#: graphicswin.cpp:104 +#: graphicswin.cpp:105 msgid "&Full Screen" msgstr "&Plein Ecran" -#: graphicswin.cpp:106 +#: graphicswin.cpp:107 msgid "&New Group" msgstr "&Nouveau Groupe" -#: graphicswin.cpp:107 +#: graphicswin.cpp:108 msgid "Sketch In &3d" msgstr "Dessin en &3d" -#: graphicswin.cpp:108 +#: graphicswin.cpp:109 msgid "Sketch In New &Workplane" msgstr "Dessin dans un nouveau &Plan de travail" -#: graphicswin.cpp:110 +#: graphicswin.cpp:111 msgid "Step &Translating" msgstr "Espacement &Linéaire" -#: graphicswin.cpp:111 +#: graphicswin.cpp:112 msgid "Step &Rotating" msgstr "Espacement &Circulaire" -#: graphicswin.cpp:113 +#: graphicswin.cpp:114 msgid "E&xtrude" msgstr "E&xtruder" -#: graphicswin.cpp:114 +#: graphicswin.cpp:115 msgid "&Helix" msgstr "&Helix" -#: graphicswin.cpp:115 +#: graphicswin.cpp:116 msgid "&Lathe" msgstr "&Lathe" -#: graphicswin.cpp:116 +#: graphicswin.cpp:117 msgid "Re&volve" msgstr "Ré&volution" -#: graphicswin.cpp:118 +#: graphicswin.cpp:119 msgid "Link / Assemble..." msgstr "Lié / Assembler..." -#: graphicswin.cpp:119 +#: graphicswin.cpp:120 msgid "Link Recent" msgstr "Lié Récent" -#: graphicswin.cpp:121 +#: graphicswin.cpp:122 msgid "&Sketch" msgstr "&Dessin" -#: graphicswin.cpp:122 +#: graphicswin.cpp:123 msgid "In &Workplane" msgstr "Dans le &Plan de travail" -#: graphicswin.cpp:123 +#: graphicswin.cpp:124 msgid "Anywhere In &3d" msgstr "N'importe où dans la &3d" -#: graphicswin.cpp:125 +#: graphicswin.cpp:126 msgid "Datum &Point" msgstr "&Point" -#: graphicswin.cpp:126 +#: graphicswin.cpp:127 msgid "&Workplane" msgstr "&Plan de travail" -#: graphicswin.cpp:128 +#: graphicswin.cpp:129 msgid "Line &Segment" msgstr "Ligne - &Polyligne" -#: graphicswin.cpp:129 +#: graphicswin.cpp:130 msgid "C&onstruction Line Segment" msgstr "Ligne de C&onstruction" -#: graphicswin.cpp:130 +#: graphicswin.cpp:131 msgid "&Rectangle" msgstr "&Rectangle" -#: graphicswin.cpp:131 +#: graphicswin.cpp:132 msgid "&Circle" msgstr "&Cercle" -#: graphicswin.cpp:132 +#: graphicswin.cpp:133 msgid "&Arc of a Circle" msgstr "&Arc de Cercle" -#: graphicswin.cpp:133 +#: graphicswin.cpp:134 msgid "&Bezier Cubic Spline" msgstr "Spline Cubique de &Beziers" -#: graphicswin.cpp:135 +#: graphicswin.cpp:136 msgid "&Text in TrueType Font" msgstr "&Texte en Police TrueType" -#: graphicswin.cpp:136 +#: graphicswin.cpp:137 msgid "&Image" msgstr "&Image" -#: graphicswin.cpp:138 +#: graphicswin.cpp:139 msgid "To&ggle Construction" msgstr "&Basculer en mode \"Construction\"" -#: graphicswin.cpp:139 +#: graphicswin.cpp:140 msgid "Tangent &Arc at Point" msgstr "&Arc Tangent au Point" -#: graphicswin.cpp:140 +#: graphicswin.cpp:141 msgid "Split Curves at &Intersection" msgstr "Diviser les Courbes à l'&Intersection" -#: graphicswin.cpp:142 +#: graphicswin.cpp:143 msgid "&Constrain" msgstr "&Constraintes" -#: graphicswin.cpp:143 +#: graphicswin.cpp:144 msgid "&Distance / Diameter" msgstr "&Distance / Diamètre" -#: graphicswin.cpp:144 +#: graphicswin.cpp:145 msgid "Re&ference Dimension" msgstr "Dimension Maîtresse / Indicative" -#: graphicswin.cpp:145 +#: graphicswin.cpp:146 msgid "A&ngle" msgstr "A&ngle" -#: graphicswin.cpp:146 +#: graphicswin.cpp:147 msgid "Reference An&gle" msgstr "An&gle Maître / Indicatif" -#: graphicswin.cpp:147 +#: graphicswin.cpp:148 msgid "Other S&upplementary Angle" msgstr "Autre angle S&upplémentaire" -#: graphicswin.cpp:148 +#: graphicswin.cpp:149 msgid "Toggle R&eference Dim" msgstr "Basculer cote Maîtresse / cote Indicative" -#: graphicswin.cpp:150 +#: graphicswin.cpp:151 msgid "&Horizontal" msgstr "&Horizontal" -#: graphicswin.cpp:151 +#: graphicswin.cpp:152 msgid "&Vertical" msgstr "&Vertical" -#: graphicswin.cpp:153 +#: graphicswin.cpp:154 msgid "&On Point / Curve / Plane" msgstr "&Sur Point / Courbe / Plan" -#: graphicswin.cpp:154 +#: graphicswin.cpp:155 msgid "E&qual Length / Radius / Angle" msgstr "&Egale Longueur / Rayon / Angle" -#: graphicswin.cpp:155 +#: graphicswin.cpp:156 msgid "Length Ra&tio" msgstr "R&apport de Longueur" -#: graphicswin.cpp:156 +#: graphicswin.cpp:157 msgid "Length Diff&erence" msgstr "D&ifférence de Longueur" -#: graphicswin.cpp:157 +#: graphicswin.cpp:158 msgid "At &Midpoint" msgstr "Au &Milieu" -#: graphicswin.cpp:158 +#: graphicswin.cpp:159 msgid "S&ymmetric" msgstr "&Symétrique" -#: graphicswin.cpp:159 +#: graphicswin.cpp:160 msgid "Para&llel / Tangent" msgstr "Para&llèle / Tangent" -#: graphicswin.cpp:160 +#: graphicswin.cpp:161 msgid "&Perpendicular" msgstr "&Perpendiculaire" -#: graphicswin.cpp:161 +#: graphicswin.cpp:162 msgid "Same Orient&ation" msgstr "Même Orient&ation" -#: graphicswin.cpp:162 +#: graphicswin.cpp:163 msgid "Lock Point Where &Dragged" msgstr "Accrocher le point à l'&Emplacement" -#: graphicswin.cpp:164 +#: graphicswin.cpp:165 msgid "Comment" msgstr "Commentaire" -#: graphicswin.cpp:166 +#: graphicswin.cpp:167 msgid "&Analyze" msgstr "&Analyse" -#: graphicswin.cpp:167 +#: graphicswin.cpp:168 msgid "Measure &Volume" msgstr "Mesure &Volume" -#: graphicswin.cpp:168 +#: graphicswin.cpp:169 msgid "Measure A&rea" msgstr "Mesure &Aire" -#: graphicswin.cpp:169 +#: graphicswin.cpp:170 msgid "Measure &Perimeter" msgstr "Mesure &Périmètre" -#: graphicswin.cpp:170 +#: graphicswin.cpp:171 msgid "Show &Interfering Parts" msgstr "Montrer les Pièces &Interférentes" -#: graphicswin.cpp:171 +#: graphicswin.cpp:172 msgid "Show &Naked Edges" msgstr "Montrer les Arêtes &Nues" -#: graphicswin.cpp:172 +#: graphicswin.cpp:173 msgid "Show &Center of Mass" msgstr "Montrer le &Centre de Gravité" -#: graphicswin.cpp:174 +#: graphicswin.cpp:175 msgid "Show &Underconstrained Points" msgstr "Montrer les &sous-contraintes Points" -#: graphicswin.cpp:176 +#: graphicswin.cpp:177 msgid "&Trace Point" msgstr "&Tracer Point" -#: graphicswin.cpp:177 +#: graphicswin.cpp:178 msgid "&Stop Tracing..." msgstr "&Arrêt Tracé..." -#: graphicswin.cpp:178 +#: graphicswin.cpp:179 msgid "Step &Dimension..." msgstr "Espacement &Dimension..." -#: graphicswin.cpp:180 +#: graphicswin.cpp:181 msgid "&Help" msgstr "&Aide" -#: graphicswin.cpp:181 +#: graphicswin.cpp:182 msgid "&Language" msgstr "&Langue" -#: graphicswin.cpp:182 +#: graphicswin.cpp:183 msgid "&Website / Manual" msgstr "&Site web / Manuel" -#: graphicswin.cpp:184 +#: graphicswin.cpp:185 msgid "&About" msgstr "&A propos" -#: graphicswin.cpp:352 +#: graphicswin.cpp:355 msgid "(no recent files)" msgstr "(pas de fichier récent)" -#: graphicswin.cpp:360 +#: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." msgstr "" -#: graphicswin.cpp:721 +#: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." msgstr "Pas de plan de travail actif, donc la grille ne va pas apparaître." -#: graphicswin.cpp:730 +#: graphicswin.cpp:740 msgid "" "The perspective factor is set to zero, so the view will always be a parallel " "projection.\n" @@ -1126,19 +1130,19 @@ msgstr "" "Pour une projection en perspective, modifiez le facteur de perspective dans " "l'écran de configuration. Une valeur d'environ 0,3 est typique." -#: graphicswin.cpp:809 +#: graphicswin.cpp:819 msgid "" "Select a point; this point will become the center of the view on screen." msgstr "" "Sélectionnez un point. Ce point deviendra le centre de la vue à l'écran." -#: graphicswin.cpp:1103 +#: graphicswin.cpp:1114 msgid "No additional entities share endpoints with the selected entities." msgstr "" "Aucune entité supplémentaire ne partage des points d'extrémité avec les " "entités sélectionnées." -#: graphicswin.cpp:1121 +#: graphicswin.cpp:1132 msgid "" "To use this command, select a point or other entity from an linked part, or " "make a link group the active group." @@ -1146,7 +1150,7 @@ msgstr "" "Pour utiliser cette commande, sélectionnez un point ou une autre entité à " "partir d'une pièce liée ou créez un groupe de liens dans le groupe actif." -#: graphicswin.cpp:1144 +#: graphicswin.cpp:1155 msgid "" "No workplane is active. Activate a workplane (with Sketch -> In Workplane) " "to define the plane for the snap grid." @@ -1154,7 +1158,7 @@ msgstr "" "Aucun plan de travail n'est actif. Activez un plan de travail (avec Dessin -" "> Dans plan de travail) pour définir le plan pour la grille d'accrochage." -#: graphicswin.cpp:1151 +#: graphicswin.cpp:1162 msgid "" "Can't snap these items to grid; select points, text comments, or constraints " "with a label. To snap a line, select its endpoints." @@ -1163,13 +1167,13 @@ msgstr "" "des textes de commentaires ou des contraintes avec une étiquette. Pour " "accrocher une ligne, sélectionnez ses points d'extrémité." -#: graphicswin.cpp:1239 +#: graphicswin.cpp:1247 msgid "No workplane selected. Activating default workplane for this group." msgstr "" "Aucun plan de travail sélectionné. Activation du plan de travail par défaut " "pour ce groupe." -#: graphicswin.cpp:1242 +#: graphicswin.cpp:1250 msgid "" "No workplane is selected, and the active group does not have a default " "workplane. Try selecting a workplane, or activating a sketch-in-new-" @@ -1179,7 +1183,7 @@ msgstr "" "de travail par défaut. Essayez de sélectionner un plan de travail ou " "d'activer un groupe de \"Dessin dans nouveau plan travail\"." -#: graphicswin.cpp:1263 +#: graphicswin.cpp:1271 msgid "" "Bad selection for tangent arc at point. Select a single point, or select " "nothing to set up arc parameters." @@ -1187,49 +1191,49 @@ msgstr "" "Mauvaise sélection pour l'arc tangent au point. Sélectionnez un seul point, " "ou ne sélectionnez rien pour configurer les paramètres de l'arc." -#: graphicswin.cpp:1274 +#: graphicswin.cpp:1282 msgid "click point on arc (draws anti-clockwise)" msgstr "" "cliquez un point sur l'arc (dessine dans le sens inverse des aiguilles d'une " "montre)" -#: graphicswin.cpp:1275 +#: graphicswin.cpp:1283 msgid "click to place datum point" msgstr "cliquez pour placer un point" -#: graphicswin.cpp:1276 +#: graphicswin.cpp:1284 msgid "click first point of line segment" msgstr "cliquez le premier point du segment de ligne" -#: graphicswin.cpp:1278 +#: graphicswin.cpp:1286 msgid "click first point of construction line segment" msgstr "cliquez le premier point de la ligne de construction" -#: graphicswin.cpp:1279 +#: graphicswin.cpp:1287 msgid "click first point of cubic segment" msgstr "cliquez le premier point du segment cubique" -#: graphicswin.cpp:1280 +#: graphicswin.cpp:1288 msgid "click center of circle" msgstr "cliquez pour placer le centre du cercle" -#: graphicswin.cpp:1281 +#: graphicswin.cpp:1289 msgid "click origin of workplane" msgstr "cliquez pour placer l'origine du plan de travail" -#: graphicswin.cpp:1282 +#: graphicswin.cpp:1290 msgid "click one corner of rectangle" msgstr "cliquez un coin du rectangle" -#: graphicswin.cpp:1283 +#: graphicswin.cpp:1291 msgid "click top left of text" msgstr "cliquez le haut à gauche du texte" -#: graphicswin.cpp:1289 +#: graphicswin.cpp:1297 msgid "click top left of image" msgstr "cliquez le haut à gauche de l'image" -#: graphicswin.cpp:1301 +#: graphicswin.cpp:1309 msgid "" "No entities are selected. Select entities before trying to toggle their " "construction state." @@ -1363,19 +1367,19 @@ msgstr "translation" msgid "(unnamed)" msgstr "(sans nom)" -#: groupmesh.cpp:708 +#: groupmesh.cpp:709 msgid "not closed contour, or not all same style!" msgstr "contour non fermé ou tout n'est pas du même style!" -#: groupmesh.cpp:721 +#: groupmesh.cpp:722 msgid "points not all coplanar!" msgstr "les points ne sont pas tous coplanaires!" -#: groupmesh.cpp:723 +#: groupmesh.cpp:724 msgid "contour is self-intersecting!" msgstr "le contour s'entrecroise!" -#: groupmesh.cpp:725 +#: groupmesh.cpp:726 msgid "zero-length edge!" msgstr "arête de longueur nulle!" @@ -1511,11 +1515,11 @@ msgstr "Désélectionner survolé" msgid "Zoom to Fit" msgstr "Zoom pour ajuster" -#: mouse.cpp:990 mouse.cpp:1277 +#: mouse.cpp:989 mouse.cpp:1276 msgid "click next point of line, or press Esc" msgstr "cliquez pou le prochain point de ligne or appuyez sur Esc" -#: mouse.cpp:996 +#: mouse.cpp:995 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1523,15 +1527,15 @@ msgstr "" "Impossible de dessiner un rectangle en 3d; D'abord, activez un plan de " "travail avec \"Dessin -> Dans plan de travail\"." -#: mouse.cpp:1030 +#: mouse.cpp:1029 msgid "click to place other corner of rectangle" msgstr "cliquez pour placer un autre coin de rectangle" -#: mouse.cpp:1050 +#: mouse.cpp:1049 msgid "click to set radius" msgstr "cliquez pour ajuster le rayon" -#: mouse.cpp:1055 +#: mouse.cpp:1054 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1539,22 +1543,22 @@ msgstr "" "Ne peut pas dessiner l'arc en 3d; D'abord, activez un plan de travail avec " "\"Dessin -> Dans plan de travail\"." -#: mouse.cpp:1074 +#: mouse.cpp:1073 msgid "click to place point" msgstr "cliquez pour placer un point" -#: mouse.cpp:1090 +#: mouse.cpp:1089 msgid "click next point of cubic, or press Esc" msgstr "cliquez le prochain point cubique ou appuyez sur Esc" -#: mouse.cpp:1095 +#: mouse.cpp:1094 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" "Vous dessinez déjà dans un plan de travail; Sélectionner \"Dessiner en 3d\" " "avant de créer un nouveau plan de travail." -#: mouse.cpp:1111 +#: mouse.cpp:1110 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1562,11 +1566,11 @@ msgstr "" "Impossible de dessiner du texte en 3d; D'abord, activer un plan de travail " "avec \"Dessin -> Dans plan de travail\"." -#: mouse.cpp:1128 +#: mouse.cpp:1127 msgid "click to place bottom right of text" msgstr "" -#: mouse.cpp:1134 +#: mouse.cpp:1133 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1574,11 +1578,11 @@ msgstr "" "Impossible de dessiner l'image en 3d; D'abord, activez un plan de travail " "avec \"Dessin -> Dans plan de travail\"." -#: mouse.cpp:1161 +#: mouse.cpp:1160 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NOUVEAU COMMENTAIRE - DOUBLE-CLIQUE POUR EDITER" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1663,33 +1667,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 msgid "untitled" msgstr "sans nom" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1562 +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "Sauver fichier" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1564 +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "Ouvrir Fichier" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1368 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 msgctxt "button" msgid "_Cancel" msgstr "_Annuler" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 msgctxt "button" msgid "_Save" msgstr "_Sauver" -#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 msgctxt "button" msgid "_Open" msgstr "" @@ -1719,74 +1723,74 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:551 +#: solvespace.cpp:557 msgctxt "title" msgid "Modified File" msgstr "Fichier modifié" -#: solvespace.cpp:553 +#: solvespace.cpp:559 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:556 +#: solvespace.cpp:562 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:559 +#: solvespace.cpp:565 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:560 +#: solvespace.cpp:566 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:562 +#: solvespace.cpp:568 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:583 +#: solvespace.cpp:589 msgctxt "title" msgid "(new sketch)" msgstr "(nouveau dessin)" -#: solvespace.cpp:590 +#: solvespace.cpp:596 msgctxt "title" msgid "Property Browser" msgstr "Navigateur de propriété" -#: solvespace.cpp:650 +#: solvespace.cpp:658 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" -#: solvespace.cpp:718 +#: solvespace.cpp:730 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" -#: solvespace.cpp:766 +#: solvespace.cpp:778 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:770 +#: solvespace.cpp:782 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:794 +#: solvespace.cpp:806 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:810 +#: solvespace.cpp:822 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1794,7 +1798,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:819 +#: solvespace.cpp:831 #, c-format msgid "" "\n" @@ -1803,7 +1807,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:824 +#: solvespace.cpp:836 msgid "" "\n" "\n" @@ -1811,7 +1815,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:839 +#: solvespace.cpp:851 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1822,13 +1826,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:848 +#: solvespace.cpp:860 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:872 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1839,7 +1843,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:880 +#: solvespace.cpp:892 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1850,36 +1854,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:886 +#: solvespace.cpp:898 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:902 +#: solvespace.cpp:914 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:925 +#: solvespace.cpp:941 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:955 +#: solvespace.cpp:971 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:972 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:958 +#: solvespace.cpp:974 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:959 +#: solvespace.cpp:975 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:962 +#: solvespace.cpp:978 #, c-format msgid "" "\n" @@ -1887,7 +1891,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:966 +#: solvespace.cpp:982 #, c-format msgid "" "%s\n" @@ -1897,7 +1901,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:969 +#: solvespace.cpp:985 #, c-format msgid "" "%s\n" @@ -1907,7 +1911,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:982 +#: solvespace.cpp:998 #, c-format msgid "" "This is SolveSpace version %s.\n" @@ -2057,31 +2061,39 @@ msgid "New group rotating active sketch" msgstr "Nouveau groupe de révolution du dessin actif" #: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 msgid "New group step and repeat rotating" msgstr "Nouveau groupe de répétition circulaire" -#: toolbar.cpp:74 +#: toolbar.cpp:78 msgid "New group step and repeat translating" msgstr "Nouveau groupe de répétition linéaire" -#: toolbar.cpp:76 +#: toolbar.cpp:80 msgid "New group in new workplane (thru given entities)" msgstr "" "Nouveau groupe dans un nouveau plan de travail (Par des entités données)" -#: toolbar.cpp:78 +#: toolbar.cpp:82 msgid "New group in 3d" msgstr "Nouveau groupe en 3d" -#: toolbar.cpp:80 +#: toolbar.cpp:84 msgid "New group linking / assembling file" msgstr "Nouveau groupe lié / assemblage" -#: toolbar.cpp:84 +#: toolbar.cpp:88 msgid "Nearest isometric view" msgstr "Vue isométrique la plus proche" -#: toolbar.cpp:86 +#: toolbar.cpp:90 msgid "Align view to active workplane" msgstr "Aligner la vue sur le plan de travail actif" diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po index c098caaf..07bab48f 100644 --- a/res/locales/ru_RU.po +++ b/res/locales/ru_RU.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-23 07:36+0100\n" +"POT-Creation-Date: 2021-01-15 14:51-0600\n" "PO-Revision-Date: 2017-04-21 10:29+0700\n" "Last-Translator: evilspirit@evilspirit.org\n" "Language-Team: EvilSpirit\n" @@ -17,7 +17,7 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 2.0.1\n" -#: clipboard.cpp:274 +#: clipboard.cpp:310 msgid "" "Cut, paste, and copy work only in a workplane.\n" "\n" @@ -27,50 +27,50 @@ msgstr "" "можно только находясь в рабочей плоскости.\n" "Активируйте рабочую плоскость через Эскиз->В Рабочей Плоскости" -#: clipboard.cpp:291 +#: clipboard.cpp:327 msgid "Clipboard is empty; nothing to paste." msgstr "Буфер обмена пуст; нечего вставлять." -#: clipboard.cpp:338 +#: clipboard.cpp:374 msgid "Number of copies to paste must be at least one." msgstr "Укажите в поле 'количество' хотя бы одну копию для вставки." -#: clipboard.cpp:354 textscreens.cpp:783 +#: clipboard.cpp:390 textscreens.cpp:783 msgid "Scale cannot be zero." msgstr "Масштабный коэффициент не может быть нулевым." -#: clipboard.cpp:396 +#: clipboard.cpp:432 msgid "Select one point to define origin of rotation." msgstr "Выберите одну точку в качестве центра вращения." -#: clipboard.cpp:408 +#: clipboard.cpp:444 msgid "Select two points to define translation vector." msgstr "Выберите две точки, чтобы задать вектор смещения." -#: clipboard.cpp:418 +#: clipboard.cpp:454 msgid "" "Transformation is identity. So all copies will be exactly on top of each " "other." msgstr "" "Трансформация не задана. Все копии будут расположены в одном и том же месте." -#: clipboard.cpp:422 +#: clipboard.cpp:458 msgid "Too many items to paste; split this into smaller pastes." msgstr "Слишком много элементов для вставки; разбейте на несколько частей." -#: clipboard.cpp:427 +#: clipboard.cpp:463 msgid "No workplane active." msgstr "Рабочая плоскость не активна" -#: confscreen.cpp:410 +#: confscreen.cpp:418 msgid "Bad format: specify coordinates as x, y, z" msgstr "Неверный формат: введите координаты как x, y, z" -#: confscreen.cpp:420 style.cpp:659 textscreens.cpp:805 +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 msgid "Bad format: specify color as r, g, b" msgstr "Неверный формат: введите цвет как r, g, b" -#: confscreen.cpp:446 +#: confscreen.cpp:454 msgid "" "The perspective factor will have no effect until you enable View -> Use " "Perspective Projection." @@ -78,25 +78,25 @@ msgstr "" "Коэффициент перспективы не будет иметь эффект, пока вы не включите Вид-" ">Перспективная Проекция." -#: confscreen.cpp:459 confscreen.cpp:469 +#: confscreen.cpp:467 confscreen.cpp:477 #, c-format msgid "Specify between 0 and %d digits after the decimal." msgstr "Введите число от 0 до %d." -#: confscreen.cpp:481 +#: confscreen.cpp:489 msgid "Export scale must not be zero!" msgstr "Масштабный коэффициент не может быть нулевым!" -#: confscreen.cpp:493 +#: confscreen.cpp:501 msgid "Cutter radius offset must not be negative!" msgstr "Радиус режущего инструмента не может быть отрицательным!" -#: confscreen.cpp:547 +#: confscreen.cpp:555 msgid "Bad value: autosave interval should be positive" msgstr "" "Неверное значение: интервал автосохранения должен быть положительным числом" -#: confscreen.cpp:550 +#: confscreen.cpp:558 msgid "Bad format: specify interval in integral minutes" msgstr "" "Неверный формат: введите целое число, чтобы задать интервал автосохранения" @@ -276,7 +276,34 @@ msgctxt "constr-name" msgid "comment" msgstr "комментарий" -#: constraint.cpp:171 +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" +"Дуга и отрезок должны быть соединены. Соедините их крайние точки с помощью " +"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " +"касательности." + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"Сплайн и отрезок должны быть соединены. Соедините их крайние точки с помощью " +"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " +"касательности." + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" +"Кривые должны быть соединены. Соедините их крайние точки с помощью " +"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " +"касательности." + +#: constraint.cpp:231 msgid "" "Bad selection for distance / diameter constraint. This constraint can apply " "to:\n" @@ -301,7 +328,7 @@ msgstr "" " * грань и точку (расстояние от точки до плоскости грани)\n" " * окружность или дугу (диаметр / радиус)\n" -#: constraint.cpp:224 +#: constraint.cpp:284 msgid "" "Bad selection for on point / curve / plane constraint. This constraint can " "apply to:\n" @@ -321,7 +348,7 @@ msgstr "" " * точку и окружность / дугу / сплайн (точка на кривой)\n" " * точку и грань (точка на грани)\n" -#: constraint.cpp:286 +#: constraint.cpp:346 msgid "" "Bad selection for equal length / radius constraint. This constraint can " "apply to:\n" @@ -349,7 +376,7 @@ msgstr "" " * две окружности / дуги (равенство радиусов)\n" " * отрезок и дугу (равенство длины отрезка и длины дуги)\n" -#: constraint.cpp:325 +#: constraint.cpp:385 msgid "" "Bad selection for length ratio constraint. This constraint can apply to:\n" "\n" @@ -360,7 +387,7 @@ msgstr "" "\n" " * два отрезка\n" -#: constraint.cpp:342 +#: constraint.cpp:402 msgid "" "Bad selection for length difference constraint. This constraint can apply " "to:\n" @@ -372,7 +399,7 @@ msgstr "" "\n" " * два отрезка\n" -#: constraint.cpp:368 +#: constraint.cpp:428 msgid "" "Bad selection for at midpoint constraint. This constraint can apply to:\n" "\n" @@ -385,7 +412,7 @@ msgstr "" " * точку и отрезок (точка на середине отрезка)\n" " * отрезок и рабочую плоскость (середина отрезка на плоскости)\n" -#: constraint.cpp:426 +#: constraint.cpp:486 msgid "" "Bad selection for symmetric constraint. This constraint can apply to:\n" "\n" @@ -405,7 +432,7 @@ msgstr "" " * рабочую плоскость и две точки / отрезок (симметричность относительно " "рабочей плоскости\n" -#: constraint.cpp:440 +#: constraint.cpp:500 msgid "" "A workplane must be active when constraining symmetric without an explicit " "symmetry plane." @@ -413,7 +440,7 @@ msgstr "" "Рабочая плоскость должна быть активна для того, чтобы создать\n" "ограничение симметричности без явного указания плоскости симметрии." -#: constraint.cpp:470 +#: constraint.cpp:530 msgid "" "Activate a workplane (with Sketch -> In Workplane) before applying a " "horizontal or vertical constraint." @@ -421,7 +448,7 @@ msgstr "" "Рабочая плоскость должна быть активирована (Эскиз -> В рабочей плоскости)\n" "перед тем, как накладывать ограничения горизонтальности / вертикальности." -#: constraint.cpp:483 +#: constraint.cpp:543 msgid "" "Bad selection for horizontal / vertical constraint. This constraint can " "apply to:\n" @@ -435,7 +462,7 @@ msgstr "" " * две точки\n" " * отрезок\n" -#: constraint.cpp:504 +#: constraint.cpp:564 msgid "" "Bad selection for same orientation constraint. This constraint can apply " "to:\n" @@ -447,18 +474,18 @@ msgstr "" "\n" " * два координатных базиса('нормали')\n" -#: constraint.cpp:554 +#: constraint.cpp:614 msgid "Must select an angle constraint." msgstr "" "Переключатся между смежными углами можно только выбрав ограничение угла." -#: constraint.cpp:567 +#: constraint.cpp:627 msgid "Must select a constraint with associated label." msgstr "" "Переключать режим 'размера для справок' возможно только для ограничений, " "имеющих размерное значение." -#: constraint.cpp:578 +#: constraint.cpp:638 msgid "" "Bad selection for angle constraint. This constraint can apply to:\n" "\n" @@ -473,39 +500,12 @@ msgstr "" " * отрезок и координатный базис (нормаль)\n" " * два координатных базиса (нормали)\n" -#: constraint.cpp:635 -msgid "" -"The tangent arc and line segment must share an endpoint. Constrain them with " -"Constrain -> On Point before constraining tangent." -msgstr "" -"Дуга и отрезок должны быть соединены. Соедините их крайние точки с помощью " -"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " -"касательности." - -#: constraint.cpp:659 -msgid "" -"The tangent cubic and line segment must share an endpoint. Constrain them " -"with Constrain -> On Point before constraining tangent." -msgstr "" -"Сплайн и отрезок должны быть соединены. Соедините их крайние точки с помощью " -"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " -"касательности." - -#: constraint.cpp:669 +#: constraint.cpp:701 msgid "Curve-curve tangency must apply in workplane." msgstr "" "Ограничение касательности может быть наложено только в рабочей плоскости." -#: constraint.cpp:687 -msgid "" -"The curves must share an endpoint. Constrain them with Constrain -> On Point " -"before constraining tangent." -msgstr "" -"Кривые должны быть соединены. Соедините их крайние точки с помощью " -"'Ограничения -> Точка на Примитиве' перед тем, как применять ограничение " -"касательности." - -#: constraint.cpp:696 +#: constraint.cpp:711 msgid "" "Bad selection for parallel / tangent constraint. This constraint can apply " "to:\n" @@ -524,7 +524,7 @@ msgstr "" " * два отрезка, две дуги или два сплайна, соединенных крайними точками " "(касательность)\n" -#: constraint.cpp:714 +#: constraint.cpp:729 msgid "" "Bad selection for perpendicular constraint. This constraint can apply to:\n" "\n" @@ -539,7 +539,7 @@ msgstr "" " * отрезок и координатный базис (нормаль)\n" " * два координатных базиса (нормали)\n" -#: constraint.cpp:729 +#: constraint.cpp:744 msgid "" "Bad selection for lock point where dragged constraint. This constraint can " "apply to:\n" @@ -551,7 +551,7 @@ msgstr "" "\n" " * точку\n" -#: constraint.cpp:740 +#: constraint.cpp:755 msgid "click center of comment text" msgstr "кликните мышью там, где будет расположен текстовый комментарий" @@ -648,7 +648,7 @@ msgctxt "button" msgid "&No" msgstr "Нет" -#: file.cpp:869 solvespace.cpp:563 +#: file.cpp:869 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "Отменить" @@ -814,299 +814,303 @@ msgid "Show Snap &Grid" msgstr "Показать &Сетку" #: graphicswin.cpp:95 +msgid "Dim Solid for Sketch Groups" +msgstr "" + +#: graphicswin.cpp:96 msgid "Use &Perspective Projection" msgstr "Перспективная Прое&кция" -#: graphicswin.cpp:96 +#: graphicswin.cpp:97 msgid "Dimension &Units" msgstr "" -#: graphicswin.cpp:97 +#: graphicswin.cpp:98 msgid "Dimensions in &Millimeters" msgstr "Размеры в Ми&ллиметрах" -#: graphicswin.cpp:98 +#: graphicswin.cpp:99 msgid "Dimensions in M&eters" msgstr "" -#: graphicswin.cpp:99 +#: graphicswin.cpp:100 msgid "Dimensions in &Inches" msgstr "Размеры в Дю&ймах" -#: graphicswin.cpp:101 +#: graphicswin.cpp:102 msgid "Show &Toolbar" msgstr "Показывать Па&нель Инструментов" -#: graphicswin.cpp:102 +#: graphicswin.cpp:103 msgid "Show Property Bro&wser" msgstr "Показывать Брау&зер" -#: graphicswin.cpp:104 +#: graphicswin.cpp:105 msgid "&Full Screen" msgstr "Полно&экранный Режим" -#: graphicswin.cpp:106 +#: graphicswin.cpp:107 msgid "&New Group" msgstr "&Группа" -#: graphicswin.cpp:107 +#: graphicswin.cpp:108 msgid "Sketch In &3d" msgstr "Создать Эскиз в &3d" -#: graphicswin.cpp:108 +#: graphicswin.cpp:109 msgid "Sketch In New &Workplane" msgstr "Создать Эскиз в Новой &Рабочей Плоскости" -#: graphicswin.cpp:110 +#: graphicswin.cpp:111 msgid "Step &Translating" msgstr "&Линейный Массив" -#: graphicswin.cpp:111 +#: graphicswin.cpp:112 msgid "Step &Rotating" msgstr "&Круговой Массив" -#: graphicswin.cpp:113 +#: graphicswin.cpp:114 msgid "E&xtrude" msgstr "Тело &Выдавливания" -#: graphicswin.cpp:114 +#: graphicswin.cpp:115 msgid "&Helix" msgstr "" -#: graphicswin.cpp:115 +#: graphicswin.cpp:116 msgid "&Lathe" msgstr "Тело В&ращения" -#: graphicswin.cpp:116 +#: graphicswin.cpp:117 msgid "Re&volve" msgstr "" -#: graphicswin.cpp:118 +#: graphicswin.cpp:119 msgid "Link / Assemble..." msgstr "&Импорт Детали / Сборка..." -#: graphicswin.cpp:119 +#: graphicswin.cpp:120 msgid "Link Recent" msgstr "Последние &Детали" -#: graphicswin.cpp:121 +#: graphicswin.cpp:122 msgid "&Sketch" msgstr "&Эскиз" -#: graphicswin.cpp:122 +#: graphicswin.cpp:123 msgid "In &Workplane" msgstr "В &Рабочей Плоскости" -#: graphicswin.cpp:123 +#: graphicswin.cpp:124 msgid "Anywhere In &3d" msgstr "Режим &3d" -#: graphicswin.cpp:125 +#: graphicswin.cpp:126 msgid "Datum &Point" msgstr "Опорная &Точка" -#: graphicswin.cpp:126 +#: graphicswin.cpp:127 msgid "&Workplane" msgstr "Рабочая &Плоскость" -#: graphicswin.cpp:128 +#: graphicswin.cpp:129 msgid "Line &Segment" msgstr "&Отрезок" -#: graphicswin.cpp:129 +#: graphicswin.cpp:130 msgid "C&onstruction Line Segment" msgstr "&Вспомогательный Отрезок" -#: graphicswin.cpp:130 +#: graphicswin.cpp:131 msgid "&Rectangle" msgstr "Прямоу&гольник" -#: graphicswin.cpp:131 +#: graphicswin.cpp:132 msgid "&Circle" msgstr "О&кружность" -#: graphicswin.cpp:132 +#: graphicswin.cpp:133 msgid "&Arc of a Circle" msgstr "Д&уга Окружности" -#: graphicswin.cpp:133 +#: graphicswin.cpp:134 msgid "&Bezier Cubic Spline" msgstr "Кубический &Сплайн Безье" -#: graphicswin.cpp:135 +#: graphicswin.cpp:136 msgid "&Text in TrueType Font" msgstr "Т&екст TrueType" -#: graphicswin.cpp:136 +#: graphicswin.cpp:137 msgid "&Image" msgstr "И&зображение" -#: graphicswin.cpp:138 +#: graphicswin.cpp:139 msgid "To&ggle Construction" msgstr "Переключить Режим Вс&помогательных Построений" -#: graphicswin.cpp:139 +#: graphicswin.cpp:140 msgid "Tangent &Arc at Point" msgstr "Кас&ательная в Точке" -#: graphicswin.cpp:140 +#: graphicswin.cpp:141 msgid "Split Curves at &Intersection" msgstr "Ра&збить Кривые Пересечением" -#: graphicswin.cpp:142 +#: graphicswin.cpp:143 msgid "&Constrain" msgstr "&Ограничения" -#: graphicswin.cpp:143 +#: graphicswin.cpp:144 msgid "&Distance / Diameter" msgstr "&Расстояние / Диаметр" -#: graphicswin.cpp:144 +#: graphicswin.cpp:145 msgid "Re&ference Dimension" msgstr "&Справочный Размер" -#: graphicswin.cpp:145 +#: graphicswin.cpp:146 msgid "A&ngle" msgstr "&Угол" -#: graphicswin.cpp:146 +#: graphicswin.cpp:147 msgid "Reference An&gle" msgstr "С&правочный Угол" -#: graphicswin.cpp:147 +#: graphicswin.cpp:148 msgid "Other S&upplementary Angle" msgstr "Переключить Сме&жный Угол" -#: graphicswin.cpp:148 +#: graphicswin.cpp:149 msgid "Toggle R&eference Dim" msgstr "Переключить Режим Размера Для Спра&вок" -#: graphicswin.cpp:150 +#: graphicswin.cpp:151 msgid "&Horizontal" msgstr "&Горизонтальность" -#: graphicswin.cpp:151 +#: graphicswin.cpp:152 msgid "&Vertical" msgstr "&Вертикальность" -#: graphicswin.cpp:153 +#: graphicswin.cpp:154 msgid "&On Point / Curve / Plane" msgstr "&Точка на Примитиве" -#: graphicswin.cpp:154 +#: graphicswin.cpp:155 msgid "E&qual Length / Radius / Angle" msgstr "&Равенство Длин / Радиусов / Углов" -#: graphicswin.cpp:155 +#: graphicswin.cpp:156 msgid "Length Ra&tio" msgstr "Отно&шение Длин" -#: graphicswin.cpp:156 +#: graphicswin.cpp:157 msgid "Length Diff&erence" msgstr "Ра&зница Длин" -#: graphicswin.cpp:157 +#: graphicswin.cpp:158 msgid "At &Midpoint" msgstr "&На Середине" -#: graphicswin.cpp:158 +#: graphicswin.cpp:159 msgid "S&ymmetric" msgstr "С&имметричность" -#: graphicswin.cpp:159 +#: graphicswin.cpp:160 msgid "Para&llel / Tangent" msgstr "Пара&ллельность / Касательность" -#: graphicswin.cpp:160 +#: graphicswin.cpp:161 msgid "&Perpendicular" msgstr "Перпендикул&ярность" -#: graphicswin.cpp:161 +#: graphicswin.cpp:162 msgid "Same Orient&ation" msgstr "Идентичная &Ориентация" -#: graphicswin.cpp:162 +#: graphicswin.cpp:163 msgid "Lock Point Where &Dragged" msgstr "За&фиксировать" -#: graphicswin.cpp:164 +#: graphicswin.cpp:165 msgid "Comment" msgstr "Текстовый &Комментарий" -#: graphicswin.cpp:166 +#: graphicswin.cpp:167 msgid "&Analyze" msgstr "&Анализ" -#: graphicswin.cpp:167 +#: graphicswin.cpp:168 msgid "Measure &Volume" msgstr "Измерить &Объем" -#: graphicswin.cpp:168 +#: graphicswin.cpp:169 msgid "Measure A&rea" msgstr "Измерить П&лощадь" -#: graphicswin.cpp:169 +#: graphicswin.cpp:170 msgid "Measure &Perimeter" msgstr "Измерить П&ериметр" -#: graphicswin.cpp:170 +#: graphicswin.cpp:171 msgid "Show &Interfering Parts" msgstr "Показать Пе&ресекающиеся Детали" -#: graphicswin.cpp:171 +#: graphicswin.cpp:172 msgid "Show &Naked Edges" msgstr "Показать Про&блемные Ребра" -#: graphicswin.cpp:172 +#: graphicswin.cpp:173 msgid "Show &Center of Mass" msgstr "" -#: graphicswin.cpp:174 +#: graphicswin.cpp:175 msgid "Show &Underconstrained Points" msgstr "" -#: graphicswin.cpp:176 +#: graphicswin.cpp:177 msgid "&Trace Point" msgstr "Включить &Трассировку Точки" -#: graphicswin.cpp:177 +#: graphicswin.cpp:178 msgid "&Stop Tracing..." msgstr "Остановить Тра&ссировку..." -#: graphicswin.cpp:178 +#: graphicswin.cpp:179 msgid "Step &Dimension..." msgstr "Плавное Из&менение Размера..." -#: graphicswin.cpp:180 +#: graphicswin.cpp:181 msgid "&Help" msgstr "&Помощь" -#: graphicswin.cpp:181 +#: graphicswin.cpp:182 msgid "&Language" msgstr "&Язык" -#: graphicswin.cpp:182 +#: graphicswin.cpp:183 msgid "&Website / Manual" msgstr "Вебсайт / &Справка" -#: graphicswin.cpp:184 +#: graphicswin.cpp:185 msgid "&About" msgstr "О &Программе" -#: graphicswin.cpp:352 +#: graphicswin.cpp:355 msgid "(no recent files)" msgstr "(пусто)" -#: graphicswin.cpp:360 +#: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." msgstr "" -#: graphicswin.cpp:721 +#: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." msgstr "Сетку не будет видно, пока рабочая плоскость не активирована." -#: graphicswin.cpp:730 +#: graphicswin.cpp:740 msgid "" "The perspective factor is set to zero, so the view will always be a parallel " "projection.\n" @@ -1120,16 +1124,16 @@ msgstr "" "перспективы на конфигурационной странице браузера.\n" "Значение по умолчанию 0.3." -#: graphicswin.cpp:809 +#: graphicswin.cpp:819 msgid "" "Select a point; this point will become the center of the view on screen." msgstr "Выделите точку. Вид будет отцентрован по этой точке." -#: graphicswin.cpp:1103 +#: graphicswin.cpp:1114 msgid "No additional entities share endpoints with the selected entities." msgstr "Нет дополнительных объектов, соединенных с выбранными примитивами." -#: graphicswin.cpp:1121 +#: graphicswin.cpp:1132 msgid "" "To use this command, select a point or other entity from an linked part, or " "make a link group the active group." @@ -1138,7 +1142,7 @@ msgstr "" "принадлежащий импортированной детали или активируйте группу импортированной " "детали." -#: graphicswin.cpp:1144 +#: graphicswin.cpp:1155 msgid "" "No workplane is active. Activate a workplane (with Sketch -> In Workplane) " "to define the plane for the snap grid." @@ -1146,7 +1150,7 @@ msgstr "" "Рабочая плоскость не активна. Активируйте ее через Эскиз -> В Рабочей " "Плоскости чтобы определить плоскость для сетки." -#: graphicswin.cpp:1151 +#: graphicswin.cpp:1162 msgid "" "Can't snap these items to grid; select points, text comments, or constraints " "with a label. To snap a line, select its endpoints." @@ -1155,13 +1159,13 @@ msgstr "" "текстовые комментарии или ограничения с размерными значениями. Чтобы " "привязать отрезок или другой примитив, выбирайте его точки." -#: graphicswin.cpp:1239 +#: graphicswin.cpp:1247 msgid "No workplane selected. Activating default workplane for this group." msgstr "" "Рабочая плоскость не активна. Активирована рабочая плоскость по умолчанию " "для данной группы." -#: graphicswin.cpp:1242 +#: graphicswin.cpp:1250 msgid "" "No workplane is selected, and the active group does not have a default " "workplane. Try selecting a workplane, or activating a sketch-in-new-" @@ -1171,7 +1175,7 @@ msgstr "" "по умолчанию. Попробуйте выделить рабочую плоскость или создать новую с " "помощью Группа -> Создать Эскиз в Новой Рабочей Плоскости." -#: graphicswin.cpp:1263 +#: graphicswin.cpp:1271 msgid "" "Bad selection for tangent arc at point. Select a single point, or select " "nothing to set up arc parameters." @@ -1180,53 +1184,53 @@ msgstr "" "точку, либо запустите команду без выделения, чтобы перейти к окну настроек " "этой команды." -#: graphicswin.cpp:1274 +#: graphicswin.cpp:1282 msgid "click point on arc (draws anti-clockwise)" msgstr "" "кликните мышью там, где хотите создать дугу окружности (дуга будет " "нарисована против часовой стрелки)" -#: graphicswin.cpp:1275 +#: graphicswin.cpp:1283 msgid "click to place datum point" msgstr "кликните мышью там, где хотите создать опорную точку" -#: graphicswin.cpp:1276 +#: graphicswin.cpp:1284 msgid "click first point of line segment" msgstr "кликните мышью там, где хотите создать первую точку отрезка" -#: graphicswin.cpp:1278 +#: graphicswin.cpp:1286 msgid "click first point of construction line segment" msgstr "" "кликните мышью там, где хотите создать первую точку вспомогательного отрезка" -#: graphicswin.cpp:1279 +#: graphicswin.cpp:1287 msgid "click first point of cubic segment" msgstr "" "кликните мышью там, где хотите создать первую точку кубического сплайна Безье" -#: graphicswin.cpp:1280 +#: graphicswin.cpp:1288 msgid "click center of circle" msgstr "кликните мышью там, где будет находиться центр окружности" -#: graphicswin.cpp:1281 +#: graphicswin.cpp:1289 msgid "click origin of workplane" msgstr "" "кликните мышью там, где будет находиться точка, через которую будет " "построена рабочая плоскость" -#: graphicswin.cpp:1282 +#: graphicswin.cpp:1290 msgid "click one corner of rectangle" msgstr "кликните мышью там, где будет находиться один из углов прямоугольника" -#: graphicswin.cpp:1283 +#: graphicswin.cpp:1291 msgid "click top left of text" msgstr "кликните мышью там, где хотите создать текст" -#: graphicswin.cpp:1289 +#: graphicswin.cpp:1297 msgid "click top left of image" msgstr "" -#: graphicswin.cpp:1301 +#: graphicswin.cpp:1309 msgid "" "No entities are selected. Select entities before trying to toggle their " "construction state." @@ -1366,19 +1370,19 @@ msgstr "линейный-массив" msgid "(unnamed)" msgstr "(без имени)" -#: groupmesh.cpp:708 +#: groupmesh.cpp:709 msgid "not closed contour, or not all same style!" msgstr "незамкнутый контур или несовпадение стилей!" -#: groupmesh.cpp:721 +#: groupmesh.cpp:722 msgid "points not all coplanar!" msgstr "не все точки лежат в одной плоскости!" -#: groupmesh.cpp:723 +#: groupmesh.cpp:724 msgid "contour is self-intersecting!" msgstr "контур имеет самопересечения!" -#: groupmesh.cpp:725 +#: groupmesh.cpp:726 msgid "zero-length edge!" msgstr "вырожденный отрезок!" @@ -1519,69 +1523,69 @@ msgstr "Снять Выделение с Выбранного" msgid "Zoom to Fit" msgstr "Показать Все" -#: mouse.cpp:990 mouse.cpp:1277 +#: mouse.cpp:989 mouse.cpp:1276 msgid "click next point of line, or press Esc" msgstr "кликните мышью там, где хотите расположить следующую точку" -#: mouse.cpp:996 +#: mouse.cpp:995 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" "Невозможно начертить прямоугольник, когда рабочая плоскость не активна." -#: mouse.cpp:1030 +#: mouse.cpp:1029 msgid "click to place other corner of rectangle" msgstr "кликните мышью там, где хотите расположить другой угол прямоугольника" -#: mouse.cpp:1050 +#: mouse.cpp:1049 msgid "click to set radius" msgstr "кликните, чтобы задать радиус" -#: mouse.cpp:1055 +#: mouse.cpp:1054 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "Невозможно создать дугу, когда нет активной рабочей плоскости." -#: mouse.cpp:1074 +#: mouse.cpp:1073 msgid "click to place point" msgstr "кликните мышью там, где хотите создать точку" -#: mouse.cpp:1090 +#: mouse.cpp:1089 msgid "click next point of cubic, or press Esc" msgstr "" "кликните мышью там, где хотите создать следующую точку сплайна или нажмите " "Esc для завершения операции." -#: mouse.cpp:1095 +#: mouse.cpp:1094 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" "Рабочая плоскость уже активна. Перейдите в режим 3d перед созданием новой " "рабочей плоскости." -#: mouse.cpp:1111 +#: mouse.cpp:1110 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "Невозможно создать текст, когда нет активной рабочей плоскости." -#: mouse.cpp:1128 +#: mouse.cpp:1127 msgid "click to place bottom right of text" msgstr "" -#: mouse.cpp:1134 +#: mouse.cpp:1133 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1161 +#: mouse.cpp:1160 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 msgctxt "file-type" msgid "SolveSpace models" msgstr "проекты SolveSpace" @@ -1666,33 +1670,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "CSV файлы (значения, разделенные запятой)" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 msgid "untitled" msgstr "без имени" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1562 +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "Сохранить Файл" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1564 +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "Открыть Файл" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1368 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 msgctxt "button" msgid "_Cancel" msgstr "Отменить" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 msgctxt "button" msgid "_Save" msgstr "Сохранить" -#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 msgctxt "button" msgid "_Open" msgstr "" @@ -1722,74 +1726,74 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:551 +#: solvespace.cpp:557 msgctxt "title" msgid "Modified File" msgstr "Измененный Файл" -#: solvespace.cpp:553 +#: solvespace.cpp:559 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:556 +#: solvespace.cpp:562 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:559 +#: solvespace.cpp:565 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:560 +#: solvespace.cpp:566 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:562 +#: solvespace.cpp:568 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:583 +#: solvespace.cpp:589 msgctxt "title" msgid "(new sketch)" msgstr "(новый проект)" -#: solvespace.cpp:590 +#: solvespace.cpp:596 msgctxt "title" msgid "Property Browser" msgstr "Браузер" -#: solvespace.cpp:650 +#: solvespace.cpp:658 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" -#: solvespace.cpp:718 +#: solvespace.cpp:730 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" -#: solvespace.cpp:766 +#: solvespace.cpp:778 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:770 +#: solvespace.cpp:782 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:794 +#: solvespace.cpp:806 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:810 +#: solvespace.cpp:822 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1797,7 +1801,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:819 +#: solvespace.cpp:831 #, c-format msgid "" "\n" @@ -1806,7 +1810,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:824 +#: solvespace.cpp:836 msgid "" "\n" "\n" @@ -1814,7 +1818,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:839 +#: solvespace.cpp:851 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1825,13 +1829,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:848 +#: solvespace.cpp:860 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:872 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1842,7 +1846,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:880 +#: solvespace.cpp:892 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1853,36 +1857,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:886 +#: solvespace.cpp:898 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:902 +#: solvespace.cpp:914 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:925 +#: solvespace.cpp:941 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:955 +#: solvespace.cpp:971 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:972 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:958 +#: solvespace.cpp:974 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:959 +#: solvespace.cpp:975 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:962 +#: solvespace.cpp:978 #, c-format msgid "" "\n" @@ -1890,7 +1894,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:966 +#: solvespace.cpp:982 #, c-format msgid "" "%s\n" @@ -1900,7 +1904,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:969 +#: solvespace.cpp:985 #, c-format msgid "" "%s\n" @@ -1910,7 +1914,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:982 +#: solvespace.cpp:998 #, c-format msgid "" "This is SolveSpace version %s.\n" @@ -2060,30 +2064,38 @@ msgid "New group rotating active sketch" msgstr "Создать группу вращения текущего эскиза" #: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 msgid "New group step and repeat rotating" msgstr "Создать группу кругового массива" -#: toolbar.cpp:74 +#: toolbar.cpp:78 msgid "New group step and repeat translating" msgstr "Создать группу линейного массива" -#: toolbar.cpp:76 +#: toolbar.cpp:80 msgid "New group in new workplane (thru given entities)" msgstr "Создать группу в новой рабочей плоскости (через выбранные примитивы)" -#: toolbar.cpp:78 +#: toolbar.cpp:82 msgid "New group in 3d" msgstr "Новая группа в 3d" -#: toolbar.cpp:80 +#: toolbar.cpp:84 msgid "New group linking / assembling file" msgstr "Новая группа импорта детали / сборки" -#: toolbar.cpp:84 +#: toolbar.cpp:88 msgid "Nearest isometric view" msgstr "Ближайший изометрический вид" -#: toolbar.cpp:86 +#: toolbar.cpp:90 msgid "Align view to active workplane" msgstr "Выровнять вид на рабочую плоскость" diff --git a/res/locales/uk_UA.po b/res/locales/uk_UA.po index 89fd5ac0..3922b16b 100644 --- a/res/locales/uk_UA.po +++ b/res/locales/uk_UA.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-23 07:36+0100\n" +"POT-Creation-Date: 2021-01-15 14:51-0600\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: appsoft@ua.fm\n" "Language-Team: OpenOrienteeringUkraine\n" @@ -16,79 +16,79 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: clipboard.cpp:274 +#: clipboard.cpp:310 msgid "" "Cut, paste, and copy work only in a workplane.\n" "\n" "Activate one with Sketch -> In Workplane." msgstr "" -#: clipboard.cpp:291 +#: clipboard.cpp:327 msgid "Clipboard is empty; nothing to paste." msgstr "" -#: clipboard.cpp:338 +#: clipboard.cpp:374 msgid "Number of copies to paste must be at least one." msgstr "" -#: clipboard.cpp:354 textscreens.cpp:783 +#: clipboard.cpp:390 textscreens.cpp:783 msgid "Scale cannot be zero." msgstr "" -#: clipboard.cpp:396 +#: clipboard.cpp:432 msgid "Select one point to define origin of rotation." msgstr "" -#: clipboard.cpp:408 +#: clipboard.cpp:444 msgid "Select two points to define translation vector." msgstr "" -#: clipboard.cpp:418 +#: clipboard.cpp:454 msgid "" "Transformation is identity. So all copies will be exactly on top of each " "other." msgstr "" -#: clipboard.cpp:422 +#: clipboard.cpp:458 msgid "Too many items to paste; split this into smaller pastes." msgstr "" -#: clipboard.cpp:427 +#: clipboard.cpp:463 msgid "No workplane active." msgstr "" -#: confscreen.cpp:410 +#: confscreen.cpp:418 msgid "Bad format: specify coordinates as x, y, z" msgstr "" -#: confscreen.cpp:420 style.cpp:659 textscreens.cpp:805 +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 msgid "Bad format: specify color as r, g, b" msgstr "" -#: confscreen.cpp:446 +#: confscreen.cpp:454 msgid "" "The perspective factor will have no effect until you enable View -> Use " "Perspective Projection." msgstr "" -#: confscreen.cpp:459 confscreen.cpp:469 +#: confscreen.cpp:467 confscreen.cpp:477 #, c-format msgid "Specify between 0 and %d digits after the decimal." msgstr "" -#: confscreen.cpp:481 +#: confscreen.cpp:489 msgid "Export scale must not be zero!" msgstr "" -#: confscreen.cpp:493 +#: confscreen.cpp:501 msgid "Cutter radius offset must not be negative!" msgstr "" -#: confscreen.cpp:547 +#: confscreen.cpp:555 msgid "Bad value: autosave interval should be positive" msgstr "" -#: confscreen.cpp:550 +#: confscreen.cpp:558 msgid "Bad format: specify interval in integral minutes" msgstr "" @@ -267,7 +267,25 @@ msgctxt "constr-name" msgid "comment" msgstr "" -#: constraint.cpp:171 +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "" + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "" + +#: constraint.cpp:231 msgid "" "Bad selection for distance / diameter constraint. This constraint can apply " "to:\n" @@ -281,7 +299,7 @@ msgid "" " * a circle or an arc (diameter)\n" msgstr "" -#: constraint.cpp:224 +#: constraint.cpp:284 msgid "" "Bad selection for on point / curve / plane constraint. This constraint can " "apply to:\n" @@ -293,7 +311,7 @@ msgid "" " * a point and a plane face (point on face)\n" msgstr "" -#: constraint.cpp:286 +#: constraint.cpp:346 msgid "" "Bad selection for equal length / radius constraint. This constraint can " "apply to:\n" @@ -309,14 +327,14 @@ msgid "" " * a line segment and an arc (line segment length equals arc length)\n" msgstr "" -#: constraint.cpp:325 +#: constraint.cpp:385 msgid "" "Bad selection for length ratio constraint. This constraint can apply to:\n" "\n" " * two line segments\n" msgstr "" -#: constraint.cpp:342 +#: constraint.cpp:402 msgid "" "Bad selection for length difference constraint. This constraint can apply " "to:\n" @@ -324,7 +342,7 @@ msgid "" " * two line segments\n" msgstr "" -#: constraint.cpp:368 +#: constraint.cpp:428 msgid "" "Bad selection for at midpoint constraint. This constraint can apply to:\n" "\n" @@ -332,7 +350,7 @@ msgid "" " * a line segment and a workplane (line's midpoint on plane)\n" msgstr "" -#: constraint.cpp:426 +#: constraint.cpp:486 msgid "" "Bad selection for symmetric constraint. This constraint can apply to:\n" "\n" @@ -344,19 +362,19 @@ msgid "" "workplane)\n" msgstr "" -#: constraint.cpp:440 +#: constraint.cpp:500 msgid "" "A workplane must be active when constraining symmetric without an explicit " "symmetry plane." msgstr "" -#: constraint.cpp:470 +#: constraint.cpp:530 msgid "" "Activate a workplane (with Sketch -> In Workplane) before applying a " "horizontal or vertical constraint." msgstr "" -#: constraint.cpp:483 +#: constraint.cpp:543 msgid "" "Bad selection for horizontal / vertical constraint. This constraint can " "apply to:\n" @@ -365,7 +383,7 @@ msgid "" " * a line segment\n" msgstr "" -#: constraint.cpp:504 +#: constraint.cpp:564 msgid "" "Bad selection for same orientation constraint. This constraint can apply " "to:\n" @@ -373,15 +391,15 @@ msgid "" " * two normals\n" msgstr "" -#: constraint.cpp:554 +#: constraint.cpp:614 msgid "Must select an angle constraint." msgstr "" -#: constraint.cpp:567 +#: constraint.cpp:627 msgid "Must select a constraint with associated label." msgstr "" -#: constraint.cpp:578 +#: constraint.cpp:638 msgid "" "Bad selection for angle constraint. This constraint can apply to:\n" "\n" @@ -390,29 +408,11 @@ msgid "" " * two normals\n" msgstr "" -#: constraint.cpp:635 -msgid "" -"The tangent arc and line segment must share an endpoint. Constrain them with " -"Constrain -> On Point before constraining tangent." -msgstr "" - -#: constraint.cpp:659 -msgid "" -"The tangent cubic and line segment must share an endpoint. Constrain them " -"with Constrain -> On Point before constraining tangent." -msgstr "" - -#: constraint.cpp:669 +#: constraint.cpp:701 msgid "Curve-curve tangency must apply in workplane." msgstr "" -#: constraint.cpp:687 -msgid "" -"The curves must share an endpoint. Constrain them with Constrain -> On Point " -"before constraining tangent." -msgstr "" - -#: constraint.cpp:696 +#: constraint.cpp:711 msgid "" "Bad selection for parallel / tangent constraint. This constraint can apply " "to:\n" @@ -423,7 +423,7 @@ msgid "" " * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" msgstr "" -#: constraint.cpp:714 +#: constraint.cpp:729 msgid "" "Bad selection for perpendicular constraint. This constraint can apply to:\n" "\n" @@ -432,7 +432,7 @@ msgid "" " * two normals\n" msgstr "" -#: constraint.cpp:729 +#: constraint.cpp:744 msgid "" "Bad selection for lock point where dragged constraint. This constraint can " "apply to:\n" @@ -440,7 +440,7 @@ msgid "" " * a point\n" msgstr "" -#: constraint.cpp:740 +#: constraint.cpp:755 msgid "click center of comment text" msgstr "" @@ -528,7 +528,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:563 +#: file.cpp:869 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "" @@ -694,299 +694,303 @@ msgid "Show Snap &Grid" msgstr "Показати &Сітку Прикріплення" #: graphicswin.cpp:95 +msgid "Dim Solid for Sketch Groups" +msgstr "" + +#: graphicswin.cpp:96 msgid "Use &Perspective Projection" msgstr "Використовувати &Перспективну Проекцію" -#: graphicswin.cpp:96 +#: graphicswin.cpp:97 msgid "Dimension &Units" msgstr "" -#: graphicswin.cpp:97 +#: graphicswin.cpp:98 msgid "Dimensions in &Millimeters" msgstr "Розміри в &Міліметрах" -#: graphicswin.cpp:98 +#: graphicswin.cpp:99 msgid "Dimensions in M&eters" msgstr "" -#: graphicswin.cpp:99 +#: graphicswin.cpp:100 msgid "Dimensions in &Inches" msgstr "Розміри в &Дюймах" -#: graphicswin.cpp:101 +#: graphicswin.cpp:102 msgid "Show &Toolbar" msgstr "Показати Панель &Інструментів" -#: graphicswin.cpp:102 +#: graphicswin.cpp:103 msgid "Show Property Bro&wser" msgstr "Показати Вікно Власти&востей" -#: graphicswin.cpp:104 +#: graphicswin.cpp:105 msgid "&Full Screen" msgstr "&Повний Екран" -#: graphicswin.cpp:106 +#: graphicswin.cpp:107 msgid "&New Group" msgstr "&Нова Група" -#: graphicswin.cpp:107 +#: graphicswin.cpp:108 msgid "Sketch In &3d" msgstr "Креслення В &3d" -#: graphicswin.cpp:108 +#: graphicswin.cpp:109 msgid "Sketch In New &Workplane" msgstr "Креслення В Новій Робочій &Площині" -#: graphicswin.cpp:110 +#: graphicswin.cpp:111 msgid "Step &Translating" msgstr "Покрокове &Переміщення" -#: graphicswin.cpp:111 +#: graphicswin.cpp:112 msgid "Step &Rotating" msgstr "Покрокове &Обертання" -#: graphicswin.cpp:113 +#: graphicswin.cpp:114 msgid "E&xtrude" msgstr "Ви&давити" -#: graphicswin.cpp:114 +#: graphicswin.cpp:115 msgid "&Helix" msgstr "" -#: graphicswin.cpp:115 +#: graphicswin.cpp:116 msgid "&Lathe" msgstr "&Виточити" -#: graphicswin.cpp:116 +#: graphicswin.cpp:117 msgid "Re&volve" msgstr "" -#: graphicswin.cpp:118 +#: graphicswin.cpp:119 msgid "Link / Assemble..." msgstr "Приєднати / Монтувати..." -#: graphicswin.cpp:119 +#: graphicswin.cpp:120 msgid "Link Recent" msgstr "Приєднати Недавні" -#: graphicswin.cpp:121 +#: graphicswin.cpp:122 msgid "&Sketch" msgstr "&Креслення" -#: graphicswin.cpp:122 +#: graphicswin.cpp:123 msgid "In &Workplane" msgstr "В Робочій &Площині" -#: graphicswin.cpp:123 +#: graphicswin.cpp:124 msgid "Anywhere In &3d" msgstr "Будь-де В &3d" -#: graphicswin.cpp:125 +#: graphicswin.cpp:126 msgid "Datum &Point" msgstr "Опорна &Точка" -#: graphicswin.cpp:126 +#: graphicswin.cpp:127 msgid "&Workplane" msgstr "Робоча &Площина" -#: graphicswin.cpp:128 +#: graphicswin.cpp:129 msgid "Line &Segment" msgstr "&Відрізок Прямої" -#: graphicswin.cpp:129 +#: graphicswin.cpp:130 msgid "C&onstruction Line Segment" msgstr "Контсрук&ційний Відрізок Прямої" -#: graphicswin.cpp:130 +#: graphicswin.cpp:131 msgid "&Rectangle" msgstr "&Прямокутник" -#: graphicswin.cpp:131 +#: graphicswin.cpp:132 msgid "&Circle" msgstr "&Коло" -#: graphicswin.cpp:132 +#: graphicswin.cpp:133 msgid "&Arc of a Circle" msgstr "&Дуга Кола" -#: graphicswin.cpp:133 +#: graphicswin.cpp:134 msgid "&Bezier Cubic Spline" msgstr "Кубічний Сплайн &Без'є" -#: graphicswin.cpp:135 +#: graphicswin.cpp:136 msgid "&Text in TrueType Font" msgstr "&Текст з TrueType Шрифтом" -#: graphicswin.cpp:136 +#: graphicswin.cpp:137 msgid "&Image" msgstr "" -#: graphicswin.cpp:138 +#: graphicswin.cpp:139 msgid "To&ggle Construction" msgstr "Пере&мкнути Конструктивність" -#: graphicswin.cpp:139 +#: graphicswin.cpp:140 msgid "Tangent &Arc at Point" msgstr "Дотична &Дуга на Точці" -#: graphicswin.cpp:140 +#: graphicswin.cpp:141 msgid "Split Curves at &Intersection" msgstr "Розрізати Криві на &Перетині" -#: graphicswin.cpp:142 +#: graphicswin.cpp:143 msgid "&Constrain" msgstr "&Обмежити" -#: graphicswin.cpp:143 +#: graphicswin.cpp:144 msgid "&Distance / Diameter" msgstr "&Відстань / Діаметр" -#: graphicswin.cpp:144 +#: graphicswin.cpp:145 msgid "Re&ference Dimension" msgstr "Від&носний Розмір" -#: graphicswin.cpp:145 +#: graphicswin.cpp:146 msgid "A&ngle" msgstr "К&ут" -#: graphicswin.cpp:146 +#: graphicswin.cpp:147 msgid "Reference An&gle" msgstr "Відносний К&ут" -#: graphicswin.cpp:147 +#: graphicswin.cpp:148 msgid "Other S&upplementary Angle" msgstr "Інший Су&міжний Кут" -#: graphicswin.cpp:148 +#: graphicswin.cpp:149 msgid "Toggle R&eference Dim" msgstr "Перемкнути Від&носність Розмірів" -#: graphicswin.cpp:150 +#: graphicswin.cpp:151 msgid "&Horizontal" msgstr "&Горизонтально" -#: graphicswin.cpp:151 +#: graphicswin.cpp:152 msgid "&Vertical" msgstr "&Вертикально" -#: graphicswin.cpp:153 +#: graphicswin.cpp:154 msgid "&On Point / Curve / Plane" msgstr "&На точці / Кривій / Площині" -#: graphicswin.cpp:154 +#: graphicswin.cpp:155 msgid "E&qual Length / Radius / Angle" msgstr "Рі&вні Довжина / Радіус / Кут" -#: graphicswin.cpp:155 +#: graphicswin.cpp:156 msgid "Length Ra&tio" msgstr "Про&порція Довжин" -#: graphicswin.cpp:156 +#: graphicswin.cpp:157 msgid "Length Diff&erence" msgstr "Рі&зниця Довжин" -#: graphicswin.cpp:157 +#: graphicswin.cpp:158 msgid "At &Midpoint" msgstr "До &Середини" -#: graphicswin.cpp:158 +#: graphicswin.cpp:159 msgid "S&ymmetric" msgstr "Си&метрично" -#: graphicswin.cpp:159 +#: graphicswin.cpp:160 msgid "Para&llel / Tangent" msgstr "Пара&лельно / Дотична" -#: graphicswin.cpp:160 +#: graphicswin.cpp:161 msgid "&Perpendicular" msgstr "&Препендикулярно" -#: graphicswin.cpp:161 +#: graphicswin.cpp:162 msgid "Same Orient&ation" msgstr "Однакова Орієн&тація" -#: graphicswin.cpp:162 +#: graphicswin.cpp:163 msgid "Lock Point Where &Dragged" msgstr "Фіксувати Точку Після &Переміщення" -#: graphicswin.cpp:164 +#: graphicswin.cpp:165 msgid "Comment" msgstr "Коментар" -#: graphicswin.cpp:166 +#: graphicswin.cpp:167 msgid "&Analyze" msgstr "&Аналізувати" -#: graphicswin.cpp:167 +#: graphicswin.cpp:168 msgid "Measure &Volume" msgstr "Обрахувати &Об'єм" -#: graphicswin.cpp:168 +#: graphicswin.cpp:169 msgid "Measure A&rea" msgstr "Обрахувати Пл&ощу" -#: graphicswin.cpp:169 +#: graphicswin.cpp:170 msgid "Measure &Perimeter" msgstr "Обрахувати &Периметр" -#: graphicswin.cpp:170 +#: graphicswin.cpp:171 msgid "Show &Interfering Parts" msgstr "Показати &Дотичні Частини" -#: graphicswin.cpp:171 +#: graphicswin.cpp:172 msgid "Show &Naked Edges" msgstr "Показати &Приховані Ребра" -#: graphicswin.cpp:172 +#: graphicswin.cpp:173 msgid "Show &Center of Mass" msgstr "" -#: graphicswin.cpp:174 +#: graphicswin.cpp:175 msgid "Show &Underconstrained Points" msgstr "" -#: graphicswin.cpp:176 +#: graphicswin.cpp:177 msgid "&Trace Point" msgstr "&Трасувати Точку" -#: graphicswin.cpp:177 +#: graphicswin.cpp:178 msgid "&Stop Tracing..." msgstr "&Зупити Трасування..." -#: graphicswin.cpp:178 +#: graphicswin.cpp:179 msgid "Step &Dimension..." msgstr "Прорахувати &Розмір..." -#: graphicswin.cpp:180 +#: graphicswin.cpp:181 msgid "&Help" msgstr "&Довідка" -#: graphicswin.cpp:181 +#: graphicswin.cpp:182 msgid "&Language" msgstr "&Мова" -#: graphicswin.cpp:182 +#: graphicswin.cpp:183 msgid "&Website / Manual" msgstr "&Вебсайт / Посібник" -#: graphicswin.cpp:184 +#: graphicswin.cpp:185 msgid "&About" msgstr "&Про програму" -#: graphicswin.cpp:352 +#: graphicswin.cpp:355 msgid "(no recent files)" msgstr "" -#: graphicswin.cpp:360 +#: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." msgstr "" -#: graphicswin.cpp:721 +#: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." msgstr "" -#: graphicswin.cpp:730 +#: graphicswin.cpp:740 msgid "" "The perspective factor is set to zero, so the view will always be a parallel " "projection.\n" @@ -995,91 +999,91 @@ msgid "" "configuration screen. A value around 0.3 is typical." msgstr "" -#: graphicswin.cpp:809 +#: graphicswin.cpp:819 msgid "" "Select a point; this point will become the center of the view on screen." msgstr "" -#: graphicswin.cpp:1103 +#: graphicswin.cpp:1114 msgid "No additional entities share endpoints with the selected entities." msgstr "" -#: graphicswin.cpp:1121 +#: graphicswin.cpp:1132 msgid "" "To use this command, select a point or other entity from an linked part, or " "make a link group the active group." msgstr "" -#: graphicswin.cpp:1144 +#: graphicswin.cpp:1155 msgid "" "No workplane is active. Activate a workplane (with Sketch -> In Workplane) " "to define the plane for the snap grid." msgstr "" -#: graphicswin.cpp:1151 +#: graphicswin.cpp:1162 msgid "" "Can't snap these items to grid; select points, text comments, or constraints " "with a label. To snap a line, select its endpoints." msgstr "" -#: graphicswin.cpp:1239 +#: graphicswin.cpp:1247 msgid "No workplane selected. Activating default workplane for this group." msgstr "" -#: graphicswin.cpp:1242 +#: graphicswin.cpp:1250 msgid "" "No workplane is selected, and the active group does not have a default " "workplane. Try selecting a workplane, or activating a sketch-in-new-" "workplane group." msgstr "" -#: graphicswin.cpp:1263 +#: graphicswin.cpp:1271 msgid "" "Bad selection for tangent arc at point. Select a single point, or select " "nothing to set up arc parameters." msgstr "" -#: graphicswin.cpp:1274 +#: graphicswin.cpp:1282 msgid "click point on arc (draws anti-clockwise)" msgstr "" -#: graphicswin.cpp:1275 +#: graphicswin.cpp:1283 msgid "click to place datum point" msgstr "" -#: graphicswin.cpp:1276 +#: graphicswin.cpp:1284 msgid "click first point of line segment" msgstr "" -#: graphicswin.cpp:1278 +#: graphicswin.cpp:1286 msgid "click first point of construction line segment" msgstr "" -#: graphicswin.cpp:1279 +#: graphicswin.cpp:1287 msgid "click first point of cubic segment" msgstr "" -#: graphicswin.cpp:1280 +#: graphicswin.cpp:1288 msgid "click center of circle" msgstr "" -#: graphicswin.cpp:1281 +#: graphicswin.cpp:1289 msgid "click origin of workplane" msgstr "" -#: graphicswin.cpp:1282 +#: graphicswin.cpp:1290 msgid "click one corner of rectangle" msgstr "" -#: graphicswin.cpp:1283 +#: graphicswin.cpp:1291 msgid "click top left of text" msgstr "" -#: graphicswin.cpp:1289 +#: graphicswin.cpp:1297 msgid "click top left of image" msgstr "" -#: graphicswin.cpp:1301 +#: graphicswin.cpp:1309 msgid "" "No entities are selected. Select entities before trying to toggle their " "construction state." @@ -1189,19 +1193,19 @@ msgstr "" msgid "(unnamed)" msgstr "" -#: groupmesh.cpp:708 +#: groupmesh.cpp:709 msgid "not closed contour, or not all same style!" msgstr "" -#: groupmesh.cpp:721 +#: groupmesh.cpp:722 msgid "points not all coplanar!" msgstr "" -#: groupmesh.cpp:723 +#: groupmesh.cpp:724 msgid "contour is self-intersecting!" msgstr "" -#: groupmesh.cpp:725 +#: groupmesh.cpp:726 msgid "zero-length edge!" msgstr "" @@ -1331,64 +1335,64 @@ msgstr "Зняти Виділення з Наведеного" msgid "Zoom to Fit" msgstr "Умістити на Екрані" -#: mouse.cpp:990 mouse.cpp:1277 +#: mouse.cpp:989 mouse.cpp:1276 msgid "click next point of line, or press Esc" msgstr "" -#: mouse.cpp:996 +#: mouse.cpp:995 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1030 +#: mouse.cpp:1029 msgid "click to place other corner of rectangle" msgstr "" -#: mouse.cpp:1050 +#: mouse.cpp:1049 msgid "click to set radius" msgstr "" -#: mouse.cpp:1055 +#: mouse.cpp:1054 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1074 +#: mouse.cpp:1073 msgid "click to place point" msgstr "" -#: mouse.cpp:1090 +#: mouse.cpp:1089 msgid "click next point of cubic, or press Esc" msgstr "" -#: mouse.cpp:1095 +#: mouse.cpp:1094 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" -#: mouse.cpp:1111 +#: mouse.cpp:1110 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1128 +#: mouse.cpp:1127 msgid "click to place bottom right of text" msgstr "" -#: mouse.cpp:1134 +#: mouse.cpp:1133 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1161 +#: mouse.cpp:1160 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1473,33 +1477,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 msgid "untitled" msgstr "" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1562 +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1564 +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1368 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 msgctxt "button" msgid "_Cancel" msgstr "" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 msgctxt "button" msgid "_Save" msgstr "" -#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 msgctxt "button" msgid "_Open" msgstr "" @@ -1529,74 +1533,74 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:551 +#: solvespace.cpp:557 msgctxt "title" msgid "Modified File" msgstr "" -#: solvespace.cpp:553 +#: solvespace.cpp:559 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:556 +#: solvespace.cpp:562 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:559 +#: solvespace.cpp:565 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:560 +#: solvespace.cpp:566 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:562 +#: solvespace.cpp:568 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:583 +#: solvespace.cpp:589 msgctxt "title" msgid "(new sketch)" msgstr "" -#: solvespace.cpp:590 +#: solvespace.cpp:596 msgctxt "title" msgid "Property Browser" msgstr "" -#: solvespace.cpp:650 +#: solvespace.cpp:658 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" -#: solvespace.cpp:718 +#: solvespace.cpp:730 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" -#: solvespace.cpp:766 +#: solvespace.cpp:778 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:770 +#: solvespace.cpp:782 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:794 +#: solvespace.cpp:806 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:810 +#: solvespace.cpp:822 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1604,7 +1608,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:819 +#: solvespace.cpp:831 #, c-format msgid "" "\n" @@ -1613,7 +1617,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:824 +#: solvespace.cpp:836 msgid "" "\n" "\n" @@ -1621,7 +1625,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:839 +#: solvespace.cpp:851 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1632,13 +1636,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:848 +#: solvespace.cpp:860 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:872 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1649,7 +1653,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:880 +#: solvespace.cpp:892 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1660,36 +1664,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:886 +#: solvespace.cpp:898 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:902 +#: solvespace.cpp:914 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:925 +#: solvespace.cpp:941 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:955 +#: solvespace.cpp:971 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:972 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:958 +#: solvespace.cpp:974 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:959 +#: solvespace.cpp:975 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:962 +#: solvespace.cpp:978 #, c-format msgid "" "\n" @@ -1697,7 +1701,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:966 +#: solvespace.cpp:982 #, c-format msgid "" "%s\n" @@ -1707,7 +1711,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:969 +#: solvespace.cpp:985 #, c-format msgid "" "%s\n" @@ -1717,7 +1721,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:982 +#: solvespace.cpp:998 #, c-format msgid "" "This is SolveSpace version %s.\n" @@ -1865,30 +1869,38 @@ msgid "New group rotating active sketch" msgstr "Нова група обертання актиного креслення" #: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 msgid "New group step and repeat rotating" msgstr "Нова група крокування і повторення обертання" -#: toolbar.cpp:74 +#: toolbar.cpp:78 msgid "New group step and repeat translating" msgstr "Нова група крокування і повторення зміщення" -#: toolbar.cpp:76 +#: toolbar.cpp:80 msgid "New group in new workplane (thru given entities)" msgstr "Нова група в новій площині (через обрані об'екти)" -#: toolbar.cpp:78 +#: toolbar.cpp:82 msgid "New group in 3d" msgstr "Нова група в 3d" -#: toolbar.cpp:80 +#: toolbar.cpp:84 msgid "New group linking / assembling file" msgstr "Нова група приєднання / монтування файлу" -#: toolbar.cpp:84 +#: toolbar.cpp:88 msgid "Nearest isometric view" msgstr "Найближчий ізометричний вигляд" -#: toolbar.cpp:86 +#: toolbar.cpp:90 msgid "Align view to active workplane" msgstr "Вирівняти вигляд до активної робочої площини" diff --git a/res/locales/zh_CN.po b/res/locales/zh_CN.po index df48341a..34617119 100644 --- a/res/locales/zh_CN.po +++ b/res/locales/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-23 07:36+0100\n" +"POT-Creation-Date: 2021-01-15 14:51-0600\n" "PO-Revision-Date: 2020-09-28 12:42+0800\n" "Last-Translator: lomatus@163.com\n" "Language-Team: none\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.4.1\n" -#: clipboard.cpp:274 +#: clipboard.cpp:310 msgid "" "Cut, paste, and copy work only in a workplane.\n" "\n" @@ -27,72 +27,72 @@ msgstr "" "\n" "使用\"工作平面中的草图 -+\"激活一个。" -#: clipboard.cpp:291 +#: clipboard.cpp:327 msgid "Clipboard is empty; nothing to paste." msgstr "剪贴板为空;没有要粘贴的内容。" -#: clipboard.cpp:338 +#: clipboard.cpp:374 msgid "Number of copies to paste must be at least one." msgstr "要粘贴的副本数必须至少为 1 个。" -#: clipboard.cpp:354 textscreens.cpp:783 +#: clipboard.cpp:390 textscreens.cpp:783 msgid "Scale cannot be zero." msgstr "缩放不能为零。" -#: clipboard.cpp:396 +#: clipboard.cpp:432 msgid "Select one point to define origin of rotation." msgstr "选择一个点以定义旋转原点。" -#: clipboard.cpp:408 +#: clipboard.cpp:444 msgid "Select two points to define translation vector." msgstr "选择两个点来定义转换向量。" -#: clipboard.cpp:418 +#: clipboard.cpp:454 msgid "" "Transformation is identity. So all copies will be exactly on top of each " "other." msgstr "转换就是标识,因此所有的复制在彼此之上。" -#: clipboard.cpp:422 +#: clipboard.cpp:458 msgid "Too many items to paste; split this into smaller pastes." msgstr "要粘贴的项目太多; 请把他们拆分。" -#: clipboard.cpp:427 +#: clipboard.cpp:463 msgid "No workplane active." msgstr "没有工作平面处于活动状态。" -#: confscreen.cpp:410 +#: confscreen.cpp:418 msgid "Bad format: specify coordinates as x, y, z" msgstr "格式错误:将坐标指定为 x、y、z" -#: confscreen.cpp:420 style.cpp:659 textscreens.cpp:805 +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 msgid "Bad format: specify color as r, g, b" msgstr "格式错误:将颜色指定为 r、g、b" -#: confscreen.cpp:446 +#: confscreen.cpp:454 msgid "" "The perspective factor will have no effect until you enable View -> Use " "Perspective Projection." msgstr "在启用\"视图 -= 使用透视投影\"之前,透视因子将不起作用。" -#: confscreen.cpp:459 confscreen.cpp:469 +#: confscreen.cpp:467 confscreen.cpp:477 #, c-format msgid "Specify between 0 and %d digits after the decimal." msgstr "在十进制之后指定 0 和 %d 数字之间。" -#: confscreen.cpp:481 +#: confscreen.cpp:489 msgid "Export scale must not be zero!" msgstr "输出比例不能为零!" -#: confscreen.cpp:493 +#: confscreen.cpp:501 msgid "Cutter radius offset must not be negative!" msgstr "刀具半径偏移不能为负数!" -#: confscreen.cpp:547 +#: confscreen.cpp:555 msgid "Bad value: autosave interval should be positive" msgstr "坏值:自动保存间隔应为正" -#: confscreen.cpp:550 +#: confscreen.cpp:558 msgid "Bad format: specify interval in integral minutes" msgstr "格式错误:以整数分钟为单位指定间隔" @@ -271,7 +271,26 @@ msgctxt "constr-name" msgid "comment" msgstr "备注" -#: constraint.cpp:171 +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with " +"Constrain -> On Point before constraining tangent." +msgstr "切线弧和线段必须共享一个端点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them " +"with Constrain -> On Point before constraining tangent." +msgstr "" +"切线立方段和线段必须共享终结点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point " +"before constraining tangent." +msgstr "曲线必须共享一个终结点。在约束切线之前,使用约束 -= 点约束它们。" + +#: constraint.cpp:231 msgid "" "Bad selection for distance / diameter constraint. This constraint can apply " "to:\n" @@ -294,7 +313,7 @@ msgstr "" " * 平面面和点(最小距离)\n" " * 圆或弧(直径)\n" -#: constraint.cpp:224 +#: constraint.cpp:284 msgid "" "Bad selection for on point / curve / plane constraint. This constraint can " "apply to:\n" @@ -313,7 +332,7 @@ msgstr "" " * 一个点和一个圆或圆(曲线上的点)\n" " * 点和平面面(点在脸上)\n" -#: constraint.cpp:286 +#: constraint.cpp:346 msgid "" "Bad selection for equal length / radius constraint. This constraint can " "apply to:\n" @@ -339,7 +358,7 @@ msgstr "" " * 两个圆或圆(相等半径)\n" " * 线段和圆弧(线段长度等于弧长)\n" -#: constraint.cpp:325 +#: constraint.cpp:385 msgid "" "Bad selection for length ratio constraint. This constraint can apply to:\n" "\n" @@ -349,7 +368,7 @@ msgstr "" "\n" "* 两个线段\n" -#: constraint.cpp:342 +#: constraint.cpp:402 msgid "" "Bad selection for length difference constraint. This constraint can apply " "to:\n" @@ -360,7 +379,7 @@ msgstr "" "\n" "* 两个线段\n" -#: constraint.cpp:368 +#: constraint.cpp:428 msgid "" "Bad selection for at midpoint constraint. This constraint can apply to:\n" "\n" @@ -372,7 +391,7 @@ msgstr "" "* 线段和点(点在中点)\n" " * 线段和工作平面(平面上的线中点)\n" -#: constraint.cpp:426 +#: constraint.cpp:486 msgid "" "Bad selection for symmetric constraint. This constraint can apply to:\n" "\n" @@ -389,19 +408,19 @@ msgstr "" " * 线段,和两个点或线段(对称的线段)\n" " * 工作平面和两个点或线段(工作平面对称)\n" -#: constraint.cpp:440 +#: constraint.cpp:500 msgid "" "A workplane must be active when constraining symmetric without an explicit " "symmetry plane." msgstr "在没有显式对称平面约束对称时,工作平面必须处于活动状态。" -#: constraint.cpp:470 +#: constraint.cpp:530 msgid "" "Activate a workplane (with Sketch -> In Workplane) before applying a " "horizontal or vertical constraint." msgstr "在应用水平或垂直约束之前,激活工作平面(使用草图 -= 在工作平面中)。" -#: constraint.cpp:483 +#: constraint.cpp:543 msgid "" "Bad selection for horizontal / vertical constraint. This constraint can " "apply to:\n" @@ -414,7 +433,7 @@ msgstr "" "• 两点\n" " • 线段\n" -#: constraint.cpp:504 +#: constraint.cpp:564 msgid "" "Bad selection for same orientation constraint. This constraint can apply " "to:\n" @@ -425,15 +444,15 @@ msgstr "" "\n" "• 两个法线\n" -#: constraint.cpp:554 +#: constraint.cpp:614 msgid "Must select an angle constraint." msgstr "必须选择角度约束。" -#: constraint.cpp:567 +#: constraint.cpp:627 msgid "Must select a constraint with associated label." msgstr "必须选择具有关联标签的约束。" -#: constraint.cpp:578 +#: constraint.cpp:638 msgid "" "Bad selection for angle constraint. This constraint can apply to:\n" "\n" @@ -447,30 +466,11 @@ msgstr "" " * 线段和法线\n" " • 两个法线\n" -#: constraint.cpp:635 -msgid "" -"The tangent arc and line segment must share an endpoint. Constrain them with " -"Constrain -> On Point before constraining tangent." -msgstr "切线弧和线段必须共享一个端点。在约束切线之前,使用约束 -= 点约束它们。" - -#: constraint.cpp:659 -msgid "" -"The tangent cubic and line segment must share an endpoint. Constrain them " -"with Constrain -> On Point before constraining tangent." -msgstr "" -"切线立方段和线段必须共享终结点。在约束切线之前,使用约束 -= 点约束它们。" - -#: constraint.cpp:669 +#: constraint.cpp:701 msgid "Curve-curve tangency must apply in workplane." msgstr "曲线曲线切线必须应用于工作平面。" -#: constraint.cpp:687 -msgid "" -"The curves must share an endpoint. Constrain them with Constrain -> On Point " -"before constraining tangent." -msgstr "曲线必须共享一个终结点。在约束切线之前,使用约束 -= 点约束它们。" - -#: constraint.cpp:696 +#: constraint.cpp:711 msgid "" "Bad selection for parallel / tangent constraint. This constraint can apply " "to:\n" @@ -487,7 +487,7 @@ msgstr "" " * 两个法线(平行)\n" " * 共享端点的两条线段、弧线或贝塞尔(切线)\n" -#: constraint.cpp:714 +#: constraint.cpp:729 msgid "" "Bad selection for perpendicular constraint. This constraint can apply to:\n" "\n" @@ -501,7 +501,7 @@ msgstr "" " * 线段和法线\n" " • 两个法线\n" -#: constraint.cpp:729 +#: constraint.cpp:744 msgid "" "Bad selection for lock point where dragged constraint. This constraint can " "apply to:\n" @@ -512,7 +512,7 @@ msgstr "" "\n" "• 一点\n" -#: constraint.cpp:740 +#: constraint.cpp:755 msgid "click center of comment text" msgstr "单击注释文本的中心" @@ -606,7 +606,7 @@ msgctxt "button" msgid "&No" msgstr "否(&N)" -#: file.cpp:869 solvespace.cpp:563 +#: file.cpp:869 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "取消(&C)" @@ -772,299 +772,303 @@ msgid "Show Snap &Grid" msgstr "显示捕捉轴线 (&G)" #: graphicswin.cpp:95 +msgid "Dim Solid for Sketch Groups" +msgstr "" + +#: graphicswin.cpp:96 msgid "Use &Perspective Projection" msgstr "使用远景透视(&P)" -#: graphicswin.cpp:96 +#: graphicswin.cpp:97 msgid "Dimension &Units" msgstr "标注单位(&U)" -#: graphicswin.cpp:97 +#: graphicswin.cpp:98 msgid "Dimensions in &Millimeters" msgstr "标注单位 mm (&M)" -#: graphicswin.cpp:98 +#: graphicswin.cpp:99 msgid "Dimensions in M&eters" msgstr "标注单位m (&E)" -#: graphicswin.cpp:99 +#: graphicswin.cpp:100 msgid "Dimensions in &Inches" msgstr "标准单位英寸 (&I)" -#: graphicswin.cpp:101 +#: graphicswin.cpp:102 msgid "Show &Toolbar" msgstr "显示工具条(&T)" -#: graphicswin.cpp:102 +#: graphicswin.cpp:103 msgid "Show Property Bro&wser" msgstr "显示属性浏览器(&W)" -#: graphicswin.cpp:104 +#: graphicswin.cpp:105 msgid "&Full Screen" msgstr "全屏(&F)" -#: graphicswin.cpp:106 +#: graphicswin.cpp:107 msgid "&New Group" msgstr "新组合(&N)" -#: graphicswin.cpp:107 +#: graphicswin.cpp:108 msgid "Sketch In &3d" msgstr "在三维内绘制(&3)" -#: graphicswin.cpp:108 +#: graphicswin.cpp:109 msgid "Sketch In New &Workplane" msgstr "在新工作面绘制(&W)" -#: graphicswin.cpp:110 +#: graphicswin.cpp:111 msgid "Step &Translating" msgstr "移动(&T)" -#: graphicswin.cpp:111 +#: graphicswin.cpp:112 msgid "Step &Rotating" msgstr "旋转(&R)" -#: graphicswin.cpp:113 +#: graphicswin.cpp:114 msgid "E&xtrude" msgstr "挤出(&E)" -#: graphicswin.cpp:114 +#: graphicswin.cpp:115 msgid "&Helix" msgstr "螺旋(&H)" -#: graphicswin.cpp:115 +#: graphicswin.cpp:116 msgid "&Lathe" msgstr "扫略(&L)" -#: graphicswin.cpp:116 +#: graphicswin.cpp:117 msgid "Re&volve" msgstr "旋转(&V)" -#: graphicswin.cpp:118 +#: graphicswin.cpp:119 msgid "Link / Assemble..." msgstr "链接/装配..." -#: graphicswin.cpp:119 +#: graphicswin.cpp:120 msgid "Link Recent" msgstr "连接最近文件" -#: graphicswin.cpp:121 +#: graphicswin.cpp:122 msgid "&Sketch" msgstr "绘图(&S)" -#: graphicswin.cpp:122 +#: graphicswin.cpp:123 msgid "In &Workplane" msgstr "在工作平面(&W)" -#: graphicswin.cpp:123 +#: graphicswin.cpp:124 msgid "Anywhere In &3d" msgstr "在3D的任何位置(&3)" -#: graphicswin.cpp:125 +#: graphicswin.cpp:126 msgid "Datum &Point" msgstr "基准点(&P)" -#: graphicswin.cpp:126 +#: graphicswin.cpp:127 msgid "&Workplane" msgstr "工作面(&W)" -#: graphicswin.cpp:128 +#: graphicswin.cpp:129 msgid "Line &Segment" msgstr "线段(&S)" -#: graphicswin.cpp:129 +#: graphicswin.cpp:130 msgid "C&onstruction Line Segment" msgstr "构造线段(&C)" -#: graphicswin.cpp:130 +#: graphicswin.cpp:131 msgid "&Rectangle" msgstr "矩形(&R)" -#: graphicswin.cpp:131 +#: graphicswin.cpp:132 msgid "&Circle" msgstr "圆线(&C)" -#: graphicswin.cpp:132 +#: graphicswin.cpp:133 msgid "&Arc of a Circle" msgstr "圆弧(&A)" -#: graphicswin.cpp:133 +#: graphicswin.cpp:134 msgid "&Bezier Cubic Spline" msgstr "立方体线的贝塞尔曲线(&B)" -#: graphicswin.cpp:135 +#: graphicswin.cpp:136 msgid "&Text in TrueType Font" msgstr "TrueTyoe字体文字(&T)" -#: graphicswin.cpp:136 +#: graphicswin.cpp:137 msgid "&Image" msgstr "图片(&I)" -#: graphicswin.cpp:138 +#: graphicswin.cpp:139 msgid "To&ggle Construction" msgstr "切换构造(&G)" -#: graphicswin.cpp:139 +#: graphicswin.cpp:140 msgid "Tangent &Arc at Point" msgstr "弧线切线点(&A)" -#: graphicswin.cpp:140 +#: graphicswin.cpp:141 msgid "Split Curves at &Intersection" msgstr "在交叉处拆分曲线(&I)" -#: graphicswin.cpp:142 +#: graphicswin.cpp:143 msgid "&Constrain" msgstr "约束(&C)" -#: graphicswin.cpp:143 +#: graphicswin.cpp:144 msgid "&Distance / Diameter" msgstr "距离/直径(&D)" -#: graphicswin.cpp:144 +#: graphicswin.cpp:145 msgid "Re&ference Dimension" msgstr "参考标注(&F)" -#: graphicswin.cpp:145 +#: graphicswin.cpp:146 msgid "A&ngle" msgstr "角度(&A)" -#: graphicswin.cpp:146 +#: graphicswin.cpp:147 msgid "Reference An&gle" msgstr "参考角度(&G)" -#: graphicswin.cpp:147 +#: graphicswin.cpp:148 msgid "Other S&upplementary Angle" msgstr "其它增补角度(&U)" -#: graphicswin.cpp:148 +#: graphicswin.cpp:149 msgid "Toggle R&eference Dim" msgstr "切换参考标注(&E)" -#: graphicswin.cpp:150 +#: graphicswin.cpp:151 msgid "&Horizontal" msgstr "水平约束(&H)" -#: graphicswin.cpp:151 +#: graphicswin.cpp:152 msgid "&Vertical" msgstr "垂直约束(&V)" -#: graphicswin.cpp:153 +#: graphicswin.cpp:154 msgid "&On Point / Curve / Plane" msgstr "在点线面(&O)" -#: graphicswin.cpp:154 +#: graphicswin.cpp:155 msgid "E&qual Length / Radius / Angle" msgstr "等于/长度/半径/角度(&Q)" -#: graphicswin.cpp:155 +#: graphicswin.cpp:156 msgid "Length Ra&tio" msgstr "长度比例(&T)" -#: graphicswin.cpp:156 +#: graphicswin.cpp:157 msgid "Length Diff&erence" msgstr "长度偏差(&E)" -#: graphicswin.cpp:157 +#: graphicswin.cpp:158 msgid "At &Midpoint" msgstr "在中点(&M)" -#: graphicswin.cpp:158 +#: graphicswin.cpp:159 msgid "S&ymmetric" msgstr "对称(&Y)" -#: graphicswin.cpp:159 +#: graphicswin.cpp:160 msgid "Para&llel / Tangent" msgstr "水平/切线(&L)" -#: graphicswin.cpp:160 +#: graphicswin.cpp:161 msgid "&Perpendicular" msgstr "垂直的(&P)" -#: graphicswin.cpp:161 +#: graphicswin.cpp:162 msgid "Same Orient&ation" msgstr "相同方向(&A)" -#: graphicswin.cpp:162 +#: graphicswin.cpp:163 msgid "Lock Point Where &Dragged" msgstr "锁定点位置(&D)" -#: graphicswin.cpp:164 +#: graphicswin.cpp:165 msgid "Comment" msgstr "备注" -#: graphicswin.cpp:166 +#: graphicswin.cpp:167 msgid "&Analyze" msgstr "分析(&A)" -#: graphicswin.cpp:167 +#: graphicswin.cpp:168 msgid "Measure &Volume" msgstr "测量体积(&V)" -#: graphicswin.cpp:168 +#: graphicswin.cpp:169 msgid "Measure A&rea" msgstr "测量面积(&R)" -#: graphicswin.cpp:169 +#: graphicswin.cpp:170 msgid "Measure &Perimeter" msgstr "测量周长(&P)" -#: graphicswin.cpp:170 +#: graphicswin.cpp:171 msgid "Show &Interfering Parts" msgstr "显示干涉零件(&I)" -#: graphicswin.cpp:171 +#: graphicswin.cpp:172 msgid "Show &Naked Edges" msgstr "显示孤立边(&N)" -#: graphicswin.cpp:172 +#: graphicswin.cpp:173 msgid "Show &Center of Mass" msgstr "显示中心(&C)" -#: graphicswin.cpp:174 +#: graphicswin.cpp:175 msgid "Show &Underconstrained Points" msgstr "显示无效约束点(&U)" -#: graphicswin.cpp:176 +#: graphicswin.cpp:177 msgid "&Trace Point" msgstr "跟踪点(&T)" -#: graphicswin.cpp:177 +#: graphicswin.cpp:178 msgid "&Stop Tracing..." msgstr "停止跟踪(&S)" -#: graphicswin.cpp:178 +#: graphicswin.cpp:179 msgid "Step &Dimension..." msgstr "逐步标注(&D)" -#: graphicswin.cpp:180 +#: graphicswin.cpp:181 msgid "&Help" msgstr "帮助(&H)" -#: graphicswin.cpp:181 +#: graphicswin.cpp:182 msgid "&Language" msgstr "语言(&L)" -#: graphicswin.cpp:182 +#: graphicswin.cpp:183 msgid "&Website / Manual" msgstr "网页/手册(&W)" -#: graphicswin.cpp:184 +#: graphicswin.cpp:185 msgid "&About" msgstr "关于(&A)" -#: graphicswin.cpp:352 +#: graphicswin.cpp:355 msgid "(no recent files)" msgstr "(无文件)" -#: graphicswin.cpp:360 +#: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." msgstr "文件不存在: \"%s\"。" -#: graphicswin.cpp:721 +#: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." msgstr "没有激活的工作面,因此无法显示轴网。" -#: graphicswin.cpp:730 +#: graphicswin.cpp:740 msgid "" "The perspective factor is set to zero, so the view will always be a parallel " "projection.\n" @@ -1073,91 +1077,91 @@ msgid "" "configuration screen. A value around 0.3 is typical." msgstr "" -#: graphicswin.cpp:809 +#: graphicswin.cpp:819 msgid "" "Select a point; this point will become the center of the view on screen." msgstr "" -#: graphicswin.cpp:1103 +#: graphicswin.cpp:1114 msgid "No additional entities share endpoints with the selected entities." msgstr "" -#: graphicswin.cpp:1121 +#: graphicswin.cpp:1132 msgid "" "To use this command, select a point or other entity from an linked part, or " "make a link group the active group." msgstr "" -#: graphicswin.cpp:1144 +#: graphicswin.cpp:1155 msgid "" "No workplane is active. Activate a workplane (with Sketch -> In Workplane) " "to define the plane for the snap grid." msgstr "" -#: graphicswin.cpp:1151 +#: graphicswin.cpp:1162 msgid "" "Can't snap these items to grid; select points, text comments, or constraints " "with a label. To snap a line, select its endpoints." msgstr "" -#: graphicswin.cpp:1239 +#: graphicswin.cpp:1247 msgid "No workplane selected. Activating default workplane for this group." msgstr "" -#: graphicswin.cpp:1242 +#: graphicswin.cpp:1250 msgid "" "No workplane is selected, and the active group does not have a default " "workplane. Try selecting a workplane, or activating a sketch-in-new-" "workplane group." msgstr "" -#: graphicswin.cpp:1263 +#: graphicswin.cpp:1271 msgid "" "Bad selection for tangent arc at point. Select a single point, or select " "nothing to set up arc parameters." msgstr "" -#: graphicswin.cpp:1274 +#: graphicswin.cpp:1282 msgid "click point on arc (draws anti-clockwise)" msgstr "点击弧线的点(逆时针方向绘制)" -#: graphicswin.cpp:1275 +#: graphicswin.cpp:1283 msgid "click to place datum point" msgstr "点击放置基准点" -#: graphicswin.cpp:1276 +#: graphicswin.cpp:1284 msgid "click first point of line segment" msgstr "点击线条的起点" -#: graphicswin.cpp:1278 +#: graphicswin.cpp:1286 msgid "click first point of construction line segment" msgstr "点击构造线的起点" -#: graphicswin.cpp:1279 +#: graphicswin.cpp:1287 msgid "click first point of cubic segment" msgstr "点击立方体的起点" -#: graphicswin.cpp:1280 +#: graphicswin.cpp:1288 msgid "click center of circle" msgstr "点击圆弧的中心" -#: graphicswin.cpp:1281 +#: graphicswin.cpp:1289 msgid "click origin of workplane" msgstr "点击工作面的原点" -#: graphicswin.cpp:1282 +#: graphicswin.cpp:1290 msgid "click one corner of rectangle" msgstr "点击一个矩形倒角" -#: graphicswin.cpp:1283 +#: graphicswin.cpp:1291 msgid "click top left of text" msgstr "点击文字左上角" -#: graphicswin.cpp:1289 +#: graphicswin.cpp:1297 msgid "click top left of image" msgstr "点击图片左上角" -#: graphicswin.cpp:1301 +#: graphicswin.cpp:1309 msgid "" "No entities are selected. Select entities before trying to toggle their " "construction state." @@ -1276,19 +1280,19 @@ msgstr "移动" msgid "(unnamed)" msgstr "(未命名)" -#: groupmesh.cpp:708 +#: groupmesh.cpp:709 msgid "not closed contour, or not all same style!" msgstr "未闭合轮廓,或样式不一致!" -#: groupmesh.cpp:721 +#: groupmesh.cpp:722 msgid "points not all coplanar!" msgstr "点不在相同平面!" -#: groupmesh.cpp:723 +#: groupmesh.cpp:724 msgid "contour is self-intersecting!" msgstr "轮廓自相交!" -#: groupmesh.cpp:725 +#: groupmesh.cpp:726 msgid "zero-length edge!" msgstr "边缘长度为零!" @@ -1418,64 +1422,64 @@ msgstr "取消覆盖区域的全选" msgid "Zoom to Fit" msgstr "自动缩放" -#: mouse.cpp:990 mouse.cpp:1277 +#: mouse.cpp:989 mouse.cpp:1276 msgid "click next point of line, or press Esc" msgstr "点击下一个点或取消(ESC)" -#: mouse.cpp:996 +#: mouse.cpp:995 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "无法在3D内绘制矩形; 首先,激活工作面,草图->在工作面。" -#: mouse.cpp:1030 +#: mouse.cpp:1029 msgid "click to place other corner of rectangle" msgstr "点击放置其它矩形倒角" -#: mouse.cpp:1050 +#: mouse.cpp:1049 msgid "click to set radius" msgstr "点击设置半径" -#: mouse.cpp:1055 +#: mouse.cpp:1054 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "无法在3D空间内绘制弧线,可使用 草图->在工作面 激活工作面。" -#: mouse.cpp:1074 +#: mouse.cpp:1073 msgid "click to place point" msgstr "点击放置点" -#: mouse.cpp:1090 +#: mouse.cpp:1089 msgid "click next point of cubic, or press Esc" msgstr "点击下一个点或取消(ESC)" -#: mouse.cpp:1095 +#: mouse.cpp:1094 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "已经在工作面绘制;在新建工作面前在三维空间绘制。" -#: mouse.cpp:1111 +#: mouse.cpp:1110 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "无法在三维空间内绘制文字,可使用 草图->在工作面 激活工作面。" -#: mouse.cpp:1128 +#: mouse.cpp:1127 msgid "click to place bottom right of text" msgstr "点击文字的右下角放置" -#: mouse.cpp:1134 +#: mouse.cpp:1133 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 激活工作面。" -#: mouse.cpp:1161 +#: mouse.cpp:1160 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "新备注 - 双击编辑" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 msgctxt "file-type" msgid "SolveSpace models" msgstr "SolveSpace模型" @@ -1560,33 +1564,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "逗号分隔数据" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 msgid "untitled" msgstr "未命名" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1562 +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "保存文件" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1564 +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "打开文件" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1368 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 msgctxt "button" msgid "_Cancel" msgstr "取消_C" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 msgctxt "button" msgid "_Save" msgstr "保存_S" -#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 msgctxt "button" msgid "_Open" msgstr "打开_O" @@ -1616,74 +1620,74 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:551 +#: solvespace.cpp:557 msgctxt "title" msgid "Modified File" msgstr "" -#: solvespace.cpp:553 +#: solvespace.cpp:559 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:556 +#: solvespace.cpp:562 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:559 +#: solvespace.cpp:565 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:560 +#: solvespace.cpp:566 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:562 +#: solvespace.cpp:568 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:583 +#: solvespace.cpp:589 msgctxt "title" msgid "(new sketch)" msgstr "" -#: solvespace.cpp:590 +#: solvespace.cpp:596 msgctxt "title" msgid "Property Browser" msgstr "" -#: solvespace.cpp:650 +#: solvespace.cpp:658 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This " "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" -#: solvespace.cpp:718 +#: solvespace.cpp:730 #, c-format msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" -#: solvespace.cpp:766 +#: solvespace.cpp:778 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:770 +#: solvespace.cpp:782 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:794 +#: solvespace.cpp:806 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:810 +#: solvespace.cpp:822 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1691,7 +1695,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:819 +#: solvespace.cpp:831 #, c-format msgid "" "\n" @@ -1700,7 +1704,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:824 +#: solvespace.cpp:836 msgid "" "\n" "\n" @@ -1708,7 +1712,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:839 +#: solvespace.cpp:851 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1719,13 +1723,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:848 +#: solvespace.cpp:860 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:872 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1736,7 +1740,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:880 +#: solvespace.cpp:892 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1747,36 +1751,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:886 +#: solvespace.cpp:898 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:902 +#: solvespace.cpp:914 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:925 +#: solvespace.cpp:941 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:955 +#: solvespace.cpp:971 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:972 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:958 +#: solvespace.cpp:974 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:959 +#: solvespace.cpp:975 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:962 +#: solvespace.cpp:978 #, c-format msgid "" "\n" @@ -1784,7 +1788,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:966 +#: solvespace.cpp:982 #, c-format msgid "" "%s\n" @@ -1794,7 +1798,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:969 +#: solvespace.cpp:985 #, c-format msgid "" "%s\n" @@ -1804,7 +1808,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:982 +#: solvespace.cpp:998 #, c-format msgid "" "This is SolveSpace version %s.\n" @@ -1952,30 +1956,38 @@ msgid "New group rotating active sketch" msgstr "新组中旋转体当前草图" #: toolbar.cpp:72 +msgid "New group helix from active sketch" +msgstr "" + +#: toolbar.cpp:74 +msgid "New group revolve active sketch" +msgstr "" + +#: toolbar.cpp:76 msgid "New group step and repeat rotating" msgstr "新组中逐步重复旋转体" -#: toolbar.cpp:74 +#: toolbar.cpp:78 msgid "New group step and repeat translating" msgstr "新组中逐步重复移动体" -#: toolbar.cpp:76 +#: toolbar.cpp:80 msgid "New group in new workplane (thru given entities)" msgstr "在新工作平面创建组(通过指定对象)" -#: toolbar.cpp:78 +#: toolbar.cpp:82 msgid "New group in 3d" msgstr "在3D中新建组" -#: toolbar.cpp:80 +#: toolbar.cpp:84 msgid "New group linking / assembling file" msgstr "新组 连接/装配文件" -#: toolbar.cpp:84 +#: toolbar.cpp:88 msgid "Nearest isometric view" msgstr "ISO视图" -#: toolbar.cpp:86 +#: toolbar.cpp:90 msgid "Align view to active workplane" msgstr "切换视图至当前工作面" diff --git a/res/messages.pot b/res/messages.pot index 5a6ef365..33af7b26 100644 --- a/res/messages.pot +++ b/res/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2020-11-23 07:36+0100\n" +"POT-Creation-Date: 2021-01-15 14:51-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,76 +17,76 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: clipboard.cpp:274 +#: clipboard.cpp:310 msgid "" "Cut, paste, and copy work only in a workplane.\n" "\n" "Activate one with Sketch -> In Workplane." msgstr "" -#: clipboard.cpp:291 +#: clipboard.cpp:327 msgid "Clipboard is empty; nothing to paste." msgstr "" -#: clipboard.cpp:338 +#: clipboard.cpp:374 msgid "Number of copies to paste must be at least one." msgstr "" -#: clipboard.cpp:354 textscreens.cpp:783 +#: clipboard.cpp:390 textscreens.cpp:783 msgid "Scale cannot be zero." msgstr "" -#: clipboard.cpp:396 +#: clipboard.cpp:432 msgid "Select one point to define origin of rotation." msgstr "" -#: clipboard.cpp:408 +#: clipboard.cpp:444 msgid "Select two points to define translation vector." msgstr "" -#: clipboard.cpp:418 +#: clipboard.cpp:454 msgid "Transformation is identity. So all copies will be exactly on top of each other." msgstr "" -#: clipboard.cpp:422 +#: clipboard.cpp:458 msgid "Too many items to paste; split this into smaller pastes." msgstr "" -#: clipboard.cpp:427 +#: clipboard.cpp:463 msgid "No workplane active." msgstr "" -#: confscreen.cpp:410 +#: confscreen.cpp:418 msgid "Bad format: specify coordinates as x, y, z" msgstr "" -#: confscreen.cpp:420 style.cpp:659 textscreens.cpp:805 +#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805 msgid "Bad format: specify color as r, g, b" msgstr "" -#: confscreen.cpp:446 +#: confscreen.cpp:454 msgid "" "The perspective factor will have no effect until you enable View -> Use Perspective Projection." msgstr "" -#: confscreen.cpp:459 confscreen.cpp:469 +#: confscreen.cpp:467 confscreen.cpp:477 #, c-format msgid "Specify between 0 and %d digits after the decimal." msgstr "" -#: confscreen.cpp:481 +#: confscreen.cpp:489 msgid "Export scale must not be zero!" msgstr "" -#: confscreen.cpp:493 +#: confscreen.cpp:501 msgid "Cutter radius offset must not be negative!" msgstr "" -#: confscreen.cpp:547 +#: confscreen.cpp:555 msgid "Bad value: autosave interval should be positive" msgstr "" -#: confscreen.cpp:550 +#: confscreen.cpp:558 msgid "Bad format: specify interval in integral minutes" msgstr "" @@ -265,7 +265,25 @@ msgctxt "constr-name" msgid "comment" msgstr "" -#: constraint.cpp:171 +#: constraint.cpp:140 +msgid "" +"The tangent arc and line segment must share an endpoint. Constrain them with Constrain -> On " +"Point before constraining tangent." +msgstr "" + +#: constraint.cpp:158 +msgid "" +"The tangent cubic and line segment must share an endpoint. Constrain them with Constrain -> On " +"Point before constraining tangent." +msgstr "" + +#: constraint.cpp:183 +msgid "" +"The curves must share an endpoint. Constrain them with Constrain -> On Point before constraining " +"tangent." +msgstr "" + +#: constraint.cpp:231 msgid "" "Bad selection for distance / diameter constraint. This constraint can apply to:\n" "\n" @@ -278,7 +296,7 @@ msgid "" " * a circle or an arc (diameter)\n" msgstr "" -#: constraint.cpp:224 +#: constraint.cpp:284 msgid "" "Bad selection for on point / curve / plane constraint. This constraint can apply to:\n" "\n" @@ -289,7 +307,7 @@ msgid "" " * a point and a plane face (point on face)\n" msgstr "" -#: constraint.cpp:286 +#: constraint.cpp:346 msgid "" "Bad selection for equal length / radius constraint. This constraint can apply to:\n" "\n" @@ -303,21 +321,21 @@ msgid "" " * a line segment and an arc (line segment length equals arc length)\n" msgstr "" -#: constraint.cpp:325 +#: constraint.cpp:385 msgid "" "Bad selection for length ratio constraint. This constraint can apply to:\n" "\n" " * two line segments\n" msgstr "" -#: constraint.cpp:342 +#: constraint.cpp:402 msgid "" "Bad selection for length difference constraint. This constraint can apply to:\n" "\n" " * two line segments\n" msgstr "" -#: constraint.cpp:368 +#: constraint.cpp:428 msgid "" "Bad selection for at midpoint constraint. This constraint can apply to:\n" "\n" @@ -325,7 +343,7 @@ msgid "" " * a line segment and a workplane (line's midpoint on plane)\n" msgstr "" -#: constraint.cpp:426 +#: constraint.cpp:486 msgid "" "Bad selection for symmetric constraint. This constraint can apply to:\n" "\n" @@ -334,17 +352,17 @@ msgid "" " * workplane, and two points or a line segment (symmetric about workplane)\n" msgstr "" -#: constraint.cpp:440 +#: constraint.cpp:500 msgid "A workplane must be active when constraining symmetric without an explicit symmetry plane." msgstr "" -#: constraint.cpp:470 +#: constraint.cpp:530 msgid "" "Activate a workplane (with Sketch -> In Workplane) before applying a horizontal or vertical " "constraint." msgstr "" -#: constraint.cpp:483 +#: constraint.cpp:543 msgid "" "Bad selection for horizontal / vertical constraint. This constraint can apply to:\n" "\n" @@ -352,22 +370,22 @@ msgid "" " * a line segment\n" msgstr "" -#: constraint.cpp:504 +#: constraint.cpp:564 msgid "" "Bad selection for same orientation constraint. This constraint can apply to:\n" "\n" " * two normals\n" msgstr "" -#: constraint.cpp:554 +#: constraint.cpp:614 msgid "Must select an angle constraint." msgstr "" -#: constraint.cpp:567 +#: constraint.cpp:627 msgid "Must select a constraint with associated label." msgstr "" -#: constraint.cpp:578 +#: constraint.cpp:638 msgid "" "Bad selection for angle constraint. This constraint can apply to:\n" "\n" @@ -376,29 +394,11 @@ msgid "" " * two normals\n" msgstr "" -#: constraint.cpp:635 -msgid "" -"The tangent arc and line segment must share an endpoint. Constrain them with Constrain -> On " -"Point before constraining tangent." -msgstr "" - -#: constraint.cpp:659 -msgid "" -"The tangent cubic and line segment must share an endpoint. Constrain them with Constrain -> On " -"Point before constraining tangent." -msgstr "" - -#: constraint.cpp:669 +#: constraint.cpp:701 msgid "Curve-curve tangency must apply in workplane." msgstr "" -#: constraint.cpp:687 -msgid "" -"The curves must share an endpoint. Constrain them with Constrain -> On Point before constraining " -"tangent." -msgstr "" - -#: constraint.cpp:696 +#: constraint.cpp:711 msgid "" "Bad selection for parallel / tangent constraint. This constraint can apply to:\n" "\n" @@ -408,7 +408,7 @@ msgid "" " * two line segments, arcs, or beziers, that share an endpoint (tangent)\n" msgstr "" -#: constraint.cpp:714 +#: constraint.cpp:729 msgid "" "Bad selection for perpendicular constraint. This constraint can apply to:\n" "\n" @@ -417,14 +417,14 @@ msgid "" " * two normals\n" msgstr "" -#: constraint.cpp:729 +#: constraint.cpp:744 msgid "" "Bad selection for lock point where dragged constraint. This constraint can apply to:\n" "\n" " * a point\n" msgstr "" -#: constraint.cpp:740 +#: constraint.cpp:755 msgid "click center of comment text" msgstr "" @@ -506,7 +506,7 @@ msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:563 +#: file.cpp:869 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "" @@ -672,299 +672,303 @@ msgid "Show Snap &Grid" msgstr "" #: graphicswin.cpp:95 -msgid "Use &Perspective Projection" +msgid "Dim Solid for Sketch Groups" msgstr "" #: graphicswin.cpp:96 -msgid "Dimension &Units" +msgid "Use &Perspective Projection" msgstr "" #: graphicswin.cpp:97 -msgid "Dimensions in &Millimeters" +msgid "Dimension &Units" msgstr "" #: graphicswin.cpp:98 -msgid "Dimensions in M&eters" +msgid "Dimensions in &Millimeters" msgstr "" #: graphicswin.cpp:99 +msgid "Dimensions in M&eters" +msgstr "" + +#: graphicswin.cpp:100 msgid "Dimensions in &Inches" msgstr "" -#: graphicswin.cpp:101 +#: graphicswin.cpp:102 msgid "Show &Toolbar" msgstr "" -#: graphicswin.cpp:102 +#: graphicswin.cpp:103 msgid "Show Property Bro&wser" msgstr "" -#: graphicswin.cpp:104 +#: graphicswin.cpp:105 msgid "&Full Screen" msgstr "" -#: graphicswin.cpp:106 +#: graphicswin.cpp:107 msgid "&New Group" msgstr "" -#: graphicswin.cpp:107 +#: graphicswin.cpp:108 msgid "Sketch In &3d" msgstr "" -#: graphicswin.cpp:108 +#: graphicswin.cpp:109 msgid "Sketch In New &Workplane" msgstr "" -#: graphicswin.cpp:110 +#: graphicswin.cpp:111 msgid "Step &Translating" msgstr "" -#: graphicswin.cpp:111 +#: graphicswin.cpp:112 msgid "Step &Rotating" msgstr "" -#: graphicswin.cpp:113 +#: graphicswin.cpp:114 msgid "E&xtrude" msgstr "" -#: graphicswin.cpp:114 +#: graphicswin.cpp:115 msgid "&Helix" msgstr "" -#: graphicswin.cpp:115 +#: graphicswin.cpp:116 msgid "&Lathe" msgstr "" -#: graphicswin.cpp:116 +#: graphicswin.cpp:117 msgid "Re&volve" msgstr "" -#: graphicswin.cpp:118 +#: graphicswin.cpp:119 msgid "Link / Assemble..." msgstr "" -#: graphicswin.cpp:119 +#: graphicswin.cpp:120 msgid "Link Recent" msgstr "" -#: graphicswin.cpp:121 +#: graphicswin.cpp:122 msgid "&Sketch" msgstr "" -#: graphicswin.cpp:122 +#: graphicswin.cpp:123 msgid "In &Workplane" msgstr "" -#: graphicswin.cpp:123 +#: graphicswin.cpp:124 msgid "Anywhere In &3d" msgstr "" -#: graphicswin.cpp:125 +#: graphicswin.cpp:126 msgid "Datum &Point" msgstr "" -#: graphicswin.cpp:126 +#: graphicswin.cpp:127 msgid "&Workplane" msgstr "" -#: graphicswin.cpp:128 +#: graphicswin.cpp:129 msgid "Line &Segment" msgstr "" -#: graphicswin.cpp:129 +#: graphicswin.cpp:130 msgid "C&onstruction Line Segment" msgstr "" -#: graphicswin.cpp:130 +#: graphicswin.cpp:131 msgid "&Rectangle" msgstr "" -#: graphicswin.cpp:131 +#: graphicswin.cpp:132 msgid "&Circle" msgstr "" -#: graphicswin.cpp:132 +#: graphicswin.cpp:133 msgid "&Arc of a Circle" msgstr "" -#: graphicswin.cpp:133 +#: graphicswin.cpp:134 msgid "&Bezier Cubic Spline" msgstr "" -#: graphicswin.cpp:135 +#: graphicswin.cpp:136 msgid "&Text in TrueType Font" msgstr "" -#: graphicswin.cpp:136 +#: graphicswin.cpp:137 msgid "&Image" msgstr "" -#: graphicswin.cpp:138 +#: graphicswin.cpp:139 msgid "To&ggle Construction" msgstr "" -#: graphicswin.cpp:139 +#: graphicswin.cpp:140 msgid "Tangent &Arc at Point" msgstr "" -#: graphicswin.cpp:140 +#: graphicswin.cpp:141 msgid "Split Curves at &Intersection" msgstr "" -#: graphicswin.cpp:142 +#: graphicswin.cpp:143 msgid "&Constrain" msgstr "" -#: graphicswin.cpp:143 +#: graphicswin.cpp:144 msgid "&Distance / Diameter" msgstr "" -#: graphicswin.cpp:144 +#: graphicswin.cpp:145 msgid "Re&ference Dimension" msgstr "" -#: graphicswin.cpp:145 +#: graphicswin.cpp:146 msgid "A&ngle" msgstr "" -#: graphicswin.cpp:146 +#: graphicswin.cpp:147 msgid "Reference An&gle" msgstr "" -#: graphicswin.cpp:147 +#: graphicswin.cpp:148 msgid "Other S&upplementary Angle" msgstr "" -#: graphicswin.cpp:148 +#: graphicswin.cpp:149 msgid "Toggle R&eference Dim" msgstr "" -#: graphicswin.cpp:150 +#: graphicswin.cpp:151 msgid "&Horizontal" msgstr "" -#: graphicswin.cpp:151 +#: graphicswin.cpp:152 msgid "&Vertical" msgstr "" -#: graphicswin.cpp:153 +#: graphicswin.cpp:154 msgid "&On Point / Curve / Plane" msgstr "" -#: graphicswin.cpp:154 +#: graphicswin.cpp:155 msgid "E&qual Length / Radius / Angle" msgstr "" -#: graphicswin.cpp:155 +#: graphicswin.cpp:156 msgid "Length Ra&tio" msgstr "" -#: graphicswin.cpp:156 +#: graphicswin.cpp:157 msgid "Length Diff&erence" msgstr "" -#: graphicswin.cpp:157 +#: graphicswin.cpp:158 msgid "At &Midpoint" msgstr "" -#: graphicswin.cpp:158 +#: graphicswin.cpp:159 msgid "S&ymmetric" msgstr "" -#: graphicswin.cpp:159 +#: graphicswin.cpp:160 msgid "Para&llel / Tangent" msgstr "" -#: graphicswin.cpp:160 +#: graphicswin.cpp:161 msgid "&Perpendicular" msgstr "" -#: graphicswin.cpp:161 +#: graphicswin.cpp:162 msgid "Same Orient&ation" msgstr "" -#: graphicswin.cpp:162 +#: graphicswin.cpp:163 msgid "Lock Point Where &Dragged" msgstr "" -#: graphicswin.cpp:164 +#: graphicswin.cpp:165 msgid "Comment" msgstr "" -#: graphicswin.cpp:166 +#: graphicswin.cpp:167 msgid "&Analyze" msgstr "" -#: graphicswin.cpp:167 +#: graphicswin.cpp:168 msgid "Measure &Volume" msgstr "" -#: graphicswin.cpp:168 +#: graphicswin.cpp:169 msgid "Measure A&rea" msgstr "" -#: graphicswin.cpp:169 +#: graphicswin.cpp:170 msgid "Measure &Perimeter" msgstr "" -#: graphicswin.cpp:170 +#: graphicswin.cpp:171 msgid "Show &Interfering Parts" msgstr "" -#: graphicswin.cpp:171 +#: graphicswin.cpp:172 msgid "Show &Naked Edges" msgstr "" -#: graphicswin.cpp:172 +#: graphicswin.cpp:173 msgid "Show &Center of Mass" msgstr "" -#: graphicswin.cpp:174 +#: graphicswin.cpp:175 msgid "Show &Underconstrained Points" msgstr "" -#: graphicswin.cpp:176 +#: graphicswin.cpp:177 msgid "&Trace Point" msgstr "" -#: graphicswin.cpp:177 +#: graphicswin.cpp:178 msgid "&Stop Tracing..." msgstr "" -#: graphicswin.cpp:178 +#: graphicswin.cpp:179 msgid "Step &Dimension..." msgstr "" -#: graphicswin.cpp:180 +#: graphicswin.cpp:181 msgid "&Help" msgstr "" -#: graphicswin.cpp:181 +#: graphicswin.cpp:182 msgid "&Language" msgstr "" -#: graphicswin.cpp:182 +#: graphicswin.cpp:183 msgid "&Website / Manual" msgstr "" -#: graphicswin.cpp:184 +#: graphicswin.cpp:185 msgid "&About" msgstr "" -#: graphicswin.cpp:352 +#: graphicswin.cpp:355 msgid "(no recent files)" msgstr "" -#: graphicswin.cpp:360 +#: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." msgstr "" -#: graphicswin.cpp:721 +#: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." msgstr "" -#: graphicswin.cpp:730 +#: graphicswin.cpp:740 msgid "" "The perspective factor is set to zero, so the view will always be a parallel projection.\n" "\n" @@ -972,89 +976,89 @@ msgid "" "around 0.3 is typical." msgstr "" -#: graphicswin.cpp:809 +#: graphicswin.cpp:819 msgid "Select a point; this point will become the center of the view on screen." msgstr "" -#: graphicswin.cpp:1103 +#: graphicswin.cpp:1114 msgid "No additional entities share endpoints with the selected entities." msgstr "" -#: graphicswin.cpp:1121 +#: graphicswin.cpp:1132 msgid "" "To use this command, select a point or other entity from an linked part, or make a link group the " "active group." msgstr "" -#: graphicswin.cpp:1144 +#: graphicswin.cpp:1155 msgid "" "No workplane is active. Activate a workplane (with Sketch -> In Workplane) to define the plane " "for the snap grid." msgstr "" -#: graphicswin.cpp:1151 +#: graphicswin.cpp:1162 msgid "" "Can't snap these items to grid; select points, text comments, or constraints with a label. To " "snap a line, select its endpoints." msgstr "" -#: graphicswin.cpp:1239 +#: graphicswin.cpp:1247 msgid "No workplane selected. Activating default workplane for this group." msgstr "" -#: graphicswin.cpp:1242 +#: graphicswin.cpp:1250 msgid "" "No workplane is selected, and the active group does not have a default workplane. Try selecting a " "workplane, or activating a sketch-in-new-workplane group." msgstr "" -#: graphicswin.cpp:1263 +#: graphicswin.cpp:1271 msgid "" "Bad selection for tangent arc at point. Select a single point, or select nothing to set up arc " "parameters." msgstr "" -#: graphicswin.cpp:1274 +#: graphicswin.cpp:1282 msgid "click point on arc (draws anti-clockwise)" msgstr "" -#: graphicswin.cpp:1275 +#: graphicswin.cpp:1283 msgid "click to place datum point" msgstr "" -#: graphicswin.cpp:1276 +#: graphicswin.cpp:1284 msgid "click first point of line segment" msgstr "" -#: graphicswin.cpp:1278 +#: graphicswin.cpp:1286 msgid "click first point of construction line segment" msgstr "" -#: graphicswin.cpp:1279 +#: graphicswin.cpp:1287 msgid "click first point of cubic segment" msgstr "" -#: graphicswin.cpp:1280 +#: graphicswin.cpp:1288 msgid "click center of circle" msgstr "" -#: graphicswin.cpp:1281 +#: graphicswin.cpp:1289 msgid "click origin of workplane" msgstr "" -#: graphicswin.cpp:1282 +#: graphicswin.cpp:1290 msgid "click one corner of rectangle" msgstr "" -#: graphicswin.cpp:1283 +#: graphicswin.cpp:1291 msgid "click top left of text" msgstr "" -#: graphicswin.cpp:1289 +#: graphicswin.cpp:1297 msgid "click top left of image" msgstr "" -#: graphicswin.cpp:1301 +#: graphicswin.cpp:1309 msgid "No entities are selected. Select entities before trying to toggle their construction state." msgstr "" @@ -1160,19 +1164,19 @@ msgstr "" msgid "(unnamed)" msgstr "" -#: groupmesh.cpp:708 +#: groupmesh.cpp:709 msgid "not closed contour, or not all same style!" msgstr "" -#: groupmesh.cpp:721 +#: groupmesh.cpp:722 msgid "points not all coplanar!" msgstr "" -#: groupmesh.cpp:723 +#: groupmesh.cpp:724 msgid "contour is self-intersecting!" msgstr "" -#: groupmesh.cpp:725 +#: groupmesh.cpp:726 msgid "zero-length edge!" msgstr "" @@ -1302,55 +1306,55 @@ msgstr "" msgid "Zoom to Fit" msgstr "" -#: mouse.cpp:990 mouse.cpp:1277 +#: mouse.cpp:989 mouse.cpp:1276 msgid "click next point of line, or press Esc" msgstr "" -#: mouse.cpp:996 +#: mouse.cpp:995 msgid "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In Workplane." msgstr "" -#: mouse.cpp:1030 +#: mouse.cpp:1029 msgid "click to place other corner of rectangle" msgstr "" -#: mouse.cpp:1050 +#: mouse.cpp:1049 msgid "click to set radius" msgstr "" -#: mouse.cpp:1055 +#: mouse.cpp:1054 msgid "Can't draw arc in 3d; first, activate a workplane with Sketch -> In Workplane." msgstr "" -#: mouse.cpp:1074 +#: mouse.cpp:1073 msgid "click to place point" msgstr "" -#: mouse.cpp:1090 +#: mouse.cpp:1089 msgid "click next point of cubic, or press Esc" msgstr "" -#: mouse.cpp:1095 +#: mouse.cpp:1094 msgid "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" -#: mouse.cpp:1111 +#: mouse.cpp:1110 msgid "Can't draw text in 3d; first, activate a workplane with Sketch -> In Workplane." msgstr "" -#: mouse.cpp:1128 +#: mouse.cpp:1127 msgid "click to place bottom right of text" msgstr "" -#: mouse.cpp:1134 +#: mouse.cpp:1133 msgid "Can't draw image in 3d; first, activate a workplane with Sketch -> In Workplane." msgstr "" -#: mouse.cpp:1161 +#: mouse.cpp:1160 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" -#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:505 +#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511 msgctxt "file-type" msgid "SolveSpace models" msgstr "" @@ -1435,33 +1439,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1317 platform/guimac.mm:1360 platform/guiwin.cpp:1615 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 msgid "untitled" msgstr "" -#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1318 -#: platform/guiwin.cpp:1562 +#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1568 msgctxt "title" msgid "Save File" msgstr "" -#: platform/guigtk.cpp:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1301 -#: platform/guiwin.cpp:1564 +#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1570 msgctxt "title" msgid "Open File" msgstr "" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1368 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 msgctxt "button" msgid "_Cancel" msgstr "" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 +#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 msgctxt "button" msgid "_Save" msgstr "" -#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367 +#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 msgctxt "button" msgid "_Open" msgstr "" @@ -1491,71 +1495,71 @@ msgctxt "button" msgid "Do&n't Load" msgstr "" -#: solvespace.cpp:551 +#: solvespace.cpp:557 msgctxt "title" msgid "Modified File" msgstr "" -#: solvespace.cpp:553 +#: solvespace.cpp:559 #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" msgstr "" -#: solvespace.cpp:556 +#: solvespace.cpp:562 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" msgstr "" -#: solvespace.cpp:559 +#: solvespace.cpp:565 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." msgstr "" -#: solvespace.cpp:560 +#: solvespace.cpp:566 msgctxt "button" msgid "&Save" msgstr "" -#: solvespace.cpp:562 +#: solvespace.cpp:568 msgctxt "button" msgid "Do&n't Save" msgstr "" -#: solvespace.cpp:583 +#: solvespace.cpp:589 msgctxt "title" msgid "(new sketch)" msgstr "" -#: solvespace.cpp:590 +#: solvespace.cpp:596 msgctxt "title" msgid "Property Browser" msgstr "" -#: solvespace.cpp:650 +#: solvespace.cpp:658 msgid "" "Constraints are currently shown, and will be exported in the toolpath. This is probably not what " "you want; hide them by clicking the link at the top of the text window." msgstr "" -#: solvespace.cpp:718 +#: solvespace.cpp:730 #, c-format msgid "Can't identify file type from file extension of filename '%s'; try .dxf or .dwg." msgstr "" -#: solvespace.cpp:766 +#: solvespace.cpp:778 msgid "Constraint must have a label, and must not be a reference dimension." msgstr "" -#: solvespace.cpp:770 +#: solvespace.cpp:782 msgid "Bad selection for step dimension; select a constraint." msgstr "" -#: solvespace.cpp:794 +#: solvespace.cpp:806 msgid "The assembly does not interfere, good." msgstr "" -#: solvespace.cpp:810 +#: solvespace.cpp:822 #, c-format msgid "" "The volume of the solid model is:\n" @@ -1563,7 +1567,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:819 +#: solvespace.cpp:831 #, c-format msgid "" "\n" @@ -1572,7 +1576,7 @@ msgid "" " %s" msgstr "" -#: solvespace.cpp:824 +#: solvespace.cpp:836 msgid "" "\n" "\n" @@ -1580,7 +1584,7 @@ msgid "" "This introduces error, typically of around 1%." msgstr "" -#: solvespace.cpp:839 +#: solvespace.cpp:851 #, c-format msgid "" "The surface area of the selected faces is:\n" @@ -1591,13 +1595,13 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:848 +#: solvespace.cpp:860 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, not coplanar, or self-" "intersecting." msgstr "" -#: solvespace.cpp:860 +#: solvespace.cpp:872 #, c-format msgid "" "The area of the region sketched in this group is:\n" @@ -1608,7 +1612,7 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:880 +#: solvespace.cpp:892 #, c-format msgid "" "The total length of the selected entities is:\n" @@ -1619,36 +1623,36 @@ msgid "" "This introduces error, typically of around 1%%." msgstr "" -#: solvespace.cpp:886 +#: solvespace.cpp:898 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" -#: solvespace.cpp:902 +#: solvespace.cpp:914 msgid "Bad selection for trace; select a single point." msgstr "" -#: solvespace.cpp:925 +#: solvespace.cpp:941 #, c-format msgid "Couldn't write to '%s'" msgstr "" -#: solvespace.cpp:955 +#: solvespace.cpp:971 msgid "The mesh is self-intersecting (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:956 +#: solvespace.cpp:972 msgid "The mesh is not self-intersecting (okay, valid)." msgstr "" -#: solvespace.cpp:958 +#: solvespace.cpp:974 msgid "The mesh has naked edges (NOT okay, invalid)." msgstr "" -#: solvespace.cpp:959 +#: solvespace.cpp:975 msgid "The mesh is watertight (okay, valid)." msgstr "" -#: solvespace.cpp:962 +#: solvespace.cpp:978 #, c-format msgid "" "\n" @@ -1656,7 +1660,7 @@ msgid "" "The model contains %d triangles, from %d surfaces." msgstr "" -#: solvespace.cpp:966 +#: solvespace.cpp:982 #, c-format msgid "" "%s\n" @@ -1666,7 +1670,7 @@ msgid "" "Zero problematic edges, good.%s" msgstr "" -#: solvespace.cpp:969 +#: solvespace.cpp:985 #, c-format msgid "" "%s\n" @@ -1676,7 +1680,7 @@ msgid "" "%d problematic edges, bad.%s" msgstr "" -#: solvespace.cpp:982 +#: solvespace.cpp:998 #, c-format msgid "" "This is SolveSpace version %s.\n" @@ -1824,30 +1828,38 @@ msgid "New group rotating active sketch" msgstr "" #: toolbar.cpp:72 -msgid "New group step and repeat rotating" +msgid "New group helix from active sketch" msgstr "" #: toolbar.cpp:74 -msgid "New group step and repeat translating" +msgid "New group revolve active sketch" msgstr "" #: toolbar.cpp:76 -msgid "New group in new workplane (thru given entities)" +msgid "New group step and repeat rotating" msgstr "" #: toolbar.cpp:78 -msgid "New group in 3d" +msgid "New group step and repeat translating" msgstr "" #: toolbar.cpp:80 -msgid "New group linking / assembling file" +msgid "New group in new workplane (thru given entities)" +msgstr "" + +#: toolbar.cpp:82 +msgid "New group in 3d" msgstr "" #: toolbar.cpp:84 +msgid "New group linking / assembling file" +msgstr "" + +#: toolbar.cpp:88 msgid "Nearest isometric view" msgstr "" -#: toolbar.cpp:86 +#: toolbar.cpp:90 msgid "Align view to active workplane" msgstr "" From 76589a8a879218f7ed67ffbbcd8070086baa6fe8 Mon Sep 17 00:00:00 2001 From: Jonathan Westhues Date: Fri, 15 Jan 2021 16:50:38 -0800 Subject: [PATCH 098/113] Fix SpaceNavigator type 6DOF controllers on Windows. We were creating the event but never dispatching it. --- src/platform/guiwin.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/platform/guiwin.cpp b/src/platform/guiwin.cpp index 745720a4..d8851958 100644 --- a/src/platform/guiwin.cpp +++ b/src/platform/guiwin.cpp @@ -734,6 +734,11 @@ public: event.type = SixDofEvent::Type::RELEASE; event.button = SixDofEvent::Button::FIT; } + } else { + return 0; + } + if(window->onSixDofEvent) { + window->onSixDofEvent(event); } return 0; } From 422bb0cb35d281ed20abb35dd7bef4fae5783e12 Mon Sep 17 00:00:00 2001 From: Reini Urban Date: Sun, 17 Jan 2021 15:37:34 +0100 Subject: [PATCH 099/113] Translations: update de_DE for 3.0 See #890 make -C src translate_solvespace to update all line numbers --- res/locales/de_DE.po | 24 ++++++++++++------------ res/locales/en_US.po | 8 ++++---- res/locales/fr_FR.po | 8 ++++---- res/locales/ru_RU.po | 8 ++++---- res/locales/uk_UA.po | 8 ++++---- res/locales/zh_CN.po | 8 ++++---- res/messages.pot | 8 ++++---- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po index 82807643..64ef5d4d 100644 --- a/res/locales/de_DE.po +++ b/res/locales/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-15 14:51-0600\n" +"POT-Creation-Date: 2021-01-17 15:23+0100\n" "PO-Revision-Date: 2018-07-19 06:55+0000\n" "Last-Translator: Reini Urban \n" "Language-Team: none\n" @@ -827,7 +827,7 @@ msgstr "Arbeitsraster anzeigen" #: graphicswin.cpp:95 msgid "Dim Solid for Sketch Groups" -msgstr "" +msgstr "Feste Farbe für Festkörper in Skizzen Gruppen" #: graphicswin.cpp:96 msgid "Use &Perspective Projection" @@ -1263,7 +1263,7 @@ msgid "" "lines)\n" " * a workplane (copy of the workplane)\n" msgstr "" -"Ungültige Auswahl für Skizze in neuer Arbeitsebene Diese Gruppe kann " +"Ungültige Auswahl für Skizze in neuer Arbeitsebene. Diese Gruppe kann " "erstellt werden mit:\n" "\n" " * einem Punkt (durch den Punkt, orthogonal zu den Koordinatenachsen)\n" @@ -1286,7 +1286,7 @@ msgstr "Extrusion" #: group.cpp:168 msgid "Lathe operation can only be applied to planar sketches." -msgstr "" +msgstr "Rotieren kann nur mit planaren Skizzen ausgeführt werden." #: group.cpp:179 msgid "" @@ -1296,7 +1296,7 @@ msgid "" "to line / normal, through point)\n" " * a line segment (revolved about line segment)\n" msgstr "" -"Ungültige Auswahl für neue Gruppe mit Drehquerschnitt Diese Gruppe kann " +"Ungültige Auswahl für neue Gruppe mit Drehquerschnitt. Diese Gruppe kann " "erstellt werden mit:\n" "\n" " * einem Punkt und einem Liniensegment oder einer Normale (Drehung um " @@ -1310,7 +1310,7 @@ msgstr "Drehung" #: group.cpp:194 msgid "Revolve operation can only be applied to planar sketches." -msgstr "" +msgstr "Revolve kann nur mit planaren Skizzen ausgeführt werden." #: group.cpp:205 msgid "" @@ -1328,7 +1328,7 @@ msgstr "Revolve" #: group.cpp:222 msgid "Helix operation can only be applied to planar sketches." -msgstr "" +msgstr "Helix kann nur mit planaren Skizzen ausgeführt werden." #: group.cpp:233 msgid "" @@ -1687,18 +1687,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "Werte durch Komma getrennt (CSV)" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 msgid "untitled" msgstr "unbenannt" #: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1573 msgctxt "title" msgid "Save File" msgstr "Datei speichern" #: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1575 msgctxt "title" msgid "Open File" msgstr "Datei öffnen" @@ -2150,11 +2150,11 @@ msgstr "Neue Gruppe mit rotierter aktiver Skizze" #: toolbar.cpp:72 msgid "New group helix from active sketch" -msgstr "" +msgstr "Neue Gruppe Helix von aktiver Skizze" #: toolbar.cpp:74 msgid "New group revolve active sketch" -msgstr "" +msgstr "Neue Gruppe mit gedrehter aktiver Skizze" #: toolbar.cpp:76 msgid "New group step and repeat rotating" diff --git a/res/locales/en_US.po b/res/locales/en_US.po index 9772d574..bc3c30b2 100644 --- a/res/locales/en_US.po +++ b/res/locales/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-15 14:51-0600\n" +"POT-Creation-Date: 2021-01-17 15:23+0100\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -1653,18 +1653,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "Comma-separated values" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 msgid "untitled" msgstr "untitled" #: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1573 msgctxt "title" msgid "Save File" msgstr "Save File" #: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1575 msgctxt "title" msgid "Open File" msgstr "Open File" diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po index a6f4c1e8..a86196e0 100644 --- a/res/locales/fr_FR.po +++ b/res/locales/fr_FR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-15 14:51-0600\n" +"POT-Creation-Date: 2021-01-17 15:23+0100\n" "PO-Revision-Date: 2018-07-14 06:12+0000\n" "Last-Translator: whitequark \n" "Language-Team: none\n" @@ -1667,18 +1667,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 msgid "untitled" msgstr "sans nom" #: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1573 msgctxt "title" msgid "Save File" msgstr "Sauver fichier" #: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1575 msgctxt "title" msgid "Open File" msgstr "Ouvrir Fichier" diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po index 07bab48f..83311537 100644 --- a/res/locales/ru_RU.po +++ b/res/locales/ru_RU.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-15 14:51-0600\n" +"POT-Creation-Date: 2021-01-17 15:23+0100\n" "PO-Revision-Date: 2017-04-21 10:29+0700\n" "Last-Translator: evilspirit@evilspirit.org\n" "Language-Team: EvilSpirit\n" @@ -1670,18 +1670,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "CSV файлы (значения, разделенные запятой)" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 msgid "untitled" msgstr "без имени" #: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1573 msgctxt "title" msgid "Save File" msgstr "Сохранить Файл" #: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1575 msgctxt "title" msgid "Open File" msgstr "Открыть Файл" diff --git a/res/locales/uk_UA.po b/res/locales/uk_UA.po index 3922b16b..de049298 100644 --- a/res/locales/uk_UA.po +++ b/res/locales/uk_UA.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-15 14:51-0600\n" +"POT-Creation-Date: 2021-01-17 15:23+0100\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: appsoft@ua.fm\n" "Language-Team: OpenOrienteeringUkraine\n" @@ -1477,18 +1477,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 msgid "untitled" msgstr "" #: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1573 msgctxt "title" msgid "Save File" msgstr "" #: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1575 msgctxt "title" msgid "Open File" msgstr "" diff --git a/res/locales/zh_CN.po b/res/locales/zh_CN.po index 34617119..67728ec1 100644 --- a/res/locales/zh_CN.po +++ b/res/locales/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-15 14:51-0600\n" +"POT-Creation-Date: 2021-01-17 15:23+0100\n" "PO-Revision-Date: 2020-09-28 12:42+0800\n" "Last-Translator: lomatus@163.com\n" "Language-Team: none\n" @@ -1564,18 +1564,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "逗号分隔数据" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 msgid "untitled" msgstr "未命名" #: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1573 msgctxt "title" msgid "Save File" msgstr "保存文件" #: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1575 msgctxt "title" msgid "Open File" msgstr "打开文件" diff --git a/res/messages.pot b/res/messages.pot index 33af7b26..d2af1d37 100644 --- a/res/messages.pot +++ b/res/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-15 14:51-0600\n" +"POT-Creation-Date: 2021-01-17 15:23+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -1439,18 +1439,18 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1625 +#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 msgid "untitled" msgstr "" #: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1568 +#: platform/guiwin.cpp:1573 msgctxt "title" msgid "Save File" msgstr "" #: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1570 +#: platform/guiwin.cpp:1575 msgctxt "title" msgid "Open File" msgstr "" From 0adb13c5e855ac41b611701fc9600925b224e3c9 Mon Sep 17 00:00:00 2001 From: ruevs Date: Sun, 17 Jan 2021 20:07:41 +0200 Subject: [PATCH 100/113] Change "Dim Solid for Sketch Groups" to "Darken Inactive Solids" Discussion here: https://github.com/solvespace/solvespace/issues/890 --- src/graphicswin.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/graphicswin.cpp b/src/graphicswin.cpp index d368c321..32b4b082 100644 --- a/src/graphicswin.cpp +++ b/src/graphicswin.cpp @@ -92,7 +92,7 @@ const MenuEntry Menu[] = { { 1, N_("&Center View At Point"), Command::CENTER_VIEW, F|4, KN, mView }, { 1, NULL, Command::NONE, 0, KN, NULL }, { 1, N_("Show Snap &Grid"), Command::SHOW_GRID, '>', KC, mView }, -{ 1, N_("Dim Solid for Sketch Groups"), Command::DIM_SOLID_MODEL, 0, KC, mView }, +{ 1, N_("Darken Inactive Solids"), Command::DIM_SOLID_MODEL, 0, KC, mView }, { 1, N_("Use &Perspective Projection"), Command::PERSPECTIVE_PROJ, '`', KC, mView }, { 1, N_("Dimension &Units"), Command::NONE, 0, KN, NULL }, { 2, N_("Dimensions in &Millimeters"), Command::UNITS_MM, 0, KR, mView }, From 1817816b4a93b8f2a40386c7ca5fe7548a41a78d Mon Sep 17 00:00:00 2001 From: ruevs Date: Sun, 17 Jan 2021 20:21:24 +0200 Subject: [PATCH 101/113] Update translations --- res/locales/de_DE.po | 4 ++-- res/locales/en_US.po | 8 ++++---- res/locales/fr_FR.po | 4 ++-- res/locales/ru_RU.po | 4 ++-- res/locales/uk_UA.po | 4 ++-- res/locales/zh_CN.po | 6 +++--- res/messages.pot | 4 ++-- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po index 64ef5d4d..24a2f190 100644 --- a/res/locales/de_DE.po +++ b/res/locales/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 15:23+0100\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" "PO-Revision-Date: 2018-07-19 06:55+0000\n" "Last-Translator: Reini Urban \n" "Language-Team: none\n" @@ -826,7 +826,7 @@ msgid "Show Snap &Grid" msgstr "Arbeitsraster anzeigen" #: graphicswin.cpp:95 -msgid "Dim Solid for Sketch Groups" +msgid "Darken Inactive Solids" msgstr "Feste Farbe für Festkörper in Skizzen Gruppen" #: graphicswin.cpp:96 diff --git a/res/locales/en_US.po b/res/locales/en_US.po index bc3c30b2..e7acd7e1 100644 --- a/res/locales/en_US.po +++ b/res/locales/en_US.po @@ -2,12 +2,12 @@ # Copyright (C) 2017 the SolveSpace authors # This file is distributed under the same license as the SolveSpace package. # Automatically generated, 2017. -# +# msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 15:23+0100\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -807,8 +807,8 @@ msgid "Show Snap &Grid" msgstr "Show Snap &Grid" #: graphicswin.cpp:95 -msgid "Dim Solid for Sketch Groups" -msgstr "Dim Solid for Sketch Groups" +msgid "Darken Inactive Solids" +msgstr "Darken Inactive Solids" #: graphicswin.cpp:96 msgid "Use &Perspective Projection" diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po index a86196e0..784b9610 100644 --- a/res/locales/fr_FR.po +++ b/res/locales/fr_FR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 15:23+0100\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" "PO-Revision-Date: 2018-07-14 06:12+0000\n" "Last-Translator: whitequark \n" "Language-Team: none\n" @@ -820,7 +820,7 @@ msgid "Show Snap &Grid" msgstr "Afficher la &grille d'accrochage" #: graphicswin.cpp:95 -msgid "Dim Solid for Sketch Groups" +msgid "Darken Inactive Solids" msgstr "" #: graphicswin.cpp:96 diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po index 83311537..8cc4e607 100644 --- a/res/locales/ru_RU.po +++ b/res/locales/ru_RU.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 15:23+0100\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" "PO-Revision-Date: 2017-04-21 10:29+0700\n" "Last-Translator: evilspirit@evilspirit.org\n" "Language-Team: EvilSpirit\n" @@ -814,7 +814,7 @@ msgid "Show Snap &Grid" msgstr "Показать &Сетку" #: graphicswin.cpp:95 -msgid "Dim Solid for Sketch Groups" +msgid "Darken Inactive Solids" msgstr "" #: graphicswin.cpp:96 diff --git a/res/locales/uk_UA.po b/res/locales/uk_UA.po index de049298..1f2a2101 100644 --- a/res/locales/uk_UA.po +++ b/res/locales/uk_UA.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 15:23+0100\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: appsoft@ua.fm\n" "Language-Team: OpenOrienteeringUkraine\n" @@ -694,7 +694,7 @@ msgid "Show Snap &Grid" msgstr "Показати &Сітку Прикріплення" #: graphicswin.cpp:95 -msgid "Dim Solid for Sketch Groups" +msgid "Darken Inactive Solids" msgstr "" #: graphicswin.cpp:96 diff --git a/res/locales/zh_CN.po b/res/locales/zh_CN.po index 67728ec1..245b452a 100644 --- a/res/locales/zh_CN.po +++ b/res/locales/zh_CN.po @@ -2,12 +2,12 @@ # Copyright (C) 2020 the PACKAGE authors # This file is distributed under the same license as the SolveSpace package. # , 2020. -# +# msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 15:23+0100\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" "PO-Revision-Date: 2020-09-28 12:42+0800\n" "Last-Translator: lomatus@163.com\n" "Language-Team: none\n" @@ -772,7 +772,7 @@ msgid "Show Snap &Grid" msgstr "显示捕捉轴线 (&G)" #: graphicswin.cpp:95 -msgid "Dim Solid for Sketch Groups" +msgid "Darken Inactive Solids" msgstr "" #: graphicswin.cpp:96 diff --git a/res/messages.pot b/res/messages.pot index d2af1d37..c5ce2b77 100644 --- a/res/messages.pot +++ b/res/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 15:23+0100\n" +"POT-Creation-Date: 2021-01-17 19:54+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -672,7 +672,7 @@ msgid "Show Snap &Grid" msgstr "" #: graphicswin.cpp:95 -msgid "Dim Solid for Sketch Groups" +msgid "Darken Inactive Solids" msgstr "" #: graphicswin.cpp:96 From 36719c62345ec1dd35400aa8e4fd7ecda3f6140e Mon Sep 17 00:00:00 2001 From: Reini Urban Date: Sun, 17 Jan 2021 20:04:03 +0100 Subject: [PATCH 102/113] Improved de_DE See #890 and its changed menu item --- res/locales/de_DE.po | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po index 24a2f190..9222a1dc 100644 --- a/res/locales/de_DE.po +++ b/res/locales/de_DE.po @@ -827,7 +827,7 @@ msgstr "Arbeitsraster anzeigen" #: graphicswin.cpp:95 msgid "Darken Inactive Solids" -msgstr "Feste Farbe für Festkörper in Skizzen Gruppen" +msgstr "Dunklere inaktive Festkörper" #: graphicswin.cpp:96 msgid "Use &Perspective Projection" @@ -1116,7 +1116,7 @@ msgstr "(keine vorhergehenden Dateien)" #: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." -msgstr "" +msgstr "Datei '%s' existiert nicht." #: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." @@ -1320,6 +1320,12 @@ msgid "" "to line / normal, through point)\n" " * a line segment (revolved about line segment)\n" msgstr "" +"Ungültige Auswahl für eine neue Revolve Gruppe. Diese Gruppe kann erzeugt " +"werden mit:\n" +"\n" +" * einem Punkt und einem Liniensegment oder Normale (gedreht um eine " +"Achse parallel zu Linie / Normale, durch Punkt)\n" +" * einem Liniensegment (gedreht um Liniensegment)\n" #: group.cpp:217 msgctxt "group-name" From d3951afb1288caa5ac6151181dcf9e7988f86ffe Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sun, 17 Jan 2021 17:38:04 -0500 Subject: [PATCH 103/113] GTK: Fix a warning for file->open dialogs. SetCurrentName only applies to save dialogs, so call it conditionally. --- src/platform/guigtk.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/platform/guigtk.cpp b/src/platform/guigtk.cpp index e8113ed2..1f0cc55d 100644 --- a/src/platform/guigtk.cpp +++ b/src/platform/guigtk.cpp @@ -1295,13 +1295,16 @@ public: } } +//TODO: This is not getting called when the extension selection is changed. void FilterChanged() { std::string extension = GetExtension(); if(extension.empty()) return; Platform::Path path = GetFilename(); - SetCurrentName(path.WithExtension(extension).FileName()); + if(gtkChooser->get_action() != GTK_FILE_CHOOSER_ACTION_OPEN) { + SetCurrentName(path.WithExtension(extension).FileName()); + } } void FreezeChoices(SettingsRef settings, const std::string &key) override { From 6d9bbb69d6c628cf7da066818095697c4986352a Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Mon, 18 Jan 2021 14:57:15 -0500 Subject: [PATCH 104/113] Update build instructons Add use of OPEN_MP to linux and macOS build instructions, and a mention of ENABLE_LTO. --- README.md | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6e575a5d..a5bb470e 100644 --- a/README.md +++ b/README.md @@ -94,13 +94,15 @@ After that, build SolveSpace as following: mkdir build cd build - cmake .. -DCMAKE_BUILD_TYPE=Release + cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_OPENMP=ON make sudo make install +Link Time Optimization is supported by adding -DENABLE_LTO=ON to cmake at the +expense of longer build time. + The graphical interface is built as `build/bin/solvespace`, and the command-line interface -is built as `build/bin/solvespace-cli`. It is possible to build only the command-line interface -by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation. +is built as `build/bin/solvespace-cli`. It is possible to build only the command-line interface by passing the `-DENABLE_GUI=OFF` flag to the cmake invocation. ### Building for Windows @@ -154,9 +156,12 @@ After that, build SolveSpace as following: mkdir build cd build - cmake .. -DCMAKE_BUILD_TYPE=Release + cmake .. -DCMAKE_BUILD_TYPE=Release -DENABLE_OPENMP=ON make +Link Time Optimization is supported by adding -DENABLE_LTO=ON to cmake at the +expense of longer build time. + Alternatively, generate an XCode project, open it, and build the "Release" scheme: mkdir build From d16e33ac48cb717f24a06a30e268227c860476d2 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Thu, 21 Jan 2021 15:25:09 -0600 Subject: [PATCH 105/113] Update to THREE.js revision 111 as found in Debian Testing Required some small JavaScript changes to replace deprecated usage. --- res/CMakeLists.txt | 2 +- res/threejs/SolveSpaceControls.js | 8 ++++---- res/threejs/three-r111.min.js.gz | Bin 0 -> 150121 bytes res/threejs/three-r76.js.gz | Bin 189743 -> 0 bytes src/export.cpp | 9 ++++++--- 5 files changed, 11 insertions(+), 8 deletions(-) create mode 100644 res/threejs/three-r111.min.js.gz delete mode 100644 res/threejs/three-r76.js.gz diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt index e261ba21..9152488d 100644 --- a/res/CMakeLists.txt +++ b/res/CMakeLists.txt @@ -284,7 +284,7 @@ add_resources( shaders/edge.frag shaders/edge.vert shaders/outline.vert - threejs/three-r76.js.gz + threejs/three-r111.min.js.gz threejs/hammer-2.0.8.js.gz threejs/SolveSpaceControls.js) diff --git a/res/threejs/SolveSpaceControls.js b/res/threejs/SolveSpaceControls.js index e141acee..ca74fd52 100644 --- a/res/threejs/SolveSpaceControls.js +++ b/res/threejs/SolveSpaceControls.js @@ -470,9 +470,9 @@ solvespace = function(obj, params) { 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]]); + var newLightPos = new THREE.Vector3(obj.lights.d[i].direction[0], + obj.lights.d[i].direction[1], + obj.lights.d[i].direction[2]).applyMatrix4(changeBasis); directionalLightArray[i].position.set(newLightPos[0], newLightPos[1], newLightPos[2]); } @@ -515,7 +515,7 @@ solvespace = function(obj, params) { } geometry.computeBoundingSphere(); - return new THREE.Mesh(geometry, new THREE.MultiMaterial(materialList)); + return new THREE.Mesh(geometry, materialList); } function createEdges(meshObj) { diff --git a/res/threejs/three-r111.min.js.gz b/res/threejs/three-r111.min.js.gz new file mode 100644 index 0000000000000000000000000000000000000000..7e6f57f193dbe4f9463bd9e1f232d6d3e37832dc GIT binary patch literal 150121 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෋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

wF@RB5oZrwJD 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 Three.js Solvespace Mesh - + @@ -1019,7 +1021,10 @@ void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const Platform::Path &filename fprintf(f, htmlbegin, THREE_FN.c_str(), LoadStringFromGzip("threejs/" + THREE_FN + ".gz").c_str(), - LoadString("threejs/SolveSpaceControls.js").c_str()); + HAMMER_FN.c_str(), + LoadStringFromGzip("threejs/" + HAMMER_FN + ".gz").c_str(), + CONTROLS_FN.c_str(), + LoadString("threejs/" + CONTROLS_FN).c_str()); } fprintf(f, "var solvespace_model_%s = {\n" From 2e1f5324c8d3bba948f8fc3a66484185cfd6b643 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Sat, 23 Jan 2021 11:45:33 -0500 Subject: [PATCH 107/113] Update ru_RU translation --- res/locales/ru_RU.po | 182 +++++++++++++++++++++++++++++++++---------- 1 file changed, 141 insertions(+), 41 deletions(-) diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po index 8cc4e607..d4377246 100644 --- a/res/locales/ru_RU.po +++ b/res/locales/ru_RU.po @@ -7,7 +7,7 @@ msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" "POT-Creation-Date: 2021-01-17 19:54+0200\n" -"PO-Revision-Date: 2017-04-21 10:29+0700\n" +"PO-Revision-Date: 2021-01-22 18:50+0700\n" "Last-Translator: evilspirit@evilspirit.org\n" "Language-Team: EvilSpirit\n" "Language: ru_RU\n" @@ -15,7 +15,7 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -"X-Generator: Poedit 2.0.1\n" +"X-Generator: Poedit 2.4.2\n" #: clipboard.cpp:310 msgid "" @@ -560,6 +560,7 @@ msgid "" "No solid model present; draw one with extrudes and revolves, or use Export " "2d View to export bare lines and curves." msgstr "" +"Тела не найдены; создайте их или используйте экспорт двумерных объектов." #: export.cpp:61 msgid "" @@ -570,10 +571,17 @@ msgid "" " * a point and two line segments (plane through point and parallel to " "lines)\n" msgstr "" +"Неправильное выделение для экспорта сечения. Необходимо выделить:\n" +"\n" +" * Ничего, но с активированной рабочей плоскостью (рабочая плоскость " +"будет плоскостью сечения)\n" +" * грань (сечение через грань)\n" +" * точку и два отрезка (сечение плоскостью, заданной двумя отрезками, " +"построенной через указанную точку)\n" #: export.cpp:822 msgid "Active group mesh is empty; nothing to export." -msgstr "" +msgstr "Активная группа не содержит тел; нечего экспортировать." #: exportvector.cpp:337 msgid "freehand lines were replaced with continuous lines" @@ -624,7 +632,7 @@ msgstr "Файл Отсутствует" #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." -msgstr "" +msgstr "Связанный файл “%s” отсутствует." #: file.cpp:862 msgctxt "dialog" @@ -767,7 +775,7 @@ msgstr "С&бросить Выделение" #: graphicswin.cpp:78 msgid "&Line Styles..." -msgstr "" +msgstr "Стили Линий..." #: graphicswin.cpp:79 msgid "&View Projection..." @@ -775,7 +783,7 @@ msgstr "&View Прое&кция..." #: graphicswin.cpp:81 msgid "Con&figuration..." -msgstr "" +msgstr "Настройки..." #: graphicswin.cpp:84 msgid "&View" @@ -815,7 +823,7 @@ msgstr "Показать &Сетку" #: graphicswin.cpp:95 msgid "Darken Inactive Solids" -msgstr "" +msgstr "Затемнять Неактивные Тела" #: graphicswin.cpp:96 msgid "Use &Perspective Projection" @@ -823,7 +831,7 @@ msgstr "Перспективная Прое&кция" #: graphicswin.cpp:97 msgid "Dimension &Units" -msgstr "" +msgstr "Единицы Измерения" #: graphicswin.cpp:98 msgid "Dimensions in &Millimeters" @@ -831,7 +839,7 @@ msgstr "Размеры в Ми&ллиметрах" #: graphicswin.cpp:99 msgid "Dimensions in M&eters" -msgstr "" +msgstr "Размеры в Метрах" #: graphicswin.cpp:100 msgid "Dimensions in &Inches" @@ -875,7 +883,7 @@ msgstr "Тело &Выдавливания" #: graphicswin.cpp:115 msgid "&Helix" -msgstr "" +msgstr "Тело Винтовое" #: graphicswin.cpp:116 msgid "&Lathe" @@ -883,7 +891,7 @@ msgstr "Тело В&ращения" #: graphicswin.cpp:117 msgid "Re&volve" -msgstr "" +msgstr "Тело В&ращения" #: graphicswin.cpp:119 msgid "Link / Assemble..." @@ -1063,11 +1071,11 @@ msgstr "Показать Про&блемные Ребра" #: graphicswin.cpp:173 msgid "Show &Center of Mass" -msgstr "" +msgstr "Показать Центр Масс" #: graphicswin.cpp:175 msgid "Show &Underconstrained Points" -msgstr "" +msgstr "Показать Свободные Точки" #: graphicswin.cpp:177 msgid "&Trace Point" @@ -1104,7 +1112,7 @@ msgstr "(пусто)" #: graphicswin.cpp:363 #, c-format msgid "File '%s' does not exist." -msgstr "" +msgstr "Файл '%s' не существует." #: graphicswin.cpp:725 msgid "No workplane is active, so the grid will not appear." @@ -1229,6 +1237,7 @@ msgstr "кликните мышью там, где хотите создать #: graphicswin.cpp:1297 msgid "click top left of image" msgstr "" +"кликните мышью там, где будет расположен левый верхний угол изображения" #: graphicswin.cpp:1309 msgid "" @@ -1278,6 +1287,8 @@ msgstr "тело-выдавливания" #: group.cpp:168 msgid "Lathe operation can only be applied to planar sketches." msgstr "" +"Операция создания тела вращения может быть применена только к плоским " +"эскизам." #: group.cpp:179 msgid "" @@ -1304,6 +1315,8 @@ msgstr "тело-вращения" #: group.cpp:194 msgid "Revolve operation can only be applied to planar sketches." msgstr "" +"Операция создания тела вращения может быть применена только к плоским " +"эскизам." #: group.cpp:205 msgid "" @@ -1313,15 +1326,25 @@ msgid "" "to line / normal, through point)\n" " * a line segment (revolved about line segment)\n" msgstr "" +"Неправильное выделение для создания группы тела вращения. \n" +"Группа может быть создана, используя в качестве выделения следующие " +"примитивы:\n" +"\n" +" * точку и отрезок / координатных базис (нормаль) (тело вращения вокруг " +"оси, проходящей через точку и параллельной отрезку / нормали)\n" +" * отрезок (тело вращения вокруг оси, проходящей через отрезок)\n" +"\n" #: group.cpp:217 msgctxt "group-name" msgid "revolve" -msgstr "" +msgstr "тело-вращения" #: group.cpp:222 msgid "Helix operation can only be applied to planar sketches." msgstr "" +"Операция создания винтового тела может быть применена только к плоским " +"эскизам." #: group.cpp:233 msgid "" @@ -1331,11 +1354,19 @@ msgid "" "to line / normal, through point)\n" " * a line segment (revolved about line segment)\n" msgstr "" +"Неправильное выделение для создания винтового тела.\n" +"Группа может быть создана, используя в качестве выделения следующие " +"примитивы:\n" +"\n" +" * точку и отрезок или координатный базис (нормаль) (вращение вокруг " +"направления, параллельного линии / нормали, построенное через выбранную " +"точку)\n" +" * отрезок (вращение вокруг отрезка)\n" #: group.cpp:245 msgctxt "group-name" msgid "helix" -msgstr "" +msgstr "тело-винтовое" #: group.cpp:258 msgid "" @@ -1424,6 +1455,8 @@ msgid "" "Select two entities that intersect each other (e.g. two lines/circles/arcs " "or a line/circle/arc and a point)." msgstr "" +"Выберите два пересекающихся примитива (два отрезка/окружности/дуги или " +"отрезок/окружность/дугу и точку)" #: modify.cpp:736 msgid "Can't split; no intersection found." @@ -1573,13 +1606,13 @@ msgstr "Невозможно создать текст, когда нет акт #: mouse.cpp:1127 msgid "click to place bottom right of text" -msgstr "" +msgstr "кликните, чтобы расположить правый нижний угол текста" #: mouse.cpp:1133 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." -msgstr "" +msgstr "Невозможно создать изображение. Активируйте рабочую плоскость." #: mouse.cpp:1160 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" @@ -1593,7 +1626,7 @@ msgstr "проекты SolveSpace" #: platform/gui.cpp:90 msgctxt "file-type" msgid "IDF circuit board" -msgstr "" +msgstr "IDF печатная плата" #: platform/gui.cpp:94 msgctxt "file-type" @@ -1623,7 +1656,7 @@ msgstr "Three.js-совместимая полигональная сетка" #: platform/gui.cpp:102 msgctxt "file-type" msgid "VRML text file" -msgstr "" +msgstr "VRML файл" #: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120 msgctxt "file-type" @@ -1699,7 +1732,7 @@ msgstr "Сохранить" #: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 msgctxt "button" msgid "_Open" -msgstr "" +msgstr "_Открыть" #: solvespace.cpp:169 msgctxt "title" @@ -1709,22 +1742,22 @@ msgstr "Автосохранение Доступно" #: solvespace.cpp:170 msgctxt "dialog" msgid "An autosave file is available for this sketch." -msgstr "" +msgstr "Автоматически сохраненный файл доступен для данного проекта." #: solvespace.cpp:171 msgctxt "dialog" msgid "Do you want to load the autosave file instead?" -msgstr "" +msgstr "Хотите загрузить автосохраненный файл вместо исходного?" #: solvespace.cpp:172 msgctxt "button" msgid "&Load autosave" -msgstr "" +msgstr "&Загрузить Автосохранение" #: solvespace.cpp:174 msgctxt "button" msgid "Do&n't Load" -msgstr "" +msgstr "&Не Загружать" #: solvespace.cpp:557 msgctxt "title" @@ -1735,27 +1768,27 @@ msgstr "Измененный Файл" #, c-format msgctxt "dialog" msgid "Do you want to save the changes you made to the sketch “%s”?" -msgstr "" +msgstr "Сохранить изменения, сделанные в файле “%s”?" #: solvespace.cpp:562 msgctxt "dialog" msgid "Do you want to save the changes you made to the new sketch?" -msgstr "" +msgstr "Сохранить изменения, сделанные в новом проекте?" #: solvespace.cpp:565 msgctxt "dialog" msgid "Your changes will be lost if you don't save them." -msgstr "" +msgstr "Изменения будут утеряны, если их не сохранить." #: solvespace.cpp:566 msgctxt "button" msgid "&Save" -msgstr "" +msgstr "&Сохранить" #: solvespace.cpp:568 msgctxt "button" msgid "Do&n't Save" -msgstr "" +msgstr "&Не Сохранять" #: solvespace.cpp:589 msgctxt "title" @@ -1773,6 +1806,9 @@ msgid "" "is probably not what you want; hide them by clicking the link at the top of " "the text window." msgstr "" +"Ограничения отображаются, и будут экспортированы в файл. Предположительно, " +"это не то, что требуется, если так, необходимо спрятать их, нажав ссылку " +"вверху окна Браузера." #: solvespace.cpp:730 #, c-format @@ -1780,18 +1816,22 @@ msgid "" "Can't identify file type from file extension of filename '%s'; try .dxf or ." "dwg." msgstr "" +"Неподдерживаемый тип файла '%s'; Поддерживаются файлы с расширением .dxf и ." +"dwg." #: solvespace.cpp:778 msgid "Constraint must have a label, and must not be a reference dimension." -msgstr "" +msgstr "У ограничения должно быть значение и оно не должно быть справочным." #: solvespace.cpp:782 msgid "Bad selection for step dimension; select a constraint." msgstr "" +"Неправильное выделение для операции изменения значения с заданным шагом; " +"необходимо выбрать ограничение со значением." #: solvespace.cpp:806 msgid "The assembly does not interfere, good." -msgstr "" +msgstr "Сборка не содержит пересечения деталей - это хорошо." #: solvespace.cpp:822 #, c-format @@ -1800,6 +1840,9 @@ msgid "" "\n" " %s" msgstr "" +"Объем тел:\n" +"\n" +" %s" #: solvespace.cpp:831 #, c-format @@ -1809,6 +1852,10 @@ msgid "" "\n" " %s" msgstr "" +"\n" +"Объем тел текущей группы:\n" +"\n" +" %s" #: solvespace.cpp:836 msgid "" @@ -1817,6 +1864,10 @@ msgid "" "Curved surfaces have been approximated as triangles.\n" "This introduces error, typically of around 1%." msgstr "" +"\n" +"\n" +"Кривые аппроксимированы кусочно-линейными функциями.\n" +"Это приводит к ошибке в расчетах, обычно в пределах 1%." #: solvespace.cpp:851 #, c-format @@ -1828,12 +1879,20 @@ msgid "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." msgstr "" +"Площадь поверхности выбранных граней:\n" +"\n" +" %s\n" +"\n" +"Кривые аппроксимированы кусочно-линейными функциями.\n" +"Это приводит к ошибке в расчетах, обычно в пределах 1%%." #: solvespace.cpp:860 msgid "" "This group does not contain a correctly-formed 2d closed area. It is open, " "not coplanar, or self-intersecting." msgstr "" +"Эта группа не содержит замкнутых областей. В ней нет замкнутых контуров, " +"примитивы не лежат в одной плоскости или самопересекаются." #: solvespace.cpp:872 #, c-format @@ -1845,6 +1904,12 @@ msgid "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." msgstr "" +"Площадь замкнутой области текущей группы:\n" +"\n" +" %s\n" +"\n" +"Кривые аппроксимированы кусочно-линейными функциями.\n" +"Это приводит к ошибке в расчетах, обычно в пределах 1%%." #: solvespace.cpp:892 #, c-format @@ -1856,35 +1921,43 @@ msgid "" "Curves have been approximated as piecewise linear.\n" "This introduces error, typically of around 1%%." msgstr "" +"Длина выбранных примитивов:\n" +"\n" +" %s\n" +"\n" +"Кривые аппроксимированы кусочно-линейными функциями.\n" +"Это приводит к ошибке в расчетах, обычно в пределах 1%%." #: solvespace.cpp:898 msgid "Bad selection for perimeter; select line segments, arcs, and curves." msgstr "" +"Неправильное выделение для расчета периметра; необходимо выбирать только " +"отрезки, дуги и кривые в качестве исходных данных" #: solvespace.cpp:914 msgid "Bad selection for trace; select a single point." -msgstr "" +msgstr "Неправильное выделение для трассировки; необходимо выбрать одну точку." #: solvespace.cpp:941 #, c-format msgid "Couldn't write to '%s'" -msgstr "" +msgstr "Невозможно записать в '%s'" #: solvespace.cpp:971 msgid "The mesh is self-intersecting (NOT okay, invalid)." -msgstr "" +msgstr "Полигональная стека содержит самопересечения (это плохо)" #: solvespace.cpp:972 msgid "The mesh is not self-intersecting (okay, valid)." -msgstr "" +msgstr "Полигональная стека не содержит самопересечений (это хорошо)" #: solvespace.cpp:974 msgid "The mesh has naked edges (NOT okay, invalid)." -msgstr "" +msgstr "Полигональная сетка содержит \"оголенные\" ребра (это плохо)" #: solvespace.cpp:975 msgid "The mesh is watertight (okay, valid)." -msgstr "" +msgstr "Полигональная сетка герметична (это хорошо)" #: solvespace.cpp:978 #, c-format @@ -1893,6 +1966,9 @@ msgid "" "\n" "The model contains %d triangles, from %d surfaces." msgstr "" +"\n" +"\n" +"Модель содержит %d треугольников, содержащихся в %d поверхностях." #: solvespace.cpp:982 #, c-format @@ -1903,6 +1979,11 @@ msgid "" "\n" "Zero problematic edges, good.%s" msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"Нет проблемных ребер - это хорошо.%s" #: solvespace.cpp:985 #, c-format @@ -1913,6 +1994,11 @@ msgid "" "\n" "%d problematic edges, bad.%s" msgstr "" +"%s\n" +"\n" +"%s\n" +"\n" +"%d найдены проблемные ребра - это плохо.%s" #: solvespace.cpp:998 #, c-format @@ -1930,6 +2016,20 @@ msgid "" "\n" "© 2008-%d Jonathan Westhues and other authors.\n" msgstr "" +"Это SolveSpace версии %s.\n" +"\n" +"Для дополнительной информации посетите сайт: http://solvespace.com/\n" +"\n" +"SolveSpace - это свободное программное обеспечение: поощряется изменение, " +"улучшение\n" +"распространение программы по условиям лицензии GNU\n" +"General Public License (GPL) версии 3 или новее.\n" +"\n" +"НИКАКИХ ГАРАНТИЙ за пределами прав, \n" +"предусмотренных законом. Дополнительная информация на сайте: http://gnu.org/" +"licenses/\n" +"\n" +"© 2008-%d Джонатан Вэстью и другие авторы.\n" #: style.cpp:166 msgid "" @@ -1985,7 +2085,7 @@ msgstr "Начертить текст TrueType" #: toolbar.cpp:28 msgid "Sketch image from a file" -msgstr "" +msgstr "Импортировать изображение из файла" #: toolbar.cpp:30 msgid "Create tangent arc at selected point" @@ -2065,11 +2165,11 @@ msgstr "Создать группу вращения текущего эскиз #: toolbar.cpp:72 msgid "New group helix from active sketch" -msgstr "" +msgstr "Создать группу тела выдавливания по винтовой линии из текущего эскиза" #: toolbar.cpp:74 msgid "New group revolve active sketch" -msgstr "" +msgstr "Создать группу тела вращения из текущего эскиза" #: toolbar.cpp:76 msgid "New group step and repeat rotating" From ebb194eda673c97501edeefd5849c9a70291d061 Mon Sep 17 00:00:00 2001 From: phkahler <14852918+phkahler@users.noreply.github.com> Date: Mon, 25 Jan 2021 20:41:28 -0500 Subject: [PATCH 108/113] Add version command to solvespace-cli --- src/platform/entrycli.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/platform/entrycli.cpp b/src/platform/entrycli.cpp index 61b20db1..70b6919b 100644 --- a/src/platform/entrycli.cpp +++ b/src/platform/entrycli.cpp @@ -4,6 +4,7 @@ // Copyright 2016 whitequark //----------------------------------------------------------------------------- #include "solvespace.h" +#include "config.h" static void ShowUsage(const std::string &cmd) { fprintf(stderr, "Usage: %s [filename...]", cmd.c_str()); @@ -29,6 +30,8 @@ Common options: Whether to export the background colour in vector formats. Defaults to off. Commands: + version + Prints the current solvespace version. thumbnail --output --size --view [--chord-tol ] Outputs a rendered view of the sketch, like the SolveSpace GUI would. @@ -174,7 +177,10 @@ static bool RunCommand(const std::vector args) { }; unsigned width = 0, height = 0; - if(args[1] == "thumbnail") { + if(args[1] == "version") { + fprintf(stderr, "SolveSpace version %s \n\n", PACKAGE_VERSION); + return false; + } else if(args[1] == "thumbnail") { auto ParseSize = [&](size_t &argn) { if(argn + 1 < args.size() && args[argn] == "--size") { argn++; From 11a8a0abd5e21a0da6c818674f8b4b657a401a6c Mon Sep 17 00:00:00 2001 From: robnee Date: Fri, 29 Jan 2021 08:52:10 -0500 Subject: [PATCH 109/113] do not Invalidate() when dragging new points to prevent refresh bugs on Windows --- src/mouse.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/mouse.cpp b/src/mouse.cpp index 729c8ee2..263211da 100644 --- a/src/mouse.cpp +++ b/src/mouse.cpp @@ -305,7 +305,6 @@ void GraphicsWindow::MouseMoved(double x, double y, bool leftDown, HitTestMakeSelection(mp); SS.MarkGroupDirtyByEntity(pending.point); orig.mouse = mp; - Invalidate(); break; case Pending::DRAGGING_POINTS: From 1c5c4c048c83eaa440e82f9d4a3394338a29afda Mon Sep 17 00:00:00 2001 From: ruevs Date: Mon, 1 Feb 2021 15:43:19 +0200 Subject: [PATCH 110/113] Fix a crash when opening an empty file. Fixes: https://github.com/solvespace/solvespace/issues/918 The problem was that here: https://github.com/solvespace/solvespace/blob/11a8a0abd5e21a0da6c818674f8b4b657a401a6c/src/file.cpp#L480 we cleared all groups. Then we tried to read an empty file and therefore this `while` exited immediately: https://github.com/solvespace/solvespace/blob/11a8a0abd5e21a0da6c818674f8b4b657a401a6c/src/file.cpp#L487 and we came to here: https://github.com/solvespace/solvespace/blob/11a8a0abd5e21a0da6c818674f8b4b657a401a6c/src/file.cpp#L548 where there was no `fileLoadError` and thus we were left with no groups, and so this assert failed: https://github.com/solvespace/solvespace/blob/11a8a0abd5e21a0da6c818674f8b4b657a401a6c/src/graphicswin.cpp#L394 since is is not allowed to have no groups :-) --- src/file.cpp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/file.cpp b/src/file.cpp index f36e49b3..160b5ec7 100644 --- a/src/file.cpp +++ b/src/file.cpp @@ -468,6 +468,7 @@ void SolveSpaceUI::LoadUsingTable(const Platform::Path &filename, char *key, cha } bool SolveSpaceUI::LoadFromFile(const Platform::Path &filename, bool canCancel) { + bool fileIsEmpty = true; allConsistent = false; fileLoadError = false; @@ -485,6 +486,8 @@ bool SolveSpaceUI::LoadFromFile(const Platform::Path &filename, bool canCancel) char line[1024]; while(fgets(line, (int)sizeof(line), fh)) { + fileIsEmpty = false; + char *s = strchr(line, '\n'); if(s) *s = '\0'; // We should never get files with \r characters in them, but mailers @@ -545,6 +548,11 @@ bool SolveSpaceUI::LoadFromFile(const Platform::Path &filename, bool canCancel) fclose(fh); + if(fileIsEmpty) { + Error(_("The file is empty. It may be corrupt.")); + NewFile(); + } + if(fileLoadError) { Error(_("Unrecognized data in file. This file may be corrupt, or " "from a newer version of the program.")); From 02aa9ea827a128636e2d56d472e25b311868e073 Mon Sep 17 00:00:00 2001 From: ruevs Date: Mon, 1 Feb 2021 15:56:14 +0200 Subject: [PATCH 111/113] Update translations Including de_DE and ru_RU strings. --- res/locales/de_DE.po | 106 ++++++++++++++++++++++--------------------- res/locales/en_US.po | 106 ++++++++++++++++++++++--------------------- res/locales/fr_FR.po | 106 ++++++++++++++++++++++--------------------- res/locales/ru_RU.po | 106 ++++++++++++++++++++++--------------------- res/locales/uk_UA.po | 106 ++++++++++++++++++++++--------------------- res/locales/zh_CN.po | 106 ++++++++++++++++++++++--------------------- res/messages.pot | 106 ++++++++++++++++++++++--------------------- 7 files changed, 385 insertions(+), 357 deletions(-) diff --git a/res/locales/de_DE.po b/res/locales/de_DE.po index 9222a1dc..bbd3fcda 100644 --- a/res/locales/de_DE.po +++ b/res/locales/de_DE.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"POT-Creation-Date: 2021-02-01 15:45+0200\n" "PO-Revision-Date: 2018-07-19 06:55+0000\n" "Last-Translator: Reini Urban \n" "Language-Team: none\n" @@ -619,7 +619,11 @@ msgctxt "group-name" msgid "#references" msgstr "#Referenzen" -#: file.cpp:549 +#: file.cpp:552 +msgid "The file is empty. It may be corrupt." +msgstr "Die Datei ist leer. Es kann beschädigt sein." + +#: file.cpp:557 msgid "" "Unrecognized data in file. This file may be corrupt, or from a newer version " "of the program." @@ -627,18 +631,18 @@ msgstr "" "Nicht erkannte Daten in der Datei. Diese Datei könnte beschädigt sein oder " "von einer neueren Version des Programms stammen." -#: file.cpp:859 +#: file.cpp:867 msgctxt "title" msgid "Missing File" msgstr "Fehlende Datei" -#: file.cpp:860 +#: file.cpp:868 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "Die verlinkte Datei “%s” fehlt." -#: file.cpp:862 +#: file.cpp:870 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -650,17 +654,17 @@ msgstr "" "Falls Sie ablehnen, wird jegliche mit der fehlenden Datei verknüpfte " "Geometrie verworfen." -#: file.cpp:865 +#: file.cpp:873 msgctxt "button" msgid "&Yes" msgstr "&Ja" -#: file.cpp:867 +#: file.cpp:875 msgctxt "button" msgid "&No" msgstr "&Nein" -#: file.cpp:869 solvespace.cpp:569 +#: file.cpp:877 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "&Abbrechen" @@ -1446,105 +1450,105 @@ msgstr "" msgid "Can't split; no intersection found." msgstr "Trennen nicht möglich; keine Überschneidung gefunden." -#: mouse.cpp:560 +#: mouse.cpp:559 msgid "Assign to Style" msgstr "Linientyp zuordnen" -#: mouse.cpp:576 +#: mouse.cpp:575 msgid "No Style" msgstr "Kein Linientyp" -#: mouse.cpp:579 +#: mouse.cpp:578 msgid "Newly Created Custom Style..." msgstr "Neu erstellter benutzerdefinierter Linientyp…" -#: mouse.cpp:586 +#: mouse.cpp:585 msgid "Group Info" msgstr "Info zu Gruppe" -#: mouse.cpp:606 +#: mouse.cpp:605 msgid "Style Info" msgstr "Info zu Linientyp" -#: mouse.cpp:626 +#: mouse.cpp:625 msgid "Select Edge Chain" msgstr "Kantenverlauf auswählen" -#: mouse.cpp:632 +#: mouse.cpp:631 msgid "Toggle Reference Dimension" msgstr "Von/zu Referenzangabe wechseln" -#: mouse.cpp:638 +#: mouse.cpp:637 msgid "Other Supplementary Angle" msgstr "Anderer Komplementärwinkel" -#: mouse.cpp:643 +#: mouse.cpp:642 msgid "Snap to Grid" msgstr "Auf Raster ausrichten" -#: mouse.cpp:652 +#: mouse.cpp:651 msgid "Remove Spline Point" msgstr "Spline-Punkt löschen" -#: mouse.cpp:687 +#: mouse.cpp:686 msgid "Add Spline Point" msgstr "Spline-Punkt hinzufügen" -#: mouse.cpp:691 +#: mouse.cpp:690 msgid "Cannot add spline point: maximum number of points reached." msgstr "" "Spline-Punkt kann nicht hinzugefügt werden: maximale Anzahl der Punkte " "erreicht." -#: mouse.cpp:716 +#: mouse.cpp:715 msgid "Toggle Construction" msgstr "Konstruktionselement an/aus" -#: mouse.cpp:731 +#: mouse.cpp:730 msgid "Delete Point-Coincident Constraint" msgstr "Einschränkung \"Punkte deckungsgleich\" löschen" -#: mouse.cpp:750 +#: mouse.cpp:749 msgid "Cut" msgstr "Ausschneiden" -#: mouse.cpp:752 +#: mouse.cpp:751 msgid "Copy" msgstr "Kopieren" -#: mouse.cpp:756 +#: mouse.cpp:755 msgid "Select All" msgstr "Alle auswählen" -#: mouse.cpp:761 +#: mouse.cpp:760 msgid "Paste" msgstr "Einfügen" -#: mouse.cpp:763 +#: mouse.cpp:762 msgid "Paste Transformed..." msgstr "Einfügen und transformieren…" -#: mouse.cpp:768 +#: mouse.cpp:767 msgid "Delete" msgstr "Löschen" -#: mouse.cpp:771 +#: mouse.cpp:770 msgid "Unselect All" msgstr "Alle deselektieren" -#: mouse.cpp:778 +#: mouse.cpp:777 msgid "Unselect Hovered" msgstr "Aktive deselektieren" -#: mouse.cpp:787 +#: mouse.cpp:786 msgid "Zoom to Fit" msgstr "Zoom an Bildschirm anpassen" -#: mouse.cpp:989 mouse.cpp:1276 +#: mouse.cpp:988 mouse.cpp:1275 msgid "click next point of line, or press Esc" msgstr "Klicken Sie auf den nächsten Punkt der Linie, oder drücken Sie Esc" -#: mouse.cpp:995 +#: mouse.cpp:994 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1552,15 +1556,15 @@ msgstr "" "Ein Rechteck kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " "Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." -#: mouse.cpp:1029 +#: mouse.cpp:1028 msgid "click to place other corner of rectangle" msgstr "Klicken Sie auf die gegenüberliegende Ecke des Rechtecks" -#: mouse.cpp:1049 +#: mouse.cpp:1048 msgid "click to set radius" msgstr "Klicken Sie, um den Radius festzulegen" -#: mouse.cpp:1054 +#: mouse.cpp:1053 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1568,23 +1572,23 @@ msgstr "" "Ein Kreisbogen kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " "Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." -#: mouse.cpp:1073 +#: mouse.cpp:1072 msgid "click to place point" msgstr "Klicken Sie, um einen Punkt zu platzieren" -#: mouse.cpp:1089 +#: mouse.cpp:1088 msgid "click next point of cubic, or press Esc" msgstr "" "Klicken Sie auf den nächsten Punkt der kubischen Linie, oder drücken Sie Esc" -#: mouse.cpp:1094 +#: mouse.cpp:1093 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" "Eine Arbeitsebene ist bereits aktiv. Skizzieren Sie in 3D, bevor Sie eine " "neue Arbeitsebene erstellen." -#: mouse.cpp:1110 +#: mouse.cpp:1109 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1592,11 +1596,11 @@ msgstr "" "Text kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " "Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." -#: mouse.cpp:1127 +#: mouse.cpp:1126 msgid "click to place bottom right of text" msgstr "Klicken Sie auf die untere rechte Ecke des Texts" -#: mouse.cpp:1133 +#: mouse.cpp:1132 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1604,7 +1608,7 @@ msgstr "" "Das Bild kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine " "Arbeitsebene mit \"Skizze -> In Arbeitsebene\"." -#: mouse.cpp:1160 +#: mouse.cpp:1159 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEUER KOMMENTAR -- DOPPELKLICKEN ZUM BEARBEITEN" @@ -1693,33 +1697,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "Werte durch Komma getrennt (CSV)" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639 msgid "untitled" msgstr "unbenannt" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1573 +#: platform/guigtk.cpp:1335 platform/guigtk.cpp:1368 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1582 msgctxt "title" msgid "Save File" msgstr "Datei speichern" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1575 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1369 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1584 msgctxt "title" msgid "Open File" msgstr "Datei öffnen" -#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375 msgctxt "button" msgid "_Cancel" msgstr "_Abbrechen" -#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373 msgctxt "button" msgid "_Save" msgstr "_Speichern" -#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374 msgctxt "button" msgid "_Open" msgstr "_Öffnen" diff --git a/res/locales/en_US.po b/res/locales/en_US.po index e7acd7e1..27f02444 100644 --- a/res/locales/en_US.po +++ b/res/locales/en_US.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"POT-Creation-Date: 2021-02-01 15:45+0200\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: Automatically generated\n" "Language-Team: none\n" @@ -599,7 +599,11 @@ msgctxt "group-name" msgid "#references" msgstr "#references" -#: file.cpp:549 +#: file.cpp:552 +msgid "The file is empty. It may be corrupt." +msgstr "The file is empty. It may be corrupt." + +#: file.cpp:557 msgid "" "Unrecognized data in file. This file may be corrupt, or from a newer version " "of the program." @@ -607,18 +611,18 @@ msgstr "" "Unrecognized data in file. This file may be corrupt, or from a newer version " "of the program." -#: file.cpp:859 +#: file.cpp:867 msgctxt "title" msgid "Missing File" msgstr "Missing File" -#: file.cpp:860 +#: file.cpp:868 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "The linked file “%s” is not present." -#: file.cpp:862 +#: file.cpp:870 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -631,17 +635,17 @@ msgstr "" "If you decline, any geometry that depends on the missing file will be " "permanently removed." -#: file.cpp:865 +#: file.cpp:873 msgctxt "button" msgid "&Yes" msgstr "&Yes" -#: file.cpp:867 +#: file.cpp:875 msgctxt "button" msgid "&No" msgstr "&No" -#: file.cpp:869 solvespace.cpp:569 +#: file.cpp:877 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "&Cancel" @@ -1410,103 +1414,103 @@ msgstr "" msgid "Can't split; no intersection found." msgstr "Can't split; no intersection found." -#: mouse.cpp:560 +#: mouse.cpp:559 msgid "Assign to Style" msgstr "Assign to Style" -#: mouse.cpp:576 +#: mouse.cpp:575 msgid "No Style" msgstr "No Style" -#: mouse.cpp:579 +#: mouse.cpp:578 msgid "Newly Created Custom Style..." msgstr "Newly Created Custom Style..." -#: mouse.cpp:586 +#: mouse.cpp:585 msgid "Group Info" msgstr "Group Info" -#: mouse.cpp:606 +#: mouse.cpp:605 msgid "Style Info" msgstr "Style Info" -#: mouse.cpp:626 +#: mouse.cpp:625 msgid "Select Edge Chain" msgstr "Select Edge Chain" -#: mouse.cpp:632 +#: mouse.cpp:631 msgid "Toggle Reference Dimension" msgstr "Toggle Reference Dimension" -#: mouse.cpp:638 +#: mouse.cpp:637 msgid "Other Supplementary Angle" msgstr "Other Supplementary Angle" -#: mouse.cpp:643 +#: mouse.cpp:642 msgid "Snap to Grid" msgstr "Snap to Grid" -#: mouse.cpp:652 +#: mouse.cpp:651 msgid "Remove Spline Point" msgstr "Remove Spline Point" -#: mouse.cpp:687 +#: mouse.cpp:686 msgid "Add Spline Point" msgstr "Add Spline Point" -#: mouse.cpp:691 +#: mouse.cpp:690 msgid "Cannot add spline point: maximum number of points reached." msgstr "Cannot add spline point: maximum number of points reached." -#: mouse.cpp:716 +#: mouse.cpp:715 msgid "Toggle Construction" msgstr "Toggle Construction" -#: mouse.cpp:731 +#: mouse.cpp:730 msgid "Delete Point-Coincident Constraint" msgstr "Delete Point-Coincident Constraint" -#: mouse.cpp:750 +#: mouse.cpp:749 msgid "Cut" msgstr "Cut" -#: mouse.cpp:752 +#: mouse.cpp:751 msgid "Copy" msgstr "Copy" -#: mouse.cpp:756 +#: mouse.cpp:755 msgid "Select All" msgstr "Select All" -#: mouse.cpp:761 +#: mouse.cpp:760 msgid "Paste" msgstr "Paste" -#: mouse.cpp:763 +#: mouse.cpp:762 msgid "Paste Transformed..." msgstr "Paste Transformed..." -#: mouse.cpp:768 +#: mouse.cpp:767 msgid "Delete" msgstr "Delete" -#: mouse.cpp:771 +#: mouse.cpp:770 msgid "Unselect All" msgstr "Unselect All" -#: mouse.cpp:778 +#: mouse.cpp:777 msgid "Unselect Hovered" msgstr "Unselect Hovered" -#: mouse.cpp:787 +#: mouse.cpp:786 msgid "Zoom to Fit" msgstr "Zoom to Fit" -#: mouse.cpp:989 mouse.cpp:1276 +#: mouse.cpp:988 mouse.cpp:1275 msgid "click next point of line, or press Esc" msgstr "click next point of line, or press Esc" -#: mouse.cpp:995 +#: mouse.cpp:994 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1514,15 +1518,15 @@ msgstr "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." -#: mouse.cpp:1029 +#: mouse.cpp:1028 msgid "click to place other corner of rectangle" msgstr "click to place other corner of rectangle" -#: mouse.cpp:1049 +#: mouse.cpp:1048 msgid "click to set radius" msgstr "click to set radius" -#: mouse.cpp:1054 +#: mouse.cpp:1053 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1530,21 +1534,21 @@ msgstr "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." -#: mouse.cpp:1073 +#: mouse.cpp:1072 msgid "click to place point" msgstr "click to place point" -#: mouse.cpp:1089 +#: mouse.cpp:1088 msgid "click next point of cubic, or press Esc" msgstr "click next point of cubic, or press Esc" -#: mouse.cpp:1094 +#: mouse.cpp:1093 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" "Sketching in a workplane already; sketch in 3d before creating new workplane." -#: mouse.cpp:1110 +#: mouse.cpp:1109 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1552,11 +1556,11 @@ msgstr "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." -#: mouse.cpp:1127 +#: mouse.cpp:1126 msgid "click to place bottom right of text" msgstr "click to place bottom right of text" -#: mouse.cpp:1133 +#: mouse.cpp:1132 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1564,7 +1568,7 @@ msgstr "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." -#: mouse.cpp:1160 +#: mouse.cpp:1159 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NEW COMMENT -- DOUBLE-CLICK TO EDIT" @@ -1653,33 +1657,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "Comma-separated values" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639 msgid "untitled" msgstr "untitled" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1573 +#: platform/guigtk.cpp:1335 platform/guigtk.cpp:1368 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1582 msgctxt "title" msgid "Save File" msgstr "Save File" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1575 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1369 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1584 msgctxt "title" msgid "Open File" msgstr "Open File" -#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375 msgctxt "button" msgid "_Cancel" msgstr "_Cancel" -#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373 msgctxt "button" msgid "_Save" msgstr "_Save" -#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374 msgctxt "button" msgid "_Open" msgstr "_Open" diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po index 784b9610..50c30201 100644 --- a/res/locales/fr_FR.po +++ b/res/locales/fr_FR.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"POT-Creation-Date: 2021-02-01 15:45+0200\n" "PO-Revision-Date: 2018-07-14 06:12+0000\n" "Last-Translator: whitequark \n" "Language-Team: none\n" @@ -616,7 +616,11 @@ msgctxt "group-name" msgid "#references" msgstr "#références" -#: file.cpp:549 +#: file.cpp:552 +msgid "The file is empty. It may be corrupt." +msgstr "" + +#: file.cpp:557 msgid "" "Unrecognized data in file. This file may be corrupt, or from a newer version " "of the program." @@ -624,18 +628,18 @@ msgstr "" "Données non reconnues dans le fichier. Ce fichier peut être corrompu ou " "depuis une version plus récente du programme." -#: file.cpp:859 +#: file.cpp:867 msgctxt "title" msgid "Missing File" msgstr "Fichier manquant" -#: file.cpp:860 +#: file.cpp:868 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "" -#: file.cpp:862 +#: file.cpp:870 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -644,17 +648,17 @@ msgid "" "permanently removed." msgstr "" -#: file.cpp:865 +#: file.cpp:873 msgctxt "button" msgid "&Yes" msgstr "" -#: file.cpp:867 +#: file.cpp:875 msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:569 +#: file.cpp:877 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1422,104 +1426,104 @@ msgstr "" msgid "Can't split; no intersection found." msgstr "Impossible de diviser; pas d'intersection trouvée." -#: mouse.cpp:560 +#: mouse.cpp:559 msgid "Assign to Style" msgstr "Appliquer au style" -#: mouse.cpp:576 +#: mouse.cpp:575 msgid "No Style" msgstr "Pas de style" -#: mouse.cpp:579 +#: mouse.cpp:578 msgid "Newly Created Custom Style..." msgstr "Style personnalisé nouvellement créé ..." -#: mouse.cpp:586 +#: mouse.cpp:585 msgid "Group Info" msgstr "Info Groupe" -#: mouse.cpp:606 +#: mouse.cpp:605 msgid "Style Info" msgstr "Info Style" -#: mouse.cpp:626 +#: mouse.cpp:625 msgid "Select Edge Chain" msgstr "Sélection Chaîne d'arêtes" -#: mouse.cpp:632 +#: mouse.cpp:631 msgid "Toggle Reference Dimension" msgstr "Basculer cote maîtresse / cote indicative" -#: mouse.cpp:638 +#: mouse.cpp:637 msgid "Other Supplementary Angle" msgstr "Autre angle supplémentaire" -#: mouse.cpp:643 +#: mouse.cpp:642 msgid "Snap to Grid" msgstr "Accrocher à la grille" -#: mouse.cpp:652 +#: mouse.cpp:651 msgid "Remove Spline Point" msgstr "Effacer le point de la Spline" -#: mouse.cpp:687 +#: mouse.cpp:686 msgid "Add Spline Point" msgstr "Ajouter un point à la Spline" -#: mouse.cpp:691 +#: mouse.cpp:690 msgid "Cannot add spline point: maximum number of points reached." msgstr "" "Impossible d'ajouter le point spline: nombre maximum de points atteints." -#: mouse.cpp:716 +#: mouse.cpp:715 msgid "Toggle Construction" msgstr "Basculer en mode \"construction\"." -#: mouse.cpp:731 +#: mouse.cpp:730 msgid "Delete Point-Coincident Constraint" msgstr "Effacer la contraint Point-Coïncident" -#: mouse.cpp:750 +#: mouse.cpp:749 msgid "Cut" msgstr "Couper" -#: mouse.cpp:752 +#: mouse.cpp:751 msgid "Copy" msgstr "Copier" -#: mouse.cpp:756 +#: mouse.cpp:755 msgid "Select All" msgstr "Sélectionner tout" -#: mouse.cpp:761 +#: mouse.cpp:760 msgid "Paste" msgstr "Coller" -#: mouse.cpp:763 +#: mouse.cpp:762 msgid "Paste Transformed..." msgstr "Coller transformé..." -#: mouse.cpp:768 +#: mouse.cpp:767 msgid "Delete" msgstr "Effacer" -#: mouse.cpp:771 +#: mouse.cpp:770 msgid "Unselect All" msgstr "Désélectionner tout" -#: mouse.cpp:778 +#: mouse.cpp:777 msgid "Unselect Hovered" msgstr "Désélectionner survolé" -#: mouse.cpp:787 +#: mouse.cpp:786 msgid "Zoom to Fit" msgstr "Zoom pour ajuster" -#: mouse.cpp:989 mouse.cpp:1276 +#: mouse.cpp:988 mouse.cpp:1275 msgid "click next point of line, or press Esc" msgstr "cliquez pou le prochain point de ligne or appuyez sur Esc" -#: mouse.cpp:995 +#: mouse.cpp:994 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1527,15 +1531,15 @@ msgstr "" "Impossible de dessiner un rectangle en 3d; D'abord, activez un plan de " "travail avec \"Dessin -> Dans plan de travail\"." -#: mouse.cpp:1029 +#: mouse.cpp:1028 msgid "click to place other corner of rectangle" msgstr "cliquez pour placer un autre coin de rectangle" -#: mouse.cpp:1049 +#: mouse.cpp:1048 msgid "click to set radius" msgstr "cliquez pour ajuster le rayon" -#: mouse.cpp:1054 +#: mouse.cpp:1053 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1543,22 +1547,22 @@ msgstr "" "Ne peut pas dessiner l'arc en 3d; D'abord, activez un plan de travail avec " "\"Dessin -> Dans plan de travail\"." -#: mouse.cpp:1073 +#: mouse.cpp:1072 msgid "click to place point" msgstr "cliquez pour placer un point" -#: mouse.cpp:1089 +#: mouse.cpp:1088 msgid "click next point of cubic, or press Esc" msgstr "cliquez le prochain point cubique ou appuyez sur Esc" -#: mouse.cpp:1094 +#: mouse.cpp:1093 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" "Vous dessinez déjà dans un plan de travail; Sélectionner \"Dessiner en 3d\" " "avant de créer un nouveau plan de travail." -#: mouse.cpp:1110 +#: mouse.cpp:1109 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1566,11 +1570,11 @@ msgstr "" "Impossible de dessiner du texte en 3d; D'abord, activer un plan de travail " "avec \"Dessin -> Dans plan de travail\"." -#: mouse.cpp:1127 +#: mouse.cpp:1126 msgid "click to place bottom right of text" msgstr "" -#: mouse.cpp:1133 +#: mouse.cpp:1132 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." @@ -1578,7 +1582,7 @@ msgstr "" "Impossible de dessiner l'image en 3d; D'abord, activez un plan de travail " "avec \"Dessin -> Dans plan de travail\"." -#: mouse.cpp:1160 +#: mouse.cpp:1159 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "NOUVEAU COMMENTAIRE - DOUBLE-CLIQUE POUR EDITER" @@ -1667,33 +1671,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639 msgid "untitled" msgstr "sans nom" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1573 +#: platform/guigtk.cpp:1335 platform/guigtk.cpp:1368 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1582 msgctxt "title" msgid "Save File" msgstr "Sauver fichier" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1575 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1369 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1584 msgctxt "title" msgid "Open File" msgstr "Ouvrir Fichier" -#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375 msgctxt "button" msgid "_Cancel" msgstr "_Annuler" -#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373 msgctxt "button" msgid "_Save" msgstr "_Sauver" -#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374 msgctxt "button" msgid "_Open" msgstr "" diff --git a/res/locales/ru_RU.po b/res/locales/ru_RU.po index d4377246..42a3fa3a 100644 --- a/res/locales/ru_RU.po +++ b/res/locales/ru_RU.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"POT-Creation-Date: 2021-02-01 15:45+0200\n" "PO-Revision-Date: 2021-01-22 18:50+0700\n" "Last-Translator: evilspirit@evilspirit.org\n" "Language-Team: EvilSpirit\n" @@ -615,7 +615,11 @@ msgctxt "group-name" msgid "#references" msgstr "система-координат" -#: file.cpp:549 +#: file.cpp:552 +msgid "The file is empty. It may be corrupt." +msgstr "Файл пуст. Возможно он поврежден." + +#: file.cpp:557 msgid "" "Unrecognized data in file. This file may be corrupt, or from a newer version " "of the program." @@ -623,18 +627,18 @@ msgstr "" "Некоторые данные из этого файла не распознаны. Возможно, файл поврежден или " "создан в более новой версии программы" -#: file.cpp:859 +#: file.cpp:867 msgctxt "title" msgid "Missing File" msgstr "Файл Отсутствует" -#: file.cpp:860 +#: file.cpp:868 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "Связанный файл “%s” отсутствует." -#: file.cpp:862 +#: file.cpp:870 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -646,17 +650,17 @@ msgstr "" "Если вы ответите \"Нет\", то вся геометрия, которая зависит от " "отсутствующего файла будет удалена." -#: file.cpp:865 +#: file.cpp:873 msgctxt "button" msgid "&Yes" msgstr "Да" -#: file.cpp:867 +#: file.cpp:875 msgctxt "button" msgid "&No" msgstr "Нет" -#: file.cpp:869 solvespace.cpp:569 +#: file.cpp:877 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "Отменить" @@ -1462,159 +1466,159 @@ msgstr "" msgid "Can't split; no intersection found." msgstr "Невозможно разделить пересекаемые примитивы: пересечений нет." -#: mouse.cpp:560 +#: mouse.cpp:559 msgid "Assign to Style" msgstr "Применить Стиль" -#: mouse.cpp:576 +#: mouse.cpp:575 msgid "No Style" msgstr "Стиль по Умолчанию" -#: mouse.cpp:579 +#: mouse.cpp:578 msgid "Newly Created Custom Style..." msgstr "Создать Новый Стиль..." -#: mouse.cpp:586 +#: mouse.cpp:585 msgid "Group Info" msgstr "Настройки Группы" -#: mouse.cpp:606 +#: mouse.cpp:605 msgid "Style Info" msgstr "Настройки Стиля" -#: mouse.cpp:626 +#: mouse.cpp:625 msgid "Select Edge Chain" msgstr "Выделить Последовательность Примитивов" -#: mouse.cpp:632 +#: mouse.cpp:631 msgid "Toggle Reference Dimension" msgstr "Переключить Режим Размера Для Справок" -#: mouse.cpp:638 +#: mouse.cpp:637 msgid "Other Supplementary Angle" msgstr "Переключить Смежный Угол" -#: mouse.cpp:643 +#: mouse.cpp:642 msgid "Snap to Grid" msgstr "Привязать к Сетке" -#: mouse.cpp:652 +#: mouse.cpp:651 msgid "Remove Spline Point" msgstr "Удалить Точку Сплайна" -#: mouse.cpp:687 +#: mouse.cpp:686 msgid "Add Spline Point" msgstr "Добавить Точку Сплайна" -#: mouse.cpp:691 +#: mouse.cpp:690 msgid "Cannot add spline point: maximum number of points reached." msgstr "" "Невозможно добавить точку сплайна: достигнуто ограничение максимального " "количества точек для сплайна." -#: mouse.cpp:716 +#: mouse.cpp:715 msgid "Toggle Construction" msgstr "Переключить Режим 'Дополнительные Построения'." -#: mouse.cpp:731 +#: mouse.cpp:730 msgid "Delete Point-Coincident Constraint" msgstr "Удалить Ограничение Совпадения Точек" -#: mouse.cpp:750 +#: mouse.cpp:749 msgid "Cut" msgstr "Вырезать" -#: mouse.cpp:752 +#: mouse.cpp:751 msgid "Copy" msgstr "Копировать" -#: mouse.cpp:756 +#: mouse.cpp:755 msgid "Select All" msgstr "Выделить Все" -#: mouse.cpp:761 +#: mouse.cpp:760 msgid "Paste" msgstr "Вставить" -#: mouse.cpp:763 +#: mouse.cpp:762 msgid "Paste Transformed..." msgstr "Вставить с Трансформацией..." -#: mouse.cpp:768 +#: mouse.cpp:767 msgid "Delete" msgstr "Удалить" -#: mouse.cpp:771 +#: mouse.cpp:770 msgid "Unselect All" msgstr "Сбросить Выделение" -#: mouse.cpp:778 +#: mouse.cpp:777 msgid "Unselect Hovered" msgstr "Снять Выделение с Выбранного" -#: mouse.cpp:787 +#: mouse.cpp:786 msgid "Zoom to Fit" msgstr "Показать Все" -#: mouse.cpp:989 mouse.cpp:1276 +#: mouse.cpp:988 mouse.cpp:1275 msgid "click next point of line, or press Esc" msgstr "кликните мышью там, где хотите расположить следующую точку" -#: mouse.cpp:995 +#: mouse.cpp:994 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" "Невозможно начертить прямоугольник, когда рабочая плоскость не активна." -#: mouse.cpp:1029 +#: mouse.cpp:1028 msgid "click to place other corner of rectangle" msgstr "кликните мышью там, где хотите расположить другой угол прямоугольника" -#: mouse.cpp:1049 +#: mouse.cpp:1048 msgid "click to set radius" msgstr "кликните, чтобы задать радиус" -#: mouse.cpp:1054 +#: mouse.cpp:1053 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "Невозможно создать дугу, когда нет активной рабочей плоскости." -#: mouse.cpp:1073 +#: mouse.cpp:1072 msgid "click to place point" msgstr "кликните мышью там, где хотите создать точку" -#: mouse.cpp:1089 +#: mouse.cpp:1088 msgid "click next point of cubic, or press Esc" msgstr "" "кликните мышью там, где хотите создать следующую точку сплайна или нажмите " "Esc для завершения операции." -#: mouse.cpp:1094 +#: mouse.cpp:1093 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" "Рабочая плоскость уже активна. Перейдите в режим 3d перед созданием новой " "рабочей плоскости." -#: mouse.cpp:1110 +#: mouse.cpp:1109 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "Невозможно создать текст, когда нет активной рабочей плоскости." -#: mouse.cpp:1127 +#: mouse.cpp:1126 msgid "click to place bottom right of text" msgstr "кликните, чтобы расположить правый нижний угол текста" -#: mouse.cpp:1133 +#: mouse.cpp:1132 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "Невозможно создать изображение. Активируйте рабочую плоскость." -#: mouse.cpp:1160 +#: mouse.cpp:1159 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ" @@ -1703,33 +1707,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "CSV файлы (значения, разделенные запятой)" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639 msgid "untitled" msgstr "без имени" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1573 +#: platform/guigtk.cpp:1335 platform/guigtk.cpp:1368 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1582 msgctxt "title" msgid "Save File" msgstr "Сохранить Файл" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1575 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1369 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1584 msgctxt "title" msgid "Open File" msgstr "Открыть Файл" -#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375 msgctxt "button" msgid "_Cancel" msgstr "Отменить" -#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373 msgctxt "button" msgid "_Save" msgstr "Сохранить" -#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374 msgctxt "button" msgid "_Open" msgstr "_Открыть" diff --git a/res/locales/uk_UA.po b/res/locales/uk_UA.po index 1f2a2101..86ce77b4 100644 --- a/res/locales/uk_UA.po +++ b/res/locales/uk_UA.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"POT-Creation-Date: 2021-02-01 15:45+0200\n" "PO-Revision-Date: 2017-01-05 10:30+0000\n" "Last-Translator: appsoft@ua.fm\n" "Language-Team: OpenOrienteeringUkraine\n" @@ -492,24 +492,28 @@ msgctxt "group-name" msgid "#references" msgstr "" -#: file.cpp:549 +#: file.cpp:552 +msgid "The file is empty. It may be corrupt." +msgstr "" + +#: file.cpp:557 msgid "" "Unrecognized data in file. This file may be corrupt, or from a newer version " "of the program." msgstr "" -#: file.cpp:859 +#: file.cpp:867 msgctxt "title" msgid "Missing File" msgstr "" -#: file.cpp:860 +#: file.cpp:868 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "" -#: file.cpp:862 +#: file.cpp:870 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -518,17 +522,17 @@ msgid "" "permanently removed." msgstr "" -#: file.cpp:865 +#: file.cpp:873 msgctxt "button" msgid "&Yes" msgstr "" -#: file.cpp:867 +#: file.cpp:875 msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:569 +#: file.cpp:877 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1243,152 +1247,152 @@ msgstr "" msgid "Can't split; no intersection found." msgstr "" -#: mouse.cpp:560 +#: mouse.cpp:559 msgid "Assign to Style" msgstr "Встановити Стиль" -#: mouse.cpp:576 +#: mouse.cpp:575 msgid "No Style" msgstr "Без Стилю" -#: mouse.cpp:579 +#: mouse.cpp:578 msgid "Newly Created Custom Style..." msgstr "Створити Користувацький Стиль..." -#: mouse.cpp:586 +#: mouse.cpp:585 msgid "Group Info" msgstr "Параметри Групи" -#: mouse.cpp:606 +#: mouse.cpp:605 msgid "Style Info" msgstr "Параметри Стилю" -#: mouse.cpp:626 +#: mouse.cpp:625 msgid "Select Edge Chain" msgstr "Виділити Ланцюг Ребер" -#: mouse.cpp:632 +#: mouse.cpp:631 msgid "Toggle Reference Dimension" msgstr "Перемкнути Відносність Розміру" -#: mouse.cpp:638 +#: mouse.cpp:637 msgid "Other Supplementary Angle" msgstr "Інший Суміжний Кут" -#: mouse.cpp:643 +#: mouse.cpp:642 msgid "Snap to Grid" msgstr "Прикріпити до Сітки" -#: mouse.cpp:652 +#: mouse.cpp:651 msgid "Remove Spline Point" msgstr "Видалити Точку Сплайну" -#: mouse.cpp:687 +#: mouse.cpp:686 msgid "Add Spline Point" msgstr "Додати Точку Сплайну" -#: mouse.cpp:691 +#: mouse.cpp:690 msgid "Cannot add spline point: maximum number of points reached." msgstr "" -#: mouse.cpp:716 +#: mouse.cpp:715 msgid "Toggle Construction" msgstr "Пермкнути Конструктивність" -#: mouse.cpp:731 +#: mouse.cpp:730 msgid "Delete Point-Coincident Constraint" msgstr "Роз'єднати З'єднання Точок" -#: mouse.cpp:750 +#: mouse.cpp:749 msgid "Cut" msgstr "Вирізати" -#: mouse.cpp:752 +#: mouse.cpp:751 msgid "Copy" msgstr "Копіювати" -#: mouse.cpp:756 +#: mouse.cpp:755 msgid "Select All" msgstr "Виділити Усе" -#: mouse.cpp:761 +#: mouse.cpp:760 msgid "Paste" msgstr "Вставити" -#: mouse.cpp:763 +#: mouse.cpp:762 msgid "Paste Transformed..." msgstr "Вставити Трансформованим..." -#: mouse.cpp:768 +#: mouse.cpp:767 msgid "Delete" msgstr "Видалити" -#: mouse.cpp:771 +#: mouse.cpp:770 msgid "Unselect All" msgstr "Зняти Виділення з Усього" -#: mouse.cpp:778 +#: mouse.cpp:777 msgid "Unselect Hovered" msgstr "Зняти Виділення з Наведеного" -#: mouse.cpp:787 +#: mouse.cpp:786 msgid "Zoom to Fit" msgstr "Умістити на Екрані" -#: mouse.cpp:989 mouse.cpp:1276 +#: mouse.cpp:988 mouse.cpp:1275 msgid "click next point of line, or press Esc" msgstr "" -#: mouse.cpp:995 +#: mouse.cpp:994 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1029 +#: mouse.cpp:1028 msgid "click to place other corner of rectangle" msgstr "" -#: mouse.cpp:1049 +#: mouse.cpp:1048 msgid "click to set radius" msgstr "" -#: mouse.cpp:1054 +#: mouse.cpp:1053 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1073 +#: mouse.cpp:1072 msgid "click to place point" msgstr "" -#: mouse.cpp:1089 +#: mouse.cpp:1088 msgid "click next point of cubic, or press Esc" msgstr "" -#: mouse.cpp:1094 +#: mouse.cpp:1093 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" -#: mouse.cpp:1110 +#: mouse.cpp:1109 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1127 +#: mouse.cpp:1126 msgid "click to place bottom right of text" msgstr "" -#: mouse.cpp:1133 +#: mouse.cpp:1132 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "" -#: mouse.cpp:1160 +#: mouse.cpp:1159 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" @@ -1477,33 +1481,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639 msgid "untitled" msgstr "" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1573 +#: platform/guigtk.cpp:1335 platform/guigtk.cpp:1368 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1582 msgctxt "title" msgid "Save File" msgstr "" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1575 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1369 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1584 msgctxt "title" msgid "Open File" msgstr "" -#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375 msgctxt "button" msgid "_Cancel" msgstr "" -#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373 msgctxt "button" msgid "_Save" msgstr "" -#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374 msgctxt "button" msgid "_Open" msgstr "" diff --git a/res/locales/zh_CN.po b/res/locales/zh_CN.po index 245b452a..1c2ce7f6 100644 --- a/res/locales/zh_CN.po +++ b/res/locales/zh_CN.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"POT-Creation-Date: 2021-02-01 15:45+0200\n" "PO-Revision-Date: 2020-09-28 12:42+0800\n" "Last-Translator: lomatus@163.com\n" "Language-Team: none\n" @@ -570,24 +570,28 @@ msgctxt "group-name" msgid "#references" msgstr "#参考" -#: file.cpp:549 +#: file.cpp:552 +msgid "The file is empty. It may be corrupt." +msgstr "" + +#: file.cpp:557 msgid "" "Unrecognized data in file. This file may be corrupt, or from a newer version " "of the program." msgstr "未识别文件内数据。该文件可能损坏,或使用新版本应用程序尝试打开。" -#: file.cpp:859 +#: file.cpp:867 msgctxt "title" msgid "Missing File" msgstr "文件丢失" -#: file.cpp:860 +#: file.cpp:868 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "连接的文件不存在:\"%s\"。" -#: file.cpp:862 +#: file.cpp:870 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -596,17 +600,17 @@ msgid "" "permanently removed." msgstr "您是否想手工查找?如果是,所有基于该丢失文件的几何对象将会被全部删除." -#: file.cpp:865 +#: file.cpp:873 msgctxt "button" msgid "&Yes" msgstr "是(&Y)" -#: file.cpp:867 +#: file.cpp:875 msgctxt "button" msgid "&No" msgstr "否(&N)" -#: file.cpp:869 solvespace.cpp:569 +#: file.cpp:877 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "取消(&C)" @@ -1330,152 +1334,152 @@ msgstr "" msgid "Can't split; no intersection found." msgstr "无法拆分;未发现较差点。" -#: mouse.cpp:560 +#: mouse.cpp:559 msgid "Assign to Style" msgstr "指定样式" -#: mouse.cpp:576 +#: mouse.cpp:575 msgid "No Style" msgstr "无样式" -#: mouse.cpp:579 +#: mouse.cpp:578 msgid "Newly Created Custom Style..." msgstr "新组样式。" -#: mouse.cpp:586 +#: mouse.cpp:585 msgid "Group Info" msgstr "组信息" -#: mouse.cpp:606 +#: mouse.cpp:605 msgid "Style Info" msgstr "样式信息" -#: mouse.cpp:626 +#: mouse.cpp:625 msgid "Select Edge Chain" msgstr "选择边缘链" -#: mouse.cpp:632 +#: mouse.cpp:631 msgid "Toggle Reference Dimension" msgstr "切换参考标注" -#: mouse.cpp:638 +#: mouse.cpp:637 msgid "Other Supplementary Angle" msgstr "其它补充角度" -#: mouse.cpp:643 +#: mouse.cpp:642 msgid "Snap to Grid" msgstr "捕捉至轴网" -#: mouse.cpp:652 +#: mouse.cpp:651 msgid "Remove Spline Point" msgstr "删除样条线的点" -#: mouse.cpp:687 +#: mouse.cpp:686 msgid "Add Spline Point" msgstr "增加样条线的点" -#: mouse.cpp:691 +#: mouse.cpp:690 msgid "Cannot add spline point: maximum number of points reached." msgstr "无法增加样条线点:超过最大限制。" -#: mouse.cpp:716 +#: mouse.cpp:715 msgid "Toggle Construction" msgstr "切换构造" -#: mouse.cpp:731 +#: mouse.cpp:730 msgid "Delete Point-Coincident Constraint" msgstr "删除点一致约束" -#: mouse.cpp:750 +#: mouse.cpp:749 msgid "Cut" msgstr "剪切" -#: mouse.cpp:752 +#: mouse.cpp:751 msgid "Copy" msgstr "复制" -#: mouse.cpp:756 +#: mouse.cpp:755 msgid "Select All" msgstr "全选" -#: mouse.cpp:761 +#: mouse.cpp:760 msgid "Paste" msgstr "粘贴" -#: mouse.cpp:763 +#: mouse.cpp:762 msgid "Paste Transformed..." msgstr "粘贴移动的..." -#: mouse.cpp:768 +#: mouse.cpp:767 msgid "Delete" msgstr "删除" -#: mouse.cpp:771 +#: mouse.cpp:770 msgid "Unselect All" msgstr "取消全选" -#: mouse.cpp:778 +#: mouse.cpp:777 msgid "Unselect Hovered" msgstr "取消覆盖区域的全选" -#: mouse.cpp:787 +#: mouse.cpp:786 msgid "Zoom to Fit" msgstr "自动缩放" -#: mouse.cpp:989 mouse.cpp:1276 +#: mouse.cpp:988 mouse.cpp:1275 msgid "click next point of line, or press Esc" msgstr "点击下一个点或取消(ESC)" -#: mouse.cpp:995 +#: mouse.cpp:994 msgid "" "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "无法在3D内绘制矩形; 首先,激活工作面,草图->在工作面。" -#: mouse.cpp:1029 +#: mouse.cpp:1028 msgid "click to place other corner of rectangle" msgstr "点击放置其它矩形倒角" -#: mouse.cpp:1049 +#: mouse.cpp:1048 msgid "click to set radius" msgstr "点击设置半径" -#: mouse.cpp:1054 +#: mouse.cpp:1053 msgid "" "Can't draw arc in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "无法在3D空间内绘制弧线,可使用 草图->在工作面 激活工作面。" -#: mouse.cpp:1073 +#: mouse.cpp:1072 msgid "click to place point" msgstr "点击放置点" -#: mouse.cpp:1089 +#: mouse.cpp:1088 msgid "click next point of cubic, or press Esc" msgstr "点击下一个点或取消(ESC)" -#: mouse.cpp:1094 +#: mouse.cpp:1093 msgid "" "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "已经在工作面绘制;在新建工作面前在三维空间绘制。" -#: mouse.cpp:1110 +#: mouse.cpp:1109 msgid "" "Can't draw text in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "无法在三维空间内绘制文字,可使用 草图->在工作面 激活工作面。" -#: mouse.cpp:1127 +#: mouse.cpp:1126 msgid "click to place bottom right of text" msgstr "点击文字的右下角放置" -#: mouse.cpp:1133 +#: mouse.cpp:1132 msgid "" "Can't draw image in 3d; first, activate a workplane with Sketch -> In " "Workplane." msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 激活工作面。" -#: mouse.cpp:1160 +#: mouse.cpp:1159 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "新备注 - 双击编辑" @@ -1564,33 +1568,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "逗号分隔数据" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639 msgid "untitled" msgstr "未命名" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1573 +#: platform/guigtk.cpp:1335 platform/guigtk.cpp:1368 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1582 msgctxt "title" msgid "Save File" msgstr "保存文件" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1575 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1369 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1584 msgctxt "title" msgid "Open File" msgstr "打开文件" -#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375 msgctxt "button" msgid "_Cancel" msgstr "取消_C" -#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373 msgctxt "button" msgid "_Save" msgstr "保存_S" -#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374 msgctxt "button" msgid "_Open" msgstr "打开_O" diff --git a/res/messages.pot b/res/messages.pot index c5ce2b77..534faa40 100644 --- a/res/messages.pot +++ b/res/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: SolveSpace 3.0\n" "Report-Msgid-Bugs-To: whitequark@whitequark.org\n" -"POT-Creation-Date: 2021-01-17 19:54+0200\n" +"POT-Creation-Date: 2021-02-01 15:45+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -473,22 +473,26 @@ msgctxt "group-name" msgid "#references" msgstr "" -#: file.cpp:549 +#: file.cpp:552 +msgid "The file is empty. It may be corrupt." +msgstr "" + +#: file.cpp:557 msgid "Unrecognized data in file. This file may be corrupt, or from a newer version of the program." msgstr "" -#: file.cpp:859 +#: file.cpp:867 msgctxt "title" msgid "Missing File" msgstr "" -#: file.cpp:860 +#: file.cpp:868 #, c-format msgctxt "dialog" msgid "The linked file “%s” is not present." msgstr "" -#: file.cpp:862 +#: file.cpp:870 msgctxt "dialog" msgid "" "Do you want to locate it manually?\n" @@ -496,17 +500,17 @@ msgid "" "If you decline, any geometry that depends on the missing file will be permanently removed." msgstr "" -#: file.cpp:865 +#: file.cpp:873 msgctxt "button" msgid "&Yes" msgstr "" -#: file.cpp:867 +#: file.cpp:875 msgctxt "button" msgid "&No" msgstr "" -#: file.cpp:869 solvespace.cpp:569 +#: file.cpp:877 solvespace.cpp:569 msgctxt "button" msgid "&Cancel" msgstr "" @@ -1214,143 +1218,143 @@ msgstr "" msgid "Can't split; no intersection found." msgstr "" -#: mouse.cpp:560 +#: mouse.cpp:559 msgid "Assign to Style" msgstr "" -#: mouse.cpp:576 +#: mouse.cpp:575 msgid "No Style" msgstr "" -#: mouse.cpp:579 +#: mouse.cpp:578 msgid "Newly Created Custom Style..." msgstr "" -#: mouse.cpp:586 +#: mouse.cpp:585 msgid "Group Info" msgstr "" -#: mouse.cpp:606 +#: mouse.cpp:605 msgid "Style Info" msgstr "" -#: mouse.cpp:626 +#: mouse.cpp:625 msgid "Select Edge Chain" msgstr "" -#: mouse.cpp:632 +#: mouse.cpp:631 msgid "Toggle Reference Dimension" msgstr "" -#: mouse.cpp:638 +#: mouse.cpp:637 msgid "Other Supplementary Angle" msgstr "" -#: mouse.cpp:643 +#: mouse.cpp:642 msgid "Snap to Grid" msgstr "" -#: mouse.cpp:652 +#: mouse.cpp:651 msgid "Remove Spline Point" msgstr "" -#: mouse.cpp:687 +#: mouse.cpp:686 msgid "Add Spline Point" msgstr "" -#: mouse.cpp:691 +#: mouse.cpp:690 msgid "Cannot add spline point: maximum number of points reached." msgstr "" -#: mouse.cpp:716 +#: mouse.cpp:715 msgid "Toggle Construction" msgstr "" -#: mouse.cpp:731 +#: mouse.cpp:730 msgid "Delete Point-Coincident Constraint" msgstr "" -#: mouse.cpp:750 +#: mouse.cpp:749 msgid "Cut" msgstr "" -#: mouse.cpp:752 +#: mouse.cpp:751 msgid "Copy" msgstr "" -#: mouse.cpp:756 +#: mouse.cpp:755 msgid "Select All" msgstr "" -#: mouse.cpp:761 +#: mouse.cpp:760 msgid "Paste" msgstr "" -#: mouse.cpp:763 +#: mouse.cpp:762 msgid "Paste Transformed..." msgstr "" -#: mouse.cpp:768 +#: mouse.cpp:767 msgid "Delete" msgstr "" -#: mouse.cpp:771 +#: mouse.cpp:770 msgid "Unselect All" msgstr "" -#: mouse.cpp:778 +#: mouse.cpp:777 msgid "Unselect Hovered" msgstr "" -#: mouse.cpp:787 +#: mouse.cpp:786 msgid "Zoom to Fit" msgstr "" -#: mouse.cpp:989 mouse.cpp:1276 +#: mouse.cpp:988 mouse.cpp:1275 msgid "click next point of line, or press Esc" msgstr "" -#: mouse.cpp:995 +#: mouse.cpp:994 msgid "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In Workplane." msgstr "" -#: mouse.cpp:1029 +#: mouse.cpp:1028 msgid "click to place other corner of rectangle" msgstr "" -#: mouse.cpp:1049 +#: mouse.cpp:1048 msgid "click to set radius" msgstr "" -#: mouse.cpp:1054 +#: mouse.cpp:1053 msgid "Can't draw arc in 3d; first, activate a workplane with Sketch -> In Workplane." msgstr "" -#: mouse.cpp:1073 +#: mouse.cpp:1072 msgid "click to place point" msgstr "" -#: mouse.cpp:1089 +#: mouse.cpp:1088 msgid "click next point of cubic, or press Esc" msgstr "" -#: mouse.cpp:1094 +#: mouse.cpp:1093 msgid "Sketching in a workplane already; sketch in 3d before creating new workplane." msgstr "" -#: mouse.cpp:1110 +#: mouse.cpp:1109 msgid "Can't draw text in 3d; first, activate a workplane with Sketch -> In Workplane." msgstr "" -#: mouse.cpp:1127 +#: mouse.cpp:1126 msgid "click to place bottom right of text" msgstr "" -#: mouse.cpp:1133 +#: mouse.cpp:1132 msgid "Can't draw image in 3d; first, activate a workplane with Sketch -> In Workplane." msgstr "" -#: mouse.cpp:1160 +#: mouse.cpp:1159 msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT" msgstr "" @@ -1439,33 +1443,33 @@ msgctxt "file-type" msgid "Comma-separated values" msgstr "" -#: platform/guigtk.cpp:1321 platform/guimac.mm:1363 platform/guiwin.cpp:1630 +#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639 msgid "untitled" msgstr "" -#: platform/guigtk.cpp:1332 platform/guigtk.cpp:1365 platform/guimac.mm:1321 -#: platform/guiwin.cpp:1573 +#: platform/guigtk.cpp:1335 platform/guigtk.cpp:1368 platform/guimac.mm:1321 +#: platform/guiwin.cpp:1582 msgctxt "title" msgid "Save File" msgstr "" -#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366 platform/guimac.mm:1304 -#: platform/guiwin.cpp:1575 +#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1369 platform/guimac.mm:1304 +#: platform/guiwin.cpp:1584 msgctxt "title" msgid "Open File" msgstr "" -#: platform/guigtk.cpp:1336 platform/guigtk.cpp:1372 +#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375 msgctxt "button" msgid "_Cancel" msgstr "" -#: platform/guigtk.cpp:1337 platform/guigtk.cpp:1370 +#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373 msgctxt "button" msgid "_Save" msgstr "" -#: platform/guigtk.cpp:1338 platform/guigtk.cpp:1371 +#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374 msgctxt "button" msgid "_Open" msgstr "" From cdeb6c90fb753a2b0f6d033affedbcceab046758 Mon Sep 17 00:00:00 2001 From: Ryan Pavlik Date: Sat, 6 Feb 2021 14:42:27 -0600 Subject: [PATCH 112/113] Update mimalloc to 2.0.0 release. --- extlib/mimalloc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extlib/mimalloc b/extlib/mimalloc index a9686d6e..27627843 160000 --- a/extlib/mimalloc +++ b/extlib/mimalloc @@ -1 +1 @@ -Subproject commit a9686d6ecf00e4467e772f7c0b4ef76a15f325f6 +Subproject commit 27627843648ef84aee1621976f25bee5946e6bda From 7795b0bc1911a01eaa4661e252488d8f07ec2135 Mon Sep 17 00:00:00 2001 From: robnee Date: Sun, 7 Feb 2021 09:20:57 -0500 Subject: [PATCH 113/113] mark group dirty when toggling reference dimension --- src/describescreen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/describescreen.cpp b/src/describescreen.cpp index 17f73612..03fafee1 100644 --- a/src/describescreen.cpp +++ b/src/describescreen.cpp @@ -47,6 +47,7 @@ void TextWindow::ScreenConstraintToggleReference(int link, uint32_t v) { SS.UndoRemember(); c->reference = !c->reference; + SS.MarkGroupDirty(c->group); SS.ScheduleShowTW(); }