因为之前一直使用OSG做显示,最近想试试OCC自带的显示效果怎么样,所以这篇文章做了一个简单的测试,添加一些小功能,说说感受。
我是直接在github上下载eryar老师的occqt例子进行修改的,配置的话比较简单,因为不熟悉AIS,所以也花了一些时间去了解怎么添加一些功能。话不多说,先来看下效果:
简单的实现了下基本的旋转、拖动、缩放、平移以及视图效果。 这个比较简单,就不贴具体的代码了,直接调用即可。这里就提提一下如何实现aisViewCube的位置摆放,这里需要修改SetTransformPersistence的第三个参数。比如如下代码实现aisviewcube在右上角:
aisViewCube->SetTransformPersistence(
new Graphic3d_TransformPers(
Graphic3d_TMF_TriedronPers,
toOccCorner(m_viewTrihedronCorner),
Graphic3d_Vec2i(85, 85)));
其中:Qt::Corner m_viewTrihedronCorner = Qt::TopRightCorner;//右上角
如果要在其他地方的话,可以参考如下:
Aspect_TypeOfTriedronPosition OccView::toOccCorner(Qt::Corner corner)
{
switch (corner) {
case Qt::TopLeftCorner: return Aspect_TOTP_LEFT_UPPER;
case Qt::TopRightCorner: return Aspect_TOTP_RIGHT_UPPER;
case Qt::BottomLeftCorner: return Aspect_TOTP_LEFT_LOWER;
case Qt::BottomRightCorner: return Aspect_TOTP_RIGHT_LOWER;
}
return Aspect_TOTP_LEFT_UPPER; // Fallback
}
渐变色背景实现一般就是这2句:
Quantity_Color blue = Quantity_Color(152 / 255.0, 152 / 255.0, 152 / 255.0, Quantity_TOC_RGB);
myView->SetBgGradientColors(blue, Quantity_NOC_WHITE, Aspect_GFM_VER);
意思也很好理解,这里就不多复述了。
后面简单测试了下碰撞检测,用的是求交方法,这个方法对于简单模型还是比较有效的,但是如果模型很大,那么求交就会很慢,所以对于大模型还是不推荐使用这个方法,求交也是OCC自带的功能,可以以2个shape作为参数写成一个函数,参考如下:
bool occQt::IsCommon(TopoDS_Shape shapeA, TopoDS_Shape shapeB)
{
if (shapeA.IsNull() || shapeB.IsNull())
{
qDebug() << "no model imported";
return false;
}
//没有实时性要求,采用bool求交的方法
Standard_Boolean bRunParallel;
Standard_Real aFuzzyValue;
BRepAlgoAPI_Common aBuilder;
// perpare the arguments
TopTools_ListOfShape aLS;
TopTools_ListOfShape aLT;
aLS.Append(shapeA); //xx m_TppoTargetBody
aLT.Append(shapeB); //yy m_TopoMoveBody
bRunParallel = Standard_True;
aFuzzyValue = 2.1e-5;
// set the arguments
aBuilder.SetArguments(aLS);
aBuilder.SetTools(aLT);
aBuilder.SetRunParallel(bRunParallel);
aBuilder.SetFuzzyValue(aFuzzyValue);
// run the algorithm
aBuilder.Build();
if (aBuilder.HasErrors())
{
std::ofstream fout;
fout.open("errormessage.txt", std::ios_base::app);
aBuilder.DumpErrors(fout);
fout.flush();
fout.close();
qDebug() << "error";
return false;
}
// result of the operation aR
const TopoDS_Shape& aR = aBuilder.Shape();
Bnd_Box B;
BRepBndLib::Add(aR, B);
double Xmin, Ymin, Zmin, Xmax, Ymax, Zmax;
if (!B.IsVoid())
{
B.Get(Xmin, Ymin, Zmin, Xmax, Ymax, Zmax);
}
int nb = aR.NbChildren();
if (!B.IsVoid()) //交集部分的最小包围box存在,则说明碰撞
{
std::cout << "common" << std::endl;
return true;
}
else
{
std::cout << "no common" << std::endl;
return false;
}
}
后记:对于OCC的AIS显示做了初步了解,AIS有些功能封装的很不错,但是有些功能还是不怎么方便,显示速度还是不错的。值得继续学习研究。。。。