PPR Hub

Product Modeler

Enabling New Features in a Product Document to be Deleted

Deleting new features
Use Case
CAAPstIntegrateNewFeatures > CAAPstINFBuildCatalog > CAAPstINFCreateDocument > CAAPstINFInitCont > CAAPstINFNavigate > CAAPstINFVisu > CAAPstINFGraphicalProperties  > CAAPstINFEdit > CAAPstINFCCP > CAAPstINFDelete > CAAPstINFUpdate

Abstract

This article discusses the CAAPstINFDelete use case. This use case explains how to delete features created "from scratch" in an applicative container of a Product document.


What You Will Learn With This Use Case

This use case is intended to illustrate how to program the delete of features created "from scratch" in an applicative container of a Product document.  Two types of geometrical features are treated in this use case:

  1. Referenced features: these are features that are used as input data for the definition of other features. In the case of this use case, the "CAAPstINFPoint" feature is used to define both "CAAPstINFLine" and "CAAPstINFWire" features. 
  2. Referencing features: these are features that reference other features which define them. In this use case, "CAAPstINFLine" and "CAAPstINFWire" reference "CAAPstINFPoint" features.

These geometrical features are the only ones that are allowed to be deleted. Enabling or disabling the "Delete" operation is filtered through the CATICSOFilter interface. 

This use case will show you how to program the CATILifeCycleObject interface implementations for the two types of geometrical objects defined in this use case, as well as how to program the CATICSOFilter interface implementations for all the features created in this use case. 

You should already be familiar with the CAAPstIntegrateNewFeatures use case article [1] in order to more easily understand the context of this particular use case. A general pre-requisite knowledge of the Feature Modeler may be required to fully understand this sample. You may want to review the basics of the Feature Modeler by looking over the "Feature Modeler Overview" technical article [2]. Finally, it may be useful for you to look over the "Product Structure Model" technical article [3] as well.

[Top]

The CAAPstINFDelete Use Case

The CAAPstINFDelete a use case that is part of the CAAPstIntegrateNewFeatures use case defined in the CAAProductStructure.edu framework that illustrates the integration of ObjectModelerBase and ApplicationFrame framework capabilities in the scope of a Product document.

[Top]

What Does the CAAPstINFDelete Use Case Do

This use case shows how to program the CATILifeCycleObject interface implementations for the geometrical features defined in this use case. It also shows how to enable the delete operation through the contextual menu for these geometrical features as well. 

First of all, let's take a look at the contents of the Product document:

Fig. 1: Contents of the CAAPstINFDocument.CATProduct document.

The  "CAAPstINFLine" feature references two "CAAPstINFPoint" features. If any one of these two points were to be deleted, the "CAAPstINFLine" feature would not longer have a valid definition and it should, therefore, be deleted as well. In the case of the "CAAPstINFWire" feature, although its definition is composed of any number of points (minimum two), we consider, as for the line, that its definition is no longer valid if any one of the points it references is deleted. Therefore, the tasks defined in the CATILifeCycleObject implementation for the "CAAPstINFPoint" object are the same for both of these features.

Notice that the "CAAPstINFLine" and "CAAPstINFWire" features which are simply referencing features can be deleted without impacting the existence of other features, since no other feature depends on them for its definition. The tasks defined in the CATILifeCycleObject implementation are the same for both "CAAPstINFLine" and "CAAPstINFWire" features.

There are two CATICsoFilter implementations as well. The first filters the operations available on the "CAAPstINFRoot" features which are not allowed to be deleted. The second filters the operations available on the other features which are allowed to be deleted. 

[Top]

How to Launch the CAAPstINFDelete Use Case

See the section entitled "How to Launch the CAAPstIntegrateNewFeatures Use Case" in the "Integrating New Features in a Product Structure" use case for a detailed description of how this use case should be launched.

Specifically, the code described in this article is executed during the following scenario:

Launch CATIA. When the application is ready, follow the scenario described below:

The CAAPstINFDocument.CATProduct document that can be found in the CNext/resources/graphic directory of the CAAProductStructure.edu framework. 

[Top]

Where to Find the CAAPstINFDelete Code

This use case describes the implementation class of the CATILifeCycleObject interface on the one hand for the "CAAPstINFPoint" feature, called CAAEPstINFLCOPoint, which is found in the CAAEPstINFLCOPoint.cpp source file and CAAEPstINFLCOPoint.h header file and on the other hand for the "CAAPstINFLine" and "CAAPstINFWire" features, called CAAEPstINFLCO, which is found in the CAAEPstINFLCO.cpp source file and CAAEPstINFLCO.h header file. Both of these implementations can be found in the CAAPstINFModeler.m shared library. It also describes the implementation of the CATICSOFilter interface, on the one hand for the "CAAPstINFRoot" feature called CAAEPstINFCSORoot, which is found in the CAAEPstINFCSORoot.cpp source file and CAAEPstINFCSORoot.h header file and on the other hand for all the other geometrical objects called CAAEPstINFCSOFeature which is found in the CAAEPstINFCSOFeature.cpp source file and CAAEPstINFCSOFeature.h header file. Both of these implementations can be found in the CAAPstINFCommands.m shared library.

Windows InstallRootDirectory\CAAProductStructure.edu\CAAPstINFModeler.m and CAAPstINFCommands.m
Unix InstallRootDirectory/CAAProductStructure.edu/CAAPstINFModeler.m and CAAPstINFCommands.m

where InstallRootDirectory is the directory where the CAA CD-ROM is installed.

[Top]

Step-by-Step

There are three logical steps in CAAPstINFDelete:

  1. Implementing the CATILifeCycleObject Interface for Line and Wire Features
  2. Implementing the CATILifeCycleObject Interface for Point Features
  3. Implementing the CATICSOFilter Interface for Root Features
  4. Implementing the CATICSOFilter Interface for Geometrical Features

We will now comment each of these sections by looking at the code.

[Top]

Implementing the CATILifeCycleObject Interface for Line and Wire Features

void CAAEPstINFLCO::remove (int forCloseContext )
{
    cout << "******CAAEPstINFLCO::remove" << endl;

    HRESULT rc;

    if (!forCloseContext)
    {
       // Update the navigation tree
       CATIRedrawEvent *piRedrawEventOnFeature = NULL;
       rc = this -> QueryInterface(IID_CATIRedrawEvent,
	                          (void**) &piRedrawEventOnFeature);
       if (SUCCEEDED(rc))
       {
           piRedrawEventOnFeature -> RedrawParent();
           piRedrawEventOnFeature -> Release();
           piRedrawEventOnFeature = NULL;
       }

       // Force an update of the visualization process
       CATIModelEvents *piModelEventsOnFeature = NULL;
       rc = this -> QueryInterface(IID_CATIModelEvents,
	                          (void**) &piModelEventsOnFeature);

       if (SUCCEEDED(rc))
       {
           CATDelete delNotif (this);
           piModelEventsOnFeature -> Dispatch(delNotif);
           piModelEventsOnFeature -> Release();
           piModelEventsOnFeature = NULL;
       }
    }

    CATSpecLifeCycleObjectExt::remove(forCloseContext);

    return;
}

This implementation is called whenever a "CAAPstINFLine" or "CAAPstINFWire" feature has been requested to be deleted. Because these are not referenced features, the only tasks necessary are to refresh the navigation and visualization in order to account for the deleted feature.

First of all, to refresh the specs tree, it is necessary to retrieve a CATIRedrawEvent pointer on the feature to be deleted. Then we can use the RedrawParent method to refresh the specs tree starting with the deleted feature's parent.

To refresh the visualization, we retrieve a pointer to the CATIModelEvents interface on the feature to be deleted. Not that this interface has been implemented on the "CAAPstINFLine" and "CAAPstINFWire" features. Then, we need to create an instance of CATDelete on the feature to be deleted and dispatch this instance using the Dispatch method of CATIModelEvents in order to notify the visualization process that a feature has been deleted and that a refresh is necessary.

Finally, using the CATSpecLifeCycleObjectExt::remove method, the feature is deleted.

[Top]

Implementing the CATILifeCycleObject Interface for Point Features

1. Delete the referencing features.

void CAAEPstINFLCOPoint::remove (int forCloseContext)
{
    cout << "******CAAEPstINFLCOPoint::remove" << endl;

    HRESULT rc;

    CATISpecObject *piSpecObjectOnThis = NULL;
    rc = this -> QueryInterface(IID_CATISpecObject,
	                       (void**) &piSpecObjectOnThis);
    if (FAILED(rc)) return;

    // Retrieve a list of the attributes pointing the Point
    CATListValCATISpecAttribute_var *pList = NULL;
    pList = piSpecObjectOnThis -> InverseAttrLink();
    piSpecObjectOnThis -> Release();
    piSpecObjectOnThis = NULL;
    if (NULL == pList) return;

    for(int i=1;i<=pList->Size();i++)
    {
	// Retrieve the spec object owner of the pointing attribute
	CATISpecObject *piPointingObject = (*pList)[i] -> GetOwner();
         CATUnicodeString specType = piPointingObject -> GetType();
		
	// If the spec object owner is a "CAAPstINFLine" or "CAAPstINFWire",
	// this object must also be deleted.
	if (specType == "CAAPstINFLine" || specType == "CAAPstINFWire")
	{
	    // Retrieve the father of the Line or Wire because since it is aggregated, it must
	    // be removed from the father level.
    	    CATISpecObject *piPointingObjFather = piPointingObject -> GetFather();
	    if (NULL != piPointingObjFather)
	    {
		piPointingObjFather -> Remove(piPointingObject);
		piPointingObjFather -> Release();
		piPointingObjFather = NULL;
	    }
	}
         piPointingObject -> Release();
	piPointingObject = NULL;
    }
    delete pList;
    pList = NULL;
...

Before actually deleting the "CAAPstINFPoint" feature itself, it is necessary to scan through the features pointing to it. If we run accross a "CAAPstINFLine" or "CAAPstINFWire" feature, since these features are no longer valid when the point is deleted, they must also be deleted.

In order to retrieve a list of the pointing objects, we can use the InverseAttrLink method of CATISpecObject which returns a list of pointing attributes. Then we can loop through the list returned and retrieve the pointing feature themselves using the GetOwner method of CATISpecAttribute. Now, we can test the type of the feature returned using the GetType method of CATISpecObject. If the type of the feature is "CAAPstINFLine" or CAAPstINFWire", the feature must be deleted. Since these features are aggregated at the "CAAPstINFRoot" level, they must also be deleted at this level, so it is necessary to retrieve the parent feature using the GetFather method of CATISpecObject. Finally, we delete the feature using the Remove method of CATISpecObject on the parent ("CAAPstINFRoot" aggregating feature).

[Top]

2. Refresh the navigation and visualization and delete the point.

...
    if (!forCloseContext)
    {
        // Update the navigation tree
        CATIRedrawEvent *piRedrawEventOnFeature = NULL;
        rc = this -> QueryInterface(IID_CATIRedrawEvent,
	                           (void**) &piRedrawEventOnFeature);
        if (SUCCEEDED(rc))
        {
            piRedrawEventOnFeature -> RedrawParent();
            piRedrawEventOnFeature -> Release();
            piRedrawEventOnFeature = NULL;
        }

        // Force an update of the visualization process
        CATIModelEvents *piModelEventsOnFeature = NULL;
        rc = this -> QueryInterface(IID_CATIModelEvents,
	                           (void**) &piModelEventsOnFeature);

        if (SUCCEEDED(rc))
        {
            CATDelete delNotif (this);
            piModelEventsOnFeature -> Dispatch(delNotif);
            piModelEventsOnFeature -> Release();
            piModelEventsOnFeature = NULL;
        }
    }

    CATSpecLifeCycleObjectExt::remove(forCloseContext);

    return;
}

As for the "CAAPstINFLine" and "CAAPstINFWire" features in the previous section, we need to refresh the navigation and visualization in order to account for the deleted objects. So, first of all, we retrieve a CATIRedrawEvent pointer on the feature to be deleted. Then we can use the RedrawParent method to refresh the specs tree starting with the deleted feature's parent.

First of all, to refresh the specs tree, it is necessary to retrieve a CATIRedrawEvent pointer on the feature to be deleted. Then we can use the RedrawParent method to refresh the specs tree starting with the deleted feature's parent.

To refresh the visualization, we retrieve a pointer to the CATIModelEvents interface on the feature to be deleted. Note that this interface has been implemented on the "CAAPstINFPoint" feature. Then, we need to create an instance of CATDelete on the feature to be deleted and dispatch this instance using the Dispatch method of CATIModelEvents in order to notify the visualization process that a feature has been deleted and that a refresh is necessary.

Finally, using the CATSpecLifeCycleObjectExt::remove method, the "CAAPstINFPoint" feature is deleted.

[Top]

Implementing the CATICSOFilter Interface for Root Features

HRESULT CAAEPstINFCSORoot::CommandIsAvailable (const char *pHeaderID, const CATCSO *pCSO)
{
    cout << "******CAAEPstINFCSORoot::CommandIsAvailable" << endl;
    HRESULT result;
    result = E_FAIL;
  
    if (!strcmp(pHeaderID, "Paste")) 
       result = S_OK;

    return result;	
}

The implementation of the CATICSOFilter interface on the "CAAPstINFRoot" feature defines which operations of the contextual menu are available for this particular feature type. Because this is a root feature, the only operation we allow is the "Paste". You will see this operation in further detail in the use case dealing with Cut, Copy and Paste operations [4].

[Top]

Implementing the CATICSOFilter Interface for Geometrical Features

HRESULT CAAEPstINFCSO::CommandIsAvailable (const char *pHeaderID, const CATCSO *pCSO)
{
    cout << "******CAAEPstINFCSO::CommandIsAvailable" << endl;
    return S_OK;
}

By providing an empty implementations, all of the contextual menu operations are made available for the features implementing this interface.

[Top]


In Short

The CAAPstINFDelete use case has shown you how program the delete operation of a "from scratch" feature by implementing the CATILifeCycleObject interface. It has also shown how to make the Delete operation available in the contextual menu of the feature by implementing the CATICSOFilter interface. 

[Top]


References

[1] Integrating New Features in a Product Document
[2] Feature Modeler Overview
[3] Using the Provider Mechanism
[4] Enabling Cut, Copy and Paste Operations on New Features in a Product Document
[Top]

History

Version: 1 [June 2002] Document created
[Top]

Copyright © 2002, Dassault Systèmes. All rights reserved.