#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)) { 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(); vw->SetText(ts->text); 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)) { 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) { fontDev(); vw->SwitchView(view); } // 字体测试 void NativeRender::fontDev() { //获取鸿蒙系统字体管理信息 // OH_Drawing_FontConfigInfoErrorCode fontConfigInfoErrorCode; // 用于接收错误代码 // OH_Drawing_FontConfigInfo *fontConfigInfo = OH_Drawing_GetSystemFontConfigInfo(&fontConfigInfoErrorCode); // if (fontConfigInfoErrorCode != SUCCESS_FONT_CONFIG_INFO) { // OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_DOMAIN, "PrintSysFontMetrics", "获取系统信息失败,错误代码为: %{public}d", // fontConfigInfoErrorCode); // } // // 获取系统字体配置信息示例 // if (fontConfigInfo != nullptr) { // // 获取字体文件路径数量,打印日志 // size_t fontDirCount = fontConfigInfo->fontDirSize; // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "PrintSysFontMetrics", "字体文件路径数量为: %{public}zu\n", // fontDirCount); // // 遍历字体文件路径列表,打印日志 // for (size_t i = 0; i < fontDirCount; ++i) { // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "PrintSysFontMetrics", "字体文件路径为: %{public}s\n", // fontConfigInfo->fontDirSet[i]); // } // // 获取通用字体集数量,打印日志 // size_t genericCount = fontConfigInfo->fontGenericInfoSize; // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "PrintSysFontMetrics", "通用字体集数量为: %{public}zu\n", // genericCount); // // 遍历获取每个通用字体集中的字体家族名(例如 HarmonyOS Sans),打印日志 // for (size_t i = 0; i < genericCount; ++i) { // OH_Drawing_FontGenericInfo &genericInfo = fontConfigInfo->fontGenericInfoSet[i]; // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "PrintSysFontMetrics", // "获取第%{public}zu个通用字体集中的字体家族名为: %{public}s", i, genericInfo.familyName); // for(size_t i = 0; i < genericInfo.adjustInfoSize; ++i){ // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "PrintSysFontMetrics", // "获取第%{public}zu个通用字体集中的字体别名: %{public}s", i, genericInfo.aliasInfoSet->familyName); // } // // } // // } //OCCT字体管理信息获取 // auto mgr=Font_FontMgr::GetInstance(); // Handle(Font_SystemFont) sysFont=new Font_SystemFont("HarmonyOS_Sans_Regular"); // sysFont->SetFontPath(Font_FontAspect_Regular, "/data/storage/el1/bundle/entry/resources/rawfile/fonts/HarmonyOS_Sans_Regular.ttf"); // TCollection_ExtendedString aFontName("HarmonyOS_Sans_Regular"); // 为你自定义的字体起一个名称,后续绘制时会用到 // // // 注册字体。第二个参数如果是 Standard_True,表示强制注册,即使同名也覆盖。 // bool isRegistered = mgr->RegisterFont(sysFont, Standard_True); // // if (!isRegistered) { // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Error: Cannot register font: %{public}s",sysFont->FontName().ToCString()); // return; // 或者进行错误处理 // } else { // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","Successfully registered font: %{public}s",sysFont->FontName().ToCString()); // } // mgr->InitFontDataBase(); // mgr->AddFontAlias("HarmonyOS-Sans", "HarmonyOS-Sans"); // Font_FontAspect aspect = Font_FA_Regular; // // 查找sans别名,优先匹配HarmonyOS Sans // Handle(Font_SystemFont) font = mgr->FindFont("HarmonyOS_Sans_Regular", aspect); // if (!font.IsNull()) { // // 打印实际匹配到的字体名,若为HarmonyOS Sans则生效 // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","SO库匹配到的字体名:%{public}s",font->FontName().ToCString()); // } // Handle(Font_SystemFont) sysFont=new Font_SystemFont("HarmonyOS-Sans"); // sysFont->SetFontPath(Font_FontAspect_Regular, "/data/storage/el1/bundle/entry/resources/rawfile/fonts"); // bool err=mgr->RegisterFont(sysFont,true); // if(err){ // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT RegisterFont Done"); // } // NCollection_Sequence> theAliases; // mgr->GetAllAliases(theAliases); // for(auto ft:theAliases){ // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Aliases: %{public}s", ft->ToCString()); // } //Handle(Font_SystemFont)sFont = mgr->GetFont("HarmonyOS-Sans"); //OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT sysFont: %{public}s", sFont->FontName().ToCString()); //查找指定的字体 // const TCollection_AsciiString theFontName='HarmonyOS-Sans'; // Font_FontAspect theFontAspect; // mgr->FindFont(theFontName, theFontAspect); // OH_LOG_Print(LOG_APP, LOG_INFO, LOG_DOMAIN, "OCCT","OCCT Font_FontAspect: %{public}s", theFontAspect); //字体示例 Handle(AIS_TextLabel) aTextLabel = new AIS_TextLabel(); //TCollection_ExtendedString tostr; //const char* str = "\xC4\xE3\xBA\xC3"; //Resource_Unicode::ConvertGBToUnicode(str, tostr); const char16_t chinese_array[] = u"新时代社会主义新中国接班人"; aTextLabel->SetText(chinese_array); aTextLabel->Attributes()->SetTextAspect(ts->text); gp_Pnt position(0.0, 0.0, 0.0); // 例如,在原点 aTextLabel->SetPosition(position); ctx->context->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