(04)VTK移动模型,判断是否相交

前言

在模型相交检测时(碰撞检测),使用了重写vtkInteractorStyleTrackballActor函数的自己构建的交互器,实现检测鼠标按键,并显示不同颜色在不同相交情况时。

方法

重写 vtkInteractorStyleTrackballActor

// Define interaction style
class MouseInteractorStyle6 : public vtkInteractorStyleTrackballActor
{
public:
	static MouseInteractorStyle6* New();
	vtkTypeMacro(MouseInteractorStyle6, vtkInteractorStyleTrackballActor);

	virtual void OnLeftButtonDown()
	{
		std::cout << "Pressed left mouse button." << std::endl;
		// Forward events
		vtkInteractorStyleTrackballActor::OnLeftButtonDown();
	}

	virtual void OnMiddleButtonUp()
	{

		int x = this->Interactor->GetEventPosition()[0];
		int y = this->Interactor->GetEventPosition()[1];
		this->FindPokedRenderer(x, y);
		this->FindPickedActor(x, y);

		if (this->CurrentRenderer == NULL || this->InteractionProp == NULL)
		{
			std::cout << "Nothing selected." << std::endl;
			return;
		}

		vtkSmartPointer<vtkPropCollection> actors =	vtkSmartPointer<vtkPropCollection>::New();

		this->InteractionProp->GetActors(actors);
		actors->InitTraversal();
		vtkActor* actor = vtkActor::SafeDownCast(actors->GetNextProp());

		vtkPolyData* polydata = vtkPolyData::SafeDownCast(actor->GetMapper()->GetInputAsDataSet());

		vtkSmartPointer<vtkTransform> transform =	vtkSmartPointer<vtkTransform>::New();
		transform->SetMatrix(actor->GetMatrix());

		vtkSmartPointer<vtkTransformPolyDataFilter> transformPolyData =	vtkSmartPointer<vtkTransformPolyDataFilter>::New();

		transformPolyData->SetInputData(polydata);
		transformPolyData->SetTransform(transform);
		transformPolyData->Update();

		vtkSmartPointer<vtkSelectEnclosedPoints> selectEnclosedPoints =	vtkSmartPointer<vtkSelectEnclosedPoints>::New();
		selectEnclosedPoints->SetInputConnection(transformPolyData->GetOutputPort());
		selectEnclosedPoints->SetSurfaceData(this->Sphere);
		selectEnclosedPoints->Update();

		vtkDataArray* insideArray = vtkDataArray::SafeDownCast(selectEnclosedPoints->GetOutput()->GetPointData()->GetArray("SelectedPoints"));

		bool inside = false;
		for (vtkIdType i = 0; i < insideArray->GetNumberOfTuples(); i++)
		{
			if (insideArray->GetComponent(i, 0) == 1)
			{
				inside = true;
				break;
			}
		}

		if (inside)
		{
			this->CubeActor->GetProperty()->SetColor(1, 0, 0);
		}
		else
		{
			this->CubeActor->GetProperty()->SetColor(0, 1, 0);

		}

		this->StopState();

	}

	vtkPolyData* Sphere;
	vtkActor* CubeActor;
};
vtkStandardNewMacro(MouseInteractorStyle6); 

加载两个模型(一个是球,另一个是通过构造多边形并进行拉伸形成立方体的一个立方体模型)

	{
		// Sphere
		vtkSmartPointer<vtkSphereSource> sphereSource =	vtkSmartPointer<vtkSphereSource>::New();
		sphereSource->SetRadius(2000);
		sphereSource->Update();

		vtkSmartPointer<vtkPolyDataMapper> sphereMapper = vtkSmartPointer<vtkPolyDataMapper>::New();
		sphereMapper->SetInputConnection(sphereSource->GetOutputPort());

		vtkSmartPointer<vtkActor> sphereActor =	vtkSmartPointer<vtkActor>::New();
		sphereActor->SetMapper(sphereMapper); 

		// Visualize
		vtkSmartPointer<vtkRenderer> renderer =	vtkSmartPointer<vtkRenderer>::New();
		vtkSmartPointer<vtkRenderWindow> renderWindow =	vtkSmartPointer<vtkRenderWindow>::New();
		renderWindow->AddRenderer(renderer);

		vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =	vtkSmartPointer<vtkRenderWindowInteractor>::New();
		renderWindowInteractor->SetRenderWindow(renderWindow);

		renderer->AddActor(sphereActor);
		vtkSmartPointer<vtkLinearExtrusionFilter> m_extrude_chuang = vtkSmartPointer<vtkLinearExtrusionFilter>::New();
		{
			//{
			const int num_points = 4;
			vtkSmartPointer<vtkUnstructuredGrid> polygonGrid = vtkSmartPointer<vtkUnstructuredGrid>::New();
			vtkSmartPointer<vtkPoints> polygonPoints = vtkSmartPointer<vtkPoints>::New();
			vtkSmartPointer<vtkPolygon> polygon = vtkSmartPointer<vtkPolygon>::New();
			vtkSmartPointer<vtkDataSetMapper> polygonMapper = vtkSmartPointer<vtkDataSetMapper>::New();
			vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
			double chuangkuan_danbian = 800;//图纸显示为935mm
			double top_left[num_points][3] = {
				{ 100, -1 * chuangkuan_danbian, 0 },
				{ 2360, -1 * chuangkuan_danbian, 0 },
				{ 2360, chuangkuan_danbian, 0 },
				{ 100, chuangkuan_danbian, 0 },
			};
			double ChangHight = 851;
			// 几何数据 + 拓扑数据
			polygonPoints->SetNumberOfPoints(num_points);
			polygon->GetPointIds()->SetNumberOfIds(num_points);
			for (int i = 0; i < num_points; ++i){
				polygonPoints->SetPoint(i, top_left[i]);
				polygon->GetPointIds()->SetId(i, i);
			}

			polygonGrid->InsertNextCell(polygon->GetCellType(), polygon->GetPointIds());
			polygonGrid->SetPoints(polygonPoints);

			vtkNew<vtkDataSetSurfaceFilter> surface_filter;
			surface_filter->SetInputData(polygonGrid);
			surface_filter->Update();

			vtkNew<vtkTriangleFilter> filter;
			filter->SetInputData(surface_filter->GetOutput());
			filter->Update();

			// Apply linear extrusion(对平面进行拉伸成3D)
			m_extrude_chuang->SetInputConnection(filter->GetOutputPort());
			m_extrude_chuang->SetExtrusionTypeToNormalExtrusion();
			m_extrude_chuang->SetVector(0, 0, 1);// 沿文字方向挤压,沿着z向上
			m_extrude_chuang->SetScaleFactor(ChangHight);// 设置挤压比例 //blog.csdn.net/wanyongtai/article/details/106490653
			m_extrude_chuang->Update();
		} 

		vtkSmartPointer<vtkDataSetMapper> polygonMapper = vtkSmartPointer<vtkDataSetMapper>::New();
		polygonMapper->SetInputConnection(m_extrude_chuang->GetOutputPort());
		vtkSmartPointer<vtkActor> coneActor2 = vtkSmartPointer<vtkActor>::New();
		coneActor2->SetMapper(polygonMapper);

		renderer->AddActor(coneActor2);

		renderWindow->Render();

		vtkSmartPointer<MouseInteractorStyle6> style =
			vtkSmartPointer<MouseInteractorStyle6>::New();
		style->Sphere = sphereSource->GetOutput();
		style->CubeActor = coneActor2;
 
		coneActor2->GetProperty()->SetColor(0, 1, 0);
		renderWindowInteractor->SetInteractorStyle(style);
		renderWindowInteractor->Start();
 }

结果

 

  • 2
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 6
    评论
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

rexinx

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值