Parsing and Creating PRC Files¶
Note
Starting Acrobat X, the ability to convert various 3D formats for use with PDF is no longer supported. The associated APIs are, therefore, not available from Acrobat X SDK onwards.
The Adobe Acrobat 3D API lets you develop Acrobat plugins and PDF Library applications that create and access data in a PRC stream. Such a stream can be embedded within a PDF document as a 3D annotation. This chapter explains how to export the contents of a PRC stream, and how to create a PRC stream.
PRC data can appear in PDF documents as streams referenced by 3D annotations. PRC data is a highly-compressed 3D representation supported in Acrobat 8.1 and later. It can represent faceted and exact geometry data. The PRC format is specified in the PRC Format Specification.
Before you read this chapter, it is strongly recommended that you become familiar with 3D concepts and OpenGL, and with 3D annotations. (See Creating 3D annotations.) OpenGL is an open-source API for setting and accessing 3D data.
For a description of the PRC file format, see the PRC Format Specification.
Working with the Acrobat 3D API¶
The Acrobat 3D API provides a programmatic interface to the Acrobat 3D Library. It is the only mechanism that lets you create, access, and change PRC data that appears in a PDF document. It does not enable reading or writing PDF documents. (U3D is another 3D format that can be referenced by 3D annotations.)
You can use the Acrobat 3D API to develop the following settings:
Plugins that work with Acrobat Pro Extended
Applications that use the PDF Library. (Acrobat Pro Extended must also be installed.) When the Acrobat 3D Library initializes itself, it verifies the presence of Acrobat Pro Extended on the same computer.
Versions¶
The following table shows the correlation between the Acrobat 3D Library versions and the Acrobat products that supports them. The table also shows the PRC format supported by the Acrobat 3D Library version.
Acrobat 3D Library version |
Product |
Supports PRC format version |
|---|---|---|
2.0 |
Acrobat Pro Extended
version 9.0
PDF Library version 9.0 |
7094 and earlier |
2.1 |
Acrobat Pro Extended
version 9.1
PDF Library version 9.1 |
7094 and earlier |
Compatibility with different PRC format versions¶
In addition to supporting the PRC format specified in the previous table, Acrobat 3D Library provides forward and backward compatibility with other PRC format versions:
Forward compatibility: The Acrobat 3D Library is designed to avoid failing if it reads PRC documents that conform to future releases of the PRC format. It does so by ignoring any information it does not understand.
Backward compatibility: In a major release, Acrobat 3D Library support for PRC is backward compatible. Each new version of the software can read PRC files that conform to an earlier PRC format version.
Compatibility between the Acrobat 3D Library and the Acrobat 3D API¶
The Acrobat 3D API provides the public declarations for a particular version of the Acrobat 3D Library. Plugins developed with one version of the Acrobat 3D API are installed with the same version of Acrobat 3D Library, where that library is contained in Acrobat Pro Extended.
Acrobat 3D Library is designed to support backward compatibility within minor releases of the library.
Requirements¶
To develop an Acrobat 3D Extended plugin or PDFL application that uses the Acrobat 3D Library, you must download the samples, documentation, and header files from this SDK.
A licensed copy of Acrobat Pro Extended must be installed on the computer on which the plugin or PDF Library application is running. The Acrobat 3D Library verifies the presence of Acrobat Pro Extended before initializing its relationship with the application or plugin.
The file that contains the Acrobat 3D Library is A3DLIB.dll, which is located in the following directory:
C:Program FilesAdobeAcrobatAcrobat
Data types, naming conventions, and character encoding¶
The Acrobat 3D API adopts the Acrobat library definitions for basic types. Here are the basic types from the Acrobat library: ASInt8, ASInt16, ASInt32, ASUns8, ASUns16, ASUns32, and ASBool.
The Acrobat 3D API declares all non-basic types, which fall into these general categories:
PRC entities. Correspond to the non-terminal structures in the PRC format, such as product occurrences, tessellation base data, and texture transformations. Your software uses NULL pointers to reference PRC entities.
Data structures. Contain the data used to create a PRC entity. Data structures can also receive the data obtained from parsing a PRC entity. There is one data structure for each type of PRC entity.
Acrobat 3D API uses a naming convention that is self-documenting. The name for each function, structure, enumeration, and enumerator provides clues as to its type, its relationship to a PRC entity described in the PRC format, and its role relative to that PRC entity.
Character encoding is UTF-8, which uses the character encoding scheme described by the Internet Engineering Task Force (IETF) document UTF-8, a transformation format of ISO 10646. That document is available at http://tools.ietf.org/html/rfc3629.
Structured and recursive nature of PRC parsing¶
Plugins and applications that process PRC data should be structured to reflect the hierarchy of the PRC format. Ideally, they implement one function to process or create each of the PRC entities. Additionally, they implement other functions to perform repeated tasks, such as processing or creating attribute data that can apply to a broad category of PRC entities.
Additionally, plugins and applications that process PRC data should support recursive function calls.
The PRC format is a highly-compressed hierarchical structure. The structural entities in a PRC document enable the definition of subassemblies that represent some part of the overall image, such as a gear or a nut. Subassemblies are then grouped to create more complex assemblies, or they can be referenced from other subassemblies similar to a macro.
The following diagram illustrates the hierarchical relationships that can exist between the structural elements:
Model files can have multiple child product occurrences.
Product occurrences can have multiple child product occurrences and a part definition. They can also reference product occurrences that act as prototypes or external data.
Part definitions have multiple child representation items.
Because some PRC entities can contain child entities of the same type, plugins that parse or create PRC data use recursion.
Implementing external linking in your plugin¶
The Acrobat 3D Library’s import library (the.lib file) is not provided in the Acrobat SDK or through any other means. As a result, you must use explicit linking to resolve the external links in your plugin.
With explicit linking, the executable using the DLL must make function calls to explicitly load and unload the DLL, and to access the DLL’s exported functions. Your plugin must call the exported functions through a function pointer. More specifically, your plugin must perform the following tasks:
Call the
LoadLibraryfunction (or a similar function) to load the DLL and obtain a module handle.Call the
GetProcAddressfunction to obtain a function pointer to each exported function that your plugin calls. Because applications are calling the DLL’s functions through a pointer, the compiler does not generate external references, so there is no need to link with an import library.Call the
FreeLibraryfunction when done with the DLL.
Note
The Acrobat 3D API functions in this chapter are described as though implicit linking were possible. Wherever you see a direct call to one of these functions, you should instead use the pointer to the function. See Implementing external linking.
Implementing external linking¶
Call the
LoadLibraryfunction (or a similar function) to load the DLL and obtain a module handle.Call the
GetProcAddressfunction to obtain a function pointer to each exported function that your plugin calls. Because applications are calling the DLL’s functions through a pointer, the compiler does not generate external references, so there is no need to link with an import library.Main code segment that loads the Acrobat 3D library and defines function pointers
HMODULE hModuleA3DPRCSDK = A3DPRCLoadLibrary();
if (!hModuleA3DPRCSDK) {
AVAlertNote("Failed to load A3DLIB.dll!");
_unlink(prcName);
_unlink(jsName);
return;
}
A3DPRCFunctionPointersInitialize(hModuleA3DPRCSDK);
/*------------------------------------
/* Your plugin initializes its relationship with the Acrobat 3D Library
/* and then it parses or creates PRC content.
/*------------------------------------
A3DPRCUnloadLibrary(hModuleA3DPRCSDK);
} else {
char strMsg[128];
sprintf(strMsg, "A3DDllInitialize returned %dn", iRet);
AVAlertNote(strMsg);
_unlink(prcName);
_unlink(jsName);
A3DPRCUnloadLibrary(hModuleA3DPRCSDK);
}
Loading the DLL and obtaining a module handle
HMODULE A3DPRCLoadLibrary()
{
HMODULE hModuleA3DPRCSDK;
wchar_t acFilePath[MAX_PATH];
GetModuleFileNameW(NULL, acFilePath, MAX_PATH);
wchar_t* backslash = wcsrchr(acFilePath, L'');
if (backslash)
acFilePath[backslash - acFilePath] = 0;
wcscat(acFilePath, L"A3DLIB.dll");
#ifdef UNICODE
hModuleA3DPRCSDK = LoadLibraryExW(acFilePath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
#else
hModuleA3DPRCSDK = LoadLibraryExA(acFilePath, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
#endif
if (hModuleA3DPRCSDK)
return hModuleA3DPRCSDK;
return NULL;
}
Setting up the function pointers
void A3DPRCFunctionPointersInitialize(HMODULE hModule)
{
#define A3D_API(returntype,name,params) st_PF##name = (PF##name)GetProcAddress(hModule,#name);
#include <A3DSDK.h>
#include <A3DSDKTypes.h>
#include <A3DSDKBase.h>
#include <A3DSDKErrorCodes.h>
#include <A3DSDKGeometry.h>
#include <A3DSDKTessellation.h>
#include <A3DSDKGraphics.h>
#include <A3DSDKStructure.h>
#include <A3DSDKRootEntities.h>
#include <A3DSDKRepItems.h>
#include <A3DSDKTessellation.h>
#include <A3DSDKMarkup.h>
#include <A3DSDKGlobalData.h>
#include <A3DSDKTexture.h>
#include <A3DSDKMisc.h>
#include <A3DSDKGeometryCrv.h>
#include <A3DSDKGeometrySrf.h>
#include <A3DSDKTopology.h>
#undef A3D_API
}
Declaring the macro that resolves to the function pointer
#define A3DCALL(name,params) st_PF##name params
Using the macro to invoke an Acrobat 3D API function
if(iErr == A3D_SUCCESS) {
ASInt32 iRet = A3DCALL(A3DDllInitialize,(iMajorVersion, iMinorVersion));
if(iRet == A3D_SUCCESS) {
…
}
}
Parsing a PRC file¶
This section describes how to parse the data in a PRC file. You can then export the PRC data to an external file that uses a different CAD format, provided you understand the structure of that format and have an API that supports that format. It is beyond the scope of this chapter to explain how to convert PRC data into a specific CAD format. It is also beyond the scope of this chapter to provide an exhaustive explanation of parsing all aspects of a PRC file.
The following diagram shows the structure of a plugin that parses PRC data.
The following diagram shows the sequence of tasks required to parse a Brep model entity.
Handling errors¶
Most of the Acrobat 3D API functions return an integer that indicates success or failure. A return value of A3D_SUCCESS indicates success, and any negative return value indicates failure. The following example shows one approach for evaluating this returned result:
ASInt32 iRet = A3DAsmModelFileLoadFromFile(acFileName, NULL, &p);
if (iRet == A3D_SUCCESS) {
…
} else
fprintf("Error: %1dn", iRet);
Although subsequent explanations in this section omit this description, you must still check for errors when an Acrobat 3D API function returns.
Copying the embedded PRC file to a separate file¶
This section explains how to export a PRC stream represented in a PDF document as a 3D annotation.
Copy the embedded PRC file to a separate file
Retrieve the 3D annotation from within a PDF document. (See Retrieving existing annotations.) Ensure that the annotation dictionary type is
3DDand that the subtype isPRC.Write the PRC stream to a separate file. This will simplify accessing the data in the stream.
Initializing the Acrobat 3D API¶
This section explains how to initialize the Acrobat 3D API.
Initialize your interface with the Acrobat 3D API
Verify that your plugin is compatible with the Acrobat 3D Library by comparing the version of the Acrobat 3D API against which you compiled and the version of the Acrobat 3D Library available to your plugin. Obtain the version identifiers for the currently installed Acrobat 3D Library by invoking the
A3DDllGetVersionfunction. Evaluate the returned values as follows:Ensure that the value of the
piMajorVersionargument matches theA3D_DLL_MAJORVERSIONenumeration.Ensure that the value of the
piMinorVersionargument is equal to or greater than theA3D_DLL_MINORVERSIONenumeration. The Acrobat 3D Library provides backward compatibility for earlier releases of the API that have the same major version identifier.
Initialize the Acrobat 3D API by supplying the version identifiers for the Acrobat 3D API.
if(iErr == A3D_SUCCESS) {
ASInt32 iRet = A3DCALL(
A3DDllInitialize,(A3D_DLL_MAJORVERSION, A3D_DLL_MINORVERSION));
if(iRet == A3D_SUCCESS) { … }
}
Warning
For simplicity, this example uses a syntax that assumes the import library is available. That library is not publicly available, so your code must use a syntax that supports external linking (see Implementing external linking in your plugin). The following example shows the syntax to use:
Parsing structure PRC entities¶
The Acrobat 3D API Reference groups the PRC entities that provide structure to the PRC document into the structure module. The PRC entities in the structure module are described here:
Model file: Is a root PRC entity. There is only one model file in a PRC file.
Product occurrence: Can contain multiple child product occurrences and one part definition. It can also reference other product occurrences used as prototypes or external data.
Part definition: Contains representation items.
Filter: Specifies inclusion or exclusion of topology, geometry, tessellation, or graphic entities, based on the entity’s layer or entity type.
Parse the model file data¶
Load the PRC file into memory by invoking the A3DAsmModelFileLoadFromFile function. In the following example, the
acFileNameargument points to anA3DUTF8Chararray that contains the name of the PRC file, the second parameter must beNULL, and theppointer references a null A3DAsmModelFile object in which the Acrobat 3D Library stores the PRC model file.
A3DAsmModelFile* p = NULL;
ASInt32 iRet = A3DAsmModelFileLoadFromFile(acFileName, NULL, &p);
Populate the model file with the model file data by invoking the A3DAsmModelFileGet function to place the data in that structure. The A3D_INITIALIZE_DATA macro clears the memory allocated to the structure and checks the size of the structure to avoid alignment problems. The A3DAsmModelFileGet function creates a data structure from the model file pointer created in the previous step.
A3DAsmModelFileData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DAsmModelFileGet(p, &sData);
Save the value of the
m_dUnitmember in the structure in which you are saving data obtained from parsing the PRC file (your export structure). This member specifies a multiple of millimeters. The value of this member must be non-zero. A value of 1 indicates the units are in millimeters; and a value of 10 indicates the units are in centimeters.If the
m_bUnitFromCADis present, save its value in your export structure. If thebUnitFromCADmember is true, then them_bUnitis from the native CAD file.Parse the entity base. (See Parsing root-base entity data.)
Declare an A3DMiscCascadedAttributes structure. This will be the root entry in a stack on which you store child product occurrences and other subordinate structures. This stack is used to iterate through the PRC structure.
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesCreate(&pAttr);
As you parse subsequent PRC entities, you push the attributes onto this stack. For more information about using cascaded attribute stacks, see Parsing PRC entities that specify graphics or click the Related Pages tab on the Acrobat 3D API Reference.
Parse each product occurrence pointer in the
sData.m_ppPOccurrencesarray. The number of pointers is specified insData.m_uiPOccurrencesSize.
for (ASUns32 ui = 0; ui < sData.m_uiPOccurrencesSize; ui++)
parsePOccurrence(sData.m_ppPOccurrences[ui], pAttr);
For information about parsing product occurrences, see Parse a product occurrence.
Parse a product occurrence¶
Parse the entity base, saving the entity name and other relevant data to your export structure. (See Parsing root-base entity data.)
Create and push a cascaded attributes structure for a product occurrence object, and push that structure onto the stack. (See Parsing graphic attributes using miscellaneous cascaded attributes.) Save relevant values to your export structure.
Declare and initialize an
A3DAsmProductOccurrenceDatastructure.
A3DAsmProductOccurrenceData sData;
A3D_INITIALIZE_DATA(sData);
Get the product occurrence data by invoking the
A3DAsmProductOccurrenceGetfunction.
iRet = A3DAsmProductOccurrenceGet(p, &sData);
Parse the product occurrence data to identify subordinate or imported product occurrences and recursively parse the contents of each, as described in Parse a product occurrence (this section). The member names and their significance are described below:
m_pPrototype: Pointer to a product occurrence prototype, which typically represents a subassembly or partm_pExternalData: Pointer to an external product occurrencem_uiPOccurrencesSize: Number of child product occurrences, where them_ppPOccurrencesarray references those child product occurrences
The following example parses prototype or external product occurrences. The sData variable is a populated A3DAsmProductOccurrenceData structure.
if (sData.m_pPrototype) {
parsePOccurrence(sData.m_pPrototype, pAttr);
}
if (sData.m_pExternalData) {
parsePOccurrence(sData.m_pExternalData, pAttr);
}
The following example parses child product occurrences (sData.ppPOccurrences[ui]. As before, the sdata variable is a populated A3DAsmProductOccurrenceData structure.
for (ASUns32 ui = 0; ui < sData.m_uiPOccurrencesSize; ui++)
parsePOccurrence(sData.m_ppPOccurrences[ui], pAttr);
If the product occurrence data references a part (
sData.m_pPart), parse it. (See Parse a product occurrence.)Parse any scene display parameters in the product occurrence.
Delete the
A3DAsmProductOccurrenceDatastructure created in Step Declare and initialize an ``A3DAsmProductOccurrenceData` structure. <Plugins_A3D_API.html#50618396_31716>`__ by invoking theA3DAsmProductOccurrenceGetfunction with the first argument set toNULLand the second argument pointing to the product occurrence data.
iRet = A3DAsmProductOccurrenceGet(NULL, &sData);
Parse a part definition¶
Parse the entity base, saving the entity name and other relevant data to your export structure. (See Parsing root-base entity data.)
Create and push a cascaded attributes structure for a product occurrence object, and push that structure onto the stack. (See Parsing graphic attributes using miscellaneous cascaded attributes.) Record information from the data structure of the miscellaneous cascaded attributes structure that is meaningful to your representation.
Declare and initialize an
A3DAsmPartDefinitionDatastructure, as shown in the following example:
A3DAsmPartDefinitionData sData;
A3D_INITIALIZE_DATA(sData);
iRet = A3DAsmPartDefinitionGet(p, &sData);
Parse each representation item referenced by the part definition (See Parsing representation items.) In the following example,
sData.m_uiRepItemsSizeis the number of representation item entities in the part definition, and entry in thesData.m_ppRepItems[ui]array references a separate representation item.
for (ASUns32 ui = 0; ui < sData.m_uiRepItemsSize; ui++)
parseRI(sData.m_ppRepItems[ui], pAttr);
Delete the
A3DAsmPartDefinitionDatastructure created in Step Declare and initialize an ``A3DAsmPartDefinitionData` structure, as shown in the following example: <Plugins_A3D_API.html#50618396_28760>`__ by invoking theA3DAsmPartDefinitionGetfunction with the first argument set toNULLand the second argument pointing to the part definition data.
A3DAsmPartDefinitionGet(NULL, &sData);
Parsing representation items¶
Representation items describe objects present in the 3D image, such as a wheel or a bolt. The exception is the representation item set (type kA3DTypeRiSet ), which is a container for other representation items.
Parse a generic representation item
Parse the entity base, saving the entity name and other relevant data to your export structure. (See Parsing root-base entity data.)
Create and push a miscellaneous cascaded attributes structure for the representation item, and then get the data for that structure (See Parsing PRC entities that specify graphics.) Record information from the miscellaneous cascaded attributes data structure that is meaningful to your representation.
Invoke the
A3DEntityGetTypefunction to determine the type of representation item, providing the following arguments:The first argument (
pin the following example) is a pointer to the representation item.The second argument (
eTypein the following example) is a pointer to a variable in which the function stores the type enumerator.
A3DEEntityType eType;
iRet = A3DEntityGetType(p, &eType);
Parse the representation item depending on the type of representation item, as shown in the following example. (See Parse a representation item set (PRC entity A3DRiSet) or Parse a Brep model representation item (PRC entity A3DRiBrepModel).)
switch(eType) {
case kA3DTypeRiBrepModel:
parseRiBrepModel(p, father);
break;
case kA3DTypeRiSet:
…
break;
case kA3DTypeRiPointSet:
…
break;
…
default:
…
}
Get the representation item attributes by invoking the
A3DRiRepresentationItemGetfunction.
A3DRiRepresentationItemData sData;
A3D_INITIALIZE_DATA(sData);
iRet = A3DRiRepresentationItemGet(p, &sData);
Parse the tessellation base data referenced by the
m_pTessBasemember. (See Parsing tessellation PRC entities.)
parseTess(sData.m_pTessBase, p, pAttr);
Parse the coordinate system referenced by the
m_pCoordinateSystemmember. (See Parse coordinate system data.)
parseRiCSys(sData.m_pCoordinateSystem);
Delete the
A3DRiRepresentationItemDatacreated in Step Get the representation item attributes by invoking the ``A3DRiRepresentationItemGet` function. <Plugins_A3D_API.html#50618396_17261>`__ by invoking theA3DRiRepresentationItemGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DRiRepresentationItemGet(NULL, &sData);
Parse a representation item set (PRC entity A3DRiSet)¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Create and push a cascaded attributes structure for a product occurrence object, and push that structure onto the stack. (See Parsing graphic attributes using miscellaneous cascaded attributes.) Save relevant values to your export structure.
Declare and initialize an
A3DRiSetDatastructure, and then get the data from the representation PRC entity.
A3DRiSetData sData;
A3D_INITIALIZE_DATA(sData);
iRet = A3DRiSetGet(p, &sData);
Parse each representation item in the representation item set. (See Parsegeneric.) The
m_uiRepItemsSizefield specifies the number of child representation items, and the m_ppRepItems[] field is an array of pointers to the child representation items.
for(ASUns32 ui = 0; ui<sData.m_uiRepItemsSize; ui++)
parseRI(sData.m_ppRepItems[ui], pAttr, son);
Delete the A3DRiSetGet function created in Step Declare and initialize an ``A3DAsmPartDefinitionData` structure, as shown in the following example: <Plugins_A3D_API.html#50618396_28760>`__ by invoking the
A3DAsmPartDefinitionGetfunction with the first argument set toNULLand the second argument pointing to the part definition data.
A3DRiSetGet(NULL, &sData);
Parse a Brep model representation item (PRC entity A3DRiBrepModel)¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Get the Brep model data by invoking the
A3DRiBrepModelGetfunction. The first argument (pin the following example) is a pointer to the PRC entity, and the second argument (&sDatain the following example) is the location of theA3DRiBrepModelDatastructure.
A3DRiBrepModelData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DRiBrepModelGet(p, &sData);
Parse the Brep model’s topology body data, referenced by the
m_pBrepDatamember. (See Parse topology body data.)Parse the Brep model’s data, referenced by the
m_pBrepDatamember. (See Parse the Brep model’s data.)
Warning
The same member (m_pBrepData ) is used to parse topology body data and topology model data. The Brep model’s topology body data is recast as the A3DTopoBody type, which is an abstract root type for any topological body. The A3DTopoBodyGet function takes an argument of type A3DTopoBody.
Delete the
A3DRiBrepModelDatacreated in Step Get the Brep model data by invoking the ``A3DRiBrepModelGet` function. The first argument (pin the following example) is a pointer to the PRC entity, and the second argument (&sDatain the following example) is the location of theA3DRiBrepModelDatastructure. <Plugins_A3D_API.html#50618396_45175>`__ by invoking theA3DRiBrepModelGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DRiBrepModelGet(NULL, &sData);
Parse coordinate system data¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Declare and initialize an
A3DRiCoordinateSystemDatastructure.
A3DRiCoordinateSystemData sData;
A3D_INITIALIZE_DATA(sData);
Get the coordinate system data by invoking the
A3DRiCoordinateSystemGetfunction. The first argument (pin the following example) is a pointer to theA3DRiCoordinateSystementity, and the second argument (&sDatain the following example) is the location of theA3DRiCoordinateSystemDatastructure.
ASInt32 iRet = A3DRiCoordinateSystemGet(p, &sData);
Parse the coordinate system transformation data referenced by the
m_pTransformationmember of theA3DRiCoordinateSystemDatastructure.Delete the
A3DRiCoordinateSystemDatastructure created in Step Declare and initialize an ``A3DRiCoordinateSystemData` structure. <Plugins_A3D_API.html#50618396_58902>`__ by invoking theA3DRiCoordinateSystemGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DRiCoordinateSystemGet(NULL, &sData);
Parsing tessellation PRC entities¶
Tessellation entities represent polygon facets.
Parse tessellation base data¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Populate an
A3DTessBaseDatastructure with the tessellation base data by invoking theA3DTessBaseGetfunction. The first argument (pin the following example) is a pointer to the tessellation base data, and the second argument (&sDatain the following example) is the location of theA3DTessBaseDatastructure.
A3DTessBaseData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DTessBaseGet(p, &sData);
Export the coordinate size (sData.m_uiCoordSize), the coordinates array (sData.m_pdCoords), and the calculate attributes (
sData.m_bIsCalculated) to your tessellation base data element.Parse the tessellation data based on its type. The PRC format defines these types for tessellation data:
kA3DTypeTess3D, which is used for solids and surfaces (See Parse 3D tessellation data.)kA3DTypeTess3DWire, which is used for 3D wireframeskA3DTypeTessMarkup, which is used for markups
A3DEEntityType eType;
ASInt32 iErr = A3DEntityGetType(p, &eType);
if (iErr == A3D_SUCCESS) {
switch(eType) {
case kA3DTypeTess3D:
parse3DTess(p, pRepItem, pFatherAttr);
break;
case kA3DTypeTess3DWire:
parse3DWireTess(p);
break;
case kA3DTypeTessMarkup:
parse3DTessMarkup(p);
break;
default:
// error response.
}
Delete the A3DTessBaseData created in Step Populate an ``A3DTessBaseData` structure with the tessellation base data by invoking the
A3DTessBaseGetfunction. The first argument (pin the following example) is a pointer to the tessellation base data, and the second argument (&sDatain the following example) is the location of theA3DTessBaseDatastructure. <Plugins_A3D_API.html#50618396_69214>`__ by invoking theA3DRiBrepModelGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DTessBaseGet(NULL, &sData);
Parse 3D tessellation data¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Populate an
A3DTess3DDatastructure with the tessellation data by invoking theA3DTess3DGetfunction.
A3DTess3DData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DTess3DGet(p, &sData);
Represent relevant data from the 3D tessellation data element in your export structure.
For each face in the tessellation data, create and push the cascaded attributes face data and then access its data members. (See Parsing graphic attributes using miscellaneous cascaded attributes.) In the following example, the
CreateAndPushCascadedAttributesFaceis a private function that pushes the miscellaneous cascaded attributes for a tessellation face onto the stack.
ASUns32 uiNumberOfFaces = sData.m_uiFaceTessSize;
for (ASUns32 ui = 0; ui < uiNumberOfFaces; ui++) {
A3DTessFaceData& sTessFaceData = sData.m_psFaceTessData[ui];
A3DMiscCascadedAttributes* pAttr;
A3DMiscCascadedAttributesData sAttrData;
// Read CascadedAttributes for one of the facec
CreateAndPushCascadedAttributesFace(pRepItem, p, &sTessFaceData,
ui, pFatherAttr, &pAttr, &sAttrData);
A3DMiscCascadedAttributesDelete(pAttr);
A3DMiscCascadedAttributesGet(NULL, &sAttrData);
}
Delete the cascaded attributes data structure.
A3DMiscCascadedAttributesDelete(pAttr);
Delete the cascaded attributes structure.
A3DMiscCascadedAttributesGet(NULL, &sAttrData);
Delete the
A3DTess3DDatastructure created in Step Populate an ``A3DTess3DData` structure with the tessellation data by invoking theA3DTess3DGetfunction. <Plugins_A3D_API.html#50618396_64792>`__.
A3DTess3DGet(NULL, &sData);
Parsing topology PRC entities¶
The Acrobat 3D API Reference groups the PRC entities that specify topology into the topology module. The PRC entities in this module specify the surfaces of 3D objects. This section describes how to parse the topology data in a Brep model.
Topology data in a Brep model contains data specific to the Brep and data that is generic to topology models.
Data specific to Brep topology models
The following entities contain the geometric data that represents the Brep data:
Topology Brep data: A topological boundary representation comprised of a bounding box and references to multiple Connex entities (See Create a topology Brep data entity.)
Connex: A collection of shell entities, such as a hollow sphere that contains another sphere that is represented by two connexes (See Parse Connex data.)
Shell: A collection of face entities (See Parse a shell entity.)
Face: A surface and a collection of loops (See Parse the face’s surface data.)
Data general to all topology models
The following entities contain data that applies to any topology model:
Topology body data: A mask indicating the source of the bounding box (See Parse topology body data.)
Topology context: A mask indicating the behavior of the topology context (See Parse topology context data.)
Parse topology body data¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Get the topology body data by invoking the
A3DTopoBodyGetfunction. The first argument (pin the following example) is a pointer to the Brep model’s topology body data, and the second argument (&sDatain the following example) is the location of theA3DTopoBodyDatastructure.
A3DTopoBodyData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DTopoBodyGet(p, &sData);
Parse the context of the topology body context data, referenced by the
m_pContextmember. (See Parse topology context data.)
parseContext(sData.m_pContext);
Delete the
A3DTopoBodyDatastructure created in Step Get the topology body data by invoking the ``A3DTopoBodyGet` function. The first argument (pin the following example) is a pointer to the Brep model’s topology body data, and the second argument (&sDatain the following example) is the location of theA3DTopoBodyDatastructure. <Plugins_A3D_API.html#50618396_67857>`__, by invoking theA3DTopoBodyGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DTopoBodyGet(NULL, &sData);
Parse topology context data¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Get the data in the topology context data by invoking the
A3DTopoContextGetfunction. The first argument (pin the following example) is a pointer to the topology context data, and the second argument (&sDatain the following example) is the location of theA3DTopoContextDatastructure.
A3DTopoContextData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DTopoContextGet(p, &sData);
If you plan to evaluate graphic data relative to the current surface, save the Body Scale for use in scaling the face’s surface data to fit the Nurbs surface. (See Parse the face’s surface data.) Body scale has no particular meaning for Nurb data conversion and can be called only on specific surface types.
stdContextScale = sData.m_dScale;
Delete the
A3DTopoContextDatastructure, created in Step Get the data in the topology context data by invoking the ``A3DTopoContextGet` function. The first argument (pin the following example) is a pointer to the topology context data, and the second argument (&sDatain the following example) is the location of theA3DTopoContextDatastructure. <Plugins_A3D_API.html#50618396_30926>`__, by invoking theA3DTopoContextGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DTopoContextGet(NULL, &sData);
Parse the Brep model’s data¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Get the data in the Brep model by invoking the A3DTopoBrepDataGet function. The first argument (
pin the following example) is a pointer to the Brep model’s data, and the second argument (&sDatain the following example) is the location of theA3DBrepDataDatastructure.
A3DTopoBrepDataData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DTopoBrepDataGet(p, &sData);
The Brep data can reference Connex entities. The
m_uiConnexSizemember indicates the number of such references, and the m_ppConnexes[] member provides the references. Parse each Connex entry. (See Parse Connex data.)
for(ASUns32 ui = 0; ui < sData.m_uiConnexSize; ui++)
parseConnex(sData.m_ppConnexes[ui]);
Save the bounding box referenced by
m_sBoundingBoxas an attribute of the Brep data element in your export structure.Delete the
A3DTopoBrepDataDatastructure, created in Step Get the data in the Brep model by invoking the A3DTopoBrepDataGet function. The first argument (``p` in the following example) is a pointer to the Brep model’s data, and the second argument (&sDatain the following example) is the location of theA3DBrepDataDatastructure. <Plugins_A3D_API.html#50618396_62843>`__, by invoking theA3DTopoBrepDataGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DTopoBrepDataGet(NULL, &sData);
Parse Connex data¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Get the data in the Brep model by invoking the A3DTopoConnexGet function. The first argument (
pin the following example) is a pointer to the Connex entity, and the second argument (&sDatain the following example) is the location of theA3DTopoConnexDatastructure.
A3DTopoConnexData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DTopoConnexGet(p, &sData);
The Connex data can reference multiple Shell entities. The
m_uiShellSizemember indicates the number of such references, and the m_ppShells[] member provides the references. Parse each Shell entity. (See Parse a shell entity.)
for(ASUns32 ui = 0; ui < sData.m_uiShellSize; ui++)
parseShell(sData.m_ppShells[ui]);
Delete the
A3DTopoConnexDatastructure, created in Step Get the data in the Brep model by invoking the A3DTopoConnexGet function. The first argument (``p` in the following example) is a pointer to the Connex entity, and the second argument (&sDatain the following example) is the location of theA3DTopoConnexDatastructure. <Plugins_A3D_API.html#50618396_62700>`__, by invoking theA3DTopoConnexGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DTopoConnexGet(NULL, &sData);
Parse a shell entity¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Get the data in the topology shell entity by invoking the A3DTopoShellGet function. The first argument (
pin the following example) is a pointer to the topology shell entity, and the second argument (&sDatain the following example) is the location of theA3DTopoShellDatastructure.
A3DTopoShellData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DTopoShellGet(p, &sData);
The shell data can reference multiple face entities. The
m_uiFaceSizemember indicates the number of such references, and the m_ppFaces[] member provides the references. Parse each face entity, as described in Parse the face’s surface data. [
for(ASUns32 ui = 0; ui < sData.m_uiFaceSize; ui++)
parseFace(ui, sData.m_ppFaces[ui]);
Save the closed indicator (the
m_bClosedmember) and the orientation of the surface normal with respect to the shell normal (them_pucOrientationWithShellmember) as attributes in the shell element in your export structure.Delete the
A3DTopoShellDatastructure, created in Step Get the data in the topology shell entity by invoking the A3DTopoShellGet function. The first argument (``p` in the following example) is a pointer to the topology shell entity, and the second argument (&sDatain the following example) is the location of theA3DTopoShellDatastructure. <Plugins_A3D_API.html#50618396_30248>`__, by invoking theA3DTopoShellGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DTopoShellGet(NULL, &sData);
Parse the face’s surface data¶
Parse the entity base. (See Parsing root-base entity data.) Save the entity name and other relevant data to your export structure.
Get the data in the topology face entity by invoking the A3DTopoFaceGet function. The first argument (
pin the following example) is a pointer to the topology face entity, and the second argument (&sDatain the following example) is the location of theA3DTopoFaceDatastructure.
A3DTopoFaceData sData;
A3D_INITIALIZE_DATA(sData);
ASInt32 iRet = A3DTopoFaceGet(p, &sData);
Parse the surface data referenced by the
m_pSurfacemember in theA3DTopoFaceDatastructure. (See Parse generic surface data.)If you are converting the PRC data to a 3D model that does not support UV mapping, you must create a curve on surfaceto editors: this is a standard graphic term and convert it to Nurbs data. (See Convert surface data to Nurbs (for other than UV-mapped surfaces).)
Delete the
A3DTopoFaceDatastructure created in Step Get the data in the topology face entity by invoking the A3DTopoFaceGet function. The first argument (``p` in the following example) is a pointer to the topology face entity, and the second argument (&sDatain the following example) is the location of theA3DTopoFaceDatastructure. <Plugins_A3D_API.html#50618396_74067>`__ by invoking theA3DTopoFaceGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sDatain the following example).
A3DTopoFaceGet(NULL, &sData);
Convert surface data to Nurbs (for other than UV-mapped surfaces)¶
Declare and initialize an
A3DCrvOnSurfDatastructure.Populate the
A3DCrvOnSurfDatastructure with the surface base and surface domain information from theA3DTopoFaceDatastructure.Create an
A3DCrvOnSurfPRC entity by invoking theA3DCrvOnSurfCreatefunction. The first argument in this function call is theA3DCrvOnSurfDatastructure, and the second is a pointer to the resulting PRC entity.Convert a curve on the surface in the
A3DCrvOnSurfPRC entity by invoking theA3DCrvBaseGetAsNurbsfunction.
Parse generic surface data¶
Determine the type of surface data by invoking the
A3DEntityGetTypefunction. The first argument references the surface, and the second is a pointer to a variable in which the function stores the type enumerator.Parse the surface data using the Acrobat 3D API functions most appropriate for the surface type. Use the A3DEntityGetType function to determine surface type. If the surface type is of type
kA3DTypeSurfNurbsor if the surface type is unknown, parse the surface data as Nurbs surface data (see Parse Nurbs surface data).
A3DEEntityType eType;
iRet = A3DEntityGetType(p, &eType);
switch (eType) {
case kA3DTypeSurfNurbs:
parseSurfaceNurbs(p);
break;
case kA3DTypeSurfSphere:
parseSurfSphere(p);
break;
case kA3DTypeSurfBlend01:
parseSurfaceBlend01(p);
break;
…
}
Parse Nurbs surface data¶
Declare and initialize an A3DSurfNurbsData structure.
Populate the surface Nurbs data structure by invoking the A3DSurfBaseGetAsNurbs function, providing the following arguments:
The first argument (
sData.m_pSurfacein the following example) is a pointer to the surface base entity.The second argument (
1e-3 / stdContextScale) is a ratio that the function uses to scale the Nurbs data. The value1e-3specifies the desired tolerance (0.001 mm in the following example). ThestdContextScaleglobal variable is the Body Scale, which was obtained from theA3DTopoContextDatastructure. (See Parse topology body data.) The adjustment is calculated by dividing the targeted tolerance by the Body Scale.The third argument (
bUseSameParameterization) specifies that the conversion from the surface data to Nurbs data should use the parameterization data (if any) that is already specified in the face’s surface definition.The fourth argument (
&sNurbsData) is a pointer to an empty structure in which the function stores the Nurbs data.
ASBool bUseSameParameterization = TRUE;
A3DSurfNurbsData sNurbsData;
A3D_INITIALIZE_DATA(sNurbsData);
iRet = A3DSurfBaseGetAsNurbs(sData.m_pSurface, 1e-3 / stdContextScale,
bUseSameParametrization, &sNurbsData);
Determine the result of the
A3DSurfBaseGetAsNurbsfunction. In addition to returning the standard success and failure values, this function can also return the warningA3D_SRF_NURBS_CANNOT_KEEP_PARAMETERIZATION. This warning indicates that the conversion yielded a valid Nurbs surface but that associated space parametric trimming curves may be unreliable.
if (iRet == A3D_SUCCESS ||
iRet == A3D_SRF_NURBS_CANNOT_KEEP_PARAMETERIZATION) {
…
}
If Step Parse the surface data referenced by the ``m_pSurface` member in the
A3DTopoFaceDatastructure. (See Parse generic surface data.) <Plugins_A3D_API.html#50618396_80778>`__ did not return with an error, delete theA3DSurfNurbsDatastructure by invoking theA3DSurfNurbsGetfunction with the first argument set toNULLand the second argument set to the location of the structure (&sNurbsDatain the following example).
A3DSurfNurbsGet(NULL, &sNurbsData);
Parsing PRC entities that specify graphics¶
The Acrobat 3D API Reference groups the PRC entities that specify graphics into the graphic module. The graphics module includes the following categories of PRC entities:
Graphics entities: Specify attributes that can apply to any graphic entity, such as color, line pattern, and coordinate system transformation.
Camera entities: Specify the position and direction from which a scene is viewed.
Light entities: Specify the quality of light applied to a 3D scene.
SceneDisplay: Specify viewing characteristics for a 3D representation, such as camera, lights, plane clipping, and background style.
[DG says: “parsing graphic PRC entities”. Explanation of Graphic Entities is very strange, and I cannot understand its meaning. These entities are very precise, and define precise things!!!!]
Some characteristics of PRC entities that specify graphics can be accessed only through the Acrobat 3D API miscellaneous cascaded attributes. These characteristics include the entity’s layer, coordinate system, and style attributes. Style attributes include line pattern index, RGB color index, and transparency setting. (See Parsing attributes that appear in an entity base.)
Parsing attributes that appear in an entity base¶
This section explains how to obtain data from the root-base entity or from the miscellaneous cascaded attributes.
The Acrobat 3D Library uses a parallel structure for representing attributes that apply to PRC entities that have a particular PRC entity base. Data that is specific to the entity is defined in A3D EntityName Data structures (for example the A3DAsmPartDefinitionData structure). These structures are used to create or parse the entity. Other data is defined in entities specific to the global or base types. (See the Related Pages on the Acrobat 3D API Reference.)
Parsing root-base entity data¶
Declare and initialize a
A3DRootBaseDatastructure.
A3DRootBaseData sData;
A3D_INITIALIZE_DATA(sData);
Populate the
A3DRootBaseDatastructure by invoking theA3DRootBaseGetfunction.
ASInt32 iRet = A3DRootBaseGet(p, &sData);
Save the value of the
m_pcNameto your export structure.For each
A3DMiscAttributeentity referenced by the array that is referenced bym_ppAttributes, process the contents. (See Parse the miscellaneous attribute entity.)Delete the
A3DRootBaseDatastructure.
A3DRootBaseGet(NULL, &sData);
Parse the miscellaneous attribute entity¶
Declare and initialize an
A3DMiscAttributeDatastructure.Populate the
A3DMiscAttributeDatastructure by invoking theA3DMiscAttributeGetfunction. The first argument references theA3DMiscAttributeentity (from root base datam_ppAttributesmember), and the second argument references theA3DMiscAttributeDatabeing populated.Determine whether the root data contains modeler data by checking the
m_pSingleAttributesDatamember. If its value is non-null, save the modeler data to your export structure.Save the value of the
m_pcNameattribute to your export structure.Delete the
A3DMiscAttributeDatastructure created in Step Declare and initialize an ``A3DMiscAttributeData` structure. <Plugins_A3D_API.html#50618396_78650>`__.
Parsing graphic attributes using miscellaneous cascaded attributes¶
Miscellaneous cascaded attributes manage the inheritable graphics data that can be applied to a PRC entity. Such inheritable data includes the show and remove settings, style attributes such as color and pattern, layer attributes, and coordinate system transformations.
The A3DGraphicsCreate function lets you set the graphics data for an entity. It also lets you set inheritance behavior for the attributes. These bits can specify that an attribute be inherited from a child entity or from a parent entity.
The A3DGraphicsGet function gets the graphics data for an entity, but it does not take into account inherited settings.
The following diagram illustrates the steps required to create and push miscellaneous cascaded attributes, depending on whether the entity represents a tessellation face.
To create and push a miscellaneous cascaded attributes structure¶
Declare the structure for creating and pushing a cascaded attributes structure.
Create and push a cascaded attributes structure. For entities in the tessellation module, include a pointer to the tessellation base entity (see Create and push a cascaded attributes structure for entities in the tessellated module. For all other entities in the graphics module, see Create and push a cascaded attributes structure for graphic entities.
Delete the structure created for the miscellaneous cascaded attributes.
Declare the structure for creating and pushing a cascaded attributes structure¶
Declare an empty cascaded data structure in which the cascaded attributes are to be stored. The macro
A3D_INITIALIZE_DATAclears the memory allocated to the structure and checks the size of the structure to avoid alignment problems.
A3DMiscCascadedAttributesData sAttrData;
A3D_INITIALIZE_DATA(sAttrData);
Declare a null pointer to a miscellaneous cascaded attributes object.
A3DMiscCascadedAttributes* pAttr;
Create and push a cascaded attributes structure for graphic entities¶
Create an empty miscellaneous cascaded attributes object by invoking the
A3DMiscCascadedAttributesCreatefunction, providing as an argument the address of the previously created null pointer.
ASInt32 iRet = A3DMiscCascadedAttributesCreate(&pAttr);
Invoke the
A3DMiscCascadedAttributesPushfunction, which creates theA3DMiscCascadedAttributesobject for the current PRC entity and pushes the parentA3DMiscCascadedAttributesobject onto the stack. Provide the following arguments toA3DMiscCascadedAttributesPush.The first argument (
pAttrin the following example) is a pointer to an empty miscellaneous cascaded attribute object. TheA3DMiscCascadedAttributesPushfunction populates this object.The second argument (
pBasein the following example) is a pointer to the PRC entity of interest, recast as aconst A3DRootBaseWithGraphics*.The third argument (
pFatherAttrin the following example) is a pointer to the parent entity’sA3DMiscCascadedAttributesobject. Do not confuse this structure with the parent entity’sA3DMiscCascadedAttributesDatastructure.
iRet = A3DMiscCascadedAttributesPush (pAttr, pBase, pFatherAttr);
Get the data from the newly created cascaded attributes structure by invoking the
A3DMiscCascadedAttributesGetfunction. Provide the following arguments:The first argument (
pAttrin the following example) references the cascaded attribute structure populated in Step Invoke the ``A3DMiscCascadedAttributesPush` function, which creates theA3DMiscCascadedAttributesobject for the current PRC entity and pushes the parentA3DMiscCascadedAttributesobject onto the stack. Provide the following arguments toA3DMiscCascadedAttributesPush. <Plugins_A3D_API.html#50618396_62288>`__.The second argument (sAttrData in the following example) references the empty
A3DMiscCascadedAttributesDatastructure created previously. (See Declare the structure for creating and pushing a cascaded attributes structure.) TheA3DMiscCascadedAttributesGetfunction stores the entity’s attributes in this structure.
iRet = A3DMiscCascadedAttributesGet(pAttr, &sAttrData);
Create and push a cascaded attributes structure for entities in the tessellated module¶
Invoke the
A3DMiscCascadedAttributesPushTessFacefunction, providing the following arguments:The first argument (
pAttrin the following example) is a pointer to an empty miscellaneous cascaded attribute object. TheA3DMiscCascadedAttributesPushTessFacefunction populates this object.The second argument (pRepItem in the following example) is a pointer to the representation item that contains the tessellation face.
The third argument (
pTessBasein the following example) is a pointer to the tessellation entity that contains the face, recast as aconst A3DTessBase*pointer. This argument can be cast from theA3DTess3Dentity.The fourth argument (psTessFaceData in the following example) references an array of pointers to the
A3DTessFaceDatastructures that contain the face data. Use theA3DTess3DGetfunction to obtain that structure.The fifth argument (uiFaceIndex in the following example) is the face index used with the fourth argument to access the face data from the
m_psFaceTessDatamember of the psTess3DData structure.The sixth argument (
pFatherAttrin the following example) is a pointer to the parent entity’sA3DMiscCascadedAttributesobject. Do not confuse this structure with the parent entity’sA3DMiscCascadedAttributesDatastructure.
ASInt32 iRet = A3DMiscCascadedAttributesCreate(ppAttr);
// This API is dedicated to tessellation
iRet = A3DMiscCascadedAttributesPushTessFace(pAttr, pRepItem, pTessBase,
psTessFaceData, uiFaceIndex, pFatherAttr);
A3D_INITIALIZE_DATA((*psAttrData));
iRet = A3DMiscCascadedAttributesGet(*ppAttr, psAttrData);
Save relevant data to your export structure.
Delete the structure created for the miscellaneous cascaded attributes
Delete the
A3DMiscCascadedAttributesstructure by invoking theA3DMiscCascadedAttributesDeletefunction.
A3DMiscCascadedAttributesDelete(pAttr);
Delete the
A3DMiscCascadedAttributesDatastructure by invoking theA3DMiscCascadedAttributesGetfunction, setting the first argument toNULLand the second to the address of the structure. Here is an example:
A3DMiscCascadedAttributesGet(NULL, &sAttrData);
A3DMiscCascadedAttributes* pAttr;
Terminating the interface with the Acrobat 3D API¶
When all parsing is complete, you must delete the in-memory model of the PRC, de-allocate any other memory allocations, and terminate the Acrobat 3D API.
Terminate your interface with the Acrobat 3D API¶
Delete the model file in memory. This model was created when the
A3DAsmModelFileLoadFromFilefunction was called.
A3DAsmModelFileDelete(p)
Ensure that all memory is de-allocated.
Terminate the Acrobat 3D API by invoking the
A3DDllTerminatefunction, as follows:
A3DDllTerminate();
Creating a PRC file that uses boundary representation¶
The Acrobat 3D SDK lets you create a representation item for a boundary representation that is optionally accompanied by tessellation data. Boundary representations with or without tessellation data can represent curves, or open or closed solids. (See Creating a tessellation entity for representing faceted objects.)
This section explains how to create a PRC file that represents a circular band (a co-edge) that is UV-mapped to a clear cylinder surface (pictured below). More specifically, the solid in this 3D image contains a single face, which in turn contains a cylinder and a loop. The loop contains a single co-edge that contains two circular curves. The co-edge is UV-mapped to the cylinder. The following images show the resulting image from different perspectives. To open a PDF document that contains the PRC content pictured below, click here.
The following diagram shows the tasks required to create each PRC entity to represent the image pictured above. This diagram is intended to portray a bottom-up process, where upper-level functions are not complete until their lower-level functions are completed. That is, the most basic PRC entities (such as vertices, edges and coedges) are created first, followed by the more complex PRC entities that consist of those basic PRC entities and other data. The last PRC entity to be created is the model file.
Error handling¶
For information about handling errors, see Handling errors.
Creating a model file entity and exporting it to a physical file¶
This section describes how to initiate the process of creating a model file and how to export that data to a physical file.
Create a file that contains the PRC data¶
Create a pointer that references a populated model file entity. (See Create a model file entity.) In the following example,
createModelFileis a private function that returns a pointer to a populated model file.
A3DAsmModelFile* pModelFile = createModelFile();
Create the model file entity. (See Create a model file entity.)
Save the contents of the model file to a physical file by invoking the
A3DAsmModelFileWriteToFilefunction.
if (p != NULL) {
if (_access(pcPRCName, 00) != -1)
_unlink(pcPRCName);
ASInt32 iRet = A3DAsmModelFileWriteToFile(p, NULL, pcPRCName);
Delete the model file populated in Step Create a pointer that references a populated model file entity. (See Create a model file entity.) In the following example, ``createModelFile` is a private function that returns a pointer to a populated model file. <Plugins_A3D_API.html#50618396_97368>`__.
A3DAsmModelFileDelete(pModelFile);
Note
The Acrobat 3D API functions in this chapter are described as though implicit linking were possible. Wherever you see a direct call to one of these functions, you should instead use the pointer to the function. See Implementing external linking.
Creating structure PRC entities¶
This section explains how to create the PRC entities that represent the structure of the PRC file, such as the model file, product occurrences, and part definitions. The names of structure module entities have the form A3DAsm Entity_name.
Create a model file entity¶
If the model file references multiple product occurrences, create an array to accommodate a pointer that references each product occurrence.
For each product occurrence in the model file, create a pointer that references a populated product occurrence entity. (See Create a product occurrence.) In the following example,
createOccurrenceis a private function that returns a pointer to a populated product occurrence.
A3DAsmProductOccurrence* p = createOccurrence();
Declare and initialize a model file data structure and set the values of its members, as follows:
m_uiPOccurrencesSize represents the number of child product occurrences.
m_dUnit is a multiple of millimeters that specifies the units used by the 3D data in the structure element.
m_ppPOccurrences references the array of product occurrence pointers.
A3DAsmModelFileData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_uiPOccurrencesSize = 1;
sData.m_dUnit = 1.0;
sData.m_ppPOccurrences = &p;
Encapsulate the model file data by invoking the
A3DAsmModelFileCreatefunction. The first argument is a pointer to the model file data, and the second argument is a pointer to the model file entity.
ASInt32 iRet = A3DAsmModelFileCreate(&sData, &pModelFile);
Optionally, associate the model file entity with root-level attributes (see Defining root-level attributes for a PRC entity).
Create a product occurrence¶
Declare a null pointer to a product occurrence.
A3DAsmProductOccurrence* pProductOccurrrence = NULL;
Create a pointer to a populated part definition. (See Create a part definition.) In the following example,
createPartis a private function that returns a pointer to a populated part definition entity.
A3DAsmPartDefinition* p = createPart();
Set the
m_pPartmember to reference the part created in Step Create a pointer to a populated part definition. (See Create a part definition.) In the following example, ``createPart` is a private function that returns a pointer to a populated part definition entity. <Plugins_A3D_API.html#50618396_82443>`__.
A3DAsmProductOccurrenceData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_pPart = p;
Package the product occurrence data as a PRC entity by invoking the
A3DAsmProductOccurrenceCreatefunction. The first argument is a pointer to the product occurrence data, and the second argument is an indirect pointer to the product occurrence.
ASInt32 iRet =
A3DAsmProductOccurrenceCreate(&sData, &pProductOccurrence);
Define the cascaded attributes for the product occurrence. (See Defining root-level attributes for a PRC entity.)
Create a part definition¶
Declare a null pointer to a part definition.
A3DAsmPartDefinition* pPartDefinition = NULL;
Declare and initialize a part definition data structure, as shown in the following example.
A3DAsmPartDefinitionData sData;
A3D_INITIALIZE_DATA(sData);
For each representation item referenced by this part definition, create a pointer to that representation item and populate it. (See Create a Brep model representation item.) In the following example,
createRIBrepis a private function that returns a pointer to a populated Brep representation item.
A3DRiRepresentationItem* p = createRIBrep();
Set the
m_uiRepItemsSizemember of the part definition to the number of representation items.Set the
m_ppRepItemsmember of the part definition to the array of pointers for the representation items. The following example describes a part definition that references a single representation item:
sData.m_uiRepItemsSize = 1;
sData.m_ppRepItems = &p;
Package the part definition data as a PRC entity by invoking the
A3DAsmPartDefinitionCreatefunction. The first argument is a pointer to the product occurrence data, and the second is the pointer to the part definition created in Step Declare a null pointer to a part definition..
ASInt32 iRet = A3DAsmPartDefinitionCreate(&sData, &pPartDefinition);
Creating representation item PRC entities¶
The Acrobat 3D API Reference groups the PRC entities that specify individual objects present in the CAD file into the representation item module. Representation items define a particular aspect of the geometric data. The Brep model representation item is one of the PRC entities available for packaging distinct 3D objects. Some of the other representation items include set, point set, poly Brep model, and polywire.
Create a Brep model representation item¶
Declare a pointer to a Brep model entity.
A3DRiBrepModel* pBrepModel = NULL;
Create a pointer to a populated topology Brep data entity. (See Create a topology Brep data entity.) The
createTopoBrepfunction in the following example is a private function that returns a reference to a populated topology Brep data entity.
A3DTopoBrep* p = createTopoBrep();
Declare and initialize a Brep model data structure, and set its member values. In the following example, the
m_pBrepDatamember references the Brep data entity created in the previous step, and them_bSolidmember is set toFALSE, indicating that the Brep model is a shell.
A3DRiBrepModelData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_pBrepData = p;
sData.m_bSolid = FALSE;
Package the Brep model data as a PRC entity by invoking the
A3DRiBrepModelCreatefunction. The first argument is a pointer to the Brep data structure, and the second is a pointer to the Brep model created in Step Declare a pointer to a Brep model entity..
ASInt32 iRet=A3DRiBrepModelCreate(&sData, &pBrepModel);
Creating topology PRC entities¶
The Acrobat 3D API Reference groups the PRC entities that specify topology into the topology module. The topology module uses a hierarchy of faces to define the shapes of 3D objects.
Create a topology Brep data entity¶
Create a null pointer to a topology Brep data entity.
A3DTopoBrepData* pTopoBrepData = NULL;
Tip : Do not confuse the A3DTopoBrepData entity with the A3DTopoBrepDataData structure. The former references a PRC entity (an opaque type), while the latter reveals the data in that entity.
For each topology connex data in the Brep data entity, create a pointer that references a populated topology connex entity. (See Create a topology connex entity.) In the following example,
createTopoConnexis a private function that returns a reference to a populated topology connex entity.
A3DTopoConnex* p = createTopoConnex();
If the Brep representation item references multiple topology connex entities, allocate memory for an array of references to the topology connexes in the Brep data entity.
Declare and initialize a
A3DTopoBrepDataDatastructure. Set them_ppConnexesmember to reference the array of topology connex entities, and set them_uiConnexSizemember to the number of entries in the array.
A3DTopoBrepDataData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_ppConnexes = &p;
sData.m_uiConnexSize = 1;
Package the A3DTopoBrepDataData structure as a PRC entity by invoking the
A3DAsmPartDefinitionCreatefunction. The first argument is a pointer to the Brep-data data structure (A3DTopoBrepDataData), and the second is the pointer to the Brep data entity created in Step Create a null pointer to a topology Brep data entity..
ASInt32 iRet = A3DTopoBrepDataCreate(&sData, &pTopoBrepData);
Create a topology connex entity¶
Declare a pointer to a topology connex entity.
A3DTopoConnex* pTopoConnex = NULL;
For each topology shell in the topology connex entity, create a pointer that references a populated topology shell entity. (See Create a topology shell entity.) In the following example,
createTopoShellis a private function that returns a reference to a populated topology shell entity.
A3DTopoShell* p = createTopoShell();
If the topology connex entity references multiple topology shell entities, allocate memory for an array to accommodate each topology shell entity pointer.
Declare and initialize an
A3DTopoConnexDatastructure. Set the m_ppShells member to reference the array that contains the pointers, and set the m_uiShellSize member to the number of pointers.
A3DTopoConnexData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_ppShells = &p;
sData.m_uiShellSize = 1;
Package the topology connex data as a PRC entity by invoking the
A3DTopoConnexCreatefunction. The first argument is a pointer to the Brep-data data structure (A3DTopoBrepDataData), and the second is the pointer to the topology connex entity created in Step Declare a pointer to a topology connex entity..
ASInt32 iRet = A3DTopoConnexCreate(&sData, &pTopoConnex);
Create a topology shell entity¶
Declare a null pointer to a topology shell entity.
A3DTopoShell* pTopoShell = NULL;
If the topology shell references multiple topology face entities, create an array to accommodate each pointer.
For each topology face in the topology shell, create a pointer that references a populated topology face entity. (See Create a topology face entity.) In the following example,
createTopoFaceis a private function that returns a reference to a populated topology shell entity.
A3DTopoFace* p = createTopoFace();
Declare and initialize an
A3DTopoShellDatastructure. Set them_ppFacesmember to reference the array of topology face entities, and set them_uiFaceSizemember to the number of topology shell face entities.
A3DTopoShellData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_ppFaces = &p;
sData.m_uiFaceSize = 1;
Set the
A3DTopoShellDatastructure’sm_pucOrientationWithShellmember to reference an ASUns8 integer that specifies the orientation of the surface normal with respect to the shell normal. If the shell is closed and otherwise arbitrary, the shell normal points outside the material. The following example specifies that the surface normal has the same orientation as the face and shell.
Warning
Despite the simplicity of the values it expresses, the m_pucOrientationWithShell is a pointer to an ASUns8 integer; it is not itself an ASUns8 integer.
ASUns8 orient = 1;
sData.m_pucOrientationWithShell = &orient;
Package the topology shell data as a PRC entity by invoking the
A3DTopoShellCreatefunction. The first argument is a pointer to the topology shell data, and the second is the pointer to the topology shell entity created in Step Declare a null pointer to a topology shell entity..
ASInt32 iRet = A3DTopoShellCreate(&sData, &pTopoShell);
Create a topology face entity¶
The example described here UV-maps onto a cylinder surface a topology loop representing a circular band.
Declare a null pointer to a topology face entity.
A3DTopoFace* pTopoFace = NULL;
If the topology face references multiple loop entities, declare an array to accommodate each pointer.
For each loop in the topology face, create a pointer that references a populated loop entity. (See Create a topology loop entity.) In the following example,
createTopoLoopis a private function that returns a reference to a populated loop entity.
A3DDouble outerradius = 0.5;
A3DDouble innerradius = 0.4;
A3DTopoLoop* loops[2];
loops[0] = createTopoLoop(outerradius);
loops[1] = createTopoLoop(innerradius);
Declare and initialize an
A3DTopoFaceDatastructure. Set the m_ppLoops member to reference the array of loop entity pointers, and set the m_uiLoopSize member to the number of loop entities in the array. Set the m_uiOuterLoopIndex member to the array index of the topology loop that describes the outer loop. If unknown, set that member toA3D_LOOP_UNKNOW_OUTER_INDEX.
In the following example, m_uiOuterLoopIndex indicates that the outer loop is the first entry in the loops array.
A3DTopoFaceData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_ppLoops = loops;
sData.m_uiLoopSize = 2;
sData.m_uiOuterLoopIndex = 0;
Declare a pointer that references a populated surface base entity. (See Create a surface cylinder entity.) Set the m_pSurface member of the
A3DTopoFaceDatastructure to reference the populated surface. In the following example,createSurfaceis a private function that returns a reference to a populated cylinder surface entity. The returned value is cast as a pointer to a surface base.
A3DSurfBase * p = createSurface();
sData.m_pSurface = p;
Package the topology face data as a PRC entity by invoking the A3DTopoFaceCreate function. The first argument is a pointer to the topology face data, and the second is the pointer to the topology face entity created in Step Declare a null pointer to a topology face entity..
ASInt32 iRet = A3DTopoFaceCreate(&sData, &pTopoFace);
Create a topology loop entity¶
A loop is a connected series of co-edges and describes the boundary of a face. Generally, loops are closed, having no start or end point.
Declare a null pointer to a topology loop entity.
A3DTopoLoop* pTopoLoop = NULL;
If the topology loop references multiple co-edge entities, declare an array to accommodate each pointer.
For each co-edge in the loop, do the following:
Create a pointer that references a populated circle entity with a given radius. (See Create a circular curve entity.)
Create a pointer that references a populated co-edge entity with a given curve. (See Create a topology co-edge entity.)
In the following example, createCircle is a private function that takes a radius and returns a reference to a populated circular curve entity, and createTopoCoEdge is a private function that takes a pointer to a circle entity and returns a reference to a populated co-edge entity. The circle-entity describes a curve.
A3DCrvBase* p = createCircle(radius);
A3DTopoCoEdge* q = createTopoCoEdge(p);
Declare and initialize an A3DTopoLoopData structure. Set the m_ppCoEdges member to reference the array of co-edge entity pointers, and set the m_uiCoEdgeSize member to the number of entities in the array.
A3DTopoLoopData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_ppCoEdges = &q;
sData.m_uiCoEdgeSize = 1;
Set the A3DTopoLoopData structure’s m_ucOrientationWithSurface member to specify the orientation of the loop relative to the surface normal vector. The following example specifies that the orientation is perpendicular to the surface normal vector (or parallel with the surface).
sData.m_ucOrientationWithSurface = 1;
Package the topology face data as a PRC entity by invoking the A3DTopoLoopCreate function. The first argument is a pointer to the topology loop data, and the second is the pointer to the topology loop entity created in Step Declare a null pointer to a topology loop entity..
ASInt32 iRet=A3DTopoLoopCreate(&sData, &pTopoLoop);
Create a topology co-edge entity¶
A coedge is a directed edge. The two co-edges related to an edge point in the same or opposite directions along the edge. Each co-edge is associated with a loop of one of the two neighboring/adjacent faces.
Create a pointer to a populated
A3DTopoEdgeentity. (See Create a topology edge entity.)Declare and initialize a topology co-edge data entity.
Set the m_pUVCurve member of the data entity to reference the circle entity created earlier (see Create a topology loop entity).
Set the m_pEdge member to the edge entity created in Step Create a pointer to a populated ``A3DTopoEdge` entity. (See Create a topology edge entity.) <Plugins_A3D_API.html#50618396_38878>`__.
Warning
To set the value of the m_pUVCurve member using meaningful data, you need your own modeler.
A3DTopoCoEdgeData sData;
A3D_INITIALIZE_DATA(sData);
sData.m_pUVCurve = p;
sData.m_pEdge = q;
Set the m_ucOrientationWithLoop member to indicate the relative orientation of the loop.
sData.m_ucOrientationWithLoop = 1; /* Same orientation as the adjacent co-edge
sData.m_ucOrientationUVWithLoop = 1;
Package the co-edge data as a PRC entity by invoking the A3DTopoEdgeCreate function. The first argument is a pointer to the topology loop data, and the second is the pointer to the topology edge entity created in Step Create a pointer to a populated ``A3DTopoEdge` entity. (See Create a topology edge entity.) <Plugins_A3D_API.html#50618396_38878>`__.
ASInt32 iRet = A3DTopoCoEdgeCreate(&sData, &pp);
Create a topology edge entity¶
Declare a null pointer to a topology edge entity.
A3DTopoEdge* pTopoEdge = NULL;
Declare and initialize a topology edge data structure.
A3DTopoEdgeData sData;
A3D_INITIALIZE_DATA(sData);
Populate the members with data.
Package the topology face data as a PRC entity by invoking the A3DTopoEdgeCreate function. The first argument is a pointer to the topology loop data, and the second is the pointer to the topology edge entity created in Step Declare a null pointer to a topology edge entity..
ASInt32 iRet = A3DTopoEdgeCreate(&sData, &pTopoEdge);
Creating geometry PRC entities¶
The Acrobat 3D API Reference describes the PRC entities that specify geometry in the Geometry module. This module contains these submodules:
Curves: Entities that represent different kinds of curves, such as NURBS, elliptic, and helical.
Surfaces: Entities that represent different kinds of surfaces, such as NURBS, spheric, and toric.
Common Structures for Geometric Entities: Entities that supplement data in the Curves and Surfaces modules.
This section describes the creation of a cylinder surface on which a circular co-edge is UV-mapped.
A circular curve includes a coordinate system and parameterization settings. By default, the reference domain is [0, 2PI]. A circular curve uses an A3IntervalData entity as the linear domain and an A3DMiscCartesianTransformationData structure as the coordinate system. New parameterization is computed from two coefficients applied to the reference parameterization [0, 2PI].
Create a surface cylinder entity¶
Declare a null pointer to an A3DSurfCylinder entity.
A3DSurfCylinder* pSurfCylinder = NULL;
Declare and initialize a surface cylinder data structure, and initialize the structures it contains.
A3DSurfCylinderData sData;
A3D_INITIALIZE_DATA(sData);
A3D_INITIALIZE_DATA(sData.m_sParam);
A3D_INITIALIZE_DATA(sData.m_sTrsf);
Set the UV-parameterization data of the surface cylinder data structure, which specifies how the circular curve is mapped to the cylinder. The following example specifies the trimming and orientation of the mapping:
Minimum and maximum extents in the UV domain (
sData.m_sParam.m_sUVDomain) establish the trimming contour in the final parameterization space. Each extent is a 2D vector. The following example clips the texture represented by the co-edge to the area described by [0.0, 0.0] and [360.0 40.0].Coefficients establish parameterization along the U and V axes. In this example, U values are expressed as inverted degrees (1.0/degrees). V values are expressed as inverted lengths (1.0/length).
sData.m_sParam.m_sUVDomain.m_sMin.m_dX = 0.0;
sData.m_sParam.m_sUVDomain.m_sMin.m_dY = 0.0;
sData.m_sParam.m_sUVDomain.m_sMax.m_dX = 360.0;
sData.m_sParam.m_sUVDomain.m_sMax.m_dY = 40.0;
// Parameters go from -1 to +1 in both directions
sData.m_sParam.m_dUCoeffA =
1.0 / (sData.m_sParam.m_sUVDomain.m_sMax.m_dX / 2);
sData.m_sParam.m_dUCoeffB = -1.0;
sData.m_sParam.m_dVCoeffA =
1.0 / (sData.m_sParam.m_sUVDomain.m_sMax.m_dY / 2);
sData.m_sParam.m_dVCoeffB = -1.0;
sData.m_sParam.m_bSwapUV = FALSE;
sData.m_sTrsf.m_ucBehaviour = kA3DTransformationIdentity;
Set other member values of the surface cylinder data structure. In the following example, the radius of the cylinder is set to 10.0. The unit of measure (as multiples of millimeters) was previously set for the model file entity. (See Create a model file entity.)
sData.m_dRadius = 10.0;
Package the cylinder data as a PRC entity by invoking the A3DSurfCylinderCreate function. The first argument is a pointer to the surface cylinder data, and the second is the pointer to the surface cylinder entity created in Step Declare a null pointer to an A3DSurfCylinder entity..
ASInt32 iRet = A3DSurfCylinderCreate(&sData, &pSurfCylinder);
Create a circular curve entity¶
Declare a null pointer to a circular curve entity.
A3DCrvCircle* pCrvCircle = NULL;
Declare and initialize a circular curve data structure, and initialize the structures it contains.
A3DCrvCircleData sData;
A3D_INITIALIZE_DATA(sData);
A3D_INITIALIZE_DATA(sData.m_sParam);
A3D_INITIALIZE_DATA(sData.m_sTrsf);
Set the values of the circular curve data structure. The following example sets the radius of the circle to a value originally specified during loop creation. (See Create a topology face entity.)
sData.m_dRadius = radius;
Set the values of the parameterization structure within the circular curve data structure. In this example, the interval defines the circular arc as the entire circle and the co-efficients set the parameterization across the entire length of the circular arc.
sData.m_sParam.m_dCoeffA = 1.0;
sData.m_sParam.m_dCoeffB = 0.0;
sData.m_sParam.m_sInterval.m_dMin = 0.0;
sData.m_sParam.m_sInterval.m_dMax = 360;
Set the values of the Cartesian transformation structure within the circular curve data structure. The following example sets the behavior of the Cartesian transformation data to the identity transformation.
sData.m_sTrsf.m_ucBehaviour = kA3DTransformationIdentity;
Package the curve data as a PRC entity by invoking the A3DCrvCircleCreate function. The first argument is a pointer to the curve circle data, and the second is the pointer to the circular curve entity created in Step Declare a null pointer to a circular curve entity..
ASInt32 iRet = A3DCrvCircleCreate(&sData, &pCrvCircle);
Defining root-level attributes for a PRC entity¶
The Acrobat 3D API lets you create a set of attributes named root-level attributes that can be applied to any PRC entity. These attributes are packaged as an A3DRootBase entity that is referenced from the PRC entity they describe.
A3DRootBaseData. This structure has a name and can have pointers to multipleA3DMiscAttributeentities.A3DMiscAttributeData. This structure has a name and can reference a singleA3DMiscSinglestructure.A3DMiscSingleAttributeData. This structure is used for modeler data, such as string or time. It has a title, a type designation, and data. The name in the parentA3DMiscAttributeDatamust match the title in theA3DMiscSingleAttributeData. This structure is terminal.
Note
See the Acrobat 3D API Reference for limitations on including modeler data in the root-level attributes for a PRC entity.
Here is a diagram that shows the structure of the A3DRootBase entity that can be associated with any PRC entity. The A3DMiscSingleAttributeData structures are used only for modeler attributes. The sample code that comes after the following task descriptions exemplifies this structure.
Define miscellaneous attributes that omit modeler data¶
Determine the string to use at the top level of the attributes and (optionally) the strings to use at subordinate levels.
Declare an array to accommodate pointers to the
A3DMiscAttributeentities that you will create in a subsequent step.For each subordinate-level string, declare and initialize an
A3DMiscAttributeDatastructure. Set them_pcTitlemember to the subordinate-level string. Leave them_uiSizeandm_pSingleAttributesDatamembers set to 0 because this structure omits modeler data.Package each
A3DMiscAttributeDatastructure as anA3DMiscAttributeentity by invoking theA3DMiscAttributeCreatefunction. Save the entity pointer in the array created in Step Declare an array to accommodate pointers to the ``A3DMiscAttribute` entities that you will create in a subsequent step. <Plugins_A3D_API.html#50618396_49803>`__.Declare and initialize an
A3DRootBaseDatastructure. Set itsm_pcNamemember to the top-level string. Set them_ppAttributesmember to reference the array that contains pointers to theA3DMiscAttributeentities.Invoke the A3DRootBaseSet function to package the
A3DRootBaseDatastructure as anA3DRootBaseentity associated with a PRC entity. The first argument in this call is a pointer to the entity, and the second is a pointer to theA3DRootBaseDatastructure.
Define miscellaneous attributes that include modeler data¶
Determine the strings to use for modeler data and the type represented by each string. Here are the possible types and the enumerations that identify them:
kA3DModellerAttributeTypeIntinteger (32 bits)kA3DModellerAttributeTypeRealfloating pointkA3DModellerAttributeTypeTimeinteger (32 bits), which uses the same conventions as thetime_tC datatype.kA3DModellerAttributeTypeStringUTF-8 character string
Determine the titles to use for each piece of modeler data.
Declare an array to accommodate pointers to the
A3DMiscAttributeDataentities that you will create in a subsequent step.For each modeler attribute associated with the root base entity, do the following:
Declare and initialize an A3DMiscSingleAttributeData structure. Set the
m_eTypemember to the type of the data, set them_pcDatamember to a string that represents the data, and set them_pcTitlemember to a title that identifies the data.Declare and initialize an
A3DMiscAttributeDatastructure. Set them_pcTitlemember to the same title used in the A3DMiscSingleAttributeData structure. Set them_uiSizemember to 1, and them_pSingleAtttributesDatamember to reference the A3DMiscSingleAttributeData structure.
Warning
Each A3DMiscSingleAttributeData structure that references another A3DMiscSingleAttributeData structure must reference only one such structure and must have the same title as that structure.
Package each
A3DMiscAttributeDatastructure as anA3DMiscAttributeentity by invoking theA3DMiscAttributeCreatefunction. Save the entity pointer in the array created in Step Declare an array to accommodate pointers to the ``A3DMiscAttributeData` entities that you will create in a subsequent step. <Plugins_A3D_API.html#50618396_41483>`__.Declare and initialize an
A3DRootBaseDatastructure. (See Step Declare and initialize an ``A3DRootBaseData` structure. Set itsm_pcNamemember to the top-level string. Set them_ppAttributesmember to reference the array that contains pointers to theA3DMiscAttributeentities. <Plugins_A3D_API.html#50618396_71665>`__ in Define miscellaneous attributes that omit modeler data.)Package the
A3DRootBaseDatastructure as anA3DRootBaseentity. (See Step Invoke the A3DRootBaseSet function to package the ``A3DRootBaseData` structure as anA3DRootBaseentity associated with a PRC entity. The first argument in this call is a pointer to the entity, and the second is a pointer to theA3DRootBaseDatastructure. <Plugins_A3D_API.html#50618396_44847>`__ in Define miscellaneous attributes that omit modeler data.)
The following sample code creates base root attributes that describe three sets of modeler data. For information about the relationships between the structures and entities that represent this data, see the diagram provided in Defining root-level attributes for a PRC entity.
A3DVoid setAttributes(A3DEntity* p)
{
A3DMiscSingleAttributeData Single;
A3D_INITIALIZE_DATA(Single);
Single.m_eType = kA3DModellerAttributeTypeString;
Single.m_pcTitle = "Title";
Single.m_pcData = "Simple Brep building demonstration";
A3DMiscAttributeData sAttribs;
A3D_INITIALIZE_DATA(sAttribs);
sAttribs.m_pcTitle = Single.m_pcTitle;
sAttribs.m_pSingleAttributesData = &Single;
sAttribs.m_uiSize = 1;
ASInt32 iRet = A3DMiscAttributeCreate(&sAttribs, &pAttr[0]);
Single.m_pcTitle = "Author";
Single.m_pcData = "Adobe Lyon";
sAttribs.m_pcTitle = Single.m_pcTitle;
iRet = A3DMiscAttributeCreate(&sAttribs, &pAttr[1]);
Single.m_pcTitle = "Company";
Single.m_pcData = "Adobe Systems Incorporated";
sAttribs.m_pcTitle = Single.m_pcTitle;
iRet = A3DMiscAttributeCreate(&sAttribs, &pAttr[2]);
A3DRootBaseData sRootData;
A3D_INITIALIZE_DATA(sRootData);
sRootData.m_pcName = "Trimmed surface";
sRootData.m_ppAttributes = pAttr;
sRootData.m_uiSize = 3;
iRet = A3DRootBaseSet(p, &sRootData);
}
Creating a 3D annotation that references the PRC file¶
Within an existing PDF document, create a 3D annotation. (See Creating Annotations.) Use the file created in Creating a model file entity and exporting it to a physical file to create the 3D stream dictionary. Set the 3D stream dictionary Type attribute to 3D and the Subtype attribute to PRC, as shown in the following example.
CosObj attrObj = CosStreamDict(stm3D);
CosDictPutKeyString(attrObj, "Type",
CosNewNameFromString(cosDoc, false, "3D"));
CosDictPutKeyString(attrObj, "Subtype",
CosNewName(cosDoc, false, ASAtomFromString("PRC")));
CosDictPutKeyString(cosAnnot, "3DD", stm3D);
Creating a tessellation entity for representing faceted objects¶
This section explains how to add tessellation base data to an existing representation item. The Acrobat 3D SDK defines a dedicated type you can use to create faceted entities.
Create the tessellation base data¶
Create a A3DTessBaseData structure and set its member values to represent the facets. The following explanation assumes facets are defined as triangles, although you could define facets having more than three points.
m_uiCoordSize. Set this member to the number of coordinates required to represent all facets in the object. This value is calculated as 9 *facetSize. The 9 multiplier is the number of points in each facet (3) times the number of coordinates in each point (3). ThefacetSizevariable represents the number of facets in the object.m_pdCoords. Set this member to an array of NA3DDoubleentries, where N is the value calculated for them_uiCoordSizemember.
Add coordinates for each vertex of each facet to the array referenced by the
m_pdCoordsmember. The X, Y, and Z coordinates for each vertex are represented in sequential entries in the array, as shown in this example:
sTessBaseData.m_pdCoords[j++] = x;
sTessBaseData.m_pdCoords[j++] = y;
sTessBaseData.m_pdCoords[j++] = z;
Create the tessellation facet data¶
Create an A3DTess3DData structure and set its members to represent the facet normals:
m_uiNormalSize. Set this member to the size of the array required to represent the normals for all facets in the objects. This is calculated as 3 *facetSize. The 3 multiplier is the number of cordinates to represent each vector.m_pdNormals. Set this member to an array of NA3DDoubleentries, where N is the value calculated for them_uiNormalSizemember.m_uiTriangulatedIndexSize. Set this member to the number of entries required to represent the indexes associated with each facet in the objects. Each facet can have one to four indexes that reference texture coordinates, one index that references a facet normal, and three indexes that reference vertices. Normals are read from the
m_pdNormalsarray, and textures are read from them_pdTextureCoordsarray.m_puiTriangulatedIndexes. Set this member to an array of N ASUns32 entries, where N is the number of entries in the m_uiTriangulatedIndexSize member. This array contains the indexes of the points (m_pdCoords), normals (m_pdNormals), and texture arrays for each face’s triangulated representation. The entries in this array correspond to the contents in the
A3DTessFaceDataentity.
Add the indexes for each facet, considering the number of entries to represent each facet. Each facet contains the following sequential representations in this array:
(Optional) Index of the first texture in the array referenced by the m_pdTextureCoords member. This entry can be followed by three more entries for additional texture indexes.
Index of the facet normal in the array referenced by the m_pdNormals member.
Index of the first facet vertex in the array referenced by the m_pdCoords member.
Index of the second facet vertex in the array referenced by the m_pdCoords member.
Index of the third facet vertex in the array referenced by the m_pdCoords member.
In the following example for STL data, facetSize is set to 0 for the first facet represented by the array and to 1 for the second facet in the array.
sTess3DData.m_puiTriangulatedIndexes[4 * facetSize] = i;
sTess3DData.m_puiTriangulatedIndexes[4 * facetSize + 1] = j;
sTess3DData.m_puiTriangulatedIndexes[4 * facetSize+2] = j + 3;
sTess3DData.m_puiTriangulatedIndexes[4 * facetSize+3] = j + 6;
Add the coordinates of each facet normal to the array referenced by the
m_pdNormalsmember. The X, Y, and Z coordinates for each vector are represented in sequential entries in the array, as shown in this example:
sTess3DData.m_pdNormals[i++] = x;
sTess3DData.m_pdNormals[i++] = y;
sTess3DData.m_pdNormals[i++] = z;
For each face, create an
A3DTessFaceDataentity and set its member values as follows:m_usUsedEntitiesFlags. Set this member to an enumeration that specifies the entities used in the current face tessellation. For example, thekA3DTessFaceDataTriangleOneNormalenumeration specifies that the face data is a triangle with a single normal facet.m_uiSizesTriangulatedSize. Set this member to the number of entries in the array referenced by them_puiSizesTriangulatedmember.m_puiSizesTriangulated. Set this value to the repetition sequence applied to them_usUsedEntitiesFlagsmember. A single entry with a value of 1 indicates that the first flag inm_usUsedEntitiesFlagsapplies to all face data.m_uiStartTriangulated. Set this value to the starting index for the wire in the array of point indexes of theA3DTess3DDataentity.
Set the
A3DTess3DDatastructure’sm_psFaceTessDatamember to reference an array that in turn references each face that applied to the facets. Set them_uiFaceTessSizemember to the number of faces in this array.Declare a pointer to a null
A3DTess3Dentity.Package the tessellation data by invoking the
A3DTess3DCreatefunction, providing the location of theA3DTess3DDatastructure as the first argument and the location of theA3DTess3Dpointer as the second argument.
A3DTess3D* pTess3D = NULL;
A3DTess3DCreate(&sTess3DData, &pTess3D);
Package the tessellation base data with in the
A3DTess3Dentity by invoking theA3DTessBaseSetfunction.
A3DTessBaseSet(&pTess3D, &sTessBaseData);
Add the
A3DTess3Ddata to a representation item. (See Creating representation item PRC entities.)
The following code sample creates an A3D tessellation entity from a file that conforms to the STL format. It packages this entity with a poly Brep model representation item. STL is a file format native to the stereolithography CAD software created by 3D Systems.
// Create structure for facet data
A3DTessBaseData sTessBaseData;
A3D_INITIALIZE_DATA(sTessBaseData);
sTessBaseData.m_uiCoordSize = 9 * facetSize;
sTessBaseData.m_pdCoords =
(A3DDouble*)allocCllBck(sTessBaseData.m_uiCoordSize * sizeof(A3DDouble));
//Create structure for normal vector data
A3DTess3DData sTess3DData;
A3D_INITIALIZE_DATA(sTess3DData);
sTess3DData.m_uiNormalSize = 3 * facetSize;
sTess3DData.m_pdNormals =
(A3DDouble*)allocCllBck(sTess3DData.m_uiNormalSize * sizeof(A3DDouble));
//Total amount of indexes is calculated as follows:
//(one normal + one triangle (3 points)) * Number of facets
sTess3DData.m_uiTriangulatedIndexSize = 4 * facetSize;
sTess3DData.m_puiTriangulatedIndexes =
(ASUns32*)allocCllBck(sTess3DData.m_uiTriangulatedIndexSize *
sizeof(ASUns32));
//Set up variables used in reading STL data.
A3DUTF8Char name[100];
A3DUTF8Char dummy[100];
A3DDouble x, y, z;
ASInt32 iRet = 0;
ASUns32 i = 0;
ASUns32 j = 0;
const A3DUTF8Char* pcName = NULL;
rewind(stlFile);
curr = 0;
facetSize = 0;
memset(sBuffer, 0, A3D_MAX_BUFFER);
while(fgets(sBuffer, A3D_MAX_BUFFER, stlFile) > 0) {
sscanf(sBuffer, "%s", key);
if(!_stricmp(key, "solid")) {
iRet = sscanf(sBuffer, "%s %s", key, name);
if (iRet != 2)
sprintf(name,"unnamed");
} else if (!_stricmp(key, "facet")) {
iRet = sscanf(sBuffer,"%s %s %lf %lf %lf",key,dummy,&x,&y,&z);
sTess3DData.m_puiTriangulatedIndexes[4 * facetSize] = i;
sTess3DData.m_puiTriangulatedIndexes[4 * facetSize + 1] = j;
sTess3DData.m_puiTriangulatedIndexes[4 * facetSize + 2] = j + 3;
sTess3DData.m_puiTriangulatedIndexes[4 * facetSize + 3] = j + 6;
sTess3DData.m_pdNormals[i++] = x;
sTess3DData.m_pdNormals[i++] = y;
sTess3DData.m_pdNormals[i++] = z;
facetSize++;
} else if (!_stricmp(key, "vertex")) {
iRet = sscanf(sBuffer, "%s %lf %lf %lf", key, &x, &y, &z);
sTessBaseData.m_pdCoords[j++] = x;
sTessBaseData.m_pdCoords[j++] = y;
sTessBaseData.m_pdCoords[j++] = z;
}
curr += strlen(sBuffer);
prgIncCllBck(curr);
memset(sBuffer, 0, A3D_MAX_BUFFER);
}
fclose(stlFile);
prgEndCllBck();
//one can consider that STL consists in one single face made of total amount of triangles
A3DTessFaceData sTessFaceData;
A3D_INITIALIZE_DATA(sTessFaceData);
sTessFaceData.m_usUsedEntitiesFlags = kA3DTessFaceDataTriangleOneNormal;
sTessFaceData.m_uiSizesTriangulatedSize = 1; /* size of the next array */
sTessFaceData.m_puiSizesTriangulated = &facetSize;
sTessFaceData.m_uiStartTriangulated = 0;
//so, only one face
sTess3DData.m_uiFaceTessSize = 1;
sTess3DData.m_psFaceTessData = &sTessFaceData;
A3DTess3D* pTess3D = NULL;
A3DTess3DCreate(&sTess3DData, &pTess3D);
A3DTessBaseSet(pTess3D, &sTessBaseData);
// Create a PolyBrepModel representation item
A3DRiPolyBrepModel *pRiPolyBrepModel = NULL;
A3DRiPolyBrepModelData sPolyBrepModelData;
A3D_INITIALIZE_DATA(sPolyBrepModelData);
sPolyBrepModelData.m_bIsClosed = TRUE;
A3DRiPolyBrepModelCreate(&sPolyBrepModelData, &pRiPolyBrepModel);
// Assign the tessellation to the PolyBrepModel
A3DRiRepresentationItemData sRiData;
A3D_INITIALIZE_DATA(sRiData);
sRiData.m_pTessBase = pTess3D;
A3DRiRepresentationItemSet(pRiPolyBrepModel, &sRiData);