@@ -572,9 +572,34 @@ def copy(self, parent: "Component", name: str = None) -> "Body":
572572 """
573573 return
574574
575+ @abstractmethod
576+ def get_raw_tessellation (
577+ self ,
578+ tess_options : TessellationOptions | None = None ,
579+ reset_cache : bool = False ,
580+ ) -> dict :
581+ """Tessellate the body and return the raw tessellation data.
582+
583+ Parameters
584+ ----------
585+ tess_options : TessellationOptions | None, default: None
586+ A set of options to determine the tessellation quality.
587+ reset_cache : bool, default: False
588+ Whether to reset the tessellation cache and re-request the tessellation
589+ from the server.
590+
591+ Returns
592+ -------
593+ dict
594+ Dictionary with face IDs as keys and face tessellation data as values.
595+ """
596+
575597 @abstractmethod
576598 def tessellate (
577- self , merge : bool = False , tess_options : TessellationOptions | None = None
599+ self ,
600+ merge : bool = False ,
601+ tess_options : TessellationOptions | None = None ,
602+ reset_cache : bool = False ,
578603 ) -> Union ["PolyData" , "MultiBlock" ]:
579604 """Tessellate the body and return the geometry as triangles.
580605
@@ -586,6 +611,9 @@ def tessellate(
586611 When ``True``, the individual faces of the tessellation are merged.
587612 tess_options : TessellationOptions | None, default: None
588613 A set of options to determine the tessellation quality.
614+ reset_cache : bool, default: False
615+ Whether to reset the tessellation cache and re-request the tessellation
616+ from the server.
589617
590618 Returns
591619 -------
@@ -856,6 +884,7 @@ def __init__(
856884 self ._surface_offset = None
857885 self ._is_alive = True
858886 self ._tessellation = None
887+ self ._raw_tessellation = None
859888 self ._fill_style = FillStyle .DEFAULT
860889 self ._color = None
861890
@@ -876,6 +905,7 @@ def reset_tessellation_cache(func): # noqa: N805
876905 @wraps (func )
877906 def wrapper (self : "MasterBody" , * args , ** kwargs ):
878907 self ._tessellation = None
908+ self ._raw_tessellation = None
879909 return func (self , * args , ** kwargs )
880910
881911 return wrapper
@@ -1251,12 +1281,46 @@ def copy(self, parent: "Component", name: str = None) -> "Body": # noqa: D102
12511281 body_id = f"{ parent .id } /{ tb .id } " if parent .parent_component else tb .id
12521282 return Body (body_id , response .get ("name" ), parent , tb )
12531283
1284+ def get_raw_tessellation ( # noqa: D102
1285+ self ,
1286+ tess_options : TessellationOptions | None = None ,
1287+ reset_cache : bool = False ,
1288+ ) -> dict :
1289+ if not self .is_alive :
1290+ return {}
1291+
1292+ # If the server does not support tessellation options, ignore them
1293+ if tess_options is not None and self ._grpc_client .backend_version < (25 , 2 , 0 ):
1294+ self ._grpc_client .log .warning (
1295+ "Tessellation options are not supported by server"
1296+ f" version { self ._grpc_client .backend_version } . Ignoring options."
1297+ )
1298+ tess_options = None
1299+
1300+ self ._grpc_client .log .debug (f"Requesting tessellation for body { self .id } ." )
1301+
1302+ # cache tessellation
1303+ if not self ._raw_tessellation or reset_cache :
1304+ if tess_options is not None :
1305+ response = self ._grpc_client .services .bodies .get_tesellation_with_options (
1306+ id = self .id , options = tess_options , raw_data = True
1307+ )
1308+ else :
1309+ response = self ._grpc_client .services .bodies .get_tesellation (
1310+ id = self .id , backend_version = self ._grpc_client .backend_version , raw_data = True
1311+ )
1312+
1313+ self ._raw_tessellation = response .get ("tessellation" )
1314+
1315+ return self ._raw_tessellation
1316+
12541317 @graphics_required
12551318 def tessellate ( # noqa: D102
12561319 self ,
12571320 merge : bool = False ,
12581321 transform : Matrix44 = IDENTITY_MATRIX44 ,
12591322 tess_options : TessellationOptions | None = None ,
1323+ reset_cache : bool = False ,
12601324 ) -> Union ["PolyData" , "MultiBlock" ]:
12611325 # lazy import here to improve initial module load time
12621326 import pyvista as pv
@@ -1275,16 +1339,14 @@ def tessellate( # noqa: D102
12751339 self ._grpc_client .log .debug (f"Requesting tessellation for body { self .id } ." )
12761340
12771341 # cache tessellation
1278- if not self ._tessellation :
1342+ if not self ._tessellation or reset_cache :
12791343 if tess_options is not None :
12801344 response = self ._grpc_client .services .bodies .get_tesellation_with_options (
1281- id = self .id ,
1282- options = tess_options ,
1345+ id = self .id , options = tess_options , raw_data = False
12831346 )
12841347 else :
12851348 response = self ._grpc_client .services .bodies .get_tesellation (
1286- id = self .id ,
1287- backend_version = self ._grpc_client .backend_version ,
1349+ id = self .id , backend_version = self ._grpc_client .backend_version , raw_data = False
12881350 )
12891351
12901352 self ._tessellation = response .get ("tessellation" )
@@ -1441,6 +1503,7 @@ def wrapper(self: "Body", *args, **kwargs):
14411503 def _reset_tessellation_cache (self ): # noqa: N805
14421504 """Reset the cached tessellation for a body."""
14431505 self ._template ._tessellation = None
1506+ self ._template ._raw_tessellation = None
14441507 # if this reference is stale, reset the real cache in the part
14451508 # this gets the matching id master body in the part
14461509 master_in_part = next (
@@ -1453,6 +1516,7 @@ def _reset_tessellation_cache(self): # noqa: N805
14531516 )
14541517 if master_in_part is not None :
14551518 master_in_part ._tessellation = None
1519+ master_in_part ._raw_tessellation = None
14561520
14571521 @property
14581522 def id (self ) -> str : # noqa: D102
@@ -1786,12 +1850,23 @@ def get_collision(self, body: "Body") -> CollisionType: # noqa: D102
17861850 def copy (self , parent : "Component" , name : str = None ) -> "Body" : # noqa: D102
17871851 return self ._template .copy (parent , name )
17881852
1853+ @ensure_design_is_active
1854+ def get_raw_tessellation ( # noqa: D102
1855+ self ,
1856+ tess_options : TessellationOptions | None = None ,
1857+ reset_cache : bool = False ,
1858+ ) -> dict :
1859+ return self ._template .get_raw_tessellation (tess_options , reset_cache )
1860+
17891861 @ensure_design_is_active
17901862 def tessellate ( # noqa: D102
1791- self , merge : bool = False , tess_options : TessellationOptions | None = None
1863+ self ,
1864+ merge : bool = False ,
1865+ tess_options : TessellationOptions | None = None ,
1866+ reset_cache : bool = False ,
17921867 ) -> Union ["PolyData" , "MultiBlock" ]:
17931868 return self ._template .tessellate (
1794- merge , self .parent_component .get_world_transform (), tess_options
1869+ merge , self .parent_component .get_world_transform (), tess_options , reset_cache
17951870 )
17961871
17971872 @ensure_design_is_active
0 commit comments