X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;ds=sidebyside;f=src%2FGEOMImpl%2FGEOMImpl_IMeasureOperations.cxx;h=4d500a92d236293a6bcdfd2e1f9bda5ea8178387;hb=de2617e3f55fc12bac2da61fcbaf2d96f1e38926;hp=94ecb8458ea7d0709a8a754271f8b43733741fbf;hpb=9499b99fe2dcb53e1ea364f97986f8f432b04600;p=modules%2Fgeom.git diff --git a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx index 94ecb8458..4d500a92d 100644 --- a/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx +++ b/src/GEOMImpl/GEOMImpl_IMeasureOperations.cxx @@ -1,22 +1,24 @@ -// Copyright (C) 2005 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// Copyright (C) 2007-2011 CEA/DEN, EDF R&D, OPEN CASCADE +// +// Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// +// // This library is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either +// License as published by the Free Software Foundation; either // version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU // Lesser General Public License for more details. // -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA // // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com -// + #include #include @@ -24,26 +26,47 @@ #include #include #include +#include + +#include +#include #include #include -#include "utilities.h" +#include + +#include +#include +#include +//#include +#include +#include +//#include +#include + +#include + +#include #include #include +// OCCT Includes #include #include #include #include #include +#include +#include #include -#include #include -#include -#include +#include +#include #include +#include +#include #include @@ -51,6 +74,7 @@ #include #include +#include #include #include #include @@ -62,11 +86,46 @@ #include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include + +#include #include // CAREFUL ! position of this file is critic : see Lucien PIGNOLONI / OCC +#include +#include +#include +#include +#include +#include +#include +#include + + //============================================================================= /*! - * constructor: + * Constructor */ //============================================================================= GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine, int theDocID) @@ -77,7 +136,7 @@ GEOMImpl_IMeasureOperations::GEOMImpl_IMeasureOperations (GEOM_Engine* theEngine //============================================================================= /*! - * destructor + * Destructor */ //============================================================================= GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations() @@ -85,6 +144,734 @@ GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations() MESSAGE("GEOMImpl_IMeasureOperations::~GEOMImpl_IMeasureOperations"); } +//============================================================================= +/*! Get kind and parameters of the given shape. + */ +//============================================================================= +GEOMImpl_IMeasureOperations::ShapeKind GEOMImpl_IMeasureOperations::KindOfShape + (Handle(GEOM_Object) theShape, + Handle(TColStd_HSequenceOfInteger)& theIntegers, + Handle(TColStd_HSequenceOfReal)& theDoubles) +{ + SetErrorCode(KO); + ShapeKind aKind = SK_NO_SHAPE; + + if (theIntegers.IsNull()) theIntegers = new TColStd_HSequenceOfInteger; + else theIntegers->Clear(); + + if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal; + else theDoubles->Clear(); + + if (theShape.IsNull()) + return aKind; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return aKind; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) return aKind; + + int geom_type = theShape->GetType(); + + // check if it's advanced shape + if ( geom_type > ADVANCED_BASE ) { + SetErrorCode(OK); + return SK_ADVANCED; + } + + // Call algorithm + GEOMAlgo_ShapeInfoFiller aSF; + aSF.SetShape(aShape); + aSF.Perform(); + Standard_Integer iErr = aSF.ErrorStatus(); + if (iErr) { + SetErrorCode("Error in GEOMAlgo_ShapeInfoFiller"); + return SK_NO_SHAPE; + } + const GEOMAlgo_ShapeInfo& anInfo = aSF.Info(); + + // Interprete results + TopAbs_ShapeEnum aType = anInfo.Type(); + switch (aType) + { + case TopAbs_COMPOUND: + case TopAbs_COMPSOLID: + { + // (+) geompy.kind.COMPOUND nb_solids nb_faces nb_edges nb_vertices + // (+) geompy.kind.COMPSOLID nb_solids nb_faces nb_edges nb_vertices + // ??? "nb_faces" - all faces or only 'standalone' faces? + if (aType == TopAbs_COMPOUND) + aKind = SK_COMPOUND; + else + aKind = SK_COMPSOLID; + + //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPOUND)); + //theIntegers->Append(anInfo.NbSubShapes(TopAbs_COMPSOLID)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_SOLID)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + break; + + case TopAbs_SHELL: + { + // (+) geompy.kind.SHELL geompy.info.closed nb_faces nb_edges nb_vertices + // (+) geompy.kind.SHELL geompy.info.unclosed nb_faces nb_edges nb_vertices + aKind = SK_SHELL; + + theIntegers->Append((int)anInfo.KindOfClosed()); + + theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + break; + + case TopAbs_WIRE: + { + // (+) geompy.kind.WIRE geompy.info.closed nb_edges nb_vertices + // (+) geompy.kind.WIRE geompy.info.unclosed nb_edges nb_vertices + aKind = SK_WIRE; + + theIntegers->Append((int)anInfo.KindOfClosed()); + + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + break; + + case TopAbs_SOLID: + { + aKind = SK_SOLID; + + GEOMAlgo_KindOfName aKN = anInfo.KindOfName(); + switch (aKN) + { + case GEOMAlgo_KN_SPHERE: + // (+) geompy.kind.SPHERE xc yc zc R + { + aKind = SK_SPHERE; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + theDoubles->Append(anInfo.Radius1()); + } + break; + case GEOMAlgo_KN_CYLINDER: + // (+) geompy.kind.CYLINDER xb yb zb dx dy dz R H + { + aKind = SK_CYLINDER; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Height()); + } + break; + case GEOMAlgo_KN_BOX: + // (+) geompy.kind.BOX xc yc zc ax ay az + { + aKind = SK_BOX; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + gp_Dir aX = anAx3.XDirection(); + + // ax ay az + if (aD.IsParallel(gp::DZ(), Precision::Angular()) && + aX.IsParallel(gp::DX(), Precision::Angular())) { + theDoubles->Append(anInfo.Length()); // ax' + theDoubles->Append(anInfo.Width()); // ay' + theDoubles->Append(anInfo.Height()); // az' + } + else if (aD.IsParallel(gp::DZ(), Precision::Angular()) && + aX.IsParallel(gp::DY(), Precision::Angular())) { + theDoubles->Append(anInfo.Width()); // ay' + theDoubles->Append(anInfo.Length()); // ax' + theDoubles->Append(anInfo.Height()); // az' + } + else if (aD.IsParallel(gp::DX(), Precision::Angular()) && + aX.IsParallel(gp::DZ(), Precision::Angular())) { + theDoubles->Append(anInfo.Height()); // az' + theDoubles->Append(anInfo.Width()); // ay' + theDoubles->Append(anInfo.Length()); // ax' + } + else if (aD.IsParallel(gp::DX(), Precision::Angular()) && + aX.IsParallel(gp::DY(), Precision::Angular())) { + theDoubles->Append(anInfo.Height()); // az' + theDoubles->Append(anInfo.Length()); // ax' + theDoubles->Append(anInfo.Width()); // ay' + } + else if (aD.IsParallel(gp::DY(), Precision::Angular()) && + aX.IsParallel(gp::DZ(), Precision::Angular())) { + theDoubles->Append(anInfo.Width()); // ay' + theDoubles->Append(anInfo.Height()); // az' + theDoubles->Append(anInfo.Length()); // ax' + } + else if (aD.IsParallel(gp::DY(), Precision::Angular()) && + aX.IsParallel(gp::DX(), Precision::Angular())) { + theDoubles->Append(anInfo.Length()); // ax' + theDoubles->Append(anInfo.Height()); // az' + theDoubles->Append(anInfo.Width()); // ay' + } + else { + // (+) geompy.kind.ROTATED_BOX xo yo zo zx zy zz xx xy xz ax ay az + aKind = SK_ROTATED_BOX; + + // Direction and XDirection + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(aX.X()); + theDoubles->Append(aX.Y()); + theDoubles->Append(aX.Z()); + + // ax ay az + theDoubles->Append(anInfo.Length()); + theDoubles->Append(anInfo.Width()); + theDoubles->Append(anInfo.Height()); + } + } + break; + case GEOMAlgo_KN_TORUS: + // (+) geompy.kind.TORUS xc yc zc dx dy dz R_1 R_2 + { + aKind = SK_TORUS; + + gp_Pnt aO = anInfo.Location(); + theDoubles->Append(aO.X()); + theDoubles->Append(aO.Y()); + theDoubles->Append(aO.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Radius2()); + } + break; + case GEOMAlgo_KN_CONE: + // (+) geompy.kind.CONE xb yb zb dx dy dz R_1 R_2 H + { + aKind = SK_CONE; + + gp_Pnt aO = anInfo.Location(); + theDoubles->Append(aO.X()); + theDoubles->Append(aO.Y()); + theDoubles->Append(aO.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Radius2()); + theDoubles->Append(anInfo.Height()); + } + break; + case GEOMAlgo_KN_POLYHEDRON: + // (+) geompy.kind.POLYHEDRON nb_faces nb_edges nb_vertices + { + aKind = SK_POLYHEDRON; + + theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + break; + default: + // (+) geompy.kind.SOLID nb_faces nb_edges nb_vertices + { + theIntegers->Append(anInfo.NbSubShapes(TopAbs_FACE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + } + } + break; + + case TopAbs_FACE: + { + aKind = SK_FACE; + + GEOMAlgo_KindOfName aKN = anInfo.KindOfName(); + switch (aKN) { + case GEOMAlgo_KN_SPHERE: + // (+) geompy.kind.SPHERE2D xc yc zc R + { + aKind = SK_SPHERE2D; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + theDoubles->Append(anInfo.Radius1()); + } + break; + case GEOMAlgo_KN_CYLINDER: + // (+) geompy.kind.CYLINDER2D xb yb zb dx dy dz R H + { + aKind = SK_CYLINDER2D; + + gp_Pnt aO = anInfo.Location(); + theDoubles->Append(aO.X()); + theDoubles->Append(aO.Y()); + theDoubles->Append(aO.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Height()); + } + break; + case GEOMAlgo_KN_TORUS: + // (+) geompy.kind.TORUS2D xc yc zc dx dy dz R_1 R_2 + { + aKind = SK_TORUS2D; + + gp_Pnt aO = anInfo.Location(); + theDoubles->Append(aO.X()); + theDoubles->Append(aO.Y()); + theDoubles->Append(aO.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Radius2()); + } + break; + case GEOMAlgo_KN_CONE: + // (+) geompy.kind.CONE2D xc yc zc dx dy dz R_1 R_2 H + { + aKind = SK_CONE2D; + + gp_Pnt aO = anInfo.Location(); + theDoubles->Append(aO.X()); + theDoubles->Append(aO.Y()); + theDoubles->Append(aO.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Radius2()); + theDoubles->Append(anInfo.Height()); + } + break; + case GEOMAlgo_KN_DISKCIRCLE: + // (+) geompy.kind.DISK_CIRCLE xc yc zc dx dy dz R + { + aKind = SK_DISK_CIRCLE; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + } + break; + case GEOMAlgo_KN_DISKELLIPSE: + // (+) geompy.kind.DISK_ELLIPSE xc yc zc dx dy dz R_1 R_2 + { + aKind = SK_DISK_ELLIPSE; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Radius2()); + } + break; + case GEOMAlgo_KN_RECTANGLE: + case GEOMAlgo_KN_TRIANGLE: + case GEOMAlgo_KN_QUADRANGLE: + case GEOMAlgo_KN_POLYGON: + // (+) geompy.kind.POLYGON xo yo zo dx dy dz nb_edges nb_vertices + { + aKind = SK_POLYGON; + + gp_Pnt aO = anInfo.Location(); + theDoubles->Append(aO.X()); + theDoubles->Append(aO.Y()); + theDoubles->Append(aO.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + break; + case GEOMAlgo_KN_PLANE: // infinite + // (+) geompy.kind.PLANE xo yo zo dx dy dz + { + aKind = SK_PLANE; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + } + break; + default: + if (anInfo.KindOfShape() == GEOMAlgo_KS_PLANE) { + // (+) geompy.kind.PLANAR xo yo zo dx dy dz nb_edges nb_vertices + + aKind = SK_PLANAR; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + else { + // ??? geompy.kind.FACE nb_edges nb_vertices _surface_type_id_ + // (+) geompy.kind.FACE nb_edges nb_vertices + + theIntegers->Append(anInfo.NbSubShapes(TopAbs_EDGE)); + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + } + } + break; + + case TopAbs_EDGE: + { + aKind = SK_EDGE; + + GEOMAlgo_KindOfName aKN = anInfo.KindOfName(); + switch (aKN) { + case GEOMAlgo_KN_CIRCLE: + { + // (+) geompy.kind.CIRCLE xc yc zc dx dy dz R + aKind = SK_CIRCLE; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + } + break; + case GEOMAlgo_KN_ARCCIRCLE: + { + // (+) geompy.kind.ARC_CIRCLE xc yc zc dx dy dz R x1 y1 z1 x2 y2 z2 + aKind = SK_ARC_CIRCLE; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + + gp_Pnt aP1 = anInfo.Pnt1(); + theDoubles->Append(aP1.X()); + theDoubles->Append(aP1.Y()); + theDoubles->Append(aP1.Z()); + + gp_Pnt aP2 = anInfo.Pnt2(); + theDoubles->Append(aP2.X()); + theDoubles->Append(aP2.Y()); + theDoubles->Append(aP2.Z()); + } + break; + case GEOMAlgo_KN_ELLIPSE: + { + // (+) geompy.kind.ELLIPSE xc yc zc dx dy dz R_1 R_2 + aKind = SK_ELLIPSE; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Radius2()); + } + break; + case GEOMAlgo_KN_ARCELLIPSE: + { + // (+) geompy.kind.ARC_ELLIPSE xc yc zc dx dy dz R_1 R_2 x1 y1 z1 x2 y2 z2 + aKind = SK_ARC_ELLIPSE; + + gp_Pnt aC = anInfo.Location(); + theDoubles->Append(aC.X()); + theDoubles->Append(aC.Y()); + theDoubles->Append(aC.Z()); + + gp_Ax3 anAx3 = anInfo.Position(); + gp_Dir aD = anAx3.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + + theDoubles->Append(anInfo.Radius1()); + theDoubles->Append(anInfo.Radius2()); + + gp_Pnt aP1 = anInfo.Pnt1(); + theDoubles->Append(aP1.X()); + theDoubles->Append(aP1.Y()); + theDoubles->Append(aP1.Z()); + + gp_Pnt aP2 = anInfo.Pnt2(); + theDoubles->Append(aP2.X()); + theDoubles->Append(aP2.Y()); + theDoubles->Append(aP2.Z()); + } + break; + case GEOMAlgo_KN_LINE: + { + // ??? geompy.kind.LINE x1 y1 z1 x2 y2 z2 + // (+) geompy.kind.LINE x1 y1 z1 dx dy dz + aKind = SK_LINE; + + gp_Pnt aO = anInfo.Location(); + theDoubles->Append(aO.X()); + theDoubles->Append(aO.Y()); + theDoubles->Append(aO.Z()); + + gp_Dir aD = anInfo.Direction(); + theDoubles->Append(aD.X()); + theDoubles->Append(aD.Y()); + theDoubles->Append(aD.Z()); + } + break; + case GEOMAlgo_KN_SEGMENT: + { + // (+) geompy.kind.SEGMENT x1 y1 z1 x2 y2 z2 + aKind = SK_SEGMENT; + + gp_Pnt aP1 = anInfo.Pnt1(); + theDoubles->Append(aP1.X()); + theDoubles->Append(aP1.Y()); + theDoubles->Append(aP1.Z()); + + gp_Pnt aP2 = anInfo.Pnt2(); + theDoubles->Append(aP2.X()); + theDoubles->Append(aP2.Y()); + theDoubles->Append(aP2.Z()); + } + break; + default: + // ??? geompy.kind.EDGE nb_vertices _curve_type_id_ + // (+) geompy.kind.EDGE nb_vertices + theIntegers->Append(anInfo.NbSubShapes(TopAbs_VERTEX)); + } + } + break; + + case TopAbs_VERTEX: + { + // (+) geompy.kind.VERTEX x y z + aKind = SK_VERTEX; + + gp_Pnt aP = anInfo.Location(); + theDoubles->Append(aP.X()); + theDoubles->Append(aP.Y()); + theDoubles->Append(aP.Z()); + } + break; + } + + SetErrorCode(OK); + return aKind; +} + +//============================================================================= +/*! Get LCS, corresponding to the given shape. + * Origin of the LCS is situated at the shape's center of mass. + * Axes of the LCS are obtained from shape's location or, + * if the shape is a planar face, from position of its plane. + */ +//============================================================================= +gp_Ax3 GEOMImpl_IMeasureOperations::GetPosition (const TopoDS_Shape& theShape) +{ + gp_Ax3 aResult; + + if (theShape.IsNull()) + return aResult; + + // Axes + aResult.Transform(theShape.Location().Transformation()); + if (theShape.ShapeType() == TopAbs_FACE) { + Handle(Geom_Surface) aGS = BRep_Tool::Surface(TopoDS::Face(theShape)); + if (!aGS.IsNull() && aGS->IsKind(STANDARD_TYPE(Geom_Plane))) { + Handle(Geom_Plane) aGPlane = Handle(Geom_Plane)::DownCast(aGS); + gp_Pln aPln = aGPlane->Pln(); + aResult = aPln.Position(); + } + } + + // Origin + gp_Pnt aPnt; + + TopAbs_ShapeEnum aShType = theShape.ShapeType(); + + if (aShType == TopAbs_VERTEX) { + aPnt = BRep_Tool::Pnt(TopoDS::Vertex(theShape)); + } + else { + if (aShType == TopAbs_COMPOUND) { + aShType = GEOMImpl_IShapesOperations::GetTypeOfSimplePart(theShape); + } + + GProp_GProps aSystem; + if (aShType == TopAbs_EDGE || aShType == TopAbs_WIRE) + BRepGProp::LinearProperties(theShape, aSystem); + else if (aShType == TopAbs_FACE || aShType == TopAbs_SHELL) + BRepGProp::SurfaceProperties(theShape, aSystem); + else + BRepGProp::VolumeProperties(theShape, aSystem); + + aPnt = aSystem.CentreOfMass(); + } + + aResult.SetLocation(aPnt); + + return aResult; +} + +//============================================================================= +/*! + * GetPosition + */ +//============================================================================= +void GEOMImpl_IMeasureOperations::GetPosition + (Handle(GEOM_Object) theShape, + Standard_Real& Ox, Standard_Real& Oy, Standard_Real& Oz, + Standard_Real& Zx, Standard_Real& Zy, Standard_Real& Zz, + Standard_Real& Xx, Standard_Real& Xy, Standard_Real& Xz) +{ + SetErrorCode(KO); + + //Set default values: global CS + Ox = Oy = Oz = Zx = Zy = Xy = Xz = 0.; + Zz = Xx = 1.; + + if (theShape.IsNull()) return; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("The Objects has NULL Shape"); + return; + } + + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + + gp_Ax3 anAx3 = GetPosition(aShape); + + gp_Pnt anOri = anAx3.Location(); + gp_Dir aDirZ = anAx3.Direction(); + gp_Dir aDirX = anAx3.XDirection(); + + // Output values + anOri.Coord(Ox, Oy, Oz); + aDirZ.Coord(Zx, Zy, Zz); + aDirX.Coord(Xx, Xy, Xz); + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return; + } + + SetErrorCode(OK); +} //============================================================================= /*! @@ -118,6 +905,9 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass //Compute the CentreOfMass value try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif if (!GetSolver()->ComputeFunction(aFunction)) { SetErrorCode("Measure driver failed to compute centre of mass"); return NULL; @@ -136,6 +926,124 @@ Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetCentreOfMass return aCDG; } +//============================================================================= +/*! + * GetVertexByIndex + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetVertexByIndex + (Handle(GEOM_Object) theShape, + Standard_Integer theIndex) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return NULL; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return NULL; + + //Add a new Vertex object + Handle(GEOM_Object) aVertex = GetEngine()->AddObject(GetDocID(), GEOM_POINT); + + //Add a function + Handle(GEOM_Function) aFunction = + aVertex->AddFunction(GEOMImpl_MeasureDriver::GetID(), VERTEX_BY_INDEX); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL; + + GEOMImpl_IMeasure aCI (aFunction); + aCI.SetBase(aRefShape); + aCI.SetIndex(theIndex); + + //Compute + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Vertex by index driver failed."); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump(aFunction) << aVertex << " = geompy.GetVertexByIndex(" << theShape << ", " << theIndex << ")"; + + SetErrorCode(OK); + return aVertex; +} + +//============================================================================= +/*! + * GetNormal + */ +//============================================================================= +Handle(GEOM_Object) GEOMImpl_IMeasureOperations::GetNormal + (Handle(GEOM_Object) theFace, + Handle(GEOM_Object) theOptionalPoint) +{ + SetErrorCode(KO); + + if (theFace.IsNull()) return NULL; + + //Add a new Normale object + Handle(GEOM_Object) aNorm = GetEngine()->AddObject(GetDocID(), GEOM_VECTOR); + + //Add a new Normale function + Handle(GEOM_Function) aFunction = + aNorm->AddFunction(GEOMImpl_MeasureDriver::GetID(), VECTOR_FACE_NORMALE); + if (aFunction.IsNull()) return NULL; + + //Check if the function is set correctly + if (aFunction->GetDriverGUID() != GEOMImpl_MeasureDriver::GetID()) return NULL; + + GEOMImpl_IMeasure aCI (aFunction); + + Handle(GEOM_Function) aFace = theFace->GetLastFunction(); + if (aFace.IsNull()) return NULL; + + aCI.SetBase(aFace); + + if (!theOptionalPoint.IsNull()) { + Handle(GEOM_Function) anOptPnt = theOptionalPoint->GetLastFunction(); + aCI.SetPoint(anOptPnt); + } + + //Compute the Normale value + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (!GetSolver()->ComputeFunction(aFunction)) { + SetErrorCode("Measure driver failed to compute normake of face"); + return NULL; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return NULL; + } + + //Make a Python command + GEOM::TPythonDump pd (aFunction); + pd << aNorm << " = geompy.GetNormal(" << theFace; + if (!theOptionalPoint.IsNull()) { + pd << ", " << theOptionalPoint; + } + pd << ")"; + + SetErrorCode(OK); + return aNorm; +} + //============================================================================= /*! * GetBasicProperties @@ -162,6 +1070,9 @@ void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theSha //Compute the parameters GProp_GProps LProps, SProps; try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif BRepGProp::LinearProperties(aShape, LProps); theLength = LProps.Mass(); @@ -171,9 +1082,9 @@ void GEOMImpl_IMeasureOperations::GetBasicProperties (Handle(GEOM_Object) theSha theVolume = 0.0; if (aShape.ShapeType() < TopAbs_SHELL) { for (TopExp_Explorer Exp (aShape, TopAbs_SOLID); Exp.More(); Exp.Next()) { - GProp_GProps VProps; - BRepGProp::VolumeProperties(Exp.Current(), VProps); - theVolume += VProps.Mass(); + GProp_GProps VProps; + BRepGProp::VolumeProperties(Exp.Current(), VProps); + theVolume += VProps.Mass(); } } } @@ -211,362 +1122,1343 @@ void GEOMImpl_IMeasureOperations::GetInertia return; } - //Compute the parameters - GProp_GProps System; - + //Compute the parameters + GProp_GProps System; + + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + if (aShape.ShapeType() == TopAbs_VERTEX || + aShape.ShapeType() == TopAbs_EDGE || + aShape.ShapeType() == TopAbs_WIRE) { + BRepGProp::LinearProperties(aShape, System); + } else if (aShape.ShapeType() == TopAbs_FACE || + aShape.ShapeType() == TopAbs_SHELL) { + BRepGProp::SurfaceProperties(aShape, System); + } else { + BRepGProp::VolumeProperties(aShape, System); + } + gp_Mat I = System.MatrixOfInertia(); + + I11 = I(1,1); + I12 = I(1,2); + I13 = I(1,3); + + I21 = I(2,1); + I22 = I(2,2); + I23 = I(2,3); + + I31 = I(3,1); + I32 = I(3,2); + I33 = I(3,3); + + GProp_PrincipalProps Pr = System.PrincipalProperties(); + Pr.Moments(Ix,Iy,Iz); + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return; + } + + SetErrorCode(OK); +} + +//============================================================================= +/*! + * GetBoundingBox + */ +//============================================================================= +void GEOMImpl_IMeasureOperations::GetBoundingBox + (Handle(GEOM_Object) theShape, + Standard_Real& Xmin, Standard_Real& Xmax, + Standard_Real& Ymin, Standard_Real& Ymax, + Standard_Real& Zmin, Standard_Real& Zmax) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("The Objects has NULL Shape"); + return; + } + + //Compute the parameters + Bnd_Box B; + + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + BRepBndLib::Add(aShape, B); + B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return; + } + + SetErrorCode(OK); +} + +//============================================================================= +/*! + * GetTolerance + */ +//============================================================================= +void GEOMImpl_IMeasureOperations::GetTolerance + (Handle(GEOM_Object) theShape, + Standard_Real& FaceMin, Standard_Real& FaceMax, + Standard_Real& EdgeMin, Standard_Real& EdgeMax, + Standard_Real& VertMin, Standard_Real& VertMax) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("The Objects has NULL Shape"); + return; + } + + //Compute the parameters + Standard_Real T; + FaceMin = EdgeMin = VertMin = RealLast(); + FaceMax = EdgeMax = VertMax = -RealLast(); + + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) { + TopoDS_Face Face = TopoDS::Face(ExF.Current()); + T = BRep_Tool::Tolerance(Face); + if (T > FaceMax) + FaceMax = T; + if (T < FaceMin) + FaceMin = T; + } + for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) { + TopoDS_Edge Edge = TopoDS::Edge(ExE.Current()); + T = BRep_Tool::Tolerance(Edge); + if (T > EdgeMax) + EdgeMax = T; + if (T < EdgeMin) + EdgeMin = T; + } + for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) { + TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current()); + T = BRep_Tool::Tolerance(Vertex); + if (T > VertMax) + VertMax = T; + if (T < VertMin) + VertMin = T; + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return; + } + + SetErrorCode(OK); +} + +//============================================================================= +/*! + * CheckShape + */ +//============================================================================= +bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape, + const Standard_Boolean theIsCheckGeom, + TCollection_AsciiString& theDump) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) return false; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return false; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("The Objects has NULL Shape"); + return false; + } + + //Compute the parameters + bool isValid = false; + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + BRepCheck_Analyzer ana (aShape, theIsCheckGeom); + if (ana.IsValid()) { + theDump.Clear(); + isValid = true; + } else { + StructuralDump(ana, aShape, theDump); + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return false; + } + + SetErrorCode(OK); + return isValid; +} + +//============================================================================= +/*! + * CheckSelfIntersections + */ +//============================================================================= +bool GEOMImpl_IMeasureOperations::CheckSelfIntersections + (Handle(GEOM_Object) theShape, + Handle(TColStd_HSequenceOfInteger)& theIntersections) +{ + SetErrorCode(KO); + bool isGood = false; + + if (theIntersections.IsNull()) + theIntersections = new TColStd_HSequenceOfInteger; + else + theIntersections->Clear(); + + if (theShape.IsNull()) + return isGood; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return isGood; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) return isGood; + + // 0. Prepare data + BRep_Builder aBB; + TopoDS_Compound aCS; + TopoDS_Shape aScopy; + NMTDS_Tools::CopyShape(aShape, aScopy); + + // Map sub-shapes and their indices + TopTools_IndexedMapOfShape anIndices; + TopExp::MapShapes(aScopy, anIndices); + + aBB.MakeCompound(aCS); + aBB.Add(aCS, aScopy); + + NMTTools_CheckerSI aCSI; // checker of self-interferences + aCSI.SetCompositeShape(aCS); + + // 1. Launch the checker + aCSI.Perform(); + Standard_Integer iErr = aCSI.StopStatus(); + if (iErr) { + return false; // Error + } + + isGood = true; + + // 2. Take the shapes from DS + const NMTDS_ShapesDataStructure& aDS = *(aCSI.DS()); + Standard_Integer aNbS = aDS.NumberOfShapesOfTheObject(); + + // 3. Get the pairs of interfered shapes + NMTDS_PInterfPool pIP = aCSI.IP(); + //const NMTDS_ListOfPassKeyBoolean& aLPKB = pIP->Get(); + const NMTDS_ListOfPairBoolean& aLPKB = pIP->Get(); + + Standard_Integer n1, n2; + //NMTDS_ListIteratorOfListOfPassKeyBoolean aIt; + NMTDS_ListIteratorOfListOfPairBoolean aIt; + + aIt.Initialize(aLPKB); + for (; aIt.More(); aIt.Next()) { + //const NMTDS_PassKeyBoolean& aPKB = aIt.Value(); + const NMTDS_PairBoolean& aPKB = aIt.Value(); + aPKB.Ids(n1, n2); + + if (n1 > aNbS || n2 > aNbS) + return false; // Error + + const TopoDS_Shape& aS1 = aDS.Shape(n1); + const TopoDS_Shape& aS2 = aDS.Shape(n2); + + theIntersections->Append(anIndices.FindIndex(aS1)); + theIntersections->Append(anIndices.FindIndex(aS2)); + isGood = false; + } + + SetErrorCode(OK); + return isGood; +} + +//============================================================================= +/*! + * IsGoodForSolid + */ +//============================================================================= +TCollection_AsciiString GEOMImpl_IMeasureOperations::IsGoodForSolid (Handle(GEOM_Object) theShape) +{ + SetErrorCode(KO); + + TCollection_AsciiString aRes = ""; + + if (theShape.IsNull()) { + aRes = "WRN_NULL_OBJECT_OR_SHAPE"; + } + else { + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) { + aRes = "WRN_NULL_OBJECT_OR_SHAPE"; + } + else { + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) { + aRes = "WRN_NULL_OBJECT_OR_SHAPE"; + } + else { + if (aShape.ShapeType() == TopAbs_COMPOUND) { + TopoDS_Iterator It (aShape, Standard_True, Standard_True); + if (It.More()) aShape = It.Value(); + } + if (aShape.ShapeType() == TopAbs_SHELL) { + BRepCheck_Shell chkShell (TopoDS::Shell(aShape)); + if (chkShell.Closed() == BRepCheck_NotClosed) { + aRes = "WRN_SHAPE_UNCLOSED"; + } + } + else { + aRes = "WRN_SHAPE_NOT_SHELL"; + } + } + } + } + + if (aRes.IsEmpty()) + SetErrorCode(OK); + + return aRes; +} + +//============================================================================= +/*! + * WhatIs + */ +//============================================================================= +TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape) +{ + SetErrorCode(KO); + + TCollection_AsciiString Astr; + + if (theShape.IsNull()) return Astr; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) return Astr; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull()) { + SetErrorCode("The Objects has NULL Shape"); + return Astr; + } + + //Compute the parameters + if (aShape.ShapeType() == TopAbs_EDGE) { + if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) { + Astr = Astr + " It is a degenerated edge \n"; + } + } + + Astr = Astr + " Number of sub-shapes : \n"; + + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + int iType, nbTypes [TopAbs_SHAPE]; + for (iType = 0; iType < TopAbs_SHAPE; ++iType) + nbTypes[iType] = 0; + nbTypes[aShape.ShapeType()]++; + + TopTools_MapOfShape aMapOfShape; + aMapOfShape.Add(aShape); + TopTools_ListOfShape aListOfShape; + aListOfShape.Append(aShape); + + TopTools_ListIteratorOfListOfShape itL (aListOfShape); + for (; itL.More(); itL.Next()) { + TopoDS_Iterator it (itL.Value()); + for (; it.More(); it.Next()) { + TopoDS_Shape s = it.Value(); + if (aMapOfShape.Add(s)) { + aListOfShape.Append(s); + nbTypes[s.ShapeType()]++; + } + } + } + + Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n"; + Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n"; + Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n"; + Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n"; + Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n"; + Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n"; + Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n"; + Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n"; + Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent()); + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return Astr; + } + + SetErrorCode(OK); + return Astr; +} + + +//======================================================================= +//function : CheckSingularCase +//purpose : auxilary for GetMinDistance() +// workaround for bugs 19899, 19908 and 19910 from Mantis +//======================================================================= +static double CheckSingularCase(const TopoDS_Shape& aSh1, + const TopoDS_Shape& aSh2, + gp_Pnt& Ptmp1, gp_Pnt& Ptmp2) +{ + bool IsChange1 = false; + double AddDist1 = 0.0; + TopExp_Explorer anExp; + TopoDS_Shape tmpSh1, tmpSh2; + int nbf = 0; + for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) { + nbf++; + tmpSh1 = anExp.Current(); + } + if(nbf==1) { + TopoDS_Shape sh = aSh1; + while(sh.ShapeType()==TopAbs_COMPOUND) { + TopoDS_Iterator it(sh); + sh = it.Value(); + } + Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh1)); + if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) || + S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) { + if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) { + // non solid case + double U1,U2,V1,V2; + // changes for 0020677: EDF 1219 GEOM: MinDistance gives 0 instead of 20.88 + //S->Bounds(U1,U2,V1,V2); changed by + ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh1),U1,U2,V1,V2); + // end of changes for 020677 (dmv) + Handle(Geom_RectangularTrimmedSurface) TrS1 = + new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2); + Handle(Geom_RectangularTrimmedSurface) TrS2 = + new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2); + BRep_Builder B; + TopoDS_Face F1,F2; + TopoDS_Compound Comp; + B.MakeCompound(Comp); + B.MakeFace(F1,TrS1,1.e-7); + B.Add(Comp,F1); + B.MakeFace(F2,TrS2,1.e-7); + B.Add(Comp,F2); + Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + sfs->Init(Comp); + sfs->SetPrecision(1.e-6); + sfs->SetMaxTolerance(1.0); + sfs->Perform(); + tmpSh1 = sfs->Shape(); + IsChange1 = true; + } + else { + if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) { + Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S); + gp_Pnt PC = SS->Location(); + BRep_Builder B; + TopoDS_Vertex V; + B.MakeVertex(V,PC,1.e-7); + tmpSh1 = V; + AddDist1 = SS->Radius(); + IsChange1 = true; + } + else { + Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S); + gp_Ax3 ax3 = TS->Position(); + Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius()); + BRep_Builder B; + TopoDS_Edge E; + B.MakeEdge(E,C,1.e-7); + tmpSh1 = E; + AddDist1 = TS->MinorRadius(); + IsChange1 = true; + } + } + } + else + tmpSh1 = aSh1; + } + else + tmpSh1 = aSh1; + bool IsChange2 = false; + double AddDist2 = 0.0; + nbf = 0; + for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) { + nbf++; + tmpSh2 = anExp.Current(); + } + if(nbf==1) { + TopoDS_Shape sh = aSh2; + while(sh.ShapeType()==TopAbs_COMPOUND) { + TopoDS_Iterator it(sh); + sh = it.Value(); + } + Handle(Geom_Surface) S = BRep_Tool::Surface(TopoDS::Face(tmpSh2)); + if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) || + S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) { + if( sh.ShapeType()==TopAbs_SHELL || sh.ShapeType()==TopAbs_FACE ) { + // non solid case + double U1,U2,V1,V2; + //S->Bounds(U1,U2,V1,V2); + ShapeAnalysis::GetFaceUVBounds(TopoDS::Face(tmpSh2),U1,U2,V1,V2); + Handle(Geom_RectangularTrimmedSurface) TrS1 = + new Geom_RectangularTrimmedSurface(S,U1,(U1+U2)/2.,V1,V2); + Handle(Geom_RectangularTrimmedSurface) TrS2 = + new Geom_RectangularTrimmedSurface(S,(U1+U2)/2.,U2,V1,V2); + BRep_Builder B; + TopoDS_Face F1,F2; + TopoDS_Compound Comp; + B.MakeCompound(Comp); + B.MakeFace(F1,TrS1,1.e-7); + B.Add(Comp,F1); + B.MakeFace(F2,TrS2,1.e-7); + B.Add(Comp,F2); + Handle(ShapeFix_Shape) sfs = new ShapeFix_Shape; + sfs->Init(Comp); + sfs->SetPrecision(1.e-6); + sfs->SetMaxTolerance(1.0); + sfs->Perform(); + tmpSh2 = sfs->Shape(); + IsChange2 = true; + } + else { + if( S->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) ) { + Handle(Geom_SphericalSurface) SS = Handle(Geom_SphericalSurface)::DownCast(S); + gp_Pnt PC = SS->Location(); + BRep_Builder B; + TopoDS_Vertex V; + B.MakeVertex(V,PC,1.e-7); + tmpSh2 = V; + AddDist2 = SS->Radius(); + IsChange2 = true; + } + else if( S->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) { + Handle(Geom_ToroidalSurface) TS = Handle(Geom_ToroidalSurface)::DownCast(S); + gp_Ax3 ax3 = TS->Position(); + Handle(Geom_Circle) C = new Geom_Circle(ax3.Ax2(),TS->MajorRadius()); + BRep_Builder B; + TopoDS_Edge E; + B.MakeEdge(E,C,1.e-7); + tmpSh2 = E; + AddDist2 = TS->MinorRadius(); + IsChange2 = true; + } + } + } + else + tmpSh2 = aSh2; + } + else + tmpSh2 = aSh2; + + if( !IsChange1 && !IsChange2 ) + return -2.0; + + BRepExtrema_DistShapeShape dst(tmpSh1,tmpSh2); + if (dst.IsDone()) { + double MinDist = 1.e9; + gp_Pnt PMin1, PMin2, P1, P2; + for (int i = 1; i <= dst.NbSolution(); i++) { + P1 = dst.PointOnShape1(i); + P2 = dst.PointOnShape2(i); + Standard_Real Dist = P1.Distance(P2); + if (MinDist > Dist) { + MinDist = Dist; + PMin1 = P1; + PMin2 = P2; + } + } + if(MinDist<1.e-7) { + Ptmp1 = PMin1; + Ptmp2 = PMin2; + } + else { + gp_Dir aDir(gp_Vec(PMin1,PMin2)); + if( MinDist > (AddDist1+AddDist2) ) { + Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1, + PMin1.Y() + aDir.Y()*AddDist1, + PMin1.Z() + aDir.Z()*AddDist1 ); + Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2, + PMin2.Y() - aDir.Y()*AddDist2, + PMin2.Z() - aDir.Z()*AddDist2 ); + return (MinDist - AddDist1 - AddDist2); + } + else { + if( AddDist1 > 0 ) { + Ptmp1 = gp_Pnt( PMin1.X() + aDir.X()*AddDist1, + PMin1.Y() + aDir.Y()*AddDist1, + PMin1.Z() + aDir.Z()*AddDist1 ); + Ptmp2 = Ptmp1; + } + else { + Ptmp2 = gp_Pnt( PMin2.X() - aDir.X()*AddDist2, + PMin2.Y() - aDir.Y()*AddDist2, + PMin2.Z() - aDir.Z()*AddDist2 ); + Ptmp1 = Ptmp2; + } + } + } + double res = MinDist - AddDist1 - AddDist2; + if(res<0.) res = 0.0; + return res; + } + return -2.0; +} +/* old variant +static bool CheckSingularCase(const TopoDS_Shape& aSh1, + const TopoDS_Shape& aSh2, + gp_Pnt& Ptmp) +{ + TopExp_Explorer anExp; + TopoDS_Shape tmpSh1, tmpSh2; + int nbf = 0; + for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) { + nbf++; + tmpSh1 = anExp.Current(); + } + if(nbf==1) { + Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1)); + if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) || + S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) { + nbf = 0; + for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) { + nbf++; + tmpSh2 = anExp.Current(); + Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2)); + GeomAPI_IntSS ISS(S1,S2,1.e-7); + if(ISS.IsDone()) { + for(int i=1; i<=ISS.NbLines(); i++) { + Handle(Geom_Curve) C3d = ISS.Line(i); + BRep_Builder B; + TopoDS_Edge E; + B.MakeEdge(E,C3d,1.e-7); + BRepExtrema_DistShapeShape dst(tmpSh2,E); + if (dst.IsDone()) { + gp_Pnt PMin1, PMin2, P1, P2; + double MinDist = 1.e9; + for (int i = 1; i <= dst.NbSolution(); i++) { + P1 = dst.PointOnShape1(i); + P2 = dst.PointOnShape2(i); + Standard_Real Dist = P1.Distance(P2); + if (MinDist > Dist) { + MinDist = Dist; + Ptmp = P1; + } + } + if(MinDist<1.e-7) + return true; + } + } + } + } + } + } + nbf = 0; + for ( anExp.Init( aSh2, TopAbs_FACE ); anExp.More(); anExp.Next() ) { + nbf++; + tmpSh1 = anExp.Current(); + } + if(nbf==1) { + Handle(Geom_Surface) S1 = BRep_Tool::Surface(TopoDS::Face(tmpSh1)); + if( S1->IsKind(STANDARD_TYPE(Geom_SphericalSurface)) || + S1->IsKind(STANDARD_TYPE(Geom_ToroidalSurface)) ) { + nbf = 0; + for ( anExp.Init( aSh1, TopAbs_FACE ); anExp.More(); anExp.Next() ) { + nbf++; + tmpSh2 = anExp.Current(); + Handle(Geom_Surface) S2 = BRep_Tool::Surface(TopoDS::Face(tmpSh2)); + GeomAPI_IntSS ISS(S1,S2,1.e-7); + if(ISS.IsDone()) { + for(int i=1; i<=ISS.NbLines(); i++) { + Handle(Geom_Curve) C3d = ISS.Line(i); + BRep_Builder B; + TopoDS_Edge E; + B.MakeEdge(E,C3d,1.e-7); + BRepExtrema_DistShapeShape dst(tmpSh2,E); + if (dst.IsDone()) { + gp_Pnt P1,P2; + double MinDist = 1.e9; + for (int i = 1; i <= dst.NbSolution(); i++) { + P1 = dst.PointOnShape1(i); + P2 = dst.PointOnShape2(i); + Standard_Real Dist = P1.Distance(P2); + if (MinDist > Dist) { + MinDist = Dist; + Ptmp = P1; + } + } + if(MinDist<1.e-7) + return true; + } + } + } + } + } + } + return false; +} +*/ + + +//============================================================================= +/*! + * AreCoordsInside + */ +//============================================================================= +std::vector GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape, + const std::vector& coords, + double tolerance) +{ + std::vector res; + if (!theShape.IsNull()) { + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (!aRefShape.IsNull()) { + TopoDS_Shape aShape = aRefShape->GetValue(); + if (!aShape.IsNull()) { + BRepClass3d_SolidClassifier SC(aShape); + unsigned int nb_points = coords.size()/3; + for (int i = 0; i < nb_points; i++) { + double x = coords[3*i]; + double y = coords[3*i+1]; + double z = coords[3*i+2]; + gp_Pnt aPnt(x, y, z); + SC.Perform(aPnt, tolerance); + res.push_back( ( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON ) ); + } + } + } + } + return res; +} + +//============================================================================= +/*! + * GetMinDistance + */ +//============================================================================= +Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance + (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2, + Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1, + Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2) +{ + SetErrorCode(KO); + Standard_Real MinDist = 1.e9; + + if (theShape1.IsNull() || theShape2.IsNull()) return MinDist; + + Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction(); + Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction(); + if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist; + + TopoDS_Shape aShape1 = aRefShape1->GetValue(); + TopoDS_Shape aShape2 = aRefShape2->GetValue(); + if (aShape1.IsNull() || aShape2.IsNull()) { + SetErrorCode("One of Objects has NULL Shape"); + return MinDist; + } + + //Compute the parameters + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + + // Issue 0020231: A min distance bug with torus and vertex. + // Make GetMinDistance() return zero if a sole VERTEX is inside any of SOLIDs + + // which of shapes consists of only one vertex? + TopExp_Explorer exp1(aShape1,TopAbs_VERTEX), exp2(aShape2,TopAbs_VERTEX); + TopoDS_Shape V1 = exp1.More() ? exp1.Current() : TopoDS_Shape(); + TopoDS_Shape V2 = exp2.More() ? exp2.Current() : TopoDS_Shape(); + exp1.Next(); exp2.Next(); + if ( exp1.More() ) V1.Nullify(); + if ( exp2.More() ) V2.Nullify(); + // vertex and container of solids + TopoDS_Shape V = V1.IsNull() ? V2 : V1; + TopoDS_Shape S = V1.IsNull() ? aShape1 : aShape2; + if ( !V.IsNull() ) { + // classify vertex against solids + gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( V ) ); + for ( exp1.Init( S, TopAbs_SOLID ); exp1.More(); exp1.Next() ) { + BRepClass3d_SolidClassifier classifier( exp1.Current(), p, 1e-6); + if ( classifier.State() == TopAbs_IN ) { + p.Coord(X1, Y1, Z1); + p.Coord(X2, Y2, Z2); + SetErrorCode(OK); + return 0.0; + } + } + } + // End Issue 0020231 + + // skl 30.06.2008 + // additional workaround for bugs 19899, 19908 and 19910 from Mantis + gp_Pnt Ptmp1, Ptmp2; + double dist = CheckSingularCase(aShape1, aShape2, Ptmp1, Ptmp2); + if(dist>-1.0) { + Ptmp1.Coord(X1, Y1, Z1); + Ptmp2.Coord(X2, Y2, Z2); + SetErrorCode(OK); + return dist; + } + + BRepExtrema_DistShapeShape dst (aShape1, aShape2); + if (dst.IsDone()) { + gp_Pnt PMin1, PMin2, P1, P2; + + for (int i = 1; i <= dst.NbSolution(); i++) { + P1 = dst.PointOnShape1(i); + P2 = dst.PointOnShape2(i); + + Standard_Real Dist = P1.Distance(P2); + if (MinDist > Dist) { + MinDist = Dist; + PMin1 = P1; + PMin2 = P2; + } + } + + PMin1.Coord(X1, Y1, Z1); + PMin2.Coord(X2, Y2, Z2); + } + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + return MinDist; + } + + SetErrorCode(OK); + return MinDist; +} + +//======================================================================= +/*! + * Get coordinates of point + */ +//======================================================================= +void GEOMImpl_IMeasureOperations::PointCoordinates (Handle(GEOM_Object) theShape, + Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ) +{ + SetErrorCode(KO); + + if (theShape.IsNull()) + return; + + Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); + if (aRefShape.IsNull()) + return; + + TopoDS_Shape aShape = aRefShape->GetValue(); + if (aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX) + { + SetErrorCode( "Shape must be a vertex" ); + return; + } + + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) ); + theX = aPnt.X(); + theY = aPnt.Y(); + theZ = aPnt.Z(); + + SetErrorCode(OK); + } + catch (Standard_Failure) + { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode( aFail->GetMessageString() ); + } +} + +//======================================================================= +/*! + * Compute angle (in degrees) between two lines + */ +//======================================================================= +Standard_Real GEOMImpl_IMeasureOperations::GetAngle (Handle(GEOM_Object) theLine1, + Handle(GEOM_Object) theLine2) +{ + if (theLine1->GetType() == GEOM_VECTOR && + theLine2->GetType() == GEOM_VECTOR) + return GetAngleBtwVectors(theLine1, theLine2); + + SetErrorCode(KO); + + Standard_Real anAngle = -1.0; + + if (theLine1.IsNull() || theLine2.IsNull()) + return anAngle; + + Handle(GEOM_Function) aRefLine1 = theLine1->GetLastFunction(); + Handle(GEOM_Function) aRefLine2 = theLine2->GetLastFunction(); + if (aRefLine1.IsNull() || aRefLine2.IsNull()) + return anAngle; + + TopoDS_Shape aLine1 = aRefLine1->GetValue(); + TopoDS_Shape aLine2 = aRefLine2->GetValue(); + if (aLine1.IsNull() || aLine2.IsNull() || + aLine1.ShapeType() != TopAbs_EDGE || + aLine2.ShapeType() != TopAbs_EDGE) + { + SetErrorCode("Two edges must be given"); + return anAngle; + } + + try { +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + TopoDS_Edge E1 = TopoDS::Edge(aLine1); + TopoDS_Edge E2 = TopoDS::Edge(aLine2); + + double fp,lp; + Handle(Geom_Curve) C1 = BRep_Tool::Curve(E1,fp,lp); + Handle(Geom_Curve) C2 = BRep_Tool::Curve(E2,fp,lp); + + if ( C1.IsNull() || C2.IsNull() || + !C1->IsKind(STANDARD_TYPE(Geom_Line)) || + !C2->IsKind(STANDARD_TYPE(Geom_Line))) + { + SetErrorCode("The edges must be linear"); + return anAngle; + } + + Handle(Geom_Line) L1 = Handle(Geom_Line)::DownCast(C1); + Handle(Geom_Line) L2 = Handle(Geom_Line)::DownCast(C2); + + gp_Lin aLin1 = L1->Lin(); + gp_Lin aLin2 = L2->Lin(); + + anAngle = aLin1.Angle(aLin2); + anAngle /= PI180; // convert radians into degrees + + if (anAngle > 90.0) { + anAngle = 180.0 - anAngle; + } + + SetErrorCode(OK); + } + catch (Standard_Failure) + { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + SetErrorCode(aFail->GetMessageString()); + } + + return anAngle; +} + +//======================================================================= +/*! + * Compute angle (in degrees) between two vectors + */ +//======================================================================= +Standard_Real GEOMImpl_IMeasureOperations::GetAngleBtwVectors (Handle(GEOM_Object) theVec1, + Handle(GEOM_Object) theVec2) +{ + SetErrorCode(KO); + + Standard_Real anAngle = -1.0; + + if (theVec1.IsNull() || theVec2.IsNull()) + return anAngle; + + Handle(GEOM_Function) aRefVec1 = theVec1->GetLastFunction(); + Handle(GEOM_Function) aRefVec2 = theVec2->GetLastFunction(); + if (aRefVec1.IsNull() || aRefVec2.IsNull()) + return anAngle; + + TopoDS_Shape aVec1 = aRefVec1->GetValue(); + TopoDS_Shape aVec2 = aRefVec2->GetValue(); + if (aVec1.IsNull() || aVec2.IsNull() || + aVec1.ShapeType() != TopAbs_EDGE || + aVec2.ShapeType() != TopAbs_EDGE) + { + SetErrorCode("Two edges must be given"); + return anAngle; + } + try { - if (aShape.ShapeType() == TopAbs_VERTEX || - aShape.ShapeType() == TopAbs_EDGE || - aShape.ShapeType() == TopAbs_WIRE) { - BRepGProp::LinearProperties(aShape, System); - } else if (aShape.ShapeType() == TopAbs_FACE || - aShape.ShapeType() == TopAbs_SHELL) { - BRepGProp::SurfaceProperties(aShape, System); - } else { - BRepGProp::VolumeProperties(aShape, System); +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + TopoDS_Edge aE1 = TopoDS::Edge(aVec1); + TopoDS_Edge aE2 = TopoDS::Edge(aVec2); + + TopoDS_Vertex aP11, aP12, aP21, aP22; + TopExp::Vertices(aE1, aP11, aP12, Standard_True); + TopExp::Vertices(aE2, aP21, aP22, Standard_True); + if (aP11.IsNull() || aP12.IsNull() || aP21.IsNull() || aP22.IsNull()) { + SetErrorCode("Bad edge given"); + return anAngle; } - gp_Mat I = System.MatrixOfInertia(); - - I11 = I(1,1); - I12 = I(1,2); - I13 = I(1,3); - I21 = I(2,1); - I22 = I(2,2); - I23 = I(2,3); + gp_Vec aV1 (BRep_Tool::Pnt(aP11), BRep_Tool::Pnt(aP12)); + gp_Vec aV2 (BRep_Tool::Pnt(aP21), BRep_Tool::Pnt(aP22)) ; - I31 = I(3,1); - I32 = I(3,2); - I33 = I(3,3); + anAngle = aV1.Angle(aV2); + anAngle /= PI180; // convert radians into degrees - GProp_PrincipalProps Pr = System.PrincipalProperties(); - Pr.Moments(Ix,Iy,Iz); + SetErrorCode(OK); } - catch (Standard_Failure) { + catch (Standard_Failure) + { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); SetErrorCode(aFail->GetMessageString()); - return; } - SetErrorCode(OK); + return anAngle; } + //============================================================================= /*! - * GetBoundingBox + * CurveCurvatureByParam */ //============================================================================= -void GEOMImpl_IMeasureOperations::GetBoundingBox - (Handle(GEOM_Object) theShape, - Standard_Real& Xmin, Standard_Real& Xmax, - Standard_Real& Ymin, Standard_Real& Ymax, - Standard_Real& Zmin, Standard_Real& Zmax) +Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByParam + (Handle(GEOM_Object) theCurve, Standard_Real& theParam) { SetErrorCode(KO); + Standard_Real aRes = -1.0; - if (theShape.IsNull()) return; + if(theCurve.IsNull()) return aRes; - Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); - if (aRefShape.IsNull()) return; + Handle(GEOM_Function) aRefShape = theCurve->GetLastFunction(); + if(aRefShape.IsNull()) return aRes; TopoDS_Shape aShape = aRefShape->GetValue(); - if (aShape.IsNull()) { - SetErrorCode("The Objects has NULL Shape"); - return; + if(aShape.IsNull()) { + SetErrorCode("One of Objects has NULL Shape"); + return aRes; } - //Compute the parameters - Bnd_Box B; + Standard_Real aFP, aLP, aP; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(TopoDS::Edge(aShape), aFP, aLP); + aP = aFP + (aLP - aFP) * theParam; + + if(aCurve.IsNull()) return aRes; + //Compute curvature try { - BRepBndLib::Add(aShape, B); - B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax); +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + GeomLProp_CLProps Prop = GeomLProp_CLProps + (aCurve, aP, 2, Precision::Confusion()); + aRes = fabs(Prop.Curvature()); + SetErrorCode(OK); } catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); SetErrorCode(aFail->GetMessageString()); - return; + return aRes; } - SetErrorCode(OK); + if( aRes > Precision::Confusion() ) + aRes = 1/aRes; + else + aRes = RealLast(); + + return aRes; } + //============================================================================= /*! - * GetTolerance + * CurveCurvatureByPoint */ //============================================================================= -void GEOMImpl_IMeasureOperations::GetTolerance - (Handle(GEOM_Object) theShape, - Standard_Real& FaceMin, Standard_Real& FaceMax, - Standard_Real& EdgeMin, Standard_Real& EdgeMax, - Standard_Real& VertMin, Standard_Real& VertMax) +Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByPoint + (Handle(GEOM_Object) theCurve, Handle(GEOM_Object) thePoint) { SetErrorCode(KO); + Standard_Real aRes = -1.0; - if (theShape.IsNull()) return; + if( theCurve.IsNull() || thePoint.IsNull() ) return aRes; - Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); - if (aRefShape.IsNull()) return; + Handle(GEOM_Function) aRefCurve = theCurve->GetLastFunction(); + Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction(); + if( aRefCurve.IsNull() || aRefPoint.IsNull() ) return aRes; - TopoDS_Shape aShape = aRefShape->GetValue(); - if (aShape.IsNull()) { - SetErrorCode("The Objects has NULL Shape"); - return; + TopoDS_Edge anEdge = TopoDS::Edge(aRefCurve->GetValue()); + TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue()); + if( anEdge.IsNull() || aPnt.IsNull() ) { + SetErrorCode("One of Objects has NULL Shape"); + return aRes; } - //Compute the parameters - Standard_Real T; - FaceMin = EdgeMin = VertMin = RealLast(); - FaceMax = EdgeMax = VertMax = -RealLast(); + Standard_Real aFP, aLP; + Handle(Geom_Curve) aCurve = BRep_Tool::Curve(anEdge, aFP, aLP); + if(aCurve.IsNull()) return aRes; + gp_Pnt aPoint = BRep_Tool::Pnt(aPnt); + //Compute curvature try { - for (TopExp_Explorer ExF (aShape, TopAbs_FACE); ExF.More(); ExF.Next()) { - TopoDS_Face Face = TopoDS::Face(ExF.Current()); - T = BRep_Tool::Tolerance(Face); - if (T > FaceMax) - FaceMax = T; - if (T < FaceMin) - FaceMin = T; - } - for (TopExp_Explorer ExE (aShape, TopAbs_EDGE); ExE.More(); ExE.Next()) { - TopoDS_Edge Edge = TopoDS::Edge(ExE.Current()); - T = BRep_Tool::Tolerance(Edge); - if (T > EdgeMax) - EdgeMax = T; - if (T < EdgeMin) - EdgeMin = T; - } - for (TopExp_Explorer ExV (aShape, TopAbs_VERTEX); ExV.More(); ExV.Next()) { - TopoDS_Vertex Vertex = TopoDS::Vertex(ExV.Current()); - T = BRep_Tool::Tolerance(Vertex); - if (T > VertMax) - VertMax = T; - if (T < VertMin) - VertMin = T; +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + GeomAPI_ProjectPointOnCurve PPCurve(aPoint, aCurve, aFP, aLP); + if(PPCurve.NbPoints()>0) { + GeomLProp_CLProps Prop = GeomLProp_CLProps + (aCurve, PPCurve.LowerDistanceParameter(), 2, Precision::Confusion()); + aRes = fabs(Prop.Curvature()); + SetErrorCode(OK); } } catch (Standard_Failure) { Handle(Standard_Failure) aFail = Standard_Failure::Caught(); SetErrorCode(aFail->GetMessageString()); - return; + return aRes; } - SetErrorCode(OK); + if( aRes > Precision::Confusion() ) + aRes = 1/aRes; + else + aRes = RealLast(); + + return aRes; } + //============================================================================= /*! - * CheckShape + * getSurfaceCurvatures */ //============================================================================= -bool GEOMImpl_IMeasureOperations::CheckShape (Handle(GEOM_Object) theShape, - TCollection_AsciiString& theDump) +Standard_Real GEOMImpl_IMeasureOperations::getSurfaceCurvatures + (const Handle(Geom_Surface)& aSurf, + Standard_Real theUParam, + Standard_Real theVParam, + Standard_Boolean theNeedMaxCurv) { SetErrorCode(KO); + Standard_Real aRes = 1.0; - if (theShape.IsNull()) return false; - - Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); - if (aRefShape.IsNull()) return false; - - TopoDS_Shape aShape = aRefShape->GetValue(); - if (aShape.IsNull()) { - SetErrorCode("The Objects has NULL Shape"); - return false; - } + if (aSurf.IsNull()) return aRes; - //Compute the parameters - bool isValid = false; try { - BRepCheck_Analyzer ana (aShape, false); - if (ana.IsValid()) { - theDump.Clear(); - isValid = true; - } else { - StructuralDump(ana, aShape, theDump); +#if OCC_VERSION_LARGE > 0x06010000 + OCC_CATCH_SIGNALS; +#endif + GeomLProp_SLProps Prop = GeomLProp_SLProps + (aSurf, theUParam, theVParam, 2, Precision::Confusion()); + if(Prop.IsCurvatureDefined()) { + if(Prop.IsUmbilic()) { + //cout<<"is umbilic"<GetMessageString()); - return false; + return aRes; } - SetErrorCode(OK); - return isValid; + if( fabs(aRes) > Precision::Confusion() ) + aRes = 1/aRes; + else + aRes = RealLast(); + + return aRes; } + //============================================================================= /*! - * WhatIs + * MaxSurfaceCurvatureByParam */ //============================================================================= -TCollection_AsciiString GEOMImpl_IMeasureOperations::WhatIs (Handle(GEOM_Object) theShape) +Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByParam + (Handle(GEOM_Object) theSurf, + Standard_Real& theUParam, + Standard_Real& theVParam) { SetErrorCode(KO); + Standard_Real aRes = -1.0; - TCollection_AsciiString Astr; - - if (theShape.IsNull()) return Astr; + if (theSurf.IsNull()) return aRes; - Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); - if (aRefShape.IsNull()) return Astr; + Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction(); + if(aRefShape.IsNull()) return aRes; TopoDS_Shape aShape = aRefShape->GetValue(); - if (aShape.IsNull()) { - SetErrorCode("The Objects has NULL Shape"); - return Astr; + if(aShape.IsNull()) { + SetErrorCode("One of Objects has NULL Shape"); + return aRes; } + TopoDS_Face F = TopoDS::Face(aShape); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F); + //Compute the parameters - if (aShape.ShapeType() == TopAbs_EDGE) { - if (BRep_Tool::Degenerated(TopoDS::Edge(aShape))) { - Astr = Astr + " It is a degenerated edge \n"; - } - } + Standard_Real U1,U2,V1,V2; + ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2); + Standard_Real U = U1 + (U2-U1)*theUParam; + Standard_Real V = V1 + (V2-V1)*theVParam; - Astr = Astr + " Number of sub-shapes : \n"; + return getSurfaceCurvatures(aSurf, U, V, true); +} - try { - int iType, nbTypes [TopAbs_SHAPE]; - for (iType = 0; iType < TopAbs_SHAPE; ++iType) - nbTypes[iType] = 0; - nbTypes[aShape.ShapeType()]++; - TopTools_MapOfShape aMapOfShape; - aMapOfShape.Add(aShape); - TopTools_ListOfShape aListOfShape; - aListOfShape.Append(aShape); +//============================================================================= +/*! + * MaxSurfaceCurvatureByPoint + */ +//============================================================================= +Standard_Real GEOMImpl_IMeasureOperations::MaxSurfaceCurvatureByPoint + (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint) +{ + SetErrorCode(KO); + Standard_Real aRes = -1.0; - TopTools_ListIteratorOfListOfShape itL (aListOfShape); - for (; itL.More(); itL.Next()) { - TopoDS_Iterator it (itL.Value()); - for (; it.More(); it.Next()) { - TopoDS_Shape s = it.Value(); - if (aMapOfShape.Add(s)) { - aListOfShape.Append(s); - nbTypes[s.ShapeType()]++; - } - } - } + if( theSurf.IsNull() || thePoint.IsNull() ) return aRes; - Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbTypes[TopAbs_VERTEX]) + "\n"; - Astr = Astr + " EDGE : " + TCollection_AsciiString(nbTypes[TopAbs_EDGE]) + "\n"; - Astr = Astr + " WIRE : " + TCollection_AsciiString(nbTypes[TopAbs_WIRE]) + "\n"; - Astr = Astr + " FACE : " + TCollection_AsciiString(nbTypes[TopAbs_FACE]) + "\n"; - Astr = Astr + " SHELL : " + TCollection_AsciiString(nbTypes[TopAbs_SHELL]) + "\n"; - Astr = Astr + " SOLID : " + TCollection_AsciiString(nbTypes[TopAbs_SOLID]) + "\n"; - Astr = Astr + " COMPSOLID : " + TCollection_AsciiString(nbTypes[TopAbs_COMPSOLID]) + "\n"; - Astr = Astr + " COMPOUND : " + TCollection_AsciiString(nbTypes[TopAbs_COMPOUND]) + "\n"; - Astr = Astr + " SHAPE : " + TCollection_AsciiString(aMapOfShape.Extent()); - } - catch (Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); - return Astr; + Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction(); + Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction(); + if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes; + + TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue()); + TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue()); + if( aFace.IsNull() || aPnt.IsNull() ) { + SetErrorCode("One of Objects has NULL Shape"); + return 0; } - SetErrorCode(OK); - return Astr; + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + if(aSurf.IsNull()) return aRes; + gp_Pnt aPoint = BRep_Tool::Pnt(aPnt); + + //Compute the parameters + ShapeAnalysis_Surface sas(aSurf); + gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion()); + + return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), true); } + //============================================================================= /*! - * GetMinDistance + * MinSurfaceCurvatureByParam */ //============================================================================= -Standard_Real GEOMImpl_IMeasureOperations::GetMinDistance - (Handle(GEOM_Object) theShape1, Handle(GEOM_Object) theShape2, - Standard_Real& X1, Standard_Real& Y1, Standard_Real& Z1, - Standard_Real& X2, Standard_Real& Y2, Standard_Real& Z2) +Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByParam + (Handle(GEOM_Object) theSurf, + Standard_Real& theUParam, + Standard_Real& theVParam) { SetErrorCode(KO); - Standard_Real MinDist = 1.e9; + Standard_Real aRes = -1.0; - if (theShape1.IsNull() || theShape2.IsNull()) return MinDist; + if (theSurf.IsNull()) return aRes; - Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction(); - Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction(); - if (aRefShape1.IsNull() || aRefShape2.IsNull()) return MinDist; + Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction(); + if(aRefShape.IsNull()) return aRes; - TopoDS_Shape aShape1 = aRefShape1->GetValue(); - TopoDS_Shape aShape2 = aRefShape2->GetValue(); - if (aShape1.IsNull() || aShape2.IsNull()) { + TopoDS_Shape aShape = aRefShape->GetValue(); + if(aShape.IsNull()) { SetErrorCode("One of Objects has NULL Shape"); - return MinDist; + return aRes; } - //Compute the parameters - try { - BRepExtrema_DistShapeShape dst (aShape1, aShape2); - if (dst.IsDone()) { - gp_Pnt PMin1, PMin2, P1, P2; - - for (int i = 1; i <= dst.NbSolution(); i++) { - P1 = dst.PointOnShape1(i); - P2 = dst.PointOnShape2(i); - - Standard_Real Dist = P1.Distance(P2); - if (MinDist > Dist) { - MinDist = Dist; - PMin1 = P1; - PMin2 = P2; - } - } + TopoDS_Face F = TopoDS::Face(aShape); + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(F); - PMin1.Coord(X1, Y1, Z1); - PMin2.Coord(X2, Y2, Z2); - } - } - catch (Standard_Failure) { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode(aFail->GetMessageString()); - return MinDist; - } + //Compute the parameters + Standard_Real U1,U2,V1,V2; + ShapeAnalysis::GetFaceUVBounds(F,U1,U2,V1,V2); + Standard_Real U = U1 + (U2-U1)*theUParam; + Standard_Real V = V1 + (V2-V1)*theVParam; - SetErrorCode(OK); - return MinDist; + return getSurfaceCurvatures(aSurf, U, V, false); } -//======================================================================= -//function : PointCoordinates -//purpose : Get coordinates of point -//======================================================================= -void GEOMImpl_IMeasureOperations::PointCoordinates( Handle(GEOM_Object) theShape, - Standard_Real& theX, Standard_Real& theY, Standard_Real& theZ ) + +//============================================================================= +/*! + * MinSurfaceCurvatureByPoint + */ +//============================================================================= +Standard_Real GEOMImpl_IMeasureOperations::MinSurfaceCurvatureByPoint + (Handle(GEOM_Object) theSurf, Handle(GEOM_Object) thePoint) { - SetErrorCode( KO ); + SetErrorCode(KO); + Standard_Real aRes = -1.0; - if ( theShape.IsNull() ) - return; + if( theSurf.IsNull() || thePoint.IsNull() ) return aRes; - Handle(GEOM_Function) aRefShape = theShape->GetLastFunction(); - if ( aRefShape.IsNull() ) - return; + Handle(GEOM_Function) aRefShape = theSurf->GetLastFunction(); + Handle(GEOM_Function) aRefPoint = thePoint->GetLastFunction(); + if( aRefShape.IsNull() || aRefPoint.IsNull() ) return aRes; - TopoDS_Shape aShape = aRefShape->GetValue(); - if ( aShape.IsNull() || aShape.ShapeType() != TopAbs_VERTEX ) - { - SetErrorCode( "Shape must be a vertex" ); - return; + TopoDS_Face aFace = TopoDS::Face(aRefShape->GetValue()); + TopoDS_Vertex aPnt = TopoDS::Vertex(aRefPoint->GetValue()); + if( aFace.IsNull() || aPnt.IsNull() ) { + SetErrorCode("One of Objects has NULL Shape"); + return 0; } - try - { - gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) ); - theX = aPnt.X(); - theY = aPnt.Y(); - theZ = aPnt.Z(); - SetErrorCode( OK ); - } - catch ( Standard_Failure ) - { - Handle(Standard_Failure) aFail = Standard_Failure::Caught(); - SetErrorCode( aFail->GetMessageString() ); - } + Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace); + if(aSurf.IsNull()) return aRes; + gp_Pnt aPoint = BRep_Tool::Pnt(aPnt); + + //Compute the parameters + ShapeAnalysis_Surface sas(aSurf); + gp_Pnt2d UV = sas.ValueOfUV(aPoint,Precision::Confusion()); + + return getSurfaceCurvatures(aSurf, UV.X(), UV.Y(), false); } + //======================================================================= //function : StructuralDump //purpose : Structural (data exchange) style of output. @@ -809,6 +2701,7 @@ void GEOMImpl_IMeasureOperations::StructuralDump (const BRepCheck_Analyzer& theA } } + //======================================================================= //function : GetProblemShapes // purpose : for StructuralDump @@ -892,14 +2785,14 @@ void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer& const Handle(BRepCheck_Result)& res = theAna.Result(sub); for (res->InitContextIterator(); - res->MoreShapeInContext(); - res->NextShapeInContext()) { + res->MoreShapeInContext(); + res->NextShapeInContext()) { if (res->ContextualShape().IsSame(theShape) && !Contains(theMap(sub), theShape)) { - theMap(sub).Append(theShape); - itl.Initialize(res->StatusOnShape()); + theMap(sub).Append(theShape); + itl.Initialize(res->StatusOnShape()); - if (itl.Value() != BRepCheck_NoError) { - Standard_Integer ii = 0; + if (itl.Value() != BRepCheck_NoError) { + Standard_Integer ii = 0; for (ii = 1; ii <= sl->Length(); ii++) if (sl->Value(ii).IsSame(sub)) break; @@ -918,8 +2811,8 @@ void GEOMImpl_IMeasureOperations::GetProblemSub (const BRepCheck_Analyzer& NbProblems->SetValue((Standard_Integer)stat, NbProblems->Value((Standard_Integer)stat) + 1); } - } - break; + } + break; } } }