c75ae59e88ab9526580a10cf38b03749da6512bb
[occt.git] / dox / user_guides / ocaf / ocaf.md
1 OCAF  {#occt_user_guides__ocaf}
2 ========================
3
4 @tableofcontents
5
6 @section occt_ocaf_1 Introduction
7
8 This manual explains how to use the Open CASCADE Application Framework (OCAF).
9 It provides basic documentation on using OCAF. For advanced information on OCAF 
10 and its applications, see our offerings on our web site at 
11 <a href="http://www.opencascade.org/support/training/">www.opencascade.org/support/training/</a> 
12
13 OCAF (the Open CASCADE Application Framework) is a RAD (Rapid Application Development) framework used for 
14 specifying and organizing application data. To do this, OCAF provides: 
15
16   * Ready-to-use data common to most CAD/CAM applications,
17   * A scalable extension protocol for implementing new application specific data,
18   * An infrastructure
19   * To attach any data to any topological element
20   * To link data produced by different applications (*associativity of data*)
21   * To register the modeling process - the creation history, or parametrics, used to carry out the modifications.
22
23 Using OCAF, the application designer concentrates on the functionality and its specific algorithms. In this way, he avoids architectural problems notably implementing Undo-redo and saving application data. 
24
25 In OCAF, all of the above are already handled for the application designer, allowing him to reach a significant increase in productivity. 
26
27 In this respect, 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 a logical supplement to these libraries. 
28
29 The table below contrasts the design of a modeling application using object libraries alone and using OCAF. 
30
31 **Table 1: Services provided by OCAF** 
32
33 |Development tasks      |Comments | Without OCAF        | With OCAF |
34 |------------------:|---------:|---------------:|-----------:|
35 |Creation of geometry| Algorithm Calling the modeling libraries |       To be created by the user       | To be created by the user| 
36 | Data organization | Including specific attributes and modeling process | To be created by the user |  Simplified| 
37 | Saving data in a file | Notion of document | To be created by the user | Provided |
38 | Document-view management |    |  To be created by the user | Provided |
39 | Application infrastructure | New, Open, Close, Save and Save As File menus | To be created by the user | Provided | 
40 | Undo-Redo | Robust, multi-level       | To be created by the user     | Provided |
41 | Application-specific dialog boxes     |    | To be created by the user  |     To be created by the user |
42
43
44
45 The relationship between OCAF and the Open CASCADE Technology (**OCCT**) Object Libraries can be seen in the image below. 
46
47 @figure{/user_guides/ocaf/images/ocaf_image003.svg, "OCAF Architecture"}
48
49 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. 
50
51 The subsequent chapters of this document explain the concepts and show how to use the services of OCAF.
52
53 @section occt_ocaf_2 Basic Concepts
54
55 @subsection occt_ocaf_2_1 Overview
56
57 In most existing geometric modeling systems, the data structure is shape driven. They usually use a brep model, where solids and surfaces are defined by a collection of entities such as faces, edges etc., and by attributes such as application data. These attributes are attached to the entities. Examples of application data include: 
58
59   * color,
60   * material,
61   * information that a particular edge is blended.
62
63 A shape, however, is inevitably tied to its underlying geometry. And geometry is highly subject to change in applications such as parametric modeling or product development. In this sort of application, using a brep (boundary representation) data structure proves to be a not very effective solution. A solution other than the shape must be found, i.e. a solution where attributes are attached to a deeper invariant structure of the model. Here, the topology itself will be one attribute among many. 
64
65 In OCAF, data structure is reference key-driven. The reference key is implemented in the form of labels. Application data is attached to these labels as attributes. By means of these labels and a tree structure they are organized in, the reference key aggregates all user data, not just shapes and their geometry. These attributes have similar importance; no attribute is master in respect of the others. 
66
67 The reference keys of a model - in the form of labels - have to be kept together in a single container. This container is called a document. 
68
69 @image html /user_guides/ocaf/images/ocaf_image004.png  "Topology-driven vs. reference key-driven approaches"
70 @image latex /user_guides/ocaf/images/ocaf_image004.png  "Topology-driven vs. reference key-driven approaches"
71
72 @subsection occt_ocaf_2_2 Applications and documents
73
74 OCAF documents are in turn managed by an OCAF application, which is in charge of: 
75
76   * Creating new documents
77   * Saving documents and opening them
78   * Initializing document views.
79
80 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. 
81
82 @subsection occt_ocaf_2_3 The document and the data framework
83
84 Inside a document, there is a data framework, a model, for example. This is a set of labels organized in a tree structure characterized by the following features: 
85   * The first label in a framework is the root of the tree;
86   * Each label has a tag expressed as an integer value;
87   * Sub-labels of a label are called its children;
88   * Each label which is not the root has one father – label from an upper level of the framework;
89   * Labels which have the same father are called brothers;
90   * Brothers cannot share the same tag;
91   * A label is uniquely defined by an entry expressed as a list of tags (entry) of fathers from the root: this list of tags is written from right to left: tag of label, tag of its father, tag of father of its father,..., 0 (tag of the root label).
92   
93 @image html /user_guides/ocaf/images/ocaf_image005.png "A simple framework model"
94 @image latex /user_guides/ocaf/images/ocaf_image005.png "A simple framework model"
95
96 In the above figure inside the circles are the tags of corresponding labels. Under the circles are the lists of tags. The root label always has a zero tag. 
97
98 The children of a root label are middle-level labels with tags 1 and 3. These labels are brothers. 
99
100 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). 
101
102 For example, an application for designing table lamps will first allocate a label for the lamp unit (the lamp is illustrated below). The root label never has brother labels, so, for a lot of lamps in the framework allocation, one of the root label sub-labels for the lamp unit is used. By doing so, you would avoid any confusion between table lamps in the data framework. Parts of the lamp have different material, color and other attributes, so, for each sub-unit of the lamp a child label of the lamp label with specified tags is allocated: 
103
104   * a lamp-shade label with tag 1
105   * a bulb label with tag 2
106   * a stem label with tag 3
107
108 Label tags are chosen at will. They are just identifiers of the lamp parts. Now you can refine all units: set to the specified label geometry, color, material and other information about the lamp or it’s parts. This information is placed into special attributes of the label: the pure label contains no data – it is only a key to access data. 
109
110 The thing to remember is 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 what you wanted to use in your design, the part name could be integrated into the framework as an attribute. 
111
112 @image html /user_guides/ocaf/images/ocaf_image006.png
113 @image latex /user_guides/ocaf/images/ocaf_image006.png
114
115 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. 
116
117 @image html /user_guides/ocaf/images/ocaf_image007.png
118 @image latex /user_guides/ocaf/images/ocaf_image007.png
119
120
121 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. 
122
123 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. 
124
125 Note that the root label can have attributes too, usually global attributes: the name of the document, for example. 
126
127 As in the case of the table lamp example above, OCAF documents aggregate a battery of ready-to-use attributes, which represent typical data used in CAD. This data includes not only the Shape attribute, but a wide range of Standard attributes corresponding to the following types: 
128
129   * Geometric attributes
130   * General attributes
131   * Relationship attributes
132   * Auxiliary attributes
133
134 @subsubsection occt_ocaf_2_3_1 Documents
135
136 Documents offer access to the data framework and manage the following items: 
137
138   * Manage the notification of changes
139   * Update external links
140   * Manage the saving and restoring of data
141   * Store the names of software extensions.
142   * Manage command transactions
143   * Manage Undo and Redo options.
144
145 @subsubsection occt_ocaf_2_3_2 Shape attribute
146
147 The shape attribute implements the functionality of the OCCT topology manipulation: 
148
149   * reference to the shapes
150   * tracking of shape evolution
151
152 @subsubsection occt_ocaf_2_3_3 Standard attributes
153
154 Several ready-to-use base attributes already exist. These 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).... 
155
156 @subsubsection occt_ocaf_2_3_4 Visualization attributes
157
158 These 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. 
159
160 @subsubsection occt_ocaf_2_3_5 Function services
161
162 Where 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. 
163
164 @image html /user_guides/ocaf/images/ocaf_image008.png "Document structure"
165 @image latex /user_guides/ocaf/images/ocaf_image008.png "Document structure"
166
167 @section occt_ocaf_3 Data Framework Services
168
169 @subsection occt_ocaf_3_1 Overview
170
171 The data framework offers a single environment in which data from different application components can be handled. 
172
173 This allows you to exchange and modify data simply, consistently, with a maximum level of information, and with stable semantics. 
174
175 The building blocks of this approach are: 
176
177   * The tag
178   * The label
179   * The attribute
180
181 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. 
182
183 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. 
184
185 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. 
186
187 The most important property is that a label’s entry is its persistent address in the data framework. 
188
189 @image html /user_guides/ocaf/images/ocaf_image009.png "Contents of a document"
190 @image latex /user_guides/ocaf/images/ocaf_image009.png "Contents of a document"
191
192 @subsection occt_ocaf_3_2 The Tag
193
194 A tag is an integer, which identifies a label in two ways: 
195
196   * Relative identification
197   * Absolute identification.
198
199 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. 
200
201 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. 
202
203 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. 
204
205 The tag can be created in two ways: 
206
207   * Random delivery
208   * User-defined delivery
209
210 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. 
211
212 @subsubsection occt_ocaf_3_2_1 Creating child labels using random delivery of tags
213
214 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*. 
215
216
217 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
218 TDF_Label child1 = TDF_TagSource::NewChild (level2); 
219 TDF_Label child2 = TDF_TagSource::NewChild (level2); 
220 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
221
222 @subsubsection occt_ocaf_3_2_2 Creation of a child label by user delivery from a tag
223
224 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. 
225
226 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. 
227
228
229 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
230 TDF_Label achild = root.FindChild(3,Standard_False); 
231 if (!achild.IsNull()) { 
232 Standard_Integer tag = achild.Tag(); 
233
234 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
235
236 @subsection occt_ocaf_3_3 The Label
237
238 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 (refer to the following figure): 
239
240 @image html /user_guides/ocaf/images/ocaf_image007.png
241 @image latex /user_guides/ocaf/images/ocaf_image007.png
242
243
244 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. 
245
246 @subsubsection occt_ocaf_3_3_1 Label creation
247
248 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. 
249
250 @subsubsection occt_ocaf_3_3_2 Creating child labels
251
252 To create a new child label in the data framework using explicit delivery of tags, use *TDF_Label::FindChild*. 
253
254
255 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
256 //creating a label with tag 10 at Root 
257 TDF_Label lab1 = aDF->Root().FindChild(10); 
258
259 //creating labels 7 and 2 on label 10 
260 TDF_Label lab2 = lab1.FindChild(7); 
261
262 TDF_Label lab3 = lab1.FindChild(2); 
263 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
264 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. 
265
266
267 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
268 TDF_Label level1 = root.FindChild(3,Standard_True); 
269 TDF_Label level2 = level1.FindChild(1,Standard_True); 
270 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
271 @subsubsection occt_ocaf_3_3_3 Retrieving child labels
272
273 You can retrieve child labels of your current label by iteration on the first level in the scope of this label. 
274
275
276 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
277 TDF_Label current; 
278 // 
279 for (TDF_ChildIterator it1 (current,Standard_False); it1.More(); it1.Next()) { 
280 achild = it1.Value(); 
281 // 
282 // do something on a child (level 1) 
283 // 
284
285 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
286 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. 
287 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
288 for (TDF_ChildIterator itall (current,Standard_True); itall.More(); itall.Next()) { 
289 achild = itall.Value(); 
290 // 
291 // do something on a child (all levels) 
292 // 
293
294 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
295 Using *TDF_Tool::Entry* with *TDF_ChildIterator* you can retrieve the entries of your current label’s child labels as well. 
296
297  
298 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
299 void DumpChildren(const TDF_Label& aLabel) 
300
301   TDF_ChildIterator it; 
302   TCollection_AsciiString es; 
303   for (it.Initialize(aLabel,Standard_True); it.More(); it.Next()){ 
304     TDF_Tool::Entry(it.Value(),es); 
305     cout  =  as.ToCString()  =  endl; 
306   } 
307
308 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
309 @subsubsection occt_ocaf_3_3_4 Retrieving the father label
310
311 Retrieving the father label of a current label. 
312
313
314 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
315 TDF_Label father = achild.Father(); 
316 isroot = father.IsRoot(); 
317 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
318 @subsection occt_ocaf_3_4 The Attribute
319
320 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. 
321
322 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. 
323
324 @subsubsection occt_ocaf_3_4_1 Retrieving an attribute from a label
325
326 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. 
327
328
329 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
330 if(current.FindAttribute(TDataStd_Integer::GetID(),INT)) 
331
332   // the attribute is found 
333
334 else 
335
336   // the attribute is not found 
337
338 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
339 @subsubsection occt_ocaf_3_4_2 Identifying an attribute using a GUID
340
341 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*. 
342
343
344 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
345 Handle(TDataStd_Integer) INT = new TDataStd_Integer(); 
346 Standard_GUID guid = INT->ID(); 
347 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
348
349 @subsubsection occt_ocaf_3_4_3 Attaching an attribute to a label
350
351 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. 
352
353 *TDF_Attribute::Label* for *INT* then returns the label *attach* to which *INT* is attached. 
354
355
356 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
357 current.Add (INT); // INT is now attached to current 
358 current.Add (INT); // causes failure 
359 TDF_Label attach = INT->Label(); 
360 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
361 @subsubsection occt_ocaf_3_4_4 Testing the attachment to a label
362
363 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. 
364
365 *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*. 
366
367
368 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
369 // Testing of attribute attachment 
370 // 
371 if (current.IsA(TDataStd_Integer::GetID())) { 
372 // the label has an Integer attribute attached 
373
374 if (current.HasAttribute()) { 
375 // the label has at least one attribute attached 
376 Standard_Integer nbatt = current.NbAttributes(); 
377 // the label has nbatt attributes attached 
378
379 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
380 @subsubsection occt_ocaf_3_4_5 Removing an attribute from a label
381
382 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*. 
383
384
385 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
386 current.Forget(TDataStd_Integer::GetID()); 
387 // integer attribute is now not attached to current label 
388 current.ForgetAll(); 
389 // current has now 0 attributes attached 
390 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
391 @subsubsection occt_ocaf_3_4_6 Specific attribute creation
392
393 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. 
394
395 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) 
396
397 In order to create a new attribute in the standard way do the following: 
398 * Create a class inherited from *TDF_Attribute* and implement all purely virtual and necessary virtual methods:
399         + **ID()** – returns a unique GUID of a given attribute 
400         + **Restore(attribute)** – sets fields of this attribute equal to the fields of a given attribute of the same type 
401         + **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 . 
402         + **NewEmpty()** - returns a new attribute of this class with empty fields 
403         + **Dump(stream)** -  outputs information about a given attribute to a given stream debug (usually outputs an attribute of type string only) 
404 * Create the persistence classes for this attribute according to the file format chosen for the document (see below).
405
406 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. 
407
408 If you use a standard file format and you want your new attributes to be stored during document saving and retrieved to the data framework whenever a document is opened, you must do the following: 
409
410   1. If you place an attribute to a new package, it is desirable (although not mandatory) if your package name starts with letter "T" (transient), for example: attribute *TMyAttributePackage_MyAttribute* in the package *TMyAttributePackage*.
411   2. Create a new package with name "P[package name]" (for example *PMyAttributePackage*) with class *PMyAttributePackage_MyAttribute* inside. The new class inherits the *PDF_Attribute* class and contains fields of attributes, which must be saved or retrieved ("P" - persistent).
412   3. Create a new package with name "M[package name]" (for example *MMyAttributePackage*) with classes *MMyAttributePackage_MyAttributeRetrievalDriver* and *MMyAttributePackage_MyAttributeStorageDriver* inside. The new classes inherit *MDF_ARDriver* and *MDF_ASDriver* classes respectively and contain the translation functionality: from T... attribute to P... and vice versa (M - middle) (see the realization of the standard attributes).
413   4. M... package must contain *AddStorageDrivers(aDriverSeq : ASDriverHSequence* from MDF) and *AddRetrievalDrivers(aDriverSeq : ASDriverHSequence* from MDF) methods, which append to the given sequence *\<aDriverSeq\>* of drivers  a sequence of all new attribute drivers (see the previous point), which will be used for the attributes storage/retrieval. 
414   5 Use the standard schema (*StdSchema* unit) or create a new one to add your P-package and compile it. 
415
416 If you use the XML format, do the following: 
417   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).
418   2. Create a new package (or do it in the current one) with two package methods: 
419           * Factory, which loads the document storage and retrieval drivers; and 
420           * AttributeDrivers, which calls the methods AddDrivers for all packages responsible for persistence of the document.
421   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.
422 If you use the binary format, do the following: 
423   1. Create a new package with name Bin[package name] (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 (see below).
424   2. Create a new package (or do it in the current one) with two package methods: 
425           * Factory, which loads the document storage and retrieval drivers; and 
426           * AttributeDrivers, which calls the methods AddDrivers for all packages responsible for persistence of the document.
427   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.
428 See <a href="#occt_ocaf_4_3_3">Saving the document</a> and <a href="#occt_ocaf_4_3_4">Opening the document from a file</a> for the description of document save/open mechanisms. 
429
430 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: 
431   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).
432   2. Create child labels and allocate all necessary data through standard attributes at the child labels.
433   3. Define an interface class for access to the data of the child labels.
434
435 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. 
436
437 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). 
438
439 1. The first way: creation of a new attribute. The implementation of the transformation by creation of a new attribute is represented in the <a href="#occt_ocaf_11">Samples</a>. 
440
441 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: 
442   * Type of transformation (gp_Translation) as TDataStd_Integer;
443   * First point as TDataStd_RealArray (three values: X1, Y1 and Z1);
444   * Second point as TDataStd_RealArray (three values: X2, Y2 and Z2).
445
446 @image html /user_guides/ocaf/images/ocaf_image010.png "Data tree for translation"
447 @image latex /user_guides/ocaf/images/ocaf_image010.png "Data tree for translation"
448
449 If the type of transformation is changed to rotation, the data tree looks like this: 
450   * Type of transformation (gp_Rotation) as TDataStd_Integer;
451   * Point of axis of rotation as TDataStd_RealArray (three values: X, Y and Z);
452   * Axis of rotation as TDataStd_RealArray (three values: DX, DY and DZ);
453   * Angle of rotation as TDataStd_Real.
454
455 @image html /user_guides/ocaf/images/ocaf_image011.png "Data tree for rotation"
456 @image latex /user_guides/ocaf/images/ocaf_image011.png "Data tree for rotation"
457
458 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). 
459
460   
461 @section occt_ocaf_4_ Standard Document Services
462
463 @subsection occt_ocaf_4_1 Overview
464
465 Standard documents offer ready-to-use documents containing a TDF-based data framework. Each document can contain only one framework. 
466
467 The documents themselves are contained in the instantiation of a class inheriting from TDocStd_Application. This application manages the creation, storage and retrieval of documents. 
468
469 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. 
470
471 To sum up, standard documents alone provide access to the data framework. They also allow you to: 
472
473   * Update external links
474   * Manage the saving and opening of data
475   * Manage the undo/redo functionality.
476
477
478 @subsection occt_ocaf_4_2 The Application
479
480 As a container for your data framework, you need a document, and your document must be contained in your application. This application will be a class inheriting from *TDocStd_Application*. 
481
482 @subsubsection occt_ocaf_4_2_1 Creating an application
483
484 To create an application, use the following syntax. 
485
486 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
487 Handle(TDocStd_Application) app 
488 = new MyApplication_Application (); 
489 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
490 Note that *MyApplication_Application* is a class, which you have to create and which will inherit from *TDocStd_Application*. 
491
492 @subsubsection occt_ocaf_4_2_2 Creating a new document
493
494 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*. 
495
496 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
497 Handle(TDocStd_Document) doc; 
498 app->NewDocument("NewDocumentFormat", doc); 
499 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
500
501 @subsubsection occt_ocaf_4_2_3 Retrieving the application to which the document belongs
502
503 To retrieve the application containing your document, you use the syntax below. 
504
505 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
506 app = Handle(TDocStd_Application)::DownCast 
507 (doc->Application()); 
508 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
509 @subsection occt_ocaf_4_3 The Document
510
511 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. 
512
513 @subsubsection occt_ocaf_4_3_1 Accessing the main label of the framework
514
515 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. 
516
517 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
518 TDF_Label label = doc->Main(); 
519 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
520 @subsubsection occt_ocaf_4_3_2 Retrieving the document from a label in its framework
521
522 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. 
523 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
524 doc = TDocStd_Document::Get(label); 
525 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
526
527 @subsubsection occt_ocaf_4_3_3 Saving the document
528
529 If in your document you use only standard attributes (from the packages TDF, TDataStd, TNaming, TFunction, TPrsStd and TDocStd), you just do the following steps: 
530
531 * In your application class (which inherits class *TDocStd_Application*) implement two methods:
532         + Formats (TColStd_SequenceOfExtendedString& theFormats), which append to a given sequence \<theFormats\> your document format string, for example, "NewDocumentFormat" – this string is also set in the document creation command 
533         + ResourcesName(), which returns a string with a name of resources file (this file contains a description about the extension of the document, storage/retrieval drivers GUIDs...), for example, "NewFormat" 
534 * Create the resource file (with name, for example, "NewFormat") with the following strings:
535
536 ~~~~~
537 formatlist:NewDocumentFormat 
538 NewDocumentFormat: New Document Format Version 1.0 
539 NewDocumentFormat.FileExtension: ndf 
540 NewDocumentFormat.StoragePlugin: bd696000-5b34-11d1-b5ba-00a0c9064368 
541 NewDocumentFormat.RetrievalPlugin: bd696001-5b34-11d1-b5ba-00a0c9064368 
542 NewDocumentFormatSchema: bd696002-5b34-11d1-b5ba-00a0c9064368 
543 NewDocumentFormat.AttributeStoragePlugin:57b0b826-d931-11d1-b5da-00a0c9064368 
544 NewDocumentFormat.AttributeRetrievalPlugin:57b0b827-d931-11d1-b5da-00a0c9064368 
545 ~~~~~
546
547 * Create the resource file "Plugin" with GUIDs and corresponding plugin libraries, which looks like this:
548
549 **Example** 
550 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
551 ! Description of available plugins 
552 ! ************ 
553  
554 b148e300-5740-11d1-a904-080036aaa103.Location: libFWOSPlugin.so 
555
556 ! standard document drivers plugin 
557
558 bd696000-5b34-11d1-b5ba-00a0c9064368.Location: libPAppStdPlugin.so 
559 bd696001-5b34-11d1-b5ba-00a0c9064368.Location: libPAppStdPlugin.so 
560
561 ! standard schema plugin 
562
563 bd696002-5b34-11d1-b5ba-00a0c9064368.Location: libPAppStdPlugin.so 
564
565 ! standard attribute drivers plugin 
566
567 57b0b826-d931-11d1-b5da-00a0c9064368.Location: libPAppStdPlugin.so 
568 57b0b827-d931-11d1-b5da-00a0c9064368.Location: libPAppStdPlugin.so 
569 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
570
571 In order to set the paths for these files it is necessary to set the environments: *CSF_PluginDefaults* and *CSF_NewFormatDefaults*. For example, set the files in the directory *MyApplicationPath/MyResources*: 
572
573 ~~~~~
574 setenv CSF_PluginDefaults MyApplicationPath/MyResources 
575 setenv CSF_NewFormatDefaults MyApplicationPath/MyResources 
576 ~~~~~
577
578 Once these steps are taken you may run your application, create documents and Save/Open them. These resource files already exist in the OCAF (format "Standard"). 
579
580 If you use your specific attributes from packages, for example, P-, M- and TMyAttributePackage, see "Specific attribute creation" on page 20; you must take some additional steps for the new plugin implementation: 
581
582 1. Add our "P" package to the standard schema. You can get an already existing (in Open CASCADE Technology sources) schema from StdSchema unit and add your package string to the cdl-file: "package  PMyAttributePackage".
583 2. Next step consists of implementation of an executable, which will connect our documents to our application and open/save them. Copy the package PAppStdPlugin and change its name to MyTheBestApplicationPlugin. In the PLUGIN macros type the name of your factory which will be defined in the next step.
584 3. Factory is a method, which returns drivers (standard drivers and our defined drivers from the "M" package) by a GUID. Copy the package where the standard factory is defined (it is PAppStd in the OCAF sources). Change its name to MyTheBestSchemaLocation. The Factory() method of the PappStd package checks the GUID set as its argument and returns the corresponding table of drivers. Set two new GUIDs for your determined storage and retrieval drivers. Append two "if" declarations inside the Factory() method which should check whether the set GUID coincides with GUIDs defined by the Factory() method as far as our storage and retrieval drivers are concerned. If the GUID coincides with one of them, the method should return a table of storage or retrieval drivers respectively.
585 4. Recompile all. Add the strings with GUIDs – in accordance with your plugin library GUID - to the "Plugin" file.
586
587 @subsubsection occt_ocaf_4_3_4 Opening the document from a file
588
589 To open the document from a file where it has been previously saved, you use TDocStd_Application::Open as in the example below. The arguments are the path of the file and the document saved in this file. 
590
591 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
592 app->Open("/tmp/example.caf", doc); 
593 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
594
595 @subsection occt_ocaf_4_4 External Links
596
597 External links refer from one document to another. They allow you to update the copy of data  framework later on. 
598
599 @image html /user_guides/ocaf/images/ocaf_image012.png  "External links between documents"
600 @image latex /user_guides/ocaf/images/ocaf_image012.png  "External links between documents"
601
602 Note that documents can be copied with or without a possibility of updating an external link. 
603
604 @subsubsection occt_ocaf_4_4_1 Copying the document
605
606 #### With the possibility of updating it later
607
608 To copy a document with a possibility of updating it later, you use TDocStd_XLinkTool::CopyWithLink. 
609
610 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
611 Handle(TDocStd_Document) doc1; 
612 Handle(TDocStd_Document) doc2; 
613
614 TDF_Label source = doc1->GetData()->Root(); 
615 TDF_Label target = doc2->GetData()->Root(); 
616 TDocStd_XLinkTool XLinkTool; 
617
618 XLinkTool.CopyWithLink(target,source); 
619 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
620
621 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. 
622
623 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*. 
624
625 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
626 XLinkTool.UpdateLink(target); 
627 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
628
629 #### Without any link between the copy and the original
630
631 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.* 
632
633 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
634 XLinkTool.Copy(target, source); 
635
636 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
637
638
639 @section occt_ocaf_5_ OCAF Shape Attributes
640 @subsection occt_ocaf_5_1 Overview
641
642 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. 
643
644 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. 
645
646 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. 
647
648 @image html /user_guides/ocaf/images/ocaf_image013.png
649 @image latex /user_guides/ocaf/images/ocaf_image013.png
650
651 Different algorithms may dispose sub-shapes of the result shape at the individual labels depending on whether it is necessary to do so: 
652
653 * 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.
654 * 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.
655
656
657 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. 
658
659 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. 
660
661 @image html /user_guides/ocaf/images/ocaf_image014.png "Resulting box"
662 @image latex /user_guides/ocaf/images/ocaf_image014.png "Resulting box"
663
664 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, as well as to the new shape – the shape resulting from the fuse operation – and has evolution MODIFY (see the following figure). 
665
666 Named shapes, which contain information about modified faces, belong to the fuse result sub-labels: sub-label with tag 1 – modified faces of the first box, sub-label with tag 2 – generated faces of the box 2. 
667
668 @image html /user_guides/ocaf/images/ocaf_image015.png
669 @image latex /user_guides/ocaf/images/ocaf_image015.png
670
671 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: 
672
673   * face F1’ as a modification of F11  face
674   * face F1’’ as generation of F12 face
675   * edges as an intersection of two contiguous faces
676   * vertices as an intersection of three contiguous faces
677
678 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. 
679
680 @subsection occt_ocaf_5_2 Services provided
681
682 @subsubsection occt_ocaf_5_2_1 Registering shapes and their evolution
683
684 When using TNaming_NamedShape to create attributes, the following fields of an attribute are filled: 
685
686 * 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.
687 * The type of evolution: a term of the TNaming_Evolution enumeration:
688 * PRIMITIVE – newly created topology, with no previous history
689 * 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 )
690 * MODIFY – the new shape is a modified old shape
691 * DELETE – the new shape is empty; the named shape with this evolution just indicates that the old shape topology is deleted from the model
692 * SELECTED – a named shape with this evolution has no effect on the history of the topology; it is 
693 used for the selected shapes that are placed to the separate label 
694
695 Only pairs of shapes with equal evolution can be stored in one named shape. 
696
697 @subsubsection occt_ocaf_5_2_2 Using naming resources
698
699 The class TNaming_Builder allows you to create 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. 
700
701 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
702 // a new empty named shape is created at "label" 
703 TNaming_Builder builder(label); 
704 // set a pair of shapes with evolution GENERATED 
705 builder.Generated(oldshape1,newshape1); 
706 // set another pair of shapes with the same evolution 
707 builder.Generated(oldshape2,newshape2); 
708 // get the result – TNaming_NamedShape attribute 
709 Handle(TNaming_NamedShape) ns = builder.NamedShape(); 
710 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
711 @subsubsection occt_ocaf_5_2_3 Reading the contents of a named shape attribute
712
713 You can use TNaming_NamedShape class to get evolution of this named shape (method TNaming_NamedShape::Evolution()) and "value" of the named shape – compound of new shapes of all pairs of this named shape (method TNaming_NamedShape::Get()). 
714   
715 More detailed information about the contents of the named shape or about the modification history of a topology can be obtained with the following: 
716
717 * TNaming_Tool provides a common high-level functionality for access to the named shapes contents:
718 * GetShape(Handle(TNaming_NamedShape)) method returns a compound of new shapes of the given named shape
719 * CurrentShape(Handle(TNaming_NamedShape)) method returns a compound of the shapes – last modifications ( latest versions ) of the shapes from the given named shape
720 * NamedShape(TopoDS_Shape,TDF_Label) method returns a named shape, which contains a given shape as a new shape. Given label is any label from the data framework – it just gives access to it
721 * TNaming_Iterator given access to the named shape hooks pairs.
722
723 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
724 // create an iterator for a named shape 
725 TNaming_Iterator iter(namedshape); 
726 // iterate while some pairs are not iterated 
727 while(iter.More()) { 
728 // get the new shape from the current pair 
729 TopoDS_Shape newshape = iter.NewShape(); 
730 // get the old shape from the current pair 
731 TopoDS_Shape oldshape = iter.OldShape(); 
732 // do something... 
733
734 // go to the next pair 
735 iter.Next(); 
736
737 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
738
739
740 @subsubsection occt_ocaf_5_2_4 Selection Mechanism
741
742 One of user interfaces for topological naming resources is the TNaming_Selector class. You can use this class to: 
743
744   * Store a selected shape on a label
745   * Access the named shape
746   * Update this naming
747
748 Selector places a new named shape with evolution SELECTED to the given label. By the given context shape (main shape, which contains a selected sub-shape), its evolution and naming structure the selector creates a "name" of the selected shape – unique description how to find a selected topology. 
749
750 After any modification of a context shape and updating of the corresponding naming structure, you must call the TNaming_Selector::Solve method. If the naming structure is right, then the selector automatically updates the selected shape in the corresponding named shape, else it fails. 
751
752 @subsubsection occt_ocaf_5_2_5 Exploring shape evolution
753
754 The class TNaming_Tool provides a toolkit to read current data contained in the attribute. 
755
756 If you need to create a topological attribute for existing data, use the method NamedShape. 
757
758 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
759 class MyPkg_MyClass 
760
761 public: Standard_Boolean SameEdge (const Handle(CafTest_Line)& L1, const Handle(CafTest_Line)& L2); 
762 }; 
763
764 Standard_Boolean CafTest_MyClass::SameEdge (const Handle(CafTest_Line)& L1, const Handle(CafTest_Line)& L2) 
765
766   Handle(TNaming_NamedShape) NS1 = L1->NamedShape(); 
767   Handle(TNaming_NamedShape) NS2 = L2->NamedShape(); 
768   return BRepTools::Compare(NS1,NS2); 
769
770 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
771
772 @section occt_ocaf_6_ Standard Attributes
773
774 @subsection occt_ocaf_6_1 Overview
775
776 There are several 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: 
777
778   * Geometric attributes
779   * General attributes
780   * Relationship attributes
781   * Auxiliary attributes
782
783 ### Geometric attributes
784
785
786   * Axis – simply identifies, that the concerned TNaming_NamedShape attribute with an axis shape inside belongs to the same label 
787   * 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
788   * Geometry – simply identifies, that the concerned TNaming_NamedShape attribute with a specified-type geometry belongs to the same label 
789   * Plane – simply identifies, that the concerned TNaming_NamedShape attribute with a plane shape inside belongs to the same label 
790   * Point – simply identifies, that the concerned TNaming_NamedShape attribute with a  point shape inside belongs to the same label 
791   * Shape – simply identifies, that the concerned TNaming_NamedShape attribute belongs to the same label
792   * PatternStd  – identifies one of five available pattern models (linear, circular, rectangular, circular rectangular and mirror)
793   * Position – identifies the position in 3d global space
794
795 ### General attributes
796
797
798   * AsciiString – contains AsciiString value
799   * BooleanArray – contains an array of Boolean
800   * BooleanList – contains a list of Boolean
801   * ByteArray – contains an array of Byte (unsigned char) values
802   * Comment – contains a string – some comment for a given label (or attribute)
803   * Expression – contains an expression string and a list of used variables attributes
804   * ExtStringArray – contains an array of ExtendedString values
805   * ExtStringList – contains a list of ExtendedString values
806   * Integer – contains an integer value
807   * IntegerArray – contains an array of  integer values
808   * IntegerList – contains a list of integer values
809   * IntPackedMap – contains a packed map of integers
810   * Name – contains a string – some name of a given label (or attribute)
811   * NamedData – may contain up to 6 of the following named data sets (vocabularies): DataMapOfStringInteger, DataMapOfStringReal, DataMapOfStringString, DataMapOfStringByte, DataMapOfStringHArray1OfInteger, DataMapOfStringHArray1OfReal
812   * NoteBook – contains a NoteBook object attribute
813   * Real – contains a real value
814   * RealArray – contains an array of  real values
815   * RealList    – contains a list of real values
816   * Relation – contains a relation string and a list of used variables attributes
817   * Tick – defines a boolean attribute
818   * Variable – simply identifies, that a variable belongs to this label; contains the "is constraint" flag and a string of used units ("mm", "m"...)
819   * 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)
820   
821 ### Relationship attributes 
822
823
824   * Reference – contains reference to the label of its own data framework
825   * ReferenceArray – contains an array of references
826   * ReferenceList – contains a list of references
827   * 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.
828
829 ### Auxiliary attributes
830
831   * Directory – hi-level tool attribute for sub-labels management
832   * 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.
833
834 All of these 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. 
835
836
837 @subsection occt_ocaf_6_2 Services common to all attributes
838
839 @subsubsection occt_ocaf_6_2_1 Accessing GUIDs
840
841 To access the GUID of an attribute, you can use two methods: 
842
843   * 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.
844   * 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.
845
846 @subsubsection occt_ocaf_6_2_2 Conventional Interface of Standard Attributes
847
848 It is usual to create standard named methods for the attributes: 
849
850   * 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.
851   * Method *Get()* returns the value of an attribute if it is characterized by one value.
852   * Method *Dump(Standard_OStream)* outputs debug information about a given attribute to a given stream.
853   
854 @section occt_ocaf_7 Visualization Attributes
855
856 @subsection occt_ocaf_7_1 Overview
857
858 Standard visualization attributes implement the Application Interactive Services (see Open CASCADE Technology 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. 
859
860 @subsection occt_ocaf_7_2 Services provided
861
862 @subsubsection occt_ocaf_7_2_1 Defining an interactive viewer attribute
863
864 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. 
865
866 To initialize the AIS viewer as in the example below, use method Find. 
867
868 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
869 // "access" is any label of the data framework 
870 Handle(TPrsStd_AISViewer) viewer = TPrsStd_AISViewer::Find(access) 
871 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
872
873 @subsection occt_ocaf_7_2_2 Defining a presentation attribute
874
875 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. 
876
877 @subsubsection occt_ocaf_7_2_3 Creating your own driver
878
879 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. 
880
881 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: 
882 @image html /user_guides/ocaf/images/ocaf_image016.png
883 @image latex /user_guides/ocaf/images/ocaf_image016.png
884
885 As usual, the GUID of a driver and the GUID of a displayed attribute are the same. 
886
887 @subsubsection occt_ocaf_7_2_4 Using a container for drivers
888
889 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. 
890
891 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. 
892
893 **Example** 
894 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
895 DriverTable::Get() -> InitStandardDrivers(); 
896 // next, attach your named shape to a label 
897 TPrsStd_AISPresentation::Set(NS}; 
898 // here, attach the AISPresentation to NS. 
899 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
900
901 @section occt_ocaf_8 Function Services
902
903 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. 
904
905 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. 
906
907 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. 
908
909 @subsection occt_ocaf_8_1 Finding functions, their owners and roots
910
911 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. 
912
913 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. 
914
915 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. 
916
917 @subsection occt_ocaf_8_2 Storing and accessing information about function status
918
919 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. 
920
921 @subsection occt_ocaf_8_3 Propagating modifications
922
923 An application must implement its functions, function drivers and the common solver for parametric model creation. For example, check the following model (see the following illustration): 
924
925 @image html /user_guides/ocaf/images/ocaf_image017.png
926 @image latex /user_guides/ocaf/images/ocaf_image017.png
927
928 The procedure of its creation is as follows:
929   * create a rectangular planar face F with height 100 and width 200
930   * create prism P using face F as a basis
931   * create fillet L at the edge of the prism
932   * change the width of F from 200 to 300:
933   * the solver for the function of face F starts
934   * the solver detects that an argument of the face *F* function has been modified
935   * the solver calls the driver of the face F function for a  regeneration of the face
936   * 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
937
938   * the solver detects the function of P – it depends on the function of F
939   * the solver calls the driver of the prism P function
940   * the driver rebuilds prism P and adds the label of this prism to the logbook as  impacted
941   * the solver detects the function of L  – it depends on the function of P
942   * the solver calls the L function driver
943   * the driver rebuilds fillet L and adds the label of the fillet to the logbook as impacted
944
945 @section occt_ocaf_9 XML Support
946
947 Writing and reading XML files in OCCT is provided by LDOM package, which constitutes an integral part
948 of XML OCAF persistence, which is the optional component provided on top of Open CASCADE Technology.
949
950 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: 
951 * 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, LDOM_CDATASection) represent the corresponding XML types and serve as branches of the tree of elements. 
952 * Provide class LDOM_Parser to read XML files and convert them to LDOM_Document objects.
953 * Provide class LDOM_XmlWriter to convert LDOM_Document to a character stream in XML format and store it in file. 
954
955 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: 
956 * 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). 
957 * To minimize the time required for parsing and formatting XML, as well as for access to DOM data structures. 
958
959 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:
960 * 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. 
961 * Some superfluous methods are deleted: getPreviousSibling, getParentNode, etc. 
962 * No resolution of XML Entities of any kind 
963 * No support for DTD: the parser just checks for observance of general XML rules and never validates documents. 
964 * Only 5 available types of DOM nodes: LDOM_Element, LDOM_Attr, LDOM_Text, LDOM_Comment, LDOM_CDATASection. 
965 * No support of Namespaces; prefixed names are used instead of qualified names. 
966 * No support of the interface DOMException (no exception when attempting to remove a non-existing node). 
967
968 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. 
969
970 @subsection occt_ocaf_9_1 Document Drivers
971
972 The drivers for document storage and retrieval  manage  conversion between a transient OCAF
973 Document in memory and its persistent reflection in a container (disk, memory, network ...). For XML Persistence, they are defined in the package XmlDrivers. 
974
975 The main methods (entry points) of these drivers are: 
976 * *Write()* - for a storage driver; 
977 * *Read()* - for a retrieval driver. 
978
979 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: 
980
981 First it is necessary to convert the transient document into another form (called persistent), suitable for writing into a file, and vice versa. 
982 In XML Persistence LDOM_Document is used as the persistent form of an OCAF Document and the DOM_Nodes are the persistent objects. 
983 An OCAF Document is a tree of labels with attributes. Its transformation into a persistent form can be functionally divided into two parts: 
984 * Conversion of the labels structure, which is performed by the method XmlMDF::FromTo()
985 * Conversion of the attributes and their underlying objects, which is performed by the corresponding attribute drivers (one driver per attribute type). 
986
987 The driver for each attribute is selected from a table of drivers, either by attribute
988 type (on storage) or by the name of the corresponding DOM_Element (on retrieval).
989 The table of drivers is created by by methods *XmlDrivers_DocumentStorageDriver::AttributeDrivers()*
990 and *XmlDrivers_DocumentRetrievalDriver::AttributeDrivers()*. 
991
992 Then the persistent document is written into a file (or read from a file). 
993 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.
994
995 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. 
996
997 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. 
998
999 @subsection occt_ocaf_9_2 Attribute Drivers
1000
1001 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 T*_* is called XmlM*_*. Conversion between transient and persistent form of attribute is performed by two methods Paste() of attribute driver. 
1002
1003 *XmlMDF_ADriver* is the root class for all attribute drivers.
1004
1005 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. 
1006
1007 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. 
1008
1009 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. 
1010
1011 @subsection occt_ocaf_9_3 XML Document Structure
1012
1013 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:
1014 * **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. 
1015 * **Element comments** - consists of an unlimited number of \<comment\> sub-elements containing necessary comment strings. 
1016 * **Element label** is 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).
1017 * **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.
1018
1019 ### OCAF Attributes Representation 
1020
1021 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. 
1022 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. 
1023 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. 
1024
1025 ### Example of resulting XML file 
1026
1027 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. 
1028
1029 ~~~~~
1030 <?xml version="1.0" encoding="UTF-8"?> 
1031 <document format="XmlOcaf" xmlns="http://www.opencascade.org/OCAF/XML" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
1032 xsi:schemaLocation="http://www.opencascade.org/OCAF/XML http://www.opencascade.org/OCAF/XML/XmlOcaf.xsd">
1033
1034 <info date="2001-10-04" schemav="0" objnb="3"> 
1035 <iitem>Copyright: Open Cascade, 2001</iitem> 
1036 <iitem>STORAGE_VERSION: PCDM_ReadWriter_1</iitem> 
1037 <iitem>REFERENCE_COUNTER: 0</iitem> 
1038 <iitem>MODIFICATION_COUNTER: 1</iitem> 
1039 </info> 
1040 <comments/> 
1041 <label tag="0"> 
1042 <TDataStd_Name id="1">Document_1</TDataStd_Name> 
1043 <label tag="2"> 
1044 <TNaming_NamedShape id="2" evolution="primitive"> 
1045 <olds/> 
1046 <news> 
1047 <shape tshape="+34" index="1"/> 
1048 </news> 
1049 </TNaming_NamedShape> 
1050 </label> 
1051 </label> 
1052 \<shapes\> 
1053 ... 
1054 </shapes> 
1055 </document> 
1056
1057 ~~~~~
1058
1059 @subsection occt_ocaf_9_4 XML Schema
1060
1061 The XML Schema defines the class of a document. 
1062
1063 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). 
1064
1065 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. 
1066
1067 The Schema files (XSD) are intended for two purposes: 
1068 * documenting the data format of files generated by OCAF; 
1069 * validation of documents when they are used by external (non-OCAF) applications, e.g., to generate reports. 
1070
1071 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. 
1072
1073 ### Management of Namespaces 
1074
1075 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 [File XmlXcaf.xsd]. For the correct management of Namespaces it is necessary to: 
1076 * Define *targetNamespace* in the new XSD file describing the format. 
1077 * 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:"). 
1078 * 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. 
1079 * Pass (in every OCAF attribute driver) the namespace prefix of the *targetNamespace* to the constructor of *XmlMDF_ADriver*. 
1080   
1081 @section occt_ocaf_10 GLOSSARY
1082
1083 * **Application** - a document container holding all documents containing all application data. 
1084 * **Application data** - the data produced by an application, as opposed to data referring to it. 
1085 * **Associativity of data** - the ability to propagate modifications made to one document to other documents, which refer to such document. Modification propagation is: 
1086   * unidirectional, that is, from the referenced to the referencing document(s), or
1087   * bi-directional, from the referencing to the referenced document and vice-versa.
1088 * **Attribute** - a container for application data. An attribute is attached to a label in the hierarchy of the data framework. 
1089 * **Child** - a label created from another label, which by definition, is the father label. 
1090 * **Compound document** - a set of interdependent documents, linked to each other by means of external references. These references provide the associativity of data. 
1091 * **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. 
1092 * *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: 
1093         * Manage modifications, providing Undo and Redo functions 
1094         * Manage command transactions 
1095         * Update external links 
1096         * Manage save and restore options 
1097         * Store the names of software extensions. 
1098 * **Driver** - an abstract class, which defines the communications protocol with a system. 
1099 * **Entry** - an ASCII character string containing the tag list of a label. 
1100
1101
1102 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1103 0:3:24:7:2:7 
1104 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1105
1106 * **External links** - references from one data structure to another data structure in another document. 
1107 To store these references properly, a label must also contain an external link attribute. 
1108 * **Father** - a label, from which other labels have been created. The other labels are, by definition, the children of this label. 
1109 * **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: 
1110
1111   * defining new classes which inherit from these abstract classes
1112   * composing framework class instances
1113   * implementing the services required by the framework.
1114
1115 In C++, the application behavior is implemented in virtual functions redefined in these derived classes. This is known as overriding. 
1116
1117 * **GUID** - Global Universal ID. A string of 37 characters intended to uniquely identify an object. 
1118
1119 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1120 2a96b602-ec8b-11d0-bee7-080009dc3333 
1121 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1122
1123 * **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. 
1124 * **Modified label** - containing attributes whose data has been modified. 
1125 * **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. 
1126 * **Resource file** - a file containing a list of each document’s schema name and the storage and retrieval plug-ins for that document. 
1127 * **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. 
1128 * **Scope** - the set of all the attributes and labels which depend on a given label. 
1129 * **Tag list** - a list of integers, which identify the place of a label in the data framework.  This list is displayed in an entry. 
1130 * **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. 
1131 * **Topological tracking** - following a topological entity in a model through the steps taken to edit and regenerate that model. 
1132 * **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.   
1133
1134 @section occt_ocaf_11 Samples
1135 @subsection occt_ocaf_11_1 Implementation of Attribute Transformation in a CDL file
1136
1137 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1138 class Transformation from MyPackage inherits Attribute from TDF 
1139
1140     ---Purpose: This attribute implements a transformation data container. 
1141
1142 uses 
1143
1144      Attribute       from TDF, 
1145      Label           from TDF, 
1146      GUID            from Standard, 
1147      RelocationTable from TDF, 
1148      Pnt             from gp, 
1149      Ax1             from gp, 
1150      Ax2             from gp, 
1151      Ax3             from gp, 
1152      Vec             from gp, 
1153      Trsf            from gp, 
1154      TrsfForm        from gp 
1155
1156 is 
1157
1158     ---Category: Static methods 
1159     --          =============== 
1160
1161     GetID (myclass)     
1162     ---C++: return const &    
1163     ---Purpose: The method returns a unique GUID of this attribute. 
1164     --          By means of this GUID this attribute may be identified   
1165     --          among other attributes attached to the same label. 
1166     returns GUID from Standard; 
1167
1168     Set (myclass; theLabel : Label from TDF) 
1169     ---Purpose: Finds or creates the attribute attached to <theLabel>. 
1170     --          The found or created attribute is returned. 
1171     returns Transformation from MyPackage; 
1172
1173
1174     ---Category: Methods for access to the attribute data 
1175     --           ======================================== 
1176       
1177     Get (me) 
1178     ---Purpose: The method returns the transformation. 
1179     returns Trsf from gp; 
1180
1181
1182     ---Category: Methods for setting the data of transformation 
1183     --           ============================================== 
1184
1185     SetRotation (me : mutable; 
1186                          theAxis : Ax1 from gp; 
1187                          theAngle : Real from Standard); 
1188     ---Purpose: The method defines a rotation type of transformation. 
1189
1190     SetTranslation (me : mutable; 
1191                             theVector : Vec from gp); 
1192     ---Purpose: The method defines a translation type of transformation. 
1193
1194     SetMirror (me : mutable; 
1195                    thePoint : Pnt from gp); 
1196     ---Purpose: The method defines a point mirror type of transformation 
1197     --          (point symmetry). 
1198
1199     SetMirror (me : mutable; 
1200                    theAxis : Ax1 from gp); 
1201     ---Purpose: The method defines an axis mirror type of transformation 
1202     --          (axial symmetry). 
1203
1204     SetMirror (me : mutable; 
1205                    thePlane : Ax2 from gp); 
1206     ---Purpose: The method defines a point mirror type of transformation 
1207     --          (planar symmetry). 
1208
1209     SetScale (me : mutable; 
1210                   thePoint : Pnt from gp; 
1211                   theScale : Real from Standard); 
1212     ---Purpose: The method defines a scale type of transformation. 
1213
1214     SetTransformation (me : mutable; 
1215                                theCoordinateSystem1 : Ax3 from gp; 
1216                                theCoordinateSystem2 : Ax3 from gp); 
1217     ---Purpose: The method defines a complex type of transformation 
1218     --          from one co-ordinate system to another. 
1219
1220
1221     ---Category: Overridden methods from TDF_Attribute 
1222     --           ===================================== 
1223       
1224     ID (me) 
1225     ---C++: return const &   
1226     ---Purpose: The method returns a unique GUID of the attribute. 
1227     --          By means of this GUID this attribute may be identified   
1228     --          among other attributes attached to the same label. 
1229     returns GUID from Standard; 
1230
1231     Restore (me: mutable;   
1232                  theAttribute : Attribute from TDF); 
1233     ---Purpose: The method is called on Undo / Redo. 
1234     --          It copies the content of <theAttribute> 
1235     --          into this attribute (copies the fields). 
1236
1237     NewEmpty (me) 
1238     ---Purpose: It creates a new instance of this attribute. 
1239     --          It is called on Copy / Paste, Undo / Redo. 
1240     returns mutable Attribute from TDF; 
1241
1242     Paste (me;   
1243                theAttribute : mutable Attribute from TDF; 
1244                theRelocationTable : mutable RelocationTable from TDF); 
1245     ---Purpose:: The method is called on Copy / Paste. 
1246     --           It copies the content of this attribute into 
1247     --           <theAttribute> (copies the fields). 
1248
1249     Dump(me; anOS : in out OStream from Standard) 
1250     ---C++: return; 
1251     ---Purpose: Prints the content of this attribute into the stream. 
1252     returns OStream from Standard is redefined; 
1253
1254
1255     ---Category: Constructor 
1256     --           =========== 
1257
1258     Create 
1259     ---Purpose: The C++ constructor of this atribute class. 
1260     --          Usually it is never called outside this class. 
1261     returns mutable Transformation from MyPackage;      
1262
1263
1264 fields 
1265
1266     -- Type of transformation 
1267     myType : TrsfForm from gp; 
1268
1269     -- Axes (Ax1, Ax2, Ax3) 
1270     myAx1 : Ax1 from gp; 
1271     myAx2 : Ax2 from gp; 
1272     myFirstAx3 : Ax3 from gp; 
1273     mySecondAx3 : Ax3 from gp; 
1274       
1275     -- Scalar values 
1276     myAngle : Real from Standard; 
1277     myScale : Real from Standard; 
1278       
1279     -- Points 
1280     myFirstPoint : Pnt from gp; 
1281     mySecondPoint : Pnt from gp; 
1282
1283
1284 end Transformation; 
1285 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1286
1287 @subsection occt_ocaf_11_2 Implementation of Attribute Transformation in a CPP file
1288
1289 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~{.cpp}
1290 #include MyPackage_Transformation.ixx; 
1291
1292 //======================================================================= 
1293 //function : GetID 
1294 //purpose  : The method returns a unique GUID of this attribute. 
1295 //           By means of this GUID this attribute may be identified   
1296 //           among other attributes attached to the same label. 
1297 //======================================================================= 
1298 const Standard_GUID& MyPackage_Transformation::GetID()   
1299
1300   static Standard_GUID ID("4443368E-C808-4468-984D-B26906BA8573"); 
1301   return ID; 
1302
1303
1304 //======================================================================= 
1305 //function : Set 
1306 //purpose  : Finds or creates the attribute attached to <theLabel>. 
1307 //           The found or created attribute is returned. 
1308 //======================================================================= 
1309 Handle(MyPackage_Transformation) MyPackage_Transformation::Set(const TDF_Label& theLabel)   
1310
1311   Handle(MyPackage_Transformation) T; 
1312   if (!theLabel.FindAttribute(MyPackage_Transformation::GetID(), T))   
1313   { 
1314     T = new MyPackage_Transformation();   
1315     theLabel.AddAttribute(T); 
1316   } 
1317   return T; 
1318
1319
1320 //======================================================================= 
1321 //function : Get 
1322 //purpose  : The method returns the transformation. 
1323 //======================================================================= 
1324 gp_Trsf MyPackage_Transformation::Get() const 
1325
1326   gp_Trsf transformation; 
1327   switch (myType) 
1328   { 
1329     case gp_Identity: 
1330     { 
1331       break; 
1332     } 
1333     case gp_Rotation: 
1334     { 
1335       transformation.SetRotation(myAx1, myAngle); 
1336       break; 
1337     } 
1338     case gp_Translation: 
1339     { 
1340       transformation.SetTranslation(myFirstPoint, mySecondPoint); 
1341       break; 
1342     } 
1343     case gp_PntMirror: 
1344     { 
1345       transformation.SetMirror(myFirstPoint); 
1346       break; 
1347     } 
1348     case gp_Ax1Mirror: 
1349     { 
1350       transformation.SetMirror(myAx1); 
1351       break; 
1352     } 
1353     case gp_Ax2Mirror: 
1354     { 
1355       transformation.SetMirror(myAx2); 
1356       break; 
1357     } 
1358     case gp_Scale: 
1359     { 
1360       transformation.SetScale(myFirstPoint, myScale); 
1361       break; 
1362     } 
1363     case gp_CompoundTrsf: 
1364     { 
1365       transformation.SetTransformation(myFirstAx3, mySecondAx3); 
1366       break; 
1367     } 
1368     case gp_Other: 
1369     { 
1370       break; 
1371     } 
1372   } 
1373   return transformation; 
1374
1375
1376 //======================================================================= 
1377 //function : SetRotation 
1378 //purpose  : The method defines a rotation type of transformation. 
1379 //======================================================================= 
1380 void MyPackage_Transformation::SetRotation(const gp_Ax1& theAxis, const Standard_Real theAngle) 
1381
1382   Backup(); 
1383   myType = gp_Rotation; 
1384   myAx1 = theAxis; 
1385   myAngle = theAngle; 
1386
1387
1388 //======================================================================= 
1389 //function : SetTranslation 
1390 //purpose  : The method defines a translation type of transformation. 
1391 //======================================================================= 
1392 void MyPackage_Transformation::SetTranslation(const gp_Vec& theVector) 
1393
1394   Backup(); 
1395   myType = gp_Translation; 
1396   myFirstPoint.SetCoord(0, 0, 0); 
1397   mySecondPoint.SetCoord(theVector.X(), theVector.Y(), theVector.Z()); 
1398
1399
1400 //======================================================================= 
1401 //function : SetMirror 
1402 //purpose  : The method defines a point mirror type of transformation 
1403 //           (point symmetry). 
1404 //======================================================================= 
1405 void MyPackage_Transformation::SetMirror(const gp_Pnt& thePoint) 
1406
1407   Backup(); 
1408   myType = gp_PntMirror; 
1409   myFirstPoint = thePoint; 
1410
1411
1412 //======================================================================= 
1413 //function : SetMirror 
1414 //purpose  : The method defines an axis mirror type of transformation 
1415 //           (axial symmetry). 
1416 //======================================================================= 
1417 void MyPackage_Transformation::SetMirror(const gp_Ax1& theAxis) 
1418
1419   Backup(); 
1420   myType = gp_Ax1Mirror; 
1421   myAx1 = theAxis; 
1422
1423
1424 //======================================================================= 
1425 //function : SetMirror 
1426 //purpose  : The method defines a point mirror type of transformation 
1427 //           (planar symmetry). 
1428 //======================================================================= 
1429 void MyPackage_Transformation::SetMirror(const gp_Ax2& thePlane) 
1430
1431   Backup(); 
1432   myType = gp_Ax2Mirror; 
1433   myAx2 = thePlane; 
1434
1435
1436 //======================================================================= 
1437 //function : SetScale 
1438 //purpose  : The method defines a scale type of transformation. 
1439 //======================================================================= 
1440 void MyPackage_Transformation::SetScale(const gp_Pnt& thePoint, const Standard_Real theScale) 
1441
1442   Backup(); 
1443   myType = gp_Scale; 
1444   myFirstPoint = thePoint; 
1445   myScale = theScale; 
1446
1447
1448 //======================================================================= 
1449 //function : SetTransformation 
1450 //purpose  : The method defines a complex type of transformation 
1451 //           from one co-ordinate system to another. 
1452 //======================================================================= 
1453 void MyPackage_Transformation::SetTransformation(const gp_Ax3& theCoordinateSystem1,   
1454                                                                          const gp_Ax3& theCoordinateSystem2) 
1455
1456   Backup(); 
1457   myFirstAx3 = theCoordinateSystem1; 
1458   mySecondAx3 = theCoordinateSystem2; 
1459
1460
1461 //======================================================================= 
1462 //function : ID 
1463 //purpose  : The method returns a unique GUID of the attribute. 
1464 //           By means of this GUID this attribute may be identified   
1465 //           among other attributes attached to the same label. 
1466 //======================================================================= 
1467 const Standard_GUID& MyPackage_Transformation::ID() const   
1468 {   
1469   return GetID();   
1470
1471
1472 //======================================================================= 
1473 //function : Restore 
1474 //purpose  : The method is called on Undo / Redo. 
1475 //           It copies the content of <theAttribute> 
1476 //           into this attribute (copies the fields). 
1477 //======================================================================= 
1478 void MyPackage_Transformation::Restore(const Handle(TDF_Attribute)& theAttribute)   
1479
1480   Handle(MyPackage_Transformation) theTransformation = Handle(MyPackage_Transformation)::DownCast(theAttribute); 
1481   myType = theTransformation->myType; 
1482   myAx1 = theTransformation->myAx1; 
1483   myAx2 = theTransformation->myAx2; 
1484   myFirstAx3 = theTransformation->myFirstAx3; 
1485   mySecondAx3 = theTransformation->mySecondAx3; 
1486   myAngle = theTransformation->myAngle; 
1487   myScale = theTransformation->myScale; 
1488   myFirstPoint = theTransformation->myFirstPoint; 
1489   mySecondPoint = theTransformation->mySecondPoint; 
1490
1491
1492 //======================================================================= 
1493 //function : NewEmpty 
1494 //purpose  : It creates a new instance of this attribute. 
1495 //           It is called on Copy / Paste, Undo / Redo. 
1496 //======================================================================= 
1497 Handle(TDF_Attribute) MyPackage_Transformation::NewEmpty() const 
1498 {    
1499   return new MyPackage_Transformation();   
1500
1501
1502 //======================================================================= 
1503 //function : Paste 
1504 //purpose  : The method is called on Copy / Paste. 
1505 //           It copies the content of this attribute into 
1506 //           <theAttribute> (copies the fields). 
1507 //======================================================================= 
1508 void MyPackage_Transformation::Paste(const Handle(TDF_Attribute)& theAttribute, 
1509                                                      const Handle(TDF_RelocationTable)& ) const 
1510
1511   Handle(MyPackage_Transformation) theTransformation = Handle(MyPackage_Transformation)::DownCast(theAttribute); 
1512   theTransformation->myType = myType; 
1513   theTransformation->myAx1 = myAx1; 
1514   theTransformation->myAx2 = myAx2; 
1515   theTransformation->myFirstAx3 = myFirstAx3; 
1516   theTransformation->mySecondAx3 = mySecondAx3; 
1517   theTransformation->myAngle = myAngle; 
1518   theTransformation->myScale = myScale; 
1519   theTransformation->myFirstPoint = myFirstPoint; 
1520   theTransformation->mySecondPoint = mySecondPoint; 
1521
1522
1523 //======================================================================= 
1524 //function : Dump 
1525 //purpose  : Prints the content of this attribute into the stream. 
1526 //======================================================================= 
1527 Standard_OStream& MyPackage_Transformation::Dump(Standard_OStream& anOS) const 
1528 {    
1529   anOS = "Transformation: "; 
1530   switch (myType) 
1531   { 
1532     case gp_Identity: 
1533     { 
1534       anOS = "gp_Identity"; 
1535       break; 
1536     } 
1537     case gp_Rotation: 
1538     { 
1539       anOS = "gp_Rotation"; 
1540       break; 
1541     } 
1542     case gp_Translation: 
1543     { 
1544       anOS = "gp_Translation"; 
1545       break; 
1546     } 
1547     case gp_PntMirror: 
1548     { 
1549       anOS = "gp_PntMirror"; 
1550       break; 
1551     } 
1552     case gp_Ax1Mirror: 
1553     { 
1554       anOS = "gp_Ax1Mirror"; 
1555       break; 
1556     } 
1557     case gp_Ax2Mirror: 
1558     { 
1559       anOS = "gp_Ax2Mirror"; 
1560       break; 
1561     } 
1562     case gp_Scale: 
1563     { 
1564       anOS = "gp_Scale"; 
1565       break; 
1566     } 
1567     case gp_CompoundTrsf: 
1568     { 
1569       anOS = "gp_CompoundTrsf"; 
1570       break; 
1571     } 
1572     case gp_Other: 
1573     { 
1574       anOS = "gp_Other"; 
1575       break; 
1576     } 
1577   } 
1578   return anOS; 
1579
1580
1581 //=======================================================================
1582 //function : MyPackage_Transformation 
1583 //purpose  : A constructor. 
1584 //=======================================================================
1585 MyPackage_Transformation::MyPackage_Transformation():myType(gp_Identity){ 
1586
1587 }
1588 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1589
1590 @subsection occt_ocaf_11_3  Implementation of typical actions with standard OCAF attributes.
1591
1592 There are four sample files provided in the directory 'OpenCasCade/ros/samples/ocafsamples'. They present typical actions with OCAF services (mainly for newcomers). 
1593 The method *Sample()* of each file is not dedicated for execution 'as is', it is rather a set of logical actions using some OCAF services.
1594
1595 ### TDataStd_Sample.cxx
1596 This sample contains templates for typical actions with the following standard OCAF attributes:
1597 - Starting with data framework;
1598 - TDataStd_Integer attribute management;
1599 - TDataStd_RealArray attribute management;
1600 - TDataStd_Comment attribute management;
1601 - TDataStd_Name attribute management;
1602 - TDataStd_UAttribute attribute management;
1603 - TDF_Reference attribute management;
1604 - TDataXtd_Point attribute management;
1605 - TDataXtd_Plane attribute management;
1606 - TDataXtd_Axis attribute management;
1607 - TDataXtd_Geometry attribute management;
1608 - TDataXtd_Constraint attribute management;
1609 - TDataStd_Directory attribute management;
1610 - TDataStd_TreeNode attribute management.
1611   
1612 ### TDocStd_Sample.cxx
1613 This sample contains template for the following typical actions:
1614 - creating application;
1615 - creating the new document (document contains a framework);
1616 - retrieving the document from a label of its framework;
1617 - filling a document with data;
1618 - saving a document in the file;
1619 - closing a document;
1620 - opening the document stored in the file;
1621 - copying content of a document to another document with possibility to update the copy in the future.
1622  
1623 ### TPrsStd_Sample.cxx
1624 This sample contains template for the following typical actions:
1625 - starting with data framework;
1626 - setting the TPrsStd_AISViewer in the framework;
1627 - initialization of aViewer;
1628 - finding TPrsStd_AISViewer attribute in the DataFramework;
1629 - getting AIS_InteractiveContext from TPrsStd_AISViewer;
1630 - adding driver to the map of drivers;
1631 - getting driver from the map of drivers;
1632 - setting TNaming_NamedShape to \<ShapeLabel\>;
1633 - setting the new  TPrsStd_AISPresentation to \<ShapeLabel\>;
1634 - displaying;
1635 - erasing;
1636 - updating and displaying presentation of the attribute to be displayed;
1637 - setting a color to the displayed attribute;
1638 - getting transparency of the displayed attribute;
1639 -  modify attribute;
1640 - updating presentation of the attribute in viewer.
1641
1642 ### TNaming_Sample.cxx
1643 This sample contains template for typical actions with OCAF Topological Naming services.
1644 The following scenario is used:
1645 - data framework initialization;
1646 - creating Box1 and pushing it as PRIMITIVE in DF;
1647 - creating Box2 and pushing it as PRIMITIVE in DF;
1648 - moving Box2 (applying a transformation);
1649 - pushing the selected edges of the top face of Box1 in DF;
1650 - creating a Fillet (using the selected edges) and pushing the result as a modification of Box1;
1651 - creating a Cut (Box1, Box2) as a modification of Box1 and push it in DF;
1652 - recovering the result from DF.
1653