1dae4838a36e458e6bd68b22540c0cc70fa8c216
[occt.git] / dox / user_guides / shape_healing / shape_healing.md
1 Shape Healing  {#occt_user_guides__shape_healing}
2 ===================
3
4 @tableofcontents
5
6 @section occt_shg_1 Overview
7
8 This manual explains how to use Shape Healing. It provides basic documentation on its operation. For advanced information on Shape Healing and its applications, see our offerings on our web site at <a href="http://www.opencascade.org/support/training/">www.opencascade.org/support/training/</a>  
9
10 The **Shape Healing** toolkit provides a set of tools to work on the geometry and topology of Open CASCADE Technology (**OCCT**) shapes. Shape Healing adapts shapes so as to make them as appropriate for use by Open CASCADE Technology as possible. 
11 **Shape Healing** currently includes several packages that are designed to help you to: 
12   *  analyze shape characteristics and, in particular, identify shapes that do not comply with Open CASCADE Technology validity rules 
13   *  fix some of the problems shapes may have 
14   *  upgrade shape characteristics for users needs, for example a C0 supporting surface can be upgraded so that it becomes C1 continuous. 
15   
16 The following diagram shows dependencies of API packages: 
17
18 @figure{/user_guides/shape_healing/images/shape_healing_image009.svg, "Shape Healing packages"}
19
20 Each sub-domain has its own scope of functionality: 
21 * analysis - exploring shape properties, computing shape features, detecting violation of OCCT requirements (shape itself is not modified);
22 * fixing - fixing shape to meet the OCCT requirements (the shape may change its original form: modifying, removing, constructing sub-shapes, etc.); 
23 * upgrade - shape improvement for better usability in Open CASCADE Technology or other algorithms (the shape is replaced with a new one, but geometrically they are the same); 
24 * customization - modifying shape representation to fit specific needs (shape is not modified, only the form of its representation is modified); 
25 * processing  - mechanism of managing shape modification via a user-editable resource file. 
26
27 Message management is used for creating messages, filling them with various parameters and storing them in the trace file. This tool provides functionality for attaching messages to the shapes for deferred analysis of various run-time events. In this document only general principles of using Shape Healing will be described. For more detailed information please see the corresponding CDL files. 
28
29 Tools responsible for analysis, fixing and upgrading of shapes can give the information about how these operations were performed. This information can be obtained by the user with the help of mechanism of status querying. 
30
31 @subsection occt_shg_1_1 Querying the statuses
32
33 Each fixing and upgrading tool has its own status, which is reset when their methods are called. The status can contain several flags, which give the information about how the method was performed. For exploring the statuses, a set of methods named *Status...()* is provided. These methods accept enumeration *ShapeExtend_Status* and return True if the status has the corresponding flag set. The meaning of flags for each method is described below. 
34
35 The status may contain a set of Boolean flags (internally represented by bits). Flags are coded by enumeration ShapeExtend_Status. This enumeration provides the following families of statuses: 
36 * *ShapeExtend_OK*  -  The situation is OK, no operation is necessary and has not been performed. 
37 * *ShapeExtend_DONE* - The operation has been successfully performed. 
38 * *ShapeExtend_FAIL* - An error has occurred during operation. 
39
40 It is possible to test the status for the presence of some flag(s), using Status...() method(s) provided by the class: 
41
42 ~~~~~
43 if ( object.Status.. ( ShapeExtend_DONE ) ) {// something was done 
44
45 ~~~~~
46
47 8 'DONE' and 8 'FAIL' flags, named ShapeExtend_DONE1 ... ShapeExtend_FAIL8, are defined for a detailed analysis of the encountered situation. Each method assigns its own meaning to each flag, documented in the CDL for that method. There are also three enumerative values used for testing several flags at a time: 
48 * *ShapeExtend_OK*   -     if no flags have been set; 
49 * *ShapeExtend_DONE* - if at least one ShapeExtend_DONEi has been set; 
50 * *ShapeExtend_FAIL* - if at least one ShapeExtend_FAILi has been set. 
51
52 @section occt_shg_2 Repair
53
54 Algorithms for fixing problematic (violating the OCCT requirements) shapes are placed in package *ShapeFix*. 
55
56 Each class of package *ShapeFix* deals with one certain type of shapes or with some family of problems. 
57
58 There is no necessity for you to detect problems before using *ShapeFix* because all components of package *ShapeFix* make an analysis of existing problems before fixing them by a corresponding tool from package of *ShapeAnalysis* and then fix the discovered problems. 
59
60 The *ShapeFix* package currently includes functions that: 
61   * add a 2D curve or a 3D curve where one is missing,
62   * correct a deviation of a 2D curve from a 3D curve when it exceeds a given tolerance value,
63   * limit the tolerance value of shapes within a given range,
64   * set a given tolerance value for shapes,
65   * repair the connections between adjacent edges of a wire,
66   * correct self–intersecting wires,
67   * add seam edges,
68   * correct gaps between 3D and 2D curves,
69   * merge and remove small edges,
70   * correct orientation of shells and solids.
71
72 @subsection occt_shg_2_1 Basic Shape Repair
73
74 The simplest way for fixing shapes is to use classes *ShapeFix_Shape* and *ShapeFix_Wireframe* on a whole shape with default parameters. A combination of these tools can fix most of the problems that shapes may have. 
75 The sequence of actions is as follows : 
76
77 1. Create tool *ShapeFix_Shape* and initialize it by shape: 
78 ~~~~~
79 Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; 
80 sfs->Init ( shape ); 
81 ~~~~~
82 2. Set the basic precision and the maximum allowed tolerance:
83 ~~~~~
84 sfs->SetPrecision ( Prec ); 
85 sfs->SetMaxTolerance ( maxTol ); 
86 ~~~~~
87 where *Prec* – basic precision,  *maxTol* – maximum allowed tolerance. 
88 All problems will be detected for cases when a dimension of invalidity is larger than the basic precision or a tolerance of sub-shape on that problem is detected.
89 The maximum tolerance value limits the increasing tolerance for fixing a problem. If a value larger than the maximum allowed tolerance is necessary for correcting a detected problem the problem can not be fixed.
90 3. Launch fixing:
91 ~~~~~
92 sfs->Perform(); 
93 ~~~~~
94 4. Get the result:
95 ~~~~~
96 TopoDS_Shape aResult = sfs-Shape(); 
97 ~~~~~
98 In some cases using  only *ShapeFix_Shape* can be insufficient. It is possible to use tools for merging and removing small edges and fixing gaps between 2D and 3D curves.
99 5. Create *ShapeFix_Wireframe* tool and initialize it by shape:
100 ~~~~~
101 Handle(ShapeFix_Wirefarme) SFWF = new ShapeFix_Wirefarme(shape); 
102 Or 
103 Handle(ShapeFix_Wirefarme) SFWF = new ShapeFix_Wirefarme; 
104 SFWF->Load(shape); 
105 ~~~~~
106 6. Set the basic precision and the maximum allowed tolerance:
107 ~~~~~
108 sfs->SetPrecision ( Prec ); 
109 sfs->SetMaxTolerance ( maxTol ); 
110 ~~~~~
111 See the description for *Prec* and *maxTol* above. 
112 7. Merge and remove small edges:
113 ~~~~~
114 SFWF-DropSmallEdgesMode() = Standard_True; 
115 SFWF-FixSmallEdges(); 
116 ~~~~~
117 **Note:** Small edges are not removed with the default mode, but in many cases removing small edges is very useful for fixing a shape. 
118 8. Fix gaps for 2D and 3D curves
119 ~~~~~
120 SFWF-FixWireGaps(); 
121 ~~~~~
122 9. Get the result
123 ~~~~~
124 TopoDS_Shape Result = SFWF-Shape(); 
125 ~~~~~
126
127
128 @subsection occt_shg_2_2 Shape Correction.
129
130 If you do not want to make fixes on the whole shape or make a definite set of fixes you can set flags for separate fix cases (marking them ON or OFF) and you can also use classes for fixing specific types of sub-shapes such as solids, shells, faces, wires, etc.  
131
132 For each type of sub-shapes there are specific types of fixing tools such as *ShapeFix_Solid, ShapeFix_Shell, ShapeFix_Face, ShapeFix_Wire,* etc.
133
134 @subsubsection occt_shg_2_2_1 Fixing sub-shapes
135 If you want to make a fix on one subshape of a certain shape it is possible to take the following steps: 
136   * create a tool for a specified subshape type and initialize this tool by the subshape;
137   * create a tool for rebuilding the shape and initialize it by the whole shape (section 5.1);
138   * set a tool for rebuilding the shape in the tool for fixing the subshape;
139   * fix the subshape;
140   * get the resulting whole shape containing a new corrected subshape.
141
142 For example, in the following way it is possible to fix face *Face1* of shape *Shape1*: 
143
144 ~~~~~
145 //create tools for fixing a face 
146 Handle(ShapeFix_Face)  SFF= new ShapeFix_Face; 
147
148 // create tool for rebuilding a shape and initialize it by shape 
149 Handle(ShapeBuild_ReShape) Context = new ShapeBuild_ReShape;  
150 Context-Apply(Shape1); 
151
152 //set a tool for rebuilding a shape in the tool for fixing 
153 SFF-SetContext(Context); 
154         
155 //initialize the fixing tool by one face 
156 SFF-Init(Face1); 
157
158 //fix the set face 
159 SFF-Perform(); 
160         
161 //get the result 
162 TopoDS_Shape  NewShape = Context-Apply(Shape1); 
163 //Resulting shape contains the fixed face. 
164 ~~~~~
165
166 A set of required fixes and invalid sub-shapes can be obtained with the help of tools responsible for the analysis of shape validity (section 3.2). 
167
168 @subsection occt_shg_2_3 Repairing tools
169
170 Each class of package ShapeFix deals with one certain type of shapes or with a family of problems. Each repairing tool makes fixes for the specified shape and its sub-shapes with the help of method *Perform()* containing an optimal set of fixes. The execution of these fixes in the method Perform can be managed with  help of a set of control flags (fixes can be either forced or forbidden). 
171
172 @subsubsection occt_shg_2_3_1 General Workflow 
173
174 The following sequence of actions should be applied to perform fixes:
175 1. Create a tool. 
176 2. Set the following values: 
177         + the working precision by method  *SetPrecision()* (default 1.e-7) 
178         + set the maximum allowed tolerance by method *SetMaxTolerance()* (by default it is equal to the working precision). 
179         + set the minimum tolerance by method *SetMinTolerance()* (by default it is equal to the working precision). 
180         + set a tool for rebuilding shapes after the modification (tool *ShapeBuild_ReShape*) by method *SetContext()*. For separate faces, wires and edges this tool is set optionally. 
181         + to force or forbid some of fixes, set the corresponding flag to 0 or 1. 
182 3. Initialize the tool by the shape with the help of methods Init or Load
183 4. Use method *Perform()* or create a custom set of fixes. 
184 5. Check the statuses of fixes by the general method *Status* or specialized methods *Status_*(for example *StatusSelfIntersection* (*ShapeExtentd_DONE*)). See the description of statuses below. 
185 6. Get the result in two ways : 
186         - with help of a special method *Shape(),Face(),Wire().Edge()*. 
187         - from the rebuilding tool by method *Apply* (for access to rebuilding tool use method *Context()*): 
188 ~~~~~
189         TopoDS_Shape resultShape = fixtool-Context()-Apply(initialShape); 
190 ~~~~~
191 Modification fistory for the shape and its sub-shapes can be obtained from the tool for shape re-building (*ShapeBuild_ReShape*). 
192
193 ~~~~~
194 TopoDS_Shape modifsubshape = fixtool-Context() 
195 -Apply(initsubshape); 
196 ~~~~~
197
198  
199 @subsubsection occt_shg_2_3_2 Flags Management
200  
201 The flags *Fix...Mode()* are used to control the execution of fixing procedures from the API fixing methods. By default, these flags have values equal to -1, this means that the corresponding procedure will either be called or not called, depending on the situation. If the flag is set to 1, the procedure is executed anyway; if the flag is 0, the procedure is not executed. The name of the flag corresponds to the fixing procedure that is controlled. For each fixing tool there exists its own set of flags. To set a flag to the desired value, get a tool containing this flag and set the flag to the required value. 
202
203 For example, it is possible to forbid performing fixes to remove small edges - *FixSmall* 
204
205 ~~~~~
206 Handle(ShapeFix_Shape) Sfs = new ShapeFix_Shape(shape); 
207 Sfs- FixWireTool ()-FixSmallMode () =0; 
208 if(Sfs-Perform()) 
209         TopoDS_Shape resShape = Sfs-Shape(); 
210 ~~~~~
211
212
213 @subsubsection occt_shg_2_3_3 Repairing tool for shapes
214
215 Class *ShapeFix_Shape* allows using repairing tools for all sub-shapes of a shape. It provides access to all repairing tools for fixing sub-shapes of the specified shape and to all control flags from these tools.
216
217 For example, it is possible to force the removal of invalid 2D curves from a face. 
218
219 ~~~~~
220 TopoDS_Face face … // face with invalid 2D curves. 
221 //creation of tool and its initialization by shape. 
222 Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape(face); 
223 //set work precision and max allowed tolerance. 
224 sfs->SetPrecision(prec); 
225 sfs->SetMaxTolerance(maxTol); 
226 //set the value of flag for forcing the removal of 2D curves 
227 sfs->FixWireTool()-FixRemovePCurveMode() =1; 
228 //reform fixes 
229 sfs->Perform(); 
230 //getting the result 
231 if(sfs->Status(ShapeExtend_DONE) ) { 
232  cout << Shape was fixed << endl; 
233  TopoDS_Shape resFace = sfs->Shape(); 
234
235 else if(sfs->Status(ShapeExtend_FAIL)) { 
236 cout<< Shape could not be fixed << endl; 
237
238 else if(sfs->Status(ShapeExtent_OK)) { 
239 cout<< Initial face is valid with specified precision =<< precendl; 
240
241 ~~~~~
242
243 @subsubsection occt_shg_2_3_4 Repairing tool for solids
244
245 Class *ShapeFix_Solid* allows fixing solids and building a solid from a shell to obtain a valid solid with a finite volume. The tool *ShapeFix_Shell* is used for correction of shells belonging to a solid. 
246
247 This tool has the following control flags:
248 * *FixShellMode* - Mode for applying fixes of ShapeFix_Shell, True by default. 
249 * *CreateOpenShellMode* - If it is equal to true solids are created from open shells, else solids are created from closed shells only, False by default. 
250
251 @subsubsection occt_shg_2_3_5 Repairing tool for shells 
252 Class *ShapeFix_Shell* allows fixing wrong orientation of faces in a shell. It changes the orientation of faces in the shell  so that all faces in the shell have coherent orientations. If it is impossible to orient all faces in the shell (like in case of Mebious tape), then a few manifold or non-manifold shells will be created depending on the specified Non-manifold mode. The *ShapeFix_Face* tool is used to correct faces in the shell. 
253 This tool has the following control flags:
254 * *FixFaceMode* - mode for applying the fixes of  *ShapeFix_Face*, *True* by default. 
255 * *FixOrientationMode*  - mode for applying a fix for the orientation of faces in the shell. 
256
257 @subsubsection occt_shg_2_3_6 Repairing tool for faces 
258
259 Class *ShapeFix_Face* allows fixing the problems connected with wires of a face. It allows controlling the creation of a face (adding wires), and fixing wires by means of tool *ShapeFix_Wire*. 
260 When a wire is added to a face, it can be reordered and degenerated edges can be fixed. This is performed or not depending on the user-defined flags (by default, False). 
261 The following fixes are available: 
262   * fixing of wires orientation on the face. If the face has no wire, the natural bounds are computed. If the face is on a spherical surface and has two or more wires on it describing holes, the natural bounds are added. In case of a single wire, it is made to be an outer one. If the face has several wires, they are oriented to lay one outside another (if possible). If the supporting surface is periodic, 2D curves of internal wires can be shifted on integer number of periods to put them inside the outer wire. 
263   * fixing the case when the face on the closed surface is defined by a set of closed wires, and the seam is missing (this is not valid in OCCT). In that case, these wires are connected by means of seam edges into the same wire.
264
265 This tool has the following control flags: 
266 * *FixWireMode*  - mode for applying fixes of a wire, True by default. 
267 * *FixOrientationMode*  - mode for orienting a wire to border a limited square, True by default. 
268 * *FixAddNaturalBoundMode* - mode for adding natural bounds to a face, False by default. 
269 * *FixMissingSeamMode* – mode to fix a missing seam, True by default. If True, tries to insert a seam. 
270 * *FixSmallAreaWireMode* - mode to fix a small-area wire, False by default. If True, drops wires bounding small areas. 
271
272 ~~~~~
273
274 TopoDS_Face face = ...; 
275 TopoDS_Wire wire = ...; 
276
277 //Creates a tool and adds a wire to the face 
278 ShapeFix_Face sff (face); 
279 sff.Add (wire); 
280
281 //use method Perform to fix the wire and the face 
282 sff.Perfom(); 
283
284 //or make a separate fix for the orientation of wire on the face 
285 sff.FixOrientation(); 
286
287 //Get the resulting face 
288 TopoDS_Face newface = sff.Face(); 
289 ~~~~~
290
291 @subsubsection occt_shg_2_3_7 Repairing tool for wires 
292
293 Class *ShapeFix_Wire* allows fixing a wire. Its method *Perform()* performs all the available fixes in addition to the geometrical filling of gaps. The geometrical filling of gaps can be made with the help of the tool for fixing the wireframe of shape *ShapeFix_Wireframe*.  
294
295 The fixing order and the default behavior of *Perform()* is as follows: 
296   * Edges in the wire are reordered by *FixReorder*. Most of fixing methods expect edges in a wire to be ordered, so it is necessary to make call to *FixReorder()* before making any other fixes. Even if it is forbidden, the analysis of whether the wire is ordered or not is performed anyway. 
297   * Small edges are removed by *FixSmall* . 
298   * Edges in the wire are connected (topologically) by *FixConnected* (if the wire is ordered). 
299   * Edges (3Dcurves and 2D curves)  are fixed by *FixEdgeCurves* (without *FixShifted* if the wire is not ordered). 
300   * Degenerated edges  are added by *FixDegenerated*(if the wire is ordered). 
301   * Self-intersection is fixed by *FixSelfIntersection* (if the wire is ordered and *ClosedMode* is True). 
302   * Lacking edges are fixed by *FixLacking* (if the wire is ordered). 
303   
304  The flag *ClosedWireMode* specifies whether the wire is (or should be) closed or not. If that flag is True (by default), fixes that require or force connection between edges are also executed for the last and the first edges. 
305   
306 The fixing methods can be turned on/off by using their corresponding control flags: 
307 * *FixReorderMode,* 
308 * *FixSmallMode,* 
309 * *FixConnectedMode,* 
310 * *FixEdgeCurvesMode,* 
311 * *FixDegeneratedMode,* 
312 * *FixSelfIntersectionMode* 
313
314 Some fixes can be made in three ways: 
315   * Increasing the tolerance of an edge or a vertex. 
316   * Changing topology (adding/removing/replacing an edge in the wire and/or replacing the vertex in the edge, copying the edge etc.). 
317   * Changing geometry (shifting a vertex or adjusting ends of an edge curve to vertices, or re-computing a 3D curve or 2D curves of the edge). 
318   
319 When it is possible to make a fix in more than one way (e.g., either by increasing the tolerance or shifting a vertex), it is chosen according to the user-defined flags: 
320 * *ModifyTopologyMode* -   allows modifying topology, False by default. 
321 * *ModifyGeometryMode* -  allows modifying geometry. Now this flag is used only in fixing self-intersecting edges (allows to modify 2D curves) and is True by default. 
322   
323 #### Fixing disordered edges
324
325 *FixReorder* is necessary for most other fixes (but is not necessary for Open CASCADE Technology). It checks whether edges in the wire go in a sequential order (the end of a preceding edge is the start of a following one). If it is not so, an attempt to reorder the edges is made. 
326
327 #### Fixing small edges
328
329 *FixSmall* method searches for the edges, which have a length less than the given value (degenerated edges are ignored). If such an edge is found, it is removed provided that one of the following conditions is satisfied: 
330   * both end vertices of that edge are one and the same vertex, 
331   * end vertices of the edge are different, but the flag *ModifyTopologyMode* is True. In the latter case, method *FixConnected* is applied to the preceding and the following edges to ensure their connection.
332  
333 #### Fixing disconnected edges
334
335 *FixConnected* method forces two adjacent edges to share the same common vertex (if they do not have a common one). It checks whether the end vertex of the preceding edge coincides with the start vertex of the following edge with the given precision, and then creates a new vertex and sets it as a common vertex for the fixed edges. At that point, edges are copied, hence the wire topology is changed (regardless of the *ModifyTopologyMode* flag). If the vertices do not coincide, this method fails. 
336
337 #### Fixing the consistency of edge curves
338
339 *FixEdgeCurves* method performs a set of fixes dealing with 3D curves and 2D curves of edges in a wire. 
340
341 These fixes will be activated with the help of a set of fixes from the repairing tool for edges called *ShapeFix_Edge*. Each of these fixes can be forced or forbidden by means of setting the corresponding flag to either True or False. 
342
343 The mentioned fixes and the conditions of their execution are: 
344   * fixing a disoriented 2D curve by call to *ShapeFix_Edge::FixReversed2d* - if not forbidden by flag *FixReversed2dMode*;
345   * removing a wrong 2D curve  by call to *ShapeFix_Edge::FixRemovePCurve* - only if forced by flag *FixRemovePCurveMode*;
346   * fixing a missing  2D curve by call to *ShapeFix_Edge::FixAddPCurve* - if not forbidden by flag *FixAddPCurveMode*; 
347   * removing a wrong 3D curve by call to *ShapeFix_Edge::FixRemoveCurve3d* - only if forced by flag *FixRemoveCurve3dMode*; 
348   * fixing a missing 3D curve by call to *ShapeFix_Edge::FixAddCurve3d* - if not forbidden by flag *FixAddCurve3dMode*;
349   * fixing 2D curves of seam edges - if not forbidden by flag *FixSeamMode*; 
350   * fixing 2D curves which can be shifted at an integer number of periods on the closed surface by call to *ShapeFix_Edge::FixShifted*  - if not forbidden by flag *FixShiftedMode*. 
351   
352 This fix is required if 2D curves of some edges in a wire lying on a closed surface were recomputed from 3D curves. In that case, the 2D curve for the edge, which goes along the seam of the surface, can be incorrectly shifted at an integer number of periods. The method *FixShifted* detects such cases and shifts wrong 2D curves back, ensuring that the 2D curves of the edges in the wire are connected.
353
354   * fixing the SameParameter problem by call to *ShapeFix_Edge::FixSameParameter* - if not forbidden by flag *FixSameParameterMode*.
355   
356   
357 #### Fixing degenerated edges
358
359 *FixDegenerated*  method checks whether an edge in a wire lies on a degenerated point of the supporting surface, or whether there is a degenerated point between the edges. If one of these cases is detected for any edge, a new degenerated edge is created and it replaces the current edge in the first case or is added to the wire in the second case. The newly created degenerated edge has a straight 2D curve, which goes from the end of the 2D curve of the preceding edge to the start of the following one. 
360
361 #### Fixing intersections of 2D curves of the edges
362
363 *FixSelfIntersection* method detects and fixes the following problems: 
364   * self-intersection of 2D curves of individual edges. If the flag *ModifyGeometryMode()* is False this fix will be performed by increasing the tolerance of one of end vertices to a value less then *MaxTolerance()*.
365   * intersection of 2D curves of each of the two adjacent edges (except the first and the last edges if the flag ClosedWireMode is False). If such intersection is found, the common vertex is modified in order to comprise the intersection point. If the flag *ModifyTopologyMode* is False this fix will be performed by increasing the tolerance of the vertex to a value less then *MaxTolerance()*.
366   * intersection of 2D curves of non-adjacent edges. If such intersection is found the tolerance of the nearest vertex is increased to comprise the intersection point. If such increase cannot be done with a tolerance less than *MaxTolerance* this fix will not be performed.
367
368 #### Fixing a lacking edge
369
370 *FixLacking* method checks whether a wire is not closed in the parametrical space of the surface (while it can be closed in 3D). This is done by checking whether the gap between 2D curves of each of the two adjacent edges in the wire is smaller than the tolerance of the corresponding vertex. The algorithm computes the gap between the edges, analyses positional relationship of the ends of these edges and (if possible) tries to insert a new edge into the gap or increases the tolerance. 
371
372 #### Fixing gaps in 2D and 3D wire by geometrical filling
373 The following methods check gaps between the ends of 2D or 3D curves of adjacent edges:
374 * Method *FixGap2d* moves the ends of 2D curves to the middle point. 
375 * Method *FixGaps3d* moves the ends of 3D curves to a common vertex. 
376
377 Boolean flag *FixGapsByRanges* is used to activate an additional mode applied before converting to B-Splines. When this mode is on, methods try to find the most precise intersection of curves, or the most precise projection of a target point, or an extremity point between two curves (to modify their parametric range accordingly). This mode is off by default. Independently of the additional mode described above, if gaps remain, these methods convert curves to B-Spline form and shift their ends if a gap is detected. 
378
379 #### Example: A custom set of fixes 
380
381
382 Let us create a custom set of fixes as an example. 
383 ~~~~~
384 TopoDS_Face face = ...; 
385 TopoDS_Wire wire = ...; 
386 Standard_Real precision = 1e-04; 
387 ShapeFix_Wire sfw (wire, face, precision); 
388 //Creates a tool and loads objects into it 
389 sfw.FixReorder(); 
390 //Orders edges in the wire so that each edge 
391 //starts at the end of the one before it 
392 sfw.FixConnected(); 
393 //Forces all adjacent edges to share 
394 //the same vertex 
395 Standard_Boolean LockVertex = Standard_True; 
396 if (sfw.FixSmall (LockVertex, precision)) { 
397   //Removes all edges which are shorter than 
398   //the given precision and have the same vertex at both ends 
399
400 if (sfw.FixSelfIntersection()) { 
401   //Fixes self-intersecting edges and intersecting 
402   //adjacent edges 
403   cout;Wire was slightly self-intersecting. Repaired;endl; 
404
405 if ( sfw.FixLacking ( Standard_False ) ) { 
406   //Inserts edges to connect adjacent 
407   //non-continuous edges 
408
409 TopoDS_Wire newwire = sfw.Wire(); 
410 //Returns the corrected wire 
411 ~~~~~
412
413 #### Example: Correction of a wire 
414
415 Let us correct the following wire:
416
417 @image html /user_guides/shape_healing/images/shape_healing_image013.png "Initial shape"
418 @image latex /user_guides/shape_healing/images/shape_healing_image013.png "Initial shape"
419
420 It is necessary to apply the <a href="#_3_1_2">Tools for the analysis of validity of wires</a> to check that:
421 * the edges are correctly oriented;
422 * there are no edges that are too short;
423 * there are no intersecting adjacent edges;
424 and then immediately apply fixing tools. 
425
426 ~~~~~
427 TopoDS_Face face = ...;
428 TopoDS_Wire wire = ...;
429 Standard_Real precision = 1e-04;
430 ShapeAnalysis_Wire saw (wire, face, precision);
431 ShapeFix_Wire sfw (wire, face, precision);
432 if (saw.CheckOrder()) {
433   cout<<“Some edges in the wire need to be reordered”<<endl;
434   // Two edges are incorrectly oriented
435   sfw.FixReorder();
436   cout<<“Reordering is done”<<endl;
437 }
438 // their orientation is corrected
439 if (saw.CheckSmall (precision)) {
440   cout<<“Wire contains edge(s) shorter than “<<precision<<endl;
441   // An edge that is shorter than the given
442   // tolerance is found
443   Standard_Boolean LockVertex = Standard_True;
444   if (sfw.FixSmall (LockVertex, precision)) {
445     cout<<“Edges shorter than “<<precision<<“ have been removed”
446 <<endl;
447     //The edge is removed
448   }
449 }
450 if (saw.CheckSelfIntersection()) {
451   cout<<“Wire has self-intersecting or intersecting
452 adjacent edges”<<endl;
453   // Two intersecting adjacent edges are found
454   if (sfw.FixSelfIntersection()) {
455     cout<<“Wire was slightly self-intersecting. Repaired”<<endl;
456     // The edges are cut at the intersection point so
457     // that they no longer intersect
458   }
459 }
460 ~~~~~
461
462 As the result all failures have been fixed.
463
464 @image html /user_guides/shape_healing/images/shape_healing_image014.png "Resulting shape"
465 @image latex /user_guides/shape_healing/images/shape_healing_image014.png "Resulting shape"
466
467 @subsubsection occt_shg_2_3_8 Repairing tool for edges 
468
469 Class *ShapeFix_Edge*  provides tools for fixing invalid edges. The following geometrical and/or topological inconsistencies are detected and fixed: 
470   * missing 3D curve or 2D curve, 
471   * mismatching orientation of a 3D curve and a 2D curve, 
472   * incorrect SameParameter flag (curve deviation is greater than the edge tolerance). 
473 Each fixing method first checks whether the problem exists using methods of the *ShapeAnalysis_Edge* class. If the problem is not detected, nothing is done. 
474 This tool does not have the method *Perform()*. 
475
476 To see how this tool works, it is possible to take an edge, where the maximum deviation between the 3D curve and 2D curve P1 is greater than the edge tolerance.
477
478 @image html /user_guides/shape_healing/images/shape_healing_image011.png "Initial shape"
479 @image latex /user_guides/shape_healing/images/shape_healing_image011.png "Initial shape"
480
481 First it is necessary to apply the <a href="#_3_1_3">Tool for checking the validity of edges</a> to find that maximum deviation between pcurve and 3D curve is greater than tolerance. Then we can use the repairing tool to increase the tolerance and make the deviation acceptable.
482
483 ~~~~~   
484 ShapeAnalysis_Edge sae;
485 TopoDS_Face face = ...; 
486 TopoDS_Wire wire = ...; 
487 Standard_Real precision = 1e-04; 
488 ShapeFix_Edge sfe;
489 Standard_Real maxdev;
490 if (sae.CheckSameParameter (edge, maxdev)) {
491   cout<<“Incorrect SameParameter flag”<<endl;
492   cout<<“Maximum deviation “<<maxdev<< “, tolerance “
493 <<BRep_Tool::Tolerance(edge)<<endl;
494   sfe.FixSameParameter();
495   cout<<“New tolerance “<<BRep_Tool::Tolerance(edge)<<endl;
496 }
497 ~~~~~
498
499 @image html /user_guides/shape_healing/images/shape_healing_image012.png "Resulting shape"
500 @image latex /user_guides/shape_healing/images/shape_healing_image012.png "Resulting shape"
501
502 As the result, the  edge tolerance has been increased.
503
504
505 @subsubsection occt_shg_2_3_9 Repairing tool for the wireframe of a shape 
506
507 Class *ShapeFix_Wireframe provides methods for geometrical fixing of gaps and merging small edges in a shape. This class performs the following operations: 
508   * fills gaps in the 2D and 3D wireframe of a shape. 
509   * merges and removes small edges.
510   
511 Fixing of small edges can be managed with the help of two flags: 
512   * *ModeDropSmallEdges()* – mode for removing small edges that can not be merged, by default it is equal to Standard_False. 
513   * *LimitAngle* – maximum possible angle for merging two adjacent edges, by default no limit angle is applied (-1).
514 To perform fixes it is necessary to: 
515   * create a tool and initialize it by shape,
516   * set the working precision problems will be detected with and the maximum allowed tolerance
517   * perform fixes
518   
519 ~~~~~
520 //creation of a tool 
521 Handle(ShapeFix_Wireframe) sfwf = new ShapeFix_Wireframe(shape); 
522 //sets the working precision problems will be detected with and 
523 //the maximum allowed tolerance 
524 sfwf->SetPrecision(prec); 
525 sfwf->SetMaxTolerance(maxTol); 
526 //fixing of gaps 
527 sfwf->FixWireGaps(); 
528 //fixing of small edges 
529 //setting of the drop mode for the fixing of small edges and max possible angle between merged edges. 
530 sfwf->ModeDropSmallEdges = Standard_True; 
531 sfwf->SetLimliteAngle(angle); 
532 //performing the fix 
533 sfwf->FixSmallEdges(); 
534 //getting the result 
535 TopoDS_Shape resShape = sfwf->Shape(); 
536 ~~~~~
537
538 It is desirable that a shape is topologically correct before applying the methods of this class. 
539
540 @subsubsection occt_shg_2_3_10 Tool for removing small faces from a shape 
541
542 Class ShapeFix_FixSmallFaceThis tool is intended for dropping small faces from the shape. The following cases are processed: 
543 * Spot face: if the size of the face is less than the given precision;
544 * Strip face: if the size of the face in one dimension is less then the given precision. 
545
546 The sequence of actions for performing the fix is the same as for the fixes described above: 
547
548 ~~~~~
549 //creation of a tool 
550 Handle(ShapeFix_FixSmallFace) sff = new ShapeFix_FixSmallFace(shape); 
551 //setting of tolerances 
552 sff->SetPrecision(prec); 
553 sff->SetMaxTolerance(maxTol); 
554 //performing fixes 
555 sff.Perform(); 
556 //getting the result 
557 TopoDS_Shape resShape = sff.FixShape(); 
558 ~~~~~
559
560 @subsubsection occt_shg_2_3_11 Tool to modify  tolerances of shapes (Class ShapeFix_ShapeTolerance).
561
562 This tool provides a functionality to set tolerances of a shape and its sub-shapes. 
563 In Open CASCADE Technology only vertices, edges and faces have tolerances. 
564
565 This tool allows processing each concrete type of sub-shapes or all types at a time. 
566 You set the tolerance functionality as follows: 
567   * set a tolerance for sub-shapes, by method SetTolerance,
568   * limit tolerances with given ranges, by method LimitTolerance.
569   
570 ~~~~~
571 //creation of a tool 
572 ShapeFix_ShapeTolerance Sft; 
573 //setting a specified tolerance on shape and all of its sub-shapes. 
574 Sft.SetTolerance(shape,toler); 
575 //setting a specified tolerance for vertices only 
576 Sft.SetTolerance(shape,toler,TopAbs_VERTEX); 
577 //limiting the tolerance on the shape and its sub-shapes between minimum and 
578 //maximum tolerances 
579 Sft.LimitTolerance(shape,tolermin,tolermax); 
580 ~~~~~
581
582
583 @section occt_shg_3 Analysis
584
585 @subsection occt_shg_3_1 Analysis of shape validity
586
587 The *ShapeAnalysis* package provides tools for the analysis of topological shapes. 
588 It is not necessary to check a shape by these tools before the execution of repairing tools because these tools are used for the analysis before performing fixes inside the repairing tools. 
589 However, if you want, these tools can be used for detecting some of shape problems independently from the repairing tools. 
590
591  It can be done in the following way: 
592   * create an analysis tool. 
593   * initialize it by shape and set a tolerance problems will be detected with if it is necessary.
594   * check the problem that interests you.
595   
596 ~~~~~
597 TopoDS_Face face = ...; 
598 ShapeAnalysis_Edge sae; 
599 //Creates a tool for analyzing an edge 
600 for(TopExp_Explorer Exp(face,TopAbs_EDGE);Exp.More();Exp.Next()) { 
601   TopoDS_Edge edge = TopoDS::Edge (Exp.Current()); 
602   if (!sae.HasCurve3d (edge)) { 
603     cout  *Edge has no 3D curve*  endl;  } 
604
605 ~~~~~
606
607 @subsubsection occt_shg_3_1_1 Analysis of orientation of wires on a face.
608
609 It is possible to check whether a face has an outer boundary with the help of method *ShapeAnalysis::IsOuterBound*. 
610
611 ~~~~~
612 TopoDS_Face face … //analyzed face 
613 if(!ShapeAnalysis::IsOuterBound(face)) { 
614 cout*Face has not outer boundary**endl; 
615
616 ~~~~~
617
618 @subsubsection occt_shg_3_1_2 Analysis of wire validity
619
620 Class *ShapeAnalysis_Wire* is intended to analyze a wire. It provides functionalities both to explore wire properties and to check its conformance to Open CASCADE Technology requirements. 
621 These functionalities include: 
622   * checking the order of edges in the wire, 
623   * checking for the presence of small edges (with a length less than the given value), 
624   * checking for the presence of disconnected edges (adjacent edges having different vertices), 
625   * checking the consistency of edge curves, 
626   * checking for the presence or missing of degenerated edges, 
627   * checking for the presence of self-intersecting edges and intersecting edges (edges intersection is understood as intersection of their 2D curves), 
628   * checking for lacking edges to fill gaps in the surface parametrical space, 
629   * analyzing the wire orientation (to define the outer or the inner bound on the face), 
630   * analyzing the orientation of the shape (edge or wire) being added to an already existing wire. 
631
632 **Note** that all checking operations except for the first one are based on the assumption that edges in the wire are ordered. Thus, if the wire is detected as non-ordered it is necessary to order it before calling other checking operations. This can be done, for example, with the help of the *ShapeFix_Wire::FixOrder()* method. 
633
634 This tool should be initialized with wire, face (or a surface with a location) or precision. 
635 Once the tool has been initialized, it is possible to perform the necessary checking operations. In order to obtain all information on a wire at a time the global method *Perform* is provided. It calls all other API checking operations to check each separate case. 
636
637 API methods check for corresponding cases only, the value and the status they return can be analyzed to understand whether the case was detected or not. 
638
639 Some methods in this class are: 
640   *  *CheckOrder* checks whether edges in the wire are in the right order 
641   *  *CheckConnected* checks whether edges are disconnected 
642   *  *CheckSmall* checks whether there are edges that are shorter than the given value 
643   *  *CheckSelfIntersection* checks, whether there are self-intersecting or adjacent intersecting edges. If the intersection takes place due to nonadjacent edges, it is not detected. 
644   
645 This class maintains status management. Each API method stores the status of its last execution which can be queried by the corresponding *Status..()* method. In addition, each API method returns a Boolean value, which is True when a case being analyzed is detected (with the set *ShapeExtend_DONE* status), otherwise it is False. 
646
647 ~~~~~
648 TopoDS_Face face = ...; 
649 TopoDS_Wire wire = ...; 
650 Standard_Real precision = 1e-04; 
651 ShapeAnalysis_Wire saw (wire, face, precision); 
652 //Creates a tool and loads objects into it 
653 if (saw.CheckOrder()) { 
654   cout*Some edges in the wire need to be reordered*endl; 
655   cout*Please ensure that all the edges are correctly 
656 ordered before further analysis*endl; 
657   return; 
658
659 if (saw.CheckSmall (precision)) { 
660   cout*Wire contains edge(s) shorter than *precisionendl; 
661
662 if (saw.CheckConnected()) { 
663   cout*Wire is disconnected*endl; 
664
665 if (saw.CheckSelfIntersection()) { 
666   cout*Wire has self-intersecting or intersecting 
667 adjacent edges*  endl; 
668
669 ~~~~~
670
671 @subsubsection occt_shg_3_1_3 Analysis of edge validity 
672
673 Class *ShapeAnalysis_Edge* is intended to analyze edges. It provides the following functionalities to work with an edge: 
674   * querying geometrical representations (3D curve and pcurve(s) on a given face or surface), 
675   * querying topological sub-shapes (bounding vertices), 
676   * checking overlapping edges,
677   * analyzing the curves consistency: 
678                 + mutual orientation of the 3D curve and 2D curve (co-directions or opposite directions), 
679                 + correspondence of 3D and 2D curves to vertices. 
680
681 This class supports status management described above. 
682
683 ~~~~~
684 TopoDS_Face face = ...; 
685 ShapeAnalysis_Edge sae; 
686 //Creates a tool for analyzing an edge 
687 for(TopExp_Explorer Exp(face,TopAbs_EDGE);Exp.More();Exp.Next()) { 
688   TopoDS_Edge edge = TopoDS::Edge (Exp.Current()); 
689   if (!sae.HasCurve3d (edge)) { 
690     cout  *Edge has no 3D curve*  endl; 
691   } 
692   Handle(Geom2d_Curve) pcurve; 
693   Standard_Real cf, cl; 
694   if (sae.PCurve (edge, face, pcurve, cf, cl, Standard_False)) { 
695     //Returns the pcurve and its range on the given face 
696     cout*Pcurve range [*cf*, *cl*]* endl; 
697   } 
698   Standard_Real maxdev; 
699   if (sae.CheckSameParameter (edge, maxdev)) { 
700     //Checks the consistency of all the curves 
701     //in the edge 
702     cout*Incorrect SameParameter flag*endl; 
703   } 
704   cout*Maximum deviation *maxdev*, tolerance* 
705              BRep_Tool::Tolerance(edge)endl; 
706
707 //checks the overlapping of two edges 
708 if(sae.CheckOverlapping(edge1,edge2,prec,dist)) { 
709  cout*Edges are overlapped with tolerance = *precendl; 
710  cout*Domain of overlapping =*distendl; 
711
712 ~~~~~
713
714 @subsubsection occt_shg_3_1_4 Analysis of presence of small faces
715
716 Class *ShapeAnalysis_CheckSmallFace* class is intended for analyzing small faces from the shape using the following methods: 
717 * *CheckSpotFace()* checks if the size of the face is less than the given precision; 
718 * *CheckStripFace* checks if the size of the face in one dimension is less than the given precision.
719
720 ~~~~~
721 TopoDS_Shape shape … // checked shape 
722 //Creation of a tool 
723 ShapeAnalysis_CheckSmallFace saf; 
724 //exploring the shape on faces and checking each face 
725 Standard_Integer numSmallfaces =0; 
726 for(TopExp_Explorer aExp(shape,TopAbs_FACE); aExp.More(); aExp.Next()) { 
727  TopoDS_Face face = TopoDS::Face(aexp.Current()); 
728  TopoDS_Edge E1,E2; 
729 if(saf.CheckSpotFace(face,prec) || 
730 saf.CheckStripFace(face,E1,E2,prec)) 
731 NumSmallfaces++; 
732
733 if(numSmallfaces) 
734  cout*Number of small faces in the shape =* numSmallfaces endl; 
735 ~~~~~ 
736  
737 @subsubsection occt_shg_3_1_5 Analysis of shell validity and closure 
738
739 Class *ShapeAnalysis_Shell* allows checking the orientation of edges in a manifold shell. With the help of this tool, free edges (edges entered into one face) and bad edges (edges entered into the shell twice with the same orientation) can be found. By occurrence of bad and free edges a conclusion about the shell validity and the closure of the shell can be made. 
740
741 ~~~~~
742 TopoDS_Shell shell // checked shape 
743 ShapeAnalysis_Shell sas(shell); 
744 //analysis of the shell , second parameter is set to True for //getting free edges,(default False) 
745 sas.CheckOrientedShells(shell,Standard_True); 
746 //getting the result of analysis 
747 if(sas.HasBadEdges()) { 
748 cout<<"Shell is invalid"<<endl; 
749 TopoDS_Compound badEdges = sas.BadEdges(); 
750
751 if(sas.HasFreeEdges()) { 
752  cout<<"Shell is open"<<endl; 
753  TopoDS_Compound freeEdges = sas.FreeEdges(); 
754
755 ~~~~~
756
757 @subsection occt_shg_3_2 Analysis of shape properties.
758 @subsubsection occt_shg_3_2_1 Analysis of tolerance on shape 
759
760 Class *ShapeAnalysis_ShapeTolerance* allows computing tolerances of the shape and its sub-shapes. In Open CASCADE Technology only vertices, edges and faces have tolerances: 
761
762 This tool allows analyzing each concrete type of sub-shapes or all types at a time. 
763 The analysis of tolerance functionality is the following: 
764   * computing the minimum, maximum and average tolerances of sub-shapes, 
765   * finding sub-shapes with tolerances exceeding the given value, 
766   * finding sub-shapes with tolerances in the given range. 
767   
768 ~~~~~
769 TopoDS_Shape shape = ...; 
770 ShapeAnalysis_ShapeTolerance sast; 
771 Standard_Real AverageOnShape = sast.Tolerance (shape, 0); 
772 cout*Average tolerance of the shape is *AverageOnShapeendl; 
773 Standard_Real MinOnEdge = sast.Tolerance (shape,-1,TopAbs_EDGE); 
774 cout*Minimum tolerance of the edges is *MinOnEdgeendl; 
775 Standard_Real MaxOnVertex = sast.Tolerance (shape,1,TopAbs_VERTEX); 
776 cout*Maximum tolerance of the vertices is *MaxOnVertexendl; 
777 Standard_Real MaxAllowed = 0.1; 
778 if (MaxOnVertex  MaxAllowed) { 
779   cout*Maximum tolerance of the vertices exceeds 
780                    maximum allowed*endl; 
781
782 ~~~~~
783
784 @subsubsection occt_shg_3_2_2 Analysis of free boundaries. 
785
786 Class ShapeAnalysis_FreeBounds is intended to analyze and output the free bounds of a shape. Free bounds are wires consisting of edges referenced only once by only one face in the shape. 
787 This class works on two distinct types of shapes when analyzing their free bounds: 
788 * Analysis of possible free bounds taking the specified tolerance into account. This analysis can be applied to a compound of faces. The analyzer of the sewing algorithm (*BRepAlgo_Sewing*) is used to forecast what free bounds would be obtained after the sewing of these faces is performed. The following method should be used for this analysis:
789 ~~~~~
790 ShapeAnalysis_FreeBounds safb(shape,toler); 
791 ~~~~~
792 * Analysis of already existing free bounds. Actual free bounds (edges shared by the only face in the shell) are output in this case. *ShapeAnalysis_Shell* is used for that. 
793 ~~~~~
794 ShapeAnalysis_FreeBounds safb(shape); 
795 ~~~~~
796
797 When connecting edges into wires this algorithm tries to build wires of maximum length. Two options are provided for the user to extract closed sub-contours out of closed and/or open contours. Free bounds are returned as two compounds, one for closed and one for open wires. To obtain a result it is necessary to use methods: 
798 ~~~~~
799 TopoDS_Compound ClosedWires  = safb.GetClosedWires(); 
800 TopoDS_Compound OpenWires = safb.GetOpenWires(); 
801 ~~~~~
802 This class also provides some static methods for advanced use: connecting edges/wires to wires, extracting closed sub-wires from wires, distributing wires into compounds for closed and open wires. 
803
804 ~~~~~
805 TopoDS_Shape shape = ...; 
806 Standard_Real SewTolerance = 1.e-03; 
807 //Tolerance for sewing 
808 Standard_Boolean SplitClosed = Standard_False; 
809 Standard_Boolean SplitOpen = Standard_True; 
810 //in case of analysis of possible free boundaries 
811 ShapeAnalysis_FreeBounds safb (shape, SewTolerance, 
812 SplitClosed, SplitOpen); 
813 //in case of analysis of existing free bounds 
814 ShapeAnalysis_FreeBounds safb (shape, SplitClosed, SplitOpen); 
815 //getting the results 
816 TopoDS_Compound ClosedWires = safb.GetClosedWires(); 
817 //Returns a compound of closed free bounds 
818 TopoDS_Compound OpenWires = safb.GetClosedWires(); 
819 //Returns a compound of open free bounds 
820 ~~~~~
821
822 @subsubsection occt_shg_3_2_3 Analysis of shape contents
823
824 Class *ShapeAnalysis_ShapeContents* provides tools counting the number of sub-shapes and selecting a sub-shape by the following criteria: 
825
826 Methods for getting the number of sub-shapes: 
827   * number of solids,
828   * number of shells,
829   * number of faces,
830   * number of edges,
831   * number of vertices.
832   
833 Methods for calculating the number of geometrical objects or sub-shapes with a specified type: 
834   * number of free faces,
835   * number of free wires,
836   * number of free edges,
837   * number of C0 surfaces,
838   * number of C0 curves,
839   * number of BSpline surfaces,… etc
840   
841 and selecting sub-shapes by various criteria. 
842
843 The corresponding flags should be set to True for storing a shape by a specified criteria: 
844   * faces based on indirect surfaces - *safc.MofifyIndirectMode() = Standard_True*; 
845   * faces based on offset surfaces - *safc.ModifyOffsetSurfaceMode() = Standard_True*; 
846   * edges if their 3D curves are trimmed - *safc.ModifyTrimmed3dMode() = Standard_True*; 
847   * edges if their 3D curves and 2D curves are offset curves - *safc.ModifyOffsetCurveMode() = Standard_True*; 
848   * edges if their 2D curves are trimmed - *safc.ModifyTrimmed2dMode() = Standard_True*; 
849
850 Let us, for example, select faces based on offset surfaces.
851
852 ~~~~~ 
853 ShapeAnalysis_ShapeContents safc; 
854 //set a corresponding flag for storing faces based on the offset surfaces 
855 safc.ModifyOffsetSurfaceMode() = Standard_True; 
856 safc.Perform(shape); 
857 //getting the number of offset surfaces in the shape 
858 Standard_Integer NbOffsetSurfaces = safc.NbOffsetSurf(); 
859 //getting the sequence of faces based on offset surfaces. 
860 Handle(TopTools_HSequenceOfShape) seqFaces = safc.OffsetSurfaceSec(); 
861 ~~~~~
862
863 @section occt_shg_4 Upgrading
864
865 Upgrading tools are intended for adaptation of shapes for better use by Open CASCADE Technology or for customization to particular needs, i.e. for export to another system. This means that not only it corrects and upgrades but also changes the definition of a shape with regard to its geometry, size and other aspects. Convenient API allows you to create your own tools to perform specific upgrading. Additional tools for particular cases provide an ability to divide shapes and surfaces according to certain criteria. 
866
867 @subsection occt_shg_4_1 Tools for splitting a shape according to a specified criterion
868
869 @subsubsection occt_shg_4_1_1 Overview
870
871 These tools provide such modifications when one topological object can be divided or converted to several ones according to specified criteria. Besides, there are high level API tools for particular cases which: 
872   * Convert the geometry of shapes up to a given continuity, 
873   * split revolutions by U to segments less than the given value, 
874   * convert to Bezier surfaces and Bezier curves, 
875   * split closed faces,
876   * convert C0 BSpline curve to a sequence of C1 BSpline curves. 
877   
878 All tools for particular cases are based on general tools for shape splitting but each of them has its own tools for splitting or converting geometry in accordance with the specified criteria. 
879
880 General tools for shape splitting are: 
881   * tool for splitting the whole shape,
882   * tool for splitting a face,
883   * tool for splitting wires.
884   
885 Tools for shape splitting use tools for geometry splitting: 
886   * tool for splitting surfaces,
887   * tool for splitting 3D curves,
888   * tool for splitting 2D curves.
889   
890 @subsubsection occt_shg_4_1_2 Using tools available for shape splitting.
891 If it is necessary to split a shape by a specified continuity, split closed faces in the shape, split surfaces of revolution in the shape by angle or to convert all surfaces, all 3D curves, all 2D curves in the shape to Bezier, it is possible to use the existing/available tools. 
892
893 The usual way to use these tools exception for the tool of converting a C0 BSpline curve is the following: 
894   * a tool is created and initialized by shape.
895   * work precision for splitting and the maximum allowed tolerance are set
896   * the value of splitting criterion Is set (if necessary)
897   * splitting is performed.
898   * splitting statuses are obtained.
899   * result is obtained
900   * the history of modification of the initial shape and its sub-shapes is output (this step is optional).
901
902 Let us, for example, split all surfaces and all 3D and 2D curves having a continuity of less the C2. 
903
904 ~~~~~
905 //create a tool and initializes it by shape. 
906 ShapeUpgrade_ShapeDivideContinuity ShapeDivedeCont(initShape); 
907
908 //set the working 3D and 2D precision and the maximum allowed //tolerance 
909 ShapeDivideCont.SetTolerance(prec); 
910 ShapeDivideCont.SetTolerance2D(prec2d); 
911 ShapeDivideCont.SetMaxTolerance(maxTol); 
912
913 //set the values of criteria for surfaces, 3D curves and 2D curves. 
914 ShapeDivideCont.SetBoundaryCriterion(GeomAbs_C2); 
915 ShapeDivideCont.SetPCurveCriterion(GeomAbs_C2); 
916 ShapeDivideCont.SetSurfaceCriterion(GeomAbs_C2); 
917
918 //perform the splitting. 
919 ShapeDivideCont.Perform(); 
920
921 //check the status and gets the result 
922 if(ShapeDivideCont.Status(ShapeExtend_DONE) 
923  TopoDS_Shape result = ShapeDivideCont.GetResult(); 
924 //get the history of modifications made to faces 
925 for(TopExp_Explorer aExp(initShape,TopAbs_FACE); aExp.More(0; aExp.Next()) { 
926   TopoDS_Shape modifShape = ShapeDivideCont.GetContext()- 
927 Apply(aExp.Current()); 
928
929 ~~~~~
930
931 @subsubsection occt_shg_4_1_3 Creation of a new tool for splitting a shape.
932 To create a new splitting tool it is necessary to create tools for geometry splitting according to a desirable criterion. The new tools should be inherited from basic tools for geometry splitting. Then the new tools should be set into corresponding tools for shape splitting. 
933   * a new tool for surface splitting  should be set into the tool for face splitting
934   * new tools for splitting of 3D and 2D curves  should be set into the splitting tool for wires.
935   
936 To change the value of criterion of shape splitting it is necessary to create a new tool for shape splitting that should be inherited from the general splitting tool for shapes. 
937
938 Let us split a shape according to a specified criterion. 
939
940 ~~~~~
941 //creation of new tools for geometry splitting by a specified //criterion. 
942 Handle(MyTools_SplitSurfaceTool) MySplitSurfaceTool = 
943 new MyTools_SplitSurfaceTool; 
944 Handle(MyTools_SplitCurve3DTool) MySplitCurve3Dtool = 
945 new MyTools_SplitCurve3DTool; 
946 Handle(MyTools_SplitCurve2DTool) MySplitCurve2Dtool = 
947 new MyTools_SplitCurve2DTool; 
948
949 //creation of a tool for splitting the shape and initialization of //that tool by shape. 
950 TopoDS_Shape initShape 
951 MyTools_ShapeDivideTool ShapeDivide (initShape); 
952
953 //setting of work precision for splitting and maximum allowed //tolerance. 
954 ShapeDivide.SetPrecision(prec); 
955 ShapeDivide.SetMaxTolerance(MaxTol); 
956
957 //setting of new splitting geometry tools in the shape splitting //tools 
958 Handle(ShapeUpgrade_FaceDivide) FaceDivide = 
959 ShapeDivide-GetSplitFaceTool(); 
960 Handle(ShapeUpgrade_WireDivide) WireDivide = 
961 FaceDivide-GetWireDivideTool(); 
962 FaceDivide-SetSplitSurfaceTool(MySplitSurfaceTool); 
963 WireDivide-SetSplitCurve3dTool(MySplitCurve3DTool); 
964 WireDivide-SetSplitCurve2dTool(MySplitCurve2DTool); 
965
966 //setting of the value criterion. 
967  ShapeDivide.SetValCriterion(val); 
968             
969 //shape splitting 
970 ShapeDivide.Perform(); 
971
972 //getting the result 
973 TopoDS_Shape splitShape = ShapeDivide.GetResult(); 
974
975 //getting the history of modifications of faces 
976 for(TopExp_Explorer aExp(initShape,TopAbs_FACE); aExp.More(0; aExp.Next()) { 
977 TopoDS_Shape modifShape = ShapeDivide.GetContext()- 
978 Apply(aExp.Current()); 
979
980 ~~~~~
981
982 @subsection occt_shg_4_2 General splitting tools.
983  
984 @subsubsection occt_shg_4_2_1 General tool for shape splitting 
985
986 Class *ShapeUpgrade_ShapeDivide* provides shape splitting and converting according to the given criteria. It performs these operations for each face with the given tool for face splitting (*ShapeUpgrade_FaceDivide* by default). 
987
988 This tool provides access to the tool for dividing faces with the help of the methods *SetSplitFaceTool* and *GetSpliFaceTool.* 
989
990 @subsubsection occt_shg_4_2_2 General tool for face splitting
991
992 Class *ShapeUpgrade_FaceDivide* divides a Face (edges in the wires, by splitting 3D and 2D curves, as well as the face itself, by splitting the supporting surface) according to the given criteria. 
993
994 The area of the face intended for division is defined by 2D curves of the wires on the Face. 
995 All 2D curves are supposed to be defined (in the parametric space of the supporting surface). 
996 The result is available after the call to the *Perform* method. It is a Shell containing all resulting Faces. All modifications made during the splitting operation are recorded in the external context (*ShapeBuild_ReShape*). 
997
998 This tool provides access to the tool for wire division and surface splitting by means of the following methods: 
999 * *SetWireDivideTool,* 
1000 * *GetWireDivideTool,* 
1001 * *SetSurfaceSplitTool,* 
1002 * *GetSurfaceSplitTool*. 
1003
1004 @subsubsection occt_shg_4_2_3 General tool for wire splitting
1005 Class *ShapeUpgrade_WireDivide* divides edges in the wire lying on the face or free wires or free edges with a given criterion. It splits the 3D curve and 2D curve(s) of the edge on the face. Other 2D curves, which may be associated with the edge, are simply copied. If the 3D curve is split then the 2D curve on the face is split as well, and vice-versa. The original shape is not modified. Modifications made are recorded in the context (*ShapeBuild_ReShape*). 
1006
1007 This tool provides access to the tool for dividing and splitting 3D and 2D curves by means of the following methods: 
1008 * *SetEdgeDivdeTool,* 
1009 * *GetEdgeDivideTool,* 
1010 * *SetSplitCurve3dTool,* 
1011 * *GetSplitCurve3dTool,* 
1012 * *SetSplitCurve2dTool,* 
1013 * *GetSplitCurve2dTool* 
1014
1015 and it also provides access to the mode for splitting edges by methods *SetEdgeMode* and *GetEdgeMode*.
1016  
1017 This mode sets whether only free edges, only shared edges or all edges are split.
1018
1019 @subsubsection occt_shg_4_2_4 General tool for edge splitting
1020
1021 Class *ShapeUpgrade_EdgeDivide* divides edges and their geometry according to the specified criteria. It is used in the wire-dividing tool. 
1022
1023 This tool provides access to the tool for dividing and splitting 3D and 2D curves by the following methods: 
1024 * *SetSplitCurve3dTool,* 
1025 * *GetSplitCurve3dTool,* 
1026 * *SetSplitCurve2dTool,* 
1027 * *GetSplitCurve2dTool*. 
1028
1029 @subsubsection occt_shg_4_2_5 General tools for geometry splitting
1030 There are three general tools for geometry splitting. 
1031   * General tool for surface splitting.(*ShapeUpgrade_SplitSurface*)
1032   * General tool for splitting 3D curves.(*ShapeUpgrade_SplitCurve3d*)
1033   * General tool for splitting 2D curves.(*ShapeUpgrade_SplitCurve2d*)
1034   
1035 All these tools are constructed the same way: 
1036 They have methods: 
1037   * for initializing by geometry (method *Init*) 
1038   * for splitting (method *Perform*)
1039   * for getting the status after splitting and the results:
1040         + *Status* – for getting the result status; 
1041         + *ResSurface* - for splitting surfaces; 
1042         + *GetCurves* - for splitting 3D and 2D curves. 
1043 During the process of splitting in the method *Perform* : 
1044   * splitting values in the parametric space are computed according to a specified criterion (method  *Compute*) 
1045   * splitting is made in accordance with the values computed for splitting (method *Build*).
1046
1047 To create new tools for geometry splitting it is enough to inherit a new tool from the general tool for splitting a corresponding type of geometry and to re-define the method for computation of splitting values according to the specified criterion in them. (method *Compute*). 
1048
1049 Header file for the tool for surface splitting by continuity: 
1050
1051 ~~~~~
1052 class ShapeUpgrade_SplitSurfaceContinuity : public ShapeUpgrade_SplitSurface { 
1053 Standard_EXPORT ShapeUpgrade_SplitSurfaceContinuity(); 
1054
1055 //methods to set the criterion and the tolerance into the splitting //tool 
1056 Standard_EXPORT   void SetCriterion(const GeomAbs_Shape Criterion) ; 
1057 Standard_EXPORT   void SetTolerance(const Standard_Real Tol) ; 
1058
1059 //re-definition of method Compute 
1060 Standard_EXPORT virtual void Compute(const Standard_Boolean Segment) ; 
1061 Standard_EXPORT ~ShapeUpgrade_SplitSurfaceContinuity(); 
1062 private: 
1063 GeomAbs_Shape myCriterion; 
1064 Standard_Real myTolerance; 
1065 Standard_Integer myCont; 
1066 }; 
1067 ~~~~~
1068
1069 @subsection occt_shg_4_3 Specific splitting tools.
1070
1071 @subsubsection occt_shg_4_3_1 Conversion of shape geometry to the target continuity
1072 Class *ShapeUpgrade_ShapeDivideContinuity* allows converting geometry with continuity less than the specified continuity to geometry with target continuity. If converting is not possible than geometrical object is split into several ones, which satisfy the given criteria. A topological object based on this geometry is replaced by several objects based on the new geometry. 
1073
1074 ~~~~~
1075 ShapeUpgrade_ShapeDivideContinuity sdc (shape); 
1076 sdc.SetTolerance (tol3d); 
1077 sdc.SetTolerance3d (tol2d); // if known, else 1.e-09 is taken 
1078 sdc.SetBoundaryCriterion (GeomAbs_C2); // for Curves 3D 
1079 sdc.SetPCurveCriterion (GeomAbs_C2); // for Curves 2D 
1080 sdc.SetSurfaceCriterion (GeomAbs_C2); // for Surfaces 
1081 sdc.Perform (); 
1082 TopoDS_Shape bshape = sdc.Result(); 
1083 .. to also get the correspondances before/after 
1084 Handle(ShapeBuild_ReShape) ctx = sdc.Context(); 
1085 .. on a given shape 
1086 if (ctx.IsRecorded (sh)) { 
1087   TopoDS_Shape newsh = ctx->Value (sh); 
1088 // if there are several results, they are re-recorded inside a Compound 
1089 // .. process as needed 
1090
1091 ~~~~~
1092
1093 @subsubsection occt_shg_4_3_2 Splitting by angle
1094 Class *ShapeUpgrade_ShapeDivideAngle* allows  splitting all surfaces of revolution, cylindrical, toroidal, conical, spherical surfaces in the given shape so that each resulting segment covers not more than the defined angle (in radians). 
1095
1096 @subsubsection occt_shg_4_3_3 Conversion of 2D, 3D curves and surfaces to Bezier
1097
1098 Class *ShapeUpgrade_ShapeConvertToBezier* is an API tool for performing a conversion of 3D, 2D curves to Bezier curves and surfaces to Bezier based surfaces (Bezier surface, surface of revolution based on Bezier curve, offset surface based on any of previous types).
1099  
1100 This tool provides access to various flags for conversion of different types of curves and surfaces to Bezier by methods: 
1101 * For 3D curves: 
1102         * *Set3dConversion,* 
1103         * *Get3dConversion,* 
1104         * *Set3dLineConversion,* 
1105         * *Get3dLineConversion,* 
1106         * *Set3dCircleConversion,* 
1107         * *Get3dCircleConversion,* 
1108         * *Set3dConicConversion,* 
1109         * *Get3dConicConversion* 
1110 * For 2D curves: 
1111         * *Set2dConversion,* 
1112         * *Get2dConversion* 
1113 * For surfaces : 
1114         * *GetSurfaceConversion,* 
1115         * *SetPlaneMode,* 
1116         * *GetPlaneMode,* 
1117         * *SetRevolutionMode,* 
1118         * *GetRevolutionMode,* 
1119         * *SetExtrusionMode,* 
1120         * *GetExtrusionMode,* 
1121         * *SetBSplineMode,* 
1122         * *GetBSplineMode,* 
1123
1124 Let us attempt to produce a conversion of planes to Bezier surfaces. 
1125 ~~~~~
1126 //Creation and initialization of a tool. 
1127 ShapeUpgrade_ShapeConvertToBezier SCB (Shape); 
1128 //setting tolerances 
1129 ….. 
1130 //setting mode for conversion of planes 
1131 SCB.SetSurfaceConversion (Standard_True); 
1132 SCB.SetPlaneMode(Standard_True); 
1133 SCB.Perform(); 
1134 If(SCB.Status(ShapeExtend_DONE) 
1135     TopoDS_Shape result = SCB.GetResult(); 
1136 ~~~~~
1137
1138 @subsubsection occt_shg_4_3_4 Tool for splitting closed faces
1139
1140 Class *ShapeUpgrade_ShapeDivideClosed* provides splitting of closed faces in the shape to a defined number of components by the U and V parameters. It topologically and (partially) geometrically processes closed faces and performs splitting with the help of class *ShapeUpgrade_ClosedFaceDivide*. 
1141
1142 ~~~~~
1143 TopoDS_Shape aShape = …; 
1144 ShapeUpgrade_ShapeDivideClosed tool (aShape ); 
1145 Standard_Real closeTol = …; 
1146 tool.SetPrecision(closeTol); 
1147 Standard_Real maxTol = …; 
1148 tool.SetMaxTolerance(maxTol); 
1149 Standard_Integer NbSplitPoints = …; 
1150 tool.SetNbSplitPoints(num); 
1151 if ( ! tool.Perform() && tool.Status (ShapeExtend_FAIL) ) { 
1152   cout;Splitting of closed faces failed;endl; 
1153   . . . 
1154
1155 TopoDS_Shape aResult = tool.Result(); 
1156 ~~~~~
1157
1158 @subsubsection occt_shg_4_3_5 Tool for splitting a C0 BSpline 2D or 3D curve to a sequence C1 BSpline curves
1159
1160 The API methods for this tool is a package of methods *ShapeUpgrade::C0BSplineToSequenceOfC1BsplineCurve*, which converts a C0 B-Spline curve into a sequence of C1 B-Spline curves. This method splits a B-Spline at the knots with multiplicities equal to degree, it does not use any tolerance and therefore does not change the geometry of the B-Spline. The method returns True if C0 B-Spline was successfully split, otherwise returns False (if BS is C1 B-Spline). 
1161
1162 @subsubsection occt_shg_4_3_6 Tool for splitting faces
1163
1164 *ShapeUpgrade_ShapeDivideArea* can work with compounds, solids, shells and faces. 
1165 During the work this tool examines each face of a specified shape and if the face area exceeds the specified maximal area, this face is divided. Face splitting is performed in the parametric space of this face. The values of splitting in U and V directions are calculated with the account of translation of the bounding box form parametric space to 3D space. 
1166
1167 Such calculations are necessary to avoid creation of strip faces. In the process of splitting the holes on the initial face are taken into account. After the splitting all new faces are checked by area again and the splitting procedure is repeated for the faces whose area still exceeds the max allowed area. Sharing between faces in the shape is preserved and the resulting shape is of the same type as the source shape. 
1168
1169 An example of using this tool is presented in the figures below: 
1170
1171 @image html /user_guides/shape_healing/images/shape_healing_image003.png "Source Face"
1172 @image latex /user_guides/shape_healing/images/shape_healing_image003.png "Source Face"
1173
1174 @image html /user_guides/shape_healing/images/shape_healing_image004.png "Resulting shape"
1175 @image latex /user_guides/shape_healing/images/shape_healing_image004.png "Resulting shape"
1176
1177
1178 *ShapeUpgrade_ShapeDivideArea* is inherited from the base class *ShapeUpgrade_ShapeDivide* and should be used in the following way: 
1179 *       This class should be initialized on a shape with the help of the constructor or  method *Init()* from the base class. 
1180 *       The maximal allowed area should be specified by the method *MaxArea()*.
1181 *       To produce a splitting use  method Perform from the base class. 
1182 *       The result shape can be obtained with the help the method *Result()*.
1183
1184 ~~~~~
1185 ShapeUpgrade_ShapeDivideArea tool (inputShape); 
1186 tool.MaxArea() = aMaxArea; 
1187 tool.Perform(); 
1188 if(tool.Status(ShapeExtend_DONE)) { 
1189   TopoDS_Shape ResultShape = tool.Result(); 
1190   ShapeFix::SameParameter ( ResultShape, Standard_False ); 
1191
1192 ~~~~~
1193
1194 **Note** that the use of method *ShapeFix::SameParameter* is necessary, otherwise the parameter edges obtained as a result of splitting can be different. 
1195
1196 #### Additional methods
1197
1198 * Class *ShapeUpgrade_FaceDivideArea* inherited from *ShapeUpgrade_FaceDivide* is intended for splitting a face by the maximal area criterion. 
1199 * Class *ShapeUpgrade_SplitSurfaceArea* inherited from *ShapeUpgrade_SplitSurface* calculates the parameters of face splitting in the parametric space. 
1200
1201
1202 @subsection occt_shg_4_4 Customization of shapes
1203
1204 Customization tools are intended for adaptation of shape geometry in compliance with the customer needs. They modify a geometrical object to another one in the shape. 
1205
1206 To implement the necessary shape modification it is enough to initialize the appropriate tool by the shape and desirable parameters and to get the resulting shape. For example for conversion of indirect surfaces in the shape do the following:
1207
1208 ~~~~~
1209 TopoDS_Shape initialShape .. 
1210 TopoDS_Shape resultShape = ShapeCustom::DirectFaces(initialShape); 
1211 ~~~~~
1212
1213 @subsubsection occt_shg_4_4_1 Conversion of indirect surfaces.
1214
1215 ~~~~~
1216 ShapeCustom::DirectFaces 
1217         static TopoDS_Shape DirectFaces(const TopoDS_Shape& S); 
1218 ~~~~~ 
1219
1220 This method provides conversion of indirect elementary surfaces (elementary surfaces with left-handed coordinate systems) in the shape into direct ones. New 2d curves (recomputed for converted surfaces) are added to the same edges being shared by both the resulting shape and the original shape S. 
1221
1222 @subsubsection occt_shg_4_4_2 Shape Scaling 
1223
1224 ~~~~~
1225 ShapeCustom::ScaleShape 
1226         TopoDS_Shape ShapeCustom::ScaleShape(const TopoDS_Shape& S,
1227                 const Standard_Real scale); 
1228 ~~~~~
1229
1230 This method returns a new shape, which is a scaled original shape with a coefficient equal to the specified value of scale. It uses the tool *ShapeCustom_TrsfModification*. 
1231
1232 @subsubsection occt_shg_4_4_3 Conversion of curves and surfaces to BSpline
1233
1234 *ShapeCustom_BSplineRestriction* allows approximation of surfaces, curves and 2D curves with a specified degree, maximum number of segments, 2d tolerance and 3d tolerance. If the approximation result cannot be achieved with the specified continuity, the latter can be reduced. 
1235
1236 The method with all parameters looks as follows:
1237 ~~~~~
1238 ShapeCustom::BsplineRestriction 
1239         TopoDS_Shape ShapeCustom::BSplineRestriction (const TopoDS_Shape& S, 
1240                 const Standard_Real Tol3d, const Standard_Real Tol2d, 
1241                 const Standard_Integer MaxDegree, 
1242                 const Standard_Integer MaxNbSegment, 
1243                 const GeomAbs_Shape Continuity3d, 
1244                 const GeomAbs_Shape Continuity2d, 
1245                 const Standard_Boolean Degree, 
1246                 const Standard_Boolean Rational, 
1247                 const Handle(ShapeCustom_RestrictionParameters)& aParameters) 
1248 ~~~~~
1249                 
1250 It returns a new shape with all surfaces, curves and 2D curves of BSpline/Bezier type or based on them, converted with a degree less than *MaxDegree* or with a number of spans less then *NbMaxSegment* depending on the priority parameter *Degree*. If this parameter is equal to True then *Degree* will be increased to the value *GmaxDegree*, otherwise *NbMaxSegments* will be increased to the value *GmaxSegments*. *GmaxDegree* and *GMaxSegments* are the maximum possible degree and the number of spans correspondingly. These values will be used in cases when an approximation with specified parameters is impossible and either *GmaxDegree* or *GMaxSegments* is selected depending on the priority. 
1251
1252 Note that if approximation is impossible with *GMaxDegree*, even then the number of spans can exceed the specified *GMaxSegment*. Rational specifies whether Rational BSpline/Bezier should be converted into polynomial B-Spline. 
1253
1254 Also note that the continuity of surfaces in the resulting shape can be less than the given value. 
1255
1256 #### Flags
1257
1258 To convert other types of curves and surfaces to BSpline with required parameters it is necessary to use flags from class ShapeCustom_RestrictionParameters, which is just a container of flags. 
1259 The following flags define whether a specified-type geometry has been converted to BSpline with the required parameters: 
1260 * *ConvertPlane,  * 
1261 * *ConvertBezierSurf,   * 
1262 * *ConvertRevolutionSurf* 
1263 * *ConvertExtrusionSurf,.* 
1264 * *ConvertOffsetSurf,* 
1265 * *ConvertCurve3d,* - for conversion of all types of 3D curves. 
1266 * *ConvertOffsetCurv3d,* - for conversion of offset 3D curves. 
1267 * *ConvertCurve2d,* - for conversion of all types of 2D curves. 
1268 * *ConvertOffsetCurv2d,* - for conversion of offset 2D curves. 
1269 * *SegmentSurfaceMode* - defines whether the surface would be approximated within the boundaries of the face lying on this surface. 
1270
1271
1272
1273 @subsubsection occt_shg_4_4_4 Conversion of elementary surfaces into surfaces of revolution 
1274
1275 ~~~~~
1276 ShapeCustom::ConvertToRevolution()
1277         TopoDS_Shape ShapeCustom::ConvertToRevolution(const TopoDS_Shape& S) ; 
1278 ~~~~~
1279
1280 This method returns a new shape with all elementary periodic surfaces converted to *Geom_SurfaceOfRevolution*. It uses the tool *ShapeCustom_ConvertToRevolution*. 
1281
1282 @subsubsection occt_shg_4_4_5 Conversion of elementary surfaces into Bspline surfaces
1283
1284 ~~~~~
1285 ShapeCustom::ConvertToBSpline() 
1286         TopoDS_Shape ShapeCustom::ConvertToBSpline( const TopoDS_Shape& S, 
1287                 const Standard_Boolean extrMode, 
1288                 const Standard_Boolean revolMode, 
1289                 const Standard_Boolean offsetMode); 
1290 ~~~~~           
1291
1292 This method returns a new shape with all surfaces of linear extrusion, revolution and offset surfaces converted according to flags to *Geom_BSplineSurface* (with the same parameterization). It uses the tool *ShapeCustom_ConvertToBSpline*. 
1293
1294 @subsubsection occt_shg_4_4_6 Getting the history of modification of sub-shapes.
1295 If, in addition to the resulting shape, you want to get the history of modification of sub-shapes you should not use the package methods described above and should use your own code instead: 
1296 1. Create a tool that is responsible for the necessary modification. 
1297 2. Create the tool *BRepTools_Modifier* that performs a specified modification in the shape. 
1298 3. To get the history and to keep the assembly structure use the method *ShapeCustom::ApplyModifier*. 
1299
1300
1301 The general calling syntax for scaling is
1302 ~~~~~ 
1303 TopoDS_Shape scaled_shape = ShapeCustom::ScaleShape(shape, scale); 
1304 ~~~~~
1305
1306 Note that scale is a real value. You can refine your mapping process by using additional calls to follow shape mapping subshape by subshape. The following code along with pertinent includes can be used: 
1307
1308 ~~~~~
1309 p_Trsf T; 
1310 Standard_Real scale = 100; // for example! 
1311 T.SetScale (gp_Pnt (0, 0, 0), scale); 
1312 Handle(ShapeCustom_TrsfModification) TM = new 
1313 ShapeCustom_TrsfModification(T); 
1314 TopTools_DataMapOfShapeShape context; 
1315 BRepTools_Modifier MD; 
1316 TopoDS_Shape res = ShapeCustom::ApplyModifier ( 
1317 Shape, TM, context,MD ); 
1318 ~~~~~
1319
1320 The map, called context in our example, contains the history. 
1321 Substitutions are made one by one and all shapes are transformed. 
1322 To determine what happens to a particular subshape, it is possible to use: 
1323
1324 ~~~~~
1325 TopoDS_Shape oneres = context.Find (oneshape); 
1326 //In case there is a doubt, you can also add: 
1327 if (context.IsBound(oneshape)) oneres = context.Find(oneshape); 
1328 //You can also sweep the entire data map by using: 
1329 TopTools_DataMapIteratorOfDataMapOfShapeShape 
1330 //To do this, enter: 
1331 for(TopTools_DataMapIteratorOfDataMapOfShapeShape 
1332 iter(context);iter(more ();iter.next ()) { 
1333   TopoDs_Shape oneshape = iter.key (); 
1334   TopoDs_Shape oneres = iter.value (); 
1335
1336 ~~~~~
1337
1338
1339 @subsubsection occt_shg_4_4_7 Remove internal wires
1340
1341 *ShapeUpgrade_RemoveInternalWires* tool removes internal wires with contour area less than the specified minimal area. It can work with compounds, solids, shells and faces.
1342
1343 If the flag *RemoveFaceMode* is set to TRUE, separate faces or a group of faces with outer wires, which consist only of edges that belong to the removed internal wires, are removed (seam edges are not taken into account). Such faces can be removed only for a sewed shape.
1344
1345 Internal wires can be removed   by the methods *Perform*.  Both methods *Perform* can not be carried out if the class has not been initialized by the shape. In such case the status of *Perform* is set to FAIL . 
1346
1347 The method *Perform* without arguments removes from all faces in the specified shape internal wires whose area is less than the minimal area.
1348
1349 The other method *Perform* has a sequence of shapes as an argument. This sequence can contain faces or wires. 
1350 If the sequence of shapes contains wires, only the internal wires are removed.
1351
1352 If the sequence of shapes contains faces, only the internal wires from these faces are removed. 
1353
1354 *       The status of the performed operation can be obtained using  method *Status()*;
1355 *       The resulting shape can be obtained using  method *GetResult()*.
1356
1357 An example of using this tool is presented in the figures below: 
1358
1359 @image html /user_guides/shape_healing/images/shape_healing_image005.png "Source Face"
1360 @image latex /user_guides/shape_healing/images/shape_healing_image005.png "Source Face"
1361 @image html /user_guides/shape_healing/images/shape_healing_image006.png "Resulting shape"
1362 @image latex /user_guides/shape_healing/images/shape_healing_image006.png "Resulting shape"
1363
1364 After the processing three internal wires with contour area less than the specified minimal area have been removed. One internal face has been removed. The outer wire of this face consists of the edges belonging to the removed internal wires and a seam edge. 
1365 Two other internal faces have not been removed because their outer wires consist not only of edges belonging to the removed wires.
1366
1367 @image html /user_guides/shape_healing/images/shape_healing_image007.png "Source Face"
1368 @image latex /user_guides/shape_healing/images/shape_healing_image007.png "Source Face"
1369
1370 @image html /user_guides/shape_healing/images/shape_healing_image008.png "Resulting shape"
1371 @image latex /user_guides/shape_healing/images/shape_healing_image008.png "Resulting shape"
1372
1373 After the processing six internal wires with contour area less than the specified minimal area have been removed. Six internal faces have been removed. These faces can be united into groups of faces. Each group of faces has an outer wire consisting only of edges belonging to the removed internal wires. Such groups of faces are also removed. 
1374
1375 The example of method application is also given below:
1376
1377 ~~~~~
1378 //Initialisation of the class by shape. 
1379 Handle(ShapeUpgrade_RemoveInternalWires) aTool = new ShapeUpgrade_RemoveInternalWires(inputShape); 
1380 //setting parameters 
1381 aTool-MinArea() = aMinArea; 
1382 aTool-RemoveFaceMode() = aModeRemoveFaces; 
1383  
1384 //when method Perform is carried out on separate shapes. 
1385 aTool-Perform(aSeqShapes); 
1386  
1387 //when method Perform is carried out on whole shape. 
1388 aTool-Perform(); 
1389 //check status set after method Perform 
1390 if(aTool-Status(ShapeExtend_FAIL) { 
1391   cout*Operation failed* ;;\n;; 
1392    return; 
1393
1394
1395 if(aTool-Status(ShapeExtend_DONE1)) { 
1396     const TopTools_SequenceOfShape& aRemovedWires =aTool-RemovedWires(); 
1397      coutaRemovedWires.Length(); internal wires were removed;;\n;; 
1398     
1399   } 
1400
1401   if(aTool-Status(ShapeExtend_DONE2)) { 
1402     const TopTools_SequenceOfShape& aRemovedFaces =aTool-RemovedFaces(); 
1403      coutaRemovedFaces.Length(); small faces were removed;;\n;; 
1404     
1405   }   
1406     //getting result shape 
1407   TopoDS_Shape res = aTool-GetResult(); 
1408 ~~~~~
1409
1410 @subsubsection occt_shg_4_4_8 Conversion of surfaces 
1411
1412 Class ShapeCustom_Surface allows:
1413   * converting BSpline and Bezier surfaces to the analytical form (using method *ConvertToAnalytical())*
1414   * converting closed B-Spline surfaces to periodic ones.(using method *ConvertToPeriodic*)
1415   
1416 To convert surfaces to analytical form this class analyzes the form and the closure of the source surface and defines whether it can be approximated by analytical surface of one of the following types: 
1417 *       *Geom_Plane,*
1418 *       *Geom_SphericalSurface,*
1419 *       *Geom_CylindricalSurface,* 
1420 *       *Geom_ConicalSurface,* 
1421 *       *Geom_ToroidalSurface*.
1422  
1423 The conversion is done only if the new (analytical) surface does not deviate from the source one more than by the given precision. 
1424
1425 ~~~~~
1426 Handle(Geom_Surface) initSurf; 
1427 ShapeCustom_Surface ConvSurf(initSurf); 
1428 //conversion to analytical form 
1429 Handle(Geom_Surface) newSurf  = ConvSurf.ConvertToAnalytical(allowedtol,Standard_False); 
1430 //or conversion to a periodic surface 
1431 Handle(Geom_Surface) newSurf  = ConvSurf.ConvertToPeriodic(Standard_False); 
1432 //getting the maximum deviation of the new surface from the initial surface 
1433 Standard_Real maxdist = ConvSurf.Gap(); 
1434 ~~~~~
1435
1436 @section occt_shg_5_ Auxiliary tools for repairing, analysis and upgrading
1437
1438 @subsection occt_shg_5_1 Tool for rebuilding shapes
1439
1440   Class *ShapeBuild_ReShape* rebuilds a shape by making pre-defined substitutions on some of its components. During the first phase, it records requests to replace or remove some individual shapes. For each shape, the last given request is recorded. Requests may be applied as *Oriented* (i.e. only to an item with the same orientation) or not (the orientation of the replacing shape corresponds to that of the original one). Then these requests may be applied to any shape, which may contain one or more of these individual shapes. 
1441
1442 This tool has a flag for taking the location of shapes into account (for keeping the structure of assemblies) (*ModeConsiderLocation*). If this mode is equal to Standard_True, the shared shapes with locations will be kept. If this mode is equal to Standard_False, some different shapes will be produced from one shape with different locations after rebuilding. By default, this mode is equal to Standard_False. 
1443
1444 To use this tool for the reconstruction of shapes it is necessary to take the following steps:
1445 1. Create this tool and use method *Apply()* for its initialization by the initial shape. Parameter *until* sets the level of shape type and requests are taken into account up to this level only. Sub-shapes of the type standing beyond the *line* set by parameter until will not be rebuilt and no further exploration will be done 
1446 2. Replace or remove sub-shapes of the initial shape. Each sub-shape can be replaced by a shape of the same type or by shape containing shapes of that type only (for example, *TopoDS_Edge* can be replaced by *TopoDS_Edge, TopoDS_Wire* or *TopoDS_Compound* containing *TopoDS_Edges*). If an incompatible shape type is encountered, it is ignored and flag FAIL1 is set in Status. 
1447 For a sub-shape it is recommended to use method *Apply* before methods *Replace* and *Remove*, because the sub-shape has already been changed for the moment by its previous modifications or modification of its sub-shape (for example *TopoDS_Edge* can be changed by a modification of its *TopoDS_Vertex*, etc.). 
1448 3. Use method *Apply* for the initial shape again to get the resulting shape after all modifications have been made.
1449 4. Use method *Apply* to obtain the history of sub-shape modification.
1450
1451 **Note** that in fact class *ShapeBuild_ReShape* is an alias for class *BRepTools_ReShape*. They differ only in queries of statuses in the *ShapeBuild_ReShape* class. 
1452
1453 Let us use the tool to get the result shape after modification of sub-shapes of the initial shape:
1454
1455 ~~~~~ 
1456 TopoDS_Shape initialShape… 
1457 //creation of a rebuilding tool 
1458 Handle(ShapeBuild_ReShape) Context = new ShapeBuild_ReShape. 
1459
1460 //next step is optional. It can be used for keeping 
1461 //the assembly structure. 
1462 Context- ModeConsiderLocation = Standard_True; 
1463
1464 //initialization of this tool by the initial shape 
1465 Context-Apply(initialShape); 
1466 … 
1467 //getting the intermediate result for replacing subshape1 with  
1468 //the modified subshape1. 
1469 TopoDS_Shape tempshape1 = Context-Apply(subshape1); 
1470
1471 //replacing the intermediate shape obtained from subshape1 with the //newsubshape1. 
1472 Context-Replace(tempsubshape1,newsubshape1); 
1473 … 
1474 //for removing the subshape 
1475 TopoDS_Shape tempshape2 = Context-Apply(subshape2); 
1476 Context-Remove(tempsubshape2); 
1477
1478 //getting the result and the history of modification 
1479 TopoDS_Shape resultShape = Context-Apply(initialShape); 
1480
1481 //getting the resulting subshape from the subshape1 of the initial //shape. 
1482 TopoDS_Shape result_subshape1 = Context-Apply(subshape1); 
1483 ~~~~~
1484
1485 @subsection occt_shg_5_2 Status definition
1486
1487 *ShapExtend_Status* is used to report the status after executing some methods that can either fail, do something, or do nothing. The status is a set of flags DONEi, FAILi, any combination of them can be set at the same time. For exploring the status, enumeration is used. 
1488
1489 The values have the following meaning: 
1490 | Value | Meaning |
1491 | :----- | :----------------- |
1492 |*OK,*     |  Nothing is done, everything OK |
1493 |*DONE1,*  |  Something was done, case 1 |
1494 |*DONE8*,  |  Something was done, case 8 |
1495 |*DONE*,   |  Something was done (any of DONE#) |
1496 |*FAIL1*,  |  The method failed, case 1 |
1497 |*FAIL8*,  |  The method failed, case 8 |
1498 |*FAIL*    |  The method failed (any of FAIL# occurred) |
1499
1500
1501 @subsection occt_shg_5_3 Tool representing a wire 
1502 Class *ShapeExtend_WireData* provides a data structure necessary to work with the wire as with an ordered list of edges, and that is required for many algorithms. The advantage of this class is that it allows to work with incorrect wires. 
1503
1504 The object of the class *ShapeExtend_WireData* can be initialized by *TopoDS_Wire* and converted back to *TopoDS_Wire*. 
1505
1506 An edge in the wire is defined by its rank number. Operations of accessing, adding and removing an edge at/to the given rank number are provided. Operations of circular permutation and reversing (both orientations of all edges and the order of edges) are provided on the whole wire as well. 
1507
1508 This class also provides a method to check if the edge in the wire is a seam (if the wire lies on a face). 
1509
1510 Let us remove edges from the wire and define whether it is seam edge 
1511
1512 ~~~~~
1513 TopoDS_Wire ini = .. 
1514 Handle(ShapeExtend_Wire) asewd = new ShapeExtend_Wire(initwire); 
1515 //Removing edge Edge1 from the wire. 
1516
1517 Standard_Integer index_edge1 = asewd->Index(Edge1); 
1518 asewd.Remove(index_edge1); 
1519 //Definition of whether Edge2 is a seam edge 
1520 Standard_Integer index_edge2 = asewd->Index(Edge2); 
1521 asewd->IsSeam(index_edge2); 
1522 ~~~~~
1523
1524
1525 @subsection occt_shg_5_4 Tool for exploring shapes 
1526 Class *ShapeExtend_Explorer* is intended to explore shapes and convert different representations (list, sequence, compound) of complex shapes. It provides tools for: 
1527   * obtaining the type of the shapes in the context of *TopoDS_Compound*, 
1528   * exploring shapes in the context of *TopoDS_Compound*, 
1529   * converting different representations of shapes (list, sequence, compound). 
1530   
1531 @subsection occt_shg_5_5 Tool for attaching messages to objects 
1532 Class *ShapeExtend_MsgRegistrator* attaches messages to objects (generic Transient or shape). The objects of this class are transmitted to the Shape Healing algorithms so that they could collect messages occurred during shape processing. Messages are added to the Maps (stored as a field) that can be used, for instance, by Data Exchange processors to attach those messages to initial file entities. 
1533
1534 Let us send and get a message attached to object:
1535
1536 ~~~~~ 
1537 Handle(ShapeExtend_MsgRegistrator) MessageReg = new ShapeExtend_MsgRegistrator; 
1538 //attaches messages to an object (shape or entity) 
1539 Message_Msg msg.. 
1540 TopoDS_Shape Shape1… 
1541 MessageReg-Send(Shape1,msg,Message_WARNING); 
1542 Handle(Standard_Transient) ent .. 
1543 MessageReg-Send(ent,msg,Message_WARNING); 
1544 //gets messages attached to shape 
1545 const ShapeExtend_DataMapOfShapeListOfMsg& msgmap = 
1546 MessageReg-MapShape(); 
1547 if (msgmap.IsBound (Shape1)) { 
1548  const Message_ListOfMsg &msglist = msgmap.Find (Shape1); 
1549  for (Message_ListIteratorOfListOfMsg iter (msglist); 
1550 iter.More(); iter.Next()) { 
1551        Message_Msg msg = iter.Value(); 
1552  } 
1553     } 
1554 ~~~~~
1555
1556 @subsection occt_shg_5_6 Tools for performance measurement
1557
1558 Classes *MoniTool_Timer* and *MoniTool_TimerSentry* are used for measuring the performance of a current operation or any part of code, and provide the necessary API. Timers are used for debugging and performance optimizing purposes. 
1559
1560 Let us try to use timers in *XSDRAWIGES.cxx* and *IGESBRep_Reader.cxx* to analyse the performance of command *igesbrep*:
1561
1562 ~~~~~
1563 XSDRAWIGES.cxx
1564   ...
1565   #include <MoniTool_Timer.hxx>
1566   #include <MoniTool_TimerSentry.hxx>
1567   ...
1568   MoniTool_Timer::ClearTimers();
1569   ...
1570   MoniTool_TimerSentry MTS("IGES_LoadFile");
1571   Standard_Integer status = Reader.LoadFile(fnom.ToCString());
1572   MTS.Stop();
1573   ...
1574   MoniTool_Timer::DumpTimers(cout);
1575   return;
1576                                                                                 
1577                         
1578 IGESBRep_Reader.cxx
1579   ...
1580   #include <MoniTool_TimerSentry.hxx>
1581   ...
1582   Standard_Integer nb = theModel->NbEntities();
1583   ...
1584   for (Standard_Integer i=1; i<=nb; i++) {
1585     MoniTool_TimerSentry MTS("IGESToBRep_Transfer");
1586     ...
1587     try {
1588       TP.Transfer(ent);
1589       shape = TransferBRep::ShapeResult (theProc,ent);
1590     }
1591     ...
1592   }
1593 ~~~~~
1594
1595 The result of *DumpTimer()* after translation of a file is as follows: 
1596 * TIMER: *IGES_LoadFile* Elapsed: 1.0 sec CPU User:   0.9 sec CPU Sys: 0.0 sec hits: 1  
1597 * TIMER: *IGESToBRep_Transfer* Elapsed: 14.5 sec CPU User:   4.4 sec CPU Sys: 0.1 sec hits: 1311 
1598
1599
1600 @section occt_shg_6 Shape Processing
1601
1602 @subsection occt_shg_6_1 Usage Workflow
1603
1604 The Shape Processing module allows defining and applying the general Shape Processing as a customizable sequence of Shape Healing operators. The customization is implemented via the user-editable resource file, which defines the sequence of operators to be executed and their parameters. 
1605
1606 The Shape Processing functionality is implemented with the help of the *XSAlgo* interface. The main function *XSAlgo_AlgoContainer::ProcessShape()* does shape processing with specified tolerances and returns the resulting shape and associated information in the form of *Transient*. 
1607
1608 This function is used in the following way:
1609
1610 ~~~~~
1611 TopoDS_Shape aShape = …; 
1612 Standard_Real Prec = …, 
1613 Standard_Real MaxTol = …; 
1614 TopoDS_Shape aResult; 
1615 Handle(Standard_Transient) info; 
1616 TopoDS_Shape aResult = XSAlgo::AlgoContainer()-ProcessShape(aShape, 
1617         Prec, MaxTol., *Name of ResourceFile*, *NameSequence*, info ); 
1618 ~~~~~
1619
1620 Let us create a custom sequence of operations: 
1621
1622 1. Create a resource file with the name *ResourceFile*, which includes the following string: 
1623 ~~~~~
1624 NameSequence.exec.op:    MyOper 
1625 ~~~~~
1626 where *MyOper* is the name of operation. 
1627 2. Input a custom parameter for this operation in the resource file, for example: 
1628 ~~~~~
1629 NameSequence.MyOper.Tolerance: 0.01 
1630 ~~~~~
1631 where *Tolerance* is the name of the parameter and 0.01 is its value. 
1632 3. Add the following string into *void ShapeProcess_OperLibrary::Init()*: 
1633 ~~~~~
1634 ShapeProcess::RegisterOperator(;MyOper;, 
1635 new ShapeProcess_UOperator(myfunction)); 
1636 ~~~~~
1637 where *myfunction* is a function which implements the operation. 
1638 4. Create this function in *ShapeProcess_OperLibrary* as follows:
1639 ~~~~~
1640 static Standard_Boolean myfunction (const 
1641                         Handle(ShapeProcess_Context)& context) 
1642
1643         Handle(ShapeProcess_ShapeContext) ctx = 
1644                         Handle(ShapeProcess_ShapeContext)::DownCast(context); 
1645   if(ctx.IsNull()) return Standard_False; 
1646   TopoDS_Shape aShape = ctx->Result(); 
1647   //receive our parameter: 
1648   Standard_Real toler; 
1649   ctx->GetReal(;Tolerance;, toler);
1650 ~~~~~
1651 5. Make the necessary operations with *aShape* using the received value of parameter *Tolerance* from the resource file. 
1652 ~~~~~
1653   return Standard_True; 
1654
1655 ~~~~~
1656 6. Define some operations (with their parameters) *MyOper1, MyOper2, MyOper3*, etc. and describe the corresponding functions in *ShapeProcess_OperLibrary*. 
1657 7. Perform the required sequence using the specified name of operations and values of parameters in the resource file. 
1658
1659 For example: input of the following string:
1660 ~~~~~
1661 NameSequence.exec.op:    MyOper1,MyOper3 
1662 ~~~~~
1663 means that the corresponding functions from *ShapeProcess_OperLibrary* will be performed with the original shape *(aShape)* using parameters defined for *MyOper1* and *MyOper3* in the resource file. 
1664
1665 It is necessary to note that these operations will be performed step by step and the result obtained after performing the first operation will be used as the initial shape for the second operation. 
1666
1667 @subsection occt_shg_6_2 Operators
1668
1669 ### DirectFaces 
1670 This operator sets all faces based on indirect surfaces, defined with left-handed coordinate systems as direct faces. This concerns surfaces defined by Axis Placement (Cylinders, etc). Such Axis Placement may be indirect, which is allowed in Cascade, but not allowed in some other systems. This operator reverses indirect placements and recomputes PCurves accordingly. 
1671
1672 ### SameParameter
1673 This operator is required after calling some other operators, according to the computations they do. Its call is explicit, so each call can be removed according to the operators, which are either called or not afterwards. This mainly concerns splitting operators that can split edges. 
1674
1675 The operator applies the computation *SameParameter* which ensures that various representations of each edge (its 3d curve, the pcurve on each of the faces on which it lies) give the same 3D point for the same parameter, within a given tolerance.  
1676 * For each edge coded as *same parameter*, deviation of curve representation is computed and if the edge tolerance is less than that deviation, the tolerance is increased so that it satisfies the deviation. No geometry modification, only an increase of tolerance is possible.  
1677 * For each edge coded as *not same parameter* the deviation is computed as in the first case. Then an attempt is made to achieve the edge equality to *same parameter* by means of modification of 2d curves. If the deviation of this modified edge is less than the original deviation then this edge is returned, otherwise the original edge (with non-modified 2d curves) is returned with an increased (if necessary) tolerance.  Computation is done by call to the standard algorithm *BRepLib::SameParameter*. 
1678
1679 This operator can be called with the following parameters: 
1680         * *Boolean : Force* (optional) - if True, encodes all edges as *not same parameter* then runs the computation. Else, the computation is done only for those edges already coded as *not same parameter*. 
1681         * *Real : Tolerance3d* (optional) - if not defined, the local tolerance of each edge is taken for its own computation. Else, this parameter gives the global tolerance for the whole shape.
1682         
1683 ### BSplineRestriction
1684
1685 This operator is used for conversion of surfaces, curves 2d curves to BSpline surfaces with a specified degree and a specified number of spans. It performs approximations on surfaces, curves and 2d curves with a specified degree, maximum number of segments, 2d tolerance, 3d tolerance. The specified continuity can be reduced if the approximation with a specified continuity was not done successfully. 
1686
1687 This operator can be called with the following parameters: 
1688 * *Boolean : SurfaceMode* allows considering the surfaces; 
1689 * *Boolean : Curve3dMode*  allows considering the 3d curves; 
1690 * *Boolean : Curve2dMode* allows considering the 2d curves; 
1691 * *Real : Tolerance3d* defines 3d tolerance to be used in computation; 
1692 * *Real : Tolerance2d* defines 2d tolerance to be used when computing 2d curves; 
1693 * *GeomAbs_Shape (C0 G1 C1 G2 C2 CN) : Continuity3d* is the continuity required in 2d; 
1694 * *GeomAbs_Shape (C0 G1 C1 G2 C2 CN) : Continuity2d* is the continuity required in 3d; 
1695 * *Integer : RequiredDegree* gives the required degree;
1696 * *Integer : RequiredNbSegments* gives the required number of segments;
1697 * *Boolean : PreferDegree* if true, *RequiredDegree* has a priority, else *RequiredNbSegments* has a priority;
1698 * *Boolean : RationalToPolynomial*  serves for conversion of BSplines to polynomial form; 
1699 * *Integer : MaxDegree* gives the maximum allowed Degree, if *RequiredDegree* cannot be reached; 
1700 * *Integer : MaxNbSegments* gives the maximum allowed NbSegments, if *RequiredNbSegments* cannot be reached.
1701  
1702 The following flags allow managing the conversion of special types of curves or surfaces, in addition to BSpline. They are controlled by *SurfaceMode, Curve3dMode* or *Curve2dMode* respectively; by default, only BSplines and Bezier Geometries are considered:
1703 * *Boolean : OffsetSurfaceMode*  
1704 * *Boolean : LinearExtrusionMode*  
1705 * *Boolean : RevolutionMode*  
1706 * *Boolean : OffsetCurve3dMode* 
1707 * *Boolean : OffsetCurve2dMode* 
1708 * *Boolean : PlaneMode* 
1709 * *Boolean : BezierMode* 
1710 * *Boolean : ConvCurve3dMode* 
1711 * *Boolean : ConvCurve2dMode* 
1712
1713 For each of the Mode parameters listed above, if it is True, the specified geometry is converted to BSpline, otherwise only its basic geometry is checked and converted (if necessary) keeping the original type of geometry (revolution, offset, etc). 
1714
1715 * *Boolean :SegmentSurfaceMode* has effect only for Bsplines and Bezier surfaces. When False a surface will be replaced by a Trimmed Surface, else new geometry will be created by splitting the original Bspline or Bezier surface. 
1716
1717 ### ElementaryToRevolution
1718
1719 This operator converts elementary periodic surfaces to SurfaceOfRevolution. 
1720
1721 ### SplitAngle
1722
1723 This operator splits surfaces of revolution, cylindrical, toroidal, conical, spherical surfaces in the given shape so that each resulting segment covers not more than the defined number of degrees. 
1724
1725 It can be called with the following parameters: 
1726 * *Real : Angle* - the maximum allowed angle for resulting faces; 
1727 *  *Real : MaxTolerance* - the maximum tolerance used in computations.
1728  
1729 ### SurfaceToBSpline
1730 This operator converts some specific types of Surfaces, to BSpline (according to parameters). 
1731 It can be called with the following parameters: 
1732 * *Boolean : LinearExtrusionMode* allows converting surfaces of Linear Extrusion; 
1733 * *Boolean : RevolutionMode* allows converting surfaces of Revolution; 
1734 * *Boolean : OffsetMode* allows converting Offset Surfaces 
1735
1736 ### ToBezier
1737
1738 This operator is used for data supported as Bezier only  and converts various types of geometries to Bezier. It can be called with the following parameters used in computation of conversion :  
1739 * *Boolean : SurfaceMode*  
1740 * *Boolean : Curve3dMode*  
1741 * *Boolean : Curve2dMode*  
1742 * *Real : MaxTolerance* 
1743 * *Boolean : SegmentSurfaceMode* (default is True) has effect only for Bsplines and Bezier surfaces. When False a surface will be replaced by a Trimmed Surface, else new geometry will be created by splitting the original Bspline or Bezier surface. 
1744
1745 The following parameters are controlled by *SurfaceMode, Curve3dMode* or *Curve2dMode* (according to the case): 
1746 * *Boolean : Line3dMode*  
1747 * *Boolean : Circle3dMode*  
1748 * *Boolean : Conic3dMode*  
1749 * *Boolean : PlaneMode*  
1750 * *Boolean : RevolutionMode*  
1751 * *Boolean : ExtrusionMode*  
1752 * *Boolean : BSplineMode* 
1753
1754 ### SplitContinuity
1755 This operator splits a shape in order to have each geometry (surface, curve 3d, curve 2d) correspond the given criterion of continuity. It can be called with the following parameters: 
1756 * *Real : Tolerance3d*  
1757 * *Integer (GeomAbs_Shape ) : CurveContinuity*  
1758 * *Integer (GeomAbs_Shape ) : SurfaceContinuity*  
1759 * *Real : MaxTolerance* 
1760
1761 Because of algorithmic limitations in the operator *BSplineRestriction* (in some particular cases, this operator can produce unexpected C0 geometry), if *SplitContinuity* is called, it is recommended to call it after *BSplineRestriction*. 
1762 Continuity Values will be set as *GeomAbs_Shape* (i.e. C0 G1 C1 G2 C2 CN) besides direct integer values (resp. 0 1 2 3 4 5). 
1763
1764 ### SplitClosedFaces
1765 This operator splits faces, which are closed even if they are not revolutionary or cylindrical, conical, spherical, toroidal. This corresponds to BSpline or Bezier surfaces which can be closed (whether periodic or not), hence they have a seam edge.  As a result, no more seam edges remain. The number of points allows to control the minimum count of faces to be produced per input closed face. 
1766
1767 This operator can be called with the following parameters: 
1768 * *Integer : NbSplitPoints* gives the number of points to use for splitting (the number of intervals produced is *NbSplitPoints+1*); 
1769 * *Real : CloseTolerance* tolerance used to determine if a face is closed;  
1770 * *Real : MaxTolerance* is used in the computation of splitting.
1771  
1772 ### FixGaps
1773
1774 This operator must be called when *FixFaceSize* and/or *DropSmallEdges* are called. Using Surface Healing may require an additional call to *BSplineRestriction* to ensure that modified geometries meet the requirements for BSpline. 
1775 This operators repairs geometries which contain gaps between edges in wires (always performed) or gaps on faces, controlled by parameter *SurfaceMode*, Gaps on Faces are fixed by using algorithms of Surface Healing 
1776 This operator can be called with the following parameters: 
1777 * *Real : Tolerance3d* sets the tolerance to reach in 3d. If a gap is less than this value, it is not fixed. 
1778 * *Boolean : SurfaceMode* sets the mode of fixing gaps between edges and faces (yes/no) ;
1779 * *Integer : SurfaceAddSpans* sets the number of spans to add to the surface in order to fix gaps ;
1780 * *GeomAbs_Shape (C0 G1 C1 G2 C2 CN) : SurfaceContinuity* sets the minimal continuity of a resulting surface ;
1781 * *Integer : NbIterations* sets the number of iterations 
1782 * *Real : Beta* sets the elasticity coefficient for modifying a surface [1-1000] ;
1783 * *Reals : Coeff1 to Coeff6* sets energy coefficients for modifying a surface [0-10000] ;
1784 * *Real : MaxDeflection*  sets maximal deflection of surface from an old position. 
1785
1786 This operator may change the original geometry. In addition, it is CPU consuming, and it may fail in some cases.  Also **FixGaps** can help only when there are gaps obtained as a result of removal of small edges that can be removed by **DropSmallEdges** or **FixFaceSize**. 
1787
1788 ### FixFaceSize
1789 This operator  removes faces, which are small in all directions (spot face) or small in one direction (strip face). It can be called with the parameter *Real : Tolerance*, which sets the minimal dimension, which is used to consider a face, is small enough to be removed. 
1790
1791 ### DropSmallEdges
1792 This operator drops edges in a wire, and merges them with adjacent edges, when they are smaller than the given value (*Tolerance3d*) and when the topology allows such merging (i.e. same adjacent faces for each of the merged edges). Free (non-shared by adjacent faces) small edges can be also removed in case if they share the same vertex Parameters. 
1793
1794 It can be called with the parameter *Real : Tolerance3d*, which sets the dimension used to determine if an edge is small. 
1795
1796 ### FixShape
1797
1798 This operator may be added for fixing invalid shapes. It performs various checks and fixes, according to the modes listed hereafter. Management of a set of fixes can be performed by flags as follows: 
1799 * if the flag for a fixing tool is set to 0 , it is not performed;
1800 * if set to 1 , it is performed in any case;
1801 * if not set, or set to -1 , for each shape to be applied on, a check is done to evaluate whether a fix is needed. The fix is performed if the check is positive.
1802  
1803 By default, the flags are not set, the checks are carried out each individual shape. 
1804
1805 This operator can be called with the following parameters: 
1806 * *Real : Tolerance3d* sets basic tolerance used for fixing; 
1807 * *Real : MaxTolerance3d* sets maximum allowed value for the resulting tolerance; 
1808 * *Real : MinTolerance3d* sets minimum allowed value for the resulting tolerance. 
1809 * *Boolean : FixFreeShellMode*
1810 * *Boolean : FixFreeFaceMode*  
1811 * *Boolean : FixFreeWireMode*  
1812 * *Boolean : FixSameParameterMode*
1813 * *Boolean : FixSolidMode*
1814 * *Boolean : FixShellMode*
1815 * *Boolean : FixFaceMode*
1816 * *Boolean : FixWireMode*
1817 * *Boolean : FixOrientationMode*
1818 * *Boolean : FixMissingSeamMode*
1819 * *Boolean : FixSmallAreaWireMode* 
1820 * *Boolean (not checked) : ModifyTopologyMode* specifies the mode for modifying topology. Should be False (default) for shapes with shells and can be True for free faces. 
1821 * *Boolean (not checked) : ModifyGeometryMode* specifies the mode for modifying geometry. Should be False if geometry is to be kept and True if it can be modified. 
1822 * *Boolean (not checked) : ClosedWireMode*  specifies the mode for wires. Should be True for wires on faces and False for free wires. 
1823 * *Boolean (not checked) : PreferencePCurveMode (not used)* specifies the preference of 3d or 2d representations for an edge 
1824 * *Boolean : FixReorderMode*  
1825 * *Boolean : FixSmallMode*  
1826 * *Boolean : FixConnectedMode*  
1827 * *Boolean : FixEdgeCurvesMode*  
1828 * *Boolean : FixDegeneratedMode*  
1829 * *Boolean : FixLackingMode*  
1830 * *Boolean : FixSelfIntersectionMode*  
1831 * *Boolean : FixGaps3dMode*  
1832 * *Boolean : FixGaps2dMode*  
1833 * *Boolean : FixReversed2dMode*  
1834 * *Boolean : FixRemovePCurveMode*  
1835 * *Boolean : FixRemoveCurve3dMode*  
1836 * *Boolean : FixAddPCurveMode*  
1837 * *Boolean : FixAddCurve3dMode*  
1838 * *Boolean : FixSeamMode* 
1839 * *Boolean : FixShiftedMode* 
1840 * *Boolean : FixEdgeSameParameterMode*
1841 * *Boolean : FixSelfIntersectingEdgeMode* 
1842 * *Boolean : FixIntersectingEdgesMode*  
1843 * *Boolean : FixNonAdjacentIntersectingEdgesMode* 
1844
1845 ### SplitClosedEdges
1846 This operator handles closed edges i.e. edges with one vertex. Such edges are not supported in some receiving systems. This operator  splits topologically closed edges (i.e. edges having one vertex) into two edges. Degenerated edges and edges with a size of less than Tolerance are not processed. 
1847
1848 @section occt_shg_7 Messaging mechanism
1849
1850 Various messages about modification, warnings and fails can be generated in the process of shape fixing or upgrade. The messaging mechanism allows generating messages, which will be sent to the chosen target medium  a file or the screen. The messages may report failures and/or warnings or provide information on events such as analysis, fixing or upgrade of shapes. 
1851
1852 @subsection occt_shg_7_1  Message Gravity
1853 Enumeration *Message_Gravity* is used for defining message gravity. 
1854 It provides the following message statuses: 
1855 * *Message_FAIL* - the message reports a fail;
1856 * *Message_WARNING*  - the message reports a warning;
1857 * *Message_INFO* - the message supplies information. 
1858
1859 @subsection occt_shg_7_2 Tool for loading a message file into memory
1860 Class *Message_MsgFile* allows defining messages by loading a custom message file into memory. It is necessary to create a custom message file before loading it into memory, as its path will be used as the argument to load it. Each message in the message file is identified by a key. The user can get the text content of the message by specifying the message key. 
1861
1862 ### Format of the message file
1863
1864 The message file is an ASCII file, which defines a set of messages. Each line of the file must have a length of less than 255 characters.  
1865 All lines in the file starting with the exclamation sign (perhaps preceded by spaces and/or tabs) are considered as comments and are ignored. 
1866 A message file may contain several messages. Each message is identified by its key (string). 
1867 Each line in the file starting with the *dot* character (perhaps preceded by spaces and/or tabs) defines the key. The key is a string starting with a symbol placed after the dot and ending with the symbol preceding the ending of the newline character *\n*. 
1868 All the lines in the file after the key and before the next keyword (and which are not comments) define the message for that key. If the message consists of several lines, the message string will contain newline symbols *\n* between each line (but not at the end). 
1869 The following example illustrates the structure of a message file: 
1870
1871 ~~~~~
1872 !This is a sample message file 
1873 !------------------------------ 
1874 !Messages for ShapeAnalysis package 
1875
1876 .SampleKeyword 
1877 Your message string goes here 
1878
1879 !... 
1880
1881 !End of message file 
1882 ~~~~~
1883
1884 ### Loading the message file
1885
1886 A custom file can be loaded into memory using the method *Message_MsgFile::LoadFile*, taking as an argument the path to your file as in the example below: 
1887 ~~~~~
1888 Standard_CString MsgFilePath = ;(path)/sample.file;; 
1889 Message_MsgFile::LoadFile (MsgFilePath); 
1890 ~~~~~
1891
1892 @subsection occt_shg_7_3 Tool for managing filling messages 
1893
1894 The class *Message_Msg* allows using the message file loaded as a template. This class provides a tool for preparing the message, filling it with parameters, storing and outputting to the default trace file. 
1895 A message is created from a key: this key identifies the message to be created in the message file. The text of the message is taken from the loaded message file (class *Message_MsgFile* is used). 
1896 The text of the message can contain places for parameters, which are to be filled by the proper values when the message is prepared. These parameters can be of the following types: 
1897 * string - coded in the text as *%s*, 
1898 * integer - coded in the text as *%d*, 
1899 * real - coded in the text as *%f*. 
1900 The parameter fields are filled by the message text by calling the corresponding methods *AddInteger, AddReal* and *AddString*. Both the original text of the message and the input text with substituted parameters are stored in the object. The prepared and filled message can be output to the default trace file. The text of the message (either original or filled) can be also obtained. 
1901 ~~~~~
1902 Message_Msg msg01 (;SampleKeyword;); 
1903 //Creates the message msg01, identified in the file by the keyword SampleKeyword 
1904 msg1.AddInteger (73); 
1905 msg1.AddString (;SampleFile;); 
1906 //fills out the code areas 
1907 ~~~~~
1908
1909 @subsection occt_shg_7_4 Tool for managing trace files
1910
1911 Class *Message_TraceFile* is intended to manage the trace file (or stream) for outputting messages and the current trace level. Trace level is an integer number, which is used when messages are sent. Generally, 0 means minimum,  0 various levels. If the current trace level is lower than the level of the message it is not output to the trace file. The trace level is to be managed and used by the users. 
1912 There are two ways of using trace files: 
1913 * define an object of *Message_TraceFile*, with its own definition (file name or cout, trace level), and use it where it is defined, 
1914 * use the default trace file (file name or cout, trace level), usable from anywhere. 
1915 Use the constructor method to define the target file and the level of the messages as in the example below: 
1916 ~~~~~
1917 Message_TraceFile myTF 
1918         (tracelevel, *tracefile.log*, Standard_False); 
1919 ~~~~~
1920 The parameters are as follows:  
1921 * *tracelevel* is a Standard_Integer and modifies the level of messages. It has the following values and semantics: 
1922         + 0: gives general information such as the start and end of process;
1923         + 1: gives exceptions raised and fail messages;
1924         + 2: gives the same information as 1 plus warning messages.
1925 * *filename* is the string containing the path to the log file. 
1926 The Boolean set to False will rewrite the existing file. When set to True, new messages will be appended to the existing file. 
1927
1928 A new default log file can be added using  method *SetDefault* with the same arguments as in the constructor. 
1929 The default trace level can be changed by using method *SetDefLevel*. In this way, the information received in the log file is modified. 
1930 It is possible to close the log file and set the default trace output to the screen display instead of the log file using the method *SetDefault* without any arguments. 
1931