Sign added and some formatting changes
[occt.git] / dox / user_guides / foundation_classes / foundation_classes.md
CommitLineData
ba06f8bb 1Foundation Classes {#occt_user_guides__foundation_classes}
72b7576f 2=================================
3
e5bd0d98 4@tableofcontents
5
72b7576f 6@section occt_fcug_1 Introduction
7
e2b55410 8This 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 the offerings on our web site at <a href="http://www.opencascade.org/support/training/">www.opencascade.org/support/training/</a>.
9
10Foundation 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.
72b7576f 11
72b7576f 12Foundation Classes include the following:
13
dba69de2 14### Root Classes
72b7576f 15Root 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,
e2b55410 17 * safe handling of dynamically created objects, ensuring automatic deletion of unreferenced objects (see *Standard_Transient* class),
72b7576f 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.
e2b55410 22Root classes are mainly implemented in *Standard* and *MMgt* packages.
72b7576f 23
dba69de2 24### Strings
72b7576f 25Strings are classes that handle dynamically sized sequences of characters based on both ASCII (normal 8-bit character type) and Unicode (16-bit character type).
26Strings may also be manipulated by handles, and consequently be shared.
4ee1bdf4 27Strings are implemented in the *TCollection* package.
72b7576f 28
dba69de2 29### Collections
72b7576f 30Collections are the classes that handle dynamically sized aggregates of data.
31Collection 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*.
32
33Collections include a wide range of generic classes such as run-time sized arrays, lists, stacks, queues, sets and hash maps.
4ee1bdf4 34Collections are implemented in the *TCollection* and *NCollection* packages.
72b7576f 35
dba69de2 36### Collections of Standard Objects
37
4ee1bdf4 38The *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.
72b7576f 39
dba69de2 40### Vectors and Matrices
41
72b7576f 42These classes provide commonly used mathematical algorithms and basic calculations (addition, multiplication, transposition, inversion, etc.) involving vectors and matrices.
43
dba69de2 44### Primitive Geometric Types
45
72b7576f 46Open CASCADE Technology primitive geometric types are a STEP-compliant implementation of basic geometric and algebraic entities.
47They provide:
48 * Descriptions of elementary geometric shapes:
49 * Points,
50 * Vectors,
51 * Lines,
52 * Circles and conics,
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:
56 * Translations
57 * Rotations
58 * Symmetries
59 * Scaling transformations
60 * Composed transformations
61 * Tools (coordinates and matrices) for algebraic computation.
62
dba69de2 63### Common Math Algorithms
72b7576f 64
65Open CASCADE Technology common math algorithms provide a C++ implementation of the most frequently used mathematical algorithms.
66These include:
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.
71
dba69de2 72### Exceptions
73
72b7576f 74A hierarchy of commonly used exception classes is provided, all based on class Failure, the root of exceptions.
75Exceptions 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.
dba69de2 76
77### Quantities
78
72b7576f 79These 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.
80
dba69de2 81### Application services
82
72b7576f 83Foundation 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:
e2b55410 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;
72b7576f 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.
e2b55410 88
72b7576f 89
e2b55410 90@section occt_fcug_2 Basics
91This 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.
72b7576f 92
dba69de2 93
e2b55410 94@subsection occt_fcug_2_a Library organization
dba69de2 95
e2b55410 96This chapter introduces some basic concepts, which are used not only in Foundation Classes, but throughout the whole OCCT library.
97
98@subsubsection occt_fcug_2_a_1 Modules and toolkits
72b7576f 99
72b7576f 100The 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.
dba69de2 101
72b7576f 102Every 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.
dba69de2 103
e2b55410 104@subsubsection occt_fcug_2_a_2 Packages
72b7576f 105A **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.
106*Geom_Circle*.
dba69de2 107Data types described in a package may include one or more of the following data types:
72b7576f 108 * Enumerations
109 * Object classes
110 * Exceptions
111 * Pointers to other object classes
dba69de2 112Inside a package, two data types cannot bear the same name.
72b7576f 113
e5bd0d98 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"
72b7576f 116
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.
121
e2b55410 122@subsubsection occt_fcug_2_a_3 Classes
72b7576f 123The 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).
124
72b7576f 125Classes fall into three categories:
e2b55410 126* Ordinary classes.
127* Deferred classes. A **deferred 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. The C++ equivalent of a deferred CDL class is an abstract class.
128* Generic classes. A **generic class** offers a set of functional behaviors to manipulate other data types. Instantiation of a generic class requires that a data type is given for its argument(s). The generic classes in CDL perform the same mission as template classes in C++.
72b7576f 129
e2b55410 130@subsubsection occt_fcug_2_a_4 Generic Classes
72b7576f 131Generic classes are implemented in two steps. First you declare the generic class to establish the model, then you instantiate this class by giving information about the generic types.
132
e2b55410 133#### Declaring a Generic Class
dba69de2 134
72b7576f 135The generic classes in Open CASCADE Technology are similar by their intent to C++ templates with explicit instantiation.
136A generic class is declared in CDL as operating on data items of non-fixed types which are declared as arguments of the generic class. It is possible to put a restriction on these data types to be of subtype of some definite class. Definition of the generic class does not create new class type in C++ terms; it only defines a pattern for generation (instantiation) of the real classes.
137
dba69de2 138#### Instantiation of a Generic Class
139
72b7576f 140When a generic class is instantiated, its argument types are substituted by actually existing data types (elementary types or classes). The result of instantiation is a new C++ class with an arbitrary name (specified in the instantiating declaration). By convention, the name of the instantiated class is usually constructed from the name of the generic class and names of actual argument types. As for any other class, the name of the class instantiating a generic type is prefixed by the name of the package in which instantiation is declared.
141@code
142class Array1OfReal instantiates Array1 from TCollection (Real);
143@endcode
144
145This declaration located in a CDL file of the *TColStd* package defines a new C++ class *TColStd_Array1OfReal* as the instantiation of generic class *TCollection_Array1* for *Real* values.
146More than one class can be instantiated from the same generic class with the same argument types. Such classes will be identical by implementation, but considered as two different classes by C++.
147No class can inherit from a generic class.
148A generic class can be a deferred class. A generic class can also accept a deferred class as its argument. In both these cases, any class instantiated from it will also be deferred. The resulting class can then be inherited by another class.
149
dba69de2 150#### Nested Generic Classes
151
72b7576f 152It often happens that many classes are linked by a common generic type. This is the case when a base structure furnishes an iterator. In this context, it is necessary to make sure that the group of linked generic classes is indeed instantiated for the same type of object. In order to group the instantiation, you may declare certain classes as being nested.
153When generic class is instantiated, its nested classes are instantiated as well. The name of the instantiation of the nested class is constructed from the name of that nested class and name of the main generic class, connected by ‘Of’.
154@code
155class MapOfReal instantiates Map from TCollection (Real,MapRealHasher);
156@endcode
157This declaration in *TColStd* defines not only class *TColStd_MapOfReal*, but also class *TColStd_MapIteratorOfMapOfReal*, which is instantiated from nested class *MapIterator* of the generic class *TCollection_Map*. Note that instantiation of the nested class is separate class, it is not nested class to the instantiation of the main class.
158**Nested classes**, even though they are described as non-generic classes, are generic by construction being inside the class they are a member of.
dba69de2 159
e2b55410 160@subsubsection occt_fcug_2_a_5 Inheritance
72b7576f 161The 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”.
162For example, having already developed a class *BankAccount* you could quickly specialize new classes: *SavingsAccount, LongTermDepositAccount, MoneyMarketAccount, RevolvingCreditAccount*, etc....
dba69de2 163
e2b55410 164The 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.
165
166One way of ensuring the use of inheritance is to declare classes at the top of a hierarchy as being **deferred**. 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.
167
168@subsection occt_fcug_2_b Persistence and Data Schema
169The data schema is the structure used by an application to store its data. Data schemas consist of persistent classes.
170
171An object is called **persistent** if it can be permanently stored. Thus, the object can be reused at a later date by the application, which created it, or by another application.
172
173In order for an object to be persistent for CDL, its type must be declared as inheriting from the class *Standard_Persistent* or have a parent class inheriting from the *Standard_Persistent* class. Note that classes inheriting from *Standard_Persistent* are handled by a reference.
174
175Objects instantiated from classes which inherit from the Standard_Storable class cannot themselves be stored individually, but they can be stored as fields of an object which inherits from *Standard_Persistent*. Note that objects inheriting from *Standard_Storable* are handled by a value.
176
177@subsection occt_fcug_2_1 Data Types
dba69de2 178
e2b55410 179An 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.
72b7576f 180
72b7576f 181The data types in Open CASCADE Technology fall into two categories:
182 * Data types manipulated by handle (or reference)
183 * Data types manipulated by value
184
e5bd0d98 185@image html /user_guides/foundation_classes/images/foundation_classes_image004.png "Manipulation of data types"
186@image latex /user_guides/foundation_classes/images/foundation_classes_image004.png "Manipulation of data types"
72b7576f 187
188A 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.
189 * A variable of a type manipulated by value contains the instance itself.
190 * A variable of a type manipulated by handle contains a reference to the instance.
191The first examples of types manipulated by values are the predefined **primitive types**: *Boolean, Character, Integer, Real*, etc.
dba69de2 192
72b7576f 193A 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++:
194
195~~~~~
196Handle(myClass) m = new myClass;
197~~~~~
198
199In 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.
200
dba69de2 201
72b7576f 202
72b7576f 203@subsubsection occt_fcug_2_1_1 Primitive Types
e2b55410 204
72b7576f 205The primitive types are predefined in the language and they are **manipulated by value**.
206Some of these primitives inherit from the **Storable** class. This means they can be used in the implementation of persistent objects, either contained in entities declared within the methods of the object, or they form part of the internal representation of the object.
dba69de2 207
72b7576f 208The primitives inheriting from *Standard_Storable* are the following:
209* **Boolean** is used to represent logical data. It may have only two values: *Standard_True* and *Standard_False*.
210* **Character** designates any ASCII character.
211* **ExtCharacter** is an extended character.
212* **Integer** is a whole number.
213* **Real** denotes a real number (i.e. one with whole and a fractional part, either of which may be null).
214* **ShortReal** is a real with a smaller choice of values and memory size.
215There are also non-Storable primitives. They are:
216* **CString** is used for literal constants.
217* **ExtString** is an extended string.
218* **Address** represents a byte address of undetermined size.
219The services offered by each of these types are described in the **Standard** Package.
220The table below presents the equivalence existing between C++ fundamental types and OCCT primitive types.
221
222**Table 1: Equivalence between C++ Types and OCCT Primitive Types**
e5bd0d98 223
224| C++ Types | OCCT Types |
225| :--------- | :----------- |
226| int | Standard_Integer |
72b7576f 227| double | Standard_Real |
e5bd0d98 228| float | Standard_ShortReal |
229| unsigned int | Standard_Boolean |
230| char | Standard_Character |
72b7576f 231| short | Standard_ExtCharacter |
dba69de2 232| char\* | Standard_CString |
233| void\* | Standard_Address |
234| short\* | Standard_ExtString |
72b7576f 235
dba69de2 236\* The types with asterisk are pointers.
72b7576f 237
72b7576f 238**Reminder of the classes listed above:**
239
4ee1bdf4 240* **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.
241* **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.
242* **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.
243* **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.
244* **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).
245* **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).
246* **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.
247* **Standard_Address** : fundamental type representing a generic pointer. *Address* is implemented as a *typedef* of the C++ *void* fundamental type.
248* **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.
72b7576f 249
250@subsubsection occt_fcug_2_1_2 Types manipulated by value
251There are three categories of types which are manipulated by value:
252 * Primitive types
253 * Enumerated types
4ee1bdf4 254 * Types defined by classes not inheriting from *Standard_Persistent* or *Standard_Transient*, whether directly or not.
72b7576f 255Types 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.
256
e5bd0d98 257@image html /user_guides/foundation_classes/images/foundation_classes_image005.png "Manipulation of a data type by value"
258@image latex /user_guides/foundation_classes/images/foundation_classes_image005.png "Manipulation of a data type by value"
72b7576f 259
4ee1bdf4 260Types that are known to the schema (i.e. they are either **primitives** or they inherit from *Storable*) and are manipulated by value, can be stored inside a persistent object as part of the representation. Only in this way can a “manipulated by value” object be stored in a file.
72b7576f 261
262@subsubsection occt_fcug_2_1_3 Types manipulated by reference (handle)
263There are two categories of types which are manipulated by handle:
4ee1bdf4 264 * Types defined by classes inheriting from the *Persistent* class, which are therefore storable in a file.
265 * Types defined by classes inheriting from the *Transient* class.
72b7576f 266
e5bd0d98 267@image html /user_guides/foundation_classes/images/foundation_classes_image006.png "Manipulation of a data type by reference"
268@image latex /user_guides/foundation_classes/images/foundation_classes_image006.png "Manipulation of a data type by reference"
72b7576f 269
e2b55410 270@subsubsection occt_fcug_2_1_4 When is it necessary to use a handle?
72b7576f 271
272The following table summarizes how various data types are handled and stored.
273
e5bd0d98 274| Type | Manipulated by handle | Manipulated by value |
275| :------- | :-------------------- | :-------------------- |
72b7576f 276| storable | Persistent | Primitive, Storable (if nested in a persistent class)|
277|temporary | Transient | Other |
278
e2b55410 279When you design an object, it can be difficult to choose how to manipulate that
280object: by value or by handle. The following ideas can help you to make up your mind:
281
282* If your object may have a long lifetime within the application and you want to make multiple
283references to it, it would be preferable to manipulate this object with a handle. The memory for the
284object will be allocated on the heap. The handle which points to that memory is a light object which
285can be rapidly passed in argument. This avoids the penalty of copying a large object.
286* If your object will have a limited lifetime, for example, used within a single algorithm, it would
287be preferable to manipulate this object by value, non-regarding its size, because this object is
288allocated on the stack and the allocation and de-allocation of memory is extremely rapid, which
289avoids the implicit calls to *new* and *delete* occasioned by allocation on the heap.
290* Finally, if an object will be created only once during, but will exist throughout the lifetime of
291the application, the best choice may be a class manipulated by handle or a value declared as a
292global variable.
293
72b7576f 294
295@subsection occt_fcug_2_2 Programming with Handles
e2b55410 296
72b7576f 297@subsubsection occt_fcug_2_2_1 Handle Definition
e2b55410 298
72b7576f 299A handle may be compared with a C++ pointer. Several handles can reference the same object. Also, a single handle may reference several objects, but only one at a time. To have access to the object it refers to, the handle must be de-referenced just as with a C++ pointer.
dba69de2 300
72b7576f 301Transient and Persistent classes may be manipulated either with handles or with values. Handles which reference non-persistent objects are called non-storable handles; therefore, a persistent object cannot contain a non-storable handle.
302
4ee1bdf4 303#### Organization of Classes
304
72b7576f 305Classes used with handles are persistent or transient.
dba69de2 306
72b7576f 307Classes that inherit from *Standard_Transient* are transient while classes that inherit from *Standard_Persistent* are persistent.
dba69de2 308
72b7576f 309In this chapter we will discuss only transient classes and relevant handles. Persistent classes and their handles are organized in a similar manner.
dba69de2 310
72b7576f 311Class *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.
dba69de2 312
4ee1bdf4 313For every class derived (directly or indirectly) from *Transient*, CDL extractor creates associated class *Handle()* whose name is the same as the name of that class prefixed by *Handle_*. Open CASCADE Technology provides preprocessor macro *Handle()* that produces a name of a *Handle()* class for a given transient class name.
314
315#### Using a Handle
72b7576f 316
72b7576f 317
318A handle is characterized by the object it references.
dba69de2 319
320Before 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:
72b7576f 321~~~~~
322Handle(Geom_Point) p1, p2;
323~~~~~
324Declaring 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()*.
dba69de2 325
72b7576f 326To 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.
dba69de2 327
72b7576f 328**Note** that handles should only be used for object sharing. For all local operations, it is advisable to use classes manipulated by values.
329
330@subsubsection occt_fcug_2_2_2 Type Management
331
72b7576f 332Open 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). For every class type derived from *Standard_Transient*, CDL extractor creates a code instantiating single instance of the class *Standard_Type* (type descriptor) that holds information on that type: its name and list of ancestor types.
e2b55410 333
72b7576f 334That instance (actually, a handle on it) is returned by the virtual method *DynamicType()* of the class derived from *Standard_Transient*. The other virtual method *IsKind()* provides a means to check whether a given object has specified type or inherits it.
dba69de2 335
72b7576f 336In order to refer to the type descriptor object for a given class type, use macros *STANDARD_TYPE()* with argument being a name of the class.
337
4ee1bdf4 338#### Type Conformity
339
72b7576f 340The 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.
dba69de2 341
72b7576f 342Consider the persistent class *CartesianPoint*, a sub-class of *Point*; the rule of type conformity can be illustrated as follows:
343
344~~~~~
345Handle (Geom_Point) p1;
346Handle (Geom_CartesianPoint) p2;
347p2 = new Geom_CartesianPoint;
dba69de2 348p1 = p2; // OK, the types are compatible
72b7576f 349~~~~~
350
351
352The compiler sees p1 as a handle to *Point* though the actual object referenced by *p1* is of the *CartesianPoint* type.
353
4ee1bdf4 354#### Explicit Type Conversion
355
72b7576f 356According 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.
dba69de2 357
72b7576f 358A 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.
359
360~~~~~~
361Handle (Geom_Point) p1;
362Handle (Geom_CartesianPoint) p2, p3;
363p2 = new Geom_CartesianPoint;
364p1 = p2; // OK, standard assignment
365p3 = Handle (Geom_CartesianPoint)::DownCast (p1);
366// OK, the actual type of p1 is CartesianPoint, although the static type of the handle is Point
367~~~~~~
368
369If 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:
370
371~~~~~~
e5bd0d98 372void MyFunction (const Handle(A) & a)
72b7576f 373{
dba69de2 374 Handle(B) b = Handle(B)::Downcast(a);
375 if (! b.IsNull()) {
376 // we can use “b” if class B inherits from A
377 }
378 else {
379 // the types are incompatible
380 }
72b7576f 381}
382~~~~~~
383Downcasting is used particularly with collections of objects of different types; however, these objects should inherit from the same root class.
dba69de2 384
385For 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:
72b7576f 386
387~~~~~
388Handle (A) a;
389Handle (B) b;
390Handle (Standard_Transient) t;
391SequenceOfTransient s;
392a = new A;
393s.Append (a);
394b = new B;
395s.Append (b);
396t = s.Value (1);
397// here, you cannot write:
398// a = t; // ERROR !
399// so you downcast:
400a = Handle (A)::Downcast (t)
401if (! a.IsNull()) {
dba69de2 402 // types are compatible, you can use a
72b7576f 403}
404else {
dba69de2 405 // the types are incompatible
72b7576f 406}
407~~~~~
408
409@subsubsection occt_fcug_2_2_3 Using Handles to Create Objects
e2b55410 410
72b7576f 411To 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.
412
413~~~~~
414Handle (Geom_CartesianPoint) p;
415p = new Geom_CartesianPoint (0, 0, 0);
416~~~~~
417
418Unlike for a pointer, the **delete** operator does not work on a handle; the referenced object is automatically destroyed when no longer in use.
419
420@subsubsection occt_fcug_2_2_4 Invoking Methods
421Once you have a handle on a persistent or transient 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.
dba69de2 422
72b7576f 423To test or to modify the state of the handle, the method is translated by the *dot* operator.
424The example below illustrates how to access the coordinates of an (optionally initialized) point object:
425
426~~~~~
427Handle (Geom_CartesianPoint) centre;
428Standard_Real x, y, z;
429if (centre.IsNull()) {
dba69de2 430 centre = new PGeom_CartesianPoint (0, 0, 0);
72b7576f 431}
432centre->Coord(x, y, z);
433~~~~~
434
435The example below illustrates how to access the type object of a Cartesian point:
436
437~~~~~
438Handle(Standard_Transient) p = new Geom_CartesianPoint(0.,0.,0.);
439if ( p->DynamicType() == STANDARD_TYPE(Geom_CartesianPoint) )
dba69de2 440 cout << ;Type check OK; << endl;
72b7576f 441else
dba69de2 442 cout << ;Type check FAILED; << endl;
72b7576f 443~~~~~
444
445*NullObject* exception will be raised if a field or a method of an object is accessed via a *Null* handle.
446
4ee1bdf4 447#### Invoking Class Methods
448
72b7576f 449A 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
451For example, we can find the maximum degree of a Bezier curve:
452
453~~~~~
454Standard_Integer n;
455n = Geom_BezierCurve::MaxDegree();
456~~~~~
457
4ee1bdf4 458@subsubsection occt_fcug_2_2_5 Handle deallocation
e2b55410 459
460Before 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*.
dba69de2 461
72b7576f 462When 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.
dba69de2 463
72b7576f 464The principle of allocation can be seen in the example below.
465
466~~~~~
467...
468{
469Handle (TColStd_HSequenceOfInteger) H1 = new TColStd_HSequenceOfInteger;
dba69de2 470 // H1 has one reference and corresponds to 48 bytes of memory
471 {
472 Handle (TColStd_HSequenceOfInteger) H2;
473 H2 = H1; // H1 has two references
474 if (argc == 3) {
475 Handle (TColStd_HSequenceOfInteger) H3;
476 H3 = H1;
477 // Here, H1 has three references
478 ...
479 }
480 // Here, H1 has two references
481 }
482 // Here, H1 has 1 reference
72b7576f 483}
484// Here, H1 has no reference and the referred TColStd_HSequenceOfInteger object is deleted.
485~~~~~
486
e2b55410 487You can easily cast a reference to the handle object to <i> void* </i> by defining the following:
488
489~~~~
490 void *pointer;
491 Handle(Some_class) aHandle;
492 // Here only a pointer will be copied
493 Pointer = &aHandle;
494 // Here the Handle object will be copied
495 aHandle = * (Handle(Some_Class) *)pointer;
496~~~~
4ee1bdf4 497
e2b55410 498
499@subsubsection occt_fcug_2_2_6 Cycles
500
501Cycles appear if two or more objects reference each other by handles (stored as fields). In this condition automatic destruction will not work.
dba69de2 502
72b7576f 503Consider 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.
e2b55410 504
72b7576f 505The 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).
dba69de2 506
72b7576f 507There are two approaches how to avoid such situation:
508 * Use C++ pointer for one kind of references, e.g. from a primitive to the graph
509 * Nullify one set of handles (e.g. handles to a graph in primitives) when a graph object needs to be destroyed
510
e2b55410 511@subsubsection occt_fcug_2_2_7 Creating Transient Classes without CDL
72b7576f 512
513Though generation of Handle class and related C++ code is normally performed by CDL extractor, it is also possible to define a class managed by handle without CDL. To facilitate that, several macros are provided in the file Standard_DefineHandle.hxx:
514
515* **DEFINE_STANDARD_HANDLE(class_name,ancestor_name)** - declares Handle class for a class *class_name* that inherits class *ancestor_name* (for instance, *Standard_Transient*). This macro should be put in a header file; the declaration of the handle to a base class must be available (usually put before or after the declaration of the class *class_name*, or into a separate header file).
516* **IMPLEMENT_STANDARD_HANDLE(class_name,ancestor_name)** - implements method *DownCast()* of the *Handle* class. Should be located in a C++ file (normally the file where methods of the class *class_name* are implemented).
517* **DEFINE_STANDARD_RTTI(class_name)** - declares methods required for RTTI in the class *class_name* declaration; should be in public: section.
e2b55410 518* **IMPLEMENT_STANDARD_RTTIEXT(class_name,ancestor_name)** - implements above methods. Usually put into the C++ file implementing class *class_name*.
72b7576f 519Note that it is important to ensure correctness of macro arguments, especially the ancestor name, otherwise the definition may be inconsistent (no compiler warnings will be issued in case of mistake).
520
521In *Appli_ExtSurface.hxx* file:
522~~~~~
523#include <Geom_Surface.hxx>
524class Appli_ExtSurface : public Geom_Surface
525{
526. . .
527public:
dba69de2 528 DEFINE_STANDARD_RTTI(Appli_ExtSurface)
72b7576f 529}
530DEFINE_STANDARD_HANDLE(Appli_ExtSurface,Geom_Surface)
531~~~~~
532
533In *Appli_ExtSurface.cxx* file:
534~~~~~
535#include <Appli_ExtSurface.hxx>
536IMPLEMENT_STANDARD_HANDLE(Appli_ExtSurface,Geom_Surface)
537IMPLEMENT_STANDARD_RTTIEXT(Appli_ExtSurface,Geom_Surface)
538~~~~~
539
e2b55410 540#### Example
541
542The following example shows how to define a class <i> SamplePoint </i> manipulated by handle.
543
544First you need to define *Sample_Point.hxx* :
545
546~~~~
547
548 #ifndef _Sample_Point_HeaderFile
549 #define _Sample_Point_HeaderFile
550 #ifndef _Standard_Macro_HeaderFile
551 #include <Standard_Macro.hxx>
552 #endif
553 #include <MMgt_TShared.hxx>
554 #include <Standard_DefineHandle.hxx>
555 // Handle definition
556 //
557
558 DEFINE_STANDARD_HANDLE(Sample_Point,MMgt_TShared)
559 class Sample_Point: public MMgt_TShared {
560 public:
561 Sample_Point();
562 Sample_Point(const Standard_Real, const
563 Standard_Real);
564 void SetX(const Standard_Real x) {
565 myX = x;
566 }
567 void SetY(const Standard_Real y) {
568 myY = y;
569 }
570 Standard_Real X() const {
571 return myX;
572 }
573 Standard_Real Y() const {
574 return myY;
575 }
576 // some methods like DynamicType() or
577 IsKind()
578 //
579 DEFINE_STANDARD_RTTI(Sample_Point)
580 private:
581 Standard_Real myX;
582 Standard_Real myY;
583 };
584 #endif
585
586~~~~
587
588Then you need to define *Sample_Point.cxx* :
589
590~~~~
72b7576f 591
e2b55410 592 #include <Sample_Point.hxx>
72b7576f 593
e2b55410 594 // Implementation of Handle and type mgt
595
596 IMPLEMENT_STANDARD_HANDLE(Sample_Point,MMgt_TShared)
597 IMPLEMENT_STANDARD_RTTI(Sample_Point,MMgt_TShared)
598
599 // For ancestors, we add a IMPLEMENT_STANDARD_SUPERTYPE and
600 // a IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY macro.
601 // We must respect the order: from the direct ancestor class to the base class.
602
603 IMPLEMENT_STANDARD_TYPE(Sample_Point)
604 IMPLEMENT_STANDARD_SUPERTYPE(MMgt_TShared)
605 IMPLEMENT_STANDARD_SUPERTYPE(Standard_Transient)
606 IMPLEMENT_STANDARD_SUPERTYPE_ARRAY()
607 IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(MMgt_TShared)
608 IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_ENTRY(Standard_Transient)
609 IMPLEMENT_STANDARD_SUPERTYPE_ARRAY_END()
610 IMPLEMENT_STANDARD_TYPE_END(Sample_Point)
611
612 // Constructors implementation
613
614 Sample_Point::Sample_Point(const
615 Standard_Real x, const Standard_Real y)
616 {
617 myX = x;
618 myY = y;
619 }
620 Sample_Point::Sample_Point()
621 {
622 myX = 0.0;
623 myY = 0.0;
624 }
625~~~~
626
627
628@subsection occt_fcug_2_3 Memory Management
629
630In 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.
631
632The Memory Manager is based on the following principles:
633
634* small memory arrays are grouped into clusters and then recycled (clusters are never released to the system),
635* 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).
636
637As 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.
638
639@subsubsection occt_fcug_2_3_1 Usage of Memory Manager
640
641To 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()*.
dba69de2 642
72b7576f 643In 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.
dba69de2 644
72b7576f 645CDL extractor defines *new()* and *delete()* in this way for all classes declared with CDL. Thus all OCCT classes (apart from a few exceptions) are allocated using the OCCT memory manager.
646Since 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*.
dba69de2 647
e2b55410 648**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.
649
650@subsubsection occt_fcug_2_3_2 How to configure the Memory Manager
72b7576f 651
72b7576f 652The 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.
653The configuration is defined by numeric values of the following environment variables:
654 * *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.
655 * *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.
656 * *MMGT_CELLSIZE*: defines the maximal size of blocks allocated in large pools of memory. Default is 200.
657 * *MMGT_NBPAGES*: defines the size of memory chunks allocated for small blocks in pages (operating-system dependent). Default is 1000.
658 * *MMGT_THRESHOLD*: defines the maximal size of blocks that are recycled internally instead of being returned to the heap. Default is 40000.
659 * *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()*.
7277133a 660
e2b55410 661@subsubsection occt_fcug_2_3_3 Optimization Techniques
662
72b7576f 663When *MMGT_OPT* is set to 1, the following optimization techniques are used:
664 * 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.
dba69de2 665
72b7576f 666In 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).
dba69de2 667
72b7576f 668 * 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.
dba69de2 669
72b7576f 670However, 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()*.
dba69de2 671
672 * 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.
673
e2b55410 674@subsubsection occt_fcug_2_3_4 Benefits and drawbacks
dba69de2 675
72b7576f 676The 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%.
dba69de2 677
e2b55410 678The 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.
679
dba69de2 680The overhead expenses induced by the OCCT memory manager are:
e2b55410 681 * 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)
682 * 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.
dba69de2 683
684Note 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.
685
72b7576f 686As 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.
dba69de2 687
7277133a 688OCCT 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.
689The 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.
72b7576f 690
e2b55410 691@subsection occt_fcug_2_4 Exceptions
692
693@subsubsection occt_fcug_2_4_1 Introduction
694
695The 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.
696
697This domain is expressed by **exceptions**. Exceptions are raised under various error conditions to protect software quality.
698
dba69de2 699Exception 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.
700
72b7576f 701A method may raise an exception which interrupts its normal execution and transfers control to the handler catching this exception.
dba69de2 702
e2b55410 703A 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.
dba69de2 704
705Open 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.
706
72b7576f 707However, 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.
dba69de2 708
72b7576f 709The following paragraphs describe recommended approaches for using exceptions when working with Open CASCADE Technology.
dba69de2 710
e2b55410 711@subsubsection occt_fcug_2_4_2 Raising an Exception
72b7576f 712
dba69de2 713#### “C++ like” Syntax
714
72b7576f 715To raise an exception of a definite type method Raise() of the appropriate exception class shall be used.
716~~~~~
717DomainError::Raise(“Cannot cope with this condition”);
718~~~~~
dba69de2 719raises 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:
72b7576f 720~~~~~
721try {
dba69de2 722 OCC_CATCH_SIGNALS
723 // try block
72b7576f 724}
725catch(DomainError) {
726// handle DomainError exceptions here
727}
728~~~~~
729
dba69de2 730#### Regular usage
731
72b7576f 732Exceptions 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.
dba69de2 733
72b7576f 734Thus,
735 * No exception should be raised during normal execution of an application.
736 * A method which may raise an exception should be protected by other methods allowing the caller to check on the validity of the call.
dba69de2 737
738For example, if you consider the *TCollection_Array1* class used with:
739 * *Value* function to extract an element
740 * *Lower* function to extract the lower bound of the array
741 * *Upper* function to extract the upper bound of the array.
742
743then, the *Value* function may be implemented as follows:
72b7576f 744
745~~~~~
e5bd0d98 746Item TCollection_Array1::Value (const Standard_Integer&index) const
72b7576f 747{
dba69de2 748 // where r1 and r2 are the lower and upper bounds of the array
08f15ad0 749 if(index < r1 || index > r2) {
dba69de2 750 OutOfRange::Raise(“Index out of range in Array1::Value”);
751 }
752 return contents[index];
72b7576f 753}
754~~~~~
755
756Here validity of the index is first verified using the Lower and Upper functions in order to protect the call.
08f15ad0 757Normally 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.
dba69de2 758
08f15ad0 759It 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:
72b7576f 760~~~~~
761<ErrorTypeName>_Raise_if(condition, “Error message”);
762~~~~~
08f15ad0 763where *ErrorTypeName* is the exception type, *condition* is the logical expression leading to the raise of the exception, and *Error message* is the associated message.
dba69de2 764
08f15ad0 765The entire call may be removed by defining one of the pre-processor symbols *No_Exception* or <i>No_<ErrorTypeName></i> at compile-time:
72b7576f 766
767~~~~~
768#define No_Exception /* remove all raises */
769~~~~~
770
08f15ad0 771Using this syntax, the *Value* function becomes:
72b7576f 772
773~~~~~
e5bd0d98 774Item TCollection_Array1::Value (const Standard_Integer&index) const
dba69de2 775 {
08f15ad0 776 OutOfRange_Raise_if(index < r1 || index > r2,
dba69de2 777 “index out of range in Array1::Value”);
778 return contents[index];
72b7576f 779}
780~~~~~
781
e2b55410 782@subsubsection occt_fcug_2_4_3 Handling an Exception
ba06f8bb 783
72b7576f 784When an exception is raised, control is transferred to the nearest handler of a given type in the call stack, that is:
785 * the handler whose try block was most recently entered and not yet exited,
786 * the handler whose type matches the raise expression.
dba69de2 787
72b7576f 788A handler of T exception type is a match for a raise expression with an exception type of E if:
789 * T and E are of the same type, or
790 * T is a supertype of E.
dba69de2 791
08f15ad0 792In 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.
dba69de2 793
794As an example, consider the exceptions of type *NumericError, Overflow, Underflow* and *ZeroDivide*, where *NumericError* is the parent type of the three others.
72b7576f 795
796~~~~~
797void f(1)
798 {
dba69de2 799 try {
800 OCC_CATCH_SIGNALS
801 // try block
802 }
803 catch(Standard_Overflow) { // first handler
804 // ...
805 }
806 catch(Standard_NumericError) { // second handler
807 // ...
808 }
72b7576f 809}
810~~~~~
811
dba69de2 812Here, 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*.
813
72b7576f 814The handlers are checked in order of appearance, from the nearest to the most distant try block, 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.
815
816~~~~~
817void f(1)
818{
dba69de2 819 int i = 0;
820 {
821 try {
822 OCC_CATCH_SIGNALS
823 g(i);// i is accessible
824 }
825 // statement here will produce compile-time errors !
826 catch(Standard_NumericError) {
827 // fix up with possible reuse of i
828 }
829 // statement here may produce unexpected side effect
830 }
831 . . .
72b7576f 832}
833~~~~~
834
dba69de2 835The 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.
836
72b7576f 837The main routine of a program would look like this:
838
839~~~~~
840#include <Standard_ErrorHandler.hxx>
841#include <Standard_Failure.hxx>
842#include <iostream.h>
843int main (int argc, char* argv[])
844{
dba69de2 845 try {
846 OCC_CATCH_SIGNALS
847 // main block
848 return 0;
849 }
850 catch(Standard_Failure) {
851 Handle(Standard_Failure) error = Standard_Failure::Caught ();
852 cout error end1;
853 }
854 return 1;
72b7576f 855}
856~~~~~
857
dba69de2 858In 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).
72b7576f 859
dba69de2 860Though 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.
72b7576f 861
dba69de2 862#### Catching signals
863
864In 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()*.
865
72b7576f 866Normally this method is called in the beginning of the main() function. It installs a handler that will convert system signals into OCCT exceptions.
dba69de2 867
868In 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.
72b7576f 869
e2b55410 870@subsubsection occt_fcug_2_4_4 Implementation on various platforms.
dba69de2 871
872The exception handling mechanism in Open CASCADE Technology is implemented in different ways depending on the preprocessor macros *NO_CXX_EXCEPTIONS* and *OCC_CONVERT_SIGNALS*, which shall be consistently defined by compilation procedures for both Open CASCADE Technology and user applications:
ba06f8bb 873
e2b55410 8741. 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++.
ba06f8bb 875
e2b55410 8762. 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.
dba69de2 877
ba06f8bb 878 This mode differs from standard C++ exception handling only for signals:
879
880 * macro *OCC_CATCH_SIGNALS* is necessary (besides call to *OSD::SetSignal()* described above) for conversion of signals into exceptions;
881 * 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.
882
e2b55410 8833. On Linux Open CASCADE Technology can also be compiled in compatibility mode. In that case macro *NO_CXX_EXCEPTIONS* is defined and the C++ exceptions are simulated with C long jumps. As a consequence, the behavior is slightly different from that expected in the C++ standard.
dba69de2 884
e2b55410 885While exception handling with *NO_CXX_EXCEPTIONS* is very similar to C++ by syntax, it has a number of peculiarities that should be taken into account:
e5bd0d98 886
ba06f8bb 887* try and catch are actually macros defined in the file *Standard_ErrorHandler.hxx*. Therefore, including this file is necessary for handling OCCT exceptions;
888* due to being a macro, catch cannot contain a declaration of the exception object after its type; only type is allowed in the catch statement. Use method *Standard_Failure::Caught()* to access an exception object;
889* catch macro may conflict with some STL classes that might use catch(...) statements in their header files. So STL headers should not be included after *Standard_ErrorHandler.hxx*;
890* Open CASCADE Technology try/catch block will not handle normal C++ exceptions; however this can be achieved using special workarounds;
e2b55410 891* the try macro defines a C++ object that holds an entry point in the exception handler. Therefore if exception is raised by code located immediately after the try/catch block but on the same nesting level as *try*, it may be handled by that *catch*. This may lead to unexpected behavior, including infinite loop. To avoid that, always surround the try/catch block with curved brackets;
892* the destructors of C++ objects allocated on the stack after handler initialization are not called by exception raising.
ba06f8bb 893
e2b55410 894In 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. For compatibility with previous versions of Open CASCADE Technology the limitations described above for *NO_CXX_EXCEPTIONS* shall be assumed.
72b7576f 895
896@subsection occt_fcug_2_5 Plug-In Management
ba06f8bb 897
72b7576f 898@subsubsection occt_fcug_2_5_1 Distribution by Plug-Ins
ba06f8bb 899
72b7576f 900A 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.
dba69de2 901
72b7576f 902A plug-in can be used to:
903 * 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),
904 * 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),
4ee1bdf4 905 * 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).
dba69de2 906
72b7576f 907The 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.
dba69de2 908
72b7576f 909Once 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).
910
4ee1bdf4 911#### C++ Plug-In Implementation
912
72b7576f 913The 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).
e2b55410 914Foundation classes provide in the package *Plugin* a method named *Load()*, which enables the client to access the required service through a library.
dba69de2 915
e2b55410 916That method reads the information regarding available plug-ins and their locations from the resource file *Plugin* found by environment variable *CSF_PluginDefaults*:
72b7576f 917
918~~~~~
919$CSF_PluginDefaults/.Plugin
920~~~~~
921
dba69de2 922The *Load* method looks for the library name in the resource file or registry through its GUID, for example, on UNIX:
72b7576f 923~~~~~
924! METADATADRIVER whose value must be OS or DM.
925
926! FW
927a148e300-5740-11d1-a904-080036aaa103.Location:
928
929libFWOSPlugin.so
930a148e300-5740-11d1-a904-080036aaa103.CCL:
931/adv_44/CAS/BAG/FW-K4C/inc/FWOS.ccl
932
933! FWDM
934a148e301-5740-11d1-a904-080036aaa103.Location:
935libFWDMPlugin.so
936a148e301-5740-11d1-a904-080036aaa103.CCL:
937/adv_44/CAS/BAG/DESIGNMANAGER-K4C/inc/DMAccess.ccl|/
938adv_44/CAS/BAG/DATABASE-K4C/inc/FWDMCommands.ccl
939a148e301-5740-11d1-a904-080036aaa103.Message: /adv_44/CAS/
940BAG/DESIGNMANAGER-K4C/etc/locale/DMAccess
941
942! Copy-Paste
9435ff7dc00-8840-11d1-b5c2-00a0c9064368.Location:
944libCDMShapeDriversPlugin.so
9455ff7dc01-8840-11d1-b5c2-00a0c9064368.Location:
946libCDMShapeDriversPlugin.so
9475ff7dc02-8840-11d1-b5c2-00a0c9064368.Location:
948libCDMShapeDriversPlugin.so
9495ff7dc03-8840-11d1-b5c2-00a0c9064368.Location:
950libCDMShapeDriversPlugin.so
9515ff7dc04-8840-11d1-b5c2-00a0c9064368.Location:
952libCDMShapeDriversPlugin.so
953
954! Plugs 2d plotters:
955d0d722a2-b4c9-11d1-b561-0000f87a4710.location: FWOSPlugin
956d0d722a2-b4c9-11d1-b561-0000f87a4710.CCL: /adv_44/CAS/BAG/
957VIEWERS-K4C/inc/CCLPlotters.ccl
958d0d722a2-b4c9-11d1-b561-0000f87a4710.Message: /adv_44/CAS/
959BAG/VIEWERS-K4C/etc/locale/CCLPlotters
960
961!SHAPES
962e3708f72-b1a8-11d0-91c2-080036424703.Location:
963libBRepExchangerPlugin.so
964e3708f72-b1a8-11d0-91c2-080036424703.CCL: /adv_44/CAS/BAG/
965FW-K4C/inc/BRep.ccl
966~~~~~
967
968
dba69de2 969Then 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 *Factory* method to return the object which supports the required service.
72b7576f 970The client may then call the functions supported by this object.
971
4ee1bdf4 972#### C++ Client Plug-In Implementation
973
dba69de2 974To invoke one of the services provided by the plug-in, you may call the *Plugin::ServiceFactory* global function with the *Standard_GUID* of the requested service as follows:
72b7576f 975
976~~~~~
977Handle(FADriver_PartStorer)::DownCast
978(PlugIn::ServiceFactory
979(PlugIn_ServiceId(yourStandardGUID)))
980~~~~~
981
dba69de2 982Let us take *FAFactory.cxx* as an example:
72b7576f 983
984~~~~~
985#include <FAFactory.ixx>
986
987#include <FADriver_PartRetriever.hxx>
988#include <FADriver_PartStorer.hxx>
989#include <FirstAppSchema.hxx>
990#include <Standard_GUID.hxx>
991#include <Standard_Failure.hxx>
992#include <FACDM_Application.hxx>
993#include <Plugin_Macro.hxx>
994
995PLUGIN(FAFactory)
996
997static Standard_GUID
dba69de2 998 StorageDriver(“45b3c690-22f3-11d2-b09e-0000f8791463”);
72b7576f 999static Standard_GUID
dba69de2 1000 RetrievalDriver(“45b3c69c-22f3-11d2-b09e-0000f8791463”);
72b7576f 1001static Standard_GUID
dba69de2 1002 Schema(“45b3c6a2-22f3-11d2-b09e-0000f8791463”);
72b7576f 1003
1004//======================================================
1005// function : Factory
1006// purpose :
1007//======================================================
1008
e5bd0d98 1009Handle(Standard_Transient) FAFactory::Factory(const Standard_GUID& aGUID)
72b7576f 1010{
dba69de2 1011 if(aGUID == StorageDriver) {
1012 cout “FAFactory : Create store driver” endl;
1013 static Handle(FADriver_PartStorer) sd = new FADriver_PartStorer();
1014 return sd;
1015 }
1016
1017 if(aGUID == RetrievalDriver) {
1018 cout “FAFactory : Create retrieve driver” endl;
1019 static Handle(FADriver_PartRetriever)
1020 rd = new FADriver_PartRetriever();
1021 return rd;
1022 }
1023
1024 if(aGUID == Schema) {
1025 cout “FAFactory : Create schema” endl;
1026 static Handle(FirstAppSchema) s = new FirstAppSchema();
1027 return s;
1028 }
1029
1030 Standard_Failure::Raise(“FAFactory: unknown GUID”);
1031 Handle(Standard_Transient) t;
1032 return t;
72b7576f 1033}
1034~~~~~
1035
dba69de2 1036#### Without using the Software Factory
72b7576f 1037
e2b55410 1038To create a factory without using the Software Factory, define a *dll* project under Windows or a library under UNIX by using a source file as specified above. The *FAFactory* class is implemented as follows:
72b7576f 1039
1040~~~~~
1041#include <Handle_Standard_Transient.hxx>
1042#include <Standard_Macro.hxx>
1043class Standard_Transient;
1044class Standard_GUID;
1045class FAFactory {
1046public:
dba69de2 1047 Standard_EXPORT static Handle_Standard_Transient
e5bd0d98 1048 Factory(const Standard_GUID& aGUID) ;
dba69de2 1049 . . .
72b7576f 1050};
1051~~~~~
1052
1053
e2b55410 1054@section occt_fcug_3 Collections, Strings, Quantities and Unit Conversion
ba06f8bb 1055
dba69de2 1056@subsection occt_fcug_3_1 Collections
ba06f8bb 1057
72b7576f 1058@subsubsection occt_fcug_3_1_1 Overview
ba06f8bb 1059
72b7576f 1060The **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.
dba69de2 1061
e2b55410 1062Collections 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).
1063
1064When 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*.
1065
dba69de2 1066However, note that:
72b7576f 1067 * Each collection directly used as an argument in OCCT public syntax is instantiated in an OCCT component.
dba69de2 1068 * 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.
72b7576f 1069The **Collections** component provides a wide range of generic collections:
dba69de2 1070 * **Arrays** are generally used for a quick access to the item, however an array is a fixed sized aggregate.
1071 * **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.
e2b55410 1072 * **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.
1073 * **Lists** are similar to sequences but have different algorithms to explore them.
1074 * Specific iterators for sequences and maps.
dba69de2 1075
1076Most collections follow value semantics: their instances are the actual collections, not **handles** to a collection. Only arrays and sequences may also be manipulated by handle, and therefore shared.
72b7576f 1077
e2b55410 1078Each collection directly used as an argument in Open CASCADE Technology public syntax
1079is instantiated in an OCCT component using the corresponding generic class in package
1080<i> TCollection</i>, by means of compiling the CDL declaration of the instance.
1081Thus OCCT generic classes require compilation of definitions in the CDL language and therefore
1082can only be instantiated in WOK.
1083
1084If you do not use CDL in your project (CDL compilation under WOK is necessary
1085to instantiate any generic Collection from package <i>TCollection</i>), then you should
1086use the Collections defined in <i> NCollection</i> package. It contains definitions of the
1087same generic collection classes described above, but in a form of C++ templates.
1088Therefore, to instantiate any collection type no additional support is required beyond
1089the ANSI C++ compiler.
1090
72b7576f 1091@subsubsection occt_fcug_3_1_2 Generic general-purpose Aggregates
1092
dba69de2 1093#### TCollection_Array1
1094
1095These are unidimensional arrays similar to C arrays, i.e. of fixed size but dynamically dimensioned at construction time.
1096As 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.
1097
1098*Array1* is a generic class which depends on *Item*, the type of element in the array.
1099
1100*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.
1101
1102#### TCollection_Array2
1103
1104These are bi-dimensional arrays of fixed size but dynamically dimensioned at construction time.
1105
1106As 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.
1107
1108*Array2* is a generic class which depends on *Item*, the type of element in the array.
1109
1110*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.
1111
1112#### TCollection_HArray1
1113
1114These are unidimensional arrays similar to C arrays, i.e. of fixed size but dynamically dimensioned at construction time.
1115As 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.
1116
1117*HArray1* objects are **handles** to arrays.
1118 * *HArray1* arrays may be shared by several objects.
1119 * You may use a *TCollection_Array1* structure to have the actual array.
1120
1121*HArray1* is a generic class which depends on two parameters:
72b7576f 1122 * **Item**, the type of element in the array,
dba69de2 1123 * **Array**, the actual type of array handled by *HArray1*. This is an instantiation with **Item** of the *TCollection_Array1* generic class.
72b7576f 1124
dba69de2 1125*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.
1126
1127#### TCollection_HArray2
1128
1129These are bi-dimensional arrays of fixed size but dynamically dimensioned at construction time.
1130
1131As 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.
1132
1133*HArray2* objects are **handles** to arrays.
1134 * *HArray2* arrays may be shared by several objects.
1135 * You may use a *TCollection_Array2* structure to have the actual array.
72b7576f 1136
dba69de2 1137*HArray2* is a generic class which depends on two parameters:
1138 * *Item*, the type of element in the array,
1139 * *Array*, the actual type of array handled by *HArray2*. This is an instantiation with *Item* of the *TCollection_Array2* generic class.
72b7576f 1140
dba69de2 1141#### TCollection_HSequence
1142
1143This is a sequence of items indexed by an integer.
1144
1145Sequences 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.
1146
1147*HSequence* objects are **handles** to sequences.
1148 * *HSequence* sequences may be shared by several objects.
1149 * You may use a *TCollection_Sequence* structure to have the actual sequence.
1150
1151*HSequence* is a generic class which depends on two parameters:
1152 * *Item*, the type of element in the sequence,
1153 * *Seq*, the actual type of sequence handled by *HSequence*. This is an instantiation with *Item* of the *TCollection_Sequence* generic class.
1154
1155#### TCollection_HSet
1156
1157This is a collection of non-ordered items without any duplicates. At each transaction, the system checks if there are no duplicates.
1158*HSet* objects are *handles* to sets.
1159*HSet* is a generic class which depends on two parameters:
1160 * *Item*, the type of element in the set,
1161 * *Set*, the actual type of set handled by *HSet*. This is an instantiation with *TCollection_Set* generic class.
1162
1163#### TCollection_List
1164
1165These are ordered lists of non-unique objects which can be accessed sequentially using an iterator.
72b7576f 1166Item 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.
dba69de2 1167
1168*List* is a generic class, which depends on *Item*, the type of element in the structure.
1169Use a *ListIterator* iterator to explore a *List* structure.
1170
1171An iterator class is automatically instantiated from the *TCollection_ListIterator* class at the time of instantiation of a *List* structure.
1172
72b7576f 1173A sequence is a better structure when searching for items by value.
dba69de2 1174
72b7576f 1175Queues and stacks are other kinds of list with a different access to data.
1176
dba69de2 1177#### TCollection_Queue
72b7576f 1178
dba69de2 1179This is a structure, where items are added at the end and removed from the front. The first item entered will be the first removed (**FIFO** structure: First In First Out). *Queue* is a generic class which depends on *Item*, the type of element in the structure.
1180
1181#### TCollection_Sequence
1182
1183This is a sequence of items indexed by an integer.
1184Sequences 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.
1185
1186*Sequence* is a generic class which depends on *Item*, the type of element in the sequence.
1187
1188#### TCollection_Set
1189
1190This is a collection of non-ordered items without any duplicates. At each transaction, the system checks if there are no duplicates.
72b7576f 1191
72b7576f 1192A set generates the same result as a map. A map is more effective; so it is advisable to use maps instead of sets.
72b7576f 1193
dba69de2 1194*Set* is a generic class which depends on *Item*, the type of element in the set.
1195Use *SetIterator* iterator to explore a *Set* structure.
1196
1197#### TCollection_Stack
1198
1199This is a structure where items are added and removed from the top. The last item entered will be the first removed.
1200
1201*Stack* is a generic class which depends on *Item*, the type of element in the structure.
1202Use a *StackIterator* iterator to explore a *Stack* structure.
72b7576f 1203
1204@subsubsection occt_fcug_3_1_3 Generic Maps
1205
dba69de2 1206Maps are dynamically extended data structures where data is quickly accessed with a key. *TCollection_BasicMap* is a root class for maps.
1207
1208#### General properties of maps
72b7576f 1209
72b7576f 1210Map 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.
dba69de2 1211
72b7576f 1212The 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.
dba69de2 1213
72b7576f 1214The 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.
1215
1216The 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.
dba69de2 1217
72b7576f 1218That is why maps are commonly used as internal data structures for algorithms.
1219
dba69de2 1220#### Definitions
1221
72b7576f 1222A map is a data structure for which data are addressed by *keys*.
dba69de2 1223
1224Once inserted in the map, a map item is referenced as an *entry* of the map.
1225
72b7576f 1226Each entry of the map is addressed by a key. Two different keys address two different entries of the map.
1227The position of an entry in the map is called a *bucket*.
dba69de2 1228
72b7576f 1229A 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.
dba69de2 1230
1231The *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.
1232
1233Both the hashing function and the equality test between two keys are provided by a *hasher* object.
1234
72b7576f 1235A map may be explored by a *map iterator*. This exploration provides only inserted entries in the map (i.e. non empty buckets).
1236
dba69de2 1237#### Collections of generic maps
1238
1239The *Collections* component provides numerous generic derived maps.
1240
1241These 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.
1242
72b7576f 1243*Keys, items* and *hashers* are parameters of these generic derived maps.
dba69de2 1244
1245*TCollection_MapHasher* class describes the functions required by any *hasher*, which is to be used with a map instantiated from the **Collections** component.
1246
1247An 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*).
1248
1249##### TCollection_DataMap
1250
1251This is a map used to store keys with associated items. An entry of **DataMap** is composed of both the key and the item.
1252The *DataMap* can be seen as an extended array where the keys are the indexes.
1253
1254*DataMap* is a generic class which depends on three parameters:
4ee1bdf4 1255 * *Key* is the type of key for an entry in the map,
1256 * *Item* is the type of element associated with a key in the map,
1257 * *Hasher* is the type of hasher on keys.
dba69de2 1258
1259Use a *DataMapIterator* iterator to explore a *DataMap* map.
1260
1261An iterator class is automatically instantiated from the *TCollection_DataMapIterator* generic class at the time of instantiation of a *DataMap* map.
1262
1263*TCollection_MapHasher* class describes the functions required for a *Hasher* object.
1264
1265##### TCollection_DoubleMap
1266
1267This is a map used to bind pairs of keys (Key1,Key2) and retrieve them in linear time.
1268
1269*Key1* is referenced as the first key of the *DoubleMap* and *Key2* as the second key.
1270
1271An entry of a *DoubleMap* is composed of a pair of two keys: the first key and the second key.
1272
1273*DoubleMap* is a generic class which depends on four parameters:
1274 * *Key1* is the type of the first key for an entry in the map,
1275 * *Key2* is the type of the second key for an entry in the map,
1276 * *Hasher1* is the type of hasher on first keys,
1277 * *Hasher2* is the type of hasher on second keys.
1278
1279Use *DoubleMapIterator* to explore a *DoubleMap* map.
1280
1281An iterator class is automatically instantiated from the *TCollection_DoubleMapIterator* class at the time of instantiation of a *DoubleMap* map.
1282
1283*TCollection_MapHasher* class describes the functions required for a *Hasher1* or a *Hasher2* object.
1284
1285##### TCollection_IndexedDataMap
1286
1287This is map to store keys with associated items and to bind an index to them.
1288
1289Each 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.
1290
1291An 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:
72b7576f 1292 * of an array because data may be accessed with an index,
1293 * and of a map because data may also be accessed with a key.
1294
dba69de2 1295*IndexedDataMap* is a generic class which depends on three parameters:
4ee1bdf4 1296 * *Key* is the type of key for an entry in the map,
1297 * *Item* is the type of element associated with a key in the map,
1298 * *Hasher* is the type of hasher on keys.
dba69de2 1299
1300##### TCollection_IndexedMap
1301
1302This is map used to store keys and to bind an index to them.
72b7576f 1303
72b7576f 1304Each 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.
72b7576f 1305
dba69de2 1306An 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.
1307
1308*IndexedMap* is a generic class which depends on two parameters:
1309 * *Key* is the type of key for an entry in the map,
1310 * *Hasher* is the type of hasher on keys.
1311
1312##### TCollection_Map
1313
1314This is a basic hashed map, used to store and retrieve keys in linear time.
1315
1316An 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.
1317
1318*Map* is a generic class which depends on two parameters:
1319 * *Key* is the type of key in the map,
1320 * *Hasher* is the type of hasher on keys.
1321
1322Use a *MapIterator* iterator to explore a *Map* map.
72b7576f 1323
dba69de2 1324##### TCollection_MapHasher
1325
1326This is a hasher on the *keys* of a map instantiated from the *Collections* component.
72b7576f 1327
72b7576f 1328A hasher provides two functions:
dba69de2 1329* *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.
1330* *IsEqual* is the equality test between two keys. Hashers are used as parameters in generic maps provided by the **Collections** component.
1331
1332*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.
1333
1334Elsewhere, 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.
1335
1336Note 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.
72b7576f 1337
1338@subsubsection occt_fcug_3_1_4 Iterators
1339
dba69de2 1340#### TCollection_BasicMapIterator
72b7576f 1341
dba69de2 1342This is a root class for map iterators. A map iterator provides a step by step exploration of all the entries of a map.
72b7576f 1343
dba69de2 1344#### TCollection_DataMapIterator
72b7576f 1345
dba69de2 1346These are functions used for iterating the contents of a *DataMap* map.
72b7576f 1347
dba69de2 1348A 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.
72b7576f 1349
dba69de2 1350#### TCollection_DoubleMapIterator
1351
1352These are functions used for iterating the contents of a *DoubleMap* map.
1353
1354#### TCollection_ListIterator
1355
1356These are unctions used for iterating the contents of a *List* data structure.
1357
1358A *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.
1359
1360An iterator class is automatically instantiated from this generic class at the time of instantiation of a *List* data structure.
1361
1362#### TCollection_MapIterator
1363
1364These are functions used for iterating the contents of a *Map* map.
1365An iterator class is automatically instantiated from this generic class at the time of instantiation of a *Map* map.
1366
1367#### TCollection_SetIterator
1368
1369These are functions used for iterating the contents of a *Set* data structure.
1370An iterator class is automatically instantiated from this generic class at the time of instantiation of a *Set* structure.
72b7576f 1371
dba69de2 1372#### TCollection_StackIterator
1373
4ee1bdf4 1374These are functions used for iterating the contents of a **Stack** data structure.
dba69de2 1375
1376An iterator class is automatically instantiated from this generic class at the time of instantiation of a *Stack* structure.
72b7576f 1377
1378@subsection occt_fcug_3_2 Collections of Standard Objects
1379@subsubsection occt_fcug_3_2_1 Overview
dba69de2 1380While 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.
1381The *TColStd* and *TShort* packages provide frequently used instantiations of generic classes with objects from the *Standard* package or strings from the *TCollection* package.
72b7576f 1382
1383@subsubsection occt_fcug_3_2_2 Description
1384These instantiations are the following:
4ee1bdf4 1385 * Unidimensional arrays: instantiations of the *TCollection_Array1* generic class with *Standard* Objects and *TCollection* strings.
dba69de2 1386 * Bidimensional arrays: instantiations of the *TCollection_Array2* generic class with *Standard* Objects.
1387 * Unidimensional arrays manipulated by handles: instantiations of the *TCollection_HArray1* generic class with *Standard* Objects and *TCollection* strings.
1388 * Bidimensional arrays manipulated by handles: instantiations of the *TCollection_HArray2* generic class with *Standard* Objects.
1389 * Sequences: instantiations of the *TCollection_Sequence* generic class with *Standard* objects and *TCollection* strings.
1390 * Sequences manipulated by handles: instantiations of the *TCollection_HSequence* generic class with *Standard* objects and *TCollection* strings.
1391 * Lists: instantiations of the *TCollection_List* generic class with *Standard* objects.
1392 * Queues: instantiations of the *TCollection_Queue* generic class with *Standard* objects.
1393 * Sets: instantiations of the *TCollection_Set* generic class with *Standard* objects.
1394 * Sets manipulated by handles: instantiations of the *TCollection_HSet* generic class with *Standard* objects.
1395 * Stacks: instantiations of the *TCollection_Stack* generic class with *Standard* objects.
1396 * Hashers on map keys: instantiations of the *TCollection_MapHasher* generic class with *Standard* objects.
1397 * Basic hashed maps: instantiations of the *TCollection_Map* generic class with *Standard* objects.
1398 * Hashed maps with an additional item: instantiations of the *TCollection_DataMap* generic class with *Standard* objects.
1399 * Basic indexed maps: instantiations of the *TCollection_IndexedMap* generic class with *Standard* objects.
1400 * Indexed maps with an additional item: instantiations of the *TCollection_IndexedDataMap* generic class with *Standard_Transient* objects.
1401 * 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).
72b7576f 1402
1403@subsection occt_fcug_3_3 NCollections
1404@subsubsection occt_fcug_3_3_1 Overview
1405
dba69de2 1406*NCollection* package allows to not use WOK development environment in projects. Though it is quite natural to develop a code based on OCCT in any environment accepted in the industry, there is still one limitation: the so-called OCCT generic classes provided in TCollection package require compilation of the definitions in the CDL language and therefore can only be instantiated in WOK development environment.
72b7576f 1407
1408The NCollection library provides a full replacement of all TCollection generic classes so that any OCCT collection could be instantiated via C++ template or macro definitions. It can be used in WOK as a package development unit, or in any other configuration, since it only uses the standard capabilities of C++ compiler.
1409
dba69de2 1410Macro 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. On the contrary, template classes in *NCollection_\*.hxx* files are recommended, they are supported by OPEN CASCADE Company and further developed according to various needs.
72b7576f 1411
dba69de2 1412The technology used in this unit continues and complements the one offered in the header file *Standard_DefineHandle* – allowing to implement outside CDL the classes managed by Handle, also providing OCCT RTTI support.
72b7576f 1413
1414@subsubsection occt_fcug_3_3_2 Instantiation of collection classes
1415
dba69de2 1416Now we are going to implement the definitions from *NCollection* in the code, taking as an example a sequence of points (analogue of *TColgp_SequenceOfPnt*).
72b7576f 1417
dba69de2 1418#### Definition of a new collection class
72b7576f 1419
1420Let the header file be *MyPackage_SequenceOfPnt.hxx* :
1421
1422Template class instantiaton
1423~~~~~
1424#include <NCollection_Sequence.hxx>
1425#include <gp_Pnt.hxx>
1426typedef NCollection_Sequence<gp_Pnt> MyPackage_SequenceOfPnt;
1427~~~~~
1428
1429Macro instantiation
1430~~~~~
1431#include <NCollection_DefineSequence.hxx>
1432#include <gp_Pnt.hxx>
1433~~~~~
1434
1435The following line defines the class "base collection of points"
1436~~~~~
1437DEFINE_BASECOLLECTION(MyPackage_BaseCollPnt, gp_Pnt)
1438~~~~~
1439
dba69de2 1440The following line defines the class *MyPackage_SequenceOfPnt*
72b7576f 1441
1442~~~~~
1443DEFINE_SEQUENCE (MyPackage_SequenceOfPnt, MyPackage_BaseCollPnt , gp_Pnt)
1444~~~~~
1445
dba69de2 1446#### Definition of a new collection class managed by Handle
72b7576f 1447
1448It is necessary to provide relevant statements both in the header ( .hxx file) and the C++ source ( .cxx file).
1449
1450Header file MyPackage_HSequenceOfPnt.hxx:
1451
1452~~~~~
1453#include <NCollection_DefineHSequence.hxx>
1454#include <gp_Pnt.hxx>
1455~~~~~
1456
1457The following line defines the class "base collection of points"
1458
1459~~~~~
1460DEFINE_BASECOLLECTION(MyPackage_BaseCollPnt, gp_Pnt)
1461~~~~~
1462
dba69de2 1463The following line defines the class *MyPackage_SequenceOfPnt*
72b7576f 1464
1465~~~~~
1466DEFINE_SEQUENCE (MyPackage_SequenceOfPnt, MyPackage_BaseCollPnt, gp_Pnt)
1467~~~~~
1468
dba69de2 1469The following line defines the classes *MyPackage_HSequenceOfPnt* and *Handle(MyPackage_HSequenceOfPnt)*
72b7576f 1470
1471~~~~~
1472DEFINE_HSEQUENCE (MyPackage_HSequenceOfPnt, MyPackage_SequenceOfPnt)
1473~~~~~
1474
dba69de2 1475Source code file will be *MyPackage_HSequenceOfPnt.cxx* or any other .cxx file (once in the whole project):
72b7576f 1476
1477~~~~~
1478IMPLEMENT_HSEQUENCE (MyPackage_HSequenceOfPnt)
1479~~~~~
1480
1481@subsubsection occt_fcug_3_3_3 Class architecture
1482
72b7576f 1483
dba69de2 1484To understand the basic architecture of the classes instantiated from *NCollection* macros, please refer to the documentation on *TCollection* package, particularly to CDL files. Almost all API described there is preserved in *NCollection*. Changes are described in corresponding *NCollection_Define\*.hxx* files.
72b7576f 1485
dba69de2 1486Nevertheless the internal structure of NCollection classes is more complex than that of *TCollection* ones, providing more capabilities. The advanced layer of architecture is described in the next chapter Features.
72b7576f 1487
1488There are two principal changes:
dba69de2 1489* In *TCollection* some classes ( Stack, List, Set, Map, DataMap, DoubleMap ) define the Iterator type, the name of Iterator being like *MyPackage_DoubleMapIteratorOfDoubleMapOfIntegerReal*. In *NCollection* each Iterator is always defined as subtype of the collection *MyPackage_DoubleMapOfIntegerReal::Iterator*.
1490* Hashed collections (of type Map\* ) require in *TCollection* that the special class *Map\*Hasher* is defined. In *NCollection* it is only required that the global functions *IsEqual* and *HashCode* are defined.
1491
1492#### Interface to classes defined in CDL
72b7576f 1493
dba69de2 1494The classes defined above can be used as types for fields, parameters of methods and return values in CDL definitions. In our example, if MyPackage is a CDL package, you will need to create the file *MyPackage_SequenceOfPnt.hxx* containing or including the above definitions, and then to add the line: imported *SequenceOfPnt* to file *MyPackage.cdl*;
72b7576f 1495
1496Then the new collection type can be used in any CDL definition under the name *SequenceOfPnt* from *MyPackage*.
1497
1498@subsubsection occt_fcug_3_3_4 New collection types
1499
1500There are 4 collection types provided as template classes:
dba69de2 1501* *NCollection_Vector*
1502* *NCollection_UBTree*
1503* *NCollection_SparseArray*
1504* *NCollection_CellFilter*
72b7576f 1505
dba69de2 1506#### Vector
72b7576f 1507
1508This type is implemented internally as a list of arrays of the same size. Its properties:
1509* Direct (constant-time) access to members like in Array1 type; data are allocated in compact blocks, this provides faster iteration.
1510* Can grow without limits, like List, Stack or Queue types.
1511* Once having the size LEN, it cannot be reduced to any size less than LEN – there is no operation of removal of items.
1512
1513Insertion in a Vector-type class is made by two methods:
1514* _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).
1515* _Append(theValue)_ – list-type insertion equivalent to _myVec.SetValue(myVec.Length(), theValue)_ – incrementing the size of the collection.
1516
1517Other essential properties coming from List and Array1 type collections:
dba69de2 1518* Like in *List*, the method *Clear()* destroys all contained objects and releases the allocated memory.
1519* Like in *Array1*, the methods *Value()* and *ChangeValue()* return a contained object by index. Also, these methods have the form of overloaded operator ().
72b7576f 1520
dba69de2 1521#### UBTree
72b7576f 1522
1523The name of this type stands for “Unbalanced Binary Tree”. It stores the members in a binary tree of overlapped bounding objects (boxes or else).
1524Once 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.
1525The 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)).
1526
dba69de2 1527Defining various classes inheriting *NCollection_UBTree::Selector* we can perform various kinds of selection over the same b-tree object.
72b7576f 1528
dba69de2 1529The 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:
72b7576f 1530
1531~~~~~
1532 class MyBndType
1533 {
1534 public:
1535 inline void Add (const MyBndType& other);
1536 // Updates me with other bounding type instance
1537
1538 inline Standard_Boolean IsOut (const MyBndType& other) const;
1539 // Classifies other bounding type instance relatively me
1540
1541 inline Standard_Real SquareExtent() const;
1542 // Computes the squared maximal linear extent of me (for a box it is the squared diagonal of the box).
1543 };
dba69de2 1544~~~~~
1545
72b7576f 1546
dba69de2 1547This interface is implemented in types of Bnd package: *Bnd_Box, Bnd_Box2d, Bnd_B2x, Bnd_B3x*.
72b7576f 1548
dba69de2 1549To 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.
1550The 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.
1551Instantiation 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.
1552Below 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.
72b7576f 1553
1554~~~~~
1555typedef NCollection_UBTree<MyData, Bnd_B2f> UBTree;
1556typedef NCollection_List<MyData> ListOfSelected;
1557//! Tree Selector type
1558class MyTreeSelector : public UBTree::Selector
1559{
1560public:
1561 // This constructor initializes the selection criterion (e.g., a point)
1562
1563 MyTreeSelector (const gp_XY& thePnt) : myPnt(thePnt) {}
1564 // Get the list of selected objects
1565
1566 const ListOfSelected& ListAccepted () const
1567 { return myList; }
1568 // Bounding box rejection - definition of virtual method. @return True if theBox is outside the selection criterion.
1569
1570 Standard_Boolean Reject (const Bnd_B2f& theBox) const
1571 { return theBox.IsOut(myPnt); }
1572 // Redefined from the base class. Called when the bounding of theData conforms to the selection criterion. This method updates myList.
1573
1574 Standard_Boolean Accept (const MyData& theData)
1575 { myList.Append(theData); }
1576 private:
1577 gp_XY myPnt;
1578 ListOfSelected myList;
1579};
1580. . .
1581// Create a UBTree instance and fill it with data, each data item having the corresponding 2D box.
1582
1583UBTree aTree;
1584NCollection_UBTreeFiller <MyData, Bnd_B2f> aTreeFiller(aTree);
1585for(;;) {
1586 const MyData& aData = …;
1587 const Bnd_B2d& aBox = aData.GetBox();
1588 aTreeFiller.Add(aData, aBox);
1589}
1590aTreeFiller.Fill();
1591. . .
1592// Perform selection based on ‘aPoint2d’
1593MyTreeSelector aSel(aPoint2d);
1594aTree.Select(aSel);
1595const ListOfSelected = aSel.ListAccepted();
1596~~~~~
1597
1598
dba69de2 1599#### SparseArray
1600
72b7576f 1601
1602This 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.
1603
dba69de2 1604This 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).
72b7576f 1605
1606This type has both interfaces of DataMap and Vector to access items.
1607
dba69de2 1608#### CellFilter
72b7576f 1609
1610This 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.
1611
1612@subsubsection occt_fcug_3_3_5 Features
1613
1614NCollection defines some specific features, in addition to the public API inherited from TCollection classes.
1615
dba69de2 1616#### Iterators
1617
72b7576f 1618Every 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:
1619
1620* _void Init (const MyCollection&)_ - initializes the iterator on the collection object;
1621* _Standard_Boolean More () const_ - makes a query if there is another non-iterated member;
1622* _void Next ()_ - increments the iterator;
1623* _const ItemType& Value () const_ - returns the current member;
1624* _ItemType& ChangeValue () const_ - returns the mutable current member
1625
1626~~~~~
1627typedef Ncollection_Sequence<gp_Pnt>
1628MyPackage_SequenceOfPnt
1629void Perform (const MyPackage_SequenceOfPnt& theSequence)
1630{
1631 MyPackage_SequenceOfPnt::Iterator anIter (theSequence);
1632 for (; anIter.More(); anIter.Next()) {
1633 const gp_Pnt aPnt& = anIter.Value();
1634....
1635 }
1636}
dba69de2 1637~~~~~
1638
1639This feature is present only for some classes in *TCollection (Stack, List, Set, Map, DataMap, DoubleMap)*. In *NCollection* it is generalized.
72b7576f 1640
1641
dba69de2 1642#### Class BaseCollection
72b7576f 1643
dba69de2 1644There 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.
72b7576f 1645
1646This base class has the following public API:
1647* abstract class Iterator as the base class for all Iterators descried above;
1648* _Iterator& CreateIterator () const_ - creates and returns the Iterator on this collection;
1649* _Standard_Integer Size () const_ - returns the number of items in this collection;
dba69de2 1650* *void Assign (const NCollection_BaseCollection& theOther)* - copies the contents of the Other to this collection object;
72b7576f 1651
1652These 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:
1653
1654~~~~~
1655#include <NColection_Map.hxx>
1656typedef NCollection_Map<gp_Pnt> MyPackage_MapOfPnt;
1657typedef NCollection_BaseCollection<gp_Pnt> MyPackage_BaseCollPnt;
1658MyPackage_MapOfPnt aMapPnt;
1659....
1660gp_Pnt aResult = COG (aMapPnt);
1661....
1662gp_Pnt COG(const MyPackage_BaseCollPnt& theColl)
1663{
1664 gp_XYZ aCentreOfGravity(0., 0., 0.);
1665// create type-independent iterator (it is abstract type instance)
1666 MyPackage_BaseCollString::Iterator& anIter = theColl.CreateIterator();
1667 for (; anIter.More(); anIter.Next()) {
1668 aCentreOfGravity += anIter.Value().XYZ();
1669 }
1670 return aCentreOfGravity / theColl.Size();
1671}
1672~~~~~
1673
1674Note that there are fundamental differences between the shown type-independent iterator and the iterator belonging to a particular non-abstract collection:
1675* Type-independent iterator can only be obtained via the call CreateIterator(); the typed iterator - only via the explicit construction.
1676* 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 Init() .
1677* 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.
1678
1679The common point between them is that it is possible to create any number of both types of iterators on the same collection object.
1680
dba69de2 1681#### Heterogeneous Assign
72b7576f 1682
4ee1bdf4 1683The 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*.
72b7576f 1684
4ee1bdf4 1685For example, conversion of *Map* into *Array1* is performed like this:
72b7576f 1686
1687~~~~~
1688#include <NCollection_Map.hxx>
1689#include <NCollection_Array1.hxx>
1690typedef NCollection_Map<gp_Pnt> MyPackage_MapOfPnt;
1691typedef NCollection_Array1<gp_Pnt> MyPackage_Array1OfPnt;
1692....
1693MyPackage_MapOfPnt aMapPnt;
1694....
1695MyPackage_Array1OfPnt anArr1Pnt (1, aMapPnt.Size());
1696anArr1Pnt.Assign (aMapPnt); // heterogeneous assignment
1697~~~~~
1698
1699There are some aspects to mention:
4ee1bdf4 1700* 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.
1701* 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*.
1702* 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:
72b7576f 1703
1704~~~~~
1705MyPackage_Array1OfPnt anArr1Pnt (1, 100);
1706MyPackage_MapOfPnt aMapPnt;
1707....
1708aMapPnt.Assign(anArr1Pnt);
1709anArr1Pnt.Assign(aMapPnt);
1710~~~~~
1711
4ee1bdf4 1712Objects 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).
72b7576f 1713
dba69de2 1714#### Allocator
72b7576f 1715
4ee1bdf4 1716All 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:
72b7576f 1717
1718~~~~~
1719Standard_EXPORT virtual void* Allocate (const size_t size);
1720Standard_EXPORT virtual void Free (void * anAddress);
1721~~~~~
1722
4ee1bdf4 1723It 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.
72b7576f 1724
4ee1bdf4 1725Nevertheless, the it is possible to define a custom *Allocator* type to manage the memory in the most optimal or convenient way for his algorithms.
72b7576f 1726
4ee1bdf4 1727As 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.
72b7576f 1728
1729
1730
1731@subsection occt_fcug_3_4 Strings
1732
e2b55410 1733Strings are classes that handle dynamically sized sequences of characters based on
1734ASCII/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.
1735
1736String classes provide the following services to manipulate character strings:
1737 * Editing operations on string objects, using a built-in string manager
1738 * Handling of dynamically-sized sequences of characters
1739 * Conversion from/to ASCII and UTF-8 strings.
1740
1741Strings may also be manipulated by handles and therefore shared.
72b7576f 1742
1743@subsubsection occt_fcug_3_4_1 Examples
72b7576f 1744
dba69de2 1745#### TCollection_AsciiString
1746
1747A 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.
1748*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.
1749
1750#### TCollection_ExtendedString
1751
4ee1bdf4 1752A 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.
dba69de2 1753
1754*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.
1755
1756#### TCollection_HAsciiString
1757
1758A 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.
1759*HAsciiString* objects are *handles* to strings.
1760 * *HAsciiString* strings may be shared by several objects.
1761 * You may use an *AsciiString* object to get the actual string.
1762*HAsciiString* objects use an *AsciiString* string as a field.
1763
1764#### TCollection_HExtendedString
1765
1766A 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.
1767*HExtendedString* objects are *handles* to strings.
1768 * *HExtendedString* strings may be shared by several objects.
1769 * You may use an *ExtendedString* object to get the actual string.
1770*HExtendedString* objects use an *ExtendedString* string as a field.
72b7576f 1771
1772@subsubsection occt_fcug_3_4_2 Conversion
4ee1bdf4 1773
1774*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.
72b7576f 1775
e2b55410 1776@subsection occt_fcug_3_5 Quantities
1777
1778Quantities 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.
1779
1780Quantity classes provide the following services:
1781 * Definition of primitive types representing most of mathematical and physical quantities;
1782 * 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*)
1783 * Resources to manage time information such as dates and time periods
1784 * Resources to manage color definition
1785
1786A mathematical quantity is characterized by the name and the value (real).
1787
1788A 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.
1789
1790The fact that both physical and mathematical quantities are manipulated as real values means that :
1791 * They are defined as aliases of real values, so all functions provided by the <i>Standard_Real</i> class are available on each quantity.
1792 * It is possible to mix several physical quantities in a mathematical or physical formula involving real values.
1793
1794<i>Quantity</i> package includes all commonly used basic physical quantities.
1795
1796@subsection occt_fcug_3_6 Unit Conversion
72b7576f 1797
dba69de2 1798The *UnitsAPI* global functions are used to convert a value from any unit into another unit. Conversion is executed among three unit systems:
72b7576f 1799 * the **SI System**,
1800 * the user’s **Local System**,
1801 * the user’s **Current System**.
dba69de2 1802The **SI System** is the standard international unit system. It is indicated by *SI* in the signatures of the *UnitsAPI* functions.
1803
4ee1bdf4 1804The 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.
dba69de2 1805
1806Both 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.
4ee1bdf4 1807The 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.
72b7576f 1808A physical quantity is defined by a string (example: LENGTH).
1809
1810
1811@section occt_occt_fcug_4 Math Primitives and Algorithms
e2b55410 1812
72b7576f 1813@subsection occt_occt_fcug_4_1 Overview
e2b55410 1814
72b7576f 1815Math primitives and algorithms available in Open CASCADE Technology include:
1816 * Vectors and matrices
1817 * Geometric primitives
1818 * Math algorithms
dba69de2 1819
72b7576f 1820@subsection occt_occt_fcug_4_2 Vectors and Matrices
e2b55410 1821
1822The 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.
1823
1824The <i> Vector</i> and <i> Matrix </i> classes provide commonly used mathematical algorithms which
1825include:
1826
1827 * Basic calculations involving vectors and matrices;
1828 * Computation of eigenvalues and eigenvectors of a square matrix;
1829 * Solvers for a set of linear algebraic equations;
1830 * Algorithms to find the roots of a set of non-linear equations;
1831 * Algorithms to find the minimum function of one or more independent variables.
1832
1833These classes also provide a data structure to represent any expression,
1834relation, or function used in mathematics, including the assignment of variables.
1835
1836Vectors and matrices have arbitrary ranges which must be defined at declaration time
1837and cannot be changed after declaration.
72b7576f 1838
1839~~~~~
1840math_Vector v(1, 3);
1841// a vector of dimension 3 with range (1..3)
1842math_Matrix m(0, 2, 0, 2);
1843// a matrix of dimension 3x3 with range (0..2, 0..2)
1844math_Vector v(N1, N2);
1845// a vector of dimension N2-N1+1 with range (N1..N2)
1846~~~~~
1847
1848Vector and Matrix objects use value semantics. In other words, they cannot be shared and are copied through assignment.
1849
1850~~~~~
1851math_Vector v1(1, 3), v2(0, 2);
1852v2 = v1;
1853// v1 is copied into v2. a modification of v1 does not affect v2
1854~~~~~
1855
1856Vector and Matrix values may be initialized and obtained using indexes which must lie within the range definition of the vector or the matrix.
1857
1858~~~~~
1859math_Vector v(1, 3);
1860math_Matrix m(1, 3, 1, 3);
1861Standard_Real value;
1862
1863v(2) = 1.0;
1864value = v(1);
1865m(1, 3) = 1.0;
1866value = m(2, 2);
1867~~~~~
1868
1869Some operations on Vector and Matrix objects may not be legal. In this case an exception is raised. Two standard exceptions are used:
dba69de2 1870 * *Standard_DimensionError* exception is raised when two matrices or vectors involved in an operation are of incompatible dimensions.
1871 * *Standard_RangeError* exception is raised if an access outside the range definition of a vector or of a matrix is attempted.
72b7576f 1872
1873~~~~~~
1874math_Vector v1(1, 3), v2(1, 2), v3(0, 2);
1875v1 = v2;
1876// error: Standard_DimensionError is raised
1877
1878v1 = v3;
1879// OK: ranges are not equal but dimensions are
1880// compatible
1881
1882v1(0) = 2.0;
1883// error: Standard_RangeError is raised
1884~~~~~~
1885
1886@subsection occt_occt_fcug_4_3 Primitive Geometric Types
e2b55410 1887
1888Open CASCADE Technology primitive geometric types are a STEP-compliant implementation of basic geometric and algebraic entities.
1889They provide:
1890 * Descriptions of primitive geometric shapes, such as:
1891 * Points;
1892 * Vectors;
1893 * Lines;
1894 * Circles and conics;
1895 * Planes and elementary surfaces;
1896 * Positioning of these shapes in space or in a plane by means of an axis or a coordinate system;
1897 * Definition and application of geometric transformations to these shapes:
1898 * Translations;
1899 * Rotations;
1900 * Symmetries;
1901 * Scaling transformations;
1902 * Composed transformations;
1903 * Tools (coordinates and matrices) for algebraic computation.
1904
1905All 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.
1906
e5bd0d98 1907The *gp* package defines the basic non-persistent 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.
e2b55410 1908
1909Please, 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.
1910
1911If 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.
1912
1913Therefore, 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:
1914 * the point of parameter u on a 2D or 3D gp curve,
1915 * the point of parameter (u,v) on a gp elementary surface, and
1916 * any derivative vector at this point.
1917
1918Note: the <i> gp</i> entities cannot be shared when they are inside more complex data structures.
72b7576f 1919
1920@subsection occt_occt_fcug_4_4 Collections of Primitive Geometric Types
dba69de2 1921
72b7576f 1922Before 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.
1923If 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.
dba69de2 1924In 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.*
72b7576f 1925These are non-persistent classes.
dba69de2 1926
72b7576f 1927@subsection occt_occt_fcug_4_5 Basic Geometric Libraries
1928There are various library packages available which offer a range of basic computations on curves and surfaces.
dba69de2 1929If 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.
1930* *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.
1931* *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.
1932
1933Additionally, *Bnd* package provides a set of classes and tools to operate with bounding boxes of geometric objects in 2d and 3d space.
1934
72b7576f 1935@subsection occt_occt_fcug_4_6 Common Math Algorithms
1936The common math algorithms library provides a C++ implementation of the most frequently used mathematical algorithms. These include:
1937 * Algorithms to solve a set of linear algebraic equations,
1938 * Algorithms to find the minimum of a function of one or more independent variables,
1939 * Algorithms to find roots of one, or of a set, of non-linear equations,
1940 * An algorithm to find the eigenvalues and eigenvectors of a square matrix.
dba69de2 1941
72b7576f 1942All mathematical algorithms are implemented using the same principles. They contain:
1943A 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.
dba69de2 1944
1945A function *IsDone* returning the boolean true if the calculation was successful.
72b7576f 1946A set of functions, specific to each algorithm, enabling all the various results to be obtained.
dba69de2 1947Calling these functions is legal only if the function *IsDone* answers **true**, otherwise the exception *StdFail_NotDone* is raised.
1948
1949The 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*:
72b7576f 1950
1951~~~~~~
1952class Gauss {
1953public:
e5bd0d98 1954 Gauss (const math_Matrix& A);
dba69de2 1955 Standard_Boolean IsDone() const;
e5bd0d98 1956 void Solve (const math_Vector& B,
1957 math_Vector& X) const;
72b7576f 1958};
1959~~~~~~
1960
1961Now the main program uses the Gauss class to solve the equations a*x1=b1 and a*x2=b2:
1962
1963~~~~~
1964#include <math_Vector.hxx>
1965#include <math_Matrix.hxx>
1966main ()
1967{
dba69de2 1968 math_Vector a(1, 3, 1, 3);
1969 math_Vector b1(1, 3), b2(1, 3);
1970 math_Vector x1(1, 3), x2(1, 3);
1971 // a, b1 and b2 are set here to the appropriate values
1972 math_Gauss sol(a); // computation of the
1973 // LU decomposition of A
1974 if(sol.IsDone()) { // is it OK ?
1975 sol.Solve(b1, x1); // yes, so compute x1
1976 sol.Solve(b2, x2); // then x2
1977 ...
1978 }
1979 else { // it is not OK:
1980 // fix up
1981 sol.Solve(b1, x1); // error:
1982 // StdFail_NotDone is raised
1983 }
72b7576f 1984}
1985~~~~~
1986
dba69de2 1987The 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*:
72b7576f 1988
1989~~~~~
1990class BissecNewton {
1991 public:
e5bd0d98 1992 BissecNewton (math_FunctionWithDerivative& f,
72b7576f 1993 const Standard_Real bound1,
1994 const Standard_Real bound2,
1995 const Standard_Real tolx);
1996 Standard_Boolean IsDone() const;
1997 Standard_Real Root();
1998};
1999~~~~~
2000
dba69de2 2001The 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*:
72b7576f 2002
2003~~~~~
2004class math_FunctionWithDerivative {
2005 public:
2006 virtual Standard_Boolean Value
e5bd0d98 2007 (const Standard_Real x, Standard_Real& f) = 0;
72b7576f 2008 virtual Standard_Boolean Derivative
e5bd0d98 2009 (const Standard_Real x, Standard_Real& d) = 0;
72b7576f 2010 virtual Standard_Boolean Values
2011 (const Standard_Real x,
e5bd0d98 2012 Standard_Real& f,
2013 Standard_Real& d) = 0;
72b7576f 2014};
2015~~~~~
2016
dba69de2 2017Now 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.
72b7576f 2018
2019~~~~~
2020#include <math_BissecNewton.hxx>
2021#include <math_FunctionWithDerivative.hxx>
2022class myFunction : public math_FunctionWithDerivative
2023{
dba69de2 2024 Standard_Real coefa, coefb, coefc;
2025
2026 public:
2027 myFunction (const Standard_Real a, const Standard_Real b,
2028 const Standard_Real c) :
2029 coefa(a), coefb(b), coefc(c)
2030 {}
2031
2032 virtual Standard_Boolean Value (const Standard_Real x,
e5bd0d98 2033 Standard_Real& f)
dba69de2 2034 {
2035 f = coefa * x * x + coefb * x + coefc;
2036 }
2037
2038 virtual Standard_Boolean Derivative (const Standard_Real x,
e5bd0d98 2039 Standard_Real& d)
dba69de2 2040 {
2041 d = coefa * x * 2.0 + coefb;
2042 }
2043
2044 virtual Standard_Boolean Values (const Standard_Real x,
e5bd0d98 2045 Standard_Real& f, Standard_Real& d)
dba69de2 2046 {
2047 f = coefa * x * x + coefb * x + coefc;
2048 d = coefa * x * 2.0 + coefb;
2049 }
72b7576f 2050};
2051
2052main()
2053{
dba69de2 2054 myFunction f(1.0, 0.0, 4.0);
2055 math_BissecNewton sol(F, 1.5, 2.5, 0.000001);
72b7576f 2056 if(Sol.IsDone()) { // is it OK ?
dba69de2 2057 Standard_Real x = sol.Root(); // yes.
2058 }
2059 else { // no
2060 }
72b7576f 2061~~~~~
2062
2063@subsection occt_occt_fcug_4_7 Precision
2064
2065On 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.
dba69de2 2066
2067The *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.
2068
72b7576f 2069Do not write _if (X1 == X2),_ instead write _if (Abs(X1-X2) < Precision)._
dba69de2 2070
72b7576f 2071Also, to order real numbers, keep in mind that _if (X1 < X2 - Precision)_ is incorrect.
dba69de2 2072_if (X2 - X1 > Precision)_ is far better when *X1* and *X2* are high numbers.
2073
72b7576f 2074This package proposes a set of methods providing precision settings for the most commonly encountered situations.
dba69de2 2075
72b7576f 2076In 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.
dba69de2 2077
72b7576f 2078High-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.
dba69de2 2079Different precision settings offered by this package cover the most common needs of geometric algorithms such as *Intersection* and *Approximation*.
72b7576f 2080The choice of a precision value depends both on the algorithm and on the geometric space. The geometric space may be either:
dba69de2 2081 * a real space, 3d or 2d where the lengths are measured in meters, micron, inches, etc.
2082 * a parametric space, 1d on a curve or 2d on a surface where numbers have no dimension.
72b7576f 2083The 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.
2084This 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:
2085
2086~~~~~
2087Abs(t1-t2) < ParametricPrecision
2088Distance (P(t1),P(t2)) < RealPrecision.
2089~~~~~
2090
2091@subsubsection occt_occt_fcug_4_7_1 The Precision package
dba69de2 2092The *Precision* package offers a number of package methods and default precisions for use in dealing with angles, distances, intersections, approximations, and parametric space.
72b7576f 2093It provides values to use in comparisons to test for real number equalities.
2094 * Angular precision compares angles.
2095 * Confusion precision compares distances.
2096 * Intersection precision is used by intersection algorithms.
2097 * Approximation precision is used by approximation algorithms.
2098 * Parametric precision gets a parametric space precision from a 3D precision.
4ee1bdf4 2099 * *Infinite* returns a high number that can be considered to be infinite. Use <i>-Infinite</i> for a high negative number.
72b7576f 2100
2101@subsubsection occt_occt_fcug_4_7_2 Standard Precision values
2102This 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.
4ee1bdf4 2103The 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.
72b7576f 2104The geometric packages provide Parametric precisions for the different types of curves.
dba69de2 2105The *Precision* package provides methods to test whether a real number can be considered to be infinite.
2106
2107#### Precision::Angular
72b7576f 2108
4ee1bdf4 2109This 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*.
72b7576f 2110
2111It can be used to check confusion of two angles as follows:
2112_Abs(Angle1 - Angle2) < Precision::Angular()_
2113
2114It is also possible to check parallelism of two vectors (_Vec_ from _gp_) as follows _V1.IsParallel(V2,Precision::Angular())_
2115
4ee1bdf4 2116Note 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:
72b7576f 2117_Abs(D1 * D2) < Precision::Angular()_
2118
dba69de2 2119#### Precision::Confusion
2120
72b7576f 2121This 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.
2122
2123It can be used to check confusion of two points (_Pnt_ from _gp_) as follows:
2124_P1.IsEqual(P2,Precision::Confusion())_
2125
2126It is also possible to find a vector of null length (_Vec_ from _gp_) :
2127_V.Magnitude() < Precision::Confusion()_
2128
dba69de2 2129#### Precision::Intersection
2130
72b7576f 2131This 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*.
2132
dba69de2 2133#### Precision::Approximation
2134
72b7576f 2135This 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*.
2136Note that Approximation is greater than Confusion, so care must be taken when using Confusion in an approximation process.
2137
2138@section occt_fcug_5 Data Storage
2139@subsection occt_fcug_5_1 Saving and Opening Files
2140
e5bd0d98 2141@image html /user_guides/foundation_classes/images/foundation_classes_image007.png "Example of Saving-Opening workflow"
2142@image latex /user_guides/foundation_classes/images/foundation_classes_image007.png "Example of Saving-Opening workflow"
72b7576f 2143
2144In the example, the roots of the transferable transient objects *TopoDS_Shape, Geom_Geometry* and *Geom2d_Geometry* are used in algorithms, they contain data and temporary results.
dba69de2 2145The associated objects in the persistent domain are *PTopoDS_HShape, PGeom_Geometry* and *PGeom2d_Geometry*. They contain a real data structure which is stored in a file.
72b7576f 2146Note that when an object is stored, if it contains another stored object, the references to the contained object are also managed.
e5bd0d98 2147@image html /user_guides/foundation_classes/images/foundation_classes_image008.png "Saving-Opening mechanism"
2148@image latex /user_guides/foundation_classes/images/foundation_classes_image008.png "Saving-Opening mechanism"
72b7576f 2149
2150
2151@subsection occt_fcug_5_2 Basic Storage Procedures
72b7576f 2152
2153@subsubsection occt_fcug_5_2_1 Saving
2154
2155The storage procedure of a transient object follows five main steps.
21561. Create an I/O driver for files. For example, *FSD_File f()*;
21572. Instance the data schema, which will process your persistent information. The schema is used for read/write operations. If ShapeSchema is the name of your schema:
2158~~~~~
2159Handle(ShapeSchema) s = new ShapeSchema;
2160~~~~~
dba69de2 21613. Create a persistent shape from a transient shape.
72b7576f 2162~~~~~
2163TopoDS_Shape aShape;
2164PTColStd_TransientPersistentMap aMap;
2165Handle(PTopoDS_HShape) aPShape = MgtBRep::Translate
2166 (aShape, aMap, MgtBRep_WithoutTriangle);
2167~~~~~
dba69de2 21684. Create a new container and fill it using the *AddRoot()* method.
72b7576f 2169~~~~~
2170Handle(Storage_Data) d = new Storage_Data;
2171d -> AddRoot (“ObjectName”, aPShape);
2172~~~~~
2173You may add as many objects as you want in this container.
72b7576f 21745. Save to the archive.
2175~~~~~
2176s -> Write (f,d);
2177~~~~~
2178
2179@subsubsection occt_fcug_5_2_2 Opening
2180The retrieval mechanism is the opposite of the storage mechanism. The procedure for retrieving an object is as follows:
2181
21821. Create an I/O driver and instance a data schema (if not done).
dba69de2 21832. Read the persistent object from the archive and get the list of objects using *Roots()* method.
72b7576f 2184~~~~~
2185Handle(Storage_Data) d = s -> Read(f);
2186Handle(Storage_HSeqOfRoot) roots = d-> Roots();
2187~~~~~
dba69de2 21883. Loop on root objects to get *Standard_Persistent* objects (the following sequence only gets the first root).
72b7576f 2189~~~~~
2190Handle(Standard_Persistent) p;
2191Handle(Standard_Root) r;
2192if(roots -> Length() >= 1) {
dba69de2 2193 r = roots -> Value(1);
2194 p = r -> Object();
72b7576f 2195}
2196~~~~~
dba69de2 21974. DownCast the persistent object to a *PTopoDS_Hshape*.
72b7576f 2198~~~~~
2199Handle(PTopoDS_HShape) aPShape;
2200aPShape = Handle(PTopoDS_HShape)::DownCast(p);
2201~~~~~
dba69de2 22025. Create the *TopoDS_Shape*.
72b7576f 2203~~~~~
2204TopoDS_Shape aShape;
dba69de2 2205PTColStd_PersistentTransientMap aMap;
72b7576f 2206MgtBRep::Translate (aPShape, aMap, aShape, MgtBRep_WithoutTriangle);
2207~~~~~
2208
2209
2210