9.7 Integrating Visualize with Parasolid and HOOPS Exchange

Exchange-Parasolid Sprocket

9.7.1 Prerequisites
9.7.2 File Loading
9.7.3 Importing Multiple Models
9.7.4 Accessing Parasolid and Exchange Data
9.7.5 Updating the Model After Parasolid Modeling Operations
9.7.6 Creating Geometry in Memory Using Parasolid and Adding it to the Scene
9.7.7 Limitations
9.7.8 Miscellaneous
9.7.9 Table: Synchronizing Visualize and the Native Parasolid API

Designed to facilitate CAD conversion and geometric modeling in a single interface, the Exchange-Parasolid Sprocket is useful for developers who wish to load files using HOOPS Exchange and then interact with the geometry in the scene using the Parasolid modeling kernel.

The Exchange-Parasolid Sprocket is available on Windows, Linux and MacOS platforms, and you must have a license for both Exchange and Parasolid in order to use the sprocket.

Visualize, Exchange, and Parasolid interact with each other in the following manner:

  1. Visualize displays the model on screen, builds a Component structure, provides the user access to Parasolid and Exchange data, and keeps the Parasolid data, Exchange data, Component structure, and visual rendition synchronized.
  2. Exchange loads and translates the model and manages Views, PMI, and the assembly structure.
  3. Parasolid tessellates the model and performs modeling operations.

Throughout this guide, we sometimes refer to "PRC" – this refers to the intermediate CAD data format used by Exchange during file conversion. In Visualize, PRC also forms the basis of the Component structure used in the Exchange-Parasolid Sprocket.

9.7.1 Prerequisites

To satisfy the prerequisites, users should complete the prerequisite steps for both the Exchange and the Parasolid sprockets, which are found in section 9.5 and section 9.6 of the Programming Guide.

9.7.2 File Loading and Translation

When using the Exchange-Parasolid Sprocket, the contents of each Exchange Representation Item is translated to Parasolid. The translation process takes place automatically as part of the import and is configurable by the user. Since the geometry being inserted into the scene will be tessellated by Parasolid, Parasolid tessellation settings also need to be provided.

Since Visualize's Parasolid integration supports convergent modeling, even files without B-rep can be loaded and translated to Parasolid, if the format is supported by Exchange.

Here's a basic example of loading and translating a file with default options:

[snippet 9.7.1.a]
// load and translate a file using the default options
try
{
ExchangeParasolid::ImportNotifier notifier = HPS::ExchangeParasolid::File::Import(
filename, //the file to import
Exchange::ImportOptionsKit::GetDefault(), //options for reading the file with Exchange
Exchange::TranslationOptionsKit::GetDefault(), //options for translating the file to Parasolid
Parasolid::FacetTessellationKit::GetDefault(), //options for Parasolid facet tessellation
Parasolid::LineTessellationKit::GetDefault()); //options for Parasolid line tessellation
notifier.Wait();
HPS::CADModel modelFile = notifier.GetCADModel();
// get the View and attach it to the Canvas
HPS::View myView = modelFile.ActivateDefaultCapture();
myCanvas.AttachViewAsLayout(myView);
// alternatively, if you already have a View object, you can simply
// get the Model and attach it directly:
HPS::Model model = modelFile.GetModel();
myView.AttachModel(model);
}
catch (const HPS::IOException& ioe)
{
// handle error
}
// load and translate a file using the default options
try
{
ExchangeParasolid.ImportNotifier notifier = HPS.ExchangeParasolid.File.Import(
filename, //the file to import
Exchange.ImportOptionsKit.GetDefault(), //options for reading the file with Exchange
Exchange.TranslationOptionsKit.GetDefault(), //options for translating the file to Parasolid
Parasolid.FacetTessellationKit.GetDefault(), //options for Parasolid facet tessellation
Parasolid.LineTessellationKit.GetDefault()); //options for Parasolid line tessellation
notifier.Wait();
HPS.CADModel modelFile = notifier.GetCADModel();
// get the View and attach it to the Canvas
HPS.View myView = modelFile.ActivateDefaultCapture();
myCanvas.AttachViewAsLayout(myView);
// alternatively, if you already have a View object, you can simply
// get the Model and attach it directly:
HPS.Model model = modelFile.GetModel();
myView.AttachModel(model);
}
catch (HPS.IOException)
{
// handle error
}

The usual caveats described in the other Sprocket guides still apply here:

  • The user can call HPS::IONotifier::Wait() on the notifier to wait until after the import has completed. The import happens on a separate thread, and it is not guaranteed to be completed until after HPS::IONotifier::Wait() returns or until the HPS::IONotifier::Status() call returns something other than HPS::Event::Status::InProgress.
  • The import can be canceled by calling HPS::IONotifier::Cancel() on the notifier.
  • The import status can be queried while the import is in progress.

Options for File Loading

The Options for File Loading section in the Exchange Sprocket programming guide applies to the Exchange-Parasolid Sprocket, too. As the sample above shows there are several options kit which need to be passed to the HPS::ExchangeParasolid::File::Import() function call:

  1. An HPS::Exchange::ImportOptionsKit. This kit determines how the file is read by Exchange. The options specified in the Exchange Sprocket sections still apply (for example, calling SetPMI(false) on this kit will result in PMIs not being imported).
  2. An HPS::Exchange::TranslationOptionsKit. This kit determines how the file is translated into Parasolid, and optionally performs some functions such as sewing and healing. It's worth noting that one of the options allows users to use multiple processes to translate the data, speeding up the process. See the function HPS::Exchange::TranslationOptionsKit::SetMultiProcessCount for more information.
  3. A HPS::Parasolid::FacetTessellationKit and a HPS::Parasolid::LineTessellationKit. These kits determine how Parasolid will tessellate facets and lines respectively. The description of these kits is the same as the one found in the Import Options section of the Parasolid programming guide. It is worth noting that if you don't need to fine tune all the tessellation options, you can just call the HPS::Parasolid::FacetTessellationKit::SetTessellationLevel() function from the HPS::Parasolid::FacetTessellationKit, and use the default HPS::Parasolid::LineTessellationKit. This way the two are guaranteed to be compatible.
    (When these kits are not compatible, it can result in lines that do not exactly lie on faces or lines that are tessellated more coarsely than the faces they belong to.)

9.7.3 Importing Multiple Models

Multiple models can be imported into the same scene using the same functionality described in Importing multiple models in the Exchange Programming Guide.

Note: When importing multiple models, the Parasolid entities from all models in the same scene are placed in the same Parasolid partition.

Component Structure of Exchange-Parasolid Files

  • The top of the component structure for Exchange-Parasolid files will be an HPS::Exchange::CADModel.
  • From there the component structure will continue as expected for an Exchange file: the CADModel will contain Product Occurrence components, which will in turn contain either other Product Occurrence components or a Part Definition component. Part Definition components will contain Representation Item components.
  • When importing a model through Exchange-Parasolid, components under the Representation Item level will all be Parasolid components. For example, Representation Item components will contain Parasolid Topological Body components.
  • The component structure will still contain Views and Filters if the original CAD file contained them.

Sample Component Structure of an Exchange-Parasolid File

The following graphic demonstrates a hypothetical Component structure for an Exchange-Parasolid file:

[figure 9.7.3a] A sample of a Component structure in a hypothetical CAD model imported into the Exchange-Parasolid Sprocket.

The most important aspect of this structure is that the Exchange representation item will always contain a single Parasolid topological body (and not a Parasolid assembly or other data). In the next section, we'll look at a sample that shows how to use the function HPS::Component::GetSubcomponents() to retrieve these elements.

9.7.4 Accessing Parasolid and Exchange Data

By using the the Visualize Component structure, it's possible to gain access to Exchange or Parasolid entities directly. You can then operate on these entities using the native Exchange and Parasolid APIs.

The first step in this process is to find the component we are interested in. Each component can query its parent and children component through its HPS::Component::GetOwners() and HPS::Component::GetSubcomponents() functions. It can also query all its descendants of a particular type by calling HPS::Component::GetAllSubcomponents().

The type of a component can be found using the HPS::Component::GetComponentType() function, and the result can be checked against the HPS::Component::ComponentType enumeration. The HPS::Component class also contains the HPS::Component::HasComponentType() function, which allows us to check against a bitmask. For example, the function can be used to determine whether a component is an Exchange or a Parasolid component, or whether the component represents any of the topological items supported by Exchange or Parasolid.

Once an interesting component has been located, we can access its underlying data. For Exchange components, we create an HPS::Exchange::Component from the Component object, and call HPS::Exchange::Component::GetExchangeEntity(). For Parasolid components, we create an HPS::Parasolid::Component from the component object, and call HPS::Parasolid::Component::GetParasolidEntity().

[snippet 9.7.4.a]
// Query the CADModel for its children components
ComponentArray subcomponents = cad_model.GetSubcomponents();
if (!subcomponents.empty())
{
// Check that the component type of the first child component is Exchange Product Occurrence
Component::ComponentType component_type = subcomponents[0].GetComponentType();
if (component_type == Component::ComponentType::ExchangeProductOccurrence)
{
// Since we know this component is an Exchange component, we can cast it to
// an Exchange::Component object and access its data
Exchange::Component exchange_component(subcomponents[0]);
A3DEntity * entity = exchange_component.GetExchangeEntity();
// We can now use the Exchange native API to interact with it
A3DAsmProductOccurrenceData pocc_data;
A3D_INITIALIZE_DATA(A3DAsmProductOccurrenceData, pocc_data);
A3DAsmProductOccurrenceGet(entity, &pocc_data);
}
}
// Now let's look for all subcomponents of the CADModel which are Parasolid Topological Faces
subcomponents = cad_model.GetAllSubcomponents(Component::ComponentType::ParasolidTopoFace);
if (!subcomponents.empty())
{
// Check that the component type of the first Parasolid Topo Face we found is indeed
// a Parasolid component by checking its type mask
if (subcomponents[0].HasComponentType(Component::ComponentType::ParasolidComponentMask))
{
// Since we know this component is a Parasolid component, we can cast it to
// a Parasolid::Component object and access its data
Parasolid::Component parasolid_component(subcomponents[0]);
PK_ENTITY_t entity = parasolid_component.GetParasolidEntity();
// We can now use the Parasolid native API to interact with it
PK_SURF_t surface;
PK_FACE_ask_surf(entity, &surface);
}
}
// Query the CADModel for its children components
HPS.Component[] subcomponents = cad_model.GetSubcomponents();
if (!subcomponents.empty())
{
// Check that the component type of the first child component is Exchange Product Occurrence
Component.ComponentType component_type = subcomponents[0].GetComponentType();
if (component_type == Component.ComponentType.ExchangeProductOccurrence)
{
// Since we know this component is an Exchange component, we can set it to
// an Exchange.Component object and access its data
Exchange.Component exchange_component = new Exchange.Component(subcomponents[0]);
IntPtr entity = exchange_component.GetExchangeEntity();
// We can now use the Exchange native API to interact with it
HPS.Component pocc_data = cad_model.GetSubcomponents()[0];
}
}
// Now let's look for all subcomponents of the CADModel which are Parasolid Topological Faces
subcomponents = cad_model.GetAllSubcomponents(Component.ComponentType.ParasolidTopoFace);
if (!subcomponents.empty())
{
// Check that the component type of the first Parasolid Topo Face we found is indeed
// a Parasolid component by checking its type mask
if (subcomponents[0].HasComponentType(Component.ComponentType.ParasolidComponentMask))
{
// Since we know this component is a Parasolid component, we can cast it to
// a Parasolid::Component object and access its data
Parasolid.Component parasolid_component = new Parasolid.Component(subcomponents[0]);
PK.ENTITY_t entity = parasolid_component.GetParasolidEntity();
// We can now use the Parasolid native API to interact with it
PK.SURF_t surface;
PK.FACE.ask_surf(entity, &surface);
}
}

9.7.5 Updating the Model After Parasolid Modeling Operations

After a modelling operation takes place in Parasolid, Visualize will have to be notified about which Parasolid bodies have changed, so that they can be retessellated and have their component structure updated to reflect their new status.

This can be done through the HPS::ExchangeParasolid::File::Tessellate() function or the HPS::Parasolid::Component::Tessellate() function.

Note: Currently the HPS::Parasolid::Component::Tessellate() and HPS::ExchangeParasolid::File::Tessellate() functions update Visualize to reflect the changes made in Parasolid. This function does NOT however update the PRC representation of the model held by Exchange. Therefore, after calling either of these Tessellate functions, in order to export an accurate representation of the model, use the Parasolid API (e.g., PK_PART_transmit) and reload the model into Visualize from disk.

The following code sample demonstrates how to add a fillet to an edge of a model and retessellate it using the native Parasolid API:

[snippet 9.7.5.a]
// Load a model, fillet an edge using parasolid, and retessellate it to see the result
// Load a model and translate it to Parasolid
Exchange::ImportOptionsKit exchange_import = Exchange::ImportOptionsKit::GetDefault();
exchange_import.SetBRepMode(Exchange::BRepMode::BRepAndTessellation);
Exchange::TranslationOptionsKit translation_options = Exchange::TranslationOptionsKit::GetDefault();
ExchangeParasolid::ImportNotifier notifier = ExchangeParasolid::File::Import(
filename, exchange_import, translation_options,
Parasolid::FacetTessellationKit::GetDefault(), Parasolid::LineTessellationKit::GetDefault());
notifier.Wait();
if (notifier.Status() != IOResult::Success)
{
// handle error
}
View view = notifier.GetCADModel().ActivateDefaultCapture();
myCanvas.AttachViewAsLayout(view);
//find the edges, and pick the first one
CADModel cad_model = notifier.GetCADModel();
ComponentArray edge_components = cad_model.GetAllSubcomponents(Component::ComponentType::ParasolidTopoEdge);
if (edge_components.empty())
{
// handle the error
}
Parasolid::Component para_edge_component(edge_components[0]);
PK_EDGE_t edge_entity = para_edge_component.GetParasolidEntity();
// find the body which owns this edge, by traversing the parents of the edge, until when we find a body
HPS::Component owner = para_edge_component.GetOwners()[0];
while (owner.GetComponentType() != HPS::Component::ComponentType::ParasolidTopoBody)
owner = owner.GetOwners()[0];
// set the blends on the edge
int number_of_edges = 0;
PK_EDGE_t * edges = nullptr;
PK_EDGE_set_blend_constant_o_t blend_options;
PK_EDGE_set_blend_constant_o_m(blend_options);
PK_ERROR_t error = PK_EDGE_set_blend_constant(1, &edge_entity, 0.005, &blend_options, &number_of_edges, &edges);
if (error != PK_ERROR_no_errors)
{
//handle the error
}
// commit the blends on the body which owns this edge
int number_of_blend_faces = 0;
PK_FACE_t * created_blend_faces = nullptr;
PK_FACE_array_t * underlying_topology = nullptr;
int * replaced_topologies = nullptr;
PK_blend_fault_t status = PK_blend_fault_no_fault_c;
PK_EDGE_t faulty_edge = PK_ENTITY_null;
PK_ENTITY_t topology_associated_with_fault = PK_ENTITY_null;
PK_BODY_fix_blends_o_t fix_blend_options;
PK_BODY_fix_blends_o_m(fix_blend_options);
HPS::Parasolid::Component para_component(owner);
error = PK_BODY_fix_blends(para_component.GetParasolidEntity(), &fix_blend_options, &number_of_blend_faces, &created_blend_faces, &underlying_topology, &replaced_topologies, &status, &faulty_edge, &topology_associated_with_fault);
if (error != PK_ERROR_no_errors || (status != PK_blend_fault_no_fault_c && status != PK_blend_fault_repaired_c))
{
//handle the error
}
//retessellate the body to update the component structure and see the result on screen
para_component.Tessellate(facet_tessellation, HPS::Parasolid::LineTessellationKit::GetDefault());
myCanvas.Update();
//Load a model, fillet an edge using parasolid, and retessellate it to see the result
//Load a model and translate it to Parasolid
Exchange.ImportOptionsKit exchange_import = Exchange.ImportOptionsKit.GetDefault();
exchange_import.SetBRepMode(Exchange.BRepMode.BRepAndTessellation);
Exchange.TranslationOptionsKit translation_options = Exchange.TranslationOptionsKit.GetDefault();
ExchangeParasolid.ImportNotifier notifier = ExchangeParasolid.File.Import(
filename, exchange_import, translation_options,
Parasolid.FacetTessellationKit.GetDefault(), Parasolid.LineTessellationKit.GetDefault());
notifier.Wait();
if (notifier.Status() != IOResult.Success)
{
//handle error
}
View myView = notifier.GetCADModel().ActivateDefaultCapture();
myCanvas.AttachViewAsLayout(myView);
HPS.CADModel modelFile = notifier.GetCADModel();
HPS.Model model = modelFile.GetModel();
myView.AttachModel(model);
//find the edges, and pick the first one
CADModel cad_model = notifier.GetCADModel();
HPS.Component[] edge_components = cad_model.GetAllSubcomponents(Component.ComponentType.ParasolidTopoEdge);
if (edge_components.empty())
{
//handle the error
}
Parasolid.Component para_edge_component = new Parasolid.Component(edge_components[0]);
PK.EDGE_t[] edge_entity = new PK.EDGE_t[1];
edge_entity[0] = para_edge_component.GetParasolidEntity();
//find the body which owns this edge, by traversing the parents of the edge, until when we find a body
HPS.Component owner = para_edge_component.GetOwners()[0];
while (owner.GetComponentType() != HPS.Component.ComponentType.ParasolidTopoBody)
owner = owner.GetOwners()[0];
//set the blends on the edge
int number_of_edges = 0;
PK.EDGE_t* edges = null;
PK.EDGE.set_blend_constant_o_t blend_options = new PK.EDGE.set_blend_constant_o_t(true);
PK.ERROR.code_t error = PK.EDGE.set_blend_constant(1, edge_entity, 0.005, &blend_options, &number_of_edges, &edges);
if (error != PK.ERROR.code_t.no_errors)
{
//handle the error
}
//commit the blends on the body which owns this edge
int number_of_blend_faces = 0;
PK.FACE_t* created_blend_faces = null;
PK.FACE.array_t* underlying_topology = null;
int* replaced_topologies = null;
PK.blend_fault_t status = PK.blend_fault_t.no_fault_c;
PK.EDGE_t faulty_edge = PK.EDGE_t.@null;
PK.ENTITY_t topology_associated_with_fault = PK.EDGE_t.@null;
PK.BODY.fix_blends_o_v fix_blend_options = new PK.BODY.fix_blends_o_v(true);
HPS.Parasolid.Component para_component = new HPS.Parasolid.Component(owner);
error = PK.BODY.fix_blends(para_component.GetParasolidEntity(), &fix_blend_options, &number_of_blend_faces, &created_blend_faces, &underlying_topology, &replaced_topologies, &status, &faulty_edge, &topology_associated_with_fault);
if (error != PK.ERROR.code_t.no_errors || (status != PK.blend_fault_t.no_fault_c && status != PK.blend_fault_t.repaired_c))
{
//handle the error
}
//retessellate the body to update the component structure and see the result on screen
HPS.Parasolid.FacetTessellationKit facet_tessellation = HPS.Parasolid.FacetTessellationKit.GetDefault();
para_component.Tessellate(facet_tessellation, HPS.Parasolid.LineTessellationKit.GetDefault());
myCanvas.Update();

Here is the output when applying this code to a simple cube; the edge on the left is where the fillet has been applied:

[figure 9.7.5.a] Cube modified with native Parasolid API and retessellated.

9.7.6 Creating Geometry in Memory Using Parasolid and Adding it to the Scene

Note: This is the Exchange-Parasolid equivalent of the Entity Creation section of the Parasolid programming guide.

Sometimes you may want to create a model from scratch instead of loading one, or other times you may want to create some geometry from scratch and then add it to an existing model you've already loaded. In either case, you'll need a way to take what you've created in memory using Parasolid and add it to the scene.

The HPS::ExchangeParasolid::File::AddEntity() function allows you to not only update the Visualize component structure but also to create new PRC data to update the Exchange structure. (Please see the API Reference for details about the limitations of the HPS::ExchangeParasolid::File::AddEntity() function.)

Below is a sample of how to add a new Parasolid body to the model PartWithPMI.CATPart, located in the samples/data directory. Here's the model before adding the new body:

[figure 9.7.6.a] Model before addition of new Parasolid body.

This code snippet demonstrates loading a model via Exchange, creating a Parasolid body in memory (a red cube), and using the HPS::ExchangeParasolid::File::AddEntity() function to add the Parasolid body to the Exchange CAD model:

[snippet 9.7.6.a]
/*** create a parasolid body and add it at the top level of an existing Exchange model ***/
Exchange::ImportOptionsKit import_kit = Exchange::ImportOptionsKit::GetDefault();
import_kit.SetPMI(false); // omitting PMI for better visibility of new body
Exchange::ImportNotifier notifier = Exchange::File::Import(my_cad_file, import_kit);
notifier.Wait();
HPS::CADModel cad_model = notifier.GetCADModel();
Exchange::CADModel exchange_cad_model(cad_model);
View view1 = cad_model.ActivateDefaultCapture();
// create a Parasolid body (a cube)
PK_BODY_t solid_body = PK_ENTITY_null;
PK_BODY_create_solid_block(0.05f, 0.05f, 0.05f, nullptr, &solid_body); // parasolid dimensions in meters
//make the cube red
PK_ATTDEF_t system_color;
PK_ATTDEF_find("SDL/TYSA_COLOUR_2", &system_color);
PK_ATTRIB_t color_attribute;
PK_ATTRIB_create_empty(solid_body, system_color, &color_attribute);
double color[] = { 1, 0, 0 };
PK_ATTRIB_set_doubles(color_attribute, 0, 3, color);
// apply a translation matrix to the cube we're adding
MatrixKit translation;
translation.Translate(100.0f, 0.0f, 50.0f);
// add cube to existing CAD Model
HPS::Parasolid::Component added_component = ExchangeParasolid::File::AddEntity(exchange_cad_model, solid_body, translation);
// retrieve the Parasolid entity for inspection
PK_ENTITY_t entity = added_component.GetParasolidEntity();
PK_CLASS_t entity_type;
PK_ENTITY_ask_class(entity, &entity_type);
/*** create a parasolid body and add it at the top level of an existing Exchange model ***/
Exchange.ImportOptionsKit import_kit = Exchange.ImportOptionsKit.GetDefault();
import_kit.SetPMI(false); // omitting PMI for better visibility of new body
Exchange.ImportNotifier notifier = Exchange.File.Import(my_cad_file, import_kit);
notifier.Wait();
HPS.CADModel cad_model = notifier.GetCADModel();
Exchange.CADModel exchange_cad_model = new Exchange.CADModel(cad_model);
View view1 = cad_model.ActivateDefaultCapture();
// create a Parasolid body (a cube)
PK.BODY_t solid_body = PK.ENTITY_t.@null;
PK.BODY.create_solid_block(0.05f, 0.05f, 0.05f, null, &solid_body); // parasolid dimensions in meters
//make the cube red
PK.ATTDEF_t system_color;
PK.ERROR.code_t error = PK.ATTDEF.find("SDL/TYSA_COLOUR_2", &system_color);
PK.ATTRIB_t color_attribute;
error = PK.ATTRIB.create_empty(solid_body, system_color, &color_attribute);
double [] color = { 1, 0, 0 };
error = PK.ATTRIB.set_doubles(color_attribute, 0, 3, color);
// apply a translation matrix to the cube we're adding
MatrixKit translation = new MatrixKit();
translation.Translate(100.0f, 0.0f, 50.0f);
// add cube to existing CAD Model
HPS.Parasolid.Component added_component = ExchangeParasolid.File.AddEntity(exchange_cad_model, solid_body, translation);
// retrieve the Parasolid entity for inspection
PK.ENTITY_t entity = added_component.GetParasolidEntity();
PK.CLASS_t entity_type;
PK.ENTITY.ask_class(entity, &entity_type);

And here's the final output, with the red cube inserted into the CAD model:

[figure 9.7.6.b] Model after addition of new Parasolid body (in red).

9.7.7 Limitations

  • When importing files that do not contain B-rep information, colors will not be imported.
  • Currently the HPS::Parasolid::Component::Tessellate() and HPS::ExchangeParasolid::File::Tessellate() functions update Visualize to reflect the changes made in Parasolid. This function does NOT however update the PRC representation of the model held by Exchange. Therefore, after calling either of these Tessellate functions, in order to export an accurate representation of the model, use the Parasolid API (e.g., PK_PART_transmit) and reload the model into Visualize from disk.

9.7.8 Miscellaneous

9.7.9 Synchronizing Visualize and the Native Parasolid API

This chart shows which Visualize functions must be called after a specific native Parasolid operation:

Native Parasolid Operation Related Visualize Call Updates PRC?
Adds new Body to the Parasolid partition HPS::ExchangeParasolid::File::AddEntity() YES
Modifies existing Body HPS::ExchangeParasolid::File::Tessellate() NO
Deletes Body HPS::Component::Delete() YES