
.. _python-users-page:

##########################################
Python Users: |FamilyName| for Python
##########################################

**************************
Setting up the Environment
**************************

Prerequisites
=============

You will need Python to be installed on your system. Version 3.7 to 3.11 are supported. There is a version for each of 
these python packages.
You will also need to install the requests module, eg. pip install requests. On Windows you will also need 
Visual C++ runtimes (see Deployment section below) which are usually already installed.

License
=======

To use |FamilyName| for Python you will need a license. You can generate your license on 
https://developer.techsoft3d.com/ or by contacting support@techsoft3d.com.
When you receive your license, please update the license string in the **cee_envision/hoops_license.py** file.

You can also do initialization of |FamilyName| for Python manually and provide you license to the 
cee_envision.core.CoreComponent.initialize method. 
See **Examples/minimal_core.py** for an example on how to do this.

.. code-block:: python

    from cee_envision import core
    comp_instance = core.CoreComponent.initialize(my_license_string)


Configure your Installation
===========================

The only thing you need to configure to run the examples is the license as described above.

The examples scripts use the helpers/setup_environment.py to configure the **PYTHONPATH** and on Windows the PATH. You 
can choose to use this helper or in any other way setup the **PYTHONPATH** (and optionally PATH) for |FamilyName| 
for Python to work. **PYTHONPATH** should point to the root of the |FamilyName| for Python installation.

***************
Example Scripts
***************

**Minimal Test Example**

This example creates a simple geometry with the cee_envision.geo module and exports the model to a PNG image. Run this 
to verify that the |FamilyName| for Python installation is ok and that the off-screen rendering using OSMesa works 
as expected. The script will create an image called script_outputs/minimalImage.png

To run the example:

-   go to the **./Examples** folder 
-   using the terminal do:
    ::

        python minimal_osmesa.py


**Tutorial**

This example shows how to use |FamilyName| for Python to extract information from the CAE file. It is also an 
introduction to the CAE object model of |FamilyName| for Python.

To run the example:

-   go to the **./Examples** folder 
-   using the terminal do:
    ::
        
        python tutorial.py

**Run the Export Examples**

The Export Examples is a collection of examples showing how to use |FamilyName| for Python to export to the Envision 
free viewers using VTFx, export to a cloud streaming database (CUG) 
and upload to Ceetron Cloud for remote visualization in a browser.

To run the example:

-   go to the **./Examples/ExportExamples** folder 
-   using the terminal do:
    ::

        python test-examples.py


If all works well, this will run a number of tests on provided example models located in **./Examples/DemoFiles**: 
Ansys, Fluent, openFOAM and VTK-VTM

Tested functions, all with custom display model configuration:

-   Export to CUG
-   Export to VTFx
-   Send model to Ceetron Cloud account
-   Addition of a custom result to example Ansys model
-   Export of the example Ansys model to a custom format, producing myFile.txt which is opened automatically
    
All result output is stored in "example_test_results" which can be deleted afterwards.

**Take a Look at custom_vtfx_export.py**

The other custom modules (custom_cug_export and custom_send_to_cloud) follow the same pattern: arguments are parsed and 
verified. 
A model is then opened, configured and exported to a VTFx file, or CUG folder or sent to cloud.

Note that the configuration of the model is passed as an argument : the user specifies the name of the configuration 
function and its parameters. 
For example, the following command line calls the configuration function "setLastStateAndScalar" with parameter 
"XX Stress*"

::

    python custom_vtfx_export.py ../DemoFiles/example_ansys.rst example_ansys_xx_stress.vtfx setLastStateAndScalar "XX Stress*"

The same can be achieved within a Python file:
 
.. code-block:: python

    import custom_vtx_export
    custom_vtfx_export.run("../DemoFiles/example_ansys.rst", "example_test_results/example_ansys_xx_stress.vtfx", "setLastStateAndScalar", "XX Stress*")

Please note that if multiple files need to be opened to get a full model, they need to be specified as the first 
argument using a "," as a separator. For example, this command line operates on a Fluent model using two files: 
example_fluent.cas (geometry) and example_fluent.dat (results)

::

    custom_vtfx_export.run("../DemoFiles/example_fluent.cas,../DemoFiles/example_fluent.dat",   "example_test_results/example_fluent_all_velocity.vtfx",    "setLastStateAndScalar",    "All Vel*")
    

**Use for Your Own Needs**

The customizable part of all these export and shares (VTFx, CUG, SendToCloud) is thus isolated as a configuration 
function in the configure model. This is where you would write your own display model configuration functions, which can 
then be invoked by name on the command line as seen above. The functions rely on |FamilyName| programming, please 
refer to the documentation or contact Tech Soft 3D for an introductory training to get you up to speed.

*************
Documentation
*************

|FamilyName| for Python offers all of the features from |ProductName|. |ProductName| is written in C++ and 
|FamilyName| for Python is provided as a wrapper layer on top of this. Because of this, all documentation and 
tutorial snippets are provided in C++ only. However, we believe that reading class/function descriptions and code 
examples in the C++ generated documentation will be straightforward for a Python programmer.  

The Python wrapping targets Python 3.7 to Python 3.11.

You may wish to consider using Anaconda, which is a friendly Python distribution including a large variety of packages 
used in the engineering community.

Modules
=======

|FamilyName| for Python is provided as a Python module named cee, which contains one submodule per C++ namespace.

+---------------------+----------------------+-----------------+
| Python module       | |FamilyName|         | C++ namespace   |
+---------------------+----------------------+-----------------+
| cee_envision.core   | CeeCore              | cee             |
+---------------------+----------------------+-----------------+
| cee_envision.vis    | CeeVisualization     | cee::vis        |
+---------------------+----------------------+-----------------+
| cee_envision.geo    | CeeGeometry          | cee::geo        |
+---------------------+----------------------+-----------------+
| cee_envision.ug     | CeeUnstructGrid      | cee::ug         |
+---------------------+----------------------+-----------------+
| cee_envision.plt    | CeePlot2d            | cee::plt        |
+---------------------+----------------------+-----------------+
| cee_envision.rep    | CeeReport            | cee::rep        |
+---------------------+----------------------+-----------------+
| cee_envision.exp    | CeeExport            | cee::exp        |
+---------------------+----------------------+-----------------+
| cee_envision.imp    | CeeImportCae         | cee::imp        |
+---------------------+----------------------+-----------------+
| cee_envision.osmesa | CeeOSMesa            | cee::osmesa     |
+---------------------+----------------------+-----------------+
| cee_envision.vtfx   | CeeVTFx              | cee::vtfx       |
+---------------------+----------------------+-----------------+

************************************************
Getting Started with |FamilyName| for Python
************************************************

Once the python components are all set you can verify your installation by launching the script **minimal_osmesa.py** 
within the **Examples/** folder.
The documentation for each C++ namespace translated into Python modules are found in the main C++ documentation.

Please read a list of topics before starting. This will help you understand the main concepts of |ProductName|, 
license, CloudIds and others (see :ref:`topics-page`).
The |ProductName| components overview are found in :ref:`components-page`.

********************************************
From C++ Documentation to Actual Python Code
********************************************

The C++ namespace are translated into Python Modules. 

.. code-block:: python

    # C++
    using namespace cee::app

    # Python 
    import cee_envision.app 


walking through the library

.. code-block:: python

    # C++
    cee::Str fileName = "path/to/my/file";
    cee::ug::Error error;

    cee::ug::Model* model = cee::app::Models.open(filename,  &error);

     

    # Python 
    from cee_envision.app import models
    fileName = "path/to/my/file"

    model = models.open(fileName)


Accessing methods by pointers in C++ become dot in Python.

For instance, the visibility for an object is typically accessed using visible()/setVisible() in C++. 

.. code-block:: python

    # C++
    # class cee::ug::PartSettings
    int partId = 1;
    size_t globalGeometryIndex = 1;
    cee::ug::PartSettings* settings = model->partSettings(globalGeometryIndex, partId);
    settings()->setVisible(false); // request to hide part on the view

    # Python 
    partId = 1
    globalGeometryIndex = 1

    settings = model.partSettings(globalGeometryIndex, partId)
    settings.setVisible(False) 


As you can see, the translation is very straight forward. Please check the tutorials in :ref:`tutorials-page` and come 
back to this section to help you translate the C++ code into python.

Inheritance
===========

Due to limitations in the Python wrapper layer, there is a special handling of inheritance in the Python version of 
|ProductName|. The problem is downcasting objects that are fetched from within |ProductName|. 

For instance:

.. code-block:: python

    myGeo = GeometryModel()
    myView.addModel(myGeo)

    model = myView.model(0)                                    # Get myGeo as a Model from the cee_envision.vis.View instance. 
    geometryModel = GeometryModel.castFromBaseClass(model)     # Cast to a GeometryModel using the provided method
    markupModel = MarkupModel.castFromBaseClass(model)         # This results in markupModel being None

In this scenario, in order to obtain an instance of GeometryModel when getting a Model from the view, we have provided 
casting methods for all such classes. Using the static castFromBaseClass will always give you a correct cast. For an 
invalid cast, the returned value will be null. 

Identity Operator
=================

Due to the wrapping mechanism of underlying C++ objects, the Python "is" operator does not provide the expected behavior 
when objects are passed on to C++, for example to be stored in C++ pointer collections.
In these cases, if identity needs to be tested, a specific operator named `swigis` has been implemented in the 
cee_envision.core module.

.. code-block:: python
 
    ...

    from cee_envision.core import swigis

    ...

    resources = ImageResources()

    image1 = Image()
    res.addImageResource("image 1", image1) # object image1 will be stored in a C++ object collection

    image2 = res.imageResource("image 1") # retrieving the same object

    print(image2 is image1)         # unexpectedly False (Python objects wrapping the C++ are different)
    print(image2 |swigis| image1)   # allows to compare underlying C++ objects

**********
Deployment
**********

For |ProductName|, the development language is C++, which means that any product developed using one of our toolkits 
must are depending on Visual C++ redistributables. For more information on deployment of Visual C++ based applications, 
see `Deployment in Visual C++ <https://learn.microsoft.com/en-us/cpp/windows/deployment-in-visual-cpp>`_

Using the redistributable packages is recommended because they enable automatic updates of the Visual C++ libraries.
The latest Visual C++ Redistributable Packages for Visual Studio 2015-2022 can be downloaded using this permalink for 
the latest supported x64 version: https://aka.ms/vs/17/release/vc_redist.x64.exe



