290866be273fd03bb5b1979a9122142511cf2b17
[occt.git] / dox / user_guides / xde / xde.md
1  Extended Data Exchange (XDE)  {#occt_user_guides__xde}
2 ============================
3
4 @tableofcontents
5
6 @section occt_xde_1 Introduction
7
8 This manual explains how to use the Extended Data Exchange (XDE). It provides basic documentation on setting up and using XDE. For advanced information on XDE and its applications, see our offerings  at <a href="http://www.opencascade.com/services/support/">on our web site</a>. 
9
10 The Extended Data Exchange (XDE) module allows extending the scope of exchange by translating  additional data attached to geometric BREP data, thereby improving the interoperability with external software. 
11
12 Data types such as colors, layers, assembly descriptions and validation properties (i.e. center of gravity, etc.) are supported. These data are stored together with shapes in an XCAF document. It is also possible to add a new types of data taking the existing tools as prototypes.
13
14 Finally, the XDE provides reader and writer tools for reading and writing the data supported by XCAF to and from IGES and STEP files. 
15
16 @figure{/user_guides/xde/images/646_xde_11_400.png,"Shape imported using XDE"}
17
18 The XDE component requires @ref occt_user_guides__shape_healing "Shape Healing" toolkit for operation. 
19
20 @subsection occt_xde_1_1 Basic terms
21
22 For better understanding of XDE, certain key terms are defined: 
23 * **Shape** - a standalone shape, which does not belong to the assembly structure.
24 * **Instance** - a replication of another shape with a location that can be the same location or a different one.
25 * **Assembly** - a construction that is either a root or a sub-assembly. 
26
27 @subsection occt_xde_1_2 XDE Organization
28
29 The basis of XDE, called XCAF, is a framework based on OCAF (Open CASCADE Technology Application Framework) and is intended to be used with assemblies and with various kinds of attached data (attributes). Attributes can be Individual attributes for a shape, specifying some characteristics of a shape, or they can be Grouping attributes, specifying that a shape belongs to a given group whose definition is specified apart from the shapes. 
30
31 XDE works in an OCAF document with a specific organization defined in a dedicated XCAF module. This organization is used by various functions of XDE to exchange standardized data other than shapes and geometry. 
32
33 The Assembly Structure and attributes assigned to shapes are stored in the OCAF tree. It is possible to obtain TopoDS representation for each level of the assembly in the form of *TopoDS_Compound* or *TopoDS_Shape* using the API. 
34
35 Basic elements used by XDE are introduced in the XCAF sub-module by the package XCAFDoc. These elements consist in descriptions of commonly used data structures (apart from the shapes themselves) in normalized data exchanges. They are not attached to specific applications and do not bring specific semantics, but are structured according to the use and needs of data exchanges. 
36 The Document used by XDE usually starts as a *TDocStd_Document*. 
37
38 @subsection occt_xde_1_3 Assemblies
39 XDE supports assemblies by separating shape definitions and their locations. Shapes are simple OCAF objects without a location definition. An assembly consists of several components. Each of these components references one and the same specified shape with different locations. All this provides an increased flexibility in working on multi-level assemblies. 
40
41 For example, a mechanical assembly can be defined as follows: 
42 @image html /user_guides/xde/images/xde_image003.png "Assembly Description"
43 @image latex /user_guides/xde/images/xde_image003.png "Assembly Description"
44
45
46 @image html /user_guides/xde/images/xde_image004.png "Assembly View"
47 @image latex /user_guides/xde/images/xde_image004.png "Assembly View"
48
49
50 XDE defines the specific organization of the assembly content. Shapes are stored on sub-labels of label 0:1:1. There can be one or more roots (called free shapes) whether they are true trees or simple shapes. A shape can be considered to be an Assembly (such as AS1 under 0:1:1:1 in Figure1) if it is defined with Components (sub-shapes, located or not). 
51
52 *XCAFDoc_ShapeTool* is a tool that allows managing the Shape section of the XCAF document. This tool is implemented as an attribute and located at the root label of the shape section. 
53
54 @subsection occt_xde_1_4 Validation Properties
55 Validation properties are geometric characteristics of Shapes (volume, centroid, surface area) written to STEP files by the sending system. These characteristics are read by the receiving system to validate the quality of the translation. This is done by comparing the values computed by the original system with the same values computed by the receiving system on the resulting model. 
56
57 Advanced Data Exchange supports both reading and writing of validation properties, and provides a tool to check them. 
58
59 @image html /user_guides/xde/images/xde_image005.png "Validation Property Descriptions" 
60 @image latex /user_guides/xde/images/xde_image005.png "Validation Property Descriptions" 
61
62 Check logs contain deviations of computed values from the values stored in a STEP file. A typical example appears as follows: 
63
64 | Label | Area defect   | Volume defect | dX    | dY    | DZ    | Name |
65 | :---- | :----- | :----- | :----- | :---- | :---- | :---- |
66 | 0:1:1:1 | 312.6 (0%) | -181.7 (0%) | 0.00 | 0.00 | 0.00       | "S1" |
67 | 0:1:1:2 |  -4.6 (0%) | -191.2 (0%)    | -0.00  | 0.00 | -0.00 | "MAINBODY" |
68 | 0:1:1:3 | -2.3 (0%) | -52.5 (0%)      | -0.00 | 0.00  | 0.00 | "MAIN_BODY_BACK" |
69 | 0:1:1:4 | -2.3 (0%) | -51.6 (0%) | 0.00 |     0.00 | -0.00 | "MAIN_BODY_FRONT" |
70 | 0:1:1:5 | 2.0 (0%) | 10.0 (0%) | -0.00 |      0.00 |  -0.00 | "HEAD" |
71 | 0:1:1:6 | 0.4 (0%) | 0.0 (0%) |       0.00    | -0.00 | -0.00 | "HEAD_FRONT" |
72 | 0:1:1:7 |  0.4 (0%) | 0.0 (0%) | 0.00 | -0.00 | -0.00 | "HEAD_BACK" |
73 | 0:1:1:8 | -320.6 (0%) | 10.9 (0%)     | -0.00 | 0.00 | 0.00 | "TAIL" |
74 | 0:1:1:9 | 0.0 (0%) | 0.0 (0%) | -0.00 | -0.00 | 0.00 | "TAIL_MIDDLE" |
75 | 0:1:1:10 | -186.2 (0%) |      4.8 (0%) |      -0.00 | 0.00 | -0.00 | "TAIL_TURBINE" |
76 | 0:1:1:11 | 0.3 (0%) | -0.0 (0%) |     -0.00 | -0.00 | 0.00 |  "FOOT" |
77 | 0:1:1:12      | 0.0 (0%) | -0.0 (0%) | 0.00 | -0.00 | -0.00 |"FOOT_FRONT" |
78 | 0:1:1:13 | 0.0 (0%) | 0.0 (0%) | -0.00 | 0.00 | 0.00 | "FOOT_BACK" |
79
80
81 In our example, it can be seen that no errors were detected for either area, volume or positioning data. 
82
83 @subsection occt_xde_1_5 Names
84
85 XDE supports reading and writing the names of shapes to and from IGES and STEP file formats. This functionality can be switched off if you do not need this type of data, thereby reducing the size of the document. 
86
87 @figure{/user_guides/xde/images/614_xde_04_400.png, "Instance Names"}
88
89 @subsection occt_xde_1_6 Colors and Layers
90 XDE can read and write colors and layers assigned to shapes or their subparts (down to the level of faces and edges) to and from both IGES and STEP formats. Three types of colors are defined in the enumeration *XCAFDoc_ColorType*: 
91   * generic color <i>(XCAFDoc_ColorGen)</i>
92   * surface color <i>(XCAFDoc_ColorSurf)</i>
93   * curve color <i>(XCAFDoc_ColorCurv)</i>
94   
95  @figure{/user_guides/xde/images/xde_image006.png, "Colors and Layers"}
96
97
98 @section occt_xde_2 Working with XDE
99
100 @subsection occt_xde_2_1 Getting started
101
102 As explained in the last chapter, XDE uses *TDocStd_Documents* as a starting point. The general purpose of XDE is: 
103   * Checking if an existing document is fit for XDE;
104   * Getting an application and initialized document;
105   * Initializing a document to fit it for XDE;
106   * Adding, setting and finding data;
107   * Querying and managing shapes;
108   * Attaching properties to shapes.
109   
110 The Document used by XDE usually starts as a *TDocStd_Document*. 
111
112 @subsubsection occt_xde_2_1_1 Environment variables
113 To use XDE you have to set the environment variables properly. Make sure that two important environment variables are set as follows: 
114   * *CSF_PluginDefaults* points to sources of  <i>\%CASROOT%/src/XCAFResources ($CASROOT/src/XCAFResources)</i>.
115   * *CSF_XCAFDefaults* points to sources of <i>\%CASROOT%/src/XCAFResources ($CASROOT/src/XCAFResources)</i>.
116
117 @subsubsection occt_xde_2_1_2 General Check
118 Before working with shapes, properties, and other types of information, the global organization of an XDE Document can be queried or completed to determine if an existing Document is actually structured for use with XDE. 
119
120 To find out if an existing *TDocStd_Document* is suitable for XDE, use: 
121 ~~~~~
122 Handle(TDocStd_Document) doc... 
123 if ( XCAFDoc_DocumentTool::IsXCAFDocument (doc) ) { .. yes .. } 
124 ~~~~~
125 If the Document is suitable for XDE, you can perform operations and queries explained in this guide. However, if a Document is not fully structured for XDE, it must be initialized. 
126
127 @subsubsection occt_xde_2_1_3 Get an Application or an Initialized Document
128 If you want to retrieve an existing application or an existing document (known to be correctly structured for XDE), use: 
129 ~~~~~
130 Handle(TDocStd_Document) aDoc; 
131 Handle(XCAFApp_Application) anApp = XCAFApp_Application::GetApplication(); 
132 anApp->NewDocument(;MDTV-XCAF;,aDoc); 
133 ~~~~~
134
135 @subsection occt_xde_2_2 Shapes and Assemblies
136
137 @subsubsection occt_xde_2_2_1 Initialize an XDE Document (Shapes)
138 An XDE Document begins with a *TDocStd_Document*. Assuming you have a *TDocStd_Document* already created, you can ensure that it is correctly structured for XDE by initializing the XDE structure as follows: 
139 ~~~~~
140 Handle(TDocStd_Document) doc... 
141 Handle (XCAFDoc_ShapeTool) myAssembly = 
142 XCAFDoc_DocumentTool::ShapeTool (Doc->Main()); 
143 TDF_Label aLabel = myAssembly->NewShape() 
144 ~~~~~
145 **Note** that the method *XCAFDoc_DocumentTool::ShapeTool* returns the *XCAFDoc_ShapeTool*. The first time this method is used, it creates the *XCAFDoc_ShapeTool*. In our example, a handle is used for the *TDocStd_Document*.
146
147 @subsubsection occt_xde_2_2_2 Get a Node considered as an Assembly
148 To get a node considered as an Assembly from an XDE structure, you can use the Label of the node. Assuming that you have a properly initialized *TDocStd_Document*, use: 
149 ~~~~~
150 Handle(TDocStd_Document) doc... 
151 Handle(XCAFDoc_ShapeTool) myAssembly = XCAFDoc_DocumentTool::ShapeTool (aLabel); 
152 ~~~~~
153 In the previous example, you can also get the Main Item of an XDE document, which records the root shape representation (as a Compound if it is an Assembly) by using *ShapeTool(Doc->Main())* instead of *ShapeTool(aLabel)*. 
154
155 You can then query or edit this Assembly node, the Main Item or another one (*myAssembly* in our examples). 
156
157 **Note** that for the examples in the rest of this guide, *myAssembly* is always presumed to be accessed this way, so this information will not be repeated.
158
159 @subsubsection occt_xde_2_2_3 Updating the Assembly after Filling or Editing
160 Some actions in this chapter affect the content of the document, considered as an Assembly. As a result, you will sometimes need to update various representations (including the compounds). 
161
162 To update the representations, use: 
163 ~~~~~
164 myAssembly->UpdateAssembly(aLabel); 
165 ~~~~~
166 Since this call is always used by the editing functions, you need not apply it for such functions. However, you will need this call if special edits, not using XCAF functions, are used on the document. 
167
168 @subsubsection occt_xde_2_2_4 Adding or Setting Top Level Shapes
169
170 Shapes can be added as top-level shapes. Top level means that they can be added to an upper level assembly or added on their own at the highest level as a component or referred by a located instance. Therefore two types of top-level shapes can be added: 
171   * shapes with upper level references
172   * free shapes (that correspond to roots) without any upper reference
173
174 **Note** that several top-level shapes can be added to the same component.
175  
176 A shape to be added can be defined as a compound (if required), with the following interpretations: 
177   * If the Shape is a compound, according to the user choice, it may or may not be interpreted as representing an Assembly. If it is an Assembly, each of its sub-shapes defines a sub-label. 
178   * If the Shape is not a compound, it is taken as a whole, without breaking it down. 
179   
180 To break down a Compound in the assembly structure, use: 
181 ~~~~~
182 Standard_Boolean makeAssembly; 
183 // True to interpret a Compound as an Assembly, 
184 // False to take it as a whole 
185 aLabel = myAssembly->AddShape(aShape, makeAssembly); 
186 ~~~~~
187 Each node of the assembly therefore refers to its sub-shapes. 
188
189 Concerning located instances of sub-shapes, the corresponding shapes, (without location) appear at distinct sub-labels. They are referred to by a shape instance, which associates a location. 
190
191 @subsubsection occt_xde_2_2_5 Setting a given Shape at a given Label
192 A top-level shape can be changed. In this example, no interpretation of compound is performed: 
193 ~~~~~
194 Standard_CString LabelString ...; 
195 // identifies the Label (form ;0:i:j...;) 
196 TDF_Label aLabel...; 
197 // A label must be present 
198 myAssembly->SetShape(aLabel, aShape); 
199 ~~~~~
200
201 @subsubsection occt_xde_2_2_6 Getting a Shape from a Label
202 To get a shape from its Label from the top-level, use: 
203 ~~~~~
204 TDF_Label aLabel...
205 // A label must be present
206 if (aLabel.IsNull()) { 
207   // no such label : abandon
208 }
209 TopoDS_Shape aShape;
210 aShape = myAssembly->GetShape(aLabel);
211 if (aShape.IsNull()) {
212   // this label is not for a Shape
213 }
214 ~~~~~
215 **Note** that if the label corresponds to an assembly, the result is a compound. 
216
217 @subsubsection occt_xde_2_2_7 Getting a Label from a Shape
218 To get a Label, which is attached to a Shape from the top-level, use: 
219 ~~~~~
220 Standard_Boolean findInstance = Standard_False; 
221 // (this is default value)
222 aLabel = myAssembly->FindShape(aShape [,findInstance]);
223 if (aLabel.IsNull()) { 
224   // no label found for this shape
225 }
226 ~~~~~
227 If *findInstance* is True, a search is made for the shape with the same location. If it is False (default value), a search is made among original, non-located shapes. 
228
229 @subsubsection occt_xde_2_2_8 Other Queries on a Label
230
231 Various other queries can be made from a Label within the Main Item of XDE: 
232 #### Main Shapes
233
234 To determine if a Shape is recorded (or not), use: 
235 ~~~~~
236 if ( myAssembly->IsShape(aLabel) ) { .. yes .. } 
237 ~~~~~
238
239 To determine if the shape is top-level, i.e. was added by the *AddShape* method, use: 
240 ~~~~~
241 if ( myAssembly->IsTopLevel(aLabel) ) { .. yes .. } 
242 ~~~~~
243
244 To get a list of top-level shapes added by the *AddShape* method, use: 
245 ~~~~~
246 TDF_LabelSequence frshapes; 
247 myAssembly->GetShapes(frshapes); 
248 ~~~~~
249
250 To get all free shapes at once if the list above has only one item, use: 
251 ~~~~~
252 TopoDS_Shape result = myAssembly->GetShape(frshapes.Value(1)); 
253 ~~~~~
254
255 If there is more than one item, you must create and fill a compound, use: 
256
257 ~~~~~
258 TopoDS_Compound C; 
259 BRep_Builder B; 
260 B.MakeCompound(C); 
261 for(Standard_Integer i=1; i=frshapes.Length(); i++) { 
262   TopoDS_Shape S = myAssembly->GetShape(frshapes.Value(i)); 
263   B.Add(C,S); 
264
265 ~~~~~
266
267 In our example, the result is the compound C. 
268 To determine if a shape is a free shape (no reference or super-assembly), use: 
269
270 ~~~~~
271 if ( myAssembly->IsFree(aLabel) ) { .. yes .. } 
272 ~~~~~
273
274 To get a list of Free Shapes (roots), use: 
275
276 ~~~~~
277 TDF_LabelSequence frshapes; 
278 myAssembly->GetFreeShapes(frshapes); 
279 ~~~~~
280
281 To get the shapes, which use a given shape as a component, use: 
282 ~~~~~
283 TDF_LabelSequence users; 
284 Standard_Integer nbusers = myAssembly->GetUsers(aLabel,users); 
285 ~~~~~
286 The count of users is contained with *nbusers*. It contains 0 if there are no users. 
287
288 #### Assembly and Components
289 To determine if a label is attached to the main part or to a sub-part (component), use: 
290 ~~~~~
291 if (myAssembly->IsComponent(aLabel)) { .. yes .. } 
292 ~~~~~
293 To determine whether a label is a node of a (sub-) assembly or a simple shape, use: 
294 ~~~~~
295 if ( myAssembly->IsAssembly(aLabel) ) { .. yes .. } 
296 ~~~~~
297
298 If the label is a node of a (sub-) assembly, you can get the count of components, use: 
299 ~~~~~
300 Standard_Boolean subchilds = Standard_False; //default 
301 Standard_Integer nbc = myAssembly->NbComponents (aLabel [,subchilds]); 
302 ~~~~~
303
304 If *subchilds* is True, commands also consider sub-levels. By default, only level one is checked. 
305
306 To get component Labels themselves, use: 
307 ~~~~~
308 Standard_Boolean subchilds = Standard_False; //default 
309 TDF_LabelSequence comps; 
310 Standard_Boolean isassembly = myAssembly->GetComponents 
311 (aLabel,comps[,subchilds]); 
312 ~~~~~
313 @subsubsection occt_xde_2_2_9 Instances and References for Components
314 To determine if a label is a simple shape, use: 
315 ~~~~~
316 if ( myAssembly->IsSimpleShape(aLabel) ) { .. yes .. } 
317 ~~~~~
318 To determine if a label is a located reference to another one, use: 
319 ~~~~~
320 if ( myAssembly->IsReference(aLabel) ) { .. yes .. } 
321 ~~~~~
322 If the label is a located reference, you can get the location, use: 
323 ~~~~~
324 TopLoc_Location loc = myAssembly->GetLocation (aLabel); 
325 ~~~~~
326 To get the label of a referenced original shape (also tests if it is a reference), use: 
327 ~~~~~
328 Standard_Boolean isref = myAssembly->GetReferredShape 
329 (aLabel, refLabel); 
330 ~~~~~
331
332 **Note** *isref* returns False if *aLabel* is not for a reference. 
333
334 @subsection occt_xde_2_3 Editing Shapes
335 In addition to the previously described *AddShape* and *SetShape*, several shape edits are possible. 
336
337 To remove a Shape, and all its sub-labels, use: 
338 ~~~~~
339 Standard_Boolean remsh = myAssembly->RemoveShape(aLabel); 
340 // remsh is returned True if done 
341 ~~~~~
342 This operation will fail if the shape is neither free nor top level.
343
344 To add a Component to the Assembly, from a new shape, use: 
345 ~~~~~
346 Standard_Boolean expand = Standard_False; //default 
347 TDF_Label aLabel = myAssembly->AddComponent (aShape [,expand]); 
348 ~~~~~
349 If *expand* is True and *aShape* is a Compound, *aShape* is broken down to produce sub-components, one for each of its sub-shapes. 
350
351 To add a component to the assembly, from a previously recorded shape (the new component is defined by the label of the reference shape, and its location), use: 
352 ~~~~~
353 TDF_Label refLabel ...; // the label of reference shape 
354 TopLoc_Location loc ...; // the desired location 
355 TDF_Label aLabel = myAssembly->AddComponent (refLabel, loc); 
356 ~~~~~
357 To remove a component from the assembly, use: 
358 ~~~~~
359 myAssembly->RemoveComponent (aLabel); 
360 ~~~~~
361
362 @subsection occt_xde_2_4 Management of Sub-Shapes
363 In addition to components of a (sub-)assembly, it is possible to have individual identification of some sub-shapes inside any shape. Therefore, you can attach specific attributes such as Colors. Some additional actions can be performed on sub-shapes that are neither top-level, nor components: 
364 To add a sub-shape to a given Label, use: 
365 ~~~~~
366 TDF_Label subLabel = myAssembly->AddSubShape (aLabel, subShape); 
367 ~~~~~
368
369 To find the Label attached to a given sub-shape, use: 
370 ~~~~~
371 TDF_Label subLabel; // new label to be computed 
372 if ( myAssembly-> FindSubShape (aLabel, subShape, subLabel)) { .. yes .. } 
373 ~~~~~
374 If the sub-shape is found (yes), *subLabel* is filled by the correct value. 
375
376 To find the top-level simple shape (not a compound whether free or not), which contains a given sub-shape, use: 
377 ~~~~~
378 TDF_Label mainLabel = myAssembly->FindMainShape(subShape); 
379 ~~~~~
380 **Note** that there should be only one shape for a valid model. In any case, the search stops on the first one found. 
381
382 To get the sub-shapes of a shape, which are recorded under a label, use: 
383 ~~~~~
384 TDF_LabelSequence subs; 
385 Standard_Boolean hassubs = myAssembly->GetSubShapes (aLabel,subs); 
386 ~~~~~
387 @subsection occt_xde_2_5 Properties
388 Some properties can be attached directly to shapes. These properties are: 
389   * Name (standard definition from OCAF)
390   * Centroid (for validation of transfer)
391   * Volume (for validation of transfer)
392   * Area (for validation of transfer)
393 Some other properties can also be attached, and are also managed by distinct tools for Colors and Layers. Colors and Layers are managed as an alternative way of organizing data (by providing a way of identifying groups of shapes). 
394 Colors are put into a table of colors while shapes refer to this table. There are two ways of attaching a color to a shape: 
395   * By attaching an item from the table.
396   * Adding the color directly.
397 When the color is added directly, a search is performed in the table of contents to determine if it contains the requested color. Once this search and initialize operation is done, the first way of attaching a color to a shape is used. 
398 @subsubsection occt_xde_2_5_1 Name
399 Name is implemented and used as a *TDataStd_Name*, which can be attached to any label. Before proceeding, consider that: 
400   * In IGES, every entity can have a name with an optional numeric part called a Subscript Label. For example, *MYCURVE* is a name, and *MYCURVE(60)* is a name with a Subscript Label.
401   * In STEP, there are two levels: Part Names and Entity Names: 
402                 * Part Names are attached to ;main shapes; such as parts and assemblies. These Part Names are specifically supported by XDE. 
403                 * Entity Names can be attached to every Geometric Entity. This option is rarely used, as it tends to overload the exploitation of the data structure. Only some specific cases justify using this option: for example, when the sending system can really ensure the stability of an entity name after each STEP writing. If such stability is ensured, you can use this option to send an Identifier for external applications using a database. 
404 **Note** that both IGES or STEP files handle names as pure ASCII strings.
405  
406 These considerations are not specific to XDE. What is specific to data exchange is the way names are attached to entities. 
407
408 To get the name attached to a label (as a reminder using OCAF), use: 
409 ~~~~~
410 Handle(TDataStd_Name) N; 
411 if ( !aLabel.FindAttribute(TDataStd_Name::GetID(),N)) { 
412   // no name is attached 
413
414 TCollection_ExtendedString name = N->Get(); 
415 ~~~~~
416
417 Don't forget to consider Extended String as ASCII, for the exchange file. 
418
419 To set a name to a label (as a reminder using OCAF), use: 
420 ~~~~~
421 TCollection_ExtendedString aName ...; 
422 // contains the desired name for this Label (ASCII) 
423 TDataStd_Name::Set (aLabel, aName); 
424 ~~~~~
425
426 @subsubsection occt_xde_2_5_2 Centroid
427 A Centroid is defined by a Point to fix its position. It is handled as a property, item of the class *XCAFDoc_Centroid*, sub-class of *TDF_Attribute*. However, global methods give access to the position itself. 
428
429 This notion has been introduced in STEP, together with that of Volume, and Area, as defining the Validation Properties: this feature allows exchanging the geometries and some basic attached values, in order to perform a synthetic checking on how they are maintained after reading and converting the exchange file. This exchange depends on reliable exchanges of Geometry and Topology. Otherwise, these values can be considered irrelevant. 
430
431 A centroid can be determined at any level of an assembly, thereby allowing a check of both individual simple shapes and their combinations including locations. 
432
433 To get a Centroid attached to a Shape, use: 
434 ~~~~~
435 gp_Pnt pos; 
436 Handle(XCAFDoc_Centroid) C; 
437 aLabel.FindAttribute ( XCAFDoc_Centroid::GetID(), C ); 
438 if ( !C.IsNull() ) pos = C->Get(); 
439 ~~~~~
440
441 To set a Centroid to a Shape, use: 
442 ~~~~~
443 gp_Pnt pos (X,Y,Z); 
444 // the position previously computed for the centroid 
445 XCAFDoc_Centroid::Set ( aLabel, pos ); 
446 ~~~~~
447
448 @subsubsection occt_xde_2_5_3 Area
449 An Area is defined by a Real, it corresponds to the computed Area of a Shape, provided that it contains surfaces. It is handled as a property, item of the class *XCAFDoc_Area*, sub-class of *TDF_Attribute*. 
450 This notion has been introduced in STEP but it is usually disregarded for a Solid, as Volume is used instead. In addition, it is attached to simple shapes, not to assemblies. 
451
452 To get an area attached to a Shape, use: 
453 ~~~~~
454 Standard_Real area; 
455 Handle(XCAFDoc_Area) A; 
456 L.FindAttribute ( XCAFDoc_Area::GetID(), A ); 
457 if ( !A.IsNull() ) area = A->Get(); 
458
459 To set an area value to a Shape, use: 
460 Standard_Real area ...; 
461 // value previously computed for the area 
462 XCAFDoc_Area::Set ( aLabel, area ); 
463 ~~~~~
464 @subsubsection occt_xde_2_5_4 Volume
465 A Volume is defined by a Real and corresponds to the computed volume of a Shape, provided that it contains solids. It is handled as a property, an item of the class *XCAFDoc_Volume*, sub-class of *TDF_Attribute*. 
466 This notion has been introduced in STEP. It may be attached to simple shapes or their assemblies for computing cumulated volumes and centers of gravity. 
467
468 To get a Volume attached to a Shape, use: 
469 ~~~~~
470 Standard_Real volume; 
471 Handle(XCAFDoc_Volume) V; 
472 L.FindAttribute ( XCAFDoc_Volume::GetID(), V ); 
473 if ( !V.IsNull() ) volume = V->Get(); 
474 ~~~~~
475
476 To set a volume value to a Shape, use: 
477 ~~~~~
478 Standard_Real volume ...; 
479 // value previously computed for the volume 
480 XCAFDoc_Volume::Set ( aLabel, volume ); 
481 ~~~~~
482 @subsection occt_xde_2_6 Colors and Layers
483
484 XDE can read and write colors and layers assigned to shapes or their subparts (down to level of faces and edges) to and from both IGES and STEP formats. 
485
486 @figure{/user_guides/xde/images/239_xde_12_400.png,"Motor Head"}
487
488 In an XDE document, colors are managed by the class *XCAFDoc_ColorTool*. This is done with the same principles as for ShapeTool with Shapes, and with the same capability of having a tool on the Main Label, or on any sub-label. The Property itself is defined as an *XCAFDoc_Color*, sub-class of *TDF_Attribute*.
489  
490 Colors are stored in a child of the starting document label: it is the second level (0.1.2), while Shapes are at the first level. Each color then corresponds to a dedicated label, the property itself is a Quantity_Color, which has a name and value for Red, Green, Blue. A Color may be attached to Surfaces (flat colors) or to Curves (wireframe colors), or to both. A Color may be attached to a sub-shape. In such a case, the sub-shape (and its own sub-shapes) takes its own Color as a priority.
491
492 Layers are handled using the same principles as Colors. In all operations described below you can simply replace **Color** with **Layer** when dealing with Layers. Layers are supported by the class *XCAFDoc_LayerTool*. 
493
494 The class of the property is *XCAFDoc_Layer*, sub-class of *TDF_Attribute* while its definition is a *TCollection_ExtendedString*. Integers are generally used when dealing with Layers. The general cases are: 
495   * IGES has *LevelList* as a list of Layer Numbers (not often used)
496   * STEP identifies a Layer (not by a Number, but by a String), to be more general.
497
498 Colors and Shapes are related to by Tree Nodes. 
499
500 These definitions are common to various exchange formats, at least for STEP and IGES. 
501
502 @subsubsection occt_xde_2_6_1 Initialization
503 To query, edit, or initialize a Document to handle Colors of XCAF, use: 
504 ~~~~~
505 Handle(XCAFDoc_ColorTool) myColors = 
506 XCAFDoc_DocumentTool::ColorTool(Doc->Main ()); 
507 ~~~~~
508 This call can be used at any time. The first time it is used, a relevant structure is added to the document. This definition is used for all the following color calls and will not be repeated for these. 
509
510 @subsubsection occt_xde_2_6_2 Adding a Color
511 There are two ways to add a color. You can: 
512   * add a new Color defined as *Quantity_Color* and then directly set it to a Shape (anonymous Color)
513   * define a new Property Color, add it to the list of Colors, and then set it to various shapes.
514 When the Color is added by its value *Quantity_Color*, it is added only if it has not yet been recorded (same RGB values) in the Document. 
515
516 To set a Color to a Shape using a label, use:
517 ~~~~~
518 Quantity_Color Col (red,green,blue); 
519 XCAFDoc_ColorType ctype ..; 
520 // can take one of these values : 
521 // XCAFDoc_ColorGen : all types of geometries 
522 // XCAFDoc_ColorSurf : surfaces only 
523 // XCAFDoc_ColorCurv : curves only 
524 myColors->SetColor ( aLabel, Col, ctype ); 
525 ~~~~~
526 Alternately, the Shape can be designated directly, without using its label, use: 
527 ~~~~~
528 myColors->SetColor ( aShape, Col, ctype ); 
529 // Creating and Adding a Color, explicitly 
530 Quantity_Color Col (red,green,blue); 
531 TDF_Label ColLabel = myColors->AddColor ( Col ); 
532 ~~~~~
533 **Note** that this Color can then be named, allowing later retrieval by its Name instead of its Value. 
534
535 To set a Color, identified by its Label and already recorded, to a Shape, use: 
536 ~~~~~
537 XCAFDoc_ColorType ctype ..; // see above
538 if ( myColors->SetColors ( aLabel, ColLabel, ctype) ) {.. it is done .. }
539 ~~~~~
540 In this example, *aLabel* can be replaced by *aShape* directly. 
541
542 @subsubsection occt_xde_2_6_3 Queries on Colors
543 Various queries can be performed on colors. However, only specific queries are included in this section, not general queries using names. 
544
545 To determine if a Color is attached to a Shape, for a given color type (ctype), use: 
546 ~~~~~
547 if ( myColors->IsSet (aLabel , ctype)) { 
548   // yes, there is one .. 
549
550 ~~~~~
551 In this example, *aLabel* can be replaced by *aShape* directly. 
552
553 To get the Color attached to a Shape (for any color type), use: 
554 ~~~~~
555 Quantity_Color col; 
556 // will receive the recorded value (if there is some)
557 if ( !myColors->GetColor(aLabel, col) ) { 
558 // sorry, no color .. 
559 }
560 ~~~~~
561
562 Color name can also be queried from *col.StringName* or *col.Name*. 
563 In this example, *aLabel* can be replaced by *aShape* directly. 
564
565 To get the Color attached to a Shape, with a specific color type, use: 
566 ~~~~~
567 XCAFDoc_ColorType ctype ..; 
568 Quantity_Color col; 
569 // will receive the recorded value (if there is some) 
570 if ( !myColors->GetColor(aLabel, ctype, col) ) { 
571 // sorry, no color .. 
572
573 ~~~~~
574
575
576 To get all the Colors recorded in the Document, use: 
577
578 ~~~~~
579 Quantity_Color col; // to receive the values 
580 TDF_LabelSequence ColLabels; 
581 myColors->GetColors(ColLabels); 
582 Standard_Integer i, nbc = ColLabels.Length(); 
583 for (i = 1; i = nbc; i ++) { 
584   aLabel = Labels.Value(i); 
585   if ( !myColors->GetColor(aLabel, col) ) continue; 
586   // col receives the color n0 i .. 
587
588 ~~~~~
589
590 To find a Color from its Value, use: 
591 ~~~~~
592 Quantity_Color Col (red,green,blue); 
593 TDF_Label ColLabel = myColors-FindColor (Col); 
594 if ( !ColLabel.IsNull() ) { .. found .. } 
595 ~~~~~
596
597 @subsubsection occt_xde_2_6_4 Editing Colors
598 Besides adding colors, the following attribute edits can be made: 
599
600 To unset a Color on a Shape, use: 
601 ~~~~~
602 XCAFDoc_ColorType ctype ...; 
603 // desired type (XCAFDoc_ColorGen for all ) 
604 myColors->UnSetColor (aLabel,ctype); 
605 ~~~~~
606 To remove a Color and all the references to it (so that the related shapes will become colorless), use: 
607 ~~~~~
608 myColors->RemoveColor(ColLabel); 
609 ~~~~~
610
611   
612 @subsection occt_xde_2_8 Reading and Writing STEP or IGES
613 Note that saving and restoring the document itself are standard OCAF operations. As the various previously described definitions enter into this frame, they will not be explained any further. 
614 The same can be said for Viewing: presentations can be defined from Shapes and Colors. 
615
616 There are several important points to consider: 
617   * Previously defined Readers and Writers for dealing with Shapes only, whether Standard or Advanced, remain unchanged in their form and in their dependencies. In addition, functions other than mapping are also unchanged.
618   * XDE provides mapping with data other than Shapes. Names, Colors, Layers, Validation Properties (Centroid, Volume, Area), and Assembly Structure are hierarchic with rigid motion.
619   * XDE mapping is relevant for use within the Advanced level of Data Exchanges, rather than Standard ones, because a higher level of information is better suited to a higher quality of shapes. In addition, this allows to avoid the multiplicity of combinations between various options. Note that this choice is not one of architecture but of practical usage and packaging.
620   * Reader and Writer classes for XDE are generally used like those for Shapes. However, their use is adapted to manage a Document rather than a Shape.
621   
622 The packages to manage this are *IGESCAFControl* for IGES, and *STEPCAFControl* for STEP. 
623 @subsubsection occt_xde_2_8_1 Reading a STEP file
624 To read a STEP file by itself, use: 
625
626 ~~~~~
627 STEPCAFControl_Reader reader; 
628 IFSelect_ReturnStatus readstat = reader.ReadFile(filename); 
629 // The various ways of reading a file are available here too : 
630 // to read it by the reader, to take it from a WorkSession ... 
631 Handle(TDocStd_Document) doc... 
632 // the document referred to is already defined and 
633 // properly initialized. 
634 // Now, the transfer itself 
635 if ( !reader.Transfer ( doc ) ) { 
636   cout;Cannot read any relevant data from the STEP file;endl; 
637   // abandon .. 
638
639 // Here, the Document has been filled from a STEP file, 
640 // it is ready to use 
641 ~~~~~
642
643 In addition, the reader provides methods that are applicable to document transfers and for directly querying of the data produced. 
644 @subsubsection occt_xde_2_8_2 Writing a STEP file
645 To write a STEP file by itself, use: 
646
647 ~~~~~
648 STEPControl_StepModelType mode = 
649 STEPControl_AsIs; 
650 // Asis is the recommended value, others are available 
651 // Firstly, perform the conversion to STEP entities 
652 STEPCAFControl_Writer writer; 
653 //(the user can work with an already prepared WorkSession or create a //new one) 
654 Standard_Boolean scratch = Standard_False; 
655 STEPCAFControl_Writer writer ( WS, scratch ); 
656 // Translating document (conversion) to STEP 
657 if ( ! writer.Transfer ( Doc, mode ) ) { 
658   cout;The document cannot be translated or gives no result;endl; 
659   // abandon .. 
660
661 // Writing the File 
662 IFSelect_ReturnStatus stat = writer.Write(file-name); 
663 ~~~~~
664
665 @subsubsection occt_xde_2_8_3 Reading an IGES File
666 Use the same procedure as for a STEP file but with IGESCAFControl instead of STEPCAFControl. 
667 @subsubsection occt_xde_2_8_4 Writing an IGES File
668 Use the same procedure as for a STEP file but with IGESCAFControl instead of STEPCAFControl.
669  
670 @subsection occt_xde_2_9 Using an XDE Document
671 There are several ways of exploiting XDE data from an application, you can: 
672  1. Get the data relevant for the application by mapping XDE/Appli, then discard the XDE data once it has been used.
673  2. Create a reference from the Application Document to the XDE Document, to have its data available as external data.
674  3. Embed XDE data inside the Application Document (see the following section for details).
675  4. Directly exploit XDE data such as when using file checkers.
676 @subsubsection occt_xde_2_91 XDE Data inside an Application Document
677 To have XCAF data elsewhere than under label 0.1, you use the DocLabel of XDE. The method DocLabel from XCAFDoc_DocumentTool determines the relevant Label for XCAF. However, note that the default is 0.1. 
678
679 In addition, as XDE data is defined and managed in a modular way, you can consider exclusively Assembly Structure, only Colors, and so on. 
680
681 As XDE provides an extension of the data structure, for relevant data in standardized exchanges, note the following: 
682   * This data structure is fitted for data exchange, rather than for use by the final application.
683   * The provided definitions are general, for common use and therefore do not bring strongly specific semantics.
684   
685 As a result, if an application works on Assemblies, on Colors or Layers, on Validation Properties (as defined in STEP), it can rely on all or a part of the XDE definitions, and include them in its own data structure. 
686
687 In addition, if an application has a data structure far from these notions, it can get data (such as Colors and Names on Shapes) according to its needs, but without having to consider the whole.