# 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
@佚名
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-11-10 22:47 by
@佚名
哦。
那可以看看
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放进去。