You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

538 lines
14 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma once
#include <osgViewer/Viewer>
#include <osgViewer/ViewerEventHandlers>
#include <osgViewer/api/win32/GraphicsWindowWin32>
#include <osgDB/ReadFile>
#include <osgUtil/Optimizer>
#include <osgManipulator/TrackballDragger>
#include <osgManipulator/TranslateAxisDragger>
#include <osgManipulator/Translate2DDragger>
#include <osgGA/TrackballManipulator>
#include "../Assist/XJOSGCommon.h"
#include "../XJOSGObject/XJOSGObject.h"
#include "XJOSGView/XJOSGView.h"
#include "XJObjectManager/XJObjectManager.h"
#include "XJAlgorithm/XJPoint2D.h"
#include "XJUserEventHandler.h"
#include "XJTrackballManipulator.h"
#include "HUDCamera.h"
#include "XJV3D_Viewer.h"
#include "XJOSGObjManager.h"
#include "BaseOperator/ViewerSelector.h"
#include "BaseOperator/SelectionManager.h"
#include "BaseOperator/OBaseOperator.h"
#include "BaseOperator/XJMouseOperator.h"
#include "BaseOperator/OpPickZValue.h"
#include "BaseOperator/OpMarkupMouse.h"
#include <string>
#include <vector>
#include <map>
using namespace OSGView;
class PromptionHandler;
class BoxPicker;
static int osgCurManagerIndex;
class CXJOSGViewInternal : public CXJObserver
{
public:
//构造函数获取上一级窗口句柄
CXJOSGViewInternal();
virtual ~CXJOSGViewInternal();
enum {MAX_NOTE_LEN = 512};
void SetHWND(void* hWnd) {m_hWnd = (::HWND)hWnd;}
//更新帧操作
void Frame();
bool Done();
//申请重绘
void RequestRedraw();
//初始化OSG
void InitOSG(const std::string& bkgFile);
//释放OSG场景内存
int TerminateOSG();
//用于遍历UI交互事件
void RunEventHandle();
/*视图对象的创建与更新*/
int UpdateObjectView(CXJObject *obj, EOSGUpdateType updateType = UPDATE_ALL); //自动创建,并更新显示对象
//激化用户指定的事件操作器
void ActivateEventOperator(CXJMouseOperator* pEventOp);
void DeactiveEventOperator();
/***视图变换***/
void TopView();
void LeftView();
void RightView();
void BottonView();
void FrontView();
void BackView();
void ZoomAll();
void TopNoZoomView();
void SetProjViewWithoutZoom(Point3D dir, Point3D up);
void ZoomView(double px, double py, double scale);
void GetViewPos(Point2D& pt, double& scale);
//设置相机投影方式(正交投影,或者透视投影)
void StartOrthoProjection();
void StartPerspectProjection();
//get the selected list of the obj's omkey
const std::vector<int>& GetSelOmKeyList();
//return the number of selected obj
int NbSelected() const;
//return the CXJObject's omkey selected by index
int SelectedObjOmKey(int index);
//set current operator
void LocalSetOperator(OBaseOperator* op);
//is threr a operator handler;
bool HasOperatorHandler();
//there is no event handle in osgview
void OnNoSelectEvent();
void UnlightDynamicDetectedObject();
int DrawPolygonOnScreen(std::vector<std::vector<Point3D>>& polyList, Point3D curPosition);
//清空视图上的多边形
void ClearPolygonOnScreen();
//清空视图上的标记
void ClearMarkUp();
//Rotate camera by left mouse button
void OnCameraOrbit();
//pan camera by left mouse button
void OnCameraPan();
//use trackball manipulator
void OnCameraTrackball();
//allow trackball throw
void OnCameraContinuousOrbit();
//rotate with axisthe camera axis need update in real time
void OnCameraVerticalAxisOrbit();
//only hilight obj
void HilightObject(CXJOSGObject* sel);
//select and Hilight a osgobj
int SelectObject(CXJOSGObject* sel);
int PickedObject();
//get the intersection pt
int PickedPoint(osg::Vec3d& pnt, osg::Vec3d& normal);
int PickedDir(osg::Vec3d& dir);
//unselect and unHilight all obj from list
void DeSelectSelList();
//set selected obj's visibility in selList
void InvisibleSelList(bool visible);
//set selected obj's transparency in selList
void TransparentSelList(bool transparent);
//set selected obj's wireframe in selList
void WireframeSelList(bool wireframe);
void SetPolygonOffsets(CXJObject* pobj, float aFactor, float aUnits);
//设置操作器是否可用
void SetViewManipulatorEnable(bool enable);
/****拾取视图对象操作*****/
int PickObject(int x, int y, CXJOSGObject* &obj, bool reverseY = false);
//设置选择模式
void SetPickMode(int pickMode = 0);
/*******模型拖动操作器*******/
//粗模式下的拖放操作
void TrackBallDragger(CXJObject *obj);
void SetRotateDraggerStep(double step);
void TranslateAxisDragger(CXJObject *obj);
void TranslateDirDragger(std::vector<CXJObject*> objList, Point3D dir);
void TranslateDirAndRotateDragger(std::vector<CXJObject*> objList, Point3D dir);
void RotateDirDragger(CXJObject *obj,Point3D dir);
void SetTranslationDraggerStep(double step);
void Translate2DDragger(CXJObject *obj);
void TranslateLocalCordDragger(CXJObject* obj, const Point3D& localCorX,
const Point3D& localCorY, const Point3D& localCorZ);
void TrackBallLocalCordDragger(CXJObject* obj, const Point3D& localCorX,
const Point3D& localCorY, const Point3D& localCorZ);
//清空拖动器对象
void ClearDraggerObject();
//是否存在Dragger
bool IsExistDragger();
/**********模型视图变换和矩阵操作*************/
//平移指定显示对象给定x,y,z三个坐标
void TranslateObject(CXJObject *obj,float x,float y,float z);
//旋转指定显示对象,给定旋转点、旋转轴和旋转角度
void RotateObject(CXJObject* obj,Point3D basePt,Point3D rotateDir,float angle);
//变换指定显示对象,从初始向量变换到目标向量位置
//将法矢转化为旋转轴和角度
void ConvertDirToAngleAxis(const Point3D& dir, Point3D& rotAxis, double& angle);
bool MakeRotationByAxes(const Point3D& xdir, const Point3D& ydir, const Point3D& zdir,
Point3D& rotateAxis, double& angle, const char* priorityOrder = "ZXY");
//重设对象的试图位置
void ResetObjectViewPos(CXJObject* obj);
void TransformObjectOnce(CXJObject* obj, Point3D originPt, Point3D oriVec, Point3D destVec);
void GetObjectRotation(CXJObject *obj, float &x, float &y, float &z,float &ang);
void GetObjectTranslation(CXJObject *obj, float &x, float &y, float &z);
void TranslatePointW2NP(Point3D& pp, double& r);
void TranslatePointW2NFP(Point3D& p, Point3D& NPoint, Point3D& FPoint);
/***********创建临时显示对象*************/
//删除临时创建的多个偏移平面
void DeleteTempOffsetPlane();
//删除临时创建的多个阵列2D线
void DeleteTempPattern2D();
//临时显示高亮线段集
void ShowLineSet(const std::vector<Point3D>& pts);
void ClearLineSet();
//临时显示高亮点
void ShowSelPt(osg::Vec3 &pt);
void ClearSelPt();
//临时显示高亮点集
void ShowPointSet(const std::vector<Point3D>& pts);
void ClearPointSet();
/**下面的这种方式以后会被舍弃**/
//临时显示对象
int CreateTempObject(CXJObject* obj);
int DeleteTempObject();
//删除指定对象的临时显示对象
void DeleteTempObject(const CXJObject* pObj);
//获得指定视点的位置,相机朝向和向上方向
void GetCameraLookAt(Point3D &eye,Point3D &target,Point3D &up);
void SetCameraLookAt(Point3D a_normal,Point3D a_up);
void SetCameraLookAt(const Point3D& eye, const Point3D& target, const Point3D& up);
//设置纹理图片存储路径
void SetBackGroudBmpPath(const std::string bmpPath);
void SetBackGroudColor(int r, int g, int b, float a=1);
//设置分割后的模型显示在前端
void setModelShowInFront(CXJObject* pobj, bool isFront = true);
//获得平面与网格的交点集
int GetPlaneMeshIntersection(CXJObject* pobj, double plnDir[3], double plnPoint[3],
std::vector<std::vector<Point3D>>& pnts, int& PolygonNum );
//获得直线与显示对象的交点
int GetIntersectPt(CXJObject* pobj, const Point3D& start, Point3D& lineDir, Point3D& intersectPt);
//设置视图三个角上的Text displayPos为显示文字位置
//0---左上角显示, 1--右上角显示, 2--左下角显示
void setHUDText(wchar_t* str, HUDTextWinPos displayPos, AlignmentType alighment);
//设置HUDText的一系列属性
void setHUDTextProperties(float charactersize, osg::Vec4 textColor, std::string font);
//用于自定义图片来设置视图背景
bool setPictureOnBackGround(const std::string& picPath);
//设置默认背景图片
void setDefaultBackGround();
//在视图上进行二维绘图
//拾取二维图片上的点
int Pick2DPoint(int x, int y, osg::Vec2 &pnt2D, osg::Vec3 &pnt3D);
//将屏幕点转化为世界坐标系下的点
void ProjectWindowsToObject(int x, int y, osg::Vec3& pt);
//将空间点转化为屏幕上的坐标点
void ProjectObjectToWindow(const Point3D& pt, int& x, int& y );
//相机位置朝向平面正方向
void ZoomAndShowTopView_Sketch(osg::Vec3 axisZ, osg::Vec3 axisY);
void ZoomAndShowFrontView_Sketch(osg::Vec3 center, osg::Vec3 norml, osg::Vec3 up);
/***视图对象与内核对象的转换**/
CXJOSGObject* GetViewPointer(int osgKey);
CXJOSGObject* GetObjectView(const CXJObject * obj);
CXJOSGObject* GetObjectView(int omkey);
int GetViewObject(CXJOSGObject* obj) ;
int GetViewObject(int osgKey);
/**************在OSG视图上显示模型*****************************************/
//在屏幕上绘制多段线,不受相机操作器的旋转变化
int DrawPolylineOnWindow(std::vector<Point3D>& polyline);
int DrawPolylineOnMFCWindow(std::vector<Point3D>& polyline, int state = 0);
//清除屏幕上绘制的多段线
int ClearPolylineOnWindow();
//在屏幕上绘制圆,指定圆心位置和半径
int DrawCircleOnWindow(int x, int y, float circleRad = 50.0);
//清除屏幕上绘制的圆
int ClearCircleOnWindow();
//在场景中绘制多段线,受相机操作器的旋转变化
int DrawPolylineOnSceneGraph(std::vector<Point3D>& polyline);
int ClearPolylineOnSceneGraph();
//删除容器中所有的osg对象
void DeleteAllOSGObjects();
osgViewer::Viewer* getViewer() {return m_viewer;}
//渲染,注意这里是静态的,可启动为全局线程
static void Render(void* ptr);
ViewerSelector* GetViewerSelector() {return m_viewerSelector;}
CXJOSGObjManager* GetOSGObjManager() {return m_osgObjManager;}
//每帧绘制前处理
void PreFrameUpdate(void);
//每帧绘制后处理
void PostFrameUpdate(void);
//得到激活的操作器
const osgGA::GUIEventHandler* GetActiveOperator() const{ return m_ActiveEventHandler.get();}
//获取颜色带
HUDAnalysis* GetHUDAnalysis() const {return m_hudAnalysis;}
//绘制图片
void DrawImage(std::string path);
void TakeObjectPicture(const std::vector<CXJObject*>& objList, std::string path,
const osg::Vec3d& cen,
const osg::Vec3d& dir,
const osg::Vec3d& up,
double rad,
int w, int h);
void EnablePickZValue(CXJObject* pobj, bool bEnable = true);
void EnableOpDrawPolygon(bool bEnable);
void GetOpDrawPolygon(std::vector<Point2D>& polygen);
void EnableAntiAliasing(bool bEnable);
void ShowMouse(int px, int py);
void GetMousePos(int& px, int& py);
bool IsWindows7();
protected:
//根据指定路径的图片纹理来创建背景色
osg::ref_ptr<osg::Camera> CreateBackGround(std::string BmpPath);
//创建前序渲染或后序渲染的相机节点
osg::ref_ptr<osg::Camera> CreateHUDCamera(osg::Camera::RenderOrder renderOrder);
private:
//初始化操作器
void InitManipulators(void);
//初始化场景
void InitSceneGraph(const std::string& bkgFile);
//初始化2D场景图层
void Init2DSceeGraphLayer();
//初始化拖动器图层
void InitOsgDraggerLayer();
//初始化相机配置
void InitCameraConfig(void);
//初始化显示坐标系位置和方向
void InitCoordinateSystem(void);
//初始化处理事件响应函数
void InitEventHandlers(void);
//初始化HUD文字
void InitHUDText(void);
void UpdateProjectionMatrix();
//friend CXJOSGObjManager* GetOSGObjManager(); //友元函数
//friend ViewerSelector* GetViewerSelector(); //友元函数
private:
//窗口句柄
HWND m_hWnd;
//观察体viewer
XJV3D_Viewer* m_viewer;
//trackball操作器
osg::ref_ptr</*osgGA::TrackballManipulator*/CXJTrackballManipulator> m_trackball;
//加入KeySwitch选择操作器
osg::ref_ptr<CXJManipulator> m_keyswitchManipulator;
//存放OMKey和对应的视图对象
//std::map<int, CXJOSGObject* > m_mapOm3D;
//显示对象管理器
CXJOSGObjManager* m_osgObjManager; //静态成员函数需要在类外进行初始化
//视图拾取器
ViewerSelector* m_viewerSelector;
//选择对象管理器
osg::ref_ptr<SelectionManager> m_selectionManager;
//the current operator
osg::ref_ptr<osgGA::GUIEventHandler> m_ActiveEventHandler;
bool m_bHasOperator; //包含操作事件标志
//背景纹理的存储路径
std::string m_DebugPath;
osg::Vec4 m_bgColor;
//表示背景是纯色,默认是纯色
bool m_bIsBackgroundPureColor;
//键盘响应事件
osg::ref_ptr<PromptionHandler> m_KeyboardHandler;
//拖拽操作器
osg::ref_ptr<osgManipulator::TrackballDragger> m_trackballDragger;
osg::ref_ptr<osgManipulator::TranslateAxisDragger> m_translateAxisDragger;
osg::ref_ptr<osgManipulator::Translate2DDragger> m_translate2DDragger;
osg::ref_ptr<osg::Switch> m_trackballDraggerSwitch;
osg::ref_ptr<osg::Switch> m_translateAxisDraggerSwitch;
osg::ref_ptr<osg::Switch> m_translate2DDraggerSwitch;
/*******************场景操作**************************/
OpPickZValue* m_opPickZValue;
OpMarkupMouse* m_opMarkMouse;
private:
//场景根节点
osg::ref_ptr<osg::Group> m_root;
//坐标系节点
osg::ref_ptr<osg::Group> m_csysGroup;
//临时显示对象
osg::ref_ptr<osg::Group> m_tempObjectGroup;
//这个容器中存储对CT图像的操作
osg::ref_ptr<osg::Switch> m_CTImageGroup;
//场景中的3D节点组织
osg::ref_ptr<osg::Switch> m_3DGroup;
CXJPlane* m_2DPlane;
std::vector<CXJPlane*> m_ClipPlanes;
osg::ref_ptr<HUDText> m_hudText;
//颜色带
osg::ref_ptr<HUDAnalysis> m_hudAnalysis;
};
//场景更新回调
class XJSceneGraphUpdateCallBack : public osg::NodeCallback
{
public:
XJSceneGraphUpdateCallBack()
: m_update(false),
m_ViewInternal(NULL),
m_pobj(NULL),
m_updateType(UPDATE_ALL)
{
}
virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
{
if (m_update == false)
{
traverse(node,nv);
return;
}
if (NULL != m_ViewInternal && NULL != m_pobj)
{
m_update = false;
traverse(node,nv);
}
}
public:
void SetUpdateRun(bool update) {m_update = update;}
bool GetUpdateRun(){return m_update;}
void SetViewInternal(CXJOSGViewInternal* viewinternal) {m_ViewInternal = viewinternal;}
void UpdateObject(CXJObject* pobj,EOSGUpdateType updateType)
{
m_pobj = pobj;
m_updateType = updateType;
}
private:
bool m_update;
CXJOSGViewInternal* m_ViewInternal;
CXJObject* m_pobj;
EOSGUpdateType m_updateType;
};