Mechanical Modeler |
Part Design |
Implementing a Mechanical Design Feature BuildingImplementing the CATIBuild and CATIBuildShape interfaces |
Use Case |
AbstractThis article discusses the CAAPriUserPad use case. This use case explains how to implement the CATIBuild and CATIBuildShape interfaces for mechanical design features. A simplified pad feature is used as a mechanical feature as example. A knowledge of the Mechanical Modeler [1] is strongly recommended. |
This use case is intended to help you make your first steps in programming with Part Design. Its main intent is to introduce important concepts about the way to implement the CATIBuild and CATIBuildShape interfaces of Mechanical Design feature. Specifically, you will learn how to:
Before getting to this use case itself, refer to the article "Integrating a New Geometrical Feature in the Update Mechanism" [2] which explains in details how to implement the CATIBuild and CATIBuildShape interfaces.
[Top]
CAAPriBuildUserPad is a use case of the CAAPartInterfaces.edu framework that illustrates the PartInterfaces and MechanicalModeler frameworks capabilities.
[Top]
The goal of CAAPriBuildUserPad is to show how to implement the CATIBuild and CATIBuildShape interfaces on a given form feature, namely a user pad. The user pad already exists as a StartUp in the CAAPriFormFeature catalog and has the type CAAPriUserPad. It is a form feature, in other words the CAAPriUserPad StartUp derives from the MechanicalFormFeature StartUp [3].
The CAAPriBuildUserPadMain.m module contains a main program that creates a Part document, instantiates the CAAPriUserPad StartUp, calls its Build method, saves the resulting Part document Fig.2, instantiates again the CAAPriUserPad StartUp with a new sketch, calls its Build method, and saves the resulting Part in a second Part document Fig.3.
The Build in Details
Build a feature consists in to create a result. A result is:
Build
method constructs an object which manages the access stability of the CATCell
of the CATBody. This object is a scope created by the procedural
report of the User Pad. The following schema explains in details the construction of a form feature.
A form feature is a solid feature (in opposite to a surfacic feature) which is a
chain link. These links are chained together by the ResultIN
and ResultOUT
attributes. The ResultIN
attribute of a solid feature references the
ResultOUT
attribute of the previous feature in the chain. Refer to the article entitled
"Specification/Result Mechanism Applied to Mechanical Feature" [5]
for complete details about the ResultIN
and ResultOUT
attributes.
BuildShape
method builds a scope and
a CATBody named Topo C - This result is associated with the form
feature itself - The User Pad in this example.Build
method builds a scope and
a CATBody named Topo B - This result is associated with the SolidB
feature. This feature is named the result feature of the form feature. Topo
B
is computed by performing a logical operation between Topo C
and the geometry associated to the Solid A
feature (Topo
A)
.
Solid A
being the previous shape before
the current feature in the chain.[Top]
To launch CAAPriBuildUserPad, you will need to set up the build time environment, then compile CAAPriBuildUserPad along with its prerequisites, set up the run time environment, and then execute the use case [6].
Launch the use case as follows:
e:>CAAPriBuildUserPadMain outputDirectory\CAAUserPad1.CATPart outputDirectory\CAAUserPad2.CATPart |
$ CAAPriBuildUserPadMain outputDirectory/CAAUserPad1.CATPart outputDirectory/CAAUserPad2.CATPart |
where:
outputDirectory |
The directory into which CAAUserPad1.CATPart and CAAUserPad2.CATPart
will be stored |
CAAUserPad1.CATPart
| The file that contains the pad created |
CAAUserPad2.CATPart |
The file that contains the pad after it is modified |
[Top]
The CAAPriBuildUserPadMain use case is made of a main program named CAAPriBuildUserPad and located in the CAAPriBuildUserPadMain.m module of the CAAPartInterfaces.edu framework. The CATIBuild and CATIBuildShape interface implementations are located in the CAAPriBuildUserPad.m module of the same framework.
Windows |
InstallRootDirectory\CAAPartInterfaces.edu\CAAPriBuildUserPad.m\ InstallRootDirectory\CAAPartInterfaces.edu\CAAPriBuildUserPadMain.m\ |
Unix |
InstallRootDirectory/CAAPartInterfaces.edu/CAAPriBuildUserPad.m/ InstallRootDirectory/CAAPartInterfaces.edu/CAAPriBuildUserPadMain.m/ |
where InstallRootDirectory
is the directory where the CAA CD-ROM
is installed.
[Top]
CATIBuild is implemented using a class named CAAPriEBuild class
that is a code extension of the late type CAAPriUserPad. Build
,
the unique method of this interface has always this structure:
... HRESULT CAAPriEBuild::Build () { HRESULT rc = E_FAIL ; Declaring the Useful Pointers CATTry { Computing the Form of the Feature Removing all Possible Update Errors Retrieving Data for the Procedural Report Creating the Procedural Report Running the Topological Operators Storing the Procedural Report Cleaning the Useless Data } // Managing the Errors CATCatch(CATMfErrUpdate , pUpdateError) { Managing the CATMfErrUpdate Error } CATCatch(CATError , pError) { Managing the CATError Error } CATEndTry return rc ; } ... |
This method contains a CATTry
and CATCatch
sections because some methods can throw an error [7].
[Top]
Before the CATTry
section you declare all the pointers:
CATTry
and CATCatch
sections: such
as piUpdateErrorOnThis
the CATIUpdateError interface
pointer on the user pad.
CATTry
section and not released before the
call of a method which can throw an error
... CATIUpdateError * piUpdateErrorOnThis = NULL; CATIBuildShape * piBuildShape = NULL; CATIMfProcReport * piProcReport = NULL; CATGeoFactory * piGeomFactory = NULL; CATDynBoolean * pOperatorBool = NULL; CATSoftwareConfiguration * pSoftConfig = NULL ; rc = QueryInterface( IID_CATIUpdateError , (void**) &piUpdateErrorOnThis); if ( FAILED(rc) ) return rc ; ... |
All this pointers will be explained in the next sections.
[Top]
Before to compute the final result of the feature, its form is
necessary. It is computed thanks to the BuildShape
method.
... CATIBuildShape * piBuildShape = NULL; rc = QueryInterface(IID_CATIBuildShape,(void**)&piBuildShape); if ( SUCCEEDED(rc) ) { int val = piBuildShape->BuildShape(); if ( 0 == val ) { rc = E_FAIL ; } piBuildShape->Release(); piBuildShape = NULL ; } ... |
The BuildShape
method can throw an error or return an error.
[Top]
It is safer to remove all possible update error that may be associated to the
current User Pad feature. To do so, use the UnsetUpdateError
of the
CATIUpdateError interface. Refer to the article entitled "A
Description of Update Errors" [8] for details on
this interface.
... rc = QueryInterface( IID_CATIUpdateError , (void**) &piUpdateErrorOnThis); if ( SUCCEEDED(rc) ) { piUpdateErrorOnThis->UnsetUpdateError(); } ... |
The implementation of CATIUpdateError interface for the User Pad is provided by an extension of late type MechanicalFeature. Since UserPad late type derives from MechanicalFeature late type, see the Fig.1, you automatically benefit from this implementation.
[Top]
This step consists in three sub-steps which are :
... CATIShapeFeatureBody * pIShapeFeatureBodyOnThis = NULL ; if ( SUCCEEDED(rc) ) { rc = QueryInterface( IID_CATIShapeFeatureBody,(void**) &pIShapeFeatureBodyOnThis); } CATISpecObject_var spResultIn ; if ( SUCCEEDED(rc) ) { CATListValCATISpecAttribute_var *pListSpecAttribute = NULL ; pListSpecAttribute = pIShapeFeatureBodyOnThis->GetBodyINAttributes(); if ( NULL != pListSpecAttribute ) { CATISpecAttribute_var spSpecAttribute = (*pListSpecAttribute)[1]; if ( NULL_var != spSpecAttribute ) { spResultIn = spSpecAttribute->GetSpecObject(); } ... } } ... |
The form feature implements the CATIShapeFeatureBody (MechanicalModeler)
interface. This interface enables you to retrieve the ResultIN
attribute
associated with the feature. This attribute, spSpecAttribute
, is
always the first element of the list returned by the GetBodyINAttributes
method. As usual, to retrieve the feature referenced by the attribute use the GetSpecObject
method of the CATISpecAttribute (ObjectSpecsModeler) interface. spResultIn
will be one of the two elements following by the procedural report. The second
is this.
ResultIN
and this) The first is those associated with the ResultIN
feature. In the Fig.4, it is the CATBody named TopoA
.
You always use the CATIShapeFeatureBody (MechanicalModeler)
interface. The first element of the list returned by the GetBodyIN
method is the CATBody of the ResultIN
feature, spCATBodyOnResultIn
.
... CATBody_var spCATBodyOnResultIn ; if ( SUCCEEDED(rc) ) { CATListValCATBaseUnknown_var *pListBodyIn = NULL ; pListBodyIn = pIShapeFeatureBodyOnThis->GetBodyIN("CATBody"); if ( NULL != pListBodyIn ) { spCATBodyOnResultIn = (*pListBodyIn)[1]; ... } } ... |
The second is those associated with this. It is the form
computed by the BuildShape
method. In the Fig.4, it is
the CATBody named TopoC.
You always use the CATIShapeFeatureBody (MechanicalModeler)
interface. The first element of the list returned by the GetShape
method is the CATBody of this, spCATBodyOnThis
.
... CATBody_var spCATBodyOnThis ; if ( SUCCEEDED(rc) ) { CATListValCATBaseUnknown_var *pListBody = NULL ; pListBody = pIShapeFeatureBodyOnThis->GetShape("CATBody"); if ( NULL != pListBody ) { spCATBodyOnThis = (*pListBody)[1]; ... } } ... |
If the ResultIN
feature does not exist and the form
exists, the form feature is the first of the chain, so the build operation is
done. The "Creating the Procedural
Report", "Run the
Topological Operators" and "Storing the Procedural Report"
sections are skipped.
If the form does not exist, it is an error, the returned code of
the Build
method will be E_FAIL.
[Top]
The procedural report is the means to generate the scope of the feature by using the topological report to generate the name of the following cells. The procedural report is managed by the CATIMfProcReport interface.
The first thing is to declare the following cells by the procedural journal during the Build operation. In the case of a form feature, the specifications to follow are always this, and if the the body exists for ResultIN, ResultIN too.
... CATLISTV(CATBaseUnknown_var) ListSpec; CATListOfCATUnicodeString ListKeys; ListSpec.Append( this ); ListKeys.Append( MfKeyNone ); if (NULL_var != spCATBodyOnResultIn) { ListSpec.Append( spResultIn); ListKeys.Append( MfKeyNone ); } ... |
ListSpec
is the list of specifications to follow, and ListKeys
is the list of associated keys. These two lists have the same size. The default
value of a key is MfKeyNone
. A different key value will indicate
that the historical relationship of a node should be replaced with a user
information. The value of the key must be in relationship with the
information given by the topological report.
... if ( SUCCEEDED(rc) ) { rc = QueryInterface( IID_CATIMfProcReport , (void**) &piProcReport ); if ( SUCCEEDED(rc) ) { int BoolOper = 1; piProcReport->CreateProcReport(ListSpec,ListKeys,BoolOper); } } ... |
Once the CATIMfProcReport interface pointer on the User Pad is
retrieved, piProcReport
, you can create the procedural report
thanks to the CreateProcReport
method. The last argument of this
method is 1
because the result ( the scope ) will be affected to
the solid feature and not the user pad itself. On the Fig.4 this
solid feature is named SolidB
. Note
that piProcReport
is declared at the top of the Build
method because it can be released in a CATCatch
section.
[Top]
This step consists in three sub-steps which are always:
The geometrical factory is handled by the CATGeoFactory interface. This interface is implemented by the geometrical container of the Part document [9]. You retrieve this container thanks to the CATIContainerOfDocument interface implemented on the Part document. The CATILinkableObject interface is the means for each feature to retrieve its containing document.
... if ( SUCCEEDED(rc) ) { CATILinkableObject *piLinkableObjectOnUserPad= NULL; rc = QueryInterface( IID_CATILinkableObject, (void**)& piLinkableObjectOnUserPad); if ( SUCCEEDED(rc) ) { CATDocument * pDocument = NULL ; pDocument = piLinkableObjectOnUserPad->GetDocument(); if ( NULL != pDocument ) { CATIContainerOfDocument * pIContainerOfDocument = NULL ; rc = pDocument->QueryInterface(IID_CATIContainerOfDocument, (void**)& pIContainerOfDocument ); if ( SUCCEEDED(rc) ) { CATIContainer * pIContainerOnGeomContainer = NULL ; rc = pIContainerOfDocument->GetResultContainer (pIContainerOnGeomContainer); if ( SUCCEEDED(rc) ) { rc = pIContainerOnGeomContainer->QueryInterface( IID_CATGeoFactory , (void**) &piGeomFactory ); ... } ... |
The GetResultContainer
is the method of the CATIContainerOfDocument
to retrieve the geometrical container. piGeomFactory
is the pointer
on the geometrical factory interface. This pointer is declared at
the beginning of the Build
method because it can be released in
a CATCatch
section.
The procedural report then provides a pointer on a new topological journal that will log all topological operations.
... CATTopData TopData ; if ( SUCCEEDED(rc) ) { CATCGMJournalList *pCGMJournalList = piProcReport->GetCGMJournalList(); TopData.SetJournal(pCGMJournalList) ; pSoftConfig = new CATSoftwareConfiguration(); TopData.SetSoftwareConfiguration(pSoftConfig) ; } ... |
pCGMJournalList
is the pointer on the topological journal. This
pointer must not be released. pSoftConfig
is a pointer
declared at the beginning of
the Build
method because it can be released in a CATCatch
section.
This section consists in to valuate, pResultBody
, a CATBody
instance. This pointer is declared locally, and is not declared at the top of the
method. It is not necessary since its lifecycle is managed by the DeletedProcReport
method in the CATCatch
sections.
... CATBody *pResultBody = NULL ; .... ... |
There are two cases two consider:
spCATBodyOnResultIn
is the CATBody associated with the ResultIN feature, if this
smart pointer is not null, the user pad has a RESULTIN , so it is not the
first solid feature of the body feature.
... if (NULL_var != spCATBodyOnResultIn) { CATDynBooleanType internalOperType = CATBoolUnion; pOperatorBool = ::CATCreateDynBoolean(piGeomFactory, &TopData, internalOperType, spCATBodyOnResultIn, spCATBodyOnThis); if ( NULL != pOperatorBool ) { pOperatorBool->Run(); pResultBody = pOperatorBool->GetResult(); } } ... |
A boolean operation is performed between the User Pad feature shape (spCATBodyOnThis
)
and the
topological result of the previous feature (spCATBodyOnResultIn
). The topological journal which is the
second argument of the CATDynCreateBoolean
global function is also updated.
pOperatorBool
is a CATDynBoolean interface pointer declared at
the top of the Build
method. pResultBody
is
the resulting topology, the CATBody named TopoB
on the Fig.4
The body associated with the result is the body created by the CATIBuildShape interface. But since a topological result can only be associated with an unique geometrical feature, a new CATBody is created. Nevertheless, if a CATBody is unique for a geometrical feature, cells can be shared between two CATBody. So the resulting CATBody will be created using the cells (the domains) of the body created by the CATIBuildShape interface.
... pResultBody = piGeomFactory->CreateBody(); if ( NULL != pResultBody ) { CATDomain *Domain = NULL; int NbDomain = spCATBodyOnThis->GetNbDomains(); for (int i = 1; i <= NbDomain; i++) { Domain = spCATBodyOnThis->GetDomain(i); pResultBody->AddDomain(Domain); } } ... |
spCATBodyOnThis
is the smart pointer on the CATBody
created by the
CATIBuildShape interface. The valuation of this pointer has been done in the Retrieving the two CATBody
(of ResultIN
and this section.
[Top]
It is now high time to store (fill) the procedural report corresponding to
the creation of the geometric result of the User Pad. That's the job of the CATIMfProcReport::StoreProcReport
method.
... if ( SUCCEEDED(rc) ) { if ( NULL != pResultBody ) { int BoolOper = 1 ; piProcReport->StoreProcReport(pResultBody,Copy, BoolOper); } else { CATMfErrUpdate *pErrorNoIntersection = new CATMfErrUpdate(); CATUnicodeString Diagnostic("Error during boolean operation."); pErrorNoIntersection->SetDiagnostic(1,Diagnostic); CATThrow(pErrorNoIntersection); } } } ... |
The last argument of the StoreProcReport
method, BoolOper,
is the same as the value in the CreateProcReport
method.
[Top]
In this last part of the CATTry
section, you clean the data
declared in the first section entitled "Declaring
the Useful Pointers" and not released/deleted during the CATTry
section. For example, the piBuildShape
pointer is not released here, once if the BuildShape
method do not throw an error, the pointer is released just after the BuildShape
call. See the "Computing the
Form of the Feature" section.
Generally, you have to consider:
pOperatorBool
, the
topological operator
piUpdateErrorOnThis
piProcReport
pSoftConfig
piGeomFactory
Some errors may be thrown during these previous operations, the CATTry
bloc catches them. The CATCatch
blocks treats the error. There
are two kinds of errors:
Each CATCatch
section processes the error and cleans
the pointers declared at the top of the Build
method.
The highest-level errors are of type CATMfErrUpdate. The error is re-thrown without modification.
...
CATCatch ( CATMfErrUpdate , pUpdateError)
{
if(NULL != piUpdateErrorOnThis)
{
piUpdateErrorOnThis->SetUpdateError(pUpdateError);
piUpdateErrorOnThis->Release();
piUpdateErrorOnThis = NULL ;
}
// Here the pointers declared at the top of the
|
All other types of errors derive from CATError. The following code associates the diagnostic and the error.
...
CATCatch ( CATError , pError)
{
CATMfErrUpdate *pErrorToThrow = new CATMfErrUpdate();
pErrorToThrow->SetDiagnostic(1,pError->GetNLSMessage());
::Flush(pError);
if(NULL != piUpdateErrorOnThis)
{
piUpdateErrorOnThis->SetUpdateError(pErrorToThrow);
piUpdateErrorOnThis->Release();
piUpdateErrorOnThis = NULL ;
}
// Here the pointers declared at the top of the
|
A new CATMfErrUpdate is created. pError
, the CATError,
must be released in the error process. The Flush
global function do
that.
In the two CATCatch
sections it is important to :
DeleteProcReport
method.and for the data declared in the first section entitled "Declaring the Useful Pointers":
pOperatorBool
CATTry
section: ( You should always have, at least, these five pointers for a form
feature)
piUpdateErrorOnThis
piProcReport
pSoftConfig
piGeomFactory
piBuildShape
[Top]
CATIBuildShape is implemented using a class named CAAPriEBuildShape
class that is a data extension of the late type CAAPriUserPad. BuildShape
,
the unique method of this interface has always this structure:
... int CAAPriEBuildShape::BuildShape () { int rcode = 1 ; //OK HRESULT rc = E_FAILD; Declaring the Useful Pointers CATTry { Removing all Possible Update Errors Retrieving Data for the Procedural Report Creating the Procedural Report Running the Topological Operator Storing the Procedural Report Cleaning the Useless Data } // Managing the Errors CATCatch(CATMfErrUpdate , pUpdateError) { Managing the CATMfErrUpdate Error } CATCatch(CATError , pError) { Managing the CATError Error } CATEndTry if ( FAILED(rc) ) { rcode = 0 ; } return rcode ; } ... |
This method contains a CATTry
and CATCatch
sections because some methods can throw an error [7].
[Top]
Before the CATTry
section you declare all the pointers:
CATTry
and CATCatch
sections: such
as piUpdateErrorOnThis
the CATIUpdateError interface
pointer on the user pad.
CATTry
section and not released before the
call of a method which can throw an error
... CATIUpdateError * piUpdateErrorOnThis = NULL; CATTopPrism * pOperatorPrism = NULL; CATIPrtProfile * pPrtProfile = NULL; CATIMfProcReport * piProcReport = NULL; CATGeoFactory * piGeomFactory = NULL; CATSoftwareConfiguration * pSoftConfig = NULL ; CATBody_var spBodyOnProfile ; ... |
All this pointers will be explained in the next sections.
[Top]
It is safer to remove all possible update error that may be associated to the
current user pad feature. To do so, use the UnsetUpdateError
of the
CATIUpdateError interface.
... rc = QueryInterface( IID_CATIUpdateError , (void**) &piUpdateErrorOnThis); if ( SUCCEEDED(rc) ) { piUpdateErrorOnThis->UnsetUpdateError(); } ... |
[Top]
This step consists in three sub-steps which are:
The profile is an attribute of the UserPad feature and referenced in the "Profile"
string.
... CATMathDirection ExtrusionDirection ; CATISpecObject_var spSpecObjectOnProfileElt; if ( SUCCEEDED(rc) ) { CATISpecObject * pSpecObjectOnThis = NULL; rc = QueryInterface( IID_CATISpecObject , (void**) &pSpecObjectOnThis ); if ( SUCCEEDED(rc) ) { CATUnicodeString strProfile = "Profile"; CATISpecAttribute * pProfileAtt = NULL ; pProfileAtt = pSpecObjectOnThis->GetAttribute(strProfile); pSpecObjectOnThis->Release(); pSpecObjectOnThis = NULL ; if ( NULL != pProfileAtt ) { CATISpecObject * pSpecObjectOnProfileAtt = NULL; pSpecObjectOnProfileAtt = pProfileAtt->GetSpecObject(); ... |
pProfileAtt
is the "profile" attribute of the User
Pad. pSpecObjectOnProfileAtt
is the feature associated with this
attribute. The CATIPrtProfile
interface applied to pSpecObjectOnProfileAtt
enables you to retrieve the direction of extrusion, ExtrusionDirection
and the profile itself, spSpecObjectOnProfileElt.
... if ( NULL != pSpecObjectOnProfileAtt ) { rc = pSpecObjectOnProfileAtt->QueryInterface( IID_CATIPrtProfile , (void**) &pPrtProfile ); pSpecObjectOnProfileAtt->Release(); pSpecObjectOnProfileAtt = NULL ; if ( SUCCEEDED(rc) ) { CATMathPlane SketchPlane ; rc = pPrtProfile->GetPlane(SketchPlane) ; if ( SUCCEEDED(rc) ) { CATMathVector normalDir; SketchPlane.GetNormal(normalDir); ExtrusionDirection = normalDir ; if ( SUCCEEDED(rc) ) { pPrtProfile->GetElement(1,spSpecObjectOnProfileElt) ; ... |
The Pad direction, ExtrusionDirection
, has been defined normal
to the sketch plane. The profile, spSpecObjectOnProfileElt, retrieved by the GetElement
method of the CATIPrtProfile
interface will be the feature followed by the procedural report.
To be complete, if spSpecObjectOnProfileElt, pSpecObjectOnProfileAtt
or pProfileAtt
are NULL or NULL_var, an update error [8]
is thrown like this:
... CATMfErrUpdate *pError = new CATMfErrUpdate(); CATUnicodeString Diagnostic("xxxxx"); pError ->SetDiagnostic(1,Diagnostic); CATThrow(pError ); ... |
In this case the CATTry
section in interrupted.
pPrtProfile
is the CATIPrtProfile interface pointer on
the feature referenced by the Profile
attribute of the User Pad.
This part consists in to compute the CATBody forming the profile to
extrude, spBodyOnProfile. But previously some checks are necessary to
validate the profile.
... if ( SUCCEEDED(rc) ) { int nbContour = pPrtProfile->GetContourCount(); if (nbContour == 1) { CATBody_var LocalBody ; pPrtProfile->GetBody(0,LocalBody); CATDomain * pDomain = LocalBody->GetDomain(1); CATWire_var spWireOnDomain(pDomain); if (spWireOnDomain != NULL_var) { CATBoolean isClosed = spWireOnDomain->IsClosed(); if(TRUE != isClosed) { CATMfErrUpdate *pErrorNotClosedProfile = new CATMfErrUpdate(); CATUnicodeString Diagnostic("The associated profile is not closed"); pErrorNotClosedProfile->SetDiagnostic(1,Diagnostic); CATThrow(pErrorNotClosedProfile); } ... |
If the profile is wrong an error, pErrorNotClosedProfile
, is
generated and thrown to interrupt the process.
Once the Profile is validated, spBodyOnProfile
is computed by
the GetBody
method of the CATIPrtProfile interface. This CATBody
should be removed from the topological container at the end of the method.
... pPrtProfile->GetBody(1,spBodyOnProfile); if ( NULL_var == spBodyOnProfile ) { CATMfErrUpdate *pErrorNoProfileToExtrude = new CATMfErrUpdate(); CATUnicodeString Diagnostic("No elt to extrude"); pErrorNoProfileToExtrude->SetDiagnostic(1,Diagnostic); CATThrow(pErrorNoProfileToExtrude); ... |
[Top]
The procedural report is the means to generate the scope of the feature by using the topological report to generate the name of the following cells. The procedural report is managed by the CATIMfProcReport interface. The first thing is to declare the following cells by the procedural journal during the Build operation.
... CATLISTV(CATBaseUnknown_var) ListSpec; CATListOfCATUnicodeString ListKeys; if ( SUCCEEDED(rc) ) { ListSpec.Append( spSpecObjectOnProfileElt ); ListKeys.Append( MfKeyExtrudedFrom ); } ... |
ListSpec
is the list of specifications to follow, and ListKeys
is the list of associated keys. There is only one specification, the profile, spSpecObjectOnProfileElt
and the associated keyword is valuated to MfKeyExtrudedFrom
.
... if ( SUCCEEDED(rc) ) { rc = QueryInterface( IID_CATIMfProcReport , (void**) &piProcReport ); if ( SUCCEEDED(rc) ) { int BoolOper = 0; piProcReport->CreateProcReport(ListSpec,ListKeys,BoolOper); } } ... |
Once the CATIMfProcReport interface pointer on the User Pad is
retrieved, piProcReport
, you can create the procedural report
thanks to the CreateProcReport
method. The last argument of this
method is 0
, the default value, because the result ( the scope )
will be affected to the feature itself [Fig.1]. Note that piProcReport
is declared at the top of the Build
method because it can be
released in a CATCatch
section.
[Top]
This step consists in three sub-steps which are always:
See the "Retrieving the Geometrical Factory Interface" section in the Build implementation.
See the "Retrieving the Topological Journal" section in the Build implementation.
The prism operator is created with the following arguments:
TopData
the topological jounal : See the Retrieving the Topological Journal spBodyOnProfile
the profile to extrude -See the Retrieving and
Checking the CATBody associated with the Profile sectionExtrusionDirection
the pad direction - See the
Retrieving the Profile section startOffset
the offset value of the first limit. Valuated to 0, the pad
begins from the sketch plane endOffset
the offset value of the last limit.
... CATBody *pResultBody = NULL ; if ( SUCCEEDED(rc) ) { CATLength endOffset = 30.; CATLength startOffset = 0.; pOperatorPrism = CATCreateTopPrism(piGeomFactory, &TopData, spBodyOnProfile, &ExtrusionDirection, startOffset, endOffset); ... |
The pad operation creates a positive shape (negative in pocket case) and the CatBoolUnion
argument is used to characterize the operation. The two SetLimit
methods applied allow first and last limits to be defined.
if ( NULL != pOperatorPrism ) { pOperatorPrism->SetOperation(CatBoolUnion); CATTopLimitType startLimitType = CatLimOffsetFromProfile; CATTopPropagationType startPropagType = CatPropagSingle; // Defines the first limit for the operator pOperatorPrism->SetLimit(CatLimStart, startLimitType, 1, startOffset, NULL, CATBody_var(NULL_var), startPropagType, FALSE); // Defines the second limit for the operator CATTopLimitType endLimitType = CatLimOffsetFromProfile; CATTopPropagationType endPropagType = CatPropagSingle; pOperatorPrism->SetLimit(CatLimEnd, endLimitType, 0, endOffset, NULL, CATBody_var(NULL_var), endPropagType, FALSE); // Performs the operation pOperatorPrism->Run(); // Retrieves the performed body pResultBody = pOperatorPrism->GetResult(); ... |
pResultBody is the CATBody named TopoC
on the figure [Fig.1]
associated with the form of the User Pad. Note that pResultBody
is not declared at the top of the method. It is not necessary once its lifecycle
is managed by the DeletedProcReport
method in the CATCatch
sections
[Top]
It is now high time to store (fill) the procedural report corresponding to
the creation of the geometric result of the User Pad. That's the job of the CATIMfProcReport::StoreProcReport
method.
... if ( SUCCEEDED(rc) ) { if ( NULL != pResultBody ) { int BoolOper = 0 ; piProcReport->StoreProcReport(pResultBody,NoCopy,BoolOper); } else { CATMfErrUpdate *pErrorBuildShape = new CATMfErrUpdate(); CATUnicodeString Diagnostic("Error during BuildShape operation"); pErrorBuildShape->SetDiagnostic(1,Diagnostic); CATThrow(pErrorBuildShape); } } ... |
The last argument of the StoreProcReport
method, BoolOper,
is the same as the value in the CreateProcReport
method.
[Top]
In this last part of the CATTry
section, you clean the data
declared in the first section entitled "Declaring the
Useful Pointers" and not released/deleted during the CATTry
section. For example, the pPrtProfile
pointer is not released
here, once it has been safer released in the CATTry
section (not
described in this article, refer to the code)
spBodyOnProfile,
pOperatorPrism
the
topological operator,
piUpdateErrorOnThis
piProcReport
pSoftConfig
piGeomFactory
This section is identical to the "Managing Error" section of the
Build
method. Depending on the data used during the method, only the
"cleaning
useless data" section is different. In the two CATCatch
sections of the BuildShape
method it is important to:
DeleteProcReport
method. See the "Managing the CATMfErrUpdate Error"
section of the Build method.
and for the data declared in the first section entitled "Declaring the Useful Pointers":
spBodyOnProfile
pOperatorPrism
CATTry
section:
piUpdateErrorOnThis
piProcReport
pSoftConfig
piGeomFactory
pPrtProfile
[Top]
This use case has demonstrated the way to manage the build of a form feature.
[Top]
Version: 1 [Apr 2000] | Document created |
Version: 2 [Jan 2003] | Document updated |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.