# 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放进去。