您的位置:首页 > 运维架构

Open CASCADE基础介绍(1)

2008-10-24 17:27 393 查看

Open CASCADE基础介绍(1)

一直在用OCC作项目,但这方面的中文资料很少,看来OCC在中国还不是十分普及;
后来,项目中使用OCC和DirectX结合使用,取得了很好的效果;
 随着OCC6.3版本的推出,Open CASCADE在速度方面已有了很大的改变。以下为一些OCC的基础知识,愿与各位OCC爱好者共同学习;

一:OCC中的基础类:

gp_Pnt

在OCC中,gp_Pnt表示一个顶点,gp_Vec表示一个向量,可以用两个顶点来生成一个向量。<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

比如:
gp_Pnt P1(0,0,0);                       
gp_Pnt P2(5,0,0);                       
gp_Vec V1 (P1,P2);

向量有一个方法.IsOpposite(),可以用来测试两个向量的方向是相对还是平行;
比如:                                        

gp_Pnt P3(-5,0,2);

gp_Vec V2 (P1,P3);                                          
Standard_Boolean result =V1.IsOpposite(V2,Precision::Angular());
 

另外向量还有一些重要方法:
--Standard_Real Magnitude() const;计算向量的大小;
--Standard_Real SquareMagnitude() const;计算向量的平方;
--向量的加减乘除操作;
--向量的单位化;
--通过一个点,线,面得出其镜像的向量;
--向量的旋转,平移,缩放;
具体的函数名称可以看OCC的头文件说明;
 

有时需要决定一组空间点是位于一个点;一条直线,或一个平面,或一个空间:
OCC中提供了相应的算法;
比如:
TColgp_Array1OfPnt array (1,5); // sizing array                 
array.SetValue(1,gp_Pnt(0,0,1));                                
array.SetValue(2,gp_Pnt(1,2,2));                                
array.SetValue(3,gp_Pnt(2,3,3));                                
array.SetValue(4,gp_Pnt(4,4,4));                                
array.SetValue(5,gp_Pnt(5,5,5));                                
                                                                 
GProp_PEquation PE (array,1.5 );                                
                                                                
if (PE.IsPoint()){ /* ... */  } //是否是同一个点   
gp_Lin L;                                                       
if (PE.IsLinear()) {  L = PE.Line();    } //是否位于一条直线上;                    
if (PE.IsPlanar()){ /* ... */  }   //是否在一个平面内; 
if (PE.IsSpace()) { /* ... */  } 
 

gp_Dir类:

此类用来描述3D空间中的一个单位向量;
常用方法:
(1):IsEqual(const gp_Dir& Other,const Standard_Real AngularTolerance) const;两个单位向量是否相等;
(2):IsNormal(const gp_Dir& Other,const Standard_Real AngularTolerance) const;两个单位向量的夹角是否是PI/2;
(3):IsOpposite(const gp_Dir& Other,const Standard_Real AngularTolerance) const;两个单位向量是否方向相反;
(4):IsParallel(const gp_Dir& Other,const Standard_Real AngularTolerance) const;两个单位向量夹角O或PI;
(5):Angle(const gp_Dir& Other) const;求两个向量之间的夹角;
(6):void CrossCross(const gp_Dir& V1,const gp_Dir& V2) ;计算三个向量之间的叉积;
(7):Standard_Real Dot(const gp_Dir& Other) const;计算点积;
(8):Standard_Real DotCross(const gp_Dir& V1,const gp_Dir& V2) const;计算叉积再点积;
(9):gp_Dir Reversed() const;得到反方向,
 

在OCC中用 gp_Lin2d 类,来生成一个二维空间的直线,有它的原点和单位向量;
 

gp_Ax2d 类:

通过原点和X方向单位和Y方向单位建立一个二维坐标系;利用sense参数可以决定是右手系还是左手系;
可以利用平移、旋转、缩放、镜像来更改坐标系;
类似地,gp_Ax3类:
用来描述一个3D空间的坐标系。而gp_Ax2类用来表示一个二维空间坐标系;可以为右手系,也可以是左手系;
 

二、曲线类

GeomAPI和GeomConvert包:

GeomAPI开发包提供了一个几何体的可编程应用程序接口;
比如:
求点P和曲线C的距离D:
 D = GeomAPI_ProjectPointOnCurve(P,C);
或者
GeomAPI_ProjectPointOnCurve PonC(P,C); <br>
  D = PonC.LowerDistance();
 

GeomConvert包提供了一些全局函数,可以用来实现转化一个Geom曲线为BSpline曲线等;
比如:
Handle(Geom_BSplineSurface) aPipeSurface =                        
    Handle(Geom_BSplineSurface)::DownCast(aPipe.Surface());       
Handle(Geom_BSplineSurface) anotherBSplineSurface =               
    GeomConvert::SplitBSplineSurface(aPipeSurface,1,2,3,6);
 

OCC中三维几何曲线的类型有:
--线
--园
--椭圆
--二次曲线
--抛物线
--Bezier曲线
--BSpline曲线
可以将一个二维的几何曲线转化为某个平面内的一个三维曲线:
比如:
Standard_Real radius = 5;                               
gp_Ax2d ax2d(gp_Pnt2d(2,3),gp_Dir2d(1,0));             
//生成一个二维园                                                      
Handle(Geom2d_Circle) circ2d = new Geom2d_Circle(ax2d,radius);                    
                                                        
gp_Ax2d circ2dXAxis = circ2d->XAxis();                 

                                                       

// 然后,在这个平面里转化为三维曲线;                 
Handle(Geom_Curve) C3D = GeomAPI::To3d(circ2d,gp_Pln(gp_Ax3(gp::XOY())));   
Handle(Geom_Circle) C3DCircle = Handle(Geom_Circle)::DownCast(C3D);                 
                                                       
gp_Ax<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" />1 C3DCircleXAxis = C3DCircle->XAxis();            

                                                       

另外,可以以将一个三维曲线,投影到一个平面内,从而生成一个二维曲线
gp_Pln ProjectionPlane(gp_Pnt(1,1,0),gp_Dir( 1,1,1 ));                                                         
Handle(Geom2d_Curve) C2D = GeomAPI::To2d(C3D,ProjectionPlane);                                                       
Handle(Geom2d_Circle) C2DCircle =Handle(Geom2d_Circle)::DownCast(C2D);                
gp_Ax2d C2DCircleXAxis = C2DCircle->XAxis();

 

将一个基本几何图形进行空间变换可以使用它自带的函数:
比如:
Handle(Geom_Geometry) aRotatedEntity  = circle->Rotated(gp::OZ(),PI/4);
如果想获取图形的类型名称:            
Standard_CString aRotatedEntityTypeName = aRotatedEntity->DynamicType()->Name();
 

gp_Parab2d类:

描述一个平面内的抛物线;
示例:
gp_Pnt2d P(2,3);                         
gp_Dir2d D(4,5);                         
gp_Ax22d A(P,D);                         
gp_Parab2d Para(A,6);
 

GCE2d_MakeParabola类:

生成一个抛物线图形;
 

Geom2d_BSplineCurve类:

描述样条曲线;
 

Geom2dAPI_Interpolate类:

通过一组点来修改一个样条曲线;
 

FairCurve_Batten类:

用一个常量或线性增加的值来构造曲线;可以用来设计木纹或塑料板条;图形为二维的,可以模拟物理样条或板条.

Geom2d_TrimmedCurve类:

此类通过两个值,定义曲线的一部分,
--可以用来计算曲线的参数值和点坐标;
--可以得到曲线的一般特征,比如连续的等级,封闭特点,周期性,边界参数;
--当用一个矩阵应用于曲线或原始曲线转化后进行相应参数的改变;
所有的曲线必须几何连续,曲线至少一阶可导。一般来说,在生成一个曲线时,要先检查一下所应用的参数是否可以生成一个光滑曲线;否则会出现错误;
另外注意一点:不可以构造空长度的曲线或自相交的曲线;
此类的基类是Geom2d_BoundedCurve类:
它是一个抽象类;描述二维空间中的边界曲线的一般行为;除了Geom2d_TrimmedCurve是它的一个派生类外,它还有二个派生类:
- Geom2d_BezierCurve
- Geom2d_BSplineCurve
Geom2d_BoundedCurve类的基类是Geom2d_Curve类:
Geom2d_Curve:抽象类;此抽象类描述了2D空间的曲线的一般特征;派生出的类有多个:包括直线,园,二次曲线,Bizier,BSpline曲线等;这些曲线的特点是可以参数化;
 

Geom2d_Curve类的基类是Geom2d_Geometry类;
此抽象类主要定义了曲线的变换,平移,旋转,缩放及拷贝等方法;
 

Geom2d_Geometry类的基类是MMgt_TShared类;
此抽象类为管理对象的基类,可以引用计数,及删除方法;
 

Standard_Transient:此抽象类为所有类共同的基类;
Geom2dAPI_InterCurveCurve类:
此类用来实现二维曲线的相交;
一种情况是曲线与曲线的相交,另外一种情况是曲线自身的相交;
主要方法有:
--Standard_Integer NbPoints() const;相交点数;
--Standard_Integer NbSegments() const;切线相交数;
--void Segment(const Standard_Integer Index,Handle(Geom2d_Curve)& Curve1,Handle(Geom2d_Curve)& Curve2)
const;返回其中一个线段;
 

下面的示例是两个曲线相交的例子:
首先,生成第一个曲线,在这里,应用点数组来生成一个曲线;
--定义数组
Handle(TColgp_HArray1OfPnt2d) harray =  new TColgp_HArray1OfPnt2d (1,5); // sizing harray              
--输入点数组的值
harray->SetValue(1,gp_Pnt2d (0,0));                                
harray->SetValue(2,gp_Pnt2d (-3,1));                               
harray->SetValue(3,gp_Pnt2d (-2,5));                                
harray->SetValue(4,gp_Pnt2d (2,9));                                
harray->SetValue(5,gp_Pnt2d (-4,14));                              
 
--检测一下点与点之间是否为同一点;0.01为公差值,依实际需要可以更改此参数;                                                                 
Geom2dAPI_Interpolate anInterpolation(harray,Standard_False,0.01); 
--生成曲线
anInterpolation.Perform();                                        
Handle(Geom2d_BSplineCurve) SPL = anInterpolation.Curve();         
 

--第二个曲线用两点来生成                                                                    
gp_Pnt2d P1(-1,-2);gp_Pnt2d P2(0,15);gp_Dir2d V1 = gp::DY2d();                                          
Handle(Geom2d_TrimmedCurve) TC1=  GCE2d_MakeSegment(P1,V1,P2);                                   
  
--下面进行曲线的求交                                                                 
Standard_Real tolerance = Precision::Confusion();                  
Geom2dAPI_InterCurveCurve ICC (SPL,TC1,tolerance); 
 

--得到交点               
Standard_Integer NbPoints =ICC.NbPoints();                          
gp_Pnt2d PK;                                                       
for (Standard_Integer k = 1;k<=NbPoints;k++)                       
  {
                                                              
    PK = ICC.Point(k);                                              
    // 针对每个交点,进行相应处理;                  
  }                                                                
 
Geom2d_OffsetCurve类:
此类用来实现偏移曲线;
比如:
--生成一个曲线
TColgp_Array1OfPnt2d array (1,5); // sizing array                     
array.SetValue(1,gp_Pnt2d (-4,0)); array.SetValue(2,gp_Pnt2d (-7,2)); 
array.SetValue(3,gp_Pnt2d (-6,3)); array.SetValue(4,gp_Pnt2d (-4,3)); 
array.SetValue(5,gp_Pnt2d (-3,5));                                    
Handle(Geom2d_BSplineCurve) SPL1 = Geom2dAPI_PointsToBSpline(array);   
 
--生成一个偏移曲线                                                                     
Standard_Real dist = 1;                                               
Handle(Geom2d_OffsetCurve) OC =                                       
       new Geom2d_OffsetCurve(SPL1,dist);                             
Standard_Boolean result = OC->IsCN(2); 
 
GccAna_Pnt2dBisec类
此类实现两点之间的等分线.
示例:
gp_Pnt2d P1(1,2);           
gp_Pnt2d P2(4,5);           
gp_Lin2d L;                 
GccAna_Pnt2dBisec B(P1,P2); 
if (B.IsDone())             
{ L = B.ThisSolution(); }
因为所生成的为直线,所以显示时要转化为线段:
if (B.IsDone())
         {
        Handle(Geom2d_TrimmedCurve) aLine = GCE2d_MakeSegment(L,-8,8);
        Handle(ISession2D_Curve) aCurve = new ISession2D_Curve(aLine);
        aDoc->GetISessionContext()->Display(aCurve, Standard_False);
      }
gce_MakeCirc2d类
用来创建园:创建园的方法很多,主要构造方法有:
--园心和通过的一点;
--通过一个园和一个距离值,创建一个同心园;
--三点决定一个园;
--园心和半径;
gp_Elips2d类:
可以生成一个椭园,也可以生成椭园上的一段园弧;
比如:
Standard_Real major = 12;                                               
Standard_Real minor = 4;                                               
gp_Ax2d axis = gp::OX2d();                                             
gp_Elips2d EE(axis,major,minor);;                                          
Handle(Geom2d_TrimmedCurve) arc = GCE2d_MakeArcOfEllipse(EE,0.0,PI/4);
上面是利用长短轴的方法构造椭圆,也可以用二次方程的方式来构造椭园;
其中椭园类中方法可以求出焦点1和焦点2的位置,两焦点之间的位置,离心率;旋转,平移,缩放等操作.
 

三、关于面的类

gp_Pln类:

定义一个平面,构造的方法可以是点法式,或通过ABCD系数;
另外,还提供了一些常用的方法,比如:
--求点到平面,线到平面,平面与平面的距离及平方距离;
--点是否在平面内,线是否在平面内;
--通过一个点,一个轴的镜像平面;
--平面的旋转,缩放与平移;

Geom_ElementarySurface类:

此类用来描述一个表面,此类的派生类有:
平面;园柱面;锥面;球面;园环面;
它的基类是Geom_Surface,是一个抽象类;
Geom_Surface类的基类是Geom_Geometry类;
 

Geom_RectangularTrimmedSurface类:

用来生成一个有边界的平面;
比如:
Handle(Geom_Plane) aProjectionPlane = GC_MakePlane(ProjectionPlane).Value();
    Handle(Geom_RectangularTrimmedSurface) aProjectionPlaneSurface=
        new Geom_RectangularTrimmedSurface(aProjectionPlane,-8.,8.,-12.,12.);       
DisplaySurface(aDoc,aProjectionPlaneSurface);
此类的基类是Geom_BoundedSurface类;
此类的兄弟类还有
- Geom_BezierSurface,
- Geom_BSplineSurface

ConicalSurface类:用来创建一个园锥表面;

构造表面的方法有:
--已知一个园锥表面,和空间一点,过此点的平行于已知园锥表面;
--已知一个园锥表面,和一个距离,创建一个平行于已知园锥表面的园锥表面;
--通过四个点构造一个园锥表面;
--通过一个轴和两个点;
--通过两个点和两个半径;
GeomAPI_IntCS类:
此类用来计算一个园弧和和一个表面的交点或相交线段;
GeomFill_BSplineCurves类:
此类用来构造一个可以填充的BSpline表面,构造它可以用两个三个或四个BSpline曲线作为边界;
填充类型有三种:
enum GeomFill_FillingStyle {
 GeomFill_StretchStyle,
GeomFill_CoonsStyle,
GeomFill_CurvedStyle
};
以下示例为用两个样条曲线生成一个表面:
GeomFill_FillingStyle Type = GeomFill_StretchStyle;                                  
GeomFill_BSplineCurves aGeomFill1(SPL1,SPL2,Type);                                   
Handle(Geom_BSplineSurface)    aBSplineSurface1 = aGeomFill1.Surface();
GeomFill_Pipe类:
此类用来构造一个pipe,沿着一个路径sweep一个截面,这两个都是曲线类型;一般来说,结果是一个BSpline表面;
常见的有几种方法:
--给定一个路径和一个半径,截面是个园,位置是路径的第一个点,
比如:
GeomFill_Pipe aPipe(SPL1,1);                                      
aPipe.Perform();                                                  
Handle(Geom_Surface) aSurface= aPipe.Surface();                   
Standard_CString aSurfaceEntityTypeName="Not Computed";           
if (!aSurface.IsNull())                                           
   aSurfaceEntityTypeName = aSurface->DynamicType()->Name();
 

--给定一个路径和一个截面。
比如:
Handle(Geom_Ellipse) E = GC_MakeEllipse( gp::XOY() ,3,1).Value(); 
GeomFill_Pipe aPipe2(SPL1,E);                                     
aPipe2.Perform();                                                 
Handle(Geom_Surface) aSurface2= aPipe2.Surface();                  
Standard_CString aSurfaceEntityTypeName2="Not Computed";          
if (!aSurface2.IsNull())  {                                       
    aSurfaceEntityTypeName2 = aSurface2->DynamicType()->Name();   
    aSurface2->Translate(gp_Vec(5,0,0));  }
 

--给定一个路径和两个截面,中间截面为过度线;
示例:
Handle(Geom_TrimmedCurve) TC1 =                                   
    GC_MakeSegment(gp_Pnt(1,1,1),gp_Pnt(5,5,5));                  
Handle(Geom_TrimmedCurve) TC2 =                                   
    GC_MakeSegment(gp_Pnt(1,1,0),gp_Pnt(4,5,6));                  
GeomFill_Pipe aPipe3(SPL1,TC1,TC2);                               
aPipe3.Perform();                                                 
Handle(Geom_Surface) aSurface3 = aPipe3.Surface();                
Standard_CString aSurfaceEntityTypeName3="Not Computed";          
if (!aSurface3.IsNull())                                          
  {                                                               
    aSurfaceEntityTypeName3 = aSurface3->DynamicType()->Name();    
        aSurface3->Translate(gp_Vec(10,0,0));                     
  }                             
--给定一个路径和N个截面,中间为过渡线;
一般情况下,所生结果为:NURBS,但是,在一些特殊的情况下,可以生成平面,园柱,球,园锥等;
参数,U,沿着截面的方向,V沿着路径方向;
Geom_BezierSurface类:
生成一个Bezier表面;
Geom_OffsetSurface类:
用来偏移一个表面;
比如:
Standard_Real offset = 1;                                                       
Handle(Geom_OffsetSurface) GOS = new Geom_OffsetSurface(aGeomSurface, offset);
Geom_SweptSurface类:
有两个派生类,分别用来生成一个回转体表面和一个延展体表面;
 Geom_SurfaceOfLinearExtrusion:用来描述一个线性延展表面;
它的基类是:Geom_Surface类
比如:
Handle(Geom_BSplineCurve) aCurve =GeomAPI_PointsToBSpline(array).Curve();               
gp_Dir aDir(1,2,3);                                       
Handle(Geom_SurfaceOfLinearExtrusion) SOLE =new Geom_SurfaceOfLinearExtrusion(aCurve,aDir);       
Handle(Geom_RectangularTrimmedSurface) aTrimmedSurface =new Geom_RectangularTrimmedSurface(SOLE,-10,10,false);
 

Geom_SurfaceOfRevolution类,表示一个回转体表面;
比如:
Handle(Geom_BSplineCurve) aCurve = GeomAPI_PointsToBSpline(array).Curve();         
Handle(Geom_SurfaceOfRevolution) SOR =new Geom_SurfaceOfRevolution(aCurve,gp::OX()); 

  1:利用一个二维数组来生成曲面的方法:
TColgp_Array2OfPnt array3 (1,5,1,5);                          
array3.SetValue(1,1,gp_Pnt (-4,-4,5));
...
array3.SetValue(2,1,gp_Pnt (-2,-4,4));
...
Handle(Geom_BSplineSurface) aSurf2 =GeomAPI_PointsToBSplineSurface(array3).Surface();
 

2:GeomAPI_ExtremaSurfaceSurface类:
计算两个表面之间的极值点;
主要方法:
(1):Quantity_Length LowerDistance() const;计算两个表面的最短距离;
(2):Standard_EXPORT   void LowerDistanceParameters(Quantity_Parameter& U1,Quantity_Parameter& V1,Quantity_Parameter& U2,Quantity_Parameter& V2) const;
得到第一个表面上的极值点的UV参数和第二个表面上的极值点的UV参数;
(3):void NearestPoints(gp_Pnt& P1,gp_Pnt& P2) const;得到第一个表面上的极值点和第二个表面上的极值点;
(4): Quantity_Length Distance(const Standard_Integer Index) const;得到第N个极值点的距离;
(5):Standard_Integer NbExtrema() const;极值的数目;
......
示例:
GeomAPI_ExtremaSurfaceSurface ESS(aSurf1,aSurf2);
Quantity_Length dist = ESS.LowerDistance();
gp_Pnt P1,P2;
ESS.NearestPoints(P1,P2);
 

gp_Pnt P3,P4;
Handle(Geom_Curve) aCurve;
Standard_Integer NbExtrema = ESS.NbExtrema();
for(Standard_Integer k=1;k<=NbExtrema;k++){
    ESS.Points(k,P3,P4);                                     
    aCurve= GC_MakeSegment(P3,P4).Value();
    DisplayCurve(aDoc,aCurve,Quantity_NOC_YELLOW3,false);
}
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息