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