OpenCasCade学习笔记(三):加载显示STEP格式图片,并实现平移、缩放和旋转操作

OpenCasCade学习笔记(三):加载显示STEP格式图片,并实现平移、缩放和旋转操作

C3DWidget.h

#pragma once

#include <QtWidgets/QApplication>
#include <QtWidgets/QWidget>
#include "qevent.h"
#include "stable.h"

#define BUTTON_OFF	0
#define BUTTON_ON	1

class C3DWidget : public QWidget
{
	Q_OBJECT

public:
	C3DWidget(QWidget *parent = Q_NULLPTR);

protected:
	//!三维场景转换模式
	enum CurrentAction3d
	{
		CurAction3d_Nothing,
		CurAction3d_DynamicPanning, //平移
		CurAction3d_DynamicZooming, //缩放
		CurAction3d_DynamicRotation //旋转
	};

	//!覆写绘图事件
	void paintEvent(QPaintEvent *);
	//!覆写窗口尺寸变化事件
	void resizeEvent(QResizeEvent *);
	//!返回窗口的绘制引擎
	QPaintEngine *paintEngine() const;
	//!覆写键盘按键按下事件
	//void keyPressEvent(QKeyEvent *event);
	//!覆写键盘按键释放事件
	//void keyReleaseEvent(QKeyEvent *event);
	//!覆写鼠标按键按下事件
	void mousePressEvent(QMouseEvent *event);
	//!覆写鼠标按键释放事件
	void mouseReleaseEvent(QMouseEvent *event);
	//!覆写鼠标移动事件
	void mouseMoveEvent(QMouseEvent *event);
	//!覆写鼠标滚轮事件
	void wheelEvent(QWheelEvent *event);

	//加载step模型
	void loadSTEP();
	//显示STEP模型
	void displaySTEP();
	
	//把屏幕坐标转换为窗口坐标
	gp_Pnt ConvertClickToPoint(Standard_Real theX, Standard_Real theY, Handle(V3d_View) theView);
	void DrawLineByMouse(gp_Pnt thePntStart, gp_Pnt thePntEnd);

private:
	//!交互式上下文能够管理一个或多个查看器(viewer)中的图形行为和交互式对象的选择
	Handle(AIS_InteractiveContext) m_context;
	//!定义查看器(viewer)类型对象上的服务
	Handle(V3d_Viewer) m_viewer;
	//!创建一个视图
	Handle(V3d_View) m_view;
	//!创建3d接口定义图形驱动程序
	Handle(Graphic3d_GraphicDriver) m_graphic_driver;
	//存储STEP模型形状
	TopoDS_Shape m_Shape;
	Handle_AIS_Shape myAISShape;
	//线的模型
	Handle_AIS_Shape myLine;

	Standard_Integer m_x_max;    //!记录鼠标平移坐标X
	Standard_Integer m_y_max;    //!记录鼠标平移坐标Y
	CurrentAction3d m_current_mode; //!三维场景转换模式(平移\缩放\旋转)

	bool leftMouseBtn = BUTTON_OFF; //记录鼠标左键状态
	gp_Pnt m_line_start_point;      //记录鼠标画线开始点
	//gp_Pnt m_line_end_point;      //记录鼠标画线结束点
//	bool draw_line = false;
};

C3DWidget.cpp

#include "C3DWidget.h"
#include "ProjLib.hxx"
#include "ELSLib.hxx"
#include "GC_MakeSegment.hxx"
#include "BRepBuilderAPI_MakeEdge.hxx"
#include <gl\GLU.h>
#include <GeomAPI_IntCS.hxx>
#include "qdebug.h"


C3DWidget::C3DWidget(QWidget *parent)
	: QWidget(parent)
{
	//若交互式上下文为空,则创建对象
	if (m_context.IsNull())
	{
		//此对象提供与X server的连接,在Windows和Mac OS中不起作用
		Handle(Aspect_DisplayConnection) m_display_donnection = new Aspect_DisplayConnection();
		//创建OpenGl图形驱动
		if (m_graphic_driver.IsNull())
		{
			m_graphic_driver = new OpenGl_GraphicDriver(m_display_donnection);
		}
		//获取QWidget的窗口系统标识符
		WId window_handle = (WId)winId();
		//创建Windows NT 窗口
		Handle(WNT_Window) wind = new WNT_Window((Aspect_Handle)window_handle);
		//创建3D查看器
		m_viewer = new V3d_Viewer(m_graphic_driver, Standard_ExtString("viewer3d"));
		//创建视图
		m_view = m_viewer->CreateView();
		m_view->SetWindow(wind);
		//打开窗口
		if (!wind->IsMapped())
		{
			wind->Map();
		}
		m_context = new AIS_InteractiveContext(m_viewer);  //创建交互式上下文
		//配置查看器的光照
		m_viewer->SetDefaultLights();
		m_viewer->SetLightOn();
		//设置视图的背景颜色为灰色
		m_view->SetBackgroundColor(Quantity_NOC_GRAY60);
		m_view->MustBeResized();
		//显示直角坐标系,可以配置在窗口显示位置、文字颜色、大小、样式
		m_view->TriedronDisplay(Aspect_TOTP_LEFT_LOWER, Quantity_NOC_GOLD, 0.08, V3d_ZBUFFER);
		//设置显示模式
		m_context->SetDisplayMode(AIS_Shaded, Standard_True);

		loadSTEP();
		displaySTEP();
	}
	//配置QWidget
	setAttribute(Qt::WA_PaintOnScreen);
	setAttribute(Qt::WA_NoSystemBackground);
	setBackgroundRole(QPalette::NoRole);  //无背景
	setFocusPolicy(Qt::StrongFocus);
	setAttribute(Qt::WA_PaintOnScreen);
	setAttribute(Qt::WA_NoSystemBackground);
	setMouseTracking(true);   //开启鼠标位置追踪
}

void C3DWidget::paintEvent(QPaintEvent *)
{
	//if(draw_line == false)
		m_view->Redraw();
}

void C3DWidget::resizeEvent(QResizeEvent *)
{
	if (!m_view.IsNull())
	{
		m_view->MustBeResized();
	}
}

QPaintEngine *C3DWidget::paintEngine() const
{
	return 0;
}

void C3DWidget::loadSTEP()
{
	/*将STEP文件转换为OCCT形状:
		加载文件,
		检查文件一致性,
		设置翻译参数,
		执行翻译,
		获取结果。*/

		//load the file
	STEPControl_Reader reader;
	IFSelect_ReturnStatus stat = reader.ReadFile("sample.STEP");
	switch (stat)
	{
	case IFSelect_RetVoid:
		std::cout << "normal execution which created nothing, or no data to process!" << std::endl;
		break;
	case IFSelect_RetDone:
		break;
	case IFSelect_RetError:
		std::cout << "error in command or input data, no execution!" << std::endl;
		break;
	case IFSelect_RetFail:
		std::cout << "execution was run and has failed!" << std::endl;
		break;
	case IFSelect_RetStop:
		std::cout << "indicates end or stop (such as Raise)!" << std::endl;
		break;
	default:
		break;
	}
	if (stat != IFSelect_RetDone)
		return;

	//Selecting STEP entities for translation : The whole file
	//加载文件
	Standard_Integer NbRoots = reader.NbRootsForTransfer();
	Standard_Integer num = reader.TransferRoots();

	//Mapping STEP entities to Open CASCADE Technology shapes
	m_Shape = reader.OneShape();
}

void C3DWidget::displaySTEP()
{
	//display STEP 
	myAISShape = new AIS_Shape(m_Shape);
	myAISShape->SetDisplayMode(AIS_Shaded);
	m_context->Display(myAISShape, true);
}

void C3DWidget::mousePressEvent(QMouseEvent *event)
{
	if (((event->buttons() & Qt::MidButton) && (QApplication::keyboardModifiers() == Qt::CTRL)))//平移
	{
		m_current_mode = CurAction3d_DynamicPanning;
		m_x_max = event->pos().x(); //记录起始X位置
		m_y_max = event->pos().y(); //记录起始Y位置
	}
	else if (event->buttons() & Qt::MidButton)  //旋转
	{
		m_current_mode = CurAction3d_DynamicRotation;
		m_view->StartRotation(event->pos().x(), event->pos().y());
	}

	if (event->buttons() & Qt::LeftButton)
	{
		leftMouseBtn = BUTTON_ON;
		//m_line_start_point = ConvertClickToPoint(event->pos().x(), event->pos().x(), m_view);
	}
}

void C3DWidget::mouseReleaseEvent(QMouseEvent *event)
{
	GLdouble res[3];
	GLdouble mm[16], pm[16]; GLint vp[4];
	GLfloat   pix;
	m_current_mode = CurAction3d_Nothing;

	if (leftMouseBtn == BUTTON_ON)
	{
		leftMouseBtn = BUTTON_OFF;

		//GLdouble x = event->pos().x();
		//GLdouble y = event->pos().y();

		//GLint viewport[4];
		//GLdouble modleview[16];
		//GLdouble projection[16];

		获取必要的矩阵
		//glPushMatrix();
		//glLoadIdentity();
		//glLoadMatrixd(m_view->Camera()->OrientationMatrix());
		//glGetIntegerv(GL_VIEWPORT, viewport);//获取视口
		//glGetDoublev(GL_MODELVIEW_MATRIX, modleview);//获取模型视图矩阵
		//glGetDoublev(GL_PROJECTION_MATRIX, projection);//获取投影矩阵
		//glPopMatrix();

		将屏幕坐标转换为窗口坐标
		//GLdouble winX = x;
		//GLdouble winY = viewport[3] - y;
		//GLdouble winZ1 = 0;
		//GLdouble winZ2 = 10;
		//double x1, y1, z1, x2, y2, z2;

		坐标变换
		//gluUnProject(winX, winY, winZ1, modleview, projection, viewport, &x1, &y1, &z1);
		//gluUnProject(winX, winY, winZ2, modleview, projection, viewport, &x2, &y2, &z2);
		//
		生成直线
		//Handle(Geom_Line) aLine = new Geom_Line(gp_Pnt(x1, y1, z1), gp_Dir(x2 - x1, y2 - y1, z2 - z1));
		//GeomAPI_IntCS intCS(aLine, aSurface);
		//gp_Pnt aPnt = intCS.Point(1);
		//qDebug() << aPnt.X() << aPnt.Y() << aPnt.Z();

		//====================方案二=====================
		获取模型视图矩阵
		//glGetDoublev(GL_MODELVIEW_MATRIX, mm);
		获取投影矩阵
		//glGetDoublev(GL_PROJECTION_MATRIX, pm);
		获取视口
		//glGetIntegerv(GL_VIEWPORT, vp);

		读取缓冲区的深度分量
		//glReadPixels(event->pos().x(), event->pos().y(), 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &pix);
		//GLfloat depthrange[2] = { 0,0 };
		//glGetFloatv(GL_DEPTH_RANGE, depthrange);
		//if (pix == depthrange[1])
		//	qDebug() << "false";
		反投影
		//gluUnProject(event->pos().x(), event->pos().y(), pix, mm, pm, vp, &res[0], &res[1], &res[2]);
		qDebug() << res[0] << res[1] << res[2];
	}
}

void C3DWidget::mouseMoveEvent(QMouseEvent *event)
{
	switch (m_current_mode)
	{
	case CurAction3d_DynamicPanning:
		//执行平移
		m_view->Pan(event->pos().x() - m_x_max, m_y_max - event->pos().y());
		m_x_max = event->pos().x();
		m_y_max = event->pos().y();
		break;
	case CurAction3d_DynamicRotation:
		//执行旋转
		m_view->Rotation(event->pos().x(), event->pos().y());
		break;
	}

	//if (leftMouseBtn == BUTTON_ON)
	//{
	//	gp_Pnt m_line_end_point = ConvertClickToPoint(event->pos().x(), event->pos().x(), m_view);
	//	DrawLineByMouse(m_line_start_point, m_line_end_point);
	//}
}

void C3DWidget::wheelEvent(QWheelEvent *event)
{
	m_view->StartZoomAtPoint(event->pos().x(), event->pos().y());
	m_view->ZoomAtPoint(0, 0, event->angleDelta().y(), 0); //执行缩放
}

gp_Pnt C3DWidget::ConvertClickToPoint(Standard_Real theX, Standard_Real theY, Handle(V3d_View) theView)
{
	Standard_Real XEye, YEye, ZEye, XAt, YAt, ZAt;
	theView->Eye(XEye, YEye, ZEye);
	theView->At(XAt, YAt, ZAt);
	gp_Pnt EyePoint(XEye, YEye, ZEye);
	gp_Pnt AtPoint(XAt, YAt, ZAt);

	gp_Vec EyeVector(EyePoint, AtPoint);
	gp_Dir EyeDir(EyeVector);

	gp_Pln PlaneOfTheView = gp_Pln(AtPoint, EyeDir);
	Standard_Real X, Y, Z;
	theView->Convert(int(theX), int(theY), X, Y, Z);
	gp_Pnt ConvertedPoint(X, Y, Z);
	gp_Pnt2d ConvertedPointOnPlane = ProjLib::Project(PlaneOfTheView, ConvertedPoint);

	gp_Pnt ResultPoint = ElSLib::Value(ConvertedPointOnPlane.X(),ConvertedPointOnPlane.Y(),PlaneOfTheView);
	return ResultPoint;
}

void C3DWidget::DrawLineByMouse(gp_Pnt thePntStart, gp_Pnt thePntEnd)
{
	//检查传入参数
	if (thePntStart.IsEqual(thePntEnd, 1e-3))
		return;

	//构建拓扑线段
	Handle(Geom_TrimmedCurve) aSegment =
		GC_MakeSegment(thePntStart, thePntEnd);
	TopoDS_Edge aEdge = BRepBuilderAPI_MakeEdge(aSegment);

	//将构建的拓扑线段设置至AIS_Shape形状中
	myAISShape->SetShape(aEdge);

	//移除前面绘画的旧线段, 绘制新线段。
	m_context->Remove(myAISShape, true);
	m_context->Display(myAISShape, false);

	//更新View
	m_context->UpdateCurrentViewer();
}

stable.h

#pragma once

#include <AIS_InteractiveContext.hxx>
#include <AIS_InteractiveObject.hxx>
#include <AIS_ListOfInteractive.hxx>
#include <AIS_ListIteratorOfListOfInteractive.hxx>
#include <AIS_Shape.hxx>
#include <AIS_Trihedron.hxx>

#include <Aspect_Background.hxx>
#include <Aspect_TypeOfline.hxx>
#include <Aspect_WidthOfline.hxx>
#include <Aspect_Window.hxx>
#include <Bnd_Box2d.hxx>
#include <BndLib_Add2dCurve.hxx>
#include <BRep_Builder.hxx>
#include <BRep_Tool.hxx>

#include <BRepBuilderAPI.hxx> 
#include <BRepAlgo.hxx> 
#include <BRepTools.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <Standard_DefineHandle.hxx>
#include <DsgPrs_LengthPresentation.hxx>
#include <GCE2d_MakeSegment.hxx>
#include <GCPnts_TangentialDeflection.hxx>
#include <Geom_CartesianPoint.hxx>
#include <Geom_Axis2Placement.hxx>
#include <Geom_CartesianPoint.hxx>
#include <Geom_Line.hxx>
#include <Geom_Surface.hxx>
#include <Geom2d_BezierCurve.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom2d_Curve.hxx>
#include <Geom2d_TrimmedCurve.hxx>
#include <Geom2dAdaptor_Curve.hxx>
#include <GeomAbs_CurveType.hxx>
#include <GeomAdaptor_Curve.hxx>
#include <GeomTools_Curve2dSet.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Circ2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Lin2d.hxx>
#include <gp_Pnt2d.hxx>
#include <gp_Vec.hxx>
#include <gp_Vec2d.hxx>
#include <MMgt_TShared.hxx>
#include <OSD_Environment.hxx>
#include <Precision.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_IsoAspect.hxx>
#include <Prs3d_LineAspect.hxx>
#include <Prs3d_Text.hxx>
#include <Quantity_Factor.hxx>
#include <Quantity_Length.hxx>
#include <Quantity_NameOfColor.hxx>
#include <Quantity_PhysicalQuantity.hxx>
#include <Quantity_PlaneAngle.hxx>
#include <Quantity_TypeOfColor.hxx>
#include <SelectMgr_EntityOwner.hxx>
#include <SelectMgr_SelectableObject.hxx>
#include <SelectMgr_Selection.hxx>
#include <SelectMgr_SelectionManager.hxx>
#include <Standard_Boolean.hxx>
#include <Standard_CString.hxx>
#include <Standard_ErrorHandler.hxx>
#include <Standard_Integer.hxx>
#include <Standard_IStream.hxx>
#include <Standard_Macro.hxx>
#include <Standard_NotImplemented.hxx>
#include <Standard_OStream.hxx>
#include <Standard_Real.hxx>
#include <StdPrs_Curve.hxx>
#include <StdPrs_Point.hxx>
#include <StdPrs_PoleCurve.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColgp_HArray1OfPnt2d.hxx>
#include <TCollection_AsciiString.hxx>
#include <TColStd_HSequenceOfTransient.hxx>
#include <TColStd_MapIteratorOfMapOfTransient.hxx>
#include <TColStd_MapOfTransient.hxx>
#include <TopExp_Explorer.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_ListIteratorOfListOfShape.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Vertex.hxx>
#include <TopExp.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <TopTools_HSequenceOfShape.hxx>
#include <TopTools_DataMapOfShapeInteger.hxx>
#include <UnitsAPI.hxx>
#include <V3d_View.hxx>
#include <V3d_Viewer.hxx>
#include <WNT_Window.hxx>
#include <OpenGl_GraphicDriver.hxx>  

// specific STEP
#include <STEPControl_Controller.hxx>
#include <STEPControl_Reader.hxx>
#include <STEPControl_Writer.hxx>

main.cpp

#include "C3DWidget.h"

int main(int argc, char *argv[])
{
	QApplication a(argc, argv);
	C3DWidget w;
	w.show();
	return a.exec();
}

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值