# eryar

PipeCAD - Plant Piping Design Software.
RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
posts - 595, comments - 590, trackbacks - 0, articles - 0

Abstract. OpenCASCADE linear extrusion surface is a generalized cylinder. Such a surface is obtained by sweeping a curve (called the “extruded curve” or “basis”) in a given direction (referred to as the direction of extrusion and defined by a unit vector). The u parameter is along the extruded curve. The v parameter is along the direction of extrusion. The form of a surface of linear extrusion is generally a ruled surface. It can be a cylindrical surface, or a planar surface.

Key Words. OpenCASCADE, Extrusion Surface, Sweeping

1. Introduction

Figure 1.1 Extrusion Shapes

Figure 1.2 Swept surface/ loft surface

2.Cylinder Surface Definition

v 对于固定的u0, S(u0, v)为由C(u0)到C(u0)+dW的直线段；

v 对于固定的v0：

S(u,v)定义在节点矢量U和V上，这里V＝{0，0，1，1}，U为C(u)的节点矢量。控制顶点由Pi,0=Pi和Pi,1=Pi+dW给出，权值wi,0=wi,1=wi。如下图所示为一般柱面：

Figure 2.1 A general cylinder obtained by translating C(u) a distance d along W.

//=======================================================================
//function : Bounds
//purpose  :
//=======================================================================
void Geom_SurfaceOfLinearExtrusion::Bounds ( Standard_Real& U1,
Standard_Real
& U2,
Standard_Real
& V1,
Standard_Real
& V2 ) const {

V1
= -Precision::Infinite();  V2 = Precision::Infinite();
U1
= basisCurve->FirstParameter();  U2 = basisCurve->LastParameter();
}

//=======================================================================
//function : D0
//purpose  :
//=======================================================================
void Geom_SurfaceOfLinearExtrusion::D0 (const Standard_Real U,

const Standard_Real V,
Pnt
& P)  const {

XYZ Pxyz
= direction.XYZ();
Pxyz.Multiply (V);
->Value (U).XYZ());
P.SetXYZ(Pxyz);
}

3.Display the Surface

/*
*    Copyright (c) 2013 to current year. All Rights Reserved.
*
*           File : Main.cpp
*         Author : eryar@163.com
*           Date : 2014-11-23 10:18
*
*    Description : Test the Linear Extrusion Surface of OpenCASCADE.
*
*      Key Words : OpenCascade, Linear Extrusion Surface, General Cylinder
*
*/

#define WNT
#include
<Precision.hxx>

#include
<gp_Circ.hxx>

#include
<Geom_SurfaceOfLinearExtrusion.hxx>

#include
<GC_MakeCircle.hxx>
#include
<GC_MakeSegment.hxx>
#include
<GC_MakeArcOfCircle.hxx>

#pragma comment(lib,
"TKernel.lib")
#pragma comment(lib,
"TKMath.lib")
#pragma comment(lib,
"TKG3d.lib")
#pragma comment(lib,
"TKGeomBase.lib")

// OpenSceneGraph.
#include <osgViewer/Viewer>
#include
<osgViewer/ViewerEventHandlers>

#include
<osgGA/StateSetManipulator>

#pragma comment(lib,
"osgd.lib")
#pragma comment(lib,
#pragma comment(lib,
"osgViewerd.lib")

const double TOLERANCE_EDGE = 1e-6;
const double APPROXIMATION_DELTA = 0.05;

/**
* @brief Render 3D geometry surface.
*/
osg::Node
* BuildSurface(const Handle_Geom_Surface& theSurface)
{
osg::ref_ptr
<osg::Geode> aGeode = new osg::Geode();

Standard_Real aU1
= 0.0;
Standard_Real aV1
= 0.0;
Standard_Real aU2
= 0.0;
Standard_Real aV2
= 0.0;
= 0.0;
= 0.0;

theSurface
->Bounds(aU1, aU2, aV1, aV2);

// trim the parametrical space to avoid infinite space.
Precision::IsNegativeInfinite(aU1) ? aU1 = -1.0 : aU1;
Precision::IsInfinite(aU2)
? aU2 = 1.0 : aU2;

Precision::IsNegativeInfinite(aV1)
? aV1 = -1.0 : aV1;
Precision::IsInfinite(aV2)
? aV2 = 1.0 : aV2;

// Approximation in v direction.
aDeltaU = (aU2 - aU1) * APPROXIMATION_DELTA;
= (aV2 - aV1) * APPROXIMATION_DELTA;

for (Standard_Real u = aU1; (u - aU2) <= TOLERANCE_EDGE; u += aDeltaU)
{
osg::ref_ptr
<osg::Geometry> aLine = new osg::Geometry();
osg::ref_ptr
<osg::Vec3Array> aPoints = new osg::Vec3Array();

for (Standard_Real v = aV1; (v - aV2) <= TOLERANCE_EDGE; v += aDeltaV)
{
gp_Pnt aPoint
= theSurface->Value(u, v);

aPoints
->push_back(osg::Vec3(aPoint.X(), aPoint.Y(), aPoint.Z()));
}

// Set vertex array.
aLine->setVertexArray(aPoints);
aLine

aGeode
}

// Approximation in u direction.
for (Standard_Real v = aV1; (v - aV2) <= TOLERANCE_EDGE; v += aDeltaV)
{
osg::ref_ptr
<osg::Geometry> aLine = new osg::Geometry();
osg::ref_ptr
<osg::Vec3Array> aPoints = new osg::Vec3Array();

for (Standard_Real u = aU1; (u - aU2) <= TOLERANCE_EDGE; u += aDeltaU)
{
gp_Pnt aPoint
= theSurface->Value(u, v);

aPoints
->push_back(osg::Vec3(aPoint.X(), aPoint.Y(), aPoint.Z()));
}

// Set vertex array.
aLine->setVertexArray(aPoints);
aLine

aGeode
}

return aGeode.release();
}

/**
* @brief Build the test scene.
*/
osg::Node
* BuildScene(void)
{
osg::ref_ptr
<osg::Group> aRoot = new osg::Group();

// test the linear extrusion surface.

// test linear extrusion surface of a line.
Handle_Geom_Curve aSegment = GC_MakeSegment(gp_Pnt(3.00.00.0), gp_Pnt(6.00.00.0));
Handle_Geom_Surface aPlane
= new Geom_SurfaceOfLinearExtrusion(aSegment, gp::DZ());

aRoot

// test linear extrusion surface of a arc.
Handle_Geom_Curve aArc = GC_MakeArcOfCircle(gp_Circ(gp::ZOX(), 2.0), 0.0, M_PI, true);
Handle_Geom_Surface aSurface
= new Geom_SurfaceOfLinearExtrusion(aArc, gp::DY());

aRoot

// test linear extrusion surface of a circle.
Handle_Geom_Curve aCircle = GC_MakeCircle(gp::XOY(), 1.0);
Handle_Geom_Surface aCylinder
= new Geom_SurfaceOfLinearExtrusion(aCircle, gp::DZ());

aRoot

return aRoot.release();
}

int main(int argc, char* argv[])
{
osgViewer::Viewer aViewer;

aViewer.setSceneData(BuildScene());

new osgGA::StateSetManipulator(
aViewer.getCamera()
->getOrCreateStateSet()));
new osgViewer::StatsHandler);
new osgViewer::WindowSizeHandler);

return aViewer.run();

return 0;
}

Figure 3.1 General Cylinder for: Circle, Arc, Line

4.Conclusion

5. References

1. 赵罡，穆国旺，王拉柱译. 非均匀有理B样条. 清华大学出版社. 2010

2. Les Piegl, Wayne Tiller. The NURBS Book. Springer-Verlag. 1997