+ * 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 {
+ OCC_CATCH_SIGNALS;
+ int iType, nbTypes [TopAbs_SHAPE], nbFlatType [TopAbs_SHAPE];
+ for (iType = 0; iType < TopAbs_SHAPE; ++iType) {
+ nbTypes[iType] = 0;
+ nbFlatType[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_Shape sp = itL.Value();
+ TopoDS_Iterator it (sp);
+ for (; it.More(); it.Next()) {
+ TopoDS_Shape s = it.Value();
+ if (aMapOfShape.Add(s)) {
+ aListOfShape.Append(s);
+ nbTypes[s.ShapeType()]++;
+ if ((sp.ShapeType() == TopAbs_COMPOUND) || (sp.ShapeType() == TopAbs_COMPSOLID)) {
+ nbFlatType[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()) + "\n";
+
+ if ((aShape.ShapeType() == TopAbs_COMPOUND) || (aShape.ShapeType() == TopAbs_COMPSOLID)){
+ Astr = Astr + " --------------------- \n Flat content : \n";
+ if (nbFlatType[TopAbs_VERTEX] > 0)
+ Astr = Astr + " VERTEX : " + TCollection_AsciiString(nbFlatType[TopAbs_VERTEX]) + "\n";
+ if (nbFlatType[TopAbs_EDGE] > 0)
+ Astr = Astr + " EDGE : " + TCollection_AsciiString(nbFlatType[TopAbs_EDGE]) + "\n";
+ if (nbFlatType[TopAbs_WIRE] > 0)
+ Astr = Astr + " WIRE : " + TCollection_AsciiString(nbFlatType[TopAbs_WIRE]) + "\n";
+ if (nbFlatType[TopAbs_FACE] > 0)
+ Astr = Astr + " FACE : " + TCollection_AsciiString(nbFlatType[TopAbs_FACE]) + "\n";
+ if (nbFlatType[TopAbs_SHELL] > 0)
+ Astr = Astr + " SHELL : " + TCollection_AsciiString(nbFlatType[TopAbs_SHELL]) + "\n";
+ if (nbFlatType[TopAbs_SOLID] > 0)
+ Astr = Astr + " SOLID : " + TCollection_AsciiString(nbFlatType[TopAbs_SOLID]) + "\n";
+ }
+ }
+ catch (Standard_Failure& aFail) {
+ SetErrorCode(aFail.GetMessageString());
+ return Astr;
+ }
+
+ SetErrorCode(OK);
+ return Astr;
+}
+
+//=============================================================================
+/*!
+ * AreCoordsInside
+ */
+//=============================================================================
+std::vector<bool>
+GEOMImpl_IMeasureOperations::AreCoordsInside(Handle(GEOM_Object) theShape,
+ const std::vector<double>& coords,
+ double tolerance)
+{
+ std::vector<bool> isInsideRes;
+ if (!theShape.IsNull()) {
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (!aRefShape.IsNull()) {
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if (!aShape.IsNull())
+ {
+ TopTools_IndexedMapOfShape mapShape;
+ {
+ TopExp_Explorer anExp;
+ for ( anExp.Init( aShape, TopAbs_SOLID ); anExp.More(); anExp.Next() )
+ mapShape.Add( anExp.Current() );
+ for ( anExp.Init( aShape, TopAbs_FACE, TopAbs_SOLID ); anExp.More(); anExp.Next() )
+ mapShape.Add( anExp.Current() );
+ for ( anExp.Init( aShape, TopAbs_EDGE, TopAbs_FACE ); anExp.More(); anExp.Next() )
+ mapShape.Add( anExp.Current() );
+ for ( anExp.Init( aShape, TopAbs_VERTEX, TopAbs_EDGE ); anExp.More(); anExp.Next() )
+ mapShape.Add( anExp.Current() ); //// ?????????
+ }
+ size_t nb_points = coords.size()/3, nb_points_inside = 0;
+ isInsideRes.resize( nb_points, false );
+
+ for ( int iS = 1; iS <= mapShape.Extent(); ++iS )
+ {
+ if ( nb_points_inside == nb_points )
+ break;
+ aShape = mapShape( iS );
+ switch ( aShape.ShapeType() ) {
+ case TopAbs_SOLID:
+ {
+ BRepClass3d_SolidClassifier SC( TopoDS::Solid( aShape ));
+ for ( size_t i = 0; i < nb_points; i++)
+ {
+ if ( isInsideRes[ i ]) continue;
+ gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
+ SC.Perform( aPnt, tolerance );
+ isInsideRes[ i ] = (( SC.State() == TopAbs_IN ) || ( SC.State() == TopAbs_ON ));
+ nb_points_inside += isInsideRes[ i ];
+ }
+ break;
+ }
+ case TopAbs_FACE:
+ {
+ Standard_Real u1,u2,v1,v2;
+ const TopoDS_Face& face = TopoDS::Face( aShape );
+ Handle(Geom_Surface) surf = BRep_Tool::Surface( face );
+ surf->Bounds( u1,u2,v1,v2 );
+ GeomAPI_ProjectPointOnSurf project;
+ project.Init(surf, u1,u2, v1,v2, tolerance );
+ for ( size_t i = 0; i < nb_points; i++)
+ {
+ if ( isInsideRes[ i ]) continue;
+ gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
+ project.Perform( aPnt );
+ if ( project.IsDone() &&
+ project.NbPoints() > 0 &&
+ project.LowerDistance() <= tolerance )
+ {
+ Standard_Real u, v;
+ project.LowerDistanceParameters(u, v);
+ gp_Pnt2d uv( u, v );
+ BRepClass_FaceClassifier FC ( face, uv, tolerance );
+ isInsideRes[ i ] = (( FC.State() == TopAbs_IN ) || ( FC.State() == TopAbs_ON ));
+ nb_points_inside += isInsideRes[ i ];
+ }
+ }
+ break;
+ }
+ case TopAbs_EDGE:
+ {
+ Standard_Real f,l;
+ const TopoDS_Edge& edge = TopoDS::Edge( aShape );
+ Handle(Geom_Curve) curve = BRep_Tool::Curve( edge, f, l );
+ GeomAPI_ProjectPointOnCurve project;
+ project.Init( curve, f, l );
+ for ( size_t i = 0; i < nb_points; i++)
+ {
+ if ( isInsideRes[ i ]) continue;
+ gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
+ project.Perform( aPnt );
+ isInsideRes[ i ] = ( project.NbPoints() > 0 &&
+ project.LowerDistance() <= tolerance );
+ nb_points_inside += isInsideRes[ i ];
+ }
+ break;
+ }
+ case TopAbs_VERTEX:
+ {
+ gp_Pnt aVPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ));
+ for ( size_t i = 0; i < nb_points; i++)
+ {
+ if ( isInsideRes[ i ]) continue;
+ gp_Pnt aPnt( coords[3*i], coords[3*i+1], coords[3*i+2] );
+ isInsideRes[ i ] = ( aPnt.SquareDistance( aVPnt ) <= tolerance * tolerance );
+ nb_points_inside += isInsideRes[ i ];
+ }
+ break;
+ }
+ default:;
+ } // switch ( aShape.ShapeType() )
+ }
+ }
+ }
+ }
+ return isInsideRes;
+}
+
+//=============================================================================
+/*!
+ * 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 {
+ OCC_CATCH_SIGNALS;
+
+ gp_Pnt aPnt1, aPnt2;
+
+ MinDist = GEOMUtils::GetMinDistance(aShape1, aShape2, aPnt1, aPnt2);
+
+ if (MinDist >= 0.0) {
+ aPnt1.Coord(X1, Y1, Z1);
+ aPnt2.Coord(X2, Y2, Z2);
+ } else {
+ return MinDist;
+ }
+ }
+ catch (Standard_Failure& aFail) {
+ SetErrorCode(aFail.GetMessageString());
+ return MinDist;
+ }
+
+ SetErrorCode(OK);
+ return MinDist;
+}
+
+//=======================================================================
+/*!
+ * Get coordinates of closest points of two shapes
+ */
+//=======================================================================
+Standard_Integer GEOMImpl_IMeasureOperations::ClosestPoints (Handle(GEOM_Object) theShape1,
+ Handle(GEOM_Object) theShape2,
+ Handle(TColStd_HSequenceOfReal)& theDoubles)
+{
+ SetErrorCode(KO);
+ Standard_Integer nbSolutions = 0;
+
+ if (theShape1.IsNull() || theShape2.IsNull()) return nbSolutions;
+
+ Handle(GEOM_Function) aRefShape1 = theShape1->GetLastFunction();
+ Handle(GEOM_Function) aRefShape2 = theShape2->GetLastFunction();
+ if (aRefShape1.IsNull() || aRefShape2.IsNull()) return nbSolutions;
+
+ TopoDS_Shape aShape1 = aRefShape1->GetValue();
+ TopoDS_Shape aShape2 = aRefShape2->GetValue();
+ if (aShape1.IsNull() || aShape2.IsNull()) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return nbSolutions;
+ }
+
+ // Compute the extremities
+ try {
+ OCC_CATCH_SIGNALS;
+
+ // skl 30.06.2008
+ // additional workaround for bugs 19899, 19908 and 19910 from Mantis
+ gp_Pnt P1s, P2s;
+ double dist = GEOMUtils::GetMinDistanceSingular(aShape1, aShape2, P1s, P2s);
+ bool singularBetter = dist >= 0;
+
+ BRepExtrema_DistShapeShape dst (aShape1, aShape2);
+ if (dst.IsDone()) {
+ nbSolutions = dst.NbSolution();
+ if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
+
+ gp_Pnt P1, P2;
+ for (int i = 1; i <= nbSolutions; i++) {
+ P1 = dst.PointOnShape1(i);
+ P2 = dst.PointOnShape2(i);
+
+ theDoubles->Append(P1.X());
+ theDoubles->Append(P1.Y());
+ theDoubles->Append(P1.Z());
+ theDoubles->Append(P2.X());
+ theDoubles->Append(P2.Y());
+ theDoubles->Append(P2.Z());
+
+ Standard_Real Dist = P1.Distance(P2);
+ singularBetter = singularBetter && dist < Dist;
+ }
+ }
+
+ if (singularBetter) {
+ if (theDoubles.IsNull()) theDoubles = new TColStd_HSequenceOfReal;
+ else theDoubles->Clear();
+
+ nbSolutions = 1;
+
+ theDoubles->Append(P1s.X());
+ theDoubles->Append(P1s.Y());
+ theDoubles->Append(P1s.Z());
+ theDoubles->Append(P2s.X());
+ theDoubles->Append(P2s.Y());
+ theDoubles->Append(P2s.Z());
+ }
+ }
+ catch (Standard_Failure& aFail) {
+ SetErrorCode(aFail.GetMessageString());
+ return nbSolutions;
+ }
+
+ SetErrorCode(OK);
+ return nbSolutions;
+}
+
+//=======================================================================
+/*!
+ * 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 {
+ OCC_CATCH_SIGNALS;
+ gp_Pnt aPnt = BRep_Tool::Pnt( TopoDS::Vertex( aShape ) );
+ theX = aPnt.X();
+ theY = aPnt.Y();
+ theZ = aPnt.Z();
+
+ SetErrorCode(OK);
+ }
+ catch (Standard_Failure& aFail)
+ {
+ 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 {
+ OCC_CATCH_SIGNALS;
+ 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 *= 180. / M_PI; // convert radians into degrees
+
+ if (anAngle > 90.0) {
+ anAngle = 180.0 - anAngle;
+ }
+
+ SetErrorCode(OK);
+ }
+ catch (Standard_Failure& aFail)
+ {
+ 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;
+
+ if (theVec1->GetType() != GEOM_VECTOR || theVec2->GetType() != GEOM_VECTOR) {
+ SetErrorCode("Two vectors must be given");
+ 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 {
+ OCC_CATCH_SIGNALS;
+ 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_Vec aV1 (BRep_Tool::Pnt(aP11), BRep_Tool::Pnt(aP12));
+ gp_Vec aV2 (BRep_Tool::Pnt(aP21), BRep_Tool::Pnt(aP22)) ;
+
+ anAngle = aV1.Angle(aV2);
+ anAngle *= 180. / M_PI; // convert radians into degrees
+
+ SetErrorCode(OK);
+ }
+ catch (Standard_Failure& aFail)
+ {
+ SetErrorCode(aFail.GetMessageString());
+ }
+
+ return anAngle;
+}
+
+
+//=============================================================================
+/*!
+ * PatchFace
+ */
+ //=============================================================================
+Handle(TColStd_HSequenceOfTransient) GEOMImpl_IMeasureOperations::PatchFace(Handle(GEOM_Object) theShape)
+{
+ SetErrorCode(KO);
+
+ if (theShape.IsNull()) return NULL;
+
+ Handle(GEOM_Object) aPatchFace = GetEngine()->AddObject(GEOM_PATCH_FACE);
+ Handle(GEOM_Function) aFunction = aPatchFace->AddFunction(GEOMImpl_PatchFaceDriver::GetID(), 1);
+ if (aFunction.IsNull()) return NULL;
+
+ //Check if the function is set correctly
+ if (aFunction->GetDriverGUID() != GEOMImpl_PatchFaceDriver::GetID()) return NULL;
+
+ GEOMImpl_IPatchFace aPI(aFunction);
+ Handle(GEOM_Function) aRefShape = theShape->GetLastFunction();
+ if (aRefShape.IsNull()) return NULL;
+
+ aPI.SetShape(aRefShape);
+ Handle(TColStd_HSequenceOfTransient) aSeq = new TColStd_HSequenceOfTransient;
+
+ // Perform
+ try
+ {
+ OCC_CATCH_SIGNALS;
+ if (!GetSolver()->ComputeFunction(aFunction))
+ {
+ SetErrorCode("patch face driver failed");
+ return NULL;
+ }
+
+ // Get result compound and collect all faces into result sequence
+ TopoDS_Shape aResCompound = aFunction->GetValue();
+ TopTools_IndexedMapOfShape anIndices;
+ TopExp::MapShapes(aResCompound, anIndices);
+
+ Handle(TColStd_HArray1OfInteger) anArray;
+ for (TopExp_Explorer anExpW(aResCompound, TopAbs_FACE); anExpW.More(); anExpW.Next())
+ {
+ TopoDS_Shape aValue = anExpW.Value();
+ anArray = new TColStd_HArray1OfInteger(1, 1);
+ anArray->SetValue(1, anIndices.FindIndex(aValue));
+
+ Handle(GEOM_Object) anObj = GetEngine()->AddSubShape(aPatchFace, anArray);
+ if (!anObj.IsNull())
+ {
+ aSeq->Append(anObj);
+ }
+ }
+ }
+ catch (Standard_Failure& aFail)
+ {
+ SetErrorCode(aFail.GetMessageString());
+ return aSeq;
+ }
+
+ //Make a Python command
+ GEOM::TPythonDump(aFunction, true)
+ << "[" << aSeq << "] = geompy.PatchFace(" << theShape << ")";
+
+ SetErrorCode(OK);
+ return aSeq;
+}
+
+//=============================================================================
+/*!
+ * CurveCurvatureByParam
+ */
+//=============================================================================
+Standard_Real GEOMImpl_IMeasureOperations::CurveCurvatureByParam
+ (Handle(GEOM_Object) theCurve, Standard_Real& theParam)
+{
+ SetErrorCode(KO);
+ Standard_Real aRes = -1.0;
+
+ if(theCurve.IsNull()) return aRes;
+
+ Handle(GEOM_Function) aRefShape = theCurve->GetLastFunction();
+ if(aRefShape.IsNull()) return aRes;
+
+ TopoDS_Shape aShape = aRefShape->GetValue();
+ if(aShape.IsNull()) {
+ SetErrorCode("One of Objects has NULL Shape");
+ return aRes;
+ }
+
+ 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 {
+ OCC_CATCH_SIGNALS;
+ GeomLProp_CLProps Prop = GeomLProp_CLProps
+ (aCurve, aP, 2, Precision::Confusion());
+ aRes = fabs(Prop.Curvature());
+ SetErrorCode(OK);
+ }
+ catch (Standard_Failure& aFail) {
+ SetErrorCode(aFail.GetMessageString());
+ return aRes;
+ }
+
+ if( aRes > Precision::Confusion() )
+ aRes = 1/aRes;
+ else
+ aRes = RealLast();
+
+ return aRes;
+}
+
+
+//=============================================================================
+/*!
+ * CurveCurvatureByPoint