leven50 发表于 2024-10-23 10:08:46

【初级教程六】常用建模操作及布尔运算

本帖最后由 天工开发者团队 于 2024-10-23 17:28 编辑

一、前置性代码
         后续会用到一些公共的功能函数封装在这里,创建一个矩形
void CreateRectangle(TGPart::ProfilePtr& pProfile, double cenX = 0.0, double cenY = 0.0, double len = 0.1, double width = 0.08);void CreateRectangle(TGPart::ProfilePtr& pProfile, double cenX, double cenY, double len, double width)
{
    // 添加矩形
    TGFrameworkSupport::Lines2dPtr pLines2d = pProfile->GetLines2d();
    std::array<TGFrameworkSupport::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); // 左边

    TGFrameworkSupport::Relations2dPtr pRelations2d = pProfile->GetRelations2d();
    for (int i = 0; i < 4; i++)
    {
      TGFrameworkSupport::Line2dPtr pLine = lines;
      TGFrameworkSupport::Line2dPtr pNextLine = lines[(i + 1) % 4];
      pRelations2d->AddKeypoint(
            pLine,
            (int)TGConstants::KeypointIndexConstants::igLineEnd,
            pNextLine,
            (int)TGConstants::KeypointIndexConstants::igLineStart,
            true);
    }
}       创建_variant_t 对象
template<typename T>
_variant_t CreateVariant(T* t, VARENUM em)
{
    // 暂时支持数量为一的一维数组
    SAFEARRAYBOUND bound = { 1, 0 };
    SAFEARRAY* pSafeArry = SafeArrayCreate(em, 1, &bound);
    SafeArrayPutElement(pSafeArry, &bound.lLbound, t);
    VARIANT var;
    VariantInit(&var);
    var.vt = VT_ARRAY | em;
    var.parray = pSafeArry;
    return _variant_t(var);
}

二、拉伸体创建
         拉伸概念:命令通过将草图言垂直草图所在的参考平面的方向拉伸而生成实体特征。

         API:
// API所在数据结构 Models
ModelPtr AddFiniteExtrudedProtrusion(
    long NumberOfProfiles,// 拉伸操作所基于轮廓的数量
    SAFEARRAY** ProfileArray,// 拉伸操作所基于轮廓的数组,与数量保持一致
    enum FeaturePropertyConstants ProfilePlaneSide,// 拉伸方向基于轮廓的方向
    double ExtrusionDistance,// 拉伸的长度
    const _variant_t& KeyPointOrTangentFace = vtMissing,
    const _variant_t& KeyPointFlags = vtMissing,
    const _variant_t& FromSurfOrRefPlane = vtMissing,
    const _variant_t& ToSurfOrRefPlane = vtMissing);       使用示例:
void FiniteExtrudedProtrusion()
{
    namespace pt = TGPart;
    namespace fw = TGFramework;
    namespace fwp = TGFrameworkSupport;
    // 获取Application
    fw::Application* application = TGAddinApp::GetTGApp()->GetTGAddin()->GetApplication();
    // 获取PartDocumentPtr
    pt::PartDocumentPtr partDoc = application->Documents->Add("SolidEdge.PartDocument");

    // 新建草图
    pt::SketchsPtr pSketchs = partDoc->Sketches;
    pt::SketchPtr pSketch = pSketchs->Add();
    // 参考平面
    pt::RefPlanesPtr pRefPlanes = partDoc->RefPlanes;
    pt::RefPlanePtr pRefPlane = pRefPlanes->Item(1);//xoy
    // 获取轮廓
    pt::ProfilePtr pProfile = pSketch->GetProfiles()->Add(pRefPlane);
    // 添加圆,圆心(0,0),半径0.2
    fwp::Circles2dPtr pCircle2d = pProfile->Circles2d;
    pCircle2d->AddByCenterRadius(0, 0, 0.2);
    auto profileStatus = pProfile->End(TGPart::ProfileValidationType::igProfileClosed);
    // Create the extended protrusion.
    ATL::CComSafeArray<IDispatch*> aProfiles(1);
    aProfiles = pProfile;
    //// 单侧拉伸,igRight右侧(即法向侧),igLeft 左侧(法向反方向侧)
    // 基于圆的轮廓做拉伸,拉伸方向为右侧,长度为0.2
    pt::ModelPtr model = partDoc->Models->AddFiniteExtrudedProtrusion(1, aProfiles.GetSafeArrayPtr(),
      TGPart::FeaturePropertyConstants::igRight,
      0.2);

    // 对称拉伸0.2,两边各拉伸0.1
    pt::ModelPtr pModelScd = partDoc->Models->AddFiniteExtrudedProtrusion(1, aProfiles.GetSafeArrayPtr(),
      TGPart::FeaturePropertyConstants::igSymmetric,
      0.2);

    // 非对称拉伸 法向侧拉伸0.3 法向侧反方向拉伸0.5
    pt::RefPlanePtr pTopPlane = pRefPlanes->AddParallelByDistance(pRefPlane, 0.3, pt::igNormalSide);
    pt::RefPlanePtr pBottomPlane = pRefPlanes->AddParallelByDistance(pRefPlane, -0.5, pt::igNormalSide);
    _variant_t   argTop(pTopPlane.GetInterfacePtr());
    _variant_t   argBot(pBottomPlane.GetInterfacePtr());
    pt::ModelPtr pModelTrd = partDoc->Models->AddFiniteExtrudedProtrusion(1, aProfiles.GetSafeArrayPtr(),
      TGPart::FeaturePropertyConstants::igRight, 0, vtMissing, vtMissing, argTop, argBot);
}         代码效果图:


三、旋转体创建
         旋转概念:命令通过指定旋转轴旋转指定草图轮廓而生成旋转特征。

// API所在数据结构 Models
API:ModelPtr AddRevolvedProtrusion(
    long NumberOfProfiles,// 旋转的轮廓的数量
    SAFEARRAY** ProfileArray,// 旋转的轮廓的数组
    struct RefAxis* RefAxis,// 旋转依据的旋转轴
    enum FeaturePropertyConstants ProfileSide,// 轮廓相对于旋转轴的位置
    enum FeaturePropertyConstants ExtentType1,// 第一个范围类型的常量,用于指定旋转的范围
    enum FeaturePropertyConstants ExtentSide1,// 第一个范围的侧面
    double FiniteAngle1,// 旋转的角度,此处是弧度制
    IDispatch* KeyPointOrTangentFace1,// 关键点,一般为NULL
    enum KeyPointExtentConstants* KeyPointFlags1,// 旋转的轮廓的数
    enum FeaturePropertyConstants ExtentType2,// 第二个范围类型的常量,用于指定旋转的范围
    enum FeaturePropertyConstants ExtentSide2,// 第二个范围的侧面
    double FiniteAngle2,// 旋转的角度,此处为弧度制
    IDispatch* KeyPointOrTangentFace2,// 关键点,一般为NULL
    enum KeyPointExtentConstants* KeyPointFlags2);// 关键点类型,一般为NULL       使用示例:
void RevolvedProtrusion()
{
    using namespace TGPart;
    Application* application = TGAddinApp::GetTGApp()->GetApplication();
    TGPart::PartDocumentPtr partDoc = application->GetActiveDocument();
    auto models = partDoc->Models;
    // 新建草图
    auto sketches = partDoc->Sketches;
    auto sketche = sketches->Add();
    // 参考平面
    TGPart::RefPlanesPtr pRefPlanes = partDoc->GetRefPlanes();
    TGPart::RefPlanePtr pRefPlane = pRefPlanes->Item(1); // xoy
    // 轮廓
    TGPart::ProfilesPtr pProfiles = sketche->GetProfiles();
    TGPart::ProfilePtr pProfile = pProfiles->Add(pRefPlane);
    //创建一个中线点为(0.05,0.05),长度为0.1,宽度为0.08的矩形
    CreateRectangle(pProfile, 0.05, 0.05, 0.1, 0.08);
    // 旋转轴,由点(0,0)与(0,0.5)之间构成的旋转轴线
    TGFrameworkSupport::Lines2dPtr pLines2d = pProfile->GetLines2d();
    TGFrameworkSupport::Line2dPtr axis = pLines2d->AddBy2Points(0, 0, 0, 0.5);
    pProfile->ToggleConstruction(axis);
    TGPart::RefAxisPtr pRefAxis = (TGPart::RefAxisPtr)pProfile->SetAxisOfRevolution(axis);
    pProfile->End(TGPart::ProfileValidationType::igProfileClosed);

    // 指定轮廓相对于旋转轴的位置
    TGPart::FeaturePropertyConstants profileSide = TGPart::FeaturePropertyConstants::igRight;
    // 第一个范围类型的常量,用于指定旋转的范围,此处为有限范围
    TGPart::FeaturePropertyConstants extentType1 = TGPart::FeaturePropertyConstants::igFinite;
    // 第一个范围的侧面 左侧
    TGPart::FeaturePropertyConstants extentSide1 = TGPart::FeaturePropertyConstants::igLeft;;
    // 旋转角度 为360
#define PI 3.1415926
    double Angle = 2 * PI;
    // 第二个范围类型的常量,用于指定旋转的范围,此处为有限范围
    TGPart::FeaturePropertyConstants extentType2 = TGPart::FeaturePropertyConstants::igFinite;
    // 第一个范围的侧面 左侧
    TGPart::FeaturePropertyConstants extentSide2 = TGPart::FeaturePropertyConstants::igLeft;
    // Create the extended protrusion.
    CComSafeArray<IDispatch*> aProfiles(1);
    aProfiles = pProfile;
    // AddFiniteRevolvedProtrusion
    auto res = models->AddRevolvedProtrusion(
      1,
      aProfiles.GetSafeArrayPtr(),
      pRefAxis,
      profileSide,
      extentType1,
      extentSide1,
      Angle,
      NULL, NULL, extentType2, extentSide2, Angle, NULL, NULL
    );
}         代码效果图:



四、拔模
         概念:使用拔模命令 可将拔模角添加到一个或多个零件面

         API:
// API所在数据结构 Drafts   
DraftPtr Add(
    IDispatch* DraftPlane,// 拔模的平面,参照平面和方向
    long NumberOfFaceSets,// 拔模的面的数量
    const _variant_t& FaceSetArray,// 拔模的面的数组 IDispatch* 类型
    const _variant_t& DraftAngleArray,// 每个面拔模的角度 弧度制
    enum FeaturePropertyConstants DraftSide);// 拔模的方向         代码示例:
void Draft()
{
    Application* application = TGAddinApp::GetTGApp()->GetApplication();
    TGPart::PartDocumentPtr partDoc = application->GetActiveDocument();
    // 新建草图
    auto sketche = partDoc->Sketches->Add();
    // 参考平面
    TGPart::RefPlanePtr pRefPlane = partDoc->GetRefPlanes()->Item(1); // xoy
    TGPart::ProfilePtr pProfile = sketche->GetProfiles()->Add(pRefPlane);
    // 创建一个矩形
    CreateRectangle(pProfile);
    CComSafeArray<IDispatch*> aProfiles(1);
    aProfiles = pProfile;
    // 基于矩形去进行拉伸,右侧拉伸、长度为0.05
    TGPart::ModelPtr model = partDoc->Models->AddFiniteExtrudedProtrusion(
      1,
      aProfiles.GetSafeArrayPtr(),
      TGPart::FeaturePropertyConstants::igRight,
      0.05);
    TGGeometry::FacesPtr pSideFaces = (TGGeometry::FacesPtr)(model->GetExtrudedProtrusions()->Item(1)->GetSideFaces());
    // 拔模的面
    IDispatchPtr s = pSideFaces->Item(1);
    //拔模角度
#define PI 3.1415926
    double angle = 45 * (PI) / 180;
    // 构造参数
    _variant_t    faceSetArray = CreateVariant<IDispatch>(s, VT_DISPATCH);
    _variant_t    anglrArray = CreateVariant<double>(&angle, VT_R8);
    // 向内角度的 一个面的 拔模角度为45
    DraftPtr pDraft = model->GetDrafts()->Add(
      pRefPlane,
      1,
      faceSetArray,
      anglrArray,
      FeaturePropertyConstants::igInside
    );
}       代码效果图:


五、布尔运算
         概念:3D 建模通常涉及到实体的使用。有时,您可能需要执行以下操作:
1、将多个体组合成一个体。
2、减去体中的部分。
3、处理体的相交。
4、分割体。
使用布尔命令,可以基于现有的体创建所需的体。
布尔操作的输出体类型与目标体相同。
布尔运算的操作都是通过各自的操作集合来进行添加的,具体如下图如示:
布尔运算的要求是有一个目标体,一个工具体,那么一个零件环境中需要有两个设计体,那么我们先用代码创建两个设计体。
目标代码:创建两个设计体,设计体一基于矩形的拉伸体,设计体二基于圆的拉伸体。
void CreateTwoDesign(TGPart::PartDocumentPtr& pDoc)
{
    TGPart::ModelsPtr pModels = pDoc->Models;
    TGPart::ModelPtr pModelOne = pModels->Item(1);
    // 新建草图
    auto sketches = pDoc->Sketches;
    auto sketche = sketches->Add();
    // 参考平面
    TGPart::RefPlanesPtr pRefPlanes = pDoc->GetRefPlanes();
    TGPart::RefPlanePtr pRefPlane = pRefPlanes->Item(1); // xoy
    // 轮廓
    TGPart::ProfilesPtr pProfiles = sketche->GetProfiles();
    TGPart::ProfilePtr pProfile = pProfiles->Add(pRefPlane);
    // 添加矩形
    CreateRectangle(pProfile);
    CComSafeArray<IDispatch*> aProfiles(1);
    aProfiles = pProfile;
    // 基于矩形去进行拉伸,右侧拉伸、长度为0.05
    TGPart::ModelPtr model = pDoc->Models->AddFiniteExtrudedProtrusion(
      1,
      aProfiles.GetSafeArrayPtr(),
      TGPart::FeaturePropertyConstants::igRight,
      0.05);
    // 添加一个设计体2
    auto res = pModels->AddBody(TGPart::AddBodyTypeConstants::igPartType, "设计体2");
    sketches = pDoc->Sketches;
    sketche = sketches->Add();
    // 参考平面
    pRefPlanes = pDoc->GetRefPlanes();
    pRefPlane = pRefPlanes->Item(2); // xoy
    // 轮廓
    pProfiles = sketche->GetProfiles();
    pProfile = pProfiles->Add(pRefPlane);
    // 添加圆的线段圆心(0,0)半径0.01
    Circles2dPtr pCircle2d = pProfile->Circles2d;
    pCircle2d->AddByCenterRadius(0, 0, 0.01);
    auto profileStatus = pProfile->End(TGPart::ProfileValidationType::igProfileClosed);
    aProfiles = pProfile;
    // 基于圆去进行拉伸 ,右侧拉伸,长度为0.05
    model = pDoc->Models->AddFiniteExtrudedProtrusion(
      1,
      aProfiles.GetSafeArrayPtr(),
      TGPart::FeaturePropertyConstants::igRight,
      0.05);
}5.1、合并
         概念:使用“合并”命令(布尔) 将选定的体合并成一个体。目标体占用所有选定的工具体。

       API:
// API所在数据结构 Unions
UnionPtr Add(
    long nNumTargets,// 目标体的个数
    SAFEARRAY** TargetArray,// 目标提的数组 IDispatch* 类型
    long nNumTools,// 工具体的个数
    SAFEARRAY** ToolsArray,// 工具体的数组 IDispatch* 类型
    enum SETargetDesignBodyOption TargetDesignBodyOption,// 指定目标设计体的选项
    enum SETargetConstructionBodyOption TargetConstructionBodyOption);// 指定工具设计体的选项         示例代码:
void Union()
{
    Application* application = TGAddinApp::GetTGApp()->GetApplication();
    TGPart::PartDocumentPtr pDoc = application->GetActiveDocument();
    // 创建两个设计体
    CreateTwoDesign(pDoc);
    TGPart::ModelsPtr pModels = pDoc->Models;
    TGPart::ModelPtr pModel = pModels->Item(1);
    TGPart::UnionsPtr pUnions = pModel->GetUnions();
    // 获取目标体
    auto bodyObj = pModels->Item(1)->Body;
    // 获取工具体
    auto bodyTool = pModels->Item(2)->Body;
    // 创建数组
    CComSafeArray<IDispatch*> aBodysObj(1);
    aBodysObj = bodyObj;
    CComSafeArray<IDispatch*> aBodysTool(1);
    aBodysTool = bodyTool;
    // 合并目标体和工具体
    pUnions->Add(
      1,
      aBodysObj.GetSafeArrayPtr(),
      1,
      aBodysTool.GetSafeArrayPtr(),
      TGPart::SETargetDesignBodyOption::igCreateMultipleDesignBodiesOnNonManifoldOption,
      TGPart::SETargetConstructionBodyOption::igCreateMultipleConstructionBodiesOnNonManifoldOption);
}       代码效果图:


5.2、 减去
         概念:使用减去命令(布尔)从选定的目标体中移除工具体体积。可以选择多个目标体和多个工具体。

       API:
// API所在数据结构 Subtracts
SubtractPtr Add(
    long nNumTargets,// 目标体的个数
    SAFEARRAY** TargetArray,// 目标提的数组 IDispatch* 类型
    long nNumTools,// 工具体的个数
    SAFEARRAY** ToolsArray,// 工具体的数组 IDispatch* 类型
    SAFEARRAY** DirectionArray,// 方向数组(通常不需要,设为空)
    enum SETargetDesignBodyOption TargetDesignBodyOption,// 指定目标设计体的选项
    enum SETargetConstructionBodyOption TargetConstructionBodyOption);// 指定工具设计体的选项       示例代码:
void Subtracts()
{
    Application* application = TGAddinApp::GetTGApp()->GetApplication();
    TGPart::PartDocumentPtr pDoc = application->GetActiveDocument();
    // 创建两个设计体
    CreateTwoDesign(pDoc);
    TGPart::ModelsPtr pModels = pDoc->Models;
    TGPart::ModelPtr pModel = pModels->Item(1);
    TGPart::SubtractsPtr pSubtracts = pModel->GetSubtracts();
    // 获取目标体
    auto bodyObj = pModels->Item(1)->Body;
    // 获取工具体
    auto bodyTool = pModels->Item(2)->Body;
    // 创建数组
    CComSafeArray<IDispatch*> aBodysObj(1);
    aBodysObj = bodyObj;
    CComSafeArray<IDispatch*> aBodysTool(1);
    aBodysTool = bodyTool;
    // 创建方向数组(通常不需要,设为空)
    CComSafeArray<int> aToolDir(1);
    aToolDir = TGPart::SESubtractDirection::igSubtractDirectionNone;
    // 完成减去操作
    pSubtracts->Add(
      1,
      aBodysObj.GetSafeArrayPtr(),
      1,
      aBodysTool.GetSafeArrayPtr(),
      aToolDir.GetSafeArrayPtr(),
      TGPart::SETargetDesignBodyOption::igCreateMultipleDesignBodiesOnNonManifoldOption,
      TGPart::SETargetConstructionBodyOption::igCreateMultipleConstructionBodiesOnNonManifoldOption);
}         代码效果图:


5.3、相交
          概念:使用“相交”命令(布尔) 可以修改体,使其新体积等于两个选定的体的共同体积。

       API:
// API所在数据结构 Intersects
IntersectPtr Add(
    long nNumTargets,// 目标体的个数
    SAFEARRAY** TargetArray,// 目标提的数组 IDispatch* 类型
    long nNumTools,// 工具体的个数
    SAFEARRAY** ToolsArray,// 工具体的数组 IDispatch* 类型
    enum SETargetDesignBodyOption TargetDesignBodyOption,//指定目标设计体的选项
    enum SETargetConstructionBodyOption TargetConstructionBodyOption);//指定工具设计体的选项       示例代码:
void Intersects()
{
    Application* application = TGAddinApp::GetTGApp()->GetApplication();
    TGPart::PartDocumentPtr pDoc = application->GetActiveDocument();
    // 创建两个设计体
    CreateTwoDesign(pDoc);
    TGPart::ModelsPtr pModels = pDoc->Models;
    TGPart::ModelPtr pModel = pModels->Item(1);
    TGPart::IntersectsPtr pIntersects = pModel->GetIntersects();
    // 获取目标体
    auto bodyObj = pModels->Item(1)->Body;
    // 获取工具体
    auto bodyTool = pModels->Item(2)->Body;
    // 创建数组
    CComSafeArray<IDispatch*> aBodysObj(1);
    aBodysObj = bodyObj;
    CComSafeArray<IDispatch*> aBodysTool(1);
    aBodysTool = bodyTool;
    // 完成相交的操作
    pIntersects->Add(
      1,
      aBodysObj.GetSafeArrayPtr(),
      1,
      aBodysTool.GetSafeArrayPtr(),
      TGPart::SETargetDesignBodyOption::igCreateMultipleDesignBodiesOnNonManifoldOption,
      TGPart::SETargetConstructionBodyOption::igCreateMultipleConstructionBodiesOnNonManifoldOption);
}       代码效果图:

5.4、分割
概念: “分割”命令(布尔) 可以利用工具体分割目标体。

         API:
// API所在数据结构 Splits
SplitPtr Add(
    long nNumTargets,// 目标体的个数
    SAFEARRAY** TargetArray,// 目标提的数组 IDispatch* 类型
    long nNumTools,// 工具体的个数
    SAFEARRAY** ToolsArray,// 工具体的数组 IDispatch* 类型
    enum SETargetDesignBodyOption TargetDesignBodyOption,// 指定目标设计体的选项
    enum SETargetConstructionBodyOption TargetConstructionBodyOption);// 指定工具设计体的选项         示例代码:
void Splits()
{
    Application* application = TGAddinApp::GetTGApp()->GetApplication();
    TGPart::PartDocumentPtr pDoc = application->GetActiveDocument();
    // 创建两个设计体
    CreateTwoDesign(pDoc);
    TGPart::ModelsPtr pModels = pDoc->Models;
    TGPart::ModelPtr pModel = pModels->Item(1);
    // 获取目标体
    auto bodyObj = pModels->Item(1)->Body;
    // 获取工具体
    auto bodyTool = pModels->Item(2)->Body;
    // 创建数组
    TGPart::SplitsPtr pSplits = pModel->GetSplits();
    CComSafeArray<IDispatch*> aBodysObj(1);
    aBodysObj = bodyObj;
    CComSafeArray<IDispatch*> aBodysTool(1);
    aBodysTool = bodyTool;
    // 完成分割的操作
    pSplits->Add(
      1,
      aBodysObj.GetSafeArrayPtr(),
      1,
      aBodysTool.GetSafeArrayPtr(),
      TGPart::SETargetDesignBodyOption::igCreateMultipleDesignBodiesOnNonManifoldOption,
      TGPart::SETargetConstructionBodyOption::igCreateMultipleConstructionBodiesOnNonManifoldOption);
}









页: [1]
查看完整版本: 【初级教程六】常用建模操作及布尔运算