前言
本文翻译自CATIAV5help文档,加上部分自己的理解,从今天起翻译技术文档,保持周更三篇到五篇.
自动生成的目录页
概述
本文介绍了被CATIA V5支持的一般情况的拓扑概念.
定义拓扑结构后,描述基本的元素实体(单元,域,体),然后介绍和说明非流形(non-mainfold)拓扑.汇总表向读者可视化了这些概念之间的联系,
拓扑在几何设计中的应用
译者注:这个流程和我们在零件设计的过程中息息相关.稍后会贴出一段代码来说明这段流程. .
拓扑允许通过对象的详细的边界信息和相互间的联系信息来(表示对象)建模,
.1.壳对象由一个拓扑学中的面(F)的二维实体构成
.2.面F被四个相连的一维边界限制,称这个边界为(E!,E2,E3,E4
)每条边(例如E1)是一条几何曲线©限制,位于曲面上,以两个顶点(V1,V2为界)
.3.边缘由他们的顶点连接,以限制面
(规整的)对象称为流形(mainfold)而呈现(头发"hair",鳞片"scale")状称为非流形.
,非流形的使用对于简化物体的表达非常有帮助,一个实体的加强筋就可以表示为一个二维的(鳞片"scale")
在这个对象中,加强筋被建模为一个二维的拓扑元素,但也关联到了3D对象的一个面,这是一个非流形的表面配置
不带面F的对象B是流形即,标准型
详细定义查看本文流形与非;流形的的定义部分.请到目录中查看
CGM(CATIA Geometric Modeler CATIA几何建模器)使用一种细胞混合""的技术,它允许你1.统一处理多维概念 2.表示所有的流形和非流形对象
基本的拓扑对象
拓扑管理三种类型的实体
Cell | 最基本的拓扑对象 |
---|---|
domain | 一组连接的单元 |
body | 要建模的本身 |
cell
单元是基础几何的连接限制。
根据它们所在空间的尺寸,有四种类型的细胞。
空间维度 | cell类型 | 与几何的联系 |
---|---|---|
0 | Vertex顶点 | 点Point |
1 | Edge边 | 曲线Curve |
2 | Face面 | 曲面Surface |
3 | volume | 3D空间 |
高维单元受低维单元的限制:体积是 3D 空间受面的限制,面是曲面受边的限制,边是曲线受顶点的限制。
domain
域是一组由维度为 n-1 的单元连接的维度为 n 的单元。一个域可能只包含一个单元格。
域对于完全操纵高维单元的边界很有用。例如,如果一张脸由四个相连的边界定,那么所有这些边都可以方便地分组到一个域中。与单元格一样,域根据其实际包含的内容具有特定的名称。
|
A … | is a set of … | bounding … |
---|---|---|
loop | edges connected by vertices | a face |
vertex in face | one vertex | a face |
lump | volumes connected by faces | the 3D space |
shell | faces connected by edges | the 3D space or a volume |
wire | edges connected by vertices | the 3D Space |
in | one vertex the 3D Space or a volume |
体积中的块、壳、线和顶点是 3D 实体的边界。面中的环和顶点是二维实体的边界。没有域与边的边界(一维实体)相关联:顶点直接限制边,因为这样的域不会为模型带来任何附加值。
- 环是一组边,这些边由以面为界的顶点连接
- 壳是由限制体积的边连接的一组面
- 线是由 3D 空间中的顶点连接的一组边
- 面中的顶点浸入面中。在图中的情况下,它表示面 F 和圆锥 C 之间的连接:这是一个非流形配置。
域可以定义外部、内部或沉浸式边界:面中的顶点或体积中的顶点是典型的沉浸式边界。请注意,循环(resp. shell)也可以浸入面(resp.volume)中,但是这种类型的域总是被称为循环(resp.shell)而不是“面中的边缘”(resp.“face in体积”)。
阅读域的不同定义,您可以看到两个面(分别是两个体积)不能仅通过顶点连接(分别通过边或顶点)。在这种情况下,有必要有两个壳(分别是两个块)。域定义了非流形对象内的流形组件。
立方体 C1 和 C2 具有共同的面 F。它们可以组合在同一个块中。
立方体 C3 和 C4 只有边 E 相同:它们必须放入不同的块中,因为块是由面连接的一组体积。每个块是非流形全局对象的流形组件。
body
一个体是一组不一定相连的域(没有任何尺寸的共同边界)。体必须满足以下属性。
- 任何与body 中的cell 绑定的cell 也属于body。
- 一个体中任意两个单元的基础几何的交集也是一个单元的基础几何(并且该单元必须属于该体,遵循属性 1)。换句话说,“如果没有代表交叉点的单元格,则没有基础几何的交叉点”。
设 F1 是物体 B 的一个面。边 E,即 F1 的边界,也必须属于物体 B。
如果面 F1 和 F2(分别位于面 F1 和 F2 上)是物体 B 的单元,则位于 S1
body只引用域,即使域中只有一个单元格。请参见下一节的示例:主体仅包含一个体积,但它通过块域包含它。和 S2 交点上的边 E 必须存在并且也是 B 的单元。
example
此示例显示了将表示具有腔的长方体的主体分解为单元和域。为了描述清晰,有些关系没有显示出来。
- body由一个体积(volume)组成的块(lump)组成。
- 体积有两个壳边界:内壳和外壳。
- 每个壳由六个面组成。
- 每个面都由一个循环界定。
- 每个 Loop 拥有 4 个 Edge,每个 Edge 由两个 Vertices 界定。
- 请注意,每条边都被两个面使用,每个顶点也被引用了 3 次。
歧管和非歧管概念(流形与非流形概念)
定义
CGM 允许您创建和使用流形和非流形实体。从数学上讲,N 流形对象是一组点,其邻域由 N 维碗表示。取一个块域(分别是外壳,循环)。如果对于这个域的每个点,存在一个域的邻域仅相当于一个球体(分别是圆盘、段),则块(分别是壳、环)是 3D(分别是 2D、1D)-多方面的。否则,它是非流形的。
下图显示了流形和非流形对象的示例。有非流形的地方被突出显示。实体可以是:
- 奇异:如果存在仅由维度 n-2 的单元连接的维度为 n 的单元。 (B4、B5、C4、C5)
- 异构:在同一主体中混合不同维度的域(C6)。
- 一般:维度为 n 的单元格与相同维度的其他单元格(A2,B6)有超过 2 个连接
|
流形 | 非流形 | |
---|---|---|
1D_ | ![]() | |
2D_ | ![]() |
|–|–|
| 3D_ |
|
非流形拓扑提供了几个好处:
- 允许零件的简化表示:对象内部的一个非常小的槽可以表示为在设计的早期阶段浸入体积中的面,加强筋可以建模为面,…
- 允许拓扑操作始终返回解决方案。即使最终结果是多方面的,中间步骤也可能是非多方面的。对流形体的拓扑操作可能会返回非流形配置:let 是一个立方体。现在让我们成为一个与立方体相切并在其内部的圆柱体。这两个对象是多方面的。现在操作立方体和圆柱体的联合:生成的物体是非流形的。现在被平面分割:最终的结果是流形的,尽管中间体不是。下图说明了这种情况:
图 8:中间结果是非流形的,而最终结果是流形的
将主体划分为域
当一个物体包含非连接单元或非流形配置时,有必要将其划分为多个流形域。以下步骤确保将主体唯一分解为域:
- 如果存在未连接的单元集,请将它们放在不同的域中。
- 不同维度的分离域。
正文引用了两个域: - a Lump for the 3D part of the body
- a Shell for the 2D stiffener
面 F6(分别为 F7)有两个环:一个用于外部边界,另一个用于定义“面边”E1(分别为 E2)。该边也被称为面 Face 的边界:这允许 3D 和 2D 域之间的连接。
(为了清楚起见,有些关系没有显示出来。)
放入仅具有公共边或仅具有公共顶点(分别仅具有公共顶点)的不同块(分别为壳)、体积(分别为面)。
两个面 F1 和 F2 只有顶点 V 相同:每个面都有自己的壳。
边 E14、E15、E21、E22 具有共同的顶点 V:该顶点允许两个域之间的连接。 - 包含与其他两个单元有共同边界的单元的拆分域
图 11:将一般主体分解为域和单元格(第一种情况)
面 F2 的边 E21 也限定了面 F1。然后它被两个循环引用,Loop2 用于 F2,L 定义了面 F1 的沉浸域
图 12:将一般主体分解为域和单元格(第二种情况)
边缘 E 不再浸入:它是三个面的外部边界的一部分。在这种情况下,主体具有三个壳。
如果实体只包含两个面 F1 和 F2,则它只有一个由两个面组成的壳。
关于非歧管主体的限制
大多数操作可以在非流形体上执行,但不是全部。趋势是允许用户检查他是否接受生成非流形结果。例如,您将无法挤出或填充具有封闭部分但具有自由边缘的轮廓,除非您取消选中“歧管”复选框,否则您将无法将非歧管主体连接到另一个body。
请注意,CGM 服务允许您创建非流形实体,而 CATIA 工作台通常会将创建的实体“分解”为适当的域。这样,生成的实体不是流形的,但包含易于操作的子元素。下面的例子说明了这种策略。
示例 1:在连接操作中使用 NON-MANIFOLD 主体
通过组装三条并发的线(使用CATTopWire然后CATHybAssemble)创建一个三边体(见右图)。这个体是由四个顶点和三条边组成的。它显然是非模态的。你可以通过使用CATBody::GetCellsHighestDimension方法来检查这一点。
如果您尝试使用 Join 交互式命令将突出显示的主体(一条线)与三边主体连接,您将收到以下消息:
“Update error: Non Manifold Body”.
现在,如果您尝试移除使生成的主体非流形的边缘(使用“连接定义”对话框中的“要移除的子元素”选项卡),您将收到以下消息:
“Bad topology”.
此消息告诉您要删除的子元素未完全包含在域中。实际上,它与另外两条线共享一个顶点。你不能在你的操作中走得更远,你必须重建初始主体以使其成为歧管或将其划分为如上所述的多个域。在这种情况下,最好的方法是将主体分成三个不共享任何顶点的单边线。
示例 2:在连接操作中使用 MANIFOLD 主体(与示例 1 进行比较)
给定一个看起来像上面的三边流形体,但由三根线和六个顶点组成,如果您尝试将突出显示的主体(一条线)与三边主体连接,您还将收到以下消息:
“Update error: Non Manifold Body”.
但是现在,如果您尝试删除使生成的实体不流形的边(使用“连接定义”对话框中的“要删除的子元素”选项卡),CATIA 将删除它并且连接操作将完成。
当您尝试使用 Sketcher 命令创建非流形体时,创建的体将是非流形体,但实际上它会自动划分为流形域,以便进一步操作需要删除不合适的元素将变得更容易. Sketcher 坚持这一策略。
总结
主体是一组域,其中包含连接的单元格,这些单元格以较低维度的域为界,…
建立规则以提供body的独特分解。
下图总结了域和单元之间的关系。箭头 domain->cell 表示关系“由…组成”。箭头单元格-> 域表示关系“有界”。
代码样例
//引用和界面搭建部分省略
//创建新的Part文件
CATDocument * pDoc = NULL;
HRESULT rc = CATDocumentServices::New("Part", pDoc);
if ( FAILED(rc) || NULL == pDoc ) return ;
//新Part文件初始化
CATInit * pInit = NULL;
rc = pDoc->QueryInterface(IID_CATInit, (void**)&pInit);
if (FAILED(rc)|| NULL == pInit ) return ;
pInit->Init(TRUE);
//获取结构container
CATIContainerOfDocument_var spNewDocContainer = pDoc;
CATIContainer *piNewContainer = NULL;
rc = spNewDocContainer->GetSpecContainer(piNewContainer);
if (FAILED(rc) || piNewContainer == NULL) return ;
CATIPrtContainer* pPrtCon = NULL;
rc= piNewContainer->QueryInterface( IID_CATIPrtContainer,(void **)&pPrtCon);
if (FAILED(rc) || pPrtCon == NULL) return ;
//设置草图工厂,设置轴系工厂
CATIPrtContainer* pIPrtContOnDocument = pPrtCon;
CATIMf3DAxisSystemFactory * pIMf3DAxisSystemFactoryOnFeatCont = NULL ;
rc=pIPrtContOnDocument->QueryInterface(IID_CATIMf3DAxisSystemFactory,
(void **) & pIMf3DAxisSystemFactoryOnFeatCont);
CATISketchFactory * pISketchFactoryOnFeatCont = NULL ;
rc=pIPrtContOnDocument->QueryInterface(IID_CATISketchFactory,
(void **) & pISketchFactoryOnFeatCont);
//创建轴系
CATMathPoint Origin (100.0,.0,.0);
CATMathVector Xdir (1.0,0.0,.0);
CATMathVector Ydir (0.0,0.0,1.0);
CATIMf3DAxisSystem_var NewAxisSystem ;
rc = pIMf3DAxisSystemFactoryOnFeatCont->CreateAxisSystem(Origin,Xdir,Ydir,NewAxisSystem);
//添加轴系到视图中
CATISpecObject * pSpecObjectOnAxisSystem = NULL ;
rc=NewAxisSystem->QueryInterface(IID_CATISpecObject,(void **)&pSpecObjectOnAxisSystem);
CATTry pSpecObjectOnAxisSystem->Update();
CATCatch(CATError,error)
{
Flush(error);
return ;
}
CATEndTry
//获取轴系的xy平面
CATIBRepAccess_var PlaneBRep ;
rc = NewAxisSystem->GetPlaneBRepAccess(CATAxisSystemZNumber,PlaneBRep);
//Brep对象特征化
CATIFeaturize * pIFeaturizeOnPlane = NULL ;
rc = PlaneBRep->QueryInterface(IID_CATIFeaturize,(void **) &pIFeaturizeOnPlane);
CATISpecObject_var MFPlane = pIFeaturizeOnPlane->FeaturizeF();
//创建草图
CATISpecObject_var NewSketch = pISketchFactoryOnFeatCont->CreateSketch(MFPlane);
//启动草图编辑器
CATISketch_var spSketch(NewSketch); if ( NULL_var == spSketch ) return ;
spSketch->OpenEdition();
//开始草图绘图
CATI2DWFFactory_var sketch2DFactory(spSketch); // 获取 2D工厂来创建图形
CATI2DPoint_var spPt_bottom_left, spPt_bottom_right, spPt_top_right, spPt_top_left;
CATI2DLine_var spLine1, spLine2, spLine3, spLine4;
double pt_bottom_left[2] = {10., 10.};
double pt_bottom_right[2] = {50., 10.};
double pt_top_right[2] = {50., 50.};
double pt_top_left[2] = {10., 50.};
spPt_bottom_left = sketch2DFactory->CreatePoint(pt_bottom_left);
spPt_bottom_right = sketch2DFactory->CreatePoint(pt_bottom_right);
spPt_top_right = sketch2DFactory->CreatePoint(pt_top_right);
spPt_top_left = sketch2DFactory->CreatePoint(pt_top_left);
spLine1 = sketch2DFactory->CreateLine(pt_bottom_left,pt_bottom_right);
spLine2 = sketch2DFactory->CreateLine(pt_bottom_right,pt_top_right);
spLine3 = sketch2DFactory->CreateLine(pt_top_right,pt_top_left);
spLine4 = sketch2DFactory->CreateLine(pt_top_left,pt_bottom_left);
// 将线连接起来
CATI2DCurve_var spCurve1 (spLine1);
CATI2DCurve_var spCurve2 (spLine2);
CATI2DCurve_var spCurve3 (spLine3);
CATI2DCurve_var spCurve4 (spLine4);
spCurve1->SetStartPoint(spPt_bottom_left);
spCurve1->SetEndPoint(spPt_bottom_right);
spCurve2->SetStartPoint(spPt_bottom_right);
spCurve2->SetEndPoint(spPt_top_right);
spCurve3->SetStartPoint(spPt_top_right);
spCurve3->SetEndPoint(spPt_top_left);
spCurve4->SetStartPoint(spPt_top_left);
spCurve4->SetEndPoint(spPt_bottom_left);
//设置草图约束
CATI2DConstraintFactory_var spConstraint2DFactory(spSketch);
spConstraint2DFactory->CreateConstraint( spLine1, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Horizontal, 0, 0 );//水平约束
spConstraint2DFactory->CreateConstraint( spLine2, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Vertical, 0, 0 ); //垂直约束
spConstraint2DFactory->CreateConstraint( spLine3, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Horizontal, 0, 0 ); //水平约束
spConstraint2DFactory->CreateConstraint( spLine4, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Vertical, 0, 0 ); //垂直约束
spConstraint2DFactory->CreateConstraint( spLine2, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Length, 0, 0 ); //长度约束
spConstraint2DFactory->CreateConstraint( spLine2, NULL, spLine4, NULL, NULL, NULL, NULL,
Cst2DType_Distance, 0, 0 ); //距离约束
//创建草图修饰——圆倒角
double radius = 10.;
double pt_center[2] = {70., 40.};
CATI2DCurve_var spCurve5 = sketch2DFactory->CreateCorner(spCurve3, spCurve4, pt_center, &radius);
CATI2DTopologicalOperators_var spOperateur = spSketch;
spOperateur->InsertCorner(spCurve5,spLine3,1,spLine4,1);
spConstraint2DFactory->CreateConstraint( spLine3, NULL, spCurve5, NULL, NULL, NULL, NULL,
Cst2DType_Tangent, 0, 0);
spConstraint2DFactory->CreateConstraint( spCurve5, NULL, spLine4, NULL, NULL, NULL, NULL,
Cst2DType_Tangent, 0, 0);
spConstraint2DFactory->CreateConstraint( spCurve5, NULL, NULL, NULL, NULL, NULL, NULL,
Cst2DType_Radius, 0, 1);
//关闭草图编辑器
spSketch->CloseEdition();
//添加草图到视图中
CATISpecObject * pSpecObjectOnSketch = NULL ;
rc=spSketch->QueryInterface(IID_CATISpecObject,(void **)&pSpecObjectOnSketch);
CATTry pSpecObjectOnSketch->Update();
CATCatch(CATError,error)
{
Flush(error);
return ;
}
CATEndTry
//创建几何特征集
CATIPrtContainer* ipPrtCont = pPrtCon;//结构Container
CATIMechanicalRootFactory *pSetToolFactory=NULL;//设置MechanicalRoot工厂
rc=ipPrtCont->QueryInterface(IID_CATIMechanicalRootFactory,(void **)& pSetToolFactory);
if(FAILED(rc)|| pSetToolFactory ==NULL) return;
CATIPrtPart_var spPart=ipPrtCont->GetPart();
if(spPart==NULL_var) return ;
CATISpecObject_var spPRTTool;
spPRTTool= pSetToolFactory->CreatePRTTool("复制的几何体",spPart);
//复制凸台特征用接口 CATICutAndPastable
if (spSpecObj == NULL_var) return;
//获取特征容器
CATIContainer_var spContainer = spSpecObj->GetFeatContainer();
if (spContainer == NULL_var)return;
//由容器查找到剪切粘贴接口
CATICutAndPastable *pCutAndPastable = NULL;
rc = spContainer->QueryInterface(IID_CATICutAndPastable, (void **)&pCutAndPastable);
if (FAILED(rc) || pCutAndPastable==NULL)return ;
//添加删除元素
CATLISTV(CATBaseUnknown_var) listOfUnknown;
listOfUnknown.Append(spSpecObj);
pCutAndPastable->Paste(listOfUnknown);
//复制凸台特征到 复制的几何体 用接口CATMmrInterPartCopy
CATISpecObject_var SourceToCopy = spSpecObj;
CATISpecObject_var Target = spPRTTool;
//创建CATMmrInterPartCopy类的实例
CATMmrInterPartCopy * ptCATMmrInterPartCopy = new CATMmrInterPartCopy (SourceToCopy, Target) ;
//用SetLinkMode 方法设置复制选项
ptCATMmrInterPartCopy ->SetLinkMode(FALSE);
//采用run()方法执行复制任务
CATUnicodeString ErrorMsg = "" ;
rc = ptCATMmrInterPartCopy ->Run(&ErrorMsg);
//采用GetResult方法获取复制结果。代码如下:
CATISpecObject_var Result;
rc = ptCATMmrInterPartCopy ->GetResult(Result);
//复制结果添加到视图
Result->Update();
//更改实体的颜色属性
CATIMfGeometryAccess *pPadAsGeomAccess = NULL;//定义拓扑几何元素接口
rc= Result->QueryInterface
(IID_CATIMfGeometryAccess, (void**)&pPadAsGeomAccess) ;//获取拓扑几何元素接口
if (FAILED(rc) ) return ;
CATLISTV(CATBaseUnknown_var) PadBReps;
pPadAsGeomAccess->GetBReps(PadBReps);//获取所有的拓扑元素 BRep面
// 6-3 替BRep面 更改颜色
for(int currentBRep=1; currentBRep<=PadBReps.Size(); currentBRep++)
{
CATIVisProperties
*pPadBrepAsGraphics = 0;
const CATBaseUnknown_var& currentPadBRep = PadBReps[currentBRep];
if (NULL_var !=
currentPadBRep)
rc = currentPadBRep->QueryInterface(IID_CATIVisProperties,(void**)&pPadBrepAsGraphics) ;//获取面的属性接口
if ( SUCCEEDED(rc) )
{
int R,G,B;
R=0;
G=200;
B=0;
CATVisPropertiesValues color;//定义颜色属性
color.SetColor(R, G, B); // green
pPadBrepAsGraphics->SetPropertiesAtt(color, CATVPColor, CATVPMesh);//设置颜色属性
pPadBrepAsGraphics->Release();
pPadBrepAsGraphics = NULL ;
}
}
//重命名特征
if ( NULL_var == Result ) return;
CATIAlias* pAlias = NULL;
rc = Result->QueryInterface(IID_CATIAlias, (void**)&pAlias);//获取名称接口
if ( SUCCEEDED(rc) )
{
pAlias->SetAlias("复制的块");//设置名称
pAlias->Release();
pAlias = NULL;
}
//更改Part特征名称为NewPart
CATIAPartDocument* pCATIAPrtDoc = NULL;
CATIAProductDocument * pCATIAPrdtDoc = NULL;
rc = pDoc->QueryInterface(IID_CATIAPartDocument, (void**)&pCATIAPrtDoc);
rc = pDoc->QueryInterface( IID_CATIAProductDocument, (void**)&pCATIAPrdtDoc );
if ( NULL == pCATIAPrdtDoc && NULL == pCATIAPrtDoc ) return;
CATIAProduct* pCATIAPrtRoot = NULL;
if ( NULL != pCATIAPrtDoc )
{
pCATIAPrtDoc->get_Product(pCATIAPrtRoot);
}
else if ( NULL != pCATIAPrdtDoc )
{
pCATIAPrdtDoc->get_Product(pCATIAPrtRoot);
}
if (NULL == pCATIAPrtRoot )return;
CATUnicodeString PartNumber ="NewPart";
CATBSTR bstr;
PartNumber.ConvertToBSTR(&bstr);
pCATIAPrtRoot->put_PartNumber(bstr);
pCATIAPrtRoot->Update();
CATBSTR newBstr;
pCATIAPrtRoot->get_PartNumber(newBstr);
CATUnicodeString s;
s.BuildFromBSTR(newBstr);
if ( NULL != pCATIAPrtDoc )
{
pCATIAPrtDoc->Release(); pCATIAPrtDoc = NULL;
}
if ( NULL != pCATIAPrdtDoc )
{
pCATIAPrdtDoc->Release(); pCATIAPrdtDoc = NULL;
}
//设置草图为显示状态
CATIVisProperties *pVisProperties = NULL;
rc = pSpecObjectOnSketch->QueryInterface(IID_CATIVisProperties,(void**)&pVisProperties);
if( SUCCEEDED(rc) && pVisProperties!=NULL)
{
CATVisPropertiesValues MyProp;
pVisProperties->GetPropertiesAtt(MyProp, CATVPShow);
MyProp.SetShowAttr(CATShowAttr);
pVisProperties -> SetPropertiesAtt(MyProp,CATVPShow ,CATVPGlobalType);// CATVPShow CATVPGlobalType
pVisProperties -> Release();
pVisProperties = NULL ;
}
pSpecObjectOnSketch->Update();
//设置文件路径
CATUnicodeString DocTitle="NewPart";
CATUnicodeString DocName="NewPart.CATPart";
CATUnicodeString DocPath="D:\\";
CATDocumentServices::SaveAsNew(*pDoc, DocPath+ DocName);//
五月二十九日初稿,