CATIA-V5中Handle的创建(方向Handle、角度Handle)

创建步骤:
(1)首先创建一个新的FrameWork


image.png

(2)针对方向Handle与角度Handle,分别创建各自的Module:


image.png

(3)新建接口:
SJDIDirectionHandleRep:
image.png

添加以下纯虚函数:

      virtual HRESULT SetDatas(
          CATMathPoint* ipmathOriginPoint,
          CATMathDirection* ipmathDirection,
          CATUnicodeString& ustrStringVal,  
          int inColorRVal=0,
          int inColorGVal=255,
          int inColorBVal=0) = 0;
      virtual HRESULT SetGraphicRepresentation (CATRep*  ipRep ) = 0;
      virtual HRESULT GetGraphicRepresentation (CATRep** oppRep ) = 0;
      virtual HRESULT GetOriginalPoint(CATMathPoint& imathPoint) = 0;
      virtual HRESULT GetAlignDir(CATMathDirection& imathDir) = 0;

其中:ipmathOriginPoint为方向Handle位置点;ipmathDirection为方向Handle的方向;ustrStringVal为Handle上标注的文字。
SJDIAngleHandleRep添加以下纯虚函数:

      virtual HRESULT SetDatas(
          double*  idPoints,
          CATMathVector&  iMathNormal,
          CATMathVector&  iMathReferenceAxis,
          CATUnicodeString& ustrStringVal,
          double&   idRadios,
          int iColorRVal=0,
          int iColorGVal=255,
          int iColorBVal=0) = 0;
      virtual HRESULT SetGraphicRepresentation (CATRep*  ipRep ) = 0;
      virtual HRESULT GetGraphicRepresentation (CATRep** oppRep ) = 0;
      virtual HRESULT GetOriginalPoint(CATMathPoint& omathPoint) = 0;
      virtual HRESULT GetNormalDir(CATMathVector& omathDir) = 0;
      virtual HRESULT GetReferenceAxisDir(CATMathVector& omathDir) = 0;

其中:idPoints为Handle中各条线的构造点;iMathNormal为Handle的法线方向;iMathReferenceAxis为Handle的旋转轴方向;ustrStringVal为Handle上标注的文字。
(4)新建Component


image.png

SJDDirectHandleRepComp:
继承自CATModelForRep3D

CATImplementClass(SJDDirectHandleRepComp,
                  Implementation,
                  CATModelForRep3D,
                  CATnull );

TIE mode为SJDIDirectionHandleRep

TIE_SJDIDirectionHandleRep(SJDDirectHandleRepComp);

SJDAngleHandleRepComp:
继承自CATModelForRep3D

CATImplementClass(SJDAngleHandleRepComp,
                  Implementation,
                  CATModelForRep3D,
                  CATnull );

TIE mode为SJDIAngleHandleRep

TIE_SJDIAngleHandleRep(SJDAngleHandleRepComp);

在上述所创建的Component中添加Handle创建的主要逻辑
方向Handle:

HRESULT SJDDirectHandleRepComp::SetDatas (CATMathPoint*  ipmathOriginPoint , CATMathDirection*  ipmathDirection , CATUnicodeString&  ustrStringVal , int  inColorRVal , int  inColorGVal , int  inColorBVal)
{
    HRESULT rc = S_OK;
    _mathPt = (*ipmathOriginPoint);
    _mathDir = (*ipmathDirection);
    rc = UpdateHandle(inColorRVal,inColorGVal,inColorBVal,ustrStringVal);
    if (S_OK != rc)
    {
        return S_FALSE;
    }
   return S_OK;
}
HRESULT SJDDirectHandleRepComp::UpdateHandle(int  inColorRVal, int  inColorGVal, int  inColorBVal,CATUnicodeString&  ustrStringVal)
{
    HRESULT rc=S_OK;
    // 构造方向Handle的箭头
    CAT3DCustomRep* pRepForCenter = new CAT3DCustomRep();
    if (NULL == pRepForCenter)
    {
        return S_FALSE; 
    }
    int lenAll=20;
    int lenHead=5;
    int lenBase=0;
    CATMathPointf       iMathOrign(_mathPt.GetX(), _mathPt.GetY(), _mathPt.GetZ());
    CATMathDirectionf   iMathDir(_mathDir.GetX(), _mathDir.GetY(), _mathDir.GetZ());
    CAT3DFixedArrowGP*  pArrow = new CAT3DFixedArrowGP(iMathOrign, iMathDir, lenAll, lenHead, lenBase );
    if (NULL == pArrow)
    {
        return S_FALSE; 
    }

    //set color
    CATGraphicAttributeSet attGP;
    attGP.SetColor(TRUECOLOR);
    attGP.SetColorRGBA(inColorRVal,inColorGVal,inColorBVal,255);
    attGP.SetThickness(4);

    //add graphic primitive
    pRepForCenter->AddGP(pArrow,attGP);

    if (ustrStringVal.GetLengthInChar() != 0)
    {
        // 设定显示文字信息
        CAT3DAnnotationTextGP *pText = new CAT3DAnnotationTextGP(
            iMathOrign, ustrStringVal,BOTTOM_CENTER,15.0);
        if (NULL == pText)
        {
            return S_FALSE; 
        }
        pRepForCenter->AddGP(pText,attGP);
    }

    SetGraphicRepresentation(pRepForCenter);

    return S_OK;
}

角度Handle:

HRESULT SJDAngleHandleRepComp::SetDatas (double*  idPoints , CATMathVector&  iMathNormal , CATMathVector&  iMathReferenceAxis , CATUnicodeString&  ustrStringVal , double&  idAngle , int  iColorRVal , int  iColorGVal , int  iColorBVal)
{
    HRESULT rc = S_OK;
    _mathPt = CATMathPoint(idPoints[3],idPoints[4],idPoints[5]);
    _mathNormalDir = iMathNormal;
    _mathReferenceAxisDir = iMathReferenceAxis;

    rc = UpdateHandle(idPoints,_mathNormalDir,idAngle,_mathReferenceAxisDir,
        ustrStringVal,iColorRVal,iColorGVal,iColorBVal);
    if (S_OK != rc)
    {
        return S_FALSE;
    }
   return S_OK;
}

此次所做的角度Handle是由两条直线(两直线形成角度的两条边)、两直线所夹的圆弧、圆弧上的箭头直线、角度Handle的角度。
上述三种部件均需要分别进行绘制。

HRESULT SJDAngleHandleRepComp::UpdateHandle(
    double*             idPoints,
    CATMathVector&      iMathNormal,
    double&             idAngle,
    CATMathVector&      iMathReferenceAxis,
    CATUnicodeString&  iUstrStringVal,
    int  iColorRVal, 
    int  iColorGVal, 
    int  iColorBVal
    )
{
    HRESULT rc = S_OK;
    CAT3DCustomRep * pRepForHandle = new CAT3DCustomRep();
    if (NULL == pRepForHandle)
    {
        return S_FALSE; 
    }

    /*
    * Handle中的线
    */
    // 构造折线
    float Coord[6];
    for (int iLoop = 0; iLoop < 6;iLoop++)
    {
        Coord[iLoop] = idPoints[iLoop];
    }
    CAT3DLineGP *pLineGroup1 = new CAT3DLineGP(Coord, 2);
    if (NULL == pLineGroup1)
    {
        return S_FALSE; 
    }
    //set color
    CATGraphicAttributeSet attGP;
    attGP.SetColor(TRUECOLOR);
    attGP.SetColorRGBA(iColorRVal,iColorGVal,iColorBVal,255);
    attGP.SetThickness(4);
    //add graphic primitive
    pRepForHandle->AddGP(pLineGroup1,attGP);

    for (int iLoop = 0; iLoop < 6;iLoop++)
    {
        Coord[iLoop] = idPoints[iLoop + 3];
    }
    CAT3DLineGP *pLineGroup2 = new CAT3DLineGP(Coord, 2);
    if (NULL == pLineGroup2)
    {
        return S_FALSE; 
    }
    pRepForHandle->AddGP(pLineGroup2,attGP);

    /*
    * Handle中的角度圆弧
    */
    CATMathPointf mathCenterPnt (idPoints[3], idPoints[4], idPoints[5]);
    CATMathVectorf  mathNormalVector(iMathNormal.GetX(),iMathNormal.GetY(),iMathNormal.GetZ());
    CATMathVectorf  mathReferenceAxis(iMathReferenceAxis.GetX(),iMathReferenceAxis.GetY(),iMathReferenceAxis.GetZ());
        
    // 计算圆弧半径(为第一定位点与第二定位点距离的/2)
    double      dRadius = sqrt(pow((idPoints[3] - idPoints[0]),2) + pow((idPoints[4] - idPoints[1]),2)
        + pow((idPoints[5] - idPoints[2]),2)) * 0.5;    

    // 设定角度为
    double dStartAngle = 0;
    double dEndAngle = (idAngle* CATPI) / 180;
    CAT3DArcCircleGP *pCircleGroup = new CAT3DArcCircleGP(
        mathCenterPnt,mathNormalVector,dRadius,mathReferenceAxis,dStartAngle,dEndAngle);
    if (NULL == pCircleGroup)
    {
        return S_FALSE; 
    }
    //add graphic primitive
    pRepForHandle->AddGP(pCircleGroup,attGP);

    /*
    * 创建箭头直线<->
    */
    double      dWrkMoveLength1 = 0.0;
    double      dWrkMoveLength2 = 0.0;
    double      dWrkMoveLength3 = 0.0;

    // 计算基准点坐标
    double idPoint1[3] = {idPoints[0],idPoints[1],idPoints[2]};
    double idPoint2[3] = {idPoints[3],idPoints[4],idPoints[5]};
    double idPoint3[3] = {idPoints[6],idPoints[7],idPoints[8]};

    CATMathVector   mathP2P1Vector = CATMathVector();
    mathP2P1Vector.SetX(idPoint1[0] - idPoint2[0]);
    mathP2P1Vector.SetY(idPoint1[1] - idPoint2[1]);
    mathP2P1Vector.SetZ(idPoint1[2] - idPoint2[2]);
    mathP2P1Vector.Normalize();
    idPoint1[0] = idPoint2[0] + dRadius * mathP2P1Vector.GetX();
    idPoint1[1] = idPoint2[1] + dRadius * mathP2P1Vector.GetY();
    idPoint1[2] = idPoint2[2] + dRadius * mathP2P1Vector.GetZ();

    CATMathVector   mathP2P3Vector = CATMathVector();
    mathP2P3Vector.SetX(idPoint3[0] - idPoint2[0]);
    mathP2P3Vector.SetY(idPoint3[1] - idPoint2[1]);
    mathP2P3Vector.SetZ(idPoint3[2] - idPoint2[2]);
    mathP2P3Vector.Normalize();
    idPoint3[0] = idPoint2[0] + dRadius * mathP2P3Vector.GetX();
    idPoint3[1] = idPoint2[1] + dRadius * mathP2P3Vector.GetY();
    idPoint3[2] = idPoint2[2] + dRadius * mathP2P3Vector.GetZ();
    
    // 左上线
    // 求点与点的中点(E)
    double  dMidPoint1[3] = {0.0,0.0,0.0};
    dMidPoint1[0] = (idPoint1[0] + idPoint3[0]) * 0.5;
    dMidPoint1[1] = (idPoint1[1] + idPoint3[1]) * 0.5;
    dMidPoint1[2] = (idPoint1[2] + idPoint3[2]) * 0.5;
    // 点与dTempPoint1(E)的距离
    double  dMoveLen[3] = {0.0,0.0,0.0};
    dMoveLen[0] = dMidPoint1[0] - idPoint3[0];
    dMoveLen[1] = dMidPoint1[1] - idPoint3[1];
    dMoveLen[2] = dMidPoint1[2] - idPoint3[2];
    dWrkMoveLength1 = sqrt(pow(dMoveLen[0],2)+ pow(dMoveLen[1],2) + pow(dMoveLen[2],2));

    // dTempPoint1(E)->点的矢量
    CATMathVector   mathMoveEP2Vector = CATMathVector();
    mathMoveEP2Vector.SetX(idPoint2[0] - dMidPoint1[0]);
    mathMoveEP2Vector.SetY(idPoint2[1] - dMidPoint1[1]);
    mathMoveEP2Vector.SetZ(idPoint2[2] - dMidPoint1[2]);
    mathMoveEP2Vector.Normalize();
    // 移动距离
    dWrkMoveLength2 = dWrkMoveLength1 * tan(((45.0 - 5.0 * 0.5) * CATPI) / 180.0);

    // 计算箭头的端点D
    double  dEndPoint[3] = {0.0,0.0,0.0};
    dEndPoint[0] = dMidPoint1[0] + mathMoveEP2Vector.GetX() * dWrkMoveLength2;
    dEndPoint[1] = dMidPoint1[1] + mathMoveEP2Vector.GetY() * dWrkMoveLength2;
    dEndPoint[2] = dMidPoint1[2] + mathMoveEP2Vector.GetZ() * dWrkMoveLength2;

    // 计算点->D的矢量
    CATMathVector   mathMoveP3DVector = CATMathVector();
    mathMoveP3DVector.SetX(dEndPoint[0] - idPoint3[0]);
    mathMoveP3DVector.SetY(dEndPoint[1] - idPoint3[1]);
    mathMoveP3DVector.SetZ(dEndPoint[2] - idPoint3[2]);
    mathMoveP3DVector.Normalize();
    // 计算距离
    dMoveLen[0] = dEndPoint[0] - idPoint3[0];
    dMoveLen[1] = dEndPoint[1] - idPoint3[1];
    dMoveLen[2] = dEndPoint[2] - idPoint3[2];
    dWrkMoveLength3 = sqrt(pow(dMoveLen[0],2)+ pow(dMoveLen[1],2) + pow(dMoveLen[2],2));

    // 确定最终的D点坐标
    dEndPoint[0] = idPoint3[0] + mathMoveP3DVector.GetX() * dWrkMoveLength3 * 0.5;
    dEndPoint[1] = idPoint3[1] + mathMoveP3DVector.GetY() * dWrkMoveLength3 * 0.5;
    dEndPoint[2] = idPoint3[2] + mathMoveP3DVector.GetZ() * dWrkMoveLength3 * 0.5;

    Coord[0] = idPoint3[0];
    Coord[1] = idPoint3[1];
    Coord[2] = idPoint3[2];
    Coord[3] = dEndPoint[0];
    Coord[4] = dEndPoint[1];
    Coord[5] = dEndPoint[2];
    CAT3DLineGP *pLineGroup3 = new CAT3DLineGP(Coord, 2);
    if (NULL == pLineGroup3)
    {
        return S_FALSE; 
    }
    pRepForHandle->AddGP(pLineGroup3,attGP);

    // 左下线
    // 计算箭头的端点D
    double  dReEndPoint[3] = {0.0,0.0,0.0};
    dReEndPoint[0] = dMidPoint1[0] - mathMoveEP2Vector.GetX() * dWrkMoveLength2;
    dReEndPoint[1] = dMidPoint1[1] - mathMoveEP2Vector.GetY() * dWrkMoveLength2;
    dReEndPoint[2] = dMidPoint1[2] - mathMoveEP2Vector.GetZ() * dWrkMoveLength2;

    // 计算点->D'的矢量
    mathMoveP3DVector.SetX(dReEndPoint[0] - idPoint3[0]);
    mathMoveP3DVector.SetY(dReEndPoint[1] - idPoint3[1]);
    mathMoveP3DVector.SetZ(dReEndPoint[2] - idPoint3[2]);
    mathMoveP3DVector.Normalize();

    // 确定最终的D点坐标
    dReEndPoint[0] = idPoint3[0] + mathMoveP3DVector.GetX() * dWrkMoveLength3 * 0.5;
    dReEndPoint[1] = idPoint3[1] + mathMoveP3DVector.GetY() * dWrkMoveLength3 * 0.5;
    dReEndPoint[2] = idPoint3[2] + mathMoveP3DVector.GetZ() * dWrkMoveLength3 * 0.5;

    Coord[0] = idPoint3[0];
    Coord[1] = idPoint3[1];
    Coord[2] = idPoint3[2];
    Coord[3] = dReEndPoint[0];
    Coord[4] = dReEndPoint[1];
    Coord[5] = dReEndPoint[2];
    CAT3DLineGP *pLineGroup4 = new CAT3DLineGP(Coord, 2);
    if (NULL == pLineGroup4)
    {
        return S_FALSE; 
    }
    pRepForHandle->AddGP(pLineGroup4,attGP);

    // 右上线
    // 计算点->D的矢量
    dEndPoint[0] = dMidPoint1[0] + mathMoveEP2Vector.GetX() * dWrkMoveLength2;
    dEndPoint[1] = dMidPoint1[1] + mathMoveEP2Vector.GetY() * dWrkMoveLength2;
    dEndPoint[2] = dMidPoint1[2] + mathMoveEP2Vector.GetZ() * dWrkMoveLength2;
    CATMathVector   mathMoveP1DVector = CATMathVector();
    mathMoveP1DVector.SetX(dEndPoint[0] - idPoint1[0]);
    mathMoveP1DVector.SetY(dEndPoint[1] - idPoint1[1]);
    mathMoveP1DVector.SetZ(dEndPoint[2] - idPoint1[2]);
    mathMoveP1DVector.Normalize();

    // 确定最终的D点坐标
    dEndPoint[0] = idPoint1[0] + mathMoveP1DVector.GetX() * dWrkMoveLength3 * 0.5;
    dEndPoint[1] = idPoint1[1] + mathMoveP1DVector.GetY() * dWrkMoveLength3 * 0.5;
    dEndPoint[2] = idPoint1[2] + mathMoveP1DVector.GetZ() * dWrkMoveLength3 * 0.5;

    Coord[0] = idPoint1[0];
    Coord[1] = idPoint1[1];
    Coord[2] = idPoint1[2];
    Coord[3] = dEndPoint[0];
    Coord[4] = dEndPoint[1];
    Coord[5] = dEndPoint[2];
    CAT3DLineGP *pLineGroup5 = new CAT3DLineGP(Coord, 2);
    if (NULL == pLineGroup5)
    {
        return S_FALSE; 
    }
    pRepForHandle->AddGP(pLineGroup5,attGP);

    // 右下线
    dReEndPoint[0] = dMidPoint1[0] - mathMoveEP2Vector.GetX() * dWrkMoveLength2;
    dReEndPoint[1] = dMidPoint1[1] - mathMoveEP2Vector.GetY() * dWrkMoveLength2;
    dReEndPoint[2] = dMidPoint1[2] - mathMoveEP2Vector.GetZ() * dWrkMoveLength2;
    // 计算点->D'的矢量
    mathMoveP1DVector.SetX(dReEndPoint[0] - idPoint1[0]);
    mathMoveP1DVector.SetY(dReEndPoint[1] - idPoint1[1]);
    mathMoveP1DVector.SetZ(dReEndPoint[2] - idPoint1[2]);
    mathMoveP1DVector.Normalize();

    // 确定最终的D点坐标
    dReEndPoint[0] = idPoint1[0] + mathMoveP1DVector.GetX() * dWrkMoveLength3 * 0.5;
    dReEndPoint[1] = idPoint1[1] + mathMoveP1DVector.GetY() * dWrkMoveLength3 * 0.5;
    dReEndPoint[2] = idPoint1[2] + mathMoveP1DVector.GetZ() * dWrkMoveLength3 * 0.5;

    Coord[0] = idPoint1[0];
    Coord[1] = idPoint1[1];
    Coord[2] = idPoint1[2];
    Coord[3] = dReEndPoint[0];
    Coord[4] = dReEndPoint[1];
    Coord[5] = dReEndPoint[2];
    CAT3DLineGP *pLineGroup6 = new CAT3DLineGP(Coord, 2);
    if (NULL == pLineGroup6)
    {
        return S_FALSE; 
    }
    pRepForHandle->AddGP(pLineGroup6,attGP);

    /*
     * 文字信息
     */
    if (iUstrStringVal.GetLengthInChar() != 0)
    {
        CATUnicodeString    ustrTemp;
        ustrTemp.BuildFromNum(idAngle);
        iUstrStringVal.Append("-");
        iUstrStringVal.Append(ustrTemp);
        CAT3DAnnotationTextGP *pText = new CAT3DAnnotationTextGP(
            mathCenterPnt, iUstrStringVal,BOTTOM_CENTER,15.0);
        if (NULL == pText)
        {
            return S_FALSE; 
        }
        pRepForHandle->AddGP(pText,attGP);
    }

    SetGraphicRepresentation(pRepForHandle);
    return S_OK;
}

(5)创建扩展的Component


image.png

SJDPointInstance继承自CATBaseUnknown
Extended component为:SJDDirectHandleRepComp
Extend Type为DataExtension

CATImplementClass(SJDPointInstance,
                  DataExtension,
                  CATBaseUnknown,
                  SJDDirectHandleRepComp );

TIE mode为CATICreateInstance

TIE_CATICreateInstance( SJDPointInstance);

在这个component中主要定义以下函数:

HRESULT __stdcall SJDPointInstance::CreateInstance (void ** oPPV)
{
    SJDDirectHandleRepComp *pVisArrowModel=new SJDDirectHandleRepComp();

    if( NULL == pVisArrowModel ) return (E_OUTOFMEMORY);

    *oPPV = (void *)pVisArrowModel;
    return S_OK;
}

角度Handle类似。

使用时:
(1)首先要准备好构建Handle的所需的数据:如位置点、方向等;
(2)之后使用如下方法创建其instance,进而创建Handle的形状

void YFBOCreateRibCmd::CreateDirectHandle(CATMathPoint& iMathOriginPnt,CATUnicodeString& iustrHandleName,SJDIDirectionHandleRep*& opDirectionHandle)
{
    // 创建一个箭头
    CATMathDirection mathDir(0.0,0.0,1.0);
    ::CATInstantiateComponent("SJDDirectHandleRepComp", IID_SJDIDirectionHandleRep, (void**)&opDirectionHandle);
    if ( opDirectionHandle != NULL)
    {
        opDirectionHandle->SetDatas(&iMathOriginPnt,&mathDir,iustrHandleName);
    }
}

你可能感兴趣的:(CATIA-V5中Handle的创建(方向Handle、角度Handle))