Salome HOME
Merge with version on tag OCC-V2_1_0d
[modules/geom.git] / src / GEOMImpl / GEOMImpl_IMeasureOperations.cxx
1 using namespace std;
2
3 #include "GEOMImpl_IMeasureOperations.hxx"
4
5 #include "GEOMImpl_Types.hxx"
6 #include "GEOMImpl_MeasureDriver.hxx"
7 #include "GEOMImpl_IMeasure.hxx"
8
9 #include "GEOM_Function.hxx"
10
11 #include "utilities.h"
12 #include "OpUtil.hxx"
13 #include "Utils_ExceptHandlers.hxx"
14
15 #include <TFunction_DriverTable.hxx>
16 #include <TFunction_Driver.hxx>
17 #include <TFunction_Logbook.hxx>
18 #include <TDF_Tool.hxx>
19
20 #include <BRep_Tool.hxx>
21 #include <BRepCheck.hxx>
22 #include <BRepCheck_Result.hxx>
23 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
24 #include <BRepGProp.hxx>
25 #include <BRepBndLib.hxx>
26 #include <BRepExtrema_DistShapeShape.hxx>
27
28 #include <Bnd_Box.hxx>
29
30 #include <GProp_GProps.hxx>
31 #include <GProp_PrincipalProps.hxx>
32
33 #include <TopAbs.hxx>
34 #include <TopoDS.hxx>
35 #include <TopoDS_Edge.hxx>
36 #include <TopoDS_Face.hxx>
37 #include <TopoDS_Shape.hxx>
38 #include <TopoDS_Vertex.hxx>
39 #include <TopoDS_Iterator.hxx>
40 #include <TopExp_Explorer.hxx>
41 #include <TopTools_MapOfShape.hxx>
42 #include <TopTools_ListOfShape.hxx>
43 #include <TopTools_ListIteratorOfListOfShape.hxx>
44
45 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
46
47 //=============================================================================
48 /*!
49  *   constructor:
50  */
51 //=============================================================================
52 GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine, int theDocID)
53 : GEOM_IOperations(theEngine, theDocID)
54 {
55   MESSAGE("GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations");
56 }
57
58 //=============================================================================
59 /*!
60  *  destructor
61  */
62 //=============================================================================
63 GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations()
64 {
65   MESSAGE("GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations");
66 }
67
68
69 //=============================================================================
70 /*!
71  *  GetCentreOfMass
72  */
73 //=============================================================================
74 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
75                                                 (Handle(GEOM_Object) theShape)
76 {
77   SetErrorCode(KO);
78
79   if (theShape.IsNull()) return NULL;
80
81   //Add a new CentreOfMass object
82   Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GetDocID(), GEOM_CDG);
83
84   //Add a new CentreOfMass function
85   Handle(GEOM_Function) aFunction =
86     aCDG->AddFunction(GEOMImpl_MeasureDriver::GetID(), CDG_MEASURE);
87   if (aFunction.IsNull()) return NULL;
88
89   //Check if the function is set correctly
90   if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
91
92   GEOMImpl_IMeasure aCI (aFunction);
93
94   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
95   if (aRefShape.IsNull()) return NULL;
96
97   aCI.SetBase(aRefShape);
98
99   //Compute the CentreOfMass value
100   try {
101     if (!GetSolver()->ComputeFunction(aFunction)) {
102       SetErrorCode("Measure driver failed to compute centre of mass");
103       return NULL;
104     }
105   }
106   catch (Standard_Failure) {
107     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
108     SetErrorCode(aFail->GetMessageString());
109     return NULL;
110   }
111
112   //Make a Python command
113   TCollection_AsciiString anEntry, aDescr;
114   TDF_Tool::Entry(aCDG->GetEntry(), anEntry);
115   aDescr += anEntry + " = IMeasureOperations.MakeCentreOfMass(";
116   TDF_Tool::Entry(theShape->GetEntry(), anEntry);
117   aDescr += anEntry + ")";
118
119   aFunction->SetDescription(aDescr);
120
121   SetErrorCode(OK);
122   return aCDG;
123 }
124
125 //=============================================================================
126 /*!
127  *  GetBasicProperties
128  */
129 //=============================================================================
130 void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theShape,
131                                                       Standard_Real& theLength,
132                                                       Standard_Real& theSurfArea,
133                                                       Standard_Real& theVolume)
134 {
135   SetErrorCode(KO);
136
137   if (theShape.IsNull()) return;
138
139   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
140   if (aRefShape.IsNull()) return;
141
142   TopoDS_Shape aShape = aRefShape->GetValue();
143   if (aShape.IsNull()) {
144     SetErrorCode("The Objects has NULL Shape");
145     return;
146   }
147
148   //Compute the parameters
149   GProp_GProps LProps, SProps;
150   try {
151     BRepGProp::LinearProperties(aShape, LProps);
152     theLength = LProps.Mass();
153
154     BRepGProp::SurfaceProperties(aShape, SProps);
155     theSurfArea = SProps.Mass();
156
157     theVolume = 0.0;
158     if (aShape.ShapeType() < TopAbs_SHELL) {
159       for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
160         GProp_GProps VProps;
161         BRepGProp::VolumeProperties(Exp.Current(), VProps);
162         theVolume += VProps.Mass();
163       }
164     }
165   }
166   catch (Standard_Failure) {
167     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
168     SetErrorCode(aFail->GetMessageString());
169     return;
170   }
171
172   SetErrorCode(OK);
173 }
174
175 //=============================================================================
176 /*!
177  *  GetInertia
178  */
179 //=============================================================================
180 void GEOMImpl_IMeasureOperations::GetInertia
181                    (Handle(GEOM_Object) theShape,
182                     Standard_Real& I11, Standard_Real& I12, Standard_Real& I13,
183                     Standard_Real& I21, Standard_Real& I22, Standard_Real& I23,
184                     Standard_Real& I31, Standard_Real& I32, Standard_Real& I33,
185                     Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz)
186 {
187   SetErrorCode(KO);
188
189   if (theShape.IsNull()) return;
190
191   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
192   if (aRefShape.IsNull()) return;
193
194   TopoDS_Shape aShape = aRefShape->GetValue();
195   if (aShape.IsNull()) {
196     SetErrorCode("The Objects has NULL Shape");
197     return;
198   }
199
200   //Compute the parameters
201   GProp_GProps System;
202
203   try {
204     if (aShape.ShapeType() == TopAbs_VERTEX ||
205         aShape.ShapeType() == TopAbs_EDGE ||
206         aShape.ShapeType() == TopAbs_WIRE) {
207       BRepGProp::LinearProperties(aShape, System);
208     } else if (aShape.ShapeType() == TopAbs_FACE ||
209                aShape.ShapeType() == TopAbs_SHELL) {
210       BRepGProp::SurfaceProperties(aShape, System);
211     } else {
212       BRepGProp::VolumeProperties(aShape, System);
213     }
214     gp_Mat I = System.MatrixOfInertia();
215
216     I11 = I(1,1);
217     I12 = I(1,2);
218     I13 = I(1,3);
219
220     I21 = I(2,1);
221     I22 = I(2,2);
222     I23 = I(2,3);
223
224     I31 = I(3,1);
225     I32 = I(3,2);
226     I33 = I(3,3);
227
228     GProp_PrincipalProps Pr = System.PrincipalProperties();
229     Pr.Moments(Ix,Iy,Iz);
230   }
231   catch (Standard_Failure) {
232     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
233     SetErrorCode(aFail->GetMessageString());
234     return;
235   }
236
237   SetErrorCode(OK);
238 }
239
240 //=============================================================================
241 /*!
242  *  GetBoundingBox
243  */
244 //=============================================================================
245 void GEOMImpl_IMeasureOperations::GetBoundingBox
246                                      (Handle(GEOM_Object) theShape,
247                                       Standard_Real& Xmin, Standard_Real& Xmax,
248                                       Standard_Real& Ymin, Standard_Real& Ymax,
249                                       Standard_Real& Zmin, Standard_Real& Zmax)
250 {
251   SetErrorCode(KO);
252
253   if (theShape.IsNull()) return;
254
255   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
256   if (aRefShape.IsNull()) return;
257
258   TopoDS_Shape aShape = aRefShape->GetValue();
259   if (aShape.IsNull()) {
260     SetErrorCode("The Objects has NULL Shape");
261     return;
262   }
263
264   //Compute the parameters
265   Bnd_Box B;
266
267   try {
268     BRepBndLib::Add(aShape, B);
269     B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
270   }
271   catch (Standard_Failure) {
272     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
273     SetErrorCode(aFail->GetMessageString());
274     return;
275   }
276
277   SetErrorCode(OK);
278 }
279
280 //=============================================================================
281 /*!
282  *  GetTolerance
283  */
284 //=============================================================================
285 void GEOMImpl_IMeasureOperations::GetTolerance
286                                (Handle(GEOM_Object) theShape,
287                                 Standard_Real& FaceMin, Standard_Real& FaceMax,
288                                 Standard_Real& EdgeMin, Standard_Real& EdgeMax,
289                                 Standard_Real& VertMin, Standard_Real& VertMax)
290 {
291   SetErrorCode(KO);
292
293   if (theShape.IsNull()) return;
294
295   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
296   if (aRefShape.IsNull()) return;
297
298   TopoDS_Shape aShape = aRefShape->GetValue();
299   if (aShape.IsNull()) {
300     SetErrorCode("The Objects has NULL Shape");
301     return;
302   }
303
304   //Compute the parameters
305   Standard_Real T;
306   FaceMin = EdgeMin = VertMin = RealLast();
307   FaceMax = EdgeMax = VertMax = -RealLast();
308
309   try {
310     for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) {
311       TopoDS_Face Face = TopoDS::Face(ExF.Current());
312       T = BRep_Tool::Tolerance(Face);
313       if (T > FaceMax)
314         FaceMax = T;
315       if (T < FaceMin)
316         FaceMin = T;
317     }
318     for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) {
319       TopoDS_Edge Edge = TopoDS::Edge(ExE.Current());
320       T = BRep_Tool::Tolerance(Edge);
321       if (T > EdgeMax)
322         EdgeMax = T;
323       if (T < EdgeMin)
324         EdgeMin = T;
325     }
326     for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
327       TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
328       T = BRep_Tool::Tolerance(Vertex);
329       if (T > VertMax)
330         VertMax = T;
331       if (T < VertMin)
332         VertMin = T;
333     }
334   }
335   catch (Standard_Failure) {
336     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
337     SetErrorCode(aFail->GetMessageString());
338     return;
339   }
340
341   SetErrorCode(OK);
342 }
343
344 //=============================================================================
345 /*!
346  *  CheckShape
347  */
348 //=============================================================================
349 bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object)      theShape,
350                                               TCollection_AsciiString& theDump)
351 {
352   SetErrorCode(KO);
353
354   if (theShape.IsNull()) return false;
355
356   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
357   if (aRefShape.IsNull()) return false;
358
359   TopoDS_Shape aShape = aRefShape->GetValue();
360   if (aShape.IsNull()) {
361     SetErrorCode("The Objects has NULL Shape");
362     return false;
363   }
364
365   //Compute the parameters
366   bool isValid = false;
367   try {
368     BRepCheck_Analyzer ana (aShape, false);
369     if (ana.IsValid()) {
370       theDump.Clear();
371       isValid = true;
372     } else {
373       StructuralDump(ana, aShape, theDump);
374     }
375   }
376   catch (Standard_Failure) {
377     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
378     SetErrorCode(aFail->GetMessageString());
379     return false;
380   }
381
382   SetErrorCode(OK);
383   return isValid;
384 }
385
386 //=============================================================================
387 /*!
388  *  WhatIs
389  */
390 //=============================================================================
391 TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
392 {
393   SetErrorCode(KO);
394
395   TCollection_AsciiString Astr;
396
397   if (theShape.IsNull()) return Astr;
398
399   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
400   if (aRefShape.IsNull()) return Astr;
401
402   TopoDS_Shape aShape = aRefShape->GetValue();
403   if (aShape.IsNull()) {
404     SetErrorCode("The Objects has NULL Shape");
405     return Astr;
406   }
407
408   //Compute the parameters
409   if (aShape.ShapeType() == TopAbs_EDGE) {
410     if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
411       Astr = Astr + " It is a degenerated edge \n";
412     }
413   }
414
415   Astr = Astr + " Number of sub-shapes : \n";
416
417   try {
418     int iType, nbTypes [TopAbs_SHAPE];
419     for (iType = 0; iType < TopAbs_SHAPE; ++iType)
420       nbTypes[iType] = 0;
421     nbTypes[aShape.ShapeType()]++;
422
423     TopTools_MapOfShape aMapOfShape;
424     aMapOfShape.Add(aShape);
425     TopTools_ListOfShape aListOfShape;
426     aListOfShape.Append(aShape);
427
428     TopTools_ListIteratorOfListOfShape itL (aListOfShape);
429     for (; itL.More(); itL.Next()) {
430       TopoDS_Iterator it (itL.Value());
431       for (; it.More(); it.Next()) {
432         TopoDS_Shape s = it.Value();
433         if (aMapOfShape.Add(s)) {
434           aListOfShape.Append(s);
435           nbTypes[s.ShapeType()]++;
436         }
437       }
438     }
439
440     Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n";
441     Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n";
442     Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n";
443     Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n";
444     Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n";
445     Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n";
446     Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n";
447     Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n";
448     Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent());
449   }
450   catch (Standard_Failure) {
451     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
452     SetErrorCode(aFail->GetMessageString());
453     return Astr;
454   }
455
456   SetErrorCode(OK);
457   return Astr;
458 }
459
460 //=============================================================================
461 /*!
462  *  GetMinDistance
463  */
464 //=============================================================================
465 Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
466   (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
467    Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1,
468    Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2)
469 {
470   SetErrorCode(KO);
471   Standard_Real MinDist = 1.e9;
472
473   if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
474
475   Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
476   Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
477   if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
478
479   TopoDS_Shape aShape1 = aRefShape1->GetValue();
480   TopoDS_Shape aShape2 = aRefShape2->GetValue();
481   if (aShape1.IsNull() || aShape2.IsNull()) {
482     SetErrorCode("One of Objects has NULL Shape");
483     return MinDist;
484   }
485
486   //Compute the parameters
487   try {
488     BRepExtrema_DistShapeShape dst (aShape1, aShape2);
489     if (dst.IsDone()) {
490       gp_Pnt PMin1, PMin2, P1, P2;
491
492       for (int i = 1; i <= dst.NbSolution(); i++) {
493         P1 = dst.PointOnShape1(i);
494         P2 = dst.PointOnShape2(i);
495
496         Standard_Real Dist = P1.Distance(P2);
497         if (MinDist > Dist) {
498           MinDist = Dist;
499           PMin1 = P1;
500           PMin2 = P2;
501         }
502       }
503
504       PMin1.Coord(X1, Y1, Z1);
505       PMin2.Coord(X2, Y2, Z2);
506     }
507   }
508   catch (Standard_Failure) {
509     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
510     SetErrorCode(aFail->GetMessageString());
511     return MinDist;
512   }
513
514   SetErrorCode(OK);
515   return MinDist;
516 }
517
518 //=======================================================================
519 //function : PointCoordinates
520 //purpose  : Get coordinates of point
521 //=======================================================================
522 void GEOMImpl_IMeasureOperations::PointCoordinates( Handle(GEOM_Object) theShape,
523                         Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ )
524 {
525   SetErrorCode( KO );
526
527   if ( theShape.IsNull() )
528     return;
529
530   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
531   if ( aRefShape.IsNull() )
532     return;
533
534   TopoDS_Shape aShape = aRefShape->GetValue();
535   if ( aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX )
536   {
537     SetErrorCode( "Shape must be a vertex" );
538     return;
539   }
540
541   try
542   {
543     gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
544     theX = aPnt.X();
545     theY = aPnt.Y();
546     theZ = aPnt.Z();
547     SetErrorCode( OK );
548   }
549   catch ( Standard_Failure )
550   {
551     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
552     SetErrorCode( aFail->GetMessageString() );
553   }
554 }
555
556 //=======================================================================
557 //function : StructuralDump
558 //purpose  : Structural (data exchange) style of output.
559 //=======================================================================
560 void GEOMImpl_IMeasureOperations::StructuralDump (const BRepCheck_Analyzer& theAna,
561                                                   const TopoDS_Shape&       theShape,
562                                                   TCollection_AsciiString&  theDump)
563 {
564   Standard_Integer i;
565   theDump.Clear();
566   theDump += " -- The Shape has problems :\n";
567   theDump += "  Check                                    Count\n";
568   theDump += " ------------------------------------------------\n";
569
570   Standard_Integer last_stat = (Standard_Integer)BRepCheck_CheckFail;
571   Handle(TColStd_HArray1OfInteger) NbProblems =
572     new TColStd_HArray1OfInteger(1, last_stat);
573   for (i = 1; i <= last_stat; i++)
574     NbProblems->SetValue(i,0);
575
576   Handle(TopTools_HSequenceOfShape) sl;
577   sl = new TopTools_HSequenceOfShape();
578   TopTools_DataMapOfShapeListOfShape theMap;
579   theMap.Clear();
580   GetProblemShapes(theAna, theShape, sl, NbProblems, theMap);
581   theMap.Clear();
582
583   Standard_Integer count = 0;
584   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurve);
585   if (count > 0) {
586     theDump += "  Invalid Point on Curve ................... ";
587     theDump += TCollection_AsciiString(count) + "\n";
588   }
589   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurveOnSurface);
590   if (count > 0) {
591     theDump += "  Invalid Point on CurveOnSurface .......... ";
592     theDump += TCollection_AsciiString(count) + "\n";
593   }
594   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnSurface);
595   if (count > 0) {
596     theDump += "  Invalid Point on Surface ................. ";
597     theDump += TCollection_AsciiString(count) + "\n";
598   }
599   count = NbProblems->Value((Standard_Integer)BRepCheck_No3DCurve);
600   if (count > 0) {
601     theDump += "  No 3D Curve .............................. ";
602     theDump += TCollection_AsciiString(count) + "\n";
603   }
604   count = NbProblems->Value((Standard_Integer)BRepCheck_Multiple3DCurve);
605   if (count > 0) {
606     theDump += "  Multiple 3D Curve ........................ ";
607     theDump += TCollection_AsciiString(count) + "\n";
608   }
609   count = NbProblems->Value((Standard_Integer)BRepCheck_Invalid3DCurve);
610   if (count > 0) {
611     theDump += "  Invalid 3D Curve ......................... ";
612     theDump += TCollection_AsciiString(count) + "\n";
613   }
614   count = NbProblems->Value((Standard_Integer)BRepCheck_NoCurveOnSurface);
615   if (count > 0) {
616     theDump += "  No Curve on Surface ...................... ";
617     theDump += TCollection_AsciiString(count) + "\n";
618   }
619   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnSurface);
620   if (count > 0) {
621     theDump += "  Invalid Curve on Surface ................. ";
622     theDump += TCollection_AsciiString(count) + "\n";
623   }
624   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnClosedSurface);
625   if (count > 0) {
626     theDump += "  Invalid Curve on closed Surface .......... ";
627     theDump += TCollection_AsciiString(count) + "\n";
628   }
629   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameRangeFlag);
630   if (count > 0) {
631     theDump += "  Invalid SameRange Flag ................... ";
632     theDump += TCollection_AsciiString(count) + "\n";
633   }
634   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameParameterFlag);
635   if (count > 0) {
636     theDump += "  Invalid SameParameter Flag ............... ";
637     theDump += TCollection_AsciiString(count) + "\n";
638   }
639   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidDegeneratedFlag);
640   if (count > 0) {
641     theDump += "  Invalid Degenerated Flag ................. ";
642     theDump += TCollection_AsciiString(count) + "\n";
643   }
644   count = NbProblems->Value((Standard_Integer)BRepCheck_FreeEdge);
645   if (count > 0) {
646     theDump += "  Free Edge ................................ ";
647     theDump += TCollection_AsciiString(count) + "\n";
648   }
649   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidMultiConnexity);
650   if (count > 0) {
651     theDump += "  Invalid MultiConnexity ................... ";
652     theDump += TCollection_AsciiString(count) + "\n";
653   }
654   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidRange);
655   if (count > 0) {
656     theDump += "  Invalid Range ............................ ";
657     theDump += TCollection_AsciiString(count) + "\n";
658   }
659   count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyWire);
660   if (count > 0) {
661     theDump += "  Empty Wire ............................... ";
662     theDump += TCollection_AsciiString(count) + "\n";
663   }
664   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantEdge);
665   if (count > 0) {
666     theDump += "  Redundant Edge ........................... ";
667     theDump += TCollection_AsciiString(count) + "\n";
668   }
669   count = NbProblems->Value((Standard_Integer)BRepCheck_SelfIntersectingWire);
670   if (count > 0) {
671     theDump += "  Self Intersecting Wire ................... ";
672     theDump += TCollection_AsciiString(count) + "\n";
673   }
674   count = NbProblems->Value((Standard_Integer)BRepCheck_NoSurface);
675   if (count > 0) {
676     theDump += "  No Surface ............................... ";
677     theDump += TCollection_AsciiString(count) + "\n";
678   }
679   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidWire);
680   if (count > 0) {
681     theDump += "  Invalid Wire ............................. ";
682     theDump += TCollection_AsciiString(count) + "\n";
683   }
684   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantWire);
685   if (count > 0) {
686     theDump += "  Redundant Wire ........................... ";
687     theDump += TCollection_AsciiString(count) + "\n";
688   }
689   count = NbProblems->Value((Standard_Integer)BRepCheck_IntersectingWires);
690   if (count > 0) {
691     theDump += "  Intersecting Wires ....................... ";
692     theDump += TCollection_AsciiString(count) + "\n";
693   }
694   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidImbricationOfWires);
695   if (count > 0) {
696     theDump += "  Invalid Imbrication of Wires ............. ";
697     theDump += TCollection_AsciiString(count) + "\n";
698   }
699   count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyShell);
700   if (count > 0) {
701     theDump += "  Empty Shell .............................. ";
702     theDump += TCollection_AsciiString(count) + "\n";
703   }
704   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantFace);
705   if (count > 0) {
706     theDump += "  Redundant Face ........................... ";
707     theDump += TCollection_AsciiString(count) + "\n";
708   }
709   count = NbProblems->Value((Standard_Integer)BRepCheck_UnorientableShape);
710   if (count > 0) {
711     theDump += "  Unorientable Shape ....................... ";
712     theDump += TCollection_AsciiString(count) + "\n";
713   }
714   count = NbProblems->Value((Standard_Integer)BRepCheck_NotClosed);
715   if (count > 0) {
716     theDump += "  Not Closed ............................... ";
717     theDump += TCollection_AsciiString(count) + "\n";
718   }
719   count = NbProblems->Value((Standard_Integer)BRepCheck_NotConnected);
720   if (count > 0) {
721     theDump += "  Not Connected ............................ ";
722     theDump += TCollection_AsciiString(count) + "\n";
723   }
724   count = NbProblems->Value((Standard_Integer)BRepCheck_SubshapeNotInShape);
725   if (count > 0) {
726     theDump += "  Subshape not in Shape .................... ";
727     theDump += TCollection_AsciiString(count) + "\n";
728   }
729   count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientation);
730   if (count > 0) {
731     theDump += "  Bad Orientation .......................... ";
732     theDump += TCollection_AsciiString(count) + "\n";
733   }
734   count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientationOfSubshape);
735   if (count > 0) {
736     theDump += "  Bad Orientation of Subshape .............. ";
737     theDump += TCollection_AsciiString(count) + "\n";
738   }
739   count = NbProblems->Value((Standard_Integer)BRepCheck_CheckFail);
740   if (count > 0) {
741     theDump += "  checkshape failure ....................... ";
742     theDump += TCollection_AsciiString(count) + "\n";
743   }
744
745   theDump += " ------------------------------------------------\n";
746   theDump += "*** Shapes with problems : ";
747   theDump += TCollection_AsciiString(sl->Length()) + "\n";
748
749   Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
750   nbv = nbe = nbw = nbf = nbs = nbo = 0;
751
752   for (i = 1; i <= sl->Length(); i++) {
753     TopoDS_Shape shi = sl->Value(i);
754     TopAbs_ShapeEnum sti = shi.ShapeType();
755     switch (sti) {
756       case TopAbs_VERTEX : nbv++; break;
757       case TopAbs_EDGE   : nbe++; break;
758       case TopAbs_WIRE   : nbw++; break;
759       case TopAbs_FACE   : nbf++; break;
760       case TopAbs_SHELL  : nbs++; break;
761       case TopAbs_SOLID  : nbo++; break;
762       default            : break;
763     }
764   }
765
766   if (nbv > 0) {
767     theDump += "VERTEX : ";
768     if (nbv < 10) theDump += " ";
769     theDump += TCollection_AsciiString(nbv) + "\n";
770   }
771   if (nbe > 0) {
772     theDump += "EDGE   : ";
773     if (nbe < 10) theDump += " ";
774     theDump += TCollection_AsciiString(nbe) + "\n";
775   }
776   if (nbw > 0) {
777     theDump += "WIRE   : ";
778     if (nbw < 10) theDump += " ";
779     theDump += TCollection_AsciiString(nbw) + "\n";
780   }
781   if (nbf > 0) {
782     theDump += "FACE   : ";
783     if (nbf < 10) theDump += " ";
784     theDump += TCollection_AsciiString(nbf) + "\n";
785   }
786   if (nbs > 0) {
787     theDump += "SHELL  : ";
788     if (nbs < 10) theDump += " ";
789     theDump += TCollection_AsciiString(nbs) + "\n";
790   }
791   if (nbo > 0) {
792     theDump += "SOLID  : ";
793     if (nbo < 10) theDump += " ";
794     theDump += TCollection_AsciiString(nbo) + "\n";
795   }
796 }
797
798 //=======================================================================
799 //function : GetProblemShapes
800 // purpose : for StructuralDump
801 //=======================================================================
802 void GEOMImpl_IMeasureOperations::GetProblemShapes (const BRepCheck_Analyzer&           theAna,
803                                                     const TopoDS_Shape&                 theShape,
804                                                     Handle(TopTools_HSequenceOfShape)&  sl,
805                                                     Handle(TColStd_HArray1OfInteger)&   NbProblems,
806                                                     TopTools_DataMapOfShapeListOfShape& theMap)
807 {
808   for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
809     GetProblemShapes(theAna, iter.Value(), sl, NbProblems, theMap);
810   }
811   TopAbs_ShapeEnum styp = theShape.ShapeType();
812   BRepCheck_ListIteratorOfListOfStatus itl;
813   if (!theMap.IsBound(theShape)) {
814     theMap.Bind(theShape,TopTools_ListOfShape());
815
816     if (!theAna.Result(theShape).IsNull()) {
817       itl.Initialize(theAna.Result(theShape)->Status());
818       // !!! May be, we have to print all the problems, not only the first one ?
819       if (itl.Value() != BRepCheck_NoError) {
820         sl->Append(theShape);
821         BRepCheck_Status stat = itl.Value();
822         NbProblems->SetValue((Standard_Integer)stat,
823                              NbProblems->Value((Standard_Integer)stat) + 1);
824       }
825     }
826   }
827
828   switch (styp) {
829   case TopAbs_EDGE:
830     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
831     break;
832   case TopAbs_FACE:
833     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_WIRE, theMap);
834     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_EDGE, theMap);
835     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
836     break;
837   case TopAbs_SHELL:
838     break;
839   case TopAbs_SOLID:
840     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_SHELL, theMap);
841     break;
842   default:
843     break;
844   }
845 }
846
847 //=======================================================================
848 //function : Contains
849 //=======================================================================
850 static Standard_Boolean Contains (const TopTools_ListOfShape& L,
851                                   const TopoDS_Shape& S)
852 {
853   TopTools_ListIteratorOfListOfShape it;
854   for (it.Initialize(L); it.More(); it.Next()) {
855     if (it.Value().IsSame(S)) {
856       return Standard_True;
857     }
858   }
859   return Standard_False;
860 }
861
862 //=======================================================================
863 //function : GetProblemSub
864 // purpose : for StructuralDump
865 //=======================================================================
866 void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer&           theAna,
867                                                  const TopoDS_Shape&                 theShape,
868                                                  Handle(TopTools_HSequenceOfShape)&  sl,
869                                                  Handle(TColStd_HArray1OfInteger)&   NbProblems,
870                                                  const TopAbs_ShapeEnum              Subtype,
871                                                  TopTools_DataMapOfShapeListOfShape& theMap)
872 {
873   BRepCheck_ListIteratorOfListOfStatus itl;
874   TopExp_Explorer exp;
875   for (exp.Init(theShape, Subtype); exp.More(); exp.Next()) {
876     const TopoDS_Shape& sub = exp.Current();
877
878     const Handle(BRepCheck_Result)& res = theAna.Result(sub);
879     for (res->InitContextIterator();
880          res->MoreShapeInContext();
881          res->NextShapeInContext()) {
882       if (res->ContextualShape().IsSame(theShape) && !Contains(theMap(sub), theShape)) {
883         theMap(sub).Append(theShape);
884         itl.Initialize(res->StatusOnShape());
885
886         if (itl.Value() != BRepCheck_NoError) {
887           Standard_Integer ii = 0;
888
889           for (ii = 1; ii <= sl->Length(); ii++)
890             if (sl->Value(ii).IsSame(sub)) break;
891
892           if (ii > sl->Length()) {
893             sl->Append(sub);
894             BRepCheck_Status stat = itl.Value();
895             NbProblems->SetValue((Standard_Integer)stat,
896                                  NbProblems->Value((Standard_Integer)stat) + 1);
897           }
898           for (ii = 1; ii <= sl->Length(); ii++)
899             if (sl->Value(ii).IsSame(theShape)) break;
900           if (ii > sl->Length()) {
901             sl->Append(theShape);
902             BRepCheck_Status stat = itl.Value();
903             NbProblems->SetValue((Standard_Integer)stat,
904                                  NbProblems->Value((Standard_Integer)stat) + 1);
905           }
906         }
907         break;
908       }
909     }
910   }
911 }