#include "NativeRender.h" #ifndef NATIVE_TAG #define NATIVE_TAG "NativeRender" #endif namespace NativeOpenCAX { NativeRender::NativeRender() { } NativeRender::~NativeRender() { shapes_.clear(); } bool NativeRender::init(int width, int height,EGLCore* eglCore) { rendOption.eglCore=eglCore; rendOption.width=width; rendOption.height=height; if(!InitGraphicDriver(rendOption)){ HILOG_ERROR(NATIVE_TAG,"InitGraphicDriver Fail!"); return false; } if(!InitTextSyle(rendOption)){ HILOG_ERROR(NATIVE_TAG,"InitTextSyle Fail!"); return false; } if(!InitViewer(rendOption)){ HILOG_ERROR(NATIVE_TAG,"InitViewer Fail!"); return false; } if(!InitCtx(rendOption)){ HILOG_ERROR(NATIVE_TAG,"InitCtx Fail!"); return false; } if(!InitWorldAxis(rendOption)){ HILOG_ERROR(NATIVE_TAG,"InitWorldAxis Fail!"); return false; } if(!InitLocalAxis(rendOption)){ HILOG_ERROR(NATIVE_TAG,"InitLocalAxis Fail!"); return false; } if(!InitView(rendOption)){ HILOG_ERROR(NATIVE_TAG,"InitView Fail!"); return false; } if(!InitCamera(rendOption)){ HILOG_ERROR(NATIVE_TAG,"InitCamera Fail!"); return false; } return true; } bool NativeRender::loadModel(const std::string& filePath) { // 清除现有模型 for (auto& shape : shapes_) { rendOption.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()); return false; } // 将文件内容转换为OCCT形状 reader.TransferRoots(); int numShapes = reader.NbShapes(); if (numShapes <= 0) { printf("Error: No shapes found in STEP file\n"); return false; } // 加载所有形状 for (Standard_Integer 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(); 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); rendOption.context->Display(aisShape, Standard_True); shapes_.push_back(aisShape); } } // 调整相机到合适位置 rendOption.view->FitAll(0.5, Standard_True); rendOption.view->ZFitAll(); 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 x, float y) { axis.translationX = x; axis.translationY = y; } void NativeRender::render() { if (rendOption.view.IsNull()) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render","View Is Null"); return; } // 执行渲染 rendOption.view->Redraw(); } void NativeRender::resize(int width, int height) { rendOption.width = width; rendOption.height = height; if (!rendOption.view.IsNull()) { rendOption.view->MustBeResized(); } } void NativeRender::setRotation(float xAngle, float yAngle) { //axis.rotationX = xAngle; //axis.rotationY = yAngle; if (rendOption.view.IsNull()) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "addRotationDelta", "View Is Null"); return; } //Handle(Graphic3d_Camera) camera = rendOption.view->Camera(); // --- 方案一:直接对相机进行增量旋转 --- // 这种方式模拟了“轨道”行为,绕着相机看向的目标点旋转。 // 获取当前相机状态 gp_Pnt currentEye = rendOption.camera->Eye(); gp_Pnt currentCenter = rendOption.camera->Center(); gp_Dir currentUp = rendOption.camera->Up(); // 计算当前的视线方向和距离 gp_Vec viewDir = currentCenter.XYZ() - currentEye.XYZ(); double distance = viewDir.Magnitude(); gp_Pnt rotationCenter = currentCenter; // 旋转中心设为当前目标点 // 创建旋转增量 gp_Quaternion rotX, rotY; // 从 gp_Ax1 中提取方向向量 (gp_Dir -> gp_Vec) gp_Vec xRotationAxis = rendOption.camera->Direction().XYZ().Crossed(currentUp.XYZ()); // 叉积得到X旋转轴 if (xRotationAxis.Magnitude() > gp::Resolution()) { // 防止零向量导致的无效四元数 rotX.SetVectorAndAngle(xRotationAxis, xAngle * M_PI / 180.0); } else { rotX.SetIdent(); // 如果叉积为零,则无旋转 } // 从 gp_Ax1 中提取方向向量 (gp_Dir -> gp_Vec) gp_Vec yRotationAxis = currentUp.XYZ(); // Y旋转轴就是当前的Up方向 if (yRotationAxis.Magnitude() > gp::Resolution()) { rotY.SetVectorAndAngle(yRotationAxis, yAngle * M_PI / 180.0); } else { rotY.SetIdent(); // 如果Up向量无效,则无旋转 } // 组合旋转 gp_Quaternion totalRotation = rotY * rotX; // 应用旋转到眼睛位置 gp_Vec newViewDir = totalRotation * viewDir.Normalized(); gp_Pnt newEye = rotationCenter.XYZ() - newViewDir.XYZ() * distance; // 计算新的 Up 方向 gp_Dir newUp = totalRotation * currentUp; // 设置新相机参数 rendOption.camera->SetEye(newEye); rendOption.camera->SetCenter(rotationCenter); rendOption.camera->SetUp(newUp); HILOG_ERROR(NATIVE_TAG,"Rotation"); //rendOption.view->Redraw(); } void NativeRender::setZoomLevel(float zoom) { axis.zoomLevel = std::max(0.1f, std::min(zoom, 5.0f)); // 限制缩放范围 } void NativeRender::resetView() { axis.rotationX = 0.0f; axis.rotationY = 0.0f; axis.zoomLevel = 1.0f; if (!rendOption.view.IsNull()) { rendOption.view->SetProj(V3d_XposYnegZpos); rendOption.view->FitAll(0.05, Standard_False); } } void NativeRender::setClearColor(float r, float g, float b, float a) { rendOption.clearColor = Quantity_Color(r, g, b, Quantity_TOC_RGB); if (!rendOption.view.IsNull()) { rendOption.view->SetBackgroundColor(rendOption.clearColor); } } } // namespace NativeRenderer