Geometric Modeler |
Topology |
Overview of the Topological OperatorsHow to use them to create bodies |
Use Case |
AbstractBuild on a common scheme, the topological operators are transient objects used to create bodies. The use case illustrates their use in chaining them to create bodies: primitive creation (CATSolidCylinder, CATSolidCuboid), skin body creation (CATTopSkin), prism (CATTopPrism), Boolean operation (CATDynBoolean), filleting (CATDynFillet) and shelling (CATDynShell). The volume of the resulting body is also computed (CATDynMassProperties3D). The use of the journal, describing the topological modifications from the input bodies to the resulting body, is not described here. See the dedicated use case "Managing the Journal" [1] to have more information on this point. |
In this use case, the general scheme of the topological operators is explained.
Using topological operators is an easy way to create new consistent topological objects. There are two types of operators:
All these operators follow the smart concept [3]: they never modify the input bodies. They always create new topological objects, which share topological cells to reduce the model size.
The operators can log, under request, the follow-up of the faces and free edges from the input bodies to the resulting body. This data is written, under request, on a topological journal [4] attached to each operator. Hence, the topological journal offers the developer the means to develop procedural applications, such as feature based modeling, but this point in not detailed here. See the dedicated use case [1] to have more information on the use of the journal.
The topological operators are transient objects used to define topological operations, and cannot be streamed.
The AdvancedTopologicalOpe framework provides advanced topological operators in surface design. They follow the general scheme of the topological operators, but are not described here.[Top]
All the operators are based on the same scheme as follow that:
Unlike the geometric operators, the topological operators do not provide a BASIC and an ADVANCED modes. The topological operators are always set in ADVANCED mode: the run is always mandatory.
[Top]
CAATopOverview is a use case of the CAATopologicalOperators.edu framework that illustrates TopologicalOperators framework capabilities.
[Top]
The use case creates the body of Fig.1 by chaining topological operators.
[Top]
To launch CAATopOverview, you will need to set up the build time environment, then compile CAATopOverview.m along with its prerequisites, set up the run time environment, and then execute the use case [8].
If you simply type CAATopOverview with no argument, the use case executes, but doesn't save the result in an NCGM file. If you want to save this result, provide the full pathname of the NCGM file to create. For example:
With Windows CAATopOverview e:\Overview.NCGM
With UNIX CAATopOverview /u/Overview.NCGM
This NCGM file can be displayed using the CAAGemBrowser use case.
[Top]
The CAATopOverview use case is made of a main named CAATopOverview.cpp located in the CAATopOverview.m module of the CAATopologicalOperators.edu framework:
Windows | InstallRootDirectory\CAATopologicalOperators.edu\CAATopOverview.m\ |
Unix | InstallRootDirectory/CAATopologicalOperators.edu/CAATopOverview.m/ |
where InstallRootDirectory is the directory where the CAA CD-ROM is installed.
[Top]
The main program:
[Top]
The geometry factory (CATGeoFactory) creates and manages all the CATICGMObject : it creates the points, curves, surfaces and bodies and remove them [7].
The CATGeoFactory creation itself is done by the global function ::CATCreateCGMContainer.
Notice that the factory can be defined by reading a NCGM file that was previously stored. In that case, the global function ::CATLoadCGMContainer must be used.
CATGeoFactory* piGeomFactory = ::CATCreateCGMContainer() ; if (NULL==piGeomFactory) return (1); |
[Top]
This section illustrates the use of the type of topological operators that derive from CATGeoToTopOperator. There are two ways to create a skin body:
CATPlane * piPlane = piGeomFactory->CreatePlane(CATMathOIJ); // xy plane if (NULL == piPlane) { ::CATCloseCGMContainer(piGeomFactory); return (1); } |
Now, using the characteristics of the plane (CATPlane::GetAxis), the CATPLine and CATPCircle of the contour are created.
The lines and circles are created with the corresponding CATGeoFactory::CreatePLine and CATGeoFactory::CreatePCircle methods. As these lines and circles are defining on the surface, they can only be created from surface parameters. However, no assumption can be done on the parameterization of the geometric objects. The parameters on the plane are evaluated with the CATSurface::GetParam method, from 3D points that are known to be on the plane. This method can be called because the plane is a canonical object, and the points are already on it. If one of these conditions were not filled, it would be mandatory to call the CATProjectionPtSur geometric operator.
CATTopSkin needs
The principle of the algorithm is
The use of the CATMathPoint::DistanceTo method to compute the minimum distance between a point (this calling DistanceTo ) and an array of points: the method retrieves the index (beginning at 0) in the input array of the point realizing the minimum distance.
The geometry being created, the CATTopSkin can now be invoked according to the general scheme that:
CATCreateTopSkin
// Creates the operator // first defines an open configuration for the operator CATSoftwareConfiguration * pConfig = new CATSoftwareConfiguration(); // defines the data of the operator: configuration + journal CATTopData topdata(pConfig,NULL); // now creates the operator CATTopSkin * pSkinOp = ::CATCreateTopSkin (piGeomFactory, &topdata, piPlane, nbPCurves, aPCurves, aLimits, aOrientations); if (NULL==pSkinOp) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Runs pSkinOp->Run(); // Gets the resulting body CATBody * piSkinBody = pSkinOp->GetResult(); if (NULL==piSkinBody) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Deletes the operator delete pSkinOp; pSkinOp = NULL; |
The operator configuration is the level of software you want to use to
run this operator. By default, define an open configuration as in this use
case to run with the current level. Moreover here, the pointer to the
journal is set to NULL
in the operator data. So that the
journal is not filled.
The configuration must be released after use. Here, it is released after the call to the last operator.
[Top]
The created SkinBody is now extruded to create a prism with CATTopPrism. To use it:
CATMathDirection zDir(0., 0., 1.); double startOffset = 10.; double endOffset = 30.; CATTopPrism *pPrismOp = ::CATTopCreatePrism (piGeomFactory, &topdata piSkinBody, &zDir, startOffset, endOffset); if (NULL==pPrismOp) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Runs pPrismOp->Run(); // Gets the resulting body CATBody * piMainBody1=NULL; piMainBody1 = pPrismOp->GetResult(); if (NULL==piMainBody1) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Deletes the operator delete pPrismOp; pPrismOp = NULL; |
As the body to extrude is a skin body, MainBody1 is a volume body. If the body to extrude were a wire body, the result would be a skin body. Other types of prism operations can be defined, especially "until" operations: the limits of the prism are reached when encountering another body. This case is detailed in the CAATopJournal use case [1].
[Top]
This section illustrates the use of CATSolidPrimitive operators: no run is called to do the operation, that is done at the operator creation.
To create a box, use CATSolidCuboid:
CATCreateSolidCuboid
. The
points that are given are four corners of the box. The operation is
automatically run.
CATMathPoint vO( -2., 2., 28.), vOI(-2., 15., 28.), vOJ(-15., 2., 28.), vOK(-2., 2., 35.); CATSolidCuboid *pCuboidOp = ::CATCreateSolidCuboid( piGeomFactory, &topdata, vO, vOI, vOJ, vOK); if (NULL==pCuboidOp) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Gets the result (the operator is run at is creation) CATBody *piCuboidBody=NULL; piCuboidBody = pCuboidOp->GetResult(); if (NULL==piCuboidBody) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Deletes the operator delete pCuboidOp; pCuboidOp = NULL; |
To create a cylinder, use CATSolidCylinder :
CATCreateSolidCylinder
.
The two points defines the axis of the cylinder. The operation is
automatically run
CATMathPoint axisStart ( -20, 10, 20 ), axisEnd( -20, 10, 32 ); double radius = 4.0; CATSolidCylinder *pCylinderOp = ::CATCreateSolidCylinder(piGeomFactory, &topdata axisStart, axisEnd, radius); if (NULL==pCylinderOp) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Gets the resulting body (the operator is run at its creation) CATBody *piCylinderBody = NULL; piCylinderBody = pCylinderOp->GetResult(); if (NULL==piCylinderBody) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Deletes the operator delete pCylinderOp; pCylinderOp = NULL; |
See the CAATopJournal use case [1] to see how to create a skin body cylinder.
[Top]
To use CATDynBoolean:
This code also shows an example of use the CATICGMContainer::Remove method to suppress the no more used bodies: the RemoveDependancies option declares that not only the body, but also its domains, cells and geometry are removed, except if they were used by other CGM entities.
The same is done for a Boolean subtract: the option CATBoolRemoval is used. MainBody3 contains the result of all the operations, while the no-more used bodies (MainBody2 , CylinderBody) are removed.
pBoolOp = ::CATCreateDynBoolean (piGeomFactory, &topdata, CATBoolRemoval, piMainBody2, piCylinderBody); if (NULL==pBoolOp) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Runs pBoolOp->Run(); // Gets the resulting body CATBody * piMainBody3 = NULL; piMainBody3 = pBoolOp->GetResult(); if (NULL==piMainBody3) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Deletes the operator delete pBoolOp; pBoolOp = NULL; piGeomFactory->Remove(piCylinderBody); piCylinderBody = NULL; piGeomFactory->Remove(piMainBody2); piMainBody2 = NULL; |
[Top]
First define the edges to fillet. These edges are the external boundary of the upper face of the prism after the two Boolean operations, in other words in our case, the face with 2 holes (the paths of the cylinder and the box). To retrieve them:
A filleting operation is defined by affecting (possibly variable) radius to edges:
// for a constant radius, only the first argument is useful CATDynFilletRadius * pRadius = new CATDynFilletRadius(1., // radius value NULL, // the cell on which the radius is defined NULL, // The ratio of the edge length defining the point NULL); // must be kept to NULL if (NULL==pRadius) { ::CATCloseCGMContainer(piGeomFactory); return (1); } CATLISTP(CATDynFilletRadius) listRadius; listRadius.Append(pRadius); // ribbon definition CATDynEdgeFilletRibbon * pRibbon = new CATDynEdgeFilletRibbon(listEdges, listRadius); if (NULL==pRibbon) { ::CATCloseCGMContainer(piGeomFactory); return (1); } pRibbon ->SetSegmentationMode(CATDynTrim); |
The fillet operation can now be defined and run. To use it
Also deletes the no more used object (radius, ribbon) and removes the old body (MainBody3).
CATDynFillet * pFilletOp = CATCreateDynFillet(piGeomFactory,&topdata,piMainBody3); if (NULL==pFilletOp) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Appends the ribbon pFilletOp ->Append(pRibbon); // Runs pFilletOp ->Run(); // Gets the resulting body CATBody * piMainBody4 = NULL; piMainBody4 = pFilletOp->GetResult(); if (NULL==piMainBody4) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Deletes the operator delete pFilletOp; pFilletOp = NULL; if (NULL != pRadius) delete pRadius; pRadius = NULL; if (NULL != pRibbon) delete pRibbon; pRibbon = NULL; piGeomFactory->Remove(piMainBody3); piMainBody3 = NULL; |
[Top]
Take two offset bodies of one initial body. The shelling operation digs a volume by removing one offset body (internal) from the other one (external). Some faces can also be not offset: these faces are called openings. In the use case, the opening face is the bottom face of the prism: it is the unique face with five edges and one domain. The way to retrieve it is similar to the way used in the section Fillets. First void the list (RemoveAll), and remember that the list begins at 1!
listEdges.RemoveAll(); piFace = NULL; for (i=1;i<=nbFaces;i++) { if ( 1== (listFaces[i]->GetNbDomains()) ) { piLoop = listFaces[i]->GetDomain(1); piLoop ->GetAllCells(listC, 1); numberOfEdges = listC.Size(); if (5==listC.Size()) { piFace=listFaces[i]; } } } if (NULL == piFace) return (3); |
The shelling operation can now be defined and run. To use it:
Also removes the old body (MainBody4).
CATDynShell* pShellOp = CATCreateDynShell (piGeomFactory, &topdata, // the configuration and the journal piMainBody4, // the body to shell -1., // first offset value (inside the body) 0.); // second offset value (initial body) if (NULL==pShellOp) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Sets the opening faces CATLISTP(CATFace) openings; openings.Append((CATFace*)piFace); pShellOp-> Append(openings); // Runs pShellOp->Run(); // Gets the resulting body CATBody * piMainBody5 = NULL; piMainBody5 = pShellOp->GetResult(); if (NULL==piMainBody5) { ::CATCloseCGMContainer(piGeomFactory); return (1); } // Deletes the operator delete pShellOp; pShellOp = NULL; piGeomFactory->Remove(piMainBody4,CATICGMContainer::RemoveDependancies); piMainBody4 = NULL; |
[Top]
CATDynMassProperties3D is an operator to analyze a body. Here we ask for the computation of the volume of the body, result of all the operations. To use it:
CATDynMassProperties3D *pPropOp = CATDynCreateMassProperties3D (piMainBody5); if (NULL != pPropOp) { cout << "Volume of the final object" << pPropOp->GetVolume() << endl; delete pPropOp; pPropOp = NULL; } |
[Top]
Before ending, we must first release the software configuration.
// Releases the configuration pConfig->Release(); |
To save the model in a file, the ::CATSaveCGMContainer global function is used. Notice that in the use case, the save is conditioned by an input parameter representing the file inside which the model must be saved.
The use case ends with the closure of the geometry factory, done by the ::CATCloseCGMContainer global function.
if(1==toStore) { #ifdef _WINDOWS_SOURCE ofstream filetowrite(pfileName, ios::binary ) ; #else ofstream filetowrite(pfileName,ios::out,filebuf::openprot) ; #endif ::CATSaveCGMContainer(piGeomFactory,filetowrite); filetowrite.close(); } // // Closes the container // ::CATCloseCGMContainer(piGeomFactory); |
[Top]
This use case creates a body by chaining several types of topological operations, such Boolean, Filleting or Shelling, and primitive creation. The journal is not detailed.
[Top]
Version: 1.1 [Oct 2000] | Operator configuration |
Version: 1 [May 2000] | Document created |
[Top] |
Copyright © 2000, Dassault Systèmes. All rights reserved.