#include "NativeRender.h" #include "Aspect_NeutralWindow.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include namespace NativeOpenCAX { NativeRender::NativeRender() : rotationX_(0.0f), rotationY_(0.0f), zoomLevel_(1.0f), width_(1280), height_(720), clearColor_(Quantity_NOC_BLACK), translationX_(0.0f), translationY_(0.0f) { } NativeRender::~NativeRender() { shapes_.clear(); } bool NativeRender::init(int width, int height,EGLCore* eglCore) { eglCore_=eglCore; initTextStyle(); initViewer(); initContext(); initView(); if (view_.IsNull()) { return false; } view_->SetBackgroundColor(clearColor_); view_->MustBeResized(); view_->RedrawImmediate(); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","NativeRender Init Done"); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","width: %{public}d",width_); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "NativeRenderInit","height: %{public}d",height_); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render", "GL Error before render: 0x%{public}x", glGetError()); return true; } void NativeRender::initViewer(){ displayPixelRatio(); Handle(Aspect_DisplayConnection) displayConnection=new Aspect_DisplayConnection(); // 创建图形驱动 if (graphicDriver_.IsNull()) { graphicDriver_ = new OpenGl_GraphicDriver(displayConnection,Standard_False); graphicDriver_->ChangeOptions().buffersNoSwap = Standard_True; graphicDriver_->InitEglContext(eglGetCurrentDisplay(), eglGetCurrentContext(), eglCore_->getConfig()); } // 创建V3d_Viewer viewer_ = new V3d_Viewer(graphicDriver_); viewer_->SetDefaultBackgroundColor (Quantity_NOC_BLACK); viewer_->SetDefaultLights(); viewer_->SetLightOn(); } float NativeRender::displayPixelRatio(){ float densityPixels; NativeDisplayManager_ErrorCode errCode = OH_NativeDisplayManager_GetDefaultDisplayVirtualPixelRatio(&densityPixels); if (errCode == NativeDisplayManager_ErrorCode::DISPLAY_MANAGER_OK) { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "DMSTest", "rotation=%{public}d", densityPixels); return densityPixels; } else { OH_LOG_Print(LOG_APP, LOG_INFO, LOG_PRINT_DOMAIN, "DMSTest", "GetDefaultDisplayRotation errCode=%{public}d", errCode); } } void NativeRender::initContext(){ context_ = new AIS_InteractiveContext(viewer_); context_->SetDisplayMode(AIS_Shaded, Standard_False); // 默认使用着色模式 context_->SetPixelTolerance (int(displayPixelRatio() * 6.0)); // increase tolerance and adjust to hi-dpi screens } void NativeRender::initView() { Handle(Aspect_NeutralWindow) m_Window = new Aspect_NeutralWindow(); m_Window->SetSize (width_, height_); view_ = viewer_->CreateView(); // 设置渲染参数 view_->SetImmediateUpdate (false); //view_->ChangeRenderingParams().ToShowStats = true; view_->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * displayPixelRatio() + 0.5); view_->ChangeRenderingParams().Method = Graphic3d_RM_RASTERIZATION; view_->ChangeRenderingParams().IsShadowEnabled = Standard_False; view_->ChangeRenderingParams().IsReflectionEnabled = Standard_False; view_->ChangeRenderingParams().IsAntialiasingEnabled = Standard_True; view_->ChangeRenderingParams().Resolution = 2; view_->ChangeRenderingParams().StatsTextAspect = text_->Aspect(); view_->ChangeRenderingParams().StatsTextHeight = (int )text_->Height(); // 设置背景渐变 view_->SetBgGradientColors( Quantity_Color(Quantity_NOC_GRAY), Quantity_Color(Quantity_NOC_BLACK), Aspect_GFM_VER, // 垂直渐变 Standard_False ); // 设置默认相机位置 view_->SetProj(V3d_XposYnegZpos); //可选:显示坐标轴 view_->ZBufferTriedronSetup(); // 设置相机参数 Handle(Graphic3d_Camera) camera = view_->Camera(); camera->SetFOVy(45.0); // 使用正确的FOV设置API camera->SetZRange(1.0, 1000.0); view_->SetWindow(m_Window,(Aspect_RenderingContext )eglGetCurrentContext()); } void NativeRender::initTextStyle(){ text_ = new Prs3d_TextAspect(); text_->SetFont (Font_NOF_ASCII_MONO); text_->SetHeight (12); text_->Aspect()->SetColor (Quantity_NOC_GRAY95); text_->Aspect()->SetColorSubTitle (Quantity_NOC_BLACK); text_->Aspect()->SetDisplayType (Aspect_TODT_SHADOW); text_->Aspect()->SetTextFontAspect (Font_FA_Bold); text_->Aspect()->SetTextZoomable (false); text_->SetHorizontalJustification (Graphic3d_HTA_LEFT); text_->SetVerticalJustification (Graphic3d_VTA_BOTTOM); } bool NativeRender::loadModel(const std::string& filePath) { // 清除现有模型 for (auto& shape : shapes_) { context_->Remove(shape, Standard_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()); loadDefaultModel(); return false; } // 将文件内容转换为OCCT形状 reader.TransferRoots(); int numShapes = reader.NbShapes(); if (numShapes <= 0) { printf("Error: No shapes found in STEP file\n"); loadDefaultModel(); return false; } // 加载所有形状 for (Standard_Integer i = 1; i <= numShapes; i++) { TopoDS_Shape shape = reader.Shape(i); if (!shape.IsNull()) { Handle(AIS_Shape) aisShape = new AIS_Shape(shape); // 设置材质 Handle(Prs3d_Drawer) drawer = aisShape->Attributes(); Handle(Prs3d_ShadingAspect) shadingAspect = new Prs3d_ShadingAspect(); // 随机颜色 int colorIndex = i % 7; Quantity_Color color; switch (colorIndex) { case 0: color = Quantity_NOC_RED; break; case 1: color = Quantity_NOC_GREEN; break; case 2: color = Quantity_NOC_BLUE1; break; case 3: color = Quantity_NOC_YELLOW; break; case 4: color = Quantity_NOC_MAGENTA1; break; case 5: color = Quantity_NOC_CYAN1; break; case 6: color = Quantity_NOC_ORANGE; break; default: color = Quantity_NOC_WHITE; } shadingAspect->SetColor(color); shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC); drawer->SetShadingAspect(shadingAspect); context_->Display(aisShape, Standard_True); shapes_.push_back(aisShape); } } // 调整相机到合适位置 view_->FitAll(0.05, Standard_True); view_->ZFitAll(); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "LoadModel","Successfully loaded STEP file with %{public}d shapes",numShapes); return true; } void NativeRender::loadDefaultModel() { // 创建一个默认的3D立方体 TopoDS_Shape box = BRepPrimAPI_MakeBox(10.0, 10.0, 10.0).Shape(); Handle(AIS_Shape) aisBox = new AIS_Shape(box); // 设置材质和颜色 Handle(Prs3d_Drawer) drawer = aisBox->Attributes(); Handle(Prs3d_ShadingAspect) shadingAspect = new Prs3d_ShadingAspect(); shadingAspect->SetColor(Quantity_NOC_RED); shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC); drawer->SetShadingAspect(shadingAspect); context_->Display(aisBox, Standard_True); shapes_.push_back(aisBox); // 创建一个球体 TopoDS_Shape sphere = BRepPrimAPI_MakeSphere(gp_Pnt(20.0, 0.0, 0.0), 5.0).Shape(); Handle(AIS_Shape) aisSphere = new AIS_Shape(sphere); shadingAspect = new Prs3d_ShadingAspect(); shadingAspect->SetColor(Quantity_NOC_BLUE1); shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC); aisSphere->Attributes()->SetShadingAspect(shadingAspect); context_->Display(aisSphere, Standard_True); shapes_.push_back(aisSphere); // 创建一个圆柱体 TopoDS_Shape cylinder = BRepPrimAPI_MakeCylinder(3.0, 15.0).Shape(); Handle(AIS_Shape) aisCylinder = new AIS_Shape(cylinder); shadingAspect = new Prs3d_ShadingAspect(); shadingAspect->SetColor(Quantity_NOC_GREEN); shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC); aisCylinder->Attributes()->SetShadingAspect(shadingAspect); gp_Trsf transform; transform.SetTranslation(gp_Vec(-15.0, -15.0, 0.0)); aisCylinder->SetLocalTransformation(transform); context_->Display(aisCylinder, Standard_True); shapes_.push_back(aisCylinder); // 调整相机 view_->FitAll(0.05, Standard_True); view_->ZFitAll(); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "LoadDefaultModel","Loaded default model (cube, sphere, cylinder)"); } //setTranslation void NativeRender::setTranslation(float x, float y) { translationX_ = x; translationY_ = y; } void NativeRender::render() { if (view_.IsNull()) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render","View Is Null"); return; } //glClearColor(1, 0, 0, 1); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glViewport(0, 0, width_, height_); // 应用旋转 Handle(Graphic3d_Camera) camera = view_->Camera(); // 计算旋转 gp_Quaternion rotation; rotation.SetEulerAngles(gp_EulerSequence::gp_Extrinsic_XYZ, rotationX_ * M_PI / 180.0, rotationY_ * M_PI / 180.0, 0.0); // 计算相机位置 gp_Dir camDir(0.0, 1.0, 0.0); gp_Vec camVec = rotation * gp_Vec(camDir); gp_Pnt camPos = gp_Pnt(0.0, 0.0, 0.0).Translated(camVec.Reversed() * 50.0 * zoomLevel_); // 设置相机参数 camera->SetEye(camPos); camera->SetCenter(gp_Pnt(translationX_, translationY_, 0.0)); camera->SetUp(gp_Dir(0.0, 0.0, 1.0)); // 执行渲染 view_->Redraw(); } void NativeRender::resize(int width, int height) { width_ = width; height_ = height; if (!view_.IsNull()) { view_->MustBeResized(); } } void NativeRender::setRotation(float xAngle, float yAngle) { rotationX_ = xAngle; rotationY_ = yAngle; } void NativeRender::setZoomLevel(float zoom) { zoomLevel_ = std::max(0.1f, std::min(zoom, 5.0f)); // 限制缩放范围 } void NativeRender::resetView() { rotationX_ = 0.0f; rotationY_ = 0.0f; zoomLevel_ = 1.0f; if (!view_.IsNull()) { view_->SetProj(V3d_XposYnegZpos); view_->FitAll(0.05, Standard_False); } } void NativeRender::setClearColor(float r, float g, float b, float a) { clearColor_ = Quantity_Color(r, g, b, Quantity_TOC_RGB); if (!view_.IsNull()) { view_->SetBackgroundColor(clearColor_); } } } // namespace NativeRenderer