OpenCascade笔记:使用TopOpeBRep_ShapeIntersector,进行碰撞检查

使用简介

传入两个TopoDS_Shape,执行碰撞,然后遍历取出结果

使用步骤

  • 使用TopoDS_Compound构造复杂的TopoDS_Shape S1,也可采用从文件读取或其他方式。
  • 使用TopoDS_Compound构造复杂的TopoDS_Shape S2,也可采用从文件读取或其他方式。
  • TopOpeBRep_ShapeIntersector传入S1,S2,执行碰撞检查
  • 遍历取出碰撞检查结果(注:遍历的结果要去重)

代码示例

void TestCollision::Test()
{
	if (!m_pRootGroup) 
	{
		return;
	}

	//1、构造S1
	TopoDS_Compound aS1;
	BRep_Builder aBuilder1;
	aBuilder1.MakeCompound(aS1);
	aBuilder1.Add(aS1, BRepPrimAPI_MakeBox(gp_Pnt(0, 0, 0), 6, 6, 6).Shape());
	aBuilder1.Add(aS1, BRepBuilderAPI_MakeEdge(gp_Pnt(18, 18, 0), gp_Pnt(18, 15, 30)).Shape());
	
	//2、构造S2
	TopoDS_Compound aS2;
	BRep_Builder aBuilder2;
	aBuilder2.MakeCompound(aS2);
	aBuilder2.Add(aS2, BRepPrimAPI_MakeBox(gp_Pnt(5, 5, 5), 10, 10, 10).Shape());
	aBuilder2.Add(aS2, BRepPrimAPI_MakeBox(gp_Pnt(13, 13, 13), 10, 10, 10).Shape());
	
	//3、执行碰撞检查
	TopOpeBRep_ShapeIntersector aShapeInter;
	//设置误差没起作用,暂时不会用
//	TopOpeBRep_FaceEdgeIntersector& aFaceEdgeInter = aShapeInter.ChangeFaceEdgeIntersector();
//	aFaceEdgeInter.ForceTolerance(2.1);//设置误差2.1
	aShapeInter.InitIntersection(aS1, aS2);

	//4、取出碰撞检查结果	
	std::set<Standard_Integer> mUniquiSet;//用于排除遍历碰撞结果中相同的图形
	std::vector<TopoDS_Shape> mInterResultArray;//保存结果
	for (; aShapeInter.MoreIntersection(); aShapeInter.NextIntersection())
	{
		//1:S1中相交的图形,2:S2中相交的图形
		TopoDS_Shape aResultShape = aShapeInter.CurrentGeomShape(2);
		
		//去重
		Standard_Integer nHashCode = aResultShape.HashCode(INT_MAX);
		if (mUniquiSet.count(nHashCode) > 0)
		{
			continue;
		}
		mUniquiSet.insert(nHashCode);

		//保存结果
		mInterResultArray.push_back(aResultShape);
	}


	//5、使用osg显示
	//
	//S1的osg节点
	osg::ref_ptr<osg::Group> pS1GroupNode = new osg::Group;
	osg::ref_ptr<osg::Material> pMaterial1 = new osg::Material;
	pMaterial1->setAmbient(osg::Material::Face::FRONT_AND_BACK, osg::Vec4(1.0, 1.0, 0.0, 1.0));
	pMaterial1->setDiffuse(osg::Material::Face::FRONT_AND_BACK, osg::Vec4(1.0, 1.0, 0.0, 1.0));
	pS1GroupNode->getOrCreateStateSet()->setAttributeAndModes(pMaterial1, osg::StateAttribute::ON);
	m_pRootGroup->addChild(pS1GroupNode);
	pS1GroupNode->addChild(TPShapeToOsgNode::Instance().ToNodeFillMode(aS1));
	//S2的osg节点
	osg::ref_ptr<osg::Group> pS2GroupNode = new osg::Group;
	osg::ref_ptr<osg::Material> pMaterial2 = new osg::Material;
	pMaterial2->setAmbient(osg::Material::Face::FRONT_AND_BACK, osg::Vec4(0.5, 0.5, 0.0, 1.0));
	pMaterial2->setDiffuse(osg::Material::Face::FRONT_AND_BACK, osg::Vec4(0.5, 0.5, 0.0, 1.0));
	pS2GroupNode->getOrCreateStateSet()->setAttributeAndModes(pMaterial2, osg::StateAttribute::ON);
	m_pRootGroup->addChild(pS2GroupNode);
	pS2GroupNode->addChild(TPShapeToOsgNode::Instance().ToNodeFillMode(aS2));
	//碰撞检查结果的osg节点
	osg::ref_ptr<osg::Group> pInterResultNode = new osg::Group;
	osg::ref_ptr<osg::Material> pTempColor = new osg::Material;
	pTempColor->setAmbient(osg::Material::Face::FRONT_AND_BACK, osg::Vec4(1.0, 0.0, 0.0, 1.0));
	pTempColor->setDiffuse(osg::Material::Face::FRONT_AND_BACK, osg::Vec4(1.0, 0.0, 0.0, 1.0));
	pInterResultNode->getOrCreateStateSet()->setAttributeAndModes(pTempColor, osg::StateAttribute::ON);
	m_pRootGroup->addChild(pInterResultNode);
	for (auto it = mInterResultArray.begin(); it != mInterResultArray.end(); ++it)
	{
		auto pNodeTemp = TPShapeToOsgNode::Instance().ToNodeLineMode(*it);
		pInterResultNode->addChild(pNodeTemp);
	}
}

运行结果

采用osg来显示occ图形
在这里插入图片描述

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值