leven50 发表于 2024-10-18 10:34:00

【初级教程二】常用二维图形创建

本帖最后由 leven50 于 2024-12-20 09:21 编辑

一、简介
1.1 草图、剖面
         天工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剖面。
      需要注意的是,天工CAD要求同一个剖面集(Profiles)下的各个剖面所参照的参考平面都是同一个。
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)而成,在这个二维参考平面上画线(,,则这条线在三维空间中的真实坐标为(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 = pLines2d->AddBy2Points(cenX - len / 2, cenY - width / 2, cenX + len / 2, cenY - width / 2);// 底边
    lines = pLines2d->AddBy2Points(cenX + len / 2, cenY - width / 2, cenX + len / 2, cenY + width / 2); // 右边
    lines = pLines2d->AddBy2Points(cenX + len / 2, cenY + width / 2, cenX - len / 2, cenY + width / 2); // 上边
    lines = 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;
      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);
}         上述代码示例了创建二次曲线的一般过程,运行效果如下。可以看到起点-控制点,终点-控制点连线总是与最终生成的二次曲线相切,此处创建的是抛物线。

页: [1]
查看完整版本: 【初级教程二】常用二维图形创建