diff --git a/.github/scripts/gen_overview.py b/.github/scripts/gen_overview.py new file mode 100644 index 0000000..8f170bd --- /dev/null +++ b/.github/scripts/gen_overview.py @@ -0,0 +1,307 @@ +# +# gen_overview.py +# +# Carl Zeiss GOM Metrology GmbH, 2024 +# +# --- +'''Generate ZEISS INSPECT App Examples Overview markdown file''' + +import os +import json +import argparse + + +BASEDIR = 'AppExamples' + +CATEGORY_DESCRIPTIONS = { + 'data_interfaces': 'How to access data of ZEISS INSPECT elements', + 'dialog_widgets': 'How to use custom dialogs and handle user input events', + 'misc': 'Miscellaneous', + 'script_icons': 'How to set icons for scripts or buttons', + 'script_resources': 'How to access binary data of your App (resources)', + 'scripted_actuals': 'Building custom actual elements with Python code', + 'scripted_checks': 'Building custom checks with Python code', + 'projects': 'ZEISS INSPECT projects' +} + +EXAMPLE_PROJECTS = { + 'zeiss_part_test_project': {'index': 1}, + 'zeiss_part_test_measurement': {'index': 2}, + 'volume_test_project': {'index': 3} +} + +def gen_table(_category, _tag_index): + """ + Generate App overview as table + + | App | Description | Example Projects | References | Tags | + | --- | ----------- | ---------------- | ---------- | ---- | + """ + + # App table header + # Using non-breaking spaces ( ) to enforce a common/minimum column width + md = f"| {24*' '}App{24*' '} | {36*' '}Description{36*' '} | Example Projects | References | {7*' '}Tags{7*' '} |\n" + md += "| --- | ----------- | ---------------- | ---------- | ---- |\n" + + apps = os.path.join(BASEDIR, _category) + for _app in os.listdir(apps): + metainfo_path = os.path.abspath(os.path.join(BASEDIR, _category, _app, 'metainfo.json')) + with open(metainfo_path, 'r', encoding="utf-8") as f: + metainfo = json.load(f) + if sphinx_doc: + view = f"https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/{_category}/{_app}/doc/Documentation.md" + else: + view = f"{_category}/{_app}/doc/Documentation.md" + download = f"https://software-store.zeiss.com/products/apps/{metainfo['title']}" + + # Title, links to source code and App download + title = metainfo['title'] + md += f"| {title}
[view]({view}) / [download]({download}) | " + + # Description + md += f"{metainfo['description'].encode('windows-1252').decode('utf-8')} |" + + # Example projects + if 'example-projects' in metainfo: + for _example in metainfo['example-projects']: + if _example in EXAMPLE_PROJECTS: + md += f" [{EXAMPLE_PROJECTS[_example]['index']})](#example-projects) " + md += " | " + + # References + if 'references' in metainfo: + for reference in metainfo['references']: + md += f"[{reference[0]}]({reference[1]})
" + + md += " | " + + # Tags + for _tag in metainfo['tags']: + if not _tag in _tag_index: + _tag_index[_tag] = [] + _tag_index[_tag].append(title) + _badge = _tag.replace('-', '--') + if sphinx_doc: + md += f"![Static Badge](https://img.shields.io/badge/{_badge}-blue)
" + else: + md += f"[![Static Badge](https://img.shields.io/badge/{_badge}-blue)](#{_tag})
" + md += " |" + + md += "\n" + return md, _tag_index + +def gen_boilerplate(_category, _tag_index): + """ + Generate App overview as table + + ### App + + Description + ... + + Example Projects + ... + + References + ... + + Tags + ... + """ + + md = "" + block_odd = True + + apps = os.path.join(BASEDIR, _category) + for _app in os.listdir(apps): + metainfo_path = os.path.abspath(os.path.join(BASEDIR, _category, _app, 'metainfo.json')) + with open(metainfo_path, 'r', encoding="utf-8") as f: + metainfo = json.load(f) + if sphinx_doc: + view = f"https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/{_category}/{_app}/doc/Documentation.md" + else: + view = f"{_category}/{_app}/doc/Documentation.md" + download = f"https://software-store.zeiss.com/products/apps/{metainfo['title']}" + + if block_odd: + next_class = "example-block-odd" + else: + next_class = "example-block-even" + block_odd = not block_odd + + # Title, links to source code and App download + # Using HTML instead of markdown to allow alternating background color via
attribute + title = metainfo['title'] + #md += f"### {title} — [view]({view}) / [download]({download})\n\n" + md += f'
\n' + md += f'
\n' + md += \ +f'''

{title} — view / +download +

+\n\n''' + + #md += f"![Icon](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/{category}/{app}/icon.png)\n" + + # Description + md += ":Description:\n" + md += f" {metainfo['description'].encode('windows-1252').decode('utf-8')}\n\n" + + # Example projects + if 'example-projects' in metainfo: + md += ":Example Projects:\n" + for _example in metainfo['example-projects']: + if _example in EXAMPLE_PROJECTS: + md += f" [{_example}](#example-projects)\n" + md += "\n" + + # References + if 'references' in metainfo: + md += ":References:\n" + for i, reference in enumerate(metainfo['references']): + if i == 0: + md += f" [{reference[0]}]({reference[1]})" + else: + md += f", [{reference[0]}]({reference[1]})" + md += "\n" + + # Tags + if len(metainfo['tags']): + md += ":Tags:\n" + md += " " + for _tag in metainfo['tags']: + if not _tag in _tag_index: + _tag_index[_tag] = [] + _tag_index[_tag].append(title) + _badge = _tag.replace('-', '--') + if sphinx_doc: + md += f"![Static Badge](https://img.shields.io/badge/{_badge}-blue) " + else: + md += f"[![Static Badge](https://img.shields.io/badge/{_badge}-blue)](#{_tag})
" + + md += "\n" + md += '\n
\n' + md += '\n
\n\n' + + return md, _tag_index + +# ---------------------------------------------------------------------------- +# MAIN +# +if __name__ == '__main__': + # + # Parse command line arguments + # + parser = argparse.ArgumentParser() + + # autopep8: off + parser.add_argument('--sphinx-doc', action='store_true', help='Select sphinx_doc layout') + parser.add_argument('--title', type=str, + default='ZEISS INSPECT App Examples Overview', + help='Page title') + parser.add_argument('--meta-description', type=str, + default='Examples for using the ZEISS INSPECT 2025 App Python API', + help='Description in HTML metadata') + # autopep8: on + + args = parser.parse_args() + sphinx_doc = args.sphinx_doc + + app_overview = "" + tagIndex = {} + + if sphinx_doc: + app_overview += \ +f"""--- +myst: + html_meta: + "description": "{args.meta_description}" + "keywords": "Metrology, ZEISS INSPECT, Python API, GOM API, Scripting, Add-ons, Apps, Examples" +--- +""" + + # Override some default styles / add custom styles for this page + if sphinx_doc: + app_overview += \ +""" + +""" + + app_overview += f"# {args.title}\n" + + categories = os.listdir(BASEDIR) + for category in sorted(categories): + if category == '.gitignore': + continue + + if os.path.isdir(os.path.abspath(os.path.join(BASEDIR, category))): + + # Category heading + app_overview += f"\n## {category} — {CATEGORY_DESCRIPTIONS[category]}\n\n" + if sphinx_doc: + app_overview += '
\n' + + if sphinx_doc: + tmp, tagIndex = gen_boilerplate(category, tagIndex) + else: + tmp, tagIndex = gen_table(category, tagIndex) + + app_overview += tmp + + # Example projects + app_overview += "\n## Example projects\n\n" + + for example, infos in EXAMPLE_PROJECTS.items(): + if sphinx_doc: + app_overview += f"* {example}\n" + else: + app_overview += f"{infos['index']}) {example}\n" + + app_overview += "\n[Download Example Projects App](https://software-store.zeiss.com/products/apps/ExampleProjects)" + + + # Tag index + app_overview += "\n\n## Tag Index\n" + + for tag in sorted(tagIndex): + #app_overview += f"\n### {tag}:\n" + badge = tag.replace('-', '--') + if sphinx_doc: + app_overview += f"\n### ![Static Badge](https://img.shields.io/badge/{badge}-blue)\n\n" + else: + app_overview += f"\n### ![Static Badge](https://img.shields.io/badge/{badge}-blue)\n\n" + + for app in sorted(tagIndex[tag]): + if sphinx_doc: + app_overview += f"* {app}\n" + else: + app_overview += f"* [{app}](#{app})\n" + app_overview += "\n" + + + # Related links + app_overview += "\n## Related\n\n" + app_overview += "* [ZEISS IQS GitHub — App Development Documentation](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html)\n" + app_overview += "* [ZEISS Quality Software Store](https://software-store.zeiss.com)\n" + + + print(app_overview) diff --git a/.github/workflows/update_overview.yaml b/.github/workflows/update_overview.yaml index a6ec570..05f980a 100644 --- a/.github/workflows/update_overview.yaml +++ b/.github/workflows/update_overview.yaml @@ -1,10 +1,28 @@ name: Update overview and create PR -on: - workflow_dispatch: +on: [workflow_dispatch,push] +env: + GH_TOKEN: ${{ github.token }} jobs: create_file_and_pr: runs-on: ubuntu-latest steps: + - name: Set branches + id: set_branches + run: + | + CURRENT_BRANCH=${GITHUB_REF#refs/*/} + echo "Current branch: ${CURRENT_BRANCH}" + TARGET_BRANCH=${GITHUB_REF#refs/*/} + echo "Target branch: ${TARGET_BRANCH}" + echo "current_branch=${CURRENT_BRANCH}" >> $GITHUB_OUTPUT + echo "target_branch=${TARGET_BRANCH}" >> $GITHUB_OUTPUT + - name: Set reviewers + id: reviewers + run: + | + REVIEWERS="fblankenburgzeiss,mprinkezs" # separate by commas + echo "Reviewers: ${REVIEWERS}" + echo "reviewers=${REVIEWERS}" >> $GITHUB_OUTPUT - name: Setup Python uses: actions/setup-python@v5 with: @@ -12,22 +30,90 @@ jobs: - name: Check out the repository uses: actions/checkout@v4 with: - #ref: ${{ github.event.inputs.branch_name }} - ref: main + ref: ${{ format('{0}', steps.set_branches.outputs.current_branch) }} fetch-depth: 0 # Fetch all history for all branches and tags + - name: Git config + run: | + git config --global user.email "action@github.com" + git config --global user.name "GitHub Action" + - name: Create a new branch run: | - #git checkout -b ${{ github.event.inputs.branch_name }} || git checkout ${{ github.event.inputs.branch_name }} git checkout -b overview-update || git checkout overview-update - - name: Create a new file + - name: Update overview (ZEISS) + run: | + python .github/scripts/gen_overview.py > AppExamples/README.md + if [ -z "$(git status --porcelain)" ]; then + echo "No changes to commit." + echo "changes=false" >> $GITHUB_ENV + else + echo "Changes detected." + echo "changes=true" >> $GITHUB_ENV + fi + + - name: Push changes (ZEISS) + if: env.changes == 'true' run: | - # echo "${{ github.event.inputs.file_content }}" > ${{ github.event.inputs.file_path }} - python .github/scripts/gen_overview > AppExamples/README.md - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" git add AppExamples/README.md git commit -m "Updated AppExamples/README.md" - #git push --set-upstream origin ${{ github.event.inputs.branch_name }} - git push --set-upstream origin overview-update + git push origin +overview-update:overview-update + + - name: Create Pull Request + if: env.changes == 'true' + uses: devops-infra/action-pull-request@v0.5.5 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + #source_branch: apidoc-update-main + target_branch: ${{ format('{0}', steps.set_branches.outputs.target_branch) }} + title: ${{ format('Updated App Examples Overview (AppExamples/README.md) ({0})', steps.set_branches.outputs.target_branch) }} + #template: .github/PULL_REQUEST_TEMPLATE.md + body: "**Automated pull request**" + reviewer: ${{ format('{0}', steps.reviewers.outputs.reviewers) }} + #assignee: octocat + label: documentation + #milestone: My milestone + #draft: true + #old_string: "" + #new_string: "** Automatic pull request**" + get_diff: true + ignore_users: "dependabot" + allow_no_diff: false + + - name: Update overview (ZeissIQS) + run: | + python .github/scripts/gen_overview.py --sphinx-doc > examples_overview.md + gh repo clone ZeissIQS/zeiss-inspect-addon-api + cd zeiss-inspect-addon-api + git checkout -b overview-update --track origin/main + cp ../examples_overview.md doc/python_examples/examples_overview.md + if [ -z "$(git status --porcelain)" ]; then + echo "No changes to commit." + echo "changes=false" >> $GITHUB_ENV + else + echo "Changes detected." + echo "changes=true" >> $GITHUB_ENV + fi + + - name: Push changes (ZeissIQS) + if: env.changes == 'true' + run: | + cd zeiss-inspect-addon-api + git add doc/python_examples/examples_overview.md + git commit -m "Updated doc/python_examples/examples_overview.md" + git remote set-url origin https://x-access-token:${{ secrets.TARGET_REPO_PAT_2 }}@github.com/ZeissIQS/zeiss-inspect-addon-api.git + git push origin +overview-update:overview-update + + # Note: Pull Request in ZeissIQS project is created by a separate workflow in ZeissIQS due to permission issues + #- name: Create Pull Request (ZeissIQS) + # if: env.changes == 'true' + # run: | + # echo "${{ secrets.TARGET_REPO_PAT_2 }}" | gh auth login --with-token + # gh pr create --repo ZeissIQS/zeiss-inspect-addon-api \ + # --head overview-update \ + # --title "${{ format('Updated App Examples Overview (AppExamples/README.md) ({0})', steps.set_branches.outputs.target_branch) }}" \ + # --body "**Automated pull request**" \ + # --label documentation \ + # --reviewer ${{ format('{0}', steps.reviewers.outputs.reviewers) }} + diff --git a/AppExamples/README.md b/AppExamples/README.md new file mode 100644 index 0000000..c46aaa9 --- /dev/null +++ b/AppExamples/README.md @@ -0,0 +1,300 @@ +# ZEISS INSPECT App Examples Overview + +## data_interfaces — How to access data of ZEISS INSPECT elements + +|                         App                         |                                     Description                                     | Example Projects | References |        Tags        | +| --- | ----------- | ---------------- | ---------- | ---- | +| ReferencePointsAndMeshData
[view](data_interfaces/ReferencePointsAndMeshData/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ReferencePointsAndMeshData) | This example demonstrates how to access the reference points in a measurement and the mesh from Python. | [1)](#example-projects) | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#element-data-interfaces)
| [![Static Badge](https://img.shields.io/badge/reference--points-blue)](#reference-points)
[![Static Badge](https://img.shields.io/badge/mesh-blue)](#mesh)
[![Static Badge](https://img.shields.io/badge/measurement-blue)](#measurement)
| +| CheckResultsDataArray
[view](data_interfaces/CheckResultsDataArray/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/CheckResultsDataArray) | This example demonstrates two ways of accessing result data from checks using the element properties and data interfaces. | [1)](#example-projects) | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#access-element-properties)
| [![Static Badge](https://img.shields.io/badge/element--properties-blue)](#element-properties)
[![Static Badge](https://img.shields.io/badge/element--data-blue)](#element-data)
| +| VolumeSectionImageData
[view](data_interfaces/VolumeSectionImageData/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/VolumeSectionImageData) | This example demonstrates how to access the image data of a volume section. | [3)](#example-projects) | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#element-data-interfaces)
| [![Static Badge](https://img.shields.io/badge/element--data-blue)](#element-data)
| + +## dialog_widgets — How to use custom dialogs and handle user input events + +|                         App                         |                                     Description                                     | Example Projects | References |        Tags        | +| --- | ----------- | ---------------- | ---------- | ---- | +| WidgetVisibility
[view](dialog_widgets/WidgetVisibility/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/WidgetVisibility) | This example shows how to use a dialog event handler to turn on/off widget visibilities. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html)
| [![Static Badge](https://img.shields.io/badge/dialog-blue)](#dialog)
[![Static Badge](https://img.shields.io/badge/widget--properties-blue)](#widget-properties)
| +| UnitDialogEventHandler
[view](dialog_widgets/UnitDialogEventHandler/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/UnitDialogEventHandler) | This basic example demonstrates how to use an event handler on a script dialog to set the unit to multiple widgets. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html#unit-widget)
| [![Static Badge](https://img.shields.io/badge/dialog-blue)](#dialog)
[![Static Badge](https://img.shields.io/badge/unit--widget-blue)](#unit-widget)
| +| ExplorerSelectedElementsInDialog
[view](dialog_widgets/ExplorerSelectedElementsInDialog/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ExplorerSelectedElementsInDialog) | This example shows how to get a list of elements selected in the element explorer and use it in a script dialog. | [1)](#example-projects) | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html#selection-element-widget)
| [![Static Badge](https://img.shields.io/badge/dialog-blue)](#dialog)
[![Static Badge](https://img.shields.io/badge/selection--element--widget-blue)](#selection-element-widget)
| +| DropdownWidget
[view](dialog_widgets/DropdownWidget/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/DropdownWidget) | This basic example shows how to use the dropdown widget and how to define items at script runtime. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html#selection-list-widget)
| [![Static Badge](https://img.shields.io/badge/dialog-blue)](#dialog)
[![Static Badge](https://img.shields.io/badge/selection--list--widget-blue)](#selection-list-widget)
| + +## misc — Miscellaneous + +|                         App                         |                                     Description                                     | Example Projects | References |        Tags        | +| --- | ----------- | ---------------- | ---------- | ---- | +| CSVExample
[view](misc/CSVExample/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/CSVExample) | This example demonstrates how to read and write CSV files (comma separated values) from an App. | [1)](#example-projects) | | [![Static Badge](https://img.shields.io/badge/import-blue)](#import)
[![Static Badge](https://img.shields.io/badge/export-blue)](#export)
[![Static Badge](https://img.shields.io/badge/project--keywords-blue)](#project-keywords)
| +| DialogReopenExample
[view](misc/DialogReopenExample/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/DialogReopenExample) | This examples demonstrates, how a dialog can be closed from its own handler, just to be opened again. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html#executing-dialogs)
| [![Static Badge](https://img.shields.io/badge/dialog-blue)](#dialog)
| +| PointPixelTransformations
[view](misc/PointPixelTransformations/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/PointPixelTransformations) | This example demonstrates how to find the 2D pixel coordinates of a 3D point coordinate and vice versa. | [2)](#example-projects) | [API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/python_api.html#gom-api-imaging)
| [![Static Badge](https://img.shields.io/badge/measurement-blue)](#measurement)
[![Static Badge](https://img.shields.io/badge/reference--points-blue)](#reference-points)
| +| Service Test
[view](misc/ServiceExample/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/Service Test) | Service API Example | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/using_services/using_services.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/python_api.html#gom-api-services)
| [![Static Badge](https://img.shields.io/badge/service-blue)](#service)
| + +## projects — ZEISS INSPECT projects + +|                         App                         |                                     Description                                     | Example Projects | References |        Tags        | +| --- | ----------- | ---------------- | ---------- | ---- | +| ExampleProjects
[view](projects/ExampleProjects/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ExampleProjects) | ZEISS INSPECT Example Projects | | | [![Static Badge](https://img.shields.io/badge/project-blue)](#project)
| + +## script_icons — How to set icons for scripts or buttons + +|                         App                         |                                     Description                                     | Example Projects | References |        Tags        | +| --- | ----------- | ---------------- | ---------- | ---- | +| ScriptIcon
[view](script_icons/ScriptIcon/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptIcon) | This example shows how an icon can be set to a script, whereas the icon itself resides in the App as a resource. | | | [![Static Badge](https://img.shields.io/badge/menu-blue)](#menu)
| + +## script_resources — How to access binary data of your App (resources) + +|                         App                         |                                     Description                                     | Example Projects | References |        Tags        | +| --- | ----------- | ---------------- | ---------- | ---- | +| ScriptResources
[view](script_resources/ScriptResources/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptResources) | A simple example showing the usage of script resources. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/using_script_resources.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/resource_api.html)
| [![Static Badge](https://img.shields.io/badge/resources-blue)](#resources)
| + +## scripted_actuals — Building custom actual elements with Python code + +|                         App                         |                                     Description                                     | Example Projects | References |        Tags        | +| --- | ----------- | ---------------- | ---------- | ---- | +| ScriptedActualVolume
[view](scripted_actuals/ScriptedActualVolume/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualVolume) | This is an example for a scripted actual ‘volume’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#volume)
| [![Static Badge](https://img.shields.io/badge/xray-blue)](#xray)
[![Static Badge](https://img.shields.io/badge/volume-blue)](#volume)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedElementProgress
[view](scripted_actuals/ScriptedElementProgress/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedElementProgress) | This examples demonstrates how to show progress information to the user while calcualting a scripted element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
| [![Static Badge](https://img.shields.io/badge/computation--progress-blue)](#computation-progress)
| +| ScriptedActualCircle
[view](scripted_actuals/ScriptedActualCircle/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualCircle) | This is an example for a scripted actual ‘circle’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#circle)
| [![Static Badge](https://img.shields.io/badge/circle-blue)](#circle)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualCone
[view](scripted_actuals/ScriptedActualCone/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualCone) | This is an example for a scripted actual ‘cone’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#cone)
| [![Static Badge](https://img.shields.io/badge/cone-blue)](#cone)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualDistance
[view](scripted_actuals/ScriptedActualDistance/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualDistance) | This is an example for a scripted actual ‘distance’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#distance)
| [![Static Badge](https://img.shields.io/badge/distance-blue)](#distance)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualSection
[view](scripted_actuals/ScriptedActualSection/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualSection) | This is an example for a scripted actual ‘section’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#section)
| [![Static Badge](https://img.shields.io/badge/section-blue)](#section)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualPoint
[view](scripted_actuals/ScriptedActualPoint/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualPoint) | These are two examples for scripted actual points, which serve as an introduction to the concept of scripted actual elements. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#point)
| [![Static Badge](https://img.shields.io/badge/point-blue)](#point)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualVolumeDefects
[view](scripted_actuals/ScriptedActualVolumeDefects/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualVolumeDefects) | This is an example for a scripted actual ‘volume defects’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#volume-defects)
| [![Static Badge](https://img.shields.io/badge/xray-blue)](#xray)
[![Static Badge](https://img.shields.io/badge/volume--defects-blue)](#volume-defects)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualVolumeRegion
[view](scripted_actuals/ScriptedActualVolumeRegion/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualVolumeRegion) | This is an example for a scripted actual ‘volume region’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#volume-region)
| [![Static Badge](https://img.shields.io/badge/xray-blue)](#xray)
[![Static Badge](https://img.shields.io/badge/volume--region-blue)](#volume-region)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualCurve
[view](scripted_actuals/ScriptedActualCurve/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualCurve) | This is an example for a scripted actual ‘curve’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#curve)
| [![Static Badge](https://img.shields.io/badge/curve-blue)](#curve)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualSurface
[view](scripted_actuals/ScriptedActualSurface/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualSurface) | This is an example for a scripted actual ‘surface’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#surface)
| [![Static Badge](https://img.shields.io/badge/surface-blue)](#surface)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualCylinder
[view](scripted_actuals/ScriptedActualCylinder/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualCylinder) | This is an example for a scripted actual ‘cylinder’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#cylinder)
| [![Static Badge](https://img.shields.io/badge/cylinder-blue)](#cylinder)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualPointCloud
[view](scripted_actuals/ScriptedActualPointCloud/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualPointCloud) | This is an example for a scripted actual ‘point cloud’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#point-cloud)
| [![Static Badge](https://img.shields.io/badge/point--cloud-blue)](#point-cloud)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualVolumeSection
[view](scripted_actuals/ScriptedActualVolumeSection/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualVolumeSection) | This is an example for a scripted actual ‘volume section’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#volume-section)
| [![Static Badge](https://img.shields.io/badge/xray-blue)](#xray)
[![Static Badge](https://img.shields.io/badge/volume--section-blue)](#volume-section)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| ScriptedActualSurfaceCurve
[view](scripted_actuals/ScriptedActualSurfaceCurve/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedActualSurfaceCurve) | This is an example for a scripted actual ‘surface curve’ element. | | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#surface-curve)
| [![Static Badge](https://img.shields.io/badge/surface--curve-blue)](#surface-curve)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| +| TrimeshDeformMesh
[view](scripted_actuals/TrimeshDeformMesh/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/TrimeshDeformMesh) | This example demonstrates how to generate a custom surface element using a scripted element. The example script accesses mesh information from an existing mesh in the project and adds a random deformation to each point. | [1)](#example-projects) | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#surface)
| [![Static Badge](https://img.shields.io/badge/mesh-blue)](#mesh)
[![Static Badge](https://img.shields.io/badge/surface-blue)](#surface)
[![Static Badge](https://img.shields.io/badge/scripted--actual-blue)](#scripted-actual)
| + +## scripted_checks — Building custom checks with Python code + +|                         App                         |                                     Description                                     | Example Projects | References |        Tags        | +| --- | ----------- | ---------------- | ---------- | ---- | +| ScriptedSurfaceCheck
[view](scripted_checks/ScriptedSurfaceCheck/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedSurfaceCheck) | This example demonstrates how to create a scalar surface check by a script. Also, the usage of custom coordinate systems and element preview in scripted checks is shown. | [1)](#example-projects) | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#scalar-surface)
| [![Static Badge](https://img.shields.io/badge/scripted--check-blue)](#scripted-check)
[![Static Badge](https://img.shields.io/badge/surface-blue)](#surface)
| +| ScriptedScalarCheck
[view](scripted_checks/ScriptedScalarCheck/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedScalarCheck) | This example shows how to create a scalar check by script. A scalar check is the most basic check, as it assigns a scalar value to an element. Nearly all elements you can find in the software can be checked like this. | [1)](#example-projects) | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#scalar)
| [![Static Badge](https://img.shields.io/badge/scripted--check-blue)](#scripted-check)
[![Static Badge](https://img.shields.io/badge/scalar-blue)](#scalar)
| +| ScriptedCurveCheck
[view](scripted_checks/ScriptedCurveCheck/doc/Documentation.md) / [download](https://software-store.zeiss.com/products/apps/ScriptedCurveCheck) | This example demonstrates how to create a scalar curve check by a script. Also, the usage of custom coordinate systems in scripted checks is shown. | [1)](#example-projects) | [HowTo](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.html)
[API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#scalar-curve)
| [![Static Badge](https://img.shields.io/badge/scripted--check-blue)](#scripted-check)
[![Static Badge](https://img.shields.io/badge/curve-blue)](#curve)
| + +## Example projects + +1) zeiss_part_test_project +2) zeiss_part_test_measurement +3) volume_test_project + +[Download Example Projects App](https://software-store.zeiss.com/products/apps/ExampleProjects) + +## Tag Index + +### ![Static Badge](https://img.shields.io/badge/circle-blue) + +* [ScriptedActualCircle](#ScriptedActualCircle) + + +### ![Static Badge](https://img.shields.io/badge/computation--progress-blue) + +* [ScriptedElementProgress](#ScriptedElementProgress) + + +### ![Static Badge](https://img.shields.io/badge/cone-blue) + +* [ScriptedActualCone](#ScriptedActualCone) + + +### ![Static Badge](https://img.shields.io/badge/curve-blue) + +* [ScriptedActualCurve](#ScriptedActualCurve) +* [ScriptedCurveCheck](#ScriptedCurveCheck) + + +### ![Static Badge](https://img.shields.io/badge/cylinder-blue) + +* [ScriptedActualCylinder](#ScriptedActualCylinder) + + +### ![Static Badge](https://img.shields.io/badge/dialog-blue) + +* [DialogReopenExample](#DialogReopenExample) +* [DropdownWidget](#DropdownWidget) +* [ExplorerSelectedElementsInDialog](#ExplorerSelectedElementsInDialog) +* [UnitDialogEventHandler](#UnitDialogEventHandler) +* [WidgetVisibility](#WidgetVisibility) + + +### ![Static Badge](https://img.shields.io/badge/distance-blue) + +* [ScriptedActualDistance](#ScriptedActualDistance) + + +### ![Static Badge](https://img.shields.io/badge/element--data-blue) + +* [CheckResultsDataArray](#CheckResultsDataArray) +* [VolumeSectionImageData](#VolumeSectionImageData) + + +### ![Static Badge](https://img.shields.io/badge/element--properties-blue) + +* [CheckResultsDataArray](#CheckResultsDataArray) + + +### ![Static Badge](https://img.shields.io/badge/export-blue) + +* [CSVExample](#CSVExample) + + +### ![Static Badge](https://img.shields.io/badge/import-blue) + +* [CSVExample](#CSVExample) + + +### ![Static Badge](https://img.shields.io/badge/measurement-blue) + +* [PointPixelTransformations](#PointPixelTransformations) +* [ReferencePointsAndMeshData](#ReferencePointsAndMeshData) + + +### ![Static Badge](https://img.shields.io/badge/menu-blue) + +* [ScriptIcon](#ScriptIcon) + + +### ![Static Badge](https://img.shields.io/badge/mesh-blue) + +* [ReferencePointsAndMeshData](#ReferencePointsAndMeshData) +* [TrimeshDeformMesh](#TrimeshDeformMesh) + + +### ![Static Badge](https://img.shields.io/badge/point-blue) + +* [ScriptedActualPoint](#ScriptedActualPoint) + + +### ![Static Badge](https://img.shields.io/badge/point--cloud-blue) + +* [ScriptedActualPointCloud](#ScriptedActualPointCloud) + + +### ![Static Badge](https://img.shields.io/badge/project-blue) + +* [ExampleProjects](#ExampleProjects) + + +### ![Static Badge](https://img.shields.io/badge/project--keywords-blue) + +* [CSVExample](#CSVExample) + + +### ![Static Badge](https://img.shields.io/badge/reference--points-blue) + +* [PointPixelTransformations](#PointPixelTransformations) +* [ReferencePointsAndMeshData](#ReferencePointsAndMeshData) + + +### ![Static Badge](https://img.shields.io/badge/resources-blue) + +* [ScriptResources](#ScriptResources) + + +### ![Static Badge](https://img.shields.io/badge/scalar-blue) + +* [ScriptedScalarCheck](#ScriptedScalarCheck) + + +### ![Static Badge](https://img.shields.io/badge/scripted--actual-blue) + +* [ScriptedActualCircle](#ScriptedActualCircle) +* [ScriptedActualCone](#ScriptedActualCone) +* [ScriptedActualCurve](#ScriptedActualCurve) +* [ScriptedActualCylinder](#ScriptedActualCylinder) +* [ScriptedActualDistance](#ScriptedActualDistance) +* [ScriptedActualPoint](#ScriptedActualPoint) +* [ScriptedActualPointCloud](#ScriptedActualPointCloud) +* [ScriptedActualSection](#ScriptedActualSection) +* [ScriptedActualSurface](#ScriptedActualSurface) +* [ScriptedActualSurfaceCurve](#ScriptedActualSurfaceCurve) +* [ScriptedActualVolume](#ScriptedActualVolume) +* [ScriptedActualVolumeDefects](#ScriptedActualVolumeDefects) +* [ScriptedActualVolumeRegion](#ScriptedActualVolumeRegion) +* [ScriptedActualVolumeSection](#ScriptedActualVolumeSection) +* [TrimeshDeformMesh](#TrimeshDeformMesh) + + +### ![Static Badge](https://img.shields.io/badge/scripted--check-blue) + +* [ScriptedCurveCheck](#ScriptedCurveCheck) +* [ScriptedScalarCheck](#ScriptedScalarCheck) +* [ScriptedSurfaceCheck](#ScriptedSurfaceCheck) + + +### ![Static Badge](https://img.shields.io/badge/section-blue) + +* [ScriptedActualSection](#ScriptedActualSection) + + +### ![Static Badge](https://img.shields.io/badge/selection--element--widget-blue) + +* [ExplorerSelectedElementsInDialog](#ExplorerSelectedElementsInDialog) + + +### ![Static Badge](https://img.shields.io/badge/selection--list--widget-blue) + +* [DropdownWidget](#DropdownWidget) + + +### ![Static Badge](https://img.shields.io/badge/service-blue) + +* [Service Test](#Service Test) + + +### ![Static Badge](https://img.shields.io/badge/surface-blue) + +* [ScriptedActualSurface](#ScriptedActualSurface) +* [ScriptedSurfaceCheck](#ScriptedSurfaceCheck) +* [TrimeshDeformMesh](#TrimeshDeformMesh) + + +### ![Static Badge](https://img.shields.io/badge/surface--curve-blue) + +* [ScriptedActualSurfaceCurve](#ScriptedActualSurfaceCurve) + + +### ![Static Badge](https://img.shields.io/badge/unit--widget-blue) + +* [UnitDialogEventHandler](#UnitDialogEventHandler) + + +### ![Static Badge](https://img.shields.io/badge/volume-blue) + +* [ScriptedActualVolume](#ScriptedActualVolume) + + +### ![Static Badge](https://img.shields.io/badge/volume--defects-blue) + +* [ScriptedActualVolumeDefects](#ScriptedActualVolumeDefects) + + +### ![Static Badge](https://img.shields.io/badge/volume--region-blue) + +* [ScriptedActualVolumeRegion](#ScriptedActualVolumeRegion) + + +### ![Static Badge](https://img.shields.io/badge/volume--section-blue) + +* [ScriptedActualVolumeSection](#ScriptedActualVolumeSection) + + +### ![Static Badge](https://img.shields.io/badge/widget--properties-blue) + +* [WidgetVisibility](#WidgetVisibility) + + +### ![Static Badge](https://img.shields.io/badge/xray-blue) + +* [ScriptedActualVolume](#ScriptedActualVolume) +* [ScriptedActualVolumeDefects](#ScriptedActualVolumeDefects) +* [ScriptedActualVolumeRegion](#ScriptedActualVolumeRegion) +* [ScriptedActualVolumeSection](#ScriptedActualVolumeSection) + + +## Related + +* [ZEISS IQS GitHub — App Development Documentation](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) +* [ZEISS Quality Software Store](https://software-store.zeiss.com) + diff --git a/AppExamples/data_interfaces/CheckResultsDataArray/doc/Documentation.md b/AppExamples/data_interfaces/CheckResultsDataArray/doc/Documentation.md new file mode 100644 index 0000000..f467dd5 --- /dev/null +++ b/AppExamples/data_interfaces/CheckResultsDataArray/doc/Documentation.md @@ -0,0 +1,28 @@ +# CheckResultsDataArray + +![](check_results_data_array.png) + +## Short description + +This example demonstrates two ways of accessing result data from checks using the element properties and data interfaces. + +## Highlights + +Basically, if you have obtained an `gom.Reference` element reference, e.g. by selecting an element by name (`gom.app.project.inspection['Surface comparison 1']`), you can access the results of the check: + +1. **By evaluating an expression** + + `single_scalar_value = element.get ('result_dimension[0].deviation')` + +* simple for single values +* works without using `numpy` library + +2. **By the data interface of this element using the `.data` token** + + `scalars = np.array (element.data.result_dimension.deviation)` + +* gets large datasets of all stages very efficiently + +## Related + +* How-to: [Access element properties and data](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#access-element-properties) \ No newline at end of file diff --git a/AppExamples/data_interfaces/CheckResultsDataArray/doc/README.md b/AppExamples/data_interfaces/CheckResultsDataArray/doc/README.md index 17772ce..52bfbf1 100644 --- a/AppExamples/data_interfaces/CheckResultsDataArray/doc/README.md +++ b/AppExamples/data_interfaces/CheckResultsDataArray/doc/README.md @@ -1,7 +1,9 @@ ## CheckResultsDataArray -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [CheckResultsDataArray](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/data_interfaces/check_results_data_array.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. You can [download this App](https://software-store.zeiss.com/products/apps/CheckResultsDataArray) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/data_interfaces/CheckResultsDataArray/doc/check_results_data_array.png b/AppExamples/data_interfaces/CheckResultsDataArray/doc/check_results_data_array.png new file mode 100644 index 0000000..63dac1b Binary files /dev/null and b/AppExamples/data_interfaces/CheckResultsDataArray/doc/check_results_data_array.png differ diff --git a/AppExamples/data_interfaces/CheckResultsDataArray/metainfo.json b/AppExamples/data_interfaces/CheckResultsDataArray/metainfo.json index 490edaa..370ef13 100644 --- a/AppExamples/data_interfaces/CheckResultsDataArray/metainfo.json +++ b/AppExamples/data_interfaces/CheckResultsDataArray/metainfo.json @@ -2,14 +2,20 @@ "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example demonstrates two ways of accessing result data from checks using the element properties and data interfaces.", "environment": "ZeissInspectExampleProjects", + "example-projects": ["zeiss_part_test_project"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#access-element-properties"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "element-properties", "element-data" + ], "title": "CheckResultsDataArray", "uuid": "cc4de73f-a8b9-4c01-8f45-141a74f29333", "version": "1.0.0" diff --git a/AppExamples/data_interfaces/CheckResultsDataArray/scripts/check_results_data_array.py b/AppExamples/data_interfaces/CheckResultsDataArray/scripts/check_results_data_array.py index 85b7a61..db2899b 100644 --- a/AppExamples/data_interfaces/CheckResultsDataArray/scripts/check_results_data_array.py +++ b/AppExamples/data_interfaces/CheckResultsDataArray/scripts/check_results_data_array.py @@ -5,7 +5,7 @@ # Carl Zeiss GOM Metrology GmbH, 2024 # # This App is part of the ZEISS INSPECT Python API Examples: -# https://zeissiqs.github.io/zeiss-inspect-addon-api/2023/python_examples/ +# https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/ # --- import gom diff --git a/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/Documentation.md b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/Documentation.md new file mode 100644 index 0000000..f7244dc --- /dev/null +++ b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/Documentation.md @@ -0,0 +1,196 @@ +# ReferencePointsAndMeshData + +![Point Cloud and Surface Elements from Reference Points/Mesh](refpoints_and_mesh.png){w=800px} + +## Short description + +This example demonstrates how to access the reference points in a measurement and the mesh from Python. For demonstration purposes, scripted point clouds or scripted surfaces are created from both data structures, respectively. + +## Highlights + +### 1. Accessing the reference points of a measurement + +In the Script Object dialog, select the keyword `Data arrays/Geometry/Coordinate` of the reference points element: + +![Script Object, Object Group: Elements, Measurements/Actual Measurements Series/Scan 1/Referenzpunkte, Keyword: Data arrays/Geometry/Coordinate](reference_points_script_object.png) + +The resulting Python data structure is a numpy-array of shape (1, \, 3): + +Index 0 +: Stage + +Index 1 +: Reference Points [0...\-1] + +Index 2 +: Coordinate [x, y, z] + +```{code-block} python +reference_points = np.array (gom.app.project.measurement_series[MEASUREMENT_SERIES].results['points'].data.coordinate) +``` + +`reference_points[0]` (i.e. stage index 0) gives a 2-dimensional numpy-array of the reference points' coordinates: + +``` +[[-235.58721273 -39.50188087 -21.06407058] + [-191.48581469 -13.62221568 -48.50181859] + ... + [ 228.23743314 41.62522002 -141.81405049]] +``` + +`reference_points[0].tolist()` creates an ordinary Python list from the numpy-array: + +``` +[[-235.5872127320349, -39.501880871176816, -21.064070577410664], + [-191.48581468551652, -13.62221567687171, -48.50181859232822], + ..., + [228.23743314034266, 41.62522001509065, -141.8140504931894]] +``` + +This can be used as input parameter to a script for creating a point cloud element: + +```{code-block} python +create_point_cloud = gom.script.sys.create_element_by_script ( + check_type='none', + element_type='point_cloud', + name=element_names['reference_points'], + parameters= { + 'points': reference_points[0].tolist() + }, + script_uuid='ff73513a-e857-43da-b4d2-382f80f25c28' +) +``` + +The function `gom.script.sys.create_element_by_script()` calls the script `create_point_cloud.py` by its `script_uuid`. The `script_uuid` can be found via the Add-on Explorer in the Script Properties (see [3. Script for creating a surface element](#3-script-for-creating-a-surface-element)). + +### 2. Accessing a mesh + +In the Script Object dialog, select the data structures `Data arrays/Geometry/Coordinate` and `Data arrays/Geometry/Triangle` of the mesh element: + +![Script Object, Object Group: Elements, Part/Mesh, Keyword: Data arrays/Geometry/Coordinate](mesh_coordinates.png) + +The **coordinates** are the vertex points of the mesh. + +The resulting Python data structure is a numpy-array of shape (1, \, 3): + +Index 0 +: Stage + +Index 1 +: Vertex Points [0...\-1] + +Index 2 +: Coordinate [x, y, z] + +```{code-block} python +part_points = np.array (gom.app.project.parts[PART].actual.data.coordinate) +``` + +Example: +``` +[[[-260.26819582 -55.07607781 -29.85369619] + [-260.2262357 -54.66295906 -29.56445928] # Index 1 + [-260.22035056 -54.82045257 -30.00434273] + [-260.20548655 -55.16190509 -29.58630829] + [-260.19041153 -54.08518361 -29.07912709] # Index 4 + [-260.18363995 -54.31011231 -29.50854346] # Index 5 + ... + [ 223.86296211 175.77943045 -208.493199 ]]] +``` + +Numpy-arrays can be handled very efficiently. The following code example creates a copy of the original mesh vertex points and shifts all points in Z direction by 200mm: + +```{code-block} python +shifted_part_points = part_points.copy() +shifted_part_points[0, :, 2] += 200 +``` + +![Script Object, Object Group: Elements, Part/Mesh, Keyword: Data arrays/Geometry/Triangle](mesh_triangles.png) + +The **triangles** are the edges between the vertex points. The resulting data structure is a numpy-array of shape (1, \, 3). + +Index 0 +: Stage + +Index 1 +: Triangle [0...\-1] + +Index 2 +: Indices into array of vertex points [indexA, indexB, indexC], which define the points A, B, C of each triangle. + +```{code-block} python +part_triangles = np.array (gom.app.project.parts[PART].actual.data.triangle) +``` + +Example: +``` +[[[ 1 4 5] + [ 3 6 0] + [ 3 7 11] + ... + [244350 244335 244338] + [244350 244341 244349] + [244350 244349 244343]]] +``` + +I.e. the first row (indices into array of vertex points) defines a triangle with points IndexA=1, IndexB=4 and IndexC=5 or edges ab=(1, 4), bc=(4, 5) and ca=(5, 1). + +Looking up the indexes in the array of vertex points in the example above gives the point coordinates: + +A = [-260.2262357 -54.66295906 -29.56445928] + +B = [-260.19041153 -54.08518361 -29.07912709] + +C = [-260.18363995 -54.31011231 -29.50854346] + + +The arrays of vertex points and triangles can be used as input parameters to a script for creating a surface element: + +```{code-block} python +create_surface = gom.script.sys.create_element_by_script ( + check_type='none', + element_type='surface', + name=element_names['shifted_part_surface'], + parameters= { + 'vertices': shifted_part_points[0].tolist(), + 'triangles': part_triangles[0].tolist() + }, + script_uuid='af863fa6-27d6-44d9-bba3-636eb09119fa' +) +``` + +### 3. Script for creating a surface element + +The scripts `create_point_cloud.py` and `create_surface.py` are provided in the example Add-on. + +Since no user interaction is required, the `dialog()` function shown in [Introduction to scripted elements](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_elements_introduction.html) as part of the code pattern can be omitted. Consequently, the checkbox Interactive Script in the Script Properties dialog is disabled. + +![Create Surface - Script Properties](create_surface_script_properties.png) + +```{code-block} python +:caption: create_surface.py + +def calculation(context, params): + valid_results=False + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = { + 'vertices': params['vertices'], + 'triangles': params['triangles'] + } + except Exception as error: + context.error[stage] = str(error) + else: + valid_results=True + return valid_results +``` + +## Related + +* How-to: [Access element properties and data](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#access-element-properties) +* How-to: [Introduction to scripted elements](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_elements_introduction.html) +* How-to: [Scripted actuals](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html) +* Python API Specification: [Scripted elements API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html) diff --git a/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/README.md b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/README.md index e3bb16a..f5c4346 100644 --- a/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/README.md +++ b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/README.md @@ -1,7 +1,9 @@ ## ReferencePointsAndMeshData -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [ReferencePointsAndMeshData](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/data_interfaces/reference_points_and_mesh_data.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/ReferencePointsAndMeshData) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/ReferencePointsAndMeshData) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/create_surface_script_properties.png b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/create_surface_script_properties.png new file mode 100644 index 0000000..9091025 Binary files /dev/null and b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/create_surface_script_properties.png differ diff --git a/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/mesh_coordinates.png b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/mesh_coordinates.png new file mode 100644 index 0000000..a2b0080 Binary files /dev/null and b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/mesh_coordinates.png differ diff --git a/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/mesh_triangles.png b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/mesh_triangles.png new file mode 100644 index 0000000..aed3a83 Binary files /dev/null and b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/mesh_triangles.png differ diff --git a/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/reference_points_script_object.png b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/reference_points_script_object.png new file mode 100644 index 0000000..0f69fb7 Binary files /dev/null and b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/reference_points_script_object.png differ diff --git a/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/refpoints_and_mesh.png b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/refpoints_and_mesh.png new file mode 100644 index 0000000..46e2ef6 Binary files /dev/null and b/AppExamples/data_interfaces/ReferencePointsAndMeshData/doc/refpoints_and_mesh.png differ diff --git a/AppExamples/data_interfaces/ReferencePointsAndMeshData/metainfo.json b/AppExamples/data_interfaces/ReferencePointsAndMeshData/metainfo.json index 5236221..d228255 100644 --- a/AppExamples/data_interfaces/ReferencePointsAndMeshData/metainfo.json +++ b/AppExamples/data_interfaces/ReferencePointsAndMeshData/metainfo.json @@ -2,14 +2,20 @@ "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example demonstrates how to access the reference points in a measurement and the mesh from Python.", "environment": "ZeissInspectExampleProjects", + "example-projects": ["zeiss_part_test_project"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#element-data-interfaces"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "reference-points", "mesh", "measurement" + ], "title": "ReferencePointsAndMeshData", "uuid": "be912619-f2b3-4733-83ff-69a0b5ce394e", "version": "1.0.0" diff --git a/AppExamples/data_interfaces/VolumeSectionImageData/doc/Documentation.md b/AppExamples/data_interfaces/VolumeSectionImageData/doc/Documentation.md new file mode 100644 index 0000000..4fc520f --- /dev/null +++ b/AppExamples/data_interfaces/VolumeSectionImageData/doc/Documentation.md @@ -0,0 +1,30 @@ +# VolumeSectionImageData + +![Volume section image](volume_section_image.jpg) + +## Short description + +This example demonstrates how to access the image data of a volume section. + +## Highlights + +There are two output formats available. + +1. **The raw image data** + + This is essentially the same as getting a slice of the volume. Data type and value are the same as the volume the section belongs to. + + `raw_image = np.array (element.data.raw)` + +2. **The rendered image** + + This yields the the image as rendered for the 3D view. + + `rgb_image = np.array (element.data.rgb)` + + This image is in RGBA format. Therefore you'll get the array shape of (1, 305, 295, 4). 1 project stage, 305x295 pixels, and 4 pixel values (RGBA). + You can use this image also for processing with other libraries. The screenshot above shows the image opened with `Pillow`. + +## Related + +* How-to: [Access element properties and data](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#access-element-properties) \ No newline at end of file diff --git a/AppExamples/data_interfaces/VolumeSectionImageData/doc/README.md b/AppExamples/data_interfaces/VolumeSectionImageData/doc/README.md index e5977d3..f1e7709 100644 --- a/AppExamples/data_interfaces/VolumeSectionImageData/doc/README.md +++ b/AppExamples/data_interfaces/VolumeSectionImageData/doc/README.md @@ -1,7 +1,9 @@ ## VolumeSectionImageData -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [VolumeSectionImageData](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/data_interfaces/volume_section_image_data.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/VolumeSectionImageData) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/VolumeSectionImageData) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/data_interfaces/VolumeSectionImageData/doc/volume_section_image.jpg b/AppExamples/data_interfaces/VolumeSectionImageData/doc/volume_section_image.jpg new file mode 100644 index 0000000..fb0c4f9 Binary files /dev/null and b/AppExamples/data_interfaces/VolumeSectionImageData/doc/volume_section_image.jpg differ diff --git a/AppExamples/data_interfaces/VolumeSectionImageData/metainfo.json b/AppExamples/data_interfaces/VolumeSectionImageData/metainfo.json index b3ad912..0bead15 100644 --- a/AppExamples/data_interfaces/VolumeSectionImageData/metainfo.json +++ b/AppExamples/data_interfaces/VolumeSectionImageData/metainfo.json @@ -2,14 +2,20 @@ "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example demonstrates how to access the image data of a volume section.", "environment": "ZeissInspectExampleProjects", + "example-projects": ["volume_test_project"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.html#element-data-interfaces"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "element-data" + ], "title": "VolumeSectionImageData", "uuid": "a254652f-75b8-4d77-8be4-04b7c5578194", "version": "1.0.0" diff --git a/AppExamples/dialog_widgets/DropdownWidget/doc/Documentation.md b/AppExamples/dialog_widgets/DropdownWidget/doc/Documentation.md new file mode 100644 index 0000000..b3ef96d --- /dev/null +++ b/AppExamples/dialog_widgets/DropdownWidget/doc/Documentation.md @@ -0,0 +1,21 @@ +# DropdownWidget + +![Selection list widget](dropdown_widget.jpg) + +## Short description + +This basic example shows how to use the selection list widged (aka. dropdown widget) and how to define items at script runtime. + +## Highlights + +Suppose you have created a script dialog that contains a `Selection -> Selection element` widget with a widget name `list`. + +Then, you can define the items of this dropdown menu by script: + +```python +DIALOG.list.items = ['yes', 'we', 'can'] +``` + +## Related + +* How-to: [User-defined Dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) diff --git a/AppExamples/dialog_widgets/DropdownWidget/doc/README.md b/AppExamples/dialog_widgets/DropdownWidget/doc/README.md index bae9e37..7fb88fd 100644 --- a/AppExamples/dialog_widgets/DropdownWidget/doc/README.md +++ b/AppExamples/dialog_widgets/DropdownWidget/doc/README.md @@ -1,7 +1,9 @@ ## DropdownWidget -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [DropdownWidget](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/dialog_widgets/dropdown_widget.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/DropdownWidget) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/DropdownWidget) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). diff --git a/AppExamples/dialog_widgets/DropdownWidget/doc/dropdown_widget.jpg b/AppExamples/dialog_widgets/DropdownWidget/doc/dropdown_widget.jpg new file mode 100644 index 0000000..af5f740 Binary files /dev/null and b/AppExamples/dialog_widgets/DropdownWidget/doc/dropdown_widget.jpg differ diff --git a/AppExamples/dialog_widgets/DropdownWidget/metainfo.json b/AppExamples/dialog_widgets/DropdownWidget/metainfo.json index ca0c863..5d48615 100644 --- a/AppExamples/dialog_widgets/DropdownWidget/metainfo.json +++ b/AppExamples/dialog_widgets/DropdownWidget/metainfo.json @@ -6,9 +6,14 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html#selection-list-widget"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "dialog", "selection-list-widget" + ], "title": "DropdownWidget", "uuid": "7fbc06f5-86af-4b38-8161-965de5956f5f", "version": "1.0.0" diff --git a/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/Documentation.md b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/Documentation.md new file mode 100644 index 0000000..a5b2b74 --- /dev/null +++ b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/Documentation.md @@ -0,0 +1,36 @@ +# ExplorerSelectedElementsInDialog + +![](explorer_selected_elements_in_dialog.png) + +## Short description + +Sometimes you might want to get the list of elements currently selected in the element explorer. This example shows how to do so, e.g. in a script dialog. + +## Highlights + +You can get all elements of a certain category by using a `gom.ElementSelection`. Then you can iterate over this list to check which ones are currently selected. + +```python +actual_elements = gom.ElementSelection ({'category': ['key', 'elements', 'part', gom.app.project.parts['Training Object'], 'explorer_category', 'actual']}) +selected_actuals = [element.name for element in actual_elements if element.is_selected] +``` + +```{hint} +As the `gom.ElementSelection`s get pretty lengthy, it is advised to generate these expressions using the "Script Object" explorer (`F2`). Select a category of elements and directly click "OK" to insert a corresponding selection expression. + +![Script object explorer image](explorer_selected_elements_script_explorer.png) +``` + +In the example, an exemplary selection of elements is also triggered by the script: + +```python +example_selection = [gom.app.project.actual_elements['Plane 1'], gom.app.project.actual_elements['Plane X +0.00 mm']] +gom.script.explorer.apply_selection (selection=example_selection) +``` + + +## Related + +* How-to: [Python API Introduction](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.md) +* How-to: [User-defined Dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) +* How-to: [Selecting elements in scripts](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/selecting_elements.md) diff --git a/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/README.md b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/README.md index 3378b7c..7f48c89 100644 --- a/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/README.md +++ b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/README.md @@ -1,7 +1,9 @@ ## ExplorerSelectedElementsInDialog -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [ExplorerSelectedElementsInDialog](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/dialog_widgets/explorer_selected_elements_in_dialog.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/ExplorerSelectedElementsInDialog) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/ExplorerSelectedElementsInDialog) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/explorer_selected_elements_in_dialog.png b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/explorer_selected_elements_in_dialog.png new file mode 100644 index 0000000..d0283da Binary files /dev/null and b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/explorer_selected_elements_in_dialog.png differ diff --git a/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/explorer_selected_elements_script_explorer.png b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/explorer_selected_elements_script_explorer.png new file mode 100644 index 0000000..fe1ac7f Binary files /dev/null and b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/doc/explorer_selected_elements_script_explorer.png differ diff --git a/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/metainfo.json b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/metainfo.json index 717273a..027c99e 100644 --- a/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/metainfo.json +++ b/AppExamples/dialog_widgets/ExplorerSelectedElementsInDialog/metainfo.json @@ -2,14 +2,20 @@ "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example shows how to get a list of elements selected in the element explorer and use it in a script dialog. ", "environment": "ZeissInspectExampleProjects", + "example-projects": ["zeiss_part_test_project"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html#selection-element-widget"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "dialog", "selection-element-widget" + ], "title": "ExplorerSelectedElementsInDialog", "uuid": "7fbfa2c1-8166-4835-9819-56746a63edff", "version": "1.0.0" diff --git a/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/Documentation.md b/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/Documentation.md new file mode 100644 index 0000000..9464152 --- /dev/null +++ b/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/Documentation.md @@ -0,0 +1,36 @@ +# UnitDialogEventHandler + +![](unit_dialog_event_handler.jpg) + +## Short description + +This basic example demonstrates how to use an event handler on a script dialog to set the unit to multiple widgets. + +## Highlights + +After creating a dialog with `gom.script.sys.create_user_defined_dialog`, you can **set an event handler** to this dialog. In this simple case, the `unit` property of a decimal input widget and a tolerance widget are set according to what the user selected in the `DIALOG.unit` widget: + +```python +if widget == DIALOG.unit: + DIALOG.input.unit = DIALOG.unit.value + DIALOG.tolerances.unit = DIALOG.unit.value +``` +Another interesting part of this example is the corresponding **test**. In `addon_tests/test_dialog_widgets_unit_dialog` is shown how a very basic testing of the event_handler can be implemented: + +```python +DIALOG=example.setup_dialog() +# Generating some events to test the event_handler +unit_widget = DIALOG.unit +unit_widget.value = "FORCE" + +# Test if the event_handler correctly links widget values +DIALOG.handler(unit_widget) +assert (DIALOG.input.unit == "FORCE") +assert (DIALOG.tolerances.unit == "FORCE") +``` + +This usage of the `DIALOG.handler` function mimics the user-interaction of changing the value of the `unit` widget manually to `"FORCE"`. + +## Related + +* How-to: [User-defined Dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/README.md b/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/README.md index 6a6517f..2baae52 100644 --- a/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/README.md +++ b/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/README.md @@ -1,7 +1,9 @@ ## UnitDialogEventHandler -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [UnitDialogEventHandler](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/dialog_widgets/unit_dialog_event_handler.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/UnitDialogEventHandler) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/UnitDialogEventHandler) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). diff --git a/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/unit_dialog_event_handler.jpg b/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/unit_dialog_event_handler.jpg new file mode 100644 index 0000000..dff17ff Binary files /dev/null and b/AppExamples/dialog_widgets/UnitDialogEventHandler/doc/unit_dialog_event_handler.jpg differ diff --git a/AppExamples/dialog_widgets/UnitDialogEventHandler/metainfo.json b/AppExamples/dialog_widgets/UnitDialogEventHandler/metainfo.json index 952377f..847a671 100644 --- a/AppExamples/dialog_widgets/UnitDialogEventHandler/metainfo.json +++ b/AppExamples/dialog_widgets/UnitDialogEventHandler/metainfo.json @@ -6,9 +6,14 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html#unit-widget"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "dialog", "unit-widget" + ], "title": "UnitDialogEventHandler", "uuid": "edc0b486-0816-4a7c-b98f-04295605f942", "version": "1.0.0" diff --git a/AppExamples/dialog_widgets/WidgetVisibility/doc/Documentation.md b/AppExamples/dialog_widgets/WidgetVisibility/doc/Documentation.md new file mode 100644 index 0000000..bf8495e --- /dev/null +++ b/AppExamples/dialog_widgets/WidgetVisibility/doc/Documentation.md @@ -0,0 +1,24 @@ +# WidgetVisibility + +![](widget_visibility_off.jpg) ![](widget_visibility_on.jpg) + +## Short description + +This example shows how to use a dialog event handler to turn on/off widget visibilities. + +## Highlights + +The example dialog was designed to contain a simple text label symbolizing the main content. Below, you find a "More" section consisting of a title, toggle button and a second text label. +The second label's visibility is changed (toggled) by the button. + +```python +def dialog_event_handler (widget): + # [...] + if widget == DIALOG.button: + DIALOG.label_bottom.visible = not DIALOG.label_bottom.visible +``` + + +## Related + +* How-to: [User-defined Dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/dialog_widgets/WidgetVisibility/doc/README.md b/AppExamples/dialog_widgets/WidgetVisibility/doc/README.md index 412abfc..507a8f4 100644 --- a/AppExamples/dialog_widgets/WidgetVisibility/doc/README.md +++ b/AppExamples/dialog_widgets/WidgetVisibility/doc/README.md @@ -1,7 +1,9 @@ ## WidgetVisibility -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [WidgetVisibility](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/dialog_widgets/widget_visibility.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/WidgetVisibility) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/WidgetVisibility) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). diff --git a/AppExamples/dialog_widgets/WidgetVisibility/doc/widget_visibility_off.jpg b/AppExamples/dialog_widgets/WidgetVisibility/doc/widget_visibility_off.jpg new file mode 100644 index 0000000..52a2f67 Binary files /dev/null and b/AppExamples/dialog_widgets/WidgetVisibility/doc/widget_visibility_off.jpg differ diff --git a/AppExamples/dialog_widgets/WidgetVisibility/doc/widget_visibility_on.jpg b/AppExamples/dialog_widgets/WidgetVisibility/doc/widget_visibility_on.jpg new file mode 100644 index 0000000..eb405e4 Binary files /dev/null and b/AppExamples/dialog_widgets/WidgetVisibility/doc/widget_visibility_on.jpg differ diff --git a/AppExamples/dialog_widgets/WidgetVisibility/metainfo.json b/AppExamples/dialog_widgets/WidgetVisibility/metainfo.json index 60c7c9d..276c969 100644 --- a/AppExamples/dialog_widgets/WidgetVisibility/metainfo.json +++ b/AppExamples/dialog_widgets/WidgetVisibility/metainfo.json @@ -6,9 +6,14 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "dialog", "widget-properties" + ], "title": "WidgetVisibility", "uuid": "ca7d5655-6eec-4e8f-8f70-4cf35fee4833", "version": "1.0.0" diff --git a/AppExamples/misc/CSVExample/doc/Documentation.md b/AppExamples/misc/CSVExample/doc/Documentation.md new file mode 100644 index 0000000..18af9b4 --- /dev/null +++ b/AppExamples/misc/CSVExample/doc/Documentation.md @@ -0,0 +1,145 @@ +# CSVExample + +![CSV Example Figure](csv_example.png) + +## Short description + +This example demonstrates how to read and write CSV files (comma separated values) from an App. The CSV file access is implemented using the [CSV Library](https://docs.python.org/3/library/csv.html) provided with the Python installation. + +For demonstration purposes, project keywords are read from or written to a CSV file, but the example can be used as a template for other items. + +![Define Project Keywords Dialog](define_project_keywords.png) + +## Prerequisite + +Both example scripts check if a project has been opened and quit with an error message dialog if this is not the case: + +```{code-block} python +if not hasattr(gom.app, 'project'): + gom.script.sys.execute_user_defined_dialog (file='no_project.gdlg') + quit(0) +``` + +## CSV read example: `csv_import.py` + +The CSV module is imported: + +```{code-block} python +import csv +``` + +The current project keywords and their values are listed: + +```{code-block} python +print("-- Current keywords --") +for k in gom.app.project.project_keywords: + print(f"{k}='{gom.app.project.get(k)}'") +``` + +A dialog is used to request the CSV file to be opened: + +```{code-block} python +RESULT=gom.script.sys.execute_user_defined_dialog (file='import_file.gdlg') +``` + +The CSV file is opened and a `csv_reader` object for accessing its content is created: + +```{code-block} python +with open(RESULT.file) as csv_file: + csv_reader = csv.reader(csv_file, delimiter=';') +``` + +The class `csv.reader` allows some configurations, such as the column delimiter. + +The scripts reads the CSV file line by line. Each line is provided as an array with the columns as its array elements. The first line is expected to contain a specific table header (`Project Keyword;Description;Value`). The remaining lines are used to create or change project keywords: + +```{code-block} python +with open(RESULT.file) as csv_file: + csv_reader = csv.reader(csv_file, delimiter=';') + line_count = 0 + for row in csv_reader: + # [...] + key = row[0] + desc = row[1] + val = row[2] + if line_count == 0: + print(f'Column names are {", ".join(row)}') + if key != "Project Keyword" or desc != "Description" or val != "Value": + gom.script.sys.execute_user_defined_dialog (file='wrong_format.gdlg') + quit(0) + + else: + # Add or change project keyword (see below) + # [...] + + line_count += 1 +``` + +The keywords in the array `gom.app.project.project_keywords` have the prefix `user_`, but this prefix has to be removed for the method `gom.script.sys.set_project_keywords()`. + +The script distinguishes the following cases: +1. The keyword in the Excel file is new +2. The keyword in the Excel file already exists, but its value has changed +3. The keyword in the Excel file already exists, but its description has changed +4. The keyword in the Excel file already exists and remains unchanged + +```{code-block} python +ukw = "user_" + key +if not ukw in gom.app.project.project_keywords: + print(f"New keyword {key}='{val}' added") + gom.script.sys.set_project_keywords(keywords={key:val}, keywords_description={key:desc}) +else: + ex_val = gom.app.project.get(ukw) + ex_desc = gom.app.project.get(f'description({ukw})') + if (val == ex_val) and (desc == ex_desc): + print(f"Existing keyword {key}='{val}' - not changed") + else: + if val != ex_val: + print(f"Existing keyword {key}='{ex_val}' changed to '{val}'") + gom.script.sys.set_project_keywords(keywords={key:val}) + if desc != ex_desc: + print(f"Existing keyword {key} - description '{ex_desc}' changed to '{desc}'") + gom.script.sys.set_project_keywords(keywords_description={key:desc}) +``` + +Finally, the updated project keywords are listed: + +```{code-block} python +print("\n-- Updated keywords --") +for k in gom.app.project.project_keywords: + print(f"{k}='{gom.app.project.get(k)}'") +``` + +## CSV export example: `csv_export.py` + +As in `csv_import.py`, the module `csv` is imported, the presence of an open project is checked and the user is requested to select a file for exporting. + +The file is opened and the `keywords_writer` object is created. Some configuration settings are passed to the constructor. First, the header row is written using the method `writerow()` with an array containing the column headings. Next, a loop iterates over all project keywords and writes them to the CSV file using `writerow()`: + +```{code-block} python +with open(RESULT.file, mode='w', newline='') as keywords_file: + keywords_writer = csv.writer( + keywords_file, + delimiter=';', + quotechar='"', + quoting=csv.QUOTE_MINIMAL + ) + + # Header row + keywords_writer.writerow(['Project Keyword', 'Description', 'Value']) + + for key in gom.app.project.project_keywords: + val = gom.app.project.get(key) + desc = gom.app.project.get(f'description({key})') + + # Remove prefix 'user_' from key + key = key[5:] + print(f"{key} - {desc}: {val}") + + # Special case - convert gom.Date to datetime-object + if type(val) is gom.Date: + val = datetime.datetime(val.year, val.month, val.day) + + # Write next row + keywords_writer.writerow([key, desc, val]) +``` diff --git a/AppExamples/misc/CSVExample/doc/README.md b/AppExamples/misc/CSVExample/doc/README.md index 2862915..2763cd8 100644 --- a/AppExamples/misc/CSVExample/doc/README.md +++ b/AppExamples/misc/CSVExample/doc/README.md @@ -1,7 +1,9 @@ ## CSVExample -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [CSVExample](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/misc/csv_example.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/CSVExample) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/CSVExample) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/misc/CSVExample/doc/csv_example.png b/AppExamples/misc/CSVExample/doc/csv_example.png new file mode 100644 index 0000000..c8009ed Binary files /dev/null and b/AppExamples/misc/CSVExample/doc/csv_example.png differ diff --git a/AppExamples/misc/CSVExample/doc/define_project_keywords.png b/AppExamples/misc/CSVExample/doc/define_project_keywords.png new file mode 100644 index 0000000..bf18f58 Binary files /dev/null and b/AppExamples/misc/CSVExample/doc/define_project_keywords.png differ diff --git a/AppExamples/misc/CSVExample/metainfo.json b/AppExamples/misc/CSVExample/metainfo.json index 01eaf3d..320ea5a 100644 --- a/AppExamples/misc/CSVExample/metainfo.json +++ b/AppExamples/misc/CSVExample/metainfo.json @@ -1,6 +1,7 @@ { "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example demonstrates how to read and write CSV files (comma separated values) from an App.", + "example-projects": ["zeiss_part_test_project"], "labels": [], "licensing": { "licenses": [], @@ -8,7 +9,9 @@ }, "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "import", "export", "project-keywords" + ], "title": "CSVExample", "uuid": "c680fdb2-7802-4387-ac9c-ef2ae66c5526", "version": "1.0.0" diff --git a/AppExamples/misc/DialogReopenExample/doc/Documentation.md b/AppExamples/misc/DialogReopenExample/doc/Documentation.md new file mode 100644 index 0000000..89cc00d --- /dev/null +++ b/AppExamples/misc/DialogReopenExample/doc/Documentation.md @@ -0,0 +1,46 @@ +# DialogReopenExample + +![](dialog_reopen_example.jpg) + +## Short description + +This examples demonstrates, how a dialog can be closed from its own handler, just to be opened again. + +```{warning} +There are very rare occasions, where you should need this. Use this approach only, if you know what you are doing. +``` + +## Highlights + +The approach consists of two steps. First, declare a guard variable that yields `True` if the dialog should be reopened. + +```python +[...] +reopen = True +while reopen: + gom.script.sys.show_user_defined_dialog (dialog=DIALOG) +``` + +The example dialog contains a button to close/reopen the dialog (see top image). One of the few use cases could be, that you need to adapt the `filter` property of an `Selection element` widget after some dialog interaction, which can only be done when the dialog is closed. + +To achieve this, the dialog event handler is used: + +```python +def dialog_event_handler (widget): + global reopen + if str(widget) == "initialize": + reopen = False + if widget == DIALOG.button: + gom.script.sys.close_user_defined_dialog (dialog=DIALOG) + gom.script.sys.delay_script (time=1) # Do stuff while dialog is closed + reopen = True +``` + +```{warning} +Never reopen the dialog directly from its own handler to prevent getting undefined behaviour. +``` + + +## Related + +* How-to: [User-defined Dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/misc/DialogReopenExample/doc/README.md b/AppExamples/misc/DialogReopenExample/doc/README.md index d0e7ed1..cd2f522 100644 --- a/AppExamples/misc/DialogReopenExample/doc/README.md +++ b/AppExamples/misc/DialogReopenExample/doc/README.md @@ -1,7 +1,9 @@ ## DialogReopenExample -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [DialogReopenExample](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/misc/dialog_reopen_example.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/DialogReopenExample) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/DialogReopenExample) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/misc/DialogReopenExample/doc/dialog_reopen_example.jpg b/AppExamples/misc/DialogReopenExample/doc/dialog_reopen_example.jpg new file mode 100644 index 0000000..cc0d76f Binary files /dev/null and b/AppExamples/misc/DialogReopenExample/doc/dialog_reopen_example.jpg differ diff --git a/AppExamples/misc/DialogReopenExample/metainfo.json b/AppExamples/misc/DialogReopenExample/metainfo.json index b2d201b..2230165 100644 --- a/AppExamples/misc/DialogReopenExample/metainfo.json +++ b/AppExamples/misc/DialogReopenExample/metainfo.json @@ -6,9 +6,14 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.html#executing-dialogs"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "dialog" + ], "title": "DialogReopenExample", "uuid": "7ae503b5-2988-4eff-9b46-f1c9d9c01f63", "version": "1.0.0" diff --git a/AppExamples/misc/PointPixelTransformations/doc/Documentation.md b/AppExamples/misc/PointPixelTransformations/doc/Documentation.md new file mode 100644 index 0000000..d8616db --- /dev/null +++ b/AppExamples/misc/PointPixelTransformations/doc/Documentation.md @@ -0,0 +1,88 @@ +# PointPixelTransformations + +## Short description + +This example demonstrates how to find the 2D pixel coordinates of a 3D point coordinate and vice versa. + +## Highlights + +The example uses `gom.api.imaging` functions. The transformations work with any 3D point, but using a reference point increases the comprehensibility. + +Each measurement has two arrays for reference points with matching indices: + +`measurement.reference_point_id` - The reference points' Ids or `None` for an invalid reference point +`measurement.reference_point_coordinate` - The reference points' coordinates + +### 1. Set the point coordinate + +```{code-block} python +measurement = gom.app.project.measurement_series[MEASUREMENT_SERIES].measurements[MEASUREMENT] +stage_index = 0 + +# Using the first valid reference point in the selected measurement as the point example +for index, id in enumerate(measurement.reference_point_id): + if id is not None: + break + +reference_point = measurement.reference_point_coordinate[index] +print(f'\tFirst reference point in {MEASUREMENT_SERIES} - {MEASUREMENT}: ID = {id}, P = {reference_point})') +``` + +Reference points' IDs and coordinates + +![Table: Reference Points](point_pixel_transformations/assets/reference_points_table.png){w=800px} + +### 2. Get the left and right camera image + +```{code-block} python +left = gom.api.project.get_image_acquisition(measurement, 'left camera', [stage_index])[0] +right = gom.api.project.get_image_acquisition(measurement, 'right camera', [stage_index])[0] +``` + +### 3. Compute 2D pixel coordinates from 3D point + +```{code-block} python +image_coordinates = gom.api.imaging.compute_pixels_from_point ([(reference_point, left), (reference_point, right)]) +print(f'\tImage coordinates of reference point (left, right): {image_coordinates}') +``` + +Output: + +``` +First reference point in Scan 1 - M1: ID = 1000, P = gom.Vec3d (31.3076865556476, 201.84682632142676, -174.57793227593282)) +Image coordinates of reference point (left, right): [gom.Vec2d (1980.7299023612043, 150.31166936961336), gom.Vec2d (2545.676173697585, 124.49594153283601)] +``` + +### 4. Compute 3D point coordinate from 2D pixels + +The resulting 2D pixels from the previous step are used as the input parameters to the transformation. + +```{code-block} python +print(f'\tLeft image: {image_coordinates[0]}, Right image: {image_coordinates[1]}') +use_calibration = False +point_and_residuum = gom.api.imaging.compute_point_from_pixels ([[(image_coordinates[0], left), (image_coordinates[1], right)]], use_calibration)[0] +print(f'\tComputation result: P = {point_and_residuum[0]}, Residuum: {point_and_residuum[1]}') +``` + +Output: + +``` +Left image: gom.Vec2d (1980.7299023612043, 150.31166936961336), Right image: gom.Vec2d (2545.676173697585, 124.49594153283601) +Computation result: P = gom.Vec3d (-144.2165521110654, 168.67899387974234, -172.4471527045714), Residuum: 2.906708252303575e-08 +``` + +### 5. For comparison: Interactive display of reference points and pixel coordinates + +Explorer: Measurement — Edit Creation Parameters + +![Measurement Creation Parameters](point_pixel_transformations/assets/measurement_creation_parameters.png){w=400px} + + +Edit Creation Parameters Dialog + +![Edit Creation Parameters Dialog](point_pixel_transformations/assets/camera_image_reference_points.png){w=800px} + +## Related + +* gom.api.imaging.compute_pixels_from_point +* gom.api.imaging.compute_point_from_pixels diff --git a/AppExamples/misc/PointPixelTransformations/doc/README.md b/AppExamples/misc/PointPixelTransformations/doc/README.md index 9565c6e..30c37a2 100644 --- a/AppExamples/misc/PointPixelTransformations/doc/README.md +++ b/AppExamples/misc/PointPixelTransformations/doc/README.md @@ -1,7 +1,9 @@ ## PointPixelTransformations -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [PointPixelTransformations](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/misc/point_pixel_transformations.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/PointPixelTransformations) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/PointPixelTransformations) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/misc/PointPixelTransformations/doc/camera_image_reference_points.png b/AppExamples/misc/PointPixelTransformations/doc/camera_image_reference_points.png new file mode 100644 index 0000000..28be1e3 Binary files /dev/null and b/AppExamples/misc/PointPixelTransformations/doc/camera_image_reference_points.png differ diff --git a/AppExamples/misc/PointPixelTransformations/doc/measurement_creation_parameters.png b/AppExamples/misc/PointPixelTransformations/doc/measurement_creation_parameters.png new file mode 100644 index 0000000..d194bd6 Binary files /dev/null and b/AppExamples/misc/PointPixelTransformations/doc/measurement_creation_parameters.png differ diff --git a/AppExamples/misc/PointPixelTransformations/doc/reference_points_table.png b/AppExamples/misc/PointPixelTransformations/doc/reference_points_table.png new file mode 100644 index 0000000..b02a9c9 Binary files /dev/null and b/AppExamples/misc/PointPixelTransformations/doc/reference_points_table.png differ diff --git a/AppExamples/misc/PointPixelTransformations/metainfo.json b/AppExamples/misc/PointPixelTransformations/metainfo.json index b438a77..24a94aa 100644 --- a/AppExamples/misc/PointPixelTransformations/metainfo.json +++ b/AppExamples/misc/PointPixelTransformations/metainfo.json @@ -2,14 +2,20 @@ "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example demonstrates how to find the 2D pixel coordinates of a 3D point coordinate and vice versa.", "environment": "ZeissInspectExampleProjects", + "example-projects": ["zeiss_part_test_measurement"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/python_api.html#gom-api-imaging"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "measurement", "reference-points" + ], "title": "PointPixelTransformations", "uuid": "e5c1a499-b268-4879-a0f7-6ff8385e5de5", "version": "1.0.1" diff --git a/AppExamples/misc/ServiceExample/doc/Documentation.md b/AppExamples/misc/ServiceExample/doc/Documentation.md new file mode 100644 index 0000000..f018390 --- /dev/null +++ b/AppExamples/misc/ServiceExample/doc/Documentation.md @@ -0,0 +1,99 @@ +# ServiceExample + +## Short description + +This example demonstrates how to implement, use and manage services. + +## Highlights + +1. Service implementation + +The service API function has the `@apifunction` decorator and the service script calls `gom.run_api()`: + +```{code-block} python +:caption: Service script example multiplicator/service.py + +import gom +from gom import apifunction + +@apifunction +def multiply(value1: float, value2: float) -> float: + gom.log.debug('Function "multiply" called') + return value1 * value2 + +gom.run_api() +``` + +The service is configured in the App's `metainfo.json`: + +```{code-block} json +{ + //... + "services": [ + { + "endpoint": "gom.api.math", + "name": "Multiplicator", + "script": "multiplicator/service.py" + } + ] + //... +} +``` + +2. Service usage + +The service must be installed and started before it can be used. To use a service in a script, import its API endpoint and call its API function: + +```{code-block} python +:caption: Example script using the multiply() function provided by the multiplicator service with endpoint gom.api.math + +import gom.api.math + +result = gom.api.math.multiply (24, 7) +print(result) +``` + +3. Service management from a script + +[gom.api.services](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/python_api.html#gom-api-services) allows to query and control services from a script: + +```{code-block} python +:caption: Example script for querying and controlling services + +import sys +import gom.api.services + +SERVICE_NAME = "Reflector" + +# Find service handle by name +srv = None +for s in gom.api.services.get_services(): + if s.get_name() == SERVICE_NAME: + srv = s + +if not srv: + print("Failed to get {SERVICE_NAME} service handle") + sys.exit(0) + +# Query service properties +print(f"'{srv.get_name()}' service properties") +print(f"Autostart: {srv.get_autostart()}") +print(f"Endpoint: {srv.get_endpoint()}") +print(f"Number of instances: {srv.get_number_of_instances()}") + +# Control service +print(srv.get_status()) +print("(Re-)Starting...", end="") +srv.start() +print(srv.get_status()) +print("Stopping...", end="") +srv.stop() +print(srv.get_status()) +print("Starting...", end="") +srv.start() +``` + +## Related + +* How-to: [Using services](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/using_services/using_services.md) +* [gom.api.services](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/python_api.html#gom-api-services) diff --git a/AppExamples/misc/ServiceExample/doc/README.md b/AppExamples/misc/ServiceExample/doc/README.md new file mode 100644 index 0000000..4fbc5e3 --- /dev/null +++ b/AppExamples/misc/ServiceExample/doc/README.md @@ -0,0 +1,9 @@ +## ServiceExample + +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/dev/AppExamples). + +See [App documentation](Documentation.md) for details. + +You can [download this App](https://software-store.zeiss.com/products/apps/ServiceExample) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/misc/ServiceExample/icon.png b/AppExamples/misc/ServiceExample/icon.png new file mode 100644 index 0000000..42dbd76 Binary files /dev/null and b/AppExamples/misc/ServiceExample/icon.png differ diff --git a/AppExamples/misc/ServiceExample/license/license.txt b/AppExamples/misc/ServiceExample/license/license.txt new file mode 100644 index 0000000..bb42913 --- /dev/null +++ b/AppExamples/misc/ServiceExample/license/license.txt @@ -0,0 +1,296 @@ +ZEISS Add-Ons / Apps End User License Agreement (EULA) +====================================================== + +English version. See below for German version. +Englische Version. Siehe unten für die Deutsche Version. + +1. Introduction + +1.1 General information + +This End User License Agreement for Add-Ons / Apps ("EULA Add-Ons / Apps") is a legal agreement between "you" (either an individual or a legal entity, hereinafter referred to as "licensee" or "customer") and ZEISS ("ZEISS" or "licensor") (each individually a "party" and collectively the "parties") for your use of ZEISS software products. The agreement sets forth all rights and obligations for both licensee and ZEISS and governs your use of all Software Products installed or provided by ZEISS. Any amendment to this agreement must be in writing and in accordance with the terms and conditions contained herein. By paying the applicable license fee(s) and by downloading, installing or using the software, you agree that this agreement shall be enforceable against you in the same manner as a written, negotiated contract signed by you. If you do not agree to the terms of this agreement, you are not authorized and may not download, install or use any ZEISS software products. + +In order to use the ZEISS software products and services, the licensee must have the following: + +(a) a so-called valid subscription agreement or + +(b) a valid license from ZEISS. + +Furthermore, individual software products + +(a) which are based on a subscription agreement and / or + +(b) with a server-based licensing solution + +require and use a secure connection of the application computer to the ZEISS infrastructure and/or the "Cloud Services". + +1.2 The licensor is ZEISS, the licensee is the end customer. The licensor grants the licensee a non-exclusive, non-transferable right to use the "software product", which includes the specific software program and the subsequent extensions, updates, patches and associated documentation for internal company operation, as well as the associated manuals and software documentation. + +1.3 The software product may contain codes, objects and other intellectual property developed and licensed by licensors or third parties and integrated into the software product ("embedded third party software"). Any embedded third party software or open source code and open source licenses used shall not limit or impair the rights of use granted to licensee and may be accessed at any time within the respective software used. In individual cases, the respective license conditions can be made available by the licensor upon request at any time. + +1.4 Any terms and conditions of purchase of the licensee that conflict with or deviate from this agreement shall not become part of the agreement, even if the licensor does not expressly object to them. Amendments to the EULA must be expressly agreed in writing by both parties. + + +2. Term and termination / license fees + +2.1 The license agreement begins with license activation and ends with the period of use of the Pro Version or with the end of the payment period. + +2.2 The Licensor shall be entitled to terminate this license agreement and the corresponding rights of use with immediate effect if the licensee violates any provision of this license agreement or tacitly tolerates a violation of this license agreement by third parties or fails to fulfill its obligations under this license agreement or if the licensee files for insolvency or a change of control occurs at the licensee. + +2.3 Notwithstanding the foregoing, and unless otherwise agreed in this license agreement, this license agreement shall terminate automatically upon licensee's breach of any of its provisions. + +2.4 Under no circumstances shall license fees be fully or partially refundable upon termination or mutually agreed termination of this agreement, unless ZEISS is responsible for the early termination of this agreement. + + +3. Reproduction rights + +3.1 The licensee may reproduce the delivered software to the extent that the reproduction is necessary to use the software. Necessary reproductions of the software include, but are not limited to, the installation of the software product on the mass storage of the device in accordance with this license agreement and the loading of the software into the main memory of the computer. + +3.2 In addition, licensee shall be entitled to make copies for data backup purposes. This backup copy of the licensed software product must be marked as such. + +3.3 If, for reasons of data security or backup, a quick reactivation of the computer system, including the subject matter of the agreement, and the backup of the entire data stock, including the installed software product, are required after a total failure, licensee may create the maximum required number of backup copies. The data media concerned shall be appropriately marked. The backup copies may only be used for archiving purposes. + +3.4 The licensee is not entitled to make further copies or to instruct third parties to make further copies, in particular the licensee is not entitled to print out the program code with a printer or to make photocopies of the manual. + + +4. Resale and transfer + +4.1 The licensee is not entitled to rent, lease, lend or make the software product available to third parties within the scope of hosting or download options, unless the Licensor has expressly indicated or permitted this in writing. + +4.2 However, it is permitted to grant a right of use to third parties if they have to use the software product to the licensee’s specifications (like own employees). Independent third parties are excluded from use in any case. + +4.3 Transfer within legal entities or global groups of licensee: Provided that the transferring licensee and the receiving party are part of one legal entity or part of affiliated companies, the transfer is permitted provided that the receiving party agrees to these license terms. "Affiliate" means any legal entity that is directly or indirectly controlled by a Legal Entity or its parent company. "Control" for purposes of this license agreement means direct or indirect ownership of more than fifty percent (50%) of the stock of such entity or more than fifty percent (50%) direct or indirect participation in the decision-making body of such entity. + + +5. Back translation and program changes + +5.1 As a matter of principle, the licensee may not make any changes to the software product unless this is necessary to correct errors. The prerequisite is that this is done solely for the purpose of correcting errors that impair the functioning of the software. +In the latter case and if important program functions and working methods could be disclosed during the repair process, licensee may commission a commercially active third party to carry out the repair if this third party is not a potential competitor of licensor. +Insofar as the licensee makes changes to the software product in order to rectify errors, the licensor shall not assume any liability for the resulting consequences, in particular not through this authorization. + +5.2 The reverse translation of the licensed program code into other code forms (decompilation) and other types of reverse engineering of various different phases of software creation are permitted only to the extent that they serve to correct errors that impair the functioning of the software (in accordance with section 5.1). However, licensee may perform such decompilation only to the extent necessary for correction and, if applicable, in compliance with the terms and conditions contractually agreed with the owner of the copyright in this program. +Further, decompilation is permitted in cases to obtain information necessary for interoperability with an independently created computer program and only if such information cannot be obtained otherwise. + +5.3 A further prerequisite for the permission to reverse engineer is the performance of reverse engineering or program observation exclusively by means of procedures which the licensee is authorized to perform in accordance with this license agreement. In particular, the program code may in no case be printed out. + +5.4 All property rights and copyrights relating to the software product, the printed accompanying materials and all copies of the software product shall remain with the licensor or its suppliers. This software product is protected under German copyright law, U.S. copyright law and the provisions of international treaties. The licensee is not entitled to reproduce the printed materials accompanying the software. + + +5.5 The licensee shall not be entitled to remove, modify or add to any copyright notices or trademark notices placed by licensor. This includes, without limitation, all references in physical and/or electronic media or documents, in "setup wizards" or in "about..." dialog boxes, and/or in other references displayed on or activated via the Internet, in program code or other embodiments originally included in the software or otherwise created by licensor. + +6. Warranty and right of termination + +6.1 The licensor warrants with respect to the software product licensed to the licensee the performance set forth in the description, provided that the software product is installed in the intended system in compliance with the licensor's guidelines. + +6.2 The licensor shall correct errors in the software product, and in all manuals and other documents, within a reasonable period of time after receiving from the licensee the corresponding information on the error necessary to correct the error. Errors shall be remedied by rectification, which shall not be invoiced, or by replacement of the delivery, at the option of the licensor. + +6.3 The licensee's right of termination due to the non-executability of the software product may only be exercised after rectifications or replacements have been made twice without success. + +6.4 The licensor neither warrants nor guarantees the functionality of the programs created by third parties or the licensee / customer, nor the error-free execution of the programs with the software or on the licensor's systems. + + +7. Liability + +7.1 If the licensee is unable to use the software product in the manner specified in the agreement and the licensee is responsible for this due to the failure to implement or the incorrect implementation of suggestions and advice before or after signing the agreement or due to the breach of other contractual obligations, the provisions set forth in this agreement shall apply mutatis mutandis to the exclusion of any further claims by the licensee. + +For damages that do not occur to the software product, respectively not to the hardware and the connected device, the liability obligation of the licensor applies exclusively in the following cases, regardless of the respective legal ground: + +- willful misconduct, + +- gross negligence of its executive bodies or officers, + +- culpable damage to life, limb and health, in the event of errors, which the lLicensor has fraudulently concealed or which it has excluded under warranty, + +- software errors within the scope of liability for personal injury and property damage due to personally implemented objects, as set out in the product liability regulations applicable to them + +7.2 In the event of culpable breach of material contractual obligations, the licensor shall also be liable for gross negligence on the part of non-executive employees and for slight negligence. In the latter case, liability shall be limited to damages that are foreseeable and typical for this type of contract. + +7.3 In addition, the licensor, its employees and its vicarious agents shall be liable for data loss or changes due to program errors, limited to the extent that this would have been unavoidable if the licensee had complied with its obligation to make back-up copies regularly and at least once a day. + +7.4 In the event of claims based on copyright infringement, the licensor shall grant the licensee the right to continue using the software product or to make modifications to the software product so that copyright protection is ensured. If this is not commercially reasonable, the licensor shall take back the subject matter of the agreement and refund the license fee paid, less an amount corresponding to the duration of the previous use. This shall apply provided that the licensee notifies the licensor of this type of claim in writing without delay and allows licensor all legal remedies and out-of-court settlements. + +7.5 The licensee or its IT provider shall be liable for server interruptions, interruption of license allocation and other support cases that are not clearly attributable to an incorrectly created license. + +The licensee or its IT provider is responsible for maintaining the necessary number of licenses to provide its services. The licensor is not liable for interruptions in use and subsequent work / production stoppages. + + +7.6 Further liability claims of the licensee are expressly excluded. +7.7 The licensee is responsible for all problems arising from the use of the software product that are not directly caused by the licensor. Therefore, licensee is responsible for all data generated and produced during the use of the software product. Accordingly, licensee is obligated and responsible for compliance with the terms and conditions set forth in this license agreement. + + +8. Security measures + +The licensee shall take suitable measures to secure the software and, if applicable, the access data for online access against access by unauthorized third parties. In particular, all copies of the software as well as the access data shall be kept in a protected place. + + +9. Industrial property rights and copyrights + +9.1 If a third party asserts claims for infringement of an industrial property right or a copyright against the customer because the customer uses a software version, firmware supplement or associated documentation supplied by ZEISS, ZEISS shall be obligated to pay any cost and damage compensation amounts awarded to the owner of the property right by a court or awarded with the prior consent of ZEISS. This is subject to the condition that the customer informs ZEISS immediately in writing of such claims and that ZEISS reserves the right to all defensive measures and out-of-court settlements. The customer is obligated to support ZEISS in the defense to the best of its ability. Under these conditions, ZEISS shall generally procure for the customer the right to continue using the software version, firmware supplement or documentation. If this should not be possible under economically reasonable conditions, ZEISS shall be obligated, at its own discretion and at its own expense, either to modify or replace the relevant item in such a way that the property right is not infringed, or to take back the item and refund the remuneration paid for it less an amount taking into account the benefits derived. + +9.2 ZEISS shall have no obligations if property right infringements are caused by the fact that software versions , firmware supplements or documentation supplied by ZEISS are not used in the intended manner or are not used on the specific systems. + + +10. Export Control + +Licensee assumes responsibility for compliance with all applicable rules and regulations, including but not limited to the export control and sanctions regulations of the Federal Republic of Germany, the European Union and the United States of America. In particular, licensee agrees not to provide the software or any related technology or documentation or any part thereof, directly or indirectly, to any sanctioned country or to any sanctioned person or entity in violation of the foregoing. + +Licensee represents and guarantees that it will not use the software or any related technology or documentation or any portion thereof in violation of any applicable law or regulation. The licensee further agrees to indemnify and hold harmless licensor from and against any and all claims resulting from licensee's failure to comply with any of the foregoing applicable provisions. + + +11. Miscellaneous + +11.1 All verbal agreements, amendments, extensions or concretizations of these license conditions as well as the special characteristics of the assurances or agreements or arrangements made must be in writing to be legally effective. If these are drafted by representatives or vicarious agents of the Licensor, they shall only become legally binding upon approval by the Licensor. + +11.2 Should parts of this contract become invalid, this shall not affect the validity of the remaining parts of this contract. The ineffective part of this contract shall be replaced by its parties with legally permissible provisions that come as close as possible to the intention of the ineffective provisions. + +11.3 The laws of the Federal Republic of Germany shall apply to this contract, excluding the law on the international sale of goods and the rules of conflict of laws. + +Version from October 2023 + +----------------------------------------------------------------------------- + +ZEISS Add-Ons / Apps End User License Agreement (EULA) +====================================================== + +German version. See above for English version. +Deutsche Version. Siehe oben für die Englische Version. + +1. Einführung + +1.1 Allgemeine Informationen + +Diese Endbenutzer-Lizenzvereinbarung für Add-Ons / Apps (End User License Agreement, „EULA Add-Ons / Apps“) ist eine rechtsgültige Vereinbarung zwischen „Ihnen“ (entweder eine natürliche oder juristische Person, im Folgenden als „Lizenznehmer“ oder „Kunde“ bezeichnet) und ZEISS („ZEISS“ oder „Lizenzgeber“) (jeweils einzeln eine „Partei“ und zusammen die „Parteien“) für Ihre Nutzung von ZEISS Softwareprodukten. Die Vereinbarung legt alle Rechte und Pflichten sowohl für den Lizenznehmer als auch für ZEISS fest und regelt Ihre Nutzung aller Softwareprodukte, die von ZEISS installiert oder zur Verfügung gestellt werden. Jede Änderung dieser Vereinbarung muss schriftlich erfolgen und mit den hierin enthaltenen Bestimmungen und Bedingungen übereinstimmen. Durch die Zahlung der geltenden Lizenzgebühr(en) und durch das Herunterladen, die Installation oder die Nutzung der Software erklären Sie sich damit einverstanden, dass diese Vereinbarung Ihnen gegenüber gleichermaßen durchsetzbar ist wie ein schriftlicher, ausgehandelter und von Ihnen unterzeichneter Vertrag. Wenn Sie den Bedingungen dieser Vereinbarung nicht zustimmen, sind Sie nicht berechtigt und dürfen keine ZEISS Softwareprodukte herunterladen, installieren oder verwenden. + +Für die Nutzung der ZEISS Softwareprodukte und Leistungen muss der Lizenznehmer über Folgendes verfügen: + +(a) einen sog. gültigen Subscriptionvertrag oder + +(b) eine gültige Lizenz von ZEISS. + +Ferner erfordern und verwenden einzelne Softwareprodukte + +(a) die auf einem Subscriptionvertrag basieren und / oder + +(b) mit einer serverbasierten Lizenzlösung + +eine sichere Verbindung des Applikationsrechners mit der ZEISS Infrastruktur und / oder den „Cloud Services“. + +1.2 Lizenzgeber ist ZEISS Lizenznehmer ist der Endkunde. Der Lizenzgeber gewährt dem Lizenznehmer ein nicht ausschließliches, nicht übertragbares Nutzungsrecht für das „Softwareprodukt“, welches das spezielle Softwareprogramm und die damit nachfolgenden Erweiterungen, Updates, Patches und zugehörige Dokumentation für den unternehmensinternen Betrieb, wie auch die dazugehörigen Handbücher und Softwaredokumentation, einschließt. + +1.3 Das Softwareprodukt kann Codes, Objekte und anderes geistiges Eigentum enthalten, das von Lizenzgebern oder Dritter entwickelt und von diesen lizenziert und in das Softwareprodukt integriert wurde („Embedded Third Party Software“). Etwaig verwendete Embedded Third Party Software oder Open Source-Code und Open Source-Lizenzen beschränken oder beeinträchtigen die gewährten Nutzungsrechte des Lizenznehmers nicht und können jederzeit innerhalb der jeweils genutzten Software abgerufen werden. Im Einzelfall können die jeweiligen Lizenzbedingungen vom Lizenzgeber auf Anforderung jederzeit zur Verfügung gestellt werden. + +1.4 Entgegenstehende oder von dieser Vereinbarung abweichende Kaufbedingungen des Lizenznehmers werden nicht Vereinbarungsbestandteil, auch wenn der Lizenzgeber diesen nicht ausdrücklich widerspricht. Änderungen der EULA müssen schriftlich und ausdrücklich durch beide Parteien vereinbart werden. + + +2. Laufzeit und Kündigung / Lizenzgebühren + +2.1 Die Lizenzvereinbarung beginnt mit Lizenzaktivierung und endet mit der Nutzungsdauer der Pro Version oder mit dem Ende der Bezahldauer. + +2.2 Der Lizenzgeber ist berechtigt, diese Lizenzvereinbarung und die entsprechenden Nutzungsrechte mit sofortiger Wirkung zu kündigen, falls der Lizenznehmer eine Bestimmung dieser Lizenzvereinbarung verletzt oder eine Verletzung dieser Lizenzvereinbarung durch Dritte stillschweigend duldet oder seine Verpflichtungen aus dieser Lizenzvereinbarung nicht erfüllt oder falls der Lizenznehmer Insolvenz anmeldet oder bei dem Lizenznehmer ein Kontrollwechsel stattfindet. + +2.3 Ungeachtet der vorstehenden Bestimmungen und sofern in dieser Lizenzvereinbarung nicht anderweitig vereinbart, endet diese Lizenzvereinbarung automatisch bei Verletzung einer seiner Bestimmungen durch den Lizenznehmer. + +2.4 Unter keinen Umständen sind bei Kündigung oder einvernehmlicher Beendigung dieses Vertrages Lizenzgebühren vollständig oder teilweise erstattungsfähig, es sei denn ZEISS hat die vorzeitige Beendigung dieses Vertrages zu vertreten. + + +3. Vervielfältigungsrechte + +3.1 Der Lizenznehmer darf die gelieferte Software in dem Umfang vervielfältigen, in dem die Vervielfältigung zur Nutzung der Software erforderlich ist. Erforderliche Vervielfältigungen der Software sind unter anderem die Installation des Softwareprodukts auf dem Massenspeicher des Geräts gemäß diesem Lizenzvertrag und das Laden der Software in den Hauptspeicher des Computers. + +3.2 Außerdem ist der Lizenznehmer zur Anfertigung von Kopien zur Datensicherung berechtigt. Diese Sicherungskopie des lizenzierten Softwareprodukts muss als solche gekennzeichnet sein. + +3.3 Sind aus Gründen der Datensicherheit oder -sicherung nach einem Totalausfall eine schnelle Reaktivierung des Computersystems, des Vertragsgegenstands eingeschlossen, sowie die Sicherung des gesamten Datenbestands, des installierten Softwareprodukts eingeschlossen, erforderlich, so kann der Lizenznehmer die maximal erforderliche Anzahl an Sicherungskopien erstellen. Die betreffenden Datenmedien sind angemessen zu kennzeichnen. Die Sicherungskopien dürfen ausschließlich zu Archivierungszwecken genutzt werden. + +3.4 Der Lizenznehmer ist nicht berechtigt, weitere Kopien zu erstellen oder Dritte anzuweisen, weitere Kopien zu erstellen, insbesondere ist er nicht berechtigt, den Programmcode mit einem Drucker auszudrucken oder Fotokopien des Handbuchs zu erstellen. + + +4. Weiterverkauf und Übertragung + +4.1 Der Lizenznehmer ist nicht berechtigt, das Softwareprodukt Dritten im Rahmen von Hosting- oder Downloadoptionen zu vermieten, verleasen, verleihen oder zur Verfügung zu stellen, es sei denn, der Lizenzgeber hat dies ausdrücklich schriftlich angegeben oder erlaubt. + +4.2 Es ist jedoch gestattet, Dritten ein Nutzungsrecht einzuräumen, wenn diese das Softwareprodukt nach Maßgabe des Lizenznehmers (wie eigene Mitarbeiter) nutzen müssen. Von der Nutzung auf jeden Fall ausgeschlossen sind unabhängige Dritte. + +4.3 Übertragung innerhalb von Rechtspersonen oder globalen Konzernen des Lizenznehmers: Sofern der übertragende Lizenznehmer und die empfangende Partei Teil einer Rechtsperson oder Teil verbundener Unternehmen sind, ist die Übertragung gestattet, sofern die empfangende Partei diesen Lizenzbedingungen zustimmt. „Verbundene Unternehmen“ bedeutet jede Rechtsperson, die direkt oder indirekt von einer Rechtsperson oder deren Muttergesellschaft kontrolliert wird. „Kontrolle“ im Sinne dieses Lizenzvertrags bedeutet direkter oder indirekter Besitz von mehr als fünfzig Prozent (50 %) der Anteile an diesem Unternehmen oder mehr als fünfzig Prozent (50 %) direkter oder indirekter Beteiligung am Entscheidungsorgan dieses Unternehmens. + + +5. Rückübersetzung und Programmänderungen + +5.1 Der Lizenznehmer darf grundsätzlich keine Änderungen am Softwareprodukt vornehmen, außer wenn dies zur Behebung von Fehlern erforderlich ist. Voraussetzung ist, dass dies ausschließlich zum Zweck der Korrektur von Fehlern geschieht, die das Funktionieren der Software beeinträchtigen. +Im letzteren Fall und wenn beim Reparaturvorgang wichtige Programmfunktionen und Arbeitsmethoden offengelegt werden könnten, kann der Lizenznehmer einen gewerblich tätigen Dritten mit der Reparatur beauftragen, wenn dieser Dritte nicht ein potenzieller Wettbewerber des Lizenzgebers ist. +Soweit der Lizenznehmer zur Behebung von Fehlern Änderungen am Softwareprodukt vornimmt, übernimmt der Lizenzgeber, insb. auch nicht durch diese Freigabe, für die daraus resultierende Folgen keine Haftung. + +5.2 Die Rückübersetzung des lizenzierten Programmcodes in andere Codeformen (Dekompilierung) und andere Arten des Reverse Engineering verschiedener unterschiedlicher Phasen der Software-Erstellung sind nur insoweit zulässig, wie sie dazu dienen, Fehler zu korrigieren, die das Funktionieren der Software beeinträchtigen (entsprechend Ziffer 5.1). Der Lizenznehmer darf eine solche Dekompilierung jedoch nur in dem für die Berichtigung erforderlichen Ausmaß und gegebenenfalls unter Einhaltung der mit dem Inhaber des Urheberrechts an diesem Programm vertraglich festgelegten Bedingungen vornehmen. +Weiter ist eine Dekompilierung in Fällen zulässig, um Informationen zu gewinnen, die zur Interoperabilität mit einem unabhängig geschaffenen Computerprogramm erforderlich sind, und nur falls diese Informationen nicht anderweitig beschafft werden können. + +5.3 Weitere Voraussetzung für die Genehmigung zur Rückübersetzung ist die Durchführung des Reverse Engineering oder der Programmbeobachtung ausschließlich durch Verfahren, zu deren Ausführung der Lizenznehmer gemäß diesem Lizenzvertrag berechtigt ist. Insbesondere darf der Programmcode in keinem Fall ausgedruckt werden. 5.4 Alle Eigentums- und Urheberrechte in Bezug auf das Softwareprodukt, die gedruckten Begleitmaterialien und sämtliche Kopien des Softwareprodukts verbleiben beim Lizenzgeber oder seinen Lieferanten. Das vorliegende Softwareprodukt ist nach deutschem Urheberrecht, US-amerikanischem Urheberrecht und den Bestimmungen internationaler Verträge geschützt. Der Lizenznehmer ist nicht berechtigt, die der Software beiliegenden gedruckten Materialien zu vervielfältigen. + +5.5 Der Lizenznehmer ist nicht berechtigt, Hinweise zum Urheberrecht oder Markennennungen, die der Lizenzgeber angebracht hat, zu entfernen, zu ändern oder zu ergänzen. Dies beinhaltet ohne Einschränkungen alle Verweise in physischen und / oder elektronischen Medien oder Dokumenten, in „Setup-Assistenten" oder in den Dialogfeldern „Über...“ und / oder in anderen Verweisen, die im Internet dargestellt oder über das Internet aktiviert werden, im Programmcode oder anderen Ausführungsformen, die ursprünglich in der Software enthalten waren oder anderweitig vom Lizenzgeber erstellt wurden. + + +6. Gewährleistung und Kündigungsrecht + +6.1 Der Lizenzgeber gewährleistet in Bezug auf das für den Lizenznehmer lizenzierte Softwareprodukt die in der Beschreibung festgelegte Leistung, insofern das Softwareprodukt in dem vorgesehenen System unter Einhaltung der Richtlinien des Lizenzgebers installiert wird. + +6.2 Der Lizenzgeber beseitigt Fehler an dem Softwareprodukt, und in allen Handbüchern sowie anderen Dokumenten, innerhalb einer angemessenen Frist nach Erhalt der zur Fehlerbeseitigung notwendigen entsprechender Angaben vom zum Fehler Lizenznehmer. Fehler werden durch Nachbesserungen, die nicht in Rechnung gestellt werden, oder durch Ersatz der Lieferung, nach Wahl des Lizenzgebers, behoben. + +6.3 Das Kündigungsrecht des Lizenznehmers aufgrund der Nichtausführbarkeit des Softwareprodukts kann erst ausgeübt werden, wenn Nachbesserungen bzw. Ersatz zweimal erfolglos erfolgt sind. + +6.4 Der Lizenzgeber gibt weder eine Garantie noch eine Gewährleistung für die Funktionalität der von Drittanbietern oder dem Lizenznehmer / Kunden erstellten Programme, ebenso wenig wie auf das fehlerfreie Ausführen der Programme mit der Software oder auf den Systemen des Lizenzgebers. + + +7. Haftung + +7.1 Falls der Lizenznehmer das Softwareprodukt nicht auf die vertraglich festgelegte Weise nutzen kann und der Lizenznehmer dies aufgrund der unterlassenen oder falschen Umsetzung von Vorschlägen und Ratschlägen vor oder nach der Unterzeichnung des Vertrages oder aufgrund der Verletzung sonstiger vertraglicher Pflichten zu vertreten hat, so gelten unter Ausschluss weiterer Ansprüche des Lizenznehmers entsprechend die in diesem Vertrag dargelegten Regelungen. + +Für Schäden, die nicht am Softwareprodukt, beziehungsweise nicht an der Hardware und dem angeschlossenen Gerät entstehen, gilt die Haftungsverpflichtung des Lizenzgebers ausschließlich in den folgenden Fällen, unabhängig vom jeweiligen Rechtsgrund: + +- vorsätzliches Fehlverhalten, + +- grobe Fahrlässigkeit seiner ausführenden Organe oder leitenden Angestellten, + +- schuldhaft herbeigeführter Schaden des Lebens, des Körpers und der Gesundheit, bei Fehlern, die der Lizenzgeber arglistig verschwiegen, oder die er unter Gewährleistung ausgeschlossen hat, + +- Softwarefehler im Rahmen der Haftung bei Personen- und Sachschäden aufgrund persönlich implementierter Objekte, wie in den dafür zutreffenden Produkthaftungsregelungen dargelegt + +7.2 Bei schuldhafter Verletzung wesentlicher Vertragspflichten haftet der Lizenzgeber auch bei grober Fahrlässigkeit seitens nichtleitender Angestellter und bei leichter Fahrlässigkeit. Im letzteren Fall ist die Haftung auf Schäden begrenzt, die vorhersehbar und typisch für diese Art von Vertrag sind. + +7.3 Außerdem haften der Lizenzgeber, seine Mitarbeiter und seine Erfüllungsgehilfen für Datenverlust oder -änderungen aufgrund von Programmfehlern, beschränkt auf den Umfang, in dem dies unvermeidbar gewesen wäre, wenn der Lizenznehmer seiner Verpflichtung, regelmäßig und mindestens einmal täglich Sicherungskopien zu erstellen, nachgekommen wäre. + +7.4 Bei Ansprüchen aufgrund von Urheberrechtsverletzungen gewährt der Lizenzgeber dem Lizenznehmer das Recht zur weiteren Nutzung des Softwareprodukts oder zur Vornahme von Änderungen am Softwareprodukt, so dass der Schutz der Urheberrechte gewährleistet ist. Wenn dies nicht wirtschaftlich sinnvoll ist, so nimmt der Lizenzgeber den Vertragsgegenstand zurück und erstattet die gezahlte Lizenzgebühr, abzüglich eines der Dauer der vorherigen Nutzung entsprechenden Betrags. Dies gilt unter der Voraussetzung, dass der Lizenznehmer dem Lizenzgeber diese Art der Ansprüche unverzüglich schriftlich mitteilt und dem Lizenzgeber alle Rechtsmittel und außergerichtlichen Regelungen gestattet. + +7.5 Für Serverunterbrechungen, Unterbrechung der Lizenzzuteilung und sonstige Support-Fälle, die nicht eindeutig auf eine fehlerhaft erstellte Lizenz zurückzuführen sind, haftet der Lizenznehmer bzw. dessen IT-Provider.. +Der Lizenznehmer oder dessen IT-Provider ist verantwortlich für die Vorhaltung der notwendigen Anzahl an Lizenzen zur Erbringung seiner Leistungen. Der Lizenzgeber haftet nicht für Nutzungsunterbrechungen und nachfolgende Arbeits- / Produktionsausfälle. + +7.6 Weitergehende Haftungsansprüche des Lizenznehmers sind ausdrücklich ausgeschlossen. + +7.7 Der Lizenznehmer ist für alle aus der Nutzung des Softwareprodukts entstehenden Probleme verantwortlich, die nicht direkt durch den Lizenzgeber verursacht werden. Daher ist der Lizenznehmer für alle Daten verantwortlich, die bei der Nutzung des Softwareprodukts erzeugt und hergestellt werden. Der Lizenznehmer ist demnach zur beziehungsweise für die Einhaltung der in dieser Lizenzvereinbarung genannten Bedingungen verpflichtet und verantwortlich. + + +8. Sicherungsmaßnahmen + +Der Lizenznehmer wird die Software sowie gegebenenfalls die Zugangsdaten für den Onlinezugriff durch geeignete Maßnahmen vor dem Zugriff durch unbefugte Dritte sichern. Insbesondere sind sämtliche Kopien der Software sowie die Zugangsdaten an einem geschützten Ort zu verwahren. + + +9. Gewerbliche Schutzrechte und Urheberrechte + +9.1 Macht ein Dritter Ansprüche aus Verletzung eines gewerblichen Schutzrechtes oder eines Urheberrechts gegen den Kunden geltend, weil dieser eine von ZEISS gelieferte Softwareversion, Firmwareergänzung oder dazugehörige Dokumentation benutzt, ist ZEISS verpflichtet, etwaige dem Schutzrechtsinhaber gerichtlich zugesprochene oder mit vorheriger Zustimmung von ZEISS zugestandene Kosten- und Schadenersatzbeträge zu bezahlen. Vorausgesetzt ist dabei, dass der Kunde ZEISS unverzüglich schriftlich über derartige Ansprüche unterrichtet und ZEISS alle Abwehrmaßnahmen und außergerichtlichen Regelungen vorbehalten bleiben. Der Kunde ist verpflichtet, ZEISS bei der Abwehr nach besten Kräften zu unterstützen. Unter diesen Voraussetzungen wird ZEISS dem Kunden grundsätzlich das Recht zum weiteren Gebrauch der Softwareversion, Firmwareergänzung oder Dokumentation verschaffen. Falls dies zu wirtschaftlich angemessenen Bedingungen nicht möglich sein sollte, ist ZEISS verpflichtet, nach eigener Wahl und auf eigene Kosten den entsprechenden Gegenstand entweder derart abzuändern oder zu ersetzen, dass das Schutzrecht nicht verletzt wird, oder den Gegenstand zurückzunehmen und das dafür bezahlte Entgelt abzüglich eines die gezogenen Nutzungen berücksichtigenden Betrages zu erstatten. + +9.2 ZEISS hat keine Verpflichtungen, falls Schutzrechtsverletzungen dadurch hervorgerufen werden, dass von ZEISS gelieferte Softwareversionen, Firmwareergänzungen oder Dokumentation nicht in der vorgesehenen Weise verwendet oder nicht auf den bestimmten Systemen eingesetzt wird. + + +10. Exportkontrolle + +Der Lizenznehmer übernimmt die Verantwortung für die Einhaltung aller anwendbaren Bestimmungen und Vorschriften, einschließlich, aber nicht beschränkt auf die Exportkontroll- und Sanktionsbestimmungen der Bundesrepublik Deutschland, der Europäischen Union sowie der Vereinigten Staaten von Amerika. Insbesondere bestätigt der Lizenznehmer, die Software sowie jedwede damit verbundene Technologie oder Dokumentation oder Teile davon weder direkt noch indirekt unter Nichtbefolgung der vorgenannten Bestimmungen in sanktionierte Länder oder an sanktionierte natürliche oder juristische Personen bereitzustellen. + +Der Lizenznehmer sichert dem Lizenzgeber zu, dass er die Software sowie jedwede damit verbundene Technologie oder Dokumentation oder Teile davon nicht unter Verletzung vorgenannter anwendbarer Gesetze oder Vorschriften verwenden wird. Weiterhin verpflichtet sich der Lizenznehmer den Lizenzgeber von allen Ansprüchen freizustellen und schadlos zu halten, welche aus der Nichteinhaltung vorgenannter anwendbarer Bestimmungen resultiert. + + +11. Sonstiges + +11.1 Sämtliche mündliche Vereinbarungen, Änderungen, Erweiterungen oder Konkretisierungen dieser Lizenzbedingungen sowie die besonderen Eigenschaften der getroffenen Zusicherungen oder Vereinbarungen oder Absprachen bedürfen zu ihrer Rechtswirksamkeit der Schriftform. Falls diese von Vertretern oder Erfüllungsgehilfen des Lizenzgebers abgefasst sind, so werden sie erst mit der Genehmigung des Lizenzgebers rechtlich bindend. + +11.2 Sollten Teile dieses Vertrags unwirksam werden, so berührt dies nicht die Wirksamkeit der übrigen Teile dieses Vertrags. Der unwirksame Teil dieses Vertrags soll durch seine Parteien durch gesetzlich zulässige Bestimmungen ersetzt werden, die der Absicht der unwirksamen Bestimmungen am nächsten kommt. + +11.3 Auf diesen Vertrag sind die Gesetze der Bundesrepublik Deutschland anwendbar, unter Ausschluss des Gesetzes über den internationalen Warenkauf und der Regeln des Kollisionsrechts. + +Stand Oktober 2023 diff --git a/AppExamples/misc/ServiceExample/metainfo.json b/AppExamples/misc/ServiceExample/metainfo.json new file mode 100644 index 0000000..9e532c7 --- /dev/null +++ b/AppExamples/misc/ServiceExample/metainfo.json @@ -0,0 +1,36 @@ +{ + "author": "Carl Zeiss GOM Metrology GmbH", + "description": "Service API Example", + "labels": [ + ], + "licensing": { + "licenses": [ + ], + "product-codes": [ + ] + }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/using_services/using_services.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/python_api.html#gom-api-services"] + ], + "services": [ + { + "endpoint": "gom.api.math", + "name": "Multiplicator", + "script": "multiplicator/service.py" + }, + { + "endpoint": "gom.api.test", + "name": "Reflector", + "script": "reflector/service.py" + } + ], + "software-revision": "0000", + "software-version": "ZEISS INSPECT 2025", + "tags": [ + "service" + ], + "title": "Service Test", + "uuid": "8bc26aa3-4b79-44ab-a6a1-18641664a406", + "version": "1.0.0" +} diff --git a/AppExamples/misc/ServiceExample/scripts/multiplicator/service.metainfo b/AppExamples/misc/ServiceExample/scripts/multiplicator/service.metainfo new file mode 100644 index 0000000..181f5fd --- /dev/null +++ b/AppExamples/misc/ServiceExample/scripts/multiplicator/service.metainfo @@ -0,0 +1,25 @@ +{ + "display_name": "service", + "folded_blocks": [ + ], + "icon": "", + "iinspect_condition": "", + "interactive": false, + "main_menu_path": { + "anchor": { + "item": "", + "submenu": [ + ], + "type": "command" + }, + "script": "userscript.multiplicator__service", + "submenu": [ + ] + }, + "multicreation_script": false, + "script_check_type": "none", + "script_element_type": "none", + "show_in_iinspect": false, + "show_in_menu": true, + "uuid": "67e51753-2171-45a0-8543-d905c9ffb541" +} diff --git a/AppExamples/misc/ServiceExample/scripts/multiplicator/service.py b/AppExamples/misc/ServiceExample/scripts/multiplicator/service.py new file mode 100644 index 0000000..1713f18 --- /dev/null +++ b/AppExamples/misc/ServiceExample/scripts/multiplicator/service.py @@ -0,0 +1,12 @@ +# -*- coding: utf-8 -*- + +import gom +from gom import apifunction + +@apifunction +def multiply(value1: float, value2: float) -> float: + gom.log.debug('Function "multiply" called') + return value1 * value2 + +gom.run_api() + diff --git a/AppExamples/misc/ServiceExample/scripts/reflector/service.metainfo b/AppExamples/misc/ServiceExample/scripts/reflector/service.metainfo new file mode 100644 index 0000000..96102c0 --- /dev/null +++ b/AppExamples/misc/ServiceExample/scripts/reflector/service.metainfo @@ -0,0 +1,25 @@ +{ + "display_name": "service", + "folded_blocks": [ + ], + "icon": "", + "iinspect_condition": "", + "interactive": false, + "main_menu_path": { + "anchor": { + "item": "", + "submenu": [ + ], + "type": "command" + }, + "script": "userscript.reflector__service", + "submenu": [ + ] + }, + "multicreation_script": false, + "script_check_type": "none", + "script_element_type": "none", + "show_in_iinspect": false, + "show_in_menu": true, + "uuid": "959bfcc7-e6a4-49c6-8231-ab8f082a5dce" +} diff --git a/AppExamples/misc/ServiceExample/scripts/reflector/service.py b/AppExamples/misc/ServiceExample/scripts/reflector/service.py new file mode 100644 index 0000000..0f37af1 --- /dev/null +++ b/AppExamples/misc/ServiceExample/scripts/reflector/service.py @@ -0,0 +1,13 @@ +# -*- coding: utf-8 -*- + +import gom +from gom import apifunction + + +@apifunction +def reflect(value: any) -> any: + gom.log.debug('Function "reflect" called') + return value + + +gom.run_api() diff --git a/AppExamples/misc/ServiceExample/scripts/usage_example.metainfo b/AppExamples/misc/ServiceExample/scripts/usage_example.metainfo new file mode 100644 index 0000000..beb4757 --- /dev/null +++ b/AppExamples/misc/ServiceExample/scripts/usage_example.metainfo @@ -0,0 +1,25 @@ +{ + "display_name": "usage_example", + "folded_blocks": [ + ], + "icon": "", + "iinspect_condition": "", + "interactive": false, + "main_menu_path": { + "anchor": { + "item": "", + "submenu": [ + ], + "type": "command" + }, + "script": "", + "submenu": [ + ] + }, + "multicreation_script": false, + "script_check_type": "none", + "script_element_type": "none", + "show_in_iinspect": false, + "show_in_menu": true, + "uuid": "f7f49f18-43cd-4516-9738-ab3a86038b08" +} diff --git a/AppExamples/misc/ServiceExample/scripts/usage_example.py b/AppExamples/misc/ServiceExample/scripts/usage_example.py new file mode 100644 index 0000000..3809ab3 --- /dev/null +++ b/AppExamples/misc/ServiceExample/scripts/usage_example.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- + +import gom +import gom.api.math +import gom.api.test + +# Call reflect function from service #2 +result = gom.api.test.reflect({'test': 123}) +print(result) + +# Call multiply function from service #1 +result = gom.api.math.multiply (23, 42) +print(result) + + + diff --git a/AppExamples/projects/ExampleProjects/doc/Documentation.md b/AppExamples/projects/ExampleProjects/doc/Documentation.md new file mode 100644 index 0000000..6326af0 --- /dev/null +++ b/AppExamples/projects/ExampleProjects/doc/Documentation.md @@ -0,0 +1,13 @@ +## ExampleProjects + +Most of the App examples rely on a certain ZEISS INSPECT project file to be loaded. Some examples load the projects automatically when it is possible (E.g. in the `if __name__ == '__main__'` block) while other example require the project to be loaded manually. This is easily done using the `setup_project.py` script. + +The project files are stored in this App to avoid duplication across multiple Apps. + +The following project files are included: + +| Project name | Description | +| --------------------------- | ------------------------------------------------------------------------- | +| zeiss_part_test_project | Simple optically measured part with a CAD, mesh and some basic inspection | +| volume_test_part | A small test volume for CT related inspections | +| zeiss_part_test_measurement | Optical measurement series and preliminary mesh of ZEISS part | \ No newline at end of file diff --git a/AppExamples/projects/ExampleProjects/doc/README.md b/AppExamples/projects/ExampleProjects/doc/README.md index 00ab503..881079b 100644 --- a/AppExamples/projects/ExampleProjects/doc/README.md +++ b/AppExamples/projects/ExampleProjects/doc/README.md @@ -1,7 +1,9 @@ ## ExampleProjects -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -It provides ZEISS INSPECT projects for trying the Python API examples. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/ExampleProjects) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/ExampleProjects) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). diff --git a/AppExamples/projects/ExampleProjects/metainfo.json b/AppExamples/projects/ExampleProjects/metainfo.json index 5a801ed..745fadc 100644 --- a/AppExamples/projects/ExampleProjects/metainfo.json +++ b/AppExamples/projects/ExampleProjects/metainfo.json @@ -9,7 +9,9 @@ }, "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "project" + ], "title": "ExampleProjects", "uuid": "eaca1f5c-bad1-4a37-b68b-7928fe46bf8c", "version": "1.0.0" diff --git a/AppExamples/script_icons/ScriptIcon/doc/Documentation.md b/AppExamples/script_icons/ScriptIcon/doc/Documentation.md new file mode 100644 index 0000000..0a33e6d --- /dev/null +++ b/AppExamples/script_icons/ScriptIcon/doc/Documentation.md @@ -0,0 +1,28 @@ +# ScriptIcon + +![Menu entry with icon, light background](menu_icon_lightbg.jpg) + + +## Short description + +This is a small example to show how an icon can be set to a script, whereas the icon itself resides in the App as a resource. + +```{note} +This example is meant as addition to the information given in how-to: [Adding workspaces to packages - Icon guidelines](../../howtos/adding_workspaces_to_apps/adding_workspaces_to_apps.md#icon-guidelines). +``` + +## Highlights + +Normally, the icon can be set using the "Script properties" dialog accessible by right-click in the Script Editor of the GOM Software. + +However, using VS Code or another text editor, the corresponding `.metainfo` files of the scripts can be edited directly. If you have icon files within your App, you can directly enter the relative path to the icon in the `"icon"` property. + +![Icon file reference in script properties](script_icon_from_file.jpg) + +If you use this approach, and follow our [icon guidelines](../../howtos/adding_workspaces_to_apps/adding_workspaces_to_apps.md#icon-guidelines), the icons get inverted in dark themes automatically. + +![Menu entry with icon, dark background](menu_icon_darkbg.jpg) + +## Related + +* How-to: [Adding workspaces to packages](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/adding_workspaces_to_apps/adding_workspaces_to_apps.md) \ No newline at end of file diff --git a/AppExamples/script_icons/ScriptIcon/doc/README.md b/AppExamples/script_icons/ScriptIcon/doc/README.md index a27c9be..e0c65d7 100644 --- a/AppExamples/script_icons/ScriptIcon/doc/README.md +++ b/AppExamples/script_icons/ScriptIcon/doc/README.md @@ -1,7 +1,9 @@ ## ScriptIcon -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [ScriptIcon](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/script_icons/script_icon_from_file.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/ScriptIcon) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/ScriptIcon) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/script_icons/ScriptIcon/doc/menu_icon_darkbg.jpg b/AppExamples/script_icons/ScriptIcon/doc/menu_icon_darkbg.jpg new file mode 100644 index 0000000..bbb2e38 Binary files /dev/null and b/AppExamples/script_icons/ScriptIcon/doc/menu_icon_darkbg.jpg differ diff --git a/AppExamples/script_icons/ScriptIcon/doc/menu_icon_lightbg.jpg b/AppExamples/script_icons/ScriptIcon/doc/menu_icon_lightbg.jpg new file mode 100644 index 0000000..c6c225b Binary files /dev/null and b/AppExamples/script_icons/ScriptIcon/doc/menu_icon_lightbg.jpg differ diff --git a/AppExamples/script_icons/ScriptIcon/doc/script_icon_from_file.jpg b/AppExamples/script_icons/ScriptIcon/doc/script_icon_from_file.jpg new file mode 100644 index 0000000..30c0010 Binary files /dev/null and b/AppExamples/script_icons/ScriptIcon/doc/script_icon_from_file.jpg differ diff --git a/AppExamples/script_icons/ScriptIcon/metainfo.json b/AppExamples/script_icons/ScriptIcon/metainfo.json index 019875f..6ad73d5 100644 --- a/AppExamples/script_icons/ScriptIcon/metainfo.json +++ b/AppExamples/script_icons/ScriptIcon/metainfo.json @@ -8,7 +8,9 @@ }, "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "menu" + ], "title": "ScriptIcon", "uuid": "d791a884-e890-40bf-a87d-d9bdf806c2c2", "version": "1.0.0" diff --git a/AppExamples/script_resources/ScriptResources/doc/Documentation.md b/AppExamples/script_resources/ScriptResources/doc/Documentation.md new file mode 100644 index 0000000..304f13a --- /dev/null +++ b/AppExamples/script_resources/ScriptResources/doc/Documentation.md @@ -0,0 +1,37 @@ +# ScriptResources + +![](script_resources.jpg) +## Short description + +A simple example showing the usage of script resources. + +## Highlights + +The example shows how to list available resources: +```python +gom.Resource.list() +``` + +Then, depending on whether a resource is found (by name), this resource is read or created with the content `Hello World`. + +```python +res = gom.Resource("test_resource.txt") + if (res.exists ()): + print ("Resource found with content: ", get_resource_content(res)) + else: + string_bytes = b"Hello World" + create_resource_with_content ("test_resource.txt", string_bytes) + print ("Resource created with content:", string_bytes) +``` + +Output: +``` +> Resource found with content: b'Hello World' +``` + +For details on how to read and write resource data, see the related documentation below. + +## Related + +* [How to: Using script resources](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/using_script_resources.md) +* [`gom.Resource` API Definition](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/resource_api.md) \ No newline at end of file diff --git a/AppExamples/script_resources/ScriptResources/doc/README.md b/AppExamples/script_resources/ScriptResources/doc/README.md index dfc8a8a..3a1cd5b 100644 --- a/AppExamples/script_resources/ScriptResources/doc/README.md +++ b/AppExamples/script_resources/ScriptResources/doc/README.md @@ -1,7 +1,9 @@ ## ScriptResources -This App is part of the [ZEISS INSPECT Python API Examples](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/index.html). +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). -See [ScriptResources](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_examples/script_resources/resource_api_example.html) on the [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html) for a detailed description. +See [App documentation](Documentation.md) for details. -You can [download this App](https://software-store.zeiss.com/products/apps/ScriptResources) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). \ No newline at end of file +You can [download this App](https://software-store.zeiss.com/products/apps/Resources) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). \ No newline at end of file diff --git a/AppExamples/script_resources/ScriptResources/doc/script_resources.jpg b/AppExamples/script_resources/ScriptResources/doc/script_resources.jpg new file mode 100644 index 0000000..ef4dcfc Binary files /dev/null and b/AppExamples/script_resources/ScriptResources/doc/script_resources.jpg differ diff --git a/AppExamples/script_resources/ScriptResources/metainfo.json b/AppExamples/script_resources/ScriptResources/metainfo.json index b94302b..700bc20 100644 --- a/AppExamples/script_resources/ScriptResources/metainfo.json +++ b/AppExamples/script_resources/ScriptResources/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/using_script_resources.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/resource_api.html"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "resources" + ], "title": "ScriptResources", "uuid": "ffb0632f-850c-418b-a44a-2fa3b0187b78", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualCircle/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualCircle/doc/Documentation.md new file mode 100644 index 0000000..f5656df --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualCircle/doc/Documentation.md @@ -0,0 +1,44 @@ +# ScriptedActualCircle + +![Scripted circle element example](scripted_actual_circle.png) + +This is an example for a scripted 'circle' element. + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = { + 'center': (params['center_x'], params['center_y'], params['center_z']), + 'direction': (params['dir_x'], params['dir_y'], params['dir_z']), + 'radius': params['radius'] + } + context.data[stage] = {"ude_mykey": "Example 2"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Circle](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#circle) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualCircle/doc/scripted_actual_circle.png b/AppExamples/scripted_actuals/ScriptedActualCircle/doc/scripted_actual_circle.png new file mode 100644 index 0000000..1c010b1 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualCircle/doc/scripted_actual_circle.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualCircle/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualCircle/metainfo.json index 6a536ba..2014663 100644 --- a/AppExamples/scripted_actuals/ScriptedActualCircle/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualCircle/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#circle"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "circle", "scripted-actual" + ], "title": "ScriptedActualCircle", "uuid": "26eacb0d-2046-4757-9b16-0df005eb62b7", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualCone/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualCone/doc/Documentation.md new file mode 100644 index 0000000..5e5dce8 --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualCone/doc/Documentation.md @@ -0,0 +1,50 @@ +# ScriptedActualCone + +![Scripted cone element example](scripted_actual_cone.png) + +This is an example for a scripted 'cone' element. + +```{caution} +Due to the internal represenstation of a Cone Element, the direction of the vector `point1` -> `point2` is always from the smaller to the larger circle (`radius1` < `radius2`). + +If you specify `radius1` > `radius2` in the creation parameters, [`point1`; `radius1`] and [`point2`; `radius2`] are swapped automatically. +``` + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = {'default': { + 'point1': gom.Vec3d(params['p1_x'], params['p1_y'], params['p1_z']), + 'radius1': params['radius_1'], + 'point2': gom.Vec3d(params['p2_x'], params['p2_y'], params['p2_z']), + 'radius2': params['radius_2'] + }} + context.data[stage] = {"ude_mykey": "Example 6"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Cone](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#cone) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualCone/doc/scripted_actual_cone.png b/AppExamples/scripted_actuals/ScriptedActualCone/doc/scripted_actual_cone.png new file mode 100644 index 0000000..9c4d50c Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualCone/doc/scripted_actual_cone.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualCone/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualCone/metainfo.json index e90ea42..88f8fc8 100644 --- a/AppExamples/scripted_actuals/ScriptedActualCone/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualCone/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#cone"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "cone", "scripted-actual" + ], "title": "ScriptedActualCone", "uuid": "8174c7e9-52de-4c18-9723-1d0f3ae66607", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualCurve/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualCurve/doc/Documentation.md new file mode 100644 index 0000000..94ad30d --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualCurve/doc/Documentation.md @@ -0,0 +1,52 @@ +# ScriptedActualCurve + +![Scripted curve element example](scripted_actual_curve.png) + +This is an example for a scripted 'curve' element. A parametric function is used to create a 3-dimensional curve - a helix - with a fixed number of points. `np.arange()` is used to iterate from `t_min` to `t_max` with a non-integer step size. + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +import math +import numpy as np + +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + # Creating a list of points using a parametric curve function: + # P(t) = ( x0 + (j * t + r) * cos(t), y0 + (j * t + r) * cos(t), z0 + k * t ) + # with t in [t_min...t_max], 1000 steps + points = [] + for t in np.arange(params['t_min'], params['t_max'], (params['t_max'] - params['t_min']) / 1000): + points.append((params['x0'] + (params['j'] * t + params['radius']) * math.cos(t), + params['y0'] + (params['j'] * t + params['radius']) * math.sin(t), + params['z0'] + params['k'] * t) + ) + context.result[stage] = [{'points': points}] + context.data[stage] = {"ude_mykey": "Example 3"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Curve](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#curve) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualCurve/doc/scripted_actual_curve.png b/AppExamples/scripted_actuals/ScriptedActualCurve/doc/scripted_actual_curve.png new file mode 100644 index 0000000..eca9cfc Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualCurve/doc/scripted_actual_curve.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualCurve/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualCurve/metainfo.json index ffa8a38..1eb13a1 100644 --- a/AppExamples/scripted_actuals/ScriptedActualCurve/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualCurve/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#curve"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "curve", "scripted-actual" + ], "title": "ScriptedActualCurve", "uuid": "c1c0e973-0ca3-4aec-9909-0bef808b2dbc", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualCylinder/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualCylinder/doc/Documentation.md new file mode 100644 index 0000000..47ddc0a --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualCylinder/doc/Documentation.md @@ -0,0 +1,46 @@ +# ScriptedActualCylinder + +![Scripted cylinder element example](scripted_actual_cylinder.png) + +This is an example for a scripted 'cylinder' element. + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + # point = gom.Vec3d(params['point_x'], params['point_y'], params['point_z']) + # direction = gom.Vec3d(params['dir_x'], params['dir_y'], params['dir_z']) + context.result[stage] = {'default': { + 'point': gom.Vec3d(params['point_x'], params['point_y'], params['point_z']), + 'radius': params['radius'], + 'direction': gom.Vec3d(params['dir_x'], params['dir_y'], params['dir_z']), + 'inner': params['inner'] + }} + context.data[stage] = {"ude_mykey": "Example 5"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Cylinder](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#cylinder) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualCylinder/doc/scripted_actual_cylinder.png b/AppExamples/scripted_actuals/ScriptedActualCylinder/doc/scripted_actual_cylinder.png new file mode 100644 index 0000000..3c5918c Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualCylinder/doc/scripted_actual_cylinder.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualCylinder/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualCylinder/metainfo.json index 9619e98..8ad7594 100644 --- a/AppExamples/scripted_actuals/ScriptedActualCylinder/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualCylinder/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#cylinder"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "cylinder", "scripted-actual" + ], "title": "ScriptedActualCylinder", "uuid": "3afe4b3c-97b5-49de-b20e-3f4ac9ddf814", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualDistance/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualDistance/doc/Documentation.md new file mode 100644 index 0000000..b8843ee --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualDistance/doc/Documentation.md @@ -0,0 +1,44 @@ +# ScriptedActualPoint + +![Scripted distance element example](distance.png) + +This is an example for a scripted 'distance' element. + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + + +def calculation(context, params): + valid_results = False + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = { + 'point1': (params['p1_x'], params['p1_y'], params['p1_z']), + 'point2': (params['p2_x'], params['p2_y'], params['p2_z']) + } + context.data[stage] = {"ude_mykey": "Example 1"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Distance](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#distance) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualDistance/doc/distance.png b/AppExamples/scripted_actuals/ScriptedActualDistance/doc/distance.png new file mode 100644 index 0000000..29437d5 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualDistance/doc/distance.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualDistance/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualDistance/metainfo.json index 1e1c62b..9c2e1b3 100644 --- a/AppExamples/scripted_actuals/ScriptedActualDistance/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualDistance/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#distance"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "distance", "scripted-actual" + ], "title": "ScriptedActualDistance", "uuid": "e355ce61-6e17-45f5-bcd2-3495aabef37d", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md new file mode 100644 index 0000000..7e61ce7 --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md @@ -0,0 +1,140 @@ +# ScriptedActualPoint + +## offset_point_simple + +![Scripted actual point in Explorer](scripted_actual_explorer.jpg) + +### Short description + +```{note} +This is a basic example meant to introduce you to the concept of scripted actual elements. Therefore, head over to the [How-to: Scripted actuals](../../howtos/scripted_elements/scripted_actuals.md) for the documentation of this example. +``` + +## offset_point_v2 (Includes preview calculation) + +![Offset point dialog](offset_point_v2.jpg) + +### Short description + +This example is an extension of the `offset_point_simple` example, which has been discussed in the general [How-to: Scripted actuals](../../howtos/scripted_elements/scripted_actuals.md#example-simple-offset-point). +It shows how to enhance user experience using preview calculation and error handling. + +### Highlights + +#### Preview calculation + +From many of the built-in commands of ZEISS INSPECT, you know the calculation of a preview element during the creation dialog. This means, you can already see the calculation result in the 3D view, while tweaking some parameters in the dialog. + +To achieve this behaviour in a scripted element, you need to set up an event handler for the dialog (see also: [How-to: User-defined dialogs](../../howtos/python_api_introduction/user_defined_dialogs.md)). + + +```{code-block} python +--- +linenos: +--- +def dialog_event_handler (widget): + # No treatment of system events + if str(widget) == 'system': + return + # If preview calculation returned with error + if str(widget) == 'error': + DIALOG.control.status = context.error + return + # If preview calculation was successful + if str(widget) == 'calculated': + DIALOG.control.status = '' + DIALOG.control.ok.enabled = True + return + + # All other changes in the dialog --> calculate preview + params['x'] = DIALOG.i_x.value; + params['y'] = DIALOG.i_y.value; + params['z'] = DIALOG.i_z.value; + params['base'] = DIALOG.point.value + context.name = DIALOG.name.value + DIALOG.control.ok.enabled = False + context.calc(params=params, dialog=DIALOG) + +DIALOG.handler = dialog_event_handler +``` + +The event handler function is to be defined taking one argument. This argument will be a handle to the cause (the event) triggering the handler. This can be a string message or a handle to a specific widget of the dialog. We'll come back to this in a second + +The handler function shown above basically reads the current set of parameters from the `DIALOG` to the `params` array (lines 16-19). In this case, the offset values and base point. Then, the preview calculation is started using the special functional `context.calc`, which is a function handle taking the set of `params` and a reference to the dialog triggering the preview (line 22). + + +```{attention} +Only call `context.calc(...)` from a script dialog's *event handler* function, **NOT** from the scripted element's `dialog` function itself. +``` + +The handler is applied to the dialog in the `dialog` function of the scripted element, just before the dialog is shown to the user (line 23). + +#### Status and error handling + +Using the dialog's event handler, we can also make the dialog responsive to successful or failed preview calculations. Therefore, the `DIALOG.control.ok.enabled` can be used to control the enabledness of the dialog's OK button. + +In line 21, the OK button is disabled before preview calculation is started. + +Furthermore, the scripted element framework provides two special event triggers: `error` and `calculated`, which are sent on failing/success of the `calculation` function to the dialog referenced in the `context.calc` call. + +In this case, we set a potential error message of a failed calcualtion to the dialogs error indicator (line 7), or enable the OK button and reset the error indicator in case of a successful calculation (lines 11-12). + + +#### Stageful `calculation` and error handling + +Above, we discussed changes applied to the scripted element's `dialog` function. Now, let's take a look at the `calculation` function. + +```{code-block} python +--- +linenos: +--- +def calculation(context, params): + valid_results=False + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + base = params['base'].in_stage[stage].center_coordinate + context.result[stage] = (base.x + params['x'], base.y + params['y'], base.z + params['z']) + context.data[stage] = { "ude_mykey" : 123456 } + except Exception as error: + context.error[stage] = str(error) + else: + valid_results=True + return valid_results +``` + +The first noticeable difference to the *offset_point_simple* example is the calculation over all *stages* of the project, whose indices can be obtained using `context.stages` (line 4). + +```{seealso} +If you are not familiar with the concept of *stages*, get an impression in our [Starter Training](https://training.gom.com/course/277348/module/788965). +``` + +Second, the [access of element properties](../../howtos/python_api_introduction/python_api_introduction.md#access-element-properties) is also respecting the current stage using the `.in_stage` mechanism (line 7). + +Third, you can see that the calculation is surrounded by a `try/except` block that catches potential errors and sets arising error messages to `context.error`. This examples catches all exceptions in a very basic way. In a real-world application, you should distinguish several types of exceptions you'd expect and set meaningful error messages. The `context.error` message is then handled in the dialog as discussed above (see [Status and error handling](#status-and-error-handling)). + +#### Storing generic element data + +You can observe an assignment to the `context.data` member (line 9). If you assign a dictionary (map) to this data structure, you can save *user-defined tokens* to the scripted element. These are key/value pairs that can hold generic information you might to retrieve in consecutive scripts or checks that reference the created scripted element. + +```{note} +Keys of *user-defined tokens* need to start with `ude_`. For more information, see the [Scripted elements API documentation](../../python_api/scripted_elements_api.md). +``` + +After element creation of such an offset point with name "Offset point 1", you could access this data again like: +```python +import gom + +print (gom.app.project.actual_elements['Offset point 1'].ude_mykey) +``` +Output: +``` +> 123456 +``` + + +## Related + +* [Scripted actuals - Point](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#point) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) diff --git a/AppExamples/scripted_actuals/ScriptedActualPoint/doc/README.md b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/README.md index e69de29..16b1106 100644 --- a/AppExamples/scripted_actuals/ScriptedActualPoint/doc/README.md +++ b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/README.md @@ -0,0 +1,9 @@ +# ScriptedActualPoint + +This App is part of the [ZEISS INSPECT Python API App Examples](https://github.com/ZEISS/zeiss-inspect-app-examples/tree/main/AppExamples). + +See [App documentation](Documentation.md) for details. + +You can [download this App](https://software-store.zeiss.com/products/apps/ScriptedActualPoint) from the [ZEISS Quality Software Store](https://software-store.zeiss.com). + +The ZEISS INSPECT App develomment documentation can be found on [ZEISS IQS GitHub](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/index.html). diff --git a/AppExamples/scripted_actuals/ScriptedActualPoint/doc/offset_point_v2.jpg b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/offset_point_v2.jpg new file mode 100644 index 0000000..e185df4 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/offset_point_v2.jpg differ diff --git a/AppExamples/scripted_actuals/ScriptedActualPoint/doc/offset_point_v2.md b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/offset_point_v2.md new file mode 100644 index 0000000..48a335a --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/offset_point_v2.md @@ -0,0 +1,127 @@ +# offset_point_v2 (Includes preview calculation) + +![](offset_point_v2.jpg) +## Short description + +This example is an extension of the `offset_point_simple` example, which has been discussed in the general [How-to: Scripted actuals](../../howtos/scripted_elements/scripted_actuals.md#example-simple-offset-point). +It shows how to enhance user experience using preview calculation and error handling. + +## Highlights + +### Preview calculation + +From many of the built-in commands of ZEISS INSPECT, you know the calculation of a preview element during the creation dialog. This means, you can already see the calculation result in the 3D view, while tweaking some parameters in the dialog. + +To achieve this behaviour in a scripted element, you need to set up an event handler for the dialog (see also: [How-to: User-defined dialogs](../../howtos/python_api_introduction/user_defined_dialogs.md)). + + +```{code-block} python +--- +linenos: +--- +def dialog_event_handler (widget): + # No treatment of system events + if str(widget) == 'system': + return + # If preview calculation returned with error + if str(widget) == 'error': + DIALOG.control.status = context.error + return + # If preview calculation was successful + if str(widget) == 'calculated': + DIALOG.control.status = '' + DIALOG.control.ok.enabled = True + return + + # All other changes in the dialog --> calculate preview + params['x'] = DIALOG.i_x.value; + params['y'] = DIALOG.i_y.value; + params['z'] = DIALOG.i_z.value; + params['base'] = DIALOG.point.value + context.name = DIALOG.name.value + DIALOG.control.ok.enabled = False + context.calc(params=params, dialog=DIALOG) + +DIALOG.handler = dialog_event_handler +``` + +The event handler function is to be defined taking one argument. This argument will be a handle to the cause (the event) triggering the handler. This can be a string message or a handle to a specific widget of the dialog. We'll come back to this in a second + +The handler function shown above basically reads the current set of parameters from the `DIALOG` to the `params` array (lines 16-19). In this case, the offset values and base point. Then, the preview calculation is started using the special functional `context.calc`, which is a function handle taking the set of `params` and a reference to the dialog triggering the preview (line 22). + + +```{attention} +Only call `context.calc(...)` from a script dialog's *event handler* function, **NOT** from the scripted element's `dialog` function itself. +``` + +The handler is applied to the dialog in the `dialog` function of the scripted element, just before the dialog is shown to the user (line 23). + +### Status and error handling + +Using the dialog's event handler, we can also make the dialog responsive to successful or failed preview calculations. Therefore, the `DIALOG.control.ok.enabled` can be used to control the enabledness of the dialog's OK button. + +In line 21, the OK button is disabled before preview calculation is started. + +Furthermore, the scripted element framework provides two special event triggers: `error` and `calculated`, which are sent on failing/success of the `calculation` function to the dialog referenced in the `context.calc` call. + +In this case, we set a potential error message of a failed calcualtion to the dialogs error indicator (line 7), or enable the OK button and reset the error indicator in case of a successful calculation (lines 11-12). + + +### Stageful `calculation` and error handling + +Above, we discussed changes applied to the scripted element's `dialog` function. Now, let's take a look at the `calculation` function. + +```{code-block} python +--- +linenos: +--- +def calculation(context, params): + valid_results=False + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + base = params['base'].in_stage[stage].center_coordinate + context.result[stage] = (base.x + params['x'], base.y + params['y'], base.z + params['z']) + context.data[stage] = { "ude_mykey" : 123456 } + except Exception as error: + context.error[stage] = str(error) + else: + valid_results=True + return valid_results +``` + +The first noticeable difference to the *offset_point_simple* example is the calculation over all *stages* of the project, whose indices can be obtained using `context.stages` (line 4). + +```{seealso} +If you are not familiar with the concept of *stages*, get an impression in our [Starter Training](https://training.gom.com/course/277348/module/788965). +``` + +Second, the [access of element properties](../../howtos/python_api_introduction/python_api_introduction.md#access-element-properties) is also respecting the current stage using the `.in_stage` mechanism (line 7). + +Third, you can see that the calculation is surrounded by a `try/except` block that catches potential errors and sets arising error messages to `context.error`. This examples catches all exceptions in a very basic way. In a real-world application, you should distinguish several types of exceptions you'd expect and set meaningful error messages. The `context.error` message is then handled in the dialog as discussed above (see [Status and error handling](#status-and-error-handling)). + +### Storing generic element data + +You can observe an assignment to the `context.data` member (line 9). If you assign a dictionary (map) to this data structure, you can save *user-defined tokens* to the scripted element. These are key/value pairs that can hold generic information you might to retrieve in consecutive scripts or checks that reference the created scripted element. + +```{note} +Keys of *user-defined tokens* need to start with `ude_`. For more information, see the [Scripted elements API documentation](../../python_api/scripted_elements_api.md). +``` + +After element creation of such an offset point with name "Offset point 1", you could access this data again like: +```python +import gom + +print (gom.app.project.actual_elements['Offset point 1'].ude_mykey) +``` +Output: +``` +> 123456 +``` + + +## Related + +* [Example: offset_point_simple](offset_point_simple.md) +* [How-to: User-defined dialogs](../../howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualPoint/doc/scripted_actual_explorer.jpg b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/scripted_actual_explorer.jpg new file mode 100644 index 0000000..7e21040 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualPoint/doc/scripted_actual_explorer.jpg differ diff --git a/AppExamples/scripted_actuals/ScriptedActualPoint/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualPoint/metainfo.json index cce1c1d..cefb154 100644 --- a/AppExamples/scripted_actuals/ScriptedActualPoint/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualPoint/metainfo.json @@ -7,9 +7,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#point"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "point", "scripted-actual" + ], "title": "ScriptedActualPoint", "uuid": "3222ba70-7a03-494d-b013-6310fde2f882", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualPointCloud/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualPointCloud/doc/Documentation.md new file mode 100644 index 0000000..47d0d50 --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualPointCloud/doc/Documentation.md @@ -0,0 +1,55 @@ +# ScriptedActualPointCloud + +![Scripted point cloud element example](scripted_actual_point_cloud.png) + +This is an example for a scripted 'point cloud' element. A parametric function is used to define the points, in this case the surface points of a torus. `np.arange()` is used to iterate from `u_min` to `u_max` and from `v_min` to `v_max` with non-integer step sizes. The step sizes `u_steps` and `v_steps` define the point density. + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + # Creating a list of points using a parametric curve function: + # / (R+r*cos(v))*cos(u) \ + # P(u, v) = | (R+r*cos(v))*sin(u) | + # \ r*sin(v) / + # with u in [u_min...u_max], v in [v_min...v_max] + points = [] + for u in np.arange(params['u_min'], params['u_max'], (params['u_max'] - params['u_min']) / params['u_steps']): + for v in np.arange(params['v_min'], params['v_max'], (params['v_max'] - params['v_min']) / params['v_steps']): + p = gom.Vec3d( + (params['R'] + params['r'] * math.cos(v * math.pi)) * math.cos(u * math.pi), + (params['R'] + params['r'] * math.cos(v * math.pi)) * math.sin(u * math.pi), + params['r'] * math.sin(v * math.pi) + ) + points.append(p) + + context.result[stage] = {'points': points} + context.data[stage] = {"ude_mykey": "Example 9"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Point cloud](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#point-cloud) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualPointCloud/doc/scripted_actual_point_cloud.png b/AppExamples/scripted_actuals/ScriptedActualPointCloud/doc/scripted_actual_point_cloud.png new file mode 100644 index 0000000..4f57126 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualPointCloud/doc/scripted_actual_point_cloud.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualPointCloud/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualPointCloud/metainfo.json index e4e4f17..9b180d0 100644 --- a/AppExamples/scripted_actuals/ScriptedActualPointCloud/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualPointCloud/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#point-cloud"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "point-cloud", "scripted-actual" + ], "title": "ScriptedActualPointCloud", "uuid": "a6d289ff-3ff2-4369-9698-d768861eb2ed", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualSection/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualSection/doc/Documentation.md new file mode 100644 index 0000000..3738c59 --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualSection/doc/Documentation.md @@ -0,0 +1,118 @@ +# ScriptedActualSection + +![Scripted section element example](scripted_actual_section.png) + +This is an example for a scripted 'section' element. The dialog allows to select an existing section, which may consist of multiple sub sections. The script creates a new section from the existing one, with the selected filter criterion. + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Functions for calculating the section + +```{code-block} python +--- +linenos: +--- +def calc_section_length(verts, indices=None): + '''Calculate length of (sub-)section''' + if indices is None: + indices = range(len(verts)) + l = 0 + + # Length: Sum of Euclidean distance between each two adjacent vertices of the curve + for i, j in zip(indices, indices[1:]): + l += la.norm(verts[j] - verts[i]) + return l + + +def get_sub_sections(base_curve, stage=0): + """Separate section curve into sub-sections by checking if a point is connected to another point + + Returns: + array of curves + """ + curve_coords = np.array(base_curve.data.coordinate)[stage] + curve_normals = np.array(base_curve.data.normal)[stage] + sub_sections = [] + start_index = 0 + for end_index, conn in enumerate(base_curve.scanline_point_connection): + if conn != "connected": + sub_sections.append((curve_coords[start_index:end_index + 1], curve_normals[start_index:end_index + 1])) + start_index = end_index + 1 + return sub_sections + + +def filter_by_length(sub_sections, mode): + '''Filter an array of curves by length and return the curve matching the filter criterion''' + max_len = 0 + min_len = 0 + r_min = None + r_max = None + + # For all sub-sections, calculate min. and max. length + # and save the vertices and normals of both the shortest/longest curve + for verts, normals in sub_sections: + ssl = calc_section_length(verts) + if max_len < ssl: + max_len = ssl + r_max = verts, normals + if min_len == 0 or min_len > ssl: + min_len = ssl + r_min = verts, normals + if mode.lower() == "max. length": + return r_max + else: + return r_min +``` + +## Dialog and calculation functions + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + '''Scripted section calculation function''' + valid_results = False + + # Check if filter mode is defined + if params["i_mode"].lower() in ["min. length", "max. length"]: + f = filter_by_length + else: + raise ValueError(f"Unknown mode: {params['i_mode']}") + + for stage in context.stages: + # Get selected section from stage + section = params["i_elem"].in_stage[stage] + + # Get sub-sections + sub_sections = get_sub_sections(section, stage) + + # Apply filter + sub_section = f(sub_sections, params["i_mode"]) + + # Get vertices and normals of resulting sub-section + verts, normals = sub_section + + data = [{"points": [gom.Vec3d(*v) for v in verts], "normals": [gom.Vec3d(*n) for n in normals]}] + + try: + context.result[stage] = {"curves": data} + context.data[stage] = {"ude_mykey": "Example 10"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + + return valid_results +``` + +## Related + +* [Scripted actuals - Section](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#section) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualSection/doc/scripted_actual_section.png b/AppExamples/scripted_actuals/ScriptedActualSection/doc/scripted_actual_section.png new file mode 100644 index 0000000..56f7853 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualSection/doc/scripted_actual_section.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualSection/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualSection/metainfo.json index d480573..34bdd61 100644 --- a/AppExamples/scripted_actuals/ScriptedActualSection/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualSection/metainfo.json @@ -7,9 +7,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#section"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "section", "scripted-actual" + ], "title": "ScriptedActualSection", "uuid": "1e1172be-c2f3-43f2-972c-a9abd279c27f", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualSurface/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualSurface/doc/Documentation.md new file mode 100644 index 0000000..58cbeac --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualSurface/doc/Documentation.md @@ -0,0 +1,55 @@ +# ScriptedActualSurface + +![Scripted surface element example](scripted_actual_surface.png) + +This is an example for a scripted 'surface' element. The dialog allows to specify the coordinates of eight vertices defining a mesh. The triangles for defining the mesh are hard-coded in this example. The resulting body is a cuboid. + +```{note} +The mesh triangles are defined by indices into the array of vertices. The vertices defining a triangle must be specified in counter-clockwise +order (as viewed from outside). +``` + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + v0 = gom.Vec3d(params['v0_x'], params['v0_y'], params['v0_z']) + #[...] + v7 = gom.Vec3d(params['v7_x'], params['v7_y'], params['v7_z']) + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = { + 'vertices': [v0, v1, v2, v3, v4, v5, v6, v7], + # two triangles per side of the cuboid + # ----- front ------ , ----- right ------- , ----- top ---------- + 'triangles': [(0, 1, 2), (0, 2, 3), (1, 5, 6), (1, 6, 2), (3, 2, 6), (3, 6, 7), + # ----- bottom ----- , ----- back -------- , ----- left --------- + (0, 1, 5), (0, 5, 4), (4, 5, 6), (4, 6, 7), (0, 4, 7), (0, 7, 3)] + } + context.data[stage] = {"ude_mykey": "Example 8"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Surface](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#surface) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualSurface/doc/scripted_actual_surface.png b/AppExamples/scripted_actuals/ScriptedActualSurface/doc/scripted_actual_surface.png new file mode 100644 index 0000000..68e956c Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualSurface/doc/scripted_actual_surface.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualSurface/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualSurface/metainfo.json index 8d531f6..feffdda 100644 --- a/AppExamples/scripted_actuals/ScriptedActualSurface/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualSurface/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#surface"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "surface", "scripted-actual" + ], "title": "ScriptedActualSurface", "uuid": "afb88e11-9894-494d-9fa5-f69d2124e9a5", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/doc/Documentation.md new file mode 100644 index 0000000..9719520 --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/doc/Documentation.md @@ -0,0 +1,55 @@ +# ScriptedActualSurfaceCurve + +![Scripted surface curve element example](scripted_actual_surface_curve.png) + +This is an example for a scripted 'surface curve' element. A parametric function is used to create a 3-dimensional surface curve - a section of a circle's parallel - with a fixed number of definition points. These point vectors are used as normals, too. `np.arange()` is used to iterate from `phi_min` to `phi_max` with a non-integer step size. + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + # Creating a list of points using a parametric curve function: + # P(t) = ( r * cos(theta) * cos(phi), r * cos(theta) * sin (phi), r * sin(phi) ) + # with + # theta = const + # phi in [phi_min...phi_max], 1000 steps + points = [] + normals = [] + for phi in np.arange(params['phi_min'], params['phi_max'], (params['phi_max'] - params['phi_min']) / 1000): + p = ( + params['r'] * math.cos(params['theta']) * math.cos(phi), + params['r'] * math.cos(params['theta']) * math.sin(phi), + params['r'] * math.sin(params['theta']) + ) + points.append(p) + normals.append(p) + context.result[stage] = [{'points': points, 'normals': normals}] + context.data[stage] = {"ude_mykey": "Example 3b"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Surface curve](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#surface-curve) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/doc/scripted_actual_surface_curve.png b/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/doc/scripted_actual_surface_curve.png new file mode 100644 index 0000000..aab119d Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/doc/scripted_actual_surface_curve.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/metainfo.json index d6c700e..9a99e67 100644 --- a/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualSurfaceCurve/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#surface-curve"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "surface-curve", "scripted-actual" + ], "title": "ScriptedActualSurfaceCurve", "uuid": "89a82686-6b9d-40a3-8158-660469c076eb", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualVolume/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualVolume/doc/Documentation.md new file mode 100644 index 0000000..3e5407b --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualVolume/doc/Documentation.md @@ -0,0 +1,112 @@ +# ScriptedActualVolume + +![Scripted volume element example](scripted_actual_volume.png) + +This is an example for a scripted 'volume' element. The volume data is created as an np.array of shape 70×70×70. Each element defines a voxel with a default gray value `gv1` (`calculation()`, lines 11&12). The function `set_voxeldata()` changes some of the gray values to `gv2` (line 13). The resulting volume object resembles a die. Finally the volume data is padded in each direction with voxels of the background gray value `gv0`. + +The dialog allows to set the gray values and to apply a transformation to the volume element. + +```{caution} +The voxel (measurement) coordinate system may differ from the CAD coordinate system. +``` + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Function for setting voxel data + +```{code-block} python +--- +linenos: +--- +def set_voxeldata(voxels, gv, e): + """Set the gray value of some voxels + + :param voxels: np.array() of shape (70, 70, 70) + :param gv: gray value to set + :param e: extend around (fixed) nominal voxel coordinate + """ + + # (1) - front + for x in range(-e, e + 1): + for y in range(-e, e + 1): + for z in range(-e, e + 1): + voxels[35 + x, e + y, 35 + z] = gv + + # (6) - back + for x in range(-e, e + 1): + for y in range(-e, e + 1): + for z in range(-e, e + 1): + voxels[15 + x, 69 - e + y, 15 + z] = gv + voxels[15 + x, 69 - e + y, 35 + z] = gv + voxels[15 + x, 69 - e + y, 55 + z] = gv + voxels[55 + x, 69 - e + y, 15 + z] = gv + voxels[55 + x, 69 - e + y, 35 + z] = gv + voxels[55 + x, 69 - e + y, 55 + z] = gv + + # (3) - top + for x in range(-e, e + 1): + for y in range(-e, e + 1): + for z in range(-e, e + 1): + voxels[15 + x, 15 + y, 69 - e + z] = gv + voxels[35 + x, 35 + y, 69 - e + z] = gv + voxels[55 + x, 55 + y, 69 - e + z] = gv + #[...] +``` + +## Dialog and calculation functions + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + + e = 4 + gv0 = params['gv_background'] + gv1 = params['gv_mat1'] + gv2 = params['gv_mat2'] + voxels = np.ones((70, 70, 70), dtype=np.uint16) + voxels = voxels * gv1 + set_voxeldata(voxels, gv2, e) + voxels = np.pad(voxels, 30, 'constant', constant_values=gv0) + + rx = params['rx'] + ry = params['ry'] + rz = params['rz'] + dx = params['dx'] + dy = params['dy'] + dz = params['dz'] + + transformation = gom.Mat4x4([ + cos(rz) * cos(ry), cos(rz) * sin(ry) * sin(rx) - sin(rz) * + cos(rx), cos(rz) * sin(ry) * cos(rx) + sin(rz) * sin(rx), dx - 35, + sin(rz) * cos(ry), sin(rz) * sin(ry) * sin(rx) + cos(rz) * + cos(rx), sin(rz) * sin(ry) * sin(rx) - cos(rz) * sin(rx), dy - 35, + -sin(ry), cos(ry) * sin(rx), cos(ry) * cos(rx), dz - 35, + 0, 0, 0, 1 + ]) + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = {'voxel_data': voxels, 'transformation': transformation} + context.data[stage] = {"ude_mykey": "Example 11"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Section](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#volume) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualVolume/doc/scripted_actual_volume.png b/AppExamples/scripted_actuals/ScriptedActualVolume/doc/scripted_actual_volume.png new file mode 100644 index 0000000..68b9f55 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualVolume/doc/scripted_actual_volume.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualVolume/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualVolume/metainfo.json index b35baf2..4a1eaa9 100644 --- a/AppExamples/scripted_actuals/ScriptedActualVolume/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualVolume/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#volume"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "xray", "volume", "scripted-actual" + ], "title": "ScriptedActualVolume", "uuid": "a5a38b5b-5f22-442e-98a4-65782b24fe39", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/doc/Documentation.md new file mode 100644 index 0000000..9f1efeb --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/doc/Documentation.md @@ -0,0 +1,56 @@ +# ScriptedActualVolumeDefects + +![Scripted volume defects element example](scripted_actual_volume_defects.png) + +This is an example for a scripted 'volume defects' element. Each defect is defined by a mesh. In this example, a single defect is created by setting the coordinates of four vertices from a dialog. The mesh triangles are hard-coded in the `calculation()` function. The resulting element has the shape of a tetrahedron. + +```{note} +The mesh triangles are defined by indices into the array of vertices. The vertices defining a triangle must be specified in counter-clockwise +order (as viewed from outside). +``` + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + v0 = (params['v0_x'], params['v0_y'], params['v0_z']) + v1 = (params['v1_x'], params['v1_y'], params['v1_z']) + v2 = (params['v2_x'], params['v2_y'], params['v2_z']) + v3 = (params['v3_x'], params['v3_y'], params['v3_z']) + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = { + 'vertices': [np.array([v0, v1, v2, v3])], + # Note: + # Triangles are defined by indices into the array of vertices. + # The vertices defining a triangle must be specified in counter-clockwise + # order, otherwise the resulting surface would be inverted, i.e. invisible! + 'triangles': [np.array([(0, 1, 2), (1, 0, 3), (0, 2, 3), (2, 1, 3)])] + } + context.data[stage] = {"ude_mykey": "Example 12"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Volume defects](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#volume-defects) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/doc/scripted_actual_volume_defects.png b/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/doc/scripted_actual_volume_defects.png new file mode 100644 index 0000000..d03098b Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/doc/scripted_actual_volume_defects.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/metainfo.json index b1a1ac9..42fafdf 100644 --- a/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualVolumeDefects/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#volume-defects"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "xray", "volume-defects", "scripted-actual" + ], "title": "ScriptedActualVolumeDefects", "uuid": "4b9bc4ad-b369-4f2f-8b18-e90f2405c5a0", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/doc/Documentation.md new file mode 100644 index 0000000..48d110e --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/doc/Documentation.md @@ -0,0 +1,56 @@ +# ScriptedActualVolumeRegion + +![Scripted volume region example](scripted_actual_volume_region.png) + +This is an example for a scripted 'volume region' element. The dialog allows to select a linked volume element and to set offset (in the global coordinate system) as well as the dimensions (in the voxel coordinate system) of the volume region. In this example, the volume region is shown in light green. + +```{caution} +The voxel (measurement) coordinate system may differ from the CAD coordinate system. +``` + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + + x0 = params['x0'] + y0 = params['y0'] + z0 = params['z0'] + + dx = int(params['dx'] / params['volume_ele'].voxel_size.x) + dy = int(params['dy'] / params['volume_ele'].voxel_size.y) + dz = int(params['dz'] / params['volume_ele'].voxel_size.z) + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = { + 'volume_element': params['volume_ele'], + 'offset': gom.Vec3d(x0, y0, z0), + 'voxel_data': np.ones((dx, dy, dz), dtype=np.uint8) + } + context.data[stage] = {"ude_mykey": "Example 13"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Volume region](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#volume-region) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/doc/scripted_actual_volume_region.png b/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/doc/scripted_actual_volume_region.png new file mode 100644 index 0000000..4448577 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/doc/scripted_actual_volume_region.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/metainfo.json index 0c697d0..3edb3c5 100644 --- a/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualVolumeRegion/metainfo.json @@ -7,9 +7,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#volume-region"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "xray", "volume-region", "scripted-actual" + ], "title": "ScriptedActualVolumeRegion", "uuid": "1b3d4fe5-67d9-41a6-b950-6533fcddd099", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeSection/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedActualVolumeSection/doc/Documentation.md new file mode 100644 index 0000000..4d8c8be --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedActualVolumeSection/doc/Documentation.md @@ -0,0 +1,88 @@ +# ScriptedActualVolumeSection + +![Scripted volume section element example](scripted_actual_volume_section.png) + +This is an example for a scripted 'volume section' element. The dialog allows to select an image file, which is converted to a grayscale image (`calculation()`, line 30) and then to an `np.array()` (line 32). Further, a transformation is applied to the image. + +```{note} +Please see [ScriptedActualPoint](https://github.com/ZEISS/zeiss-inspect-app-examples/blob/dev/AppExamples/scripted_actuals/ScriptedActualPoint/doc/Documentation.md) for a complete scripted elements example with detailed description. +``` + +## Source code excerpt + +```{code-block} python +--- +linenos: +--- +import numpy as np +from math import sin, cos +from PIL import Image +from io import BytesIO + +def dialog(context, params): + #[...] + +def calculation(context, params): + valid_results = False + + file = params['file'] + + # if filename starts with ':', it is an app resource used for testing, + # e.g. ':ScriptedElementsExamples/Grayscale_8bits_palette.png' + if file and file[0] == ':': + # read resource + test_image_resource = gom.Resource(file) + test_image = test_image_resource.open().read() + + # convert resource to file object + file = BytesIO(test_image) + + try: + image = Image.open(file) + except AttributeError: + return False + + # convert image to grayscale + image = image.convert('L') + # print (image) + img_array = np.array(image, dtype=np.float32) + # print(f"img_array: {img_array}") + # print(f"img_array.shape: {img_array.shape}") + + rx = params['rx'] + ry = params['ry'] + rz = params['rz'] + dx = params['dx'] + dy = params['dy'] + dz = params['dz'] + + transformation = gom.Mat4x4([ + cos(rz) * cos(ry), cos(rz) * sin(ry) * sin(rx) - sin(rz) * + cos(rx), cos(rz) * sin(ry) * cos(rx) + sin(rz) * sin(rx), dx, + sin(rz) * cos(ry), sin(rz) * sin(ry) * sin(rx) + cos(rz) * + cos(rx), sin(rz) * sin(ry) * sin(rx) - cos(rz) * sin(rx), dy, + -sin(ry), cos(ry) * sin(rx), cos(ry) * cos(rx), dz, + 0, 0, 0, 1 + ]) + # print(transformation) + + # Calculating all available stages + for stage in context.stages: + # Access element properties with error handling + try: + context.result[stage] = { + 'pixel_data': img_array, + 'transformation': transformation + } + context.data[stage] = {"ude_mykey": "Example 14"} + except Exception as error: + context.error[stage] = str(error) + else: + valid_results = True + return valid_results +``` + +## Related + +* [Scripted actuals - Volume section](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md#volume-section) +* [How-to: User-defined dialogs](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/user_defined_dialogs.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeSection/doc/scripted_actual_volume_section.png b/AppExamples/scripted_actuals/ScriptedActualVolumeSection/doc/scripted_actual_volume_section.png new file mode 100644 index 0000000..0c7b716 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedActualVolumeSection/doc/scripted_actual_volume_section.png differ diff --git a/AppExamples/scripted_actuals/ScriptedActualVolumeSection/metainfo.json b/AppExamples/scripted_actuals/ScriptedActualVolumeSection/metainfo.json index a337460..a81b289 100644 --- a/AppExamples/scripted_actuals/ScriptedActualVolumeSection/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedActualVolumeSection/metainfo.json @@ -6,9 +6,15 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#volume-section"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "xray", "volume-section", "scripted-actual" + ], "title": "ScriptedActualVolumeSection", "uuid": "bb1a18a6-82b6-48d4-b352-462758ece8b1", "version": "1.0.1" diff --git a/AppExamples/scripted_actuals/ScriptedElementProgress/doc/Documentation.md b/AppExamples/scripted_actuals/ScriptedElementProgress/doc/Documentation.md new file mode 100644 index 0000000..539f2e8 --- /dev/null +++ b/AppExamples/scripted_actuals/ScriptedElementProgress/doc/Documentation.md @@ -0,0 +1,29 @@ +# ScriptedElementProgress + +![Preview computation progress](scripted_element_progress_preview.jpg) + +![Element computation progress](scripted_element_progress_computation.jpg) + +## Short description + +This examples demonstrates how to show progress information to the user while calcualting a scripted element. + +## Highlights + +The scripted element itself is not of interest here, as it is rather meaningless: a point that will always be created at *(1,0,0)*. +To showcase the display of calculation progress, a loop with 100 steps containing a `sleep` call to simulate computation are performed in the `calculation` function: + +```python +def calculation (context, params): + context.progress_stages_total = limit + for i in range(limit): + context.progress_stages_computing = i + time.sleep (0.1) + + # [...] +``` +To indicate progress, you need to set `context.progress_stages_total` to the amount of steps you expect to compute. This can but not has to be the number of stages in trend projects. You can also set any arbitrary number. As soon as you set `context.progress_stages_computing`, the progress will be indicated in the bottom are of the application (see top screenshot). + +## Related + +* How-to: [Scripted actuals](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.md) \ No newline at end of file diff --git a/AppExamples/scripted_actuals/ScriptedElementProgress/doc/scripted_element_progress_computation.jpg b/AppExamples/scripted_actuals/ScriptedElementProgress/doc/scripted_element_progress_computation.jpg new file mode 100644 index 0000000..9a0df20 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedElementProgress/doc/scripted_element_progress_computation.jpg differ diff --git a/AppExamples/scripted_actuals/ScriptedElementProgress/doc/scripted_element_progress_preview.jpg b/AppExamples/scripted_actuals/ScriptedElementProgress/doc/scripted_element_progress_preview.jpg new file mode 100644 index 0000000..ebbb816 Binary files /dev/null and b/AppExamples/scripted_actuals/ScriptedElementProgress/doc/scripted_element_progress_preview.jpg differ diff --git a/AppExamples/scripted_actuals/ScriptedElementProgress/metainfo.json b/AppExamples/scripted_actuals/ScriptedElementProgress/metainfo.json index 68e4961..cb423d2 100644 --- a/AppExamples/scripted_actuals/ScriptedElementProgress/metainfo.json +++ b/AppExamples/scripted_actuals/ScriptedElementProgress/metainfo.json @@ -6,9 +6,14 @@ "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": [ + "computation-progress" + ], "title": "ScriptedElementProgress", "uuid": "253feb60-8cb0-4992-a09d-7766db64e1df", "version": "1.0.0" diff --git a/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/Documentation.md b/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/Documentation.md new file mode 100644 index 0000000..d1a0e95 --- /dev/null +++ b/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/Documentation.md @@ -0,0 +1,68 @@ +# trimesh_deform_mesh + +![Scripted surface element from deformed mesh](trimesh_deform_mesh.jpg) + +## Short description + +This example demonstrates how to generate a custom surface element using a scripted element. The example script accesses mesh information from an existing mesh in the project and adds a random deformation to each point. + +Finally, the result is transfered back to the ZEISS INSPECT Software, where an actual surface element is created. + +## Highlights + +The dialog was created using the script dialog editor and contains an "Element selection" widget to let the user choose which mesh to deform. + +### Dialog: Element filter + +In the script, a filter function is implemented to populate the "Element selection" widget only with elements of a certain type. To this end, the widget's type property is first set to "User-defined script function". + +![](trimesh_deform_mesh_dialog.jpg) + +Then, in the script, the filter property is set to the following function: + +```python +def element_filter(element): + try: + if element.type in ['mesh','cad_body']: + return True + except Exception as e: + pass + return False + + DIALOG.selected_element.filter = element_filter +``` + +Furthermore, the dialog contains a name widget with a default name set for the result element and a decimal widget to let the user choose the magnitude of deformation. + + +### Calculation: Mesh deformation with `trimesh` + +The logic of mesh deformation happens in the calculation function. Here, the stored parameters are read from the 'params' array and used to perform the calculation. + +The access to the mesh data is done via numpy arrays that can be retrieved by an elements data interface. This interface is accessible by the `.data` property and yields the results usually for all stages. Using `[s]` as a subscript gives the data for stage `s`. + +```python + vertices = np.array (selected_element.data.coordinate)[s] + triangles = np.array (selected_element.data.triangle)[s] + + # Creating a mesh in 3rd party library "trimesh" + mesh = trimesh.Trimesh (vertices, triangles) + + # Using the deformation algorithm of trimesh + deformed = trimesh.permutate.noise (mesh, deformation) + + # Converting to target dtypes + deformed_vertices = deformed.vertices + deformed_faces = np.array (deformed.faces, dtype=np.int32) + + # Setting the result to transfer back to the GOM Software + context.result[s] = { 'vertices': deformed_vertices, 'triangles': deformed_faces } +``` + +In this case, we retrieve the vertices and triangles of the selected mesh. +To deform the mesh, we then apply some noise to the data using [trimesh's noise permutator](https://trimsh.org/trimesh.permutate.html#trimesh.permutate.noise). We finally transform our results into the supported formats and set the results of this stage in the `context.result[s]` variable. + + +## Related + +* How-to: [Python API introduction - Element data interfaces](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/python_api_introduction/python_api_introduction.md#element-data-interfaces) diff --git a/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/trimesh_deform_mesh.jpg b/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/trimesh_deform_mesh.jpg new file mode 100644 index 0000000..a389a88 Binary files /dev/null and b/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/trimesh_deform_mesh.jpg differ diff --git a/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/trimesh_deform_mesh_dialog.jpg b/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/trimesh_deform_mesh_dialog.jpg new file mode 100644 index 0000000..b517b34 Binary files /dev/null and b/AppExamples/scripted_actuals/TrimeshDeformMesh/doc/trimesh_deform_mesh_dialog.jpg differ diff --git a/AppExamples/scripted_actuals/TrimeshDeformMesh/metainfo.json b/AppExamples/scripted_actuals/TrimeshDeformMesh/metainfo.json index bf5563f..e98512b 100644 --- a/AppExamples/scripted_actuals/TrimeshDeformMesh/metainfo.json +++ b/AppExamples/scripted_actuals/TrimeshDeformMesh/metainfo.json @@ -1,14 +1,19 @@ { "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example demonstrates how to generate a custom surface element using a scripted element. The example script accesses mesh information from an existing mesh in the project and adds a random deformation to each point.", + "example-projects": ["zeiss_part_test_project"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_actuals.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#surface"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": ["mesh", "surface", "scripted-actual"], "title": "TrimeshDeformMesh", "uuid": "3ace1cee-6873-40ac-bb3c-ce4fa1f2f56c", "version": "1.0.0" diff --git a/AppExamples/scripted_checks/ScriptedCurveCheck/doc/Documentation.md b/AppExamples/scripted_checks/ScriptedCurveCheck/doc/Documentation.md new file mode 100644 index 0000000..20e5471 --- /dev/null +++ b/AppExamples/scripted_checks/ScriptedCurveCheck/doc/Documentation.md @@ -0,0 +1,72 @@ +# ScriptedCurveCheck + +![Scripted curve check](scripted_curve_check.jpg) + +## Short description + +This example demonstrates how to create a scalar curve check by a script. Also, the usage of custom coordinate systems in scripted checks is shown. + +## Highlights + +First of all, we need to check if the element selected by the user by the `DIALOG.slct_element` widget is suitable for being checked with a curve check. You can implement your own filter for that, but you can also use the API convenience function for that purpose, which only allow "curve-like" elements: + +```python +DIALOG.slct_element.filter = gom.api.scripted_checks_util.is_curve_checkable +``` + +To allow calculation in a custom coordinate system (one that exists in the project), a second `Selection element` widget is inserted in the dialog, here named `cs`. In the `dialog` function, its value is saved to the element parameters. In case of no selected coordinate system, the viewing coordinate system is used. + +```python +def dialog (context, params): + # [...] + params['coordinate_system'] = DIALOG.cs.value + if params['coordinate_system'] is None: + params['coordinate_system'] = gom.app.project.view_csys +``` + +Having this *reference* to a coordinate system, we can use the API function `scripted_checks_util.get_cs_transformation_4x4` to get a 4x4 matrix for computation. + +During the computation for all stages, we then apply this (affine) transformation using the dot product. + +```python +def calculation (context, params): + # [...] + trafo_matrices = np.array (gom.api.scripted_checks_util.get_cs_transformation_4x4 (params["coordinate_system"])) + # [...] + + # Apply coordinate transformation to all vertices if necessary + if trafo_matrices is not None: + stage_trafo = trafo_matrices[s] + stage_vertices = (np.dot(stage_trafo[0:3, 0:3], stage_vertices.T) + stage_trafo[:3,3:]).T + + # The result of this stage to be filled + actual_result = np.zeros (stage_vertices.shape[0]) + nominal_result = np.random.rand (stage_vertices.shape[0]) + + for i in range (stage_vertices.shape[0]): + point = gom.Vec3d (stage_vertices[i][0], stage_vertices[i][1], stage_vertices[i][2]) + + # ---------------------------------------------------- + # --- insert your calculation for each vertex here --- + # ---------------------------------------------------- + actual_result[i] = point.y + # ---------------------------------------------------- +``` + +Finally, the result is to be set. For each point of the referenced curve, a nominal and actual value is needed. Therefore, the result takes the following form, where `actual_result` and `nominal_result` are vectors with the same length (number of curve points). + +```python +result = { "actual_values" : actual_result, "reference" : element, 'nominal_values': nominal_result } +``` + +In this case, the result is just the `y` coordinate of each point to easily see the correctness of the results including a given transformation. + +Using the example project `zeiss_part_test_project` and the viewing coordinate system, you get the screenshot shown on top. However, if you select the coordinate system `Cylinder 1|Plane 1|Origin`, you can see the transformation in effect: + +![](scripted_curve_check_cs.jpg) + + +## Related + +* [How-to: Scripted checks](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.md) +* [Scripted Element API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md) \ No newline at end of file diff --git a/AppExamples/scripted_checks/ScriptedCurveCheck/doc/scripted_curve_check.jpg b/AppExamples/scripted_checks/ScriptedCurveCheck/doc/scripted_curve_check.jpg new file mode 100644 index 0000000..e1385f1 Binary files /dev/null and b/AppExamples/scripted_checks/ScriptedCurveCheck/doc/scripted_curve_check.jpg differ diff --git a/AppExamples/scripted_checks/ScriptedCurveCheck/doc/scripted_curve_check_cs.jpg b/AppExamples/scripted_checks/ScriptedCurveCheck/doc/scripted_curve_check_cs.jpg new file mode 100644 index 0000000..b7f99de Binary files /dev/null and b/AppExamples/scripted_checks/ScriptedCurveCheck/doc/scripted_curve_check_cs.jpg differ diff --git a/AppExamples/scripted_checks/ScriptedCurveCheck/metainfo.json b/AppExamples/scripted_checks/ScriptedCurveCheck/metainfo.json index 0fad297..2ac6ac5 100644 --- a/AppExamples/scripted_checks/ScriptedCurveCheck/metainfo.json +++ b/AppExamples/scripted_checks/ScriptedCurveCheck/metainfo.json @@ -1,14 +1,19 @@ { "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example demonstrates how to create a scalar curve check by a script. Also, the usage of custom coordinate systems in scripted checks is shown.", + "example-projects": ["zeiss_part_test_project"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#scalar-curve"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": ["scripted-check", "curve"], "title": "ScriptedCurveCheck", "uuid": "9839d24c-2728-46c5-9468-fa65e38389bd", "version": "1.0.0" diff --git a/AppExamples/scripted_checks/ScriptedScalarCheck/doc/Documentation.md b/AppExamples/scripted_checks/ScriptedScalarCheck/doc/Documentation.md new file mode 100644 index 0000000..cfa0bc4 --- /dev/null +++ b/AppExamples/scripted_checks/ScriptedScalarCheck/doc/Documentation.md @@ -0,0 +1,52 @@ +# ScriptedScalarCheck + +![Scripted scalar check](scripted_scalar_check.jpg) + +## Short description + +This example shows how to create a scalar check by script. A scalar check is the most basic check, as it assigns a scalar value to an element. Nearly all elements you can find in the software can be checked like this. + +```{note} +A scripted check has a lot in common with the scripted actual elements. Therefore, the identical mechanisms and concepts will not be explained here. See [How-to: Scripted actuals](../../howtos/scripted_elements/scripted_actuals.md) if you are not already familiar with the concept of scripted elements. +``` + +## Highlights + +First of all, we need to check if the element selected by the user by the `DIALOG.slct_element` widget is suitable for being checked with a scalar check. You can implement your own filter for that, but you can also use the API convenience function for that purpose: + +```python +DIALOG.slct_element.filter = gom.api.scripted_checks_util.is_scalar_checkable +``` + +As you can assign a scalar value to all common element types, this filter allows all element types available in the *element explorer*. + +Furthermore, as described in the [How-to: Scripted checks](../../howtos/scripted_elements/scripted_checks.md), the special parameters for scripted checks are also assigned in the `dialog` function. For ease of use, the respective dialog widgets are used, so we only need to assign the widgets' values to the parameters array. + +```python +def dialog (context, params): + # [...] + params['tolerance'] = DIALOG.tolerances.value + params['unit'] = DIALOG.unit.value + params['abbreviation'] = 'ScrSca' +``` + +In the calculation function, there is not much calculation but just an exemplary assignment of scalar values to the result. For the scripted `Scalar check`, the result dictionary needs to contain `"nominal"` and `"actual"` members, as well as a reference to the element which is checked. + + +```python +def calculation (context, params): + # [...] + for s in context.stages: + actual_result = 1.0 + nominal_result = 2.0 + + context.result[s] = {"nominal" : nominal_result, + "actual" : actual_result, + "reference" : element } + return True +``` + +## Related + +* [How-to: Scripted checks](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.md) +* [Scripted Element API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md) \ No newline at end of file diff --git a/AppExamples/scripted_checks/ScriptedScalarCheck/doc/scripted_scalar_check.jpg b/AppExamples/scripted_checks/ScriptedScalarCheck/doc/scripted_scalar_check.jpg new file mode 100644 index 0000000..5393d8d Binary files /dev/null and b/AppExamples/scripted_checks/ScriptedScalarCheck/doc/scripted_scalar_check.jpg differ diff --git a/AppExamples/scripted_checks/ScriptedScalarCheck/metainfo.json b/AppExamples/scripted_checks/ScriptedScalarCheck/metainfo.json index e45de79..6d30a23 100644 --- a/AppExamples/scripted_checks/ScriptedScalarCheck/metainfo.json +++ b/AppExamples/scripted_checks/ScriptedScalarCheck/metainfo.json @@ -2,14 +2,19 @@ "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example shows how to create a scalar check by script. A scalar check is the most basic check, as it assigns a scalar value to an element. Nearly all elements you can find in the software can be checked like this.", "environment": "ZeissInspectExampleProjects", + "example-projects": ["zeiss_part_test_project"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#scalar"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": ["scripted-check", "scalar"], "title": "ScriptedScalarCheck", "uuid": "1212cf39-9f41-4ae2-bb8f-f7f76b072d91", "version": "1.0.2" diff --git a/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/Documentation.md b/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/Documentation.md new file mode 100644 index 0000000..1b5ba65 --- /dev/null +++ b/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/Documentation.md @@ -0,0 +1,35 @@ +# ScriptedSurfaceCheck + +![Scripted surface check](scripted_surface_check.jpg) + +## Short description + +This example demonstrates how to create a scalar surface check by a script. Also, the usage of custom coordinate systems and element preview in scripted checks is shown. + +## Highlights + +First of all, we need to check if the element selected by the user by the `DIALOG.slct_element` widget is suitable for being checked with a surface check. You can implement your own filter for that, but you can also use the API convenience function for that purpose, which only allow "mesh-like" elements: + +```python +DIALOG.slct_element.filter = gom.api.scripted_checks_util.is_surface_checkable +``` + +The usage of custom coordinate systems is the same as described in the [scripted_curve_check](scripted_curve_check.md) example. + +Finally, the result is to be set. For each point of the referenced mesh, a deviation value is needed. Therefore, the result takes the following form, where `deviation_result` is a vector with length equal to number of mesh points. + +```python +result = { "deviation_values" : deviation_result , "reference" : element } +``` + +As in the [scripted_curve_check](scripted_curve_check.md) example, the result for each point is just the respective `y` coordinate to easily see the correctness of the results including a given transformation. + +Using the example project `zeiss_part_test_project` and the viewing coordinate system, you get the screenshot shown on top. However, if you select the coordinate system `Cylinder 1|Plane 1|Origin`, you can see the transformation in effect: + +![](scripted_surface_check_cs.jpg) + + +## Related + +* [How-to: Scripted checks](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.md) +* [Scripted Element API](https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.md) \ No newline at end of file diff --git a/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/scripted_surface_check.jpg b/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/scripted_surface_check.jpg new file mode 100644 index 0000000..7f3fb1f Binary files /dev/null and b/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/scripted_surface_check.jpg differ diff --git a/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/scripted_surface_check_cs.jpg b/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/scripted_surface_check_cs.jpg new file mode 100644 index 0000000..b324bb7 Binary files /dev/null and b/AppExamples/scripted_checks/ScriptedSurfaceCheck/doc/scripted_surface_check_cs.jpg differ diff --git a/AppExamples/scripted_checks/ScriptedSurfaceCheck/metainfo.json b/AppExamples/scripted_checks/ScriptedSurfaceCheck/metainfo.json index bf6f7f4..44fed0e 100644 --- a/AppExamples/scripted_checks/ScriptedSurfaceCheck/metainfo.json +++ b/AppExamples/scripted_checks/ScriptedSurfaceCheck/metainfo.json @@ -1,14 +1,19 @@ { "author": "Carl Zeiss GOM Metrology GmbH", "description": "This example demonstrates how to create a scalar surface check by a script. Also, the usage of custom coordinate systems and element preview in scripted checks is shown.", + "example-projects": ["zeiss_part_test_project"], "labels": [], "licensing": { "licenses": [], "product-codes": [] }, + "references": [ + ["HowTo", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/howtos/scripted_elements/scripted_checks.html"], + ["API", "https://zeissiqs.github.io/zeiss-inspect-addon-api/2025/python_api/scripted_elements_api.html#scalar-surface"] + ], "software-revision": "0000", "software-version": "ZEISS INSPECT 2025", - "tags": [], + "tags": ["scripted-check", "surface"], "title": "ScriptedSurfaceCheck", "uuid": "81ff67e8-7701-4179-869f-e187d62b945a", "version": "1.0.0"