#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), mAxis(new Axis), nAxis(new Axis), cr(new Camera), ctx(new Context), ogd(new OpenGlGraphicDriver), ts(new TextStyle), vw(new View), vr(new Viewer), win(new Window) { width = w; height = h; } NativeRender::~NativeRender() { shapes_.clear(); } bool NativeRender::init(EGLCore &_eglCore) { eglCore = _eglCore; if (!ogd->InitOpenGlGraphicDriver(eglCore)) { HILOG_ERROR(NATIVE_TAG, "Init GraphicDriver Fail!"); return false; } if (!ts->InitTextStyle()) { HILOG_ERROR(NATIVE_TAG, "Init TextSyle Fail!"); return false; } if (!vr->InitViewer(ogd->graphicDriver)) { HILOG_ERROR(NATIVE_TAG, "Init Viewer Fail!"); return false; } if (!ctx->InitContext(vr->viewer,ts->GetFontStyle(STYLE_AXIS))) { HILOG_ERROR(NATIVE_TAG, "Init Ctx Fail!"); return false; } if (!win->InitWindow(width, height)) { HILOG_ERROR(NATIVE_TAG, "Init Window Fail!"); return false; } if (!vw->InitView(vr->viewer)) { HILOG_ERROR(NATIVE_TAG, "Init View Fail!"); return false; } else { vw->SetViewOption(ts->GetFontStyle(STYLE_AXIS)); vw->SetText(ts->GetFontStyle(STYLE_AXIS)); vw->SetWin(win->window); } if (!cr->InitCamera(vw->view)) { HILOG_ERROR(NATIVE_TAG, "Init Camera Fail!"); return false; } if (!mAxis->InitAxis(ctx->context)) { HILOG_ERROR(NATIVE_TAG, "Init AXIS Fail!"); return false; } if (!mAxis->InitAxisCube(ctx->context,ts->GetFontStyle(STYLE_FACE))) { HILOG_ERROR(NATIVE_TAG, "Init AXIS Cuba Fail!"); return false; } vw->ResetView(); return true; } bool NativeRender::loadModel(const std::string &filePath) { // 清除现有模型 for (auto &shape : shapes_) { ctx->context->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(); Handle(Prs3d_ShadingAspect) shadingAspect = new Prs3d_ShadingAspect(); // aisShape->SetDisplayMode(1); Handle(Prs3d_LineAspect) aLineAspect = new Prs3d_LineAspect(Quantity_NOC_BLACK, // 颜色,例如黑色 Aspect_TOL_DASH, // 线型 3.0 // 线宽 ); // 随机颜色 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->SetFaceBoundaryDraw(true); drawer->SetWireAspect(aLineAspect); drawer->SetShadingAspect(shadingAspect); ctx->context->Display(aisShape, true); // ctx->context->SetDisplayMode(AIS_WireFrame, Standard_False); shapes_.push_back(aisShape); } } vw->view->ZFitAll(); vw->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) { nAxis->SetTranslationX(tx); nAxis->SetTranslationY(ty); } void NativeRender::render() { if (vw->view.IsNull()) { OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render", "View Is Null"); return; } vw->MustBeResized(); vw->Redraw(); } void NativeRender::resize(int w, int h) { HILOG_ERROR(NATIVE_TAG, "InPut Size:%{public}d,%{public}d", w, h); win->Resize(w, h); } void NativeRender::setRotation(float xAngle, float yAngle) { cr->SetRotation(xAngle, yAngle); } void NativeRender::setZoomLevel(float zoom) { nAxis->SetZoomLevel(std::max(0.1f, std::min(zoom, 5.0f))); // 限制缩放范围 } void NativeRender::setClearColor(float r, float g, float b, float a) { vw->SetClearColor(r, g, b, a); } void NativeRender::resetView() { vw->ResetView(); } void NativeRender::SwitchView(std::string view) { vw->SwitchView(view); } } // namespace NativeOpenCAX