Skip to content

Commit e578f6c

Browse files
authored
fix add-text behavior (#582)
* fix add-text behavior * fix Result animation * avoid double text for animation * avoid double text for animation; fix test
1 parent 22dba2a commit e578f6c

2 files changed

Lines changed: 55 additions & 18 deletions

File tree

ansys/mapdl/reader/cyclic_reader.py

Lines changed: 32 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,9 +1595,12 @@ def animate_nodal_solution(
15951595
movie_filename=None,
15961596
**kwargs,
15971597
):
1598-
"""Animate nodal solution. Assumes nodal solution is a
1599-
displacement array from a modal solution.
1598+
"""Animate nodal solution.
16001599
1600+
Assumes nodal solution is a displacement array from a modal solution.
1601+
1602+
Parameters
1603+
----------
16011604
rnum : int or list
16021605
Cumulative result number with zero based indexing, or a
16031606
list containing (step, substep) of the requested result.
@@ -1617,8 +1620,8 @@ def animate_nodal_solution(
16171620
Shows the phase at each frame.
16181621
16191622
add_text : bool, optional
1620-
Includes result information at the bottom left-hand corner
1621-
of the plot.
1623+
Includes result information at the top left-hand corner of the
1624+
plot. Set font size with the ``font_size`` parameter.
16221625
16231626
interpolate_before_map : bool, optional
16241627
Leaving this at default generally results in a better plot.
@@ -1629,9 +1632,27 @@ def animate_nodal_solution(
16291632
A single loop of the mode will be recorded.
16301633
16311634
kwargs : optional keyword arguments, optional
1632-
See help(pyvista.plot) for additional keyword arguments.
1635+
See :func:`pyvista.plot` for additional keyword arguments.
1636+
1637+
Examples
1638+
--------
1639+
Generate a movie of a mode shape while plotting off-screen.
1640+
1641+
>>> from ansys.mapdl.reader import read_binary
1642+
>>> rst = read_binary("academic_rotor.rst")
1643+
>>> rst.animate_nodal_displacement(
1644+
... (3, 2),
1645+
... displacement_factor=0.02,
1646+
... movie_filename="movie.mp4",
1647+
... off_screen=True
1648+
... )
16331649
16341650
"""
1651+
# Avoid infinite while loop by ensure looping is disabled if off screen
1652+
# and writing a movie
1653+
if movie_filename and kwargs.get("off_screen", False):
1654+
loop = False
1655+
16351656
if "nangles" in kwargs: # pragma: no cover
16361657
n_frames = kwargs.pop("nangles")
16371658
warnings.warn(
@@ -1675,6 +1696,7 @@ def animate_nodal_solution(
16751696
scalars = (complex_disp * complex_disp).sum(1) ** 0.5
16761697

16771698
# initialize plotter
1699+
font_size = kwargs.pop("font_size", 16)
16781700
text_color = kwargs.pop("text_color", None)
16791701
cpos = kwargs.pop("cpos", None)
16801702
off_screen = kwargs.pop("off_screen", None)
@@ -1697,9 +1719,8 @@ def animate_nodal_solution(
16971719

16981720
# setup text
16991721
if add_text:
1700-
text_actor = plotter.add_text(
1701-
" ", font_size=20, position=[0, 0], color=text_color
1702-
)
1722+
# results in a corner annotation actor
1723+
text_actor = plotter.add_text(" ", font_size=font_size, color=text_color)
17031724

17041725
if cpos:
17051726
plotter.camera_position = cpos
@@ -1740,8 +1761,9 @@ def q_callback():
17401761
plot_mesh.points[:] = orig_pt + complex_disp_adj
17411762

17421763
if add_text:
1743-
text_actor.SetInput(
1744-
"%s\nPhase %.1f Degrees" % (result_info, (angle * 180 / np.pi))
1764+
text_actor.set_text(
1765+
2, # place in the upper left
1766+
f"{result_info}\nPhase {np.rad2deg(angle):.1f} Degrees",
17451767
)
17461768

17471769
plotter.update(1, force_redraw=True)

ansys/mapdl/reader/rst.py

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,7 +2979,9 @@ def _plot_point_scalars(
29792979
Increases or decreases displacement by a factor.
29802980
29812981
add_text : bool, optional
2982-
Adds information about the result when rnum is given.
2982+
Adds information about the result when rnum is given. Control the
2983+
font size with the ``font_size`` parameter and text color with
2984+
``text_color``.
29832985
29842986
overlay_wireframe : bool, optional
29852987
Overlay a wireframe of the original undeformed mesh.
@@ -3090,7 +3092,7 @@ def _plot_point_scalars(
30903092
# remove extra keyword args
30913093
kwargs.pop("node_components", None)
30923094
kwargs.pop("sel_type_all", None)
3093-
3095+
font_size = kwargs.pop("font_size", 16)
30943096
if overlay_wireframe:
30953097
plotter.add_mesh(self.grid, style="wireframe", color="w", opacity=0.5)
30963098

@@ -3117,10 +3119,11 @@ def _plot_point_scalars(
31173119
else:
31183120
plotter.open_movie(movie_filename)
31193121

3120-
# add table
31213122
if add_text and rnum is not None:
31223123
result_text = self.text_result_table(rnum)
3123-
plotter.add_text(result_text, font_size=20, color=text_color)
3124+
if not animate:
3125+
# avoid adding twice
3126+
plotter.add_text(result_text, font_size=font_size, color=text_color)
31243127

31253128
# camera position added in 0.32.0
31263129
show_kwargs = {}
@@ -3164,6 +3167,13 @@ def exit_callback(plotter, RenderWindowInteractor, event):
31643167
lambda render, event: exit_callback(plotter, render, event),
31653168
)
31663169

3170+
# setup text
3171+
if add_text:
3172+
# results in a corner annotation actor
3173+
text_actor = plotter.add_text(
3174+
" ", font_size=font_size, color=text_color
3175+
)
3176+
31673177
first_loop = True
31683178
cached_normals = [None for _ in range(n_frames)]
31693179
while self._animating:
@@ -3184,8 +3194,10 @@ def exit_callback(plotter, RenderWindowInteractor, event):
31843194
copied_mesh.point_data["Normals"][:] = cached_normals[j]
31853195

31863196
if add_text:
3187-
phase = angle * 180 / np.pi
3188-
plotter.add_text(f"{result_text} \nPhase {phase} Degrees")
3197+
text_actor.set_text(
3198+
2, # place in the upper left
3199+
f"{result_text}\nPhase: {np.rad2deg(angle):.1f} Degrees",
3200+
)
31893201

31903202
# at max supported framerate
31913203
plotter.update(1, force_redraw=True)
@@ -3311,6 +3323,7 @@ def _animate_point_scalars(
33113323
# screenshot = kwargs.pop('screenshot', None)
33123324
# interactive = kwargs.pop('interactive', True)
33133325
text_color = kwargs.pop("text_color", None)
3326+
font_size = kwargs.pop("font_size", 16)
33143327

33153328
kwargs.setdefault("smooth_shading", True)
33163329
kwargs.setdefault("color", "w")
@@ -3360,7 +3373,9 @@ def _animate_point_scalars(
33603373
if text is not None:
33613374
if len(text) != len(scalars):
33623375
raise ValueError("Length of ``text`` must be the same as ``scalars``")
3363-
plotter.add_text(text[0], font_size=20, color=text_color)
3376+
text_actor = plotter.add_text(
3377+
text[0], font_size=font_size, color=text_color
3378+
)
33643379

33653380
# orig_pts = copied_mesh.points.copy()
33663381
plotter.show(
@@ -3391,7 +3406,7 @@ def q_callback():
33913406
copied_mesh.active_scalars[:] = data
33923407

33933408
if text is not None:
3394-
plotter.add_text(text[i])
3409+
text_actor.set_text(2, text[i]) # place in the upper left
33953410

33963411
# at max supported framerate
33973412
plotter.update(1, force_redraw=True)

0 commit comments

Comments
 (0)