289 lines
12 KiB
C++
289 lines
12 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), 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<occ::handle<TCollection_HAsciiString>> 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
|