InterOp:Connect/ACIS/Assembly Representation
From DocR23
Monolithic ACIS assembly is supported. Monolithic refers to a single file holding all the data required to define the assembly. Refer to ACIS Assembly for more information.
InterOp ACIS Writer supports the following file formats and versions:
| File Format | File Extension | Version Supported |
|---|---|---|
| ASAT | .asat | ACIS R19 onwards |
| ASAB | .asab | ACIS R19 onwards |
The following options are required for reading/writing monolithic ASAT files
- Representation=Assembly
- Flatten=False
Contents |
Required DLLs
To support translation of ACIS assembly data, ensure that the following libraries (DLLs) are available in the InterOp and ACIS base directories:
InterOp:
- SPAXACISASSEMBLYIMPORTER.DLL
- SPAXACISBASE.DLL
- SPAXACISKERNEL.DLL
- SPAXASSEMBLYREP.DLL
- SPAXBASE.DLL
- SPAXINTEROP.DLL
ACIS:
- SPAACIS.DLL
Refer to Translating from ACIS Assembly Models for an AcisAsmExport sample.
Refer to Translating to ACIS Assembly Models for an AcisAsmImport sample.
Assembly PMI Annotations
InterOp supports the import of PMI annotations created at the assembly level in source assembly files. It is supported only in ASAT or ASAB route (and not in XML E-BOM and flatten route). This uses the same ACIS PMI data structures as in Part PMIs. However, instead of ENTITY as owner of PMI, we have component_entity_handle as owner of PMI. component_entity_handle is a part entity defined in context of an assembly model. Refer Handles in Assembly Modeling and the component_entity_handle class documentation for more details on its use.
Also note that assembly PMI annotations attached onto workplanes or axis systems (local coordinate systems) of parts are not supported. Set the option Representation to Assembly+PMI to import assembly PMI annotations.
Assembly Part Level PMI Annotations
Part level PMI Annotations are supported only in an XML E-BOM route. PMI Annotations in the part files of an assembly are translated to the corresponding ACIS SAT files created for each instance in an E-BOM route. However, in a Flatten route, part-level PMI annotations of an assembly are not translated.
Assembly Cut Features to ACIS
InterOp supports translation of the assembly cut features from Pro/E. Translation of assembly cut features is implemented in two ways:
- Assembly Route to XML E-BOM (output as XML+SAT)
- Flatten Route to ACIS (output as list of entities)
The above methods are explained in detail below in XML Route (EBOM) and Flatten Route.
XML Route (EBOM)
The XML route involves creating a separate SAT file for each assembly cut features.
The main features of translating an assembly cut features using an XML route are:
- A separate SAT file is created for each assembly cut features.
- Each SAT file contains tool body (BODY) and hole group (SPAGROUP) information if the cut feature is a Hole or Pattern feature.
- An additional node, named "SPACutsubassy name" is added at each corresponding subassembly level in the XML file for a cut feature in the source Pro/E subassembly file.
- In addition to the positioning and reference link, the SPACut# node contains a list of affected assembly instances under a new tag AffectedChildren.
The following sample code shows implementation of XML route translation for assembly cut features:
<Child Name="SPACut1_SubName" Identifier="Id_SPACut1_SubName"> <Position> <V1>-1.000000000000000</V1> ... <T3>700.080000000000040</T3> </Position> <RefLink Id="RefIdSPACut1_SubName" /> <AffectedChildren> <Child Id="pem_nut_10-1"/> <Child Id="Instance 02"/> <Child Id="Instance 05"/> </AffectedChildren> </Child>
Flatten Route
The flatten route method involves translating the assembly cut features from Pro/E as a SPACOLLECTION entity in ACIS. Each SPACOLLECTION entity has a generic attribute (type ATTRIB_GEN_INTEGER) attached to it. The value of this attribute indicates whether the SPACOLLECTION entity is created from an assembly cut features or not. The name of the attribute attached to a SPACOLLECTION entity is ATTRIB_XACIS_GROUP_TYPE. The value of this attribute is 4 for a SPACOLLECTION entity created from an assembly cut features. The following diagram shows translation of a Pro/E file containing three assembly cut features to ACIS:
The members of a SPACOLLECTION entity are:
- A tool BODY with attached SPAATTRIB_ASSY_CUT_TOOL attribute (type ATTRIB_GEN_INTEGER). The value of this attribute is true, which indicates that the body is a tool body.
- Bodies that will be intersected for assembly cut.
- SPAGROUP representing a hole feature/pattern if the cut feature represents a hole/pattern feature and the Manufacturing representation is set.
The following sample application can be used for assembly-level cut operations.
| Sample Application for doing Assembly level cut operations |
|---|
// ACIS
// ACIS headers
#include "kernapi.hxx"
#include "spl_api.hxx"
#include "cstrapi.hxx"
#include "intrapi.hxx"
#include "boolapi.hxx"
#include "operapi.hxx"
#include "eulerapi.hxx"
#include "ga_api.hxx"
#include "fileinfo.hxx"
#include "lists.hxx"
#include "alltop.hxx"
#include "savres.hxx"
#include "fileinfo.hxx"
#include "lists.hxx"
#include "kernapi.hxx"
#include "acistype.hxx"
#include "ga_api.hxx"
#include "at_str.hxx"
#include "collection.hxx"
#include "group.hxx"
#include "at_int.hxx"
// System
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(XLINUX) || defined(XSOLARIS) || defined(mac)
#include <wchar.h>
#endif
//-----------------------------------------------------------------------------
//Check InterOp API outcome and prints the error message
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
//Start ACIS modeler and initialize required ACIS modules
//-----------------------------------------------------------------------------
logical InitializeAcis ()
{
outcome res;
res = api_start_modeller(0);
if( TRUE == res.ok())
{
res = api_initialize_kernel();
res = api_initialize_spline();
res = api_initialize_intersectors();
res = api_initialize_euler_ops();
res = api_initialize_constructors();
res = api_initialize_generic_attributes();
res = api_initialize_booleans();
// set default FileInfo
FileInfo fileInfo;
fileInfo.set_product_id("ACIS (c) SPATIAL");
fileInfo.set_units(1); //model units are assumed to be millimeters
res = api_set_file_info( FileId | FileUnits ,fileInfo);
}
return res.ok();
}
//-----------------------------------------------------------------------------
//Terminate ACIS modules and stop the ACIS modeler
//-----------------------------------------------------------------------------
logical TerminateAcis ()
{
outcome res;
res = api_terminate_booleans();
res = api_terminate_generic_attributes();
res = api_terminate_constructors();
res = api_terminate_euler_ops();
res = api_terminate_intersectors();
res = api_terminate_spline();
res = api_terminate_kernel();
api_stop_modeller();
return res.ok();
}
logical RestoreSatFile( const char *satFileName, ENTITY_LIST &elist)
{
logical res = FALSE;
size_t length = strlen( satFileName);
logical textFile = TRUE;
if( satFileName[ length-1] == 'b')
textFile = FALSE;
FILE *fp = fopen( satFileName, textFile ? "rt" : "rb");
outcome result;
if( fp)
{
result = api_restore_entity_list( fp, textFile, elist);
fclose( fp);
fp = NULL;
res = result.ok() ? TRUE : FALSE;
}
if( TRUE == res)
printf("\nFile %s successfully read.\n", satFileName);
else
printf("\n*** ERROR ***\tCould not read SAT file: %s\n", satFileName);
return res;
}
//Create a new ACIS SAT file from the supplied ENTITY_LIST
//-----------------------------------------------------------------------------
logical SaveSatFile (ENTITY_LIST elist, const char *fileName)
{
outcome res;
FILE *fp = fopen ( fileName, "w");
if( fp == NULL)
printf("\tUnable to open file %s for output.\n", fileName);
else
{
res= api_save_entity_list ( fp, TRUE, elist);
fclose ( fp);
fp = NULL;
if( TRUE == res.ok())
printf("\nFile %s successfully written.\n", fileName);
else
printf("\n*** ERROR ***\tUnable to save SAT file %s.\n", fileName);
}
return res.ok();
}
void printHelp()
{
printf("Usage : ProcessAssemblyCutFeature.exe -i file -o file\n");
printf("ProcessAssemblyCutFeature.exe :\n");
printf("-i : Input SAT file with assembly cut feature information\n");
printf("-o : Output SAT file( after processing cut features)\n");
}
char pszInputFile[256]={'\0'};
char pszOutputFile[256]={'\0'};
// Input argument parser
int getArgs(int argc, char *argv[])
{
int err=0;
if(argc <= 1)
{
printHelp();
err = 1;
return err;
}
int i=1;
while (i<argc)
{
if (strcmp("-i", argv[i])==0)
{
if (++i<argc)
{
strncpy(pszInputFile, argv[i], 256);
}
else
{
printHelp();
err=1;
}
}
else if (strcmp("-o", argv[i])==0)
{
if (++i<argc)
{
strncpy(pszOutputFile, argv[i], 256);
}
else
{
printHelp();
err=1;
}
}
i++;
}
return err;
}
/*!
Returns whether input entity is a cut feature tool
*/
logical IsCutTool( ENTITY * ipEntity)
{
logical retVal = FALSE;
if( NULL == ipEntity )
return retVal;
ATTRIB_GEN_INTEGER* pCutToolAttrib = NULL;
outcome result = api_find_named_attribute( ipEntity, "SPAATTRIB_ASSY_CUT_TOOL", reinterpret_cast< ATTRIB_GEN_NAME*&>( pCutToolAttrib) );
if( pCutToolAttrib && ( result.ok() == TRUE))
{
int type = pCutToolAttrib->value();
retVal = TRUE;
}
return retVal;
}
/*!
Returns whether input entity is a cut feature
*/
logical IsCutFeature( ENTITY * ipEntity)
{
logical retVal = FALSE;
if( NULL == ipEntity || FALSE == is_SPACOLLECTION( ipEntity))
return retVal;
ATTRIB_GEN_INTEGER* pGrpType = NULL;
outcome result = api_find_named_attribute( ipEntity, "ATTRIB_XACIS_GROUP_TYPE", reinterpret_cast< ATTRIB_GEN_NAME*&>( pGrpType) );
if( pGrpType && ( result.ok() == TRUE))
{
int type = pGrpType->value();
if( 4 == type)
{
retVal = TRUE;
}
}
return retVal;
}
/**
* Gets ATTRIB_XACIS_NAME generic attribute value
* @param iEnt
* Input ENTITY to be queried for ATTRIB_XACIS_NAME attribute
* @param opName
* Output Name of entity
*/
logical GetEntityName( ENTITY * iEnt, char * & opName)
{
logical retVal = FALSE;
ATTRIB_GEN_STRING* pName = NULL;
outcome result = api_find_named_attribute( iEnt, "ATTRIB_XACIS_NAME", reinterpret_cast< ATTRIB_GEN_NAME*&>( pName) );
opName = NULL;
if( pName && ( result.ok() == TRUE))
{
const char* pTmpStr = pName->value();
if( pTmpStr && ( result.ok() == TRUE))
{
opName = new char [ strlen(pTmpStr) + 1];
strcpy( opName, pTmpStr);
retVal = TRUE;
}
}
return retVal;
}
/*!
Traverses list of entities to find cut features and returns list of cut features
@param iEntityList
Input list of entities
@param oCutFeatureCollections
Output list of cut features
Returns if successful
*/
logical GetCutFeatures( const ENTITY_LIST & iEntityList, ENTITY_LIST & oCutFeatureCollections)
{
if( 0 == iEntityList.count())
return FALSE;
iEntityList.init();
ENTITY * pEntity = NULL;
while( NULL != (pEntity = iEntityList.next()))
{
if( TRUE == IsCutFeature( pEntity) )
{
oCutFeatureCollections.add( pEntity);
}
}
return (oCutFeatureCollections.count() > 0) ? TRUE : FALSE;
}
/*
Get Assembly Cut feature information
@param iCutFeatures
Input list of features (SPACOLLECTIONs)
@param oCutTools
Output list of cut tools
@param oCutTargets
Output list of cut targets
Return TRUE if successful
*/
logical GetAssemblyCutInfo( const ENTITY_LIST & iCutFeatures, ENTITY_LIST & oCutTools, ENTITY_LIST & oCutTargets)
{
if( 0 == iCutFeatures.count())
return FALSE;
iCutFeatures.init();
ENTITY * pEnt = NULL;
while( NULL != ( pEnt = iCutFeatures.next()))
{
if( FALSE == is_SPACOLLECTION( pEnt))
continue;
SPACOLLECTION * pCollection = (SPACOLLECTION *)pEnt;
if( NULL == pCollection)
continue;
pCollection->init();
ENTITY * pMember = NULL;
while( NULL != ( pMember = pCollection->next()) )
{
if( TRUE == IsCutTool( pMember))
{
oCutTools.add( pMember);
}
else if( FALSE == is_SPAGROUP( pMember))
{
oCutTargets.add( pMember);
}
}
}
return TRUE;
}
/*!
Processes all cut features in input ENTITY LIST (do cut operation)
@param iEntityList
Input list of entities
Returns TRUE if successful
*/
logical ProcessAllAssemblyCutFeature( ENTITY_LIST & iEntityList)
{
logical retVal = FALSE;
if( 0 == iEntityList.count())
return FALSE;
ENTITY_LIST cutFeatureCollections;
retVal = GetCutFeatures(iEntityList, cutFeatureCollections);
if( FALSE == retVal || 0 == cutFeatureCollections.count())
{
printf("No assembly cut feature found\n");
return retVal;
}
ENTITY_LIST cutTools;
ENTITY_LIST cutTargets;
retVal = GetAssemblyCutInfo( cutFeatureCollections, cutTools, cutTargets);
cutTools.init();
ENTITY * pTool = NULL;
while( NULL != ( pTool = cutTools.next()) )
{
char * pName = NULL;
GetEntityName( pTool, pName);
if( pName)
{
printf("Performing Cut operation for feature:%s\n", pName);
delete [] pName;
}
ENTITY * pTarget = NULL;
cutTargets.init();
while( NULL != ( pTarget = cutTargets.next()) )
{
BODY * pResultBody = NULL;
BoolOptions * pBoolOpt = NULL;
AcisOptions * ao = NULL;
outcome result = api_boolean( (BODY *)pTool, (BODY *)pTarget, SUBTRACTION, NDBOOL_KEEP_TOOL,pResultBody, pBoolOpt, ao);
}
api_del_entity( pTool);
}
return retVal;
}
//----------------------------------------------------------------------------------------
void unlock_license();
int main( int argc, char * argv[])
{
unlock_license();
int err = 0;
if ( (err = getArgs(argc, argv) ) !=0)
return err;
InitializeAcis();
ENTITY_LIST eList;
logical res = RestoreSatFile( pszInputFile, eList);
ProcessAllAssemblyCutFeature( eList);
SaveSatFile( eList, pszOutputFile);
if( FALSE == res)
return res;
TerminateAcis();
return 0;
}
|
Limitations
The support for assembly cut features has the following limitations (in both E-BOM and flatten route):
- When a part file contains multiple bodies and an assembly cut is defined on only some of the bodies (even though the tool body is long enough to intersect with many bodies), InterOp does not specify exactly which bodies are affected. Instead, InterOp will specify that all bodies are affected by that cut.
- When any sub-assembly is instantiated more than once in a parent assembly, InterOp does not specify exactly which children were affected due to an assembly cut that occurs in the following situations:
- The assembly cut is defined on only some of the instances of that sub-assembly.
- Different assembly cuts are defined on different instances of the sub-assembly.
Hole and Pattern Attributes
The various properties of Holes and Patterns are attached as attributes to the SPAGROUP entity in ACIS. The following table lists the Hole feature attributes attached to the SPAGROUP entity:
| Attribute Name | Attribute Type | Hole Information |
|---|---|---|
| ATTRIB_XACIS_GROUP_TYPE | Integer
-1 – undefined type 0 – layer entity 1 – layer filter entity 2 – selection set entity 3 – hole feature 4 – entity created from an assembly cut features 5 – entity created for parameters 6 – entity created to hold all Driving Dimensions as its members 7 – entity created to hold all Material Properties 8 – entity created to hold all Document level Properties (currently document level material properties and validation properties are held) | Group type |
| SPAATTRIB_MFGTYPE | Integer (-1 to 6)
-1 – Unknown 0 – Simple hole 1 – Tapered 2 – Counter Bore 3 – Counter Sink 4 – Counter drilled 5 – Rectangular Pattern Feature 6 – Circular Pattern Feature | Hole type |
| SPAATTRIB_HLDIA | Double | Primary hole diameter |
| SPAATTRIB_HLDIAMXTL | Double | Primary diameter maximum tolerance |
| SPAATTRIB_HLDIAMNTL | Double | Primary diameter minimum tolerance |
| SPAATTRIB_HLDPTH | Double | Hole depth |
| SPAATTRIB_HLTIPANG | Double (in radians) | Hole tip angle |
| SPAATTRIB_HLDIR | SPAvector | Hole direction |
| SPAATTRIB_HLTAPANG | Double (in radians) | Taper hole angle |
| SPAATTRIB_HLCBDIA | Double | Counter bore diameter |
| SPAATTRIB_HLCBDIAMXTL | Double | Counter bore diameter maximum tolerance |
| SPAATTRIB_HLCBDIAMNTL | Double | Counter bore diameter minimum tolerance |
| SPAATTRIB_HLCBDPTH | Double | Counter bore depth |
| SPAATTRIB_HLCSDIA | Double | Counter sink diameter |
| SPAATTRIB_HLCSDIAMXTL | Double | Counter sink diameter maximum tolerance |
| SPAATTRIB_HLCSDIAMNTL | Double | Counter diameter minimum tolerance |
| SPAATTRIB_HLCSTAPANG | Double | Counter sink taper angle |
| SPAATTRIB_HASTHREAD | Bool | Whether the hole is threaded. True, if hole is threaded. |
| SPAATTRIB_HLTHRDTYPE | String | Hole thread type, specifies name of the thread type |
| SPAATTRIB_HLTHRDDIA | Double | Hole thread diameter |
| SPAATTRIB_HLTHRDPTCH | Double | Hole thread pitch |
| SPAATTRIB_HLTHRDDPTH | Double | Hole thread depth |
| SPAATTRIB_HLTHRDMXTL | Double | Hole thread maximum tolerance |
| SPAATTRIB_HLTHRDMNTL | Double | Hole thread minimum tolerance |
| SPAATTRIB_HLTHRDDIR | Bool | Hole thread direction. True indicates Right Handed else Left Handed |
| SPAATTRIB_HLCDDIA1 | Double | Counter drilled hole diameter1 |
| SPAATTRIB_HLCDDIA2 | Double | Counter drilled hole diameter2 |
| SPAATTRIB_HLCDDIAMXTL | Double | Counter drilled diameter maximum tolerance |
| SPAATTRIB_HLCDDIAMNTL | Double | Counter drilled diameter minimum tolerance |
| SPAATTRIB_HLCDDPTH | Double | Counter drilled hole depth |
| SPAATTRIB_HLCDTAPANG | Double | Counter drilled hole taper angle |
| SPAATTRIB_HLPOS | SPAposition | Center position of the hole |
Note: In addition to the above list of attributes for Hole, a generic attribute of type int, named SPAATTRIB_HLTOPFACE, is attached to the top face of the hole.
The following table lists the Pattern attributes attached to the SPAGROUP entity:
| Attribute Name | Attribute Type | Pattern Information |
|---|---|---|
| SPAATTRIB_PATRTHL | SPAGROUP | Base hole in a pattern feature (both for circular and rectangular pattern) |
| SPAATTRIB_PATANCHPT | SPAposition | Anchor position of root hole in a pattern (both for circular and rectangular pattern) |
| SPAATTRIB_PATFDIRPOS | int | Original position of base hole in first direction in a pattern (both for circular and rectangular pattern) |
| SPAATTRIB_PATSDIRPOS | int | Original position of base hole in second direction in a pattern (both for circular and rectangular pattern) |
| SPAATTRIB_PATFDIRCNT | int | Number of duplications in first direction in a pattern (both for circular and rectangular pattern) |
| SPAATTRIB_PATSDIRCNT | int | Number of duplications in second direction in a pattern (both for circular and rectangular pattern) |
| SPAATTRIB_PATFDIRSTP | double | Step between two consecutive duplications in first direction in a pattern (both for circular and rectangular pattern) |
| SPAATTRIB_PATSDIRSTP | double | Step between two consecutive duplications in second direction in a pattern |
| SPAATTRIB_RECPATFDIR | SPAvector | First direction in a rectangular pattern (Not applicable for circular pattern) |
| SPAATTRIB_RECPATSDIR | SPAvector | Second direction in a rectangular pattern (Not applicable for circular pattern) |
| SPAATTRIB_CIRPATCENOFROT | SPAposition | Center of rotation of circular pattern (Not applicable for rectangular pattern) |
| SPAATTRIB_CIRPATAXSOFROT | SPAvector | Axis of rotation of circular pattern (Not applicable for rectangular pattern) |
| SPAATTRIB_CIRPATINSTROT | logical | Circular pattern instance rotation flag, if it is True, duplication keep the same orientation. (Not applicable for rectangular pattern) |
| ATTRIB_XACIS_GROUP_TYPE | Integer, value of 3 indicates hole feature. | Group Type |
| SPAATTRIB_MFGTYPE | Integer | Pattern Type, value of 5 indicates Rectangular Pattern Feature, value of 6 indicates Circular Pattern Feature |
You can query the SPACOLLECTION entity for information and perform a Boolean operation to obtain the cut feature where the tool body is used as a tool and the affected flatten list of entities are treated as targets.
Free Parts Translation in ASAT Write
ACIS assembly supports top-level entities at assembly node (asm_model). Hence, ASAT Writer generates an ASAT file containing Free Parts at the root node as top-level entities.
In ACIS assembly, Free Parts as top-level entities can be:
- Added using the member function add_entities of asm_model class
- Queried using API asmi_model_get_entities or calling member functions on asm_model (asm_model* object pointer -> mgr() -> get_top_level_entities())
Note: Free parts are handled only at the top-level node of the source assembly; free parts in subassembly nodes are ignored.
Assembly Limitations
The following features are not supported by ACIS assembly (ASAT/ASAB):
- Atomic assemblies
- Layer/Layer Filter
- Color at instance levels
- Suppress/Hidden
- Cut/Hole
- PMI
- Hybrid assemblies
- Unit at instance level and Free Parts
- ACIS assembly (ASAT) does not support transformation with a reflection (or mirror). In this case, InterOp will copy the instance having a mirror transformation and then apply the transformation on that copied node. Then, this node will be instantiated (created) with unit transformation.