OpenCASCADE 参数曲线曲面面积 (3)

通过theLower和theUpper指定定义域,由于采用了Gauss-Legendre算法计算二重积分,所以需要指定阶数,且阶数越高积分结果精度越高,这里使用了OpenCASCADE中最高的阶数。

下面通过对基本曲面的面积计算来验证结果的正确性,并将计算结果和OpenCASCADE中计算面积的类BRepGProp::SurfaceProperties()结果进行对比。

6.Elementary Surface Area Test

下面通过对OpenCASCADE中几个初等曲面的面积进行计算,代码如下所示:

/*

Copyright(C) 2017 Shing Liu(eryar@163.com)

Permission is hereby granted, free of charge, to any person obtaining a copy

of this software and associated documentation files(the "Software"), to deal

in the Software without restriction, including without limitation the rights

to use, copy, modify, merge, publish, distribute, sublicense, and / or sell

copies of the Software, and to permit persons to whom the Software is

furnished to do so, subject to the following conditions :

The above copyright notice and this permission notice shall be included in all

copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR

IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,

FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE

AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER

LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,

OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE

SOFTWARE.

*/

#include <gp_Pnt.hxx>

#include <gp_Vec.hxx>

#include <math.hxx>

#include <math_Function.hxx>

#include <math_MultipleVarFunction.hxx>

#include <math_GaussMultipleIntegration.hxx>

#include <Geom_Plane.hxx>

#include <Geom_ConicalSurface.hxx>

#include <Geom_CylindricalSurface.hxx>

#include <Geom_SphericalSurface.hxx>

#include <Geom_ToroidalSurface.hxx>

#include <Geom_BSplineSurface.hxx>

#include <Geom_RectangularTrimmedSurface.hxx>

#include <GeomConvert.hxx>

#include <GProp_GProps.hxx>

#include <TopoDS_Face.hxx>

#include <BRepGProp.hxx>

#include <BRepBuilderAPI_MakeFace.hxx>

#pragma comment(lib, "TKernel.lib")

#pragma comment(lib, "TKMath.lib")

#pragma comment(lib, "TKG2d.lib")

#pragma comment(lib, "TKG3d.lib")

#pragma comment(lib, "TKGeomBase.lib")

#pragma comment(lib, "TKGeomAlgo.lib")

#pragma comment(lib, "TKBRep.lib")

#pragma comment(lib, "TKTopAlgo.lib")

//! 2D variable function for surface area evaluation.

class math_AreaFunction : public math_MultipleVarFunction

{

public:

    math_AreaFunction(const Handle(Geom_Surface)& theSurface)

: mySurface(theSurface)

{

}

virtual Standard_Integer NbVariables() const

{

return 2;

}

virtual Standard_Boolean Value(const math_Vector& X, Standard_Real& Y)

{

        gp_Pnt aP;

        gp_Vec aDu;

        gp_Vec aDv;

        Standard_Real E = 0.0;

        Standard_Real F = 0.0;

        Standard_Real G = 0.0;

        mySurface->D1(X(1), X(2), aP, aDu, aDv);

        E = aDu.Dot(aDu);

        F = aDu.Dot(aDv);

        G = aDv.Dot(aDv);

        Y = Sqrt(E * G - F * F);

//Y = aDu.Crossed(aDv).Magnitude();

return Standard_True;

}

private:

    Handle(Geom_Surface) mySurface;

};

void evalArea(const Handle(Geom_Surface)& theSurface, const math_Vector& theLower, const math_Vector& theUpper)

{

    math_IntegerVector aOrder(1, 2, math::GaussPointsMax());

    math_AreaFunction aFunction(theSurface);

    math_GaussMultipleIntegration anIntegral(aFunction, theLower, theUpper, aOrder);

if (anIntegral.IsDone())

{

        anIntegral.Dump(std::cout);

}

}

void evalArea(const Handle(Geom_BoundedSurface)& theSurface)

{

    math_IntegerVector aOrder(1, 2, math::GaussPointsMax());

    math_Vector aLower(1, 2, 0.0);

    math_Vector aUpper(1, 2, 0.0);

    theSurface->Bounds(aLower(1), aUpper(1), aLower(2), aUpper(2));

    math_AreaFunction aFunction(theSurface);

    math_GaussMultipleIntegration anIntegral(aFunction, aLower, aUpper, aOrder);

if (anIntegral.IsDone())

{

        anIntegral.Dump(std::cout);

}

}

void testFace(const TopoDS_Shape& theFace)

{

    GProp_GProps aSurfaceProps;

    BRepGProp::SurfaceProperties(theFace, aSurfaceProps);

    std::cout << "Face area: " << aSurfaceProps.Mass() << std::endl;

}

void testPlane()

{

    std::cout << "====== Test Plane Area =====" << std::endl;

    Handle(Geom_Plane) aPlaneSurface = new Geom_Plane(gp::XOY());

    math_Vector aLower(1, 2);

    math_Vector aUpper(1, 2);

// Parameter U range.

    aLower(1) = 0.0;

    aUpper(1) = 2.0;

// Parameter V range.

    aLower(2) = 0.0;

    aUpper(2) = 3.0;

    evalArea(aPlaneSurface, aLower, aUpper);

// Convert to BSpline Surface.

    Handle(Geom_RectangularTrimmedSurface) aTrimmedSurface =

new Geom_RectangularTrimmedSurface(aPlaneSurface, aLower(1), aUpper(1), aLower(2), aUpper(2));

    Handle(Geom_BSplineSurface) aBSplineSurface = GeomConvert::SurfaceToBSplineSurface(aTrimmedSurface);

    evalArea(aBSplineSurface);

// Test Face.

    TopoDS_Face aFace = BRepBuilderAPI_MakeFace(aTrimmedSurface, Precision::Confusion()).Face();

    testFace(aFace);

    aFace = BRepBuilderAPI_MakeFace(aBSplineSurface, Precision::Confusion()).Face();

    testFace(aFace);

}

void testCylinder()

{

    std::cout << "====== Test Cylinder Area =====" << std::endl;

    Handle(Geom_CylindricalSurface) aCylindrialSurface = new Geom_CylindricalSurface(gp::XOY(), 1.0);

    math_Vector aLower(1, 2);

    math_Vector aUpper(1, 2);

    aLower(1) = 0.0;

    aUpper(1) = M_PI * 2.0;

    aLower(2) = 0.0;

    aUpper(2) = 3.0;

    evalArea(aCylindrialSurface, aLower, aUpper);

// Convert to BSpline Surface.

    Handle(Geom_RectangularTrimmedSurface) aTrimmedSurface =

new Geom_RectangularTrimmedSurface(aCylindrialSurface, aLower(1), aUpper(1), aLower(2), aUpper(2));

    Handle(Geom_BSplineSurface) aBSplineSurface = GeomConvert::SurfaceToBSplineSurface(aTrimmedSurface);

    evalArea(aBSplineSurface);

// Test Face.

    TopoDS_Face aFace = BRepBuilderAPI_MakeFace(aTrimmedSurface, Precision::Confusion()).Face();

    testFace(aFace);

    aFace = BRepBuilderAPI_MakeFace(aBSplineSurface, Precision::Confusion()).Face();

    testFace(aFace);

}

void testSphere()

{

    std::cout << "====== Test Sphere Area =====" << std::endl;

    Handle(Geom_SphericalSurface) aSphericalSurface = new Geom_SphericalSurface(gp::XOY(), 1.0);

    math_Vector aLower(1, 2);

    math_Vector aUpper(1, 2);

    aSphericalSurface->Bounds(aLower(1), aUpper(1), aLower(2), aUpper(2));

    evalArea(aSphericalSurface, aLower, aUpper);

// Convert to BSpline Surface.

    Handle(Geom_BSplineSurface) aBSplineSurface = GeomConvert::SurfaceToBSplineSurface(aSphericalSurface);

    evalArea(aBSplineSurface);

// Test Face.

    TopoDS_Face aFace = BRepBuilderAPI_MakeFace(aSphericalSurface, Precision::Confusion()).Face();

    testFace(aFace);

    aFace = BRepBuilderAPI_MakeFace(aBSplineSurface, Precision::Confusion()).Face();

    testFace(aFace);

}

void test()

{

    testPlane();

    testSphere();

    testCylinder();

}

int main(int argc, char* argv[])

{

    test();

return 0;

}

计算结果如下图所示:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwsffj.html