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
diff --git a/.github/scripts/build-macos.sh b/.github/scripts/build-macos.sh
new file mode 100755
index 00000000..bb4c1e0c
--- /dev/null
+++ b/.github/scripts/build-macos.sh
@@ -0,0 +1,27 @@
+#!/bin/sh -xe
+
+mkdir build || true
+cd build
+
+OSX_TARGET="10.9"
+
+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" \
+ ..
+else
+ BUILD_TYPE=Debug
+ cmake \
+ -DCMAKE_OSX_DEPLOYMENT_TARGET="${OSX_TARGET}" \
+ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
+ -DENABLE_OPENMP="ON" \
+ -DENABLE_SANITIZERS="ON" \
+ ..
+fi
+
+cmake --build . --config "${BUILD_TYPE}" -- -j$(nproc)
+make -j$(nproc) test_solvespace
diff --git a/.github/scripts/build-snap.sh b/.github/scripts/build-snap.sh
new file mode 100755
index 00000000..665e5614
--- /dev/null
+++ b/.github/scripts/build-snap.sh
@@ -0,0 +1,3 @@
+#!/bin/sh -xe
+
+./pkg/snap/build.sh --use-lxd
diff --git a/.github/scripts/build-ubuntu.sh b/.github/scripts/build-ubuntu.sh
new file mode 100755
index 00000000..4c8f4ea4
--- /dev/null
+++ b/.github/scripts/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/.github/scripts/build-windows.sh b/.github/scripts/build-windows.sh
new file mode 100755
index 00000000..e81fb2ac
--- /dev/null
+++ b/.github/scripts/build-windows.sh
@@ -0,0 +1,36 @@
+#!/bin/sh -xe
+
+mkdir build
+cd build
+
+if [ "$1" = "release" ]; then
+ if [ "$2" = "openmp" ]; then
+ ENABLE_OPENMP="ON"
+ else
+ ENABLE_OPENMP="OFF"
+ fi
+ BUILD_TYPE=RelWithDebInfo
+ cmake \
+ -G "Visual Studio 16 2019" \
+ -DCMAKE_BUILD_TYPE="${BUILD_TYPE}" \
+ -DENABLE_OPENMP="${ENABLE_OPENMP}" \
+ -DENABLE_LTO=ON \
+ -DCMAKE_GENERATOR_PLATFORM="Win32" \
+ ..
+else
+ BUILD_TYPE=Debug
+ cmake \
+ -G "Visual Studio 16 2019" \
+ -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/.github/scripts/install-macos.sh b/.github/scripts/install-macos.sh
new file mode 100755
index 00000000..457dd5d4
--- /dev/null
+++ b/.github/scripts/install-macos.sh
@@ -0,0 +1,4 @@
+#!/bin/sh -xe
+
+brew install libomp
+git submodule update --init
\ No newline at end of file
diff --git a/.github/scripts/install-snap.sh b/.github/scripts/install-snap.sh
new file mode 100755
index 00000000..e10a91da
--- /dev/null
+++ b/.github/scripts/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"
diff --git a/.travis/install-debian.sh b/.github/scripts/install-ubuntu.sh
similarity index 73%
rename from .travis/install-debian.sh
rename to .github/scripts/install-ubuntu.sh
index fb20fffa..53f88b27 100755
--- a/.travis/install-debian.sh
+++ b/.github/scripts/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/.travis/install-macos.sh b/.github/scripts/install-windows.sh
similarity index 51%
rename from .travis/install-macos.sh
rename to .github/scripts/install-windows.sh
index 792126ca..738d67dd 100755
--- a/.travis/install-macos.sh
+++ b/.github/scripts/install-windows.sh
@@ -1,5 +1,3 @@
#!/bin/sh -xe
-brew update
-brew install freetype cairo
git submodule update --init
diff --git a/.github/scripts/sign-macos.sh b/.github/scripts/sign-macos.sh
new file mode 100755
index 00000000..c23dab99
--- /dev/null
+++ b/.github/scripts/sign-macos.sh
@@ -0,0 +1,70 @@
+#!/bin/bash -xe
+
+cd build
+
+openmp="bin/SolveSpace.app/Contents/Resources/lib/libomp.dylib"
+app="bin/SolveSpace.app"
+dmg="bin/SolveSpace.dmg"
+bundle_id="com.solvespace.solvespace"
+
+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
+
+ # 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
+
+ # check if all is good
+ 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}"
+
+# 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}"
+
+# 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 10
+
+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 "${dmg}"
\ No newline at end of file
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..27462aef
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,44 @@
+name: Test
+
+on:
+ pull_request:
+ branches:
+ - master
+ 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/.gitignore b/.gitignore
index 5301e142..4f76b266 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,3 +13,4 @@
/debian/libslvs1-dev/
/obj-*/
/*.slvs
+.vscode/
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.yml b/.travis.yml
deleted file mode 100644
index 1c90474b..00000000
--- a/.travis.yml
+++ /dev/null
@@ -1,57 +0,0 @@
-language: c
-git:
- submodules: false
-jobs:
- allow_failures:
- - stage: deploy
- name: Snap arm64
- include:
- - stage: test
- name: "Debian"
- os: linux
- dist: bionic
- install: ./.travis/install-debian.sh
- script: ./.travis/build-debian.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
- os: linux
- arch: amd64
- dist: bionic
- addons:
- snaps:
- - name: snapcraft
- confinement: classic
- script: ./.travis/build-snap.sh
- deploy:
- - 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
- arch: arm64
diff --git a/.travis/build-debian.sh b/.travis/build-debian.sh
deleted file mode 100755
index bb678daf..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 VERBOSE=1
-make test_solvespace
diff --git a/.travis/build-macos.sh b/.travis/build-macos.sh
deleted file mode 100755
index b87e2fdb..00000000
--- a/.travis/build-macos.sh
+++ /dev/null
@@ -1,9 +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_OSX_DEPLOYMENT_TARGET=10.7 -DCMAKE_BUILD_TYPE=$BUILD_TYPE ..
-make VERBOSE=1
-make test_solvespace
diff --git a/.travis/build-snap.sh b/.travis/build-snap.sh
deleted file mode 100755
index 634e01c4..00000000
--- a/.travis/build-snap.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#!/bin/sh -xe
-
-sudo apt-get update
-sudo ./pkg/snap/build.sh --destructive-mode
diff --git a/.travis/deploy-snap.sh b/.travis/deploy-snap.sh
deleted file mode 100755
index 91674a7c..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 push "$snap" --release "$channels"
-done
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3faa478..8447d0ef 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
@@ -53,7 +55,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.
@@ -110,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/CMakeLists.txt b/CMakeLists.txt
index 40071be4..12948781 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)
@@ -22,6 +27,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
@@ -48,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)")
@@ -69,7 +80,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}=.")
@@ -99,20 +109,19 @@ 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()
if(ENABLE_OPENMP)
- include(FindOpenMP)
- if(OpenMP_FOUND)
+ find_package( OpenMP REQUIRED )
+ 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()
-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()
@@ -144,8 +153,12 @@ 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")
+
+ 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")
set(SANITIZE_FLAGS "${SANITIZE_FLAGS} -fno-omit-frame-pointer -fno-optimize-sibling-calls")
@@ -168,17 +181,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/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 295f25fe..a5bb470e 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,10 @@
+
+
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)
This repository contains the source code of [SolveSpace][], a parametric
2d/3d CAD.
@@ -83,26 +88,29 @@ 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:
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
-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.
- apt-get install git build-essential cmake mingw-w64 libflatbuffers-dev
+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
Before building, check out the project and the necessary submodules:
@@ -110,16 +118,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
@@ -157,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
@@ -185,7 +187,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:
@@ -257,6 +259,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).
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
diff --git a/extlib/flatbuffers b/extlib/flatbuffers
deleted file mode 160000
index f73d205b..00000000
--- a/extlib/flatbuffers
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit f73d205bc7536991e620d3027a711e713a789967
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
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 195a5086..5fe5f7be 100644
--- a/pkg/snap/snap/snapcraft.yaml
+++ b/pkg/snap/snap/snapcraft.yaml
@@ -45,12 +45,14 @@ 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
- -DENABLE_TESTS=OFF
- -DSNAP=ON
+ - -DENABLE_OPENMP=ON
+ - -DENABLE_LTO=ON
build-packages:
- zlib1g-dev
- libpng-dev
diff --git a/res/CMakeLists.txt b/res/CMakeLists.txt
index 3783f242..9152488d 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
@@ -256,6 +258,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
@@ -281,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/icons/graphics-window/helix.png b/res/icons/graphics-window/helix.png
new file mode 100644
index 00000000..4b2cda68
Binary files /dev/null and b/res/icons/graphics-window/helix.png differ
diff --git a/res/icons/graphics-window/revolve.png b/res/icons/graphics-window/revolve.png
new file mode 100644
index 00000000..0cef0fa6
Binary files /dev/null and b/res/icons/graphics-window/revolve.png differ
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/de_DE.po b/res/locales/de_DE.po
index fb4f19b4..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: 2020-09-21 09:28+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"
@@ -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"
@@ -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"
@@ -620,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."
@@ -628,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:849
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "Fehlende Datei"
-#: file.cpp:850
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr "Die verlinkte Datei “%s” fehlt."
-#: file.cpp:852
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
@@ -648,20 +651,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:873
msgctxt "button"
msgid "&Yes"
msgstr "&Ja"
-#: file.cpp:857
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr "&Nein"
-#: file.cpp:859
+#: file.cpp:877 solvespace.cpp:569
msgctxt "button"
msgid "&Cancel"
msgstr "&Abbrechen"
@@ -827,300 +830,304 @@ msgid "Show Snap &Grid"
msgstr "Arbeitsraster anzeigen"
#: graphicswin.cpp:95
+msgid "Darken Inactive Solids"
+msgstr "Dunklere inaktive Festkörper"
+
+#: 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 ""
+msgstr "Datei '%s' existiert nicht."
-#: 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"
@@ -1134,20 +1141,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."
@@ -1155,7 +1162,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."
@@ -1164,7 +1171,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."
@@ -1173,13 +1180,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-"
@@ -1189,7 +1196,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."
@@ -1197,48 +1204,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."
@@ -1260,7 +1267,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"
@@ -1283,7 +1290,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 ""
@@ -1293,7 +1300,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 "
@@ -1307,7 +1314,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 ""
@@ -1317,15 +1324,21 @@ 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"
msgid "revolve"
-msgstr ""
+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 ""
@@ -1335,11 +1348,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 ""
@@ -1350,12 +1369,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"
@@ -1371,19 +1390,19 @@ msgstr "Versetzen"
msgid "(unnamed)"
msgstr "unbenannt"
-#: groupmesh.cpp:689
+#: groupmesh.cpp:709
msgid "not closed contour, or not all same style!"
msgstr "Kontur nicht geschlossen, oder kein einheitlicher Linientyp!"
-#: groupmesh.cpp:702
+#: groupmesh.cpp:722
msgid "points not all coplanar!"
msgstr "Punkte sind nicht alle koplanar!"
-#: groupmesh.cpp:704
+#: groupmesh.cpp:724
msgid "contour is self-intersecting!"
msgstr "Kontur überschneidet sich selbst!"
-#: groupmesh.cpp:706
+#: groupmesh.cpp:726
msgid "zero-length edge!"
msgstr "Kante mit Länge Null!"
@@ -1431,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:990 mouse.cpp:1277
+#: 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:996
+#: mouse.cpp:994
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1537,15 +1556,15 @@ msgstr ""
"Ein Rechteck kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine "
"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"."
-#: mouse.cpp:1030
+#: mouse.cpp:1028
msgid "click to place other corner of rectangle"
msgstr "Klicken Sie auf die gegenüberliegende Ecke des Rechtecks"
-#: mouse.cpp:1050
+#: mouse.cpp:1048
msgid "click to set radius"
msgstr "Klicken Sie, um den Radius festzulegen"
-#: mouse.cpp:1055
+#: mouse.cpp:1053
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1553,23 +1572,23 @@ msgstr ""
"Ein Kreisbogen kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine "
"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"."
-#: mouse.cpp:1074
+#: mouse.cpp:1072
msgid "click to place point"
msgstr "Klicken Sie, um einen Punkt zu platzieren"
-#: mouse.cpp:1090
+#: 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:1095
+#: 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:1111
+#: mouse.cpp:1109
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1577,11 +1596,11 @@ msgstr ""
"Text kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine "
"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"."
-#: mouse.cpp:1128
+#: mouse.cpp:1126
msgid "click to place bottom right of text"
msgstr "Klicken Sie auf die untere rechte Ecke des Texts"
-#: mouse.cpp:1134
+#: mouse.cpp:1132
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1589,136 +1608,423 @@ msgstr ""
"Das Bild kann nicht in 3D erstellt werden. Aktivieren Sie zuerst eine "
"Arbeitsebene mit \"Skizze -> In Arbeitsebene\"."
-#: mouse.cpp:1161
+#: mouse.cpp:1159
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 solvespace.cpp:511
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 "IDF Leiterplatte"
+
+#: 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
-msgctxt "file-type"
-msgid "Q3D Object file"
-msgstr "Q3D Objektdatei"
-
-#: platform/gui.cpp:98
+#: platform/gui.cpp:102
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:106 platform/gui.cpp:113 platform/gui.cpp:120
msgctxt "file-type"
msgid "STEP file"
msgstr "STEP-Datei"
-#: platform/gui.cpp:106
+#: platform/gui.cpp:110
msgctxt "file-type"
msgid "PDF file"
msgstr "PDF-Datei"
-#: platform/gui.cpp:107
+#: platform/gui.cpp:111
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr "Eingebettetes Postscript"
-#: platform/gui.cpp:108
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr "Skalierbare Vektorgrafik"
-#: platform/gui.cpp:110 platform/gui.cpp:117
+#: platform/gui.cpp:114 platform/gui.cpp:121
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr "DXF-Datei (AutoCAD 2007)"
-#: platform/gui.cpp:111
+#: platform/gui.cpp:115
msgctxt "file-type"
msgid "HPGL file"
msgstr "HPGL-Datei"
-#: platform/gui.cpp:112
+#: platform/gui.cpp:116
msgctxt "file-type"
msgid "G Code"
msgstr "G-Code"
-#: platform/gui.cpp:121
+#: platform/gui.cpp:125
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr "AutoCAD DXF- und DWG-Dateien"
-#: platform/gui.cpp:125
+#: platform/gui.cpp:129
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:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639
msgid "untitled"
msgstr "unbenannt"
-#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305
-#: platform/guiwin.cpp:1555
+#: 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:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288
-#: platform/guiwin.cpp:1557
+#: 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:1332 platform/guigtk.cpp:1368
+#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375
msgctxt "button"
msgid "_Cancel"
msgstr "_Abbrechen"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366
+#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373
msgctxt "button"
msgid "_Save"
msgstr "_Speichern"
-#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367
+#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374
msgctxt "button"
msgid "_Open"
-msgstr ""
+msgstr "_Öffnen"
+
+#: solvespace.cpp:169
+msgctxt "title"
+msgid "Autosave Available"
+msgstr "Automatische Sicherungsdatei verfügbar"
+
+#: solvespace.cpp:170
+msgctxt "dialog"
+msgid "An autosave file is available for this sketch."
+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 "Wollen Sie die automatische Sicherungsdatei stattdessen laden?"
+
+#: solvespace.cpp:172
+msgctxt "button"
+msgid "&Load autosave"
+msgstr "AutoDatei &öffnen"
+
+#: solvespace.cpp:174
+msgctxt "button"
+msgid "Do&n't Load"
+msgstr "&Nicht laden"
+
+#: solvespace.cpp:557
+msgctxt "title"
+msgid "Modified File"
+msgstr "Geänderte Datei"
+
+#: 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: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: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:566
+msgctxt "button"
+msgid "&Save"
+msgstr "&Sichern"
+
+#: solvespace.cpp:568
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr "&Verwerfen"
# solvespace.cpp:557
+#: solvespace.cpp:589
msgctxt "title"
msgid "(new sketch)"
msgstr "(Neue Skizze)"
-#: solvespace.cpp:564
+#: solvespace.cpp:596
msgctxt "title"
msgid "Property Browser"
msgstr "Attribut-Browser"
+#: 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 ""
+"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:730
+#, 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: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: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:806
+msgid "The assembly does not interfere, good."
+msgstr "Der Zusammenbau funktioniert, gut."
+
+#: solvespace.cpp:822
+#, c-format
+msgid ""
+"The volume of the solid model is:\n"
+"\n"
+" %s"
+msgstr ""
+"Das Volumen des Modell ist:\n"
+"\n"
+" %s"
+
+#: solvespace.cpp:831
+#, c-format
+msgid ""
+"\n"
+"The volume of current group mesh is:\n"
+"\n"
+" %s"
+msgstr ""
+"\n"
+"Das Volumen des Netz der aktiven Gruppe ist:\n"
+"\n"
+" %s"
+
+#: solvespace.cpp:836
+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:851
+#, 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 ""
+"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:860
+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:872
+#, 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 ""
+"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:892
+#, 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 ""
+"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: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:914
+msgid "Bad selection for trace; select a single point."
+msgstr "Falsche Auswahl für Punkt nachzeichnen. Wähle einen einzelnen Punkt."
+
+#: solvespace.cpp:941
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr "Konnte '%s' nicht schreiben"
+
+#: solvespace.cpp:971
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr "Das Netz schneidet sich selbst: Falsch, ungültig."
+
+#: solvespace.cpp:972
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr "Das Netz schneidet sich nicht: Gut, gültig."
+
+#: solvespace.cpp:974
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr "Das Netz hat lose Kanten: Falsch, ungültig."
+
+#: solvespace.cpp:975
+msgid "The mesh is watertight (okay, valid)."
+msgstr "Das Netz hat keine lose Kanten: Gut, gültig."
+
+#: solvespace.cpp:978
+#, 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:982
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Zero problematic edges, good.%s"
+msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Keine problematischen Kanten, gut.%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 problematische Kanten, schlecht.%s"
+
+#: solvespace.cpp:998
+#, 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 ""
+"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 ""
"Can't assign style to an entity that's derived from another entity; try "
@@ -1853,31 +2159,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 "Neue Gruppe Helix von aktiver Skizze"
+
+#: toolbar.cpp:74
+msgid "New group revolve active sketch"
+msgstr "Neue Gruppe mit gedrehter aktiver Skizze"
+
+#: 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"
@@ -1904,6 +2218,10 @@ 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"
+#~ 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."
@@ -1980,10 +2298,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"
@@ -1997,10 +2311,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"
@@ -2016,4 +2326,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..27f02444 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-09-21 09:28+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"
@@ -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"
@@ -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:849
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "Missing File"
-#: file.cpp:850
+#: 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:852
+#: 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:855
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr "&Yes"
-#: file.cpp:857
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr "&No"
-#: file.cpp:859
+#: file.cpp:877 solvespace.cpp:569
msgctxt "button"
msgid "&Cancel"
msgstr "&Cancel"
@@ -807,299 +811,303 @@ msgid "Show Snap &Grid"
msgstr "Show Snap &Grid"
#: graphicswin.cpp:95
+msgid "Darken Inactive Solids"
+msgstr "Darken Inactive Solids"
+
+#: 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 +1121,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 +1139,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 +1147,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 +1155,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 +1169,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 +1177,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 +1358,19 @@ msgstr "translate"
msgid "(unnamed)"
msgstr "(unnamed)"
-#: groupmesh.cpp:689
+#: groupmesh.cpp:709
msgid "not closed contour, or not all same style!"
msgstr "not closed contour, or not all same style!"
-#: groupmesh.cpp:702
+#: groupmesh.cpp:722
msgid "points not all coplanar!"
msgstr "points not all coplanar!"
-#: groupmesh.cpp:704
+#: groupmesh.cpp:724
msgid "contour is self-intersecting!"
msgstr "contour is self-intersecting!"
-#: groupmesh.cpp:706
+#: groupmesh.cpp:726
msgid "zero-length edge!"
msgstr "zero-length edge!"
@@ -1406,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:990 mouse.cpp:1277
+#: 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:996
+#: mouse.cpp:994
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1510,15 +1518,15 @@ msgstr ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-#: mouse.cpp:1030
+#: mouse.cpp:1028
msgid "click to place other corner of rectangle"
msgstr "click to place other corner of rectangle"
-#: mouse.cpp:1050
+#: mouse.cpp:1048
msgid "click to set radius"
msgstr "click to set radius"
-#: mouse.cpp:1055
+#: mouse.cpp:1053
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1526,21 +1534,21 @@ msgstr ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-#: mouse.cpp:1074
+#: mouse.cpp:1072
msgid "click to place point"
msgstr "click to place point"
-#: mouse.cpp:1090
+#: mouse.cpp:1088
msgid "click next point of cubic, or press Esc"
msgstr "click next point of cubic, or press Esc"
-#: mouse.cpp:1095
+#: 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:1111
+#: mouse.cpp:1109
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1548,11 +1556,11 @@ msgstr ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-#: mouse.cpp:1128
+#: mouse.cpp:1126
msgid "click to place bottom right of text"
msgstr "click to place bottom right of text"
-#: mouse.cpp:1134
+#: mouse.cpp:1132
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1560,136 +1568,417 @@ msgstr ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-#: mouse.cpp:1161
+#: mouse.cpp:1159
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 solvespace.cpp:511
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
-msgctxt "file-type"
-msgid "Q3D Object file"
-msgstr "Q3D Object file"
-
-#: platform/gui.cpp:98
+#: platform/gui.cpp:102
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:106 platform/gui.cpp:113 platform/gui.cpp:120
msgctxt "file-type"
msgid "STEP file"
msgstr "STEP file"
-#: platform/gui.cpp:106
+#: platform/gui.cpp:110
msgctxt "file-type"
msgid "PDF file"
msgstr "PDF file"
-#: platform/gui.cpp:107
+#: platform/gui.cpp:111
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr "Encapsulated PostScript"
-#: platform/gui.cpp:108
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr "Scalable Vector Graphics"
-#: platform/gui.cpp:110 platform/gui.cpp:117
+#: platform/gui.cpp:114 platform/gui.cpp:121
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr "DXF file (AutoCAD 2007)"
-#: platform/gui.cpp:111
+#: platform/gui.cpp:115
msgctxt "file-type"
msgid "HPGL file"
msgstr "HPGL file"
-#: platform/gui.cpp:112
+#: platform/gui.cpp:116
msgctxt "file-type"
msgid "G Code"
msgstr "G Code"
-#: platform/gui.cpp:121
+#: platform/gui.cpp:125
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr "AutoCAD DXF and DWG files"
-#: platform/gui.cpp:125
+#: platform/gui.cpp:129
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:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639
msgid "untitled"
msgstr "untitled"
-#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305
-#: platform/guiwin.cpp:1555
+#: 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:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288
-#: platform/guiwin.cpp:1557
+#: 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:1332 platform/guigtk.cpp:1368
+#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375
msgctxt "button"
msgid "_Cancel"
msgstr "_Cancel"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366
+#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373
msgctxt "button"
msgid "_Save"
msgstr "_Save"
-#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367
+#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374
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:557
msgctxt "title"
+msgid "Modified File"
+msgstr "Modified File"
+
+#: 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: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: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:566
+msgctxt "button"
+msgid "&Save"
+msgstr "&Save"
+
+#: solvespace.cpp:568
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr "Do&n't Save"
+
+#: solvespace.cpp:589
+msgctxt "title"
msgid "(new sketch)"
msgstr "(new sketch)"
-#: solvespace.cpp:564
+#: solvespace.cpp:596
msgctxt "title"
msgid "Property Browser"
msgstr "Property Browser"
+#: 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 ""
+"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:730
+#, 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: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:782
+msgid "Bad selection for step dimension; select a constraint."
+msgstr "Bad selection for step dimension; select a constraint."
+
+#: solvespace.cpp:806
+msgid "The assembly does not interfere, good."
+msgstr "The assembly does not interfere, good."
+
+#: solvespace.cpp:822
+#, 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:831
+#, 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:836
+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:851
+#, 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: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"
+"\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:892
+#, 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: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:914
+msgid "Bad selection for trace; select a single point."
+msgstr "Bad selection for trace; select a single point."
+
+#: solvespace.cpp:941
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr "Couldn't write to '%s'"
+
+#: solvespace.cpp:971
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr "The mesh is self-intersecting (NOT okay, invalid)."
+
+#: solvespace.cpp:972
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr "The mesh is not self-intersecting (okay, valid)."
+
+#: solvespace.cpp:974
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr "The mesh has naked edges (NOT okay, invalid)."
+
+#: solvespace.cpp:975
+msgid "The mesh is watertight (okay, valid)."
+msgstr "The mesh is watertight (okay, valid)."
+
+#: solvespace.cpp:978
+#, 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: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"
+"\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 "
@@ -1823,30 +2112,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"
@@ -1873,193 +2170,6 @@ 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 "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!"
+#~ msgid "Q3D Object file"
+#~ msgstr "Q3D Object file"
diff --git a/res/locales/fr_FR.po b/res/locales/fr_FR.po
index 6b643f26..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: 2020-09-21 09:28+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"
@@ -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"
@@ -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:849
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "Fichier manquant"
-#: file.cpp:850
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr ""
-#: file.cpp:852
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
@@ -644,17 +648,17 @@ msgid ""
"permanently removed."
msgstr ""
-#: file.cpp:855
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr ""
-#: file.cpp:857
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr ""
-#: file.cpp:859
+#: file.cpp:877 solvespace.cpp:569
msgctxt "button"
msgid "&Cancel"
msgstr ""
@@ -820,299 +824,303 @@ msgid "Show Snap &Grid"
msgstr "Afficher la &grille d'accrochage"
#: graphicswin.cpp:95
+msgid "Darken Inactive Solids"
+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 +1134,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 +1154,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 +1162,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 +1171,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 +1187,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 +1195,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 +1371,19 @@ msgstr "translation"
msgid "(unnamed)"
msgstr "(sans nom)"
-#: groupmesh.cpp:689
+#: 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:702
+#: groupmesh.cpp:722
msgid "points not all coplanar!"
msgstr "les points ne sont pas tous coplanaires!"
-#: groupmesh.cpp:704
+#: groupmesh.cpp:724
msgid "contour is self-intersecting!"
msgstr "le contour s'entrecroise!"
-#: groupmesh.cpp:706
+#: groupmesh.cpp:726
msgid "zero-length edge!"
msgstr "arête de longueur nulle!"
@@ -1418,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:990 mouse.cpp:1277
+#: 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:996
+#: mouse.cpp:994
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1523,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:1030
+#: mouse.cpp:1028
msgid "click to place other corner of rectangle"
msgstr "cliquez pour placer un autre coin de rectangle"
-#: mouse.cpp:1050
+#: mouse.cpp:1048
msgid "click to set radius"
msgstr "cliquez pour ajuster le rayon"
-#: mouse.cpp:1055
+#: mouse.cpp:1053
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1539,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:1074
+#: mouse.cpp:1072
msgid "click to place point"
msgstr "cliquez pour placer un point"
-#: mouse.cpp:1090
+#: mouse.cpp:1088
msgid "click next point of cubic, or press Esc"
msgstr "cliquez le prochain point cubique ou appuyez sur Esc"
-#: mouse.cpp:1095
+#: 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:1111
+#: mouse.cpp:1109
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1562,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:1128
+#: mouse.cpp:1126
msgid "click to place bottom right of text"
msgstr ""
-#: mouse.cpp:1134
+#: mouse.cpp:1132
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
@@ -1574,136 +1582,356 @@ 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:1159
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 solvespace.cpp:511
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 "VRML text file"
msgstr ""
-#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116
+#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
msgctxt "file-type"
msgid "STEP file"
msgstr ""
-#: platform/gui.cpp:106
+#: platform/gui.cpp:110
msgctxt "file-type"
msgid "PDF file"
msgstr ""
-#: platform/gui.cpp:107
+#: platform/gui.cpp:111
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr ""
-#: platform/gui.cpp:108
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr ""
-#: platform/gui.cpp:110 platform/gui.cpp:117
+#: platform/gui.cpp:114 platform/gui.cpp:121
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr ""
-#: platform/gui.cpp:111
+#: platform/gui.cpp:115
msgctxt "file-type"
msgid "HPGL file"
msgstr ""
-#: platform/gui.cpp:112
+#: platform/gui.cpp:116
msgctxt "file-type"
msgid "G Code"
msgstr ""
-#: platform/gui.cpp:121
+#: platform/gui.cpp:125
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr ""
-#: platform/gui.cpp:125
+#: platform/gui.cpp:129
msgctxt "file-type"
msgid "Comma-separated values"
msgstr ""
-#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608
+#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639
msgid "untitled"
msgstr "sans nom"
-#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305
-#: platform/guiwin.cpp:1555
+#: 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:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288
-#: platform/guiwin.cpp:1557
+#: 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:1332 platform/guigtk.cpp:1368
+#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375
msgctxt "button"
msgid "_Cancel"
msgstr "_Annuler"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366
+#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373
msgctxt "button"
msgid "_Save"
msgstr "_Sauver"
-#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367
+#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374
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:557
msgctxt "title"
+msgid "Modified File"
+msgstr "Fichier modifié"
+
+#: solvespace.cpp:559
+#, c-format
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the sketch “%s”?"
+msgstr ""
+
+#: solvespace.cpp:562
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the new sketch?"
+msgstr ""
+
+#: solvespace.cpp:565
+msgctxt "dialog"
+msgid "Your changes will be lost if you don't save them."
+msgstr ""
+
+#: solvespace.cpp:566
+msgctxt "button"
+msgid "&Save"
+msgstr ""
+
+#: solvespace.cpp:568
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr ""
+
+#: solvespace.cpp:589
+msgctxt "title"
msgid "(new sketch)"
msgstr "(nouveau dessin)"
-#: solvespace.cpp:564
+#: solvespace.cpp:596
msgctxt "title"
msgid "Property Browser"
msgstr "Navigateur de propriété"
+#: 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:730
+#, c-format
+msgid ""
+"Can't identify file type from file extension of filename '%s'; try .dxf or ."
+"dwg."
+msgstr ""
+
+#: solvespace.cpp:778
+msgid "Constraint must have a label, and must not be a reference dimension."
+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 ""
+
+#: solvespace.cpp:822
+#, c-format
+msgid ""
+"The volume of the solid model is:\n"
+"\n"
+" %s"
+msgstr ""
+
+#: solvespace.cpp:831
+#, c-format
+msgid ""
+"\n"
+"The volume of current group mesh is:\n"
+"\n"
+" %s"
+msgstr ""
+
+#: solvespace.cpp:836
+msgid ""
+"\n"
+"\n"
+"Curved surfaces have been approximated as triangles.\n"
+"This introduces error, typically of around 1%."
+msgstr ""
+
+#: solvespace.cpp:851
+#, 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: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
+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:892
+#, 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: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 ""
+
+#: solvespace.cpp:941
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr ""
+
+#: solvespace.cpp:971
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr ""
+
+#: solvespace.cpp:972
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr ""
+
+#: solvespace.cpp:974
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr ""
+
+#: solvespace.cpp:975
+msgid "The mesh is watertight (okay, valid)."
+msgstr ""
+
+#: solvespace.cpp:978
+#, c-format
+msgid ""
+"\n"
+"\n"
+"The model contains %d triangles, from %d surfaces."
+msgstr ""
+
+#: solvespace.cpp:982
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Zero problematic edges, good.%s"
+msgstr ""
+
+#: solvespace.cpp:985
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d problematic edges, bad.%s"
+msgstr ""
+
+#: solvespace.cpp:998
+#, 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 "
@@ -1837,31 +2065,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"
@@ -1964,18 +2200,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 95a3a94e..42a3fa3a 100644
--- a/res/locales/ru_RU.po
+++ b/res/locales/ru_RU.po
@@ -6,8 +6,8 @@ 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: 2017-04-21 10:29+0700\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"
"Language: ru_RU\n"
@@ -15,9 +15,9 @@ 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: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 "кликните мышью там, где будет расположен текстовый комментарий"
@@ -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"
@@ -607,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."
@@ -615,18 +627,18 @@ msgstr ""
"Некоторые данные из этого файла не распознаны. Возможно, файл поврежден или "
"создан в более новой версии программы"
-#: file.cpp:849
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr "Файл Отсутствует"
-#: file.cpp:850
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
-msgstr ""
+msgstr "Связанный файл “%s” отсутствует."
-#: file.cpp:852
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
@@ -638,17 +650,17 @@ msgstr ""
"Если вы ответите \"Нет\", то вся геометрия, которая зависит от "
"отсутствующего файла будет удалена."
-#: file.cpp:855
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr "Да"
-#: file.cpp:857
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr "Нет"
-#: file.cpp:859
+#: file.cpp:877 solvespace.cpp:569
msgctxt "button"
msgid "&Cancel"
msgstr "Отменить"
@@ -767,7 +779,7 @@ msgstr "С&бросить Выделение"
#: graphicswin.cpp:78
msgid "&Line Styles..."
-msgstr ""
+msgstr "Стили Линий..."
#: graphicswin.cpp:79
msgid "&View Projection..."
@@ -775,7 +787,7 @@ msgstr "&View Прое&кция..."
#: graphicswin.cpp:81
msgid "Con&figuration..."
-msgstr ""
+msgstr "Настройки..."
#: graphicswin.cpp:84
msgid "&View"
@@ -814,299 +826,303 @@ msgid "Show Snap &Grid"
msgstr "Показать &Сетку"
#: graphicswin.cpp:95
+msgid "Darken Inactive Solids"
+msgstr "Затемнять Неактивные Тела"
+
+#: graphicswin.cpp:96
msgid "Use &Perspective Projection"
msgstr "Перспективная Прое&кция"
-#: graphicswin.cpp:96
-msgid "Dimension &Units"
-msgstr ""
-
#: graphicswin.cpp:97
+msgid "Dimension &Units"
+msgstr "Единицы Измерения"
+
+#: graphicswin.cpp:98
msgid "Dimensions in &Millimeters"
msgstr "Размеры в Ми&ллиметрах"
-#: graphicswin.cpp:98
-msgid "Dimensions in M&eters"
-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 "Создать Эскиз в &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
-msgid "&Helix"
-msgstr ""
-
#: graphicswin.cpp:115
+msgid "&Helix"
+msgstr "Тело Винтовое"
+
+#: graphicswin.cpp:116
msgid "&Lathe"
msgstr "Тело В&ращения"
-#: graphicswin.cpp:116
+#: graphicswin.cpp:117
msgid "Re&volve"
-msgstr ""
+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 ""
+msgstr "Показать Центр Масс"
-#: graphicswin.cpp:174
+#: graphicswin.cpp:175
msgid "Show &Underconstrained Points"
-msgstr ""
+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 ""
+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"
@@ -1120,16 +1136,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 +1154,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 +1162,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 +1171,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 +1187,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 +1196,54 @@ 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."
@@ -1274,6 +1291,8 @@ msgstr "тело-выдавливания"
#: group.cpp:168
msgid "Lathe operation can only be applied to planar sketches."
msgstr ""
+"Операция создания тела вращения может быть применена только к плоским "
+"эскизам."
#: group.cpp:179
msgid ""
@@ -1300,6 +1319,8 @@ msgstr "тело-вращения"
#: group.cpp:194
msgid "Revolve operation can only be applied to planar sketches."
msgstr ""
+"Операция создания тела вращения может быть применена только к плоским "
+"эскизам."
#: group.cpp:205
msgid ""
@@ -1309,15 +1330,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 ""
@@ -1327,11 +1358,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 ""
@@ -1366,19 +1405,19 @@ msgstr "линейный-массив"
msgid "(unnamed)"
msgstr "(без имени)"
-#: groupmesh.cpp:689
+#: groupmesh.cpp:709
msgid "not closed contour, or not all same style!"
msgstr "незамкнутый контур или несовпадение стилей!"
-#: groupmesh.cpp:702
+#: groupmesh.cpp:722
msgid "points not all coplanar!"
msgstr "не все точки лежат в одной плоскости!"
-#: groupmesh.cpp:704
+#: groupmesh.cpp:724
msgid "contour is self-intersecting!"
msgstr "контур имеет самопересечения!"
-#: groupmesh.cpp:706
+#: groupmesh.cpp:726
msgid "zero-length edge!"
msgstr "вырожденный отрезок!"
@@ -1420,293 +1459,582 @@ 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
+#: 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:990 mouse.cpp:1277
+#: mouse.cpp:988 mouse.cpp:1275
msgid "click next point of line, or press Esc"
msgstr "кликните мышью там, где хотите расположить следующую точку"
-#: mouse.cpp:996
+#: mouse.cpp:994
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
"Невозможно начертить прямоугольник, когда рабочая плоскость не активна."
-#: mouse.cpp:1030
+#: mouse.cpp:1028
msgid "click to place other corner of rectangle"
msgstr "кликните мышью там, где хотите расположить другой угол прямоугольника"
-#: mouse.cpp:1050
+#: mouse.cpp:1048
msgid "click to set radius"
msgstr "кликните, чтобы задать радиус"
-#: mouse.cpp:1055
+#: mouse.cpp:1053
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr "Невозможно создать дугу, когда нет активной рабочей плоскости."
-#: mouse.cpp:1074
+#: mouse.cpp:1072
msgid "click to place point"
msgstr "кликните мышью там, где хотите создать точку"
-#: mouse.cpp:1090
+#: mouse.cpp:1088
msgid "click next point of cubic, or press Esc"
msgstr ""
"кликните мышью там, где хотите создать следующую точку сплайна или нажмите "
"Esc для завершения операции."
-#: mouse.cpp:1095
+#: mouse.cpp:1093
msgid ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
"Рабочая плоскость уже активна. Перейдите в режим 3d перед созданием новой "
"рабочей плоскости."
-#: mouse.cpp:1111
+#: mouse.cpp:1109
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr "Невозможно создать текст, когда нет активной рабочей плоскости."
-#: mouse.cpp:1128
+#: mouse.cpp:1126
msgid "click to place bottom right of text"
-msgstr ""
+msgstr "кликните, чтобы расположить правый нижний угол текста"
-#: mouse.cpp:1134
+#: mouse.cpp:1132
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
-msgstr ""
+msgstr "Невозможно создать изображение. Активируйте рабочую плоскость."
-#: mouse.cpp:1161
+#: mouse.cpp:1159
msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
msgstr "КОММЕНТАРИЙ -- ДВОЙНОЙ ЩЕЛЧОК ДЛЯ РЕДАКТИРОВАНИЯ"
-#: platform/gui.cpp:85
+#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
msgctxt "file-type"
msgid "SolveSpace models"
msgstr "проекты SolveSpace"
-#: platform/gui.cpp:89
+#: platform/gui.cpp:90
+msgctxt "file-type"
+msgid "IDF circuit board"
+msgstr "IDF печатная плата"
+
+#: 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
-msgctxt "file-type"
-msgid "Q3D Object file"
-msgstr ""
-
-#: platform/gui.cpp:98
+#: platform/gui.cpp:102
msgctxt "file-type"
msgid "VRML text file"
-msgstr ""
+msgstr "VRML файл"
-#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116
+#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
msgctxt "file-type"
msgid "STEP file"
msgstr "STEP файл"
-#: platform/gui.cpp:106
+#: platform/gui.cpp:110
msgctxt "file-type"
msgid "PDF file"
msgstr "PDF документ"
-#: platform/gui.cpp:107
+#: platform/gui.cpp:111
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr "Encapsulated PostScript"
-#: platform/gui.cpp:108
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr "SVG изображение"
-#: platform/gui.cpp:110 platform/gui.cpp:117
+#: platform/gui.cpp:114 platform/gui.cpp:121
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr "DXF файл (AutoCAD 2007)"
-#: platform/gui.cpp:111
+#: platform/gui.cpp:115
msgctxt "file-type"
msgid "HPGL file"
msgstr "HPGL файл"
-#: platform/gui.cpp:112
+#: platform/gui.cpp:116
msgctxt "file-type"
msgid "G Code"
msgstr "G Code"
-#: platform/gui.cpp:121
+#: platform/gui.cpp:125
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr "AutoCAD DXF и DWG файлы"
-#: platform/gui.cpp:125
+#: platform/gui.cpp:129
msgctxt "file-type"
msgid "Comma-separated values"
msgstr "CSV файлы (значения, разделенные запятой)"
-#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608
+#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639
msgid "untitled"
msgstr "без имени"
-#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305
-#: platform/guiwin.cpp:1555
+#: 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:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288
-#: platform/guiwin.cpp:1557
+#: 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:1332 platform/guigtk.cpp:1368
+#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375
msgctxt "button"
msgid "_Cancel"
msgstr "Отменить"
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366
+#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373
msgctxt "button"
msgid "_Save"
msgstr "Сохранить"
-#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367
+#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374
msgctxt "button"
msgid "_Open"
-msgstr ""
+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:557
msgctxt "title"
+msgid "Modified File"
+msgstr "Измененный Файл"
+
+#: solvespace.cpp:559
+#, c-format
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the sketch “%s”?"
+msgstr "Сохранить изменения, сделанные в файле “%s”?"
+
+#: solvespace.cpp:562
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the new sketch?"
+msgstr "Сохранить изменения, сделанные в новом проекте?"
+
+#: solvespace.cpp:565
+msgctxt "dialog"
+msgid "Your changes will be lost if you don't save them."
+msgstr "Изменения будут утеряны, если их не сохранить."
+
+#: solvespace.cpp:566
+msgctxt "button"
+msgid "&Save"
+msgstr "&Сохранить"
+
+#: solvespace.cpp:568
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr "&Не Сохранять"
+
+#: solvespace.cpp:589
+msgctxt "title"
msgid "(new sketch)"
msgstr "(новый проект)"
-#: solvespace.cpp:564
+#: solvespace.cpp:596
msgctxt "title"
msgid "Property Browser"
msgstr "Браузер"
+#: 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:730
+#, c-format
+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 "У ограничения должно быть значение и оно не должно быть справочным."
+
+#: solvespace.cpp:782
+msgid "Bad selection for step dimension; select a constraint."
+msgstr ""
+"Неправильное выделение для операции изменения значения с заданным шагом; "
+"необходимо выбрать ограничение со значением."
+
+#: solvespace.cpp:806
+msgid "The assembly does not interfere, good."
+msgstr "Сборка не содержит пересечения деталей - это хорошо."
+
+#: solvespace.cpp:822
+#, c-format
+msgid ""
+"The volume of the solid model is:\n"
+"\n"
+" %s"
+msgstr ""
+"Объем тел:\n"
+"\n"
+" %s"
+
+#: solvespace.cpp:831
+#, c-format
+msgid ""
+"\n"
+"The volume of current group mesh is:\n"
+"\n"
+" %s"
+msgstr ""
+"\n"
+"Объем тел текущей группы:\n"
+"\n"
+" %s"
+
+#: solvespace.cpp:836
+msgid ""
+"\n"
+"\n"
+"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
+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 ""
+"Площадь поверхности выбранных граней:\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
+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 ""
+"Площадь замкнутой области текущей группы:\n"
+"\n"
+" %s\n"
+"\n"
+"Кривые аппроксимированы кусочно-линейными функциями.\n"
+"Это приводит к ошибке в расчетах, обычно в пределах 1%%."
+
+#: solvespace.cpp:892
+#, 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 ""
+"Длина выбранных примитивов:\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 "Неправильное выделение для трассировки; необходимо выбрать одну точку."
+
+#: solvespace.cpp:941
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr "Невозможно записать в '%s'"
+
+#: solvespace.cpp:971
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr "Полигональная стека содержит самопересечения (это плохо)"
+
+#: solvespace.cpp:972
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr "Полигональная стека не содержит самопересечений (это хорошо)"
+
+#: solvespace.cpp:974
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr "Полигональная сетка содержит \"оголенные\" ребра (это плохо)"
+
+#: solvespace.cpp:975
+msgid "The mesh is watertight (okay, valid)."
+msgstr "Полигональная сетка герметична (это хорошо)"
+
+#: solvespace.cpp:978
+#, c-format
+msgid ""
+"\n"
+"\n"
+"The model contains %d triangles, from %d surfaces."
+msgstr ""
+"\n"
+"\n"
+"Модель содержит %d треугольников, содержащихся в %d поверхностях."
+
+#: solvespace.cpp:982
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Zero problematic edges, good.%s"
+msgstr ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Нет проблемных ребер - это хорошо.%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 найдены проблемные ребра - это плохо.%s"
+
+#: solvespace.cpp:998
+#, 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 ""
+"Это 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 ""
"Can't assign style to an entity that's derived from another entity; try "
@@ -1761,7 +2089,7 @@ msgstr "Начертить текст TrueType"
#: toolbar.cpp:28
msgid "Sketch image from a file"
-msgstr ""
+msgstr "Импортировать изображение из файла"
#: toolbar.cpp:30
msgid "Create tangent arc at selected point"
@@ -1840,30 +2168,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 "Выровнять вид на рабочую плоскость"
@@ -1967,10 +2303,6 @@ msgstr "Неверный формат: введите данные как x, y,
#~ "\n"
#~ "Хотите сохранить их?"
-#~ msgctxt "title"
-#~ msgid "Modified File"
-#~ msgstr "Измененный Файл"
-
#~ msgctxt "button"
#~ msgid "Do_n't Save"
#~ msgstr "Не Сохранять"
@@ -1984,10 +2316,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 d4c052d1..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: 2020-09-21 09:28+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"
@@ -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 ""
@@ -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:849
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr ""
-#: file.cpp:850
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr ""
-#: file.cpp:852
+#: file.cpp:870
msgctxt "dialog"
msgid ""
"Do you want to locate it manually?\n"
@@ -518,17 +522,17 @@ msgid ""
"permanently removed."
msgstr ""
-#: file.cpp:855
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr ""
-#: file.cpp:857
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr ""
-#: file.cpp:859
+#: file.cpp:877 solvespace.cpp:569
msgctxt "button"
msgid "&Cancel"
msgstr ""
@@ -694,299 +698,303 @@ msgid "Show Snap &Grid"
msgstr "Показати &Сітку Прикріплення"
#: graphicswin.cpp:95
+msgid "Darken Inactive Solids"
+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 +1003,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 +1197,19 @@ msgstr ""
msgid "(unnamed)"
msgstr ""
-#: groupmesh.cpp:689
+#: groupmesh.cpp:709
msgid "not closed contour, or not all same style!"
msgstr ""
-#: groupmesh.cpp:702
+#: groupmesh.cpp:722
msgid "points not all coplanar!"
msgstr ""
-#: groupmesh.cpp:704
+#: groupmesh.cpp:724
msgid "contour is self-intersecting!"
msgstr ""
-#: groupmesh.cpp:706
+#: groupmesh.cpp:726
msgid "zero-length edge!"
msgstr ""
@@ -1239,281 +1247,501 @@ 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:990 mouse.cpp:1277
+#: mouse.cpp:988 mouse.cpp:1275
msgid "click next point of line, or press Esc"
msgstr ""
-#: mouse.cpp:996
+#: mouse.cpp:994
msgid ""
"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
-#: mouse.cpp:1030
+#: mouse.cpp:1028
msgid "click to place other corner of rectangle"
msgstr ""
-#: mouse.cpp:1050
+#: mouse.cpp:1048
msgid "click to set radius"
msgstr ""
-#: mouse.cpp:1055
+#: mouse.cpp:1053
msgid ""
"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
-#: mouse.cpp:1074
+#: mouse.cpp:1072
msgid "click to place point"
msgstr ""
-#: mouse.cpp:1090
+#: mouse.cpp:1088
msgid "click next point of cubic, or press Esc"
msgstr ""
-#: mouse.cpp:1095
+#: mouse.cpp:1093
msgid ""
"Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
-#: mouse.cpp:1111
+#: mouse.cpp:1109
msgid ""
"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
-#: mouse.cpp:1128
+#: mouse.cpp:1126
msgid "click to place bottom right of text"
msgstr ""
-#: mouse.cpp:1134
+#: mouse.cpp:1132
msgid ""
"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
"Workplane."
msgstr ""
-#: mouse.cpp:1161
+#: mouse.cpp:1159
msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
msgstr ""
-#: platform/gui.cpp:85
+#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
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 "VRML text file"
msgstr ""
-#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116
+#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
msgctxt "file-type"
msgid "STEP file"
msgstr ""
-#: platform/gui.cpp:106
+#: platform/gui.cpp:110
msgctxt "file-type"
msgid "PDF file"
msgstr ""
-#: platform/gui.cpp:107
+#: platform/gui.cpp:111
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr ""
-#: platform/gui.cpp:108
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr ""
-#: platform/gui.cpp:110 platform/gui.cpp:117
+#: platform/gui.cpp:114 platform/gui.cpp:121
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr ""
-#: platform/gui.cpp:111
+#: platform/gui.cpp:115
msgctxt "file-type"
msgid "HPGL file"
msgstr ""
-#: platform/gui.cpp:112
+#: platform/gui.cpp:116
msgctxt "file-type"
msgid "G Code"
msgstr ""
-#: platform/gui.cpp:121
+#: platform/gui.cpp:125
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr ""
-#: platform/gui.cpp:125
+#: platform/gui.cpp:129
msgctxt "file-type"
msgid "Comma-separated values"
msgstr ""
-#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608
+#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639
msgid "untitled"
msgstr ""
-#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305
-#: platform/guiwin.cpp:1555
+#: 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:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288
-#: platform/guiwin.cpp:1557
+#: 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:1332 platform/guigtk.cpp:1368
+#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375
msgctxt "button"
msgid "_Cancel"
msgstr ""
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366
+#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373
msgctxt "button"
msgid "_Save"
msgstr ""
-#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367
+#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374
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:557
msgctxt "title"
+msgid "Modified File"
+msgstr ""
+
+#: solvespace.cpp:559
+#, c-format
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the sketch “%s”?"
+msgstr ""
+
+#: solvespace.cpp:562
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the new sketch?"
+msgstr ""
+
+#: solvespace.cpp:565
+msgctxt "dialog"
+msgid "Your changes will be lost if you don't save them."
+msgstr ""
+
+#: solvespace.cpp:566
+msgctxt "button"
+msgid "&Save"
+msgstr ""
+
+#: solvespace.cpp:568
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr ""
+
+#: solvespace.cpp:589
+msgctxt "title"
msgid "(new sketch)"
msgstr ""
-#: solvespace.cpp:564
+#: solvespace.cpp:596
msgctxt "title"
msgid "Property Browser"
msgstr ""
+#: 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:730
+#, c-format
+msgid ""
+"Can't identify file type from file extension of filename '%s'; try .dxf or ."
+"dwg."
+msgstr ""
+
+#: solvespace.cpp:778
+msgid "Constraint must have a label, and must not be a reference dimension."
+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 ""
+
+#: solvespace.cpp:822
+#, c-format
+msgid ""
+"The volume of the solid model is:\n"
+"\n"
+" %s"
+msgstr ""
+
+#: solvespace.cpp:831
+#, c-format
+msgid ""
+"\n"
+"The volume of current group mesh is:\n"
+"\n"
+" %s"
+msgstr ""
+
+#: solvespace.cpp:836
+msgid ""
+"\n"
+"\n"
+"Curved surfaces have been approximated as triangles.\n"
+"This introduces error, typically of around 1%."
+msgstr ""
+
+#: solvespace.cpp:851
+#, 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: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
+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:892
+#, 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: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 ""
+
+#: solvespace.cpp:941
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr ""
+
+#: solvespace.cpp:971
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr ""
+
+#: solvespace.cpp:972
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr ""
+
+#: solvespace.cpp:974
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr ""
+
+#: solvespace.cpp:975
+msgid "The mesh is watertight (okay, valid)."
+msgstr ""
+
+#: solvespace.cpp:978
+#, c-format
+msgid ""
+"\n"
+"\n"
+"The model contains %d triangles, from %d surfaces."
+msgstr ""
+
+#: solvespace.cpp:982
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Zero problematic edges, good.%s"
+msgstr ""
+
+#: solvespace.cpp:985
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d problematic edges, bad.%s"
+msgstr ""
+
+#: solvespace.cpp:998
+#, 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 "
@@ -1645,30 +1873,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
new file mode 100644
index 00000000..1c2ce7f6
--- /dev/null
+++ b/res/locales/zh_CN.po
@@ -0,0 +1,2023 @@
+# Chinese translations for SolveSpace package.
+# 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-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"
+"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:310
+msgid ""
+"Cut, paste, and copy work only in a workplane.\n"
+"\n"
+"Activate one with Sketch -> In Workplane."
+msgstr ""
+"仅在工作平面中剪切、粘贴和复制工作。\n"
+"\n"
+"使用\"工作平面中的草图 -+\"激活一个。"
+
+#: clipboard.cpp:327
+msgid "Clipboard is empty; nothing to paste."
+msgstr "剪贴板为空;没有要粘贴的内容。"
+
+#: clipboard.cpp:374
+msgid "Number of copies to paste must be at least one."
+msgstr "要粘贴的副本数必须至少为 1 个。"
+
+#: clipboard.cpp:390 textscreens.cpp:783
+msgid "Scale cannot be zero."
+msgstr "缩放不能为零。"
+
+#: clipboard.cpp:432
+msgid "Select one point to define origin of rotation."
+msgstr "选择一个点以定义旋转原点。"
+
+#: clipboard.cpp:444
+msgid "Select two points to define translation vector."
+msgstr "选择两个点来定义转换向量。"
+
+#: clipboard.cpp:454
+msgid ""
+"Transformation is identity. So all copies will be exactly on top of each "
+"other."
+msgstr "转换就是标识,因此所有的复制在彼此之上。"
+
+#: clipboard.cpp:458
+msgid "Too many items to paste; split this into smaller pastes."
+msgstr "要粘贴的项目太多; 请把他们拆分。"
+
+#: clipboard.cpp:463
+msgid "No workplane active."
+msgstr "没有工作平面处于活动状态。"
+
+#: confscreen.cpp:418
+msgid "Bad format: specify coordinates as x, y, z"
+msgstr "格式错误:将坐标指定为 x、y、z"
+
+#: confscreen.cpp:428 style.cpp:659 textscreens.cpp:805
+msgid "Bad format: specify color as r, g, b"
+msgstr "格式错误:将颜色指定为 r、g、b"
+
+#: confscreen.cpp:454
+msgid ""
+"The perspective factor will have no effect until you enable View -> Use "
+"Perspective Projection."
+msgstr "在启用\"视图 -= 使用透视投影\"之前,透视因子将不起作用。"
+
+#: confscreen.cpp:467 confscreen.cpp:477
+#, c-format
+msgid "Specify between 0 and %d digits after the decimal."
+msgstr "在十进制之后指定 0 和 %d 数字之间。"
+
+#: confscreen.cpp:489
+msgid "Export scale must not be zero!"
+msgstr "输出比例不能为零!"
+
+#: confscreen.cpp:501
+msgid "Cutter radius offset must not be negative!"
+msgstr "刀具半径偏移不能为负数!"
+
+#: confscreen.cpp:555
+msgid "Bad value: autosave interval should be positive"
+msgstr "坏值:自动保存间隔应为正"
+
+#: confscreen.cpp:558
+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: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"
+" * 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:284
+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:346
+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:385
+msgid ""
+"Bad selection for length ratio constraint. This constraint can apply to:\n"
+"\n"
+" * two line segments\n"
+msgstr ""
+"长度比率约束的选择错误。此约束可应用于:\n"
+"\n"
+"* 两个线段\n"
+
+#: constraint.cpp:402
+msgid ""
+"Bad selection for length difference constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two line segments\n"
+msgstr ""
+"长度差异约束的选择错误。此约束可应用于:\n"
+"\n"
+"* 两个线段\n"
+
+#: constraint.cpp:428
+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:486
+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:500
+msgid ""
+"A workplane must be active when constraining symmetric without an explicit "
+"symmetry plane."
+msgstr "在没有显式对称平面约束对称时,工作平面必须处于活动状态。"
+
+#: constraint.cpp:530
+msgid ""
+"Activate a workplane (with Sketch -> In Workplane) before applying a "
+"horizontal or vertical constraint."
+msgstr "在应用水平或垂直约束之前,激活工作平面(使用草图 -= 在工作平面中)。"
+
+#: constraint.cpp:543
+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:564
+msgid ""
+"Bad selection for same orientation constraint. This constraint can apply "
+"to:\n"
+"\n"
+" * two normals\n"
+msgstr ""
+"同一方向约束的选择错误。此约束可应用于:\n"
+"\n"
+"• 两个法线\n"
+
+#: constraint.cpp:614
+msgid "Must select an angle constraint."
+msgstr "必须选择角度约束。"
+
+#: constraint.cpp:627
+msgid "Must select a constraint with associated label."
+msgstr "必须选择具有关联标签的约束。"
+
+#: constraint.cpp:638
+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:701
+msgid "Curve-curve tangency must apply in workplane."
+msgstr "曲线曲线切线必须应用于工作平面。"
+
+#: constraint.cpp:711
+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: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 ""
+"垂直约束的选择错误。此约束可应用于:\n"
+"\n"
+"* 两个线段\n"
+" * 线段和法线\n"
+" • 两个法线\n"
+
+#: constraint.cpp:744
+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:755
+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: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:867
+msgctxt "title"
+msgid "Missing File"
+msgstr "文件丢失"
+
+#: file.cpp:868
+#, c-format
+msgctxt "dialog"
+msgid "The linked file “%s” is not present."
+msgstr "连接的文件不存在:\"%s\"。"
+
+#: file.cpp:870
+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:873
+msgctxt "button"
+msgid "&Yes"
+msgstr "是(&Y)"
+
+#: file.cpp:875
+msgctxt "button"
+msgid "&No"
+msgstr "否(&N)"
+
+#: file.cpp:877 solvespace.cpp:569
+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 "Darken Inactive Solids"
+msgstr ""
+
+#: graphicswin.cpp:96
+msgid "Use &Perspective Projection"
+msgstr "使用远景透视(&P)"
+
+#: graphicswin.cpp:97
+msgid "Dimension &Units"
+msgstr "标注单位(&U)"
+
+#: graphicswin.cpp:98
+msgid "Dimensions in &Millimeters"
+msgstr "标注单位 mm (&M)"
+
+#: graphicswin.cpp:99
+msgid "Dimensions in M&eters"
+msgstr "标注单位m (&E)"
+
+#: graphicswin.cpp:100
+msgid "Dimensions in &Inches"
+msgstr "标准单位英寸 (&I)"
+
+#: graphicswin.cpp:102
+msgid "Show &Toolbar"
+msgstr "显示工具条(&T)"
+
+#: graphicswin.cpp:103
+msgid "Show Property Bro&wser"
+msgstr "显示属性浏览器(&W)"
+
+#: graphicswin.cpp:105
+msgid "&Full Screen"
+msgstr "全屏(&F)"
+
+#: graphicswin.cpp:107
+msgid "&New Group"
+msgstr "新组合(&N)"
+
+#: graphicswin.cpp:108
+msgid "Sketch In &3d"
+msgstr "在三维内绘制(&3)"
+
+#: graphicswin.cpp:109
+msgid "Sketch In New &Workplane"
+msgstr "在新工作面绘制(&W)"
+
+#: graphicswin.cpp:111
+msgid "Step &Translating"
+msgstr "移动(&T)"
+
+#: graphicswin.cpp:112
+msgid "Step &Rotating"
+msgstr "旋转(&R)"
+
+#: graphicswin.cpp:114
+msgid "E&xtrude"
+msgstr "挤出(&E)"
+
+#: graphicswin.cpp:115
+msgid "&Helix"
+msgstr "螺旋(&H)"
+
+#: graphicswin.cpp:116
+msgid "&Lathe"
+msgstr "扫略(&L)"
+
+#: graphicswin.cpp:117
+msgid "Re&volve"
+msgstr "旋转(&V)"
+
+#: graphicswin.cpp:119
+msgid "Link / Assemble..."
+msgstr "链接/装配..."
+
+#: graphicswin.cpp:120
+msgid "Link Recent"
+msgstr "连接最近文件"
+
+#: graphicswin.cpp:122
+msgid "&Sketch"
+msgstr "绘图(&S)"
+
+#: graphicswin.cpp:123
+msgid "In &Workplane"
+msgstr "在工作平面(&W)"
+
+#: graphicswin.cpp:124
+msgid "Anywhere In &3d"
+msgstr "在3D的任何位置(&3)"
+
+#: graphicswin.cpp:126
+msgid "Datum &Point"
+msgstr "基准点(&P)"
+
+#: graphicswin.cpp:127
+msgid "&Workplane"
+msgstr "工作面(&W)"
+
+#: graphicswin.cpp:129
+msgid "Line &Segment"
+msgstr "线段(&S)"
+
+#: graphicswin.cpp:130
+msgid "C&onstruction Line Segment"
+msgstr "构造线段(&C)"
+
+#: graphicswin.cpp:131
+msgid "&Rectangle"
+msgstr "矩形(&R)"
+
+#: graphicswin.cpp:132
+msgid "&Circle"
+msgstr "圆线(&C)"
+
+#: graphicswin.cpp:133
+msgid "&Arc of a Circle"
+msgstr "圆弧(&A)"
+
+#: graphicswin.cpp:134
+msgid "&Bezier Cubic Spline"
+msgstr "立方体线的贝塞尔曲线(&B)"
+
+#: graphicswin.cpp:136
+msgid "&Text in TrueType Font"
+msgstr "TrueTyoe字体文字(&T)"
+
+#: graphicswin.cpp:137
+msgid "&Image"
+msgstr "图片(&I)"
+
+#: graphicswin.cpp:139
+msgid "To&ggle Construction"
+msgstr "切换构造(&G)"
+
+#: graphicswin.cpp:140
+msgid "Tangent &Arc at Point"
+msgstr "弧线切线点(&A)"
+
+#: graphicswin.cpp:141
+msgid "Split Curves at &Intersection"
+msgstr "在交叉处拆分曲线(&I)"
+
+#: graphicswin.cpp:143
+msgid "&Constrain"
+msgstr "约束(&C)"
+
+#: graphicswin.cpp:144
+msgid "&Distance / Diameter"
+msgstr "距离/直径(&D)"
+
+#: graphicswin.cpp:145
+msgid "Re&ference Dimension"
+msgstr "参考标注(&F)"
+
+#: graphicswin.cpp:146
+msgid "A&ngle"
+msgstr "角度(&A)"
+
+#: graphicswin.cpp:147
+msgid "Reference An&gle"
+msgstr "参考角度(&G)"
+
+#: graphicswin.cpp:148
+msgid "Other S&upplementary Angle"
+msgstr "其它增补角度(&U)"
+
+#: graphicswin.cpp:149
+msgid "Toggle R&eference Dim"
+msgstr "切换参考标注(&E)"
+
+#: graphicswin.cpp:151
+msgid "&Horizontal"
+msgstr "水平约束(&H)"
+
+#: graphicswin.cpp:152
+msgid "&Vertical"
+msgstr "垂直约束(&V)"
+
+#: graphicswin.cpp:154
+msgid "&On Point / Curve / Plane"
+msgstr "在点线面(&O)"
+
+#: graphicswin.cpp:155
+msgid "E&qual Length / Radius / Angle"
+msgstr "等于/长度/半径/角度(&Q)"
+
+#: graphicswin.cpp:156
+msgid "Length Ra&tio"
+msgstr "长度比例(&T)"
+
+#: graphicswin.cpp:157
+msgid "Length Diff&erence"
+msgstr "长度偏差(&E)"
+
+#: graphicswin.cpp:158
+msgid "At &Midpoint"
+msgstr "在中点(&M)"
+
+#: graphicswin.cpp:159
+msgid "S&ymmetric"
+msgstr "对称(&Y)"
+
+#: graphicswin.cpp:160
+msgid "Para&llel / Tangent"
+msgstr "水平/切线(&L)"
+
+#: graphicswin.cpp:161
+msgid "&Perpendicular"
+msgstr "垂直的(&P)"
+
+#: graphicswin.cpp:162
+msgid "Same Orient&ation"
+msgstr "相同方向(&A)"
+
+#: graphicswin.cpp:163
+msgid "Lock Point Where &Dragged"
+msgstr "锁定点位置(&D)"
+
+#: graphicswin.cpp:165
+msgid "Comment"
+msgstr "备注"
+
+#: graphicswin.cpp:167
+msgid "&Analyze"
+msgstr "分析(&A)"
+
+#: graphicswin.cpp:168
+msgid "Measure &Volume"
+msgstr "测量体积(&V)"
+
+#: graphicswin.cpp:169
+msgid "Measure A&rea"
+msgstr "测量面积(&R)"
+
+#: graphicswin.cpp:170
+msgid "Measure &Perimeter"
+msgstr "测量周长(&P)"
+
+#: graphicswin.cpp:171
+msgid "Show &Interfering Parts"
+msgstr "显示干涉零件(&I)"
+
+#: graphicswin.cpp:172
+msgid "Show &Naked Edges"
+msgstr "显示孤立边(&N)"
+
+#: graphicswin.cpp:173
+msgid "Show &Center of Mass"
+msgstr "显示中心(&C)"
+
+#: graphicswin.cpp:175
+msgid "Show &Underconstrained Points"
+msgstr "显示无效约束点(&U)"
+
+#: graphicswin.cpp:177
+msgid "&Trace Point"
+msgstr "跟踪点(&T)"
+
+#: graphicswin.cpp:178
+msgid "&Stop Tracing..."
+msgstr "停止跟踪(&S)"
+
+#: graphicswin.cpp:179
+msgid "Step &Dimension..."
+msgstr "逐步标注(&D)"
+
+#: graphicswin.cpp:181
+msgid "&Help"
+msgstr "帮助(&H)"
+
+#: graphicswin.cpp:182
+msgid "&Language"
+msgstr "语言(&L)"
+
+#: graphicswin.cpp:183
+msgid "&Website / Manual"
+msgstr "网页/手册(&W)"
+
+#: graphicswin.cpp:185
+msgid "&About"
+msgstr "关于(&A)"
+
+#: graphicswin.cpp:355
+msgid "(no recent files)"
+msgstr "(无文件)"
+
+#: graphicswin.cpp:363
+#, c-format
+msgid "File '%s' does not exist."
+msgstr "文件不存在: \"%s\"。"
+
+#: graphicswin.cpp:725
+msgid "No workplane is active, so the grid will not appear."
+msgstr "没有激活的工作面,因此无法显示轴网。"
+
+#: graphicswin.cpp:740
+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:819
+msgid ""
+"Select a point; this point will become the center of the view on screen."
+msgstr ""
+
+#: graphicswin.cpp:1114
+msgid "No additional entities share endpoints with the selected entities."
+msgstr ""
+
+#: 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:1155
+msgid ""
+"No workplane is active. Activate a workplane (with Sketch -> In Workplane) "
+"to define the plane for the snap grid."
+msgstr ""
+
+#: 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:1247
+msgid "No workplane selected. Activating default workplane for this group."
+msgstr ""
+
+#: 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:1271
+msgid ""
+"Bad selection for tangent arc at point. Select a single point, or select "
+"nothing to set up arc parameters."
+msgstr ""
+
+#: graphicswin.cpp:1282
+msgid "click point on arc (draws anti-clockwise)"
+msgstr "点击弧线的点(逆时针方向绘制)"
+
+#: graphicswin.cpp:1283
+msgid "click to place datum point"
+msgstr "点击放置基准点"
+
+#: graphicswin.cpp:1284
+msgid "click first point of line segment"
+msgstr "点击线条的起点"
+
+#: graphicswin.cpp:1286
+msgid "click first point of construction line segment"
+msgstr "点击构造线的起点"
+
+#: graphicswin.cpp:1287
+msgid "click first point of cubic segment"
+msgstr "点击立方体的起点"
+
+#: graphicswin.cpp:1288
+msgid "click center of circle"
+msgstr "点击圆弧的中心"
+
+#: graphicswin.cpp:1289
+msgid "click origin of workplane"
+msgstr "点击工作面的原点"
+
+#: graphicswin.cpp:1290
+msgid "click one corner of rectangle"
+msgstr "点击一个矩形倒角"
+
+#: graphicswin.cpp:1291
+msgid "click top left of text"
+msgstr "点击文字左上角"
+
+#: graphicswin.cpp:1297
+msgid "click top left of image"
+msgstr "点击图片左上角"
+
+#: graphicswin.cpp:1309
+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:709
+msgid "not closed contour, or not all same style!"
+msgstr "未闭合轮廓,或样式不一致!"
+
+#: groupmesh.cpp:722
+msgid "points not all coplanar!"
+msgstr "点不在相同平面!"
+
+#: groupmesh.cpp:724
+msgid "contour is self-intersecting!"
+msgstr "轮廓自相交!"
+
+#: groupmesh.cpp:726
+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:559
+msgid "Assign to Style"
+msgstr "指定样式"
+
+#: mouse.cpp:575
+msgid "No Style"
+msgstr "无样式"
+
+#: mouse.cpp:578
+msgid "Newly Created Custom Style..."
+msgstr "新组样式。"
+
+#: mouse.cpp:585
+msgid "Group Info"
+msgstr "组信息"
+
+#: mouse.cpp:605
+msgid "Style Info"
+msgstr "样式信息"
+
+#: mouse.cpp:625
+msgid "Select Edge Chain"
+msgstr "选择边缘链"
+
+#: mouse.cpp:631
+msgid "Toggle Reference Dimension"
+msgstr "切换参考标注"
+
+#: mouse.cpp:637
+msgid "Other Supplementary Angle"
+msgstr "其它补充角度"
+
+#: mouse.cpp:642
+msgid "Snap to Grid"
+msgstr "捕捉至轴网"
+
+#: mouse.cpp:651
+msgid "Remove Spline Point"
+msgstr "删除样条线的点"
+
+#: mouse.cpp:686
+msgid "Add Spline Point"
+msgstr "增加样条线的点"
+
+#: mouse.cpp:690
+msgid "Cannot add spline point: maximum number of points reached."
+msgstr "无法增加样条线点:超过最大限制。"
+
+#: mouse.cpp:715
+msgid "Toggle Construction"
+msgstr "切换构造"
+
+#: mouse.cpp:730
+msgid "Delete Point-Coincident Constraint"
+msgstr "删除点一致约束"
+
+#: mouse.cpp:749
+msgid "Cut"
+msgstr "剪切"
+
+#: mouse.cpp:751
+msgid "Copy"
+msgstr "复制"
+
+#: mouse.cpp:755
+msgid "Select All"
+msgstr "全选"
+
+#: mouse.cpp:760
+msgid "Paste"
+msgstr "粘贴"
+
+#: mouse.cpp:762
+msgid "Paste Transformed..."
+msgstr "粘贴移动的..."
+
+#: mouse.cpp:767
+msgid "Delete"
+msgstr "删除"
+
+#: mouse.cpp:770
+msgid "Unselect All"
+msgstr "取消全选"
+
+#: mouse.cpp:777
+msgid "Unselect Hovered"
+msgstr "取消覆盖区域的全选"
+
+#: mouse.cpp:786
+msgid "Zoom to Fit"
+msgstr "自动缩放"
+
+#: mouse.cpp:988 mouse.cpp:1275
+msgid "click next point of line, or press Esc"
+msgstr "点击下一个点或取消(ESC)"
+
+#: mouse.cpp:994
+msgid ""
+"Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr "无法在3D内绘制矩形; 首先,激活工作面,草图->在工作面。"
+
+#: mouse.cpp:1028
+msgid "click to place other corner of rectangle"
+msgstr "点击放置其它矩形倒角"
+
+#: mouse.cpp:1048
+msgid "click to set radius"
+msgstr "点击设置半径"
+
+#: mouse.cpp:1053
+msgid ""
+"Can't draw arc in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr "无法在3D空间内绘制弧线,可使用 草图->在工作面 激活工作面。"
+
+#: mouse.cpp:1072
+msgid "click to place point"
+msgstr "点击放置点"
+
+#: mouse.cpp:1088
+msgid "click next point of cubic, or press Esc"
+msgstr "点击下一个点或取消(ESC)"
+
+#: mouse.cpp:1093
+msgid ""
+"Sketching in a workplane already; sketch in 3d before creating new workplane."
+msgstr "已经在工作面绘制;在新建工作面前在三维空间绘制。"
+
+#: mouse.cpp:1109
+msgid ""
+"Can't draw text in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr "无法在三维空间内绘制文字,可使用 草图->在工作面 激活工作面。"
+
+#: mouse.cpp:1126
+msgid "click to place bottom right of text"
+msgstr "点击文字的右下角放置"
+
+#: mouse.cpp:1132
+msgid ""
+"Can't draw image in 3d; first, activate a workplane with Sketch -> In "
+"Workplane."
+msgstr "无法在三维空间内绘制图片,可使用 草图->在工作面 激活工作面。"
+
+#: mouse.cpp:1159
+msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
+msgstr "新备注 - 双击编辑"
+
+#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
+msgctxt "file-type"
+msgid "SolveSpace models"
+msgstr "SolveSpace模型"
+
+#: 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:98
+msgctxt "file-type"
+msgid "STL mesh"
+msgstr "STL网格"
+
+#: platform/gui.cpp:99
+msgctxt "file-type"
+msgid "Wavefront OBJ mesh"
+msgstr "Wavefront OBJ网格"
+
+#: platform/gui.cpp:100
+msgctxt "file-type"
+msgid "Three.js-compatible mesh, with viewer"
+msgstr "Three.js-网格及查看视图"
+
+#: platform/gui.cpp:101
+msgctxt "file-type"
+msgid "Three.js-compatible mesh, mesh only"
+msgstr "Three.js-仅网格"
+
+#: platform/gui.cpp:102
+msgctxt "file-type"
+msgid "VRML text file"
+msgstr "VRML文本文件"
+
+#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
+msgctxt "file-type"
+msgid "STEP file"
+msgstr "STEP文件"
+
+#: platform/gui.cpp:110
+msgctxt "file-type"
+msgid "PDF file"
+msgstr "PDF文件"
+
+#: platform/gui.cpp:111
+msgctxt "file-type"
+msgid "Encapsulated PostScript"
+msgstr "封装好的PostScript"
+
+#: platform/gui.cpp:112
+msgctxt "file-type"
+msgid "Scalable Vector Graphics"
+msgstr "SVG矢量图"
+
+#: platform/gui.cpp:114 platform/gui.cpp:121
+msgctxt "file-type"
+msgid "DXF file (AutoCAD 2007)"
+msgstr "DXF文件(AutoCAD 2007)"
+
+#: platform/gui.cpp:115
+msgctxt "file-type"
+msgid "HPGL file"
+msgstr "HPGL文件"
+
+#: platform/gui.cpp:116
+msgctxt "file-type"
+msgid "G Code"
+msgstr "G Code"
+
+#: platform/gui.cpp:125
+msgctxt "file-type"
+msgid "AutoCAD DXF and DWG files"
+msgstr "AutoCAD DXF/DWG文件"
+
+#: platform/gui.cpp:129
+msgctxt "file-type"
+msgid "Comma-separated values"
+msgstr "逗号分隔数据"
+
+#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639
+msgid "untitled"
+msgstr "未命名"
+
+#: 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:1336 platform/guigtk.cpp:1369 platform/guimac.mm:1304
+#: platform/guiwin.cpp:1584
+msgctxt "title"
+msgid "Open File"
+msgstr "打开文件"
+
+#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375
+msgctxt "button"
+msgid "_Cancel"
+msgstr "取消_C"
+
+#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373
+msgctxt "button"
+msgid "_Save"
+msgstr "保存_S"
+
+#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374
+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:557
+msgctxt "title"
+msgid "Modified File"
+msgstr ""
+
+#: solvespace.cpp:559
+#, c-format
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the sketch “%s”?"
+msgstr ""
+
+#: solvespace.cpp:562
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the new sketch?"
+msgstr ""
+
+#: solvespace.cpp:565
+msgctxt "dialog"
+msgid "Your changes will be lost if you don't save them."
+msgstr ""
+
+#: solvespace.cpp:566
+msgctxt "button"
+msgid "&Save"
+msgstr ""
+
+#: solvespace.cpp:568
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr ""
+
+#: solvespace.cpp:589
+msgctxt "title"
+msgid "(new sketch)"
+msgstr ""
+
+#: solvespace.cpp:596
+msgctxt "title"
+msgid "Property Browser"
+msgstr ""
+
+#: 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:730
+#, c-format
+msgid ""
+"Can't identify file type from file extension of filename '%s'; try .dxf or ."
+"dwg."
+msgstr ""
+
+#: solvespace.cpp:778
+msgid "Constraint must have a label, and must not be a reference dimension."
+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 ""
+
+#: solvespace.cpp:822
+#, c-format
+msgid ""
+"The volume of the solid model is:\n"
+"\n"
+" %s"
+msgstr ""
+
+#: solvespace.cpp:831
+#, c-format
+msgid ""
+"\n"
+"The volume of current group mesh is:\n"
+"\n"
+" %s"
+msgstr ""
+
+#: solvespace.cpp:836
+msgid ""
+"\n"
+"\n"
+"Curved surfaces have been approximated as triangles.\n"
+"This introduces error, typically of around 1%."
+msgstr ""
+
+#: solvespace.cpp:851
+#, 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: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
+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:892
+#, 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: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 ""
+
+#: solvespace.cpp:941
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr ""
+
+#: solvespace.cpp:971
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr ""
+
+#: solvespace.cpp:972
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr ""
+
+#: solvespace.cpp:974
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr ""
+
+#: solvespace.cpp:975
+msgid "The mesh is watertight (okay, valid)."
+msgstr ""
+
+#: solvespace.cpp:978
+#, c-format
+msgid ""
+"\n"
+"\n"
+"The model contains %d triangles, from %d surfaces."
+msgstr ""
+
+#: solvespace.cpp:982
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Zero problematic edges, good.%s"
+msgstr ""
+
+#: solvespace.cpp:985
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d problematic edges, bad.%s"
+msgstr ""
+
+#: solvespace.cpp:998
+#, 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 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 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:78
+msgid "New group step and repeat translating"
+msgstr "新组中逐步重复移动体"
+
+#: toolbar.cpp:80
+msgid "New group in new workplane (thru given entities)"
+msgstr "在新工作平面创建组(通过指定对象)"
+
+#: toolbar.cpp:82
+msgid "New group in 3d"
+msgstr "在3D中新建组"
+
+#: toolbar.cpp:84
+msgid "New group linking / assembling file"
+msgstr "新组 连接/装配文件"
+
+#: toolbar.cpp:88
+msgid "Nearest isometric view"
+msgstr "ISO视图"
+
+#: toolbar.cpp:90
+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"
+
+#~ msgctxt "file-type"
+#~ msgid "Q3D Object file"
+#~ msgstr "Q3D对象文件"
diff --git a/res/messages.pot b/res/messages.pot
index 8ea9c85b..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: 2020-09-21 09:28+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"
@@ -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 ""
@@ -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:849
+#: file.cpp:867
msgctxt "title"
msgid "Missing File"
msgstr ""
-#: file.cpp:850
+#: file.cpp:868
#, c-format
msgctxt "dialog"
msgid "The linked file “%s” is not present."
msgstr ""
-#: file.cpp:852
+#: 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:855
+#: file.cpp:873
msgctxt "button"
msgid "&Yes"
msgstr ""
-#: file.cpp:857
+#: file.cpp:875
msgctxt "button"
msgid "&No"
msgstr ""
-#: file.cpp:859
+#: file.cpp:877 solvespace.cpp:569
msgctxt "button"
msgid "&Cancel"
msgstr ""
@@ -672,299 +676,303 @@ msgid "Show Snap &Grid"
msgstr ""
#: graphicswin.cpp:95
-msgid "Use &Perspective Projection"
+msgid "Darken Inactive Solids"
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 +980,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 +1168,19 @@ msgstr ""
msgid "(unnamed)"
msgstr ""
-#: groupmesh.cpp:689
+#: groupmesh.cpp:709
msgid "not closed contour, or not all same style!"
msgstr ""
-#: groupmesh.cpp:702
+#: groupmesh.cpp:722
msgid "points not all coplanar!"
msgstr ""
-#: groupmesh.cpp:704
+#: groupmesh.cpp:724
msgid "contour is self-intersecting!"
msgstr ""
-#: groupmesh.cpp:706
+#: groupmesh.cpp:726
msgid "zero-length edge!"
msgstr ""
@@ -1210,262 +1218,489 @@ 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:990 mouse.cpp:1277
+#: mouse.cpp:988 mouse.cpp:1275
msgid "click next point of line, or press Esc"
msgstr ""
-#: mouse.cpp:996
+#: mouse.cpp:994
msgid "Can't draw rectangle in 3d; first, activate a workplane with Sketch -> In Workplane."
msgstr ""
-#: mouse.cpp:1030
+#: mouse.cpp:1028
msgid "click to place other corner of rectangle"
msgstr ""
-#: mouse.cpp:1050
+#: mouse.cpp:1048
msgid "click to set radius"
msgstr ""
-#: mouse.cpp:1055
+#: mouse.cpp:1053
msgid "Can't draw arc in 3d; first, activate a workplane with Sketch -> In Workplane."
msgstr ""
-#: mouse.cpp:1074
+#: mouse.cpp:1072
msgid "click to place point"
msgstr ""
-#: mouse.cpp:1090
+#: mouse.cpp:1088
msgid "click next point of cubic, or press Esc"
msgstr ""
-#: mouse.cpp:1095
+#: mouse.cpp:1093
msgid "Sketching in a workplane already; sketch in 3d before creating new workplane."
msgstr ""
-#: mouse.cpp:1111
+#: mouse.cpp:1109
msgid "Can't draw text in 3d; first, activate a workplane with Sketch -> In Workplane."
msgstr ""
-#: mouse.cpp:1128
+#: mouse.cpp:1126
msgid "click to place bottom right of text"
msgstr ""
-#: mouse.cpp:1134
+#: mouse.cpp:1132
msgid "Can't draw image in 3d; first, activate a workplane with Sketch -> In Workplane."
msgstr ""
-#: mouse.cpp:1161
+#: mouse.cpp:1159
msgid "NEW COMMENT -- DOUBLE-CLICK TO EDIT"
msgstr ""
-#: platform/gui.cpp:85
+#: platform/gui.cpp:85 platform/gui.cpp:89 solvespace.cpp:511
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 "VRML text file"
msgstr ""
-#: platform/gui.cpp:102 platform/gui.cpp:109 platform/gui.cpp:116
+#: platform/gui.cpp:106 platform/gui.cpp:113 platform/gui.cpp:120
msgctxt "file-type"
msgid "STEP file"
msgstr ""
-#: platform/gui.cpp:106
+#: platform/gui.cpp:110
msgctxt "file-type"
msgid "PDF file"
msgstr ""
-#: platform/gui.cpp:107
+#: platform/gui.cpp:111
msgctxt "file-type"
msgid "Encapsulated PostScript"
msgstr ""
-#: platform/gui.cpp:108
+#: platform/gui.cpp:112
msgctxt "file-type"
msgid "Scalable Vector Graphics"
msgstr ""
-#: platform/gui.cpp:110 platform/gui.cpp:117
+#: platform/gui.cpp:114 platform/gui.cpp:121
msgctxt "file-type"
msgid "DXF file (AutoCAD 2007)"
msgstr ""
-#: platform/gui.cpp:111
+#: platform/gui.cpp:115
msgctxt "file-type"
msgid "HPGL file"
msgstr ""
-#: platform/gui.cpp:112
+#: platform/gui.cpp:116
msgctxt "file-type"
msgid "G Code"
msgstr ""
-#: platform/gui.cpp:121
+#: platform/gui.cpp:125
msgctxt "file-type"
msgid "AutoCAD DXF and DWG files"
msgstr ""
-#: platform/gui.cpp:125
+#: platform/gui.cpp:129
msgctxt "file-type"
msgid "Comma-separated values"
msgstr ""
-#: platform/guigtk.cpp:1317 platform/guimac.mm:1347 platform/guiwin.cpp:1608
+#: platform/guigtk.cpp:1324 platform/guimac.mm:1363 platform/guiwin.cpp:1639
msgid "untitled"
msgstr ""
-#: platform/guigtk.cpp:1328 platform/guigtk.cpp:1361 platform/guimac.mm:1305
-#: platform/guiwin.cpp:1555
+#: 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:1329 platform/guigtk.cpp:1362 platform/guimac.mm:1288
-#: platform/guiwin.cpp:1557
+#: 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:1332 platform/guigtk.cpp:1368
+#: platform/guigtk.cpp:1339 platform/guigtk.cpp:1375
msgctxt "button"
msgid "_Cancel"
msgstr ""
-#: platform/guigtk.cpp:1333 platform/guigtk.cpp:1366
+#: platform/guigtk.cpp:1340 platform/guigtk.cpp:1373
msgctxt "button"
msgid "_Save"
msgstr ""
-#: platform/guigtk.cpp:1334 platform/guigtk.cpp:1367
+#: platform/guigtk.cpp:1341 platform/guigtk.cpp:1374
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:557
+msgctxt "title"
+msgid "Modified File"
+msgstr ""
+
+#: solvespace.cpp:559
+#, c-format
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the sketch “%s”?"
+msgstr ""
+
+#: solvespace.cpp:562
+msgctxt "dialog"
+msgid "Do you want to save the changes you made to the new sketch?"
+msgstr ""
+
+#: solvespace.cpp:565
+msgctxt "dialog"
+msgid "Your changes will be lost if you don't save them."
+msgstr ""
+
+#: solvespace.cpp:566
+msgctxt "button"
+msgid "&Save"
+msgstr ""
+
+#: solvespace.cpp:568
+msgctxt "button"
+msgid "Do&n't Save"
+msgstr ""
+
+#: solvespace.cpp:589
+msgctxt "title"
+msgid "(new sketch)"
+msgstr ""
+
+#: solvespace.cpp:596
+msgctxt "title"
+msgid "Property Browser"
+msgstr ""
+
+#: 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:730
+#, c-format
+msgid "Can't identify file type from file extension of filename '%s'; try .dxf or .dwg."
+msgstr ""
+
+#: solvespace.cpp:778
+msgid "Constraint must have a label, and must not be a reference dimension."
+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 ""
+
+#: solvespace.cpp:822
+#, c-format
+msgid ""
+"The volume of the solid model is:\n"
+"\n"
+" %s"
+msgstr ""
+
+#: solvespace.cpp:831
+#, c-format
+msgid ""
+"\n"
+"The volume of current group mesh is:\n"
+"\n"
+" %s"
+msgstr ""
+
+#: solvespace.cpp:836
+msgid ""
+"\n"
+"\n"
+"Curved surfaces have been approximated as triangles.\n"
+"This introduces error, typically of around 1%."
+msgstr ""
+
+#: solvespace.cpp:851
+#, 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: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
+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:892
+#, 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: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 ""
+
+#: solvespace.cpp:941
+#, c-format
+msgid "Couldn't write to '%s'"
+msgstr ""
+
+#: solvespace.cpp:971
+msgid "The mesh is self-intersecting (NOT okay, invalid)."
+msgstr ""
+
+#: solvespace.cpp:972
+msgid "The mesh is not self-intersecting (okay, valid)."
+msgstr ""
+
+#: solvespace.cpp:974
+msgid "The mesh has naked edges (NOT okay, invalid)."
+msgstr ""
+
+#: solvespace.cpp:975
+msgid "The mesh is watertight (okay, valid)."
+msgstr ""
+
+#: solvespace.cpp:978
+#, c-format
+msgid ""
+"\n"
+"\n"
+"The model contains %d triangles, from %d surfaces."
+msgstr ""
+
+#: solvespace.cpp:982
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"Zero problematic edges, good.%s"
+msgstr ""
+
+#: solvespace.cpp:985
+#, c-format
+msgid ""
+"%s\n"
+"\n"
+"%s\n"
+"\n"
+"%d problematic edges, bad.%s"
+msgstr ""
+
+#: solvespace.cpp:998
+#, 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 "
@@ -1597,30 +1832,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 ""
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 00000000..7e6f57f1
Binary files /dev/null and b/res/threejs/three-r111.min.js.gz differ
diff --git a/res/threejs/three-r76.js.gz b/res/threejs/three-r76.js.gz
deleted file mode 100644
index e2b9ca16..00000000
Binary files a/res/threejs/three-r76.js.gz and /dev/null differ
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
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1b6d9005..45dab944 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -80,8 +80,8 @@ include_directories(
${PNG_PNG_INCLUDE_DIR}
${FREETYPE_INCLUDE_DIRS}
${CAIRO_INCLUDE_DIRS}
- ${Q3D_INCLUDE_DIR}
- ${MIMALLOC_INCLUDE_DIR})
+ ${MIMALLOC_INCLUDE_DIR}
+ ${OpenMP_CXX_INCLUDE_DIRS})
if(Backtrace_FOUND)
include_directories(
@@ -214,7 +214,6 @@ add_library(solvespace-core STATIC
${solvespace_core_SOURCES})
add_dependencies(solvespace-core
- q3d_header
mimalloc-static)
target_link_libraries(solvespace-core
@@ -224,7 +223,6 @@ target_link_libraries(solvespace-core
${ZLIB_LIBRARY}
${PNG_LIBRARY}
${FREETYPE_LIBRARY}
- flatbuffers
mimalloc-static)
if(Backtrace_FOUND)
@@ -241,7 +239,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)
@@ -404,20 +403,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)
-
- 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()
diff --git a/src/clipboard.cpp b/src/clipboard.cpp
index 011b658d..d43ec458 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 = {};
@@ -246,25 +245,62 @@ void GraphicsWindow::PasteClipboard(Vector trans, double theta, double scale) {
c.reference = cc->reference;
c.disp = cc->disp;
c.comment = cc->comment;
+ 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
+ if (EXACT(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) {
+ dontAddConstraint = true;
+ }
+ break;
default:
break;
}
-
- hConstraint hc = Constraint::AddConstraint(&c, /*rememberForUndo=*/false);
- if(c.type == Constraint::Type::COMMENT) {
- MakeSelected(hc);
+ if (!dontAddConstraint) {
+ hConstraint hc = Constraint::AddConstraint(&c, /*rememberForUndo=*/false);
+ if(c.type == Constraint::Type::COMMENT) {
+ MakeSelected(hc);
+ }
}
}
}
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) {
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/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();
}
diff --git a/src/draw.cpp b/src/draw.cpp
index db2f33e5..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)) {
@@ -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;
@@ -335,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) {
@@ -345,9 +354,12 @@ 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;
+ // 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;
@@ -363,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) {
@@ -375,7 +389,9 @@ 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;
+ // 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;
@@ -432,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/drawentity.cpp b/src/drawentity.cpp
index d6797661..b8e3cbd5 100644
--- a/src/drawentity.cpp
+++ b/src/drawentity.cpp
@@ -64,13 +64,13 @@ 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]);
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");
@@ -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();
@@ -468,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;
@@ -484,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);
@@ -608,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/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/export.cpp b/src/export.cpp
index e0c6182c..970552c6 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.
@@ -1006,15 +956,20 @@ void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const Platform::Path &filename
SPointList spl = {};
STriangle *tr;
Vector bndl, bndh;
+
+ const std::string THREE_FN("three-r111.min.js");
+ const std::string HAMMER_FN("hammer-2.0.8.js");
+ const std::string CONTROLS_FN("SolveSpaceControls.js");
+
const char htmlbegin[] = R"(
Three.js Solvespace Mesh
-
-
-
+
+
+
@@ -1064,9 +1019,12 @@ void SolveSpaceUI::ExportMeshAsThreeJsTo(FILE *f, const Platform::Path &filename
if(filename.HasExtension("html")) {
fprintf(f, htmlbegin,
- LoadStringFromGzip("threejs/three-r76.js.gz").c_str(),
- LoadStringFromGzip("threejs/hammer-2.0.8.js.gz").c_str(),
- LoadString("threejs/SolveSpaceControls.js").c_str());
+ THREE_FN.c_str(),
+ LoadStringFromGzip("threejs/" + THREE_FN + ".gz").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"
diff --git a/src/exportstep.cpp b/src/exportstep.cpp
index d5c9d406..db42dc08 100644
--- a/src/exportstep.cpp
+++ b/src/exportstep.cpp
@@ -273,9 +273,45 @@ 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());
+
+/* // 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());
+ ++id;
+ fprintf(f, "#%d=SURFACE_STYLE_RENDERING_WITH_PROPERTIES(.NORMAL_SHADING.,#%d,(#%d));\n",
+ 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.
+ ++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());
+ ++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);
+
+ ++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++;
listOfLoops.Clear();
}
diff --git a/src/file.cpp b/src/file.cpp
index acb931f0..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."));
@@ -904,11 +912,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 +995,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/graphicswin.cpp b/src/graphicswin.cpp
index 5aed9663..32b4b082 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_("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 },
@@ -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());
@@ -1175,10 +1186,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;
}
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/importidf.cpp b/src/importidf.cpp
index c1e2e331..1789e5cc 100644
--- a/src/importidf.cpp
+++ b/src/importidf.cpp
@@ -236,21 +236,18 @@ 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;
- dtheta = 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);
- dtheta = thetab - thetaa;
+ theta = atan2(pa2.y, pa2.x);
}
+ dtheta = angle * PI/180;
+
int i, n;
if(dtheta > (3*PI/2 + 0.01)) {
n = 4;
@@ -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;
diff --git a/src/mouse.cpp b/src/mouse.cpp
index 7f90a8a3..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:
@@ -624,24 +623,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 +713,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 +747,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 +784,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();
@@ -877,7 +876,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 +916,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:
@@ -1117,7 +1115,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);
@@ -1472,18 +1470,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/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++;
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/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/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..1f0cc55d 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) {
@@ -1246,6 +1246,10 @@ public:
gtkChooser->set_filename(path.raw);
}
+ void SuggestFilename(Platform::Path path) override {
+ gtkChooser->set_current_name(path.FileStem()+"."+GetExtension());
+ }
+
void AddFilter(std::string name, std::vector extensions) override {
Glib::RefPtr gtkFilter = Gtk::FileFilter::create();
Glib::ustring desc;
@@ -1291,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 {
diff --git a/src/platform/guimac.mm b/src/platform/guimac.mm
index 0f0997c4..b2b07a8b 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
@@ -553,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);
@@ -974,9 +977,6 @@ public:
if(GetScrollbarPosition() == pos)
return;
[nsScroller setDoubleValue:(pos / (ssView.scrollerMax - ssView.scrollerMin))];
- if(onScrollbarAdjusted) {
- onScrollbarAdjusted(pos);
- }
}
void Invalidate() override {
@@ -1273,6 +1273,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 43e7a59a..d8851958 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);
}
@@ -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;
}
@@ -907,8 +912,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,8 +922,15 @@ 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;
+ event.scrollDelta = GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA;
break;
case WM_MOUSELEAVE:
@@ -1094,12 +1106,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 {
@@ -1267,7 +1279,7 @@ public:
bool IsEditorVisible() override {
BOOL visible;
- sscheck(visible = IsWindowVisible(hEditor));
+ visible = IsWindowVisible(hEditor);
return visible == TRUE;
}
@@ -1309,7 +1321,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()));
@@ -1320,7 +1332,7 @@ public:
void HideEditor() override {
if(!IsEditorVisible()) return;
- sscheck(ShowWindow(hEditor, SW_HIDE));
+ ShowWindow(hEditor, SW_HIDE);
}
void SetScrollbarVisible(bool visible) override {
@@ -1335,7 +1347,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 {
@@ -1359,7 +1371,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) {
@@ -1443,7 +1455,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:
@@ -1455,7 +1470,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;
}
}
@@ -1575,6 +1593,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/platform/platform.cpp b/src/platform/platform.cpp
index a0809821..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;
}
@@ -401,7 +403,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
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 {
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/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 {
diff --git a/src/solvespace.cpp b/src/solvespace.cpp
index d68cedf2..4e458cf4 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
@@ -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) {
@@ -341,13 +347,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 +395,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));
@@ -601,6 +633,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());
@@ -612,6 +645,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");
@@ -635,6 +669,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");
@@ -646,6 +681,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");
@@ -657,6 +693,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");
@@ -668,6 +705,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");
@@ -878,9 +916,13 @@ 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");
+ dialog->SetFilename(SS.saveFile);
if(dialog->RunModal()) {
dialog->FreezeChoices(settings, "Trace");
@@ -965,7 +1007,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, 2021);
break;
default: ssassert(false, "Unexpected menu ID");
@@ -982,6 +1024,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/solvespace.h b/src/solvespace.h
index 1157723a..e64a1ab8 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;
@@ -530,7 +530,7 @@ public:
style.Clear();
}
} UndoState;
- enum { MAX_UNDO = 16 };
+ enum { MAX_UNDO = 100 };
typedef struct {
UndoState d[MAX_UNDO];
int cnt;
@@ -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);
diff --git a/src/srf/boolean.cpp b/src/srf/boolean.cpp
index b0b175da..1edf46ed 100644
--- a/src/srf/boolean.cpp
+++ b/src/srf/boolean.cpp
@@ -20,6 +20,50 @@ void SShell::MakeFromIntersectionOf(SShell *a, SShell *b) {
MakeFromBoolean(a, b, SSurface::CombineAs::INTERSECTION);
}
+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;
+ 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 +79,21 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
ret = *this;
ret.pts = {};
+ // First find any vertex that lies on our curve.
+ List vertpts = {};
+ 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;
ret.pts.Add(p);
p = pts.NextAfter(p);
-
+
for(; p; p = pts.NextAfter(p)) {
List il = {};
@@ -100,12 +153,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,20 +196,24 @@ SCurve SCurve::MakeCopySplitAgainst(SShell *agnstA, SShell *agnstB,
ret.pts.Add(p);
prev = *p;
}
+ vertpts.Clear();
return ret;
}
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;
+ }
}
}
diff --git a/src/srf/ratpoly.cpp b/src/srf/ratpoly.cpp
index 8e43367d..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];
}
@@ -332,7 +328,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 +360,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.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));
diff --git a/src/srf/surface.h b/src/srf/surface.h
index ba4414a2..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,
@@ -335,13 +336,14 @@ 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;
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..0a827761 100644
--- a/src/srf/surfinter.cpp
+++ b/src/srf/surfinter.cpp
@@ -313,6 +313,45 @@ 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;
+ }
+ bool foundExact = false;
+ 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);
+ 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.
// First, we find all the intersections between a surface and the
// boundary of the other surface.
@@ -505,6 +544,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
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());
diff --git a/src/textwin.cpp b/src/textwin.cpp
index 131e12e9..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) {
- window->SetScrollbarPosition(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;
};
@@ -338,11 +348,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);
@@ -1130,16 +1151,16 @@ 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;
}
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);
window->Invalidate();
}
}
diff --git a/src/toolbar.cpp b/src/toolbar.cpp
index 4d0b8839..bf6b59c5 100644
--- a/src/toolbar.cpp
+++ b/src/toolbar.cpp
@@ -68,6 +68,10 @@ static ToolIcon Toolbar[] = {
N_("New group extruding active sketch"), {} },
{ "lathe", Command::GROUP_LATHE,
N_("New group rotating active sketch"), {} },
+ { "helix", Command::GROUP_HELIX,
+ N_("New group helix from active sketch"), {} },
+ { "revolve", Command::GROUP_REVOLVE,
+ N_("New group revolve active sketch"), {} },
{ "step-rotate", Command::GROUP_ROT,
N_("New group step and repeat rotating"), {} },
{ "step-translate", Command::GROUP_TRANS,
@@ -153,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 = 34*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 =
diff --git a/src/ui.h b/src/ui.h
index b44d566b..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,
@@ -179,7 +180,7 @@ public:
enum {
MAX_COLS = 100,
MIN_COLS = 45,
- MAX_ROWS = 2000
+ MAX_ROWS = 4000
};
typedef struct {
@@ -532,6 +533,7 @@ public:
Platform::MenuRef linkRecentMenu;
Platform::MenuItemRef showGridMenuItem;
+ Platform::MenuItemRef dimSolidModelMenuItem;
Platform::MenuItemRef perspectiveProjMenuItem;
Platform::MenuItemRef showToolbarMenuItem;
Platform::MenuItemRef showTextWndMenuItem;
@@ -727,6 +729,7 @@ public:
public:
int zIndex;
double distance;
+ double depth;
Selection selection;
};
@@ -802,6 +805,7 @@ public:
DrawOccludedAs drawOccludedAs;
bool showSnapGrid;
+ bool dimSolidModel;
void DrawSnapGrid(Canvas *canvas);
void AddPointToDraggedList(hEntity hp);
@@ -824,7 +828,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);
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) ||
diff --git a/test/analysis/contour_area/normal.png b/test/analysis/contour_area/normal.png
index 486fcdc4..3b50df9c 100644
Binary files a/test/analysis/contour_area/normal.png and b/test/analysis/contour_area/normal.png differ
diff --git a/test/constraint/angle/skew.png b/test/constraint/angle/skew.png
index 97fb0dbf..92d7577a 100644
Binary files a/test/constraint/angle/skew.png and b/test/constraint/angle/skew.png differ
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");
}