Back to index

salome-geom  6.5.0
GEOMImpl_IMeasureOperations.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #include <Standard_Stream.hxx>
00024 
00025 #include <GEOMImpl_IMeasureOperations.hxx>
00026 
00027 #include <GEOMImpl_Types.hxx>
00028 #include <GEOMImpl_MeasureDriver.hxx>
00029 #include <GEOMImpl_IMeasure.hxx>
00030 #include <GEOMImpl_IShapesOperations.hxx>
00031 
00032 #include <GEOMAlgo_ShapeInfo.hxx>
00033 #include <GEOMAlgo_ShapeInfoFiller.hxx>
00034 
00035 #include <GEOM_Function.hxx>
00036 #include <GEOM_PythonDump.hxx>
00037 
00038 #include <NMTTools_CheckerSI.hxx>
00039 
00040 #include <NMTDS_Tools.hxx>
00041 #include <NMTDS_InterfPool.hxx>
00042 #include <NMTDS_PInterfPool.hxx>
00043 //#include <NMTDS_PassKeyBoolean.hxx>
00044 #include <NMTDS_PairBoolean.hxx>
00045 #include <NMTDS_ShapesDataStructure.hxx>
00046 //#include <NMTDS_ListIteratorOfListOfPassKeyBoolean.hxx>
00047 #include <NMTDS_ListIteratorOfListOfPairBoolean.hxx>
00048 
00049 #include <Basics_OCCTVersion.hxx>
00050 
00051 #include <utilities.h>
00052 #include <OpUtil.hxx>
00053 #include <Utils_ExceptHandlers.hxx>
00054 
00055 // OCCT Includes
00056 #include <TFunction_DriverTable.hxx>
00057 #include <TFunction_Driver.hxx>
00058 #include <TFunction_Logbook.hxx>
00059 #include <TDF_Tool.hxx>
00060 
00061 #include <BRep_Tool.hxx>
00062 #include <BRepAdaptor_Surface.hxx>
00063 #include <BRepBndLib.hxx>
00064 #include <BRepCheck.hxx>
00065 #include <BRepCheck_ListIteratorOfListOfStatus.hxx>
00066 #include <BRepCheck_Result.hxx>
00067 #include <BRepCheck_Shell.hxx>
00068 #include <BRepExtrema_DistShapeShape.hxx>
00069 #include <BRepGProp.hxx>
00070 #include <BRepTools.hxx>
00071 
00072 #include <Bnd_Box.hxx>
00073 
00074 #include <GProp_GProps.hxx>
00075 #include <GProp_PrincipalProps.hxx>
00076 
00077 #include <TopAbs.hxx>
00078 #include <TopExp.hxx>
00079 #include <TopoDS.hxx>
00080 #include <TopoDS_Edge.hxx>
00081 #include <TopoDS_Face.hxx>
00082 #include <TopoDS_Shape.hxx>
00083 #include <TopoDS_Vertex.hxx>
00084 #include <TopoDS_Iterator.hxx>
00085 #include <TopExp_Explorer.hxx>
00086 #include <TopTools_MapOfShape.hxx>
00087 #include <TopTools_ListOfShape.hxx>
00088 #include <TopTools_ListIteratorOfListOfShape.hxx>
00089 
00090 #include <GeomAbs_SurfaceType.hxx>
00091 #include <Geom_Surface.hxx>
00092 #include <Geom_Plane.hxx>
00093 #include <Geom_SphericalSurface.hxx>
00094 #include <Geom_CylindricalSurface.hxx>
00095 #include <Geom_ToroidalSurface.hxx>
00096 #include <Geom_ConicalSurface.hxx>
00097 #include <Geom_SurfaceOfLinearExtrusion.hxx>
00098 #include <Geom_SurfaceOfRevolution.hxx>
00099 #include <Geom_BezierSurface.hxx>
00100 #include <Geom_BSplineSurface.hxx>
00101 #include <Geom_RectangularTrimmedSurface.hxx>
00102 #include <Geom_OffsetSurface.hxx>
00103 #include <Geom_Line.hxx>
00104 
00105 #include <gp_Pln.hxx>
00106 #include <gp_Lin.hxx>
00107 
00108 #include <GeomAPI_ProjectPointOnCurve.hxx>
00109 #include <GeomLProp_CLProps.hxx>
00110 #include <GeomLProp_SLProps.hxx>
00111 #include <ShapeAnalysis.hxx>
00112 #include <ShapeAnalysis_Surface.hxx>
00113 
00114 #include <Standard_Failure.hxx>
00115 #include <Standard_ErrorHandler.hxx> // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC
00116 
00117 #include <BRepClass3d_SolidClassifier.hxx>
00118 #include <BRep_Builder.hxx>
00119 #include <GeomAPI_IntSS.hxx>
00120 #include <Geom_Circle.hxx>
00121 #include <Geom_SphericalSurface.hxx>
00122 #include <Geom_ToroidalSurface.hxx>
00123 #include <ShapeFix_Shape.hxx>
00124 #include <TopoDS_Compound.hxx>
00125 
00126 
00127 //=============================================================================
00131 //=============================================================================
00132 GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine, int theDocID)
00133 : GEOM_IOperations(theEngine, theDocID)
00134 {
00135   MESSAGE("GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations");
00136 }
00137 
00138 //=============================================================================
00142 //=============================================================================
00143 GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations()
00144 {
00145   MESSAGE("GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations");
00146 }
00147 
00148 //=============================================================================
00151 //=============================================================================
00152 GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape
00153                              (Handle(GEOM_Object) theShape,
00154                               Handle(TColStd_HSequenceOfInteger)& theIntegers,
00155                               Handle(TColStd_HSequenceOfReal)&    theDoubles)
00156 {
00157   SetErrorCode(KO);
00158   ShapeKind aKind = SK_NO_SHAPE;
00159 
00160   if (theIntegers.IsNull()) theIntegers = new TColStd_HSequenceOfInteger;
00161   else                      theIntegers->Clear();
00162 
00163   if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
00164   else                     theDoubles->Clear();
00165 
00166   if (theShape.IsNull())
00167     return aKind;
00168 
00169   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
00170   if (aRefShape.IsNull()) return aKind;
00171 
00172   TopoDS_Shape aShape = aRefShape->GetValue();
00173   if (aShape.IsNull()) return aKind;
00174 
00175   int geom_type = theShape->GetType();
00176 
00177   // check if it's advanced shape
00178   if ( geom_type > ADVANCED_BASE ) {
00179     SetErrorCode(OK);
00180     return SK_ADVANCED;
00181   }
00182 
00183   // Call algorithm
00184   GEOMAlgo_ShapeInfoFiller aSF;
00185   aSF.SetShape(aShape);
00186   aSF.Perform();
00187   Standard_Integer iErr = aSF.ErrorStatus();
00188   if (iErr) {
00189     SetErrorCode("Error in GEOMAlgo_ShapeInfoFiller");
00190     return SK_NO_SHAPE;
00191   }
00192   const GEOMAlgo_ShapeInfo& anInfo = aSF.Info();
00193 
00194   // Interprete results
00195   TopAbs_ShapeEnum aType = anInfo.Type();
00196   switch (aType)
00197   {
00198   case TopAbs_COMPOUND:
00199   case TopAbs_COMPSOLID:
00200     {
00201       // (+) geompy.kind.COMPOUND     nb_solids nb_faces nb_edges nb_vertices
00202       // (+) geompy.kind.COMPSOLID    nb_solids nb_faces nb_edges nb_vertices
00203       // ??? "nb_faces" - all faces or only 'standalone' faces?
00204       if (aType == TopAbs_COMPOUND)
00205         aKind = SK_COMPOUND;
00206       else
00207         aKind = SK_COMPSOLID;
00208 
00209       //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPOUND));
00210       //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPSOLID));
00211       theIntegers->Append(anInfo.NbSubShapes(TopAbs_SOLID));
00212       theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
00213       theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
00214       theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00215     }
00216     break;
00217 
00218   case TopAbs_SHELL:
00219     {
00220       // (+) geompy.kind.SHELL  geompy.info.closed   nb_faces nb_edges nb_vertices
00221       // (+) geompy.kind.SHELL  geompy.info.unclosed nb_faces nb_edges nb_vertices
00222       aKind = SK_SHELL;
00223 
00224       theIntegers->Append((int)anInfo.KindOfClosed());
00225 
00226       theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
00227       theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
00228       theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00229     }
00230     break;
00231 
00232   case TopAbs_WIRE:
00233     {
00234       // (+) geompy.kind.WIRE  geompy.info.closed   nb_edges nb_vertices
00235       // (+) geompy.kind.WIRE  geompy.info.unclosed nb_edges nb_vertices
00236       aKind = SK_WIRE;
00237 
00238       theIntegers->Append((int)anInfo.KindOfClosed());
00239 
00240       theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
00241       theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00242     }
00243     break;
00244 
00245   case TopAbs_SOLID:
00246     {
00247       aKind = SK_SOLID;
00248 
00249       GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
00250       switch (aKN)
00251       {
00252       case GEOMAlgo_KN_SPHERE:
00253         // (+) geompy.kind.SPHERE  xc yc zc  R
00254         {
00255           aKind = SK_SPHERE;
00256 
00257           gp_Pnt aC = anInfo.Location();
00258           theDoubles->Append(aC.X());
00259           theDoubles->Append(aC.Y());
00260           theDoubles->Append(aC.Z());
00261 
00262           theDoubles->Append(anInfo.Radius1());
00263         }
00264         break;
00265       case GEOMAlgo_KN_CYLINDER:
00266         // (+) geompy.kind.CYLINDER  xb yb zb  dx dy dz  R  H
00267         {
00268           aKind = SK_CYLINDER;
00269 
00270           gp_Pnt aC = anInfo.Location();
00271           theDoubles->Append(aC.X());
00272           theDoubles->Append(aC.Y());
00273           theDoubles->Append(aC.Z());
00274 
00275           gp_Ax3 anAx3 = anInfo.Position();
00276           gp_Dir aD = anAx3.Direction();
00277           theDoubles->Append(aD.X());
00278           theDoubles->Append(aD.Y());
00279           theDoubles->Append(aD.Z());
00280 
00281           theDoubles->Append(anInfo.Radius1());
00282           theDoubles->Append(anInfo.Height());
00283         }
00284         break;
00285       case GEOMAlgo_KN_BOX:
00286         // (+) geompy.kind.BOX  xc yc zc  ax ay az
00287         {
00288           aKind = SK_BOX;
00289 
00290           gp_Pnt aC = anInfo.Location();
00291           theDoubles->Append(aC.X());
00292           theDoubles->Append(aC.Y());
00293           theDoubles->Append(aC.Z());
00294 
00295           gp_Ax3 anAx3 = anInfo.Position();
00296           gp_Dir aD = anAx3.Direction();
00297           gp_Dir aX = anAx3.XDirection();
00298 
00299           // ax ay az
00300           if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
00301               aX.IsParallel(gp::DX(), Precision::Angular())) {
00302             theDoubles->Append(anInfo.Length()); // ax'
00303             theDoubles->Append(anInfo.Width());  // ay'
00304             theDoubles->Append(anInfo.Height()); // az'
00305           }
00306           else if (aD.IsParallel(gp::DZ(), Precision::Angular()) &&
00307                    aX.IsParallel(gp::DY(), Precision::Angular())) {
00308             theDoubles->Append(anInfo.Width());  // ay'
00309             theDoubles->Append(anInfo.Length()); // ax'
00310             theDoubles->Append(anInfo.Height()); // az'
00311           }
00312           else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
00313                    aX.IsParallel(gp::DZ(), Precision::Angular())) {
00314             theDoubles->Append(anInfo.Height()); // az'
00315             theDoubles->Append(anInfo.Width());  // ay'
00316             theDoubles->Append(anInfo.Length()); // ax'
00317           }
00318           else if (aD.IsParallel(gp::DX(), Precision::Angular()) &&
00319                    aX.IsParallel(gp::DY(), Precision::Angular())) {
00320             theDoubles->Append(anInfo.Height()); // az'
00321             theDoubles->Append(anInfo.Length()); // ax'
00322             theDoubles->Append(anInfo.Width());  // ay'
00323           }
00324           else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
00325                    aX.IsParallel(gp::DZ(), Precision::Angular())) {
00326             theDoubles->Append(anInfo.Width());  // ay'
00327             theDoubles->Append(anInfo.Height()); // az'
00328             theDoubles->Append(anInfo.Length()); // ax'
00329           }
00330           else if (aD.IsParallel(gp::DY(), Precision::Angular()) &&
00331                    aX.IsParallel(gp::DX(), Precision::Angular())) {
00332             theDoubles->Append(anInfo.Length()); // ax'
00333             theDoubles->Append(anInfo.Height()); // az'
00334             theDoubles->Append(anInfo.Width());  // ay'
00335           }
00336           else {
00337             // (+) geompy.kind.ROTATED_BOX  xo yo zo  zx zy zz  xx xy xz  ax ay az
00338             aKind = SK_ROTATED_BOX;
00339 
00340             // Direction and XDirection
00341             theDoubles->Append(aD.X());
00342             theDoubles->Append(aD.Y());
00343             theDoubles->Append(aD.Z());
00344 
00345             theDoubles->Append(aX.X());
00346             theDoubles->Append(aX.Y());
00347             theDoubles->Append(aX.Z());
00348 
00349             // ax ay az
00350             theDoubles->Append(anInfo.Length());
00351             theDoubles->Append(anInfo.Width());
00352             theDoubles->Append(anInfo.Height());
00353           }
00354         }
00355         break;
00356       case GEOMAlgo_KN_TORUS:
00357         // (+) geompy.kind.TORUS  xc yc zc  dx dy dz  R_1 R_2
00358         {
00359           aKind = SK_TORUS;
00360 
00361           gp_Pnt aO = anInfo.Location();
00362           theDoubles->Append(aO.X());
00363           theDoubles->Append(aO.Y());
00364           theDoubles->Append(aO.Z());
00365 
00366           gp_Ax3 anAx3 = anInfo.Position();
00367           gp_Dir aD = anAx3.Direction();
00368           theDoubles->Append(aD.X());
00369           theDoubles->Append(aD.Y());
00370           theDoubles->Append(aD.Z());
00371 
00372           theDoubles->Append(anInfo.Radius1());
00373           theDoubles->Append(anInfo.Radius2());
00374         }
00375         break;
00376       case GEOMAlgo_KN_CONE:
00377         // (+) geompy.kind.CONE  xb yb zb  dx dy dz  R_1 R_2  H
00378         {
00379           aKind = SK_CONE;
00380 
00381           gp_Pnt aO = anInfo.Location();
00382           theDoubles->Append(aO.X());
00383           theDoubles->Append(aO.Y());
00384           theDoubles->Append(aO.Z());
00385 
00386           gp_Ax3 anAx3 = anInfo.Position();
00387           gp_Dir aD = anAx3.Direction();
00388           theDoubles->Append(aD.X());
00389           theDoubles->Append(aD.Y());
00390           theDoubles->Append(aD.Z());
00391 
00392           theDoubles->Append(anInfo.Radius1());
00393           theDoubles->Append(anInfo.Radius2());
00394           theDoubles->Append(anInfo.Height());
00395         }
00396         break;
00397       case GEOMAlgo_KN_POLYHEDRON:
00398         // (+) geompy.kind.POLYHEDRON  nb_faces nb_edges nb_vertices
00399         {
00400           aKind = SK_POLYHEDRON;
00401 
00402           theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
00403           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
00404           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00405         }
00406         break;
00407       default:
00408         // (+) geompy.kind.SOLID  nb_faces nb_edges nb_vertices
00409         {
00410           theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE));
00411           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
00412           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00413         }
00414       }
00415     }
00416     break;
00417 
00418   case TopAbs_FACE:
00419     {
00420       aKind = SK_FACE;
00421 
00422       GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
00423       switch (aKN) {
00424       case GEOMAlgo_KN_SPHERE:
00425         // (+) geompy.kind.SPHERE2D  xc yc zc  R
00426         {
00427           aKind = SK_SPHERE2D;
00428 
00429           gp_Pnt aC = anInfo.Location();
00430           theDoubles->Append(aC.X());
00431           theDoubles->Append(aC.Y());
00432           theDoubles->Append(aC.Z());
00433 
00434           theDoubles->Append(anInfo.Radius1());
00435         }
00436         break;
00437       case GEOMAlgo_KN_CYLINDER:
00438         // (+) geompy.kind.CYLINDER2D  xb yb zb  dx dy dz  R  H
00439         {
00440           aKind = SK_CYLINDER2D;
00441 
00442           gp_Pnt aO = anInfo.Location();
00443           theDoubles->Append(aO.X());
00444           theDoubles->Append(aO.Y());
00445           theDoubles->Append(aO.Z());
00446 
00447           gp_Ax3 anAx3 = anInfo.Position();
00448           gp_Dir aD = anAx3.Direction();
00449           theDoubles->Append(aD.X());
00450           theDoubles->Append(aD.Y());
00451           theDoubles->Append(aD.Z());
00452 
00453           theDoubles->Append(anInfo.Radius1());
00454           theDoubles->Append(anInfo.Height());
00455         }
00456         break;
00457       case GEOMAlgo_KN_TORUS:
00458         // (+) geompy.kind.TORUS2D  xc yc zc  dx dy dz  R_1 R_2
00459         {
00460           aKind = SK_TORUS2D;
00461 
00462           gp_Pnt aO = anInfo.Location();
00463           theDoubles->Append(aO.X());
00464           theDoubles->Append(aO.Y());
00465           theDoubles->Append(aO.Z());
00466 
00467           gp_Ax3 anAx3 = anInfo.Position();
00468           gp_Dir aD = anAx3.Direction();
00469           theDoubles->Append(aD.X());
00470           theDoubles->Append(aD.Y());
00471           theDoubles->Append(aD.Z());
00472 
00473           theDoubles->Append(anInfo.Radius1());
00474           theDoubles->Append(anInfo.Radius2());
00475         }
00476         break;
00477       case GEOMAlgo_KN_CONE:
00478         // (+) geompy.kind.CONE2D  xc yc zc  dx dy dz  R_1 R_2  H
00479         {
00480           aKind = SK_CONE2D;
00481 
00482           gp_Pnt aO = anInfo.Location();
00483           theDoubles->Append(aO.X());
00484           theDoubles->Append(aO.Y());
00485           theDoubles->Append(aO.Z());
00486 
00487           gp_Ax3 anAx3 = anInfo.Position();
00488           gp_Dir aD = anAx3.Direction();
00489           theDoubles->Append(aD.X());
00490           theDoubles->Append(aD.Y());
00491           theDoubles->Append(aD.Z());
00492 
00493           theDoubles->Append(anInfo.Radius1());
00494           theDoubles->Append(anInfo.Radius2());
00495           theDoubles->Append(anInfo.Height());
00496         }
00497         break;
00498       case GEOMAlgo_KN_DISKCIRCLE:
00499         // (+) geompy.kind.DISK_CIRCLE  xc yc zc  dx dy dz  R
00500         {
00501           aKind = SK_DISK_CIRCLE;
00502 
00503           gp_Pnt aC = anInfo.Location();
00504           theDoubles->Append(aC.X());
00505           theDoubles->Append(aC.Y());
00506           theDoubles->Append(aC.Z());
00507 
00508           gp_Ax3 anAx3 = anInfo.Position();
00509           gp_Dir aD = anAx3.Direction();
00510           theDoubles->Append(aD.X());
00511           theDoubles->Append(aD.Y());
00512           theDoubles->Append(aD.Z());
00513 
00514           theDoubles->Append(anInfo.Radius1());
00515         }
00516         break;
00517       case GEOMAlgo_KN_DISKELLIPSE:
00518         // (+) geompy.kind.DISK_ELLIPSE  xc yc zc  dx dy dz  R_1 R_2
00519         {
00520           aKind = SK_DISK_ELLIPSE;
00521 
00522           gp_Pnt aC = anInfo.Location();
00523           theDoubles->Append(aC.X());
00524           theDoubles->Append(aC.Y());
00525           theDoubles->Append(aC.Z());
00526 
00527           gp_Ax3 anAx3 = anInfo.Position();
00528           gp_Dir aD = anAx3.Direction();
00529           theDoubles->Append(aD.X());
00530           theDoubles->Append(aD.Y());
00531           theDoubles->Append(aD.Z());
00532 
00533           theDoubles->Append(anInfo.Radius1());
00534           theDoubles->Append(anInfo.Radius2());
00535         }
00536         break;
00537       case GEOMAlgo_KN_RECTANGLE:
00538       case GEOMAlgo_KN_TRIANGLE:
00539       case GEOMAlgo_KN_QUADRANGLE:
00540       case GEOMAlgo_KN_POLYGON:
00541         // (+) geompy.kind.POLYGON  xo yo zo  dx dy dz  nb_edges nb_vertices
00542         {
00543           aKind = SK_POLYGON;
00544 
00545           gp_Pnt aO = anInfo.Location();
00546           theDoubles->Append(aO.X());
00547           theDoubles->Append(aO.Y());
00548           theDoubles->Append(aO.Z());
00549 
00550           gp_Ax3 anAx3 = anInfo.Position();
00551           gp_Dir aD = anAx3.Direction();
00552           theDoubles->Append(aD.X());
00553           theDoubles->Append(aD.Y());
00554           theDoubles->Append(aD.Z());
00555 
00556           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
00557           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00558         }
00559         break;
00560       case GEOMAlgo_KN_PLANE: // infinite
00561         // (+) geompy.kind.PLANE  xo yo zo  dx dy dz
00562         {
00563           aKind = SK_PLANE;
00564 
00565           gp_Pnt aC = anInfo.Location();
00566           theDoubles->Append(aC.X());
00567           theDoubles->Append(aC.Y());
00568           theDoubles->Append(aC.Z());
00569 
00570           gp_Ax3 anAx3 = anInfo.Position();
00571           gp_Dir aD = anAx3.Direction();
00572           theDoubles->Append(aD.X());
00573           theDoubles->Append(aD.Y());
00574           theDoubles->Append(aD.Z());
00575         }
00576         break;
00577       default:
00578         if (anInfo.KindOfShape() == GEOMAlgo_KS_PLANE) {
00579           // (+) geompy.kind.PLANAR  xo yo zo  dx dy dz  nb_edges nb_vertices
00580 
00581           aKind = SK_PLANAR;
00582 
00583           gp_Pnt aC = anInfo.Location();
00584           theDoubles->Append(aC.X());
00585           theDoubles->Append(aC.Y());
00586           theDoubles->Append(aC.Z());
00587 
00588           gp_Ax3 anAx3 = anInfo.Position();
00589           gp_Dir aD = anAx3.Direction();
00590           theDoubles->Append(aD.X());
00591           theDoubles->Append(aD.Y());
00592           theDoubles->Append(aD.Z());
00593 
00594           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
00595           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00596         }
00597         else {
00598           // ??? geompy.kind.FACE  nb_edges nb_vertices _surface_type_id_
00599           // (+) geompy.kind.FACE  nb_edges nb_vertices
00600 
00601           theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE));
00602           theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00603         }
00604       }
00605     }
00606     break;
00607 
00608   case TopAbs_EDGE:
00609     {
00610       aKind = SK_EDGE;
00611 
00612       GEOMAlgo_KindOfName aKN = anInfo.KindOfName();
00613       switch (aKN) {
00614       case GEOMAlgo_KN_CIRCLE:
00615         {
00616           // (+) geompy.kind.CIRCLE  xc yc zc  dx dy dz  R
00617           aKind = SK_CIRCLE;
00618 
00619           gp_Pnt aC = anInfo.Location();
00620           theDoubles->Append(aC.X());
00621           theDoubles->Append(aC.Y());
00622           theDoubles->Append(aC.Z());
00623 
00624           gp_Ax3 anAx3 = anInfo.Position();
00625           gp_Dir aD = anAx3.Direction();
00626           theDoubles->Append(aD.X());
00627           theDoubles->Append(aD.Y());
00628           theDoubles->Append(aD.Z());
00629 
00630           theDoubles->Append(anInfo.Radius1());
00631         }
00632         break;
00633       case GEOMAlgo_KN_ARCCIRCLE:
00634         {
00635           // (+) geompy.kind.ARC_CIRCLE  xc yc zc  dx dy dz  R  x1 y1 z1  x2 y2 z2
00636           aKind = SK_ARC_CIRCLE;
00637 
00638           gp_Pnt aC = anInfo.Location();
00639           theDoubles->Append(aC.X());
00640           theDoubles->Append(aC.Y());
00641           theDoubles->Append(aC.Z());
00642 
00643           gp_Ax3 anAx3 = anInfo.Position();
00644           gp_Dir aD = anAx3.Direction();
00645           theDoubles->Append(aD.X());
00646           theDoubles->Append(aD.Y());
00647           theDoubles->Append(aD.Z());
00648 
00649           theDoubles->Append(anInfo.Radius1());
00650 
00651           gp_Pnt aP1 = anInfo.Pnt1();
00652           theDoubles->Append(aP1.X());
00653           theDoubles->Append(aP1.Y());
00654           theDoubles->Append(aP1.Z());
00655 
00656           gp_Pnt aP2 = anInfo.Pnt2();
00657           theDoubles->Append(aP2.X());
00658           theDoubles->Append(aP2.Y());
00659           theDoubles->Append(aP2.Z());
00660         }
00661         break;
00662       case GEOMAlgo_KN_ELLIPSE:
00663         {
00664           // (+) geompy.kind.ELLIPSE  xc yc zc  dx dy dz  R_1 R_2
00665           aKind = SK_ELLIPSE;
00666 
00667           gp_Pnt aC = anInfo.Location();
00668           theDoubles->Append(aC.X());
00669           theDoubles->Append(aC.Y());
00670           theDoubles->Append(aC.Z());
00671 
00672           gp_Ax3 anAx3 = anInfo.Position();
00673           gp_Dir aD = anAx3.Direction();
00674           theDoubles->Append(aD.X());
00675           theDoubles->Append(aD.Y());
00676           theDoubles->Append(aD.Z());
00677 
00678           theDoubles->Append(anInfo.Radius1());
00679           theDoubles->Append(anInfo.Radius2());
00680         }
00681         break;
00682       case GEOMAlgo_KN_ARCELLIPSE:
00683         {
00684           // (+) geompy.kind.ARC_ELLIPSE  xc yc zc  dx dy dz  R_1 R_2  x1 y1 z1  x2 y2 z2
00685           aKind = SK_ARC_ELLIPSE;
00686 
00687           gp_Pnt aC = anInfo.Location();
00688           theDoubles->Append(aC.X());
00689           theDoubles->Append(aC.Y());
00690           theDoubles->Append(aC.Z());
00691 
00692           gp_Ax3 anAx3 = anInfo.Position();
00693           gp_Dir aD = anAx3.Direction();
00694           theDoubles->Append(aD.X());
00695           theDoubles->Append(aD.Y());
00696           theDoubles->Append(aD.Z());
00697 
00698           theDoubles->Append(anInfo.Radius1());
00699           theDoubles->Append(anInfo.Radius2());
00700 
00701           gp_Pnt aP1 = anInfo.Pnt1();
00702           theDoubles->Append(aP1.X());
00703           theDoubles->Append(aP1.Y());
00704           theDoubles->Append(aP1.Z());
00705 
00706           gp_Pnt aP2 = anInfo.Pnt2();
00707           theDoubles->Append(aP2.X());
00708           theDoubles->Append(aP2.Y());
00709           theDoubles->Append(aP2.Z());
00710         }
00711         break;
00712       case GEOMAlgo_KN_LINE:
00713         {
00714           // ??? geompy.kind.LINE  x1 y1 z1  x2 y2 z2
00715           // (+) geompy.kind.LINE  x1 y1 z1  dx dy dz
00716           aKind = SK_LINE;
00717 
00718           gp_Pnt aO = anInfo.Location();
00719           theDoubles->Append(aO.X());
00720           theDoubles->Append(aO.Y());
00721           theDoubles->Append(aO.Z());
00722 
00723           gp_Dir aD = anInfo.Direction();
00724           theDoubles->Append(aD.X());
00725           theDoubles->Append(aD.Y());
00726           theDoubles->Append(aD.Z());
00727         }
00728         break;
00729       case GEOMAlgo_KN_SEGMENT:
00730         {
00731           // (+) geompy.kind.SEGMENT  x1 y1 z1  x2 y2 z2
00732           aKind = SK_SEGMENT;
00733 
00734           gp_Pnt aP1 = anInfo.Pnt1();
00735           theDoubles->Append(aP1.X());
00736           theDoubles->Append(aP1.Y());
00737           theDoubles->Append(aP1.Z());
00738 
00739           gp_Pnt aP2 = anInfo.Pnt2();
00740           theDoubles->Append(aP2.X());
00741           theDoubles->Append(aP2.Y());
00742           theDoubles->Append(aP2.Z());
00743         }
00744         break;
00745       default:
00746         // ??? geompy.kind.EDGE  nb_vertices _curve_type_id_
00747         // (+) geompy.kind.EDGE  nb_vertices
00748         theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX));
00749       }
00750     }
00751     break;
00752 
00753   case TopAbs_VERTEX:
00754     {
00755       // (+) geompy.kind.VERTEX  x y z
00756       aKind = SK_VERTEX;
00757 
00758       gp_Pnt aP = anInfo.Location();
00759       theDoubles->Append(aP.X());
00760       theDoubles->Append(aP.Y());
00761       theDoubles->Append(aP.Z());
00762     }
00763     break;
00764   }
00765 
00766   SetErrorCode(OK);
00767   return aKind;
00768 }
00769 
00770 //=============================================================================
00776 //=============================================================================
00777 gp_Ax3 GEOMImpl_IMeasureOperations::GetPosition (const TopoDS_Shape& theShape)
00778 {
00779   gp_Ax3 aResult;
00780 
00781   if (theShape.IsNull())
00782     return aResult;
00783 
00784   // Axes
00785   aResult.Transform(theShape.Location().Transformation());
00786   if (theShape.ShapeType() == TopAbs_FACE) {
00787     Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape));
00788     if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) {
00789       Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS);
00790       gp_Pln aPln = aGPlane->Pln();
00791       aResult = aPln.Position();
00792       // In case of reverse orinetation of the face invert the plane normal
00793       // (the face's normal does not mathc the plane's normal in this case)
00794       if(theShape.Orientation() == TopAbs_REVERSED)
00795       {
00796         gp_Dir Vx =  aResult.XDirection();
00797         gp_Dir N  =  aResult.Direction().Mirrored(Vx); 
00798         gp_Pnt P  =  aResult.Location();
00799         aResult = gp_Ax3(P, N, Vx);
00800       }       
00801     }
00802   }
00803 
00804   // Origin
00805   gp_Pnt aPnt;
00806 
00807   TopAbs_ShapeEnum aShType = theShape.ShapeType();
00808 
00809   if (aShType == TopAbs_VERTEX) {
00810     aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape));
00811   }
00812   else {
00813     if (aShType == TopAbs_COMPOUND) {
00814       aShType = GEOMImpl_IShapesOperations::GetTypeOfSimplePart(theShape);
00815     }
00816 
00817     GProp_GProps aSystem;
00818     if (aShType == TopAbs_EDGE || aShType == TopAbs_WIRE)
00819       BRepGProp::LinearProperties(theShape, aSystem);
00820     else if (aShType == TopAbs_FACE || aShType == TopAbs_SHELL)
00821       BRepGProp::SurfaceProperties(theShape, aSystem);
00822     else
00823       BRepGProp::VolumeProperties(theShape, aSystem);
00824 
00825     aPnt = aSystem.CentreOfMass();
00826   }
00827 
00828   aResult.SetLocation(aPnt);
00829 
00830   return aResult;
00831 }
00832 
00833 //=============================================================================
00837 //=============================================================================
00838 void GEOMImpl_IMeasureOperations::GetPosition
00839                    (Handle(GEOM_Object) theShape,
00840                     Standard_Real& Ox, Standard_Real& Oy, Standard_Real& Oz,
00841                     Standard_Real& Zx, Standard_Real& Zy, Standard_Real& Zz,
00842                     Standard_Real& Xx, Standard_Real& Xy, Standard_Real& Xz)
00843 {
00844   SetErrorCode(KO);
00845 
00846   //Set default values: global CS
00847   Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.;
00848   Zz = Xx = 1.;
00849 
00850   if (theShape.IsNull()) return;
00851 
00852   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
00853   if (aRefShape.IsNull()) return;
00854 
00855   TopoDS_Shape aShape = aRefShape->GetValue();
00856   if (aShape.IsNull()) {
00857     SetErrorCode("The Objects has NULL Shape");
00858     return;
00859   }
00860 
00861   try {
00862 #if OCC_VERSION_LARGE > 0x06010000
00863     OCC_CATCH_SIGNALS;
00864 #endif
00865 
00866     gp_Ax3 anAx3 = GetPosition(aShape);
00867 
00868     gp_Pnt anOri = anAx3.Location();
00869     gp_Dir aDirZ = anAx3.Direction();
00870     gp_Dir aDirX = anAx3.XDirection();
00871 
00872     // Output values
00873     anOri.Coord(Ox, Oy, Oz);
00874     aDirZ.Coord(Zx, Zy, Zz);
00875     aDirX.Coord(Xx, Xy, Xz);
00876   }
00877   catch (Standard_Failure) {
00878     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00879     SetErrorCode(aFail->GetMessageString());
00880     return;
00881   }
00882 
00883   SetErrorCode(OK);
00884 }
00885 
00886 //=============================================================================
00890 //=============================================================================
00891 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass
00892                                                 (Handle(GEOM_Object) theShape)
00893 {
00894   SetErrorCode(KO);
00895 
00896   if (theShape.IsNull()) return NULL;
00897 
00898   //Add a new CentreOfMass object
00899   Handle(GEOM_Object) aCDG = GetEngine()->AddObject(GetDocID(), GEOM_CDG);
00900 
00901   //Add a new CentreOfMass function
00902   Handle(GEOM_Function) aFunction =
00903     aCDG->AddFunction(GEOMImpl_MeasureDriver::GetID(), CDG_MEASURE);
00904   if (aFunction.IsNull()) return NULL;
00905 
00906   //Check if the function is set correctly
00907   if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
00908 
00909   GEOMImpl_IMeasure aCI (aFunction);
00910 
00911   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
00912   if (aRefShape.IsNull()) return NULL;
00913 
00914   aCI.SetBase(aRefShape);
00915 
00916   //Compute the CentreOfMass value
00917   try {
00918 #if OCC_VERSION_LARGE > 0x06010000
00919     OCC_CATCH_SIGNALS;
00920 #endif
00921     if (!GetSolver()->ComputeFunction(aFunction)) {
00922       SetErrorCode("Measure driver failed to compute centre of mass");
00923       return NULL;
00924     }
00925   }
00926   catch (Standard_Failure) {
00927     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00928     SetErrorCode(aFail->GetMessageString());
00929     return NULL;
00930   }
00931 
00932   //Make a Python command
00933   GEOM::TPythonDump(aFunction) << aCDG << " = geompy.MakeCDG(" << theShape << ")";
00934 
00935   SetErrorCode(OK);
00936   return aCDG;
00937 }
00938 
00939 //=============================================================================
00943 //=============================================================================
00944 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetVertexByIndex
00945                                                 (Handle(GEOM_Object) theShape,
00946                                                  Standard_Integer theIndex)
00947 {
00948   SetErrorCode(KO);
00949 
00950   if (theShape.IsNull()) return NULL;
00951 
00952   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
00953   if (aRefShape.IsNull()) return NULL;
00954 
00955   //Add a new Vertex object
00956   Handle(GEOM_Object) aVertex = GetEngine()->AddObject(GetDocID(), GEOM_POINT);
00957 
00958   //Add a function
00959   Handle(GEOM_Function) aFunction =
00960     aVertex->AddFunction(GEOMImpl_MeasureDriver::GetID(), VERTEX_BY_INDEX);
00961   if (aFunction.IsNull()) return NULL;
00962 
00963   //Check if the function is set correctly
00964   if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
00965 
00966   GEOMImpl_IMeasure aCI (aFunction);
00967   aCI.SetBase(aRefShape);
00968   aCI.SetIndex(theIndex);
00969 
00970   //Compute
00971   try {
00972 #if OCC_VERSION_LARGE > 0x06010000
00973     OCC_CATCH_SIGNALS;
00974 #endif
00975     if (!GetSolver()->ComputeFunction(aFunction)) {
00976       SetErrorCode("Vertex by index driver failed.");
00977       return NULL;
00978     }
00979   }
00980   catch (Standard_Failure) {
00981     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
00982     SetErrorCode(aFail->GetMessageString());
00983     return NULL;
00984   }
00985 
00986   //Make a Python command
00987   GEOM::TPythonDump(aFunction) << aVertex << " = geompy.GetVertexByIndex(" << theShape << ", " << theIndex << ")";
00988 
00989   SetErrorCode(OK);
00990   return aVertex;
00991 }
00992 
00993 //=============================================================================
00997 //=============================================================================
00998 Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal
00999                                          (Handle(GEOM_Object) theFace,
01000                                           Handle(GEOM_Object) theOptionalPoint)
01001 {
01002   SetErrorCode(KO);
01003 
01004   if (theFace.IsNull()) return NULL;
01005 
01006   //Add a new Normale object
01007   Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GetDocID(), GEOM_VECTOR);
01008 
01009   //Add a new Normale function
01010   Handle(GEOM_Function) aFunction =
01011     aNorm->AddFunction(GEOMImpl_MeasureDriver::GetID(), VECTOR_FACE_NORMALE);
01012   if (aFunction.IsNull()) return NULL;
01013 
01014   //Check if the function is set correctly
01015   if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL;
01016 
01017   GEOMImpl_IMeasure aCI (aFunction);
01018 
01019   Handle(GEOM_Function) aFace = theFace->GetLastFunction();
01020   if (aFace.IsNull()) return NULL;
01021 
01022   aCI.SetBase(aFace);
01023 
01024   if (!theOptionalPoint.IsNull()) {
01025     Handle(GEOM_Function) anOptPnt = theOptionalPoint->GetLastFunction();
01026     aCI.SetPoint(anOptPnt);
01027   }
01028 
01029   //Compute the Normale value
01030   try {
01031 #if OCC_VERSION_LARGE > 0x06010000
01032     OCC_CATCH_SIGNALS;
01033 #endif
01034     if (!GetSolver()->ComputeFunction(aFunction)) {
01035       SetErrorCode("Measure driver failed to compute normake of face");
01036       return NULL;
01037     }
01038   }
01039   catch (Standard_Failure) {
01040     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01041     SetErrorCode(aFail->GetMessageString());
01042     return NULL;
01043   }
01044 
01045   //Make a Python command
01046   GEOM::TPythonDump pd (aFunction);
01047   pd << aNorm << " = geompy.GetNormal(" << theFace;
01048   if (!theOptionalPoint.IsNull()) {
01049     pd << ", " << theOptionalPoint;
01050   }
01051   pd << ")";
01052 
01053   SetErrorCode(OK);
01054   return aNorm;
01055 }
01056 
01057 //=============================================================================
01061 //=============================================================================
01062 void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theShape,
01063                                                       Standard_Real& theLength,
01064                                                       Standard_Real& theSurfArea,
01065                                                       Standard_Real& theVolume)
01066 {
01067   SetErrorCode(KO);
01068 
01069   if (theShape.IsNull()) return;
01070 
01071   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01072   if (aRefShape.IsNull()) return;
01073 
01074   TopoDS_Shape aShape = aRefShape->GetValue();
01075   if (aShape.IsNull()) {
01076     SetErrorCode("The Objects has NULL Shape");
01077     return;
01078   }
01079 
01080   //Compute the parameters
01081   GProp_GProps LProps, SProps;
01082   try {
01083 #if OCC_VERSION_LARGE > 0x06010000
01084     OCC_CATCH_SIGNALS;
01085 #endif
01086     BRepGProp::LinearProperties(aShape, LProps);
01087     theLength = LProps.Mass();
01088 
01089     BRepGProp::SurfaceProperties(aShape, SProps);
01090     theSurfArea = SProps.Mass();
01091 
01092     theVolume = 0.0;
01093     if (aShape.ShapeType() < TopAbs_SHELL) {
01094       for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) {
01095         GProp_GProps VProps;
01096         BRepGProp::VolumeProperties(Exp.Current(), VProps);
01097         theVolume += VProps.Mass();
01098       }
01099     }
01100   }
01101   catch (Standard_Failure) {
01102     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01103     SetErrorCode(aFail->GetMessageString());
01104     return;
01105   }
01106 
01107   SetErrorCode(OK);
01108 }
01109 
01110 //=============================================================================
01114 //=============================================================================
01115 void GEOMImpl_IMeasureOperations::GetInertia
01116                    (Handle(GEOM_Object) theShape,
01117                     Standard_Real& I11, Standard_Real& I12, Standard_Real& I13,
01118                     Standard_Real& I21, Standard_Real& I22, Standard_Real& I23,
01119                     Standard_Real& I31, Standard_Real& I32, Standard_Real& I33,
01120                     Standard_Real& Ix , Standard_Real& Iy , Standard_Real& Iz)
01121 {
01122   SetErrorCode(KO);
01123 
01124   if (theShape.IsNull()) return;
01125 
01126   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01127   if (aRefShape.IsNull()) return;
01128 
01129   TopoDS_Shape aShape = aRefShape->GetValue();
01130   if (aShape.IsNull()) {
01131     SetErrorCode("The Objects has NULL Shape");
01132     return;
01133   }
01134 
01135   //Compute the parameters
01136   GProp_GProps System;
01137 
01138   try {
01139 #if OCC_VERSION_LARGE > 0x06010000
01140     OCC_CATCH_SIGNALS;
01141 #endif
01142     if (aShape.ShapeType() == TopAbs_VERTEX ||
01143         aShape.ShapeType() == TopAbs_EDGE ||
01144         aShape.ShapeType() == TopAbs_WIRE) {
01145       BRepGProp::LinearProperties(aShape, System);
01146     } else if (aShape.ShapeType() == TopAbs_FACE ||
01147                aShape.ShapeType() == TopAbs_SHELL) {
01148       BRepGProp::SurfaceProperties(aShape, System);
01149     } else {
01150       BRepGProp::VolumeProperties(aShape, System);
01151     }
01152     gp_Mat I = System.MatrixOfInertia();
01153 
01154     I11 = I(1,1);
01155     I12 = I(1,2);
01156     I13 = I(1,3);
01157 
01158     I21 = I(2,1);
01159     I22 = I(2,2);
01160     I23 = I(2,3);
01161 
01162     I31 = I(3,1);
01163     I32 = I(3,2);
01164     I33 = I(3,3);
01165 
01166     GProp_PrincipalProps Pr = System.PrincipalProperties();
01167     Pr.Moments(Ix,Iy,Iz);
01168   }
01169   catch (Standard_Failure) {
01170     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01171     SetErrorCode(aFail->GetMessageString());
01172     return;
01173   }
01174 
01175   SetErrorCode(OK);
01176 }
01177 
01178 //=============================================================================
01182 //=============================================================================
01183 void GEOMImpl_IMeasureOperations::GetBoundingBox
01184                                      (Handle(GEOM_Object) theShape,
01185                                       Standard_Real& Xmin, Standard_Real& Xmax,
01186                                       Standard_Real& Ymin, Standard_Real& Ymax,
01187                                       Standard_Real& Zmin, Standard_Real& Zmax)
01188 {
01189   SetErrorCode(KO);
01190 
01191   if (theShape.IsNull()) return;
01192 
01193   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01194   if (aRefShape.IsNull()) return;
01195 
01196   TopoDS_Shape aShape = aRefShape->GetValue();
01197   if (aShape.IsNull()) {
01198     SetErrorCode("The Objects has NULL Shape");
01199     return;
01200   }
01201 
01202   //Compute the parameters
01203   Bnd_Box B;
01204 
01205   try {
01206 #if OCC_VERSION_LARGE > 0x06010000
01207     OCC_CATCH_SIGNALS;
01208 #endif
01209     BRepBndLib::Add(aShape, B);
01210     B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
01211   }
01212   catch (Standard_Failure) {
01213     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01214     SetErrorCode(aFail->GetMessageString());
01215     return;
01216   }
01217 
01218   SetErrorCode(OK);
01219 }
01220 
01221 //=============================================================================
01225 //=============================================================================
01226 void GEOMImpl_IMeasureOperations::GetTolerance
01227                                (Handle(GEOM_Object) theShape,
01228                                 Standard_Real& FaceMin, Standard_Real& FaceMax,
01229                                 Standard_Real& EdgeMin, Standard_Real& EdgeMax,
01230                                 Standard_Real& VertMin, Standard_Real& VertMax)
01231 {
01232   SetErrorCode(KO);
01233 
01234   if (theShape.IsNull()) return;
01235 
01236   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01237   if (aRefShape.IsNull()) return;
01238 
01239   TopoDS_Shape aShape = aRefShape->GetValue();
01240   if (aShape.IsNull()) {
01241     SetErrorCode("The Objects has NULL Shape");
01242     return;
01243   }
01244 
01245   //Compute the parameters
01246   Standard_Real T;
01247   FaceMin = EdgeMin = VertMin = RealLast();
01248   FaceMax = EdgeMax = VertMax = -RealLast();
01249 
01250   try {
01251 #if OCC_VERSION_LARGE > 0x06010000
01252     OCC_CATCH_SIGNALS;
01253 #endif
01254     for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) {
01255       TopoDS_Face Face = TopoDS::Face(ExF.Current());
01256       T = BRep_Tool::Tolerance(Face);
01257       if (T > FaceMax)
01258         FaceMax = T;
01259       if (T < FaceMin)
01260         FaceMin = T;
01261     }
01262     for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) {
01263       TopoDS_Edge Edge = TopoDS::Edge(ExE.Current());
01264       T = BRep_Tool::Tolerance(Edge);
01265       if (T > EdgeMax)
01266         EdgeMax = T;
01267       if (T < EdgeMin)
01268         EdgeMin = T;
01269     }
01270     for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) {
01271       TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current());
01272       T = BRep_Tool::Tolerance(Vertex);
01273       if (T > VertMax)
01274         VertMax = T;
01275       if (T < VertMin)
01276         VertMin = T;
01277     }
01278   }
01279   catch (Standard_Failure) {
01280     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01281     SetErrorCode(aFail->GetMessageString());
01282     return;
01283   }
01284 
01285   SetErrorCode(OK);
01286 }
01287 
01288 //=============================================================================
01292 //=============================================================================
01293 bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object)      theShape,
01294                                               const Standard_Boolean   theIsCheckGeom,
01295                                               TCollection_AsciiString& theDump)
01296 {
01297   SetErrorCode(KO);
01298 
01299   if (theShape.IsNull()) return false;
01300 
01301   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01302   if (aRefShape.IsNull()) return false;
01303 
01304   TopoDS_Shape aShape = aRefShape->GetValue();
01305   if (aShape.IsNull()) {
01306     SetErrorCode("The Objects has NULL Shape");
01307     return false;
01308   }
01309 
01310   //Compute the parameters
01311   bool isValid = false;
01312   try {
01313 #if OCC_VERSION_LARGE > 0x06010000
01314     OCC_CATCH_SIGNALS;
01315 #endif
01316     BRepCheck_Analyzer ana (aShape, theIsCheckGeom);
01317     if (ana.IsValid()) {
01318       theDump.Clear();
01319       isValid = true;
01320     } else {
01321       StructuralDump(ana, aShape, theDump);
01322     }
01323   }
01324   catch (Standard_Failure) {
01325     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01326     SetErrorCode(aFail->GetMessageString());
01327     return false;
01328   }
01329 
01330   SetErrorCode(OK);
01331   return isValid;
01332 }
01333 
01334 //=============================================================================
01338 //=============================================================================
01339 bool GEOMImpl_IMeasureOperations::CheckSelfIntersections
01340                          (Handle(GEOM_Object)                 theShape,
01341                           Handle(TColStd_HSequenceOfInteger)& theIntersections)
01342 {
01343   SetErrorCode(KO);
01344   bool isGood = false;
01345 
01346   if (theIntersections.IsNull())
01347     theIntersections = new TColStd_HSequenceOfInteger;
01348   else
01349     theIntersections->Clear();
01350 
01351   if (theShape.IsNull())
01352     return isGood;
01353 
01354   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01355   if (aRefShape.IsNull()) return isGood;
01356 
01357   TopoDS_Shape aShape = aRefShape->GetValue();
01358   if (aShape.IsNull()) return isGood;
01359 
01360   // 0. Prepare data
01361   BRep_Builder aBB;
01362   TopoDS_Compound aCS;
01363   TopoDS_Shape aScopy;
01364   NMTDS_Tools::CopyShape(aShape, aScopy);
01365 
01366   // Map sub-shapes and their indices
01367   TopTools_IndexedMapOfShape anIndices;
01368   TopExp::MapShapes(aScopy, anIndices);
01369 
01370   aBB.MakeCompound(aCS);
01371   aBB.Add(aCS, aScopy);
01372 
01373   NMTTools_CheckerSI aCSI; // checker of self-interferences
01374   aCSI.SetCompositeShape(aCS);
01375 
01376   // 1. Launch the checker
01377   aCSI.Perform();
01378   Standard_Integer iErr = aCSI.StopStatus();
01379   if (iErr) {
01380     return false; // Error
01381   }
01382 
01383   isGood = true;
01384 
01385   // 2. Take the shapes from DS
01386   const NMTDS_ShapesDataStructure& aDS = *(aCSI.DS());
01387   Standard_Integer aNbS = aDS.NumberOfShapesOfTheObject();
01388 
01389   // 3. Get the pairs of interfered shapes 
01390   NMTDS_PInterfPool pIP = aCSI.IP();
01391   //const NMTDS_ListOfPassKeyBoolean& aLPKB = pIP->Get();
01392   const NMTDS_ListOfPairBoolean& aLPKB = pIP->Get();
01393 
01394   Standard_Integer n1, n2;
01395   //NMTDS_ListIteratorOfListOfPassKeyBoolean aIt;
01396   NMTDS_ListIteratorOfListOfPairBoolean aIt;
01397 
01398   aIt.Initialize(aLPKB);
01399   for (; aIt.More(); aIt.Next()) {
01400     //const NMTDS_PassKeyBoolean& aPKB = aIt.Value();
01401     const NMTDS_PairBoolean& aPKB = aIt.Value();
01402     aPKB.Ids(n1, n2);
01403 
01404     if (n1 > aNbS || n2 > aNbS)
01405       return false; // Error
01406 
01407     const TopoDS_Shape& aS1 = aDS.Shape(n1);
01408     const TopoDS_Shape& aS2 = aDS.Shape(n2);
01409 
01410     theIntersections->Append(anIndices.FindIndex(aS1));
01411     theIntersections->Append(anIndices.FindIndex(aS2));
01412     isGood = false;
01413   }
01414 
01415   SetErrorCode(OK);
01416   return isGood;
01417 }
01418 
01419 //=============================================================================
01423 //=============================================================================
01424 TCollection_AsciiString GEOMImpl_IMeasureOperations::IsGoodForSolid (Handle(GEOM_Object) theShape)
01425 {
01426   SetErrorCode(KO);
01427 
01428   TCollection_AsciiString aRes = "";
01429 
01430   if (theShape.IsNull()) {
01431     aRes = "WRN_NULL_OBJECT_OR_SHAPE";
01432   }
01433   else {
01434     Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01435     if (aRefShape.IsNull()) {
01436       aRes = "WRN_NULL_OBJECT_OR_SHAPE";
01437     }
01438     else {
01439       TopoDS_Shape aShape = aRefShape->GetValue();
01440       if (aShape.IsNull()) {
01441         aRes = "WRN_NULL_OBJECT_OR_SHAPE";
01442       }
01443       else {
01444         if (aShape.ShapeType() == TopAbs_COMPOUND) {
01445           TopoDS_Iterator It (aShape, Standard_True, Standard_True);
01446           if (It.More()) aShape = It.Value();
01447         }
01448         if (aShape.ShapeType() == TopAbs_SHELL) {
01449           BRepCheck_Shell chkShell (TopoDS::Shell(aShape));
01450           if (chkShell.Closed() == BRepCheck_NotClosed) {
01451             aRes = "WRN_SHAPE_UNCLOSED";
01452           }
01453         }
01454         else {
01455           aRes = "WRN_SHAPE_NOT_SHELL";
01456         }
01457       }
01458     }
01459   }
01460 
01461   if (aRes.IsEmpty())
01462     SetErrorCode(OK);
01463 
01464   return aRes;
01465 }
01466 
01467 //=============================================================================
01471 //=============================================================================
01472 TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape)
01473 {
01474   SetErrorCode(KO);
01475 
01476   TCollection_AsciiString Astr;
01477 
01478   if (theShape.IsNull()) return Astr;
01479 
01480   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01481   if (aRefShape.IsNull()) return Astr;
01482 
01483   TopoDS_Shape aShape = aRefShape->GetValue();
01484   if (aShape.IsNull()) {
01485     SetErrorCode("The Objects has NULL Shape");
01486     return Astr;
01487   }
01488 
01489   //Compute the parameters
01490   if (aShape.ShapeType() == TopAbs_EDGE) {
01491     if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) {
01492       Astr = Astr + " It is a degenerated edge \n";
01493     }
01494   }
01495 
01496   Astr = Astr + " Number of sub-shapes : \n";
01497 
01498   try {
01499 #if OCC_VERSION_LARGE > 0x06010000
01500     OCC_CATCH_SIGNALS;
01501 #endif
01502     int iType, nbTypes [TopAbs_SHAPE];
01503     for (iType = 0; iType < TopAbs_SHAPE; ++iType)
01504       nbTypes[iType] = 0;
01505     nbTypes[aShape.ShapeType()]++;
01506 
01507     TopTools_MapOfShape aMapOfShape;
01508     aMapOfShape.Add(aShape);
01509     TopTools_ListOfShape aListOfShape;
01510     aListOfShape.Append(aShape);
01511 
01512     TopTools_ListIteratorOfListOfShape itL (aListOfShape);
01513     for (; itL.More(); itL.Next()) {
01514       TopoDS_Iterator it (itL.Value());
01515       for (; it.More(); it.Next()) {
01516         TopoDS_Shape s = it.Value();
01517         if (aMapOfShape.Add(s)) {
01518           aListOfShape.Append(s);
01519           nbTypes[s.ShapeType()]++;
01520         }
01521       }
01522     }
01523 
01524     Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n";
01525     Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n";
01526     Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n";
01527     Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n";
01528     Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n";
01529     Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n";
01530     Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n";
01531     Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n";
01532     Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent());
01533   }
01534   catch (Standard_Failure) {
01535     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01536     SetErrorCode(aFail->GetMessageString());
01537     return Astr;
01538   }
01539 
01540   SetErrorCode(OK);
01541   return Astr;
01542 }
01543 
01544 
01545 //=======================================================================
01546 //function : CheckSingularCase
01547 //purpose  : auxilary for GetMinDistance()
01548 //           workaround for bugs 19899, 19908 and 19910 from Mantis
01549 //=======================================================================
01550 static double CheckSingularCase(const TopoDS_Shape& aSh1,
01551                                 const TopoDS_Shape& aSh2,
01552                                 gp_Pnt& Ptmp1, gp_Pnt& Ptmp2)
01553 {
01554   bool IsChange1 = false;
01555   double AddDist1 = 0.0;
01556   TopExp_Explorer anExp;
01557   TopoDS_Shape tmpSh1, tmpSh2;
01558   int nbf = 0;
01559   for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
01560     nbf++;
01561     tmpSh1 = anExp.Current();
01562   }
01563   if(nbf==1) {
01564     TopoDS_Shape sh = aSh1;
01565     while(sh.ShapeType()==TopAbs_COMPOUND) {
01566       TopoDS_Iterator it(sh);
01567       sh = it.Value();
01568     }
01569     Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
01570     if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
01571         S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
01572       if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
01573         // non solid case
01574         double U1,U2,V1,V2;
01575         // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88
01576         //S->Bounds(U1,U2,V1,V2); changed by
01577         ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2);
01578         // end of changes for 020677 (dmv)
01579         Handle(Geom_RectangularTrimmedSurface) TrS1 =
01580           new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
01581         Handle(Geom_RectangularTrimmedSurface) TrS2 =
01582           new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
01583         BRep_Builder B;
01584         TopoDS_Face F1,F2;
01585         TopoDS_Compound Comp;
01586         B.MakeCompound(Comp);
01587         B.MakeFace(F1,TrS1,1.e-7);
01588         B.Add(Comp,F1);
01589         B.MakeFace(F2,TrS2,1.e-7);
01590         B.Add(Comp,F2);
01591         Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
01592         sfs->Init(Comp);
01593         sfs->SetPrecision(1.e-6);
01594         sfs->SetMaxTolerance(1.0);
01595         sfs->Perform();
01596         tmpSh1 = sfs->Shape();
01597         IsChange1 = true;
01598       }
01599       else {
01600         if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
01601           Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
01602           gp_Pnt PC = SS->Location();
01603           BRep_Builder B;
01604           TopoDS_Vertex V;
01605           B.MakeVertex(V,PC,1.e-7);
01606           tmpSh1 = V;
01607           AddDist1 = SS->Radius();
01608           IsChange1 = true;
01609         }
01610         else {
01611           Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
01612           gp_Ax3 ax3 = TS->Position();
01613           Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
01614           BRep_Builder B;
01615           TopoDS_Edge E;
01616           B.MakeEdge(E,C,1.e-7);
01617           tmpSh1 = E;
01618           AddDist1 = TS->MinorRadius();
01619           IsChange1 = true;
01620         }
01621       }
01622     }
01623     else
01624       tmpSh1 = aSh1;
01625   }
01626   else
01627     tmpSh1 = aSh1;
01628   bool IsChange2 = false;
01629   double AddDist2 = 0.0;
01630   nbf = 0;
01631   for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
01632     nbf++;
01633     tmpSh2 = anExp.Current();
01634   }
01635   if(nbf==1) {
01636     TopoDS_Shape sh = aSh2;
01637     while(sh.ShapeType()==TopAbs_COMPOUND) {
01638       TopoDS_Iterator it(sh);
01639       sh = it.Value();
01640     }
01641     Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
01642     if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
01643         S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
01644       if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) {
01645         // non solid case
01646         double U1,U2,V1,V2;
01647         //S->Bounds(U1,U2,V1,V2);
01648         ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2);
01649         Handle(Geom_RectangularTrimmedSurface) TrS1 =
01650           new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2);
01651         Handle(Geom_RectangularTrimmedSurface) TrS2 =
01652           new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2);
01653         BRep_Builder B;
01654         TopoDS_Face F1,F2;
01655         TopoDS_Compound Comp;
01656         B.MakeCompound(Comp);
01657         B.MakeFace(F1,TrS1,1.e-7);
01658         B.Add(Comp,F1);
01659         B.MakeFace(F2,TrS2,1.e-7);
01660         B.Add(Comp,F2);
01661         Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape;
01662         sfs->Init(Comp);
01663         sfs->SetPrecision(1.e-6);
01664         sfs->SetMaxTolerance(1.0);
01665         sfs->Perform();
01666         tmpSh2 = sfs->Shape();
01667         IsChange2 = true;
01668       }
01669       else {
01670         if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) {
01671           Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S);
01672           gp_Pnt PC = SS->Location();
01673           BRep_Builder B;
01674           TopoDS_Vertex V;
01675           B.MakeVertex(V,PC,1.e-7);
01676           tmpSh2 = V;
01677           AddDist2 = SS->Radius();
01678           IsChange2 = true;
01679         }
01680         else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
01681           Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S);
01682           gp_Ax3 ax3 = TS->Position();
01683           Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius());
01684           BRep_Builder B;
01685           TopoDS_Edge E;
01686           B.MakeEdge(E,C,1.e-7);
01687           tmpSh2 = E;
01688           AddDist2 = TS->MinorRadius();
01689           IsChange2 = true;
01690         }
01691       }
01692     }
01693     else
01694       tmpSh2 = aSh2;
01695   }
01696   else
01697     tmpSh2 = aSh2;
01698 
01699   if( !IsChange1 && !IsChange2 )
01700     return -2.0;
01701 
01702   BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2);
01703   if (dst.IsDone()) {
01704     double MinDist = 1.e9;
01705     gp_Pnt PMin1, PMin2, P1, P2;
01706     for (int i = 1; i <= dst.NbSolution(); i++) {
01707       P1 = dst.PointOnShape1(i);
01708       P2 = dst.PointOnShape2(i);
01709       Standard_Real Dist = P1.Distance(P2);
01710       if (MinDist > Dist) {
01711         MinDist = Dist;
01712         PMin1 = P1;
01713         PMin2 = P2;
01714       }
01715     }
01716     if(MinDist<1.e-7) {
01717       Ptmp1 = PMin1;
01718       Ptmp2 = PMin2;
01719     }
01720     else {
01721       gp_Dir aDir(gp_Vec(PMin1,PMin2));
01722       if( MinDist > (AddDist1+AddDist2) ) {
01723         Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
01724                         PMin1.Y() + aDir.Y()*AddDist1,
01725                         PMin1.Z() + aDir.Z()*AddDist1 );
01726         Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
01727                         PMin2.Y() - aDir.Y()*AddDist2,
01728                         PMin2.Z() - aDir.Z()*AddDist2 );
01729         return (MinDist - AddDist1 - AddDist2);
01730       }
01731       else {
01732         if( AddDist1 > 0 ) {
01733           Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1,
01734                           PMin1.Y() + aDir.Y()*AddDist1,
01735                           PMin1.Z() + aDir.Z()*AddDist1 );
01736           Ptmp2 = Ptmp1;
01737         }
01738         else {
01739           Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2,
01740                           PMin2.Y() - aDir.Y()*AddDist2,
01741                           PMin2.Z() - aDir.Z()*AddDist2 );
01742           Ptmp1 = Ptmp2;
01743         }
01744       }
01745     }
01746     double res = MinDist - AddDist1 - AddDist2;
01747     if(res<0.) res = 0.0;
01748     return res;
01749   }
01750   return -2.0;
01751 }
01752 /* old variant
01753 static bool CheckSingularCase(const TopoDS_Shape& aSh1,
01754                               const TopoDS_Shape& aSh2,
01755                               gp_Pnt& Ptmp)
01756 {
01757   TopExp_Explorer anExp;
01758   TopoDS_Shape tmpSh1, tmpSh2;
01759   int nbf = 0;
01760   for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
01761     nbf++;
01762     tmpSh1 = anExp.Current();
01763   }
01764   if(nbf==1) {
01765     Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
01766     if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
01767         S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
01768       nbf = 0;
01769       for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
01770         nbf++;
01771         tmpSh2 = anExp.Current();
01772         Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
01773         GeomAPI_IntSS ISS(S1,S2,1.e-7);
01774         if(ISS.IsDone()) {
01775           for(int i=1; i<=ISS.NbLines(); i++) {
01776             Handle(Geom_Curve) C3d = ISS.Line(i);
01777             BRep_Builder B;
01778             TopoDS_Edge E;
01779             B.MakeEdge(E,C3d,1.e-7);
01780             BRepExtrema_DistShapeShape dst(tmpSh2,E);
01781             if (dst.IsDone()) {
01782               gp_Pnt PMin1, PMin2, P1, P2;
01783               double MinDist = 1.e9;
01784               for (int i = 1; i <= dst.NbSolution(); i++) {
01785                 P1 = dst.PointOnShape1(i);
01786                 P2 = dst.PointOnShape2(i);
01787                 Standard_Real Dist = P1.Distance(P2);
01788                 if (MinDist > Dist) {
01789                   MinDist = Dist;
01790                   Ptmp = P1;
01791                 }
01792               }
01793               if(MinDist<1.e-7)
01794                 return true;
01795             }
01796           }
01797         }
01798       }
01799     }
01800   }
01801   nbf = 0;
01802   for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
01803     nbf++;
01804     tmpSh1 = anExp.Current();
01805   }
01806   if(nbf==1) {
01807     Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1));
01808     if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ||
01809         S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) {
01810       nbf = 0;
01811       for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) {
01812         nbf++;
01813         tmpSh2 = anExp.Current();
01814         Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2));
01815         GeomAPI_IntSS ISS(S1,S2,1.e-7);
01816         if(ISS.IsDone()) {
01817           for(int i=1; i<=ISS.NbLines(); i++) {
01818             Handle(Geom_Curve) C3d = ISS.Line(i);
01819             BRep_Builder B;
01820             TopoDS_Edge E;
01821             B.MakeEdge(E,C3d,1.e-7);
01822             BRepExtrema_DistShapeShape dst(tmpSh2,E);
01823             if (dst.IsDone()) {
01824               gp_Pnt P1,P2;
01825               double MinDist = 1.e9;
01826               for (int i = 1; i <= dst.NbSolution(); i++) {
01827                 P1 = dst.PointOnShape1(i);
01828                 P2 = dst.PointOnShape2(i);
01829                 Standard_Real Dist = P1.Distance(P2);
01830                 if (MinDist > Dist) {
01831                   MinDist = Dist;
01832                   Ptmp = P1;
01833                 }
01834               }
01835               if(MinDist<1.e-7)
01836                 return true;
01837             }
01838           }
01839         }
01840       }
01841     }
01842   }
01843   return false;
01844 }
01845 */
01846 
01847 
01848 //=============================================================================
01852 //=============================================================================
01853 std::vector<bool> GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape,
01854                                                                const std::vector<double>& coords,
01855                                                                double tolerance)
01856 {
01857   std::vector<bool> res;
01858   if (!theShape.IsNull()) {
01859     Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01860     if (!aRefShape.IsNull()) {
01861       TopoDS_Shape aShape = aRefShape->GetValue();
01862       if (!aShape.IsNull()) {
01863         BRepClass3d_SolidClassifier SC(aShape);
01864         unsigned int nb_points = coords.size()/3;
01865         for (int i = 0; i < nb_points; i++) {
01866           double x = coords[3*i];
01867           double y = coords[3*i+1];
01868           double z = coords[3*i+2];
01869           gp_Pnt aPnt(x, y, z);
01870           SC.Perform(aPnt, tolerance);
01871           res.push_back( ( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON ) );
01872         }
01873       }
01874     }
01875   }
01876   return res;
01877 }
01878 
01879 //=============================================================================
01883 //=============================================================================
01884 Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance
01885   (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2,
01886    Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1,
01887    Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2)
01888 {
01889   SetErrorCode(KO);
01890   Standard_Real MinDist = 1.e9;
01891 
01892   if (theShape1.IsNull() || theShape2.IsNull()) return MinDist;
01893 
01894   Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
01895   Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
01896   if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist;
01897 
01898   TopoDS_Shape aShape1 = aRefShape1->GetValue();
01899   TopoDS_Shape aShape2 = aRefShape2->GetValue();
01900   if (aShape1.IsNull() || aShape2.IsNull()) {
01901     SetErrorCode("One of Objects has NULL Shape");
01902     return MinDist;
01903   }
01904 
01905   //Compute the parameters
01906   try {
01907 #if OCC_VERSION_LARGE > 0x06010000
01908     OCC_CATCH_SIGNALS;
01909 #endif
01910 
01911     // Issue 0020231: A min distance bug with torus and vertex.
01912     // Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs
01913 
01914     // which of shapes consists of only one vertex?
01915     TopExp_Explorer exp1(aShape1,TopAbs_VERTEX), exp2(aShape2,TopAbs_VERTEX);
01916     TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape();
01917     TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape();
01918     exp1.Next(); exp2.Next();
01919     if ( exp1.More() ) V1.Nullify();
01920     if ( exp2.More() ) V2.Nullify();
01921     // vertex and container of solids
01922     TopoDS_Shape V = V1.IsNull() ? V2 : V1;
01923     TopoDS_Shape S = V1.IsNull() ? aShape1 : aShape2;
01924     if ( !V.IsNull() ) {
01925       // classify vertex against solids
01926       gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) );
01927       for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) {
01928         BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6);
01929         if ( classifier.State() == TopAbs_IN ) {
01930           p.Coord(X1, Y1, Z1);
01931           p.Coord(X2, Y2, Z2);
01932           SetErrorCode(OK);
01933           return 0.0;
01934         }
01935       }
01936     }
01937     // End Issue 0020231
01938 
01939     // skl 30.06.2008
01940     // additional workaround for bugs 19899, 19908 and 19910 from Mantis
01941     gp_Pnt Ptmp1, Ptmp2;
01942     double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2);
01943     if(dist>-1.0) {
01944       Ptmp1.Coord(X1, Y1, Z1);
01945       Ptmp2.Coord(X2, Y2, Z2);
01946       SetErrorCode(OK);
01947       return dist;
01948     }
01949 
01950     BRepExtrema_DistShapeShape dst (aShape1, aShape2);
01951     if (dst.IsDone()) {
01952       gp_Pnt PMin1, PMin2, P1, P2;
01953 
01954       for (int i = 1; i <= dst.NbSolution(); i++) {
01955         P1 = dst.PointOnShape1(i);
01956         P2 = dst.PointOnShape2(i);
01957 
01958         Standard_Real Dist = P1.Distance(P2);
01959         if (MinDist > Dist) {
01960           MinDist = Dist;
01961           PMin1 = P1;
01962           PMin2 = P2;
01963         }
01964       }
01965 
01966       PMin1.Coord(X1, Y1, Z1);
01967       PMin2.Coord(X2, Y2, Z2);
01968     }
01969   }
01970   catch (Standard_Failure) {
01971     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
01972     SetErrorCode(aFail->GetMessageString());
01973     return MinDist;
01974   }
01975 
01976   SetErrorCode(OK);
01977   return MinDist;
01978 }
01979 
01980 //=======================================================================
01984 //=======================================================================
01985 void GEOMImpl_IMeasureOperations::PointCoordinates (Handle(GEOM_Object) theShape,
01986                         Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ)
01987 {
01988   SetErrorCode(KO);
01989 
01990   if (theShape.IsNull())
01991     return;
01992 
01993   Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
01994   if (aRefShape.IsNull())
01995     return;
01996 
01997   TopoDS_Shape aShape = aRefShape->GetValue();
01998   if (aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX)
01999   {
02000     SetErrorCode( "Shape must be a vertex" );
02001     return;
02002   }
02003 
02004   try {
02005 #if OCC_VERSION_LARGE > 0x06010000
02006     OCC_CATCH_SIGNALS;
02007 #endif
02008     gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
02009     theX = aPnt.X();
02010     theY = aPnt.Y();
02011     theZ = aPnt.Z();
02012 
02013     SetErrorCode(OK);
02014   }
02015   catch (Standard_Failure)
02016   {
02017     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02018     SetErrorCode( aFail->GetMessageString() );
02019   }
02020 }
02021 
02022 //=======================================================================
02026 //=======================================================================
02027 Standard_Real GEOMImpl_IMeasureOperations::GetAngle (Handle(GEOM_Object) theLine1,
02028                                                      Handle(GEOM_Object) theLine2)
02029 {
02030   if (theLine1->GetType() == GEOM_VECTOR &&
02031       theLine2->GetType() == GEOM_VECTOR)
02032     return GetAngleBtwVectors(theLine1, theLine2);
02033 
02034   SetErrorCode(KO);
02035 
02036   Standard_Real anAngle = -1.0;
02037 
02038   if (theLine1.IsNull() || theLine2.IsNull())
02039     return anAngle;
02040 
02041   Handle(GEOM_Function) aRefLine1 = theLine1->GetLastFunction();
02042   Handle(GEOM_Function) aRefLine2 = theLine2->GetLastFunction();
02043   if (aRefLine1.IsNull() || aRefLine2.IsNull())
02044     return anAngle;
02045 
02046   TopoDS_Shape aLine1 = aRefLine1->GetValue();
02047   TopoDS_Shape aLine2 = aRefLine2->GetValue();
02048   if (aLine1.IsNull() || aLine2.IsNull() ||
02049       aLine1.ShapeType() != TopAbs_EDGE ||
02050       aLine2.ShapeType() != TopAbs_EDGE)
02051   {
02052     SetErrorCode("Two edges must be given");
02053     return anAngle;
02054   }
02055 
02056   try {
02057 #if OCC_VERSION_LARGE > 0x06010000
02058     OCC_CATCH_SIGNALS;
02059 #endif
02060     TopoDS_Edge E1 = TopoDS::Edge(aLine1);
02061     TopoDS_Edge E2 = TopoDS::Edge(aLine2);
02062 
02063     double fp,lp;
02064     Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp);
02065     Handle(Geom_Curve) C2 = BRep_Tool::Curve(E2,fp,lp);
02066 
02067     if ( C1.IsNull() || C2.IsNull() ||
02068         !C1->IsKind(STANDARD_TYPE(Geom_Line)) ||
02069         !C2->IsKind(STANDARD_TYPE(Geom_Line)))
02070     {
02071       SetErrorCode("The edges must be linear");
02072       return anAngle;
02073     }
02074 
02075     Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(C1);
02076     Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(C2);
02077 
02078     gp_Lin aLin1 = L1->Lin();
02079     gp_Lin aLin2 = L2->Lin();
02080 
02081     anAngle = aLin1.Angle(aLin2);
02082     anAngle *= 180. / M_PI; // convert radians into degrees
02083 
02084     if (anAngle > 90.0) {
02085       anAngle = 180.0 - anAngle;
02086     }
02087 
02088     SetErrorCode(OK);
02089   }
02090   catch (Standard_Failure)
02091   {
02092     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02093     SetErrorCode(aFail->GetMessageString());
02094   }
02095 
02096   return anAngle;
02097 }
02098 
02099 //=======================================================================
02103 //=======================================================================
02104 Standard_Real GEOMImpl_IMeasureOperations::GetAngleBtwVectors (Handle(GEOM_Object) theVec1,
02105                                                                Handle(GEOM_Object) theVec2)
02106 {
02107   SetErrorCode(KO);
02108 
02109   Standard_Real anAngle = -1.0;
02110 
02111   if (theVec1.IsNull() || theVec2.IsNull())
02112     return anAngle;
02113 
02114   Handle(GEOM_Function) aRefVec1 = theVec1->GetLastFunction();
02115   Handle(GEOM_Function) aRefVec2 = theVec2->GetLastFunction();
02116   if (aRefVec1.IsNull() || aRefVec2.IsNull())
02117     return anAngle;
02118 
02119   TopoDS_Shape aVec1 = aRefVec1->GetValue();
02120   TopoDS_Shape aVec2 = aRefVec2->GetValue();
02121   if (aVec1.IsNull() || aVec2.IsNull() ||
02122       aVec1.ShapeType() != TopAbs_EDGE ||
02123       aVec2.ShapeType() != TopAbs_EDGE)
02124   {
02125     SetErrorCode("Two edges must be given");
02126     return anAngle;
02127   }
02128 
02129   try {
02130 #if OCC_VERSION_LARGE > 0x06010000
02131     OCC_CATCH_SIGNALS;
02132 #endif
02133     TopoDS_Edge aE1 = TopoDS::Edge(aVec1);
02134     TopoDS_Edge aE2 = TopoDS::Edge(aVec2);
02135 
02136     TopoDS_Vertex aP11, aP12, aP21, aP22;
02137     TopExp::Vertices(aE1, aP11, aP12, Standard_True);
02138     TopExp::Vertices(aE2, aP21, aP22, Standard_True);
02139     if (aP11.IsNull() || aP12.IsNull() || aP21.IsNull() || aP22.IsNull()) {
02140       SetErrorCode("Bad edge given");
02141       return anAngle;
02142     }
02143 
02144     gp_Vec aV1 (BRep_Tool::Pnt(aP11), BRep_Tool::Pnt(aP12));
02145     gp_Vec aV2 (BRep_Tool::Pnt(aP21), BRep_Tool::Pnt(aP22)) ;
02146 
02147     anAngle = aV1.Angle(aV2);
02148     anAngle *= 180. / M_PI; // convert radians into degrees
02149 
02150     SetErrorCode(OK);
02151   }
02152   catch (Standard_Failure)
02153   {
02154     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02155     SetErrorCode(aFail->GetMessageString());
02156   }
02157 
02158   return anAngle;
02159 }
02160 
02161 
02162 //=============================================================================
02166 //=============================================================================
02167 Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByParam
02168                         (Handle(GEOM_Object) theCurve, Standard_Real& theParam)
02169 {
02170   SetErrorCode(KO);
02171   Standard_Real aRes = -1.0;
02172 
02173   if(theCurve.IsNull()) return aRes;
02174 
02175   Handle(GEOM_Function) aRefShape = theCurve->GetLastFunction();
02176   if(aRefShape.IsNull()) return aRes;
02177 
02178   TopoDS_Shape aShape = aRefShape->GetValue();
02179   if(aShape.IsNull()) {
02180     SetErrorCode("One of Objects has NULL Shape");
02181     return aRes;
02182   }
02183 
02184   Standard_Real aFP, aLP, aP;
02185   Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFP, aLP);
02186   aP = aFP + (aLP - aFP) * theParam;
02187 
02188   if(aCurve.IsNull()) return aRes;
02189 
02190   //Compute curvature
02191   try {
02192 #if OCC_VERSION_LARGE > 0x06010000
02193     OCC_CATCH_SIGNALS;
02194 #endif
02195     GeomLProp_CLProps Prop = GeomLProp_CLProps
02196       (aCurve, aP, 2, Precision::Confusion());
02197     aRes = fabs(Prop.Curvature());
02198     SetErrorCode(OK);
02199   }
02200   catch (Standard_Failure) {
02201     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02202     SetErrorCode(aFail->GetMessageString());
02203     return aRes;
02204   }
02205 
02206   if( aRes > Precision::Confusion() )
02207     aRes = 1/aRes;
02208   else
02209     aRes = RealLast();
02210 
02211   return aRes;
02212 }
02213 
02214 
02215 //=============================================================================
02219 //=============================================================================
02220 Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByPoint
02221                    (Handle(GEOM_Object) theCurve, Handle(GEOM_Object) thePoint)
02222 {
02223   SetErrorCode(KO);
02224   Standard_Real aRes = -1.0;
02225 
02226   if( theCurve.IsNull() || thePoint.IsNull() ) return aRes;
02227 
02228   Handle(GEOM_Function) aRefCurve = theCurve->GetLastFunction();
02229   Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
02230   if( aRefCurve.IsNull() || aRefPoint.IsNull() ) return aRes;
02231 
02232   TopoDS_Edge anEdge = TopoDS::Edge(aRefCurve->GetValue());
02233   TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
02234   if( anEdge.IsNull() || aPnt.IsNull() ) {
02235     SetErrorCode("One of Objects has NULL Shape");
02236     return aRes;
02237   }
02238 
02239   Standard_Real aFP, aLP;
02240   Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFP, aLP);
02241   if(aCurve.IsNull()) return aRes;
02242   gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
02243 
02244   //Compute curvature
02245   try {
02246 #if OCC_VERSION_LARGE > 0x06010000
02247     OCC_CATCH_SIGNALS;
02248 #endif
02249     GeomAPI_ProjectPointOnCurve PPCurve(aPoint, aCurve, aFP, aLP);
02250     if(PPCurve.NbPoints()>0) {
02251       GeomLProp_CLProps Prop = GeomLProp_CLProps
02252         (aCurve, PPCurve.LowerDistanceParameter(), 2, Precision::Confusion());
02253       aRes = fabs(Prop.Curvature());
02254       SetErrorCode(OK);
02255     }
02256   }
02257   catch (Standard_Failure) {
02258     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02259     SetErrorCode(aFail->GetMessageString());
02260     return aRes;
02261   }
02262 
02263   if( aRes > Precision::Confusion() )
02264     aRes = 1/aRes;
02265   else
02266     aRes = RealLast();
02267 
02268   return aRes;
02269 }
02270 
02271 
02272 //=============================================================================
02276 //=============================================================================
02277 Standard_Real GEOMImpl_IMeasureOperations::getSurfaceCurvatures
02278                                           (const Handle(Geom_Surface)& aSurf,
02279                                            Standard_Real theUParam,
02280                                            Standard_Real theVParam,
02281                                            Standard_Boolean theNeedMaxCurv)
02282 {
02283   SetErrorCode(KO);
02284   Standard_Real aRes = 1.0;
02285 
02286   if (aSurf.IsNull()) return aRes;
02287 
02288   try {
02289 #if OCC_VERSION_LARGE > 0x06010000
02290     OCC_CATCH_SIGNALS;
02291 #endif
02292     GeomLProp_SLProps Prop = GeomLProp_SLProps
02293       (aSurf, theUParam, theVParam, 2, Precision::Confusion());
02294     if(Prop.IsCurvatureDefined()) {
02295       if(Prop.IsUmbilic()) {
02296         //cout<<"is umbilic"<<endl;
02297         aRes = fabs(Prop.MeanCurvature());
02298       }
02299       else {
02300         //cout<<"is not umbilic"<<endl;
02301         double c1 = fabs(Prop.MaxCurvature());
02302         double c2 = fabs(Prop.MinCurvature());
02303         if(theNeedMaxCurv)
02304           aRes = Max(c1,c2);
02305         else
02306           aRes = Min(c1,c2);
02307       }
02308       SetErrorCode(OK);
02309     }
02310   }
02311   catch (Standard_Failure) {
02312     Handle(Standard_Failure) aFail = Standard_Failure::Caught();
02313     SetErrorCode(aFail->GetMessageString());
02314     return aRes;
02315   }
02316 
02317   if( fabs(aRes) > Precision::Confusion() )
02318     aRes = 1/aRes;
02319   else
02320     aRes = RealLast();
02321 
02322   return aRes;
02323 }
02324 
02325 
02326 //=============================================================================
02330 //=============================================================================
02331 Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByParam
02332                                                   (Handle(GEOM_Object) theSurf,
02333                                                    Standard_Real& theUParam,
02334                                                    Standard_Real& theVParam)
02335 {
02336   SetErrorCode(KO);
02337   Standard_Real aRes = -1.0;
02338 
02339   if (theSurf.IsNull()) return aRes;
02340 
02341   Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
02342   if(aRefShape.IsNull()) return aRes;
02343 
02344   TopoDS_Shape aShape = aRefShape->GetValue();
02345   if(aShape.IsNull()) {
02346     SetErrorCode("One of Objects has NULL Shape");
02347     return aRes;
02348   }
02349 
02350   TopoDS_Face F = TopoDS::Face(aShape);
02351   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
02352 
02353   //Compute the parameters
02354   Standard_Real U1,U2,V1,V2;
02355   ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
02356   Standard_Real U = U1 + (U2-U1)*theUParam;
02357   Standard_Real V = V1 + (V2-V1)*theVParam;
02358 
02359   return getSurfaceCurvatures(aSurf, U, V, true);
02360 }
02361 
02362 
02363 //=============================================================================
02367 //=============================================================================
02368 Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByPoint
02369                     (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
02370 {
02371   SetErrorCode(KO);
02372   Standard_Real aRes = -1.0;
02373 
02374   if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
02375 
02376   Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
02377   Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
02378   if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
02379 
02380   TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
02381   TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
02382   if( aFace.IsNull() || aPnt.IsNull() ) {
02383     SetErrorCode("One of Objects has NULL Shape");
02384     return 0;
02385   }
02386 
02387   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
02388   if(aSurf.IsNull()) return aRes;
02389   gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
02390 
02391   //Compute the parameters
02392   ShapeAnalysis_Surface sas(aSurf);
02393   gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
02394 
02395   return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), true);
02396 }
02397 
02398 
02399 //=============================================================================
02403 //=============================================================================
02404 Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByParam
02405                                                   (Handle(GEOM_Object) theSurf,
02406                                                    Standard_Real& theUParam,
02407                                                    Standard_Real& theVParam)
02408 {
02409   SetErrorCode(KO);
02410   Standard_Real aRes = -1.0;
02411 
02412   if (theSurf.IsNull()) return aRes;
02413 
02414   Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
02415   if(aRefShape.IsNull()) return aRes;
02416 
02417   TopoDS_Shape aShape = aRefShape->GetValue();
02418   if(aShape.IsNull()) {
02419     SetErrorCode("One of Objects has NULL Shape");
02420     return aRes;
02421   }
02422 
02423   TopoDS_Face F = TopoDS::Face(aShape);
02424   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F);
02425 
02426   //Compute the parameters
02427   Standard_Real U1,U2,V1,V2;
02428   ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2);
02429   Standard_Real U = U1 + (U2-U1)*theUParam;
02430   Standard_Real V = V1 + (V2-V1)*theVParam;
02431 
02432   return getSurfaceCurvatures(aSurf, U, V, false);
02433 }
02434 
02435 
02436 //=============================================================================
02440 //=============================================================================
02441 Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint
02442                     (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint)
02443 {
02444   SetErrorCode(KO);
02445   Standard_Real aRes = -1.0;
02446 
02447   if( theSurf.IsNull() || thePoint.IsNull() ) return aRes;
02448 
02449   Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction();
02450   Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction();
02451   if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes;
02452 
02453   TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue());
02454   TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue());
02455   if( aFace.IsNull() || aPnt.IsNull() ) {
02456     SetErrorCode("One of Objects has NULL Shape");
02457     return 0;
02458   }
02459 
02460   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
02461   if(aSurf.IsNull()) return aRes;
02462   gp_Pnt aPoint = BRep_Tool::Pnt(aPnt);
02463 
02464   //Compute the parameters
02465   ShapeAnalysis_Surface sas(aSurf);
02466   gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion());
02467 
02468   return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false);
02469 }
02470 
02471 
02472 //=======================================================================
02473 //function : StructuralDump
02474 //purpose  : Structural (data exchange) style of output.
02475 //=======================================================================
02476 void GEOMImpl_IMeasureOperations::StructuralDump (const BRepCheck_Analyzer& theAna,
02477                                                   const TopoDS_Shape&       theShape,
02478                                                   TCollection_AsciiString&  theDump)
02479 {
02480   Standard_Integer i;
02481   theDump.Clear();
02482   theDump += " -- The Shape has problems :\n";
02483   theDump += "  Check                                    Count\n";
02484   theDump += " ------------------------------------------------\n";
02485 
02486   Standard_Integer last_stat = (Standard_Integer)BRepCheck_CheckFail;
02487   Handle(TColStd_HArray1OfInteger) NbProblems =
02488     new TColStd_HArray1OfInteger(1, last_stat);
02489   for (i = 1; i <= last_stat; i++)
02490     NbProblems->SetValue(i,0);
02491 
02492   Handle(TopTools_HSequenceOfShape) sl;
02493   sl = new TopTools_HSequenceOfShape();
02494   TopTools_DataMapOfShapeListOfShape theMap;
02495   theMap.Clear();
02496   GetProblemShapes(theAna, theShape, sl, NbProblems, theMap);
02497   theMap.Clear();
02498 
02499   Standard_Integer count = 0;
02500   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurve);
02501   if (count > 0) {
02502     theDump += "  Invalid Point on Curve ................... ";
02503     theDump += TCollection_AsciiString(count) + "\n";
02504   }
02505   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnCurveOnSurface);
02506   if (count > 0) {
02507     theDump += "  Invalid Point on CurveOnSurface .......... ";
02508     theDump += TCollection_AsciiString(count) + "\n";
02509   }
02510   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidPointOnSurface);
02511   if (count > 0) {
02512     theDump += "  Invalid Point on Surface ................. ";
02513     theDump += TCollection_AsciiString(count) + "\n";
02514   }
02515   count = NbProblems->Value((Standard_Integer)BRepCheck_No3DCurve);
02516   if (count > 0) {
02517     theDump += "  No 3D Curve .............................. ";
02518     theDump += TCollection_AsciiString(count) + "\n";
02519   }
02520   count = NbProblems->Value((Standard_Integer)BRepCheck_Multiple3DCurve);
02521   if (count > 0) {
02522     theDump += "  Multiple 3D Curve ........................ ";
02523     theDump += TCollection_AsciiString(count) + "\n";
02524   }
02525   count = NbProblems->Value((Standard_Integer)BRepCheck_Invalid3DCurve);
02526   if (count > 0) {
02527     theDump += "  Invalid 3D Curve ......................... ";
02528     theDump += TCollection_AsciiString(count) + "\n";
02529   }
02530   count = NbProblems->Value((Standard_Integer)BRepCheck_NoCurveOnSurface);
02531   if (count > 0) {
02532     theDump += "  No Curve on Surface ...................... ";
02533     theDump += TCollection_AsciiString(count) + "\n";
02534   }
02535   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnSurface);
02536   if (count > 0) {
02537     theDump += "  Invalid Curve on Surface ................. ";
02538     theDump += TCollection_AsciiString(count) + "\n";
02539   }
02540   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidCurveOnClosedSurface);
02541   if (count > 0) {
02542     theDump += "  Invalid Curve on closed Surface .......... ";
02543     theDump += TCollection_AsciiString(count) + "\n";
02544   }
02545   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameRangeFlag);
02546   if (count > 0) {
02547     theDump += "  Invalid SameRange Flag ................... ";
02548     theDump += TCollection_AsciiString(count) + "\n";
02549   }
02550   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidSameParameterFlag);
02551   if (count > 0) {
02552     theDump += "  Invalid SameParameter Flag ............... ";
02553     theDump += TCollection_AsciiString(count) + "\n";
02554   }
02555   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidDegeneratedFlag);
02556   if (count > 0) {
02557     theDump += "  Invalid Degenerated Flag ................. ";
02558     theDump += TCollection_AsciiString(count) + "\n";
02559   }
02560   count = NbProblems->Value((Standard_Integer)BRepCheck_FreeEdge);
02561   if (count > 0) {
02562     theDump += "  Free Edge ................................ ";
02563     theDump += TCollection_AsciiString(count) + "\n";
02564   }
02565   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidMultiConnexity);
02566   if (count > 0) {
02567     theDump += "  Invalid MultiConnexity ................... ";
02568     theDump += TCollection_AsciiString(count) + "\n";
02569   }
02570   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidRange);
02571   if (count > 0) {
02572     theDump += "  Invalid Range ............................ ";
02573     theDump += TCollection_AsciiString(count) + "\n";
02574   }
02575   count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyWire);
02576   if (count > 0) {
02577     theDump += "  Empty Wire ............................... ";
02578     theDump += TCollection_AsciiString(count) + "\n";
02579   }
02580   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantEdge);
02581   if (count > 0) {
02582     theDump += "  Redundant Edge ........................... ";
02583     theDump += TCollection_AsciiString(count) + "\n";
02584   }
02585   count = NbProblems->Value((Standard_Integer)BRepCheck_SelfIntersectingWire);
02586   if (count > 0) {
02587     theDump += "  Self Intersecting Wire ................... ";
02588     theDump += TCollection_AsciiString(count) + "\n";
02589   }
02590   count = NbProblems->Value((Standard_Integer)BRepCheck_NoSurface);
02591   if (count > 0) {
02592     theDump += "  No Surface ............................... ";
02593     theDump += TCollection_AsciiString(count) + "\n";
02594   }
02595   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidWire);
02596   if (count > 0) {
02597     theDump += "  Invalid Wire ............................. ";
02598     theDump += TCollection_AsciiString(count) + "\n";
02599   }
02600   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantWire);
02601   if (count > 0) {
02602     theDump += "  Redundant Wire ........................... ";
02603     theDump += TCollection_AsciiString(count) + "\n";
02604   }
02605   count = NbProblems->Value((Standard_Integer)BRepCheck_IntersectingWires);
02606   if (count > 0) {
02607     theDump += "  Intersecting Wires ....................... ";
02608     theDump += TCollection_AsciiString(count) + "\n";
02609   }
02610   count = NbProblems->Value((Standard_Integer)BRepCheck_InvalidImbricationOfWires);
02611   if (count > 0) {
02612     theDump += "  Invalid Imbrication of Wires ............. ";
02613     theDump += TCollection_AsciiString(count) + "\n";
02614   }
02615   count = NbProblems->Value((Standard_Integer)BRepCheck_EmptyShell);
02616   if (count > 0) {
02617     theDump += "  Empty Shell .............................. ";
02618     theDump += TCollection_AsciiString(count) + "\n";
02619   }
02620   count = NbProblems->Value((Standard_Integer)BRepCheck_RedundantFace);
02621   if (count > 0) {
02622     theDump += "  Redundant Face ........................... ";
02623     theDump += TCollection_AsciiString(count) + "\n";
02624   }
02625   count = NbProblems->Value((Standard_Integer)BRepCheck_UnorientableShape);
02626   if (count > 0) {
02627     theDump += "  Unorientable Shape ....................... ";
02628     theDump += TCollection_AsciiString(count) + "\n";
02629   }
02630   count = NbProblems->Value((Standard_Integer)BRepCheck_NotClosed);
02631   if (count > 0) {
02632     theDump += "  Not Closed ............................... ";
02633     theDump += TCollection_AsciiString(count) + "\n";
02634   }
02635   count = NbProblems->Value((Standard_Integer)BRepCheck_NotConnected);
02636   if (count > 0) {
02637     theDump += "  Not Connected ............................ ";
02638     theDump += TCollection_AsciiString(count) + "\n";
02639   }
02640   count = NbProblems->Value((Standard_Integer)BRepCheck_SubshapeNotInShape);
02641   if (count > 0) {
02642     theDump += "  Sub-shape not in Shape .................... ";
02643     theDump += TCollection_AsciiString(count) + "\n";
02644   }
02645   count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientation);
02646   if (count > 0) {
02647     theDump += "  Bad Orientation .......................... ";
02648     theDump += TCollection_AsciiString(count) + "\n";
02649   }
02650   count = NbProblems->Value((Standard_Integer)BRepCheck_BadOrientationOfSubshape);
02651   if (count > 0) {
02652     theDump += "  Bad Orientation of Sub-shape .............. ";
02653     theDump += TCollection_AsciiString(count) + "\n";
02654   }
02655   count = NbProblems->Value((Standard_Integer)BRepCheck_CheckFail);
02656   if (count > 0) {
02657     theDump += "  checkshape failure ....................... ";
02658     theDump += TCollection_AsciiString(count) + "\n";
02659   }
02660 
02661   theDump += " ------------------------------------------------\n";
02662   theDump += "*** Shapes with problems : ";
02663   theDump += TCollection_AsciiString(sl->Length()) + "\n";
02664 
02665   Standard_Integer nbv, nbe, nbw, nbf, nbs, nbo;
02666   nbv = nbe = nbw = nbf = nbs = nbo = 0;
02667 
02668   for (i = 1; i <= sl->Length(); i++) {
02669     TopoDS_Shape shi = sl->Value(i);
02670     TopAbs_ShapeEnum sti = shi.ShapeType();
02671     switch (sti) {
02672       case TopAbs_VERTEX : nbv++; break;
02673       case TopAbs_EDGE   : nbe++; break;
02674       case TopAbs_WIRE   : nbw++; break;
02675       case TopAbs_FACE   : nbf++; break;
02676       case TopAbs_SHELL  : nbs++; break;
02677       case TopAbs_SOLID  : nbo++; break;
02678       default            : break;
02679     }
02680   }
02681 
02682   if (nbv > 0) {
02683     theDump += "VERTEX : ";
02684     if (nbv < 10) theDump += " ";
02685     theDump += TCollection_AsciiString(nbv) + "\n";
02686   }
02687   if (nbe > 0) {
02688     theDump += "EDGE   : ";
02689     if (nbe < 10) theDump += " ";
02690     theDump += TCollection_AsciiString(nbe) + "\n";
02691   }
02692   if (nbw > 0) {
02693     theDump += "WIRE   : ";
02694     if (nbw < 10) theDump += " ";
02695     theDump += TCollection_AsciiString(nbw) + "\n";
02696   }
02697   if (nbf > 0) {
02698     theDump += "FACE   : ";
02699     if (nbf < 10) theDump += " ";
02700     theDump += TCollection_AsciiString(nbf) + "\n";
02701   }
02702   if (nbs > 0) {
02703     theDump += "SHELL  : ";
02704     if (nbs < 10) theDump += " ";
02705     theDump += TCollection_AsciiString(nbs) + "\n";
02706   }
02707   if (nbo > 0) {
02708     theDump += "SOLID  : ";
02709     if (nbo < 10) theDump += " ";
02710     theDump += TCollection_AsciiString(nbo) + "\n";
02711   }
02712 }
02713 
02714 
02715 //=======================================================================
02716 //function : GetProblemShapes
02717 // purpose : for StructuralDump
02718 //=======================================================================
02719 void GEOMImpl_IMeasureOperations::GetProblemShapes (const BRepCheck_Analyzer&           theAna,
02720                                                     const TopoDS_Shape&                 theShape,
02721                                                     Handle(TopTools_HSequenceOfShape)&  sl,
02722                                                     Handle(TColStd_HArray1OfInteger)&   NbProblems,
02723                                                     TopTools_DataMapOfShapeListOfShape& theMap)
02724 {
02725   for (TopoDS_Iterator iter(theShape); iter.More(); iter.Next()) {
02726     GetProblemShapes(theAna, iter.Value(), sl, NbProblems, theMap);
02727   }
02728   TopAbs_ShapeEnum styp = theShape.ShapeType();
02729   BRepCheck_ListIteratorOfListOfStatus itl;
02730   TopTools_ListOfShape empty;
02731   if (!theMap.IsBound(theShape)) {
02732     theMap.Bind(theShape,empty);
02733 
02734     if (!theAna.Result(theShape).IsNull()) {
02735       itl.Initialize(theAna.Result(theShape)->Status());
02736       // !!! May be, we have to print all the problems, not only the first one ?
02737       if (itl.Value() != BRepCheck_NoError) {
02738         sl->Append(theShape);
02739         BRepCheck_Status stat = itl.Value();
02740         NbProblems->SetValue((Standard_Integer)stat,
02741                              NbProblems->Value((Standard_Integer)stat) + 1);
02742       }
02743     }
02744   }
02745 
02746   switch (styp) {
02747   case TopAbs_EDGE:
02748     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
02749     break;
02750   case TopAbs_FACE:
02751     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_WIRE, theMap);
02752     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_EDGE, theMap);
02753     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_VERTEX, theMap);
02754     break;
02755   case TopAbs_SHELL:
02756     break;
02757   case TopAbs_SOLID:
02758     GetProblemSub(theAna, theShape, sl, NbProblems, TopAbs_SHELL, theMap);
02759     break;
02760   default:
02761     break;
02762   }
02763 }
02764 
02765 //=======================================================================
02766 //function : Contains
02767 //=======================================================================
02768 static Standard_Boolean Contains (const TopTools_ListOfShape& L,
02769                                   const TopoDS_Shape& S)
02770 {
02771   TopTools_ListIteratorOfListOfShape it;
02772   for (it.Initialize(L); it.More(); it.Next()) {
02773     if (it.Value().IsSame(S)) {
02774       return Standard_True;
02775     }
02776   }
02777   return Standard_False;
02778 }
02779 
02780 //=======================================================================
02781 //function : GetProblemSub
02782 // purpose : for StructuralDump
02783 //=======================================================================
02784 void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer&           theAna,
02785                                                  const TopoDS_Shape&                 theShape,
02786                                                  Handle(TopTools_HSequenceOfShape)&  sl,
02787                                                  Handle(TColStd_HArray1OfInteger)&   NbProblems,
02788                                                  const TopAbs_ShapeEnum              Subtype,
02789                                                  TopTools_DataMapOfShapeListOfShape& theMap)
02790 {
02791   BRepCheck_ListIteratorOfListOfStatus itl;
02792   TopExp_Explorer exp;
02793   for (exp.Init(theShape, Subtype); exp.More(); exp.Next()) {
02794     const TopoDS_Shape& sub = exp.Current();
02795 
02796     const Handle(BRepCheck_Result)& res = theAna.Result(sub);
02797     for (res->InitContextIterator();
02798          res->MoreShapeInContext();
02799          res->NextShapeInContext()) {
02800       if (res->ContextualShape().IsSame(theShape) && !Contains(theMap(sub), theShape)) {
02801         theMap(sub).Append(theShape);
02802         itl.Initialize(res->StatusOnShape());
02803 
02804         if (itl.Value() != BRepCheck_NoError) {
02805           Standard_Integer ii = 0;
02806 
02807           for (ii = 1; ii <= sl->Length(); ii++)
02808             if (sl->Value(ii).IsSame(sub)) break;
02809 
02810           if (ii > sl->Length()) {
02811             sl->Append(sub);
02812             BRepCheck_Status stat = itl.Value();
02813             NbProblems->SetValue((Standard_Integer)stat,
02814                                  NbProblems->Value((Standard_Integer)stat) + 1);
02815           }
02816           for (ii = 1; ii <= sl->Length(); ii++)
02817             if (sl->Value(ii).IsSame(theShape)) break;
02818           if (ii > sl->Length()) {
02819             sl->Append(theShape);
02820             BRepCheck_Status stat = itl.Value();
02821             NbProblems->SetValue((Standard_Integer)stat,
02822                                  NbProblems->Value((Standard_Integer)stat) + 1);
02823           }
02824         }
02825         break;
02826       }
02827     }
02828   }
02829 }