.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "examples\08-python-operators\02-python_operators_with_dependencies.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note :ref:`Go to the end ` to download the full example code. .. rst-class:: sphx-glr-example-title .. _sphx_glr_examples_08-python-operators_02-python_operators_with_dependencies.py: .. _ref_python_operators_with_deps: Create a plug-in package that has third-party dependencies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ This example shows how to create a Python plug-in package with third-party dependencies. You should be familiar with these examples before proceeding with this more advanced one: - :ref:`ref_wrapping_numpy_capabilities` - :ref:`ref_python_plugin_package` This plug-in contains an operator whose implementation depends on a third-party Python module named `gltf `_. This operator takes a path, a mesh, and a 3D vector field as inputs and then exports the mesh and the norm of the 3D vector field to a GLTF file at the given path. .. note:: This example requires DPF 4.0 (Ansys 2022R2) or above. For more information, see :ref:`ref_compatibility`. .. GENERATED FROM PYTHON SOURCE LINES 50-59 Create the plug-in package -------------------------- Each operator implementation derives from the :class:`ansys.dpf.core.custom_operator.CustomOperatorBase` class and a call to the :py:func:`ansys.dpf.core.custom_operator.record_operator` method, which records the operators of the plug-in package. Download the ``gltf_plugin`` plug-in package that has already been created for you. .. GENERATED FROM PYTHON SOURCE LINES 59-68 .. code-block:: Python import os from pathlib import Path from ansys.dpf.core import examples plugin_path = Path(examples.download_gltf_plugin()) folder_root = Path(str(Path.cwd()).rsplit("pydpf-core", 1)[0]) / "pydpf-core" .. GENERATED FROM PYTHON SOURCE LINES 69-86 To add third-party modules as dependencies to a plug-in package, you must create and reference a folder or ZIP file with the sites of the dependencies in an XML file located next to the folder for the plug-in package. The XML file must have the same name as the plug-in package plus an ``.xml`` extension. When the :py:func:`ansys.dpf.core.core.load_library` method is called, DPF-Core uses the ``site`` Python module to add custom to the path for the Python interpreter. To create these custom sites, requirements of the plug-in package should be installed in a Python virtual environment, the site-packages (with unnecessary folders removed) should be compressed to a ZIP file and placed with the plugin. The path to this ZIP file should be referenced in the XML as shown in the preceding code. To simplify this step, you can add a requirements file in the plug-in package: .. GENERATED FROM PYTHON SOURCE LINES 86-93 .. code-block:: Python print("\033[1m gltf_plugin/requirements.txt: \n \033[0m") requirements_path = plugin_path / "requirements.txt" with requirements_path.open("r") as file: for line in file.readlines(): print("\t\t\t" + line) .. rst-class:: sphx-glr-script-out .. code-block:: none gltf_plugin/requirements.txt: wheel pygltflib .. GENERATED FROM PYTHON SOURCE LINES 94-121 Download the script for your operating system. - For Windows, download this :download:`PowerShell script `. - For Linux, download this :download:`Shell script `. Run the downloaded script with the mandatory arguments: - ``-pluginpath``: Path to the folder with the plug-in package. - ``-zippath``: Path and name for the ZIP file. Optional arguments are: - ``-pythonexe``: Path to a Python executable of your choice. - ``-tempfolder``: Path to a temporary folder to work in. The default is the environment variable ``TEMP`` on Windows and ``/tmp/`` on Linux. Run the command for your operating system. - From Windows PowerShell, run:: create_sites_for_python_operators.ps1 -pluginpath /path/to/plugin -zippath /path/to/plugin/assets/winx64.zip # noqa: E501 - From Linux Shell, run:: create_sites_for_python_operators.sh -pluginpath /path/to/plugin -zippath /path/to/plugin/assets/linx64.zip # noqa: E501 .. GENERATED FROM PYTHON SOURCE LINES 121-165 .. code-block:: Python site_path = plugin_path / "assets" / "gltf_sites_winx64.zip" if os.name == "nt" and not site_path.exists(): cmd_file = ( folder_root / "doc" / "source" / "user_guide" / "create_sites_for_python_operators.ps1" ) args = [ "powershell", str(cmd_file), "-pluginpath", str(plugin_path), "-zippath", str(plugin_path / "assets" / "gltf_sites_winx64.zip"), ] print(args) import subprocess process = subprocess.run(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE) if process.stderr: raise RuntimeError( "Installing pygltf in a virtual environment failed with error:\n" + f"return code = {process.returncode}\n" + process.stderr.decode() + "\n\n and log:\n" + process.stdout.decode() ) else: print("Installing pygltf in a virtual environment succeeded") elif os.name == "posix" and not site_path.exists(): cmd_file = ( folder_root / "doc" / "source" / "user_guide" / "create_sites_for_python_operators.sh" ) run_cmd = f"{cmd_file}" args = ( f' -pluginpath "{plugin_path}" ' f'-zippath "{plugin_path / "assets" / "gltf_sites_winx64.zip"}"' ) print(run_cmd + args) os.system(f"chmod u=rwx,o=x {cmd_file}") os.system(run_cmd + args) print("\nInstalling pygltf in a virtual environment succeeded") .. rst-class:: sphx-glr-script-out .. code-block:: none ['powershell', 'D:\\a\\pydpf-core\\pydpf-core\\doc\\source\\user_guide\\create_sites_for_python_operators.ps1', '-pluginpath', 'D:\\a\\pydpf-core\\pydpf-core\\.tox\\doc-html\\Lib\\site-packages\\ansys\\dpf\\core\\examples\\python_plugins\\gltf_plugin', '-zippath', 'D:\\a\\pydpf-core\\pydpf-core\\.tox\\doc-html\\Lib\\site-packages\\ansys\\dpf\\core\\examples\\python_plugins\\gltf_plugin\\assets\\gltf_sites_winx64.zip'] Installing pygltf in a virtual environment succeeded .. GENERATED FROM PYTHON SOURCE LINES 166-177 Load the plug-in package ------------------------ You use the function :py:func:`ansys.dpf.core.core.load_library` to load the plug-in package. - The first argument is the path to the directory where the plug-in package is located. - The second argument is ``py_``, where ```` is the name identifying the plug-in package. - The third argument is the name of the function exposed in the ``__init__`` file for the plug-in package that is used to record operators. .. GENERATED FROM PYTHON SOURCE LINES 177-196 .. code-block:: Python from ansys.dpf import core as dpf from ansys.dpf.core import examples # Python plugins are not supported in process. dpf.start_local_server(config=dpf.AvailableServerConfigs.GrpcServer) tmp = Path(dpf.make_tmp_dir_server()) dpf.upload_files_in_folder(dpf.path_utilities.join(str(tmp), "plugins", "gltf_plugin"), plugin_path) dpf.upload_file( str(plugin_path) + ".xml", dpf.path_utilities.join(str(tmp), "plugins", "gltf_plugin.xml") ) dpf.load_library( dpf.path_utilities.join(str(tmp), "plugins", "gltf_plugin"), "py_dpf_gltf", "load_operators", ) .. rst-class:: sphx-glr-script-out .. code-block:: none 'py_dpf_gltf successfully loaded' .. GENERATED FROM PYTHON SOURCE LINES 197-198 Instantiate the operator. .. GENERATED FROM PYTHON SOURCE LINES 198-201 .. code-block:: Python new_operator = dpf.Operator("gltf_export") .. GENERATED FROM PYTHON SOURCE LINES 202-210 This new ``gltf_export`` operator requires the following as inputs: a triangle surface mesh, a displacement field on this surface mesh, and a path to export the GLTF file to. To demonstrate this new operator, a :class:`ansys.dpf.core.model.Model` class is created on a simple file and the :class:`ansys.dpf.core.operators.mesh.tri_mesh_skin` operator is used to extract the surface of the mesh in triangle elements. .. GENERATED FROM PYTHON SOURCE LINES 212-227 .. graphviz:: digraph workflow { graph [pad="0.5", nodesep="0.3", ranksep="0.3"] node [shape=box, style=filled, fillcolor="#ffcc00", margin="0"]; rankdir=LR; splines=line; ds [label="data_sources", shape=box, style=filled, fillcolor=cadetblue2]; ds -> mesh_provider [style=dashed]; mesh_provider -> skin_mesh [splines=ortho]; ds -> displacement [style=dashed]; skin_mesh -> displacement [splines=ortho]; skin_mesh -> gltf_export [splines=ortho]; displacement -> gltf_export [splines=ortho]; } .. GENERATED FROM PYTHON SOURCE LINES 229-231 Use the custom operator ----------------------- .. GENERATED FROM PYTHON SOURCE LINES 231-249 .. code-block:: Python model = dpf.Model(dpf.upload_file_in_tmp_folder(examples.find_static_rst())) mesh = model.metadata.meshed_region skin_mesh = dpf.operators.mesh.tri_mesh_skin(mesh=mesh) displacement = model.results.displacement() displacement.inputs.mesh_scoping(skin_mesh) displacement.inputs.mesh(skin_mesh) new_operator.inputs.path(str(tmp / "out")) new_operator.inputs.mesh(skin_mesh) new_operator.inputs.field(displacement.outputs.fields_container()[0]) new_operator.run() print("operator ran successfully") dpf.download_file(tmp / "out.glb", Path.cwd() / "out.glb") .. rst-class:: sphx-glr-script-out .. code-block:: none operator ran successfully .. GENERATED FROM PYTHON SOURCE LINES 250-251 You can download :download:`output ` from the ``gltf`` operator. .. rst-class:: sphx-glr-timing **Total running time of the script:** (1 minutes 21.332 seconds) .. _sphx_glr_download_examples_08-python-operators_02-python_operators_with_dependencies.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: 02-python_operators_with_dependencies.ipynb <02-python_operators_with_dependencies.ipynb>` .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: 02-python_operators_with_dependencies.py <02-python_operators_with_dependencies.py>` .. container:: sphx-glr-download sphx-glr-download-zip :download:`Download zipped: 02-python_operators_with_dependencies.zip <02-python_operators_with_dependencies.zip>` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_