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