1 Foundation Classes {#occt_user_guides__foundation_classes}
2 =================================
6 @section occt_fcug_1 Introduction
8 This manual explains how to use Open CASCADE Technology (**OCCT**) Foundation Classes. It provides basic documentation on foundation classes. For advanced information on foundation classes and their applications, see our <a href="http://www.opencascade.com/content/tutorial-learning">E-learning & Training</a> offerings.
10 Foundation Classes provide a variety of general-purpose services such as automated dynamic memory management (manipulation of objects by handle), collections, exception handling, genericity by down-casting and plug-in creation.
12 Foundation Classes include the following:
15 Root classes are the basic data types and classes on which all the other classes are built. They provide:
16 * fundamental types such as Boolean, Character, Integer or Real,
17 * safe handling of dynamically created objects, ensuring automatic deletion of unreferenced objects (see *Standard_Transient* class),
18 * configurable optimized memory manager increasing the performance of applications that intensively use dynamically created objects,
19 * extended run-time type information (RTTI) mechanism facilitating the creation of complex programs,
20 * management of exceptions,
21 * encapsulation of C++ streams.
22 Root classes are mainly implemented in *Standard* and *MMgt* packages.
25 Strings are classes that handle dynamically sized sequences of characters based on both ASCII (normal 8-bit character type) and Unicode (16-bit character type).
26 Strings may also be manipulated by handles, and consequently be shared.
27 Strings are implemented in the *TCollection* package.
30 Collections are the classes that handle dynamically sized aggregates of data.
31 Collection classes are *generic*, that is, they define a structure and algorithms allowing to hold a variety of objects which do not necessarily inherit from a unique root class (similarly to C++ templates). When you need to use a collection of a given type of object, you must *instantiate* it for this specific type of element. Once this declaration is compiled, all functions available on the generic collection are available on your *instantiated class*.
33 Collections include a wide range of generic classes such as run-time sized arrays, lists, stacks, queues, sets and hash maps.
34 Collections are implemented in the *TCollection* and *NCollection* packages.
36 ### Collections of Standard Objects
38 The *TColStd* package provides frequently used instantiations of generic classes from the *TCollection* package with objects from the *Standard* package or strings from the *TCollection* package.
40 ### Vectors and Matrices
42 These classes provide commonly used mathematical algorithms and basic calculations (addition, multiplication, transposition, inversion, etc.) involving vectors and matrices.
44 ### Primitive Geometric Types
46 Open CASCADE Technology primitive geometric types are a STEP-compliant implementation of basic geometric and algebraic entities.
48 * Descriptions of elementary geometric shapes:
53 * Planes and elementary surfaces,
54 * Positioning of these shapes in space or in a plane by means of an axis or a coordinate system,
55 * Definition and application of geometric transformations to these shapes:
59 * Scaling transformations
60 * Composed transformations
61 * Tools (coordinates and matrices) for algebraic computation.
63 ### Common Math Algorithms
65 Open CASCADE Technology common math algorithms provide a C++ implementation of the most frequently used mathematical algorithms.
67 * Algorithms to solve a set of linear algebraic equations,
68 * Algorithms to find the minimum of a function of one or more independent variables,
69 * Algorithms to find roots of one, or of a set, of non-linear equations,
70 * Algorithms to find the eigen-values and eigen-vectors of a square matrix.
74 A hierarchy of commonly used exception classes is provided, all based on class Failure, the root of exceptions.
75 Exceptions describe exceptional situations, which can arise during the execution of a function. With the raising of an exception, the normal course of program execution is abandoned. The execution of actions in response to this situation is called the treatment of the exception.
79 These are various classes supporting date and time information and fundamental types representing most physical quantities such as length, area, volume, mass, density, weight, temperature, pressure etc.
81 ### Application services
83 Foundation Classes also include implementation of several low-level services that facilitate the creation of customizable and user-friendly applications with Open CASCADE Technology. These include:
84 * Unit conversion tools, providing a uniform mechanism for dealing with quantities and associated physical units: check unit compatibility, perform conversions of values between different units and so on (see package *UnitsAPI*);
85 * Basic interpreter of expressions that facilitates the creation of customized scripting tools, generic definition of expressions and so on (see package *ExprIntrp*);
86 * Tools for dealing with configuration resource files (see package *Resource*) and customizable message files (see package *Message*), making it easy to provide a multi-language support in applications;
87 * Progress indication and user break interfaces, giving a possibility even for low-level algorithms to communicate with the user in a universal and convenient way.
90 @section occt_fcug_2 Basics
91 This chapter deals with basic services such as library organization, persistence, data types, memory management, programming with handles, exception handling, genericity by downcasting and plug-in creation.
94 @subsection occt_fcug_2_a Library organization
96 This chapter introduces some basic concepts, which are used not only in Foundation Classes, but throughout the whole OCCT library.
98 @subsubsection occt_fcug_2_a_1 Modules and toolkits
100 The whole OCCT library is organized in a set of modules. The first module, providing most basic services and used by all other modules, is called Foundation Classes and described by this manual.
102 Every module consists primarily of one or several toolkits (though it can also contain executables, resource units etc.). Physically a toolkit is represented by a shared library (e.g. .so or .dll). The toolkit is built from one or several packages.
104 @subsubsection occt_fcug_2_a_2 Packages
105 A **package** groups together a number of classes which have semantic links. For example, a geometry package would contain Point, Line, and Circle classes. A package can also contain enumerations, exceptions and package methods (functions). In practice, a class name is prefixed with the name of its package e.g.
107 Data types described in a package may include one or more of the following data types:
111 * Pointers to other object classes
112 Inside a package, two data types cannot bear the same name.
114 @image html /user_guides/foundation_classes/images/foundation_classes_image003.png "Contents of a package"
115 @image latex /user_guides/foundation_classes/images/foundation_classes_image003.png "Contents of a package"
117 **Methods** are either **functions** or **procedures**. Functions return an object, whereas procedures only communicate by passing arguments. In both cases, when the transmitted object is an instance manipulated by a handle, its identifier is passed. There are three categories of methods:
118 * **Object constructor** Creates an instance of the described class. A class will have one or more object constructors with various different arguments or none.
119 * **Instance method** Operates on the instance which owns it.
120 * **Class method** Does not work on individual instances, only on the class itself.
122 @subsubsection occt_fcug_2_a_3 Classes
123 The fundamental software component in object-oriented software development is the class. A class is the implementation of a **data type**. It defines its **behavior** (the services offered by its functions) and its **representation** (the data structure of the class -- the fields, which store its data).
125 Classes fall into three categories:
127 * Abstract classes. An **abstract class** cannot be instantiated. The purpose of having such classes is to have a given behavior shared by a hierarchy of classes and dependent on the implementation of the descendants. This is a way of guaranteeing a certain base of inherited behavior common to all the classes based on a particular deferred class.
128 * Template classes. A **template class** offers a set of functional behaviors to manipulate other data types. Instantiation of a template class requires that a data type is given for its argument(s).
130 @subsubsection occt_fcug_2_a_5 Inheritance
131 The purpose of inheritance is to reduce the development workload. The inheritance mechanism allows a new class to be declared already containing the characteristics of an existing class. This new class can then be rapidly specialized for the task in hand. This avoids the necessity of developing each component “from scratch”.
132 For example, having already developed a class *BankAccount* you could quickly specialize new classes: *SavingsAccount, LongTermDepositAccount, MoneyMarketAccount, RevolvingCreditAccount*, etc....
134 The corollary of this is that when two or more classes inherit from a parent (or ancestor) class, all these classes guarantee as a minimum the behavior of their parent (or ancestor). For example, if the parent class BankAccount contains the method Print which tells it to print itself out, then all its descendant classes guarantee to offer the same service.
136 One way of ensuring the use of inheritance is to declare classes at the top of a hierarchy as being **abstract**. In such classes, the methods are not implemented. This forces the user to create a new class which redefines the methods. This is a way of guaranteeing a certain minimum of behavior among descendant classes.
138 @subsection occt_fcug_2_1 Data Types
140 An object-oriented language structures a system around data types rather than around the actions carried out on this data. In this context, an **object** is an **instance** of a data type and its definition determines how it can be used. Each data type is implemented by one or more classes, which make up the basic elements of the system.
142 The data types in Open CASCADE Technology fall into two categories:
143 * Data types manipulated by handle (or reference)
144 * Data types manipulated by value
146 @image html /user_guides/foundation_classes/images/foundation_classes_image004.png "Manipulation of data types"
147 @image latex /user_guides/foundation_classes/images/foundation_classes_image004.png "Manipulation of data types"
149 A data type is implemented as a class. The class not only defines its data representation and the methods available on instances, but it also suggests how the instance will be manipulated.
150 * A variable of a type manipulated by value contains the instance itself.
151 * A variable of a type manipulated by handle contains a reference to the instance.
152 The first examples of types manipulated by values are the predefined **primitive types**: *Boolean, Character, Integer, Real*, etc.
154 A variable of a type manipulated by handle which is not attached to an object is said to be **null**. To reference an object, we instantiate the class with one of its constructors. For example, in C++:
157 Handle(myClass) m = new myClass;
160 In Open CASCADE Technology, the Handles are specific classes that are used to safely manipulate objects allocated in the dynamic memory by reference, providing reference counting mechanism and automatic destruction of the object when it is not referenced.
164 @subsubsection occt_fcug_2_1_1 Primitive Types
166 The primitive types are predefined in the language and they are **manipulated by value**.
168 * **Boolean** is used to represent logical data. It may have only two values: *Standard_True* and *Standard_False*.
169 * **Character** designates any ASCII character.
170 * **ExtCharacter** is an extended character.
171 * **Integer** is a whole number.
172 * **Real** denotes a real number (i.e. one with whole and a fractional part, either of which may be null).
173 * **ShortReal** is a real with a smaller choice of values and memory size.
174 * **CString** is used for literal constants.
175 * **ExtString** is an extended string.
176 * **Address** represents a byte address of undetermined size.
178 The services offered by each of these types are described in the **Standard** Package.
179 The table below presents the equivalence existing between C++ fundamental types and OCCT primitive types.
181 **Table 1: Equivalence between C++ Types and OCCT Primitive Types**
183 | C++ Types | OCCT Types |
184 | :--------- | :----------- |
185 | int | Standard_Integer |
186 | double | Standard_Real |
187 | float | Standard_ShortReal |
188 | unsigned int | Standard_Boolean |
189 | char | Standard_Character |
190 | short | Standard_ExtCharacter |
191 | char\* | Standard_CString |
192 | void\* | Standard_Address |
193 | short\* | Standard_ExtString |
195 \* The types with asterisk are pointers.
197 **Reminder of the classes listed above:**
199 * **Standard_Integer** : fundamental type representing 32-bit integers yielding negative, positive or null values. *Integer* is implemented as a *typedef* of the C++ *int* fundamental type. As such, the algebraic operations +, -, *, / as well as the ordering and equivalence relations <, <=, ==, !=, >=, > are defined on it.
200 * **Standard_Real** : fundamental type representing real numbers with finite precision and finite size. **Real** is implemented as a *typedef* of the C++ *double* (double precision) fundamental type. As such, the algebraic operations +, -, *, /, unary- and the ordering and equivalence relations <, <=, ==, !=, >=, > are defined on reals.
201 * **Standard_ShortReal** : fundamental type representing real numbers with finite precision and finite size. *ShortReal* is implemented as a *typedef* of the C++ *float* (simple precision) fundamental type. As such, the algebraic operations +, -, *, /, unary- and the ordering and equivalence relations <, <=, ==, !=, >=, > are defined on reals.
202 * **Standard_Boolean** : fundamental type representing logical expressions. It has two values: *false* and *true*. *Boolean* is implemented as a *typedef* of the C++ *unsigned int* fundamental type. As such, the algebraic operations *and, or, xor* and *not* as well as equivalence relations == and != are defined on Booleans.
203 * **Standard_Character** : fundamental type representing the normalized ASCII character set. It may be assigned the values of the 128 ASCII characters. *Character* is implemented as a *typedef* of the C++ *char* fundamental type. As such, the ordering and equivalence relations <, <=, ==, !=, >=, > are defined on characters using the order of the ASCII chart (ex: A B).
204 * **Standard_ExtCharacter** : fundamental type representing the Unicode character set. It is a 16-bit character type. *ExtCharacter* is implemented as a *typedef* of the C++ *short* fundamental type. As such, the ordering and equivalence relations <, <=, ==, !=, >=, > are defined on extended characters using the order of the UNICODE chart (ex: A B).
205 * **Standard_CString** : fundamental type representing string literals. A string literal is a sequence of ASCII (8 bits) characters enclosed in double quotes. *CString* is implemented as a *typedef* of the C++ *char* fundamental type.
206 * **Standard_Address** : fundamental type representing a generic pointer. *Address* is implemented as a *typedef* of the C++ *void* fundamental type.
207 * **Standard_ExtString** is a fundamental type representing string literals as sequences of Unicode (16 bits) characters. *ExtString* is implemented as a *typedef* of the C++ *short* fundamental type.
209 @subsubsection occt_fcug_2_1_2 Types manipulated by value
210 There are three categories of types which are manipulated by value:
213 * Types defined by classes not inheriting from *Standard_Transient*, whether directly or not.
214 Types which are manipulated by value behave in a more direct fashion than those manipulated by handle and thus can be expected to perform operations faster, but they cannot be stored independently in a file.
216 @image html /user_guides/foundation_classes/images/foundation_classes_image005.png "Manipulation of a data type by value"
217 @image latex /user_guides/foundation_classes/images/foundation_classes_image005.png "Manipulation of a data type by value"
219 @subsubsection occt_fcug_2_1_3 Types manipulated by reference (handle)
221 These are types defined by classes inheriting from the *Transient* class.
223 @image html /user_guides/foundation_classes/images/foundation_classes_image006.png "Manipulation of a data type by reference"
224 @image latex /user_guides/foundation_classes/images/foundation_classes_image006.png "Manipulation of a data type by reference"
226 @subsubsection occt_fcug_2_1_4 When is it necessary to use a handle?
228 When you design an object, it can be difficult to choose how to manipulate that
229 object: by value or by handle. The following ideas can help you to make up your mind:
231 * If your object may have a long lifetime within the application and you want to make multiple
232 references to it, it would be preferable to manipulate this object with a handle. The memory for the
233 object will be allocated on the heap. The handle which points to that memory is a light object which
234 can be rapidly passed in argument. This avoids the penalty of copying a large object.
235 * If your object will have a limited lifetime, for example, used within a single algorithm, it would
236 be preferable to manipulate this object by value, non-regarding its size, because this object is
237 allocated on the stack and the allocation and de-allocation of memory is extremely rapid, which
238 avoids the implicit calls to *new* and *delete* occasioned by allocation on the heap.
239 * Finally, if an object will be created only once during, but will exist throughout the lifetime of
240 the application, the best choice may be a class manipulated by handle or a value declared as a
244 @subsection occt_fcug_2_2 Programming with Handles
246 @subsubsection occt_fcug_2_2_1 Handle Definition
248 A handle is OCCT implementation of a smart pointer.
249 Several handles can reference the same object.
250 Also, a single handle may reference several objects, but only one at a time.
251 To have access to the object it refers to, the handle must be de-referenced just as with a C++ pointer.
253 #### Organization of Classes
255 Class *Standard_Transient* is a root of a big hierarchy of OCCT classes that are said to be operable by handles. It provides a reference counter field, inherited by all its descendant classes, that is used by associated *Handle()* classes to track a number of handles pointing to this instance of the object.
257 Objects of classes derived (directly or indirectly) from *Transient*, are normally allocated in dynamic memory using operator **new**, and manipulated by handle.
258 Handle is defined as template class *opencascade::handle<>*.
259 Open CASCADE Technology provides preprocessor macro *Handle()* that is historically used throughout OCCT code to name a handle:
261 Handle(Geom_Line) aLine; // "Handle(Geom_Line)" is expanded to "opencascade::handleL<Geom_Line>"
264 In addition, for standard OCCT classes additional *typedef* is defined for a handle, as the name of a class prefixed by *Handle_*.
265 For instance, the above example can be also coded as:
267 Handle_Geom_Line aLine; // "Handle_Geom_Line" is typedef to "opencascade::handleL<Geom_Line>"
273 A handle is characterized by the object it references.
275 Before performing any operation on a transient object, you must declare the handle. For example, if Point and Line are two transient classes from the Geom package, you would write:
277 Handle(Geom_Point) p1, p2;
279 Declaring a handle creates a null handle that does not refer to any object. The handle may be checked to be null by its method *IsNull()*. To nullify a handle, use method *Nullify()*.
281 To initialize a handle, either a new object should be created or the value of another handle can be assigned to it, on condition that their types are compatible.
283 **Note** that handles should only be used for object sharing. For all local operations, it is advisable to use classes manipulated by values.
285 @subsubsection occt_fcug_2_2_2 Type Management
287 Open CASCADE Technology provides a means to describe the hierarchy of data types in a generic way, with a possibility to check the exact type of the given object at run-time (similarly to C++ RTTI).
289 To enable this feature, a class declaration should include the declaration of OCCT RTTI.
290 Header *Standard_Type.hxx* provides two variants of preprocessor macros facilitating this:
292 * Inline variant, which declares and defines RTTI methods by a single line of code:
294 #include <Geom_Surface.hxx>
295 class Appli_ExtSurface : public Geom_Surface
299 DEFINE_STANDARD_RTTIEXT(Appli_ExtSurface,Geom_Surface)
303 * Out-of line variant, which uses one macro in the declaration (normally in the header file), and another in the implementation (in C++ source):
305 In *Appli_ExtSurface.hxx* file:
307 #include <Geom_Surface.hxx>
308 class Appli_ExtSurface : public Geom_Surface
312 DEFINE_STANDARD_RTTIEXT(Appli_ExtSurface,Geom_Surface)
316 In *Appli_ExtSurface.cxx* file:
318 #include <Appli_ExtSurface.hxx>
319 IMPLEMENT_STANDARD_RTTIEXT(Appli_ExtSurface,Geom_Surface)
322 These macros define method *DynamicType()* that returns a type descriptor - handle to singleton instance of the class *Standard_Type* describing the class.
323 The type descriptor stores the name of the class and the descriptor of its parent class.
325 Note that while inline version is easier to use, for widely used classes this method may lead to bloating of binary code of dependent libraries, due to multiple instantiations of inline method.
327 To get the type descriptor for a given class type, use macro *STANDARD_TYPE()* with the name of the class as argument.
331 if (aCurve->IsKind(STANDARD_TYPE(Geom_Line))) // equivalent to "if (dynamic_cast<Geom_Line>(aCurve.get()) != 0)"
339 The type used in the declaration of a handle is the static type of the object, the type seen by the compiler. A handle can reference an object instantiated from a subclass of its static type. Thus, the dynamic type of an object (also called the actual type of an object) can be a descendant of the type which appears in the handle declaration through which it is manipulated.
341 Consider the class *CartesianPoint*, a sub-class of *Point*; the rule of type conformity can be illustrated as follows:
344 Handle (Geom_Point) p1;
345 Handle (Geom_CartesianPoint) p2;
346 p2 = new Geom_CartesianPoint;
347 p1 = p2; // OK, the types are compatible
351 The compiler sees p1 as a handle to *Point* though the actual object referenced by *p1* is of the *CartesianPoint* type.
353 #### Explicit Type Conversion
355 According to the rule of type conformity, it is always possible to go up the class hierarchy through successive assignments of handles. On the other hand, assignment does not authorize you to go down the hierarchy. Consequently, an explicit type conversion of handles is required.
357 A handle can be converted explicitly into one of its sub-types if the actual type of the referenced object is a descendant of the object used to cast the handle. If this is not the case, the handle is nullified (explicit type conversion is sometimes called a “safe cast”). Consider the example below.
360 Handle (Geom_Point) p1;
361 Handle (Geom_CartesianPoint) p2, p3;
362 p2 = new Geom_CartesianPoint;
363 p1 = p2; // OK, standard assignment
364 p3 = Handle (Geom_CartesianPoint)::DownCast (p1);
365 // OK, the actual type of p1 is CartesianPoint, although the static type of the handle is Point
368 If conversion is not compatible with the actual type of the referenced object, the handle which was “cast” becomes null (and no exception is raised). So, if you require reliable services defined in a sub-class of the type seen by the handle (static type), write as follows:
371 void MyFunction (const Handle(A) & a)
373 Handle(B) b = Handle(B)::DownCast(a);
375 // we can use “b” if class B inherits from A
378 // the types are incompatible
382 Downcasting is used particularly with collections of objects of different types; however, these objects should inherit from the same root class.
384 For example, with a sequence of transient objects *SequenceOfTransient* and two classes A and B that both inherit from *Standard_Transient*, you get the following syntax:
389 Handle (Standard_Transient) t;
390 SequenceOfTransient s;
396 // here, you cannot write:
399 a = Handle (A)::Downcast (t)
401 // types are compatible, you can use a
404 // the types are incompatible
408 @subsubsection occt_fcug_2_2_3 Using Handles to Create Objects
410 To create an object which is manipulated by handle, declare the handle and initialize it with the standard C++ **new** operator, immediately followed by a call to the constructor. The constructor can be any of those specified in the source of the class from which the object is instanced.
413 Handle (Geom_CartesianPoint) p;
414 p = new Geom_CartesianPoint (0, 0, 0);
417 Unlike for a pointer, the **delete** operator does not work on a handle; the referenced object is automatically destroyed when no longer in use.
419 @subsubsection occt_fcug_2_2_4 Invoking Methods
420 Once you have a handle to an object, you can use it like a pointer in C++. To invoke a method which acts on the referenced object, you translate this method by the standard *arrow* operator, or alternatively, by function call syntax when this is available.
422 To test or to modify the state of the handle, the method is translated by the *dot* operator.
423 The example below illustrates how to access the coordinates of an (optionally initialized) point object:
426 Handle (Geom_CartesianPoint) centre;
427 Standard_Real x, y, z;
428 if (centre.IsNull()) {
429 centre = new PGeom_CartesianPoint (0, 0, 0);
431 centre->Coord(x, y, z);
434 The example below illustrates how to access the type object of a Cartesian point:
437 Handle(Standard_Transient) p = new Geom_CartesianPoint(0.,0.,0.);
438 if ( p->DynamicType() == STANDARD_TYPE(Geom_CartesianPoint) )
439 cout << ;Type check OK; << endl;
441 cout << ;Type check FAILED; << endl;
444 *NullObject* exception will be raised if a field or a method of an object is accessed via a *Null* handle.
446 #### Invoking Class Methods
448 A class method is called like a static C++ function, i.e. it is called by the name of the class of which it is a member, followed by the “::” operator and the name of the method.
450 For example, we can find the maximum degree of a Bezier curve:
454 n = Geom_BezierCurve::MaxDegree();
457 @subsubsection occt_fcug_2_2_5 Handle deallocation
459 Before you delete an object, you must ensure it is no longer referenced. To reduce the programming load related to this management of object life, the delete function in Open CASCADE Technology is secured by a **reference counter** of classes manipulated by handle. A handle automatically deletes an object when it is no longer referenced. Normally you never call the delete operator explicitly on instances of subclasses of *Standard_Transient*.
461 When a new handle to the same object is created, the reference counter is incremented. When the handle is destroyed, nullified, or reassigned to another object, that counter is decremented. The object is automatically deleted by the handle when reference counter becomes 0.
463 The principle of allocation can be seen in the example below.
468 Handle (TColStd_HSequenceOfInteger) H1 = new TColStd_HSequenceOfInteger;
469 // H1 has one reference and corresponds to 48 bytes of memory
471 Handle (TColStd_HSequenceOfInteger) H2;
472 H2 = H1; // H1 has two references
474 Handle (TColStd_HSequenceOfInteger) H3;
476 // Here, H1 has three references
479 // Here, H1 has two references
481 // Here, H1 has 1 reference
483 // Here, H1 has no reference and the referred TColStd_HSequenceOfInteger object is deleted.
486 You can easily cast a reference to the handle object to <i> void* </i> by defining the following:
490 Handle(Some_class) aHandle;
491 // Here only a pointer will be copied
493 // Here the Handle object will be copied
494 aHandle = * (Handle(Some_Class) *)pointer;
498 @subsubsection occt_fcug_2_2_6 Cycles
500 Cycles appear if two or more objects reference each other by handles (stored as fields). In this condition automatic destruction will not work.
502 Consider for example a graph, whose objects (primitives) have to know the graph object to which they belong, i.e. a primitive must have a reference to complete graph object. If both primitives and the graph are manipulated by handle and they refer to each other by keeping a handle as a field, the cycle appears.
504 The graph object will not be deleted when the last handle to it is destructed in the application, since there are handles to it stored inside its own data structure (primitives).
506 There are two approaches how to avoid such situation:
507 * Use C++ pointer for one kind of references, e.g. from a primitive to the graph
508 * Nullify one set of handles (e.g. handles to a graph in primitives) when a graph object needs to be destroyed
510 @subsection occt_fcug_2_3 Memory Management
512 In a work session, geometric modeling applications create and delete a considerable number of C++ objects allocated in the dynamic memory (heap). In this context, performance of standard functions for allocating and deallocating memory may be not sufficient. For this reason, Open CASCADE Technology employs a specialized memory manager implemented in the *Standard* package.
514 The Memory Manager is based on the following principles:
516 * small memory arrays are grouped into clusters and then recycled (clusters are never released to the system),
517 * large arrays are allocated and de-allocated through the standard functions of the system (the arrays are released to system when they are no longer used).
519 As a general rule, it is advisable to allocate memory through significant blocks. In this way, the user can work with blocks of contiguous data and it facilitates memory page manager processing.
521 @subsubsection occt_fcug_2_3_1 Usage of Memory Manager
523 To allocate memory in a C code with Open CASCADE Technology memory manager, simply use method *Standard::Allocate()* instead of *malloc()* and method *Standard::Free()* instead of *free()*. In addition, method *Standard::Reallocate()* is provided to replace C function *realloc()*.
525 In C++, operators *new()* and *delete()* for a class may be defined so as to allocate memory using *Standard::Allocate()* and free it using *Standard::Free()*. In that case all objects of that class and all inherited classes will be allocated using the OCCT memory manager.
527 Preprocessor macro *DEFINE_STANDARD_ALLOC* provided by header *Standard_DefineAlloc.hxx* defines *new()* and *delete()* in this way.
528 It is used for all OCCT classes (apart from a few exceptions) which thus are allocated using the OCCT memory manager.
529 Since operators *new()* and *delete()* are inherited, this is also true for any class derived from an OCCT class, for instance, for all classes derived from *Standard_Transient*.
531 **Note** that it is possible (though not recommended unless really unavoidable) to redefine *new()* and *delete()* functions for a class inheriting *Standard_Transient*. If that is done, the method *Delete()* should be also redefined to apply operator *delete* to this pointer. This will ensure that appropriate *delete()* function will be called, even if the object is manipulated by a handle to a base class.
533 @subsubsection occt_fcug_2_3_2 How to configure the Memory Manager
535 The OCCT memory manager may be configured to apply different optimization techniques to different memory blocks (depending on their size), or even to avoid any optimization and use C functions *malloc()* and *free()* directly.
536 The configuration is defined by numeric values of the following environment variables:
537 * *MMGT_OPT*: if set to 0 (default) every memory block is allocated in C memory heap directly (via *malloc()* and *free()* functions). In this case, all other options except for *MMGT_CLEAR* are ignored; if set to 1 the memory manager performs optimizations as described below; if set to 2, Intel ® TBB optimized memory manager is used.
538 * *MMGT_CLEAR*: if set to 1 (default), every allocated memory block is cleared by zeros; if set to 0, memory block is returned as it is.
539 * *MMGT_CELLSIZE*: defines the maximal size of blocks allocated in large pools of memory. Default is 200.
540 * *MMGT_NBPAGES*: defines the size of memory chunks allocated for small blocks in pages (operating-system dependent). Default is 1000.
541 * *MMGT_THRESHOLD*: defines the maximal size of blocks that are recycled internally instead of being returned to the heap. Default is 40000.
542 * *MMGT_MMAP*: when set to 1 (default), large memory blocks are allocated using memory mapping functions of the operating system; if set to 0, they will be allocated in the C heap by *malloc()*.
544 @subsubsection occt_fcug_2_3_3 Optimization Techniques
546 When *MMGT_OPT* is set to 1, the following optimization techniques are used:
547 * Small blocks with a size less than *MMGT_CELLSIZE*, are not allocated separately. Instead, a large pools of memory are allocated (the size of each pool is *MMGT_NBPAGES* pages). Every new memory block is arranged in a spare place of the current pool. When the current memory pool is completely occupied, the next one is allocated, and so on.
549 In the current version memory pools are never returned to the system (until the process finishes). However, memory blocks that are released by the method *Standard::Free()* are remembered in the free lists and later reused when the next block of the same size is allocated (recycling).
551 * Medium-sized blocks, with a size greater than *MMGT_CELLSIZE* but less than *MMGT_THRESHOLD*, are allocated directly in the C heap (using *malloc()* and *free()*). When such blocks are released by the method *Standard::Free()* they are recycled just like small blocks.
553 However, unlike small blocks, the recycled medium blocks contained in the free lists (i.e. released by the program but held by the memory manager) can be returned to the heap by method *Standard::Purge()*.
555 * Large blocks with a size greater than *MMGT_THRESHOLD*, including memory pools used for small blocks, are allocated depending on the value of *MMGT_MMAP*: if it is 0, these blocks are allocated in the C heap; otherwise they are allocated using operating-system specific functions managing memory mapped files. Large blocks are returned to the system immediately when *Standard::Free()* is called.
557 @subsubsection occt_fcug_2_3_4 Benefits and drawbacks
559 The major benefit of the OCCT memory manager is explained by its recycling of small and medium blocks that makes an application work much faster when it constantly allocates and frees multiple memory blocks of similar sizes. In practical situations, the real gain on the application performance may be up to 50%.
561 The associated drawback is that recycled memory is not returned to the operating system during program execution. This may lead to considerable memory consumption and even be misinterpreted as a memory leak. To minimize this effect it is necessary to call the method *Standard::Purge* after the completion of memory-intensive operations.
563 The overhead expenses induced by the OCCT memory manager are:
564 * size of every allocated memory block is rounded up to 8 bytes (when *MMGT_OPT* is 0 (default), the rounding is defined by the CRT; the typical value for 32-bit platforms is 4 bytes)
565 * additional 4 bytes (or 8 on 64-bit platforms) are allocated in the beginning of every memory block to hold its size (or address of the next free memory block when recycled in free list) only when *MMGT_OPT* is 1.
567 Note that these overheads may be greater or less than overheads induced by the C heap memory manager, so overall memory consumption may be greater in either optimized or standard modes, depending on circumstances.
569 As a general rule, it is advisable to allocate memory through significant blocks. In this way, you can work with blocks of contiguous data, and processing is facilitated for the memory page manager.
571 OCCT memory manager uses mutex to lock access to free lists, therefore it may have less performance than non-optimized mode in situations when different threads often make simultaneous calls to the memory manager.
572 The reason is that modern implementations of *malloc()* and *free()* employ several allocation arenas and thus avoid delays waiting mutex release, which are possible in such situations.
574 @subsection occt_fcug_2_4 Exceptions
576 @subsubsection occt_fcug_2_4_1 Introduction
578 The behavior of any object is implemented by the methods, which were defined in its class declaration. The definition of these methods includes not only their signature (their programming interface) but also their domain of validity.
580 This domain is expressed by **exceptions**. Exceptions are raised under various error conditions to protect software quality.
582 Exception handling provides a means of transferring control from a given point in a program being executed to an **exception handler** associated with another point previously executed.
584 A method may raise an exception which interrupts its normal execution and transfers control to the handler catching this exception.
586 A hierarchy of commonly used exception classes is provided. The root class is *Standard_Failure* from the *Standard* package. So each exception inherits from *Standard_Failure* either directly or by inheriting from another exception. Exception classes list all exceptions, which can be raised by any OCCT function.
588 Open CASCADE Technology also provides support for converting system signals (such as access violation or division by zero) to exceptions, so that such situations can be safely handled with the same uniform approach.
590 However, in order to support this functionality on various platforms, some special methods and workarounds are used. Though the implementation details are hidden and handling of OCCT exceptions is done basically in the same way as with C++, some peculiarities of this approach shall be taken into account and some rules must be respected.
592 The following paragraphs describe recommended approaches for using exceptions when working with Open CASCADE Technology.
594 @subsubsection occt_fcug_2_4_2 Raising an Exception
596 #### “C++ like” Syntax
598 To raise an exception of a definite type method Raise() of the appropriate exception class shall be used.
600 DomainError::Raise(“Cannot cope with this condition”);
602 raises an exception of *DomainError* type with the associated message “Cannot cope with this condition”, the message being optional. This exception may be caught by a handler of a *DomainError* type as follows:
609 // handle DomainError exceptions here
615 Exceptions should not be used as a programming technique, to replace a “goto” statement for example, but as a way to protect methods against misuse. The caller must make sure its condition is such that the method can cope with it.
618 * No exception should be raised during normal execution of an application.
619 * A method which may raise an exception should be protected by other methods allowing the caller to check on the validity of the call.
621 For example, if you consider the *TCollection_Array1* class used with:
622 * *Value* function to extract an element
623 * *Lower* function to extract the lower bound of the array
624 * *Upper* function to extract the upper bound of the array.
626 then, the *Value* function may be implemented as follows:
629 Item TCollection_Array1::Value (const Standard_Integer&index) const
631 // where r1 and r2 are the lower and upper bounds of the array
632 if(index < r1 || index > r2) {
633 OutOfRange::Raise(“Index out of range in Array1::Value”);
635 return contents[index];
639 Here validity of the index is first verified using the Lower and Upper functions in order to protect the call.
640 Normally the caller ensures the index being in the valid range before calling <i>Value()</i>. In this case the above implementation of *Value* is not optimal since the test done in *Value* is time-consuming and redundant.
642 It is a widely used practice to include that kind of protections in a debug build of the program and exclude in release (optimized) build. To support this practice, the macros <i>Raise_if()</i> are provided for every OCCT exception class:
644 <ErrorTypeName>_Raise_if(condition, “Error message”);
646 where *ErrorTypeName* is the exception type, *condition* is the logical expression leading to the raise of the exception, and *Error message* is the associated message.
648 The entire call may be removed by defining one of the preprocessor symbols *No_Exception* or <i>No_<ErrorTypeName></i> at compile-time:
651 #define No_Exception /* remove all raises */
654 Using this syntax, the *Value* function becomes:
657 Item TCollection_Array1::Value (const Standard_Integer&index) const
659 OutOfRange_Raise_if(index < r1 || index > r2,
660 “index out of range in Array1::Value”);
661 return contents[index];
665 @subsubsection occt_fcug_2_4_3 Handling an Exception
667 When an exception is raised, control is transferred to the nearest handler of a given type in the call stack, that is:
668 * the handler whose try block was most recently entered and not yet exited,
669 * the handler whose type matches the raise expression.
671 A handler of T exception type is a match for a raise expression with an exception type of E if:
672 * T and E are of the same type, or
673 * T is a supertype of E.
675 In order to handle system signals as exceptions, make sure to insert macro *OCC_CATCH_SIGNALS* somewhere in the beginning of the relevant code. The recommended location for it is first statement after opening brace of <i>try {}</i> block.
677 As an example, consider the exceptions of type *NumericError, Overflow, Underflow* and *ZeroDivide*, where *NumericError* is the parent type of the three others.
686 catch(Standard_Overflow) { // first handler
689 catch(Standard_NumericError) { // second handler
695 Here, the first handler will catch exceptions of *Overflow* type and the second one -- exceptions of *NumericError* type and all exceptions derived from it, including *Underflow* and *ZeroDivide*.
697 The handlers are checked in order of appearance, from the nearest to the try block to the most distant from it, until one matches the raise expression. For a try block, it would be a mistake to place a handler for a base exception type ahead of a handler for its derived type since that would ensure that the handler for the derived exception would never be invoked.
706 g(i);// i is accessible
708 // statement here will produce compile-time errors !
709 catch(Standard_NumericError) {
710 // fix up with possible reuse of i
712 // statement here may produce unexpected side effect
718 The exceptions form a hierarchy tree completely separated from other user defined classes. One exception of type *Failure* is the root of the entire exception hierarchy. Thus, using a handler with *Failure* type catches any OCCT exception. It is recommended to set up such a handler in the main routine.
720 The main routine of a program would look like this:
723 #include <Standard_ErrorHandler.hxx>
724 #include <Standard_Failure.hxx>
725 #include <iostream.h>
726 int main (int argc, char* argv[])
733 catch(Standard_Failure) {
734 Handle(Standard_Failure) error = Standard_Failure::Caught ();
741 In this example function *Caught* is a static member of *Failure* that returns an exception object containing the error message built in the raise expression. Note that this method of accessing a raised object is used in Open CASCADE Technology instead of usual C++ syntax (receiving the exception in catch argument).
743 Though standard C++ scoping rules and syntax apply to try block and handlers, note that on some platforms Open CASCADE Technology may be compiled in compatibility mode when exceptions are emulated by long jumps (see below). In this mode it is required that no statement precedes or follows any handler. Thus it is highly recommended to always include a try block into additional {} braces. Also this mode requires that header file *Standard_ErrorHandler.hxx* be included in your program before a try block, otherwise it may fail to handle Open CASCADE Technology exceptions; furthermore *catch()* statement does not allow passing exception object as argument.
745 #### Catching signals
747 In order for the application to be able to catch system signals (access violation, division by zero, etc.) in the same way as other exceptions, the appropriate signal handler shall be installed in the runtime by the method *OSD::SetSignal()*.
749 Normally this method is called in the beginning of the main() function. It installs a handler that will convert system signals into OCCT exceptions.
751 In order to actually convert signals to exceptions, macro *OCC_CATCH_SIGNALS* needs to be inserted in the source code. The typical place where this macro is put is beginning of the *try{}* block which catches such exceptions.
753 @subsubsection occt_fcug_2_4_4 Implementation on various platforms.
755 The exception handling mechanism in Open CASCADE Technology is implemented in different ways depending on the preprocessor macro *OCC_CONVERT_SIGNALS*, which shall be consistently defined by compilation procedures for both Open CASCADE Technology and user applications:
757 1. On Windows, these macros are not defined by default, and normal C++ exceptions are used in all cases, including throwing from signal handler. Thus the behavior is as expected in C++.
759 2. On Linux, macro *OCC_CONVERT_SIGNALS* is defined by default. The C++ exception mechanism is used for catching exceptions and for throwing them from normal code. Since it is not possible to throw C++ exception from system signal handler function, that function makes a long jump to the nearest (in the execution stack) invocation of macro *OCC_CATCH_SIGNALS*, and only there the C++ exception gets actually thrown. The macro *OCC_CATCH_SIGNALS* is defined in the file *Standard_ErrorHandler.hxx*. Therefore, including this file is necessary for successful compilation of a code containing this macro.
761 This mode differs from standard C++ exception handling only for signals:
763 * macro *OCC_CATCH_SIGNALS* is necessary (besides call to *OSD::SetSignal()* described above) for conversion of signals into exceptions;
764 * the destructors for automatic C++ objects created in the code after that macro and till the place where signal is raised will not be called in case of signal, since no C++ stack unwinding is performed by long jump.
766 In general, for writing platform-independent code it is recommended to insert macros *OCC_CATCH_SIGNALS* in try {} blocks or other code where signals may happen.
768 @subsection occt_fcug_2_5 Plug-In Management
770 @subsubsection occt_fcug_2_5_1 Distribution by Plug-Ins
772 A plug-in is a component that can be loaded dynamically into a client application, not requiring to be directly linked to it. The plug-in is not bound to its client, i.e. the plug-in knows only how its connection mechanism is defined and how to call the corresponding services.
774 A plug-in can be used to:
775 * implement the mechanism of a *driver*, i.e dynamically changing a driver implementation according to the current transactions (for example, retrieving a document stored in another version of an application),
776 * restrict processing resources to the minimum required (for example, it does not load any application services at run-time as long as the user does not need them),
777 * facilitate modular development (an application can be delivered with base functions while some advanced capabilities will be added as plug-ins when they are available).
779 The plug-in is identified with the help of the global universal identifier (GUID). The GUID includes lower case characters and cannot end with a blank space.
781 Once it has been loaded, the call to the services provided by the plug-in is direct (the client is implemented in the same language as the plug-in).
783 #### C++ Plug-In Implementation
785 The C++ plug-in implements a service as an object with functions defined in an abstract class (this abstract class and its parent classes with the GUID are the only information about the plug-in implemented in the client application). The plug-in consists of a sharable library including a method named Factory which creates the C++ object (the client cannot instantiate this object because the plug-in implementation is not visible).
786 Foundation classes provide in the package *Plugin* a method named *Load()*, which enables the client to access the required service through a library.
788 That method reads the information regarding available plug-ins and their locations from the resource file *Plugin* found by environment variable *CSF_PluginDefaults*:
791 $CSF_PluginDefaults/Plugin
794 The *Load* method looks for the library name in the resource file or registry through its GUID, for example, on UNIX:
796 ! METADATADRIVER whose value must be OS or DM.
799 a148e300-5740-11d1-a904-080036aaa103.Location: libFWOSPlugin.so
802 Then the *Load* method loads the library according to the rules of the operating system of the host machine (for example, by using environment variables such as *LD_LIBRARY_PATH* with Unix and *PATH* with Windows). After that it invokes the *PLUGINFACTORY* method to return the object, which supports the required service.
803 The client may then call the functions supported by this object.
805 #### C++ Client Plug-In Implementation
807 To invoke one of the services provided by the plug-in, you may call the *Plugin::Load()* global function with the *Standard_GUID* of the requested service as follows:
810 Handle(FADriver_PartStorer)::DownCast(PlugIn::Load (yourStandardGUID));
813 Let us take *FAFactory.hxx* and *FAFactory.cxx* as an example:
816 #include <Standard_Macro.hxx>
817 #include <Standard_GUID.hxx>
818 #include <Standard_Transient.hxx>
823 Standard_EXPORT static Handle(Standard_Transient) Factory (const Standard_GUID& theGUID);
828 #include <FAFactory.hxx>
830 #include <FADriver_PartRetriever.hxx>
831 #include <FADriver_PartStorer.hxx>
832 #include <FirstAppSchema.hxx>
833 #include <Standard_Failure.hxx>
834 #include <FACDM_Application.hxx>
835 #include <Plugin_Macro.hxx>
837 static Standard_GUID StorageDriver ("45b3c690-22f3-11d2-b09e-0000f8791463");
838 static Standard_GUID RetrievalDriver("45b3c69c-22f3-11d2-b09e-0000f8791463");
839 static Standard_GUID Schema ("45b3c6a2-22f3-11d2-b09e-0000f8791463");
841 //======================================================
842 // function : Factory
844 //======================================================
846 Handle(Standard_Transient) FAFactory::Factory (const Standard_GUID& theGUID)
848 if (theGUID == StorageDriver)
850 std::cout << "FAFactory : Create store driver\n";
851 static Handle(FADriver_PartStorer) sd = new FADriver_PartStorer();
855 if (theGUID == RetrievalDriver)
857 std::cout << "FAFactory : Create retrieve driver\n";
858 static Handle(FADriver_PartRetriever) rd = new FADriver_PartRetriever();
862 if (theGUID == Schema)
864 std::cout << "FAFactory : Create schema\n";
865 static Handle(FirstAppSchema) s = new FirstAppSchema();
869 Standard_Failure::Raise ("FAFactory: unknown GUID");
870 return Handle(Standard_Transient)();
873 // export plugin function "PLUGINFACTORY"
877 Application might also instantiate a factory by linking to the library and calling *FAFactory::Factory()* directly.
879 @section occt_fcug_3 Collections, Strings, Quantities and Unit Conversion
881 @subsection occt_fcug_3_1 Collections
883 @subsubsection occt_fcug_3_1_1 Overview
885 The **Collections** component contains the classes that handle dynamically sized aggregates of data. They include a wide range of collections such as arrays, lists and maps.
887 Collections classes are *generic* (C++ template-like), that is, they define a structure and algorithms allowing to hold a variety of objects which do not necessarily inherit from a unique root class (similarly to C++ templates).
889 When you need to use a collection of a given type of object you must *instantiate* it for this specific type of element. Once this declaration is compiled, all the functions available on the generic collection are available on your *instantiated class*.
892 * Each collection directly used as an argument in OCCT public syntax is instantiated in an OCCT component.
893 * The *TColStd* package (**Collections of Standard Objects** component) provides numerous instantiations of these generic collections with objects from the **Standard** package or from the **Strings** component.
894 The **Collections** component provides a wide range of generic collections:
895 * **Arrays** are generally used for a quick access to the item, however an array is a fixed sized aggregate.
896 * **Sequences** are variable-sized structures, they avoid the use of large and quasi-empty arrays. A sequence item is longer to access than an array item: only an exploration in sequence is effective (but sequences are not adapted for numerous explorations). Arrays and sequences are commonly used as data structures for more complex objects.
897 * **Maps** are dynamic structures, where the size is constantly adapted to the number of inserted items and access to an item is the fastest. Maps structures are commonly used in cases of numerous explorations: they are typically internal data structures for complex algorithms.
898 * **Lists** are similar to sequences but have different algorithms to explore them.
899 * Specific iterators for sequences and maps.
901 @subsubsection occt_fcug_3_1_2 Generic general-purpose Aggregates
903 #### TCollection_Array1
905 These are unidimensional arrays similar to C arrays, i.e. of fixed size but dynamically dimensioned at construction time.
906 As with a C array, the access time for an *Array1* indexed item is constant and is independent of the array size. Arrays are commonly used as elementary data structures for more complex objects.
908 *Array1* is a generic class which depends on *Item*, the type of element in the array.
910 *Array1* indexes start and end at a user-defined position. Thus, when accessing an item, you must base the index on the lower and upper bounds of the array.
912 #### TCollection_Array2
914 These are bi-dimensional arrays of fixed size but dynamically dimensioned at construction time.
916 As with a C array, the access time for an *Array2* indexed item is constant and is independent of the array size. Arrays are commonly used as elementary data structures for more complex objects.
918 *Array2* is a generic class which depends on *Item*, the type of element in the array.
920 *Array2* indexes start and end at a user-defined position. Thus, when accessing an item, you must base the index on the lower and upper bounds of the array.
922 #### TCollection_HArray1
924 These are unidimensional arrays similar to C arrays, i.e. of fixed size but dynamically dimensioned at construction time.
925 As with a C array, the access time for an *HArray1* or *HArray2* indexed item is constant and is independent of the array size. Arrays are commonly used as elementary data structures for more complex objects.
927 *HArray1* objects are **handles** to arrays.
928 * *HArray1* arrays may be shared by several objects.
929 * You may use a *TCollection_Array1* structure to have the actual array.
931 *HArray1* is a generic class which depends on two parameters:
932 * **Item**, the type of element in the array,
933 * **Array**, the actual type of array handled by *HArray1*. This is an instantiation with **Item** of the *TCollection_Array1* generic class.
935 *HArray1* indexes start and end at a user-defined position. Thus, when accessing an item, you must base the index on the lower and upper bounds of the array.
937 #### TCollection_HArray2
939 These are bi-dimensional arrays of fixed size but dynamically dimensioned at construction time.
941 As with a C array, the access time for an *HArray2* indexed item is constant and is independent of the array size. Arrays are commonly used as elementary data structures for more complex objects.
943 *HArray2* objects are **handles** to arrays.
944 * *HArray2* arrays may be shared by several objects.
945 * You may use a *TCollection_Array2* structure to have the actual array.
947 *HArray2* is a generic class which depends on two parameters:
948 * *Item*, the type of element in the array,
949 * *Array*, the actual type of array handled by *HArray2*. This is an instantiation with *Item* of the *TCollection_Array2* generic class.
951 #### TCollection_HSequence
953 This is a sequence of items indexed by an integer.
955 Sequences have about the same goal as unidimensional arrays *TCollection_HArray1*: they are commonly used as elementary data structures for more complex objects. But a sequence is a structure of *variable size*: sequences avoid the use of large and quasi-empty arrays. Exploring a sequence data structure is effective when the exploration is done in sequence; elsewhere a sequence item is longer to read than an array item. Note also that sequences are not effective when they have to support numerous algorithmic explorations: a map is better for that.
957 *HSequence* objects are **handles** to sequences.
958 * *HSequence* sequences may be shared by several objects.
959 * You may use a *TCollection_Sequence* structure to have the actual sequence.
961 *HSequence* is a generic class which depends on two parameters:
962 * *Item*, the type of element in the sequence,
963 * *Seq*, the actual type of sequence handled by *HSequence*. This is an instantiation with *Item* of the *TCollection_Sequence* generic class.
965 #### TCollection_List
967 These are ordered lists of non-unique objects which can be accessed sequentially using an iterator.
968 Item insertion in a list is very fast at any position. But searching for items by value may be slow if the list is long, because it requires a sequential search.
970 *List* is a generic class, which depends on *Item*, the type of element in the structure.
971 Use a *ListIterator* iterator to explore a *List* structure.
973 An iterator class is automatically instantiated from the *TCollection_ListIterator* class at the time of instantiation of a *List* structure.
975 A sequence is a better structure when searching for items by value.
977 Queues and stacks are other kinds of list with a different access to data.
979 #### TCollection_Sequence
981 This is a sequence of items indexed by an integer.
982 Sequences have about the same goal as unidimensional arrays (*TCollection_Array1*): they are commonly used as elementary data structures for more complex objects. But a sequence is a structure of *variable size*: sequences avoid the use of large and quasi-empty arrays. Exploring a sequence data structure is effective when the exploration is done *in sequence*; elsewhere a sequence item is longer to read than an array item. Note also that sequences are not effective when they have to support numerous algorithmic explorations: a map is better for that.
984 *Sequence* is a generic class which depends on *Item*, the type of element in the sequence.
986 @subsubsection occt_fcug_3_1_3 Generic Maps
988 Maps are dynamically extended data structures where data is quickly accessed with a key. *TCollection_BasicMap* is a root class for maps.
990 #### General properties of maps
992 Map items may contain complex non-unitary data, thus it can be difficult to manage them with an array. The map allows a data structure to be indexed by complex data.
994 The size of a map is dynamically extended. So a map may be first dimensioned for a little number of items. Maps avoid the use of large and quasi-empty arrays.
996 The access time for a map item is much better than the one for a sequence, list, queue or stack item. It is comparable with the access time for an array item. It depends on the size of the map and on the quality of the user redefinable function (the *hashing function*) to find quickly where is the item.
998 The performance of a map exploration may be better of an array exploration because the size of the map is adapted to the number of inserted items.
1000 That is why maps are commonly used as internal data structures for algorithms.
1004 A map is a data structure for which data are addressed by *keys*.
1006 Once inserted in the map, a map item is referenced as an *entry* of the map.
1008 Each entry of the map is addressed by a key. Two different keys address two different entries of the map.
1009 The position of an entry in the map is called a *bucket*.
1011 A map is dimensioned by its number of buckets, i.e. the maximum number of entries in the map. The performance of a map is conditioned by the number of buckets.
1013 The *hashing function* transforms a key into a bucket index. The number of values that can be computed by the hashing function is equal to the number of buckets of the map.
1015 Both the hashing function and the equality test between two keys are provided by a *hasher* object.
1017 A map may be explored by a *map iterator*. This exploration provides only inserted entries in the map (i.e. non empty buckets).
1019 #### Collections of generic maps
1021 The *Collections* component provides numerous generic derived maps.
1023 These maps include automatic management of the number of *buckets*: they are automatically resized when the number of *keys* exceeds the number of buckets. If you have a fair idea of the number of items in your map, you can save on automatic resizing by specifying a number of buckets at the time of construction, or by using a resizing function. This may be considered for crucial optimization issues.
1025 *Keys, items* and *hashers* are parameters of these generic derived maps.
1027 *TCollection_MapHasher* class describes the functions required by any *hasher*, which is to be used with a map instantiated from the **Collections** component.
1029 An iterator class is automatically instantiated at the time of instantiation of a map provided by the *Collections* component if this map is to be explored with an iterator. Note that some provided generic maps are not to be explored with an iterator but with indexes (*indexed maps*).
1031 ##### TCollection_DataMap
1033 This is a map used to store keys with associated items. An entry of **DataMap** is composed of both the key and the item.
1034 The *DataMap* can be seen as an extended array where the keys are the indexes.
1036 *DataMap* is a generic class which depends on three parameters:
1037 * *Key* is the type of key for an entry in the map,
1038 * *Item* is the type of element associated with a key in the map,
1039 * *Hasher* is the type of hasher on keys.
1041 Use a *DataMapIterator* iterator to explore a *DataMap* map.
1043 An iterator class is automatically instantiated from the *TCollection_DataMapIterator* generic class at the time of instantiation of a *DataMap* map.
1045 *TCollection_MapHasher* class describes the functions required for a *Hasher* object.
1047 ##### TCollection_DoubleMap
1049 This is a map used to bind pairs of keys (Key1,Key2) and retrieve them in linear time.
1051 *Key1* is referenced as the first key of the *DoubleMap* and *Key2* as the second key.
1053 An entry of a *DoubleMap* is composed of a pair of two keys: the first key and the second key.
1055 *DoubleMap* is a generic class which depends on four parameters:
1056 * *Key1* is the type of the first key for an entry in the map,
1057 * *Key2* is the type of the second key for an entry in the map,
1058 * *Hasher1* is the type of hasher on first keys,
1059 * *Hasher2* is the type of hasher on second keys.
1061 Use *DoubleMapIterator* to explore a *DoubleMap* map.
1063 An iterator class is automatically instantiated from the *TCollection_DoubleMapIterator* class at the time of instantiation of a *DoubleMap* map.
1065 *TCollection_MapHasher* class describes the functions required for a *Hasher1* or a *Hasher2* object.
1067 ##### TCollection_IndexedDataMap
1069 This is map to store keys with associated items and to bind an index to them.
1071 Each new key stored in the map is assigned an index. Indexes are incremented as keys (and items) stored in the map. A key can be found by the index, and an index can be found by the key. No key but the last can be removed, so the indexes are in the range 1...Upper, where *Upper* is the number of keys stored in the map. An item is stored with each key.
1073 An entry of an *IndexedDataMap* is composed of both the key, the item and the index. An *IndexedDataMap* is an ordered map, which allows a linear iteration on its contents. It combines the interest:
1074 * of an array because data may be accessed with an index,
1075 * and of a map because data may also be accessed with a key.
1077 *IndexedDataMap* is a generic class which depends on three parameters:
1078 * *Key* is the type of key for an entry in the map,
1079 * *Item* is the type of element associated with a key in the map,
1080 * *Hasher* is the type of hasher on keys.
1082 ##### TCollection_IndexedMap
1084 This is map used to store keys and to bind an index to them.
1086 Each new key stored in the map is assigned an index. Indexes are incremented as keys stored in the map. A key can be found by the index, and an index by the key. No key but the last can be removed, so the indexes are in the range 1...Upper where Upper is the number of keys stored in the map.
1088 An entry of an *IndexedMap* is composed of both the key and the index. An *IndexedMap* is an ordered map, which allows a linear iteration on its contents. But no data is attached to the key. An *IndexedMap* is typically used by an algorithm to know if some action is still performed on components of a complex data structure.
1090 *IndexedMap* is a generic class which depends on two parameters:
1091 * *Key* is the type of key for an entry in the map,
1092 * *Hasher* is the type of hasher on keys.
1094 ##### TCollection_Map
1096 This is a basic hashed map, used to store and retrieve keys in linear time.
1098 An entry of a *Map* is composed of the key only. No data is attached to the key. A *Map* is typically used by an algorithm to know if some action is still performed on components of a complex data structure.
1100 *Map* is a generic class which depends on two parameters:
1101 * *Key* is the type of key in the map,
1102 * *Hasher* is the type of hasher on keys.
1104 Use a *MapIterator* iterator to explore a *Map* map.
1106 ##### TCollection_MapHasher
1108 This is a hasher on the *keys* of a map instantiated from the *Collections* component.
1110 A hasher provides two functions:
1111 * *HashCode()* function transforms a key into a bucket index in the map. The number of values that can be computed by the hashing function is equal to the number of buckets in the map.
1112 * *IsEqual* is the equality test between two keys. Hashers are used as parameters in generic maps provided by the **Collections** component.
1114 *MapHasher* is a generic class which depends on the type of keys, providing that *Key* is a type from the *Standard* package. In such cases *MapHasher* may be directly instantiated with *Key*. Note that the package *TColStd* provides some of these instantiations.
1116 Elsewhere, if *Key* is not a type from the *Standard* package you must consider *MapHasher* as a template and build a class which includes its functions, in order to use it as a hasher in a map instantiated from the *Collections* component.
1118 Note that *TCollection_AsciiString* and *TCollection_ExtendedString* classes correspond to these specifications, in consequence they may be used as hashers: when *Key* is one of these two types you may just define the hasher as the same type at the time of instantiation of your map.
1120 @subsubsection occt_fcug_3_1_4 Iterators
1122 #### TCollection_BasicMapIterator
1124 This is a root class for map iterators. A map iterator provides a step by step exploration of all the entries of a map.
1126 #### TCollection_DataMapIterator
1128 These are functions used for iterating the contents of a *DataMap* map.
1130 A map is a non-ordered data structure. The order in which entries of a map are explored by the iterator depends on its contents and change when the map is edited. It is not recommended to modify the contents of a map during the iteration: the result is unpredictable.
1132 #### TCollection_DoubleMapIterator
1134 These are functions used for iterating the contents of a *DoubleMap* map.
1136 #### TCollection_ListIterator
1138 These are unctions used for iterating the contents of a *List* data structure.
1140 A *ListIterator* object can be used to go through a list sequentially, and as a bookmark to hold a position in a list. It is not an index, however. Each step of the iteration gives the current position of the iterator, to which corresponds the current item in the list. The current position is not defined if the list is empty, or when the exploration is finished.
1142 An iterator class is automatically instantiated from this generic class at the time of instantiation of a *List* data structure.
1144 #### TCollection_MapIterator
1146 These are functions used for iterating the contents of a *Map* map.
1147 An iterator class is automatically instantiated from this generic class at the time of instantiation of a *Map* map.
1149 #### TCollection_SetIterator
1151 These are functions used for iterating the contents of a *Set* data structure.
1152 An iterator class is automatically instantiated from this generic class at the time of instantiation of a *Set* structure.
1154 #### TCollection_StackIterator
1156 These are functions used for iterating the contents of a **Stack** data structure.
1158 An iterator class is automatically instantiated from this generic class at the time of instantiation of a *Stack* structure.
1160 @subsection occt_fcug_3_2 Collections of Standard Objects
1161 @subsubsection occt_fcug_3_2_1 Overview
1162 While generic classes of the *TCollection* package are the root classes that describe the generic purpose of every type of collection, classes effectively used are extracted from the *TColStd* package.
1163 The *TColStd* and *TShort* packages provide frequently used instantiations of generic classes with objects from the *Standard* package or strings from the *TCollection* package.
1165 @subsubsection occt_fcug_3_2_2 Description
1166 These instantiations are the following:
1167 * Unidimensional arrays: instantiations of the *TCollection_Array1* generic class with *Standard* Objects and *TCollection* strings.
1168 * Bidimensional arrays: instantiations of the *TCollection_Array2* generic class with *Standard* Objects.
1169 * Unidimensional arrays manipulated by handles: instantiations of the *TCollection_HArray1* generic class with *Standard* Objects and *TCollection* strings.
1170 * Bidimensional arrays manipulated by handles: instantiations of the *TCollection_HArray2* generic class with *Standard* Objects.
1171 * Sequences: instantiations of the *TCollection_Sequence* generic class with *Standard* objects and *TCollection* strings.
1172 * Sequences manipulated by handles: instantiations of the *TCollection_HSequence* generic class with *Standard* objects and *TCollection* strings.
1173 * Lists: instantiations of the *TCollection_List* generic class with *Standard* objects.
1174 * Queues: instantiations of the *TCollection_Queue* generic class with *Standard* objects.
1175 * Sets: instantiations of the *TCollection_Set* generic class with *Standard* objects.
1176 * Sets manipulated by handles: instantiations of the *TCollection_HSet* generic class with *Standard* objects.
1177 * Stacks: instantiations of the *TCollection_Stack* generic class with *Standard* objects.
1178 * Hashers on map keys: instantiations of the *TCollection_MapHasher* generic class with *Standard* objects.
1179 * Basic hashed maps: instantiations of the *TCollection_Map* generic class with *Standard* objects.
1180 * Hashed maps with an additional item: instantiations of the *TCollection_DataMap* generic class with *Standard* objects.
1181 * Basic indexed maps: instantiations of the *TCollection_IndexedMap* generic class with *Standard* objects.
1182 * Indexed maps with an additional item: instantiations of the *TCollection_IndexedDataMap* generic class with *Standard_Transient* objects.
1183 * Class *TColStd_PackedMapOfInteger* provides alternative implementation of map of integer numbers, optimized for both performance and memory usage (it uses bit flags to encode integers, which results in spending only 24 bytes per 32 integers stored in optimal case). This class also provides Boolean operations with maps as sets of integers (union, intersection, subtraction, difference, checks for equality and containment).
1185 @subsection occt_fcug_3_3 NCollections
1186 @subsubsection occt_fcug_3_3_1 Overview
1188 The *NCollection* package provides a set of template collection classes used throughout OCCT.
1190 Macro definitions of these classes are stored in *NCollection_Define\*.hxx* files. These definitions are now obsolete though still can be used, particularly for compatibility with the existing code.
1192 @subsubsection occt_fcug_3_3_2 Instantiation of collection classes
1194 Now we are going to implement the definitions from *NCollection* in the code, taking as an example a sequence of points (analogue of *TColgp_SequenceOfPnt*).
1196 #### Definition of a new collection class
1198 Let the header file be *MyPackage_SequenceOfPnt.hxx* :
1200 Template class instantiaton
1202 #include <NCollection_Sequence.hxx>
1203 #include <gp_Pnt.hxx>
1204 typedef NCollection_Sequence<gp_Pnt> MyPackage_SequenceOfPnt;
1209 #include <NCollection_DefineSequence.hxx>
1210 #include <gp_Pnt.hxx>
1213 The following line defines the class "base collection of points"
1215 DEFINE_BASECOLLECTION(MyPackage_BaseCollPnt, gp_Pnt)
1218 The following line defines the class *MyPackage_SequenceOfPnt*
1221 DEFINE_SEQUENCE (MyPackage_SequenceOfPnt, MyPackage_BaseCollPnt , gp_Pnt)
1224 #### Definition of a new collection class managed by Handle
1226 It is necessary to provide relevant statements both in the header ( .hxx file) and the C++ source ( .cxx file).
1228 Header file MyPackage_HSequenceOfPnt.hxx:
1231 #include <NCollection_DefineHSequence.hxx>
1232 #include <gp_Pnt.hxx>
1235 The following line defines the class "base collection of points"
1238 DEFINE_BASECOLLECTION(MyPackage_BaseCollPnt, gp_Pnt)
1241 The following line defines the class *MyPackage_SequenceOfPnt*
1244 DEFINE_SEQUENCE (MyPackage_SequenceOfPnt, MyPackage_BaseCollPnt, gp_Pnt)
1247 The following line defines the classes *MyPackage_HSequenceOfPnt* and *Handle(MyPackage_HSequenceOfPnt)*
1250 DEFINE_HSEQUENCE (MyPackage_HSequenceOfPnt, MyPackage_SequenceOfPnt)
1253 Source code file will be *MyPackage_HSequenceOfPnt.cxx* or any other .cxx file (once in the whole project):
1256 IMPLEMENT_HSEQUENCE (MyPackage_HSequenceOfPnt)
1259 @subsubsection occt_fcug_3_3_3 Arrays and sequences
1261 Standard collections provided by OCCT are:
1262 * *NCollection_Array1* -- fixed-size (at initialization) one-dimensional array; note that the index can start at any value, usually 1;
1263 * *NCollection_Array2* -- fixed-size (at initialization) two-dimensional array; note that the index can start at any value, usually 1;
1264 * *NCollection_List* -- plain list;
1265 * *NCollection_Sequence* -- double-connected list with access by index; note that the index starts at 1.
1267 These classes provide STL-style iterators (methods begin() and end()) and thus can be used in STL algorithms.
1269 @subsubsection occt_fcug_3_3_3x Maps
1271 NCollection provides several classes for storage of objects by value, providing fast search due to use of hash:
1272 * *NCollection_Map* -- hash set;
1273 * *NCollection_IndexedMap* -- set with a prefixed order of elements, allowing fast access by index or by value (hash-based);
1274 * *NCollection_DataMap* -- hash map;
1275 * *NCollection_IndexedDataMap* -- map with a prefixed order of elements, allowing fast access by index or by value (hash-based);
1276 * *NCollection_DoubleMap* -- two-side hash map (with two keys).
1278 @subsubsection occt_fcug_3_3_4 Other collection types
1280 There are 4 collection types provided as template classes:
1281 * *NCollection_Vector*
1282 * *NCollection_UBTree*
1283 * *NCollection_SparseArray*
1284 * *NCollection_CellFilter*
1288 This type is implemented internally as a list of arrays of the same size. Its properties:
1289 * Direct (constant-time) access to members like in Array1 type; data are allocated in compact blocks, this provides faster iteration.
1290 * Can grow without limits, like List, Stack or Queue types.
1291 * Once having the size LEN, it cannot be reduced to any size less than LEN -- there is no operation of removal of items.
1293 Insertion in a Vector-type class is made by two methods:
1294 * _SetValue(ind, theValue)_ -- array-type insertion, where ind is the index of the inserted item, can be any non-negative number. If it is greater than or equal to Length(), then the vector is enlarged (its Length() grows).
1295 * _Append(theValue)_ -- list-type insertion equivalent to _myVec.SetValue(myVec.Length(), theValue)_, incrementing the size of the collection.
1297 Other essential properties coming from List and Array1 type collections:
1298 * Like in *List*, the method *Clear()* destroys all contained objects and releases the allocated memory.
1299 * Like in *Array1*, the methods *Value()* and *ChangeValue()* return a contained object by index. Also, these methods have the form of overloaded operator ().
1303 The name of this type stands for “Unbalanced Binary Tree”. It stores the members in a binary tree of overlapped bounding objects (boxes or else).
1304 Once the tree of boxes of geometric objects is constructed, the algorithm is capable of fast geometric selection of objects. The tree can be easily updated by adding to it a new object with bounding box.
1305 The time of adding to the tree of one object is O(log(N)), where N is the total number of objects, so the time of building a tree of N objects is O(N(log(N)). The search time of one object is O(log(N)).
1307 Defining various classes inheriting *NCollection_UBTree::Selector* we can perform various kinds of selection over the same b-tree object.
1309 The object may be of any type allowing copying. Among the best suitable solutions there can be a pointer to an object, handled object or integer index of object inside some collection. The bounding object may have any dimension and geometry. The minimal interface of *TheBndType* (besides public empty and copy constructor and operator =) used in UBTree algorithm as follows:
1315 inline void Add (const MyBndType& other);
1316 // Updates me with other bounding type instance
1318 inline Standard_Boolean IsOut (const MyBndType& other) const;
1319 // Classifies other bounding type instance relatively me
1321 inline Standard_Real SquareExtent() const;
1322 // Computes the squared maximal linear extent of me (for a box it is the squared diagonal of the box).
1327 This interface is implemented in types of Bnd package: *Bnd_Box, Bnd_Box2d, Bnd_B2x, Bnd_B3x*.
1329 To select objects you need to define a class derived from *UBTree::Selector* that should redefine the necessary virtual methods to maintain the selection condition. Usually this class instance is also used to retrieve selected objects after search.
1330 The class *UBTreeFiller* is used to randomly populate a *UBTree* instance. The quality of a tree is better (considering the speed of searches) if objects are added to it in a random order trying to avoid the addition of a chain of nearby objects one following another.
1331 Instantiation of *UBTreeFiller* collects objects to be added, and then adds them at once to the given UBTree instance in a random order using the Fisher-Yates algorithm.
1332 Below is the sample code that creates an instance of *NCollection_UBTree* indexed by 2D boxes (Bnd_B2f), then a selection is performed returning the objects whose bounding boxes contain the given 2D point.
1335 typedef NCollection_UBTree<MyData, Bnd_B2f> UBTree;
1336 typedef NCollection_List<MyData> ListOfSelected;
1337 //! Tree Selector type
1338 class MyTreeSelector : public UBTree::Selector
1341 // This constructor initializes the selection criterion (e.g., a point)
1343 MyTreeSelector (const gp_XY& thePnt) : myPnt(thePnt) {}
1344 // Get the list of selected objects
1346 const ListOfSelected& ListAccepted () const
1348 // Bounding box rejection - definition of virtual method. @return True if theBox is outside the selection criterion.
1350 Standard_Boolean Reject (const Bnd_B2f& theBox) const
1351 { return theBox.IsOut(myPnt); }
1352 // Redefined from the base class. Called when the bounding of theData conforms to the selection criterion. This method updates myList.
1354 Standard_Boolean Accept (const MyData& theData)
1355 { myList.Append(theData); }
1358 ListOfSelected myList;
1361 // Create a UBTree instance and fill it with data, each data item having the corresponding 2D box.
1364 NCollection_UBTreeFiller <MyData, Bnd_B2f> aTreeFiller(aTree);
1366 const MyData& aData = …;
1367 const Bnd_B2d& aBox = aData.GetBox();
1368 aTreeFiller.Add(aData, aBox);
1372 // Perform selection based on ‘aPoint2d’
1373 MyTreeSelector aSel(aPoint2d);
1375 const ListOfSelected = aSel.ListAccepted();
1382 This type has almost the same features as Vector but it allows to store items having scattered indices. In Vector, if you set an item with index 1000000, the container will allocate memory for all items with indices in the range 0-1000000. In SparseArray, only one small block of items will be reserved that contains the item with index 1000000.
1384 This class can be also seen as equivalence of *DataMap<int,TheItemType>* with the only one practical difference: it can be much less memory-expensive if items are small (e.g. Integer or Handle).
1386 This type has both interfaces of DataMap and Vector to access items.
1390 This class represents a data structure for sorting geometric objects in n-dimensional space into cells, with associated algorithm for fast checking of coincidence (overlapping, intersection, etc.) with other objects. It can be considered as a functional alternative to UBTree, as in the best case it provides the direct access to an object like in an n-dimensional array, while search with UBTree provides logarithmic law access time.
1392 @subsubsection occt_fcug_3_3_5 Features
1394 NCollection defines some specific features, in addition to the public API inherited from TCollection classes.
1398 Every collection defines its Iterator class capable of iterating the members in some predefined order. Every Iterator is defined as a subtype of the particular collection type (e.g., MyPackage_StackOfPnt::Iterator ). The order of iteration is defined by a particular collection type. The methods of Iterator are:
1400 * _void Init (const MyCollection&)_ -- initializes the iterator on the collection object;
1401 * _Standard_Boolean More () const_ -- makes a query if there is another non-iterated member;
1402 * _void Next ()_ -- increments the iterator;
1403 * _const ItemType& Value () const_ -- returns the current member;
1404 * _ItemType& ChangeValue () const_ -- returns the mutable current member
1407 typedef Ncollection_Sequence<gp_Pnt>
1408 MyPackage_SequenceOfPnt
1409 void Perform (const MyPackage_SequenceOfPnt& theSequence)
1411 MyPackage_SequenceOfPnt::Iterator anIter (theSequence);
1412 for (; anIter.More(); anIter.Next()) {
1413 const gp_Pnt aPnt& = anIter.Value();
1419 This feature is present only for some classes in *TCollection (Stack, List, Set, Map, DataMap, DoubleMap)*. In *NCollection* it is generalized.
1422 #### Class BaseCollection
1424 There is a common abstract base class for all collections for a given item type (e.g., gp_Pnt). Developer X can arbitrarily name this base class like *MyPackage_BaseCollPnt* in the examples above. This name is further used in the declarations of any (non-abstract) collection class to designate the C++ inheritance.
1426 This base class has the following public API:
1427 * abstract class Iterator as the base class for all Iterators descried above;
1428 * _Iterator& CreateIterator () const_ -- creates and returns the Iterator on this collection;
1429 * _Standard_Integer Size () const_ -- returns the number of items in this collection;
1430 * *void Assign (const NCollection_BaseCollection& theOther)* -- copies the contents of the Other to this collection object;
1432 These members enable accessing any collection without knowing its exact type. In particular, it makes possible to implement methods receiving objects of the abstract collection type:
1435 #include <NColection_Map.hxx>
1436 typedef NCollection_Map<gp_Pnt> MyPackage_MapOfPnt;
1437 typedef NCollection_BaseCollection<gp_Pnt> MyPackage_BaseCollPnt;
1438 MyPackage_MapOfPnt aMapPnt;
1440 gp_Pnt aResult = COG (aMapPnt);
1442 gp_Pnt COG(const MyPackage_BaseCollPnt& theColl)
1444 gp_XYZ aCentreOfGravity(0., 0., 0.);
1445 // create type-independent iterator (it is abstract type instance)
1446 MyPackage_BaseCollString::Iterator& anIter = theColl.CreateIterator();
1447 for (; anIter.More(); anIter.Next()) {
1448 aCentreOfGravity += anIter.Value().XYZ();
1450 return aCentreOfGravity / theColl.Size();
1454 Note that there are fundamental differences between the shown type-independent iterator and the iterator belonging to a particular non-abstract collection:
1455 * Type-independent iterator can only be obtained via the call <i>CreateIterator()</i>; the typed iterator -- only via the explicit construction.
1456 * Type-independent iterator is an abstract class, so it is impossible to copy it or to assign it to another collection object; the typed iterators can be copied and reassigned using the method <i>Init()</i>.
1457 * Type-independent iterator is actually destroyed when its collection object is destroyed; the typed iterator is destroyed as any other C++ object in the corresponding C++ scope.
1459 The common point between them is that it is possible to create any number of both types of iterators on the same collection object.
1461 #### Heterogeneous Assign
1463 The semantics of the method *Assign()* has been changed in comparison to *TCollection*. In *NCollection* classes the method *Assign()* is virtual and it receives the object of the abstract *BaseCollection* class (see the previous section). Therefore this method can be used to assign any collection type to any other if only these collections are instantiated on the same *ItemType*.
1465 For example, conversion of *Map* into *Array1* is performed like this:
1468 #include <NCollection_Map.hxx>
1469 #include <NCollection_Array1.hxx>
1470 typedef NCollection_Map<gp_Pnt> MyPackage_MapOfPnt;
1471 typedef NCollection_Array1<gp_Pnt> MyPackage_Array1OfPnt;
1473 MyPackage_MapOfPnt aMapPnt;
1475 MyPackage_Array1OfPnt anArr1Pnt (1, aMapPnt.Size());
1476 anArr1Pnt.Assign (aMapPnt); // heterogeneous assignment
1479 There are some aspects to mention:
1480 * Unlike in *TCollection*, in *NCollection* the methods *Assign* and operator= do not coincide. The former is a virtual method defined in the *BaseCollection* class. The latter is always defined in instance classes as a non-virtual inline method and it corresponds exactly to the method *Assign* in *TCollection* classes. Therefore it is always profitable to use operator= instead of *Assign* wherever the types on both sides of assignment are known.
1481 * If the method *Assign* copies to *Array1* or *Array2* structure, it first checks if the size of the array is equal to the number of items in the copied collection object. If the sizes differ, an exception is thrown, as in *TCollection_Array1.gxx*.
1482 * Copying to *Map, IndexedMap, DataMap* and *IndexedDataMap* can bring about a loss of data: when two or more copied data items have the same key value, only one item is copied and the others are discarded. It can lead to an error in the code like the following:
1485 MyPackage_Array1OfPnt anArr1Pnt (1, 100);
1486 MyPackage_MapOfPnt aMapPnt;
1488 aMapPnt.Assign(anArr1Pnt);
1489 anArr1Pnt.Assign(aMapPnt);
1492 Objects of classes parameterised with two types (*DoubleMap, DataMap* and *IndexedDataMap*) cannot be assigned. Their method *Assign* throws the exception *Standard_TypeMismatch* (because it is impossible to check if the passed *BaseCollection* parameter belongs to the same collection type).
1496 All constructors of *NCollection* classes receive the *Allocator* Object as the last parameter. This is an object of a type managed by Handle, inheriting *NCollection_BaseAllocator*, with the following (mandatory) methods redefined:
1499 Standard_EXPORT virtual void* Allocate (const size_t size);
1500 Standard_EXPORT virtual void Free (void * anAddress);
1503 It is used internally every time when the collection allocates memory for its item(s) and releases this memory. The default value of this parameter (empty *Handle*) designates the use of *NCollection_BaseAllocator* X where the functions *Standard::Allocate* and *Standard::Free* are called. Therefore if the user of *NCollection* does not specify any allocator as a parameter to the constructor of his collection, the memory management will be identical to the one in *TCollection* and other Open CASCADE Technology classes.
1505 Nevertheless, the it is possible to define a custom *Allocator* type to manage the memory in the most optimal or convenient way for his algorithms.
1507 As one possible choice, the class *NCollection_IncAllocator* is included. Unlike *BaseAllocator*, it owns all memory it allocates from the system. Memory is allocated in big blocks (about 20kB) and the allocator keeps track of the amount of occupied memory. The method *Allocate* just increments the pointer to non-occupied memory and returns its previous value. Memory is only released in the destructor of *IncAllocator*, the method *Free* is empty. If used efficiently, this Allocator can greatly improve the performance of OCCT collections.
1511 @subsection occt_fcug_3_4 Strings
1513 Strings are classes that handle dynamically sized sequences of characters based on
1514 ASCII/Unicode UTF-8 (normal 8-bit character type) and UTF-16/UCS-2 (16-bit character type). They provide editing operations with built-in memory management which make the relative objects easier to use than ordinary character arrays.
1516 String classes provide the following services to manipulate character strings:
1517 * Editing operations on string objects, using a built-in string manager
1518 * Handling of dynamically-sized sequences of characters
1519 * Conversion from/to ASCII and UTF-8 strings.
1521 Strings may also be manipulated by handles and therefore shared.
1523 @subsubsection occt_fcug_3_4_1 Examples
1525 #### TCollection_AsciiString
1527 A variable-length sequence of ASCII characters (normal 8-bit character type). It provides editing operations with built-in memory management to make *AsciiString* objects easier to use than ordinary character arrays.
1528 *AsciiString* objects follow value semantics;, that is, they are the actual strings, not handles to strings, and are copied through assignment. You may use *HAsciiString* objects to get handles to strings.
1530 #### TCollection_ExtendedString
1532 A variable-length sequence of "extended" (UNICODE) characters (16-bit character type). It provides editing operations with built-in memory management to make *ExtendedString* objects easier to use than ordinary extended character arrays.
1534 *ExtendedString* objects follow value semantics;, that is, they are the actual strings, not handles to strings, and are copied through assignment. You may use *HExtendedString* objects to get handles to strings.
1536 #### TCollection_HAsciiString
1538 A variable-length sequence of ASCII characters (normal 8-bit character type). It provides editing operations with built-in memory management to make *HAsciiString* objects easier to use than ordinary character arrays.
1539 *HAsciiString* objects are *handles* to strings.
1540 * *HAsciiString* strings may be shared by several objects.
1541 * You may use an *AsciiString* object to get the actual string.
1542 *HAsciiString* objects use an *AsciiString* string as a field.
1544 #### TCollection_HExtendedString
1546 A variable-length sequence of extended; (UNICODE) characters (16-bit character type). It provides editing operations with built-in memory management to make *ExtendedString* objects easier to use than ordinary extended character arrays.
1547 *HExtendedString* objects are *handles* to strings.
1548 * *HExtendedString* strings may be shared by several objects.
1549 * You may use an *ExtendedString* object to get the actual string.
1550 *HExtendedString* objects use an *ExtendedString* string as a field.
1552 @subsubsection occt_fcug_3_4_2 Conversion
1554 *Resource_Unicode* provides functions to convert a non-ASCII *C string* given in ANSI, EUC, GB or SJIS format, to a Unicode string of extended characters, and vice versa.
1556 @subsection occt_fcug_3_5 Quantities
1558 Quantities are various classes supporting date and time information and fundamental types representing most physical quantities such as length, area, volume, mass, density, weight, temperature, pressure etc.
1560 Quantity classes provide the following services:
1561 * Definition of primitive types representing most of mathematical and physical quantities;
1562 * Unit conversion tools providing a uniform mechanism for dealing with quantities and associated physical units: check unit compatibility, perform conversions of values between different units, etc. (see package *UnitsAPI*)
1563 * Resources to manage time information such as dates and time periods
1564 * Resources to manage color definition
1566 A mathematical quantity is characterized by the name and the value (real).
1568 A physical quantity is characterized by the name, the value (real) and the unit. The unit may be either an international unit complying with the International Unit System (SI) or a user defined unit. The unit is managed by the physical quantity user.
1570 The fact that both physical and mathematical quantities are manipulated as real values means that :
1571 * They are defined as aliases of real values, so all functions provided by the <i>Standard_Real</i> class are available on each quantity.
1572 * It is possible to mix several physical quantities in a mathematical or physical formula involving real values.
1574 <i>Quantity</i> package includes all commonly used basic physical quantities.
1576 @subsection occt_fcug_3_6 Unit Conversion
1578 The *UnitsAPI* global functions are used to convert a value from any unit into another unit. Conversion is executed among three unit systems:
1579 * the **SI System**,
1580 * the user’s **Local System**,
1581 * the user’s **Current System**.
1582 The **SI System** is the standard international unit system. It is indicated by *SI* in the signatures of the *UnitsAPI* functions.
1584 The OCCT (former MDTV) System corresponds to the SI international standard but the length unit and all its derivatives use the millimeter instead of the meter.
1586 Both systems are proposed by Open CASCADE Technology; the SI System is the standard option. By selecting one of these two systems, you define your **Local System** through the *SetLocalSystem* function. The **Local System** is indicated by *LS* in the signatures of the *UnitsAPI* functions.
1587 The Local System units can be modified in the working environment. You define your **Current System** by modifying its units through the *SetCurrentUnit* function. The Current System is indicated by *Current* in the signatures of the *UnitsAPI* functions.
1588 A physical quantity is defined by a string (example: LENGTH).
1591 @section occt_occt_fcug_4 Math Primitives and Algorithms
1593 @subsection occt_occt_fcug_4_1 Overview
1595 Math primitives and algorithms available in Open CASCADE Technology include:
1596 * Vectors and matrices
1597 * Geometric primitives
1600 @subsection occt_occt_fcug_4_2 Vectors and Matrices
1602 The Vectors and Matrices component provides a C++ implementation of the fundamental types *Vector* and *Matrix*, which are regularly used to define more complex data structures.
1604 The <i> Vector</i> and <i> Matrix </i> classes provide commonly used mathematical algorithms which
1607 * Basic calculations involving vectors and matrices;
1608 * Computation of eigenvalues and eigenvectors of a square matrix;
1609 * Solvers for a set of linear algebraic equations;
1610 * Algorithms to find the roots of a set of non-linear equations;
1611 * Algorithms to find the minimum function of one or more independent variables.
1613 These classes also provide a data structure to represent any expression,
1614 relation, or function used in mathematics, including the assignment of variables.
1616 Vectors and matrices have arbitrary ranges which must be defined at declaration time
1617 and cannot be changed after declaration.
1620 math_Vector v(1, 3);
1621 // a vector of dimension 3 with range (1..3)
1622 math_Matrix m(0, 2, 0, 2);
1623 // a matrix of dimension 3x3 with range (0..2, 0..2)
1624 math_Vector v(N1, N2);
1625 // a vector of dimension N2-N1+1 with range (N1..N2)
1628 Vector and Matrix objects use value semantics. In other words, they cannot be shared and are copied through assignment.
1631 math_Vector v1(1, 3), v2(0, 2);
1633 // v1 is copied into v2. a modification of v1 does not affect v2
1636 Vector and Matrix values may be initialized and obtained using indexes which must lie within the range definition of the vector or the matrix.
1639 math_Vector v(1, 3);
1640 math_Matrix m(1, 3, 1, 3);
1641 Standard_Real value;
1649 Some operations on Vector and Matrix objects may not be legal. In this case an exception is raised. Two standard exceptions are used:
1650 * *Standard_DimensionError* exception is raised when two matrices or vectors involved in an operation are of incompatible dimensions.
1651 * *Standard_RangeError* exception is raised if an access outside the range definition of a vector or of a matrix is attempted.
1654 math_Vector v1(1, 3), v2(1, 2), v3(0, 2);
1656 // error: Standard_DimensionError is raised
1659 // OK: ranges are not equal but dimensions are
1663 // error: Standard_RangeError is raised
1666 @subsection occt_occt_fcug_4_3 Primitive Geometric Types
1668 Open CASCADE Technology primitive geometric types are a STEP-compliant implementation of basic geometric and algebraic entities.
1670 * Descriptions of primitive geometric shapes, such as:
1674 * Circles and conics;
1675 * Planes and elementary surfaces;
1676 * Positioning of these shapes in space or in a plane by means of an axis or a coordinate system;
1677 * Definition and application of geometric transformations to these shapes:
1681 * Scaling transformations;
1682 * Composed transformations;
1683 * Tools (coordinates and matrices) for algebraic computation.
1685 All these functions are provided by geometric processor package <i> gp</i>. Its classes for 2d and 3d objects are handled by value rather than by reference. When this sort of object is copied, it is copied entirely. Changes in one instance will not be reflected in another.
1687 The *gp* package defines the basic geometric entities used for algebraic calculation and basic analytical geometry in 2d & 3d space. It also provides basic transformations such as identity, rotation, translation, mirroring, scale transformations, combinations of transformations, etc. Entities are handled by value.
1689 Please, note that <i> gp</i> curves and surfaces are analytic: there is no parameterization and no orientation on <i>gp</i> entities, i.e. these entities do not provide functions which work with these properties.
1691 If you need, you may use more evolved data structures provided by <i> Geom</i> (in 3D space) and <i> Geom2d</i> (in the plane). However, the definition of <i> gp</i> entities is identical to the one of equivalent <i> Geom</i> and <i> Geom2d</i> entities, and they are located in the plane or in space with the same kind of positioning systems. They implicitly contain the orientation, which they express on the <i> Geom </i> and <i> Geom2d </i> entities, and they induce the definition of their parameterization.
1693 Therefore, it is easy to give an implicit parameterization to <i> gp</i> curves and surfaces, which is the parametrization of the equivalent <i> Geom</i> or <i> Geom2d</i> entity. This property is particularly useful when computing projections or intersections, or for operations involving complex algorithms where it is particularly important to manipulate the simplest data structures, i.e. those of <i> gp</i>. Thus, <i> ElCLib</i> and <i> ElSLib</i> packages provide functions to compute:
1694 * the point of parameter u on a 2D or 3D gp curve,
1695 * the point of parameter (u,v) on a gp elementary surface, and
1696 * any derivative vector at this point.
1698 Note: the <i> gp</i> entities cannot be shared when they are inside more complex data structures.
1700 @subsection occt_occt_fcug_4_4 Collections of Primitive Geometric Types
1702 Before creating a geometric object, you must decide whether you are in a 2d or in a 3d context and how you want to handle the object.
1703 If you do not need a single instance of a geometric primitive but a set of them then the package which deals with collections of this sort of object, *TColgp*, will provide the necessary functionality.
1704 In particular, this package provides standard and frequently used instantiations of generic classes with geometric objects, i.e. *XY*, *XYZ*, *Pnt*, *Pnt2d*, *Vec*, *Vec2d*, *Lin*, *Lin2d*, *Circ*, *Circ2d.*
1706 @subsection occt_occt_fcug_4_5 Basic Geometric Libraries
1707 There are various library packages available which offer a range of basic computations on curves and surfaces.
1708 If you are dealing with objects created from the *gp* package, the useful algorithms are in the elementary curves and surfaces libraries -- the *ElCLib* and *ElSLib* packages.
1709 * *EICLib* provides methods for analytic curves. This is a library of simple computations on curves from the *gp* package (Lines, Circles and Conics). It is possible to compute points with a given parameter or to compute the parameter for a point.
1710 * *EISLib* provides methods for analytic surfaces. This is a library of simple computations on surfaces from the package *gp* (Planes, Cylinders, Spheres, Cones, Tori). It is possible to compute points with a given pair of parameters or to compute the parameter for a point. There is a library for calculating normals on curves and surfaces.
1712 Additionally, *Bnd* package provides a set of classes and tools to operate with bounding boxes of geometric objects in 2d and 3d space.
1714 @subsection occt_occt_fcug_4_6 Common Math Algorithms
1715 The common math algorithms library provides a C++ implementation of the most frequently used mathematical algorithms. These include:
1716 * Algorithms to solve a set of linear algebraic equations,
1717 * Algorithms to find the minimum of a function of one or more independent variables,
1718 * Algorithms to find roots of one, or of a set, of non-linear equations,
1719 * An algorithm to find the eigenvalues and eigenvectors of a square matrix.
1721 All mathematical algorithms are implemented using the same principles. They contain:
1722 A constructor performing all, or most of, the calculation, given the appropriate arguments. All relevant information is stored inside the resulting object, so that all subsequent calculations or interrogations will be solved in the most efficient way.
1724 A function *IsDone* returning the boolean true if the calculation was successful.
1725 A set of functions, specific to each algorithm, enabling all the various results to be obtained.
1726 Calling these functions is legal only if the function *IsDone* answers **true**, otherwise the exception *StdFail_NotDone* is raised.
1728 The example below demonstrates the use of the Gauss class, which implements the Gauss solution for a set of linear equations.The following definition is an extract from the header file of the class *math_Gauss*:
1733 Gauss (const math_Matrix& A);
1734 Standard_Boolean IsDone() const;
1735 void Solve (const math_Vector& B,
1736 math_Vector& X) const;
1740 Now the main program uses the Gauss class to solve the equations a*x1=b1 and a*x2=b2:
1743 #include <math_Vector.hxx>
1744 #include <math_Matrix.hxx>
1747 math_Vector a(1, 3, 1, 3);
1748 math_Vector b1(1, 3), b2(1, 3);
1749 math_Vector x1(1, 3), x2(1, 3);
1750 // a, b1 and b2 are set here to the appropriate values
1751 math_Gauss sol(a); // computation of the
1752 // LU decomposition of A
1753 if(sol.IsDone()) { // is it OK ?
1754 sol.Solve(b1, x1); // yes, so compute x1
1755 sol.Solve(b2, x2); // then x2
1758 else { // it is not OK:
1760 sol.Solve(b1, x1); // error:
1761 // StdFail_NotDone is raised
1766 The next example demonstrates the use of the *BissecNewton* class, which implements a combination of the Newton and Bissection algorithms to find the root of a function known to lie between two bounds. The definition is an extract from the header file of the class *math_BissecNewton*:
1769 class BissecNewton {
1771 BissecNewton (math_FunctionWithDerivative& f,
1772 const Standard_Real bound1,
1773 const Standard_Real bound2,
1774 const Standard_Real tolx);
1775 Standard_Boolean IsDone() const;
1776 Standard_Real Root();
1780 The abstract class *math_FunctionWithDerivative* describes the services which have to be implemented for the function f which is to be used by a *BissecNewton* algorithm. The following definition corresponds to the header file of the abstract class *math_FunctionWithDerivative*:
1783 class math_FunctionWithDerivative {
1785 virtual Standard_Boolean Value
1786 (const Standard_Real x, Standard_Real& f) = 0;
1787 virtual Standard_Boolean Derivative
1788 (const Standard_Real x, Standard_Real& d) = 0;
1789 virtual Standard_Boolean Values
1790 (const Standard_Real x,
1792 Standard_Real& d) = 0;
1796 Now the test sample uses the *BissecNewton* class to find the root of the equation *f(x)=x**2-4* in the interval [1.5, 2.5]: the function to solve is implemented in the class *myFunction* which inherits from the class *math_FunctionWithDerivative*, then the main program finds the required root.
1799 #include <math_BissecNewton.hxx>
1800 #include <math_FunctionWithDerivative.hxx>
1801 class myFunction : public math_FunctionWithDerivative
1803 Standard_Real coefa, coefb, coefc;
1806 myFunction (const Standard_Real a, const Standard_Real b,
1807 const Standard_Real c) :
1808 coefa(a), coefb(b), coefc(c)
1811 virtual Standard_Boolean Value (const Standard_Real x,
1814 f = coefa * x * x + coefb * x + coefc;
1817 virtual Standard_Boolean Derivative (const Standard_Real x,
1820 d = coefa * x * 2.0 + coefb;
1823 virtual Standard_Boolean Values (const Standard_Real x,
1824 Standard_Real& f, Standard_Real& d)
1826 f = coefa * x * x + coefb * x + coefc;
1827 d = coefa * x * 2.0 + coefb;
1833 myFunction f(1.0, 0.0, 4.0);
1834 math_BissecNewton sol(F, 1.5, 2.5, 0.000001);
1835 if(Sol.IsDone()) { // is it OK ?
1836 Standard_Real x = sol.Root(); // yes.
1842 @subsection occt_occt_fcug_4_7 Precision
1844 On the OCCT platform, each object stored in the database should carry its own precision value. This is important when dealing with systems where objects are imported from other systems as well as with various associated precision values.
1846 The *Precision* package addresses the daily problem of the geometric algorithm developer: what precision setting to use to compare two numbers. Real number equivalence is clearly a poor choice. The difference between the numbers should be compared to a given precision setting.
1848 Do not write _if (X1 == X2),_ instead write _if (Abs(X1-X2) < Precision)._
1850 Also, to order real numbers, keep in mind that _if (X1 < X2 - Precision)_ is incorrect.
1851 _if (X2 - X1 > Precision)_ is far better when *X1* and *X2* are high numbers.
1853 This package proposes a set of methods providing precision settings for the most commonly encountered situations.
1855 In Open CASCADE Technology, precision is usually not implicit; low-level geometric algorithms accept precision settings as arguments. Usually these should not refer directly to this package.
1857 High-level modeling algorithms have to provide a precision setting to the low level geometric algorithms they call. One way is to use the settings provided by this package. The high-level modeling algorithms can also have their own strategy for managing precision. As an example the Topology Data Structure stores precision values which are later used by algorithms. When a new topology is created, it takes the stored value.
1858 Different precision settings offered by this package cover the most common needs of geometric algorithms such as *Intersection* and *Approximation*.
1859 The choice of a precision value depends both on the algorithm and on the geometric space. The geometric space may be either:
1860 * a real space, 3d or 2d where the lengths are measured in meters, micron, inches, etc.
1861 * a parametric space, 1d on a curve or 2d on a surface where numbers have no dimension.
1862 The choice of precision value for parametric space depends not only on the accuracy of the machine, but also on the dimensions of the curve or the surface.
1863 This is because it is desirable to link parametric precision and real precision. If you are on a curve defined by the equation *P(t)*, you would want to have equivalence between the following:
1866 Abs(t1-t2) < ParametricPrecision
1867 Distance (P(t1),P(t2)) < RealPrecision.
1870 @subsubsection occt_occt_fcug_4_7_1 The Precision package
1871 The *Precision* package offers a number of package methods and default precisions for use in dealing with angles, distances, intersections, approximations, and parametric space.
1872 It provides values to use in comparisons to test for real number equalities.
1873 * Angular precision compares angles.
1874 * Confusion precision compares distances.
1875 * Intersection precision is used by intersection algorithms.
1876 * Approximation precision is used by approximation algorithms.
1877 * Parametric precision gets a parametric space precision from a 3D precision.
1878 * *Infinite* returns a high number that can be considered to be infinite. Use <i>-Infinite</i> for a high negative number.
1880 @subsubsection occt_occt_fcug_4_7_2 Standard Precision values
1881 This package provides a set of real space precision values for algorithms. The real space precisions are designed for precision to *0.1* nanometers. The only unit available is the millimeter.
1882 The parametric precisions are derived from the real precisions by the *Parametric* function. This applies a scaling factor which is the length of a tangent to the curve or the surface. You, the user, provide this length. There is a default value for a curve with <i>[0,1]</i> parameter space and a length less than 100 meters.
1883 The geometric packages provide Parametric precisions for the different types of curves.
1884 The *Precision* package provides methods to test whether a real number can be considered to be infinite.
1886 #### Precision::Angular
1888 This method is used to compare two angles. Its current value is *Epsilon(2 * PI)* i.e. the smallest number *x* such that *2*PI + x* is different of *2\*PI*.
1890 It can be used to check confusion of two angles as follows:
1891 _Abs(Angle1 - Angle2) < Precision::Angular()_
1893 It is also possible to check parallelism of two vectors (_Vec_ from _gp_) as follows _V1.IsParallel(V2,Precision::Angular())_
1895 Note that *Precision::Angular()* can be used on both dot and cross products because for small angles the *Sine* and the *Angle* are equivalent. So to test if two directions of type *gp_Dir* are perpendicular, it is legal to use the following code:
1896 _Abs(D1 * D2) < Precision::Angular()_
1898 #### Precision::Confusion
1900 This method is used to test 3D distances. The current value is *1.e-7*, in other words, 1/10 micron if the unit used is the millimeter.
1902 It can be used to check confusion of two points (_Pnt_ from _gp_) as follows:
1903 _P1.IsEqual(P2,Precision::Confusion())_
1905 It is also possible to find a vector of null length (_Vec_ from _gp_) :
1906 _V.Magnitude() < Precision::Confusion()_
1908 #### Precision::Intersection
1910 This is reasonable precision to pass to an Intersection process as a limit of refinement of Intersection Points. *Intersection* is high enough for the process to converge quickly. *Intersection* is lower than *Confusion* so that you still get a point on the intersected geometries. The current value is *Confusion() / 100*.
1912 #### Precision::Approximation
1914 This is a reasonable precision to pass to an approximation process as a limit of refinement of fitting. The approximation is greater than the other precisions because it is designed to be used when the time is at a premium. It has been provided as a reasonable compromise by the designers of the Approximation algorithm. The current value is *Confusion() * 10*.
1915 Note that Approximation is greater than Confusion, so care must be taken when using Confusion in an approximation process.