0026187: Implement m-dashes in the documentation
[occt.git] / dox / user_guides / ocaf / ocaf.md
1 OCAF  {#occt_user_guides__ocaf}
2 ========================
3
4 @tableofcontents
5
6 @section occt_ocaf_1 Introduction
7
8 This manual explains how to use the Open CASCADE Application Framework (OCAF).
9 It provides basic documentation on using OCAF. For advanced information on OCAF 
10 and its applications, see our <a href="http://www.opencascade.com/content/tutorial-learning">E-learning & Training</a> offerings.
11
12 @subsection occt_ocaf_1_1 Purpose of OCAF
13
14 OCAF (the Open CASCADE Application Framework) is an  easy-to-use platform for rapidly developing
15   sophisticated domain-specific  design applications. 
16   A typical application developed using OCAF deals with two or three-dimensional (2D or 3D) geometric modeling 
17   in trade-specific Computer Aided Design (CAD) systems, manufacturing or analysis applications, 
18   simulation  applications or illustration tools. 
19   
20   Developing a design application requires addressing many technical aspects. 
21   In particular, given the functional specification of your application, you must at least:  
22   
23   * Design the  architecture of the application— definition of the software components and the way they cooperate;
24   * Define the  data model able to support the functionality required — a design application  operates on data maintained during the whole end-user working session;
25   * Structure  the software in order to:
26     * synchronize the display with the  data — commands modifying objects must update the views;  
27     * support generalized undo-redo  commands — this feature has to be taken into account very early in the design  process;  
28   * Implement  the function for saving the data — if the application has a long life cycle,  the compatibility of data between versions of the application has to be  addressed;
29   * Build the  application user interface.
30  
31 Architectural guidance and ready-to-use solutions provided by OCAF offer you the following benefits:
32   * You can concentrate on the functionality specific for your application;  
33   * The underlying mechanisms required to support the application are already provided; 
34   * The application can be rapidly be prototyped thanks to the coupling the other Open CASCADE Technology modules;
35   * The final application can be developed by industrializing the prototype — you don't need to restart the development from scratch. 
36   * The Open Source nature of the platform guarantees the long-term usefulness of your development.   
37
38 OCAF is much more than just one toolkit among many in the CAS.CADE Object Libraries. Since it can handle any data and algorithms in these libraries -- be it modeling algorithms, topology or geometry -- OCAF is their logical supplement. 
39
40 The table below contrasts the design of a modeling application using object libraries alone and using OCAF. 
41
42 **Table 1: Services provided by OCAF** 
43
44 |Development tasks      |Comments | Without OCAF        | With OCAF |
45 |------------------:|---------:|---------------:|-----------:|
46 |Creation of geometry| Algorithm Calling the modeling libraries |       To be created by the user       | To be created by the user| 
47 | Data organization | Including specific attributes and modeling process | To be created by the user |  Simplified| 
48 | Saving data in a file | Notion of document | To be created by the user | Provided |
49 | Document-view management |    |  To be created by the user | Provided |
50 | Application infrastructure | New, Open, Close, Save and Save As File menus | To be created by the user | Provided | 
51 | Undo-Redo | Robust, multi-level       | To be created by the user     | Provided |
52 | Application-specific dialog boxes     |    | To be created by the user  |     To be created by the user |
53
54 OCAF uses other modules of Open CASCADE Technology — the Shape  is implemented with the geometry supported by the <a href="#user_guides__modeling_data">Modeling Data</a> module and the viewer is the one provided with the <a href="#user_guides__visualization">Visualization</a> module. Modeling functions can be implemented using the <a href="#user_guides__modeling_algos">Modeling Algorithms</a> module.
55
56 The relationship between OCAF and the Open CASCADE Technology (**OCCT**) Object Libraries can be seen in the image below. 
57
58 @figure{/user_guides/ocaf/images/ocaf_image003.svg, "OCCT Architecture"}
59
60 In the image, the OCAF (Open CASCADE Application Framework) is shown with black rectangles and OCCT Object Libraries required by OCAF are shown with white rectangles. 
61  
62 The subsequent chapters of this document explain the concepts and show how to use the services of OCAF.
63
64 @subsection occt_ocaf_1_2 Architecture Overview
65
66 OCAF provides you with an object-oriented Application-Document-Attribute model consisting of C++ class libraries. 
67
68 @image html ocaf_wp_image003.png "The Application-Document-Attribute model"
69 @image latex ocaf_wp_image003.png "The Application-Document-Attribute model"
70
71 @subsubsection occt_ocaf_1_2_1 Application
72
73 The *Application* is an abstract class in charge of handling documents during the working session, namely:  
74   * Creating new  documents;
75   * Saving documents and opening them;
76   * Initializing document views.
77   
78 @subsubsection occt_ocaf_1_2_2 Document   
79  
80   The document, implemented by the concrete class  *Document*, is the container for the application data. Documents offer access to the data framework and serve the following purposes: 
81
82   * Manage the notification of changes
83   * Update external links
84   * Manage the saving and restoring of data
85   * Store the names of software extensions.
86   * Manage command transactions
87   * Manage Undo and Redo options. 
88   
89   Each  document is saved in a single flat ASCII file defined by its format and  extension (a ready-to-use format is provided with  OCAF).  
90
91   Apart from their role as a container of application data, documents can refer to each other; Document A, for example, can refer to a specific label in Document B. This functionality is made possible by means of the reference key.   
92   
93 @subsubsection occt_ocaf_1_2_3 Attribute
94
95   Application data is described by **Attributes**, which are instances of  classes derived from the *Attribute* abstract class, organized according to the OCAF Data  Framework. 
96   
97   The @ref occt_ocaf_3 "OCAF Data Framework" references aggregations of attributes using  persistent identifiers in a single hierarchy. A wide range of  attributes come with OCAF, including:    
98   
99   * @ref occt_ocaf_6 "Standard attributes" allow operating with simple common data in the data framework (for example: integer, real, string, array kinds of data), realize auxiliary functions (for example: tag sources attribute for the children of the label counter), create dependencies (for example: reference, tree node)....;
100   * @ref occt_ocaf_5 "Shape attributes" contain the geometry of the whole model or its elements including reference to the shapes and tracking of shape evolution;
101   * Other  geometric attributes such as **Datums** (points, axis and plane) and **Constraints** (*tangent-to, at-a-given-distance, from-a-given-angle, concentric,* etc.)
102   * User  attributes, that is, attributes typed by the application  
103   * @ref occt_ocaf_7 "Visualization attributes" allow placing viewer information to the data framework, visual representation of objects and other auxiliary visual information, which is needed for graphical data representation.
104   * @ref occt_ocaf_8 "Function services" — the purpose of these attributes is to rebuild  objects after they have been modified (parameterization of models). While the document manages the notification of changes, a function manages propagation of these changes. The function mechanism provides links between functions and calls to various algorithms. 
105   
106 In addition,  application-specific data can be added by defining new attribute classes; naturally, this changes the standard file format. The only functions that have to be implemented are:
107     * Copying the  attribute
108     * Converting  it from and to its persistent homologue (persistence is briefly presented in the paragraph @ref occt_ocaf_9a_3 "Persistent Data Storage")
109         
110 @subsection occt_ocaf_1_3  Reference-key model
111
112   In most existing geometric modeling systems, the data are topology driven. 
113   They usually use a boundary representation (BRep), where geometric models 
114   are defined by a collection of faces, edges and vertices, 
115   to which application data are attached. Examples of data include:  
116  
117   * a color;
118   * a material;
119   * information that a particular edge is blended.
120  
121   When the geometric model is parameterized, that is, when you can change 
122   the value of parameters used to build the model (the radius of a  blend, the thickness of a rib, etc.), 
123   the geometry is highly subject to change. 
124   In order to maintain the attachment of application data, the geometry must be  distinguished from other data.  
125    
126   In OCAF, the data are reference-key driven. It is a  uniform model in which reference-keys 
127   are the persistent identification of  data. All **accessible** data, including the geometry, 
128   are implemented as attributes attached to reference-keys. 
129   The geometry becomes the  value of the Shape attribute, just as a number is the value 
130   of the Integer and  Real attributes and a string that of the Name attribute.  
131    
132   On a single reference-key, many attributes can be  aggregated; 
133   the application can ask at runtime which attributes are available. 
134   For example, to associate a texture to a face in a geometric model, 
135   both the face and the texture are attached to the same reference-key.  
136  
137 @image html ocaf_image004.png "Topology driven versus reference-key driven approaches" 
138 @image latex ocaf_image004.png "Topology driven versus reference-key driven approaches" 
139
140  Reference-keys can be created in two ways:   
141  
142   * At  programming time, by the application
143   * At runtime,  by the end-user of the application (providing that you include this capability  in the application)
144  
145   As an application developer, you generate reference-keys in order to give semantics to the data. 
146   For example, a function building a  prism may create three reference-keys: 
147   one for the base of the prism, a second  for the lateral faces and a third for the top face. 
148   This makes up a semantic  built-in the application's prism feature.
149   On the other hand, in a command  allowing the end-user to set a texture to a face he/she selects, 
150   you must create  a reference-key to the selected face 
151   if it has not previously been referenced in any feature 
152   (as in the case of one of the lateral faces of the prism).  
153  
154   When you create a reference-key to selected topological  elements (faces, edges or vertices), 
155   OCAF attaches to the reference-key  information defining the selected topology — the Naming attribute. 
156   For example,  it may be the faces to which a selected edge is common to. 
157   This information, as  well as information about the evolution of the topology at each modeling step 
158   (the modified, updated and deleted faces), is used by the naming algorithm to  maintain the topology 
159   attached to the reference-key. As such, on a  parametrized model, 
160   after modifying the value of a parameter, the reference-keys still address the appropriate faces, 
161   even if their geometry has  changed. 
162   Consequently, you change the size of the cube shown in the figure above, 
163   the user texture stay attached to the right face.  
164  
165   <b>Note</b> As Topological naming is based on the reference-key and attributes such as Naming 
166   (selection information) and Shape (topology evolution  information), 
167   OCAF is not coupled to the underlying modeling libraries. 
168   The  only modeling services required by OCAF are the following:  
169
170   * Each  algorithm must provide information about the evolution of the topology 
171    (the  list of faces modified, updated and deleted by the algorithm)
172   * Exploration  of the geometric model must be available 
173    (a 3D model is made of faces bounded  by close wires, 
174    themselves composed by a sequence of edges connected by their  vertices)
175  
176   Currently, OCAF uses the Open CASCADE Technology  modeling libraries.   
177  
178   To design an OCAF-based data model, the application  developer is encouraged to aggregate 
179   ready-to-use attributes instead of defining new attributes by inheriting from an abstract root class.  
180   There are two major advantages in using aggregation  rather than inheritance:
181   
182   * As you don't  implement data by defining new classes, the format of saved data 
183     provided with OCAF doesn't change; so you don't have to write the Save and Open functions
184   * The application can query the data at runtime if a particular attribute is  available
185   
186 **Summary**
187
188   * OCAF is  based on a uniform reference-key model in which:
189     * Reference-keys provide  persistent identification of data;  
190     * Data, including geometry, are  implemented as attributes attached to reference-keys;  
191     * Topological naming maintains the  selected geometry attached to reference-keys in parametrized models; 
192   * In many  applications, the data format provided with OCAF doesn't need to be extended;
193   * OCAF is not  coupled to the underlying modeling libraries.
194   
195   
196 @section occt_ocaf_3 The Data  Framework
197  
198 @subsection occt_ocaf_3_1 Data Structure
199  
200   The OCAF Data Framework is the Open CASCADE Technology  realization 
201   of the reference-key model in a tree structure. It offers a single environment where data from different application components can be handled. This allows exchanging and modifying data simply, consistently, with a maximum level of information and stable semantics.
202   
203
204 The building blocks of this approach are: 
205
206   * The tag
207   * The label
208   * The attribute
209
210 As it has been mentioned earlier, the first label in a framework is the root label of the tree. Each label has a tag expressed as an integer value, and a label is uniquely defined by an entry expressed as a list of tags from the root, 0:1:2:1, for example. 
211
212 Each label can have a list of attributes, which contain data, and several attributes can be attached to a label. Each attribute is identified by a GUID, and although a label may have several attributes attached to it, it must not have more than one attribute of a single GUID. 
213
214 The sub-labels of a label are called its children. Conversely, each label, which is not the root, has a father. Brother labels cannot share the same tag. 
215
216 The most important property is that a label’s entry is its persistent address in the data framework. 
217   
218 @image html /user_guides/ocaf/images/ocaf_image005.png "A simple framework model"
219 @image latex /user_guides/ocaf/images/ocaf_image005.png "A simple framework model"
220
221 In this image the circles contain tags of the corresponding labels.  The lists of tags are located under the circles. The root label always has a zero tag. 
222
223 The children of a root label are middle-level labels with tags 1 and 3. These labels are brothers. 
224
225 List of tags of the right-bottom label is "0:3:4": this label has tag 4, its father (with entry "0:3") has tag 3, father of father has tag 0 (the root label always has "0" entry). 
226
227 @subsection occt_ocaf_3_2 Examples of a Data Structure
228
229 Let's have a look at the example:
230   
231 @image html ocaf_wp_image007.png "The coffee machine"  
232 @image latex ocaf_wp_image007.png "The coffee machine"    
233   
234    In the image the application for designing coffee  machines first allocates 
235   a label for the machine unit. It then adds sub-labels  for the main features 
236   (glass coffee pot, water receptacle and filter) which it  refines as needed 
237   (handle and reservoir of the coffee pot and spout of the  reservoir). 
238   
239   You now attach technical data describing the handle — its geometry and color — 
240   and the reservoir — its geometry and material. 
241   Later on, you can  modify the handle's geometry without changing its color — 
242   both remain attached  to the same label.  
243   
244 @image html ocaf_wp_image005.png "The data structure of the coffee machine"  
245 @image latex ocaf_wp_image005.png "The data structure of the coffee machine"  
246  
247   The nesting of labels is key to OCAF. This allows a  label to have its own structure 
248   with its local addressing scheme which can be  reused in a more complex structure. 
249   Take, for example, the coffee machine.  Given that the coffee pot's handle has a label of tag [1], 
250   the entry for the handle in  the context of the coffee pot only (without the machine unit) is [0:1:1]. 
251   If you now model a coffee  machine with two coffee pots, one at the label [1], 
252   the second at the label [4] in the machine unit, 
253   the handle  of the first pot would have the entry [0:1:1:1] 
254   whereas the handle of the second pot would be [0:1:4:1]. 
255   This way, we avoid any  confusion between coffee pot handles.
256
257 Another example is the application for designing table lamps. The first label is allocated to the lamp unit. 
258
259 @image html /user_guides/ocaf/images/ocaf_image006.png
260 @image latex /user_guides/ocaf/images/ocaf_image006.png
261
262 The root label cannot have brother labels. Consequently, various lamps in the framework allocation correspond to the sub-labels of the root label. This allows avoiding any confusion between table lamps in the data framework. Different lamp parts have different material, color and other attributes, so a child label of the lamp with the specified tags is allocated for each sub-unit of the lamp: 
263
264   * a lamp-shade label with tag 1
265   * a bulb label with tag 2
266   * a stem label with tag 3
267
268 Label tags are chosen at will. They are only identifiers of the lamp parts. Now you can refine all units: by setting geometry, color, material and other information about the lamp or its parts to the specified label. This information is placed into special attributes of the label: the pure label contains no data -- it is only a key to access data. 
269
270 Remember that tags are private addresses without any meaning outside the data framework. It would, for instance, be an error to use part names as tags. These might change or be removed from production in next versions of the application, whereas the exact form of that part might be reused in your design, the part name could be integrated into the framework as an attribute. 
271
272 So, after the user changes the lamp design, only corresponding attributes are changed, but the label structure is maintained. The lamp shape must be recreated by new attribute values and attributes of the lamp shape must refer to a new shape. 
273
274 @image html /user_guides/ocaf/images/ocaf_image007.png
275 @image latex /user_guides/ocaf/images/ocaf_image007.png
276
277
278 The previous figure shows the table-lamps document structure: each child of the root label contains a lamp shape attribute and refers to the sub-labels, which contain some design information about corresponding sub-units. 
279
280 The data framework structure allows to create more complex structures: each lamp label sub-label may have children labels with more detailed information about parts of the table lamp and its components. 
281
282 Note that the root label can have attributes too, usually global attributes: the name of the document, for example. 
283
284 @subsection occt_ocaf_3_3 Tag
285
286 A tag is an integer, which identifies a label in two ways: 
287
288   * Relative identification
289   * Absolute identification.
290
291 In relative identification, a label’s tag has a meaning relative to the father label only. For a specific label, you might, for example, have four child labels identified by the tags 2, 7, 18, 100. In using relative identification, you ensure that you have a safe scope for setting attributes. 
292
293 In absolute identification, a label’s place in the data framework is specified unambiguously by a colon-separated list of tags of all the labels from the one in question to the root of the data framework. This list is called an entry. *TDF_Tool::TagList* allows retrieving the entry for a specific label. 
294
295 In both relative and absolute identification, it is important to remember that the value of an integer has no intrinsic semantics whatsoever. In other words, the natural sequence that integers suggest, i.e. 0, 1, 2, 3, 4 ... -- has no importance here. The integer value of a tag is simply a key. 
296
297 The tag can be created in two ways: 
298
299   * Random delivery
300   * User-defined delivery
301
302 As the names suggest, in random delivery, the tag value is generated by the system in a random manner. In user-defined delivery, you assign it by passing the tag as an argument to a method. 
303
304 @subsubsection occt_ocaf_3_3_1 Creating child labels using random delivery of tags
305
306 To append and return a new child label, you use *TDF_TagSource::NewChild*. In the example below, the argument *level2*, which is passed to *NewChild,* is a *TDF_Label*. 
307
308
309 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
310 TDF_Label child1 = TDF_TagSource::NewChild (level2); 
311 TDF_Label child2 = TDF_TagSource::NewChild (level2); 
312 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
313
314 @subsubsection occt_ocaf_3_3_2 Creation of a child label by user delivery from a tag
315
316 The other way to create a child label from a tag is by user delivery. In other words, you specify the tag, which you want your child label to have. 
317
318 To retrieve a child label from a tag which you have specified yourself, you need to use *TDF_Label::FindChild* and *TDF_Label::Tag* as in the example below. Here, the integer 3 designates the tag of the label you are interested in, and the Boolean false is the value for the argument *create*. When this argument is set to *false*, no new child label is created. 
319
320
321 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
322 TDF_Label achild = root.FindChild(3,Standard_False); 
323 if (!achild.IsNull()) { 
324 Standard_Integer tag = achild.Tag(); 
325
326 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
327
328 @subsection occt_ocaf_3_4 Label
329
330 The tag gives a persistent address to a label. The label -- the semantics of the tag -- is a place in the data framework where attributes, which contain data, are attached. The data framework is, in fact, a tree of labels with a root as the ultimate father label.
331
332 Label can not be deleted from the data framework, so, the structure of the data framework that has been created can not be removed while the document is opened. Hence any kind of reference to an existing label will be actual while an application is working with the document. 
333
334 @subsubsection occt_ocaf_3_4_1 Label creation
335
336 Labels can be created on any labels, compared with brother labels and retrieved. You can also find their depth in the data framework (depth of the root label is 0, depth of child labels of the root is 1 and so on), whether they have children or not, relative placement of labels, data framework of this label. The class *TDF_Label* offers the above services. 
337
338 @subsubsection occt_ocaf_3_4_2 Creating child labels
339
340 To create a new child label in the data framework using explicit delivery of tags, use *TDF_Label::FindChild*. 
341
342
343 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
344 //creating a label with tag 10 at Root 
345 TDF_Label lab1 = aDF->Root().FindChild(10); 
346
347 //creating labels 7 and 2 on label 10 
348 TDF_Label lab2 = lab1.FindChild(7); 
349
350 TDF_Label lab3 = lab1.FindChild(2); 
351 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
352 You could also use the same syntax but add the Boolean *true* as a value of the argument **create**. This ensures that a new child label will be created if none is found. Note that in the previous syntax, this was also the case since **create** is *true* by default. 
353
354
355 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
356 TDF_Label level1 = root.FindChild(3,Standard_True); 
357 TDF_Label level2 = level1.FindChild(1,Standard_True); 
358 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
359 @subsubsection occt_ocaf_3_4_3 Retrieving child labels
360
361 You can retrieve child labels of your current label by iteration on the first level in the scope of this label. 
362
363
364 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
365 TDF_Label current; 
366 // 
367 for (TDF_ChildIterator it1 (current,Standard_False); it1.More(); it1.Next()) { 
368 achild = it1.Value(); 
369 // 
370 // do something on a child (level 1) 
371 // 
372
373 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
374 You can also retrieve all child labels in every descendant generation of your current label by iteration on all levels in the scope of this label. 
375 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
376 for (TDF_ChildIterator itall (current,Standard_True); itall.More(); itall.Next()) { 
377 achild = itall.Value(); 
378 // 
379 // do something on a child (all levels) 
380 // 
381
382 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
383 Using *TDF_Tool::Entry* with *TDF_ChildIterator* you can retrieve the entries of your current label’s child labels as well. 
384
385  
386 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
387 void DumpChildren(const TDF_Label& aLabel) 
388
389   TDF_ChildIterator it; 
390   TCollection_AsciiString es; 
391   for (it.Initialize(aLabel,Standard_True); it.More(); it.Next()){ 
392     TDF_Tool::Entry(it.Value(),es); 
393     cout  <<  as.ToCString()  <<  endl; 
394   } 
395
396 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
397 @subsubsection occt_ocaf_3_4_4 Retrieving the father label
398
399 Retrieving the father label of a current label. 
400
401
402 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
403 TDF_Label father = achild.Father(); 
404 isroot = father.IsRoot(); 
405 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
406
407 @subsection occt_ocaf_3_5 Attribute
408
409 The label itself contains no data. All data of any type whatsoever -- application or non-application -- is contained in attributes. These are attached to labels, and there are different types for different types of data. OCAF provides many ready-to-use standard attributes such as integer, real, constraint, axis and plane. There are also attributes for topological naming, functions and visualization. Each type of attribute is identified by a GUID. 
410
411 The advantage of OCAF is that all of the above attribute types are handled in the same way. Whatever the attribute type is, you can create new instances of them, retrieve them, attach them to and remove them from labels, "forget" and "remember" the attributes of a particular label. 
412
413 @subsubsection occt_ocaf_3_5_1 Retrieving an attribute from a label
414
415 To retrieve an attribute from a label, you use *TDF_Label::FindAttribute*. In the example below, the GUID for integer attributes, and *INT*, a handle to an attribute are passed as arguments to *FindAttribute* for the current label. 
416
417
418 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
419 if(current.FindAttribute(TDataStd_Integer::GetID(),INT)) 
420
421   // the attribute is found 
422
423 else 
424
425   // the attribute is not found 
426
427 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
428 @subsubsection occt_ocaf_3_5_2 Identifying an attribute using a GUID
429
430 You can create a new instance of an attribute and retrieve its GUID. In the example below, a new integer attribute is created, and its GUID is passed to the variable *guid* by the method ID inherited from *TDF_Attribute*. 
431
432
433 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
434 Handle(TDataStd_Integer) INT = new TDataStd_Integer(); 
435 Standard_GUID guid = INT->ID(); 
436 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
437
438 @subsubsection occt_ocaf_3_5_3 Attaching an attribute to a label
439
440 To attach an attribute to a label, you use *TDF_Label::Add*. Repetition of this syntax raises an error message because there is already an attribute with the same GUID attached to the current label. 
441
442 *TDF_Attribute::Label* for *INT* then returns the label *attach* to which *INT* is attached. 
443
444
445 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
446 current.Add (INT); // INT is now attached to current 
447 current.Add (INT); // causes failure 
448 TDF_Label attach = INT->Label(); 
449 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
450 @subsubsection occt_ocaf_3_5_4 Testing the attachment to a label
451
452 You can test whether an attribute is attached to a label or not by using *TDF_Attribute::IsA* with the GUID of the attribute as an argument. In the example below, you test whether the current label has an integer attribute, and then, if that is so, how many attributes are attached to it. *TDataStd_Integer::GetID* provides the GUID argument needed by the method IsAttribute. 
453
454 *TDF_Attribute::HasAttribute* tests whether there is an attached attribute, and *TDF_Tool::NbAttributes* returns the number of attributes attached to the label in question, e.g. *current*. 
455
456
457 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
458 // Testing of attribute attachment 
459 // 
460 if (current.IsA(TDataStd_Integer::GetID())) { 
461 // the label has an Integer attribute attached 
462
463 if (current.HasAttribute()) { 
464 // the label has at least one attribute attached 
465 Standard_Integer nbatt = current.NbAttributes(); 
466 // the label has nbatt attributes attached 
467
468 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
469 @subsubsection occt_ocaf_3_5_5 Removing an attribute from a label
470
471 To remove an attribute from a label, you use *TDF_Label::Forget* with the GUID of the deleted attribute. To remove all attributes of a label, *TDF_Label::ForgetAll*. 
472
473
474 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
475 current.Forget(TDataStd_Integer::GetID()); 
476 // integer attribute is now not attached to current label 
477 current.ForgetAll(); 
478 // current has now 0 attributes attached 
479 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
480 @subsubsection occt_ocaf_3_5_6 Specific attribute creation
481
482 If the set of existing and ready to use attributes implementing standard data types does  not cover the needs of a specific data presentation task, the user can build his own data type and the corresponding new specific attribute implementing this new data type. 
483
484 There are two ways to implement a new data type: create a new attribute (standard approach), or use the notion of User Attribute by means of a combination of standard attributes  (alternative way) 
485
486 In order to create a new attribute in the standard way do the following: 
487 * Create a class inherited from *TDF_Attribute* and implement all purely virtual and necessary virtual methods:
488         + **ID()** -- returns a unique GUID of a given attribute 
489         + **Restore(attribute)** -- sets fields of this attribute equal to the fields of a given attribute of the same type 
490         + **Paste(attribute, relocation_table)** -- sets fields of a given attribute equal to the field values of this attribute ; if the attribute has references to some objects of the data framework  and relocation_table has this element, then the given attribute must also refer to this object . 
491         + **NewEmpty()** -- returns a new attribute of this class with empty fields 
492         + **Dump(stream)** --  outputs information about a given attribute to a given stream debug (usually outputs an attribute of type string only) 
493 * Create the persistence classes for this attribute according to the file format chosen for the document (see below).
494
495 Methods *NewEmpty, Restore* and *Paste* are used for the common transactions mechanism (Undo/Redo commands). If you don’t need this attribute to react to undo/redo commands, you can write only stubs of these methods, else you must call the Backup method of the *TDF_Attribute* class every time attribute fields are changed. 
496
497 If you use a standard file format and you want your new attributes to be stored during document saving and retrieved to the data framework whenever a document is opened, you must do the following: 
498
499   1. If you place an attribute to a new package, it is desirable (although not mandatory) if your package name starts with letter "T" (transient), for example: attribute *TMyAttributePackage_MyAttribute* in the package *TMyAttributePackage*.
500   2. Create a new package with name "P[package name]" (for example *PMyAttributePackage*) with class *PMyAttributePackage_MyAttribute* inside. The new class inherits the *PDF_Attribute* class and contains fields of attributes, which must be saved or retrieved ("P" -- persistent).
501   3. Create a new package with name "M[package name]" (for example *MMyAttributePackage*) with classes *MMyAttributePackage_MyAttributeRetrievalDriver* and *MMyAttributePackage_MyAttributeStorageDriver* inside. The new classes inherit *MDF_ARDriver* and *MDF_ASDriver* classes respectively and contain the translation functionality: from T... attribute to P... and vice versa (M -- middle) (see the realization of the standard attributes).
502   4. M... package must contain *AddStorageDrivers(aDriverSeq : ASDriverHSequence* from MDF) and *AddRetrievalDrivers(aDriverSeq : ASDriverHSequence* from MDF) methods, which append to the given sequence  of drivers *aDriverSeq*, which is a sequence of all new attribute drivers (see the previous point) used for the storage/retrieval of attributes. 
503   5 Use the standard schema (*StdSchema* unit) or create a new one to add your P-package and compile it. 
504
505 If you use the XML format, do the following: 
506   1. Create a new package with the name Xml[package name] (for example *XmlMyAttributePackage*) containing  class *XmlMyAttributePackage_MyAttributeDriver*. The new class inherits *XmlMDF_ADriver* class and contains the translation functionality: from transient to persistent and vice versa (see the realization of the standard attributes in the packages *XmlMDataStd*, for example). Add package method AddDrivers which adds your class to a driver table (see below).
507   2. Create a new package (or do it in the current one) with two package methods: 
508           * *Factory*, which loads the document storage and retrieval drivers; and 
509           * *AttributeDrivers*, which calls the methods AddDrivers for all packages responsible for persistence of the document.
510   3. Create a plug-in implemented as an executable (see example *XmlPlugin*). It calls a macro PLUGIN with the package name where you implemented the method Factory.
511 If you use the binary format, do the following: 
512   1. Create a new package with name <i> Bin[package name] </i> (for example *BinMyAttributePackage*) containing a class *BinMyAttributePackage_MyAttributeDriver*. The new class inherits *BinMDF_ADriver* class and contains the translation functionality: from transient to persistent and vice versa (see the realization of the standard attributes in the packages *BinMDataStd*, for example). Add package method *AddDrivers*, which adds your class to a driver table.
513   2. Create a new package (or do it in the current one) with two package methods: 
514           * Factory, which loads the document storage and retrieval drivers; and 
515           * AttributeDrivers, which calls the methods AddDrivers for all packages responsible for persistence of the document.
516   3. Create a plug-in implemented as an executable (see example *BinPlugin*). It calls a macro PLUGIN with the package name where you implemented the method Factory.
517 See @ref occt_ocaf_4_3_3 "Saving the document" and @ref occt_ocaf_4_3_4 "Opening the document from a file" for the description of document save/open mechanisms. 
518
519 If you decided to use the alternative way (create a new attribute by means of *UAttribute* and a combination of other standard attributes), do the following: 
520   1. Set a *TDataStd_UAttribute* with a unique GUID attached to a label. This attribute defines the semantics of the data type (identifies the data type).
521   2. Create child labels and allocate all necessary data through standard attributes at the child labels.
522   3. Define an interface class for access to the data of the child labels.
523
524 Choosing the alternative way of implementation of new data types allows to forget about creating persistence classes for your new data type. Standard persistence classes will be used instead. Besides, this way allows separating the data and the methods for access to the data (interfaces). It can be used for rapid development in all cases when requirements to application performance are not very high. 
525
526 Let’s study the implementation of the same data type in both ways by the example of transformation represented by *gp_Trsf* class. The class *gp_Trsf* defines the transformation according to the type (*gp_TrsfForm*) and a set of parameters of the particular type of transformation (two points or a vector for translation, an axis and an angle for rotation, and so on). 
527
528 1. The first way: creation of a new attribute. The implementation of the transformation by creation of a new attribute is represented in the @ref occt_ocaf_11 "Samples". 
529
530 2. The second way: creation of a new data type by means of combination of standard attributes. Depending on the type of transformation it may be kept in data framework by different standard attributes. For example, a translation is defined by two points. Therefore the data tree for translation looks like this: 
531   * Type of transformation <i>(gp_Translation)</i> as *TDataStd_Integer*;
532   * First point as *TDataStd_RealArray* (three values: X1, Y1 and Z1);
533   * Second point as *TDataStd_RealArray* (three values: X2, Y2 and Z2).
534
535 @image html /user_guides/ocaf/images/ocaf_image010.png "Data tree for translation"
536 @image latex /user_guides/ocaf/images/ocaf_image010.png "Data tree for translation"
537
538 If the type of transformation is changed to rotation, the data tree looks like this: 
539   * Type of transformation <i>(gp_Rotation)</i> as *TDataStd_Integer*;
540   * Point of axis of rotation as *TDataStd_RealArray* (three values: X, Y and Z);
541   * Axis of rotation as *TDataStd_RealArray* (three values: DX, DY and DZ);
542   * Angle of rotation as *TDataStd_Real*.
543
544 @image html /user_guides/ocaf/images/ocaf_image011.png "Data tree for rotation"
545 @image latex /user_guides/ocaf/images/ocaf_image011.png "Data tree for rotation"
546
547 The attribute *TDataStd_UAttribute* with the chosen unique GUID identifies the data type. The interface class initialized by the label of this attribute allows access to the data container (type of transformation and the data of transformation according to the type). 
548   
549 @subsection occt_ocaf_3_6 Compound documents
550  
551   As the identification of data is persistent, one document can reference data contained in another document, 
552   the referencing and  referenced documents being saved in two separate files.  
553  
554   Lets look at the coffee machine application again. The  coffee pot can be placed in one document. 
555   The coffee machine document then  includes an *occurrence* — a positioned copy — of the coffee pot. 
556   This occurrence is defined by an XLink attribute (the external Link) 
557   which references the coffee pot of the first document 
558   (the XLink contains the relative path of the coffee pot document and the entry of the coffee pot data [0:1] ).  
559
560 @image html ocaf_wp_image006.png "The coffee machine compound document"
561 @image latex ocaf_wp_image006.png "The coffee machine compound document"
562  
563   In this context, the end-user of the coffee machine application can open the coffee pot document, 
564   modify the geometry of, for  example, the reservoir, and overwrite the document without worrying 
565   about the impact of the modification in the coffee machine document. 
566   To deal with this  situation, OCAF provides a service which allows the application to check 
567   whether a document is up-to-date. This service is based on a modification counter included in each document: 
568   when an external link is created, a copy of  the referenced document counter is associated to the XLink 
569   in the referencing  document. Providing that each modification of the referenced document increments its own counter,   
570   we can detect that the referencing document has to  be updated by comparing the two counters 
571   (an update function importing the data  referenced by an XLink into the referencing document is also provided).  
572  
573  @subsection occt_ocaf_3_7 Transaction mechanism
574  
575   The Data Framework also provides a transaction mechanism inspired from database management systems: 
576   the data are modified within a transaction which is terminated either by a Commit 
577   if the modifications are validated  or by an Abort if the modifications are abandoned — 
578   the data are then restored  to the state it was in prior to the transaction. 
579   This mechanism is extremely useful for:
580
581   * Securing  editing operations (if an error occurs, the transaction is abandoned and the  structure retains its integrity)
582   * Simplifying  the implementation of the **Cancel** function (when the end-user begins a command, 
583   the application may launch a transaction and operate directly in the data structure; 
584   abandoning the action causes the transaction to Abort)
585   * Executing  **Undo** (at commit time, the modifications are recorded in order to be able to  restore the data to their previous state)
586  
587   The transaction mechanism simply manages a  backup copy of attributes. 
588   During a transaction, attributes are copied before  their first modification. 
589   If the transaction is validated, the copy is  destroyed. 
590   If the transaction is abandoned, the attribute is restored to its initial value 
591   (when attributes are added or deleted, the operation is simply  reversed).
592
593   Transactions are document-centered, that is, the application starts a transaction on a document. 
594   So, modifying a referenced  document and updating one of its referencing documents requires 
595   two transactions, even if both operations are done in the same working session.
596
597   
598 @section occt_ocaf_4_ Standard Document Services
599
600 @subsection occt_ocaf_4_1 Overview
601
602 Standard documents offer ready-to-use documents containing a TDF-based data framework. Each document can contain only one framework. 
603
604 The documents themselves are contained in the instantiation of a class inheriting from *TDocStd_Application*. This application manages the creation, storage and retrieval of documents. 
605
606 You can implement undo and redo in your document, and refer from the data framework of one document to that of another one. This is done by means of external link attributes, which store the path and the entry of external links. 
607
608 To sum up, standard documents alone provide access to the data framework. They also allow you to: 
609
610   * Update external links
611   * Manage the saving and opening of data
612   * Manage the undo/redo functionality.
613
614
615 @subsection occt_ocaf_4_2 The Application
616
617 As a container for your data framework, you need a document, and your document must be contained in your application. This application will be a class inheriting from *TDocStd_Application*. 
618
619 @subsubsection occt_ocaf_4_2_1 Creating an application
620
621 To create an application, use the following syntax. 
622
623 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
624 Handle(TDocStd_Application) app 
625 = new MyApplication_Application (); 
626 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
627 Note that *MyApplication_Application* is a class, which you have to create and which will inherit from *TDocStd_Application*. 
628
629 @subsubsection occt_ocaf_4_2_2 Creating a new document
630
631 To the application which you declared in the previous example (4.2.1), you must add the document *doc* as an argument of *TDocStd_Application::NewDocument*. 
632
633 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
634 Handle(TDocStd_Document) doc; 
635 app->NewDocument("NewDocumentFormat", doc); 
636 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
637
638 @subsubsection occt_ocaf_4_2_3 Retrieving the application to which the document belongs
639
640 To retrieve the application containing your document, you use the syntax below. 
641
642 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
643 app = Handle(TDocStd_Application)::DownCast 
644 (doc->Application()); 
645 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
646 @subsection occt_ocaf_4_3 The Document
647
648 The document contains your data framework, and allows you to retrieve this framework, recover its main label, save it in a file, and open or close this file. 
649
650 @subsubsection occt_ocaf_4_3_1 Accessing the main label of the framework
651
652 To access the main label in the data framework, you use *TDocStd_Document::Main* as in the example below. The main label is the first child of the root label in the data framework, and has the entry 0:1. 
653
654 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
655 TDF_Label label = doc->Main(); 
656 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
657 @subsubsection occt_ocaf_4_3_2 Retrieving the document from a label in its framework
658
659 To retrieve the document from a label in its data framework, you use *TDocStd_Document::Get* as in the example below. The argument *label* passed to this method is an instantiation of *TDF_Label*. 
660 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
661 doc = TDocStd_Document::Get(label); 
662 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
663
664 @subsubsection occt_ocaf_4_3_3 Saving the document
665
666 If in your document you use only standard attributes (from the packages *TDF, TDataStd, TNaming, TFunction, TPrsStd* and *TDocStd*), you just do the following steps: 
667
668 * In your application class (which inherits class *TDocStd_Application*) implement two methods:
669         + Formats (TColStd_SequenceOfExtendedString& theFormats), which append to a given sequence <i>\<theFormats\></i> your document format string, for example, "NewDocumentFormat" -- this string is also set in the document creation command 
670         + ResourcesName(), which returns a string with a name of resources file (this file contains a description about the extension of the document, storage/retrieval drivers GUIDs...), for example, "NewFormat" 
671 * Create the resource file (with name, for example, "NewFormat") with the following strings:
672
673 ~~~~~
674 formatlist:NewDocumentFormat 
675 NewDocumentFormat: New Document Format Version 1.0 
676 NewDocumentFormat.FileExtension: ndf 
677 NewDocumentFormat.StoragePlugin: bd696000-5b34-11d1-b5ba-00a0c9064368 
678 NewDocumentFormat.RetrievalPlugin: bd696001-5b34-11d1-b5ba-00a0c9064368 
679 NewDocumentFormatSchema: bd696002-5b34-11d1-b5ba-00a0c9064368 
680 NewDocumentFormat.AttributeStoragePlugin:57b0b826-d931-11d1-b5da-00a0c9064368 
681 NewDocumentFormat.AttributeRetrievalPlugin:57b0b827-d931-11d1-b5da-00a0c9064368 
682 ~~~~~
683
684 * Create the resource file "Plugin" with GUIDs and corresponding plugin libraries, which looks like this:
685
686 **Example** 
687 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
688 ! Description of available plugins 
689 ! ************ 
690  
691 b148e300-5740-11d1-a904-080036aaa103.Location: libFWOSPlugin.so 
692
693 ! standard document drivers plugin 
694
695 bd696000-5b34-11d1-b5ba-00a0c9064368.Location: libPAppStdPlugin.so 
696 bd696001-5b34-11d1-b5ba-00a0c9064368.Location: libPAppStdPlugin.so 
697
698 ! standard schema plugin 
699
700 bd696002-5b34-11d1-b5ba-00a0c9064368.Location: libPAppStdPlugin.so 
701
702 ! standard attribute drivers plugin 
703
704 57b0b826-d931-11d1-b5da-00a0c9064368.Location: libPAppStdPlugin.so 
705 57b0b827-d931-11d1-b5da-00a0c9064368.Location: libPAppStdPlugin.so 
706 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
707
708 In order to set the paths for these files it is necessary to set the environments: *CSF_PluginDefaults* and *CSF_NewFormatDefaults*. For example, set the files in the directory *MyApplicationPath/MyResources*: 
709
710 ~~~~~
711 setenv CSF_PluginDefaults MyApplicationPath/MyResources 
712 setenv CSF_NewFormatDefaults MyApplicationPath/MyResources 
713 ~~~~~
714
715 Once these steps are taken you may run your application, create documents and Save/Open them. These resource files already exist in the OCAF (format "Standard"). 
716
717 If you use your specific attributes from packages, for example, <i>P-, M-</i> and *TMyAttributePackage*  (see @ref occt_ocaf_3_4_6  "Specific attribute creation") you must take some additional steps for the new plugin implementation: 
718
719 1. Add our *P* package to the standard schema. You can get an already existing (in Open CASCADE Technology sources) schema from *StdSchema* unit and add your package string to the cdl-file: package  *PMyAttributePackage*.
720 2. The next step consists in the implementation of an executable, which will connect our documents to our application and open/save them. Copy the package *PAppStdPlugin* and change its name to *MyTheBestApplicationPlugin*. In the *PLUGIN* macros type the name of your factory, which will be defined at the next step.
721 3. *Factory* is a method, which returns drivers (standard drivers and our defined drivers from the *M* package) by a GUID. Copy the package to the location, where the standard factory is defined (it is PAppStd in the OCAF sources). Change its name to *MyTheBestSchemaLocation*. The *Factory()* method of the *PappStd* package checks the GUID set as its argument and returns the corresponding table of drivers. Set two new GUIDs for your determined storage and retrieval drivers. Append two *if* declarations inside the *Factory()* method, which should check whether the set GUID coincides with GUIDs defined by the *Factory()* method as far as our storage and retrieval drivers are concerned. If the GUID coincides with one of them, the method should return a table of storage or retrieval drivers respectively.
722 4. Recompile all and add the strings with GUIDs  to the *Plugin* file in accordance with your plugin library GUID.
723
724 @subsubsection occt_ocaf_4_3_4 Opening the document from a file
725
726 To open the document from a file where it has been previously saved, you can use *TDocStd_Application::Open* as in the example below. The arguments are the path of the file and the document saved in this file. 
727
728 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
729 app->Open("/tmp/example.caf", doc); 
730 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
731
732 @subsubsection occt_ocaf_4_3_5 Cutting, copying and pasting inside a document
733
734 To cut, copy and paste inside a document, use the class *TDF_CopyLabel*.
735
736 In fact, you must define a *Label*, which contains the temporary value of a cut or 
737 copy operation (say, in <i> Lab_Clipboard</i>). You must also define two other labels:
738
739 * The data container (e.g. <i> Lab_source</i>)
740 * The destination of the copy (e.g. <i> Lab_ Target</i> )
741
742 ~~~~
743     Copy = copy (Lab_Source => Lab_Clipboard)
744     Cut = copy + Lab_Source.ForgetAll() // command clear the contents of LabelSource.
745     Paste = copy (Lab_Clipboard => Lab_target)
746 ~~~~
747
748 So we need a tool to copy all (or a part) of the content of a label and its sub-label,
749 to another place defined by a label.
750
751 ~~~~
752     TDF_CopyLabel aCopy;
753     TDF_IDFilter aFilter (Standard_False);
754
755     //Don't copy TDataStd_TreeNode attribute
756
757      aFilter.Ignore(TDataStd_TreeNode::GetDefaultTreeID());
758      aCopy.Load(aSource, aTarget); aCopy.UseFilter(aFilter); aCopy.Perform();
759
760     // copy the data structure to clipboard 
761
762     return aCopy.IsDone(); }
763 ~~~~
764
765 The filter is used to forbid copying a specified type of attribute. 
766
767 You can also have a look at the class *TDF_Closure*, which can be useful to determine the dependencies of the part you want to cut from the document.
768
769 @subsection occt_ocaf_4_4 External Links
770
771 External links refer from one document to another. They allow you to update the copy of data  framework later on. 
772
773 @image html /user_guides/ocaf/images/ocaf_image012.png  "External links between documents"
774 @image latex /user_guides/ocaf/images/ocaf_image012.png  "External links between documents"
775
776 Note that documents can be copied with or without a possibility of updating an external link. 
777
778 @subsubsection occt_ocaf_4_4_1 Copying the document
779
780 #### With the possibility of updating it later
781
782 To copy a document with a possibility of updating it later, you use *TDocStd_XLinkTool::CopyWithLink*. 
783
784 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
785 Handle(TDocStd_Document) doc1; 
786 Handle(TDocStd_Document) doc2; 
787
788 TDF_Label source = doc1->GetData()->Root(); 
789 TDF_Label target = doc2->GetData()->Root(); 
790 TDocStd_XLinkTool XLinkTool; 
791
792 XLinkTool.CopyWithLink(target,source); 
793 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
794
795 Now the target document has a copy of the source document. The copy also has a link in order to update the content of the copy if the original changes. 
796
797 In the example below, something has changed in the source document. As a result, you need to update the copy in the target document. This copy is passed to *TDocStd_XLinkTool::UpdateLink* as the argument *target*. 
798
799 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
800 XLinkTool.UpdateLink(target); 
801 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
802
803 #### Without any link between the copy and the original
804
805 You can also create a copy of the document with no link between the original and the copy. The syntax to use this option is *TDocStd_XLinkTool::Copy*. The copied document is again represented by the argument *target*, and the original -- by *source.* 
806
807 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
808 XLinkTool.Copy(target, source); 
809
810 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
811
812
813 @section occt_ocaf_5 OCAF Shape Attributes
814 @subsection occt_ocaf_5_1 Overview
815
816 A topological attribute can be seen as a hook into the topological structure. It is possible to attach data to define references to it.
817
818 OCAF shape attributes are used for topology objects and their evolution access. All topological objects are stored in one *TNaming_UsedShapes* attribute at the root label of the data framework. This attribute contains a map with all topological shapes used in a given document. 
819
820 The user can add the *TNaming_NamedShape* attribute to other labels. This attribute contains references (hooks) to shapes from the *TNaming_UsedShapes* attribute and an evolution of these shapes. The *TNaming_NamedShape* attribute contains a set of pairs of hooks: to the *Old* shape and to a *New* shape (see the following figure). It allows not only to get the topological shapes by the labels, but also to trace the evolution of the shapes and to correctly update dependent shapes by the changed one. 
821
822 If a shape is newly created, then the old shape of a corresponding named shape is an empty shape. If a shape is deleted, then the new shape in this named shape is empty. 
823
824 @image html /user_guides/ocaf/images/ocaf_image013.png
825 @image latex /user_guides/ocaf/images/ocaf_image013.png
826
827 @subsection occt_ocaf_5_2 Shape attributes in data framework. 
828
829 Different algorithms may dispose sub-shapes of the result shape at the individual labels depending on whether it is necessary to do so: 
830
831 * If a sub-shape must have some extra attributes (material of each face or color of each edge). In this case a specific sub-shape is placed to a separate label (usually to a sub-label of the result shape label) with all attributes of this sub-shape.
832 * If the topological naming algorithm is needed, a necessary and sufficient set of sub-shapes is placed to child labels of the result shape label. As usual, for a basic solid and closed shells, all faces of the shape are disposed.
833
834 *TNaming_NamedShape* may contain a few pairs of hooks with the same evolution. In this case the topology shape, which belongs to the named shape is a compound of new shapes. 
835
836 Consider the following example. Two boxes (solids) are fused into one solid (the result one). Initially each box was placed to the result label as a named shape, which has evolution PRIMITIVE and refers to the corresponding shape of the *TNaming_UsedShapes* map. The box result label has a material attribute and six child labels containing named shapes of Box faces. 
837
838 @image html /user_guides/ocaf/images/ocaf_image014.png "Resulting box"
839 @image latex /user_guides/ocaf/images/ocaf_image014.png "Resulting box"
840
841 After the fuse operation a modified result is placed to a separate label as a named shape, which refers to the old shape (one of the boxes) and to the new shape resulting from the fuse operation, and has evolution MODIFY (see the following figure). 
842
843 Named shapes, which contain information about modified faces, belong to the fuse result sub-labels: 
844 * sub-label with tag 1 -- modified faces from box 1, 
845 * sub-label with tag 2 -- modified faces from box 2. 
846
847 @image html /user_guides/ocaf/images/ocaf_image015.png
848 @image latex /user_guides/ocaf/images/ocaf_image015.png
849
850 This is necessary and sufficient information for the functionality of the right naming mechanism: any sub-shape of the result can be identified unambiguously by name type and set of labels, which contain named shapes: 
851
852   * face F1’ as a modification of face F11  
853   * face F1’’ as generation of face F12 
854   * edges as an intersection of two contiguous faces
855   * vertices as an intersection of three contiguous faces
856
857 After any modification of source boxes the application must automatically rebuild the naming entities: recompute the named shapes of the boxes (solids and faces) and fuse the resulting named shapes (solids and faces) that reference to the new named shapes. 
858
859 @subsection occt_ocaf_5_3 Registering shapes and their evolution
860
861 When using TNaming_NamedShape to create attributes, the following fields of an attribute are filled: 
862
863 * A list of shapes called the "old" and the "new" shapes A new shape is recomputed as the value of the named shape. The meaning of this pair depends on the type of evolution.
864 * The type of evolution, which is a term of the *TNaming_Evolution* enumeration used for the selected shapes that are placed to the separate label: 
865         * PRIMITIVE -- newly created topology, with no previous history;
866         * GENERATED -- as usual, this evolution of a  named shape means, that the new shape is created from a low-level old shape ( a prism face from an edge, for example );
867         * MODIFY -- the new shape is a modified old shape;
868         * DELETE -- the new shape is empty; the named shape with this evolution just indicates that the old shape topology is deleted from the model;
869         * SELECTED -- a named shape with this evolution has no effect on the history of the topology.
870
871 Only pairs of shapes with equal evolution can be stored in one named shape. 
872
873 @subsection occt_ocaf_5_4 Using naming resources
874
875 The class *TNaming_Builder* allows creating a named shape attribute. It has a label of a future attribute as an argument of the constructor. Respective methods are used for the evolution and setting of shape pairs. If for the same TNaming_Builder object a lot of pairs of shapes with the same evolution are given, then these pairs would be placed in the resulting named shape. After the creation of a new object of the TNaming_Builder class, an empty named shape is created at the given label. 
876
877 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
878 // a new empty named shape is created at "label" 
879 TNaming_Builder builder(label); 
880 // set a pair of shapes with evolution GENERATED 
881 builder.Generated(oldshape1,newshape1); 
882 // set another pair of shapes with the same evolution 
883 builder.Generated(oldshape2,newshape2); 
884 // get the result - TNaming_NamedShape attribute 
885 Handle(TNaming_NamedShape) ns = builder.NamedShape(); 
886 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
887
888 @subsection occt_ocaf_5_5 Reading the contents of a named shape attribute
889
890 You can use the method <i>TNaming_NamedShape::Evolution()</i> to get the evolution of this named shape and the method <i>TNaming_NamedShape::Get()</i> to get a compound of new shapes of all pairs of this named shape.
891   
892 More detailed information about the contents of the named shape or about the modification history of a topology can be obtained with the following: 
893 * *TNaming_Tool* provides a common high-level functionality for access to the named shapes contents:
894         * The method <i>GetShape(Handle(TNaming_NamedShape)) </i>  returns a compound of new shapes of the given named shape;
895         * The method <i>CurrentShape(Handle(TNaming_NamedShape))</i>  returns a compound of the shapes, which are latest versions of the shapes from the given named shape;
896         * The method <i>NamedShape(TopoDS_Shape,TDF_Label) </i> returns a named shape, which contains a given shape as a new shape. A given label is any label from the data framework -- it just gives access to it.
897 * *TNaming_Iterator* gives access to the named shape and hooks pairs.
898
899 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
900 // create an iterator for a named shape 
901 TNaming_Iterator iter(namedshape); 
902 // iterate while some pairs are not iterated 
903 while(iter.More()) { 
904 // get the new shape from the current pair 
905 TopoDS_Shape newshape = iter.NewShape(); 
906 // get the old shape from the current pair 
907 TopoDS_Shape oldshape = iter.OldShape(); 
908 // do something... 
909
910 // go to the next pair 
911 iter.Next(); 
912
913 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
914
915
916 @subsection occt_ocaf_5_6 Topological naming
917
918 The Topological Naming mechanism is based on 3 components:
919 * History of the used modeling operation algorithm;
920 * Registering of the built result in Data Framework (i.e. loading the necessary elements of the extracted history in OCAF document);
921 * Selection / Recomputation of a "selected" sub-shape of the algorithm result.
922
923 To get the expected result the work of the three components should be synchronized and the rules of each component should be respected.
924
925 @subsubsection occt_ocaf_5_6_1 Algorithm history
926
927 The "correct" history of a used modeling operation serves the basis of naming mechanism. It should be provided by the algorithm supporting the operation. The history content depends on the type of the topological result. The purpose of the history is to provide all entities for consistent and correct work of the Selection / Recomputation mechanism. The table below presents expected types of entities depending on the result type.
928
929 | Result type | Type of sub-shapes to be returned by history of algorithm | Comments |
930 | :---------- | :-------------------------------------------------------- | :------- |
931 | Solid or closed shell | Faces | All faces |
932 | Open shell or single face | Faces and edges of opened boundaries only | All faces plus all edges of opened boundaries |
933 | Closed wire | Edges | All edges |
934 | Opened wire | Edges and ending vertexes | All edges plus ending vertexes of the wire |
935 | Edge | Vertexes |     Two vertexes are expected |
936 | Compound or CompSolid | To be used consequentially the above declared rule applied to all sub-shapes of the first level | Compound/CompSolid to be explored level by level until any the mentioned above types will be met | 
937
938 The history should return (and track) only elementary types of sub-shapes, i.e. Faces, Edges and Vertexes, while other so-called aggregation types: Compounds, Shells, Wires, are calculated by Selection mechanism automatically.
939
940 There are some simple exceptions for several cases. For example, if the Result contains a seam edge -- in conical, cylindrical or spherical surfaces -- this seam edge should be tracked by the history and in addition should be defined before the types. All degenerated entities should be filtered and excluded from consideration.
941
942 @subsubsection occt_ocaf_5_6_2 Loading history in data framework
943
944 All elements returned by the used algorithm according to the aforementioned rules should be put in the Data Framework (or OCAF document in other words) consequently in linear order under the so-called **Result Label**. 
945
946 The "Result Label" is *TDF_label* used to keep the algorithm result *Shape* from *TopoDS* in *NamedShape* attribute. During loading sub-shapes of the result in Data Framework should be used the rules of chapter @ref occt_ocaf_5_3.  These rules are also applicable for loading the main shape, i.e. the resulting shape produced by the modeling algorithm.
947
948 @subsubsection occt_ocaf_5_6_3 Selection / re-computation mechanism
949
950 When the Data Framework is filled with all impacted entities (including the data structures resulting from the current modeling operation and the data structures resulting from the previous modeling operations, on which the current operation depends) any sub-shape of the current result can be **selected**, i.e. the corresponding new naming data structures, which support this functionality, can be produced and kept in the Data Framework.
951
952 One of the user interfaces for topological naming is the class *TNaming_Selector*. It implements the above mentioned sub-shape "selection" functionality as an additional one. I.e. it can be used for:
953 * Storing the selected shape on a label -- its **Selection**;
954 * Accessing the named shape -- check the kept value of the shape
955 * Update of this naming -- recomputation of an earlier selected shape.
956
957 The selector places a new named shape with evolution **SELECTED** to the given label. The selector creates a **name** of the selected shape, which is a unique description (data structure) of how to find the selected topology using as resources:
958 * the given context shape, i.e. the main shape kept on **Result Label**, which contains a selected sub-shape, 
959 * its evolution and
960 * naming structure.
961
962 After any modification of a context shape and update of the corresponding naming structure, it is necessary to call method *TNaming_Selector::Solve*. If the naming structure, i.e. the above mentioned **name**, is correct, the selector automatically updates the selected sub-shape in the corresponding named shape, else it fails.
963
964 @subsection occt_ocaf_5_7 Exploring shape evolution
965
966 The class *TNaming_Tool* provides a toolkit to read current data contained in the attribute. 
967
968 If you need to create a topological attribute for existing data, use the method *NamedShape*. 
969
970 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
971 class MyPkg_MyClass 
972
973 public: Standard_Boolean SameEdge (const Handle(CafTest_Line)& L1, const Handle(CafTest_Line)& L2); 
974 }; 
975
976 Standard_Boolean CafTest_MyClass::SameEdge (const Handle(CafTest_Line)& L1, const Handle(CafTest_Line)& L2) 
977
978   Handle(TNaming_NamedShape) NS1 = L1->NamedShape(); 
979   Handle(TNaming_NamedShape) NS2 = L2->NamedShape(); 
980   return BRepTools::Compare(NS1,NS2); 
981
982 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
983
984
985 @subsection occt_ocaf_5_8 Example of topological naming usage
986
987 **Topological naming** is a mechanism of Open CASCADE aimed to keep reference to the selected shape. If, for example, we select a vertex of a solid shape and “ask” the topological naming to keep reference to this vertex, it will refer to the vertex whatever happens with the shape (translations, scaling, fusion with another shape, etc.).
988
989 Let us consider an example: imagine a wooden plate. The job is to drive several nails in it:
990
991 @figure{/user_guides/ocaf/images/ocaf_image020.png, "A nail driven in a wooden plate"}
992
993 There may be several nails with different size and position. A **Hammer** should push each **Nail** exactly in the center point of the top surface. For this the user does the following:
994 *       Makes several Nails of different height and diameter (according to the need),
995 *       Chooses (selects) the upper surface of each Nail for the Hammer.
996
997 The job is done. The application should do the rest -- the Hammer calculates a center point for each selected surface of the Nail and “strikes” each Nail driving it into the wooden plate.
998
999 What happens if the user changes the position of some Nails? How will the Hammer know about it? It keeps reference to the surface of each Nail. However, if a Nail is relocated, the Hammer should know the new position of the selected surface. Otherwise, it will “strike” at the old position (keep the fingers away!)…
1000
1001 Topological naming mechanism should help the Hammer to obtain the relocated surfaces. The Hammer “asks” the mechanism to “resolve” the selected shapes by calling method *TNaming_Selection::Solve()* and the mechanism “returns” the modified surfaces located at the new position by calling  *TNaming_Selector::NamedShape()*.
1002
1003 The topological naming is represented as a “black box” in the example above. Now it is time to make the box a little more “transparent”.
1004
1005 The application contains 3 functions:
1006 * **Nail** -- produces a shape representing a nail,
1007 * **Translator** -- translates a shape along the wooden plate,
1008 * **Hammer** -- drives the nail in the wooden plate.
1009
1010 Each function gives the topological naming some hints how to “re-solve” the selected sub-shapes:
1011 * The Nail constructs a solid shape and puts each face of the shape into sub-labels: 
1012
1013 @figure{/user_guides/ocaf/images/ocaf_image021.png, "Distribution of faces through sub-labels of the Nail"}
1014
1015 * The **Translator** moves a shape and registers modification for each face: it puts a pair: “old” shape -- “new” shape at a sub-label of each moving Nail. The “old” shape represents a face of the Nail at the initial position. The “new” shape -- is the same face, but at a new position:
1016
1017 @figure{/user_guides/ocaf/images/ocaf_image022.png, "Registration of relocation of faces of a Nail"}
1018
1019 How does it work?
1020 * The Hammer selects a face of a Nail calling *TNaming_Selector::Select()*. This call makes a unique name for the selected shape. In our example, it will be a direct reference to the label of the top face of the Nail (Face 1).
1021 * When the user moves a Nail along the wooden plate, the Translator registers this modification by putting the pairs: “old” face of the Nail -- new face of the Nail into its sub-labels. 
1022 * When the Hammer calls *TNaming::Solve()*, the topological naming “looks” at the unique name of the selected shape and tries to re-solve it:
1023         * It finds the 1st appearance of the selected shape in the data tree -- it is a label under the Nail function *Face 1*.
1024         * It follows the evolution of this face. In our case, there is only one evolution -- the translation: *Face 1* (top face) -- <i>Face 1’</i> (relocated top face). So, the last evolution is the relocated top face.
1025 * Calling the method *TNaming_Selector::NamedShape()* the Hammer obtains the last evolution of the selected face -- the relocated top face.
1026
1027 The job is done.
1028
1029 P.S. Let us say a few words about a little more complicated case -- selection of a wire of the top face. Its topological name is an “intersection” of two faces. We remember that the **Nail** puts only faces under its label. So, the selected wire will represent an “intersection” of the top face and the conic face keeping the “head” of the nail. Another example is a selected vertex. Its unique name may be represented as an “intersection” of three or even more faces (depends on the shape).
1030
1031
1032 @section occt_ocaf_6 Standard Attributes
1033
1034 @subsection occt_ocaf_6_1 Overview
1035
1036 Standard attributes are ready-to-use attributes, which allow creating and modifying attributes for many basic data types. They are available in the packages *TDataStd, TDataXtd* and *TDF*. Each attribute belongs to one of four types: 
1037
1038   * Geometric attributes;
1039   * General attributes;
1040   * Relationship attributes;
1041   * Auxiliary attributes.
1042   
1043    
1044
1045 ### Geometric attributes
1046
1047   * **Axis** -- simply identifies, that the concerned *TNaming_NamedShape* attribute with an axis shape inside belongs to the same label; 
1048   * **Constraint** -- contains information about a constraint between geometries: used geometry attributes, type, value (if exists), plane (if exists), "is reversed", "is inverted" and "is verified" flags;
1049   * **Geometry** -- simply identifies, that the concerned *TNaming_NamedShape* attribute with a specified-type geometry belongs to the same label; 
1050   * **Plane** -- simply identifies, that the concerned *TNaming_NamedShape* attribute with a plane shape inside belongs to the same label;
1051   * **Point** -- simply identifies, that the concerned *TNaming_NamedShape* attribute with a  point shape inside belongs to the same label;
1052   * **Shape** -- simply identifies, that the concerned *TNaming_NamedShape* attribute belongs to the same label;
1053   * **PatternStd**  -- identifies one of five available pattern models (linear, circular, rectangular, circular rectangular and mirror);
1054   * **Position** -- identifies the position in 3d global space.
1055
1056 ### General attributes
1057
1058   * **AsciiString** -- contains AsciiString value;
1059   * **BooleanArray** -- contains an array of Boolean;
1060   * **BooleanList** -- contains a list of Boolean;
1061   * **ByteArray** -- contains an array of Byte (unsigned char) values;
1062   * **Comment** -- contains a string -- the comment for a given label (or attribute);
1063   * **Expression** -- contains an expression string and a list of used variables attributes;
1064   * **ExtStringArray** -- contains an array of *ExtendedString* values;
1065   * **ExtStringList** -- contains a list of *ExtendedString* values;
1066   * **Integer** -- contains an integer value;
1067   * **IntegerArray** -- contains an array of integer values;
1068   * **IntegerList** -- contains a list of integer values;
1069   * **IntPackedMap** -- contains a packed map of integers;
1070   * **Name** -- contains a string -- the name of a given label (or attribute);
1071   * **NamedData** -- may contain up to 6 of the following named data sets (vocabularies): *DataMapOfStringInteger, DataMapOfStringReal, DataMapOfStringString, DataMapOfStringByte, DataMapOfStringHArray1OfInteger* or *DataMapOfStringHArray1OfReal*;
1072   * **NoteBook** -- contains a *NoteBook* object attribute;
1073   * **Real** -- contains a real value;
1074   * **RealArray** -- contains an array of  real values;
1075   * **RealList** -- contains a list of real values;
1076   * **Relation** -- contains a relation string and a list of used variables attributes;
1077   * **Tick** -- defines a boolean attribute;
1078   * **Variable** -- simply identifies, that a variable belongs to this label; contains the flag *is constraint* and a string of used units ("mm", "m"...);
1079   * **UAttribute** -- attribute with a user-defined GUID. As a rule, this attribute is used as a marker, which is independent of attributes at the same label (note, that attributes with the same GUIDs can not belong to the same label).
1080   
1081 ### Relationship attributes 
1082
1083   * **Reference** -- contains reference to the label of its own data framework;
1084   * **ReferenceArray** -- contains an array of references;
1085   * **ReferenceList** -- contains a list of references;
1086   * **TreeNode** -- this attribute allows to create an internal tree in the data framework; this tree consists of nodes with the specified tree ID; each node contains references to the father, previous brother, next brother, first child nodes and tree ID.
1087
1088 ### Auxiliary attributes
1089
1090   * **Directory** -- high-level tool attribute for sub-labels management;
1091   * **TagSource** -- this attribute is used for creation of new children: it stores the tag of the last-created child of the label and gives access to the new child label creation functionality.
1092
1093 All attributes inherit class *TDF_Attribute*, so, each attribute has its own GUID and standard methods for attribute creation, manipulation, getting access to the data framework. 
1094
1095
1096 @subsection occt_ocaf_6_2 Services common to all attributes
1097
1098 @subsubsection occt_ocaf_6_2_1 Accessing GUIDs
1099
1100 To access the GUID of an attribute, you can use two methods: 
1101   * Method *GetID* is the static method of a class. It returns the GUID of any attribute, which is an object of a specified class (for example, *TDataStd_Integer* returns the GUID of an integer attribute). Only two classes from the list of standard attributes do not support these methods: *TDataStd_TreeNode* and *TDataStd_Uattribute*, because the GUIDs of these attributes are variable.
1102   * Method *ID* is the method of an object of an attribute class. It returns the GUID of this attribute. Absolutely all attributes have this method: only by this identifier you can discern the type of an attribute.
1103   
1104 To find an attribute attached to a specific label, you use the GUID of the attribute type you are looking for. This information can be found using the method  <i> GetID</i> and the method <i> Find</i> for the label as follows:
1105
1106 ~~~~
1107     Standard_GUID anID = MyAttributeClass::GetID();
1108     Standard_Boolean HasAttribute = aLabel.Find(anID,anAttribute);
1109 ~~~~
1110
1111 @subsubsection occt_ocaf_6_2_2 Conventional Interface of Standard Attributes
1112
1113 It is usual to create standard named methods for the attributes: 
1114
1115   * Method *Set(label, [value])* is the static method, which allows to add an attribute to a given label.  If an attribute is characterized by one value this method may set it.
1116   * Method *Get()* returns the value of an attribute if it is characterized by one value.
1117   * Method *Dump(Standard_OStream)* outputs debug information about a given attribute to a given stream.
1118   
1119 @subsection occt_ocaf_6_3 The choice between standard and custom attributes
1120
1121 When you start to design an application  based on OCAF, usually it is necessary to choose, which attribute will be used for allocation of data in the OCAF document: standard or newly-created?
1122
1123 It is possible to describe any model by means of standard OCAF attributes. 
1124   However, it is still a question if  this description will be  efficient in terms of memory and speed, and, at the same time, convenient to use.
1125   
1126   This depends on a particular model.  
1127    
1128   OCAF imposes the restriction that only one attribute type may be allocated to one label. 
1129   It is necessary to take into  account the design of the application data tree. 
1130   For example, if a label should  possess several double values, 
1131   it is necessary to distribute them through several child sub-labels or use an array of double values.   
1132    
1133   Let us consider several boundary implementations of the same model in OCAF tree and analyze the advantages and disadvantages of each approach.  
1134
1135   
1136 @subsubsection occt_ocaf_6_2_3 Comparison  and analysis of approaches
1137
1138   Below are described two different model implementations: 
1139   one is based on standard OCAF attributes and the other is based 
1140   on the creation of a new attribute possessing all data of the model.  
1141    
1142   A load is distributed through the shape. The measurements are taken at particular points defined by (x, y and z) co-ordinates. The load is represented as a projection onto X, Y and Z axes of the local co-ordinate system at each point of measurement. A matrix of transformation is needed 
1143   to convert the local co-ordinate system to the global one, but this is optional.   
1144    
1145   So, we have 15 double values at each point  of measurement. 
1146   If the number of such points is 100 000, for example, it means 
1147   that we have to store 1 500 000 double values in the OCAF document.  
1148    
1149   The first  approach consists in using standard OCAF attributes. 
1150   Besides, there are several  variants of how the standard attributes may be used:  
1151   * Allocation of all 1 500 000 double values as one array of double values attached to one label;
1152   * Allocation of values of one measure of load (15 values) as one array of double values and attachment of one point of measure to one label;
1153   * Allocation of each point of measure as an array of 3 double values attached to one label, the projection of load onto the local co-ordinate system  axes as another array of 3 double values attached to a sub-label, and the matrix of projection (9 values) as the third array also attached to a sub-label.  
1154   
1155   Certainly, other variants are also  possible.   
1156  
1157 @image html ocaf_tree_wp_image003.png "Allocation of all data as one  array of double values"
1158 @image latex ocaf_tree_wp_image003.png "Allocation of all data as one  array of double values"
1159  
1160   The first approach to allocation of all  data represented as one array of double values 
1161   saves initial memory and is easy to implement. 
1162   But access to the data is difficult because the values are stored in a flat array. 
1163   It will be necessary to implement a class with several methods giving access 
1164   to particular fields like the measurement points, loads and so  on.  
1165    
1166   If the values may be edited in the  application, 
1167   it means that the whole array will be backed-up on each edition. 
1168   The memory usage will increase very fast! 
1169   So, this approach may be considered only in case of non-editable data.  
1170    
1171   Let’s consider the allocation of data of  each measurement point per label (the second case). 
1172   In this case we create 100  000 labels -- one label for each measurement point 
1173   and attach an array of double  values to these labels:  
1174  
1175 @image html ocaf_tree_wp_image004.png "Allocation of data of each  measurement point as arrays of double values"
1176 @image latex ocaf_tree_wp_image004.png "Allocation of data of each  measurement point as arrays of double values"
1177  
1178   Now edition of data is safer as far as  memory usage is concerned. 
1179   Change of value for one measurement point (any  value: point co-ordinates, load, and so on) 
1180   backs-up only one small array of double values. 
1181   But this structure (tree) requires more memory space (additional  labels and attributes).  
1182    
1183   Besides, access to the values is still difficult and it is necessary 
1184   to have a class with methods of access to the  array fields.  
1185    
1186   The third case of allocation of data  through OCAF tree is represented below:  
1187
1188 @image html ocaf_tree_wp_image005.png "Allocation of data into separate arrays of double values"
1189 @image latex ocaf_tree_wp_image005.png "Allocation of data into separate arrays of double values"
1190
1191   In this case sub-labels are involved and we  can easily access the values of each measurement point, 
1192   load or matrix. We don’t need an interface class with methods of access to the data 
1193   (if it exists, it would help to use the data structure, but this is optional).  
1194
1195   On the one hand, this approach requires more  memory for allocation of the attributes (arrays of double values). 
1196   On the other  hand, it saves memory during the edition of data 
1197   by backing-up only the small array containing the modified data. 
1198   So, if the data is fully modifiable, this  approach is more preferable.  
1199
1200   Before making a conclusion, let’s consider the same model implemented through a newly created OCAF attribute.  
1201
1202   For example, we might allocate all data  belonging to one measurement point as one OCAF attribute. 
1203   In this case we  implement the third variant of using the standard attributes (see picture 3), 
1204   but we use less memory (because we use only one attribute instead of three):  
1205  
1206 @image html ocaf_tree_wp_image006.png "Allocation of data into newly  created OCAF attribute"
1207 @image latex ocaf_tree_wp_image006.png "Allocation of data into newly  created OCAF attribute"
1208
1209   The second variant of using standard OCAF attributes still has drawbacks: 
1210   when data is edited, OCAF backs-up all values  of the measurement point.   
1211    
1212   Let’s imagine that we have some  non-editable data. 
1213   It would be better for us to allocate this data separately from editable data. 
1214   Back-up will not affect non-editable data and memory will not increase so much during data edition.  
1215   
1216  @subsubsection occt_ocaf_6_2_4 Conclusion
1217
1218   When deciding which variant of data model implementation to choose, 
1219   it is necessary to take into account the application  response time, 
1220   memory allocation and memory usage in transactions.   
1221    
1222   Most of the models may be implemented using only standard OCAF attributes. 
1223   Some other models need special treatment and require implementation of new OCAF attributes.
1224
1225     
1226 @section occt_ocaf_7 Visualization Attributes
1227
1228 @subsection occt_ocaf_7_1 Overview
1229
1230 Standard visualization attributes implement the Application Interactive Services (see @ref occt_user_guides__visualization "Visualization User's Guide"). in the context of Open CASCADE Technology Application Framework. Standard visualization attributes are AISViewer and Presentation and belong to the TPrsStd package. 
1231
1232 @subsection occt_ocaf_7_2 Services provided
1233
1234 @subsubsection occt_ocaf_7_2_1 Defining an interactive viewer attribute
1235
1236 The class *TPrsStd_AISViewer* allows you to define an interactive viewer attribute. There may be only one such attribute per one data framework and it is always placed to the root label. So, it could be set or found by any label ("access label") of the data framework. Nevertheless the default architecture can be easily extended and the user can manage several Viewers per one framework by himself. 
1237
1238 To initialize the AIS viewer as in the example below, use method *Find*. 
1239
1240 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1241 // "access" is any label of the data framework 
1242 Handle(TPrsStd_AISViewer) viewer = TPrsStd_AISViewer::Find(access) 
1243 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1244
1245 @subsection occt_ocaf_7_2_2 Defining a presentation attribute
1246
1247 The class *TPrsStd_AISPresentation* allows you to define the visual presentation of document labels contents. In addition to various visual fields (color, material, transparency, *isDisplayed*, etc.), this attribute contains its driver GUID. This GUID defines the functionality, which will update the presentation every time when needed. 
1248
1249 @subsubsection occt_ocaf_7_2_3 Creating your own driver
1250
1251 The abstract class TPrsStd_Driver allows you to define your own driver classes. Simply redefine the Update method in your new class, which will rebuild the presentation. 
1252
1253 If your driver is placed to the driver table with the unique driver GUID, then every time the viewer updates presentations with a GUID identical to your driver’s GUID, the *Update* method of your driver for these presentations must be called: 
1254 @image html /user_guides/ocaf/images/ocaf_image016.png
1255 @image latex /user_guides/ocaf/images/ocaf_image016.png
1256
1257 As usual, the GUID of a driver and the GUID of a displayed attribute are the same. 
1258
1259 @subsubsection occt_ocaf_7_2_4 Using a container for drivers
1260
1261 You frequently need a container for different presentation drivers. The class *TPrsStd_DriverTable* provides this service. You can add a driver to the table, see if one is successfully added, and fill it with standard drivers. 
1262
1263 To fill a driver table with standard drivers, first initialize the AIS viewer as in the example above, and then pass the return value of the method *InitStandardDrivers* to the driver table returned by the method *Get*. Then attach a *TNaming_NamedShape* to a label and set the named shape in the presentation attribute using the method *Set*. Then attach the presentation attribute to the named shape attribute, and the *AIS_InteractiveObject*, which the presentation attribute contains, will initialize its drivers for the named shape. This can be seen in the example below. 
1264
1265 **Example** 
1266 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1267 DriverTable::Get() -> InitStandardDrivers(); 
1268 // next, attach your named shape to a label 
1269 TPrsStd_AISPresentation::Set(NS}; 
1270 // here, attach the AISPresentation to NS. 
1271 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1272
1273
1274 @section occt_ocaf_8 Function Services
1275
1276 Function services aggregate data necessary for regeneration of a model. The function mechanism -- available in the package *TFunction* -- provides links between functions and any execution algorithms, which take their arguments from the data framework, and write their results inside the same framework. 
1277
1278 When you edit any application model, you have to regenerate the model by propagating the modifications. Each propagation step calls various algorithms. To make these algorithms independent of your application model, you need to use function services. 
1279
1280 @image html /user_guides/ocaf/images/ocaf_image008.png "Document structure"
1281 @image latex /user_guides/ocaf/images/ocaf_image008.png "Document structure"
1282
1283 Take, for example, the case of a modeling sequence made up of a box with the application of a fillet on one of its edges. If you change the height of the box, the fillet will need to be regenerated as well. 
1284
1285 @subsection occt_ocaf_8_1 Finding functions, their owners and roots
1286
1287 The class *TFunction_Function* is an attribute, which stores a link to a function driver in the data framework. In the static table *TFunction_DriverTable* correspondence links between function attributes and drivers are stored. 
1288
1289 You can write your function attribute, a driver for such attribute, which updates the function result in accordance to a given map of changed labels, and set your driver with the GUID to the driver table. 
1290
1291 Then the solver algorithm of a data model can find the *Function* attribute on a corresponding label and call the *Execute* driver method to update the result of the function. 
1292
1293 @subsection occt_ocaf_8_2 Storing and accessing information about function status
1294
1295 For updating algorithm optimization, each function driver has access to the *TFunction_Logbook* object that is a container for a set of touched, impacted and valid labels. Using this object a driver gets to know which arguments of the function were modified. 
1296
1297 @subsection occt_ocaf_8_3 Propagating modifications
1298
1299 An application must implement its functions, function drivers and the common solver for parametric model creation. For example, check the following model: 
1300
1301 @image html /user_guides/ocaf/images/ocaf_image017.png
1302 @image latex /user_guides/ocaf/images/ocaf_image017.png
1303
1304 The procedure of its creation is as follows:
1305   * create a rectangular planar face *F* with height 100 and width 200;
1306   * create prism *P* using face *F* as a basis;
1307   * create fillet *L* at the edge of the prism;
1308   * change the width of *F* from 200 to 300;
1309   * the solver for the function of face *F* starts;
1310   * the solver detects that an argument of the face *F* function has been modified;
1311   * the solver calls the driver of the face *F* function for a  regeneration of the face;
1312   * the driver rebuilds face *F* and adds the label of the face *width* argument to the logbook as touched and the label of the function of face *F* as impacted;
1313
1314   * the solver detects the function of *P* -- it depends on the function of *F*;
1315   * the solver calls the driver of the prism *P* function;
1316   * the driver rebuilds prism *P* and adds the label of this prism to the logbook as  impacted;
1317   * the solver detects the function of *L*  -- it depends on the function of *P*;
1318   * the solver calls the *L* function driver;
1319   * the driver rebuilds fillet *L* and adds the label of the fillet to the logbook as impacted.
1320   
1321  @section occt_ocaf_8a Example of Function Mechanism Usage
1322  
1323  @subsection occt_ocaf_8a_1 Introduction
1324
1325   Let us describe the usage of the Function Mechanism of Open CASCADE Application Framework on a simple example.  
1326   This example represents a "nail" composed by a cone and two cylinders of different radius and height:  
1327
1328 @image html ocaf_functionmechanism_wp_image003.png "A nail"
1329 @image latex ocaf_functionmechanism_wp_image003.png " A nail"
1330
1331   These three objects (a cone and two cylinders) are  independent, 
1332   but the Function Mechanism makes them connected to each other and representing one object -- a nail.  
1333   The object "nail" has the following parameters:  
1334   
1335   * The position of the nail is defined by the apex point of the  cone. 
1336    The cylinders are built on the cone and therefore they depend on the position  of the cone. 
1337    In this way we define a dependency of the cylinders on the cone.  
1338   * The height of the nail is defined by the height of the cone.  
1339    Let’s consider that the long cylinder has 3 heights of the cone 
1340    and the header cylinder has a half of the height of the cone.  
1341   * The radius of the nail is defined by the radius of the cone. 
1342   The radius of the long cylinder coincides with this value. 
1343   Let’s consider that the  header cylinder has one and a half radiuses of the cone.  
1344   
1345   So, the cylinders depend on the cone and the cone  parameters define the size of the nail.  
1346   
1347   It means that re-positioning the cone (changing its  apex point) moves the nail, 
1348   the change of the radius of the cone produces a thinner or thicker nail, 
1349   and the change of the height of the cone shortens or  prolongates the nail.  
1350    It is suggested to examine the programming steps needed to create a 3D parametric model of the "nail".  
1351   
1352 @subsection occt_ocaf_8a_2 Step 1: Data Tree
1353
1354   The first step consists in model data allocation in the OCAF tree. 
1355   In other words, it is necessary to decide where to put the data.  
1356   
1357   In this case, the data can be organized into a simple tree 
1358   using references for definition of dependent parameters:  
1359
1360 * Nail
1361         * Cone
1362                 + Position (x,y,z)
1363                 + Radius 
1364                 + Height
1365         * Cylinder (stem)
1366                 + Position = "Cone" position translated for "Cone" height along Z;
1367                 + Radius = "Cone" radius;
1368                 + Height = "Cone" height multiplied by 3;
1369         * Cylinder (head)  
1370                 + Position = "Long cylinder" position translated for "Long cylinder" height along Z;
1371                 + Radius = "Long cylinder" radius multiplied by 1.5;
1372                 + Height = "Cone" height divided by 2. 
1373
1374   The "nail" object has three sub-leaves in the tree:  the cone and two cylinders.   
1375   
1376   The cone object is independent.  
1377   
1378   The long cylinder representing a "stem" of the nail  refers to the corresponding parameters 
1379   of the cone to define its own data  (position, radius and height). It means that the long cylinder depends on the  cone.  
1380   
1381   The parameters of the head cylinder may be expressed  through the cone parameters 
1382   only or through the cone and the long cylinder  parameters. 
1383   It is suggested to express the position and the radius of the head cylinder 
1384   through the position and the radius of the long cylinder, and the height 
1385   of the head cylinder through the height of the cone. 
1386   It means that the head cylinder depends on the cone and the long cylinder.  
1387
1388 @subsection occt_ocaf_8a_3 Step 2: Interfaces
1389
1390   The interfaces of the data model are responsible for dynamic creation 
1391   of the data tree of the represented at the previous step, data  modification and deletion.  
1392   
1393   The interface called *INail*  should contain the methods for creation 
1394   of the data tree for the nail, setting  and getting of its parameters, computation, visualization and removal.  
1395
1396 @subsubsection occt_ocaf_8a_3_1 Creation of the nail
1397
1398   This method of the interface creates a data tree for the nail  at a given leaf of OCAF data tree.  
1399   
1400   It creates three sub-leaves for the cone and two cylinders  and allocates the necessary data (references at the sub-leaves of the long and the  head cylinders).  
1401   
1402   It sets the default values of position, radius and height of  the nail.  
1403   
1404   The nail has the following user parameters:  
1405   * The position -- coincides with the position of the cone  
1406   * The radius of the stem part of the nail -- coincides with the radius  of the cone  
1407   * The height of the nail -- a sum of heights of the cone and both  cylinders  
1408   
1409   The values of the position and the radius of the  nail are defined for the cone object data. 
1410   The height of the cone is recomputed  as 2 * heights of nail and divided by 9.  
1411
1412 @subsubsection occt_ocaf_8a_3_2 Computation
1413
1414   The Function Mechanism is responsible for re-computation of  the nail. 
1415   It will be described in detail later in this document.  
1416   
1417   A data leaf consists of the reference  to the location of the  real data 
1418   and a real value defining a coefficient of multiplication of the  referenced data.  
1419   
1420   For example, the height of the long cylinder is defined as a  reference to the height of the cone 
1421   with coefficient 3. The data  leaf of the height of the long cylinder 
1422   should contain two attributes: a  reference to the height of cone and a real value equal to 3.  
1423
1424 @subsubsection occt_ocaf_8a_3_3 Visualization
1425
1426  The shape resulting of the nail function can be displayed using the standard OCAF visualization mechanism.  
1427
1428 @subsubsection occt_ocaf_8a_3_4 Removal of the nail
1429
1430 To automatically erase the nail from the viewer and the data  tree it is enough to clean the nail leaf from attributes.  
1431
1432 @subsection occt_ocaf_8a_4 Step 3: Functions
1433
1434   The nail is defined by four functions: the cone, the two cylinders  and the nail function.  
1435   The function of the cone is independent. The functions of the cylinders depend on the cone function. 
1436   The nail function depends on the  results of all functions:  
1437
1438 @image html ocaf_functionmechanism_wp_image005.png "A graph of dependencies between functions"
1439 @image latex ocaf_functionmechanism_wp_image005.png "A graph of dependencies between functions"
1440
1441   Computation of the model starts with the cone function, then the long cylinder, 
1442   after that the header cylinder and, finally, the result is generated  by the nail function at the end of function chain.  
1443
1444   The Function Mechanism of Open CASCADE Technology creates this  graph of dependencies 
1445   and allows iterating it following the dependencies. 
1446   The  only thing the Function Mechanism requires from its user 
1447   is the implementation  of pure virtual methods of *TFunction_Driver*:  
1448   
1449   * <i>\::Arguments()</i> -- returns a list of arguments for the  function  
1450   * <i>\::Results()</i> -- returns a list of results of the function  
1451   
1452   These methods give the Function Mechanism the information on the location of arguments 
1453   and results of the function and allow building a  graph of functions. 
1454   The class *TFunction_Iterator* iterates the functions of the graph in the execution order.  
1455   
1456   The pure virtual method *TFunction_Driver::Execute()* calculating the function should be overridden.  
1457   
1458   The method <i>\::MustExecute()</i> calls the method <i>\::Arguments()</i>  of the function driver 
1459   and ideally this information (knowledge of modification  of arguments of the function) is enough
1460   to make a decision whether the function  should be executed or not. Therefore, this method usually shouldn’t be  overridden.  
1461
1462   The cone and cylinder functions differ only in geometrical construction algorithms. 
1463   Other parameters are the same (position, radius and height).  
1464   
1465   It means that it is possible to create a base class -- function driver for the three functions, 
1466   and two descendant classes producing:  a cone or a cylinder.  
1467   
1468   For the base function driver the methods <i>\::Arguments()</i>  and <i>\::Results()</i> will be overridden. 
1469   Two descendant function drivers responsible for creation of a cone and a cylinder will override only the method  <i>\::Execute()</i>. 
1470   
1471   The method <i>\::Arguments()</i> of the function driver of the nail returns the results of the functions located under it in the tree of leaves.   The method <i>\::Execute()</i> just collects the  results of the functions and makes one shape -- a nail. 
1472   
1473   This way the data model using the Function Mechanism is  ready for usage.   Do not forget to introduce the function drivers for a function  driver table with the help of *TFunction_DriverTable* class.
1474
1475 @subsection occt_ocaf_8a_5 Example 1: iteration and execution of functions. 
1476
1477   This is an example of the code for iteration and execution of functions.  
1478
1479 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1480
1481     // The scope of functions is  defined.  
1482     Handle(TFunction_Scope) scope = TFunction_Scope::Set( anyLabel );  
1483      
1484     // The information on  modifications in the model is received.  
1485     TFunction_Logbook&amp; log = scope-GetLogbook();  
1486      
1487     // The iterator is iInitialized by  the scope of functions.  
1488     TFunction_Iterator iterator( anyLabel );  
1489     Iterator.SetUsageOfExecutionOrder( true );  
1490      
1491     // The function is iterated,  its  dependency is checked on the modified data and  executed if necessary.  
1492     for (; iterator.more(); iterator.Next())  
1493     {  
1494       // The function iterator may return a list of  current functions for execution.  
1495       // It might be useful for multi-threaded execution  of functions.  
1496       const  TDF_LabelList&amp; currentFunctions = iterator.Current();  
1497        
1498       //The list of current functions is iterated.  
1499       TDF_ListIteratorOfLabelList  currentterator( currentFucntions );  
1500       for (;  currentIterator.More(); currentIterator.Next())  
1501       {  
1502         //  An interface for the function is created.  
1503         TFunction_IFunction  interface( currentIterator.Value() );  
1504      
1505         //  The function driver is retrieved.  
1506         Handle(TFunction_Driver)  driver = interface.GetDriver();  
1507      
1508         //  The dependency of the function on the  modified data is checked.  
1509         If  (driver-MustExecute( log ))  
1510         {  
1511           // The function is executed.  
1512           int  ret = driver-Execute( log );  
1513           if ( ret ) 
1514             return  false;  
1515         } // end if check on modification  
1516       } // end of iteration of current functions  
1517     } // end of iteration of  functions.
1518
1519 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1520
1521 @subsection occt_ocaf_8a_6 Example 2: Cylinder function driver
1522
1523   This is an example of the code for a cylinder function driver. To make the things clearer, the methods <i>\::Arguments()</i>  and <i>\::Results()</i>  from the base class are also mentioned.   
1524
1525 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1526
1527     // A virtual method  ::Arguments() returns a list of arguments of the function.  
1528     CylinderDriver::Arguments( TDF_LabelList&amp; args )  
1529     {  
1530       // The direct arguments, located at sub-leaves of  the fucntion, are collected (see picture 2).  
1531       TDF_ChildIterator  cIterator( Label(), false );  
1532       for (;  cIterator.More(); cIterator.Next() )  
1533       {  
1534         // Direct argument.  
1535         TDF_Label  sublabel = cIterator.Value();  
1536         Args.Append(  sublabel );  
1537
1538         // The references to the external data are  checked.  
1539         Handle(TDF_Reference)  ref;  
1540         If (  sublabel.FindAttribute( TDF_Reference::GetID(), ref ) )  
1541         {  
1542           args.Append(  ref-Get() );  
1543         }
1544     }
1545      
1546     // A virtual method ::Results()  returns a list of result leaves.  
1547     CylinderDriver::Results( TDF_LabelList&amp; res )  
1548     {  
1549       // The result is kept at the function  label.  
1550       Res.Append(  Label() );  
1551     }
1552      
1553     // Execution of the function  driver.  
1554     Int CylinderDriver::Execute( TFunction_Logbook&amp; log )  
1555     {  
1556       // Position of the cylinder - position of the first  function (cone)   
1557       //is  elevated along Z for height values of all  previous functions.  
1558       gp_Ax2 axes = …. // out of the scope of this guide.  
1559       // The radius value is retrieved.  
1560       // It is located at second child sub-leaf (see the  picture 2).  
1561       TDF_Label radiusLabel  = Label().FindChild( 2 );  
1562        
1563       // The multiplicator of the radius ()is retrieved.  
1564       Handle(TDataStd_Real)  radiusValue;  
1565       radiusLabel.FindAttribute(  TDataStd_Real::GetID(), radiusValue);  
1566        
1567       // The reference to the radius is retrieved.  
1568       Handle(TDF_Reference)  refRadius;  
1569       RadiusLabel.FindAttribute(  TDF_Reference::GetID(), refRadius );  
1570        
1571       // The radius value is calculated.  
1572       double radius = 0.0;
1573       
1574       if (  refRadius.IsNull() )
1575       {
1576         radius  = radiusValue-Get();  
1577       }
1578       else  
1579       {  
1580         // The referenced radius value is  retrieved.   
1581         Handle(TDataStd_Real)  referencedRadiusValue;  
1582         RefRadius-Get().FindAttribute(TDataStd_Real::GetID()  ,referencedRadiusValue );  
1583         radius  = referencedRadiusValue-Get() * radiusValue-Get();  
1584       }  
1585        
1586       // The height value is retrieved.  
1587       double height = … // similar code to taking the radius value.  
1588        
1589       // The cylinder is created.  
1590       TopoDS_Shape cylinder  = BRepPrimAPI_MakeCylinder(axes, radius, height);  
1591        
1592       // The result (cylinder) is set  
1593       TNaming_Builder  builder( Label() );  
1594       Builder.Generated(  cylinder );  
1595        
1596       // The modification of the result leaf is saved in  the log.  
1597       log.SetImpacted(  Label() );  
1598        
1599       return 0;
1600     }
1601 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1602  
1603   
1604
1605 @section occt_ocaf_9 XML Support
1606
1607 Writing and reading XML files in OCCT is provided by LDOM package, which constitutes an integral part
1608 of XML OCAF persistence, which is the optional component provided on top of Open CASCADE Technology.
1609
1610 The Light DOM (LDOM) package contains classes maintaining a data structure whose main principles conform to W3C DOM Level 1 Recommendations. The purpose of these classes as required by XML OCAF persistence schema is to: 
1611 * Maintain a tree structure of objects in memory representing the XML document. The root of the structure is an object of the *LDOM_Document* type. This object contains all the data corresponding to a given XML document and contains one object of the *LDOM_Element* type named "document element". The document element contains other *LDOM_Element* objects forming a tree. Other types of nodes: *LDOM_Attr, LDOM_Text, LDOM_Comment* and *LDOM_CDATASection* -- represent the corresponding XML types and serve as branches of the tree of elements. 
1612 * Provide class *LDOM_Parser* to read XML files and convert them to *LDOM_Document* objects.
1613 * Provide class *LDOM_XmlWriter* to convert *LDOM_Document* to a character stream in XML format and store it in file. 
1614
1615 This package covers the functionality provided by numerous products known as "DOM parsers". Unlike most of them, LDOM was specifically developed to meet the following requirements: 
1616 * To minimize the virtual memory allocated by DOM data structures. In average, the amount of memory of LDOM is the same as the XML file size (UTF-8). 
1617 * To minimize the time required for parsing and formatting XML, as well as for access to DOM data structures. 
1618
1619 Both these requirements are important when XML files are processed by applications if these files are relatively large (occupying megabytes and even hundreds of megabytes). To meet the requirements, some limitations were imposed on the DOM Level 1 specification; these limitations are insignificant in applications like OCAF. Some of these limitations can be overridden in the course of future developments. The main limitations are:
1620 * No Unicode support as well as various other encodings; only ASCII strings are used in DOM/XML. Note: There is a data type *TCollection_ExtendedString* for wide character data. This type is supported by *LDOM_String* as a sequence of numbers. 
1621 * Some superfluous methods are deleted: *getPreviousSibling, getParentNode,* etc. 
1622 * No resolution of XML Entities of any kind 
1623 * No support for DTD: the parser just checks for observance of general XML rules and never validates documents. 
1624 * Only 5 available types of DOM nodes: *LDOM_Element, LDOM_Attr, LDOM_Text, LDOM_Comment* and *LDOM_CDATASection*. 
1625 * No support of Namespaces; prefixed names are used instead of qualified names. 
1626 * No support of the interface *DOMException* (no exception when attempting to remove a non-existing node). 
1627
1628 LDOM is dependent on Kernel OCCT classes only. Therefore, it can be used outside OCAF persistence in various algorithms where DOM/XML support may be required. 
1629
1630 @subsection occt_ocaf_9_1 Document Drivers
1631
1632 The drivers for document storage and retrieval  manage  conversion between a transient OCAF
1633 Document in memory and its persistent reflection in a container (disk, memory, network). For XML Persistence, they are defined in the package XmlDrivers. 
1634
1635 The main methods (entry points) of these drivers are: 
1636 * *Write()* -- for a storage driver; 
1637 * *Read()* -- for a retrieval driver. 
1638
1639 The most common case (which is implemented in XML Persistence) is writing/reading document to/from a regular OS file. Such conversion is performed in two steps: 
1640
1641 First it is necessary to convert the transient document into another form (called persistent), suitable for writing into a file, and vice versa. 
1642 In XML Persistence LDOM_Document is used as the persistent form of an OCAF Document and the DOM_Nodes are the persistent objects. 
1643 An OCAF Document is a tree of labels with attributes. Its transformation into a persistent form can be functionally divided into two parts: 
1644 * Conversion of the labels structure, which is performed by the method XmlMDF::FromTo()
1645 * Conversion of the attributes and their underlying objects, which is performed by the corresponding attribute drivers (one driver per attribute type). 
1646
1647 The driver for each attribute is selected from a table of drivers, either by attribute
1648 type (on storage) or by the name of the corresponding DOM_Element (on retrieval).
1649 The table of drivers is created by by methods *XmlDrivers_DocumentStorageDriver::AttributeDrivers()*
1650 and *XmlDrivers_DocumentRetrievalDriver::AttributeDrivers()*. 
1651
1652 Then the persistent document is written into a file (or read from a file). 
1653 In standard persistence Storage and FSD packages contain classes for writing/reading the persistent document into a file. In XML persistence *LDOMParser* and *LDOM_XmlWriter* are used instead.
1654
1655 Usually, the library containing document storage and retrieval drivers is loaded at run time by a plugin mechanism. To support this in XML Persistence, there is a plugin *XmlPlugin* and a *Factory()* method in the *XmlDrivers* package. This method compares passed GUIDs with known GUIDs and returns the corresponding driver or generates an exception if the GUID is unknown. 
1656
1657 The application defines which GUID is needed for document storage or retrieval and in which library it should be found. This depends on document format and application resources. Resources for XML Persistence and also for standard persistence are found in the StdResource unit. They are written for the XmlOcaf document format. 
1658
1659 @subsection occt_ocaf_9_2 Attribute Drivers
1660
1661 There is one attribute driver for XML persistence for each transient attribute from a set of standard OCAF attributes, with the exception of attribute types, which are never stored (pure transient). Standard OCAF attributes are collected in six packages, and their drivers also follow this distribution. Driver for attribute <i>T*_*</i> is called <i>XmlM*_*</i>. Conversion between transient and persistent form of attribute is performed by two methods *Paste()* of attribute driver. 
1662
1663 *XmlMDF_ADriver* is the root class for all attribute drivers.
1664
1665 At the beginning of storage/retrieval process, one instance of each attribute driver is created and appended to driver table implemented as *XmlMDF_ADriverTable*.  During OCAF Data storage, attribute drivers are retrieved from the driver table by the type of attribute. In the retrieval step, a data map is created linking names of *DOM_Elements* and attribute drivers, and then attribute drivers are sought in this map by *DOM_Element* qualified tag names. 
1666
1667 Every transient attribute is saved as a *DOM_Element* (root element of OCAF attribute) with attributes and possibly sub-nodes. The name of the root element can be defined in the attribute driver as a string passed to the base class constructor. The default is the attribute type name. Similarly, namespace prefixes for each attribute can be set. There is no default value, but it is possible to pass NULL or an empty string to store attributes without namespace prefixes. 
1668
1669 The basic class *XmlMDF_ADriver* supports errors reporting via the method *WriteMessage(const TCollection_ExtendedString&)*. It sends a message string to its message driver which is initialized in the constructor with a *Handle(CDM_MessageDriver)* passed from the application by Document Storage/Retrieval Driver. 
1670
1671 @subsection occt_ocaf_9_3 XML Document Structure
1672
1673 Every XML Document has one root element, which may have attributes and contain other nodes. In OCAF XML Documents the root element is named "document" and has attribute "format" with the name of the OCAF Schema used to generate the file. The standard XML format is "XmlOcaf". The following elements are sub-elements of \<document\> and should be unique entries as its sub-elements, in a specific order. The order is:
1674 * **Element info** -- contains strings identifying the format version and other parameters of the OCAF XML document. Normally, data under the element is used by persistence algorithms to correctly retrieve and initialize an OCAF document. The data also includes a copyright string. 
1675 * **Element comments** -- consists of an unlimited number of \<comment\> sub-elements containing necessary comment strings. 
1676 * **Element label** -- the root label of the document data structure, with the XML attribute "tag" equal to 0. It contains all the OCAF data (labels, attributes) as tree of XML elements. Every sub-label is identified by a tag (positive integer) defining a unique key for all sub-labels of a label. Every label can contain any number of elements representing OCAF attributes (see OCAF Attributes Representation below).
1677 * **Element shapes** -- contains geometrical and topological entities in BRep format. These entities being referenced by OCAF attributes written under the element \<label\>. This element is empty if there are no shapes in the document. It is only output if attribute driver *XmlMNaming_NamedShapeDriver* has been added to drivers table by the *DocumentStorageDriver*.
1678
1679 ### OCAF Attributes Representation 
1680
1681 In XML documents, OCAF attributes are elements whose name identifies the OCAF attribute type. These elements may have a simple (string or number) or complex (sub-elements) structure, depending on the architecture of OCAF attribute. Every XML type for OCAF attribute possesses a unique positive integer "id" XML attribute identifying the OCAF attribute throughout the document. To ensure "id" uniqueness, the attribute name "id" is reserved and is only used to indicate and identify elements which may be referenced from other parts of the OCAF XML document. 
1682 For every standard OCAF attribute, its XML name matches the name of a C++ class in Transient data model. Generally, the XML name of OCAF attribute can be specified in the corresponding attribute driver. 
1683 XML types for OCAF attributes are declared with XML W3C Schema in a few XSD files where OCAF attributes are grouped by the package where they are defined. 
1684
1685 ### Example of resulting XML file 
1686
1687 The following example is a sample text from an XML file obtained by storing an OCAF document with two labels (0: and 0:2) and two attributes -- *TDataStd_Name* (on label 0:) and *TNaming_NamedShape* (on label 0:2). The \<shapes\> section contents are replaced by an ellipsis. 
1688
1689 ~~~~
1690 <?xml version="1.0" encoding="UTF-8"?> 
1691 <document format="XmlOcaf" xmlns="http://www.opencascade.org/OCAF/XML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1692 xsi:schemaLocation="http://www.opencascade.org/OCAF/XML http://www.opencascade.org/OCAF/XML/XmlOcaf.xsd">
1693
1694 <info date="2001-10-04" schemav="0" objnb="3"> 
1695 <iitem>Copyright: Open Cascade, 2001</iitem> 
1696 <iitem>STORAGE_VERSION: PCDM_ReadWriter_1</iitem> 
1697 <iitem>REFERENCE_COUNTER: 0</iitem> 
1698 <iitem>MODIFICATION_COUNTER: 1</iitem> 
1699 </info> 
1700 <comments/> 
1701 <label tag="0"> 
1702 <TDataStd_Name id="1">Document_1</TDataStd_Name> 
1703 <label tag="2"> 
1704 <TNaming_NamedShape id="2" evolution="primitive"> 
1705 <olds/> 
1706 <news> 
1707 <shape tshape="+34" index="1"/> 
1708 </news> 
1709 </TNaming_NamedShape> 
1710 </label> 
1711 </label> 
1712 \<shapes\> 
1713 ... 
1714 </shapes> 
1715 </document> 
1716
1717 ~~~~
1718
1719 @subsection occt_ocaf_9_4 XML Schema
1720
1721 The XML Schema defines the class of a document. 
1722
1723 The full structure of OCAF XML documents is described as a set of XML W3C Schema files with definitions of all XML element types. The definitions provided cannot be overridden. If any application defines new persistence schemas, it can use all the definitions from the present XSD files but if it creates new or redefines existing types, the definition must be done under other namespace(s). 
1724
1725 There are other ways to declare XML data, different from W3C Schema, and it should be possible to use them to the extent of their capabilities of expressing the particular structure and constraints of our XML data model. However, it must be noted that the W3C Schema is the primary format for declarations and as such, it is the format supported for future improvements of Open CASCADE Technology, including the development of specific applications using OCAF XML persistence. 
1726
1727 The Schema files (XSD) are intended for two purposes: 
1728 * documenting the data format of files generated by OCAF; 
1729 * validation of documents when they are used by external (non-OCAF) applications, e.g., to generate reports. 
1730
1731 The Schema definitions are not used by OCAF XML Persistence algorithms when saving and restoring XML documents. There are internal checks to ensure validity when processing every type of data. 
1732
1733 ### Management of Namespaces 
1734
1735 Both the XML format and the XML OCAF persistence code are extensible in the sense that every new development can reuse everything that has been created in previous projects. For the XML format, this extensibility is supported by assigning names of XML objects (elements) to different XML Namespaces. Hence, XML elements defined in different projects (in different persistence libraries) can easily be combined into the same XML documents. An example is the XCAF XML persistence built as an extension to the Standard OCAF XML persistence <i>[File XmlXcaf.xsd]</i>. For the correct management of Namespaces it is necessary to: 
1736 * Define *targetNamespace* in the new XSD file describing the format. 
1737 * Declare (in *XSD* files) all elements and types in the targetNamespace to appear without a namespace prefix; all other elements and types use the appropriate prefix (such as "ocaf:"). 
1738 * Add (in the new *DocumentStorageDriver*) the *targetNamespace* accompanied with its prefix, using method *XmlDrivers_DocumentStorageDriver::AddNamespace*. The same is done for all namespaces objects which are used by the new persistence, with the exception of the "ocaf" namespace. 
1739 * Pass (in every OCAF attribute driver) the namespace prefix of the *targetNamespace* to the constructor of *XmlMDF_ADriver*. 
1740
1741 @section occt_ocaf_9a Persistent  Data Storage
1742
1743 @subsection occt_ocaf_9a_1 Introduction
1744
1745 In OCAF, persistence, that is, the mechanism used to  save a document in a file, is based on an explicit formal description of the  data saved.  
1746  
1747 When you open a document, the application reads the corresponding file and first creates a memory representation of it. This representation is then converted to the application data model —  the OCAF-based data structure the application operates on. The file's memory representation  consists of objects defined by classes known as persistent. 
1748   
1749 The persistent  classes needed by an application to save its documents make the application's data schema. This schema defines the way the data are organized in the file — the format of the data. In other words, the file is simply an ASCII dump of the  persistent data defined by the schema, the persistent data being created from  the application data model during the save process.  
1750    
1751 Only canonical information is saved. As a matter of  fact, the application data model usually contains additional data to optimize  processing. For example, the persistent Bézier curve is defined by its poles, whereas its data model equivalent also contains coefficients used to compute a point at a given parameter.  The additional data is calculated when the document is opened.  
1752  
1753 The major advantages of this approach are the following:  
1754   * Providing  that the data format is published, files created by OCAF-based applications 
1755    can be read without needing a runtime of the application (openness)
1756   * Although the  persistence approach makes the data format more stable, 
1757    OCAF provides a  framework for managing compatibility of data between versions of the application — 
1758    modification of the data format is supported through the  versioning of schema.
1759  
1760   OCAF includes a ready-to-use schema suitable for most  applications. 
1761   However, it can be extended if needed. For that, the only things  you have to do are:  
1762
1763   * To define  the additional persistent attributes
1764   * To implement  the functions converting these persistent attribute to and from the application  data model.
1765   
1766 Applications using compound documents extensively (saving data in many files linked together) should implement data management services. As a matter of fact, it's out the scope of OCAF to provide functions such as:
1767 * Version and configuration management of compound documents;
1768 * Querying a referenced document for its referencing documents.
1769
1770 In order to ease the delegation of document management to a data management application, OCAF encapsulates the file management functions in a driver (the meta-data driver). You have to implement this driver for your application to communicate with the data management system of your choice.
1771
1772  
1773 @subsection occt_ocaf_9a_2 Schemes of Persistence
1774
1775 There are three schemes of persistence, which you can use to store and retrieve OCAF data (documents):
1776
1777   * <i> Standard</i> persistence schema, compatible with previous OCAF applications
1778   * <i> XmlOcaf</i> persistence, allowing the storage of all OCAF data in XML form
1779   * <i> BinOcaf</i> persistence, allowing the storage of all OCAF data in binary format form
1780
1781
1782 All schemes are independent of each other, but they guarantee that the standard OCAF
1783 attributes stored and retrieved by one schema will be storable and retrievable by
1784 the other. Therefore in any OCAF application you can use any persistence schema or
1785 even all three of them. The choice is made depending on the *Format* string of stored OCAF documents
1786 or automatically by the file header data -- on retrieval.
1787
1788 Persistent data storage in OCAF using the <i> Standard</i> package is presented in: 
1789
1790   * Basic Data Storage 
1791   * Persistent Collections 
1792
1793 Persistent storage of shapes is presented in the following chapters:
1794
1795   * Persistent Geometry 
1796   * Persistent Topology 
1797
1798 Finally, information about opening and saving persistent data is presented in Standard
1799 Documents. 
1800
1801 @subsection occt_ocaf_9a_3 Basic Data Storage
1802
1803 Normally, all data structures provided by Open CASCADE Technology are run-time structures,
1804 in other words, transient data. As transient data, they exist only while an application
1805 is running and are not stored permanently. However, the Data Storage module provides
1806 resources, which enable an application to store data on disk as persistent data.
1807
1808 Data storage services also provide libraries of persistent classes and translation
1809 functions needed to translate data from transient to persistent state and vice-versa.
1810
1811 #### Libraries of persistent classes
1812
1813 Libraries of persistent classes are extensible libraries of elementary classes you
1814 use to define the database schema of your application. They include:
1815 * Unicode (8-bit or 16-bit character type) strings 
1816 * Collections of any kind of persistent data such as arrays.
1817
1818 All persistent classes are derived from the \b Persistent base class, which defines
1819 a unique way of creating and handling persistent objects. You create new persistent
1820 classes by inheriting from this base class.
1821
1822 #### Translation Functions
1823
1824 Translation functions allow you to convert persistent objects to transient ones and
1825 vice-versa. These translation functions are used to build Storage and Retrieval drivers
1826 of an application.
1827
1828 For each class of 2D and 3D geometric types, and for the general shape class in the
1829 topological data structure library, there are corresponding persistent class libraries,
1830 which allow you to translate your data with ease.
1831
1832 #### Creation of Persistent Classes
1833
1834 If you use Unix platforms as well as WOK and CDL, you can create your own persistent
1835 classes. In this case, data storage is achieved by implementing *Storage* and *Retrieval*
1836 drivers.
1837
1838 The <i> Storage </i> package is used to write and read persistent objects. 
1839 These objects are read and written by a retrieval or storage algorithm 
1840 (<i> Storage_Schema </i>object) in a container (disk, memory, network ...). 
1841 Drivers (<i> FSD_File</i> objects) assign a physical container for data to be stored or retrieved.
1842
1843 The standard procedure for an application in reading a container is as follows:
1844
1845 * open the driver in reading mode,
1846 * call the Read function from the schema, setting the driver as a parameter. This function returns an instance of the <i> Storage_Data </i> class which contains the data being read,
1847 * close the driver.
1848
1849 The standard procedure for an application in writing a container is as follows:
1850
1851 * open the driver in writing mode,
1852 * create an instance of the <i> Storage_Data </i> class, then add the persistent data to write with the function <i> AddRoot</i>,
1853 * call the function <i> Write </i> from the schema, setting the driver and the <i> Storage_Data </i> instance as parameters,
1854 * close the driver.
1855
1856 @subsection occt_ocaf_9a_4 Persistent Collections
1857
1858 Persistent collections are classes which handle dynamically sized collections of data that can be stored in the database. These collections provide three categories of service:
1859
1860   * persistent strings,
1861   * generic arrays of data, 
1862   * commonly used instantiations of arrays.
1863
1864 Persistent strings are concrete classes that handle sequences of characters based
1865 on both ASCII (normal 8-bit) and Unicode (16-bit) character sets.
1866
1867 Arrays are generic classes, that is, they can hold a variety of objects not necessarily inheriting from a unique root class. These arrays can be instantiated with any kind of storable or persistent object, and then inserted into the persistent data model of a user application.
1868
1869 The purpose of these data collections is simply to convert transient data into its persistent equivalent so that it can be stored in the database. To this end, the collections are used to create the persistent data model and assure the link with the database. They do not provide editing or query capabilities because it is more efficient, within the operative data model of the application, to work with transient data structures (from the <i> TCollection</i> package).
1870
1871 For this reason:
1872
1873   * the persistent strings only provide constructors and functions to convert between transient and persistent strings, and
1874   * the persistent data collections are limited to arrays. In other words, <i> PCollection</i> does not include sequences, lists, and so on (unlike <i> TCollection</i>).
1875
1876 Persistent string and array classes are found in the <i> PCollection</i> package. In addition, <i> PColStd</i> package provides standard, and frequently used, instantiations of persistent arrays, for very simple objects.
1877
1878 @subsection occt_ocaf_9a_5 Persistent Geometry
1879
1880 The Persistent Geometry component describes geometric data structures which can be stored in the database. These packages provide a way to convert data from the transient "world" to the persistent "world".
1881
1882 Persistent Geometry consists of a set of atomic data models parallel to the geometric data structures described in the geometry packages. Geometric data models, independent of each other, can appear within the data model of any application. The system provides the means to convert each atomic transient data model into a persistent one, but it does not provide a way for these data models to share data.
1883
1884 Consequently, you can create a data model using these components, store data in, and retrieve it from a file or a database, using the geometric components provided in the transient and persistent "worlds". In other words, you customize the system by declaring your own objects, and the conversion of the geometric components from persistent to transient and vice versa is automatically managed for you by the system.
1885
1886 However, these simple objects cannot be shared within a more complex data model. To allow data to be shared, you must provide additional tools.
1887
1888 Persistent Geometry is provided by several packages.
1889
1890 The <i> PGeom</i> package describes geometric persistent objects in 3D space, such as points,
1891 vectors, positioning systems, curves and surfaces.
1892
1893 These objects are persistent versions of those provided by the <i> Geom</i> package: for
1894 each type of transient object provided by Geom there is a corresponding type of persistent
1895 object in the <i>PGeom</i> package. In particular the inheritance structure is parallel.
1896
1897 However the <i> PGeom </i>package does not provide any functions to construct, edit or access
1898 the persistent objects. Instead the objects are manipulated as follows:
1899
1900   * Persistent objects are constructed by converting the equivalent transient <i> Geom </i> objects. To do this you use the <i>MgtGeom::Translate</i> function.
1901   * Persistent objects created in this way are used to build persistent data structures that are then stored in a file or database.
1902   * When these objects are retrieved from the file or database, they are converted back into the corresponding transient objects from the Geom package. To do this, you use <i>MgtGeom::Translate</i> function.
1903
1904 In other words, you always edit or query transient data structures within the transient
1905 data model supplied by the session.
1906 Consequently, the documentation for the <i> PGeom </i> package consists simply of a list of available objects.
1907
1908 The <i> PGeom2d </i> package describes persistent geometric objects in 2D space, such as points,
1909 vectors, positioning systems and curves. This package provides the same type of services
1910 as the <i> PGeom</i> package, but for the 2D geometric objects provided by the <i> Geom2d</i> package.
1911 Conversions are provided by the <i>MgtGeom::Translate</i> function.
1912
1913 ~~~~
1914 //Create a coordinate system
1915 Handle(Geom_Axis2Placement) aSys;
1916
1917
1918 //Create a persistent coordinate PTopoDS_HShape.cdlsystem
1919 Handle(PGeom_Axis2placement)
1920         aPSys = MgtGeom::Translate(aSys);
1921
1922 //Restore a transient coordinate system
1923 Handle(PGeom_Axis2Placement) aPSys;
1924
1925 Handle(Geom_Axis2Placement)
1926         aSys = MgtGeom::Translate(aPSys);
1927 ~~~~
1928
1929
1930 @subsection occt_ocaf_9a_6 Persistent Topology
1931
1932 The Persistent Topology component describes topological data structures which can be stored in the database. These packages provide a way to convert data from the transient "world" to the persistent "world".
1933
1934 Persistent Topology is based on the BRep concrete data model provided by the topology packages. Unlike the components of the Persistent Geometry package, topological components can be fully shared within a single model, as well as between several models.
1935
1936 Each topological component is considered to be a shape: a <i> TopoDS_Shape</i> object. The system's capacity to convert a transient shape into a persistent shape and vice-versa applies to all objects, irrespective of their complexity: vertex, edge, wire, face, shell, solid, and so on.
1937
1938 When a user creates a data model using BRep shapes, he uses the conversion functions that the system provides to store the data in, and retrieve it from the database. The data can also be shared.
1939
1940 Persistent Topology is provided by several packages.
1941
1942 The <i> PTopoDS</i> package describes the persistent data model associated with any BRep shape; it is the persistent version of any shape of type <i> TopoDS_Shape</i>. As is the case for persistent geometric models, this data structure is never edited or queried, it is simply stored in or retrieved from the database. It is created or converted by the <i>MgtBRep::Translate</i> function.
1943
1944 The <i> MgtBRepAbs</i> and <i> PTColStd </i> packages provide tools used by the conversion functions of topological objects.
1945
1946 ~~~~
1947 //Create a shape
1948 TopoDS_Shape aShape;
1949
1950 //Create a persistent shape
1951 PtColStd_DoubleTransientPersistentMap aMap;
1952
1953 Handle(PTopoDS_HShape) aPShape =
1954         aMap.Bind2(MgtBRep::Translate
1955                 aShape,aMap,MgtBRepAbs_WithTriangle));
1956
1957 aPShape.Nullify();
1958
1959 //Restore a transient shape
1960 Handle(PTopoDS_HShape) aPShape;
1961
1962 Handle(TopoDS_HShape) aShape =
1963         aMap.Bind1(MgtBRep::Translate
1964                 (aPShape,aMap,MgtBRepAbs_WithTriangle));
1965
1966 aShape.Nullify();
1967 ~~~~
1968
1969   
1970 @section occt_ocaf_10 GLOSSARY
1971
1972 * **Application** -- a document container holding all documents containing all application data. 
1973 * **Application data** -- the data produced by an application, as opposed to data referring to it. 
1974 * **Associativity of data** -- the ability to propagate modifications made to one document to other documents, which refer to such document. Modification propagation is: 
1975   * unidirectional, that is, from the referenced to the referencing document(s), or
1976   * bi-directional, from the referencing to the referenced document and vice-versa.
1977 * **Attribute** -- a container for application data. An attribute is attached to a label in the hierarchy of the data framework. 
1978 * **Child** -- a label created from another label, which by definition, is the father label. 
1979 * **Compound document** -- a set of interdependent documents, linked to each other by means of external references. These references provide the associativity of data. 
1980 * **Data framework** -- a tree-like data structure which in OCAF, is a tree of labels with data attached to them in the form of attributes. This tree of labels is accessible through the services of the *TDocStd_Document* class. 
1981 * **Document** -- a container for a data framework which grants access to the data, and is, in its turn, contained  by an application. A document also allows you to: 
1982         * Manage modifications, providing Undo and Redo functions 
1983         * Manage command transactions 
1984         * Update external links 
1985         * Manage save and restore options 
1986         * Store the names of software extensions. 
1987 * **Driver** -- an abstract class, which defines the communications protocol with a system. 
1988 * **Entry** -- an ASCII character string containing the tag list of a label. For example:
1989
1990 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1991 0:3:24:7:2:7 
1992 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1993
1994 * **External links** -- references from one data structure to another data structure in another document. 
1995 To store these references properly, a label must also contain an external link attribute. 
1996 * **Father** -- a label, from which other labels have been created. The other labels are, by definition, the children of this label. 
1997 * **Framework** -- a group of co-operating classes which enable a design to be re-used for a given category of problem. The framework guides the architecture of the application by breaking it up into abstract  classes, each of which has different responsibilities and collaborates in a predefined way. Application developer creates a specialized framework by: 
1998   * defining new classes which inherit from these abstract classes
1999   * composing framework class instances
2000   * implementing the services required by the framework.
2001
2002 In C++, the application behavior is implemented in virtual functions redefined in these derived classes. This is known as overriding. 
2003
2004 * **GUID** -- Global Universal ID. A string of 37 characters intended to uniquely identify an object. For example:
2005
2006 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2007 2a96b602-ec8b-11d0-bee7-080009dc3333 
2008 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2009
2010 * **Label** -- a point in the data framework, which allows data to be attached to it by means of attributes. It has a name in the form of an entry, which identifies its place in the data framework. 
2011 * **Modified label** -- containing attributes whose data has been modified. 
2012 * **Reference key** -- an invariant reference, which may refer to any type of data used in an application. In its transient form, it is a label in the data framework, and the data is attached to it in the form of attributes. In its persistent form, it is an entry of the label. It allows an application to recover any entity in the current session or in a previous session. 
2013 * **Resource file** -- a file containing a list of each document’s schema name and the storage and retrieval plug-ins for that document. 
2014 * **Root** -- the starting point of the data framework. This point is the top label in the framework. It is represented by the [0] entry and is created at the same time with the document you are working on. 
2015 * **Scope** -- the set of all the attributes and labels which depend on a given label. 
2016 * **Tag list** -- a list of integers, which identify the place of a label in the data framework.  This list is displayed in an entry. 
2017 * **Topological naming** -- systematic referencing of topological entities so that these entities can still be identified after the models they belong to have gone through several steps in modeling. In other words, topological naming allows you to track entities through the steps in the modeling process. This referencing is needed when a model is edited and regenerated, and can be seen as a mapping of labels and name attributes of the entities in the old version of a model to those of the corresponding entities in its new version. Note that if the topology of a model changes during the modeling, this mapping may not fully coincide. A Boolean operation, for example, may split edges. 
2018 * **Topological tracking** -- following a topological entity in a model through the steps taken to edit and regenerate that model. 
2019 * **Valid label** -- in a data framework, this is a label, which is already recomputed in the scope of regeneration sequence and includes the label containing a feature which is to be recalculated. Consider the case of a box to which you first add a fillet, then a protrusion feature. For recalculation purposes, only valid labels of each construction stage are used. In recalculating a fillet, they are only those of the box and the fillet, not the protrusion feature which was added afterwards.   
2020
2021 @section occt_ocaf_11 Samples
2022
2023 @subsection occt_ocaf_11_a Getting  Started
2024
2025   At the beginning of your development, you first define  an application class by inheriting from the Application abstract class. 
2026   You only have to create and determine the resources of the application 
2027   for specifying the format of your documents (you generally use the standard one)  and their file extension.  
2028    
2029   Then, you design the application data model by  organizing attributes you choose among those provided with OCAF. 
2030   You can specialize these attributes using the User attribute. For example, if you need  a reflection coefficient, 
2031   you aggregate a User attribute identified as a  reflection coefficient 
2032   with a Real attribute containing the value of the  coefficient (as such, you don't define a new class).  
2033    
2034   If you need application specific data not provided with  OCAF, for example, 
2035   to incorporate a finite element model in the data structure,  
2036   you define a new attribute class containing the mesh, 
2037   and you include its persistent homologue in a new file format.  
2038    
2039   Once you have implemented the commands which create and modify the data structure 
2040   according to your specification, OCAF provides you, without any additional programming:  
2041    
2042   * Persistent  reference to any data, including geometric elements — several documents can be  linked with such reference;
2043   * Document-View  association;
2044   * Ready-to-use  functions such as :
2045     * Undo-redo;  
2046     * Save and open application data.  
2047  
2048   Finally, you  develop the application's graphical user interface using the toolkit of your  choice, for example:
2049   * KDE Qt or  GNOME GTK+ on Linux;
2050   * Microsoft  Foundation Classes (MFC) on Windows Motif on Sun;
2051   * Other  commercial products such as Ilog Views.
2052  
2053   You can also implement the user interface in the Java language using 
2054   the Swing-based Java Application Desktop component (JAD)  provided with OCAF.  
2055   
2056 @subsection occt_ocaf_11_b An example of OCAF usage
2057
2058 To create a useful OCAF-based application, it is necessary to redefine two deferred methods: <i> Formats</i> and <i> ResourcesName</i>
2059
2060 In the <i> Formats </i> method, add the format of the documents, which need to be read by the application and may have been built in other applications.
2061
2062 For example:
2063
2064 ~~~~
2065     void myApplication::Formats(TColStd_SequenceOfExtendedString& Formats)
2066     {
2067       Formats.Append(TCollection_ExtendedString ("OCAF-myApplication"));
2068     }
2069 ~~~~
2070
2071 In the <i> ResourcesName</i> method, you only define the name of the resource file. This
2072 file contains several definitions for the saving and opening mechanisms associated
2073 with each format and calling of the plug-in file.
2074
2075 ~~~~
2076     Standard_CString myApplication::ResourcesName()
2077     {
2078       return Standard_CString ("Resources");
2079     }
2080 ~~~~
2081
2082 To obtain the saving and opening mechanisms, it is necessary to set two environment variables: <i> CSF_PluginDefaults</i>, which defines the path of the plug-in file, and <i> CSF_ResourcesDefault</i>, which defines the resource file:
2083
2084 ~~~~
2085     SetEnvironmentVariable ( "CSF_ResourcesDefaults",myDirectory);
2086     SetEnvironmentVariable ( "CSF_PluginDefaults",myDirectory);
2087 ~~~~
2088
2089 The plugin and the resource files of the application will be located in <i> myDirector</i>.
2090 The name of the plugin file must be <i>Plugin</i>.
2091
2092 ### Resource File
2093
2094 The resource file describes the documents (type and extension) and 
2095 the type of data that the application can manipulate 
2096 by identifying the storage and retrieval drivers appropriate for this data.
2097
2098 Each driver is unique and identified by a GUID generated, for example, with the <i> uuidgen </i> tool in Windows.
2099
2100 Five drivers are required to use all standard attributes provided within OCAF:
2101
2102   * the schema driver (ad696002-5b34-11d1-b5ba-00a0c9064368)
2103   * the document storage driver (ad696000-5b34-11d1-b5ba-00a0c9064368)
2104   * the document retrieval driver (ad696001-5b34-11d1-b5ba-00a0c9064368)
2105   * the attribute storage driver (47b0b826-d931-11d1-b5da-00a0c9064368)
2106   * the attribute retrieval driver (47b0b827-d931-11d1-b5da-00a0c9064368)
2107
2108 These drivers are provided as plug-ins and are located in the <i> PappStdPlugin</i> library.
2109
2110
2111 For example, this is a resource file, which declares a new model document OCAF-MyApplication:
2112
2113 ~~~~
2114 formatlist:OCAF-MyApplication
2115 OCAF-MyApplication.Description: MyApplication Document Version 1.0
2116 OCAF-MyApplication.FileExtension: sta
2117 OCAF-MyApplication.StoragePlugin: ad696000-5b34-11d1-b5ba-00a0c9064368
2118 OCAF-MyApplication.RetrievalPlugin: ad696001-5b34-11d1-b5ba-00a0c9064368
2119 OCAF-MyApplicationSchema: ad696002-5b34-11d1-b5ba-00a0c9064368
2120 OCAF-MyApplication.AttributeStoragePlugin: 47b0b826-d931-11d1-b5da-00a0c9064368
2121 OCAF-MyApplication.AttributeRetrievalPlugin: 47b0b827-d931-11d1-b5da-00a0c9064368
2122 ~~~~
2123  
2124   
2125 ### Plugin File
2126
2127 The plugin file describes the list of required plug-ins to run the application and the
2128 libraries in which plug-ins are located.
2129
2130 You need at least the <i> FWOSPlugin</i> and the plug-in drivers to run an OCAF application.
2131
2132 The syntax of each item is <i> Identification.Location Library_Name, </i> where:
2133 * Identification is GUID.
2134 * Location defines the location of the Identification (where its definition is found).
2135 * Library_Name is the name (and path to) the library, where the plug-in is located.
2136
2137 For example, this is a Plugin file:
2138
2139 ~~~~
2140 a148e300-5740-11d1-a904-080036aaa103.Location: FWOSPlugin
2141 ! base document drivers plugin
2142 ad696000-5b34-11d1-b5ba-00a0c9064368.Location: PAppStdPlugin
2143 ad696001-5b34-11d1-b5ba-00a0c9064368.Location: PAppStdPlugin
2144 ad696002-5b34-11d1-b5ba-00a0c9064368.Location: PAppStdPlugin
2145 47b0b826-d931-11d1-b5da-00a0c9064368.Location: PAppStdPlugin
2146 47b0b827-d931-11d1-b5da-00a0c9064368.Location: PAppStdPlugin
2147 ~~~~
2148  
2149
2150
2151 @subsection occt_ocaf_11_1 Implementation of Attribute Transformation in a CDL file
2152
2153 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2154 class Transformation from MyPackage inherits Attribute from TDF 
2155
2156     ---Purpose: This attribute implements a transformation data container. 
2157
2158 uses 
2159
2160      Attribute       from TDF, 
2161      Label           from TDF, 
2162      GUID            from Standard, 
2163      RelocationTable from TDF, 
2164      Pnt             from gp, 
2165      Ax1             from gp, 
2166      Ax2             from gp, 
2167      Ax3             from gp, 
2168      Vec             from gp, 
2169      Trsf            from gp, 
2170      TrsfForm        from gp 
2171
2172 is 
2173
2174     ---Category: Static methods 
2175     --          =============== 
2176
2177     GetID (myclass)     
2178     ---C++: return const &    
2179     ---Purpose: The method returns a unique GUID of this attribute. 
2180     --          By means of this GUID this attribute may be identified   
2181     --          among other attributes attached to the same label. 
2182     returns GUID from Standard; 
2183
2184     Set (myclass; theLabel : Label from TDF) 
2185     ---Purpose: Finds or creates the attribute attached to <theLabel>. 
2186     --          The found or created attribute is returned. 
2187     returns Transformation from MyPackage; 
2188
2189
2190     ---Category: Methods for access to the attribute data 
2191     --           ======================================== 
2192       
2193     Get (me) 
2194     ---Purpose: The method returns the transformation. 
2195     returns Trsf from gp; 
2196
2197
2198     ---Category: Methods for setting the data of transformation 
2199     --           ============================================== 
2200
2201     SetRotation (me : mutable; 
2202                          theAxis : Ax1 from gp; 
2203                          theAngle : Real from Standard); 
2204     ---Purpose: The method defines a rotation type of transformation. 
2205
2206     SetTranslation (me : mutable; 
2207                             theVector : Vec from gp); 
2208     ---Purpose: The method defines a translation type of transformation. 
2209
2210     SetMirror (me : mutable; 
2211                    thePoint : Pnt from gp); 
2212     ---Purpose: The method defines a point mirror type of transformation 
2213     --          (point symmetry). 
2214
2215     SetMirror (me : mutable; 
2216                    theAxis : Ax1 from gp); 
2217     ---Purpose: The method defines an axis mirror type of transformation 
2218     --          (axial symmetry). 
2219
2220     SetMirror (me : mutable; 
2221                    thePlane : Ax2 from gp); 
2222     ---Purpose: The method defines a point mirror type of transformation 
2223     --          (planar symmetry). 
2224
2225     SetScale (me : mutable; 
2226                   thePoint : Pnt from gp; 
2227                   theScale : Real from Standard); 
2228     ---Purpose: The method defines a scale type of transformation. 
2229
2230     SetTransformation (me : mutable; 
2231                                theCoordinateSystem1 : Ax3 from gp; 
2232                                theCoordinateSystem2 : Ax3 from gp); 
2233     ---Purpose: The method defines a complex type of transformation 
2234     --          from one co-ordinate system to another. 
2235
2236
2237     ---Category: Overridden methods from TDF_Attribute 
2238     --           ===================================== 
2239       
2240     ID (me) 
2241     ---C++: return const &   
2242     ---Purpose: The method returns a unique GUID of the attribute. 
2243     --          By means of this GUID this attribute may be identified   
2244     --          among other attributes attached to the same label. 
2245     returns GUID from Standard; 
2246
2247     Restore (me: mutable;   
2248                  theAttribute : Attribute from TDF); 
2249     ---Purpose: The method is called on Undo / Redo. 
2250     --          It copies the content of <theAttribute> 
2251     --          into this attribute (copies the fields). 
2252
2253     NewEmpty (me) 
2254     ---Purpose: It creates a new instance of this attribute. 
2255     --          It is called on Copy / Paste, Undo / Redo. 
2256     returns mutable Attribute from TDF; 
2257
2258     Paste (me;   
2259                theAttribute : mutable Attribute from TDF; 
2260                theRelocationTable : mutable RelocationTable from TDF); 
2261     ---Purpose:: The method is called on Copy / Paste. 
2262     --           It copies the content of this attribute into 
2263     --           <theAttribute> (copies the fields). 
2264
2265     Dump(me; anOS : in out OStream from Standard) 
2266     ---C++: return; 
2267     ---Purpose: Prints the content of this attribute into the stream. 
2268     returns OStream from Standard is redefined; 
2269
2270
2271     ---Category: Constructor 
2272     --           =========== 
2273
2274     Create 
2275     ---Purpose: The C++ constructor of this atribute class. 
2276     --          Usually it is never called outside this class. 
2277     returns mutable Transformation from MyPackage;      
2278
2279
2280 fields 
2281
2282     -- Type of transformation 
2283     myType : TrsfForm from gp; 
2284
2285     -- Axes (Ax1, Ax2, Ax3) 
2286     myAx1 : Ax1 from gp; 
2287     myAx2 : Ax2 from gp; 
2288     myFirstAx3 : Ax3 from gp; 
2289     mySecondAx3 : Ax3 from gp; 
2290       
2291     -- Scalar values 
2292     myAngle : Real from Standard; 
2293     myScale : Real from Standard; 
2294       
2295     -- Points 
2296     myFirstPoint : Pnt from gp; 
2297     mySecondPoint : Pnt from gp; 
2298
2299
2300 end Transformation; 
2301 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2302
2303 @subsection occt_ocaf_11_2 Implementation of Attribute Transformation in a CPP file
2304
2305 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
2306 #include MyPackage_Transformation.ixx; 
2307
2308 //======================================================================= 
2309 //function : GetID 
2310 //purpose  : The method returns a unique GUID of this attribute. 
2311 //           By means of this GUID this attribute may be identified   
2312 //           among other attributes attached to the same label. 
2313 //======================================================================= 
2314 const Standard_GUID& MyPackage_Transformation::GetID()   
2315
2316   static Standard_GUID ID("4443368E-C808-4468-984D-B26906BA8573"); 
2317   return ID; 
2318
2319
2320 //======================================================================= 
2321 //function : Set 
2322 //purpose  : Finds or creates the attribute attached to <theLabel>. 
2323 //           The found or created attribute is returned. 
2324 //======================================================================= 
2325 Handle(MyPackage_Transformation) MyPackage_Transformation::Set(const TDF_Label& theLabel)   
2326
2327   Handle(MyPackage_Transformation) T; 
2328   if (!theLabel.FindAttribute(MyPackage_Transformation::GetID(), T))   
2329   { 
2330     T = new MyPackage_Transformation();   
2331     theLabel.AddAttribute(T); 
2332   } 
2333   return T; 
2334
2335
2336 //======================================================================= 
2337 //function : Get 
2338 //purpose  : The method returns the transformation. 
2339 //======================================================================= 
2340 gp_Trsf MyPackage_Transformation::Get() const 
2341
2342   gp_Trsf transformation; 
2343   switch (myType) 
2344   { 
2345     case gp_Identity: 
2346     { 
2347       break; 
2348     } 
2349     case gp_Rotation: 
2350     { 
2351       transformation.SetRotation(myAx1, myAngle); 
2352       break; 
2353     } 
2354     case gp_Translation: 
2355     { 
2356       transformation.SetTranslation(myFirstPoint, mySecondPoint); 
2357       break; 
2358     } 
2359     case gp_PntMirror: 
2360     { 
2361       transformation.SetMirror(myFirstPoint); 
2362       break; 
2363     } 
2364     case gp_Ax1Mirror: 
2365     { 
2366       transformation.SetMirror(myAx1); 
2367       break; 
2368     } 
2369     case gp_Ax2Mirror: 
2370     { 
2371       transformation.SetMirror(myAx2); 
2372       break; 
2373     } 
2374     case gp_Scale: 
2375     { 
2376       transformation.SetScale(myFirstPoint, myScale); 
2377       break; 
2378     } 
2379     case gp_CompoundTrsf: 
2380     { 
2381       transformation.SetTransformation(myFirstAx3, mySecondAx3); 
2382       break; 
2383     } 
2384     case gp_Other: 
2385     { 
2386       break; 
2387     } 
2388   } 
2389   return transformation; 
2390
2391
2392 //======================================================================= 
2393 //function : SetRotation 
2394 //purpose  : The method defines a rotation type of transformation. 
2395 //======================================================================= 
2396 void MyPackage_Transformation::SetRotation(const gp_Ax1& theAxis, const Standard_Real theAngle) 
2397
2398   Backup(); 
2399   myType = gp_Rotation; 
2400   myAx1 = theAxis; 
2401   myAngle = theAngle; 
2402
2403
2404 //======================================================================= 
2405 //function : SetTranslation 
2406 //purpose  : The method defines a translation type of transformation. 
2407 //======================================================================= 
2408 void MyPackage_Transformation::SetTranslation(const gp_Vec& theVector) 
2409
2410   Backup(); 
2411   myType = gp_Translation; 
2412   myFirstPoint.SetCoord(0, 0, 0); 
2413   mySecondPoint.SetCoord(theVector.X(), theVector.Y(), theVector.Z()); 
2414
2415
2416 //======================================================================= 
2417 //function : SetMirror 
2418 //purpose  : The method defines a point mirror type of transformation 
2419 //           (point symmetry). 
2420 //======================================================================= 
2421 void MyPackage_Transformation::SetMirror(const gp_Pnt& thePoint) 
2422
2423   Backup(); 
2424   myType = gp_PntMirror; 
2425   myFirstPoint = thePoint; 
2426
2427
2428 //======================================================================= 
2429 //function : SetMirror 
2430 //purpose  : The method defines an axis mirror type of transformation 
2431 //           (axial symmetry). 
2432 //======================================================================= 
2433 void MyPackage_Transformation::SetMirror(const gp_Ax1& theAxis) 
2434
2435   Backup(); 
2436   myType = gp_Ax1Mirror; 
2437   myAx1 = theAxis; 
2438
2439
2440 //======================================================================= 
2441 //function : SetMirror 
2442 //purpose  : The method defines a point mirror type of transformation 
2443 //           (planar symmetry). 
2444 //======================================================================= 
2445 void MyPackage_Transformation::SetMirror(const gp_Ax2& thePlane) 
2446
2447   Backup(); 
2448   myType = gp_Ax2Mirror; 
2449   myAx2 = thePlane; 
2450
2451
2452 //======================================================================= 
2453 //function : SetScale 
2454 //purpose  : The method defines a scale type of transformation. 
2455 //======================================================================= 
2456 void MyPackage_Transformation::SetScale(const gp_Pnt& thePoint, const Standard_Real theScale) 
2457
2458   Backup(); 
2459   myType = gp_Scale; 
2460   myFirstPoint = thePoint; 
2461   myScale = theScale; 
2462
2463
2464 //======================================================================= 
2465 //function : SetTransformation 
2466 //purpose  : The method defines a complex type of transformation 
2467 //           from one co-ordinate system to another. 
2468 //======================================================================= 
2469 void MyPackage_Transformation::SetTransformation(const gp_Ax3& theCoordinateSystem1,   
2470                                                                          const gp_Ax3& theCoordinateSystem2) 
2471
2472   Backup(); 
2473   myFirstAx3 = theCoordinateSystem1; 
2474   mySecondAx3 = theCoordinateSystem2; 
2475
2476
2477 //======================================================================= 
2478 //function : ID 
2479 //purpose  : The method returns a unique GUID of the attribute. 
2480 //           By means of this GUID this attribute may be identified   
2481 //           among other attributes attached to the same label. 
2482 //======================================================================= 
2483 const Standard_GUID& MyPackage_Transformation::ID() const   
2484 {   
2485   return GetID();   
2486
2487
2488 //======================================================================= 
2489 //function : Restore 
2490 //purpose  : The method is called on Undo / Redo. 
2491 //           It copies the content of <theAttribute> 
2492 //           into this attribute (copies the fields). 
2493 //======================================================================= 
2494 void MyPackage_Transformation::Restore(const Handle(TDF_Attribute)& theAttribute)   
2495
2496   Handle(MyPackage_Transformation) theTransformation = Handle(MyPackage_Transformation)::DownCast(theAttribute); 
2497   myType = theTransformation->myType; 
2498   myAx1 = theTransformation->myAx1; 
2499   myAx2 = theTransformation->myAx2; 
2500   myFirstAx3 = theTransformation->myFirstAx3; 
2501   mySecondAx3 = theTransformation->mySecondAx3; 
2502   myAngle = theTransformation->myAngle; 
2503   myScale = theTransformation->myScale; 
2504   myFirstPoint = theTransformation->myFirstPoint; 
2505   mySecondPoint = theTransformation->mySecondPoint; 
2506
2507
2508 //======================================================================= 
2509 //function : NewEmpty 
2510 //purpose  : It creates a new instance of this attribute. 
2511 //           It is called on Copy / Paste, Undo / Redo. 
2512 //======================================================================= 
2513 Handle(TDF_Attribute) MyPackage_Transformation::NewEmpty() const 
2514 {    
2515   return new MyPackage_Transformation();   
2516
2517
2518 //======================================================================= 
2519 //function : Paste 
2520 //purpose  : The method is called on Copy / Paste. 
2521 //           It copies the content of this attribute into 
2522 //           <theAttribute> (copies the fields). 
2523 //======================================================================= 
2524 void MyPackage_Transformation::Paste(const Handle(TDF_Attribute)& theAttribute, 
2525                                                      const Handle(TDF_RelocationTable)& ) const 
2526
2527   Handle(MyPackage_Transformation) theTransformation = Handle(MyPackage_Transformation)::DownCast(theAttribute); 
2528   theTransformation->myType = myType; 
2529   theTransformation->myAx1 = myAx1; 
2530   theTransformation->myAx2 = myAx2; 
2531   theTransformation->myFirstAx3 = myFirstAx3; 
2532   theTransformation->mySecondAx3 = mySecondAx3; 
2533   theTransformation->myAngle = myAngle; 
2534   theTransformation->myScale = myScale; 
2535   theTransformation->myFirstPoint = myFirstPoint; 
2536   theTransformation->mySecondPoint = mySecondPoint; 
2537
2538
2539 //======================================================================= 
2540 //function : Dump 
2541 //purpose  : Prints the content of this attribute into the stream. 
2542 //======================================================================= 
2543 Standard_OStream& MyPackage_Transformation::Dump(Standard_OStream& anOS) const 
2544 {    
2545   anOS = "Transformation: "; 
2546   switch (myType) 
2547   { 
2548     case gp_Identity: 
2549     { 
2550       anOS = "gp_Identity"; 
2551       break; 
2552     } 
2553     case gp_Rotation: 
2554     { 
2555       anOS = "gp_Rotation"; 
2556       break; 
2557     } 
2558     case gp_Translation: 
2559     { 
2560       anOS = "gp_Translation"; 
2561       break; 
2562     } 
2563     case gp_PntMirror: 
2564     { 
2565       anOS = "gp_PntMirror"; 
2566       break; 
2567     } 
2568     case gp_Ax1Mirror: 
2569     { 
2570       anOS = "gp_Ax1Mirror"; 
2571       break; 
2572     } 
2573     case gp_Ax2Mirror: 
2574     { 
2575       anOS = "gp_Ax2Mirror"; 
2576       break; 
2577     } 
2578     case gp_Scale: 
2579     { 
2580       anOS = "gp_Scale"; 
2581       break; 
2582     } 
2583     case gp_CompoundTrsf: 
2584     { 
2585       anOS = "gp_CompoundTrsf"; 
2586       break; 
2587     } 
2588     case gp_Other: 
2589     { 
2590       anOS = "gp_Other"; 
2591       break; 
2592     } 
2593   } 
2594   return anOS; 
2595
2596
2597 //=======================================================================
2598 //function : MyPackage_Transformation 
2599 //purpose  : A constructor. 
2600 //=======================================================================
2601 MyPackage_Transformation::MyPackage_Transformation():myType(gp_Identity){ 
2602
2603 }
2604 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2605
2606 @subsection occt_ocaf_11_3  Implementation of typical actions with standard OCAF attributes.
2607
2608 There are four sample files provided in the directory 'OpenCasCade/ros/samples/ocafsamples'. They present typical actions with OCAF services (mainly for newcomers). 
2609 The method *Sample()* of each file is not dedicated for execution 'as is', it is rather a set of logical actions using some OCAF services.
2610
2611 ### TDataStd_Sample.cxx
2612 This sample contains templates for typical actions with the following standard OCAF attributes:
2613 - Starting with data framework;
2614 - TDataStd_Integer attribute management;
2615 - TDataStd_RealArray attribute management;
2616 - TDataStd_Comment attribute management;
2617 - TDataStd_Name attribute management;
2618 - TDataStd_UAttribute attribute management;
2619 - TDF_Reference attribute management;
2620 - TDataXtd_Point attribute management;
2621 - TDataXtd_Plane attribute management;
2622 - TDataXtd_Axis attribute management;
2623 - TDataXtd_Geometry attribute management;
2624 - TDataXtd_Constraint attribute management;
2625 - TDataStd_Directory attribute management;
2626 - TDataStd_TreeNode attribute management.
2627   
2628 ### TDocStd_Sample.cxx
2629 This sample contains template for the following typical actions:
2630 - creating application;
2631 - creating the new document (document contains a framework);
2632 - retrieving the document from a label of its framework;
2633 - filling a document with data;
2634 - saving a document in the file;
2635 - closing a document;
2636 - opening the document stored in the file;
2637 - copying content of a document to another document with possibility to update the copy in the future.
2638  
2639 ### TPrsStd_Sample.cxx
2640 This sample contains template for the following typical actions:
2641 - starting with data framework;
2642 - setting the TPrsStd_AISViewer in the framework;
2643 - initialization of aViewer;
2644 - finding TPrsStd_AISViewer attribute in the DataFramework;
2645 - getting AIS_InteractiveContext from TPrsStd_AISViewer;
2646 - adding driver to the map of drivers;
2647 - getting driver from the map of drivers;
2648 - setting TNaming_NamedShape to \<ShapeLabel\>;
2649 - setting the new  TPrsStd_AISPresentation to \<ShapeLabel\>;
2650 - displaying;
2651 - erasing;
2652 - updating and displaying presentation of the attribute to be displayed;
2653 - setting a color to the displayed attribute;
2654 - getting transparency of the displayed attribute;
2655 -  modify attribute;
2656 - updating presentation of the attribute in viewer.
2657
2658 ### TNaming_Sample.cxx
2659 This sample contains template for typical actions with OCAF Topological Naming services.
2660 The following scenario is used:
2661 - data framework initialization;
2662 - creating Box1 and pushing it as PRIMITIVE in DF;
2663 - creating Box2 and pushing it as PRIMITIVE in DF;
2664 - moving Box2 (applying a transformation);
2665 - pushing the selected edges of the top face of Box1 in DF;
2666 - creating a Fillet (using the selected edges) and pushing the result as a modification of Box1;
2667 - creating a Cut (Box1, Box2) as a modification of Box1 and push it in DF;
2668 - recovering the result from DF.
2669