Source code for Muscat.Bridges.PlotlyBridge
from typing import Optional, Union, TYPE_CHECKING
import numpy as np
from Muscat.Simple import Mesh
if TYPE_CHECKING:
from plotly.graph_objects import Mesh3d
[docs]
def GetPlotlySurfaceMesh(myMesh: Mesh, fieldToPlot : Optional[Union[str,np.ndarray]] = None):
"""Function to convert a Mesh and a Nodal fields (element fields to yet implemented) to
a Plotly graph_object Mesh3d library. Internally the norm of the field is computed if
the fieldToPlot is a vector field (like normals).
(This functions need the plotly package installed)
Parameters
----------
myMesh : Mesh
The mesh to be converted
fieldToPlot : Optional[Union[str,np.ndarray]], optional
point field or point field name to put the intensity field of
the Mesh3d. by default None
Returns
-------
plotly.graph_objects.Mesh3d
the mesh converted to Plotly format
Raises
------
RuntimeError
if field.shape[0] != number of node of the mesh
RuntimeError
if the field name is not present in the mesh.nodesFields
"""
import plotly.graph_objects as go
mesh = myMesh.View()
#for the moment the compute skin does permit to transport elemField data to the skin
mesh.elemFields = {}
from Muscat.Simple import ElementFilter, ED
from Muscat.MeshTools.MeshModificationTools import ComputeSkin
from Muscat.MeshTools.MeshInspectionTools import ExtractElementsByElementFilter
ComputeSkin(mesh=mesh, inPlace=True)
mesh2D = ExtractElementsByElementFilter(mesh,ElementFilter(dimensionality=2), copy=False)
from Muscat.MeshTools.MeshTetrahedrization import Tetrahedrization
mesh_of_tris = Tetrahedrization(mesh2D)
if mesh_of_tris.nodes.shape[1]<3 :
z = np.zeros_like(mesh_of_tris.nodes[:,0])
else:
z=mesh_of_tris.nodes[:,2]
res = go.Mesh3d(
x=mesh_of_tris.nodes[:,0],
y=mesh_of_tris.nodes[:,1],
z=z,
i=mesh_of_tris.GetElementsOfType(ED.Triangle_3).connectivity[:,0],
j=mesh_of_tris.GetElementsOfType(ED.Triangle_3).connectivity[:,1],
k=mesh_of_tris.GetElementsOfType(ED.Triangle_3).connectivity[:,2],
flatshading= True
)
if fieldToPlot is None:
return res
res.showscale=True
if isinstance(fieldToPlot,str):
if fieldToPlot in mesh.nodeFields:
name = fieldToPlot
fieldToPlot = mesh.nodeFields[fieldToPlot]
intensitymode = 'vertex'
elif fieldToPlot in mesh.elemFields:
name = fieldToPlot
fieldToPlot = mesh.elemFields[fieldToPlot]
intensitymode = 'cell'
else:
raise RuntimeError("Error: fieldToPlot not in nodeFields neither elemFields")
else:
name = "data"
if fieldToPlot.shape[0] == myMesh.GetNumberOfNodes():
intensitymode = 'vertex'
elif fieldToPlot.shape[0] == myMesh.GetNumberOfElements():
intensitymode = 'cell'
else:
raise RuntimeError("Error: fieldToPlot must match the number of nodes or the number of elements")
if len(fieldToPlot.shape) > 1:
fieldToPlot = np.linalg.norm(fieldToPlot, axis= 1)
name = f"norm({name})"
res.intensity = fieldToPlot
res.intensitymode = intensitymode
res.colorbar=dict(title=dict(text=name))
res.colorscale='Viridis'
return res
[docs]
def PlotMesh(mesh : Union[Mesh,'Mesh3d'], nodeFieldToPlot : Optional[Union[str,np.ndarray]] = None):
"""Plot a mesh using Plotly
(This functions need the plotly package installed)
Parameters
----------
mesh : Union[Mesh,'Mesh3d']
Mesh to plot (Muscat Mesh or plotly Mesh3D)
fieldToPlot : Optional[Union[str,np.ndarray]], optional
point field or point field name to put the intensity field of
the Mesh3d. by default None
Returns
-------
Plotly Figure
the Plotly figure
"""
import plotly.graph_objects as go
if isinstance(mesh, Mesh):
meshtoplot = GetPlotlySurfaceMesh(mesh, nodeFieldToPlot )
else:
meshtoplot = mesh
fig = go.Figure(data=[meshtoplot])
fig.show()
return fig
[docs]
def CheckIntegrity(GUI: bool = False):
from Muscat.Helpers.CheckTools import SkipTest
if SkipTest("PLOTLY_NO_FAIL"): # pragma: no cover
return "skip"
try:
import plotly
except: # pragma: no cover
return "skip : plotly not installed"
from Muscat.MeshTools.MeshTools import GetElementsCenters
from Muscat.Simple import ReadMesh
from Muscat.TestData import GetTestDataPath
myMesh: Mesh = ReadMesh(GetTestDataPath() + "dent3D.msh")
myMesh.nodeFields["xpos"] = myMesh.nodes[:,0]
myMesh.nodeFields["pos"] = myMesh.nodes
myMesh.elemFields["centers"] = GetElementsCenters(myMesh )
plotlymesh = GetPlotlySurfaceMesh(myMesh)
plotlymesh = GetPlotlySurfaceMesh(myMesh, "xpos")
if GUI:
PlotMesh(plotlymesh)
PlotMesh(myMesh)
return 'ok'
if __name__ == "__main__":
print(CheckIntegrity(True)) # pragma: no cover