Skip to content

Commit

Permalink
feat: allow picking from easy access methods (#1499)
Browse files Browse the repository at this point in the history
Co-authored-by: pyansys-ci-bot <92810346+pyansys-ci-bot@users.noreply.github.com>
  • Loading branch information
RobPasMue and pyansys-ci-bot authored Oct 24, 2024
1 parent c4c4d14 commit 85e5df3
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 31 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -164,4 +164,7 @@ docker/*-binaries.zip
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/

# Ignore scripts folder
scripts

# End of https://www.toptal.com/developers/gitignore/api/python
1 change: 1 addition & 0 deletions doc/changelog.d/1499.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
allow picking from easy access methods
59 changes: 34 additions & 25 deletions doc/source/examples/01_getting_started/05_plotter_picker.mystnb
Original file line number Diff line number Diff line change
Expand Up @@ -168,31 +168,6 @@ plotter = GeometryPlotter(use_trame=True)
plotter.show(plot_list)
```

## Render in different colors

You can render the objects in different colors automatically using PyVista's default
color cycler. In order to do this, activate the ``multi_colors=True`` option when calling
the ``plot()`` method.

In the following cell we will create a new design and plot a prism and a cylinder in different colors.

```{code-cell} ipython
design = modeler.create_design("MultiColors")

# Create a sketch of a box
sketch_box = Sketch().box(Point2D([0, 0], unit=UNITS.m), width=30 * UNITS.m, height=40 * UNITS.m)

# Create a sketch of a circle (overlapping the box slightly)
sketch_circle = Sketch().circle(Point2D([20, 0], unit=UNITS.m), radius=3 * UNITS.m)

# Extrude both sketches to get a prism and a cylinder
design.extrude_sketch("Prism", sketch_box, 50 * UNITS.m)
design.extrude_sketch("Cylinder", sketch_circle, 50 * UNITS.m)

# Design plotting
design.plot(multi_colors=True)
```

## Clip objects

You can clip any object represented in the plotter by defining a ``Plane`` object that
Expand Down Expand Up @@ -231,6 +206,40 @@ picked_list = plotter.show(plot_list)
print(picked_list)
```

It is also possible to enable picking directly for a specific ``design`` or ``component``
object alone. In the following cell, picking is enabled for the ``design`` object.

```{code-cell} ipython3
picked_list = design.plot(allow_picking=True)
print(picked_list)
```

## Render in different colors

You can render the objects in different colors automatically using PyVista's default
color cycler. In order to do this, activate the ``multi_colors=True`` option when calling
the ``plot()`` method.

In the following cell we will create a new design and plot a prism and a cylinder in different colors.

```{code-cell} ipython
design = modeler.create_design("MultiColors")

# Create a sketch of a box
sketch_box = Sketch().box(Point2D([0, 0], unit=UNITS.m), width=30 * UNITS.m, height=40 * UNITS.m)

# Create a sketch of a circle (overlapping the box slightly)
sketch_circle = Sketch().circle(Point2D([20, 0], unit=UNITS.m), radius=3 * UNITS.m)

# Extrude both sketches to get a prism and a cylinder
design.extrude_sketch("Prism", sketch_box, 50 * UNITS.m)
design.extrude_sketch("Cylinder", sketch_circle, 50 * UNITS.m)

# Design plotting
design.plot(multi_colors=True)
```


## Close session

When you finish interacting with your modeling service, you should close the active
Expand Down
31 changes: 27 additions & 4 deletions src/ansys/geometry/core/designer/component.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
"""Provides for managing components."""

from enum import Enum, unique
from typing import TYPE_CHECKING, Optional, Union
from typing import TYPE_CHECKING, Any, Optional, Union
import uuid

from beartype import beartype as check_input_types
Expand Down Expand Up @@ -1394,8 +1394,9 @@ def plot(
screenshot: str | None = None,
use_trame: bool | None = None,
use_service_colors: bool | None = None,
allow_picking: bool | None = None,
**plotting_options: dict | None,
) -> None:
) -> None | list[Any]:
"""Plot the component.
Parameters
Expand All @@ -1419,9 +1420,17 @@ def plot(
Whether to use the colors assigned to the body in the service. The default
is ``None``, in which case the ``ansys.geometry.core.USE_SERVICE_COLORS``
global setting is used.
allow_picking : bool, default: None
Whether to enable picking. The default is ``None``, in which case the
picker is not enabled.
**plotting_options : dict, default: None
Keyword arguments for plotting. For allowable keyword arguments, see the
Returns
-------
None | list[Any]
If ``allow_picking=True``, a list of picked objects is returned. Otherwise, ``None``.
Examples
--------
Create 25 small cylinders in a grid-like pattern on the XY plane and
Expand Down Expand Up @@ -1465,6 +1474,16 @@ def plot(
if use_service_colors is not None
else pyansys_geometry.USE_SERVICE_COLORS
)
# If picking is enabled, we should not merge the component
if allow_picking:
# This blocks the user from selecting the component itself
# but honestly, who would want to select the component itself since
# you already have a reference to it? It is the object you are plotting!
self._grpc_client.log.info(
"Ignoring 'merge_component=True' (default behavior) as "
"'allow_picking=True' has been requested."
)
merge_component = False

# Add merge_component and merge_bodies to the plotting options
plotting_options["merge_component"] = merge_component
Expand All @@ -1479,9 +1498,13 @@ def plot(
"'multi_colors' or 'use_service_colors' are defined."
)

pl = GeometryPlotter(use_trame=use_trame, use_service_colors=use_service_colors)
pl = GeometryPlotter(
use_trame=use_trame,
use_service_colors=use_service_colors,
allow_picking=allow_picking,
)
pl.plot(self, **plotting_options)
pl.show(screenshot=screenshot, **plotting_options)
return pl.show(screenshot=screenshot, **plotting_options)

def __repr__(self) -> str:
"""Represent the ``Component`` as a string."""
Expand Down
17 changes: 15 additions & 2 deletions src/ansys/geometry/core/plotting/plotter.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ def show(
plotting_object: Any = None,
screenshot: str | None = None,
**plotting_options,
) -> None:
) -> None | list[Any]:
"""Show the plotter.
Parameters
Expand All @@ -452,4 +452,17 @@ def show(
"""
if plotting_object is not None:
self.plot(plotting_object, **plotting_options)
self._backend.show(screenshot=screenshot, **plotting_options)
picked_objs = self._backend.show(screenshot=screenshot, **plotting_options)

# Return the picked objects if picking is enabled... but as the actual PyAnsys
# Geometry objects (or PyVista objects if not)
if picked_objs:
lib_objects = []
for element in picked_objs:
if isinstance(element, MeshObjectPlot):
lib_objects.append(element.custom_object)
elif isinstance(element, EdgePlot):
lib_objects.append(element.edge_object)
else: # Either a PyAnsys Geometry object or a PyVista object
lib_objects.append(element)
return lib_objects

0 comments on commit 85e5df3

Please sign in to comment.