├── .appveyor.yml ├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── docs ├── Makefile ├── building.rst ├── conf.py ├── images │ ├── os_faults_grid_rotate.png │ ├── os_faults_lines.png │ ├── os_file.png │ ├── os_file_import_plane.png │ ├── os_import.png │ ├── os_import_tocher.png │ ├── os_mainwindow.png │ ├── os_settings.png │ ├── os_settings_project.png │ ├── os_tocher_context.png │ ├── os_tocher_contours_k50.png │ ├── os_tocher_drag.png │ ├── os_tocher_faults_qplot.png │ ├── os_tocher_faults_qplot_reorder.png │ ├── os_tocher_full.png │ ├── os_tocher_poles.png │ ├── os_tocher_poles_changed.png │ ├── os_tocher_props_contours.png │ ├── os_tocher_props_projection.png │ └── winxp_shortcut.png ├── index.rst ├── install.rst ├── make.bat ├── reference.rst ├── support.rst └── tutorial.rst ├── example_data ├── example_project.openstereo ├── example_single_data.openstereo ├── lineaments.txt ├── normal_faults.txt ├── normal_faults.xlsx ├── qplot.txt ├── rand_15k.txt ├── rand_50k.txt ├── small.txt ├── small2.txt ├── tocher.txt └── tocher_header.txt ├── extra_wheels ├── networkx-2.1-py2.py3-none-any.whl └── pyshp-1.2.12-py2.py3-none-any.whl ├── fault.openstereo ├── install_osx.sh ├── openstereo ├── __init__.py ├── __main__.py ├── data_models.py ├── io.py ├── ndtri_back.py ├── os_auttitude.py ├── os_base.py ├── os_math.py ├── os_plot.py ├── plot_data.py ├── projection_models.py ├── tools │ ├── __init__.py │ └── mesh_process.py └── ui │ ├── __init__.py │ ├── circular_properties_ui.py │ ├── clipboard_ui.py │ ├── difference_vectors_ui.py │ ├── fault_data_ui.py │ ├── fault_properties_ui.py │ ├── import_dialog_ui.py │ ├── import_ply_ui.py │ ├── item_table_ui.py │ ├── languages.py │ ├── line_properties_ui.py │ ├── merge_data_ui.py │ ├── openstereo_rc.py │ ├── openstereo_ui.py │ ├── os_settings_ui.py │ ├── plane_properties_ui.py │ ├── rotate_data_ui.py │ ├── singleline_properties_ui.py │ ├── singleplane_properties_ui.py │ ├── singlesmallcircle_properties_ui.py │ ├── slope_properties_ui.py │ ├── smallcircle_properties_ui.py │ └── ui_interface.py ├── os_gui.py ├── os_installer32.cfg ├── os_installer64.cfg ├── requires.txt ├── setup.py ├── test_icon.py └── ui_files ├── circular_properties.ui ├── clipboard.ui ├── difference_vectors.ui ├── fault_data.ui ├── fault_properties.ui ├── i18n ├── openstereo_pt_BR.qm └── openstereo_pt_BR.ts ├── icons ├── openstereo.ico └── openstereo_mac.icns ├── import_dialog.ui ├── import_ply.ui ├── item_table.ui ├── line_properties.ui ├── merge_data.ui ├── openstereo.pro ├── openstereo.qrc ├── openstereo.ui ├── os_settings.ui ├── plane_properties.ui ├── rotate_data.ui ├── singleline_properties.ui ├── singleplane_properties.ui ├── singlesmallcircle_properties.ui ├── slope_properties.ui └── smallcircle_properties.ui /.appveyor.yml: -------------------------------------------------------------------------------- 1 | # modified from mu's config file https://github.com/mu-editor/mu/blob/master/.appveyor.yml 2 | 3 | # only_commits: 4 | # message: /\[build\]/ 5 | 6 | # skip_tags: true 7 | 8 | environment: 9 | matrix: 10 | - PYTHON: "C:\\Python36" 11 | PYTHON_VERSION: "3.6.4" 12 | PYTHON_ARCH: "64" 13 | 14 | platform: x86 15 | 16 | configuration: Release 17 | 18 | init: 19 | - cmd: ver 20 | - cmd: ECHO Processor architecture - %PROCESSOR_ARCHITECTURE% 21 | - cmd: wmic OS get OSArchitecture 22 | 23 | # As AppVeyor has multiple python install, check which one uses by default 24 | - cmd: ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH% 25 | - cmd: python --version 26 | - cmd: python -c "import struct; print(struct.calcsize('P') * 8)" 27 | - cmd: python -c "import sys; print(sys.executable)" 28 | 29 | # Set the relevant Python and pip location to the path 30 | - cmd: set PATH=%PYTHON%;%PYTHON%\scripts;%PATH% 31 | - cmd: ECHO Path - %PATH% 32 | 33 | # Verify the new default python 34 | - cmd: python --version 35 | - cmd: python -c "import struct; print(struct.calcsize('P') * 8)" 36 | - cmd: python -c "import sys; print(sys.executable)" 37 | - cmd: pip --version 38 | 39 | # Check out installed python packages 40 | - cmd: pip freeze 41 | 42 | install: 43 | #install OpenStereo dependencies 44 | - cmd: pip install -r requires.txt 45 | 46 | # Check installed packages 47 | - cmd: pip freeze 48 | - cmd: python -c "import PyQt5" 49 | 50 | # Build os using pynsist, rename dist folder and executable with timestamp 51 | # 64bit 52 | - cmd: pynsist os_installer64.cfg 53 | - ps: Rename-Item -path .\build upload64 54 | - cmd: dir upload64\nsis 55 | - ps: Rename-Item .\upload64\nsis\OpenStereo_0.9.exe OpenStereo_$(get-date -f yyyy-MM-dd_HH_mm)_$($env:APPVEYOR_REPO_BRANCH)_$($env:APPVEYOR_REPO_COMMIT.subString(0,7))_64bit.exe 56 | 57 | # Build os using pynsist, rename dist folder and executable with timestamp 58 | # 32bit 59 | - cmd: pynsist os_installer32.cfg 60 | - ps: Rename-Item -path .\build upload32 61 | - cmd: dir upload32\nsis 62 | - ps: Rename-Item .\upload32\nsis\OpenStereo_0.9.exe OpenStereo_$(get-date -f yyyy-MM-dd_HH_mm)_$($env:APPVEYOR_REPO_BRANCH)_$($env:APPVEYOR_REPO_COMMIT.subString(0,7))_32bit.exe 63 | 64 | # Build portable os using pyinstaller, rename dist folder and executable with timestamp 65 | # 32bit 66 | - cmd: pip install pyinstaller 67 | - cmd: pyinstaller -F -w -i .\ui_files\icons\openstereo.ico os_gui.py 68 | - ps: Rename-Item -path .\dist upload32p 69 | - cmd: dir upload32p 70 | - ps: Rename-Item .\upload32p\os_gui.exe OpenStereo_Portable_$(get-date -f yyyy-MM-dd_HH_mm)_32bit.exe 71 | 72 | 73 | # Not a project with an msbuild file, build done at install. 74 | build: None 75 | 76 | before_deploy: 77 | - ps: Get-ChildItem .\upload64\nsis\*.exe | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name -DeploymentName os-github-deployment } 78 | - ps: Get-ChildItem .\upload32\nsis\*.exe | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name -DeploymentName os-github-deployment } 79 | - ps: Get-ChildItem .\upload32p\*.exe | % { Push-AppveyorArtifact $_.FullName -FileName $_.Name -DeploymentName os-github-deployment } 80 | - ps: foreach($artifactName in $artifacts.keys) { $artifacts[$artifactName] } 81 | 82 | deploy: 83 | release: $(APPVEYOR_REPO_TAG_NAME) 84 | description: 'OpenStereo automatic build' 85 | provider: GitHub 86 | auth_token: 87 | secure: LBCuN9a41G36WT4b7Tab1UbTE8mji69Jup2hxpGDtdH/JarKQxpCrGadlPclRtqi 88 | draft: false 89 | prerelease: false 90 | on: 91 | # branch: master # release from master branch only 92 | APPVEYOR_REPO_TAG: true 93 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | 27 | # PyInstaller 28 | # Usually these files are written by a python script from a template 29 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 30 | *.manifest 31 | *.spec 32 | 33 | # Installer logs 34 | pip-log.txt 35 | pip-delete-this-directory.txt 36 | 37 | # Unit test / coverage reports 38 | htmlcov/ 39 | .tox/ 40 | .coverage 41 | .coverage.* 42 | .cache 43 | nosetests.xml 44 | coverage.xml 45 | *,cover 46 | .hypothesis/ 47 | 48 | # Translations 49 | *.mo 50 | *.pot 51 | 52 | # Django stuff: 53 | *.log 54 | local_settings.py 55 | 56 | # Flask stuff: 57 | instance/ 58 | .webassets-cache 59 | 60 | # Scrapy stuff: 61 | .scrapy 62 | 63 | # Sphinx documentation 64 | docs/_build/ 65 | 66 | # PyBuilder 67 | target/ 68 | 69 | # IPython Notebook 70 | .ipynb_checkpoints 71 | 72 | # pyenv 73 | .python-version 74 | 75 | # celery beat schedule file 76 | celerybeat-schedule 77 | 78 | # dotenv 79 | .env 80 | 81 | # virtualenv 82 | venv/ 83 | ENV/ 84 | 85 | # Spyder project settings 86 | .spyderproject 87 | 88 | # Rope project settings 89 | .ropeproject 90 | 91 | # vscode 92 | .vscode/ 93 | 94 | # mypy 95 | .mypy_cache/ 96 | 97 | # current commit hash 98 | # openstereo/tools/git_hash.py 99 | 100 | # pytest 101 | .pytest_cache/ -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # modified from mu's config file https://github.com/mu-editor/mu/blob/master/.travis.yml 2 | matrix: 3 | include: 4 | - os: osx 5 | osx_image: xcode8.3 6 | sudo: required 7 | language: generic 8 | python: 3.6 9 | before_install: 10 | - uname -a 11 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then sw_vers; fi 12 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then bash install_osx.sh; fi 13 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then pyenv install 3.6.5; fi 14 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then pyenv versions; fi 15 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then pyenv global 3.6.5; fi 16 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then eval "$(pyenv init -)"; fi 17 | - pip install --upgrade pip 18 | - echo $PATH 19 | - python --version 20 | - python -c "import struct; print(struct.calcsize('P') * 8)" 21 | - python -c "import sys; print(sys.executable)" 22 | - python -m pip --version 23 | - pip --version 24 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then virtualenv venv --python=python3; fi 25 | - if [ "$TRAVIS_OS_NAME" = "linux" ]; then source venv/bin/activate; fi 26 | install: 27 | - pip install -r requires.txt 28 | - pip install briefcase 29 | - pip install dmgbuild 30 | - pip install pytest-faulthandler 31 | - pip freeze 32 | script: 33 | # - if [ "$TRAVIS_OS_NAME" = "osx" ]; then make check; fi 34 | # - make clean 35 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then python setup.py macos; fi 36 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then mkdir dist; fi 37 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then zip -r -X dist/openstereo.zip macOS/openstereo.app >/dev/null; 38 | fi 39 | # - if [ "$TRAVIS_OS_NAME" = "osx" ]; then du -sk dist/; fi 40 | - if [ "$TRAVIS_OS_NAME" = "osx" ]; then mv dist/openstereo.zip dist/OpenStereo_MacOS_$(date '+%Y-%m-%d_%H_%M').zip; fi 41 | - ls -lh; 42 | 43 | # before_deploy: 44 | # # Set up git user name and tag this commit 45 | # - git config --local user.name "Arthur Endlein" 46 | # - git config --local user.email "endarthur@gmail.com" 47 | # - export TRAVIS_TAG=${TRAVIS_TAG:-$(date +'%Y%m%d%H%M%S')-$(git log --format=%h -1)} 48 | # - git tag $TRAVIS_TAG 49 | 50 | deploy: 51 | provider: releases 52 | api_key: 53 | secure: aOVW70E9RwHSMyJ6zYUAZil8RD0H7zQv2tRyWPKVUPv5mmR1DizjEAYgqVi8qjfYf/GY+RTRUMQolstMddNuCtzyxVnCc8Pg80TMMad3v/syBD8L0fyqmaQIKXnZvlOc98WCfAeyHOtuSvSPKn49NTfkHENwgMElsHNKys7wpoa9R4RraLavO/sq/Wah8+iyVaJ89vdgm9LFUq5RCt6/OOWe5hOiXiJdQ20DzfqyYiwRNb6PLZfHmoO25qnUCTm3JtlHQZrvJzKg9KkkJOLu5ZpX17ERwhDEmOeeqH67MQ6LoQTJGa4rih3dwliANPm4Qf471XGUUpTmqSGFp/EiZz+sogjIjmnXYHzb8ApgbV4pNv/KleVYDC4eMOVcCxOF1Ro8mlzyRbJ8omIjRKPbpab8CIywmR4s+vHrb4lTruoA/r4XFVakCuKDvcY/z4FvpIsF/gnuzXk7LMBRY+C+gJkZY88lfAFsSVvLPlFvnGLaIkQWos8yMXrO/KlElxGVz584kWyqBQUsPQo8KV38Ivwnus8kWNox3k2NaBHoSRemd6jaYiyxdyC+yiDXcigQD2pkPfBECu52Sy9NKAOcSzHj0Tx2wbnW0BRADlbLUiJuQtBDFxE/emo4ObT/PYeeTo9E4t/uM3T5FmSQoTgCWbeR6t3QVz9GRxJgV0lKZBQ= 54 | file: 55 | - dist/OpenStereo_MacOS_$(date '+%Y-%m-%d_%H_%M').zip 56 | skip_cleanup: true 57 | on: 58 | tags: true 59 | repo: spamlab-iee/os 60 | 61 | notifications: 62 | email: 63 | on_success: change 64 | on_failure: change 65 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | OpenStereo 2 | ========== 3 | 4 | [![Build status](https://ci.appveyor.com/api/projects/status/pbjhw57vo0hq4lf9?svg=true)](https://ci.appveyor.com/project/endarthur/os-wv5v5) 5 | [![Documentation Status](https://readthedocs.org/projects/openstereo/badge/?version=latest)](https://openstereo.readthedocs.io/en/latest/?badge=latest) 6 | [![Gitter chat](https://badges.gitter.im/endarthur/os.png)](https://gitter.im/openstereo) 7 | 8 | ------------------------------------------------------------------------ 9 | 10 | OpenStereo is an open source, cross-platform software for structural geology analysis. 11 | 12 | The software is written in Python, a high-level, cross-platform programming language and the GUI is designed with Qt5, which provide a native look on all OS. Numeric operations (like matrix and linear algebra) are performed with the Numpy module and all graphic capabilities are provided by the Matplolib library, including on-screen plotting and graphic exporting to common desktop formats (emf, eps, ps, pdf, png, svg). 13 | 14 | OpenStereo is released under the GNU General Public License v.3. 15 | 16 | Check the documentation here: 17 | 18 | https://openstereo.readthedocs.io/ 19 | 20 | ## Windows Installation 21 | 22 | Download the installer .exe from the latest release: 23 | 24 | https://github.com/spamlab-iee/os/releases/latest 25 | 26 | When updating, please uninstall the previous version before installing the new. 27 | 28 | ## macOS Installation 29 | 30 | Downloader the .app executable from the latest release: 31 | 32 | https://github.com/spamlab-iee/os/releases/latest 33 | 34 | On the first time executing a new download of OpenStereo, right click the .app file 35 | select `Open` from the context menu and click open on the window that will appear. 36 | 37 | Alternativelly, you can install OpenStereo from source by first installing pyqt5 38 | (python3 will be installed as well for this) using [homebrew](https://brew.sh/): 39 | 40 | ```bash 41 | $ brew install pyqt 42 | ``` 43 | 44 | Once that is done, install OpenStereo from this repository using pip3: 45 | 46 | ```bash 47 | $ pip3 install https://github.com/spamlab-iee/os/tarball/master#egg=openstereo 48 | ``` 49 | 50 | ## Linux Installation 51 | 52 | ### Ubuntu 53 | 54 | First install pyqt5 and pip: 55 | 56 | ```bash 57 | $ sudo apt install python3-pyqt5 python3-pip 58 | ``` 59 | 60 | Once that is done, install OpenStereo from this repository using pip3: 61 | 62 | ```bash 63 | $ pip3 install https://github.com/spamlab-iee/os/tarball/master#egg=openstereo 64 | ``` 65 | 66 | ### Mint Cinnamon 67 | 68 | First install pyqt5, pip and setuptools from the distribution repository: 69 | 70 | ```bash 71 | $ sudo apt install python3-pyqt5 python3-pip python3-setuptools 72 | ``` 73 | 74 | Then install wheel using pip: 75 | 76 | ```bash 77 | $ pip3 install wheel 78 | ``` 79 | 80 | Once that is done, install OpenStereo from this repository using pip3: 81 | 82 | ```bash 83 | $ pip3 install https://github.com/spamlab-iee/os/tarball/master#egg=openstereo 84 | ``` 85 | 86 | ### Fedora 87 | 88 | First install pyqt5: 89 | 90 | ```bash 91 | $ sudo yum install python3-qt5 92 | 93 | Once that is done, install OpenStereo from this repository using pip3: 94 | 95 | ```bash 96 | $ sudo pip3 install https://github.com/spamlab-iee/os/tarball/master#egg=openstereo 97 | ``` 98 | 99 | ### openSUSE 100 | 101 | First install pyqt5: 102 | 103 | ```bash 104 | $ sudo zypper install python3-qt5 105 | 106 | Once that is done, install OpenStereo from this repository using pip3: 107 | 108 | ```bash 109 | $ sudo pip3 install https://github.com/spamlab-iee/os/tarball/master#egg=openstereo 110 | ``` 111 | 112 | 113 | ## Installation from Source 114 | 115 | You can install this version of openstereo using: 116 | 117 | ```bash 118 | $ pip install https://github.com/spamlab-iee/os/tarball/master#egg=openstereo 119 | ``` 120 | 121 | Additionally, install PyQt5 from PyPI (for python 2.7, use package python-qt5 instead). 122 | 123 | Then run with 124 | 125 | ```bash 126 | $ openstereo 127 | ``` 128 | 129 | or 130 | 131 | ```bash 132 | $ python -m openstereo 133 | ``` 134 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | SPHINXPROJ = OpenStereo 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/building.rst: -------------------------------------------------------------------------------- 1 | Building OpenStereo 2 | =================== -------------------------------------------------------------------------------- /docs/conf.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # 4 | # OpenStereo documentation build configuration file, created by 5 | # sphinx-quickstart on Wed Aug 29 19:29:02 2018. 6 | # 7 | # This file is execfile()d with the current directory set to its 8 | # containing dir. 9 | # 10 | # Note that not all possible configuration values are present in this 11 | # autogenerated file. 12 | # 13 | # All configuration values have a default; values that are commented out 14 | # serve to show the default. 15 | 16 | # If extensions (or modules to document with autodoc) are in another directory, 17 | # add these directories to sys.path here. If the directory is relative to the 18 | # documentation root, use os.path.abspath to make it absolute, like shown here. 19 | # 20 | # import os 21 | # import sys 22 | # sys.path.insert(0, os.path.abspath('.')) 23 | 24 | 25 | # -- General configuration ------------------------------------------------ 26 | 27 | # If your documentation needs a minimal Sphinx version, state it here. 28 | # 29 | # needs_sphinx = '1.0' 30 | 31 | # Add any Sphinx extension module names here, as strings. They can be 32 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom 33 | # ones. 34 | extensions = ['sphinx.ext.autodoc', 35 | 'sphinx.ext.todo', 36 | 'sphinx.ext.mathjax', 37 | 'sphinx.ext.viewcode'] 38 | 39 | # Add any paths that contain templates here, relative to this directory. 40 | templates_path = ['_templates'] 41 | 42 | # The suffix(es) of source filenames. 43 | # You can specify multiple suffix as a list of string: 44 | # 45 | # source_suffix = ['.rst', '.md'] 46 | source_suffix = '.rst' 47 | 48 | # The master toctree document. 49 | master_doc = 'index' 50 | 51 | # General information about the project. 52 | project = 'OpenStereo' 53 | copyright = '2018' 54 | author = '' 55 | 56 | # The version info for the project you're documenting, acts as replacement for 57 | # |version| and |release|, also used in various other places throughout the 58 | # built documents. 59 | # 60 | # The short X.Y version. 61 | version = '0.9' 62 | # The full version, including alpha/beta/rc tags. 63 | release = '0.9.0' 64 | 65 | # The language for content autogenerated by Sphinx. Refer to documentation 66 | # for a list of supported languages. 67 | # 68 | # This is also used if you do content translation via gettext catalogs. 69 | # Usually you set "language" from the command line for these cases. 70 | language = None 71 | 72 | # List of patterns, relative to source directory, that match files and 73 | # directories to ignore when looking for source files. 74 | # This patterns also effect to html_static_path and html_extra_path 75 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] 76 | 77 | # The name of the Pygments (syntax highlighting) style to use. 78 | pygments_style = 'sphinx' 79 | 80 | # If true, `todo` and `todoList` produce output, else they produce nothing. 81 | todo_include_todos = True 82 | 83 | 84 | # -- Options for HTML output ---------------------------------------------- 85 | 86 | # The theme to use for HTML and HTML Help pages. See the documentation for 87 | # a list of builtin themes. 88 | # 89 | html_theme = 'sphinx_rtd_theme' 90 | 91 | # Theme options are theme-specific and customize the look and feel of a theme 92 | # further. For a list of options available for each theme, see the 93 | # documentation. 94 | # 95 | # html_theme_options = {} 96 | 97 | # Add any paths that contain custom static files (such as style sheets) here, 98 | # relative to this directory. They are copied after the builtin static files, 99 | # so a file named "default.css" will overwrite the builtin "default.css". 100 | html_static_path = ['_static'] 101 | 102 | 103 | # -- Options for HTMLHelp output ------------------------------------------ 104 | 105 | # Output file base name for HTML help builder. 106 | htmlhelp_basename = 'OpenStereodoc' 107 | 108 | 109 | # -- Options for LaTeX output --------------------------------------------- 110 | 111 | latex_elements = { 112 | # The paper size ('letterpaper' or 'a4paper'). 113 | # 114 | # 'papersize': 'letterpaper', 115 | 116 | # The font size ('10pt', '11pt' or '12pt'). 117 | # 118 | # 'pointsize': '10pt', 119 | 120 | # Additional stuff for the LaTeX preamble. 121 | # 122 | # 'preamble': '', 123 | 124 | # Latex figure (float) alignment 125 | # 126 | # 'figure_align': 'htbp', 127 | } 128 | 129 | # Grouping the document tree into LaTeX files. List of tuples 130 | # (source start file, target name, title, 131 | # author, documentclass [howto, manual, or own class]). 132 | latex_documents = [ 133 | (master_doc, 'OpenStereo.tex', 'OpenStereo Documentation', 134 | '', 'manual'), 135 | ] 136 | 137 | 138 | # -- Options for manual page output --------------------------------------- 139 | 140 | # One entry per manual page. List of tuples 141 | # (source start file, name, description, authors, manual section). 142 | man_pages = [ 143 | (master_doc, 'openstereo', 'OpenStereo Documentation', 144 | [author], 1) 145 | ] 146 | 147 | 148 | # -- Options for Texinfo output ------------------------------------------- 149 | 150 | # Grouping the document tree into Texinfo files. List of tuples 151 | # (source start file, target name, title, author, 152 | # dir menu entry, description, category) 153 | texinfo_documents = [ 154 | (master_doc, 'OpenStereo', 'OpenStereo Documentation', 155 | author, 'OpenStereo', 'One line description of project.', 156 | 'Miscellaneous'), 157 | ] 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /docs/images/os_faults_grid_rotate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_faults_grid_rotate.png -------------------------------------------------------------------------------- /docs/images/os_faults_lines.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_faults_lines.png -------------------------------------------------------------------------------- /docs/images/os_file.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_file.png -------------------------------------------------------------------------------- /docs/images/os_file_import_plane.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_file_import_plane.png -------------------------------------------------------------------------------- /docs/images/os_import.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_import.png -------------------------------------------------------------------------------- /docs/images/os_import_tocher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_import_tocher.png -------------------------------------------------------------------------------- /docs/images/os_mainwindow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_mainwindow.png -------------------------------------------------------------------------------- /docs/images/os_settings.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_settings.png -------------------------------------------------------------------------------- /docs/images/os_settings_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_settings_project.png -------------------------------------------------------------------------------- /docs/images/os_tocher_context.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_context.png -------------------------------------------------------------------------------- /docs/images/os_tocher_contours_k50.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_contours_k50.png -------------------------------------------------------------------------------- /docs/images/os_tocher_drag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_drag.png -------------------------------------------------------------------------------- /docs/images/os_tocher_faults_qplot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_faults_qplot.png -------------------------------------------------------------------------------- /docs/images/os_tocher_faults_qplot_reorder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_faults_qplot_reorder.png -------------------------------------------------------------------------------- /docs/images/os_tocher_full.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_full.png -------------------------------------------------------------------------------- /docs/images/os_tocher_poles.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_poles.png -------------------------------------------------------------------------------- /docs/images/os_tocher_poles_changed.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_poles_changed.png -------------------------------------------------------------------------------- /docs/images/os_tocher_props_contours.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_props_contours.png -------------------------------------------------------------------------------- /docs/images/os_tocher_props_projection.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/os_tocher_props_projection.png -------------------------------------------------------------------------------- /docs/images/winxp_shortcut.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/docs/images/winxp_shortcut.png -------------------------------------------------------------------------------- /docs/index.rst: -------------------------------------------------------------------------------- 1 | .. OpenStereo documentation master file, created by 2 | sphinx-quickstart on Wed Aug 29 19:29:02 2018. 3 | You can adapt this file completely to your liking, but it should at least 4 | contain the root `toctree` directive. 5 | 6 | OpenStereo -- An open source, cross-platform structural geology analysis software 7 | ================================================================================= 8 | 9 | .. toctree:: 10 | :maxdepth: 2 11 | :caption: Getting Started 12 | 13 | install 14 | support 15 | tutorial 16 | 17 | .. toctree:: 18 | :maxdepth: 2 19 | :caption: User Guide 20 | 21 | reference 22 | 23 | .. toctree:: 24 | :maxdepth: 2 25 | :caption: Developer Guide 26 | 27 | building 28 | 29 | 30 | 31 | Indices and tables 32 | ================== 33 | 34 | * :ref:`genindex` 35 | * :ref:`search` 36 | -------------------------------------------------------------------------------- /docs/install.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | 4 | Windows 5 | ------- 6 | 7 | Download the latest .exe installer from: 8 | 9 | https://github.com/endarthur/os/releases/latest 10 | 11 | When updating, please uninstall the previous version before installing the new. 12 | 13 | The releases also contain an experimental portable executable for OpenStereo, 14 | with a name starting with ``OpenStereo_Portable`` followed by the build date. 15 | Please report any issues when using the portable version. 16 | 17 | Windows XP 18 | ~~~~~~~~~~ 19 | 20 | Download and execute `WinPython-32bit-3.4.4.1Qt5.exe`_ from sourceforge. Python 21 | 3.4 is the last python available for Windows XP, and `winpython`_ is a portable 22 | distribution pre-packaged with most of the prerequisites for OpenStereo. Inside 23 | the folder you just extracted, execute the ``WinPython Command Prompt``, and 24 | install OpenStereo using:: 25 | 26 | pip install https://github.com/endarthur/os/tarball/master#egg=openstereo 27 | 28 | .. _WinPython-32bit-3.4.4.1Qt5.exe: https://sourceforge.net/projects/winpython/files/WinPython_3.4/3.4.4.1/WinPython-32bit-3.4.4.1Qt5.exe/download 29 | .. _winpython: http://winpython.github.io/ 30 | 31 | After that, you may either open the ``WinPython Command Prompt`` and run:: 32 | 33 | python -m openstereo 34 | 35 | Or create a shortcut, by right clicking on your desktop, selecting new, 36 | shortcut, browsing to the file ``python-3.4.6\pythonw.exe`` inside the folder 37 | and adding the parameter ``-m openstereo`` after the file, as such: 38 | 39 | .. image:: images/winxp_shortcut.png 40 | 41 | The icon for OpenStereo is located inside the ``ui_files/icons`` directory on 42 | the github repository, or downloaded with 43 | `this link`_. 44 | 45 | .. _this link: https://github.com/endarthur/os/raw/master/ui_files/icons/openstereo.ico 46 | 47 | macOS Installation 48 | ------------------ 49 | 50 | First install pyqt5 and python3 (python3 is automatically installed as a 51 | dependency of pyqt5) using `homebrew`_:: 52 | 53 | $ brew install pyqt 54 | 55 | .. _homebrew: https://brew.sh/ 56 | 57 | Once that is done, install OpenStereo from `github`_ using pip3:: 58 | 59 | $ pip3 install git+https://github.com/endarthur/os#egg=openstereo 60 | 61 | .. _github: https://github.com/endarthur/os 62 | 63 | Ubuntu 64 | ------ 65 | 66 | First install pyqt5 and pip:: 67 | 68 | $ sudo apt install python3-pyqt5 python3-pip 69 | 70 | Once that is done, install OpenStereo from `github`_ using pip3:: 71 | 72 | $ pip3 install https://github.com/endarthur/os/tarball/master#egg=openstereo 73 | 74 | Mint Cinnamon 75 | ------------- 76 | 77 | First install pyqt5, pip and setuptools from the distribution repository:: 78 | 79 | $ sudo apt install python3-pyqt5 python3-pip python3-setuptools 80 | 81 | Then install wheel using pip:: 82 | 83 | $ pip3 install wheel 84 | 85 | Once that is done, install OpenStereo from `github`_ using pip3:: 86 | 87 | $ pip3 install https://github.com/endarthur/os/tarball/master#egg=openstereo 88 | 89 | Fedora 90 | ------ 91 | 92 | First install pyqt5:: 93 | 94 | $ sudo yum install python3-qt5 95 | 96 | Once that is done, install OpenStereo from `github`_ using pip3:: 97 | 98 | $ sudo pip3 install https://github.com/endarthur/os/tarball/master#egg=openstereo 99 | 100 | openSUSE 101 | -------- 102 | 103 | First install pyqt5:: 104 | 105 | $ sudo zypper install python3-qt5 106 | 107 | Once that is done, install OpenStereo from `github`_ using pip3:: 108 | 109 | $ sudo pip3 install https://github.com/endarthur/os/tarball/master#egg=openstereo 110 | 111 | Arch Linux 112 | ---------- 113 | 114 | First install pyqt5 and pip:: 115 | 116 | $ sudo pacman -S python-pyqt5 python-pip 117 | 118 | After that, install openstereo from `github`_ using pip:: 119 | 120 | $ sudo pip3 install https://github.com/endarthur/os/tarball/master#egg=openstereo 121 | 122 | Installing pyqt5 from pip also works, in case there is any issue installing 123 | with pacman. 124 | 125 | Other Linux distros 126 | ------------------- 127 | 128 | In general, install pyqt5 for python3, either from the distro repositories or 129 | PyPI. PyQT5 is not listed as a requirement on OpenStereo's setup file, as its 130 | installation may fail in some cases, though the other requirements can usually 131 | be installed automatically without any issues. 132 | 133 | After installing pyqt5, install openstereo using pip3 (to force it to use 134 | python3):: 135 | 136 | $ pip3 install https://github.com/endarthur/os/tarball/master#egg=openstereo 137 | 138 | You may either have to run this command with sudo or by adding the ``--user`` 139 | flag to pip3. In case you use the flag, you'll have to run OpenStereo using:: 140 | 141 | $ python3 -m openstereo 142 | 143 | Instead of just ``openstereo``, though you can add this as an alias to your 144 | .bash_aliases file. 145 | 146 | From PyPI 147 | --------- 148 | 149 | At the command line:: 150 | 151 | pip install https://github.com/endarthur/os/tarball/master#egg=openstereo 152 | 153 | Additionally, install PyQt5 from PyPI if needed (for python 2.7, use package 154 | python-qt5 instead). 155 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=sphinx-build 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=OpenStereo 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 20 | echo.installed, then set the SPHINXBUILD environment variable to point 21 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 22 | echo.may add the Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /docs/reference.rst: -------------------------------------------------------------------------------- 1 | OpenStereo Reference 2 | ==================== 3 | 4 | .. _project-files: 5 | 6 | Project Files 7 | ------------- 8 | 9 | Project files in OpenStereo have the extension ``.openstereo``, and are 10 | zip files containing json files and (in case of a packed project) data 11 | files. 12 | 13 | .. _legend: 14 | 15 | Legend 16 | ------ 17 | 18 | When specifying the legend of a plot item it is possible to get parameters 19 | of your data automatically using the :pep:`3101` format strings specification. 20 | The auttitude container object of the dataset is passed as ``data``, and any 21 | of its parameters can be recalled using this. 22 | 23 | .. 24 | This table summarizes the available information: 25 | 26 | 27 | References 28 | ---------- 29 | 30 | .. [RJ86] Robin, P. Y. F., & Jowett, E. C. (1986). Computerized density contouring and statistical evaluation of orientation data using counting circles and continuous weighting functions. *Tectonophysics*, 121(2-4), 207-223. 31 | 32 | .. [DF85] Diggle, P. J., & Fisher, N. I. (1985). Sphere: a contouring program for spherical data. *Computers & Geosciences*, 11(6), 725-766. -------------------------------------------------------------------------------- /docs/support.rst: -------------------------------------------------------------------------------- 1 | Support 2 | ======= 3 | 4 | Open an issue on github: 5 | 6 | Github: https://github.com/endarthur/os/issues 7 | 8 | In case of an error, copy the output from the error popup on the issue, and 9 | best describe how it happened. If possible, attach any files needed to 10 | replicate the error. There is also a direct link inside openstereo to the 11 | github issues page, on the ``open issue`` option inside the ``help`` menu. 12 | 13 | You may also contact the author directly by email: 14 | 15 | endarthur@gmail.com -------------------------------------------------------------------------------- /docs/tutorial.rst: -------------------------------------------------------------------------------- 1 | An OpenStereo Tutorial 2 | ====================== 3 | 4 | First, install OpenStereo by following the instructions on the 5 | :doc:`installation page ` for your operating system. Make sure to 6 | update whenever a new release is available. 7 | 8 | After installing, open the program either from your start menu or from command 9 | line as either:: 10 | 11 | python -m openstereo 12 | 13 | Or:: 14 | 15 | openstereo 16 | 17 | Optionally, an ``.openstereo`` :ref:`project file ` can be opened:: 18 | 19 | openstereo example_project.openstereo 20 | 21 | From that, you are brought to the main window: 22 | 23 | .. image:: images/os_mainwindow.png 24 | 25 | From the File menu you can open or save projects and import files. The quickest 26 | way to open a simple data file is using the specific import actions. for 27 | example, ``Import Plane Data (DD)``: 28 | 29 | .. image:: images/os_file_import_plane.png 30 | 31 | OpenStereo supports both CSV files and excel spreadsheets. Download 32 | ``tocher_header.txt`` from the `example data`_ directory inside the 33 | repository and select it after clicking this option. After loading, either 34 | click ``Plot`` or press ``Ctrl+P`` on your keyboard to view the poles of this 35 | example: 36 | 37 | .. _example data: https://minhaskamal.github.io/DownGit/#/home?url=https://github.com/endarthur/os/tree/master/example_data 38 | 39 | 40 | .. image:: images/os_tocher_poles.png 41 | 42 | The Projection plot is interactive. The attitude of the point under the mouse 43 | will appear on the lower right corner when you mouse over the plot. Also, if 44 | you click and drag over the plot you'll be able to both measure angles 45 | and see the attitude of the plane formed by the point you first clicked and the 46 | current point: 47 | 48 | .. image:: images/os_tocher_drag.png 49 | 50 | It is also possible to plot the great circles, eigenvectors and contours of 51 | a planar dataset. Click on the check boxes of these options under the 52 | ``(P)tocher_header.txt`` item on the data tree and press plot to get a very 53 | busy view of the data: 54 | 55 | .. image:: images/os_tocher_full.png 56 | 57 | Disable the Great Circles option for now and right click on the Tocher item (or 58 | over any of its options) to get its context menu: 59 | 60 | .. image:: images/os_tocher_context.png 61 | 62 | You can rename, delete, reorder, reload and change the display properties of 63 | the item using this menu. Click on ``Properties`` to do so: 64 | 65 | .. image:: images/os_tocher_props_projection.png 66 | :align: center 67 | 68 | Most plot options for the Projection plot tab on the main window are located on 69 | this first tab, with the exception of contour plots. Try changing some options, 70 | such as color and size of poles (on the top left), while disabling poles and 71 | great circles of the first and second eigenvectors, and change the color of the 72 | pole and great circle of the third eigenvector. If you click ``OK`` the changes 73 | will be accepted and the dialog will close, but if you click ``Apply`` instead, 74 | the dialog will remain open. 75 | 76 | 77 | You can keep the dialog open and still interact with OpenStereo, even while 78 | opening the properties dialog of multiple items. Press apply and see the 79 | changes on the plot: 80 | 81 | .. image:: images/os_tocher_poles_changed.png 82 | 83 | On the Contours tab of the properties dialog you may change the many different 84 | related options: 85 | 86 | .. image:: images/os_tocher_props_contours.png 87 | :align: center 88 | 89 | Try a few different graphic options for the contours, as changing the fill 90 | contours gradient to something like ``Greens_r``. You may also change the 91 | number of contours and the way they are built. In the right side, it is 92 | possible to configure which method will be used for the contouring, 93 | either as a count of the number of poles inside a small circle around each node 94 | or by exponentially smoothing each point to every node using the Fisher 95 | distribution. 96 | 97 | The parameter K controls how smooth the contribution of each point will be. 98 | Smaller values of K will smooth more, while larger ones will make each point 99 | contribute only to a small area around it. 100 | 101 | In general you'll have to try a few different options for your dataset to find 102 | the best smoothing coefficient. To help with that, OpenStereo includes two 103 | published methods to estimate good parameters. Robin & Jowett (1986) 104 | [RJ86]_ is very quick, as it calculates the recommended K based 105 | only on the number of poles, 106 | while Diggle & Fisher (1985) [DF85]_ performs an optimization using cross validation 107 | to find which parameter best represents your data. Change the K parameter to 108 | 50 and plot the results: 109 | 110 | .. image:: images/os_tocher_contours_k50.png 111 | 112 | Skip to the ``General`` tab on the properties dialog. Here you may change which 113 | of the plot items will be added to the projection legend, and if desired, 114 | specify a legend text for each plot item instead of the default by writing 115 | on the text box besides each option. 116 | 117 | It is possible to use parameters from your dataset on the legend text. Check 118 | the :ref:`legend reference ` for how to use this feature. Specify the 119 | Pole legend for the third eigenvector as ``pole to the fitted girdle``, and its 120 | great circle legend as:: 121 | 122 | fitted girdle ({data.eigenvectors_sphere[0]}) 123 | 124 | You can also open multiple data files of the same type. Download both 125 | ``normal_faults.xlsx`` and ``qplot.txt`` from the example data and open them 126 | using the import plane data (DD) action. Disable the Tocher item and plot the new 127 | data: 128 | 129 | .. image:: images/os_tocher_faults_qplot.png 130 | 131 | The normal_faults file contains both the orientation of a plane and a line on 132 | each row. As the data set contains no headers, it has no way of detecting which 133 | columns contain the attitude for the lines and the planes, so you must provide 134 | this information. 135 | 136 | The most generic way of opening a data set in OpenStereo is using the 137 | ``Import...`` action on the file menu. After clicking this and selecting the 138 | normal_faults file the following dialog will appear: 139 | 140 | .. image:: images/os_import.png 141 | 142 | Change the data type to Lines, and the trend and plunge to columns 2 and 3, 143 | respectively. Click ``OK`` to load the lines, disable the other items and press 144 | plot to view the results: 145 | 146 | .. image:: images/os_faults_lines.png 147 | 148 | Our project now contains four items, and it's probably time for some better 149 | organization. Right click on any item and select ``Colapse All`` to hide the 150 | plot options. Rename the items by either using ``Rename...`` on the context 151 | menu or pressing F2 on your keyboard after selecting an item. After that, you 152 | may reorder the items by either clicking and dragging or using the move item 153 | actions on the menu. As an example of the results: 154 | 155 | .. image:: images/os_tocher_faults_qplot_reorder.png 156 | 157 | There are also some general configurations for the whole project, which can be 158 | found by either clicking on the ``Settings`` button under the plot or the 159 | ``Project Settings`` action on the settings menu. This dialog will appear: 160 | 161 | .. image:: images/os_settings.png 162 | :align: center 163 | 164 | Click on the ``Plot Grid`` checkbox to add an equal-area net on your plot. You 165 | may also rotate the whole projection by using the rotate grid option. For 166 | example, -30.0, 50.0 and 45.0 as azimuth, plunge and rake, respectively. Click 167 | ``Apply`` to see the results: 168 | 169 | .. image:: images/os_faults_grid_rotate.png 170 | 171 | You can also see and add some metadata to your project on ``Project`` tab on 172 | the settings dialog: 173 | 174 | .. image:: images/os_settings_project.png 175 | :align: center 176 | 177 | There are two types of OpenStereo :ref:`project files `: regular 178 | and packed. They both use the .openstereo extension, and the main difference is 179 | that packed projects include the data files inside them, to facilitate sharing 180 | projects. Packed projects may be unpacked to a directory using the 181 | ``Unpack to...`` button on the project tab of the settings dialog. 182 | 183 | To finish this tutorial, save the resulting project as a regular one (using 184 | either ``Save`` or ``Save as...`` on the file menu). Regular projects store 185 | the relative paths between the .openstereo file and the data files, so you 186 | can transport the whole project to different computers by just keeping the 187 | same directory structure, as when sharing a folder through Dropbox or a similar 188 | service. 189 | 190 | If OpenStereo can't find the data when opening the project, it will ask you for 191 | its location. To make this process easier, for each location of these you 192 | provide the software will try to find the remaining files relative to both the 193 | project file and these given locations. 194 | 195 | .. 196 | In most cases you don't need to use the import dialog directly. Download and 197 | open the ``qplot.txt`` dataset using the ``Import Line Data (Trend)``. 198 | 199 | .. 200 | .. image:: images/os_import.png 201 | :align: center 202 | 203 | If you try to open a CSV file, as is the case, OpenStereo will automatically 204 | try to detect the dialect used, mainly the delimiter. Following that it will 205 | check if your dataset contains a header. In this example, the separator is 206 | comma and it contains a header, as detected. You may change any of these 207 | options if you think they are wrong. 208 | 209 | By default, it will interpret your file as planes, and try to guess from the 210 | header which columns represent dip direction and dip, or take the first and 211 | second columns, respectively. Press ``OK`` to load the data and either click 212 | ``Plot`` or press ``Ctrl+P`` on your keyboard to view the poles of this 213 | example: -------------------------------------------------------------------------------- /example_data/example_project.openstereo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/example_data/example_project.openstereo -------------------------------------------------------------------------------- /example_data/example_single_data.openstereo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/example_data/example_single_data.openstereo -------------------------------------------------------------------------------- /example_data/lineaments.txt: -------------------------------------------------------------------------------- 1 | 299 2 | 316 3 | 179 4 | 348 5 | 227 6 | 216 7 | 159 8 | 206 9 | 200 10 | 208 11 | 209 12 | 206 13 | 359 14 | 74 15 | 325 16 | 272 17 | 323 18 | 256 19 | 170 20 | 207 21 | 209 22 | 306 23 | 61 24 | 327 25 | 221 26 | 212 27 | 338 28 | 188 29 | 215 30 | 310 31 | 144 32 | 344 33 | 172 34 | 224 35 | 190 36 | 209 37 | 249 38 | 221 39 | 330 40 | 178 41 | 251 42 | 49 43 | 271 44 | 267 45 | 8 46 | 204 47 | 329 48 | 339 49 | 316 50 | 330 51 | 259 52 | 223 53 | 227 54 | 227 55 | 334 56 | 356 57 | 8 58 | 12 59 | 270 60 | 9 61 | 240 62 | 28 63 | 188 64 | 340 65 | 222 66 | 237 67 | 165 68 | 238 69 | 230 70 | 231 71 | 142 72 | 216 73 | 235 74 | 52 75 | 234 76 | 152 77 | 331 78 | 323 79 | 34 80 | 26 81 | 228 82 | 216 83 | 206 84 | 277 85 | 21 86 | 297 87 | 21 88 | 80 89 | 274 90 | 28 91 | 357 92 | 268 93 | 191 94 | 293 95 | 239 96 | 100 97 | 68 98 | 314 99 | 296 100 | 92 101 | -------------------------------------------------------------------------------- /example_data/normal_faults.txt: -------------------------------------------------------------------------------- 1 | # fault data 2 | # undefined faults (or fractures) = U,u,F,f,0,5 3 | # normal = N,n,2,- 4 | # inverse = I,i,1,+ 5 | # dextral = D,d,3 6 | # sinistral = S,s,4 7 | # 8 | 145 40 150 39 2 9 | 338 35 354 34 2 10 | 60 56 68 55 2 11 | 158 54 158 54 2 12 | 118 48 120 48 2 13 | 34 55 70 49 2 14 | 344 17 318 15 2 15 | 166 40 170 39 2 16 | 10 85 10 85 2 17 | 18 37 18 37 2 18 | 234 43 234 43 2 19 | 296 25 316 24 2 20 | 100 54 66 49 2 21 | 190 40 190 40 2 22 | 92 60 75 59 2 23 | 182 52 195 51 2 24 | 156 68 114 62 2 25 | 224 54 230 53 2 26 | 88 38 105 37 2 27 | 38 32 38 32 2 28 | 318 24 325 23 2 29 | 254 54 214 47 2 30 | 165 47 189 44 2 31 | 164 50 164 50 2 32 | 115 75 115 75 2 33 | 195 57 185 56 2 34 | 12 36 12 36 2 35 | 104 55 104 55 2 36 | -------------------------------------------------------------------------------- /example_data/normal_faults.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/example_data/normal_faults.xlsx -------------------------------------------------------------------------------- /example_data/qplot.txt: -------------------------------------------------------------------------------- 1 | 299 84 2 | 316 82 3 | 179 89 4 | 348 66 5 | 227 80 6 | 216 76 7 | 159 86 8 | 206 80 9 | 200 78 10 | 208 80 11 | 209 71 12 | 206 71 13 | 359 46 14 | 74 90 15 | 325 81 16 | 272 81 17 | 323 86 18 | 256 79 19 | 170 81 20 | 207 81 21 | 209 86 22 | 306 84 23 | 61 90 24 | 327 85 25 | 221 59 26 | 212 84 27 | 338 74 28 | 188 74 29 | 215 77 30 | 310 84 31 | 144 87 32 | 344 81 33 | 172 89 34 | 224 75 35 | 190 71 36 | 209 84 37 | 249 79 38 | 221 71 39 | 330 85 40 | 178 87 41 | 251 75 42 | 49 88 43 | 271 09 44 | 267 68 45 | 8 87 46 | 204 80 47 | 329 66 48 | 339 89 49 | 316 83 50 | 330 60 51 | 259 80 52 | 223 78 53 | 227 70 54 | 227 75 55 | 334 59 56 | 356 65 57 | 8 64 58 | 12 77 59 | 270 72 60 | 9 65 61 | 240 66 62 | 28 80 63 | 188 70 64 | 340 43 65 | 222 80 66 | 237 77 67 | 165 88 68 | 238 75 69 | 230 73 70 | 231 61 71 | 142 65 72 | 216 81 73 | 235 86 74 | 52 89 75 | 234 75 76 | 152 83 77 | 331 70 78 | 323 81 79 | 34 28 80 | 26 67 81 | 228 66 82 | 216 75 83 | 206 77 84 | 277 77 85 | 21 75 86 | 297 48 87 | 21 66 88 | 80 89 89 | 274 50 90 | 28 37 91 | 357 35 92 | 268 85 93 | 191 64 94 | 293 55 95 | 239 53 96 | 100 83 97 | 68 63 98 | 314 52 99 | 296 53 100 | 92 89 101 | -------------------------------------------------------------------------------- /example_data/small.txt: -------------------------------------------------------------------------------- 1 | 225 25 15 2 | 115 45 25 3 | 345 15 25 4 | -------------------------------------------------------------------------------- /example_data/small2.txt: -------------------------------------------------------------------------------- 1 | 0 30 10 2 | 0 30 20 3 | 0 30 30 4 | 0 30 40 5 | 0 30 50 6 | 0 30 60 7 | 0 30 70 8 | 0 30 80 9 | -------------------------------------------------------------------------------- /example_data/tocher.txt: -------------------------------------------------------------------------------- 1 | 147.704 64.813 2 | 113.663 50.462 3 | 126.587 44.613 4 | 185.946 72.617 5 | 182.887 72.158 6 | 117.096 53.585 7 | 106.355 50.980 8 | 088.821 79.496 9 | 118.418 65.046 10 | 180.374 75.115 11 | 002.590 61.473 12 | 186.324 76.550 13 | 073.251 65.166 14 | 073.075 55.372 15 | 184.012 72.959 16 | 054.920 86.960 17 | 149.582 65.623 18 | 159.197 71.321 19 | 154.722 64.041 20 | 195.160 88.091 21 | 165.847 71.867 22 | 200.319 89.681 23 | 191.572 88.257 24 | 115.686 53.725 25 | 119.646 53.953 26 | 107.687 47.648 27 | 197.313 81.262 28 | 018.910 81.262 29 | 186.295 77.261 30 | 170.073 63.964 31 | 193.162 85.419 32 | 017.958 86.119 33 | 050.066 79.353 34 | 051.529 55.798 35 | 183.888 89.809 36 | 022.684 88.927 37 | 022.847 67.354 38 | 035.434 72.350 39 | 152.535 50.912 40 | 050.636 69.432 41 | 019.931 81.029 42 | 041.512 71.017 43 | 061.994 67.319 44 | 165.805 59.771 45 | 096.176 57.875 46 | 168.413 63.495 47 | 062.166 34.297 48 | 035.197 78.540 49 | 113.356 27.666 50 | 057.701 75.725 51 | 207.980 86.867 52 | 164.107 63.076 53 | 026.724 86.259 54 | 174.334 62.995 55 | 177.443 84.191 56 | 048.417 62.431 57 | 047.913 65.683 58 | 038.494 73.840 59 | 098.498 54.470 60 | 171.121 66.100 61 | 106.525 51.247 62 | 242.519 71.620 63 | 171.796 57.536 64 | 184.788 81.977 65 | 202.191 86.461 66 | 013.365 87.228 67 | 032.958 74.399 68 | 147.061 65.965 69 | 143.730 53.312 70 | 010.308 70.091 71 | 145.370 57.206 72 | 158.877 69.612 73 | 265.256 35.543 74 | 043.428 84.384 75 | 098.266 51.915 76 | 097.822 43.252 77 | 071.013 79.479 78 | 056.093 51.210 79 | 178.973 82.155 80 | 068.170 58.115 81 | 193.314 58.030 82 | 218.444 42.082 83 | 073.681 49.974 84 | 050.558 62.086 85 | 164.928 44.062 86 | 010.509 89.496 87 | 114.927 52.349 88 | 173.027 75.558 89 | 048.600 75.027 90 | 054.556 83.251 91 | 028.714 83.329 92 | 179.097 77.346 93 | 206.759 81.959 94 | 189.796 85.761 95 | 062.805 84.281 96 | 081.532 54.172 97 | 182.726 73.641 98 | 172.438 70.130 99 | 209.246 82.435 100 | 195.288 85.264 101 | 050.907 73.201 102 | 085.990 57.503 103 | 203.828 79.360 104 | 186.366 79.135 105 | 152.194 60.690 106 | 114.351 32.094 107 | 117.694 39.905 108 | 151.686 38.504 109 | 046.208 75.328 110 | 190.187 33.427 111 | 184.025 74.412 112 | 166.945 82.383 113 | 079.147 87.256 114 | 080.213 59.694 115 | 026.953 85.030 116 | 227.387 71.399 117 | 077.225 56.545 118 | 033.882 74.621 119 | 093.408 43.321 120 | 029.687 70.825 121 | 065.182 76.147 122 | 050.685 63.673 123 | 039.644 70.137 124 | 045.481 62.365 125 | 170.814 81.379 126 | 023.895 63.795 127 | 233.271 77.470 128 | 136.735 38.706 129 | 165.968 64.078 130 | 187.254 59.624 131 | 046.060 69.051 132 | 195.918 89.476 133 | 034.020 77.271 134 | 145.704 53.997 135 | 023.234 86.074 136 | 178.647 74.555 137 | 042.615 77.935 138 | 235.232 37.604 139 | 034.457 56.617 140 | 074.546 48.892 141 | 181.248 89.241 142 | 180.138 76.790 143 | 277.718 62.909 144 | 029.092 86.475 145 | 171.900 71.472 146 | 349.540 86.893 147 | 037.460 82.650 148 | 081.254 87.107 149 | 058.418 68.879 150 | 061.123 60.037 151 | 069.092 41.819 152 | 117.138 54.189 153 | 043.721 66.989 154 | 111.762 58.043 155 | 149.894 57.619 156 | 076.044 54.411 157 | 061.195 85.126 158 | 358.275 81.410 159 | 138.966 8.899 160 | 093.954 49.118 161 | 130.246 34.754 162 | 280.296 54.802 163 | 073.719 53.493 164 | 016.698 87.604 165 | 191.761 81.048 166 | 193.082 72.053 167 | 015.233 85.012 168 | 36.658 70.868 169 | 082.952 52.051 170 | 029.841 49.790 171 | 037.979 81.407 172 | 048.625 60.323 173 | 180.669 55.225 174 | 035.159 30.706 175 | 241.215 43.754 176 | 185.154 70.962 177 | 170.722 72.476 178 | 126.284 61.304 179 | 063.119 80.054 180 | 051.368 63.618 181 | 053.725 72.659 182 | 022.326 86.315 183 | 195.305 86.282 184 | 053.241 36.802 185 | 232.124 41.108 186 | 173.320 74.837 187 | 169.298 63.663 188 | 164.828 61.953 189 | 184.352 56.685 190 | 050.775 64.940 191 | 072.223 50.303 192 | 171.455 65.730 193 | 249.528 40.938 194 | 034.971 72.316 195 | 177.362 78.392 196 | 092.586 13.522 197 | 180.257 21.653 198 | 090.249 43.486 199 | 134.942 49.096 200 | 110.946 51.057 201 | -------------------------------------------------------------------------------- /example_data/tocher_header.txt: -------------------------------------------------------------------------------- 1 | dip direction,dip 2 | 147.704,64.813 3 | 113.663,50.462 4 | 126.587,44.613 5 | 185.946,72.617 6 | 182.887,72.158 7 | 117.096,53.585 8 | 106.355,50.980 9 | 088.821,79.496 10 | 118.418,65.046 11 | 180.374,75.115 12 | 002.590,61.473 13 | 186.324,76.550 14 | 073.251,65.166 15 | 073.075,55.372 16 | 184.012,72.959 17 | 054.920,86.960 18 | 149.582,65.623 19 | 159.197,71.321 20 | 154.722,64.041 21 | 195.160,88.091 22 | 165.847,71.867 23 | 200.319,89.681 24 | 191.572,88.257 25 | 115.686,53.725 26 | 119.646,53.953 27 | 107.687,47.648 28 | 197.313,81.262 29 | 018.910,81.262 30 | 186.295,77.261 31 | 170.073,63.964 32 | 193.162,85.419 33 | 017.958,86.119 34 | 050.066,79.353 35 | 051.529,55.798 36 | 183.888,89.809 37 | 022.684,88.927 38 | 022.847,67.354 39 | 035.434,72.350 40 | 152.535,50.912 41 | 050.636,69.432 42 | 019.931,81.029 43 | 041.512,71.017 44 | 061.994,67.319 45 | 165.805,59.771 46 | 096.176,57.875 47 | 168.413,63.495 48 | 062.166,34.297 49 | 035.197,78.540 50 | 113.356,27.666 51 | 057.701,75.725 52 | 207.980,86.867 53 | 164.107,63.076 54 | 026.724,86.259 55 | 174.334,62.995 56 | 177.443,84.191 57 | 048.417,62.431 58 | 047.913,65.683 59 | 038.494,73.840 60 | 098.498,54.470 61 | 171.121,66.100 62 | 106.525,51.247 63 | 242.519,71.620 64 | 171.796,57.536 65 | 184.788,81.977 66 | 202.191,86.461 67 | 013.365,87.228 68 | 032.958,74.399 69 | 147.061,65.965 70 | 143.730,53.312 71 | 010.308,70.091 72 | 145.370,57.206 73 | 158.877,69.612 74 | 265.256,35.543 75 | 043.428,84.384 76 | 098.266,51.915 77 | 097.822,43.252 78 | 071.013,79.479 79 | 056.093,51.210 80 | 178.973,82.155 81 | 068.170,58.115 82 | 193.314,58.030 83 | 218.444,42.082 84 | 073.681,49.974 85 | 050.558,62.086 86 | 164.928,44.062 87 | 010.509,89.496 88 | 114.927,52.349 89 | 173.027,75.558 90 | 048.600,75.027 91 | 054.556,83.251 92 | 028.714,83.329 93 | 179.097,77.346 94 | 206.759,81.959 95 | 189.796,85.761 96 | 062.805,84.281 97 | 081.532,54.172 98 | 182.726,73.641 99 | 172.438,70.130 100 | 209.246,82.435 101 | 195.288,85.264 102 | 050.907,73.201 103 | 085.990,57.503 104 | 203.828,79.360 105 | 186.366,79.135 106 | 152.194,60.690 107 | 114.351,32.094 108 | 117.694,39.905 109 | 151.686,38.504 110 | 046.208,75.328 111 | 190.187,33.427 112 | 184.025,74.412 113 | 166.945,82.383 114 | 079.147,87.256 115 | 080.213,59.694 116 | 026.953,85.030 117 | 227.387,71.399 118 | 077.225,56.545 119 | 033.882,74.621 120 | 093.408,43.321 121 | 029.687,70.825 122 | 065.182,76.147 123 | 050.685,63.673 124 | 039.644,70.137 125 | 045.481,62.365 126 | 170.814,81.379 127 | 023.895,63.795 128 | 233.271,77.470 129 | 136.735,38.706 130 | 165.968,64.078 131 | 187.254,59.624 132 | 046.060,69.051 133 | 195.918,89.476 134 | 034.020,77.271 135 | 145.704,53.997 136 | 023.234,86.074 137 | 178.647,74.555 138 | 042.615,77.935 139 | 235.232,37.604 140 | 034.457,56.617 141 | 074.546,48.892 142 | 181.248,89.241 143 | 180.138,76.790 144 | 277.718,62.909 145 | 029.092,86.475 146 | 171.900,71.472 147 | 349.540,86.893 148 | 037.460,82.650 149 | 081.254,87.107 150 | 058.418,68.879 151 | 061.123,60.037 152 | 069.092,41.819 153 | 117.138,54.189 154 | 043.721,66.989 155 | 111.762,58.043 156 | 149.894,57.619 157 | 076.044,54.411 158 | 061.195,85.126 159 | 358.275,81.410 160 | 138.966,8.899 161 | 093.954,49.118 162 | 130.246,34.754 163 | 280.296,54.802 164 | 073.719,53.493 165 | 016.698,87.604 166 | 191.761,81.048 167 | 193.082,72.053 168 | 015.233,85.012 169 | 36.658,70.868 170 | 082.952,52.051 171 | 029.841,49.790 172 | 037.979,81.407 173 | 048.625,60.323 174 | 180.669,55.225 175 | 035.159,30.706 176 | 241.215,43.754 177 | 185.154,70.962 178 | 170.722,72.476 179 | 126.284,61.304 180 | 063.119,80.054 181 | 051.368,63.618 182 | 053.725,72.659 183 | 022.326,86.315 184 | 195.305,86.282 185 | 053.241,36.802 186 | 232.124,41.108 187 | 173.320,74.837 188 | 169.298,63.663 189 | 164.828,61.953 190 | 184.352,56.685 191 | 050.775,64.940 192 | 072.223,50.303 193 | 171.455,65.730 194 | 249.528,40.938 195 | 034.971,72.316 196 | 177.362,78.392 197 | 092.586,13.522 198 | 180.257,21.653 199 | 090.249,43.486 200 | 134.942,49.096 201 | 110.946,51.057 202 | -------------------------------------------------------------------------------- /extra_wheels/networkx-2.1-py2.py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/extra_wheels/networkx-2.1-py2.py3-none-any.whl -------------------------------------------------------------------------------- /extra_wheels/pyshp-1.2.12-py2.py3-none-any.whl: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/extra_wheels/pyshp-1.2.12-py2.py3-none-any.whl -------------------------------------------------------------------------------- /fault.openstereo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/fault.openstereo -------------------------------------------------------------------------------- /install_osx.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | #from mu editor https://github.com/mu-editor/mu/blob/master/package/install_osx.sh 3 | set -ev 4 | brew update >/dev/null 2>&1 # This produces a lot of output that's not very interesting 5 | 6 | # Install Python 3.6 7 | #brew install https://raw.githubusercontent.com/Homebrew/homebrew-core/f2a764ef944b1080be64bd88dca9a1d80130c558/Formula/python.rb 8 | brew upgrade pyenv 9 | # The following are needed for Matplotlib 10 | brew install freetype -------------------------------------------------------------------------------- /openstereo/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/openstereo/__init__.py -------------------------------------------------------------------------------- /openstereo/__main__.py: -------------------------------------------------------------------------------- 1 | if __name__ == "__main__": 2 | from openstereo.os_base import os_main 3 | 4 | os_main() 5 | -------------------------------------------------------------------------------- /openstereo/ndtri_back.py: -------------------------------------------------------------------------------- 1 | import math 2 | #http://stackoverflow.com/a/41338979/1457481 3 | #translated to pure python from scipy source 4 | 5 | s2pi = 2.50662827463100050242E0 6 | 7 | P0 = [ 8 | -5.99633501014107895267E1, 9 | 9.80010754185999661536E1, 10 | -5.66762857469070293439E1, 11 | 1.39312609387279679503E1, 12 | -1.23916583867381258016E0, 13 | ] 14 | 15 | Q0 = [ 16 | 1, 17 | 1.95448858338141759834E0, 18 | 4.67627912898881538453E0, 19 | 8.63602421390890590575E1, 20 | -2.25462687854119370527E2, 21 | 2.00260212380060660359E2, 22 | -8.20372256168333339912E1, 23 | 1.59056225126211695515E1, 24 | -1.18331621121330003142E0, 25 | ] 26 | 27 | P1 = [ 28 | 4.05544892305962419923E0, 29 | 3.15251094599893866154E1, 30 | 5.71628192246421288162E1, 31 | 4.40805073893200834700E1, 32 | 1.46849561928858024014E1, 33 | 2.18663306850790267539E0, 34 | -1.40256079171354495875E-1, 35 | -3.50424626827848203418E-2, 36 | -8.57456785154685413611E-4, 37 | ] 38 | 39 | Q1 = [ 40 | 1, 41 | 1.57799883256466749731E1, 42 | 4.53907635128879210584E1, 43 | 4.13172038254672030440E1, 44 | 1.50425385692907503408E1, 45 | 2.50464946208309415979E0, 46 | -1.42182922854787788574E-1, 47 | -3.80806407691578277194E-2, 48 | -9.33259480895457427372E-4, 49 | ] 50 | 51 | P2 = [ 52 | 3.23774891776946035970E0, 53 | 6.91522889068984211695E0, 54 | 3.93881025292474443415E0, 55 | 1.33303460815807542389E0, 56 | 2.01485389549179081538E-1, 57 | 1.23716634817820021358E-2, 58 | 3.01581553508235416007E-4, 59 | 2.65806974686737550832E-6, 60 | 6.23974539184983293730E-9, 61 | ] 62 | 63 | Q2 = [ 64 | 1, 65 | 6.02427039364742014255E0, 66 | 3.67983563856160859403E0, 67 | 1.37702099489081330271E0, 68 | 2.16236993594496635890E-1, 69 | 1.34204006088543189037E-2, 70 | 3.28014464682127739104E-4, 71 | 2.89247864745380683936E-6, 72 | 6.79019408009981274425E-9, 73 | ] 74 | 75 | def ndtri(y0): 76 | if y0 <= 0 or y0 >= 1: 77 | raise ValueError("ndtri(x) needs 0 < x < 1") 78 | negate = True 79 | y = y0 80 | if y > 1.0 - 0.13533528323661269189: 81 | y = 1.0 - y 82 | negate = False 83 | 84 | if y > 0.13533528323661269189: 85 | y = y - 0.5 86 | y2 = y * y 87 | x = y + y * (y2 * polevl(y2, P0) / polevl(y2, Q0)) 88 | x = x * s2pi 89 | return x 90 | 91 | x = math.sqrt(-2.0 * math.log(y)) 92 | x0 = x - math.log(x) / x 93 | 94 | z = 1.0 / x 95 | if x < 8.0: 96 | x1 = z * polevl(z, P1) / polevl(z, Q1) 97 | else: 98 | x1 = z * polevl(z, P2) / polevl(z, Q2) 99 | x = x0 - x1 100 | if negate: 101 | x = -x 102 | return x 103 | 104 | def polevl(x, coef): 105 | accum = 0 106 | for c in coef: 107 | accum = x * accum + c 108 | return accum -------------------------------------------------------------------------------- /openstereo/os_math.py: -------------------------------------------------------------------------------- 1 | import math 2 | from math import pi, sin, cos, acos, atan2, degrees, radians, sqrt 3 | 4 | import numpy as np 5 | 6 | import auttitude as au 7 | 8 | 9 | # https://en.wikipedia.org/wiki/Earth_radius#Mean_radius 10 | earth_radius = 6371008.8 11 | 12 | 13 | # http://www.movable-type.co.uk/scripts/latlong.html 14 | def haversine(long1, long2, lat1, lat2, R=earth_radius): 15 | phi1, phi2 = radians(lat1), radians(lat2) 16 | lambda1, lambda2 = radians(long1), radians(long2) 17 | delta_phi = phi1 - phi2 18 | delta_lambda = lambda1 - lambda2 19 | a = ( 20 | sin(delta_phi / 2.0) ** 2 21 | + cos(phi1) * cos(phi2) * sin(delta_lambda / 2.0) ** 2 22 | ) 23 | c = 2 * atan2(sqrt(a), sqrt(1 - a)) 24 | return R * c 25 | 26 | 27 | # http://www.movable-type.co.uk/scripts/latlong.html 28 | def bearing(long1, long2, lat1, lat2): 29 | phi1, phi2 = radians(lat1), radians(lat2) 30 | lambda1, lambda2 = radians(long1), radians(long2) 31 | y = sin(lambda2 - lambda1) * cos(phi2) 32 | x = cos(phi1) * sin(phi2) - sin(phi1) * cos(phi2) * cos(lambda2 - lambda1) 33 | return degrees(atan2(y, x)) % 360.0 34 | 35 | 36 | # http://stackoverflow.com/a/22659261/1457481 37 | def in_interval(from_, to_, theta): 38 | from_, to_ = from_ % 360.0, to_ % 360.0 39 | return (from_ > to_ and (theta > from_ or theta < to_)) or ( 40 | from_ < to_ and (theta <= to_ and theta >= from_) 41 | ) 42 | 43 | 44 | def dcos(atti): 45 | dd, d = np.transpose(atti) 46 | return np.array((sin(d) * sin(dd), sin(d) * cos(dd), cos(d))) 47 | 48 | 49 | def dcos_lines(atti): 50 | tr, pl = np.transpose(atti) 51 | return np.array((cos(pl) * sin(tr), cos(pl) * cos(tr), -sin(pl))) 52 | 53 | 54 | def sphere(x, y, z): 55 | """Calculates the attitude of poles direction cossines.""" 56 | sign_z = np.copysign(1, z) 57 | return np.array( 58 | ( 59 | np.degrees(np.arctan2(sign_z * x, sign_z * y)) % 360, 60 | np.degrees(np.arccos(np.abs(z))), 61 | ) 62 | ).T 63 | 64 | 65 | def normal_versor(a, b): 66 | c = np.cross(a, b) 67 | return c / np.linalg.norm(c) 68 | 69 | 70 | def direction_versor(a): 71 | if a[2] == 1.0: 72 | return np.array((0.0, 1.0, 0.0)) 73 | else: 74 | d = np.cross((0.0, 0.0, 1.0), a) 75 | return d / np.linalg.norm(d) 76 | 77 | 78 | def angle(A, B): 79 | a, b = A / np.linalg.norm(A), B / np.linalg.norm(B) 80 | return math.atan2(np.linalg.norm(np.cross(a, b)), np.inner(a, b)) 81 | 82 | 83 | def angle_acos(A, B): 84 | a, b = A / np.linalg.norm(A), B / np.linalg.norm(B) 85 | return math.acos(np.clip(np.dot(a, b), -1.0, 1.0)) 86 | 87 | 88 | def normalized_cross(a, b): 89 | c = np.cross(a, b) 90 | return c / np.linalg.norm(c)[:, None] 91 | 92 | 93 | def dip_versor(a): 94 | d = np.cross(direction_versor(a), a) 95 | return d / np.linalg.norm(d) 96 | 97 | 98 | def great_circle_arc(a, b, r=radians(1.0)): 99 | dot = np.dot(a, b) 100 | theta = acos(dot) 101 | b_ = b - dot * a 102 | b_ = b_ / np.linalg.norm(b_) 103 | # c = np.cross(a, b_) 104 | theta_range = np.arange(0, theta, radians(r)) 105 | sin_range = np.sin(theta_range) 106 | cos_range = np.cos(theta_range) 107 | return (a * cos_range[:, None] + b_ * sin_range[:, None]).T 108 | 109 | 110 | def great_circle_simple(dcos, range=2 * pi, r=radians(1.0)): 111 | theta_range = np.arange(0, range, r) 112 | sin_range = np.sin(theta_range) 113 | cos_range = np.cos(theta_range) 114 | dir_v = direction_versor(dcos) 115 | dip_v = dip_versor(dcos) 116 | return (np.outer(dir_v, cos_range) + np.outer(dip_v, sin_range)).T 117 | 118 | 119 | def great_circle(dcos, n=360): 120 | theta_range = np.linspace(0, 2 * pi, n) 121 | sin_range = np.sin(theta_range) 122 | cos_range = np.cos(theta_range) 123 | dir_v = direction_versor(dcos) 124 | dip_v = dip_versor(dcos) 125 | return (np.outer(dir_v, cos_range) + np.outer(dip_v, sin_range)).T 126 | 127 | 128 | def small_circle(axis, alpha, n=360): 129 | k = np.linspace(0.0, 2 * pi, n) 130 | dir = direction_versor(axis) 131 | dip = dip_versor(axis) 132 | gc = dip[:, None] * np.sin(k) + dir[:, None] * np.cos(k) 133 | sc = gc * sin(alpha) + axis[:, None] * cos(alpha) 134 | return sc.T, -sc.T 135 | 136 | 137 | def net_grid(gcspacing=10.0, scspacing=10.0, n=360, clean_caps=True): 138 | theta = np.linspace(0.0, 2 * pi, n) 139 | gcspacing, scspacing = radians(gcspacing), radians(scspacing) 140 | theta_gc = ( 141 | np.linspace(0.0 + scspacing, pi - scspacing, n) 142 | if clean_caps 143 | else np.linspace(0.0, pi, n) 144 | ) 145 | gc_range = np.arange(0.0, pi + gcspacing, gcspacing) 146 | sc_range = np.arange(0.0, pi + scspacing, scspacing) 147 | i, j, k = np.eye(3) 148 | ik_circle = i[:, None] * np.sin(theta) + k[:, None] * np.cos(theta) 149 | great_circles = [ 150 | ( 151 | np.array((cos(alpha), 0.0, -sin(alpha)))[:, None] 152 | * np.sin(theta_gc) 153 | + j[:, None] * np.cos(theta_gc) 154 | ).T 155 | for alpha in gc_range 156 | ] + [ 157 | ( 158 | np.array((cos(alpha), 0.0, -sin(alpha)))[:, None] 159 | * np.sin(theta_gc) 160 | + j[:, None] * np.cos(theta_gc) 161 | ).T 162 | for alpha in -gc_range 163 | ] 164 | small_circles = [ 165 | (ik_circle * sin(alpha) + j[:, None] * cos(alpha)).T 166 | for alpha in sc_range 167 | ] 168 | if clean_caps: 169 | theta_gc = np.linspace(-scspacing, scspacing, n) 170 | great_circles += [ 171 | ( 172 | np.array((cos(alpha), 0.0, -sin(alpha)))[:, None] 173 | * np.sin(theta_gc) 174 | + j[:, None] * np.cos(theta_gc) 175 | ).T 176 | for alpha in (0, pi / 2.0) 177 | ] 178 | theta_gc = np.linspace(pi - scspacing, pi + scspacing, n) 179 | great_circles += [ 180 | ( 181 | np.array((cos(alpha), 0.0, -sin(alpha)))[:, None] 182 | * np.sin(theta_gc) 183 | + j[:, None] * np.cos(theta_gc) 184 | ).T 185 | for alpha in (0, pi / 2.0) 186 | ] 187 | return great_circles, small_circles 188 | 189 | 190 | # probably not needed 191 | def clip_lines(data, clip_radius=1.1): 192 | radii = np.linalg.norm(data, axis=1) 193 | radii[np.isinf(radii)] = 100.0 194 | radii[np.isnan(radii)] = 100.0 195 | inside = radii < clip_radius 196 | results = [] 197 | current = [] 198 | for i, is_inside in enumerate(inside): 199 | if is_inside: 200 | current.append(data[i]) 201 | elif current: 202 | results.append(current) 203 | current = [] 204 | if current: 205 | results.append(current) 206 | return results 207 | 208 | 209 | def au_clip_lines(data, z_tol=0.1): 210 | """segment point pairs between inside and outside of primitive, for 211 | avoiding spurious lines when plotting circles.""" 212 | z = np.transpose(data)[2] 213 | inside = z < z_tol 214 | results = [] 215 | current = [] 216 | for i, is_inside in enumerate(inside): 217 | if is_inside: 218 | current.append(data[i]) 219 | elif current: 220 | results.append(current) 221 | current = [] 222 | if current: 223 | results.append(current) 224 | return results 225 | 226 | 227 | def au_join_segments(segments, c_tol=radians(1.0)): 228 | """segment point pairs between inside and outside of primitive, for 229 | avoiding spurious lines when plotting circles.""" 230 | all_joined = False 231 | while not all_joined and len(segments) > 1: 232 | all_joined = True 233 | segment = segments.pop(0) 234 | if abs(angle_acos(segment[-1], segments[0][0])) < c_tol: 235 | segment.extend(segments.pop(0)) 236 | all_joined = False 237 | elif abs(angle_acos(segment[0], segments[0][-1])) < c_tol: 238 | segment_b = segments.pop(0) 239 | segment_b.extend(segment) 240 | segment = segment_b 241 | all_joined = False 242 | elif abs(angle_acos(segment[-1], segments[0][-1])) < c_tol: 243 | segment.extend(reversed(segments.pop(0))) 244 | all_joined = False 245 | elif abs(angle_acos(segment[0], segments[0][0])) < c_tol: 246 | segment_b = segments.pop(0) 247 | segment_b.extend(reversed(segment)) 248 | segment = segment_b 249 | all_joined = False 250 | segments.append(segment) 251 | return segments 252 | 253 | 254 | def au_close_polygon(projected_polygon): 255 | first = projected_polygon[0] 256 | last = projected_polygon[-1] 257 | mid = (first + last) / 2 258 | mid = mid / np.linalg.norm(mid) 259 | if np.dot(first, last) == 0.0: 260 | mid = np.array([first[1], -first[0]]) 261 | if np.linalg.norm(first) > 1.0 and np.linalg.norm(last) > 1.0: 262 | return np.vstack([projected_polygon, [2 * last, 3 * mid, 2 * first]]) 263 | return projected_polygon 264 | 265 | 266 | def extents_from_center(cx, cy, ex, ey, nx, ny, w, h): 267 | dx = cx - ex 268 | dy = cy - ny 269 | left = -1.0 - ex / dx 270 | right = (w - cx) / dx 271 | top = 1.0 + ny / dy 272 | bottom = -(h - cy) / dy 273 | return (left, right, bottom, top) 274 | 275 | 276 | # TODO: send this upstream to autti 277 | def resolve_sense(plane, line, sense): 278 | if plane[-1] > 0: 279 | plane = -plane 280 | sense = str(sense).lower()[0] 281 | if sense in ("u", "f", "0", "5", "?"): 282 | return line, False 283 | elif sense in ("n", "2", "-"): 284 | return line, True 285 | elif sense in ("i", "1", "+"): 286 | return -line, True 287 | 288 | line_sense = plane.direction_vector.dot(line) 289 | if sense in ("d", "3"): 290 | if line_sense > 0: 291 | return line, True 292 | else: 293 | return -line, True 294 | elif sense in ("s", "4"): 295 | if line_sense < 0: 296 | return line, True 297 | else: 298 | return -line, True 299 | else: # is this right? 300 | return line, True 301 | -------------------------------------------------------------------------------- /openstereo/plot_data.py: -------------------------------------------------------------------------------- 1 | class ProjectionPlotData(object): 2 | pass 3 | 4 | 5 | class RosePlotData(object): 6 | pass 7 | 8 | 9 | class PointPlotData(ProjectionPlotData): 10 | def __init__(self, data, point_settings, legend=False, legend_text=""): 11 | self.data = data 12 | self.point_settings = point_settings 13 | self.legend = legend 14 | self.legend_text = legend_text 15 | 16 | 17 | class CirclePlotData(ProjectionPlotData): 18 | def __init__(self, data, circle_settings, legend=False, legend_text=""): 19 | self.data = data 20 | self.circle_settings = circle_settings 21 | self.legend = legend 22 | self.legend_text = legend_text 23 | 24 | 25 | class PolygonPlotData(ProjectionPlotData): 26 | def __init__(self, data, polygon_settings, legend=False, legend_text=""): 27 | self.data = data 28 | self.polygon_settings = polygon_settings 29 | self.legend = legend 30 | self.legend_text = legend_text 31 | 32 | 33 | class ArrowPlotData(ProjectionPlotData): 34 | def __init__( 35 | self, 36 | data, 37 | arrow_settings, 38 | sense, 39 | legend=False, 40 | legend_text="", 41 | sliplinear=False, 42 | ): 43 | self.data = data 44 | self.arrow_settings = arrow_settings 45 | self.sense = sense 46 | self.legend = legend 47 | self.legend_text = legend_text 48 | self.sliplinear = sliplinear 49 | 50 | 51 | class ContourPlotData(ProjectionPlotData): 52 | def __init__( 53 | self, 54 | nodes, 55 | count, 56 | contour_settings, 57 | contour_line_settings, 58 | contour_check_settings, 59 | legend=False, 60 | n=None, 61 | ): 62 | self.nodes = nodes 63 | self.count = count 64 | self.contour_settings = contour_settings 65 | self.contour_line_settings = contour_line_settings 66 | self.contour_check_settings = contour_check_settings 67 | self.legend = legend 68 | self.n = n 69 | 70 | 71 | # import auttitude as au 72 | # class AuPlot(au.ProjectionPlot): 73 | # def clear_diagram(self): 74 | # pass 75 | 76 | # class ArrowPlotData(ProjectionPlotData): 77 | # pass 78 | 79 | 80 | class PetalsPlotData(RosePlotData): 81 | def __init__(self, nodes, radii, rose_settings): 82 | self.nodes = nodes 83 | self.radii = radii 84 | self.rose_settings = rose_settings 85 | 86 | 87 | class KitePlotData(RosePlotData): 88 | def __init__(self, nodes, radii, full_circle, kite_settings): 89 | self.nodes = nodes 90 | self.radii = radii 91 | self.full_circle = full_circle 92 | self.kite_settings = kite_settings 93 | 94 | 95 | class LinesPlotData(RosePlotData): 96 | def __init__(self, nodes, radii, mean_deviation, lines_settings): 97 | self.nodes = nodes 98 | self.radii = radii 99 | self.mean_deviation = mean_deviation 100 | self.lines_settings = lines_settings 101 | 102 | 103 | class RoseMeanPlotData(RosePlotData): 104 | def __init__(self, theta, confidence, axial, mean_settings): 105 | self.theta = theta 106 | self.confidence = confidence 107 | self.axial = axial 108 | self.mean_settings = mean_settings 109 | 110 | 111 | class ClassificationPlotData(object): 112 | def __init__(self, G, R, kx, ky, point_settings, legend, legend_text): 113 | self.G, self.R = G, R 114 | self.kx, self.ky = kx, ky 115 | self.point_settings = point_settings 116 | self.legend, self.legend_text = legend, legend_text 117 | -------------------------------------------------------------------------------- /openstereo/projection_models.py: -------------------------------------------------------------------------------- 1 | from math import sin, cos, radians, sqrt 2 | 3 | import numpy as np 4 | 5 | from openstereo.os_math import sphere 6 | 7 | sqrt2 = sqrt(2.0) 8 | 9 | 10 | class Projection(object): 11 | def __init__(self, settings): 12 | self.settings = settings 13 | self.build_rotation_matrix() 14 | 15 | def build_rotation_matrix(self): 16 | azim = radians(self.settings.rotation_settings["azim"]) 17 | plng = radians(self.settings.rotation_settings["plng"]) 18 | rake = radians(self.settings.rotation_settings["rake"]) 19 | 20 | R1 = np.array( 21 | ( 22 | (cos(rake), 0.0, sin(rake)), 23 | (0.0, 1.0, 0.0), 24 | (-sin(rake), 0.0, cos(rake)), 25 | ) 26 | ) 27 | 28 | R2 = np.array( 29 | ( 30 | (1.0, 0.0, 0.0), 31 | (0.0, cos(plng), sin(plng)), 32 | (0.0, -sin(plng), cos(plng)), 33 | ) 34 | ) 35 | 36 | R3 = np.array( 37 | ( 38 | (cos(azim), sin(azim), 0.0), 39 | (-sin(azim), cos(azim), 0.0), 40 | (0.0, 0.0, 1.0), 41 | ) 42 | ) 43 | 44 | self.R = R3.dot(R2).dot(R1) 45 | self.Ri = np.linalg.inv(self.R) 46 | 47 | def rotate(self, x, y, z): 48 | self.build_rotation_matrix() 49 | return self.R.dot((x, y, z)) 50 | 51 | def project_data( 52 | self, x, y, z, invert_positive=True, ztol=0.0, rotate=None 53 | ): 54 | if ( 55 | self.settings.check_settings["rotate"] 56 | and rotate is None 57 | or rotate is True 58 | ): 59 | x, y, z = self.rotate(x, y, z) 60 | if invert_positive: 61 | c = np.where(z > ztol, -1, 1) 62 | x, y, z = c * x, c * y, c * z 63 | if ( 64 | self.settings.general_settings["hemisphere"] == "Upper" 65 | and rotate is None 66 | ): 67 | c = np.where(z != 0.0, -1, 1) 68 | x, y = c * x, c * y 69 | return self.project(x, y, z) 70 | 71 | def read_plot(self, X, Y): 72 | if X * X + Y * Y > 1.0: 73 | return "" 74 | x, y, z = self.inverse(X, Y) 75 | if self.settings.check_settings["rotate"]: 76 | x, y, z = self.Ri.dot((x, y, z)) 77 | theta, phi = sphere(x, y, z) 78 | if phi >= 0.0: 79 | return "Pole: %05.1f/%04.1f\nLine: %05.1f/%04.1f" % ( 80 | theta, 81 | phi, 82 | (theta - 180) % 360.0, 83 | 90.0 - phi, 84 | ) 85 | else: 86 | return "" 87 | 88 | 89 | class EqualAreaProj(Projection): 90 | name = "Equal-area" 91 | 92 | def project(self, x, y, z, radius=1.0): 93 | return x * np.sqrt(1 / (1 - z)), y * np.sqrt(1 / (1 - z)) 94 | 95 | def inverse(self, X, Y, radius=1.0): 96 | X, Y = X * sqrt2, Y * sqrt2 97 | x = np.sqrt(1 - (X * X + Y * Y) / 4.0) * X 98 | y = np.sqrt(1 - (X * X + Y * Y) / 4.0) * Y 99 | z = -1.0 + (X * X + Y * Y) / 2 100 | return x, y, z 101 | 102 | 103 | class EqualAngleProj(Projection): 104 | name = "Equal-angle" 105 | 106 | def project(self, x, y, z, radius=1.0): 107 | return x / (1 - z), y / (1 - z) 108 | 109 | def inverse(self, X, Y, radius=1.0): 110 | x = 2.0 * X / (1.0 + X * X + Y * Y) 111 | y = 2.0 * Y / (1.0 + X * X + Y * Y) 112 | z = (-1.0 + X * X + Y * Y) / (1.0 + X * X + Y * Y) 113 | return x, y, z 114 | -------------------------------------------------------------------------------- /openstereo/tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/openstereo/tools/__init__.py -------------------------------------------------------------------------------- /openstereo/tools/mesh_process.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtWidgets, QtGui 2 | 3 | from openstereo.ui.import_ply_ui import Ui_Dialog as import_ply_Ui_Dialog 4 | 5 | 6 | class MeshDialog(QtWidgets.QDialog, import_ply_Ui_Dialog): 7 | default_colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255)] 8 | 9 | def __init__(self, parent=None): 10 | super(MeshDialog, self).__init__(parent) 11 | self.setupUi(self) 12 | for color in self.default_colors: 13 | self.add_color_to_list(color) 14 | self.add_color_button.clicked.connect(self.add_color) 15 | self.remove_color_button.clicked.connect(self.remove_color) 16 | 17 | def add_color_to_list(self, color): 18 | item = QtWidgets.QListWidgetItem( 19 | ",".join(str(c) for c in color), self.color_list 20 | ) 21 | item.setForeground(QtGui.QColor(*color)) 22 | 23 | def add_color(self): 24 | color = QtWidgets.QColorDialog.getColor() 25 | if color.isValid(): 26 | self.add_color_to_list((color.red(), color.green(), color.blue())) 27 | 28 | # http://stackoverflow.com/a/7486225/1457481 29 | def remove_color(self): 30 | current_item = self.color_list.currentItem() 31 | self.color_list.takeItem(self.color_list.row(current_item)) 32 | 33 | @property 34 | def colors(self): 35 | return [ 36 | tuple( 37 | [int(c) for c in self.color_list.item(i).text().split(",")] 38 | + [255] 39 | ) 40 | for i in range(self.color_list.count()) 41 | ] 42 | -------------------------------------------------------------------------------- /openstereo/ui/__init__.py: -------------------------------------------------------------------------------- 1 | from PyQt5 import QtWidgets, QtCore, QtGui 2 | 3 | 4 | # http://stackoverflow.com/a/20295812/1457481 5 | def waiting_effects(function): 6 | def new_function(*args, **kwargs): 7 | QtWidgets.QApplication.setOverrideCursor( 8 | QtGui.QCursor(QtCore.Qt.WaitCursor) 9 | ) 10 | try: 11 | return function(*args, **kwargs) 12 | except Exception as e: 13 | raise e 14 | finally: 15 | QtWidgets.QApplication.restoreOverrideCursor() 16 | 17 | return new_function 18 | -------------------------------------------------------------------------------- /openstereo/ui/clipboard_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\clipboard.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(287, 499) 15 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout_2.setObjectName("verticalLayout_2") 17 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 18 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 19 | self.fname = QtWidgets.QLineEdit(Dialog) 20 | self.fname.setReadOnly(False) 21 | self.fname.setObjectName("fname") 22 | self.horizontalLayout_2.addWidget(self.fname) 23 | self.browse = QtWidgets.QPushButton(Dialog) 24 | self.browse.setObjectName("browse") 25 | self.horizontalLayout_2.addWidget(self.browse) 26 | self.verticalLayout_2.addLayout(self.horizontalLayout_2) 27 | self.groupBox = QtWidgets.QGroupBox(Dialog) 28 | self.groupBox.setObjectName("groupBox") 29 | self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox) 30 | self.verticalLayout.setObjectName("verticalLayout") 31 | self.lines = QtWidgets.QRadioButton(self.groupBox) 32 | self.lines.setObjectName("lines") 33 | self.verticalLayout.addWidget(self.lines) 34 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 35 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 36 | self.planes = QtWidgets.QRadioButton(self.groupBox) 37 | self.planes.setChecked(True) 38 | self.planes.setObjectName("planes") 39 | self.horizontalLayout_3.addWidget(self.planes) 40 | self.planetype = QtWidgets.QComboBox(self.groupBox) 41 | self.planetype.setObjectName("planetype") 42 | self.planetype.addItem("") 43 | self.planetype.addItem("") 44 | self.horizontalLayout_3.addWidget(self.planetype) 45 | self.verticalLayout.addLayout(self.horizontalLayout_3) 46 | self.small_circle = QtWidgets.QRadioButton(self.groupBox) 47 | self.small_circle.setObjectName("small_circle") 48 | self.verticalLayout.addWidget(self.small_circle) 49 | self.circular = QtWidgets.QRadioButton(self.groupBox) 50 | self.circular.setObjectName("circular") 51 | self.verticalLayout.addWidget(self.circular) 52 | self.verticalLayout_2.addWidget(self.groupBox) 53 | self.groupBox_3 = QtWidgets.QGroupBox(Dialog) 54 | self.groupBox_3.setObjectName("groupBox_3") 55 | self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_3) 56 | self.gridLayout_2.setObjectName("gridLayout_2") 57 | self.do_skip = QtWidgets.QCheckBox(self.groupBox_3) 58 | self.do_skip.setObjectName("do_skip") 59 | self.gridLayout_2.addWidget(self.do_skip, 4, 0, 1, 1) 60 | self.has_header = QtWidgets.QCheckBox(self.groupBox_3) 61 | self.has_header.setChecked(True) 62 | self.has_header.setObjectName("has_header") 63 | self.gridLayout_2.addWidget(self.has_header, 3, 0, 1, 1) 64 | self.skip_rows = QtWidgets.QSpinBox(self.groupBox_3) 65 | self.skip_rows.setObjectName("skip_rows") 66 | self.gridLayout_2.addWidget(self.skip_rows, 4, 1, 1, 1) 67 | self.label = QtWidgets.QLabel(self.groupBox_3) 68 | self.label.setObjectName("label") 69 | self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) 70 | self.delimiter = QtWidgets.QLineEdit(self.groupBox_3) 71 | self.delimiter.setObjectName("delimiter") 72 | self.gridLayout_2.addWidget(self.delimiter, 0, 1, 1, 1) 73 | self.header_row = QtWidgets.QSpinBox(self.groupBox_3) 74 | self.header_row.setObjectName("header_row") 75 | self.gridLayout_2.addWidget(self.header_row, 3, 1, 1, 1) 76 | self.worksheet = QtWidgets.QComboBox(self.groupBox_3) 77 | self.worksheet.setObjectName("worksheet") 78 | self.gridLayout_2.addWidget(self.worksheet, 2, 1, 1, 1) 79 | self.label_5 = QtWidgets.QLabel(self.groupBox_3) 80 | self.label_5.setObjectName("label_5") 81 | self.gridLayout_2.addWidget(self.label_5, 2, 0, 1, 1) 82 | self.label_2 = QtWidgets.QLabel(self.groupBox_3) 83 | self.label_2.setObjectName("label_2") 84 | self.gridLayout_2.addWidget(self.label_2, 1, 0, 1, 1) 85 | self.comment_marker = QtWidgets.QLineEdit(self.groupBox_3) 86 | self.comment_marker.setObjectName("comment_marker") 87 | self.gridLayout_2.addWidget(self.comment_marker, 1, 1, 1, 1) 88 | self.verticalLayout_2.addWidget(self.groupBox_3) 89 | self.groupBox_2 = QtWidgets.QGroupBox(Dialog) 90 | self.groupBox_2.setObjectName("groupBox_2") 91 | self.gridLayout = QtWidgets.QGridLayout(self.groupBox_2) 92 | self.gridLayout.setObjectName("gridLayout") 93 | self.longitude_label = QtWidgets.QLabel(self.groupBox_2) 94 | self.longitude_label.setObjectName("longitude_label") 95 | self.gridLayout.addWidget(self.longitude_label, 0, 0, 1, 1) 96 | self.longitude = QtWidgets.QComboBox(self.groupBox_2) 97 | self.longitude.setObjectName("longitude") 98 | self.gridLayout.addWidget(self.longitude, 0, 1, 1, 1) 99 | self.colatitude_label = QtWidgets.QLabel(self.groupBox_2) 100 | self.colatitude_label.setObjectName("colatitude_label") 101 | self.gridLayout.addWidget(self.colatitude_label, 1, 0, 1, 1) 102 | self.colatitude = QtWidgets.QComboBox(self.groupBox_2) 103 | self.colatitude.setObjectName("colatitude") 104 | self.gridLayout.addWidget(self.colatitude, 1, 1, 1, 1) 105 | self.alpha_label = QtWidgets.QLabel(self.groupBox_2) 106 | self.alpha_label.setObjectName("alpha_label") 107 | self.gridLayout.addWidget(self.alpha_label, 2, 0, 1, 1) 108 | self.alpha = QtWidgets.QComboBox(self.groupBox_2) 109 | self.alpha.setObjectName("alpha") 110 | self.gridLayout.addWidget(self.alpha, 2, 1, 1, 1) 111 | self.verticalLayout_2.addWidget(self.groupBox_2) 112 | self.horizontalLayout = QtWidgets.QHBoxLayout() 113 | self.horizontalLayout.setObjectName("horizontalLayout") 114 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 115 | self.horizontalLayout.addItem(spacerItem) 116 | self.ok_button = QtWidgets.QPushButton(Dialog) 117 | self.ok_button.setObjectName("ok_button") 118 | self.horizontalLayout.addWidget(self.ok_button) 119 | self.cancel_button = QtWidgets.QPushButton(Dialog) 120 | self.cancel_button.setObjectName("cancel_button") 121 | self.horizontalLayout.addWidget(self.cancel_button) 122 | self.verticalLayout_2.addLayout(self.horizontalLayout) 123 | 124 | self.retranslateUi(Dialog) 125 | self.ok_button.clicked.connect(Dialog.accept) 126 | self.cancel_button.clicked.connect(Dialog.reject) 127 | QtCore.QMetaObject.connectSlotsByName(Dialog) 128 | 129 | def retranslateUi(self, Dialog): 130 | _translate = QtCore.QCoreApplication.translate 131 | Dialog.setWindowTitle(_translate("Dialog", "Import Data")) 132 | self.browse.setText(_translate("Dialog", "Browse...")) 133 | self.groupBox.setTitle(_translate("Dialog", "Data Type")) 134 | self.lines.setText(_translate("Dialog", "Lines")) 135 | self.planes.setText(_translate("Dialog", "Planes")) 136 | self.planetype.setItemText(0, _translate("Dialog", "Dip Direction")) 137 | self.planetype.setItemText(1, _translate("Dialog", "Direction")) 138 | self.small_circle.setText(_translate("Dialog", "Small Circles")) 139 | self.circular.setText(_translate("Dialog", "Azimuth Data")) 140 | self.groupBox_3.setTitle(_translate("Dialog", "File Settings")) 141 | self.do_skip.setText(_translate("Dialog", "Skip Rows")) 142 | self.has_header.setText(_translate("Dialog", "Header Row")) 143 | self.label.setText(_translate("Dialog", "Delimiter")) 144 | self.label_5.setText(_translate("Dialog", "Worksheet")) 145 | self.label_2.setText(_translate("Dialog", "Comment")) 146 | self.groupBox_2.setTitle(_translate("Dialog", "Attitude Columns")) 147 | self.longitude_label.setText(_translate("Dialog", "Dip Direction")) 148 | self.colatitude_label.setText(_translate("Dialog", "Dip")) 149 | self.alpha_label.setText(_translate("Dialog", "Alpha")) 150 | self.ok_button.setText(_translate("Dialog", "OK")) 151 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 152 | 153 | -------------------------------------------------------------------------------- /openstereo/ui/difference_vectors_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\difference_vectors.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(227, 193) 15 | self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout.setObjectName("verticalLayout") 17 | self.A = QtWidgets.QComboBox(Dialog) 18 | self.A.setObjectName("A") 19 | self.verticalLayout.addWidget(self.A) 20 | self.formLayout = QtWidgets.QFormLayout() 21 | self.formLayout.setObjectName("formLayout") 22 | self.do_percentage = QtWidgets.QRadioButton(Dialog) 23 | self.do_percentage.setChecked(True) 24 | self.do_percentage.setObjectName("do_percentage") 25 | self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.do_percentage) 26 | self.percentage_largest = QtWidgets.QDoubleSpinBox(Dialog) 27 | self.percentage_largest.setMaximum(100.0) 28 | self.percentage_largest.setProperty("value", 100.0) 29 | self.percentage_largest.setObjectName("percentage_largest") 30 | self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.percentage_largest) 31 | self.do_n = QtWidgets.QRadioButton(Dialog) 32 | self.do_n.setObjectName("do_n") 33 | self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.do_n) 34 | self.n_largest = QtWidgets.QLineEdit(Dialog) 35 | self.n_largest.setObjectName("n_largest") 36 | self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.n_largest) 37 | self.verticalLayout.addLayout(self.formLayout) 38 | spacerItem = QtWidgets.QSpacerItem(20, 61, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 39 | self.verticalLayout.addItem(spacerItem) 40 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 41 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 42 | spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 43 | self.horizontalLayout_2.addItem(spacerItem1) 44 | self.ok_button = QtWidgets.QPushButton(Dialog) 45 | self.ok_button.setObjectName("ok_button") 46 | self.horizontalLayout_2.addWidget(self.ok_button) 47 | self.cancel_button = QtWidgets.QPushButton(Dialog) 48 | self.cancel_button.setObjectName("cancel_button") 49 | self.horizontalLayout_2.addWidget(self.cancel_button) 50 | self.verticalLayout.addLayout(self.horizontalLayout_2) 51 | 52 | self.retranslateUi(Dialog) 53 | self.ok_button.clicked.connect(Dialog.accept) 54 | self.cancel_button.clicked.connect(Dialog.reject) 55 | QtCore.QMetaObject.connectSlotsByName(Dialog) 56 | 57 | def retranslateUi(self, Dialog): 58 | _translate = QtCore.QCoreApplication.translate 59 | Dialog.setWindowTitle(_translate("Dialog", "Difference Vectors")) 60 | self.do_percentage.setText(_translate("Dialog", "% largest")) 61 | self.do_n.setText(_translate("Dialog", "n largest")) 62 | self.ok_button.setText(_translate("Dialog", "OK")) 63 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 64 | 65 | -------------------------------------------------------------------------------- /openstereo/ui/fault_data_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\fault_data.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(268, 109) 15 | self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout.setObjectName("verticalLayout") 17 | self.formLayout = QtWidgets.QFormLayout() 18 | self.formLayout.setObjectName("formLayout") 19 | self.label = QtWidgets.QLabel(Dialog) 20 | self.label.setObjectName("label") 21 | self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.label) 22 | self.A = QtWidgets.QComboBox(Dialog) 23 | self.A.setObjectName("A") 24 | self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.A) 25 | self.label_2 = QtWidgets.QLabel(Dialog) 26 | self.label_2.setObjectName("label_2") 27 | self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_2) 28 | self.B = QtWidgets.QComboBox(Dialog) 29 | self.B.setObjectName("B") 30 | self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.B) 31 | self.verticalLayout.addLayout(self.formLayout) 32 | spacerItem = QtWidgets.QSpacerItem(20, 11, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 33 | self.verticalLayout.addItem(spacerItem) 34 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 35 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 36 | spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 37 | self.horizontalLayout_2.addItem(spacerItem1) 38 | self.ok_button = QtWidgets.QPushButton(Dialog) 39 | self.ok_button.setObjectName("ok_button") 40 | self.horizontalLayout_2.addWidget(self.ok_button) 41 | self.cancel_button = QtWidgets.QPushButton(Dialog) 42 | self.cancel_button.setObjectName("cancel_button") 43 | self.horizontalLayout_2.addWidget(self.cancel_button) 44 | self.verticalLayout.addLayout(self.horizontalLayout_2) 45 | 46 | self.retranslateUi(Dialog) 47 | self.ok_button.clicked.connect(Dialog.accept) 48 | self.cancel_button.clicked.connect(Dialog.reject) 49 | QtCore.QMetaObject.connectSlotsByName(Dialog) 50 | 51 | def retranslateUi(self, Dialog): 52 | _translate = QtCore.QCoreApplication.translate 53 | Dialog.setWindowTitle(_translate("Dialog", "Build Fault Data Item")) 54 | self.label.setText(_translate("Dialog", "Planes")) 55 | self.label_2.setText(_translate("Dialog", "Lines")) 56 | self.ok_button.setText(_translate("Dialog", "OK")) 57 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 58 | 59 | -------------------------------------------------------------------------------- /openstereo/ui/import_dialog_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\import_dialog.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(310, 552) 15 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout_2.setObjectName("verticalLayout_2") 17 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 18 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 19 | self.fname = QtWidgets.QLineEdit(Dialog) 20 | self.fname.setReadOnly(False) 21 | self.fname.setObjectName("fname") 22 | self.horizontalLayout_2.addWidget(self.fname) 23 | self.browse = QtWidgets.QPushButton(Dialog) 24 | self.browse.setObjectName("browse") 25 | self.horizontalLayout_2.addWidget(self.browse) 26 | self.verticalLayout_2.addLayout(self.horizontalLayout_2) 27 | self.groupBox = QtWidgets.QGroupBox(Dialog) 28 | self.groupBox.setObjectName("groupBox") 29 | self.verticalLayout = QtWidgets.QVBoxLayout(self.groupBox) 30 | self.verticalLayout.setObjectName("verticalLayout") 31 | self.horizontalLayout_4 = QtWidgets.QHBoxLayout() 32 | self.horizontalLayout_4.setObjectName("horizontalLayout_4") 33 | self.lines = QtWidgets.QRadioButton(self.groupBox) 34 | self.lines.setObjectName("lines") 35 | self.horizontalLayout_4.addWidget(self.lines) 36 | self.linetype = QtWidgets.QComboBox(self.groupBox) 37 | self.linetype.setObjectName("linetype") 38 | self.linetype.addItem("") 39 | self.linetype.addItem("") 40 | self.horizontalLayout_4.addWidget(self.linetype) 41 | self.verticalLayout.addLayout(self.horizontalLayout_4) 42 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 43 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 44 | self.planes = QtWidgets.QRadioButton(self.groupBox) 45 | self.planes.setChecked(True) 46 | self.planes.setObjectName("planes") 47 | self.horizontalLayout_3.addWidget(self.planes) 48 | self.planetype = QtWidgets.QComboBox(self.groupBox) 49 | self.planetype.setObjectName("planetype") 50 | self.planetype.addItem("") 51 | self.planetype.addItem("") 52 | self.horizontalLayout_3.addWidget(self.planetype) 53 | self.verticalLayout.addLayout(self.horizontalLayout_3) 54 | self.small_circle = QtWidgets.QRadioButton(self.groupBox) 55 | self.small_circle.setObjectName("small_circle") 56 | self.verticalLayout.addWidget(self.small_circle) 57 | self.circular = QtWidgets.QRadioButton(self.groupBox) 58 | self.circular.setObjectName("circular") 59 | self.verticalLayout.addWidget(self.circular) 60 | self.verticalLayout_2.addWidget(self.groupBox) 61 | self.groupBox_3 = QtWidgets.QGroupBox(Dialog) 62 | self.groupBox_3.setObjectName("groupBox_3") 63 | self.gridLayout_2 = QtWidgets.QGridLayout(self.groupBox_3) 64 | self.gridLayout_2.setObjectName("gridLayout_2") 65 | self.do_skip = QtWidgets.QCheckBox(self.groupBox_3) 66 | self.do_skip.setObjectName("do_skip") 67 | self.gridLayout_2.addWidget(self.do_skip, 4, 0, 1, 1) 68 | self.has_header = QtWidgets.QCheckBox(self.groupBox_3) 69 | self.has_header.setChecked(True) 70 | self.has_header.setObjectName("has_header") 71 | self.gridLayout_2.addWidget(self.has_header, 3, 0, 1, 1) 72 | self.skip_rows = QtWidgets.QSpinBox(self.groupBox_3) 73 | self.skip_rows.setObjectName("skip_rows") 74 | self.gridLayout_2.addWidget(self.skip_rows, 4, 1, 1, 1) 75 | self.label = QtWidgets.QLabel(self.groupBox_3) 76 | self.label.setObjectName("label") 77 | self.gridLayout_2.addWidget(self.label, 0, 0, 1, 1) 78 | self.delimiter = QtWidgets.QLineEdit(self.groupBox_3) 79 | self.delimiter.setObjectName("delimiter") 80 | self.gridLayout_2.addWidget(self.delimiter, 0, 1, 1, 1) 81 | self.header_row = QtWidgets.QSpinBox(self.groupBox_3) 82 | self.header_row.setObjectName("header_row") 83 | self.gridLayout_2.addWidget(self.header_row, 3, 1, 1, 1) 84 | self.worksheet = QtWidgets.QComboBox(self.groupBox_3) 85 | self.worksheet.setObjectName("worksheet") 86 | self.gridLayout_2.addWidget(self.worksheet, 2, 1, 1, 1) 87 | self.label_5 = QtWidgets.QLabel(self.groupBox_3) 88 | self.label_5.setObjectName("label_5") 89 | self.gridLayout_2.addWidget(self.label_5, 2, 0, 1, 1) 90 | self.label_2 = QtWidgets.QLabel(self.groupBox_3) 91 | self.label_2.setObjectName("label_2") 92 | self.gridLayout_2.addWidget(self.label_2, 1, 0, 1, 1) 93 | self.comment_marker = QtWidgets.QLineEdit(self.groupBox_3) 94 | self.comment_marker.setObjectName("comment_marker") 95 | self.gridLayout_2.addWidget(self.comment_marker, 1, 1, 1, 1) 96 | self.verticalLayout_2.addWidget(self.groupBox_3) 97 | self.groupBox_2 = QtWidgets.QGroupBox(Dialog) 98 | self.groupBox_2.setObjectName("groupBox_2") 99 | self.formLayout = QtWidgets.QFormLayout(self.groupBox_2) 100 | self.formLayout.setObjectName("formLayout") 101 | self.longitude_label = QtWidgets.QLabel(self.groupBox_2) 102 | self.longitude_label.setObjectName("longitude_label") 103 | self.formLayout.setWidget(0, QtWidgets.QFormLayout.LabelRole, self.longitude_label) 104 | self.longitude = QtWidgets.QComboBox(self.groupBox_2) 105 | self.longitude.setObjectName("longitude") 106 | self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.longitude) 107 | self.colatitude_label = QtWidgets.QLabel(self.groupBox_2) 108 | self.colatitude_label.setObjectName("colatitude_label") 109 | self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.colatitude_label) 110 | self.colatitude = QtWidgets.QComboBox(self.groupBox_2) 111 | self.colatitude.setObjectName("colatitude") 112 | self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.colatitude) 113 | self.rake_label = QtWidgets.QLabel(self.groupBox_2) 114 | self.rake_label.setObjectName("rake_label") 115 | self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.rake_label) 116 | self.rake = QtWidgets.QComboBox(self.groupBox_2) 117 | self.rake.setObjectName("rake") 118 | self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.rake) 119 | self.alpha_label = QtWidgets.QLabel(self.groupBox_2) 120 | self.alpha_label.setObjectName("alpha_label") 121 | self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.alpha_label) 122 | self.alpha = QtWidgets.QComboBox(self.groupBox_2) 123 | self.alpha.setObjectName("alpha") 124 | self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.alpha) 125 | self.verticalLayout_2.addWidget(self.groupBox_2) 126 | self.horizontalLayout = QtWidgets.QHBoxLayout() 127 | self.horizontalLayout.setObjectName("horizontalLayout") 128 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 129 | self.horizontalLayout.addItem(spacerItem) 130 | self.ok_button = QtWidgets.QPushButton(Dialog) 131 | self.ok_button.setObjectName("ok_button") 132 | self.horizontalLayout.addWidget(self.ok_button) 133 | self.cancel_button = QtWidgets.QPushButton(Dialog) 134 | self.cancel_button.setObjectName("cancel_button") 135 | self.horizontalLayout.addWidget(self.cancel_button) 136 | self.verticalLayout_2.addLayout(self.horizontalLayout) 137 | 138 | self.retranslateUi(Dialog) 139 | self.ok_button.clicked.connect(Dialog.accept) 140 | self.cancel_button.clicked.connect(Dialog.reject) 141 | QtCore.QMetaObject.connectSlotsByName(Dialog) 142 | 143 | def retranslateUi(self, Dialog): 144 | _translate = QtCore.QCoreApplication.translate 145 | Dialog.setWindowTitle(_translate("Dialog", "Import Data")) 146 | self.browse.setText(_translate("Dialog", "Browse...")) 147 | self.groupBox.setTitle(_translate("Dialog", "Data Type")) 148 | self.lines.setText(_translate("Dialog", "Lines")) 149 | self.linetype.setItemText(0, _translate("Dialog", "Trend/Plunge")) 150 | self.linetype.setItemText(1, _translate("Dialog", "Rake")) 151 | self.planes.setText(_translate("Dialog", "Planes")) 152 | self.planetype.setItemText(0, _translate("Dialog", "Dip Direction")) 153 | self.planetype.setItemText(1, _translate("Dialog", "Direction")) 154 | self.small_circle.setText(_translate("Dialog", "Small Circles")) 155 | self.circular.setText(_translate("Dialog", "Azimuth Data")) 156 | self.groupBox_3.setTitle(_translate("Dialog", "File Settings")) 157 | self.do_skip.setText(_translate("Dialog", "Skip Rows")) 158 | self.has_header.setText(_translate("Dialog", "Header Row")) 159 | self.label.setText(_translate("Dialog", "Delimiter")) 160 | self.label_5.setText(_translate("Dialog", "Worksheet")) 161 | self.label_2.setText(_translate("Dialog", "Comment")) 162 | self.groupBox_2.setTitle(_translate("Dialog", "Attitude Columns")) 163 | self.longitude_label.setText(_translate("Dialog", "Dip Direction")) 164 | self.colatitude_label.setText(_translate("Dialog", "Dip")) 165 | self.rake_label.setText(_translate("Dialog", "Rake")) 166 | self.alpha_label.setText(_translate("Dialog", "Alpha")) 167 | self.ok_button.setText(_translate("Dialog", "OK")) 168 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 169 | 170 | -------------------------------------------------------------------------------- /openstereo/ui/import_ply_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\import_ply.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(314, 327) 15 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout_2.setObjectName("verticalLayout_2") 17 | self.horizontalLayout = QtWidgets.QHBoxLayout() 18 | self.horizontalLayout.setObjectName("horizontalLayout") 19 | self.label = QtWidgets.QLabel(Dialog) 20 | self.label.setObjectName("label") 21 | self.horizontalLayout.addWidget(self.label) 22 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 23 | self.horizontalLayout.addItem(spacerItem) 24 | self.verticalLayout_2.addLayout(self.horizontalLayout) 25 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 26 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 27 | self.color_list = QtWidgets.QListWidget(Dialog) 28 | self.color_list.setObjectName("color_list") 29 | self.horizontalLayout_3.addWidget(self.color_list) 30 | self.verticalLayout = QtWidgets.QVBoxLayout() 31 | self.verticalLayout.setObjectName("verticalLayout") 32 | self.add_color_button = QtWidgets.QPushButton(Dialog) 33 | self.add_color_button.setObjectName("add_color_button") 34 | self.verticalLayout.addWidget(self.add_color_button) 35 | self.remove_color_button = QtWidgets.QPushButton(Dialog) 36 | self.remove_color_button.setObjectName("remove_color_button") 37 | self.verticalLayout.addWidget(self.remove_color_button) 38 | spacerItem1 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 39 | self.verticalLayout.addItem(spacerItem1) 40 | self.horizontalLayout_3.addLayout(self.verticalLayout) 41 | self.verticalLayout_2.addLayout(self.horizontalLayout_3) 42 | self.check_separate = QtWidgets.QCheckBox(Dialog) 43 | self.check_separate.setChecked(True) 44 | self.check_separate.setObjectName("check_separate") 45 | self.verticalLayout_2.addWidget(self.check_separate) 46 | self.check_export_ply = QtWidgets.QCheckBox(Dialog) 47 | self.check_export_ply.setObjectName("check_export_ply") 48 | self.verticalLayout_2.addWidget(self.check_export_ply) 49 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 50 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 51 | spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 52 | self.horizontalLayout_2.addItem(spacerItem2) 53 | self.ok_button = QtWidgets.QPushButton(Dialog) 54 | self.ok_button.setObjectName("ok_button") 55 | self.horizontalLayout_2.addWidget(self.ok_button) 56 | self.cancel_button = QtWidgets.QPushButton(Dialog) 57 | self.cancel_button.setObjectName("cancel_button") 58 | self.horizontalLayout_2.addWidget(self.cancel_button) 59 | self.verticalLayout_2.addLayout(self.horizontalLayout_2) 60 | 61 | self.retranslateUi(Dialog) 62 | self.ok_button.clicked.connect(Dialog.accept) 63 | self.cancel_button.clicked.connect(Dialog.reject) 64 | QtCore.QMetaObject.connectSlotsByName(Dialog) 65 | 66 | def retranslateUi(self, Dialog): 67 | _translate = QtCore.QCoreApplication.translate 68 | Dialog.setWindowTitle(_translate("Dialog", "Import Planes from Mesh")) 69 | self.label.setText(_translate("Dialog", "Painted Colors:")) 70 | self.add_color_button.setText(_translate("Dialog", "Add Color")) 71 | self.remove_color_button.setText(_translate("Dialog", "Remove")) 72 | self.check_separate.setText(_translate("Dialog", "Export each color to a separate file")) 73 | self.check_export_ply.setText(_translate("Dialog", "Export 3d model of resulting planes")) 74 | self.ok_button.setText(_translate("Dialog", "OK")) 75 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 76 | 77 | -------------------------------------------------------------------------------- /openstereo/ui/item_table_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\item_table.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(279, 460) 15 | self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout.setObjectName("verticalLayout") 17 | self.data_table = QtWidgets.QTableWidget(Dialog) 18 | self.data_table.setObjectName("data_table") 19 | self.data_table.setColumnCount(0) 20 | self.data_table.setRowCount(0) 21 | self.verticalLayout.addWidget(self.data_table) 22 | self.horizontalLayout = QtWidgets.QHBoxLayout() 23 | self.horizontalLayout.setObjectName("horizontalLayout") 24 | self.update_data_button = QtWidgets.QPushButton(Dialog) 25 | self.update_data_button.setObjectName("update_data_button") 26 | self.horizontalLayout.addWidget(self.update_data_button) 27 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 28 | self.horizontalLayout.addItem(spacerItem) 29 | self.toolButton_2 = QtWidgets.QToolButton(Dialog) 30 | self.toolButton_2.setObjectName("toolButton_2") 31 | self.horizontalLayout.addWidget(self.toolButton_2) 32 | self.toolButton = QtWidgets.QToolButton(Dialog) 33 | self.toolButton.setObjectName("toolButton") 34 | self.horizontalLayout.addWidget(self.toolButton) 35 | self.toolButton_3 = QtWidgets.QToolButton(Dialog) 36 | self.toolButton_3.setObjectName("toolButton_3") 37 | self.horizontalLayout.addWidget(self.toolButton_3) 38 | self.verticalLayout.addLayout(self.horizontalLayout) 39 | 40 | self.retranslateUi(Dialog) 41 | QtCore.QMetaObject.connectSlotsByName(Dialog) 42 | 43 | def retranslateUi(self, Dialog): 44 | _translate = QtCore.QCoreApplication.translate 45 | Dialog.setWindowTitle(_translate("Dialog", "Item Table")) 46 | self.update_data_button.setText(_translate("Dialog", "Update Data")) 47 | self.toolButton_2.setText(_translate("Dialog", "w")) 48 | self.toolButton.setText(_translate("Dialog", "sc")) 49 | self.toolButton_3.setText(_translate("Dialog", "ff")) 50 | 51 | -------------------------------------------------------------------------------- /openstereo/ui/languages.py: -------------------------------------------------------------------------------- 1 | os_languages = { 2 | "English (US)": "en_US", 3 | "Português (Brasil)": "pt_BR" 4 | } -------------------------------------------------------------------------------- /openstereo/ui/merge_data_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\merge_data.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(285, 174) 15 | self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout.setObjectName("verticalLayout") 17 | self.A = QtWidgets.QComboBox(Dialog) 18 | self.A.setObjectName("A") 19 | self.verticalLayout.addWidget(self.A) 20 | self.B = QtWidgets.QComboBox(Dialog) 21 | self.B.setObjectName("B") 22 | self.verticalLayout.addWidget(self.B) 23 | self.horizontalLayout = QtWidgets.QHBoxLayout() 24 | self.horizontalLayout.setObjectName("horizontalLayout") 25 | self.savename = QtWidgets.QLineEdit(Dialog) 26 | self.savename.setObjectName("savename") 27 | self.horizontalLayout.addWidget(self.savename) 28 | self.browse = QtWidgets.QPushButton(Dialog) 29 | self.browse.setObjectName("browse") 30 | self.horizontalLayout.addWidget(self.browse) 31 | self.verticalLayout.addLayout(self.horizontalLayout) 32 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 33 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 34 | self.keep = QtWidgets.QCheckBox(Dialog) 35 | self.keep.setChecked(True) 36 | self.keep.setObjectName("keep") 37 | self.horizontalLayout_3.addWidget(self.keep) 38 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 39 | self.horizontalLayout_3.addItem(spacerItem) 40 | self.verticalLayout.addLayout(self.horizontalLayout_3) 41 | spacerItem1 = QtWidgets.QSpacerItem(20, 11, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 42 | self.verticalLayout.addItem(spacerItem1) 43 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 44 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 45 | spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 46 | self.horizontalLayout_2.addItem(spacerItem2) 47 | self.ok_button = QtWidgets.QPushButton(Dialog) 48 | self.ok_button.setObjectName("ok_button") 49 | self.horizontalLayout_2.addWidget(self.ok_button) 50 | self.cancel_button = QtWidgets.QPushButton(Dialog) 51 | self.cancel_button.setObjectName("cancel_button") 52 | self.horizontalLayout_2.addWidget(self.cancel_button) 53 | self.verticalLayout.addLayout(self.horizontalLayout_2) 54 | 55 | self.retranslateUi(Dialog) 56 | self.ok_button.clicked.connect(Dialog.accept) 57 | self.cancel_button.clicked.connect(Dialog.reject) 58 | QtCore.QMetaObject.connectSlotsByName(Dialog) 59 | 60 | def retranslateUi(self, Dialog): 61 | _translate = QtCore.QCoreApplication.translate 62 | Dialog.setWindowTitle(_translate("Dialog", "Merge Data")) 63 | self.browse.setText(_translate("Dialog", "Browse...")) 64 | self.keep.setText(_translate("Dialog", "Load merged data")) 65 | self.ok_button.setText(_translate("Dialog", "OK")) 66 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 67 | 68 | -------------------------------------------------------------------------------- /openstereo/ui/rotate_data_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\rotate_data.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(283, 185) 15 | self.verticalLayout = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout.setObjectName("verticalLayout") 17 | self.A = QtWidgets.QComboBox(Dialog) 18 | self.A.setObjectName("A") 19 | self.verticalLayout.addWidget(self.A) 20 | self.gridLayout = QtWidgets.QGridLayout() 21 | self.gridLayout.setObjectName("gridLayout") 22 | self.label_3 = QtWidgets.QLabel(Dialog) 23 | self.label_3.setObjectName("label_3") 24 | self.gridLayout.addWidget(self.label_3, 0, 1, 1, 1) 25 | self.label_4 = QtWidgets.QLabel(Dialog) 26 | self.label_4.setObjectName("label_4") 27 | self.gridLayout.addWidget(self.label_4, 0, 2, 1, 1) 28 | self.label_2 = QtWidgets.QLabel(Dialog) 29 | self.label_2.setObjectName("label_2") 30 | self.gridLayout.addWidget(self.label_2, 0, 3, 1, 1) 31 | self.label = QtWidgets.QLabel(Dialog) 32 | self.label.setObjectName("label") 33 | self.gridLayout.addWidget(self.label, 1, 0, 1, 1) 34 | self.trend = QtWidgets.QDoubleSpinBox(Dialog) 35 | self.trend.setMinimum(-360.0) 36 | self.trend.setMaximum(360.0) 37 | self.trend.setObjectName("trend") 38 | self.gridLayout.addWidget(self.trend, 1, 1, 1, 1) 39 | self.plunge = QtWidgets.QDoubleSpinBox(Dialog) 40 | self.plunge.setMinimum(-90.0) 41 | self.plunge.setMaximum(90.0) 42 | self.plunge.setObjectName("plunge") 43 | self.gridLayout.addWidget(self.plunge, 1, 2, 1, 1) 44 | self.angle = QtWidgets.QDoubleSpinBox(Dialog) 45 | self.angle.setMinimum(-360.0) 46 | self.angle.setMaximum(360.0) 47 | self.angle.setObjectName("angle") 48 | self.gridLayout.addWidget(self.angle, 1, 3, 1, 1) 49 | self.verticalLayout.addLayout(self.gridLayout) 50 | self.horizontalLayout = QtWidgets.QHBoxLayout() 51 | self.horizontalLayout.setObjectName("horizontalLayout") 52 | self.savename = QtWidgets.QLineEdit(Dialog) 53 | self.savename.setObjectName("savename") 54 | self.horizontalLayout.addWidget(self.savename) 55 | self.browse = QtWidgets.QPushButton(Dialog) 56 | self.browse.setObjectName("browse") 57 | self.horizontalLayout.addWidget(self.browse) 58 | self.verticalLayout.addLayout(self.horizontalLayout) 59 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout() 60 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 61 | self.keep = QtWidgets.QCheckBox(Dialog) 62 | self.keep.setChecked(True) 63 | self.keep.setObjectName("keep") 64 | self.horizontalLayout_3.addWidget(self.keep) 65 | spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 66 | self.horizontalLayout_3.addItem(spacerItem) 67 | self.verticalLayout.addLayout(self.horizontalLayout_3) 68 | spacerItem1 = QtWidgets.QSpacerItem(20, 11, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 69 | self.verticalLayout.addItem(spacerItem1) 70 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout() 71 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 72 | spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 73 | self.horizontalLayout_2.addItem(spacerItem2) 74 | self.ok_button = QtWidgets.QPushButton(Dialog) 75 | self.ok_button.setObjectName("ok_button") 76 | self.horizontalLayout_2.addWidget(self.ok_button) 77 | self.cancel_button = QtWidgets.QPushButton(Dialog) 78 | self.cancel_button.setObjectName("cancel_button") 79 | self.horizontalLayout_2.addWidget(self.cancel_button) 80 | self.verticalLayout.addLayout(self.horizontalLayout_2) 81 | 82 | self.retranslateUi(Dialog) 83 | self.ok_button.clicked.connect(Dialog.accept) 84 | self.cancel_button.clicked.connect(Dialog.reject) 85 | QtCore.QMetaObject.connectSlotsByName(Dialog) 86 | 87 | def retranslateUi(self, Dialog): 88 | _translate = QtCore.QCoreApplication.translate 89 | Dialog.setWindowTitle(_translate("Dialog", "Rotate Data")) 90 | self.label_3.setText(_translate("Dialog", "Trend")) 91 | self.label_4.setText(_translate("Dialog", "Plunge")) 92 | self.label_2.setText(_translate("Dialog", "Angle")) 93 | self.label.setText(_translate("Dialog", "Axis")) 94 | self.browse.setText(_translate("Dialog", "Browse...")) 95 | self.keep.setText(_translate("Dialog", "Load rotated data")) 96 | self.ok_button.setText(_translate("Dialog", "OK")) 97 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 98 | 99 | -------------------------------------------------------------------------------- /openstereo/ui/singleline_properties_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\singleline_properties.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(263, 428) 15 | self.verticalLayout_3 = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout_3.setObjectName("verticalLayout_3") 17 | self.groupBox_3 = QtWidgets.QGroupBox(Dialog) 18 | self.groupBox_3.setObjectName("groupBox_3") 19 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_3) 20 | self.verticalLayout_2.setObjectName("verticalLayout_2") 21 | self.prop_data_attitude = QtWidgets.QLineEdit(self.groupBox_3) 22 | self.prop_data_attitude.setObjectName("prop_data_attitude") 23 | self.verticalLayout_2.addWidget(self.prop_data_attitude) 24 | self.verticalLayout_3.addWidget(self.groupBox_3) 25 | self.verticalLayout = QtWidgets.QVBoxLayout() 26 | self.verticalLayout.setObjectName("verticalLayout") 27 | self.groupBox = QtWidgets.QGroupBox(Dialog) 28 | self.groupBox.setObjectName("groupBox") 29 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox) 30 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 31 | self.gridLayout = QtWidgets.QGridLayout() 32 | self.gridLayout.setObjectName("gridLayout") 33 | self.label_2 = QtWidgets.QLabel(self.groupBox) 34 | self.label_2.setObjectName("label_2") 35 | self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1) 36 | self.label_3 = QtWidgets.QLabel(self.groupBox) 37 | self.label_3.setObjectName("label_3") 38 | self.gridLayout.addWidget(self.label_3, 0, 2, 1, 1) 39 | self.label = QtWidgets.QLabel(self.groupBox) 40 | self.label.setObjectName("label") 41 | self.gridLayout.addWidget(self.label, 0, 0, 1, 1) 42 | self.prop_color_point_c = QtWidgets.QPushButton(self.groupBox) 43 | self.prop_color_point_c.setText("") 44 | self.prop_color_point_c.setObjectName("prop_color_point_c") 45 | self.gridLayout.addWidget(self.prop_color_point_c, 1, 0, 1, 1) 46 | self.prop_point_marker = QtWidgets.QComboBox(self.groupBox) 47 | self.prop_point_marker.setObjectName("prop_point_marker") 48 | self.prop_point_marker.addItem("") 49 | self.prop_point_marker.addItem("") 50 | self.prop_point_marker.addItem("") 51 | self.prop_point_marker.addItem("") 52 | self.prop_point_marker.addItem("") 53 | self.prop_point_marker.addItem("") 54 | self.prop_point_marker.addItem("") 55 | self.prop_point_marker.addItem("") 56 | self.prop_point_marker.addItem("") 57 | self.prop_point_marker.addItem("") 58 | self.prop_point_marker.addItem("") 59 | self.prop_point_marker.addItem("") 60 | self.prop_point_marker.addItem("") 61 | self.prop_point_marker.addItem("") 62 | self.prop_point_marker.addItem("") 63 | self.prop_point_marker.addItem("") 64 | self.prop_point_marker.addItem("") 65 | self.prop_point_marker.addItem("") 66 | self.prop_point_marker.addItem("") 67 | self.prop_point_marker.addItem("") 68 | self.gridLayout.addWidget(self.prop_point_marker, 1, 1, 1, 1) 69 | self.prop_point_ms = QtWidgets.QDoubleSpinBox(self.groupBox) 70 | self.prop_point_ms.setObjectName("prop_point_ms") 71 | self.gridLayout.addWidget(self.prop_point_ms, 1, 2, 1, 1) 72 | self.horizontalLayout_2.addLayout(self.gridLayout) 73 | self.verticalLayout.addWidget(self.groupBox) 74 | self.verticalLayout_3.addLayout(self.verticalLayout) 75 | self.groupBox_8 = QtWidgets.QGroupBox(Dialog) 76 | self.groupBox_8.setObjectName("groupBox_8") 77 | self.gridLayout_11 = QtWidgets.QGridLayout(self.groupBox_8) 78 | self.gridLayout_11.setObjectName("gridLayout_11") 79 | self.prop_legend_point = QtWidgets.QLineEdit(self.groupBox_8) 80 | self.prop_legend_point.setObjectName("prop_legend_point") 81 | self.gridLayout_11.addWidget(self.prop_legend_point, 0, 1, 1, 1) 82 | self.prop_checklegend_point = QtWidgets.QCheckBox(self.groupBox_8) 83 | self.prop_checklegend_point.setObjectName("prop_checklegend_point") 84 | self.gridLayout_11.addWidget(self.prop_checklegend_point, 0, 0, 1, 1) 85 | self.verticalLayout_3.addWidget(self.groupBox_8) 86 | spacerItem = QtWidgets.QSpacerItem(20, 41, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 87 | self.verticalLayout_3.addItem(spacerItem) 88 | self.horizontalLayout = QtWidgets.QHBoxLayout() 89 | self.horizontalLayout.setObjectName("horizontalLayout") 90 | spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 91 | self.horizontalLayout.addItem(spacerItem1) 92 | self.ok_button = QtWidgets.QPushButton(Dialog) 93 | self.ok_button.setObjectName("ok_button") 94 | self.horizontalLayout.addWidget(self.ok_button) 95 | self.cancel_button = QtWidgets.QPushButton(Dialog) 96 | self.cancel_button.setObjectName("cancel_button") 97 | self.horizontalLayout.addWidget(self.cancel_button) 98 | self.apply = QtWidgets.QPushButton(Dialog) 99 | self.apply.setObjectName("apply") 100 | self.horizontalLayout.addWidget(self.apply) 101 | self.verticalLayout_3.addLayout(self.horizontalLayout) 102 | self.groupBox_3.raise_() 103 | self.groupBox_8.raise_() 104 | 105 | self.retranslateUi(Dialog) 106 | self.ok_button.clicked.connect(Dialog.accept) 107 | self.cancel_button.clicked.connect(Dialog.reject) 108 | QtCore.QMetaObject.connectSlotsByName(Dialog) 109 | Dialog.setTabOrder(self.prop_color_point_c, self.prop_point_marker) 110 | Dialog.setTabOrder(self.prop_point_marker, self.prop_point_ms) 111 | Dialog.setTabOrder(self.prop_point_ms, self.cancel_button) 112 | Dialog.setTabOrder(self.cancel_button, self.apply) 113 | Dialog.setTabOrder(self.apply, self.ok_button) 114 | 115 | def retranslateUi(self, Dialog): 116 | _translate = QtCore.QCoreApplication.translate 117 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 118 | self.groupBox_3.setTitle(_translate("Dialog", "Attitude")) 119 | self.groupBox.setTitle(_translate("Dialog", "Pole")) 120 | self.label_2.setText(_translate("Dialog", "Symbol")) 121 | self.label_3.setText(_translate("Dialog", "Size")) 122 | self.label.setText(_translate("Dialog", "Color")) 123 | self.prop_point_marker.setItemText(0, _translate("Dialog", "o")) 124 | self.prop_point_marker.setItemText(1, _translate("Dialog", "^")) 125 | self.prop_point_marker.setItemText(2, _translate("Dialog", "v")) 126 | self.prop_point_marker.setItemText(3, _translate("Dialog", "<")) 127 | self.prop_point_marker.setItemText(4, _translate("Dialog", ">")) 128 | self.prop_point_marker.setItemText(5, _translate("Dialog", "s")) 129 | self.prop_point_marker.setItemText(6, _translate("Dialog", "+")) 130 | self.prop_point_marker.setItemText(7, _translate("Dialog", "x")) 131 | self.prop_point_marker.setItemText(8, _translate("Dialog", "D")) 132 | self.prop_point_marker.setItemText(9, _translate("Dialog", "d")) 133 | self.prop_point_marker.setItemText(10, _translate("Dialog", "h")) 134 | self.prop_point_marker.setItemText(11, _translate("Dialog", "H")) 135 | self.prop_point_marker.setItemText(12, _translate("Dialog", "p")) 136 | self.prop_point_marker.setItemText(13, _translate("Dialog", "|")) 137 | self.prop_point_marker.setItemText(14, _translate("Dialog", "_")) 138 | self.prop_point_marker.setItemText(15, _translate("Dialog", "*")) 139 | self.prop_point_marker.setItemText(16, _translate("Dialog", "1")) 140 | self.prop_point_marker.setItemText(17, _translate("Dialog", "2")) 141 | self.prop_point_marker.setItemText(18, _translate("Dialog", "3")) 142 | self.prop_point_marker.setItemText(19, _translate("Dialog", "4")) 143 | self.groupBox_8.setTitle(_translate("Dialog", "Data Legend")) 144 | self.prop_checklegend_point.setText(_translate("Dialog", "Line")) 145 | self.ok_button.setText(_translate("Dialog", "OK")) 146 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 147 | self.apply.setText(_translate("Dialog", "Apply")) 148 | 149 | -------------------------------------------------------------------------------- /openstereo/ui/singlesmallcircle_properties_ui.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # Form implementation generated from reading ui file 'ui_files\singlesmallcircle_properties.ui' 4 | # 5 | # Created by: PyQt5 UI code generator 5.9.2 6 | # 7 | # WARNING! All changes made in this file will be lost! 8 | 9 | from PyQt5 import QtCore, QtGui, QtWidgets 10 | 11 | class Ui_Dialog(object): 12 | def setupUi(self, Dialog): 13 | Dialog.setObjectName("Dialog") 14 | Dialog.resize(263, 428) 15 | self.verticalLayout_3 = QtWidgets.QVBoxLayout(Dialog) 16 | self.verticalLayout_3.setObjectName("verticalLayout_3") 17 | self.groupBox_3 = QtWidgets.QGroupBox(Dialog) 18 | self.groupBox_3.setObjectName("groupBox_3") 19 | self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.groupBox_3) 20 | self.verticalLayout_2.setObjectName("verticalLayout_2") 21 | self.prop_data_attitude = QtWidgets.QLineEdit(self.groupBox_3) 22 | self.prop_data_attitude.setObjectName("prop_data_attitude") 23 | self.verticalLayout_2.addWidget(self.prop_data_attitude) 24 | self.verticalLayout_3.addWidget(self.groupBox_3) 25 | self.verticalLayout = QtWidgets.QVBoxLayout() 26 | self.verticalLayout.setObjectName("verticalLayout") 27 | self.groupBox = QtWidgets.QGroupBox(Dialog) 28 | self.groupBox.setObjectName("groupBox") 29 | self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.groupBox) 30 | self.horizontalLayout_2.setObjectName("horizontalLayout_2") 31 | self.gridLayout = QtWidgets.QGridLayout() 32 | self.gridLayout.setObjectName("gridLayout") 33 | self.label_2 = QtWidgets.QLabel(self.groupBox) 34 | self.label_2.setObjectName("label_2") 35 | self.gridLayout.addWidget(self.label_2, 0, 1, 1, 1) 36 | self.label_3 = QtWidgets.QLabel(self.groupBox) 37 | self.label_3.setObjectName("label_3") 38 | self.gridLayout.addWidget(self.label_3, 0, 2, 1, 1) 39 | self.label = QtWidgets.QLabel(self.groupBox) 40 | self.label.setObjectName("label") 41 | self.gridLayout.addWidget(self.label, 0, 0, 1, 1) 42 | self.prop_color_scaxis_c = QtWidgets.QPushButton(self.groupBox) 43 | self.prop_color_scaxis_c.setText("") 44 | self.prop_color_scaxis_c.setObjectName("prop_color_scaxis_c") 45 | self.gridLayout.addWidget(self.prop_color_scaxis_c, 1, 0, 1, 1) 46 | self.prop_scaxis_marker = QtWidgets.QComboBox(self.groupBox) 47 | self.prop_scaxis_marker.setObjectName("prop_scaxis_marker") 48 | self.prop_scaxis_marker.addItem("") 49 | self.prop_scaxis_marker.addItem("") 50 | self.prop_scaxis_marker.addItem("") 51 | self.prop_scaxis_marker.addItem("") 52 | self.prop_scaxis_marker.addItem("") 53 | self.prop_scaxis_marker.addItem("") 54 | self.prop_scaxis_marker.addItem("") 55 | self.prop_scaxis_marker.addItem("") 56 | self.prop_scaxis_marker.addItem("") 57 | self.prop_scaxis_marker.addItem("") 58 | self.prop_scaxis_marker.addItem("") 59 | self.prop_scaxis_marker.addItem("") 60 | self.prop_scaxis_marker.addItem("") 61 | self.prop_scaxis_marker.addItem("") 62 | self.prop_scaxis_marker.addItem("") 63 | self.prop_scaxis_marker.addItem("") 64 | self.prop_scaxis_marker.addItem("") 65 | self.prop_scaxis_marker.addItem("") 66 | self.prop_scaxis_marker.addItem("") 67 | self.prop_scaxis_marker.addItem("") 68 | self.gridLayout.addWidget(self.prop_scaxis_marker, 1, 1, 1, 1) 69 | self.prop_scaxis_ms = QtWidgets.QDoubleSpinBox(self.groupBox) 70 | self.prop_scaxis_ms.setObjectName("prop_scaxis_ms") 71 | self.gridLayout.addWidget(self.prop_scaxis_ms, 1, 2, 1, 1) 72 | self.horizontalLayout_2.addLayout(self.gridLayout) 73 | self.verticalLayout.addWidget(self.groupBox) 74 | self.groupBox_2 = QtWidgets.QGroupBox(Dialog) 75 | self.groupBox_2.setObjectName("groupBox_2") 76 | self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.groupBox_2) 77 | self.horizontalLayout_3.setObjectName("horizontalLayout_3") 78 | self.gridLayout_2 = QtWidgets.QGridLayout() 79 | self.gridLayout_2.setObjectName("gridLayout_2") 80 | self.label_4 = QtWidgets.QLabel(self.groupBox_2) 81 | self.label_4.setObjectName("label_4") 82 | self.gridLayout_2.addWidget(self.label_4, 0, 1, 1, 1) 83 | self.label_6 = QtWidgets.QLabel(self.groupBox_2) 84 | self.label_6.setObjectName("label_6") 85 | self.gridLayout_2.addWidget(self.label_6, 0, 2, 1, 1) 86 | self.label_5 = QtWidgets.QLabel(self.groupBox_2) 87 | self.label_5.setObjectName("label_5") 88 | self.gridLayout_2.addWidget(self.label_5, 0, 0, 1, 1) 89 | self.prop_color_sccirc_colors = QtWidgets.QPushButton(self.groupBox_2) 90 | self.prop_color_sccirc_colors.setText("") 91 | self.prop_color_sccirc_colors.setObjectName("prop_color_sccirc_colors") 92 | self.gridLayout_2.addWidget(self.prop_color_sccirc_colors, 1, 0, 1, 1) 93 | self.prop_sccirc_linestyles = QtWidgets.QComboBox(self.groupBox_2) 94 | self.prop_sccirc_linestyles.setObjectName("prop_sccirc_linestyles") 95 | self.prop_sccirc_linestyles.addItem("") 96 | self.prop_sccirc_linestyles.addItem("") 97 | self.prop_sccirc_linestyles.addItem("") 98 | self.prop_sccirc_linestyles.addItem("") 99 | self.gridLayout_2.addWidget(self.prop_sccirc_linestyles, 1, 1, 1, 1) 100 | self.prop_sccirc_linewidths = QtWidgets.QDoubleSpinBox(self.groupBox_2) 101 | self.prop_sccirc_linewidths.setObjectName("prop_sccirc_linewidths") 102 | self.gridLayout_2.addWidget(self.prop_sccirc_linewidths, 1, 2, 1, 1) 103 | self.horizontalLayout_3.addLayout(self.gridLayout_2) 104 | self.verticalLayout.addWidget(self.groupBox_2) 105 | self.verticalLayout_3.addLayout(self.verticalLayout) 106 | self.groupBox_8 = QtWidgets.QGroupBox(Dialog) 107 | self.groupBox_8.setObjectName("groupBox_8") 108 | self.gridLayout_11 = QtWidgets.QGridLayout(self.groupBox_8) 109 | self.gridLayout_11.setObjectName("gridLayout_11") 110 | self.prop_legend_scaxis = QtWidgets.QLineEdit(self.groupBox_8) 111 | self.prop_legend_scaxis.setObjectName("prop_legend_scaxis") 112 | self.gridLayout_11.addWidget(self.prop_legend_scaxis, 0, 1, 1, 1) 113 | self.prop_checklegend_sccirc = QtWidgets.QCheckBox(self.groupBox_8) 114 | self.prop_checklegend_sccirc.setObjectName("prop_checklegend_sccirc") 115 | self.gridLayout_11.addWidget(self.prop_checklegend_sccirc, 1, 0, 1, 1) 116 | self.prop_legend_sccirc = QtWidgets.QLineEdit(self.groupBox_8) 117 | self.prop_legend_sccirc.setObjectName("prop_legend_sccirc") 118 | self.gridLayout_11.addWidget(self.prop_legend_sccirc, 1, 1, 1, 1) 119 | self.prop_checklegend_scaxis = QtWidgets.QCheckBox(self.groupBox_8) 120 | self.prop_checklegend_scaxis.setObjectName("prop_checklegend_scaxis") 121 | self.gridLayout_11.addWidget(self.prop_checklegend_scaxis, 0, 0, 1, 1) 122 | self.verticalLayout_3.addWidget(self.groupBox_8) 123 | spacerItem = QtWidgets.QSpacerItem(20, 41, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding) 124 | self.verticalLayout_3.addItem(spacerItem) 125 | self.horizontalLayout = QtWidgets.QHBoxLayout() 126 | self.horizontalLayout.setObjectName("horizontalLayout") 127 | spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum) 128 | self.horizontalLayout.addItem(spacerItem1) 129 | self.ok_button = QtWidgets.QPushButton(Dialog) 130 | self.ok_button.setObjectName("ok_button") 131 | self.horizontalLayout.addWidget(self.ok_button) 132 | self.cancel_button = QtWidgets.QPushButton(Dialog) 133 | self.cancel_button.setObjectName("cancel_button") 134 | self.horizontalLayout.addWidget(self.cancel_button) 135 | self.apply = QtWidgets.QPushButton(Dialog) 136 | self.apply.setObjectName("apply") 137 | self.horizontalLayout.addWidget(self.apply) 138 | self.verticalLayout_3.addLayout(self.horizontalLayout) 139 | self.groupBox_3.raise_() 140 | self.groupBox_8.raise_() 141 | 142 | self.retranslateUi(Dialog) 143 | self.ok_button.clicked.connect(Dialog.accept) 144 | self.cancel_button.clicked.connect(Dialog.reject) 145 | QtCore.QMetaObject.connectSlotsByName(Dialog) 146 | Dialog.setTabOrder(self.prop_color_scaxis_c, self.prop_scaxis_marker) 147 | Dialog.setTabOrder(self.prop_scaxis_marker, self.prop_scaxis_ms) 148 | Dialog.setTabOrder(self.prop_scaxis_ms, self.prop_color_sccirc_colors) 149 | Dialog.setTabOrder(self.prop_color_sccirc_colors, self.prop_sccirc_linestyles) 150 | Dialog.setTabOrder(self.prop_sccirc_linestyles, self.prop_sccirc_linewidths) 151 | Dialog.setTabOrder(self.prop_sccirc_linewidths, self.cancel_button) 152 | Dialog.setTabOrder(self.cancel_button, self.apply) 153 | Dialog.setTabOrder(self.apply, self.ok_button) 154 | 155 | def retranslateUi(self, Dialog): 156 | _translate = QtCore.QCoreApplication.translate 157 | Dialog.setWindowTitle(_translate("Dialog", "Dialog")) 158 | self.groupBox_3.setTitle(_translate("Dialog", "Attitude")) 159 | self.groupBox.setTitle(_translate("Dialog", "Pole")) 160 | self.label_2.setText(_translate("Dialog", "Symbol")) 161 | self.label_3.setText(_translate("Dialog", "Size")) 162 | self.label.setText(_translate("Dialog", "Color")) 163 | self.prop_scaxis_marker.setItemText(0, _translate("Dialog", "o")) 164 | self.prop_scaxis_marker.setItemText(1, _translate("Dialog", "^")) 165 | self.prop_scaxis_marker.setItemText(2, _translate("Dialog", "v")) 166 | self.prop_scaxis_marker.setItemText(3, _translate("Dialog", "<")) 167 | self.prop_scaxis_marker.setItemText(4, _translate("Dialog", ">")) 168 | self.prop_scaxis_marker.setItemText(5, _translate("Dialog", "s")) 169 | self.prop_scaxis_marker.setItemText(6, _translate("Dialog", "+")) 170 | self.prop_scaxis_marker.setItemText(7, _translate("Dialog", "x")) 171 | self.prop_scaxis_marker.setItemText(8, _translate("Dialog", "D")) 172 | self.prop_scaxis_marker.setItemText(9, _translate("Dialog", "d")) 173 | self.prop_scaxis_marker.setItemText(10, _translate("Dialog", "h")) 174 | self.prop_scaxis_marker.setItemText(11, _translate("Dialog", "H")) 175 | self.prop_scaxis_marker.setItemText(12, _translate("Dialog", "p")) 176 | self.prop_scaxis_marker.setItemText(13, _translate("Dialog", "|")) 177 | self.prop_scaxis_marker.setItemText(14, _translate("Dialog", "_")) 178 | self.prop_scaxis_marker.setItemText(15, _translate("Dialog", "*")) 179 | self.prop_scaxis_marker.setItemText(16, _translate("Dialog", "1")) 180 | self.prop_scaxis_marker.setItemText(17, _translate("Dialog", "2")) 181 | self.prop_scaxis_marker.setItemText(18, _translate("Dialog", "3")) 182 | self.prop_scaxis_marker.setItemText(19, _translate("Dialog", "4")) 183 | self.groupBox_2.setTitle(_translate("Dialog", "Small Circle")) 184 | self.label_4.setText(_translate("Dialog", "Symbol")) 185 | self.label_6.setText(_translate("Dialog", "Width")) 186 | self.label_5.setText(_translate("Dialog", "Color")) 187 | self.prop_sccirc_linestyles.setItemText(0, _translate("Dialog", "-")) 188 | self.prop_sccirc_linestyles.setItemText(1, _translate("Dialog", ":")) 189 | self.prop_sccirc_linestyles.setItemText(2, _translate("Dialog", "--")) 190 | self.prop_sccirc_linestyles.setItemText(3, _translate("Dialog", "-.")) 191 | self.groupBox_8.setTitle(_translate("Dialog", "Data Legend")) 192 | self.prop_checklegend_sccirc.setText(_translate("Dialog", "Small Circle")) 193 | self.prop_checklegend_scaxis.setText(_translate("Dialog", "Axis")) 194 | self.ok_button.setText(_translate("Dialog", "OK")) 195 | self.cancel_button.setText(_translate("Dialog", "Cancel")) 196 | self.apply.setText(_translate("Dialog", "Apply")) 197 | 198 | -------------------------------------------------------------------------------- /openstereo/ui/ui_interface.py: -------------------------------------------------------------------------------- 1 | import re 2 | 3 | from PyQt5 import QtWidgets, QtGui 4 | 5 | props_re = re.compile("([^_]+)_(color_)?(.+)_([^_]+)") 6 | 7 | 8 | def color_button_factory(button, button_name): 9 | def color_button_dialog(): 10 | col = QtWidgets.QColorDialog.getColor() 11 | if col.isValid(): 12 | button.setStyleSheet( 13 | "QWidget#%s { background-color: %s }" 14 | % (button_name, col.name()) 15 | ) 16 | # button.palette().color(QtWidgets.QPalette.Background).name() 17 | 18 | return color_button_dialog 19 | 20 | 21 | def populate_properties_dialog( 22 | properties_ui, item, update_data_only=False, **kwargs 23 | ): 24 | dialog_widgets = vars(properties_ui) 25 | for widget_name in dialog_widgets: 26 | parsed_widget = props_re.match(widget_name) 27 | if parsed_widget is None: 28 | continue 29 | widget = dialog_widgets[widget_name] 30 | category, is_color, widget_item, prop_name = parsed_widget.groups() 31 | if category == "prop": 32 | item_props = item.get_item_props(widget_item) 33 | if is_color: 34 | if not update_data_only: 35 | widget.clicked.connect( 36 | color_button_factory(widget, widget_name) 37 | ) 38 | widget.setStyleSheet( 39 | "QWidget#%s { background-color: %s }" 40 | % (widget_name, item_props[prop_name]) 41 | ) 42 | # http://stackoverflow.com/a/22798753/1457481 43 | elif type(widget) == QtWidgets.QComboBox: 44 | index = ( 45 | widget.findText(item_props[prop_name]) 46 | if prop_name in item_props 47 | else 0 48 | ) 49 | if index >= 0: 50 | widget.setCurrentIndex(index) 51 | elif ( 52 | type(widget) == QtWidgets.QCheckBox 53 | or type(widget) == QtWidgets.QRadioButton 54 | ): 55 | widget.setChecked(item_props[prop_name]) 56 | elif ( 57 | type(widget) == QtWidgets.QLineEdit 58 | or type(widget) == QtWidgets.QLabel 59 | ): 60 | widget.setText(item_props[prop_name]) 61 | elif type(widget) == QtWidgets.QTextEdit: 62 | widget.clear() 63 | widget.insertPlainText(item_props[prop_name]) 64 | else: 65 | widget.setValue(item_props[prop_name]) 66 | if category == "show": 67 | if widget_item in kwargs: 68 | attribute = kwargs[widget_item][prop_name] 69 | else: 70 | item_data = getattr(item, widget_item) 71 | if not isinstance(item_data, dict): 72 | attribute = getattr(item_data, prop_name) 73 | else: 74 | attribute = item_data[prop_name] 75 | if type(widget) == QtWidgets.QTextEdit: 76 | widget.clear() 77 | widget.insertPlainText(attribute) 78 | elif ( 79 | type(widget) == QtWidgets.QLineEdit 80 | or type(widget) == QtWidgets.QLabel 81 | ): 82 | widget.setText(attribute) 83 | if category == "do" and not update_data_only: 84 | if widget_item in kwargs: 85 | action = kwargs[widget_item][prop_name] 86 | else: 87 | item_data = getattr(item, widget_item) 88 | action = getattr(item_data, prop_name) 89 | if type(widget) == QtWidgets.QPushButton: 90 | widget.clicked.connect(action) 91 | 92 | 93 | def parse_properties_dialog(properties_ui, item, post_hook=None): 94 | dialog_widgets = vars(properties_ui) 95 | for widget_name in dialog_widgets: 96 | parsed_widget = props_re.match(widget_name) 97 | if parsed_widget is None: 98 | continue 99 | widget = dialog_widgets[widget_name] 100 | category, is_color, widget_item, prop_name = parsed_widget.groups() 101 | if category == "prop": 102 | item_props = item.get_item_props(widget_item) 103 | if is_color: 104 | item_props[prop_name] = ( 105 | widget.palette().color(QtGui.QPalette.Background).name() 106 | ) 107 | # http://stackoverflow.com/a/6062987/1457481 108 | elif type(widget) == QtWidgets.QComboBox: 109 | item_props[prop_name] = str(widget.currentText()) 110 | elif ( 111 | type(widget) == QtWidgets.QCheckBox 112 | or type(widget) == QtWidgets.QRadioButton 113 | ): 114 | item_props[prop_name] = widget.isChecked() 115 | elif ( 116 | type(widget) == QtWidgets.QLineEdit 117 | or type(widget) == QtWidgets.QLabel 118 | ): 119 | item_props[prop_name] = widget.text() 120 | elif type(widget) == QtWidgets.QTextEdit: 121 | item_props[prop_name] = widget.toPlainText() 122 | else: 123 | item_props[prop_name] = widget.value() 124 | if post_hook is not None: 125 | for f in post_hook: 126 | f() # could pass self to post_hook? 127 | 128 | 129 | def apply_action_factory(main_window, item): 130 | def apply_action(): 131 | if main_window.actionPlot_on_Apply.isChecked(): 132 | main_window.plot_data() 133 | populate_properties_dialog(item.dialog_ui, item, update_data_only=True) 134 | return apply_action 135 | 136 | 137 | def update_data_button_factory(item, post_hook=None): 138 | def update_data(): 139 | data_table = item.item_table_ui.data_table 140 | data = [] 141 | m = data_table.rowCount() 142 | n = data_table.columnCount() 143 | for i in range(m): 144 | row = [] 145 | row_empty = True 146 | for j in range(n): 147 | cell = data_table.item(i, j) 148 | if cell is not None: 149 | row_empty = False 150 | if cell.text(): 151 | row.append(cell.text()) 152 | else: 153 | row.append("0") 154 | else: 155 | row.append("0") 156 | if not row_empty: 157 | data.append(row) 158 | item.auttitude_data.input_data = data 159 | item.reload_data_from_internal() 160 | selected = data_table.selectedIndexes() 161 | si = sj = 0 162 | if len(selected) == 1: 163 | si = selected[0].row() 164 | sj = selected[0].column() 165 | if post_hook is not None: 166 | for f in post_hook: 167 | f() 168 | set_selected_item(data_table, si, sj) 169 | 170 | return update_data 171 | 172 | 173 | # TODO: abstract these to a class, should be better by now 174 | def clear_table(table): 175 | for i in reversed(range(table.rowCount())): 176 | table.removeRow(i) 177 | table.setRowCount(0) 178 | table.setColumnCount(0) 179 | 180 | 181 | def set_selected_item(table, i, j): 182 | m = table.rowCount() 183 | n = table.columnCount() 184 | i = min(i, m) 185 | j = min(j, n) 186 | cell = table.item(i, j) 187 | # table.scrollToItem(cell) 188 | table.setCurrentItem(cell) 189 | 190 | 191 | def populate_item_table(item): # TODO: keep selection 192 | data = item.auttitude_data.input_data 193 | table = item.item_table_ui.data_table 194 | clear_table(table) 195 | m = len(data) 196 | n = len(data[0]) 197 | table.setRowCount(m + 10) 198 | table.setColumnCount(n) 199 | if item.kwargs["data_headers"] is not None: 200 | table.setHorizontalHeaderLabels(item.kwargs["data_headers"]) 201 | for i in range(m): 202 | for j in range(n): 203 | table.setItem(i, j, QtWidgets.QTableWidgetItem(str(data[i][j]))) 204 | -------------------------------------------------------------------------------- /os_gui.py: -------------------------------------------------------------------------------- 1 | from openstereo.os_base import os_main 2 | 3 | if __name__ == '__main__': 4 | os_main() 5 | -------------------------------------------------------------------------------- /os_installer32.cfg: -------------------------------------------------------------------------------- 1 | [Application] 2 | name=OpenStereo 3 | version=0.9 4 | # How to launch the app - this calls the 'main' function from the 'myapp' package: 5 | entry_point=openstereo.os_base:os_main 6 | license_file=LICENSE 7 | icon=ui_files/icons/openstereo.ico 8 | 9 | [Python] 10 | version=3.6.2 11 | bitness=32 12 | 13 | [Include] 14 | # Packages from PyPI that your application requires, one per line 15 | # These must have wheels on PyPI: 16 | pypi_wheels = numpy==1.14.3 17 | matplotlib==2.2.2 18 | six==1.11.0 19 | PyQt5==5.10.1 20 | sip==4.19.8 21 | xlrd==1.1.0 22 | XlsxWriter==1.1.1 23 | pyshp==1.2.12 24 | networkx==2.1 25 | ply2atti==0.2.4 26 | auttitude==0.1.0a0 27 | python-dateutil==2.6.1 28 | pyparsing==2.2.0 29 | cycler==0.10.0 30 | kiwisolver==1.0.1 31 | decorator==4.3.0 32 | setuptools==39.1.0 33 | appdirs==1.4.3 34 | scipy==1.1.0 35 | chardet==3.0.4 36 | # requests==2.19.1 37 | 38 | extra_wheel_sources = extra_wheels 39 | 40 | packages = openstereo 41 | 42 | # To bundle packages which don't publish wheels, see the docs on the 43 | # config file. -------------------------------------------------------------------------------- /os_installer64.cfg: -------------------------------------------------------------------------------- 1 | [Application] 2 | name=OpenStereo 3 | version=0.9 4 | # How to launch the app - this calls the 'main' function from the 'myapp' package: 5 | entry_point=openstereo.os_base:os_main 6 | license_file=LICENSE 7 | icon=ui_files/icons/openstereo.ico 8 | 9 | [Python] 10 | version=3.6.2 11 | bitness=64 12 | 13 | [Include] 14 | # Packages from PyPI that your application requires, one per line 15 | # These must have wheels on PyPI: 16 | pypi_wheels = numpy==1.14.3 17 | matplotlib==2.2.2 18 | six==1.11.0 19 | PyQt5==5.10.1 20 | sip==4.19.8 21 | xlrd==1.1.0 22 | XlsxWriter==1.1.1 23 | pyshp==1.2.12 24 | networkx==2.1 25 | ply2atti==0.2.4 26 | auttitude==0.1.0a0 27 | python-dateutil==2.6.1 28 | pyparsing==2.2.0 29 | cycler==0.10.0 30 | kiwisolver==1.0.1 31 | decorator==4.3.0 32 | setuptools==39.1.0 33 | appdirs==1.4.3 34 | scipy==1.1.0 35 | chardet==3.0.4 36 | # requests==2.19.1 37 | 38 | extra_wheel_sources = extra_wheels 39 | 40 | packages = openstereo 41 | 42 | # To bundle packages which don't publish wheels, see the docs on the 43 | # config file. -------------------------------------------------------------------------------- /requires.txt: -------------------------------------------------------------------------------- 1 | PyQt5 2 | numpy 3 | matplotlib 4 | xlrd 5 | PyShp 6 | networkx 7 | ply2atti 8 | auttitude 9 | appdirs 10 | chardet 11 | pynsist -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | from setuptools import setup, find_packages 4 | import distutils.cmd 5 | import distutils.log 6 | from glob import glob 7 | from os import path 8 | 9 | 10 | class BuildUICommand(distutils.cmd.Command): 11 | """Runs pyuic5 on all .ui files on the ui folder""" 12 | 13 | description = "runs pyuic5 on .ui files inside ./ui/" 14 | user_options = [] 15 | 16 | def initialize_options(self): 17 | pass 18 | 19 | def finalize_options(self): 20 | pass 21 | 22 | def run(self): 23 | """Run command.""" 24 | from PyQt5.uic import compileUi 25 | 26 | for ui_file in glob("ui_files/*.ui"): 27 | basename = path.splitext(path.basename(ui_file))[0] 28 | py_file = path.join("openstereo", "ui", basename + "_ui.py") 29 | self.announce( 30 | "Compiling Qt Designer source: %s" % str(ui_file), 31 | level=distutils.log.INFO, 32 | ) 33 | with open(py_file, "w") as fout: 34 | compileUi(ui_file, fout) 35 | # also run: 36 | # pyrcc5 .\ui_files\openstereo.qrc -o .\openstereo\ui\openstereo_rc.py 37 | # if resources changed 38 | # Thanks https://ralsina.me/stories/BBS49.html 39 | # for translation: 40 | # pylupdate5 -verbose ui_files/openstereo.pro 41 | # lrelease -verbose ui_files\i18n\openstereo_pt_BR.ts 42 | # rm .\openstereo\ui\openstereo_rc.py 43 | # pyrcc5 -verbose .\ui_files\openstereo.qrc -o .\openstereo\ui\openstereo_rc.py 44 | 45 | 46 | # class AddGitHashCommand(distutils.cmd.Command): 47 | # """Writes the hash of the current git master head to the file 48 | # openstereo/tools/git_hash.py.""" 49 | # description = "adds the hash of the master head to the module" 50 | # user_options = [] 51 | 52 | # def initialize_options(self): 53 | # pass 54 | 55 | # def finalize_options(self): 56 | # pass 57 | 58 | # def run(self): 59 | # """Run command.""" 60 | # with open(".git/refs/heads/master", "r") as fin,\ 61 | # open("./openstereo/tools/git_hash.py", "w") as fout: 62 | # fout.write(f"master_head = '{fin.read()}''") 63 | 64 | 65 | setup( 66 | name="OpenStereo", 67 | version="2.0b12", 68 | packages=find_packages(), 69 | entry_points={ 70 | "console_scripts": ["openstereo = openstereo.os_base:os_main"] 71 | }, 72 | install_requires=[ 73 | "numpy", 74 | "matplotlib", 75 | "appdirs", 76 | "PyQt5", 77 | "xlrd", 78 | "PyShp", 79 | "networkx", 80 | "ply2atti", 81 | "auttitude==0.1.4", 82 | "chardet", 83 | ], 84 | cmdclass={ 85 | "buildui": BuildUICommand, 86 | # 'addhash': AddGitHashCommand 87 | }, 88 | # metadata for upload to PyPI 89 | author="Arthur Endlein", 90 | author_email="endarthur@gmail.com", 91 | description="Software for analysis of structural data", 92 | license="GPLv3", 93 | keywords="geology attitude stereonet projection structural", 94 | url="https://github.com/spamlab-iee/os", 95 | download_url="https://github.com/spamlab-iee/os/archive/v2.0b12.tar.gz", 96 | classifiers=[ 97 | "Development Status :: 3 - Alpha", 98 | "Topic :: Scientific/Engineering", 99 | "License :: OSI Approved :: GNU General Public License v3 (GPLv3)", 100 | ], 101 | options={ 102 | "app": {"formal_name": "openstereo", "bundle": "io.github.endarthur"}, 103 | "macos": {"icon": "ui_files/icons/openstereo_mac"}, 104 | }, 105 | ) 106 | -------------------------------------------------------------------------------- /test_icon.py: -------------------------------------------------------------------------------- 1 | import os 2 | from win32com.shell import shell, shellcon 3 | import winerror 4 | 5 | class IconOverlay: 6 | 7 | _reg_clsid_ = '{4FC554DF-F0EE-4A4F-966C-9C49CCF14D59}' 8 | _reg_progid_ = 'TJG.PythonPackagesOverlayHandler' 9 | _reg_desc_ = 'Icon Overlay Handler to indicate Python packages' 10 | _public_methods_ = ['GetOverlayInfo', 'GetPriority', 'IsMemberOf'] 11 | _com_interfaces_ = [shell.IID_IShellIconOverlayIdentifier] 12 | 13 | def GetOverlayInfo(self): 14 | return (r'C:\Program Files\TortoiseHg\icons\status\added.ico', 0, shellcon.ISIOI_ICONFILE) 15 | 16 | def GetPriority(self): 17 | return 50 18 | 19 | def IsMemberOf(self, fname, attributes): 20 | if os.path.exists (os.path.join (fname, "__init__.py")): 21 | return winerror.S_OK 22 | return winerror.E_FAIL 23 | 24 | if __name__=='__main__': 25 | import win32api 26 | import win32con 27 | import win32com.server.register 28 | 29 | win32com.server.register.UseCommandLine (IconOverlay) 30 | keyname = r'Software\Microsoft\Windows\CurrentVersion\Explorer\ShellIconOverlayIdentifiers\PyPackageOverlay' 31 | key = win32api.RegCreateKey (win32con.HKEY_LOCAL_MACHINE, keyname) 32 | win32api.RegSetValue (key, None, win32con.REG_SZ, IconOverlay._reg_clsid_) -------------------------------------------------------------------------------- /ui_files/clipboard.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 287 10 | 499 11 | 12 | 13 | 14 | Import Data 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | false 23 | 24 | 25 | 26 | 27 | 28 | 29 | Browse... 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Data Type 39 | 40 | 41 | 42 | 43 | 44 | Lines 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | Planes 54 | 55 | 56 | true 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | Dip Direction 65 | 66 | 67 | 68 | 69 | Direction 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | Small Circles 80 | 81 | 82 | 83 | 84 | 85 | 86 | Azimuth Data 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | File Settings 97 | 98 | 99 | 100 | 101 | 102 | Skip Rows 103 | 104 | 105 | 106 | 107 | 108 | 109 | Header Row 110 | 111 | 112 | true 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | Delimiter 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | Worksheet 139 | 140 | 141 | 142 | 143 | 144 | 145 | Comment 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | Attitude Columns 159 | 160 | 161 | 162 | 163 | 164 | Dip Direction 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | Dip 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | Alpha 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | Qt::Horizontal 200 | 201 | 202 | 203 | 40 204 | 20 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | OK 213 | 214 | 215 | 216 | 217 | 218 | 219 | Cancel 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | ok_button 231 | clicked() 232 | Dialog 233 | accept() 234 | 235 | 236 | 163 237 | 430 238 | 239 | 240 | 145 241 | 225 242 | 243 | 244 | 245 | 246 | cancel_button 247 | clicked() 248 | Dialog 249 | reject() 250 | 251 | 252 | 244 253 | 430 254 | 255 | 256 | 145 257 | 225 258 | 259 | 260 | 261 | 262 | 263 | -------------------------------------------------------------------------------- /ui_files/difference_vectors.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 227 10 | 193 11 | 12 | 13 | 14 | Difference Vectors 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | % largest 26 | 27 | 28 | true 29 | 30 | 31 | 32 | 33 | 34 | 35 | 100.000000000000000 36 | 37 | 38 | 100.000000000000000 39 | 40 | 41 | 42 | 43 | 44 | 45 | n largest 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | Qt::Vertical 58 | 59 | 60 | 61 | 20 62 | 61 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | Qt::Horizontal 73 | 74 | 75 | 76 | 40 77 | 20 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | OK 86 | 87 | 88 | 89 | 90 | 91 | 92 | Cancel 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | ok_button 104 | clicked() 105 | Dialog 106 | accept() 107 | 108 | 109 | 234 110 | 262 111 | 112 | 113 | 199 114 | 149 115 | 116 | 117 | 118 | 119 | cancel_button 120 | clicked() 121 | Dialog 122 | reject() 123 | 124 | 125 | 315 126 | 262 127 | 128 | 129 | 199 130 | 149 131 | 132 | 133 | 134 | 135 | 136 | -------------------------------------------------------------------------------- /ui_files/fault_data.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 268 10 | 109 11 | 12 | 13 | 14 | Build Fault Data Item 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Planes 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | Lines 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | Qt::Vertical 45 | 46 | 47 | 48 | 20 49 | 11 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | Qt::Horizontal 60 | 61 | 62 | 63 | 40 64 | 20 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | OK 73 | 74 | 75 | 76 | 77 | 78 | 79 | Cancel 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | ok_button 91 | clicked() 92 | Dialog 93 | accept() 94 | 95 | 96 | 156 97 | 152 98 | 99 | 100 | 142 101 | 86 102 | 103 | 104 | 105 | 106 | cancel_button 107 | clicked() 108 | Dialog 109 | reject() 110 | 111 | 112 | 237 113 | 152 114 | 115 | 116 | 142 117 | 86 118 | 119 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /ui_files/i18n/openstereo_pt_BR.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/ui_files/i18n/openstereo_pt_BR.qm -------------------------------------------------------------------------------- /ui_files/icons/openstereo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/ui_files/icons/openstereo.ico -------------------------------------------------------------------------------- /ui_files/icons/openstereo_mac.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spamlab-iee/os/f265bfda1a7f104f2b334e0eb42aea9f38f9bf57/ui_files/icons/openstereo_mac.icns -------------------------------------------------------------------------------- /ui_files/import_dialog.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 310 10 | 552 11 | 12 | 13 | 14 | Import Data 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | false 23 | 24 | 25 | 26 | 27 | 28 | 29 | Browse... 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | Data Type 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | Lines 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | Trend/Plunge 55 | 56 | 57 | 58 | 59 | Rake 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | Planes 72 | 73 | 74 | true 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Dip Direction 83 | 84 | 85 | 86 | 87 | Direction 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | Small Circles 98 | 99 | 100 | 101 | 102 | 103 | 104 | Azimuth Data 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | File Settings 115 | 116 | 117 | 118 | 119 | 120 | Skip Rows 121 | 122 | 123 | 124 | 125 | 126 | 127 | Header Row 128 | 129 | 130 | true 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | Delimiter 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | Worksheet 157 | 158 | 159 | 160 | 161 | 162 | 163 | Comment 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | Attitude Columns 177 | 178 | 179 | 180 | 181 | 182 | Dip Direction 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | Dip 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | Rake 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | Alpha 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | Qt::Horizontal 228 | 229 | 230 | 231 | 40 232 | 20 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | OK 241 | 242 | 243 | 244 | 245 | 246 | 247 | Cancel 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | ok_button 259 | clicked() 260 | Dialog 261 | accept() 262 | 263 | 264 | 163 265 | 430 266 | 267 | 268 | 145 269 | 225 270 | 271 | 272 | 273 | 274 | cancel_button 275 | clicked() 276 | Dialog 277 | reject() 278 | 279 | 280 | 244 281 | 430 282 | 283 | 284 | 145 285 | 225 286 | 287 | 288 | 289 | 290 | 291 | -------------------------------------------------------------------------------- /ui_files/import_ply.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 314 10 | 327 11 | 12 | 13 | 14 | Import Planes from Mesh 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | Painted Colors: 23 | 24 | 25 | 26 | 27 | 28 | 29 | Qt::Horizontal 30 | 31 | 32 | 33 | 40 34 | 20 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | Add Color 52 | 53 | 54 | 55 | 56 | 57 | 58 | Remove 59 | 60 | 61 | 62 | 63 | 64 | 65 | Qt::Vertical 66 | 67 | 68 | 69 | 20 70 | 40 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Export each color to a separate file 83 | 84 | 85 | true 86 | 87 | 88 | 89 | 90 | 91 | 92 | Export 3d model of resulting planes 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | Qt::Horizontal 102 | 103 | 104 | 105 | 40 106 | 20 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | OK 115 | 116 | 117 | 118 | 119 | 120 | 121 | Cancel 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | ok_button 133 | clicked() 134 | Dialog 135 | accept() 136 | 137 | 138 | 156 139 | 152 140 | 141 | 142 | 142 143 | 86 144 | 145 | 146 | 147 | 148 | cancel_button 149 | clicked() 150 | Dialog 151 | reject() 152 | 153 | 154 | 237 155 | 152 156 | 157 | 158 | 142 159 | 86 160 | 161 | 162 | 163 | 164 | 165 | -------------------------------------------------------------------------------- /ui_files/item_table.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 279 10 | 460 11 | 12 | 13 | 14 | Item Table 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Update Data 26 | 27 | 28 | 29 | 30 | 31 | 32 | Qt::Horizontal 33 | 34 | 35 | 36 | 40 37 | 20 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | w 46 | 47 | 48 | 49 | 50 | 51 | 52 | sc 53 | 54 | 55 | 56 | 57 | 58 | 59 | ff 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /ui_files/merge_data.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 285 10 | 174 11 | 12 | 13 | 14 | Merge Data 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | Browse... 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Load merged data 43 | 44 | 45 | true 46 | 47 | 48 | 49 | 50 | 51 | 52 | Qt::Horizontal 53 | 54 | 55 | 56 | 40 57 | 20 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | Qt::Vertical 68 | 69 | 70 | 71 | 20 72 | 11 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | Qt::Horizontal 83 | 84 | 85 | 86 | 40 87 | 20 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | OK 96 | 97 | 98 | 99 | 100 | 101 | 102 | Cancel 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | ok_button 114 | clicked() 115 | Dialog 116 | accept() 117 | 118 | 119 | 156 120 | 152 121 | 122 | 123 | 142 124 | 86 125 | 126 | 127 | 128 | 129 | cancel_button 130 | clicked() 131 | Dialog 132 | reject() 133 | 134 | 135 | 237 136 | 152 137 | 138 | 139 | 142 140 | 86 141 | 142 | 143 | 144 | 145 | 146 | -------------------------------------------------------------------------------- /ui_files/openstereo.pro: -------------------------------------------------------------------------------- 1 | SOURCES += ../openstereo/ui/circular_properties_ui.py 2 | SOURCES += ../openstereo/ui/clipboard_ui.py 3 | SOURCES += ../openstereo/ui/fault_data_ui.py 4 | SOURCES += ../openstereo/ui/import_dialog_ui.py 5 | SOURCES += ../openstereo/ui/import_ply_ui.py 6 | SOURCES += ../openstereo/ui/item_table_ui.py 7 | SOURCES += ../openstereo/ui/line_properties_ui.py 8 | SOURCES += ../openstereo/ui/openstereo_ui.py 9 | SOURCES += ../openstereo/ui/os_settings_ui.py 10 | SOURCES += ../openstereo/ui/plane_properties_ui.py 11 | SOURCES += ../openstereo/ui/rotate_data_ui.py 12 | SOURCES += ../openstereo/ui/smallcircle_properties_ui.py 13 | 14 | SOURCES += ../openstereo/os_base.py 15 | 16 | TRANSLATIONS += i18n/openstereo_pt_BR.ts -------------------------------------------------------------------------------- /ui_files/openstereo.qrc: -------------------------------------------------------------------------------- 1 | 2 | 3 | icons/openstereo.ico 4 | i18n/openstereo_pt_BR.qm 5 | 6 | 7 | -------------------------------------------------------------------------------- /ui_files/rotate_data.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 283 10 | 185 11 | 12 | 13 | 14 | Rotate Data 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | Trend 26 | 27 | 28 | 29 | 30 | 31 | 32 | Plunge 33 | 34 | 35 | 36 | 37 | 38 | 39 | Angle 40 | 41 | 42 | 43 | 44 | 45 | 46 | Axis 47 | 48 | 49 | 50 | 51 | 52 | 53 | -360.000000000000000 54 | 55 | 56 | 360.000000000000000 57 | 58 | 59 | 60 | 61 | 62 | 63 | -90.000000000000000 64 | 65 | 66 | 90.000000000000000 67 | 68 | 69 | 70 | 71 | 72 | 73 | -360.000000000000000 74 | 75 | 76 | 360.000000000000000 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | Browse... 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | Load rotated data 102 | 103 | 104 | true 105 | 106 | 107 | 108 | 109 | 110 | 111 | Qt::Horizontal 112 | 113 | 114 | 115 | 40 116 | 20 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | Qt::Vertical 127 | 128 | 129 | 130 | 20 131 | 11 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | Qt::Horizontal 142 | 143 | 144 | 145 | 40 146 | 20 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | OK 155 | 156 | 157 | 158 | 159 | 160 | 161 | Cancel 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | ok_button 173 | clicked() 174 | Dialog 175 | accept() 176 | 177 | 178 | 156 179 | 152 180 | 181 | 182 | 142 183 | 86 184 | 185 | 186 | 187 | 188 | cancel_button 189 | clicked() 190 | Dialog 191 | reject() 192 | 193 | 194 | 237 195 | 152 196 | 197 | 198 | 142 199 | 86 200 | 201 | 202 | 203 | 204 | 205 | -------------------------------------------------------------------------------- /ui_files/singleline_properties.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 263 10 | 428 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | Attitude 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Pole 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Symbol 43 | 44 | 45 | 46 | 47 | 48 | 49 | Size 50 | 51 | 52 | 53 | 54 | 55 | 56 | Color 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | o 72 | 73 | 74 | 75 | 76 | ^ 77 | 78 | 79 | 80 | 81 | v 82 | 83 | 84 | 85 | 86 | < 87 | 88 | 89 | 90 | 91 | > 92 | 93 | 94 | 95 | 96 | s 97 | 98 | 99 | 100 | 101 | + 102 | 103 | 104 | 105 | 106 | x 107 | 108 | 109 | 110 | 111 | D 112 | 113 | 114 | 115 | 116 | d 117 | 118 | 119 | 120 | 121 | h 122 | 123 | 124 | 125 | 126 | H 127 | 128 | 129 | 130 | 131 | p 132 | 133 | 134 | 135 | 136 | | 137 | 138 | 139 | 140 | 141 | _ 142 | 143 | 144 | 145 | 146 | * 147 | 148 | 149 | 150 | 151 | 1 152 | 153 | 154 | 155 | 156 | 2 157 | 158 | 159 | 160 | 161 | 3 162 | 163 | 164 | 165 | 166 | 4 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | Data Legend 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | Line 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | Qt::Vertical 204 | 205 | 206 | 207 | 20 208 | 41 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | Qt::Horizontal 219 | 220 | 221 | 222 | 40 223 | 20 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | OK 232 | 233 | 234 | 235 | 236 | 237 | 238 | Cancel 239 | 240 | 241 | 242 | 243 | 244 | 245 | Apply 246 | 247 | 248 | 249 | 250 | 251 | 252 | groupBox_3 253 | verticalSpacer 254 | groupBox_8 255 | 256 | 257 | prop_color_point_c 258 | prop_point_marker 259 | prop_point_ms 260 | cancel_button 261 | apply 262 | ok_button 263 | 264 | 265 | 266 | 267 | ok_button 268 | clicked() 269 | Dialog 270 | accept() 271 | 272 | 273 | 442 274 | 381 275 | 276 | 277 | 325 278 | 201 279 | 280 | 281 | 282 | 283 | cancel_button 284 | clicked() 285 | Dialog 286 | reject() 287 | 288 | 289 | 523 290 | 381 291 | 292 | 293 | 325 294 | 201 295 | 296 | 297 | 298 | 299 | 300 | -------------------------------------------------------------------------------- /ui_files/singlesmallcircle_properties.ui: -------------------------------------------------------------------------------- 1 | 2 | 3 | Dialog 4 | 5 | 6 | 7 | 0 8 | 0 9 | 263 10 | 428 11 | 12 | 13 | 14 | Dialog 15 | 16 | 17 | 18 | 19 | 20 | Attitude 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | Pole 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | Symbol 43 | 44 | 45 | 46 | 47 | 48 | 49 | Size 50 | 51 | 52 | 53 | 54 | 55 | 56 | Color 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | o 72 | 73 | 74 | 75 | 76 | ^ 77 | 78 | 79 | 80 | 81 | v 82 | 83 | 84 | 85 | 86 | < 87 | 88 | 89 | 90 | 91 | > 92 | 93 | 94 | 95 | 96 | s 97 | 98 | 99 | 100 | 101 | + 102 | 103 | 104 | 105 | 106 | x 107 | 108 | 109 | 110 | 111 | D 112 | 113 | 114 | 115 | 116 | d 117 | 118 | 119 | 120 | 121 | h 122 | 123 | 124 | 125 | 126 | H 127 | 128 | 129 | 130 | 131 | p 132 | 133 | 134 | 135 | 136 | | 137 | 138 | 139 | 140 | 141 | _ 142 | 143 | 144 | 145 | 146 | * 147 | 148 | 149 | 150 | 151 | 1 152 | 153 | 154 | 155 | 156 | 2 157 | 158 | 159 | 160 | 161 | 3 162 | 163 | 164 | 165 | 166 | 4 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | Small Circle 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | Symbol 191 | 192 | 193 | 194 | 195 | 196 | 197 | Width 198 | 199 | 200 | 201 | 202 | 203 | 204 | Color 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | - 220 | 221 | 222 | 223 | 224 | : 225 | 226 | 227 | 228 | 229 | -- 230 | 231 | 232 | 233 | 234 | -. 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | Data Legend 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | Small Circle 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | Axis 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | Qt::Vertical 282 | 283 | 284 | 285 | 20 286 | 41 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | Qt::Horizontal 297 | 298 | 299 | 300 | 40 301 | 20 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | OK 310 | 311 | 312 | 313 | 314 | 315 | 316 | Cancel 317 | 318 | 319 | 320 | 321 | 322 | 323 | Apply 324 | 325 | 326 | 327 | 328 | 329 | 330 | groupBox_3 331 | verticalSpacer 332 | groupBox_8 333 | 334 | 335 | prop_color_scaxis_c 336 | prop_scaxis_marker 337 | prop_scaxis_ms 338 | prop_color_sccirc_colors 339 | prop_sccirc_linestyles 340 | prop_sccirc_linewidths 341 | cancel_button 342 | apply 343 | ok_button 344 | 345 | 346 | 347 | 348 | ok_button 349 | clicked() 350 | Dialog 351 | accept() 352 | 353 | 354 | 442 355 | 381 356 | 357 | 358 | 325 359 | 201 360 | 361 | 362 | 363 | 364 | cancel_button 365 | clicked() 366 | Dialog 367 | reject() 368 | 369 | 370 | 523 371 | 381 372 | 373 | 374 | 325 375 | 201 376 | 377 | 378 | 379 | 380 | 381 | --------------------------------------------------------------------------------