0031918: Application Framework - New binary format for fast reading part of OCAF...
[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.
10
11 @subsection occt_ocaf_1_1 Purpose of OCAF
12
13 OCAF (the Open CASCADE Application Framework) is an  easy-to-use platform for rapidly developing
14   sophisticated domain-specific  design applications. 
15   A typical application developed using OCAF deals with two or three-dimensional (2D or 3D) geometric modeling 
16   in trade-specific Computer Aided Design (CAD) systems, manufacturing or analysis applications, 
17   simulation  applications or illustration tools. 
18   
19   Developing a design application requires addressing many technical aspects. 
20   In particular, given the functional specification of your application, you must at least:  
21   
22   * Design the  architecture of the application— definition of the software components and the way they cooperate;
23   * Define the  data model able to support the functionality required — a design application  operates on data maintained during the whole end-user working session;
24   * Structure  the software in order to:
25     * synchronize the display with the  data — commands modifying objects must update the views;  
26     * support generalized undo-redo  commands — this feature has to be taken into account very early in the design  process;  
27   * 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;
28   * Build the  application user interface.
29  
30 Architectural guidance and ready-to-use solutions provided by OCAF offer you the following benefits:
31   * You can concentrate on the functionality specific for your application;  
32   * The underlying mechanisms required to support the application are already provided; 
33   * The application can be rapidly be prototyped thanks to the coupling the other Open CASCADE Technology modules;
34   * The final application can be developed by industrializing the prototype — you don't need to restart the development from scratch. 
35   * The Open Source nature of the platform guarantees the long-term usefulness of your development.   
36
37 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. 
38
39 The table below contrasts the design of a modeling application using object libraries alone and using OCAF. 
40
41 **Table 1: Services provided by OCAF** 
42
43 |Development tasks      |Comments | Without OCAF        | With OCAF |
44 |------------------:|---------:|---------------:|-----------:|
45 |Creation of geometry| Algorithm Calling the modeling libraries |       To be created by the user       | To be created by the user| 
46 | Data organization | Including specific attributes and modeling process | To be created by the user |  Simplified| 
47 | Saving data in a file | Notion of document | To be created by the user | Provided |
48 | Document-view management |    |  To be created by the user | Provided |
49 | Application infrastructure | New, Open, Close, Save and Save As File menus | To be created by the user | Provided | 
50 | Undo-Redo | Robust, multi-level       | To be created by the user     | Provided |
51 | Application-specific dialog boxes     |    | To be created by the user  |     To be created by the user |
52
53 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.
54
55 The relationship between OCAF and the Open CASCADE Technology (**OCCT**) Object Libraries can be seen in the image below. 
56
57 @figure{/user_guides/ocaf/images/ocaf_image003.svg,"OCCT Architecture",360}
58
59 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. 
60  
61 The subsequent chapters of this document explain the concepts and show how to use the services of OCAF.
62
63 @subsection occt_ocaf_1_2 Architecture Overview
64
65 OCAF provides you with an object-oriented Application-Document-Attribute model consisting of C++ class libraries. 
66
67 @figure{ocaf_wp_image003.png,"The Application-Document-Attribute model",420}
68
69 @subsubsection occt_ocaf_1_2_1 Application
70
71 The *Application* is an abstract class in charge of handling documents during the working session, namely:  
72   * Creating new  documents;
73   * Saving documents and opening them;
74   * Initializing document views.
75   
76 @subsubsection occt_ocaf_1_2_2 Document   
77  
78   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: 
79
80   * Manage the notification of changes
81   * Update external links
82   * Manage the saving and restoring of data
83   * Store the names of software extensions.
84   * Manage command transactions
85   * Manage Undo and Redo options. 
86   
87   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).  
88
89   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.   
90   
91 @subsubsection occt_ocaf_1_2_3 Attribute
92
93   Application data is described by **Attributes**, which are instances of  classes derived from the *Attribute* abstract class, organized according to the OCAF Data  Framework. 
94   
95   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:    
96   
97   * @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)....;
98   * @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;
99   * Other  geometric attributes such as **Datums** (points, axis and plane) and **Constraints** (*tangent-to, at-a-given-distance, from-a-given-angle, concentric,* etc.)
100   * User  attributes, that is, attributes typed by the application  
101   * @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.
102   * @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. 
103   
104 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:
105     * Copying the  attribute
106     * Converting  it from and persistent data storage
107         
108 @subsection occt_ocaf_1_3  Reference-key model
109
110   In most existing geometric modeling systems, the data are topology driven. 
111   They usually use a boundary representation (BRep), where geometric models 
112   are defined by a collection of faces, edges and vertices, 
113   to which application data are attached. Examples of data include:  
114  
115   * a color;
116   * a material;
117   * information that a particular edge is blended.
118  
119   When the geometric model is parameterized, that is, when you can change 
120   the value of parameters used to build the model (the radius of a  blend, the thickness of a rib, etc.), 
121   the geometry is highly subject to change. 
122   In order to maintain the attachment of application data, the geometry must be  distinguished from other data.  
123    
124   In OCAF, the data are reference-key driven. It is a  uniform model in which reference-keys 
125   are the persistent identification of  data. All **accessible** data, including the geometry, 
126   are implemented as attributes attached to reference-keys. 
127   The geometry becomes the  value of the Shape attribute, just as a number is the value 
128   of the Integer and  Real attributes and a string that of the Name attribute.  
129    
130   On a single reference-key, many attributes can be  aggregated; 
131   the application can ask at runtime which attributes are available. 
132   For example, to associate a texture to a face in a geometric model, 
133   both the face and the texture are attached to the same reference-key.  
134  
135 @figure{ocaf_image004.png,"Topology driven versus reference-key driven approaches",360}
136
137  Reference-keys can be created in two ways:   
138  
139   * At  programming time, by the application
140   * At runtime,  by the end-user of the application (providing that you include this capability  in the application)
141  
142   As an application developer, you generate reference-keys in order to give semantics to the data. 
143   For example, a function building a  prism may create three reference-keys: 
144   one for the base of the prism, a second  for the lateral faces and a third for the top face. 
145   This makes up a semantic  built-in the application's prism feature.
146   On the other hand, in a command  allowing the end-user to set a texture to a face he/she selects, 
147   you must create  a reference-key to the selected face 
148   if it has not previously been referenced in any feature 
149   (as in the case of one of the lateral faces of the prism).  
150  
151   When you create a reference-key to selected topological  elements (faces, edges or vertices), 
152   OCAF attaches to the reference-key  information defining the selected topology — the Naming attribute. 
153   For example,  it may be the faces to which a selected edge is common to. 
154   This information, as  well as information about the evolution of the topology at each modeling step 
155   (the modified, updated and deleted faces), is used by the naming algorithm to  maintain the topology 
156   attached to the reference-key. As such, on a  parametrized model, 
157   after modifying the value of a parameter, the reference-keys still address the appropriate faces, 
158   even if their geometry has  changed. 
159   Consequently, you change the size of the cube shown in the figure above, 
160   the user texture stay attached to the right face.  
161  
162   <b>Note</b> As Topological naming is based on the reference-key and attributes such as Naming 
163   (selection information) and Shape (topology evolution  information), 
164   OCAF is not coupled to the underlying modeling libraries. 
165   The  only modeling services required by OCAF are the following:  
166
167   * Each  algorithm must provide information about the evolution of the topology 
168    (the  list of faces modified, updated and deleted by the algorithm)
169   * Exploration  of the geometric model must be available 
170    (a 3D model is made of faces bounded  by close wires, 
171    themselves composed by a sequence of edges connected by their  vertices)
172  
173   Currently, OCAF uses the Open CASCADE Technology  modeling libraries.   
174  
175   To design an OCAF-based data model, the application  developer is encouraged to aggregate 
176   ready-to-use attributes instead of defining new attributes by inheriting from an abstract root class.  
177   There are two major advantages in using aggregation  rather than inheritance:
178   
179   * As you don't  implement data by defining new classes, the format of saved data 
180     provided with OCAF doesn't change; so you don't have to write the Save and Open functions
181   * The application can query the data at runtime if a particular attribute is  available
182   
183 **Summary**
184
185   * OCAF is  based on a uniform reference-key model in which:
186     * Reference-keys provide  persistent identification of data;  
187     * Data, including geometry, are  implemented as attributes attached to reference-keys;  
188     * Topological naming maintains the  selected geometry attached to reference-keys in parametrized models; 
189   * In many  applications, the data format provided with OCAF doesn't need to be extended;
190   * OCAF is not  coupled to the underlying modeling libraries.
191   
192   
193 @section occt_ocaf_3 The Data  Framework
194  
195 @subsection occt_ocaf_3_1 Data Structure
196  
197   The OCAF Data Framework is the Open CASCADE Technology  realization 
198   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.
199   
200
201 The building blocks of this approach are: 
202
203   * The tag
204   * The label
205   * The attribute
206
207 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. 
208
209 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. 
210
211 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. 
212
213 The most important property is that a label’s entry is its persistent address in the data framework. 
214   
215 @figure{/user_guides/ocaf/images/ocaf_image005.png,"A simple framework model",216}
216
217 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. 
218
219 The children of a root label are middle-level labels with tags 1 and 3. These labels are brothers. 
220
221 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). 
222
223 @subsection occt_ocaf_3_2 Examples of a Data Structure
224
225 Let's have a look at the example:
226   
227 @figure{ocaf_wp_image007.png,"The coffee machine",200}
228   
229    In the image the application for designing coffee  machines first allocates 
230   a label for the machine unit. It then adds sub-labels  for the main features 
231   (glass coffee pot, water receptacle and filter) which it  refines as needed 
232   (handle and reservoir of the coffee pot and spout of the  reservoir). 
233   
234   You now attach technical data describing the handle — its geometry and color — 
235   and the reservoir — its geometry and material. 
236   Later on, you can  modify the handle's geometry without changing its color — 
237   both remain attached  to the same label.  
238   
239 @figure{ocaf_wp_image005.png,"The data structure of the coffee machine",361}
240  
241   The nesting of labels is key to OCAF. This allows a  label to have its own structure 
242   with its local addressing scheme which can be  reused in a more complex structure. 
243   Take, for example, the coffee machine.  Given that the coffee pot's handle has a label of tag [1], 
244   the entry for the handle in  the context of the coffee pot only (without the machine unit) is [0:1:1]. 
245   If you now model a coffee  machine with two coffee pots, one at the label [1], 
246   the second at the label [4] in the machine unit, 
247   the handle  of the first pot would have the entry [0:1:1:1] 
248   whereas the handle of the second pot would be [0:1:4:1]. 
249   This way, we avoid any  confusion between coffee pot handles.
250
251 Another example is the application for designing table lamps. The first label is allocated to the lamp unit. 
252
253 @figure{/user_guides/ocaf/images/ocaf_image006.png,"",200}
254
255 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: 
256
257   * a lamp-shade label with tag 1
258   * a bulb label with tag 2
259   * a stem label with tag 3
260
261 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. 
262
263 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. 
264
265 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. 
266
267 @figure{/user_guides/ocaf/images/ocaf_image007.png,"",360}
268
269
270 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. 
271
272 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. 
273
274 Note that the root label can have attributes too, usually global attributes: the name of the document, for example. 
275
276 @subsection occt_ocaf_3_3 Tag
277
278 A tag is an integer, which identifies a label in two ways: 
279
280   * Relative identification
281   * Absolute identification.
282
283 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. 
284
285 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. 
286
287 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. 
288
289 The tag can be created in two ways: 
290
291   * Random delivery
292   * User-defined delivery
293
294 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. 
295
296 @subsubsection occt_ocaf_3_3_1 Creating child labels using random delivery of tags
297
298 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*. 
299
300
301 ~~~~{.cpp}
302 TDF_Label child1 = TDF_TagSource::NewChild (level2); 
303 TDF_Label child2 = TDF_TagSource::NewChild (level2); 
304 ~~~~
305
306 @subsubsection occt_ocaf_3_3_2 Creation of a child label by user delivery from a tag
307
308 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. 
309
310 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. 
311
312
313 ~~~~{.cpp}
314 TDF_Label achild = root.FindChild(3,Standard_False); 
315 if (!achild.IsNull()) { 
316 Standard_Integer tag = achild.Tag(); 
317
318 ~~~~
319
320 @subsection occt_ocaf_3_4 Label
321
322 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.
323
324 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. 
325
326 @subsubsection occt_ocaf_3_4_1 Label creation
327
328 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. 
329
330 @subsubsection occt_ocaf_3_4_2 Creating child labels
331
332 To create a new child label in the data framework using explicit delivery of tags, use *TDF_Label::FindChild*. 
333
334
335 ~~~~{.cpp}
336 //creating a label with tag 10 at Root 
337 TDF_Label lab1 = aDF->Root().FindChild(10); 
338
339 //creating labels 7 and 2 on label 10 
340 TDF_Label lab2 = lab1.FindChild(7); 
341
342 TDF_Label lab3 = lab1.FindChild(2); 
343 ~~~~
344 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. 
345
346
347 ~~~~{.cpp}
348 TDF_Label level1 = root.FindChild(3,Standard_True); 
349 TDF_Label level2 = level1.FindChild(1,Standard_True); 
350 ~~~~
351 @subsubsection occt_ocaf_3_4_3 Retrieving child labels
352
353 You can retrieve child labels of your current label by iteration on the first level in the scope of this label. 
354
355
356 ~~~~{.cpp}
357 TDF_Label current; 
358 // 
359 for (TDF_ChildIterator it1 (current,Standard_False); it1.More(); it1.Next()) { 
360 achild = it1.Value(); 
361 // 
362 // do something on a child (level 1) 
363 // 
364
365 ~~~~
366 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. 
367 ~~~~{.cpp}
368 for (TDF_ChildIterator itall (current,Standard_True); itall.More(); itall.Next()) { 
369 achild = itall.Value(); 
370 // 
371 // do something on a child (all levels) 
372 // 
373
374 ~~~~
375 Using *TDF_Tool::Entry* with *TDF_ChildIterator* you can retrieve the entries of your current label’s child labels as well. 
376
377  
378 ~~~~{.cpp}
379 void DumpChildren(const TDF_Label& aLabel) 
380
381   TDF_ChildIterator it; 
382   TCollection_AsciiString es; 
383   for (it.Initialize(aLabel,Standard_True); it.More(); it.Next()){ 
384     TDF_Tool::Entry(it.Value(),es); 
385     cout  <<  as.ToCString()  <<  endl; 
386   } 
387
388 ~~~~
389 @subsubsection occt_ocaf_3_4_4 Retrieving the father label
390
391 Retrieving the father label of a current label. 
392
393
394 ~~~~{.cpp}
395 TDF_Label father = achild.Father(); 
396 isroot = father.IsRoot(); 
397 ~~~~
398
399 @subsection occt_ocaf_3_5 Attribute
400
401 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. 
402
403 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. 
404
405 @subsubsection occt_ocaf_3_5_1 Retrieving an attribute from a label
406
407 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. 
408
409
410 ~~~~{.cpp}
411 if(current.FindAttribute(TDataStd_Integer::GetID(),INT)) 
412
413   // the attribute is found 
414
415 else 
416
417   // the attribute is not found 
418
419 ~~~~
420 @subsubsection occt_ocaf_3_5_2 Identifying an attribute using a GUID
421
422 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*. 
423
424
425 ~~~~{.cpp}
426 Handle(TDataStd_Integer) INT = new TDataStd_Integer(); 
427 Standard_GUID guid = INT->ID(); 
428 ~~~~
429
430 @subsubsection occt_ocaf_3_5_3 Attaching an attribute to a label
431
432 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. 
433
434 *TDF_Attribute::Label* for *INT* then returns the label *attach* to which *INT* is attached. 
435
436
437 ~~~~{.cpp}
438 current.Add (INT); // INT is now attached to current 
439 current.Add (INT); // causes failure 
440 TDF_Label attach = INT->Label(); 
441 ~~~~
442
443 Note. There is an exception from this rule for some sub-set of Standard attributes. See for details chapter 6.Standard Attributes.
444
445 @subsubsection occt_ocaf_3_5_4 Testing the attachment to a label
446
447 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. 
448
449 *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*. 
450
451
452 ~~~~{.cpp}
453 // Testing of attribute attachment 
454 // 
455 if (current.IsA(TDataStd_Integer::GetID())) { 
456 // the label has an Integer attribute attached 
457
458 if (current.HasAttribute()) { 
459 // the label has at least one attribute attached 
460 Standard_Integer nbatt = current.NbAttributes(); 
461 // the label has nbatt attributes attached 
462
463 ~~~~
464 @subsubsection occt_ocaf_3_5_5 Removing an attribute from a label
465
466 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*. 
467
468
469 ~~~~{.cpp}
470 current.Forget(TDataStd_Integer::GetID()); 
471 // integer attribute is now not attached to current label 
472 current.ForgetAll(); 
473 // current has now 0 attributes attached 
474 ~~~~
475 @subsubsection occt_ocaf_3_5_6 Specific attribute creation
476
477 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. 
478
479 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) 
480
481 In order to create a new attribute in the standard way, create a class inherited from *TDF_Attribute* and implement all purely virtual and necessary virtual methods:
482 * **ID()** -- returns a unique GUID of a given attribute 
483 * **Restore(attribute)** -- sets fields of this attribute equal to the fields of a given attribute of the same type 
484 * **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 . 
485 * **NewEmpty()** -- returns a new attribute of this class with empty fields 
486 * **Dump(stream)** --  outputs information about a given attribute to a given stream debug (usually outputs an attribute of type string only) 
487
488 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. 
489
490 To enable possibility to save / restore the new attribute in XML format, do the following: 
491   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).
492   2. Create a new package (or do it in the current one) with two package methods: 
493           * *Factory*, which loads the document storage and retrieval drivers; and 
494           * *AttributeDrivers*, which calls the methods AddDrivers for all packages responsible for persistence of the document.
495   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.
496
497 To enable possibility to save / restore the new attribute in binary format, do the following: 
498   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.
499   2. Create a new package (or do it in the current one) with two package methods: 
500           * Factory, which loads the document storage and retrieval drivers; and 
501           * AttributeDrivers, which calls the methods AddDrivers for all packages responsible for persistence of the document.
502   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.
503 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. 
504
505 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: 
506   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).
507   2. Create child labels and allocate all necessary data through standard attributes at the child labels.
508   3. Define an interface class for access to the data of the child labels.
509
510 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. 
511
512 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). 
513
514 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 samples__ocaf "Samples". 
515
516 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: 
517   * Type of transformation <i>(gp_Translation)</i> as *TDataStd_Integer*;
518   * First point as *TDataStd_RealArray* (three values: X1, Y1 and Z1);
519   * Second point as *TDataStd_RealArray* (three values: X2, Y2 and Z2).
520
521 @figure{/user_guides/ocaf/images/ocaf_image010.png,"Data tree for translation",240}
522
523 If the type of transformation is changed to rotation, the data tree looks like this: 
524   * Type of transformation <i>(gp_Rotation)</i> as *TDataStd_Integer*;
525   * Point of axis of rotation as *TDataStd_RealArray* (three values: X, Y and Z);
526   * Axis of rotation as *TDataStd_RealArray* (three values: DX, DY and DZ);
527   * Angle of rotation as *TDataStd_Real*.
528
529 @figure{/user_guides/ocaf/images/ocaf_image011.png,"Data tree for rotation",240}
530
531 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). 
532   
533 @subsection occt_ocaf_3_6 Compound documents
534  
535   As the identification of data is persistent, one document can reference data contained in another document, 
536   the referencing and  referenced documents being saved in two separate files.  
537  
538   Lets look at the coffee machine application again. The  coffee pot can be placed in one document. 
539   The coffee machine document then  includes an *occurrence* — a positioned copy — of the coffee pot. 
540   This occurrence is defined by an XLink attribute (the external Link) 
541   which references the coffee pot of the first document 
542   (the XLink contains the relative path of the coffee pot document and the entry of the coffee pot data [0:1] ).  
543
544 @figure{ocaf_wp_image006.png,"The coffee machine compound document",360}
545  
546   In this context, the end-user of the coffee machine application can open the coffee pot document, 
547   modify the geometry of, for  example, the reservoir, and overwrite the document without worrying 
548   about the impact of the modification in the coffee machine document. 
549   To deal with this  situation, OCAF provides a service which allows the application to check 
550   whether a document is up-to-date. This service is based on a modification counter included in each document: 
551   when an external link is created, a copy of  the referenced document counter is associated to the XLink 
552   in the referencing  document. Providing that each modification of the referenced document increments its own counter,   
553   we can detect that the referencing document has to  be updated by comparing the two counters 
554   (an update function importing the data  referenced by an XLink into the referencing document is also provided).  
555  
556  @subsection occt_ocaf_3_7 Transaction mechanism
557  
558   The Data Framework also provides a transaction mechanism inspired from database management systems: 
559   the data are modified within a transaction which is terminated either by a Commit 
560   if the modifications are validated  or by an Abort if the modifications are abandoned — 
561   the data are then restored  to the state it was in prior to the transaction. 
562   This mechanism is extremely useful for:
563
564   * Securing  editing operations (if an error occurs, the transaction is abandoned and the  structure retains its integrity)
565   * Simplifying  the implementation of the **Cancel** function (when the end-user begins a command, 
566   the application may launch a transaction and operate directly in the data structure; 
567   abandoning the action causes the transaction to Abort)
568   * Executing  **Undo** (at commit time, the modifications are recorded in order to be able to  restore the data to their previous state)
569  
570   The transaction mechanism simply manages a  backup copy of attributes. 
571   During a transaction, attributes are copied before  their first modification. 
572   If the transaction is validated, the copy is  destroyed. 
573   If the transaction is abandoned, the attribute is restored to its initial value 
574   (when attributes are added or deleted, the operation is simply  reversed).
575
576   Transactions are document-centered, that is, the application starts a transaction on a document. 
577   So, modifying a referenced  document and updating one of its referencing documents requires 
578   two transactions, even if both operations are done in the same working session.
579
580   
581 @section occt_ocaf_4_ Standard Document Services
582
583 @subsection occt_ocaf_4_1 Overview
584
585 Standard documents offer ready-to-use documents containing a TDF-based data framework. Each document can contain only one framework. 
586
587 The documents themselves are contained in the instantiation of a class *TDocStd_Application* (or its descendant). This application manages the creation, storage and retrieval of documents. 
588
589 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. 
590
591 To sum up, standard documents alone provide access to the data framework. They also allow you to: 
592
593   * Update external links
594   * Manage the saving and opening of data
595   * Manage the undo/redo functionality.
596
597
598 @subsection occt_ocaf_4_2 The Application
599
600 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 *TDocStd_Application* or a class inheriting from it. 
601
602 @subsubsection occt_ocaf_4_2_1 Creating an application
603
604 To create an application, use the following syntax. 
605
606 ~~~~{.cpp}
607 Handle(TDocStd_Application) app = new TDocStd_Application (); 
608 ~~~~
609
610 @subsubsection occt_ocaf_4_2_2 Creating a new document
611
612 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*. 
613
614 ~~~~{.cpp}
615 Handle(TDocStd_Document) doc; 
616 app->NewDocument("NewDocumentFormat", doc); 
617 ~~~~
618
619 Here "NewDocumentFormat" is identifier of the format of your document.
620 OCCT defines several standard formats, distinguishing by a set of supported OCAF attributes, and method of encoding (e.g. binary data or XML), described below.
621 If your application defines specific OCAF attributes, you need to define your own format for it.
622
623 @subsubsection occt_ocaf_4_2_3 Retrieving the application to which the document belongs
624
625 To retrieve the application containing your document, you use the syntax below. 
626
627 ~~~~{.cpp}
628 app = Handle(TDocStd_Application)::DownCast (doc->Application()); 
629 ~~~~
630 @subsection occt_ocaf_4_3 The Document
631
632 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. 
633
634 @subsubsection occt_ocaf_4_3_1 Accessing the main label of the framework
635
636 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. 
637
638 ~~~~{.cpp}
639 TDF_Label label = doc->Main(); 
640 ~~~~
641 @subsubsection occt_ocaf_4_3_2 Retrieving the document from a label in its framework
642
643 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*. 
644 ~~~~{.cpp}
645 doc = TDocStd_Document::Get(label); 
646 ~~~~
647
648 @subsubsection occt_ocaf_4_3_format Defining storage format
649
650 OCAF uses a customizable mechanism for storage of the documents.
651 In order to use OCAF persistence to save and read your documents to / from the file, you need to define one or several formats in your application.
652
653 For that, use method TDocStd_Application::DefineFormat(), for instance:
654 ~~~~{.cpp}
655 app->DefineFormat ("NewDocumentFormat", "New format for OCAF documents", "ndf",
656                    new NewDocumentFormat_RetrievalDriver(),
657                    new NewDocumentFormat_StorageDriver());
658 ~~~~
659
660 This example defines format "NewDocumentFormat" with a default file extension "ndf", and instantiates drivers for reading and storing documents from and to that format.
661 Either of the drivers can be null, in this case the corresponding action will not be supported for that format.
662
663 OCAF provides several standard formats, each covering some set of OCAF attributes:
664
665 <table>
666 <tr><th>Format</th><th>Persistent toolkit</th><th>OCAF attributes covered</th></tr>
667 <tr><td colspan=3>Legacy formats (read only)</td></tr>
668 <tr><td>OCC-StdLite    </td><td> TKStdL             </td><td> TKLCAF </td></tr>
669 <tr><td>MDTV-Standard  </td><td> TKStd              </td><td> TKLCAF + TKCAF </td></tr>
670 <tr><td colspan=3>Binary formats</td></tr>
671 <tr><td>BinLOcaf       </td><td> TKBinL             </td><td> TKLCAF </td></tr>
672 <tr><td>BinOcaf        </td><td> TKBin              </td><td> TKLCAF + TKCAF </td></tr>
673 <tr><td>BinXCAF        </td><td> TKBinXCAF          </td><td> TKLCAF + TKCAF + TKXCAF </td></tr>
674 <tr><td>TObjBin        </td><td> TKBinTObj          </td><td> TKLCAF + TKTObj </td></tr>
675 <tr><td colspan=3>XML formats</td></tr>
676 <tr><td>XmlLOcaf       </td><td> TKXmlL             </td><td> TKLCAF </td></tr>
677 <tr><td>XmlOcaf        </td><td> TKXml              </td><td> TKLCAF + TKCAF </td></tr>
678 <tr><td>XmlXCAF        </td><td> TKXmlXCAF          </td><td> TKLCAF + TKCAF + TKXCAF </td></tr>
679 <tr><td>TObjXml        </td><td> TKXmlTObj          </td><td> TKLCAF + TKTObj </td></tr>
680 </table>
681
682 For convenience, these toolkits provide static methods *DefineFormat()* accepting handle to application.
683 These methods allow defining corresponding formats easily, e.g.:
684
685 ~~~~{.cpp}
686 BinDrivers::DefineFormat (app); // define format "BinOcaf"
687 ~~~~
688
689 Use these toolkits as an example for implementation of persistence drivers for custom attributes, or new persistence formats.
690
691 The application can define several storage formats.
692 On save, the format specified in the document (see *TDocStd_Document::StorageFormat()*) will be used (save will fail if that format is not defined in the application).
693 On reading, the format identifier stored in the file is used and recorded in the document.
694
695 @subsubsection occt_ocaf_4_3_plugins Defining storage format by resource files 
696
697 The alternative  method to define formats is via usage of resource files. 
698 This  method was  used in earlier versions of OCCT and is considered as deprecated since version 7.1.0.
699 This method allows loading persistence drivers on demand, using plugin mechanism.
700
701 To use this method, create your own application class inheriting from *TDocStd_Application*, and override method *ResourcesName()*.
702 That method should return a string with a name of resource file, e.g. "NewDocumentFormat", which will contain a description of the format.
703
704 Then create that resource file and define the parameters of your format:
705
706 ~~~~
707 ndf.FileFormat: NewDocumentFormat
708 NewDocumentFormat.Description: New Document Format Version 1.0 
709 NewDocumentFormat.FileExtension: ndf 
710 NewDocumentFormat.StoragePlugin: bb5aa176-c65c-4c84-862e-6b7c1fe16921
711 NewDocumentFormat.RetrievalPlugin: 76fb4c04-ea9a-46aa-88a2-25f6a228d902 
712 ~~~~
713
714 The GUIDs should be unique and correspond to the GUIDs supported by relevant plugin.
715 You can use an existing plugins (see the table above) or create your own.
716
717 Finally, make a copy of the resource file "Plugin" from *$CASROOT/src/StdResource* and, if necessary, add the definition of your plugin in it, for instance:
718
719 ~~~~
720 bb5aa176-c65c-4c84-862e-6b7c1fe16921.Location: TKNewFormat
721 76fb4c04-ea9a-46aa-88a2-25f6a228d902.Location: TKNewFormat
722 ~~~~
723
724 In order to have these resource files loaded during the program execution, it is necessary to set two environment variables: *CSF_PluginDefaults* and *CSF_NewFormatDefaults*.
725 For example, set the files in the directory *MyApplicationPath/MyResources*: 
726
727 ~~~~
728 setenv CSF_PluginDefaults MyApplicationPath/MyResources 
729 setenv CSF_NewFormatDefaults MyApplicationPath/MyResources 
730 ~~~~
731
732 @subsubsection occt_ocaf_4_3_3 Saving a document
733
734 To save the document, make sure that its parameter *StorageFormat()* corresponds to one of the formats defined in the application, and use method *TDocStd_Application::SaveAs*, for instance: 
735
736 ~~~~{.cpp}
737 app->SaveAs(doc, "/tmp/example.caf"); 
738 ~~~~
739
740 @subsubsection occt_ocaf_4_3_4 Opening the document from a file
741
742 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. 
743
744 ~~~~
745 app->Open("/tmp/example.caf", doc); 
746 ~~~~
747
748 For binary formats only the part of the stored document can be loaded. For that the *PCDM_ReadingFilter* class could be used. It is possible to define which attributes must be loaded or omitted,
749 or to define one or several entries for sub-tree that must be loaded only. The following example opens document *doc*, but reads only "0:1:2" label and its sub-labels and only *TDataStd_Name* attributes on them.
750
751 ~~~~{.cpp}
752 Handle(PCDM_ReaderFilter) filter = new PCDM_ReaderFilter("0:1:2");
753 filter->AddRead("TDataStd_Name");
754 app->Open("example.cbf", doc, filter); 
755 ~~~~
756
757 Also, using filters, part of the document can be appended into the already loaded document from the same file. For an example, to read into the previously opened *doc* all attributes, except *TDataStd_Name* and *TDataStd_Integer*:
758
759 ~~~~{.cpp}
760 Handle(PCDM_ReaderFilter) filter2 = new PCDM_ReaderFilter(PCDM_ReaderFilter::AppendMode_Protect);
761 filter2->AddSkipped("TDataStd_Name");
762 filter2->AddSkipped("TDataStd_Integer");
763 app->Open("example.cbf", doc, filter2); 
764 ~~~~
765
766 *PCDM_ReaderFilter::AppendMode_Protect* means that if the loading algorithm finds already existing attribute in the document, it will not be overwritten by attibute from the loading file. If it is needed to
767 substitute the existing attributes, the reading mode *PCDM_ReaderFilter::AppendMode_Overwrite* must be used instead.
768
769 *AddRead* and *AddSkipped* methods for attributes should not be used in one filter. If it is so, *AddSkipped* attributes are ignored during the read.
770
771 Appending to the document content of already loaded file may be performed several times with the same or different parts of the document loaded. For that the filter reading mode must be *PCDM_ReaderFilter::AppendMode_Protect*
772 or *PCDM_ReaderFilter::AppendMode_Overwrite*, which enables the "append" mode of document open. If the filter is empty or null or skipped in arguments, it opens document with "append" mode disabled and any loading limitations.
773
774 @subsubsection occt_ocaf_4_3_5 Cutting, copying and pasting inside a document
775
776 To cut, copy and paste inside a document, use the class *TDF_CopyLabel*.
777
778 In fact, you must define a *Label*, which contains the temporary value of a cut or 
779 copy operation (say, in <i> Lab_Clipboard</i>). You must also define two other labels:
780
781 * The data container (e.g. <i> Lab_source</i>)
782 * The destination of the copy (e.g. <i> Lab_ Target</i> )
783
784 ~~~~{.cpp}
785     Copy = copy (Lab_Source => Lab_Clipboard)
786     Cut = copy + Lab_Source.ForgetAll() // command clear the contents of LabelSource.
787     Paste = copy (Lab_Clipboard => Lab_target)
788 ~~~~
789
790 So we need a tool to copy all (or a part) of the content of a label and its sub-label,
791 to another place defined by a label.
792
793 ~~~~{.cpp}
794     TDF_CopyLabel aCopy;
795     TDF_IDFilter aFilter (Standard_False);
796
797     //Don't copy TDataStd_TreeNode attribute
798
799      aFilter.Ignore(TDataStd_TreeNode::GetDefaultTreeID());
800      aCopy.Load(aSource, aTarget); aCopy.UseFilter(aFilter); aCopy.Perform();
801
802     // copy the data structure to clipboard 
803
804     return aCopy.IsDone(); }
805 ~~~~
806
807 The filter is used to forbid copying a specified type of attribute. 
808
809 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.
810
811 @subsection occt_ocaf_4_4 External Links
812
813 External links refer from one document to another. They allow you to update the copy of data  framework later on. 
814
815 @figure{/user_guides/ocaf/images/ocaf_image012.png,"External links between documents",360}
816
817 Note that documents can be copied with or without a possibility of updating an external link. 
818
819 @subsubsection occt_ocaf_4_4_1 Copying the document
820
821 #### With the possibility of updating it later
822
823 To copy a document with a possibility of updating it later, you use *TDocStd_XLinkTool::CopyWithLink*. 
824
825 ~~~~{.cpp}
826 Handle(TDocStd_Document) doc1; 
827 Handle(TDocStd_Document) doc2; 
828
829 TDF_Label source = doc1->GetData()->Root(); 
830 TDF_Label target = doc2->GetData()->Root(); 
831 TDocStd_XLinkTool XLinkTool; 
832
833 XLinkTool.CopyWithLink(target,source); 
834 ~~~~
835
836 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. 
837
838 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*. 
839
840 ~~~~{.cpp}
841 XLinkTool.UpdateLink(target); 
842 ~~~~
843
844 #### Without any link between the copy and the original
845
846 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.* 
847
848 ~~~~{.cpp}
849 XLinkTool.Copy(target, source); 
850
851 ~~~~
852
853
854 @section occt_ocaf_5 OCAF Shape Attributes
855 @subsection occt_ocaf_5_1 Overview
856
857 A topological attribute can be seen as a hook into the topological structure. It is possible to attach data to define references to it.
858
859 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. 
860
861 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. 
862
863 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. 
864
865 @figure{/user_guides/ocaf/images/ocaf_image013.png,"",455}
866
867 @subsection occt_ocaf_5_2 Shape attributes in data framework. 
868
869 Different algorithms may dispose sub-shapes of the result shape at the individual labels depending on whether it is necessary to do so: 
870
871 * 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.
872 * 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.
873
874 *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. 
875
876 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. 
877
878 @figure{/user_guides/ocaf/images/ocaf_image014.png,"Resulting box",200}
879
880 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). 
881
882 Named shapes, which contain information about modified faces, belong to the fuse result sub-labels: 
883 * sub-label with tag 1 -- modified faces from box 1, 
884 * sub-label with tag 2 -- modified faces from box 2. 
885
886 @figure{/user_guides/ocaf/images/ocaf_image015.png,"",360}
887
888 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: 
889
890   * face F1’ as a modification of face F11  
891   * face F1’’ as generation of face F12 
892   * edges as an intersection of two contiguous faces
893   * vertices as an intersection of three contiguous faces
894
895 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. 
896
897 @subsection occt_ocaf_5_3 Registering shapes and their evolution
898
899 When using TNaming_NamedShape to create attributes, the following fields of an attribute are filled: 
900
901 * 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.
902 * 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: 
903         * PRIMITIVE -- newly created topology, with no previous history;
904         * 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 );
905         * MODIFY -- the new shape is a modified old shape;
906         * DELETE -- the new shape is empty; the named shape with this evolution just indicates that the old shape topology is deleted from the model;
907         * SELECTED -- a named shape with this evolution has no effect on the history of the topology.
908
909 Only pairs of shapes with equal evolution can be stored in one named shape. 
910
911 @subsection occt_ocaf_5_4 Using naming resources
912
913 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. 
914
915 ~~~~{.cpp}
916 // a new empty named shape is created at "label" 
917 TNaming_Builder builder(label); 
918 // set a pair of shapes with evolution GENERATED 
919 builder.Generated(oldshape1,newshape1); 
920 // set another pair of shapes with the same evolution 
921 builder.Generated(oldshape2,newshape2); 
922 // get the result - TNaming_NamedShape attribute 
923 Handle(TNaming_NamedShape) ns = builder.NamedShape(); 
924 ~~~~
925
926 @subsection occt_ocaf_5_5 Reading the contents of a named shape attribute
927
928 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.
929   
930 More detailed information about the contents of the named shape or about the modification history of a topology can be obtained with the following: 
931 * *TNaming_Tool* provides a common high-level functionality for access to the named shapes contents:
932         * The method <i>GetShape(Handle(TNaming_NamedShape)) </i>  returns a compound of new shapes of the given named shape;
933         * 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;
934         * 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.
935 * *TNaming_Iterator* gives access to the named shape and hooks pairs.
936
937 ~~~~{.cpp}
938 // create an iterator for a named shape 
939 TNaming_Iterator iter(namedshape); 
940 // iterate while some pairs are not iterated 
941 while(iter.More()) { 
942 // get the new shape from the current pair 
943 TopoDS_Shape newshape = iter.NewShape(); 
944 // get the old shape from the current pair 
945 TopoDS_Shape oldshape = iter.OldShape(); 
946 // do something... 
947
948 // go to the next pair 
949 iter.Next(); 
950
951 ~~~~
952
953
954 @subsection occt_ocaf_5_6 Topological naming
955
956 The Topological Naming mechanism is based on 3 components:
957 * History of the used modeling operation algorithm;
958 * Registering of the built result in Data Framework (i.e. loading the necessary elements of the extracted history in OCAF document);
959 * Selection / Recomputation of a "selected" sub-shape of the algorithm result.
960
961 To get the expected result the work of the three components should be synchronized and the rules of each component should be respected.
962
963 @subsubsection occt_ocaf_5_6_1 Algorithm history
964
965 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.
966
967 | Result type | Type of sub-shapes to be returned by history of algorithm | Comments |
968 | :---------- | :-------------------------------------------------------- | :------- |
969 | Solid or closed shell | Faces | All faces |
970 | Open shell or single face | Faces and edges of opened boundaries only | All faces plus all edges of opened boundaries |
971 | Closed wire | Edges | All edges |
972 | Opened wire | Edges and ending vertexes | All edges plus ending vertexes of the wire |
973 | Edge | Vertexes |     Two vertexes are expected |
974 | 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 | 
975
976 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.
977
978 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.
979
980 @subsubsection occt_ocaf_5_6_2 Loading history in data framework
981
982 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**. 
983
984 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.
985
986 @subsubsection occt_ocaf_5_6_3 Selection / re-computation mechanism
987
988 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.
989
990 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:
991 * Storing the selected shape on a label -- its **Selection**;
992 * Accessing the named shape -- check the kept value of the shape
993 * Update of this naming -- recomputation of an earlier selected shape.
994
995 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:
996 * the given context shape, i.e. the main shape kept on **Result Label**, which contains a selected sub-shape, 
997 * its evolution and
998 * naming structure.
999
1000 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.
1001
1002 @subsection occt_ocaf_5_7 Exploring shape evolution
1003
1004 The class *TNaming_Tool* provides a toolkit to read current data contained in the attribute. 
1005
1006 If you need to create a topological attribute for existing data, use the method *NamedShape*. 
1007
1008 ~~~~{.cpp}
1009 class MyPkg_MyClass 
1010
1011 public: Standard_Boolean SameEdge (const Handle(CafTest_Line)& L1, const Handle(CafTest_Line)& L2); 
1012 }; 
1013
1014 Standard_Boolean CafTest_MyClass::SameEdge (const Handle(CafTest_Line)& L1, const Handle(CafTest_Line)& L2) 
1015
1016   Handle(TNaming_NamedShape) NS1 = L1->NamedShape(); 
1017   Handle(TNaming_NamedShape) NS2 = L2->NamedShape(); 
1018   return BRepTools::Compare(NS1,NS2); 
1019
1020 ~~~~
1021
1022
1023 @subsection occt_ocaf_5_8 Example of topological naming usage
1024
1025 **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.).
1026
1027 Let us consider an example: imagine a wooden plate. The job is to drive several nails in it:
1028
1029 @figure{/user_guides/ocaf/images/ocaf_image020.png,"A nail driven in a wooden plate",360}
1030
1031 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:
1032 *       Makes several Nails of different height and diameter (according to the need),
1033 *       Chooses (selects) the upper surface of each Nail for the Hammer.
1034
1035 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.
1036
1037 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!)…
1038
1039 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()*.
1040
1041 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”.
1042
1043 The application contains 3 functions:
1044 * **Nail** -- produces a shape representing a nail,
1045 * **Translator** -- translates a shape along the wooden plate,
1046 * **Hammer** -- drives the nail in the wooden plate.
1047
1048 Each function gives the topological naming some hints how to “re-solve” the selected sub-shapes:
1049 * The Nail constructs a solid shape and puts each face of the shape into sub-labels: 
1050
1051 @figure{/user_guides/ocaf/images/ocaf_image021.png,"Distribution of faces through sub-labels of the Nail",185}
1052
1053 * 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:
1054
1055 @figure{/user_guides/ocaf/images/ocaf_image022.png,"Registration of relocation of faces of a Nail",240}
1056
1057 How does it work?
1058 * 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).
1059 * 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. 
1060 * When the Hammer calls *TNaming::Solve()*, the topological naming “looks” at the unique name of the selected shape and tries to re-solve it:
1061         * It finds the 1st appearance of the selected shape in the data tree -- it is a label under the Nail function *Face 1*.
1062         * 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.
1063 * Calling the method *TNaming_Selector::NamedShape()* the Hammer obtains the last evolution of the selected face -- the relocated top face.
1064
1065 The job is done.
1066
1067 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).
1068
1069
1070 @section occt_ocaf_6 Standard Attributes
1071
1072 @subsection occt_ocaf_6_1 Overview
1073
1074 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: 
1075
1076   * Geometric attributes;
1077   * General attributes;
1078   * Relationship attributes;
1079   * Auxiliary attributes.
1080   
1081    
1082
1083 ### Geometric attributes
1084
1085   * **Axis** -- simply identifies, that the concerned *TNaming_NamedShape* attribute with an axis shape inside belongs to the same label; 
1086   * **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;
1087   * **Geometry** -- simply identifies, that the concerned *TNaming_NamedShape* attribute with a specified-type geometry belongs to the same label; 
1088   * **Plane** -- simply identifies, that the concerned *TNaming_NamedShape* attribute with a plane shape inside belongs to the same label;
1089   * **Point** -- simply identifies, that the concerned *TNaming_NamedShape* attribute with a  point shape inside belongs to the same label;
1090   * **Shape** -- simply identifies, that the concerned *TNaming_NamedShape* attribute belongs to the same label;
1091   * **PatternStd**  -- identifies one of five available pattern models (linear, circular, rectangular, circular rectangular and mirror);
1092   * **Position** -- identifies the position in 3d global space.
1093
1094 ### General attributes
1095
1096   * **AsciiString** -- contains AsciiString value;
1097   * **BooleanArray** -- contains an array of Boolean;
1098   * **BooleanList** -- contains a list of Boolean;
1099   * **ByteArray** -- contains an array of Byte (unsigned char) values;
1100   * **Comment** -- contains a string -- the comment for a given label (or attribute);
1101   * **Expression** -- contains an expression string and a list of used variables attributes;
1102   * **ExtStringArray** -- contains an array of *ExtendedString* values;
1103   * **ExtStringList** -- contains a list of *ExtendedString* values;
1104   * **Integer** -- contains an integer value;
1105   * **IntegerArray** -- contains an array of integer values;
1106   * **IntegerList** -- contains a list of integer values;
1107   * **IntPackedMap** -- contains a packed map of integers;
1108   * **Name** -- contains a string -- the name of a given label (or attribute);
1109   * **NamedData** -- may contain up to 6 of the following named data sets (vocabularies): *DataMapOfStringInteger, DataMapOfStringReal, DataMapOfStringString, DataMapOfStringByte, DataMapOfStringHArray1OfInteger* or *DataMapOfStringHArray1OfReal*;
1110   * **NoteBook** -- contains a *NoteBook* object attribute;
1111   * **Real** -- contains a real value;
1112   * **RealArray** -- contains an array of  real values;
1113   * **RealList** -- contains a list of real values;
1114   * **Relation** -- contains a relation string and a list of used variables attributes;
1115   * **Tick** -- defines a boolean attribute;
1116   * **Variable** -- simply identifies, that a variable belongs to this label; contains the flag *is constraint* and a string of used units ("mm", "m"...);
1117   * **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).
1118   
1119 ### Relationship attributes 
1120
1121   * **Reference** -- contains reference to the label of its own data framework;
1122   * **ReferenceArray** -- contains an array of references;
1123   * **ReferenceList** -- contains a list of references;
1124   * **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.
1125
1126 ### Auxiliary attributes
1127
1128   * **Directory** -- high-level tool attribute for sub-labels management;
1129   * **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.
1130
1131 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. 
1132
1133 ### Attributes supporting several attributes of the same type on the same label
1134
1135 By default only one attribute of the same type on the same label is supported.
1136 For example, you can set only one TDataStd_Real attribute on the same label.
1137 This limitation was removed for some predefined sub-set of standard attributes by adding so called 'user defined ID' feature to the attribute.
1138 The listed below attributes received this new feature:
1139
1140   * **TDataStd_AsciiString**
1141   * **TDataStd_Integer**
1142   * **TDataStd_Name**
1143   * **TDataStd_Real**
1144   * **TDataStd_BooleanArray**
1145   * **TDataStd_BooleanList**
1146   * **TDataStd_ByteArray**
1147   * **TDataStd_ExtStringArray**
1148   * **TDataStd_ExtStringList**
1149   * **TDataStd_IntegerArray**
1150   * **TDataStd_IntegerList**
1151   * **TDataStd_RealArray**
1152   * **TDataStd_RealList**
1153   * **TDataStd_ReferenceArray**
1154   * **TDataStd_ReferenceList**
1155
1156 See for details paragraph 6.4.
1157
1158 @subsection occt_ocaf_6_2 Services common to all attributes
1159
1160 @subsubsection occt_ocaf_6_2_1 Accessing GUIDs
1161
1162 To access the GUID of an attribute, you can use two methods: 
1163   * 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.
1164   * 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.
1165   
1166 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:
1167
1168 ~~~~{.cpp}
1169     Standard_GUID anID = MyAttributeClass::GetID();
1170     Standard_Boolean HasAttribute = aLabel.Find(anID,anAttribute);
1171 ~~~~
1172
1173 @subsubsection occt_ocaf_6_2_2 Conventional Interface of Standard Attributes
1174
1175 It is usual to create standard named methods for the attributes: 
1176
1177   * 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.
1178   * Method *Get()* returns the value of an attribute if it is characterized by one value.
1179   * Method *Dump(Standard_OStream)* outputs debug information about a given attribute to a given stream.
1180   
1181 @subsection occt_ocaf_6_3 The choice between standard and custom attributes
1182
1183 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?
1184
1185 It is possible to describe any model by means of standard OCAF attributes. 
1186   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.
1187   
1188   This depends on a particular model.  
1189    
1190   OCAF imposes the restriction that only one attribute type may be allocated to one label. 
1191   It is necessary to take into  account the design of the application data tree. 
1192   For example, if a label should  possess several double values, 
1193   it is necessary to distribute them through several child sub-labels or use an array of double values.   
1194    
1195   Let us consider several boundary implementations of the same model in OCAF tree and analyze the advantages and disadvantages of each approach.  
1196
1197   
1198 @subsubsection occt_ocaf_6_2_3 Comparison  and analysis of approaches
1199
1200   Below are described two different model implementations:
1201   one is based on standard OCAF attributes and the other is based
1202   on the creation of a new attribute possessing all data of the model.
1203
1204   A load is distributed through the shape.
1205   The measurements are taken at particular points defined by (x, y and z) coordinates.
1206   The load is represented as a projection onto X, Y and Z axes of the local coordinate system at each point of measurement.
1207   A matrix of transformation is needed to convert the local coordinate system to the global one, but this is optional.
1208
1209   So, we have 15 double values at each point of measurement.
1210   If the number of such points is 100 000, for example, it means
1211   that we have to store 1 500 000 double values in the OCAF document.
1212
1213   The first approach consists in using standard OCAF attributes.
1214   Besides, there are several  variants of how the standard attributes may be used:
1215   * Allocation of all 1 500 000 double values as one array of double values attached to one label;
1216   * 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;
1217   * Allocation of each point of measure as an array of 3 double values attached to one label,
1218     the projection of load onto the local coordinate system axes as another array of 3 double values attached to a sub-label,
1219     and the matrix of projection (9 values) as the third array also attached to a sub-label.
1220
1221   Certainly, other variants are also possible.
1222
1223 @figure{ocaf_tree_wp_image003.png,"Allocation of all data as one  array of double values",350}
1224  
1225   The first approach to allocation of all  data represented as one array of double values 
1226   saves initial memory and is easy to implement. 
1227   But access to the data is difficult because the values are stored in a flat array. 
1228   It will be necessary to implement a class with several methods giving access 
1229   to particular fields like the measurement points, loads and so  on.  
1230    
1231   If the values may be edited in the  application, 
1232   it means that the whole array will be backed-up on each edition. 
1233   The memory usage will increase very fast! 
1234   So, this approach may be considered only in case of non-editable data.  
1235    
1236   Let’s consider the allocation of data of  each measurement point per label (the second case). 
1237   In this case we create 100  000 labels -- one label for each measurement point 
1238   and attach an array of double  values to these labels:  
1239  
1240 @figure{ocaf_tree_wp_image004.png,"Allocation of data of each  measurement point as arrays of double values",288}
1241  
1242   Now edition of data is safer as far as  memory usage is concerned. 
1243   Change of value for one measurement point (any  value: point coordinates, load, and so on) backs-up only one small array of double values.
1244   But this structure (tree) requires more memory space (additional  labels and attributes).  
1245    
1246   Besides, access to the values is still difficult and it is necessary 
1247   to have a class with methods of access to the  array fields.  
1248    
1249   The third case of allocation of data  through OCAF tree is represented below:  
1250
1251 @figure{ocaf_tree_wp_image005.png,"Allocation of data into separate arrays of double values",354}
1252
1253   In this case sub-labels are involved and we  can easily access the values of each measurement point, 
1254   load or matrix. We don’t need an interface class with methods of access to the data 
1255   (if it exists, it would help to use the data structure, but this is optional).  
1256
1257   On the one hand, this approach requires more  memory for allocation of the attributes (arrays of double values). 
1258   On the other  hand, it saves memory during the edition of data 
1259   by backing-up only the small array containing the modified data. 
1260   So, if the data is fully modifiable, this  approach is more preferable.  
1261
1262   Before making a conclusion, let’s consider the same model implemented through a newly created OCAF attribute.  
1263
1264   For example, we might allocate all data  belonging to one measurement point as one OCAF attribute. 
1265   In this case we  implement the third variant of using the standard attributes (see picture 3), 
1266   but we use less memory (because we use only one attribute instead of three):  
1267  
1268 @figure{ocaf_tree_wp_image006.png,"Allocation of data into newly  created OCAF attribute",383}
1269
1270   The second variant of using standard OCAF attributes still has drawbacks: 
1271   when data is edited, OCAF backs-up all values  of the measurement point.   
1272    
1273   Let’s imagine that we have some  non-editable data. 
1274   It would be better for us to allocate this data separately from editable data. 
1275   Back-up will not affect non-editable data and memory will not increase so much during data edition.  
1276   
1277  @subsubsection occt_ocaf_6_2_4 Conclusion
1278
1279   When deciding which variant of data model implementation to choose, 
1280   it is necessary to take into account the application  response time, 
1281   memory allocation and memory usage in transactions.   
1282    
1283   Most of the models may be implemented using only standard OCAF attributes. 
1284   Some other models need special treatment and require implementation of new OCAF attributes.
1285
1286
1287  @subsection occt_ocaf_6_4 Standard Attributes with User Defined GUID
1288
1289  The listed above attributes allow to set at the same Label as many attributes of the same type as you want thanks to specific user's ID.
1290  Let's consider it on the example of the TDataStd_Real attribute. The previous version of the attribute allowed to set the attribute using 
1291  static method Set in next way:
1292
1293 ~~~~{.cpp}
1294 static Handle(TDataStd_Real) Set (const TDF_Label& label, const Standard_Real value);
1295 ~~~~
1296
1297  This is a default form which is kept by the attribute. It uses the default GUID for the attribute identification - TDataStd_Real::GetID(). 
1298  In case if you want to use the new feature (user defined Real attribute), for example to define several attributes which should keep a value 
1299  of the same type - Standard_Real, but to be associated with different user's notions (or objects) the new static method Set should be used. 
1300  In our example we will define two Real attributes which presents two customer's objects - Density and Volume and will be put on the same Label.
1301
1302 ~~~~{.cpp}
1303 #define DENSITY Standard_GUID("12e9454b-6dbc-11d4-b9c8-0060b0ee2810")
1304 #define VOLUME  Standard_GUID("161595c0-3628-4737-915a-c160ce94c6f7")
1305
1306 TDF_Label aLabel = ...;
1307
1308 // Real attribute type with user defined GUID associated with user's object "Density"
1309 TDataStd_Real::Set(aLabel, DENSITY, 1.2);
1310
1311 // Real attribute type with user defined GUID associated with user's object "Volume"
1312 TDataStd_Real::Set(aLabel, VOLUME, 185.5);
1313
1314  To find an user defined Real attribute just use a corresponding GUID:
1315 Handle (TDataStd_Real) anAtt;
1316 aLabel.FindAttribute (DENSITY, anAtt);
1317 ~~~~
1318
1319   @subsection occt_ocaf_6_4_1  Creation Attributes with User Defined GUID.
1320
1321  You can create a new instance of an attribute with user define GUID and add it to label in two ways.
1322  1. Using static method Set(). For example:
1323
1324 ~~~~{.cpp}
1325     TDF_Label aLabel = ...;
1326     Standard_Integer aValue = ...;
1327     Standard_GUID aGuid = TDataStd_Integer::GetID();
1328     TDataStd_Integer::Set(aLabel, aGuid, aValue);
1329 ~~~~
1330
1331  2. Using the default constructor
1332
1333 ~~~~{.cpp}
1334     Handle(TDataStd_Integer) anInt = new TDataStd_Integer();
1335     anInt->SetID(aGuid);
1336     aLabel.Add(anInt);
1337     anInt->Set(aValue);
1338 ~~~~
1339
1340     
1341 @section occt_ocaf_7 Visualization Attributes
1342
1343 @subsection occt_ocaf_7_1 Overview
1344
1345 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. 
1346
1347 @subsection occt_ocaf_7_2 Services provided
1348
1349 @subsubsection occt_ocaf_7_2_1 Defining an interactive viewer attribute
1350
1351 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. 
1352
1353 To initialize the AIS viewer as in the example below, use method *Find*. 
1354
1355 ~~~~{.cpp}
1356 // "access" is any label of the data framework 
1357 Handle(TPrsStd_AISViewer) viewer = TPrsStd_AISViewer::Find(access) 
1358 ~~~~
1359
1360 @subsection occt_ocaf_7_2_2 Defining a presentation attribute
1361
1362 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. 
1363
1364 @subsubsection occt_ocaf_7_2_3 Creating your own driver
1365
1366 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. 
1367
1368 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: 
1369 @figure{/user_guides/ocaf/images/ocaf_image016.png,"",420}
1370
1371 As usual, the GUID of a driver and the GUID of a displayed attribute are the same. 
1372
1373 @subsubsection occt_ocaf_7_2_4 Using a container for drivers
1374
1375 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. 
1376
1377 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. 
1378
1379 **Example** 
1380 ~~~~{.cpp}
1381 DriverTable::Get() -> InitStandardDrivers(); 
1382 // next, attach your named shape to a label 
1383 TPrsStd_AISPresentation::Set(NS}; 
1384 // here, attach the AISPresentation to NS. 
1385 ~~~~
1386
1387
1388 @section occt_ocaf_8 Function Services
1389
1390 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. 
1391
1392 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. 
1393
1394 @figure{/user_guides/ocaf/images/ocaf_image008.png,"Document structure",360}
1395
1396 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. 
1397
1398 @subsection occt_ocaf_8_1 Finding functions, their owners and roots
1399
1400 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. 
1401
1402 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. 
1403
1404 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. 
1405
1406 @subsection occt_ocaf_8_2 Storing and accessing information about function status
1407
1408 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. 
1409
1410 @subsection occt_ocaf_8_3 Propagating modifications
1411
1412 An application must implement its functions, function drivers and the common solver for parametric model creation. For example, check the following model: 
1413
1414 @figure{/user_guides/ocaf/images/ocaf_image017.png,"",360}
1415
1416 The procedure of its creation is as follows:
1417   * create a rectangular planar face *F* with height 100 and width 200;
1418   * create prism *P* using face *F* as a basis;
1419   * create fillet *L* at the edge of the prism;
1420   * change the width of *F* from 200 to 300;
1421   * the solver for the function of face *F* starts;
1422   * the solver detects that an argument of the face *F* function has been modified;
1423   * the solver calls the driver of the face *F* function for a  regeneration of the face;
1424   * 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;
1425
1426   * the solver detects the function of *P* -- it depends on the function of *F*;
1427   * the solver calls the driver of the prism *P* function;
1428   * the driver rebuilds prism *P* and adds the label of this prism to the logbook as  impacted;
1429   * the solver detects the function of *L*  -- it depends on the function of *P*;
1430   * the solver calls the *L* function driver;
1431   * the driver rebuilds fillet *L* and adds the label of the fillet to the logbook as impacted.
1432   
1433  @section occt_ocaf_8a Example of Function Mechanism Usage
1434  
1435  @subsection occt_ocaf_8a_1 Introduction
1436
1437   Let us describe the usage of the Function Mechanism of Open CASCADE Application Framework on a simple example.  
1438   This example represents a "nail" composed by a cone and two cylinders of different radius and height:  
1439
1440 @figure{ocaf_functionmechanism_wp_image003.png,"A nail",160}
1441
1442   These three objects (a cone and two cylinders) are  independent, 
1443   but the Function Mechanism makes them connected to each other and representing one object -- a nail.  
1444   The object "nail" has the following parameters:  
1445   
1446   * The position of the nail is defined by the apex point of the  cone. 
1447    The cylinders are built on the cone and therefore they depend on the position  of the cone. 
1448    In this way we define a dependency of the cylinders on the cone.  
1449   * The height of the nail is defined by the height of the cone.  
1450    Let’s consider that the long cylinder has 3 heights of the cone 
1451    and the header cylinder has a half of the height of the cone.  
1452   * The radius of the nail is defined by the radius of the cone. 
1453   The radius of the long cylinder coincides with this value. 
1454   Let’s consider that the  header cylinder has one and a half radiuses of the cone.  
1455   
1456   So, the cylinders depend on the cone and the cone  parameters define the size of the nail.  
1457   
1458   It means that re-positioning the cone (changing its  apex point) moves the nail, 
1459   the change of the radius of the cone produces a thinner or thicker nail, 
1460   and the change of the height of the cone shortens or  prolongates the nail.  
1461    It is suggested to examine the programming steps needed to create a 3D parametric model of the "nail".  
1462   
1463 @subsection occt_ocaf_8a_2 Step 1: Data Tree
1464
1465   The first step consists in model data allocation in the OCAF tree. 
1466   In other words, it is necessary to decide where to put the data.  
1467   
1468   In this case, the data can be organized into a simple tree 
1469   using references for definition of dependent parameters:  
1470
1471 * Nail
1472         * Cone
1473                 + Position (x,y,z)
1474                 + Radius 
1475                 + Height
1476         * Cylinder (stem)
1477                 + Position = "Cone" position translated for "Cone" height along Z;
1478                 + Radius = "Cone" radius;
1479                 + Height = "Cone" height multiplied by 3;
1480         * Cylinder (head)  
1481                 + Position = "Long cylinder" position translated for "Long cylinder" height along Z;
1482                 + Radius = "Long cylinder" radius multiplied by 1.5;
1483                 + Height = "Cone" height divided by 2. 
1484
1485   The "nail" object has three sub-leaves in the tree:  the cone and two cylinders.   
1486   
1487   The cone object is independent.  
1488   
1489   The long cylinder representing a "stem" of the nail  refers to the corresponding parameters 
1490   of the cone to define its own data  (position, radius and height). It means that the long cylinder depends on the  cone.  
1491   
1492   The parameters of the head cylinder may be expressed through the cone parameters
1493   only or through the cone and the long cylinder parameters.
1494   It is suggested to express the position and the radius of the head cylinder 
1495   through the position and the radius of the long cylinder, and the height 
1496   of the head cylinder through the height of the cone. 
1497   It means that the head cylinder depends on the cone and the long cylinder.  
1498
1499 @subsection occt_ocaf_8a_3 Step 2: Interfaces
1500
1501   The interfaces of the data model are responsible for dynamic creation 
1502   of the data tree of the represented at the previous step, data  modification and deletion.  
1503   
1504   The interface called *INail*  should contain the methods for creation 
1505   of the data tree for the nail, setting  and getting of its parameters, computation, visualization and removal.  
1506
1507 @subsubsection occt_ocaf_8a_3_1 Creation of the nail
1508
1509   This method of the interface creates a data tree for the nail at a given leaf of OCAF data tree.
1510
1511   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).
1512
1513   It sets the default values of position, radius and height of the nail.
1514
1515   The nail has the following user parameters:  
1516   * The position -- coincides with the position of the cone  
1517   * The radius of the stem part of the nail -- coincides with the radius  of the cone  
1518   * The height of the nail -- a sum of heights of the cone and both  cylinders  
1519   
1520   The values of the position and the radius of the  nail are defined for the cone object data. 
1521   The height of the cone is recomputed  as 2 * heights of nail and divided by 9.  
1522
1523 @subsubsection occt_ocaf_8a_3_2 Computation
1524
1525   The Function Mechanism is responsible for re-computation of  the nail. 
1526   It will be described in detail later in this document.  
1527   
1528   A data leaf consists of the reference  to the location of the  real data 
1529   and a real value defining a coefficient of multiplication of the  referenced data.  
1530   
1531   For example, the height of the long cylinder is defined as a  reference to the height of the cone 
1532   with coefficient 3. The data  leaf of the height of the long cylinder 
1533   should contain two attributes: a  reference to the height of cone and a real value equal to 3.  
1534
1535 @subsubsection occt_ocaf_8a_3_3 Visualization
1536
1537  The shape resulting of the nail function can be displayed using the standard OCAF visualization mechanism.  
1538
1539 @subsubsection occt_ocaf_8a_3_4 Removal of the nail
1540
1541 To automatically erase the nail from the viewer and the data  tree it is enough to clean the nail leaf from attributes.  
1542
1543 @subsection occt_ocaf_8a_4 Step 3: Functions
1544
1545   The nail is defined by four functions: the cone, the two cylinders  and the nail function.  
1546   The function of the cone is independent. The functions of the cylinders depend on the cone function. 
1547   The nail function depends on the  results of all functions:  
1548
1549 @figure{ocaf_functionmechanism_wp_image005.png,"A graph of dependencies between functions",232}
1550
1551   Computation of the model starts with the cone function, then the long cylinder, 
1552   after that the header cylinder and, finally, the result is generated  by the nail function at the end of function chain.  
1553
1554   The Function Mechanism of Open CASCADE Technology creates this  graph of dependencies 
1555   and allows iterating it following the dependencies. 
1556   The  only thing the Function Mechanism requires from its user 
1557   is the implementation  of pure virtual methods of *TFunction_Driver*:  
1558   
1559   * <i>\::Arguments()</i> -- returns a list of arguments for the  function  
1560   * <i>\::Results()</i> -- returns a list of results of the function  
1561   
1562   These methods give the Function Mechanism the information on the location of arguments 
1563   and results of the function and allow building a  graph of functions. 
1564   The class *TFunction_Iterator* iterates the functions of the graph in the execution order.  
1565   
1566   The pure virtual method *TFunction_Driver::Execute()* calculating the function should be overridden.  
1567   
1568   The method <i>\::MustExecute()</i> calls the method <i>\::Arguments()</i>  of the function driver 
1569   and ideally this information (knowledge of modification  of arguments of the function) is enough
1570   to make a decision whether the function  should be executed or not. Therefore, this method usually shouldn’t be  overridden.  
1571
1572   The cone and cylinder functions differ only in geometrical construction algorithms. 
1573   Other parameters are the same (position, radius and height).  
1574   
1575   It means that it is possible to create a base class -- function driver for the three functions, 
1576   and two descendant classes producing:  a cone or a cylinder.  
1577   
1578   For the base function driver the methods <i>\::Arguments()</i>  and <i>\::Results()</i> will be overridden. 
1579   Two descendant function drivers responsible for creation of a cone and a cylinder will override only the method  <i>\::Execute()</i>. 
1580   
1581   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. 
1582   
1583   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.
1584
1585 @subsection occt_ocaf_8a_5 Example 1: iteration and execution of functions. 
1586
1587   This is an example of the code for iteration and execution of functions.  
1588
1589 ~~~~{.cpp}
1590
1591 // The scope of functions is defined.
1592 Handle(TFunction_Scope) aScope = TFunction_Scope::Set (anyLabel);
1593
1594 // The information on modifications in the model is received.
1595 TFunction_Logbook& aLog = aScope->GetLogbook();
1596
1597 // The iterator is iInitialized by  the scope of functions.
1598 TFunction_Iterator anIterator (anyLabel);
1599 anIterator.SetUsageOfExecutionOrder (true);
1600
1601 // The function is iterated,  its dependency is checked on the modified data and  executed if necessary.
1602 for (; anIterator.more(); anIterator.Next())
1603 {
1604   // The function iterator may return a list of  current functions for execution.
1605   // It might be useful for multi-threaded execution  of functions.
1606   const TDF_LabelList& aCurrentFunctions = anIterator.Current();
1607
1608   // The list of current functions is iterated.
1609   for (TDF_ListIteratorOfLabelList aCurrentIterator (aCurrentFunctions);
1610        aCurrentIterator.More(); aCurrentIterator.Next())
1611   {
1612     //  An interface for the function is created.
1613     TFunction_IFunction anInterface (aCurrentIterator.Value());
1614
1615     //  The function driver is retrieved.
1616     Handle(TFunction_Driver) aDriver = anInterface.GetDriver();
1617
1618     //  The dependency of the function on the  modified data is checked.
1619     if (aDriver->MustExecute (aLog))
1620     {
1621       // The function is executed.
1622       int aRes = aDriver->Execute (aLog);
1623       if (aRes)
1624       {
1625         return false;
1626       }
1627     }
1628   }
1629 }
1630
1631 ~~~~
1632
1633 @subsection occt_ocaf_8a_6 Example 2: Cylinder function driver
1634
1635   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.   
1636
1637 ~~~~{.cpp}
1638
1639     // A virtual method  ::Arguments() returns a list of arguments of the function.  
1640     CylinderDriver::Arguments( TDF_LabelList&amp; args )  
1641     {  
1642       // The direct arguments, located at sub-leaves of the function, are collected (see picture 2)
1643       TDF_ChildIterator  cIterator( Label(), false );  
1644       for (;  cIterator.More(); cIterator.Next() )  
1645       {  
1646         // Direct argument.  
1647         TDF_Label  sublabel = cIterator.Value();  
1648         Args.Append(  sublabel );  
1649
1650         // The references to the external data are  checked.  
1651         Handle(TDF_Reference)  ref;  
1652         If (  sublabel.FindAttribute( TDF_Reference::GetID(), ref ) )  
1653         {  
1654           args.Append(  ref-Get() );  
1655         }
1656     }
1657      
1658     // A virtual method ::Results()  returns a list of result leaves.  
1659     CylinderDriver::Results( TDF_LabelList&amp; res )  
1660     {  
1661       // The result is kept at the function  label.  
1662       Res.Append(  Label() );  
1663     }
1664      
1665     // Execution of the function  driver.  
1666     Int CylinderDriver::Execute( TFunction_Logbook&amp; log )  
1667     {  
1668       // Position of the cylinder - position of the first  function (cone)   
1669       //is  elevated along Z for height values of all  previous functions.  
1670       gp_Ax2 axes = …. // out of the scope of this guide.  
1671       // The radius value is retrieved.  
1672       // It is located at second child sub-leaf (see the  picture 2).  
1673       TDF_Label radiusLabel  = Label().FindChild( 2 );  
1674        
1675       // The multiplicator of the radius ()is retrieved.  
1676       Handle(TDataStd_Real)  radiusValue;  
1677       radiusLabel.FindAttribute(  TDataStd_Real::GetID(), radiusValue);  
1678        
1679       // The reference to the radius is retrieved.  
1680       Handle(TDF_Reference)  refRadius;  
1681       RadiusLabel.FindAttribute(  TDF_Reference::GetID(), refRadius );  
1682        
1683       // The radius value is calculated.  
1684       double radius = 0.0;
1685       
1686       if (  refRadius.IsNull() )
1687       {
1688         radius  = radiusValue-Get();  
1689       }
1690       else  
1691       {  
1692         // The referenced radius value is  retrieved.   
1693         Handle(TDataStd_Real)  referencedRadiusValue;  
1694         RefRadius-Get().FindAttribute(TDataStd_Real::GetID()  ,referencedRadiusValue );  
1695         radius  = referencedRadiusValue-Get() * radiusValue-Get();  
1696       }  
1697        
1698       // The height value is retrieved.  
1699       double height = … // similar code to taking the radius value.  
1700        
1701       // The cylinder is created.  
1702       TopoDS_Shape cylinder  = BRepPrimAPI_MakeCylinder(axes, radius, height);  
1703        
1704       // The result (cylinder) is set  
1705       TNaming_Builder  builder( Label() );  
1706       Builder.Generated(  cylinder );  
1707        
1708       // The modification of the result leaf is saved in  the log.  
1709       log.SetImpacted(  Label() );  
1710        
1711       return 0;
1712     }
1713 ~~~~
1714  
1715   
1716
1717 @section occt_ocaf_9 XML Support
1718
1719 Writing and reading XML files in OCCT is provided by LDOM package, which constitutes an integral part
1720 of XML OCAF persistence, which is the optional component provided on top of Open CASCADE Technology.
1721
1722 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: 
1723 * 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. 
1724 * Provide class *LDOM_Parser* to read XML files and convert them to *LDOM_Document* objects.
1725 * Provide class *LDOM_XmlWriter* to convert *LDOM_Document* to a character stream in XML format and store it in file. 
1726
1727 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: 
1728 * 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). 
1729 * To minimize the time required for parsing and formatting XML, as well as for access to DOM data structures. 
1730
1731 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:
1732 * 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. 
1733 * Some superfluous methods are deleted: *getPreviousSibling, getParentNode,* etc. 
1734 * No resolution of XML Entities of any kind 
1735 * No support for DTD: the parser just checks for observance of general XML rules and never validates documents. 
1736 * Only 5 available types of DOM nodes: *LDOM_Element, LDOM_Attr, LDOM_Text, LDOM_Comment* and *LDOM_CDATASection*. 
1737 * No support of Namespaces; prefixed names are used instead of qualified names. 
1738 * No support of the interface *DOMException* (no exception when attempting to remove a non-existing node). 
1739
1740 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. 
1741
1742 @subsection occt_ocaf_9_1 Document Drivers
1743
1744 The drivers for document storage and retrieval  manage  conversion between a transient OCAF
1745 Document in memory and its persistent reflection in a container (disk, memory, network). For XML Persistence, they are defined in the package XmlDrivers. 
1746
1747 The main methods (entry points) of these drivers are: 
1748 * *Write()* -- for a storage driver; 
1749 * *Read()* -- for a retrieval driver. 
1750
1751 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: 
1752
1753 First it is necessary to convert the transient document into another form (called persistent), suitable for writing into a file, and vice versa. 
1754 In XML Persistence LDOM_Document is used as the persistent form of an OCAF Document and the DOM_Nodes are the persistent objects. 
1755 An OCAF Document is a tree of labels with attributes. Its transformation into a persistent form can be functionally divided into two parts: 
1756 * Conversion of the labels structure, which is performed by the method XmlMDF::FromTo()
1757 * Conversion of the attributes and their underlying objects, which is performed by the corresponding attribute drivers (one driver per attribute type). 
1758
1759 The driver for each attribute is selected from a table of drivers, either by attribute
1760 type (on storage) or by the name of the corresponding DOM_Element (on retrieval).
1761 The table of drivers is created by by methods *XmlDrivers_DocumentStorageDriver::AttributeDrivers()*
1762 and *XmlDrivers_DocumentRetrievalDriver::AttributeDrivers()*. 
1763
1764 Then the persistent document is written into a file (or read from a file). 
1765 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.
1766
1767 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. 
1768
1769 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. 
1770
1771 @subsection occt_ocaf_9_2 Attribute Drivers
1772
1773 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. 
1774
1775 *XmlMDF_ADriver* is the root class for all attribute drivers.
1776
1777 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. 
1778
1779 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. 
1780
1781 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. 
1782
1783 @subsection occt_ocaf_9_3 XML Document Structure
1784
1785 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:
1786 * **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. 
1787 * **Element comments** -- consists of an unlimited number of \<comment\> sub-elements containing necessary comment strings. 
1788 * **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).
1789 * **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*.
1790
1791 ### OCAF Attributes Representation 
1792
1793 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. 
1794 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. 
1795 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. 
1796
1797 ### Example of resulting XML file 
1798
1799 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. 
1800
1801 ~~~~{.cpp}
1802 <?xml version="1.0" encoding="UTF-8"?> 
1803 <document format="XmlOcaf" xmlns="http://www.opencascade.org/OCAF/XML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1804 xsi:schemaLocation="http://www.opencascade.org/OCAF/XML http://www.opencascade.org/OCAF/XML/XmlOcaf.xsd">
1805
1806 <info date="2001-10-04" schemav="0" objnb="3"> 
1807 <iitem>Copyright: Open Cascade, 2001</iitem> 
1808 <iitem>STORAGE_VERSION: PCDM_ReadWriter_1</iitem> 
1809 <iitem>REFERENCE_COUNTER: 0</iitem> 
1810 <iitem>MODIFICATION_COUNTER: 1</iitem> 
1811 </info> 
1812 <comments/> 
1813 <label tag="0"> 
1814 <TDataStd_Name id="1">Document_1</TDataStd_Name> 
1815 <label tag="2"> 
1816 <TNaming_NamedShape id="2" evolution="primitive"> 
1817 <olds/> 
1818 <news> 
1819 <shape tshape="+34" index="1"/> 
1820 </news> 
1821 </TNaming_NamedShape> 
1822 </label> 
1823 </label> 
1824 \<shapes\> 
1825 ... 
1826 </shapes> 
1827 </document> 
1828
1829 ~~~~
1830
1831 @subsection occt_ocaf_9_4 XML Schema
1832
1833 The XML Schema defines the class of a document. 
1834
1835 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). 
1836
1837 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. 
1838
1839 The Schema files (XSD) are intended for two purposes: 
1840 * documenting the data format of files generated by OCAF; 
1841 * validation of documents when they are used by external (non-OCAF) applications, e.g., to generate reports. 
1842
1843 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. 
1844
1845 ### Management of Namespaces 
1846
1847 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: 
1848 * Define *targetNamespace* in the new XSD file describing the format. 
1849 * 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:"). 
1850 * 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. 
1851 * Pass (in every OCAF attribute driver) the namespace prefix of the *targetNamespace* to the constructor of *XmlMDF_ADriver*. 
1852
1853 @section occt_tobj TObj Package
1854
1855 @subsection occt_tobj_1 Introduction
1856
1857 This document describes the package TObj, which is an add-on 
1858 to the Open CASCADE Application Framework (OCAF).
1859
1860 This package provides a set of classes and auxiliary tools facilitating 
1861 the creation of object-oriented data models on top of low-level OCAF data structures. 
1862 This includes: 
1863
1864   * Definition of classes representing data objects. Data objects store their data using primitive OCAF attributes, taking advantage of OCAF mechanisms for Undo/Redo and persistence. At the same time they provide a higher level abstraction over the pure OCAF document structure (labels / attributes).
1865   * Organization of the data model as a hierarchical (tree-like) structure of objects.
1866   * Support of cross-references between objects within one model or among different models. In case of cross-model references the models should depend hierarchically.
1867   * Persistence mechanism for storing *TObj* objects in OCAF files, which allows storing and retrieving objects of derived types without writing additional code to support persistence. 
1868
1869 This document describes basic principles of logical and physical organization 
1870 of TObj-based data models and typical approaches to implementation of classes representing model objects.
1871
1872 @subsubsection occt_tobj_1_1 Applicability
1873
1874 The main purpose of the *TObj* data model is rapid development 
1875 of the object-oriented data models for applications, using the existing 
1876 functionality provided by OCAF (Undo/Redo and persistence) 
1877 without the necessity to redevelop such functionality from scratch.
1878
1879 As opposed to using bare OCAF (at the level of labels and attributes), 
1880 TObj facilitates dealing with higher level abstracts, which are closer 
1881 to the application domain. It works best when the application data are naturally 
1882 organized in hierarchical structures, and is especially useful for complex data 
1883 models with dependencies between objects belonging to different parts of the model.
1884
1885 It should be noted that *TObj* is efficient for representing data structures containing 
1886 a limited number of objects at each level of the data structure (typically less than 1000).
1887 A greater number of objects causes performance problems due to list-based organization of OCAF documents. Therefore, other methods of storage, such as arrays, are advisable for data models or their sub-parts containing a great number of uniform objects. However, these methods 
1888 can be combined with the usage of *TObj* to represent the high-level structure of the model.
1889
1890 @subsection occt_tobj_2 TObj Model
1891
1892 @subsubsection occt_tobj_2_1 TObj Model structure
1893
1894 In the *TObj* data model the data are separated from the interfaces that manage them.
1895
1896 It should be emphasized that *TObj* package defines only the interfaces and the basic structure of the model and objects, while the actual contents and structure of the model of a particular application are defined by its specific classes inherited from *TObj* classes. The implementation can add its own features or even change the default behaviour and the data layout, though this is not recommended. 
1897
1898 Logically the *TObj* data model is represented as a tree of model objects, with upper-level objects typically being collections of other objects (called *partitions*, represented by the class *TObj_Partition*). The root object of the model is called the *Main partition* and is maintained by the model itself. This partition contains a list of sub-objects called its *children* each sub-object may contain its own children (according to its type), etc. 
1899
1900 @figure{/user_guides/ocaf/images/tobj_image003.png,"TObj Data Model",240}
1901
1902 As the *TObj* Data Model is based on OCAF (Open CASCADE Application Framework) technology, 
1903 it stores its data in the underlying OCAF document. The OCAF document consists of a tree of 
1904 items called *labels*. Each label has some data attached to it in the form of *attributes*, 
1905 and may contain an arbitrary number of sub-labels. Each sub-label is identified by its sequential 
1906 number called the *tag*. The complete sequence of tag numbers of the label 
1907 and its parents starting from the document root constitutes the complete *entry* 
1908 of the label, which uniquely identifies its position in the document.
1909
1910 Generally the structure of the OCAF tree of the *TObj* data 
1911 model corresponds to the logical structure of the model and can be presented as in the following picture: 
1912
1913 @figure{/user_guides/ocaf/images/tobj_image004.png,"TObj Data Model mapped on OCAF document",360}
1914
1915 All data of the model are stored in the root label (0:1) of the OCAF document. 
1916 An attribute *TObj_TModel* is located in this root label. It 
1917 stores the object of type *TObj_Model*. This object serves as a main interface tool 
1918 to access all data and functionalities of the data model.
1919
1920 In simple cases all data needed by the application may be 
1921 contained in a single data model. Moreover, *TObj* gives the possibility to 
1922 distribute the data between several interconnected data models. This can be 
1923 especially useful for the applications dealing with great amounts of data. because 
1924 only the data required for the current operation is loaded in the memory at one time. 
1925 It is presumed that the models have a hierarchical (tree-like) structure, 
1926 where the objects of the child models can refer to the objects of the parent 
1927 models, not vice-versa. Provided that the correct order of loading and closing 
1928 of the models is ensured, the *TObj* classes will maintain references between the objects automatically.
1929
1930 @subsubsection occt_tobj_2_2 Data Model basic features
1931
1932 The class *TObj_Model* describing the data model provides the following functionalities: 
1933
1934   * Loading and saving of the model from or in a file (methods *Load* and *Save*)
1935   * Closing and removal of the model from memory (method *Close*)
1936   * Definition of the full file name of the persistence storage for this model (method *GetFile*)
1937   * Tools to organize data objects in partitions and iterate on objects (methods *GetObjects*, *GetMainPartition*, *GetChildren*, *getPartition*, *getElementPartition*)
1938   * Mechanism to give unique names to model objects 
1939   * Copy (*clone*) of the model (methods *NewEmpty* and *Paste*)
1940   * Support of earlier model formats for proper conversion of a model loaded from a file written by a previous version of the application (methods *GetFormatVersion* and *SetFormatVersion*)
1941   * Interface to check and update the model if necessary (method *Update*)
1942   * Support of several data models in one application. For this feature use OCAF multi-transaction manager, unique names and GUIDs of the data model (methods *GetModelName*, *GetGUID*)
1943
1944 @subsubsection occt_tobj_2_3 Model Persistence
1945
1946 The persistent representation of any OCAF model is contained in an XML or a binary file, 
1947 which is defined by the format string returned by the method *GetFormat*. 
1948 The default implementation works with a binary OCAF document format (*BinOcaf*). 
1949 The other available format is *XmlOcaf*. The class **TObj_Model** declares and provides a default 
1950 implementation of two virtual methods: 
1951
1952 ~~~~{.cpp}
1953     virtual Standard_Boolean Load (const char* theFile); 
1954     virtual Standard_Boolean SaveAs (const char* theFile); 
1955 ~~~~
1956
1957 which retrieve and store the model from or 
1958 in the OCAF file. The descendants 
1959 should define the following protected method to support Load and Save operations:
1960
1961 ~~~~{.cpp}
1962     virtual Standard_Boolean initNewModel (const Standard_Boolean IsNew); 
1963 ~~~~
1964
1965 This method is called by *Load* after creation of a new model 
1966 or after its loading from the file; its purpose is to perform 
1967 the necessary initialization of the model (such as creation of necessary top-level 
1968 partitions, model update due to version changes etc.). Note that if 
1969 the specified file does not exist, method *Load* will create 
1970 a new document and call *initNewModel* with the argument **True**. 
1971 If the file has been normally loaded, the argument **False** is passed. 
1972 Thus, a new empty *TObj* model is created by calling *Load* with an empty 
1973 string or the path to a nonexistent file as argument. 
1974
1975 The method *Load* returns **True** if the model has been retrieved successfully 
1976 (or created a new), or **False** if the model could not be loaded. 
1977 If no errors have been detected during initialization (model retrieval or creation),
1978 the virtual method *AfterRetrieval* is invoked for all objects of the model. 
1979 This method initializes or updates the objects immediately after the model initialization. 
1980 It could be useful when some object data should be imported from an OCAF attribute into transient 
1981 fields which could be changed outside of the OCAF transaction mechanism. 
1982 Such fields can be stored into OCAF attributes for saving into persistent storage during the save operation.
1983
1984 To avoid memory leaks, the *TObj_Model* class destructor invokes *Close* method 
1985 which clears the OCAF document and removes all data from memory before the model is destroyed.
1986
1987 For XML and binary persistence of the *TObj* data model the corresponding drivers are implemented 
1988 in *BinLDrivers*, *BinMObj* and *XmlLDrivers*, *XmlMObj* packages. 
1989 These packages contain retrieval and storage drivers for the model, model objects and custom attributes 
1990 from the *TObj* package. The schemas support persistence for the standard OCAF and *TObj* attributes. 
1991 This is sufficient for the implementation of simple data models, but 
1992 in some cases it can be reasonable to add specific OCAF attributes to 
1993 facilitate the storage of the data specific to the application. 
1994 In this case the schema should be extended using the standard OCAF mechanism. 
1995
1996 @subsubsection occt_tobj_2_4 Access to the objects in the model
1997
1998 All objects in the model are stored in the main partition and accessed by iterators.
1999 To access all model objects use: 
2000
2001 ~~~~{.cpp}
2002     virtual Handle(TObj_ObjectIterator) GetObjects () const; 
2003 ~~~~
2004
2005 This method returns a recursive iterator on all objects stored in the model.
2006
2007 ~~~~{.cpp}
2008     virtual Handle(TObj_ObjectIterator) GetChildren () const; 
2009 ~~~~
2010
2011 This method returns an iterator on child objects of the main partition.
2012 Use the following method to get the main partition: 
2013
2014 ~~~~{.cpp}
2015     Handle(TObj_Partition) GetMainPartition() const; 
2016 ~~~~
2017
2018 To receive the iterator on objects of a specific type *AType* use the following call: 
2019
2020 ~~~~{.cpp}
2021     GetMainPartition()-&gt;GetChildren(STANDARD_TYPE(AType) ); 
2022 ~~~~
2023
2024 The set of protected methods is provided for descendant classes to deal with partitions: 
2025
2026 ~~~~{.cpp}
2027     virtual Handle(TObj_Partition) getPartition (const TDF_Label, const Standard_Boolean  theHidden) const; 
2028 ~~~~
2029
2030 This method returns (creating if necessary) a partition in the specified label of the document. 
2031 The partition can be created as hidden (*TObj_HiddenPartition* class). 
2032 A hidden partition can be useful to distinguish the data that 
2033 should not be visible to the user when browsing the model in the application. 
2034
2035 The following two methods allow getting (creating) a partition 
2036 in the sub-label of the specified label in the document 
2037 (the label of the main partition for the second method) and with the given name: 
2038
2039 ~~~~{.cpp}
2040     virtual Handle(TObj_Partition) getPartition (const TDF_Label, const Standard_Integer theIndex, const TCollection_ExtendedString& theName, const Standard_Boolean  theHidden) const; 
2041     virtual Handle(TObj_Partition) getPartition (const Standard_Integer theIndex, const TCollection_ExtendedString& theName, const Standard_Boolean  theHidden) const; 
2042 ~~~~
2043
2044 If the default object naming and the name register mechanism 
2045 is turned on, the object can be found in the model by its unique name: 
2046
2047 ~~~~{.cpp}
2048     Handle(TObj_Object) FindObject (const Handle(TCollection_HExtendedString)& theName, const Handle(TObj_TNameContainer)& theDictionary) const; 
2049 ~~~~
2050
2051 @subsubsection occt_tobj_2_5 Own model data
2052
2053 The model object can store its own data in the Data label 
2054 of its main partition, however, there is no standard API for 
2055 setting and getting these data types. The descendants can add 
2056 their own data using standard OCAF methods. The enumeration DataTag is defined 
2057 in *TObj_Model* to avoid conflict of data labels used by this class 
2058 and its descendants, similarly to objects (see below). 
2059
2060 @subsubsection occt_tobj_2_6 Object naming
2061
2062 The basic implementation of *TObj_Model* provides the default 
2063 naming mechanism: all objects must have unique names, 
2064 which are registered automatically in the data model dictionary. 
2065 The dictionary is a *TObj_TNameContainer* 
2066 attribute whose instance is located in the model root label.
2067 If necessary, the developer can add several dictionaries into 
2068 the specific partitions, providing the name registration in the 
2069 correct name dictionary and restoring the name map after document is loaded from file.
2070 To ignore name registering it is necessary to redefine the methods *SetName*, 
2071 *AfterRetrieval* of the *TObj_Object* class and skip the registration of the object name. 
2072 Use the following methods for the naming mechanism: 
2073
2074 ~~~~{.cpp}
2075     Standard_Boolean IsRegisteredName (const Handle(TCollection_HExtendedString)& theName, const Handle(TObj_TNameContainer)& theDictionary ) const; 
2076 ~~~~
2077
2078 Returns **True** if the object name is already registered in the indicated (or model) dictionary. 
2079
2080 ~~~~{.cpp}
2081     void RegisterName (const Handle(TCollection_HExtendedString)& theName, const TDF_Label& theLabel, const Handle(TObj_TNameContainer)& theDictionary ) const; 
2082 ~~~~
2083
2084 Registers the object name with the indicated label where the object 
2085 is located in the OCAF document. Note that the default implementation 
2086 of the method *SetName* of the object registers the new name automatically 
2087 (if the name is not yet registered for any other object) 
2088
2089 ~~~~{.cpp}
2090     void UnRegisterName (const Handle(TCollection_HExtendedString)& theName, const Handle(TObj_TNameContainer)& theDictionary ) const; 
2091 ~~~~
2092
2093 Unregisters the name from the dictionary.
2094 The names of *TObj* model objects are removed from the dictionary when the objects are deleted from the model.
2095
2096 ~~~~{.cpp}
2097     Handle(TObj_TNameContainer) GetDictionary() const;
2098 ~~~~
2099
2100 Returns a default instance of the model dictionary (located at the model root label). 
2101 The default implementation works only with one dictionary. 
2102 If there are a necessity to have more than one dictionary for the model objects, 
2103 it is recommended to redefine the corresponding virtual method of TObj_Object 
2104 that returns the dictionary where names of objects should be registered.
2105
2106 @subsubsection occt_tobj_2_7 API for transaction mechanism
2107
2108 Class *TObj_Model* provides the API for transaction mechanism (supported by OCAF): 
2109
2110 ~~~~{.cpp}
2111     Standard_Boolean HasOpenCommand() const; 
2112 ~~~~
2113
2114 Returns True if a Command transaction is open 
2115
2116 ~~~~{.cpp}
2117     void OpenCommand() const; 
2118 ~~~~
2119
2120 Opens a new command transaction. 
2121
2122 ~~~~{.cpp}
2123     void CommitCommand() const; 
2124 ~~~~
2125
2126 Commits the Command transaction. Does nothing If there is no open Command transaction. 
2127
2128 ~~~~{.cpp}
2129     void AbortCommand() const; 
2130 ~~~~
2131
2132 Aborts the Command transaction. Does nothing if there is no open Command transaction. 
2133
2134 ~~~~{.cpp}
2135     Standard_Boolean IsModified() const; 
2136 ~~~~
2137
2138 Returns True if the model document has a modified status (has changes after the last save) 
2139
2140 ~~~~{.cpp}
2141     void SetModified( const Standard_Boolean ); 
2142 ~~~~
2143
2144 Changes the modified status by force. For synchronization of transactions 
2145 within several *TObj_Model* documents use class *TDocStd_MultiTransactionManager*. 
2146
2147 @subsubsection occt_tobj_28 Model format and version
2148
2149 Class *TObj_Model* provides the descendant classes with a means to control 
2150 the format of the persistent file by choosing the schema used to store or retrieve operations. 
2151
2152 ~~~~{.cpp}
2153     virtual TCollection_ExtendedString GetFormat () const; 
2154 ~~~~
2155
2156 Returns the string *TObjBin* or *TObjXml* indicating 
2157 the current persistent mechanism. The default value is *TObjBin*. 
2158 Due to the evolution of functionality of the developed application, 
2159 the contents and the structure of its data model vary from version to version. 
2160 *TObj* package provides a basic mechanism supporting backward versions compatibility, 
2161 which means that newer versions of the application will be able to read 
2162 Data Model files created by previous versions (but not vice-versa) with a minimum loss of data. 
2163 For each type of Data Model, all known versions of the data format 
2164 should be enumerated in increasing order, incremented with every change 
2165 of the model format. The current version of the model 
2166 format is stored in the model file and can be checked upon retrieval. 
2167
2168 ~~~~{.cpp}
2169     Standard_Integer GetFormatVersion() const; 
2170 ~~~~
2171
2172 Returns the format version stored in the model file 
2173
2174 ~~~~{.cpp}
2175     void SetFormatVersion(const Standard_Integer theVersion); 
2176 ~~~~
2177
2178 Defines the format version used for save. 
2179
2180 Upon loading a model, the method *initNewModel()*, called immediately 
2181 after opening a model from disk (on the level of the OCAF document), 
2182 provides a specific code that checks the format version stored in that model. 
2183 If it is older than the current version of the application, the data update can be performed. 
2184 Each model can have its own specific conversion code 
2185 that performs the necessary data conversion to make them compliant with the current version. 
2186
2187 When the conversion ends the user is advised of that by the messenger interface 
2188 provided by the model (see messaging chapter for more details), 
2189 and the model version is updated. If the version of data model is not supported 
2190 (it is newer than the current or too old), the load operation should fail. 
2191 The program updating the model after version change can be implemented as static 
2192 methods directly in C++ files of the corresponding Data Model classes, 
2193 not exposing it to the other parts of the application. 
2194 These codes can use direct access to the model and objects data (attributes) 
2195 not using objects interfaces, because the data model API and object classes 
2196 could have already been changed. 
2197
2198 Note that this mechanism has been designed to maintain version compatibility 
2199 for the changes of data stored in the model, not for the changes of 
2200 low-level format of data files (such as the storage format of a specific OCAF attribute). 
2201 If the format of data files changes, a specific treatment on a case-by-case basis will be required. 
2202
2203 @subsubsection occt_tobj_2_9 Model update
2204
2205 The following methods are used for model update to ensure its consistency 
2206 with respect to the other models in case of cross-model dependencies: 
2207
2208 ~~~~{.cpp}
2209     virtual Standard_Boolean Update(); 
2210 ~~~~
2211
2212 This method is usually called after loading of the model. 
2213 The default implementation does nothing and returns **True**. 
2214
2215 ~~~~{.cpp}
2216     virtual Standard_Boolean initNewModel( const Standard_Boolean IsNew); 
2217 ~~~~
2218
2219 This method performs model initialization, check and updates (as described above). 
2220
2221 ~~~~{.cpp}
2222     virtual void updateBackReferences( const Handle(TObj_Object)& theObj); 
2223 ~~~~
2224
2225 This method is called from the previous method to update back references 
2226 of the indicated object after the retrieval of the model from file 
2227 (see data model - object relationship chapter for more details) 
2228
2229 @subsubsection occt_tobj_2_10 Model copying
2230
2231 To copy the model between OCAF documents use the following methods: 
2232
2233 ~~~~{.cpp}
2234     virtual Standard_Boolean Paste (Handle(TObj_Model) theModel, Handle(TDF_RelocationTable) theRelocTable = 0 ); 
2235 ~~~~
2236
2237 Pastes the current model to the new model. The relocation table 
2238 ensures correct copying of the sub-data shared by several parts of the model. 
2239 It stores a map of processed original objects of relevant types in their copies. 
2240
2241 ~~~~{.cpp}
2242     virtual Handle(TObj_Model) NewEmpty() = 0; 
2243 ~~~~
2244
2245 Redefines a pure virtual method to create a new empty instance of the model. 
2246
2247 ~~~~{.cpp}
2248     void CopyReferences ( const Handle(TObj_Model)& theTarget, const Handle(TDF_RelocationTable)& theRelocTable); 
2249 ~~~~
2250
2251 Copies the references from the current model to the target model. 
2252
2253 @subsubsection occt_tobj_2_11 Messaging
2254
2255 The messaging is organised using Open CASCADE Messenger from the package Message. 
2256 The messenger is stored as the field of the model instance 
2257 and can be set and retrieved by the following methods: 
2258
2259 ~~~~{.cpp}
2260     void SetMessenger( const Handle(Message_Messenger)& ); 
2261     Handle(Message_Messenger) Messenger() const; 
2262 ~~~~
2263
2264 A developer should create his own instance of the Messenger 
2265 bound to the application user interface, and attribute it to the model 
2266 for future usage. In particular the messenger is used for reporting 
2267 errors and warnings in the persistence mechanism. 
2268 Each message has a unique string identifier (key). 
2269 All message keys are stored in a special resource file TObj.msg. 
2270 This file should be loaded at the start of the application 
2271 by call to the appropriate method of the class *Message_MsgFile*. 
2272
2273 @subsection occt_tobj_3 Model object
2274
2275 Class *TObj_Object* provides basic interface and default implementation 
2276 of important features of *TObj* model objects. This implementation defines 
2277 basic approaches that are recommended for all descendants, 
2278 and provides tools to facilitate their usage. 
2279
2280 @figure{/user_guides/ocaf/images/tobj_image005.png,"TObj objects hierarchy",170}
2281
2282 @subsubsection occt_tobj_3_1 Separation of data and interface
2283
2284 In the *TObj* data model, the data are separated from the interfaces that manage them. 
2285 The data belonging to a model object are stored in its root label and sub-labels 
2286 in the form of standard OCAF attributes. This allows using standard OCAF mechanisms 
2287 for work with these data, and eases the implementation of the persistence mechanism. 
2288
2289 The instance of the interface which serves as an API for managing object data 
2290 (e.g. represents the model object) is stored in the root label of the object, 
2291 and typically does not bring its own data. The interface classes are organized in a hierarchy 
2292 corresponding to the natural hierarchy of the model objects according to the application. 
2293
2294 In the text below the term 'object' is used to denote either the instance 
2295 of the interface class or the object itself (both interface and data stored in OCAF). 
2296
2297 The special type of attribute *TObj_TObject* is used for storing instances of objects interfaces 
2298 in the OCAF tree. *TObj_TObject* is a simple container for the object of type *TObj_Object*. 
2299 All objects (interfaces) of the data model  inherit this class. 
2300
2301 @figure{/user_guides/ocaf/images/tobj_image006.png,"TObj object stored on OCAF label",360}
2302
2303
2304 @subsubsection occt_tobj_3_2 Basic features
2305
2306 The *TObj_Object* class provides some basic features that can be inherited (or, if necessary, redefined) by the descendants: 
2307
2308   * Gives access to the model to which the object belongs (method *GetModel*) and to the OCAF label in which the object is stored (method *GetLabel*). 
2309   * Supports references (and back references) to other objects in the same or in another model (methods *getReference*, *setReference*, *addReference*, *GetReferences*, *GetBackReferences*, *AddBackReference*, *RemoveBackReference*, *ReplaceReference*)
2310   * Provides the ability to contain child objects, as it is actual for partition objects (methods *GetChildren*, *GetFatherObject*)
2311   * Organizes its data in the OCAF structure by separating the sub-labels of the main label intended for various kinds of data and providing tools to organize these data (see <a href="../../../../Documents%20and%20Settings/TEMP/obj-inher">below</a>). The kinds of data stored separately are: 
2312           * Child objects stored in the label returned by the method *GetChildLabel* 
2313           * References to other objects stored in the label returned by the method *GetReferenceLabel* 
2314           * Other data, both common to all objects and specific for each subtype of the model object, are stored in the label returned by the method *GetDataLabel* 
2315   * Provides unique names of all objects in the model (methods *GetDictionary*, *GetName*, *SetName*)
2316   * Provides unified means to maintain persistence (implemented in descendants with the help of macros *DECLARE_TOBJOCAF_PERSISTENCE* and *IMPLEMENT_TOBJOCAF_PERSISTENCE*)
2317   * Allows an object to remove itself from the OCAF document and check the depending objects can be deleted according to the  back references (method *Detach*)
2318   * Implements methods for identification and versioning of objects 
2319   * Manages the object interaction with OCAF Undo/Redo mechanism (method *IsAlive*, *AfterRetrieval*, *BeforeStoring*)
2320   * Allows make a clone (methods *Clone*, *CopyReferences*, *CopyChildren*, *copyData*)
2321   * Contains additional word of bit flags (methods *GetFlags*, *SetFlags*, *TestFlags*, *ClearFlags*)
2322   * Defines the interface to sort the objects by rank (methods *GetOrder*, *SetOrder*)
2323   * Provides a number of auxiliary methods for descendants to set/get the standard attribute values, such as int, double, string, arrays etc.
2324
2325 An object can be received from the model by the following methods: 
2326
2327 ~~~~{.cpp}
2328     static Standard_Boolean GetObj ( const TDF_Label& theLabel, Handle(TObj_Object)& theResObject, const Standard_Boolean isSuper = Standard_False ); 
2329 ~~~~
2330
2331 Returns *True* if the object has been found in the indicated label (or in the upper level label if *isSuper* is *True*). 
2332
2333 ~~~~{.cpp}
2334     Handle(TObj_Object) GetFatherObject ( const Handle(Standard_Type)& theType = NULL ) const; 
2335 ~~~~
2336
2337 Returns the father object of the indicated type 
2338 for the current object (the direct father object if the type is NULL). 
2339
2340 @subsubsection occt_tobj_3_3 Data layout and inheritance
2341
2342 As far as the data objects are separated from the interfaces and stored in the OCAF tree, 
2343 the functionality to support inheritance is required. Each object has its own data 
2344 and references stored in the labels in the OCAF tree. All data are stored in the sub-tree 
2345 of the main object label. If it is necessary to inherit a class from the base class, 
2346 the descendant class should use different labels for data and references than its ancestor. 
2347
2348 Therefore each *TObj* class can reserve the range of tags in each of 
2349 *Data*, *References*, and *Child* sub-labels. 
2350 The reserved range is declared by the enumeration defined 
2351 in the class scope (called DataTag, RefTag, and ChildTag, respectively). 
2352 The item *First* of the enumeration of each type is defined via the *Last* item 
2353 of the corresponding enumeration of the parent class, thus ensuring that the tag numbers 
2354 do not overlap. The item *Last* of the enumeration defines the last tag reserved by this class. 
2355 Other items of the enumeration define the tags used for storing particular data items of the object. 
2356 See the declaration of the TObj_Partition class for the example. 
2357
2358 *TObj_Object* class provides a set of auxiliary methods for descendants 
2359 to access the data stored in sub-labels by their tag numbers: 
2360
2361 ~~~~{.cpp}
2362     TDF_Label getDataLabel (const Standard_Integer theRank1, const Standard_Integer theRank2 = 0) const; 
2363     TDF_Label getReferenceLabel (const Standard_Integer theRank1, const Standard_Integer theRank2 = 0) const; 
2364 ~~~~
2365
2366 Returns the label in *Data* or *References* sub-labels at a given tag number (theRank1). 
2367 The second argument, theRank2, allows accessing the next level of hierarchy 
2368 (theRank2-th sub-label of theRank1-th data label). 
2369 This is useful when the data to be stored are represented by multiple OCAF attributes 
2370 of the same type (e.g. sequences of homogeneous data or references). 
2371
2372 The get/set methods allow easily accessing the data located in the specified data label 
2373 for the most widely used data types (*Standard_Real*, *Standard_Integer*, *TCollection_HExtendedString*,
2374  *TColStd_HArray1OfReal*, *TColStd_HArray1OfInteger*, *TColStd_HArray1OfExtendedString*). 
2375 For instance, methods provided for real numbers are: 
2376
2377 ~~~~{.cpp}
2378     Standard_Real getReal (const Standard_Integer theRank1, const Standard_Integer theRank2 = 0) const; 
2379     Standard_Boolean setReal (const Standard_Real theValue, const Standard_Integer theRank1, const Standard_Integer theRank2 = 0, const Standard_Real theTolerance = 0.) const; 
2380 ~~~~
2381
2382 Similar methods are provided to access references to other objects: 
2383
2384 ~~~~{.cpp}
2385     Handle(TObj_Object) getReference (const Standard_Integer theRank1, const Standard_Integer theRank2 = 0) const; 
2386     Standard_Boolean setReference (const Handle(TObj_Object) &theObject, const Standard_Integer theRank1, const Standard_Integer theRank2 = 0); 
2387 ~~~~
2388
2389 The method *addReference* gives an easy way to store a sequence of homogeneous references in one label. 
2390
2391 ~~~~{.cpp}
2392     TDF_Label addReference (const Standard_Integer theRank1, const Handle(TObj_Object) &theObject); 
2393 ~~~~
2394
2395 Note that while references to other objects should be defined by descendant classes 
2396 individually according to the type of object, *TObj_Object* provides methods 
2397 to manipulate (check, remove, iterate) the existing references in the uniform way, as described below. 
2398
2399 @subsubsection occt_tobj_3_4 Persistence
2400
2401 The persistence of the *TObj* Data Model is implemented with the help 
2402 of standard OCAF mechanisms (a schema defining necessary plugins, drivers, etc.). 
2403 This implies the possibility to store/retrieve all data that are stored 
2404 as standard OCAF attributes., The corresponding handlers are added 
2405 to the drivers for *TObj*-specific attributes. 
2406
2407 The special tool is provided for classes inheriting from *TObj_Object* 
2408 to add the new types of persistence without regeneration of the OCAF schema. 
2409 The class *TObj_Persistence* provides basic means for that: 
2410
2411   * automatic run-time registration of object types
2412   * creation of a new object of the specified type (one of the registered types) 
2413
2414 Two macros defined in the file TObj_Persistence.hxx have to be included in the definition 
2415 of each model object class inheriting TObj_Object to activate the persistence mechanism: 
2416
2417 ~~~~{.cpp}
2418     DECLARE_TOBJOCAF_PERSISTENCE (classname, ancestorname) 
2419 ~~~~
2420
2421 Should be included in the private section of declaration of each class inheriting 
2422 *TObj_Object* (hxx file). This macro adds an additional constructor to the object class, 
2423 and declares an auxiliary (private) class inheriting *TObj_Persistence* 
2424 that provides a tool to create a new object of the proper type. 
2425
2426 ~~~~{.cpp}
2427     IMPLEMENT_TOBJOCAF_PERSISTENCE (classname) 
2428 ~~~~
2429
2430 Should be included in .cxx file of each object class that should be saved and restored. 
2431 This is not needed for abstract types of objects. This macro implements the functions 
2432 declared by the previous macro and creates a static member 
2433 that automatically registers that type for persistence. 
2434
2435 When the attribute *TObj_TObject* that contains the interface object is saved, 
2436 its persistence handler stores the runtime type of the object class. 
2437 When the type is restored the handler dynamically recognizes the type 
2438 and creates the corresponding object using mechanisms provided by *TObj_Persistence*. 
2439
2440 @subsubsection occt_tobj_3_5 Names of objects
2441
2442 All *TObj* model objects  have names by which the user can refer to the object. 
2443 Upon creation, each object receives a default name, constructed 
2444 from the prefix corresponding to the object type (more precisely, the prefix is defined 
2445 by the partition to which the object belongs), and the index of the object in the current partition. 
2446 The user has the possibility to change this name. The uniqueness of the name in the model is ensured 
2447 by the naming mechanism (if the name is already used, it cannot be attributed to another object). 
2448 This default implementation of *TObj* package works with a single instance of the name container (dictionary) 
2449 for name registration of objects and it is enough in most simple projects. 
2450 If necessary, it is easy to redefine a couple of object methods 
2451 (for instance *GetDictionary*()) and to take care of  construction and initialization of containers. 
2452
2453 This functionality is provided by the following methods: 
2454
2455 ~~~~{.cpp}
2456     virtual Handle(TObj_TNameContainer) GetDictionary() const; 
2457 ~~~~
2458
2459 Returns the name container where the name of object should be registered. 
2460 The default implementation returns the model name container. 
2461
2462 ~~~~{.cpp}
2463     Handle(TCollection_HExtendedString) GetName() const; 
2464     Standard_Boolean GetName( TCollection_ExtendedString& theName ) const; 
2465     Standard_Boolean GetName( TCollection_AsciiString& theName ) const; 
2466 ~~~~
2467
2468 Returns the object name. The methods with in / out argument return False if the object name is not defined. 
2469
2470 ~~~~{.cpp}
2471     virtual Standard_Boolean SetName ( const Handle(TCollection_HExtendedString)& theName ) const; 
2472     Standard_Boolean SetName         ( const Handle(TCollection_HAsciiString)& theName ) const; 
2473     Standard_Boolean SetName         ( const Standard_CString theName ) const; 
2474 ~~~~
2475
2476 Attributes a new name to the object and returns **True** if the name has been attributed successfully. 
2477 Returns False if the name has been already attributed to another object. 
2478 The last two methods are short-cuts to the first one. 
2479
2480 @subsubsection occt_tobj_3_6 References between objects 
2481
2482 Class *TObj_Object* allows creating references to other objects in the model. 
2483 Such references describe relations among objects which are not adequately reflected 
2484 by the hierarchical objects structure in the model (parent-child relationship). 
2485
2486 The references are stored internally using the attribute TObj_TReference. 
2487 This attribute is located in the sub-label of the referring object (called *master*) 
2488 and keeps reference to the main label of the referred object. 
2489 At the same time the referred object can maintain the back reference to the master object. 
2490
2491 @figure{/user_guides/ocaf/images/tobj_image007.png,"Objects relationship",360}
2492
2493
2494
2495 The back references are stored not in the OCAF document but as a transient field 
2496 of the object; they are created when the model is restored from file, 
2497 and updated automatically when the references are manipulated. 
2498 The class *TObj_TReference* allows storing references between objects 
2499 from different *TObj* models, facilitating the construction of complex relations between objects. 
2500
2501 The most used methods for work with references are: 
2502
2503 ~~~~{.cpp}
2504     virtual Standard_Boolean HasReference( const Handle(TObj_Object)& theObject) const; 
2505 ~~~~
2506
2507 Returns True if the current object refers to the indicated object. 
2508
2509 ~~~~{.cpp}
2510     virtual Handle(TObj_ObjectIterator) GetReferences ( const Handle(Standard_Type)& theType = NULL ) const; 
2511 ~~~~
2512
2513 Returns an iterator on the object references. The optional argument *theType* 
2514 restricts the types of referred objects, or does not if it is NULL. 
2515
2516 ~~~~{.cpp}
2517     virtual void RemoveAllReferences(); 
2518 ~~~~
2519
2520 Removes all references from the current object. 
2521
2522 ~~~~{.cpp}
2523     virtual void RemoveReference( const Handle(TObj_Object)& theObject ); 
2524 ~~~~
2525
2526 Removes the reference to the indicated object. 
2527
2528 ~~~~{.cpp}
2529     virtual Handle(TObj_ObjectIterator) GetBackReferences ( const Handle(Standard_Type)& theType = NULL ) const; 
2530 ~~~~
2531
2532 Returns an iterator on the object back references. 
2533 The argument theType restricts the types of master objects, or does not if it is NULL. 
2534
2535 ~~~~{.cpp}
2536     virtual void ReplaceReference  ( const Handle(TObj_Object)& theOldObject,  const Handle(TObj_Object)& theNewObject ); 
2537 ~~~~
2538
2539 Replaces the reference to theOldObject by the reference to *theNewObject*. 
2540 The handle theNewObject may be NULL to remove the reference. 
2541
2542 ~~~~{.cpp}
2543     virtual Standard_Boolean RelocateReferences  ( const TDF_Label& theFromRoot,  const TDF_Label& theToRoot, const Standard_Boolean theUpdateackRefs = Standard_True ); 
2544 ~~~~
2545
2546 Replaces all references to a descendant label of *theFromRoot* 
2547 by the references to an equivalent label under *theToRoot*. 
2548 Returns **False** if the resulting reference does not point at a *TObj_Object*. 
2549 Updates back references if theUpdateackRefs is **True**. 
2550
2551 ~~~~{.cpp}
2552     virtual Standard_Boolean CanRemoveReference ( const Handle(TObj_Object)& theObj) const; 
2553 ~~~~
2554
2555 Returns **True** if the reference can be removed and the master object 
2556 will remain valid (*weak* reference). 
2557 Returns **False** if the master object cannot be valid without the referred object (*strong* reference). 
2558 This affects the behaviour of objects removal from the model -- if the reference cannot be removed, 
2559 either the referred object will not be removed, or both the referred 
2560 and the master objects will be removed (depends on the deletion mode in the method **Detach**) 
2561
2562 @subsubsection occt_tobj_3_7 Creation and deletion of objects
2563
2564 It is recommended that all objects inheriting from *TObj_Object*
2565  should implement the same approach to creation and deletion. 
2566  
2567 The object of the *TObj* data model cannot be created independently 
2568 of the model instance, as far as it stores the object data in OCAF data structures. 
2569 Therefore an object class cannot be created directly as its constructor is protected. 
2570
2571 Instead, each object should provide a static method *Create*(), which accepts the model, 
2572 with the label, which stores the object and other type-dependent parameters 
2573 necessary for proper definition of the object. This method creates a new object with its data 
2574 (a set of OCAF attributes) in the specified label, and returns a handle to the object's interface. 
2575
2576 The method *Detach*() is provided for deletion of objects from OCAF model. 
2577 Object data are deleted from the corresponding OCAF label; however, 
2578 the handle on object remains valid. The only operation available after object deletion 
2579 is the method *IsAlive*()  checking whether the object has been deleted or not, 
2580 which returns False if the object has been deleted. 
2581
2582 When the object is deleted from the data model, the method checks 
2583 whether there are any alive references to the object. 
2584 Iterating on references the object asks each referring (master) object 
2585 whether the reference can be removed. If the master object can be unlinked, 
2586 the reference is removed, otherwise the master object will be removed too 
2587 or the referred object will be kept alive. This check is performed by the method *Detach* , 
2588 but the behavior depends on the deletion mode *TObj_DeletingMode*: 
2589
2590   * **TObj_FreeOnly** -- the object will be destroyed only if it is free, i.e. there are no references to it from other objects
2591   * **TObj_KeepDepending** -- the object will be destroyed if there are no strong references to it from master objects (all references can be unlinked)
2592   * **TObj_Force** -- the object and all depending master objects that have strong references to it will be destroyed.
2593
2594 The most used methods for object removing are: 
2595
2596 ~~~~{.cpp}
2597     virtual Standard_Boolean CanDetachObject (const TObj_DeletingMode theMode = TObj_FreeOnly ); 
2598 ~~~~
2599
2600 Returns **True** if the object can be deleted with the indicated deletion mode. 
2601
2602 ~~~~{.cpp}
2603     virtual Standard_Boolean Detach ( const TObj_DeletingMode theMode = TObj_FreeOnly ); 
2604 ~~~~
2605
2606 Removes the object from the document if possible 
2607 (according to the indicated deletion mode). 
2608 Unlinks references from removed objects. 
2609 Returns **True** if the objects have been successfully deleted. 
2610
2611 @subsubsection occt_tobj_3_8 Transformation and replication of object data
2612
2613 *TObj_Object* provides a number of special virtual methods  to support replications of objects. These methods should be redefined by descendants when necessary. 
2614
2615 ~~~~{.cpp}
2616     virtual Handle(TObj_Object) Clone (const TDF_Label& theTargetLabel, Handle(TDF_RelocationTable) theRelocTable = 0); 
2617 ~~~~
2618
2619 Copies the object to theTargetLabel. The new object will have all references of its original. 
2620 Returns a handle to the new object (null handle if fail). The data are copied directly, 
2621 but the name is changed by adding the postfix *_copy*. 
2622 To assign different names to the copies redefine the method: 
2623
2624 ~~~~{.cpp}
2625     virtual Handle(TCollection_HExtendedString) GetNameForClone ( const Handle(TObj_Object)& ) const; 
2626 ~~~~
2627
2628 Returns the name for a new object copy. It could be useful to return the same object name 
2629 if the copy will be in the other model or in the other partition with its own dictionary. 
2630 The method *Clone* uses the following public methods for object data replications: 
2631
2632 ~~~~{.cpp}
2633     virtual void CopyReferences (const const Handle(TObj_Object)& theTargetObject, const Handle(TDF_RelocationTable) theRelocTable); 
2634 ~~~~
2635
2636 Adds to the copy of the original object its references. 
2637
2638 ~~~~{.cpp}
2639     virtual void CopyChildren (TDF_Label& theTargetLabel, const Handle(TDF_RelocationTable) theRelocTable); 
2640 ~~~~
2641
2642 Copies the children of an object to the target child label. 
2643
2644 @subsubsection occt_tobj_3_9 Object flags
2645
2646 Each instance of *TObj_Object* stores a set of bit flags, 
2647 which facilitate the storage of auxiliary logical information assigned to the objects 
2648 (object state). Several typical state flags are defined in the enumeration *ObjectState*: 
2649
2650   * *ObjectState_Hidden* -- the object is marked as hidden
2651   * *ObjectState_Saved* -- the object has (or should have) the corresponding saved file on disk
2652   * *ObjectState_Imported* -- the object is imported from somewhere
2653   * *ObjectState_ImportedByFile* -- the object has been imported from file and should be updated to have correct relations with other objects
2654   * *ObjectState_Ordered* -- the partition contains objects that can be ordered.
2655
2656 The user (developer) can define any new flags in descendant classes. 
2657 To set/get an object, the flags use the following methods: 
2658
2659 ~~~~{.cpp}
2660     Standard_Integer GetFlags() const; 
2661     void SetFlags( const Standard_Integer theMask ); 
2662     Stadnard_Boolean TestFlags( const Standard_Integer theMask ) const; 
2663     void ClearFlags( const Standard_Integer theMask = 0 ); 
2664 ~~~~
2665
2666 In addition, the generic virtual interface stores the logical properties 
2667 of the object class in the form of a set of bit flags. 
2668 Type flags can be received by the method: 
2669
2670 ~~~~{.cpp}
2671     virtual Standard_Integer GetTypeFlags() const; 
2672 ~~~~
2673
2674 The default implementation returns the flag **Visible** 
2675 defined in the enumeration *TypeFlags*. This flag is used to define visibility 
2676 of the object for the user browsing the model (see class *TObj_HiddenPartition*). 
2677 Other flags can be added by the applications. 
2678
2679 @subsubsection occt_tobj_310 Partitions
2680
2681 The special kind of objects defined by the class *TObj_Partition* 
2682 (and its descendant *TObj_HiddenPartition*) is provided for partitioning 
2683 the model into a hierarchical structure. This object represents the container 
2684 of other objects. Each *TObj* model contains the main partition that is placed 
2685 in the same OCAF label as the model object, and serves as a root of the object's tree. 
2686 A hidden partition is a simple partition with a predefined hidden flag. 
2687
2688 The main partition object methods: 
2689
2690 ~~~~{.cpp}
2691     TDF_Label NewLabel() const; 
2692 ~~~~
2693
2694 Allocates and returns a new label for creation of a new child object. 
2695
2696 ~~~~{.cpp}
2697     void SetNamePrefix  ( const Handle(TCollection_HExtendedString)& thePrefix); 
2698 ~~~~
2699
2700 Defines the prefix for automatic generation of names of the newly created objects. 
2701
2702 ~~~~{.cpp}
2703     Handle(TCollection_HExtendedString) GetNamePrefix() const; 
2704 ~~~~
2705
2706 Returns the current name prefix. 
2707
2708 ~~~~{.cpp}
2709     Handle(TCollection_HExtendedString) GetNewName ( const Standard_Boolean theIsToChangeCount) const; 
2710 ~~~~
2711
2712 Generates the new name and increases the internal counter of child objects if theIsToChangeCount is **True**. 
2713
2714 ~~~~{.cpp}
2715     Standard_Integer GetLastIndex() const; 
2716 ~~~~
2717
2718 Returns the last reserved child index. 
2719
2720 ~~~~{.cpp}
2721     void SetLastIndex( const Standard_Integer theIndex ); 
2722 ~~~~
2723
2724 Sets the last reserved index. 
2725
2726 @subsection occt_tobj_4 Auxiliary classes
2727
2728 Apart from the model and the object, package *TObj* provides a set of auxiliary classes: 
2729
2730   * *TObj_Application* -- defines OCAF application supporting existence and operation with *TObj* documents.
2731   * *TObj_Assistant* -- class provides an interface to the static data to be used during save and load operations on models. In particular, in case of cross-model dependencies it allows passing information on the parent model to the OCAF loader to correctly resolve the references when loading a dependent model.
2732   * *TObj_TReference* -- OCAF attribute describes the references between objects in the *TObj* model(s). This attribute stores the label of the referred model object, and provides transparent cross-model references. At runtime, these references are simple Handles; in persistence mode, the cross-model references are automatically detected and processed by the persistence mechanism of *TObj_TReference* attribute. 
2733   * Other classes starting with *TObj_T...* -- define OCAF attributes used to store TObj-specific classes and some types of data on OCAF labels. 
2734   * Iterators -- a set of classes implementing *TObj_ObjectIterator* interface, used for iterations on *TObj* objects:
2735           * *TObj_ObjectIterator* -- a basic abstract class for other *TObj* iterators. Iterates on *TObj_Object* instances. 
2736           * *TObj_LabelIterator* -- iterates on object labels in the *TObj* model document 
2737           * *TObj_ModelIterator* -- iterates on all objects in the model. Works with sequences of other iterators. 
2738           * *TObj_OcafObjectIterator* -- Iterates on *TObj* data model objects. Can iterate on objects of a specific type. 
2739           * *TObj_ReferenceIterator* -- iterates on object references. 
2740           * *TObj_SequenceIterator* -- iterates on a sequence of *TObj* objects. 
2741           * *TObj_CheckModel* -- a tool that checks the internal consistency of the model. The basic implementation checks only the consistency of references between objects.
2742
2743 The structure of *TObj* iterators hierarchy is presented below: 
2744
2745 @figure{/user_guides/ocaf/images/tobj_image008.png,"Hierarchy of iterators",420}
2746
2747
2748 @subsection occt_tobj_5 Packaging
2749
2750 The *TObj* sources are distributed in the following packages: 
2751
2752   * *TObj* -- defines basic classes that implement *TObj* interfaces for OCAF-based modelers.
2753   * *BinLDrivers, XmlLDrivers* -- binary and XML driver of *TObj* package
2754   * *BinLPlugin, XmlLPlugin* -- plug-in for binary and XML persistence
2755   * *BinMObj, XmlMObj* -- binary and XML drivers to store and retrieve specific *TObj* data to or from OCAF document
2756   * *TKBinL, TKXmlL* -- toolkits of binary and XML persistence
2757
2758
2759 @section occt_ocaf_10 GLOSSARY
2760
2761 * **Application** -- a document container holding all documents containing all application data. 
2762 * **Application data** -- the data produced by an application, as opposed to data referring to it. 
2763 * **Associativity of data** -- the ability to propagate modifications made to one document to other documents, which refer to such document. Modification propagation is: 
2764   * unidirectional, that is, from the referenced to the referencing document(s), or
2765   * bi-directional, from the referencing to the referenced document and vice-versa.
2766 * **Attribute** -- a container for application data. An attribute is attached to a label in the hierarchy of the data framework. 
2767 * **Child** -- a label created from another label, which by definition, is the father label. 
2768 * **Compound document** -- a set of interdependent documents, linked to each other by means of external references. These references provide the associativity of data. 
2769 * **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. 
2770 * **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: 
2771         * Manage modifications, providing Undo and Redo functions 
2772         * Manage command transactions 
2773         * Update external links 
2774         * Manage save and restore options 
2775         * Store the names of software extensions. 
2776 * **Driver** -- an abstract class, which defines the communications protocol with a system. 
2777 * **Entry** -- an ASCII character string containing the tag list of a label. For example:
2778 ~~~~{.cpp}
2779 0:3:24:7:2:7 
2780 ~~~~
2781
2782 * **External links** -- references from one data structure to another data structure in another document. 
2783 To store these references properly, a label must also contain an external link attribute. 
2784 * **Father** -- a label, from which other labels have been created. The other labels are, by definition, the children of this label. 
2785 * **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: 
2786   * defining new classes which inherit from these abstract classes
2787   * composing framework class instances
2788   * implementing the services required by the framework.
2789
2790 In C++, the application behavior is implemented in virtual functions redefined in these derived classes. This is known as overriding. 
2791
2792 * **GUID** -- Global Universal ID. A string of 37 characters intended to uniquely identify an object. For example:
2793 ~~~~{.cpp}
2794 2a96b602-ec8b-11d0-bee7-080009dc3333 
2795 ~~~~
2796
2797 * **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. 
2798 * **Modified label** -- containing attributes whose data has been modified. 
2799 * **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. 
2800 * **Resource file** -- a file containing a list of each document’s schema name and the storage and retrieval plug-ins for that document. 
2801 * **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. 
2802 * **Scope** -- the set of all the attributes and labels which depend on a given label. 
2803 * **Tag list** -- a list of integers, which identify the place of a label in the data framework.  This list is displayed in an entry. 
2804 * **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. 
2805 * **Topological tracking** -- following a topological entity in a model through the steps taken to edit and regenerate that model. 
2806 * **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.