本帖最后由 天工开发者团队 于 2024-10-18 11:20 编辑
一、简介
1.1 天工Cad二维图形组织结构
天工Cad是一款三维建模软件,二维图形一般是用于草图绘制模式,绘制三维模型的各种视图,以辅助三维模型的创建、修改。三维空间中有无数个平面,每个平面中又可以有无数的二维图形,天工Cad都要管理好他们。对于二维图形,天工Cad以下图中所示组织结构来管理二维草图。
以一个零件文档为例,天工Cad可以创建多个设计体,每个设计体创建时使用到的各种视图如俯视图、侧视图都可以放在一个草图里,而一个Profile可以由下述各类二维图形集组成。
1.2 截面创建
由上图可知,常用二维图形创建的前提是已有一个截(剖)面。
- TGPart::ProfilePtr CreateXOYProfile(TGPart::PartDocumentPtr const& pPartDoc)
- {
- assert(pPartDoc);
- namespace pt = TGPart;
- pt::RefPlanePtr pXOYPlane = pPartDoc->GetRefPlanes()->Item(1l); // 获得XOY平面
- pt::SketchsPtr pSketches = pPartDoc->GetSketches();
- pt::SketchPtr pSketch = pSketches->Add(); //创建草图
- pt::ProfilePtr pXOYProfile = pSketch->GetProfiles()->Add(pXOYPlane); //创建XOY平面的截面
- return pXOYProfile;
- }
复制代码 上述代码演示了创建一个截面的通用流程,其中的关键Api是Profiles接口中的Add方法,本文后续各类图形的创建均基于此函数形成的XOY剖面。
1.2.1 Profiles::Add
- TGPart::ProfilePtr Add (IDispatch * pRefPlaneDisp );
复制代码 创建一个截面只需要Profiles接口下的Add方法,此方法输入要求是一个参考平面接口指针,在零件文档中就是TGPart::RefPlane*,也可以输入TGPart::RefPlanePtr。
1.2.2 参考平面
参考平面由一个三维空间中的参考原点以及两个互相垂直的三维矢量轴组成,由此一个参考平面相当于定义了一个坐标系统,由参考平面创建的剖面上的所有二维图形都是相对于这个坐标系统创建的。如参考平面[(1,1,10),X,Y]可由XOY平面参考原点位移至(1,1,10)而成,在这个二维参考平面上画线([1,0],[5,5],则这条线在三维空间中的真实坐标为(2,0,10),(6,6,10))。
二、点
在剖面上可以快捷地创建点,使用Points2d接口Add方法即可。
- void CreatePoint(TGPart::ProfilePtr pProfile)
- {
- // 在指定轮廓上位置(0.5,0.5)处创建一点
- TGFrameworkSupport::Point2dPtr pPt2d = pProfile->GetPoints2d()->Add(0.5, 0.5);
- }
复制代码
三、线段
创建线段使用SolidEdgeFrameworkSupport:: Lines2d接口下的诸接口即可,如下所示:
(1) 通过起终点创建
- Line2dPtr AddBy2Points(double stX, double stY, double enX, double enY);
复制代码 (2) 通过起点、长度、角度创建
- Line2dPtr AddByPointAngleLength(double stX, double stY, double Angle, double Length);
复制代码- void CreateSegment(TGPart::ProfilePtr const& pProfile)
- {
- namespace fwp = TGFrameworkSupport;
- fwp::Lines2dPtr pLines2d = pProfile->GetLines2d();
- // 创建一条起点为(0.08, 0)终点为(0.07, 0.02)的直线
- fwp::Line2dPtr pFstLine = pLines2d->AddBy2Points(0.08, 0, 0.07, 0.02);
- // 创建一条起点为原点,角度为30度,长度为0.05的直线
- fwp::Line2dPtr pSecLine = pLines2d->AddByPointAngleLength(0, 0, 30 * M_PI / 180.0, 0.05);
- }
复制代码 上述代码示例了常用的两种二维线段创建方法,运行效果如下图所示。
四、矩形/正多边形 - void CreateRectange(TGPart::ProfilePtr const& pProfile)
- {
- namespace fwp = TGFrameworkSupport;
- // 矩形在天工CAD中由四条首尾相连的直线组成
- fwp::Lines2dPtr pLines2d = pProfile->GetLines2d();
- double cenX = 0.05; // 中心X
- double cenY = 0.05; // 中心Y
- double len = 0.1; // 长
- double width = 0.08; // 宽
- std::array<fwp::Line2dPtr, 4> lines;
- lines[0] = pLines2d->AddBy2Points(cenX - len / 2, cenY - width / 2, cenX + len / 2, cenY - width / 2);// 底边
- lines[1] = pLines2d->AddBy2Points(cenX + len / 2, cenY - width / 2, cenX + len / 2, cenY + width / 2); // 右边
- lines[2] = pLines2d->AddBy2Points(cenX + len / 2, cenY + width / 2, cenX - len / 2, cenY + width / 2); // 上边
- lines[3] = pLines2d->AddBy2Points(cenX - len / 2, cenY + width / 2, cenX - len / 2, cenY - width / 2); // 左边
- fwp::Relations2dPtr pRelations2d = pProfile->GetRelations2d();
- for (int i = 0; i < 4; i++)
- {
- fwp::Line2dPtr pLine = lines[i];
- fwp::Line2dPtr pNextLine = lines[(i + 1) % 4];
- pRelations2d->AddKeypoint(
- pLine,
- (int)TGConstants::KeypointIndexConstants::igLineEnd,
- pNextLine,
- (int)TGConstants::KeypointIndexConstants::igLineStart,
- true);
- }
- pProfile->End(TGPart::ProfileValidationType::igProfileClosed);
- }
复制代码 上述代码示例了如何创建一个矩形,可从代码上看到,关键是将四条线之间的关系设为首尾相连,运行效果如下。
五、圆 使用下述两个接口可以方便地创建一个圆: (1) 提供圆心直径 - TGFrameworkSupport::Circle2d::AddByCenterRadius (double cenX,double cenY,double Radius );
复制代码 (2) 使用三点定圆 - TGFrameworkSupport::Circle2d::AddBy3Points (double x1,double y1,double x2,double y2,double x3,double y3 )
复制代码- void CreateCircle(TGPart::ProfilePtr const& pProfile)
- {
- namespace fwp = TGFrameworkSupport;
- fwp::Circles2dPtr pCircles2d = pProfile->GetCircles2d();
- //! 创建一个圆心在(0.05, 0.0)半径为0.05的圆
- fwp::Circle2dPtr pCirFst = pCircles2d->AddByCenterRadius(0.05, 0.0, 0.05);
- //! 通过三点创建一个圆
- fwp::Circle2dPtr pCirScd = pCircles2d->AddBy3Points(-0.05, -0.08, -0.08, -0.05, -0.02, -0.02);
- }
复制代码 上述代码示例了两种常用的创建圆的方法,运行效果如下。
六、椭圆 - void CreateEllipse(TGPart::ProfilePtr const& pProfile)
- {
- namespace fwp = TGFrameworkSupport;
- fwp::Ellipses2dPtr pEllipses2d = pProfile->GetEllipses2d();
- // 创建一个中心在(1.0, 0.0),主轴矢量为(5.0, 0.0),副轴与主轴长度比为0.5、逆时针方向的椭圆
- fwp::Ellipse2dPtr pEllipse = pEllipses2d->AddByCenter(1.0, 0.0, 5.0, 0.0, 0.5, fwp::Geom2dOrientationConstants::igGeom2dOrientCounterClockwise);
- }
复制代码 上述代码示例了如何创建一个椭圆,运行效果如下。
其中主要用到TGFrameworkSupport::Ellipses2d::AddByCenter方法,其原型如下: - TGFrameworkSupport::Ellipse2dPtr AddByCenter(double xCenter,double yCenter,double xMajor,double yMajor,double Ratio,enum Geom2dOrientationConstants Orientation )
复制代码 xCenter、yCenter定义椭圆中心
xMajor、yMajor定义椭圆主轴矢量
ratio 副轴主轴长度比 结合主轴矢量定义副轴长度
Orientation定义椭圆转向是逆时针还是顺时针
七、圆弧
- void CreateArc(TGPart::ProfilePtr const& pProfile)
- {
- namespace fwp = TGFrameworkSupport;
- fwp::Arcs2dPtr pArcs2d = pProfile->GetArcs2d();
- // 画一个以原点为圆心,起点为(2, 0)终点为(0, 2)的圆弧,圆弧方向为逆时针(90度)
- fwp::Arc2dPtr pFstArc = pArcs2d->AddByCenterStartEnd(0.0, 0.0, 2.0, 0.0, 0.0, 2.0);
- assert(pFstArc->GetOrientation() == fwp::Geom2dOrientationConstants::igGeom2dOrientCounterClockwise);
- // 画一个以原点为圆心,起点为(0, 2)终点为(2, 0)的圆弧,圆弧方向为逆时针(270度)
- fwp::Arc2dPtr pScdArc = pArcs2d->AddByCenterStartEnd(0.0, 0.0, 0.0, 2.0, 2.0, 0.0);
- assert(pScdArc->GetOrientation() == fwp::Geom2dOrientationConstants::igGeom2dOrientCounterClockwise);
- // 画一个以原点为圆心,起点为(0, 0.5)沿着( 0.25, 0.4,)方向到达(0.5, 0.0)的圆弧,圆弧方向为顺时针
- fwp::Arc2dPtr pTrdArc = pArcs2d->AddByStartAlongEnd(0.0, 0.5, 0.25, 0.4, 0.5, 0.0);
- fwp::Geom2dOrientationConstants orien = pTrdArc->GetOrientation();
- assert(orien == fwp::Geom2dOrientationConstants::igGeom2dOrientClockwise);
- // 画一个以原点为圆心,起点为(0.8, 0.0)沿着(0.25, 0.4)方向到达(0.5, 0.0)的圆弧,圆弧方向为逆时针
- fwp::Arc2dPtr pFourthArc = pArcs2d->AddByStartAlongEnd(0.8, 0.0, 0.4, 0.75, 0.0, 0.8);
- assert(pFourthArc->GetOrientation() == fwp::Geom2dOrientationConstants::igGeom2dOrientCounterClockwise);
- }
复制代码 上述代码演示了常用的两种创建圆弧的方法,运行效果如下。 可以看到, 因为传入的截面使用的是XOY平面创建的截面,AddByCenterStartEnd创建的弧总是逆时针的,AddByStartAlongEnd创建的弧严格由起点经中间点转向终点。
八、样条曲线 - template<typename T>
- ATL::CComSafeArray<T> ToComSafeArray(std::initializer_list<T> const& initial_list)
- {
- ATL::CComSafeArray<T> comArray((ULONG)initial_list.size());
- long i = 0;
- for (auto it = initial_list.begin(); it != initial_list.end(); ++it)
- {
- comArray.SetAt(i, *it);
- i++;
- }
- return comArray;
- }
- void CreateBSplineCurve(TGPart::ProfilePtr pProfile)
- {
- namespace fwp = TGFrameworkSupport;
- fwp::BSplineCurves2dPtr pBSplineCurves = pProfile->GetBSplineCurves2d();
- // 控制点3个
- ATL::CComSafeArray<double> poles = ToComSafeArray({ 0.0, 0.3, 0.3, 0.3, 0.3, 0.0 });
- // 节点3+2+1个;
- ATL::CComSafeArray<double> knots = ToComSafeArray({ 0.0,0.0,0.0,1.0,1.0,1.0 });
- // 创建一个二次B样条曲线(2次,3个控制点,无权重)
- fwp::BSplineCurve2dPtr pSpCvNoWeight = pBSplineCurves->Add(2, 3, poles.GetSafeArrayPtr(), knots.GetSafeArrayPtr());
- // 创建一个二次B样条曲线(2次,3个控制点,有权重)
- ATL::CComSafeArray<double> weights = ToComSafeArray({ 1.0,sin(M_PI * 0.25),1.0 }); // 权重
- _variant_t varWeights;
- varWeights.vt = VT_R8 | VT_ARRAY;
- varWeights.parray = weights.Detach();
- fwp::BSplineCurve2dPtr pSpCvWeight = pBSplineCurves->Add(2, 3, poles.GetSafeArrayPtr(), knots.GetSafeArrayPtr(),
- varWeights);
- // 创建一个必通过给定点集的4阶B样条曲线
- ATL::CComSafeArray<double> pointsOpen = ToComSafeArray({ 0.5,0.0,1.0,0.5,1.5,0.0 }); // 三个点
- fwp::BSplineCurve2dPtr pSpCvByPoints = pBSplineCurves->AddByPoints(4, 3, pointsOpen.GetSafeArrayPtr());
- // 创建一个必通过给定点集的4阶B样条曲线,并且是闭合的
- ATL::CComSafeArray<double> pointsClose = ToComSafeArray({ 1.6,0.0,2.1,0.5,2.6,0.0 }); // 三个点
- fwp::BSplineCurve2dPtr pSpCvByPointsClosed = pBSplineCurves->AddByPointsWithCloseOption(4, 3, pointsClose.GetSafeArrayPtr(), true);
- }
复制代码 上述代码演示了常用的创建样条曲线的三个Api,运行效果如下:
其中主要用到三个Api分别为:
8.1 BSplineCurves2d::Add方法 原型如下: - TGFrameworkSupport::BSplineCurve2dPtr TGFrameworkSupport::BSplineCurves2d::Add(long Degree, long NumberOfPoles, SAFEARRAY** Poles, SAFEARRAY** Knots, const _variant_t& Weights = vtMissing);
复制代码 参数分别为:
Degree:次数
NumberOfPoles:控制点个数
Poles:控制点坐标
Knots:节点区间数组,其个数应为控制点个数+次数+1
Weights:权重数组,个数等于控制点个数,默认无权重
8.2 BSplineCurves2d::AddByPoints方法 原型如下: - TGFrameworkSupport::BSplineCurve2dPtr TGFrameworkSupport::BSplineCurves2d::AddByPoints( long Order, long ArraySize, SAFEARRAY** Array);
复制代码 参数分别为:
Order:阶数
ArraySize:样条曲线要经过的点的个数
Array:点坐标集
将运行效果和示例代码结合来看,可以看出这个方法创建的样条曲线必经过(Array,ArraySize)定义的空间点。
8.3 BSplineCurves2d::AddByPointsWithCloseOption方法 原型如下: - TGFrameworkSupport::BSplineCurve2dPtr TGFrameworkSupport::BSplineCurves2d::AddByPointsWithCloseOption( long Order, long ArraySize, SAFEARRAY** Array, VARIANT_BOOL bCreateTangentiallyClosedCurve);
复制代码 此方法和AddByPoints方法相比,多了一个选项可以选择最终构造的样条曲线是否闭合。
九、二次曲线 对于二次曲线(抛物线、椭圆、双曲线),天工Cad提供了快捷的创建方法。 - void CreateConics2d(TGPart::ProfilePtr pProfile)
- {
- namespace fwp = TGFrameworkSupport;
- // rho值,rho=0.5时,创建的是抛物线的一部分;
- // rho<0.5 创建的是椭圆的一部分
- // rho>0.5 创建的是双曲线的一部分
- double rho = 0.5;
- // 创建一条二次曲线
- // 起、终点分别为(-0.5,0)和(0.5,0)
- // 控制点为(0,0.5)
- fwp::Conic2dPtr pConic2d = pProfile->GetConics2d()->AddByThreePointsAndRhoValue(-0.5, 0,
- 0.5, 0, 0, 0.5, rho);
- // 为了看清效果, 连线控制点-起点,控制点-终点
- fwp::Line2dPtr pSegSt2Control = pProfile->GetLines2d()->AddBy2Points(-0.5, 0, 0, 0.5);
- fwp::Line2dPtr pSegControl2End = pProfile->GetLines2d()->AddBy2Points(0, 0.5, 0.5, 0);
- // 二次曲线中与控制点最近点处切线
- fwp::Line2dPtr pLineFst = pProfile->GetLines2d()->AddBy2Points(-0.5, 0.25, 0.5, 0.25);
- // 辅助线转构造
- pProfile->ToggleConstruction(pSegSt2Control);
- pProfile->ToggleConstruction(pSegControl2End);
- pProfile->ToggleConstruction(pLineFst);
- }
复制代码 上述代码示例了创建二次曲线的一般过程,运行效果如下。可以看到起点-控制点,终点-控制点连线总是与最终生成的二次曲线相切,此处创建的是抛物线。 |