eryar

PipeCAD - Plant Piping Design Software.
RvmTranslator - Translate AVEVA RVM to OBJ, glTF, etc.
posts - 603, comments - 590, trackbacks - 0, articles - 0

OpenCascade BRep 格式描述之二

Posted on 2013-07-22 21:50 eryar 阅读(6933) 评论(11)  编辑 收藏 引用 所属分类: 2.OpenCASCADE

OpenCascade BRep Format Description

eryar@163.com

摘要Abstract:本文结合OpenCascade的BRep格式描述文档和源程序,对BRep格式进行分析,详细说明BRep的数据组织形式。结合源程序,可以对OpenCascade中Modeling Data模块中的模型数据结构进行理解。

关键字Key Words:OpenCascade, BRep Format, ModelingData

 

一、实例分析

OpenCascade的data目录中的face1.brep文件:

 

  1 DBRep_DrawableShape
  2 
  3 CASCADE Topology V1, (c) Matra-Datavision
  4 Locations 5
  5 1
  6               1               0               0            -0.4 
  7               0               1               0               0 
  8               0               0               1               0 
  9 1
 10               1               0               0            -0.4 
 11               0               1               0               0 
 12               0               0               1               0 
 13 1
 14               1               0               0             0.8 
 15               0               1               0               0 
 16               0               0               1               0 
 17 1
 18               1               0               0             0.8 
 19               0               1               0               0 
 20               0               0               1               0 
 21 2  1 1 2 1 3 1 4 1 0
 22 Curve2ds 8
 23 1 0 0.8 1 0 
 24 2 0 0 1 0 0 1 0.8
 25 1 1.82347658193698 0 0 1 
 26 1 1 -1.77459666924148 1 0 
 27 1 4.45970872524261 0 0 1 
 28 1 1 -0.225403330758516 1 0 
 29 1 0 0 1 0 
 30 2 0 0 1 0 0 1 0.8
 31 Curves 4
 32 2 0 0 0.8 0 0 1 1 0 0 0 1 0 0.8
 33 1 -0.2 0.774596669241484 0 0 0 1 
 34 1 -0.2 -0.774596669241484 0 0 0 1 
 35 2 0 0 0 0 0 1 1 0 0 0 1 0 0.8
 36 Polygon3D 0
 37 PolygonOnTriangulations 0
 38 Surfaces 4
 39 2 0 0 0 0 0 1 1 0 0 0 1 0 0.8
 40 1 0 0 0.8 0 0 1 1 0 0 0 1 0 
 41 1 -1 -1 -1 1 0 0 0 0 1 0 -1 0 
 42 1 0 0 0 0 0 1 1 0 0 0 1 0 
 43 Triangulations 0
 44 
 45 TShapes 10
 46 Ve
 47 2.0000002e-007
 48 -0.2 0.774596669241483 0.8
 49 0 0
 50 
 51 0101101
 52 *
 53 Ve
 54 2.0000002e-007
 55 -0.2 -0.774596669241484 0.8
 56 0 0
 57 
 58 0101101
 59 *
 60 Ed
 61  1e-007 1 1 0
 62 1  1 0 1.82347658193698 4.45970872524261
 63 2  1 1 0 1.82347658193698 4.45970872524261
 64 2  2 2 0 1.82347658193698 4.45970872524261
 65 0
 66 
 67 0101000
 68 +10 0 -9 0 *
 69 Ve
 70 2.0000002e-007
 71 -0.2 0.774596669241483 0
 72 0 0
 73 
 74 0101101
 75 *
 76 Ed
 77  1e-008 1 1 0
 78 1  2 0 0 0.8
 79 2  3 1 0 0 0.8
 80 2  4 3 5 0 0.8
 81 0
 82 
 83 0101000
 84 +7 0 -10 0 *
 85 Ve
 86 2.0000002e-007
 87 -0.2 -0.774596669241484 0
 88 0 0
 89 
 90 0101101
 91 *
 92 Ed
 93  1e-008 1 1 0
 94 1  3 0 0 0.8
 95 2  5 1 0 0 0.8
 96 2  6 3 5 0 0.8
 97 0
 98 
 99 0101000
100 +5 0 -9 0 *
101 Ed
102  1e-007 1 1 0
103 1  4 0 1.82347658193698 4.45970872524261
104 2  7 1 0 1.82347658193698 4.45970872524261
105 2  8 4 0 1.82347658193698 4.45970872524261
106 0
107 
108 0101000
109 +7 0 -5 0 *
110 Wi
111 
112 0101100
113 -8 0 -6 0 +4 0 +3 0 *
114 Fa
115 0  1e-007 1 0
116 
117 0101000
118 +2 0 *
119 
120 +1 0 
121 0
122 
123 


显示结果如下图所示:

wps_clip_image-13242

Figure 1. Wireframe mode

wps_clip_image-31210

Figure 2. Shaded mode

二、结论

因为OpenCascade的Brep格式是自己的格式,只用到了ModelingData模块,不使用DataExchange模块,可以作为数据交换的一种格式。

三、参考资料

1. BNF范式:http://hi.baidu.com/xuyingming2012/item/9060029141427bd81b49df9e

2. BRep Format Description

3. OpenCascade source code

 

 

 

Feedback

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-10-26 22:44 by 佚名
博主您好!
读您的博客受益非浅,我有个问题想请教,通过顶点vertex生成face,然后explorer face里面的vertex,发现face里的顶点与原来的顶点不相同,就是用issame也找不出相同的顶点,不知道什么原因,后来输出顶点坐标发现坐标值有误差,是不是因为精度的原因?谢谢!

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-10-27 17:56 by eryar
@佚名
您好!

不知道你用的哪个类的函数 issame()?

可以贴出相关代码看看

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-10-28 12:01 by 佚名
TopoDS_Face WhiteFace, BrownFace, RedFace, PinkFace;
TopoDS_Edge Edge1, Edge2, Edge3, Edge4, Edge5, Edge6, Edge7;
TopoDS_Wire Wire1;
gp_Pnt P1, P2, P3, P4, P5, P6, P7;

gp_Sphere sphere (gp_Ax3(gp_Pnt(0,0,0),gp_Dir(1,0,0)),150);

WhiteFace = BRepBuilderAPI_MakeFace(sphere,0.1,0.7,0.2,0.9);

//////////////////////////////////

P1.SetCoord(-15,200,10);
P2.SetCoord(5,204,0);
P3.SetCoord(15,200,0);
P4.SetCoord(-15,20,15);
P5.SetCoord(-5,20,0);
P6.SetCoord(15,20,35);
TColgp_Array2OfPnt array(1,3,1,2);
array.SetValue(1,1,P1);
array.SetValue(2,1,P2);
array.SetValue(3,1,P3);
array.SetValue(1,2,P4);
array.SetValue(2,2,P5);
array.SetValue(3,2,P6);
Handle (Geom_BSplineSurface) curve = GeomAPI_PointsToBSplineSurface(array,3,8,GeomAbs_C2,0.001);

RedFace = BRepBuilderAPI_MakeFace(curve);

////////////////////

gp_Circ circle(gp_Ax2(gp_Pnt(0,0,0),gp_Dir(1,0,0)),80);
Edge1 = BRepBuilderAPI_MakeEdge(circle,0,PI);

Edge2 = BRepBuilderAPI_MakeEdge(gp_Pnt(0,0,-80),gp_Pnt(0,-10,40));
Edge3 = BRepBuilderAPI_MakeEdge(gp_Pnt(0,-10,40),gp_Pnt(0,0,80));

TopoDS_Wire YellowWire;
BRepBuilderAPI_MakeWire MW1(Edge1,Edge2,Edge3);
if (MW1.IsDone()) {
YellowWire = MW1;
}

BrownFace = BRepBuilderAPI_MakeFace(YellowWire);


/////////////

P1.SetCoord(35,-200,40);
P2.SetCoord(50,-204,30);
P3.SetCoord(65,-200,30);
P4.SetCoord(35,-20,45);
P5.SetCoord(45,-20,30);
P6.SetCoord(65,-20,65);
TColgp_Array2OfPnt array2(1,3,1,2);
array2.SetValue(1,1,P1);
array2.SetValue(2,1,P2);
array2.SetValue(3,1,P3);
array2.SetValue(1,2,P4);
array2.SetValue(2,2,P5);
array2.SetValue(3,2,P6);

Handle (Geom_BSplineSurface) BSplineSurf = GeomAPI_PointsToBSplineSurface(array2,3,8,GeomAbs_C2,0.001);

TopoDS_Face aFace = BRepBuilderAPI_MakeFace(BSplineSurf);

//2d lines
gp_Pnt2d P12d(0.9,0.1);
gp_Pnt2d P22d(0.2,0.7);
gp_Pnt2d P32d(0.02,0.1);

Handle (Geom2d_Line) line1 = new Geom2d_Line(P12d,gp_Dir2d((0.2-0.9),(0.7-0.1)));
Handle (Geom2d_Line) line2 = new Geom2d_Line(P22d,gp_Dir2d((0.02-0.2),(0.1-0.7)));
Handle (Geom2d_Line) line3 = new Geom2d_Line(P32d,gp_Dir2d((0.9-0.02),(0.1-0.1)));


//Edges are on the BSpline surface
Edge1 = BRepBuilderAPI_MakeEdge(line1,BSplineSurf,0,P12d.Distance(P22d));
Edge2 = BRepBuilderAPI_MakeEdge(line2,BSplineSurf,0,P22d.Distance(P32d));
Edge3 = BRepBuilderAPI_MakeEdge(line3,BSplineSurf,0,P32d.Distance(P12d));
Wire1 = BRepBuilderAPI_MakeWire(Edge1,Edge2,Edge3);
Wire1.Reverse();
PinkFace = BRepBuilderAPI_MakeFace(aFace,Wire1);
TopExp_Explorer ex;
TopoDS_Shape s;
for(ex.Init(PinkFace,TopAbs_EDGE);ex.More(); ex.Next())
{
s=ex.Current();
Edge4=TopoDS::Edge(s);
if(Edge4.IsEqual(Edge2))
Edge3=Edge3;

}
这是在mfc例2中的部分代码,for循环式我加的,问题是PinkFace 明明由edge1、2、3 生成,为什么explorer PinkFace 中的edge就找不到与edge2相同的边呢?仅能找到与edge1相同的边,这种不确定的结果让人无法捉摸。
另外博主有没有好办法,在不改occ库代码的情况下,给每个topods_shape一个全局唯一标识号或标识名称。我试用hashcode,但不知如何正确设置它的上限,似乎它有可能重复,不能当作唯一标识符。

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-10-28 18:16 by eryar
@佚名
inline Standard_Boolean TopoDS_Shape::IsEqual (const TopoDS_Shape& other) const
{
return (myTShape == other.myTShape) &&
(myLocation == other.myLocation) &&
(myOrient == other.myOrient);
}
函数IsEqual()的作用是:
Returns True if two shapes are partners, i.e. if they share the same TShape. Locations and Orientations may differ.
根据上面的代码可知只是判断是不是共享了相同的TShape,如果朝向Orientation不同,返回值也是不同的。看你前面将wire1.Reverse(),可能朝向会不同。
==================================
TopoDS_Shape的HashCode产生函数代码如下:
Standard_Integer TopoDS_Shape::HashCode(const Standard_Integer Upper) const
{
//PKV
const Standard_Integer aI = (Standard_Integer) ptrdiff_t(myTShape.operator->());
const Standard_Integer aHS = ::HashCode(aI,Upper);
const Standard_Integer aHL = myLocation.HashCode(Upper);
return (aHS^aHL)%Upper;
}
应该取个大一点的Upper。

也可参考Singleton模式,使用一个static的std::map<std::string, TopoDS_Shape>自己来根据名字映射TopoDS_Shape,这就像Draw Test Harness中一样了。

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-10-29 10:17 by 佚名
谢谢博主!
我试过了,即使不reverse,用issame也找不到与原来对应的边,我原以为顶点、边、面、体自底而上构建模型会逐级引用,这样便于建立共享边界的图元,现在看来这一规则不成立,也许它仅在一个shape内成立。
我现在使用的是static的std::map<std::int, TopoDS_Shape>的问题,似乎它也不能解决反向检索的问题,比如你可以指定绘制一个编号为1的shape,但反过来,你在绘图区感知到了一个shape,不能确定它的编号是1还是其它。以前采用给topods_shape增加公共成员变量的方法来识别。后来为了避免修改occ库保持原库的完整性放弃了。

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-10-29 10:26 by 佚名
补充一点,如果保存成Handle(TopoDS_Shape)采用正向检索也能解决问题,但该方法有局限性,效率太低,当图元上万甚至更多时及近瘫痪。

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-10-29 14:11 by eryar
@佚名
在绘图区感知到了一个shape,直接对其操作即可,为什么又要得到其ID?

如果一定要这个ID,可以通过SetOwner()将ID设置到AIS_InteractiveObject中去,这样在感知到shape时可以取出ID了。

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-11-10 09:59 by 佚名
id是CAE建模的需要,这点和CAD不同,比如有几千个点,要在某两点之间连线,用id指定点,再如选择其中的几百个点连成spline,没有编号操作难度大。谢谢您提的建议,我研究研究setowner。

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-11-10 22:47 by eryar
@佚名
哦。

那可以看看
SetOwner (const Handle< Standard_Transient > &ApplicativeEntity);
//Allows you to attribute the owner ApplicativeEntity to
//an Interactive Object. This can be a shape for a set of
//sub-shapes or a sub-shape for sub-shapes which it
//is composed of. The owner takes the form of a transient.

SetOwner把一个指针数据放到AIS_InteractiveObject中去了,所以你也可以将ID放进去。

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-11-13 17:02 by 佚名
“SetOwner把一个指针数据放到AIS_InteractiveObject中去了,所以你也可以将ID放进去“。
本人水平有限,真没看出看来怎么放一个ID(int数)到AIS_InteractiveObject中,博主能否以示例代码告知,比如我想给Handle(AIS_Shape) Point 赋一个ID号为整数3,该怎么做?谢谢!

# re: OpenCascade BRep 格式描述之二  回复  更多评论   

2014-11-15 18:01 by eryar
@佚名
SetOwner可以将一块内存设置到AIS_Shape中去,
所以你可以将ID或其他数据组织成一个结构体或类,需要时取出转换一下即可。

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理