177 lines
5.7 KiB
C++
177 lines
5.7 KiB
C++
#include "NativeRender.h"
|
|
#include "Aspect_TypeOfLine.hxx"
|
|
#include "Font_FontAspect.hxx"
|
|
#include "STEPControl_Reader.hxx"
|
|
|
|
#ifndef NATIVE_TAG
|
|
#define NATIVE_TAG "NativeRender"
|
|
#endif
|
|
|
|
static std::mutex renderMutex;
|
|
namespace NativeOpenCAX {
|
|
|
|
NativeRender::NativeRender(int w, int h):
|
|
width(0),
|
|
height(0),
|
|
v3dTri(new V3dTri),
|
|
v3dTriCube(new V3dTriCube),
|
|
v3dcr(new V3dCa),
|
|
v3dctx(new V3dCtx),
|
|
v3dogd(new V3dOGD),
|
|
v3dview(new V3dView),
|
|
v3ddrawer(new V3dDrawer),
|
|
v3dviewer(new V3dViewer),
|
|
v3dwin(new V3dWin)
|
|
{
|
|
width = w;
|
|
height = h;
|
|
}
|
|
|
|
NativeRender::~NativeRender() { shapes_.clear(); }
|
|
|
|
bool NativeRender::init(EGLCore &_eglCore) {
|
|
eglCore = _eglCore;
|
|
//初始化OpenGL
|
|
if (!v3dogd->InitV3dOGD(eglCore)) {
|
|
HILOG_ERROR(NATIVE_TAG, "Init GraphicDriver Fail!");
|
|
return false;
|
|
}
|
|
//初始化视口管理
|
|
if (!v3dviewer->InitV3dViewer(v3dogd->graphicDriver)) {
|
|
HILOG_ERROR(NATIVE_TAG, "Init Viewer Fail!");
|
|
return false;
|
|
}
|
|
//初始化OCCT内部上下文
|
|
if (!v3dctx->InitV3dCtx(v3dviewer->viewer)) {
|
|
HILOG_ERROR(NATIVE_TAG, "Init Ctx Fail!");
|
|
return false;
|
|
}else{
|
|
//初始化OCCT上下文的Drawer(全局属性设置)
|
|
v3ddrawer->InitV3dAllAspect(v3dctx->ctx);
|
|
}
|
|
//初始化绑定Window
|
|
if (!v3dwin->InitV3dWin(width, height)) {
|
|
HILOG_ERROR(NATIVE_TAG, "Init Window Fail!");
|
|
return false;
|
|
}
|
|
//初始化视图
|
|
if (!v3dview->InitV3dView(v3dviewer->viewer,v3dwin->win)) {
|
|
HILOG_ERROR(NATIVE_TAG, "Init View Fail!");
|
|
return false;
|
|
} else {
|
|
v3dview->InitViewOption();
|
|
}
|
|
if (!v3dcr->InitV3dCa(v3dview->view)) {
|
|
HILOG_ERROR(NATIVE_TAG, "Init Camera Fail!");
|
|
return false;
|
|
}
|
|
//初始化世界坐标系
|
|
if (!v3dTri->InitV3dTri(v3dctx->ctx)) {
|
|
HILOG_ERROR(NATIVE_TAG, "Init AXIS Fail!");
|
|
return false;
|
|
}
|
|
//初始化正方体视角切换指示器
|
|
if (!v3dTriCube->InitV3dTriCube(v3dctx->ctx)) {
|
|
HILOG_ERROR(NATIVE_TAG, "Init AXIS Cuba Fail!");
|
|
return false;
|
|
}
|
|
//InitDevText();
|
|
v3dview->ResetView();
|
|
return true;
|
|
}
|
|
|
|
bool NativeRender::loadModel(const std::string &filePath) {
|
|
// 清除现有模型
|
|
for (auto &shape : shapes_) {
|
|
v3dctx->ctx->Remove(shape, false);
|
|
}
|
|
shapes_.clear();
|
|
|
|
// 加载STEP文件
|
|
STEPControl_Reader reader;
|
|
IFSelect_ReturnStatus status = reader.ReadFile(filePath.c_str());
|
|
if (status != IFSelect_RetDone) {
|
|
printf("Error: Failed to read STEP file: %s\n", filePath.c_str());
|
|
return false;
|
|
}
|
|
|
|
// 将文件内容转换为OCCT形状
|
|
reader.TransferRoots();
|
|
int numShapes = reader.NbShapes();
|
|
if (numShapes <= 0) {
|
|
printf("Error: No shapes found in STEP file\n");
|
|
return false;
|
|
}
|
|
|
|
// 加载所有形状
|
|
for (int i = 1; i <= numShapes; i++) {
|
|
TopoDS_Shape shape = reader.Shape(i);
|
|
Bnd_Box bbox;
|
|
BRepBndLib::Add(shape, bbox);
|
|
double xmin, ymin, zmin, xmax, ymax, zmax;
|
|
bbox.Get(xmin, ymin, zmin, xmax, ymax, zmax);
|
|
gp_Pnt center((xmin + xmax) / 2.0, (ymin + ymax) / 2.0, (zmin + zmax) / 2.0);
|
|
gp_Vec translation(-center.X(), -center.Y(), -center.Z());
|
|
gp_Trsf move;
|
|
move.SetTranslation(translation);
|
|
BRepBuilderAPI_Transform transformer(shape, move);
|
|
shape = transformer.Shape();
|
|
if (!shape.IsNull()) {
|
|
Handle(AIS_Shape) aisShape = new AIS_Shape(shape);
|
|
// 设置材质
|
|
Handle(Prs3d_Drawer) drawer = aisShape->Attributes();
|
|
drawer->SetFaceBoundaryDraw(true);
|
|
drawer->SetWireAspect(v3ddrawer->v3d_LineAspect);
|
|
drawer->SetShadingAspect(v3ddrawer->v3d_ShadingAspect);
|
|
v3dctx->ctx->Display(aisShape, true);
|
|
shapes_.push_back(aisShape);
|
|
}
|
|
}
|
|
v3dview->view->ZFitAll();
|
|
v3dview->ResetView();
|
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "LoadModel",
|
|
"Successfully loaded STEP file with %{public}d shapes", numShapes);
|
|
return true;
|
|
}
|
|
|
|
// setTranslation
|
|
void NativeRender::setTranslation(float tx, float ty) {
|
|
v3dTri->SetTranslationX(tx);
|
|
v3dTri->SetTranslationY(ty);
|
|
}
|
|
|
|
void NativeRender::render() {
|
|
if (v3dview->view.IsNull()) {
|
|
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render", "View Is Null");
|
|
return;
|
|
}
|
|
v3dview->MustBeResized();
|
|
v3dview->Redraw();
|
|
}
|
|
|
|
void NativeRender::resize(int w, int h) {
|
|
HILOG_ERROR(NATIVE_TAG, "InPut Size:%{public}d,%{public}d", w, h);
|
|
v3dwin->Resize(w, h);
|
|
}
|
|
|
|
void NativeRender::setRotation(float xAngle, float yAngle) { v3dcr->SetRotation(xAngle, yAngle); }
|
|
|
|
void NativeRender::setZoomLevel(float zoom) {
|
|
v3dTri->SetZoomLevel(std::max(0.1f, std::min(zoom, 5.0f))); // 限制缩放范围
|
|
}
|
|
void NativeRender::setClearColor(float r, float g, float b, float a) { v3dview->SetClearColor(r, g, b, a); }
|
|
void NativeRender::resetView() { v3dview->ResetView(); }
|
|
void NativeRender::SwitchView(std::string str) {
|
|
v3dview->SwitchView(str);
|
|
}
|
|
void NativeRender::InitDevText(){
|
|
Handle(AIS_TextLabel) aTextLabel = new AIS_TextLabel();
|
|
const char16_t chinese_array[] = u"新时代社会主义中国接班人";
|
|
aTextLabel->SetText(chinese_array);
|
|
gp_Pnt position(0-(width/3), 0-(height/3), 0.0); // 例如,在原点
|
|
aTextLabel->SetPosition(position);
|
|
v3dctx->ctx->Display(aTextLabel, Standard_True);
|
|
HILOG_ERROR(NATIVE_TAG, "aTextLabel字体名字:%{public}s", aTextLabel->FontName().ToCString());
|
|
HILOG_ERROR(NATIVE_TAG, "aTextLabel字体名字:%{public}s", aTextLabel->Attributes()->TextAspect()->Aspect()->Font().ToCString());
|
|
}
|
|
} // namespace NativeOpenCAX
|