]> SALOME platform Git repositories - modules/geom.git/blob - src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx
Salome HOME
Join modifications from BR_Dev_For_4_0 tag V4_1_1.
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IMeasureOperations.cxx
1 // Copyright (C) 2005  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
3 //
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
8 //
9 // This library is distributed in the hope that it will be useful
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 // Lesser General Public License for more details.
13 //
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 //
18 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 //
20
21 #include <Standard_Stream.hxx>
22
23 #include <GEOMImpl_IMeasureOperations.hxx>
24
25 #include <GEOMImpl_Types.hxx>
26 #include <GEOMImpl_MeasureDriver.hxx>
27 #include <GEOMImpl_IMeasure.hxx>
28
29 #include <GEOMAlgo_ShapeInfo.hxx>
30 #include <GEOMAlgo_ShapeInfoFiller.hxx>
31
32 #include <GEOM_Function.hxx>
33 #include <GEOM_PythonDump.hxx>
34
35 #include <utilities.h>
36 #include <OpUtil.hxx>
37 #include <Utils_ExceptHandlers.hxx>
38
39 // OCCT Includes
40 #include <TFunction_DriverTable.hxx>
41 #include <TFunction_Driver.hxx>
42 #include <TFunction_Logbook.hxx>
43 #include <TDF_Tool.hxx>
44
45 #include <BRep_Tool.hxx>
46 #include <BRepAdaptor_Surface.hxx>
47 #include <BRepBndLib.hxx>
48 #include <BRepCheck.hxx>
49 #include <BRepCheck_Result.hxx>
50 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
51 #include <BRepExtrema_DistShapeShape.hxx>
52 #include <BRepGProp.hxx>
53 #include <BRepTools.hxx>
54
55 #include <Bnd_Box.hxx>
56
57 #include <GProp_GProps.hxx>
58 #include <GProp_PrincipalProps.hxx>
59
60 #include <TopAbs.hxx>
61 #include <TopoDS.hxx>
62 #include <TopoDS_Edge.hxx>
63 #include <TopoDS_Face.hxx>
64 #include <TopoDS_Shape.hxx>
65 #include <TopoDS_Vertex.hxx>
66 #include <TopoDS_Iterator.hxx>
67 #include <TopExp_Explorer.hxx>
68 #include <TopTools_MapOfShape.hxx>
69 #include <TopTools_ListOfShape.hxx>
70 #include <TopTools_ListIteratorOfListOfShape.hxx>
71
72 #include <GeomAbs_SurfaceType.hxx>
73 #include <Geom_Surface.hxx>
74 #include <Geom_Plane.hxx>
75 #include <Geom_SphericalSurface.hxx>
76 #include <Geom_CylindricalSurface.hxx>
77 #include <Geom_ToroidalSurface.hxx>
78 #include <Geom_ConicalSurface.hxx>
79 #include <Geom_SurfaceOfLinearExtrusion.hxx>
80 #include <Geom_SurfaceOfRevolution.hxx>
81 #include <Geom_BezierSurface.hxx>
82 #include <Geom_BSplineSurface.hxx>
83 #include <Geom_RectangularTrimmedSurface.hxx>
84 #include <Geom_OffsetSurface.hxx>
85 #include <Geom_Line.hxx>
86
87 #include <gp_Pln.hxx>
88 #include <gp_Lin.hxx>
89
90 #include <Standard_Failure.hxx>
91 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
92
93 //=============================================================================
94 /*!
95  *  Constructor
96  */
97 //=============================================================================
98 GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine, int theDocID)
99 : GEOM_IOperations(theEngine, theDocID)
100 {
101   MESSAGE("GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations");
102 }
103
104 //=============================================================================
105 /*!
106  *  Destructor
107  */
108 //=============================================================================
109 GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations()
110 {
111   MESSAGE("GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations");
112 }
113
114 //=============================================================================
115 /*! Get kind and parameters of the given shape.
116  */
117 //=============================================================================
118 GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
119                              (Handle(GEOM_Object) theShape,
120                               Handle(TColStd_HSequenceOfInteger)& theIntegers,
121                               Handle(TColStd_HSequenceOfReal)&    theDoubles)
122 {
123   SetErrorCode(KO);
124   ShapeKind aKind = SK_NO_SHAPE;
125
126   if (theIntegers.IsNull()) theIntegers = new TColStd_HSequenceOfInteger;
127   else                      theIntegers->Clear();
128
129   if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
130   else                     theDoubles->Clear();
131
132   if (theShape.IsNull())
133     return aKind;
134
135   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
136   if (aRefShape.IsNull()) return aKind;
137
138   TopoDS_Shape aShape = aRefShape->GetValue();
139   if (aShape.IsNull()) return aKind;
140
141   // Call algorithm
142   GEOMAlgo_ShapeInfoFiller aSF;
143   aSF.SetShape(aShape);
144   aSF.Perform();
145   Standard_Integer iErr = aSF.ErrorStatus();
146   if (iErr) {
147     SetErrorCode("Error in GEOMAlgo_ShapeInfoFiller");
148     return SK_NO_SHAPE;
149   }
150   const GEOMAlgo_ShapeInfo& anInfo = aSF.Info();
151
152   // Interprete results
153   TopAbs_ShapeEnum aType = anInfo.Type();
154   switch (aType)
155   {
156   case TopAbs_COMPOUND:
157   case TopAbs_COMPSOLID:
158     {
159       // (+) geompy.kind.COMPOUND     nb_solids nb_faces nb_edges nb_vertices
160       // (+) geompy.kind.COMPSOLID    nb_solids nb_faces nb_edges nb_vertices
161       // ??? "nb_faces" - all faces or only 'standalone' faces?
162       if (aType == TopAbs_COMPOUND)
163         aKind = SK_COMPOUND;
164       else
165         aKind = SK_COMPSOLID;
166
167       //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPOUND));
168       //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPSOLID));
169       theIntegers->Append(anInfo.NbSubShapes(TopAbs_SOLID));
170       theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
171       theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
172       theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
173     }
174     break;
175
176   case TopAbs_SHELL:
177     {
178       // (+) geompy.kind.SHELL  geompy.info.closed   nb_faces nb_edges nb_vertices
179       // (+) geompy.kind.SHELL  geompy.info.unclosed nb_faces nb_edges nb_vertices
180       aKind = SK_SHELL;
181
182       theIntegers->Append((int)anInfo.KindOfClosed());
183
184       theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
185       theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
186       theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
187     }
188     break;
189
190   case TopAbs_WIRE:
191     {
192       // (+) geompy.kind.WIRE  geompy.info.closed   nb_edges nb_vertices
193       // (+) geompy.kind.WIRE  geompy.info.unclosed nb_edges nb_vertices
194       aKind = SK_WIRE;
195
196       theIntegers->Append((int)anInfo.KindOfClosed());
197
198       theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
199       theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
200     }
201     break;
202
203   case TopAbs_SOLID:
204     {
205       aKind = SK_SOLID;
206
207       GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
208       switch (aKN)
209       {
210       case GEOMAlgo_KN_SPHERE:
211         // (+) geompy.kind.SPHERE  xc yc zc  R
212         {
213           aKind = SK_SPHERE;
214
215           gp_Pnt aC = anInfo.Location();
216           theDoubles->Append(aC.X());
217           theDoubles->Append(aC.Y());
218           theDoubles->Append(aC.Z());
219
220           theDoubles->Append(anInfo.Radius1());
221         }
222         break;
223       case GEOMAlgo_KN_CYLINDER:
224         // (+) geompy.kind.CYLINDER  xb yb zb  dx dy dz  R  H
225         {
226           aKind = SK_CYLINDER;
227
228           gp_Pnt aC = anInfo.Location();
229           theDoubles->Append(aC.X());
230           theDoubles->Append(aC.Y());
231           theDoubles->Append(aC.Z());
232
233           gp_Ax3 anAx3 = anInfo.Position();
234           gp_Dir aD = anAx3.Direction();
235           theDoubles->Append(aD.X());
236           theDoubles->Append(aD.Y());
237           theDoubles->Append(aD.Z());
238
239           theDoubles->Append(anInfo.Radius1());
240           theDoubles->Append(anInfo.Height());
241         }
242         break;
243       case GEOMAlgo_KN_BOX:
244         // (+) geompy.kind.BOX  xc yc zc  ax ay az
245         {
246           aKind = SK_BOX;
247
248           gp_Pnt aC = anInfo.Location();
249           theDoubles->Append(aC.X());
250           theDoubles->Append(aC.Y());
251           theDoubles->Append(aC.Z());
252
253           gp_Ax3 anAx3 = anInfo.Position();
254           gp_Dir aD = anAx3.Direction();
255           gp_Dir aX = anAx3.XDirection();
256
257           // ax ay az
258           if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
259               aX.IsParallel(gp::DX(), Precision::Angular())) {
260             theDoubles->Append(anInfo.Length()); // ax'
261             theDoubles->Append(anInfo.Width());  // ay'
262             theDoubles->Append(anInfo.Height()); // az'
263           }
264           else if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
265                    aX.IsParallel(gp::DY(), Precision::Angular())) {
266             theDoubles->Append(anInfo.Width());  // ay'
267             theDoubles->Append(anInfo.Length()); // ax'
268             theDoubles->Append(anInfo.Height()); // az'
269           }
270           else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
271                    aX.IsParallel(gp::DZ(), Precision::Angular())) {
272             theDoubles->Append(anInfo.Height()); // az'
273             theDoubles->Append(anInfo.Width());  // ay'
274             theDoubles->Append(anInfo.Length()); // ax'
275           }
276           else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
277                    aX.IsParallel(gp::DY(), Precision::Angular())) {
278             theDoubles->Append(anInfo.Height()); // az'
279             theDoubles->Append(anInfo.Length()); // ax'
280             theDoubles->Append(anInfo.Width());  // ay'
281           }
282           else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
283                    aX.IsParallel(gp::DZ(), Precision::Angular())) {
284             theDoubles->Append(anInfo.Width());  // ay'
285             theDoubles->Append(anInfo.Height()); // az'
286             theDoubles->Append(anInfo.Length()); // ax'
287           }
288           else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
289                    aX.IsParallel(gp::DX(), Precision::Angular())) {
290             theDoubles->Append(anInfo.Length()); // ax'
291             theDoubles->Append(anInfo.Height()); // az'
292             theDoubles->Append(anInfo.Width());  // ay'
293           }
294           else {
295             // (+) geompy.kind.ROTATED_BOX  xo yo zo  zx zy zz  xx xy xz  ax ay az
296             aKind = SK_ROTATED_BOX;
297
298             // Direction and XDirection
299             theDoubles->Append(aD.X());
300             theDoubles->Append(aD.Y());
301             theDoubles->Append(aD.Z());
302
303             theDoubles->Append(aX.X());
304             theDoubles->Append(aX.Y());
305             theDoubles->Append(aX.Z());
306
307             // ax ay az
308             theDoubles->Append(anInfo.Length());
309             theDoubles->Append(anInfo.Width());
310             theDoubles->Append(anInfo.Height());
311           }
312         }
313         break;
314       case GEOMAlgo_KN_TORUS:
315         // (+) geompy.kind.TORUS  xc yc zc  dx dy dz  R_1 R_2
316         {
317           aKind = SK_TORUS;
318
319           gp_Pnt aO = anInfo.Location();
320           theDoubles->Append(aO.X());
321           theDoubles->Append(aO.Y());
322           theDoubles->Append(aO.Z());
323
324           gp_Ax3 anAx3 = anInfo.Position();
325           gp_Dir aD = anAx3.Direction();
326           theDoubles->Append(aD.X());
327           theDoubles->Append(aD.Y());
328           theDoubles->Append(aD.Z());
329
330           theDoubles->Append(anInfo.Radius1());
331           theDoubles->Append(anInfo.Radius2());
332         }
333         break;
334       case GEOMAlgo_KN_CONE:
335         // (+) geompy.kind.CONE  xb yb zb  dx dy dz  R_1 R_2  H
336         {
337           aKind = SK_CONE;
338
339           gp_Pnt aO = anInfo.Location();
340           theDoubles->Append(aO.X());
341           theDoubles->Append(aO.Y());
342           theDoubles->Append(aO.Z());
343
344           gp_Ax3 anAx3 = anInfo.Position();
345           gp_Dir aD = anAx3.Direction();
346           theDoubles->Append(aD.X());
347           theDoubles->Append(aD.Y());
348           theDoubles->Append(aD.Z());
349
350           theDoubles->Append(anInfo.Radius1());
351           theDoubles->Append(anInfo.Radius2());
352           theDoubles->Append(anInfo.Height());
353         }
354         break;
355       case GEOMAlgo_KN_POLYHEDRON:
356         // (+) geompy.kind.POLYHEDRON  nb_faces nb_edges nb_vertices
357         {
358           aKind = SK_POLYHEDRON;
359
360           theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
361           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
362           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
363         }
364         break;
365       default:
366         // (+) geompy.kind.SOLID  nb_faces nb_edges nb_vertices
367         {
368           theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
369           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
370           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
371         }
372       }
373     }
374     break;
375
376   case TopAbs_FACE:
377     {
378       aKind = SK_FACE;
379
380       GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
381       switch (aKN) {
382       case GEOMAlgo_KN_SPHERE:
383         // (+) geompy.kind.SPHERE2D  xc yc zc  R
384         {
385           aKind = SK_SPHERE2D;
386
387           gp_Pnt aC = anInfo.Location();
388           theDoubles->Append(aC.X());
389           theDoubles->Append(aC.Y());
390           theDoubles->Append(aC.Z());
391
392           theDoubles->Append(anInfo.Radius1());
393         }
394         break;
395       case GEOMAlgo_KN_CYLINDER:
396         // (+) geompy.kind.CYLINDER2D  xb yb zb  dx dy dz  R  H
397         {
398           aKind = SK_CYLINDER2D;
399
400           gp_Pnt aO = anInfo.Location();
401           theDoubles->Append(aO.X());
402           theDoubles->Append(aO.Y());
403           theDoubles->Append(aO.Z());
404
405           gp_Ax3 anAx3 = anInfo.Position();
406           gp_Dir aD = anAx3.Direction();
407           theDoubles->Append(aD.X());
408           theDoubles->Append(aD.Y());
409           theDoubles->Append(aD.Z());
410
411           theDoubles->Append(anInfo.Radius1());
412           theDoubles->Append(anInfo.Height());
413         }
414         break;
415       case GEOMAlgo_KN_TORUS:
416         // (+) geompy.kind.TORUS2D  xc yc zc  dx dy dz  R_1 R_2
417         {
418           aKind = SK_TORUS2D;
419
420           gp_Pnt aO = anInfo.Location();
421           theDoubles->Append(aO.X());
422           theDoubles->Append(aO.Y());
423           theDoubles->Append(aO.Z());
424
425           gp_Ax3 anAx3 = anInfo.Position();
426           gp_Dir aD = anAx3.Direction();
427           theDoubles->Append(aD.X());
428           theDoubles->Append(aD.Y());
429           theDoubles->Append(aD.Z());
430
431           theDoubles->Append(anInfo.Radius1());
432           theDoubles->Append(anInfo.Radius2());
433         }
434         break;
435       case GEOMAlgo_KN_CONE:
436         // (+) geompy.kind.CONE2D  xc yc zc  dx dy dz  R_1 R_2  H
437         {
438           aKind = SK_CONE2D;
439
440           gp_Pnt aO = anInfo.Location();
441           theDoubles->Append(aO.X());
442           theDoubles->Append(aO.Y());
443           theDoubles->Append(aO.Z());
444
445           gp_Ax3 anAx3 = anInfo.Position();
446           gp_Dir aD = anAx3.Direction();
447           theDoubles->Append(aD.X());
448           theDoubles->Append(aD.Y());
449           theDoubles->Append(aD.Z());
450
451           theDoubles->Append(anInfo.Radius1());
452           theDoubles->Append(anInfo.Radius2());
453           theDoubles->Append(anInfo.Height());
454         }
455         break;
456       case GEOMAlgo_KN_DISKCIRCLE:
457         // (+) geompy.kind.DISK_CIRCLE  xc yc zc  dx dy dz  R
458         {
459           aKind = SK_DISK_CIRCLE;
460
461           gp_Pnt aC = anInfo.Location();
462           theDoubles->Append(aC.X());
463           theDoubles->Append(aC.Y());
464           theDoubles->Append(aC.Z());
465
466           gp_Ax3 anAx3 = anInfo.Position();
467           gp_Dir aD = anAx3.Direction();
468           theDoubles->Append(aD.X());
469           theDoubles->Append(aD.Y());
470           theDoubles->Append(aD.Z());
471
472           theDoubles->Append(anInfo.Radius1());
473         }
474         break;
475       case GEOMAlgo_KN_DISKELLIPSE:
476         // (+) geompy.kind.DISK_ELLIPSE  xc yc zc  dx dy dz  R_1 R_2
477         {
478           aKind = SK_DISK_ELLIPSE;
479
480           gp_Pnt aC = anInfo.Location();
481           theDoubles->Append(aC.X());
482           theDoubles->Append(aC.Y());
483           theDoubles->Append(aC.Z());
484
485           gp_Ax3 anAx3 = anInfo.Position();
486           gp_Dir aD = anAx3.Direction();
487           theDoubles->Append(aD.X());
488           theDoubles->Append(aD.Y());
489           theDoubles->Append(aD.Z());
490
491           theDoubles->Append(anInfo.Radius1());
492           theDoubles->Append(anInfo.Radius2());
493         }
494         break;
495       case GEOMAlgo_KN_RECTANGLE:
496       case GEOMAlgo_KN_TRIANGLE:
497       case GEOMAlgo_KN_QUADRANGLE:
498       case GEOMAlgo_KN_POLYGON:
499         // (+) geompy.kind.POLYGON  xo yo zo  dx dy dz  nb_edges nb_vertices
500         {
501           aKind = SK_POLYGON;
502
503           gp_Pnt aO = anInfo.Location();
504           theDoubles->Append(aO.X());
505           theDoubles->Append(aO.Y());
506           theDoubles->Append(aO.Z());
507
508           gp_Ax3 anAx3 = anInfo.Position();
509           gp_Dir aD = anAx3.Direction();
510           theDoubles->Append(aD.X());
511           theDoubles->Append(aD.Y());
512           theDoubles->Append(aD.Z());
513
514           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
515           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
516         }
517         break;
518       case GEOMAlgo_KN_PLANE: // infinite
519         // (+) geompy.kind.PLANE  xo yo zo  dx dy dz
520         {
521           aKind = SK_PLANE;
522
523           gp_Pnt aC = anInfo.Location();
524           theDoubles->Append(aC.X());
525           theDoubles->Append(aC.Y());
526           theDoubles->Append(aC.Z());
527
528           gp_Ax3 anAx3 = anInfo.Position();
529           gp_Dir aD = anAx3.Direction();
530           theDoubles->Append(aD.X());
531           theDoubles->Append(aD.Y());
532           theDoubles->Append(aD.Z());
533         }
534         break;
535       default:
536         if (anInfo.KindOfShape() == GEOMAlgo_KS_PLANE) {
537           // (+) geompy.kind.PLANAR  xo yo zo  dx dy dz  nb_edges nb_vertices
538
539           aKind = SK_PLANAR;
540
541           gp_Pnt aC = anInfo.Location();
542           theDoubles->Append(aC.X());
543           theDoubles->Append(aC.Y());
544           theDoubles->Append(aC.Z());
545
546           gp_Ax3 anAx3 = anInfo.Position();
547           gp_Dir aD = anAx3.Direction();
548           theDoubles->Append(aD.X());
549           theDoubles->Append(aD.Y());
550           theDoubles->Append(aD.Z());
551
552           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
553           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
554         }
555         else {
556           // ??? geompy.kind.FACE  nb_edges nb_vertices _surface_type_id_
557           // (+) geompy.kind.FACE  nb_edges nb_vertices
558
559           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
560           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
561         }
562       }
563     }
564     break;
565
566   case TopAbs_EDGE:
567     {
568       aKind = SK_EDGE;
569
570       GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
571       switch (aKN) {
572       case GEOMAlgo_KN_CIRCLE:
573         {
574           // (+) geompy.kind.CIRCLE  xc yc zc  dx dy dz  R
575           aKind = SK_CIRCLE;
576
577           gp_Pnt aC = anInfo.Location();
578           theDoubles->Append(aC.X());
579           theDoubles->Append(aC.Y());
580           theDoubles->Append(aC.Z());
581
582           gp_Ax3 anAx3 = anInfo.Position();
583           gp_Dir aD = anAx3.Direction();
584           theDoubles->Append(aD.X());
585           theDoubles->Append(aD.Y());
586           theDoubles->Append(aD.Z());
587
588           theDoubles->Append(anInfo.Radius1());
589         }
590         break;
591       case GEOMAlgo_KN_ARCCIRCLE:
592         {
593           // (+) geompy.kind.ARC_CIRCLE  xc yc zc  dx dy dz  R  x1 y1 z1  x2 y2 z2
594           aKind = SK_ARC_CIRCLE;
595
596           gp_Pnt aC = anInfo.Location();
597           theDoubles->Append(aC.X());
598           theDoubles->Append(aC.Y());
599           theDoubles->Append(aC.Z());
600
601           gp_Ax3 anAx3 = anInfo.Position();
602           gp_Dir aD = anAx3.Direction();
603           theDoubles->Append(aD.X());
604           theDoubles->Append(aD.Y());
605           theDoubles->Append(aD.Z());
606
607           theDoubles->Append(anInfo.Radius1());
608
609           gp_Pnt aP1 = anInfo.Pnt1();
610           theDoubles->Append(aP1.X());
611           theDoubles->Append(aP1.Y());
612           theDoubles->Append(aP1.Z());
613
614           gp_Pnt aP2 = anInfo.Pnt2();
615           theDoubles->Append(aP2.X());
616           theDoubles->Append(aP2.Y());
617           theDoubles->Append(aP2.Z());
618         }
619         break;
620       case GEOMAlgo_KN_ELLIPSE:
621         {
622           // (+) geompy.kind.ELLIPSE  xc yc zc  dx dy dz  R_1 R_2
623           aKind = SK_ELLIPSE;
624
625           gp_Pnt aC = anInfo.Location();
626           theDoubles->Append(aC.X());
627           theDoubles->Append(aC.Y());
628           theDoubles->Append(aC.Z());
629
630           gp_Ax3 anAx3 = anInfo.Position();
631           gp_Dir aD = anAx3.Direction();
632           theDoubles->Append(aD.X());
633           theDoubles->Append(aD.Y());
634           theDoubles->Append(aD.Z());
635
636           theDoubles->Append(anInfo.Radius1());
637           theDoubles->Append(anInfo.Radius2());
638         }
639         break;
640       case GEOMAlgo_KN_ARCELLIPSE:
641         {
642           // (+) geompy.kind.ARC_ELLIPSE  xc yc zc  dx dy dz  R_1 R_2  x1 y1 z1  x2 y2 z2
643           aKind = SK_ARC_ELLIPSE;
644
645           gp_Pnt aC = anInfo.Location();
646           theDoubles->Append(aC.X());
647           theDoubles->Append(aC.Y());
648           theDoubles->Append(aC.Z());
649
650           gp_Ax3 anAx3 = anInfo.Position();
651           gp_Dir aD = anAx3.Direction();
652           theDoubles->Append(aD.X());
653           theDoubles->Append(aD.Y());
654           theDoubles->Append(aD.Z());
655
656           theDoubles->Append(anInfo.Radius1());
657           theDoubles->Append(anInfo.Radius2());
658
659           gp_Pnt aP1 = anInfo.Pnt1();
660           theDoubles->Append(aP1.X());
661           theDoubles->Append(aP1.Y());
662           theDoubles->Append(aP1.Z());
663
664           gp_Pnt aP2 = anInfo.Pnt2();
665           theDoubles->Append(aP2.X());
666           theDoubles->Append(aP2.Y());
667           theDoubles->Append(aP2.Z());
668         }
669         break;
670       case GEOMAlgo_KN_LINE:
671         {
672           // ??? geompy.kind.LINE  x1 y1 z1  x2 y2 z2
673           // (+) geompy.kind.LINE  x1 y1 z1  dx dy dz
674           aKind = SK_LINE;
675
676           gp_Pnt aO = anInfo.Location();
677           theDoubles->Append(aO.X());
678           theDoubles->Append(aO.Y());
679           theDoubles->Append(aO.Z());
680
681           gp_Dir aD = anInfo.Direction();
682           theDoubles->Append(aD.X());
683           theDoubles->Append(aD.Y());
684           theDoubles->Append(aD.Z());
685         }
686         break;
687       case GEOMAlgo_KN_SEGMENT:
688         {
689           // (+) geompy.kind.SEGMENT  x1 y1 z1  x2 y2 z2
690           aKind = SK_SEGMENT;
691
692           gp_Pnt aP1 = anInfo.Pnt1();
693           theDoubles->Append(aP1.X());
694           theDoubles->Append(aP1.Y());
695           theDoubles->Append(aP1.Z());
696
697           gp_Pnt aP2 = anInfo.Pnt2();
698           theDoubles->Append(aP2.X());
699           theDoubles->Append(aP2.Y());
700           theDoubles->Append(aP2.Z());
701         }
702         break;
703       default:
704         // ??? geompy.kind.EDGE  nb_vertices _curve_type_id_
705         // (+) geompy.kind.EDGE  nb_vertices
706         theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
707       }
708     }
709     break;
710
711   case TopAbs_VERTEX:
712     {
713       // (+) geompy.kind.VERTEX  x y z
714       aKind = SK_VERTEX;
715
716       gp_Pnt aP = anInfo.Location();
717       theDoubles->Append(aP.X());
718       theDoubles->Append(aP.Y());
719       theDoubles->Append(aP.Z());
720     }
721     break;
722   }
723
724   SetErrorCode(OK);
725   return aKind;
726 }
727
728 //=============================================================================
729 /*! Get LCS, corresponding to the given shape.
730  *  Origin of the LCS is situated at the shape's center of mass.
731  *  Axes of the LCS are obtained from shape's location or,
732  *  if the shape is a planar face, from position of its plane.
733  */
734 //=============================================================================
735 gp_Ax3 GEOMImpl_IMeasureOperations::GetPosition (const TopoDS_Shape& theShape)
736 {
737   gp_Ax3 aResult;
738
739   if (theShape.IsNull())
740     return aResult;
741
742   // Axes
743   aResult.Transform(theShape.Location().Transformation());
744   if (theShape.ShapeType() == TopAbs_FACE) {
745     Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape));
746     if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
747       Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS);
748       gp_Pln aPln = aGPlane->Pln();
749       aResult = aPln.Position();
750     }
751   }
752
753   // Origin
754   gp_Pnt aPnt;
755   if (theShape.ShapeType() == TopAbs_VERTEX) {
756     aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape));
757   }
758   else {
759     GProp_GProps aSystem;
760     if (theShape.ShapeType() == TopAbs_EDGE || theShape.ShapeType() == TopAbs_WIRE)
761       BRepGProp::LinearProperties(theShape, aSystem);
762     else if (theShape.ShapeType() == TopAbs_FACE || theShape.ShapeType() == TopAbs_SHELL)
763       BRepGProp::SurfaceProperties(theShape, aSystem);
764     else
765       BRepGProp::VolumeProperties(theShape, aSystem);
766
767     aPnt = aSystem.CentreOfMass();
768   }
769
770   aResult.SetLocation(aPnt);
771
772   return aResult;
773 }
774
775 //=============================================================================
776 /*!
777  *  GetPosition
778  */
779 //=============================================================================
780 void GEOMImpl_IMeasureOperations::GetPosition
781                    (Handle(GEOM_Object) theShape,
782                     Standard_Real& Ox, Standard_Real& Oy, Standard_Real& Oz,
783                     Standard_Real& Zx, Standard_Real& Zy, Standard_Real& Zz,
784                     Standard_Real& Xx, Standard_Real& Xy, Standard_Real& Xz)
785 {
786   SetErrorCode(KO);
787
788   //Set default values: global CS
789   Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.;
790   Zz = Xx = 1.;
791
792   if (theShape.IsNull()) return;
793
794   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
795   if (aRefShape.IsNull()) return;
796
797   TopoDS_Shape aShape = aRefShape->GetValue();
798   if (aShape.IsNull()) {
799     SetErrorCode("The Objects has NULL Shape");
800     return;
801   }
802
803   try {
804 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
805     OCC_CATCH_SIGNALS;
806 #endif
807
808     gp_Ax3 anAx3 = GetPosition(aShape);
809
810     gp_Pnt anOri = anAx3.Location();
811     gp_Dir aDirZ = anAx3.Direction();
812     gp_Dir aDirX = anAx3.XDirection();
813
814     // Output values
815     anOri.Coord(Ox, Oy, Oz);
816     aDirZ.Coord(Zx, Zy, Zz);
817     aDirX.Coord(Xx, Xy, Xz);
818   }
819   catch (Standard_Failure) {
820     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
821     SetErrorCode(aFail->GetMessageString());
822     return;
823   }
824
825   SetErrorCode(OK);
826 }
827
828 //=============================================================================
829 /*!
830  *  GetCentreOfMass
831  */
832 //=============================================================================
833 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
834                                                 (Handle(GEOM_Object) theShape)
835 {
836   SetErrorCode(KO);
837
838   if (theShape.IsNull()) return NULL;
839
840   //Add a new CentreOfMass object
841   Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GetDocID(), GEOM_CDG);
842
843   //Add a new CentreOfMass function
844   Handle(GEOM_Function) aFunction =
845     aCDG->AddFunction(GEOMImpl_MeasureDriver::GetID(), CDG_MEASURE);
846   if (aFunction.IsNull()) return NULL;
847
848   //Check if the function is set correctly
849   if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
850
851   GEOMImpl_IMeasure aCI (aFunction);
852
853   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
854   if (aRefShape.IsNull()) return NULL;
855
856   aCI.SetBase(aRefShape);
857
858   //Compute the CentreOfMass value
859   try {
860 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
861     OCC_CATCH_SIGNALS;
862 #endif
863     if (!GetSolver()->ComputeFunction(aFunction)) {
864       SetErrorCode("Measure driver failed to compute centre of mass");
865       return NULL;
866     }
867   }
868   catch (Standard_Failure) {
869     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
870     SetErrorCode(aFail->GetMessageString());
871     return NULL;
872   }
873
874   //Make a Python command
875   GEOM::TPythonDump(aFunction) << aCDG << " = geompy.MakeCDG(" << theShape << ")";
876
877   SetErrorCode(OK);
878   return aCDG;
879 }
880
881 //=============================================================================
882 /*!
883  *  GetNormal
884  */
885 //=============================================================================
886 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
887                                          (Handle(GEOM_Object) theFace,
888                                           Handle(GEOM_Object) theOptionalPoint)
889 {
890   SetErrorCode(KO);
891
892   if (theFace.IsNull()) return NULL;
893
894   //Add a new Normale object
895   Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GetDocID(), GEOM_VECTOR);
896
897   //Add a new Normale function
898   Handle(GEOM_Function) aFunction =
899     aNorm->AddFunction(GEOMImpl_MeasureDriver::GetID(), VECTOR_FACE_NORMALE);
900   if (aFunction.IsNull()) return NULL;
901
902   //Check if the function is set correctly
903   if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
904
905   GEOMImpl_IMeasure aCI (aFunction);
906
907   Handle(GEOM_Function) aFace = theFace->GetLastFunction();
908   if (aFace.IsNull()) return NULL;
909
910   aCI.SetBase(aFace);
911
912   if (!theOptionalPoint.IsNull()) {
913     Handle(GEOM_Function) anOptPnt = theOptionalPoint->GetLastFunction();
914     aCI.SetPoint(anOptPnt);
915   }
916
917   //Compute the Normale value
918   try {
919 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
920     OCC_CATCH_SIGNALS;
921 #endif
922     if (!GetSolver()->ComputeFunction(aFunction)) {
923       SetErrorCode("Measure driver failed to compute normake of face");
924       return NULL;
925     }
926   }
927   catch (Standard_Failure) {
928     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
929     SetErrorCode(aFail->GetMessageString());
930     return NULL;
931   }
932
933   //Make a Python command
934   GEOM::TPythonDump pd (aFunction);
935   pd << aNorm << " = geompy.GetNormal(" << theFace;
936   if (!theOptionalPoint.IsNull()) {
937     pd << ", " << theOptionalPoint;
938   }
939   pd << ")";
940
941   SetErrorCode(OK);
942   return aNorm;
943 }
944
945 //=============================================================================
946 /*!
947  *  GetBasicProperties
948  */
949 //=============================================================================
950 void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theShape,
951                                                       Standard_Real& theLength,
952                                                       Standard_Real& theSurfArea,
953                                                       Standard_Real& theVolume)
954 {
955   SetErrorCode(KO);
956
957   if (theShape.IsNull()) return;
958
959   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
960   if (aRefShape.IsNull()) return;
961
962   TopoDS_Shape aShape = aRefShape->GetValue();
963   if (aShape.IsNull()) {
964     SetErrorCode("The Objects has NULL Shape");
965     return;
966   }
967
968   //Compute the parameters
969   GProp_GProps LProps, SProps;
970   try {
971 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
972     OCC_CATCH_SIGNALS;
973 #endif
974     BRepGProp::LinearProperties(aShape, LProps);
975     theLength = LProps.Mass();
976
977     BRepGProp::SurfaceProperties(aShape, SProps);
978     theSurfArea = SProps.Mass();
979
980     theVolume = 0.0;
981     if (aShape.ShapeType() < TopAbs_SHELL) {
982       for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
983         GProp_GProps VProps;
984         BRepGProp::VolumeProperties(Exp.Current(), VProps);
985         theVolume += VProps.Mass();
986       }
987     }
988   }
989   catch (Standard_Failure) {
990     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
991     SetErrorCode(aFail->GetMessageString());
992     return;
993   }
994
995   SetErrorCode(OK);
996 }
997
998 //=============================================================================
999 /*!
1000  *  GetInertia
1001  */
1002 //=============================================================================
1003 void GEOMImpl_IMeasureOperations::GetInertia
1004                    (Handle(GEOM_Object) theShape,
1005                     Standard_Real& I11, Standard_Real& I12, Standard_Real& I13,
1006                     Standard_Real& I21, Standard_Real& I22, Standard_Real& I23,
1007                     Standard_Real& I31, Standard_Real& I32, Standard_Real& I33,
1008                     Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz)
1009 {
1010   SetErrorCode(KO);
1011
1012   if (theShape.IsNull()) return;
1013
1014   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1015   if (aRefShape.IsNull()) return;
1016
1017   TopoDS_Shape aShape = aRefShape->GetValue();
1018   if (aShape.IsNull()) {
1019     SetErrorCode("The Objects has NULL Shape");
1020     return;
1021   }
1022
1023   //Compute the parameters
1024   GProp_GProps System;
1025
1026   try {
1027 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1028     OCC_CATCH_SIGNALS;
1029 #endif
1030     if (aShape.ShapeType() == TopAbs_VERTEX ||
1031         aShape.ShapeType() == TopAbs_EDGE ||
1032         aShape.ShapeType() == TopAbs_WIRE) {
1033       BRepGProp::LinearProperties(aShape, System);
1034     } else if (aShape.ShapeType() == TopAbs_FACE ||
1035                aShape.ShapeType() == TopAbs_SHELL) {
1036       BRepGProp::SurfaceProperties(aShape, System);
1037     } else {
1038       BRepGProp::VolumeProperties(aShape, System);
1039     }
1040     gp_Mat I = System.MatrixOfInertia();
1041
1042     I11 = I(1,1);
1043     I12 = I(1,2);
1044     I13 = I(1,3);
1045
1046     I21 = I(2,1);
1047     I22 = I(2,2);
1048     I23 = I(2,3);
1049
1050     I31 = I(3,1);
1051     I32 = I(3,2);
1052     I33 = I(3,3);
1053
1054     GProp_PrincipalProps Pr = System.PrincipalProperties();
1055     Pr.Moments(Ix,Iy,Iz);
1056   }
1057   catch (Standard_Failure) {
1058     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1059     SetErrorCode(aFail->GetMessageString());
1060     return;
1061   }
1062
1063   SetErrorCode(OK);
1064 }
1065
1066 //=============================================================================
1067 /*!
1068  *  GetBoundingBox
1069  */
1070 //=============================================================================
1071 void GEOMImpl_IMeasureOperations::GetBoundingBox
1072                                      (Handle(GEOM_Object) theShape,
1073                                       Standard_Real& Xmin, Standard_Real& Xmax,
1074                                       Standard_Real& Ymin, Standard_Real& Ymax,
1075                                       Standard_Real& Zmin, Standard_Real& Zmax)
1076 {
1077   SetErrorCode(KO);
1078
1079   if (theShape.IsNull()) return;
1080
1081   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1082   if (aRefShape.IsNull()) return;
1083
1084   TopoDS_Shape aShape = aRefShape->GetValue();
1085   if (aShape.IsNull()) {
1086     SetErrorCode("The Objects has NULL Shape");
1087     return;
1088   }
1089
1090   //Compute the parameters
1091   Bnd_Box B;
1092
1093   try {
1094 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1095     OCC_CATCH_SIGNALS;
1096 #endif
1097     BRepBndLib::Add(aShape, B);
1098     B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
1099   }
1100   catch (Standard_Failure) {
1101     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1102     SetErrorCode(aFail->GetMessageString());
1103     return;
1104   }
1105
1106   SetErrorCode(OK);
1107 }
1108
1109 //=============================================================================
1110 /*!
1111  *  GetTolerance
1112  */
1113 //=============================================================================
1114 void GEOMImpl_IMeasureOperations::GetTolerance
1115                                (Handle(GEOM_Object) theShape,
1116                                 Standard_Real& FaceMin, Standard_Real& FaceMax,
1117                                 Standard_Real& EdgeMin, Standard_Real& EdgeMax,
1118                                 Standard_Real& VertMin, Standard_Real& VertMax)
1119 {
1120   SetErrorCode(KO);
1121
1122   if (theShape.IsNull()) return;
1123
1124   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1125   if (aRefShape.IsNull()) return;
1126
1127   TopoDS_Shape aShape = aRefShape->GetValue();
1128   if (aShape.IsNull()) {
1129     SetErrorCode("The Objects has NULL Shape");
1130     return;
1131   }
1132
1133   //Compute the parameters
1134   Standard_Real T;
1135   FaceMin = EdgeMin = VertMin = RealLast();
1136   FaceMax = EdgeMax = VertMax = -RealLast();
1137
1138   try {
1139 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1140     OCC_CATCH_SIGNALS;
1141 #endif
1142     for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) {
1143       TopoDS_Face Face = TopoDS::Face(ExF.Current());
1144       T = BRep_Tool::Tolerance(Face);
1145       if (T > FaceMax)
1146         FaceMax = T;
1147       if (T < FaceMin)
1148         FaceMin = T;
1149     }
1150     for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) {
1151       TopoDS_Edge Edge = TopoDS::Edge(ExE.Current());
1152       T = BRep_Tool::Tolerance(Edge);
1153       if (T > EdgeMax)
1154         EdgeMax = T;
1155       if (T < EdgeMin)
1156         EdgeMin = T;
1157     }
1158     for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
1159       TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
1160       T = BRep_Tool::Tolerance(Vertex);
1161       if (T > VertMax)
1162         VertMax = T;
1163       if (T < VertMin)
1164         VertMin = T;
1165     }
1166   }
1167   catch (Standard_Failure) {
1168     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1169     SetErrorCode(aFail->GetMessageString());
1170     return;
1171   }
1172
1173   SetErrorCode(OK);
1174 }
1175
1176 //=============================================================================
1177 /*!
1178  *  CheckShape
1179  */
1180 //=============================================================================
1181 bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object)      theShape,
1182                                               const Standard_Boolean   theIsCheckGeom,
1183                                               TCollection_AsciiString& theDump)
1184 {
1185   SetErrorCode(KO);
1186
1187   if (theShape.IsNull()) return false;
1188
1189   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1190   if (aRefShape.IsNull()) return false;
1191
1192   TopoDS_Shape aShape = aRefShape->GetValue();
1193   if (aShape.IsNull()) {
1194     SetErrorCode("The Objects has NULL Shape");
1195     return false;
1196   }
1197
1198   //Compute the parameters
1199   bool isValid = false;
1200   try {
1201 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1202     OCC_CATCH_SIGNALS;
1203 #endif
1204     BRepCheck_Analyzer ana (aShape, theIsCheckGeom);
1205     if (ana.IsValid()) {
1206       theDump.Clear();
1207       isValid = true;
1208     } else {
1209       StructuralDump(ana, aShape, theDump);
1210     }
1211   }
1212   catch (Standard_Failure) {
1213     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1214     SetErrorCode(aFail->GetMessageString());
1215     return false;
1216   }
1217
1218   SetErrorCode(OK);
1219   return isValid;
1220 }
1221
1222 //=============================================================================
1223 /*!
1224  *  WhatIs
1225  */
1226 //=============================================================================
1227 TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
1228 {
1229   SetErrorCode(KO);
1230
1231   TCollection_AsciiString Astr;
1232
1233   if (theShape.IsNull()) return Astr;
1234
1235   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1236   if (aRefShape.IsNull()) return Astr;
1237
1238   TopoDS_Shape aShape = aRefShape->GetValue();
1239   if (aShape.IsNull()) {
1240     SetErrorCode("The Objects has NULL Shape");
1241     return Astr;
1242   }
1243
1244   //Compute the parameters
1245   if (aShape.ShapeType() == TopAbs_EDGE) {
1246     if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
1247       Astr = Astr + " It is a degenerated edge \n";
1248     }
1249   }
1250
1251   Astr = Astr + " Number of sub-shapes : \n";
1252
1253   try {
1254 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1255     OCC_CATCH_SIGNALS;
1256 #endif
1257     int iType, nbTypes [TopAbs_SHAPE];
1258     for (iType = 0; iType < TopAbs_SHAPE; ++iType)
1259       nbTypes[iType] = 0;
1260     nbTypes[aShape.ShapeType()]++;
1261
1262     TopTools_MapOfShape aMapOfShape;
1263     aMapOfShape.Add(aShape);
1264     TopTools_ListOfShape aListOfShape;
1265     aListOfShape.Append(aShape);
1266
1267     TopTools_ListIteratorOfListOfShape itL (aListOfShape);
1268     for (; itL.More(); itL.Next()) {
1269       TopoDS_Iterator it (itL.Value());
1270       for (; it.More(); it.Next()) {
1271         TopoDS_Shape s = it.Value();
1272         if (aMapOfShape.Add(s)) {
1273           aListOfShape.Append(s);
1274           nbTypes[s.ShapeType()]++;
1275         }
1276       }
1277     }
1278
1279     Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n";
1280     Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n";
1281     Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n";
1282     Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n";
1283     Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n";
1284     Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n";
1285     Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n";
1286     Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n";
1287     Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent());
1288   }
1289   catch (Standard_Failure) {
1290     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1291     SetErrorCode(aFail->GetMessageString());
1292     return Astr;
1293   }
1294
1295   SetErrorCode(OK);
1296   return Astr;
1297 }
1298
1299 //=============================================================================
1300 /*!
1301  *  GetMinDistance
1302  */
1303 //=============================================================================
1304 Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
1305   (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
1306    Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1,
1307    Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2)
1308 {
1309   SetErrorCode(KO);
1310   Standard_Real MinDist = 1.e9;
1311
1312   if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
1313
1314   Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
1315   Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
1316   if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
1317
1318   TopoDS_Shape aShape1 = aRefShape1->GetValue();
1319   TopoDS_Shape aShape2 = aRefShape2->GetValue();
1320   if (aShape1.IsNull() || aShape2.IsNull()) {
1321     SetErrorCode("One of Objects has NULL Shape");
1322     return MinDist;
1323   }
1324
1325   //Compute the parameters
1326   try {
1327 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1328     OCC_CATCH_SIGNALS;
1329 #endif
1330     BRepExtrema_DistShapeShape dst (aShape1, aShape2);
1331     if (dst.IsDone()) {
1332       gp_Pnt PMin1, PMin2, P1, P2;
1333
1334       for (int i = 1; i <= dst.NbSolution(); i++) {
1335         P1 = dst.PointOnShape1(i);
1336         P2 = dst.PointOnShape2(i);
1337
1338         Standard_Real Dist = P1.Distance(P2);
1339         if (MinDist > Dist) {
1340           MinDist = Dist;
1341           PMin1 = P1;
1342           PMin2 = P2;
1343         }
1344       }
1345
1346       PMin1.Coord(X1, Y1, Z1);
1347       PMin2.Coord(X2, Y2, Z2);
1348     }
1349   }
1350   catch (Standard_Failure) {
1351     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1352     SetErrorCode(aFail->GetMessageString());
1353     return MinDist;
1354   }
1355
1356   SetErrorCode(OK);
1357   return MinDist;
1358 }
1359
1360 //=======================================================================
1361 /*!
1362  *  Get coordinates of point
1363  */
1364 //=======================================================================
1365 void GEOMImpl_IMeasureOperations::PointCoordinates (Handle(GEOM_Object) theShape,
1366                         Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ)
1367 {
1368   SetErrorCode(KO);
1369
1370   if (theShape.IsNull())
1371     return;
1372
1373   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
1374   if (aRefShape.IsNull())
1375     return;
1376
1377   TopoDS_Shape aShape = aRefShape->GetValue();
1378   if (aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX)
1379   {
1380     SetErrorCode( "Shape must be a vertex" );
1381     return;
1382   }
1383
1384   try {
1385 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1386     OCC_CATCH_SIGNALS;
1387 #endif
1388     gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
1389     theX = aPnt.X();
1390     theY = aPnt.Y();
1391     theZ = aPnt.Z();
1392
1393     SetErrorCode(OK);
1394   }
1395   catch (Standard_Failure)
1396   {
1397     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1398     SetErrorCode( aFail->GetMessageString() );
1399   }
1400 }
1401
1402 //=======================================================================
1403 /*!
1404  *  Compute angle (in degrees) between two lines
1405  */
1406 //=======================================================================
1407 Standard_Real GEOMImpl_IMeasureOperations::GetAngle (Handle(GEOM_Object) theLine1,
1408                                                      Handle(GEOM_Object) theLine2)
1409 {
1410   SetErrorCode(KO);
1411
1412   Standard_Real anAngle = -1.0;
1413
1414   if (theLine1.IsNull() || theLine2.IsNull())
1415     return anAngle;
1416
1417   Handle(GEOM_Function) aRefLine1 = theLine1->GetLastFunction();
1418   Handle(GEOM_Function) aRefLine2 = theLine2->GetLastFunction();
1419   if (aRefLine1.IsNull() || aRefLine2.IsNull())
1420     return anAngle;
1421
1422   TopoDS_Shape aLine1 = aRefLine1->GetValue();
1423   TopoDS_Shape aLine2 = aRefLine2->GetValue();
1424   if (aLine1.IsNull() || aLine2.IsNull() ||
1425       aLine1.ShapeType() != TopAbs_EDGE ||
1426       aLine2.ShapeType() != TopAbs_EDGE)
1427   {
1428     SetErrorCode("Two edges must be given");
1429     return anAngle;
1430   }
1431
1432   try {
1433 #if (OCC_VERSION_MAJOR << 16 | OCC_VERSION_MINOR << 8 | OCC_VERSION_MAINTENANCE) > 0x060100
1434     OCC_CATCH_SIGNALS;
1435 #endif
1436     TopoDS_Edge E1 = TopoDS::Edge(aLine1);
1437     TopoDS_Edge E2 = TopoDS::Edge(aLine2);
1438
1439     double fp,lp;
1440     Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
1441     Handle(Geom_Curve) C2 = BRep_Tool::Curve(E2,fp,lp);
1442
1443     if (!C1->IsKind(STANDARD_TYPE(Geom_Line)) ||
1444         !C2->IsKind(STANDARD_TYPE(Geom_Line)))
1445     {
1446       SetErrorCode("The edges must be linear");
1447       return anAngle;
1448     }
1449
1450     Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(C1);
1451     Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(C2);
1452
1453     gp_Lin aLin1 = L1->Lin();
1454     gp_Lin aLin2 = L2->Lin();
1455
1456     anAngle = aLin1.Angle(aLin2);
1457     anAngle /= PI180; // convert radians into degrees
1458
1459     SetErrorCode(OK);
1460   }
1461   catch (Standard_Failure)
1462   {
1463     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
1464     SetErrorCode(aFail->GetMessageString());
1465   }
1466
1467   return anAngle;
1468 }
1469
1470 //=======================================================================
1471 //function : StructuralDump
1472 //purpose  : Structural (data exchange) style of output.
1473 //=======================================================================
1474 void GEOMImpl_IMeasureOperations::StructuralDump (const BRepCheck_Analyzer& theAna,
1475                                                   const TopoDS_Shape&       theShape,
1476                                                   TCollection_AsciiString&  theDump)
1477 {
1478   Standard_Integer i;
1479   theDump.Clear();
1480   theDump += " -- The Shape has problems :\n";
1481   theDump += "  Check                                    Count\n";
1482   theDump += " ------------------------------------------------\n";
1483
1484   Standard_Integer last_stat = (Standard_Integer)BRepCheck_CheckFail;
1485   Handle(TColStd_HArray1OfInteger) NbProblems =
1486     new TColStd_HArray1OfInteger(1, last_stat);
1487   for (i = 1; i <= last_stat; i++)
1488     NbProblems->SetValue(i,0);
1489
1490   Handle(TopTools_HSequenceOfShape) sl;
1491   sl = new TopTools_HSequenceOfShape();
1492   TopTools_DataMapOfShapeListOfShape theMap;
1493   theMap.Clear();
1494   GetProblemShapes(theAna, theShape, sl, NbProblems, theMap);
1495   theMap.Clear();
1496
1497   Standard_Integer count = 0;
1498   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurve);
1499   if (count > 0) {
1500     theDump += "  Invalid Point on Curve ................... ";
1501     theDump += TCollection_AsciiString(count) + "\n";
1502   }
1503   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurveOnSurface);
1504   if (count > 0) {
1505     theDump += "  Invalid Point on CurveOnSurface .......... ";
1506     theDump += TCollection_AsciiString(count) + "\n";
1507   }
1508   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnSurface);
1509   if (count > 0) {
1510     theDump += "  Invalid Point on Surface ................. ";
1511     theDump += TCollection_AsciiString(count) + "\n";
1512   }
1513   count = NbProblems->Value((Standard_Integer)BRepCheck_No3DCurve);
1514   if (count > 0) {
1515     theDump += "  No 3D Curve .............................. ";
1516     theDump += TCollection_AsciiString(count) + "\n";
1517   }
1518   count = NbProblems->Value((Standard_Integer)BRepCheck_Multiple3DCurve);
1519   if (count > 0) {
1520     theDump += "  Multiple 3D Curve ........................ ";
1521     theDump += TCollection_AsciiString(count) + "\n";
1522   }
1523   count = NbProblems->Value((Standard_Integer)BRepCheck_Invalid3DCurve);
1524   if (count > 0) {
1525     theDump += "  Invalid 3D Curve ......................... ";
1526     theDump += TCollection_AsciiString(count) + "\n";
1527   }
1528   count = NbProblems->Value((Standard_Integer)BRepCheck_NoCurveOnSurface);
1529   if (count > 0) {
1530     theDump += "  No Curve on Surface ...................... ";
1531     theDump += TCollection_AsciiString(count) + "\n";
1532   }
1533   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnSurface);
1534   if (count > 0) {
1535     theDump += "  Invalid Curve on Surface ................. ";
1536     theDump += TCollection_AsciiString(count) + "\n";
1537   }
1538   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnClosedSurface);
1539   if (count > 0) {
1540     theDump += "  Invalid Curve on closed Surface .......... ";
1541     theDump += TCollection_AsciiString(count) + "\n";
1542   }
1543   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameRangeFlag);
1544   if (count > 0) {
1545     theDump += "  Invalid SameRange Flag ................... ";
1546     theDump += TCollection_AsciiString(count) + "\n";
1547   }
1548   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameParameterFlag);
1549   if (count > 0) {
1550     theDump += "  Invalid SameParameter Flag ............... ";
1551     theDump += TCollection_AsciiString(count) + "\n";
1552   }
1553   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidDegeneratedFlag);
1554   if (count > 0) {
1555     theDump += "  Invalid Degenerated Flag ................. ";
1556     theDump += TCollection_AsciiString(count) + "\n";
1557   }
1558   count = NbProblems->Value((Standard_Integer)BRepCheck_FreeEdge);
1559   if (count > 0) {
1560     theDump += "  Free Edge ................................ ";
1561     theDump += TCollection_AsciiString(count) + "\n";
1562   }
1563   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidMultiConnexity);
1564   if (count > 0) {
1565     theDump += "  Invalid MultiConnexity ................... ";
1566     theDump += TCollection_AsciiString(count) + "\n";
1567   }
1568   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidRange);
1569   if (count > 0) {
1570     theDump += "  Invalid Range ............................ ";
1571     theDump += TCollection_AsciiString(count) + "\n";
1572   }
1573   count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyWire);
1574   if (count > 0) {
1575     theDump += "  Empty Wire ............................... ";
1576     theDump += TCollection_AsciiString(count) + "\n";
1577   }
1578   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantEdge);
1579   if (count > 0) {
1580     theDump += "  Redundant Edge ........................... ";
1581     theDump += TCollection_AsciiString(count) + "\n";
1582   }
1583   count = NbProblems->Value((Standard_Integer)BRepCheck_SelfIntersectingWire);
1584   if (count > 0) {
1585     theDump += "  Self Intersecting Wire ................... ";
1586     theDump += TCollection_AsciiString(count) + "\n";
1587   }
1588   count = NbProblems->Value((Standard_Integer)BRepCheck_NoSurface);
1589   if (count > 0) {
1590     theDump += "  No Surface ............................... ";
1591     theDump += TCollection_AsciiString(count) + "\n";
1592   }
1593   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidWire);
1594   if (count > 0) {
1595     theDump += "  Invalid Wire ............................. ";
1596     theDump += TCollection_AsciiString(count) + "\n";
1597   }
1598   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantWire);
1599   if (count > 0) {
1600     theDump += "  Redundant Wire ........................... ";
1601     theDump += TCollection_AsciiString(count) + "\n";
1602   }
1603   count = NbProblems->Value((Standard_Integer)BRepCheck_IntersectingWires);
1604   if (count > 0) {
1605     theDump += "  Intersecting Wires ....................... ";
1606     theDump += TCollection_AsciiString(count) + "\n";
1607   }
1608   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidImbricationOfWires);
1609   if (count > 0) {
1610     theDump += "  Invalid Imbrication of Wires ............. ";
1611     theDump += TCollection_AsciiString(count) + "\n";
1612   }
1613   count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyShell);
1614   if (count > 0) {
1615     theDump += "  Empty Shell .............................. ";
1616     theDump += TCollection_AsciiString(count) + "\n";
1617   }
1618   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantFace);
1619   if (count > 0) {
1620     theDump += "  Redundant Face ........................... ";
1621     theDump += TCollection_AsciiString(count) + "\n";
1622   }
1623   count = NbProblems->Value((Standard_Integer)BRepCheck_UnorientableShape);
1624   if (count > 0) {
1625     theDump += "  Unorientable Shape ....................... ";
1626     theDump += TCollection_AsciiString(count) + "\n";
1627   }
1628   count = NbProblems->Value((Standard_Integer)BRepCheck_NotClosed);
1629   if (count > 0) {
1630     theDump += "  Not Closed ............................... ";
1631     theDump += TCollection_AsciiString(count) + "\n";
1632   }
1633   count = NbProblems->Value((Standard_Integer)BRepCheck_NotConnected);
1634   if (count > 0) {
1635     theDump += "  Not Connected ............................ ";
1636     theDump += TCollection_AsciiString(count) + "\n";
1637   }
1638   count = NbProblems->Value((Standard_Integer)BRepCheck_SubshapeNotInShape);
1639   if (count > 0) {
1640     theDump += "  Subshape not in Shape .................... ";
1641     theDump += TCollection_AsciiString(count) + "\n";
1642   }
1643   count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientation);
1644   if (count > 0) {
1645     theDump += "  Bad Orientation .......................... ";
1646     theDump += TCollection_AsciiString(count) + "\n";
1647   }
1648   count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientationOfSubshape);
1649   if (count > 0) {
1650     theDump += "  Bad Orientation of Subshape .............. ";
1651     theDump += TCollection_AsciiString(count) + "\n";
1652   }
1653   count = NbProblems->Value((Standard_Integer)BRepCheck_CheckFail);
1654   if (count > 0) {
1655     theDump += "  checkshape failure ....................... ";
1656     theDump += TCollection_AsciiString(count) + "\n";
1657   }
1658
1659   theDump += " ------------------------------------------------\n";
1660   theDump += "*** Shapes with problems : ";
1661   theDump += TCollection_AsciiString(sl->Length()) + "\n";
1662
1663   Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
1664   nbv = nbe = nbw = nbf = nbs = nbo = 0;
1665
1666   for (i = 1; i <= sl->Length(); i++) {
1667     TopoDS_Shape shi = sl->Value(i);
1668     TopAbs_ShapeEnum sti = shi.ShapeType();
1669     switch (sti) {
1670       case TopAbs_VERTEX : nbv++; break;
1671       case TopAbs_EDGE   : nbe++; break;
1672       case TopAbs_WIRE   : nbw++; break;
1673       case TopAbs_FACE   : nbf++; break;
1674       case TopAbs_SHELL  : nbs++; break;
1675       case TopAbs_SOLID  : nbo++; break;
1676       default            : break;
1677     }
1678   }
1679
1680   if (nbv > 0) {
1681     theDump += "VERTEX : ";
1682     if (nbv < 10) theDump += " ";
1683     theDump += TCollection_AsciiString(nbv) + "\n";
1684   }
1685   if (nbe > 0) {
1686     theDump += "EDGE   : ";
1687     if (nbe < 10) theDump += " ";
1688     theDump += TCollection_AsciiString(nbe) + "\n";
1689   }
1690   if (nbw > 0) {
1691     theDump += "WIRE   : ";
1692     if (nbw < 10) theDump += " ";
1693     theDump += TCollection_AsciiString(nbw) + "\n";
1694   }
1695   if (nbf > 0) {
1696     theDump += "FACE   : ";
1697     if (nbf < 10) theDump += " ";
1698     theDump += TCollection_AsciiString(nbf) + "\n";
1699   }
1700   if (nbs > 0) {
1701     theDump += "SHELL  : ";
1702     if (nbs < 10) theDump += " ";
1703     theDump += TCollection_AsciiString(nbs) + "\n";
1704   }
1705   if (nbo > 0) {
1706     theDump += "SOLID  : ";
1707     if (nbo < 10) theDump += " ";
1708     theDump += TCollection_AsciiString(nbo) + "\n";
1709   }
1710 }
1711
1712 //=======================================================================
1713 //function : GetProblemShapes
1714 // purpose : for StructuralDump
1715 //=======================================================================
1716 void GEOMImpl_IMeasureOperations::GetProblemShapes (const BRepCheck_Analyzer&           theAna,
1717                                                     const TopoDS_Shape&                 theShape,
1718                                                     Handle(TopTools_HSequenceOfShape)&  sl,
1719                                                     Handle(TColStd_HArray1OfInteger)&   NbProblems,
1720                                                     TopTools_DataMapOfShapeListOfShape& theMap)
1721 {
1722   for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
1723     GetProblemShapes(theAna, iter.Value(), sl, NbProblems, theMap);
1724   }
1725   TopAbs_ShapeEnum styp = theShape.ShapeType();
1726   BRepCheck_ListIteratorOfListOfStatus itl;
1727   TopTools_ListOfShape empty;
1728   if (!theMap.IsBound(theShape)) {
1729     theMap.Bind(theShape,empty);
1730
1731     if (!theAna.Result(theShape).IsNull()) {
1732       itl.Initialize(theAna.Result(theShape)->Status());
1733       // !!! May be, we have to print all the problems, not only the first one ?
1734       if (itl.Value() != BRepCheck_NoError) {
1735         sl->Append(theShape);
1736         BRepCheck_Status stat = itl.Value();
1737         NbProblems->SetValue((Standard_Integer)stat,
1738                              NbProblems->Value((Standard_Integer)stat) + 1);
1739       }
1740     }
1741   }
1742
1743   switch (styp) {
1744   case TopAbs_EDGE:
1745     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
1746     break;
1747   case TopAbs_FACE:
1748     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_WIRE, theMap);
1749     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_EDGE, theMap);
1750     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
1751     break;
1752   case TopAbs_SHELL:
1753     break;
1754   case TopAbs_SOLID:
1755     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_SHELL, theMap);
1756     break;
1757   default:
1758     break;
1759   }
1760 }
1761
1762 //=======================================================================
1763 //function : Contains
1764 //=======================================================================
1765 static Standard_Boolean Contains (const TopTools_ListOfShape& L,
1766                                   const TopoDS_Shape& S)
1767 {
1768   TopTools_ListIteratorOfListOfShape it;
1769   for (it.Initialize(L); it.More(); it.Next()) {
1770     if (it.Value().IsSame(S)) {
1771       return Standard_True;
1772     }
1773   }
1774   return Standard_False;
1775 }
1776
1777 //=======================================================================
1778 //function : GetProblemSub
1779 // purpose : for StructuralDump
1780 //=======================================================================
1781 void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer&           theAna,
1782                                                  const TopoDS_Shape&                 theShape,
1783                                                  Handle(TopTools_HSequenceOfShape)&  sl,
1784                                                  Handle(TColStd_HArray1OfInteger)&   NbProblems,
1785                                                  const TopAbs_ShapeEnum              Subtype,
1786                                                  TopTools_DataMapOfShapeListOfShape& theMap)
1787 {
1788   BRepCheck_ListIteratorOfListOfStatus itl;
1789   TopExp_Explorer exp;
1790   for (exp.Init(theShape, Subtype); exp.More(); exp.Next()) {
1791     const TopoDS_Shape& sub = exp.Current();
1792
1793     const Handle(BRepCheck_Result)& res = theAna.Result(sub);
1794     for (res->InitContextIterator();
1795          res->MoreShapeInContext();
1796          res->NextShapeInContext()) {
1797       if (res->ContextualShape().IsSame(theShape) && !Contains(theMap(sub), theShape)) {
1798         theMap(sub).Append(theShape);
1799         itl.Initialize(res->StatusOnShape());
1800
1801         if (itl.Value() != BRepCheck_NoError) {
1802           Standard_Integer ii = 0;
1803
1804           for (ii = 1; ii <= sl->Length(); ii++)
1805             if (sl->Value(ii).IsSame(sub)) break;
1806
1807           if (ii > sl->Length()) {
1808             sl->Append(sub);
1809             BRepCheck_Status stat = itl.Value();
1810             NbProblems->SetValue((Standard_Integer)stat,
1811                                  NbProblems->Value((Standard_Integer)stat) + 1);
1812           }
1813           for (ii = 1; ii <= sl->Length(); ii++)
1814             if (sl->Value(ii).IsSame(theShape)) break;
1815           if (ii > sl->Length()) {
1816             sl->Append(theShape);
1817             BRepCheck_Status stat = itl.Value();
1818             NbProblems->SetValue((Standard_Integer)stat,
1819                                  NbProblems->Value((Standard_Integer)stat) + 1);
1820           }
1821         }
1822         break;
1823       }
1824     }
1825   }
1826 }