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