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