解耦初始化使得后期开发渲染和设置功能更加方便

This commit is contained in:
JackLee 2026-03-06 20:51:23 +08:00
parent 6219097b60
commit b806ccbf1a
26 changed files with 39175 additions and 221 deletions

View File

@ -32,12 +32,29 @@ add_library(opencax SHARED
NativeEGLOCCT/NativeRender.h NativeEGLOCCT/NativeRender.h
NativeEGLOCCT/NativeRenderThread.h NativeEGLOCCT/NativeRenderThread.h
NativeEGLOCCT/NativeManager.h NativeEGLOCCT/NativeManager.h
NativeEGLOCCT/RenderStruct.h
NativeEGLOCCT/Axis/worldAxis.h
NativeEGLOCCT/Axis/localAxis.h
NativeEGLOCCT/OpenGLGraphicDriver/OpenGLGraphicDriver.h
NativeEGLOCCT/TextStyle/TextStyle.h
NativeEGLOCCT/Viewer/Viewer.h
NativeEGLOCCT/Context/Context.h
NativeEGLOCCT/View/View.h
NativeEGLOCCT/Camera/Camera.h
# Cpp Src # Cpp Src
NativeEGLOCCT/EGLCore.cpp NativeEGLOCCT/EGLCore.cpp
NativeEGLOCCT/NativeRender.cpp NativeEGLOCCT/NativeRender.cpp
NativeEGLOCCT/NativeRenderThread.cpp NativeEGLOCCT/NativeRenderThread.cpp
NativeEGLOCCT/NativeManager.cpp NativeEGLOCCT/NativeManager.cpp
napi_init.cpp) NativeEGLOCCT/Axis/worldAxis.cpp
NativeEGLOCCT/Axis/localAxis.cpp
NativeEGLOCCT/OpenGLGraphicDriver/OpenGLGraphicDriver.cpp
NativeEGLOCCT/TextStyle/TextStyle.cpp
NativeEGLOCCT/Viewer/Viewer.cpp
NativeEGLOCCT/Context/Context.cpp
NativeEGLOCCT/View/View.cpp
NativeEGLOCCT/Camera/Camera.cpp
napi_init.cpp )
# #
find_library(EGL-lib EGL) find_library(EGL-lib EGL)

View File

@ -0,0 +1,29 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "LocalAxis.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "InitLocalAxis"
#endif
namespace NativeOpenCAX {
bool InitLocalAxis(RenderOption& opt) {
if (opt.localAxisPlacement.IsNull()) {
// 创建场景中心参考坐标系
opt.localAxisPlacement = new Geom_Axis2Placement(gp::XOY());
opt.localAxis = new AIS_Trihedron(opt.localAxisPlacement);
opt.localAxis->SetSize(50.0);
opt.context->Display(opt.localAxis, 0, 0, true);
HILOG_INFO(NATIVE_TAG,"InitLocalAxis Done");
return true;
}
return false;
}
void ChangeLocalAxis() {
}
}

View File

@ -0,0 +1,15 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_LOCALAXIS_H
#define OPENCAX_LOCALAXIS_H
#include "../RenderStruct.h"
namespace NativeOpenCAX {
bool InitLocalAxis(RenderOption& opt);
void ChangeLocalAxis();
}
#endif //OPENCAX_LOCALAXIS_H

View File

@ -0,0 +1,29 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "WorldAxis.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "InitWorldAxis"
#endif
namespace NativeOpenCAX {
bool InitWorldAxis(RenderOption& opt) {
if (opt.worldAxisPlacement.IsNull()) {
// 添加世界坐标系(左下角)
opt.worldAxisPlacement = new Geom_Axis2Placement(gp::XOY());
opt.worldAxis = new AIS_Trihedron(opt.worldAxisPlacement);
opt.worldAxis->SetSize(30.0); // 小一点,作为指示器
opt.context->Display(opt.worldAxis, 0, 0, false);
HILOG_INFO(NATIVE_TAG,"InitWorldAxis Done");
return true;
}
return false;
}
void ChangeWorldAxis() {
}
}

View File

@ -0,0 +1,14 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_WORLDAXIS_H
#define OPENCAX_WORLDAXIS_H
#include "../RenderStruct.h"
namespace NativeOpenCAX {
bool InitWorldAxis(RenderOption& opt);
void ChangeWorldAxis();
}
#endif //OPENCAX_WORLDAXIS_H

View File

@ -0,0 +1,27 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "Camera.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "InitCamera"
#endif
namespace NativeOpenCAX {
bool InitCamera(RenderOption& opt) {
if (opt.camera.IsNull()) {
// 设置相机参数
opt.camera = opt.view->Camera();
opt.camera->SetFOVy(45.0); // 使用正确的FOV设置API
opt.camera->SetZRange(1.0, 1000.0);
HILOG_INFO(NATIVE_TAG,"InitCamera Done");
return true;
}
return false;
}
void ChangeCarmera() {}
}

View File

@ -0,0 +1,18 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_CAMERA_H
#define OPENCAX_CAMERA_H
#include "../RenderStruct.h"
namespace NativeOpenCAX{
bool InitCamera(RenderOption& opt);
void ChangeCamera();
}
#endif //OPENCAX_CAMERA_H

View File

@ -0,0 +1,27 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "Context.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "InitCtx"
#endif
namespace NativeOpenCAX {
bool InitCtx(RenderOption& opt) {
if (opt.context.IsNull()) {
opt.context = new AIS_InteractiveContext(opt.viewer);
opt.context->SetDisplayMode(AIS_Shaded, Standard_False); // 默认使用着色模式
HILOG_INFO(NATIVE_TAG,"InitCtx Done");
return true;
}
return false;
}
void ChangeCtx(){
}
}

View File

@ -0,0 +1,18 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_CONTEXT_H
#define OPENCAX_CONTEXT_H
#include "../RenderStruct.h"
namespace NativeOpenCAX{
bool InitCtx(RenderOption& opt);
void ChangeCtx();
}
#endif //OPENCAX_CONTEXT_H

View File

@ -31,7 +31,8 @@ ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
NativeManager NativeManager::pluginManager_; NativeManager NativeManager::pluginManager_;
OH_NativeXComponent_Callback NativeManager::xSurfaceTouchEventCallBack; OH_NativeXComponent_Callback NativeManager::xSurfaceTouchEventCallBack;
OH_NativeXComponent_MouseEvent_Callback NativeManager::xMouseEventCallBack; OH_NativeXComponent_MouseEvent_Callback NativeManager::xMouseEventCallBack;
ArkUI_NodeHandle xc; std::string comId;
std::string nodeId;
int32_t NativeManager::hasDraw_ = 0; int32_t NativeManager::hasDraw_ = 0;
int32_t NativeManager::hasChangeColor_ = 0; int32_t NativeManager::hasChangeColor_ = 0;
static std::map<int64_t, std::shared_ptr<NativeRenderThread>> renderThreadMap; static std::map<int64_t, std::shared_ptr<NativeRenderThread>> renderThreadMap;
@ -189,16 +190,24 @@ void NativeManager::OnSurfaceDestroyed(OH_NativeXComponent *component, void *win
} }
void NativeManager::OnSurfaceChanged(OH_NativeXComponent *component, void *window) { void NativeManager::OnSurfaceChanged(OH_NativeXComponent *component, void *window) {
OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_); OH_NativeXComponent_GetXComponentSize(component, window, &width_, &height_);
int64_t id = 0; int64_t id = 0;
{ {
std::lock_guard<std::mutex> lock(mapMutex); std::lock_guard<std::mutex> lock(mapMutex);
if (renderThreadMap.find(id) != renderThreadMap.end()) { if (renderThreadMap.find(id) != renderThreadMap.end()) {
HILOG_ERROR(NATIVE_TAG,"uint64_t Size:%{public}dX%{public}d",width_,height_);
uint32_t _width=static_cast<uint32_t>(width_);
uint32_t _height=static_cast<uint32_t>(height_);
HILOG_ERROR(NATIVE_TAG,"uint32_t Size:%{public}dX%{public}d",_width,_height);
ArkUI_NumberValue comSizeData[] = {{.u32=_width}, {.u32=_height}};
ArkUI_AttributeItem comSizeItem = {comSizeData, 2};
renderThreadMap[id]->resizeWindow(width_, height_); renderThreadMap[id]->resizeWindow(width_, height_);
} }
} }
} }
void onEvent(ArkUI_NodeEvent *event) { void onEvent(ArkUI_NodeEvent *event) {
auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); // 获取组件事件类型 auto eventType = OH_ArkUI_NodeEvent_GetEventType(event); // 获取组件事件类型
HILOG_ERROR(NATIVE_TAG,"EventType:%{public}d",eventType);
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on event"); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on event");
if (eventType == NODE_TOUCH_EVENT) { if (eventType == NODE_TOUCH_EVENT) {
ArkUI_NodeHandle handle = OH_ArkUI_NodeEvent_GetNodeHandle(event); // 获取触发该事件的组件对象 ArkUI_NodeHandle handle = OH_ArkUI_NodeEvent_GetNodeHandle(event); // 获取触发该事件的组件对象
@ -223,43 +232,39 @@ NativeManager::NativeManager() {
} }
// 创建节点组件 // 创建节点组件
ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) { ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
nodeId=tag;
// 创建Node也名创建ROW Column等容器 // 创建Node也名创建ROW Column等容器
ArkUI_NodeHandle nodeHandel = nodeAPI->createNode(ARKUI_NODE_RELATIVE_CONTAINER); ArkUI_NodeHandle nodeHandel = nodeAPI->createNode(ARKUI_NODE_RELATIVE_CONTAINER);
// 节点默认宽度or高度 // 节点默认宽度or高度
ArkUI_NumberValue nodeSizeData[] = {1280, 720};
ArkUI_NumberValue nodeMarginData[] = {{.u32 = 0}, {.f32 = 0}}; ArkUI_NumberValue nodeMarginData[] = {{.u32 = 0}, {.f32 = 0}};
// ArkUI_AttributeItem // ArkUI_AttributeItem
// 参数1:指向数值数组 // 参数1:指向数值数组
// 参数2:数组元素个数 // 参数2:数组元素个数
// 参数3:属性名(可隐藏) // 参数3:属性名(可隐藏)
ArkUI_AttributeItem nodeSizeItem = {nodeSizeData, 2};
ArkUI_AttributeItem nodeMarginItem = {nodeMarginData, 2}; ArkUI_AttributeItem nodeMarginItem = {nodeMarginData, 2};
// 设置Node宽度or高度 // 设置Node宽度or高度
nodeAPI->setAttribute(nodeHandel, NODE_SIZE, &nodeSizeItem);
nodeAPI->setAttribute(nodeHandel, NODE_MARGIN, &nodeMarginItem); nodeAPI->setAttribute(nodeHandel, NODE_MARGIN, &nodeMarginItem);
NativeManager::nodeHandleMap_[tag]=nodeHandel;
// 创建XComponent组件 // 创建XComponent组件
// 组件类型Item // 组件类型Item
ArkUI_NumberValue comTypeData[] = {ARKUI_XCOMPONENT_TYPE_SURFACE}; ArkUI_NumberValue comTypeData[] = {ARKUI_XCOMPONENT_TYPE_SURFACE};
ArkUI_AttributeItem comTypeItem = {comTypeData, 1}; ArkUI_AttributeItem comTypeItem = {comTypeData, 1};
// 组件ID Item // 组件ID Item
ArkUI_AttributeItem comIdItem = {.string = uuid_v4().c_str(), .size = 1}; comId=uuid_v4();
ArkUI_AttributeItem comIdItem = {.string = comId.c_str(), .size = 1};
// 组件Surface Size // 组件Surface Size
//ArkUI_NumberValue surfaceSizeData[] = {NAN, NAN};
ArkUI_AttributeItem surfaceSizeItem = {nodeSizeData, 2};
// 创建组件 // 创建组件
ArkUI_NodeHandle xc;
xc = nodeAPI->createNode(ARKUI_NODE_XCOMPONENT); xc = nodeAPI->createNode(ARKUI_NODE_XCOMPONENT);
// 设置XComponent组件属性 // 设置XComponent组件属性
nodeAPI->setAttribute(xc, NODE_XCOMPONENT_TYPE, &comTypeItem); nodeAPI->setAttribute(xc, NODE_XCOMPONENT_TYPE, &comTypeItem);
nodeAPI->setAttribute(xc, NODE_XCOMPONENT_ID, &comIdItem); nodeAPI->setAttribute(xc, NODE_XCOMPONENT_ID, &comIdItem);
nodeAPI->setAttribute(xc, NODE_XCOMPONENT_SURFACE_SIZE, &surfaceSizeItem);
// 焦点设置 // 焦点设置
ArkUI_NumberValue focusable[] = {1}; ArkUI_NumberValue focusable[] = {1};
focusable[0].i32 = 1; focusable[0].i32 = 1;
ArkUI_AttributeItem focusableItem = {focusable, 1}; ArkUI_AttributeItem focusableItem = {focusable, 1};
nodeAPI->setAttribute(xc, NODE_FOCUSABLE, &focusableItem); nodeAPI->setAttribute(xc, NODE_FOCUSABLE, &focusableItem);
// 设置组件Size
nodeAPI->setAttribute(xc, NODE_WIDTH, &surfaceSizeItem);
nodeAPI->setAttribute(xc, NODE_HEIGHT, &surfaceSizeItem);
// 节点ID // 节点ID
ArkUI_AttributeItem nodeIdItem = {.string = uuid_v4().c_str(), .size = 1}; ArkUI_AttributeItem nodeIdItem = {.string = uuid_v4().c_str(), .size = 1};
nodeAPI->setAttribute(xc, NODE_ID, &nodeIdItem); nodeAPI->setAttribute(xc, NODE_ID, &nodeIdItem);

View File

@ -1,32 +1,11 @@
#include "NativeRender.h" #include "NativeRender.h"
#include "Aspect_NeutralWindow.hxx"
#include <GLES3/gl3.h>
#include <cstdio>
#include <cmath>
#include <OSD_Environment.hxx>
#include <AIS_InteractiveObject.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_ShadingAspect.hxx>
#include <Graphic3d_MaterialAspect.hxx>
#include <Graphic3d_NameOfMaterial.hxx>
#include <Graphic3d_TextureEnv.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <V3d_TypeOfOrientation.hxx>
#include <Aspect_TypeOfTriedronPosition.hxx>
#ifndef NATIVE_TAG
#define NATIVE_TAG "NativeRender"
#endif
namespace NativeOpenCAX { namespace NativeOpenCAX {
NativeRender::NativeRender() 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)
{ {
} }
@ -36,93 +15,48 @@ NativeRender::~NativeRender() {
} }
bool NativeRender::init(int width, int height,EGLCore* eglCore) { bool NativeRender::init(int width, int height,EGLCore* eglCore) {
eglCore_=eglCore; rendOption.eglCore=eglCore;
initTextStyle(); rendOption.width=width;
initDriver(); rendOption.height=height;
initViewer(); if(!InitGraphicDriver(rendOption)){
initContext(); HILOG_ERROR(NATIVE_TAG,"InitGraphicDriver Fail!");
initView(); return false;
if (view_.IsNull()) { }
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 false;
} }
view_->SetBackgroundColor(clearColor_);
view_->MustBeResized();
view_->RedrawImmediate();
return true; return true;
} }
void NativeRender::initDriver() {
// 创建图形驱动
if (graphicDriver_.IsNull()) {
Handle(Aspect_DisplayConnection) displayConnection=new Aspect_DisplayConnection();
graphicDriver_ = new OpenGl_GraphicDriver(displayConnection,Standard_False);
graphicDriver_->ChangeOptions().buffersNoSwap = Standard_True;
graphicDriver_->InitEglContext(eglGetCurrentDisplay(), eglGetCurrentContext(), eglCore_->getConfig());
}
}
void NativeRender::initViewer(){
// 创建V3d_Viewer
if (!graphicDriver_.IsNull()) {
viewer_ = new V3d_Viewer(graphicDriver_);
viewer_->SetDefaultBackgroundColor (Quantity_NOC_BLACK);
viewer_->SetDefaultLights();
viewer_->SetLightOn();
}
}
void NativeRender::initContext(){
context_ = new AIS_InteractiveContext(viewer_);
context_->SetDisplayMode(AIS_Shaded, Standard_False); // 默认使用着色模式
//context_->SetPixelTolerance (int(NativeOpenCAX::DisplayInfo * 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) { bool NativeRender::loadModel(const std::string& filePath) {
// 清除现有模型 // 清除现有模型
for (auto& shape : shapes_) { for (auto& shape : shapes_) {
context_->Remove(shape, Standard_False); rendOption.context->Remove(shape, Standard_False);
} }
shapes_.clear(); shapes_.clear();
@ -145,6 +79,16 @@ bool NativeRender::loadModel(const std::string& filePath) {
// 加载所有形状 // 加载所有形状
for (Standard_Integer i = 1; i <= numShapes; i++) { for (Standard_Integer i = 1; i <= numShapes; i++) {
TopoDS_Shape shape = reader.Shape(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()) { if (!shape.IsNull()) {
Handle(AIS_Shape) aisShape = new AIS_Shape(shape); Handle(AIS_Shape) aisShape = new AIS_Shape(shape);
@ -169,87 +113,87 @@ bool NativeRender::loadModel(const std::string& filePath) {
shadingAspect->SetColor(color); shadingAspect->SetColor(color);
shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC); shadingAspect->SetMaterial(Graphic3d_NOM_PLASTIC);
drawer->SetShadingAspect(shadingAspect); drawer->SetShadingAspect(shadingAspect);
rendOption.context->Display(aisShape, Standard_True);
context_->Display(aisShape, Standard_True);
shapes_.push_back(aisShape); shapes_.push_back(aisShape);
} }
} }
// 调整相机到合适位置 // 调整相机到合适位置
view_->FitAll(0.05, Standard_True); rendOption.view->FitAll(0.05, Standard_True);
view_->ZFitAll(); rendOption.view->ZFitAll();
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "LoadModel","Successfully loaded STEP file with %{public}d shapes",numShapes); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "LoadModel","Successfully loaded STEP file with %{public}d shapes",numShapes);
return true; return true;
} }
//setTranslation //setTranslation
void NativeRender::setTranslation(float x, float y) { void NativeRender::setTranslation(float x, float y) {
translationX_ = x; axis.translationX = x;
translationY_ = y; axis.translationY = y;
} }
void NativeRender::render() { void NativeRender::render() {
if (view_.IsNull()) { if (rendOption.view.IsNull()) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render","View Is Null"); OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Render","View Is Null");
return; return;
} }
//glClearColor(1, 0, 0, 1); //glClearColor(1, 0, 0, 1);
//glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glViewport(0, 0, width_, height_); //glViewport(0, 0, width_, height_);
// 应用旋转 // 应用旋转
Handle(Graphic3d_Camera) camera = view_->Camera(); //Handle(Graphic3d_Camera) camera = view_->Camera();
// 计算旋转 // 计算旋转
gp_Quaternion rotation; //gp_Quaternion rotation;
rotation.SetEulerAngles(gp_EulerSequence::gp_Extrinsic_XYZ, //rotation.SetEulerAngles(gp_EulerSequence::gp_Extrinsic_XYZ,
rotationX_ * M_PI / 180.0, // rotationX_ * M_PI / 180.0,
rotationY_ * M_PI / 180.0, // rotationY_ * M_PI / 180.0,
0.0); // 0.0);
// 计算相机位置 // 计算相机位置
gp_Dir camDir(0.0, 1.0, 0.0); //gp_Dir camDir(0.0, 1.0, 0.0);
gp_Vec camVec = rotation * gp_Vec(camDir); //gp_Vec camVec = rotation * gp_Vec(camDir);
gp_Pnt camPos = gp_Pnt(0.0, 0.0, 0.0).Translated(camVec.Reversed() * 50.0 * zoomLevel_); //gp_Pnt camPos = gp_Pnt(0.0, 0.0, 0.0).Translated(camVec.Reversed() * 50.0 * zoomLevel_);
// 设置相机参数 // 设置相机参数
camera->SetEye(camPos); //camera->SetEye(camPos);
camera->SetCenter(gp_Pnt(translationX_, translationY_, 0.0)); //camera->SetCenter(gp_Pnt(translationX_, translationY_, 0.0));
camera->SetUp(gp_Dir(0.0, 0.0, 1.0)); //camera->SetUp(gp_Dir(0.0, 0.0, 1.0));
// 执行渲染 // 执行渲染
view_->Redraw(); rendOption.view->Redraw();
} }
void NativeRender::resize(int width, int height) { void NativeRender::resize(int width, int height) {
width_ = width; rendOption.width = width;
height_ = height; rendOption.height = height;
if (!view_.IsNull()) { if (!rendOption.view.IsNull()) {
view_->MustBeResized(); rendOption.view->MustBeResized();
} }
} }
void NativeRender::setRotation(float xAngle, float yAngle) { void NativeRender::setRotation(float xAngle, float yAngle) {
rotationX_ = xAngle; axis.rotationX = xAngle;
rotationY_ = yAngle; axis.rotationY = yAngle;
} }
void NativeRender::setZoomLevel(float zoom) { void NativeRender::setZoomLevel(float zoom) {
zoomLevel_ = std::max(0.1f, std::min(zoom, 5.0f)); // 限制缩放范围 axis.zoomLevel = std::max(0.1f, std::min(zoom, 5.0f)); // 限制缩放范围
} }
void NativeRender::resetView() { void NativeRender::resetView() {
rotationX_ = 0.0f; axis.rotationX = 0.0f;
rotationY_ = 0.0f; axis.rotationY = 0.0f;
zoomLevel_ = 1.0f; axis.zoomLevel = 1.0f;
if (!view_.IsNull()) { if (!rendOption.view.IsNull()) {
view_->SetProj(V3d_XposYnegZpos); rendOption.view->SetProj(V3d_XposYnegZpos);
view_->FitAll(0.05, Standard_False); rendOption.view->FitAll(0.05, Standard_False);
} }
} }
void NativeRender::setClearColor(float r, float g, float b, float a) { void NativeRender::setClearColor(float r, float g, float b, float a) {
clearColor_ = Quantity_Color(r, g, b, Quantity_TOC_RGB); rendOption.clearColor = Quantity_Color(r, g, b, Quantity_TOC_RGB);
if (!view_.IsNull()) { if (!rendOption.view.IsNull()) {
view_->SetBackgroundColor(clearColor_); rendOption.view->SetBackgroundColor(rendOption.clearColor);
} }
} }

View File

@ -3,33 +3,22 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <Standard_Handle.hxx>
#include <AIS_InteractiveContext.hxx>
#include <V3d_View.hxx>
#include <V3d_Viewer.hxx>
#include <OpenGl_GraphicDriver.hxx>
#include <AIS_Shape.hxx>
#include <STEPControl_Reader.hxx>
#include <TopoDS_Shape.hxx>
#include <Graphic3d_GraphicDriver.hxx>
#include <Aspect_DisplayConnection.hxx>
#include <Message.hxx>
#include <Quantity_Color.hxx>
#include <gp_Quaternion.hxx>
#include <OpenGl_Window.hxx>
#include <gp_EulerSequence.hxx>
#include <Aspect_Handle.hxx>
#include <ace/xcomponent/native_interface_xcomponent.h>
#include "common.h"
#include <EGL/egl.h>
#include "EGLCore.h"
class Aspect_Window; #include "common.h"
class gp_Quaternion; #include "EGLCore.h"
class Graphic3d_Camera; #include <Standard_Handle.hxx>
#include "Context/Context.h"
#include "Camera/Camera.h"
#include "Axis/WorldAxis.h"
#include "Axis/LocalAxis.h"
#include "OpenGLGraphicDriver/OpenGLGraphicDriver.h"
#include "TextStyle/TextStyle.h"
#include "View/View.h"
#include "Viewer/Viewer.h"
namespace NativeOpenCAX { namespace NativeOpenCAX {
class NativeRender { class NativeRender {
public: public:
NativeRender(); NativeRender();
@ -44,36 +33,10 @@ public:
void setClearColor(float r, float g, float b, float a); void setClearColor(float r, float g, float b, float a);
void setZoomLevel(float zoom); void setZoomLevel(float zoom);
void setTranslation(float x, float y); void setTranslation(float x, float y);
private: private:
void initDriver(); RenderOption rendOption;
void initViewer(); AxisOption axis;
void initContext();
void initView();
void initTextStyle();
// Bind existing EGL display/context to OCCT OpenGl driver
//void loadDefaultModel();
EGLCore* eglCore_;
Handle(OpenGl_GraphicDriver) graphicDriver_;
Handle(V3d_Viewer) viewer_;
Handle(V3d_View) view_;
Handle(AIS_InteractiveContext) context_;
Handle(Prs3d_TextAspect) text_;
std::vector<Handle(AIS_Shape)> shapes_; std::vector<Handle(AIS_Shape)> shapes_;
//旋转X轴
float rotationX_;
//旋转Y轴
float rotationY_;
//旋转Z轴
float rotationZ_;
float zoomLevel_;
int width_;
int height_;
float translationX_;
float translationY_;
float translationZ_;
Quantity_Color clearColor_;
}; };
} // namespace NativeRender } // namespace NativeRender
#endif // NATIVE_RENDER_H #endif // NATIVE_RENDER_H

View File

@ -0,0 +1,30 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "OpenGLGraphicDriver.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "InitGraphicDriver"
#endif
namespace NativeOpenCAX{
bool InitGraphicDriver(RenderOption &opt){
if (opt.graphicDriver.IsNull()) {
opt.displayConnection=new Aspect_DisplayConnection();
opt.graphicDriver = new OpenGl_GraphicDriver(opt.displayConnection,Standard_False);
opt.graphicDriver->ChangeOptions().buffersNoSwap = Standard_True;
opt.graphicDriver->InitEglContext(eglGetCurrentDisplay(), eglGetCurrentContext(), opt.eglCore->getConfig());
HILOG_INFO(NATIVE_TAG,"InitGraphicDriver Done");
return true;
}
return false;
}
void ChangeGraphicDriver(){
}
}

View File

@ -0,0 +1,18 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_OPENGLGRAPHICDRIVER_H
#define OPENCAX_OPENGLGRAPHICDRIVER_H
#include "../RenderStruct.h"
namespace NativeOpenCAX{
bool InitGraphicDriver(RenderOption &opt);
void ChangeGraphicDriver();
}
#endif //OPENCAX_OPENGLGRAPHICDRIVER_H

View File

@ -0,0 +1,83 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_REDCOMMON_H
#define OPENCAX_REDCOMMON_H
#include "common.h"
#include <cstdio>
#include <cmath>
#include <EGL/egl.h>
#include <GLES3/gl3.h>
#include <OpenGl_GraphicDriver.hxx>
#include <V3d_View.hxx>
#include <V3d_Viewer.hxx>
#include <Font_NameOfFont.hxx>
#include <Aspect_NeutralWindow.hxx>
#include <Aspect_TypeOfTriedronPosition.hxx>
#include <Geom_Axis2Placement.hxx>
#include <OpenGl_Window.hxx>
#include <OSD_Environment.hxx>
#include <AIS_Shape.hxx>
#include <AIS_Trihedron.hxx>
#include <AIS_InteractiveObject.hxx>
#include <AIS_InteractiveContext.hxx>
#include <Prs3d_Drawer.hxx>
#include <Prs3d_TextAspect.hxx>
#include <Prs3d_ShadingAspect.hxx>
#include <Graphic3d_ZLayerSettings.hxx>
#include <Graphic3d_GraphicDriver.hxx>
#include <Graphic3d_MaterialAspect.hxx>
#include <Graphic3d_NameOfMaterial.hxx>
#include <Graphic3d_TextureEnv.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepPrimAPI_MakeBox.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <V3d_TypeOfOrientation.hxx>
#include "EGLCore.h"
#include <STEPControl_Reader.hxx>
namespace NativeOpenCAX {
struct RenderOption{
int width;
int height;
Quantity_Color clearColor;
EGLCore* eglCore;
Handle(OpenGl_GraphicDriver) graphicDriver;
Handle(Aspect_DisplayConnection) displayConnection;
Handle(Aspect_NeutralWindow) window;
Handle(V3d_Viewer) viewer;
Handle(V3d_View) view;
Handle(Graphic3d_Camera) camera;
Handle(AIS_InteractiveContext) context;
Handle(Prs3d_TextAspect) text;
Handle(Geom_Axis2Placement) worldAxisPlacement;
Handle(Geom_Axis2Placement) localAxisPlacement;
Handle(AIS_Trihedron) worldAxis;
Handle(AIS_Trihedron) localAxis;
};
struct AxisOption{
//旋转X轴
float rotationX=0.0f;
//旋转Y轴
float rotationY=0.0f;
//旋转Z轴
float rotationZ=0.0f;
//缩放等级
float zoomLevel=1.0f;
//翻转X轴
float translationX=0.0f;
//翻转Y轴
float translationY=0.0f;
//翻转Z轴
float translationZ=0.0f;
};
}
#endif //OPENCAX_REDCOMMON_H

View File

@ -0,0 +1,36 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "TextStyle.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "InitTextSyle"
#endif
namespace NativeOpenCAX {
bool InitTextSyle(RenderOption& opt) {
if (opt.text.IsNull()) {
opt.text = new Prs3d_TextAspect();
opt.text->SetFont(Font_NOF_ASCII_MONO);
opt.text->SetHeight(12);
opt.text->Aspect()->SetColor(Quantity_NOC_GRAY95);
opt.text->Aspect()->SetColorSubTitle(Quantity_NOC_BLACK);
opt.text->Aspect()->SetDisplayType(Aspect_TODT_SHADOW);
opt.text->Aspect()->SetTextFontAspect(Font_FA_Bold);
opt.text->Aspect()->SetTextZoomable(false);
opt.text->SetHorizontalJustification(Graphic3d_HTA_LEFT);
opt.text->SetVerticalJustification(Graphic3d_VTA_BOTTOM);
HILOG_INFO(NATIVE_TAG,"InitTextSyle Done");
return true;
}
return false;
}
void ChangeTextSyle(){
}
}

View File

@ -0,0 +1,18 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_TEXTSTYLE_H
#define OPENCAX_TEXTSTYLE_H
#include "../RenderStruct.h"
namespace NativeOpenCAX{
bool InitTextSyle(RenderOption& opt);
void ChangeTextSyle();
}
#endif //OPENCAX_TEXTSTYLE_H

View File

@ -0,0 +1,52 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "View.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "InitView"
#endif
namespace NativeOpenCAX {
bool InitView(RenderOption& opt) {
if (opt.window.IsNull()) {
opt.window = new Aspect_NeutralWindow();
opt.window->SetSize(opt.width, opt.height);
opt.view = opt.viewer->CreateView();
// 设置渲染参数
opt.view->SetImmediateUpdate(false);
// view_->ChangeRenderingParams().ToShowStats = true;
// view_->ChangeRenderingParams().Resolution = (unsigned int )(96.0 * displayPixelRatio() + 0.5);
opt.view->ChangeRenderingParams().Method = Graphic3d_RM_RASTERIZATION;
opt.view->ChangeRenderingParams().IsShadowEnabled = Standard_False;
opt.view->ChangeRenderingParams().IsReflectionEnabled = Standard_False;
opt.view->ChangeRenderingParams().IsAntialiasingEnabled = Standard_True;
opt.view->ChangeRenderingParams().Resolution = 2;
opt.view->ChangeRenderingParams().StatsTextAspect = opt.text->Aspect();
opt.view->ChangeRenderingParams().StatsTextHeight = opt.text->Height();
// 设置背景渐变
opt.view->SetBgGradientColors(Quantity_Color(Quantity_NOC_GRAY), Quantity_Color(Quantity_NOC_BLACK),
Aspect_GFM_VER, // 垂直渐变
Standard_False);
// 设置默认相机位置
opt.view->SetProj(V3d_XposYnegZpos);
// 可选:显示坐标轴
opt.view->ZBufferTriedronSetup();
// 调整相机视角
opt.view->Camera()->SetProjectionType(Graphic3d_Camera::Projection_Perspective);
opt.view->SetBackgroundColor(Quantity_NOC_GRAY90);
opt.view->MustBeResized();
opt.view->SetWindow(opt.window,(Aspect_RenderingContext )eglGetCurrentContext());
opt.view->RedrawImmediate();
HILOG_INFO(NATIVE_TAG,"InitView Done");
return true;
}
return false;
}
void ChangeView() {}
}

View File

@ -0,0 +1,18 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_VIEW_H
#define OPENCAX_VIEW_H
#include "../RenderStruct.h"
namespace NativeOpenCAX{
bool InitView(RenderOption& opt);
void ChangeView();
}
#endif //OPENCAX_VIEW_H

View File

@ -0,0 +1,28 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#include "Viewer.h"
#ifndef NATIVE_TAG
#define NATIVE_TAG "InitViewer"
#endif
namespace NativeOpenCAX {
bool InitViewer(RenderOption &opt) {
// 创建V3d_Viewer
if (opt.viewer.IsNull()) {
opt.viewer = new V3d_Viewer(opt.graphicDriver);
opt.viewer->SetDefaultBackgroundColor(Quantity_NOC_BLACK);
opt.viewer->SetDefaultLights();
opt.viewer->SetLightOn();
HILOG_INFO(NATIVE_TAG,"InitViewer Done");
return true;
}
return false;
}
void ChangeViewer() {}
}

View File

@ -0,0 +1,18 @@
//
// Created on 2026/3/6.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef OPENCAX_VIEWER_H
#define OPENCAX_VIEWER_H
#include "../RenderStruct.h"
namespace NativeOpenCAX{
bool InitViewer(RenderOption& opt);
void ChangeViewer();
}
#endif //OPENCAX_VIEWER_H

View File

@ -44,4 +44,5 @@ const unsigned int LOG_PRINT_DOMAIN = 0xFF00;
#define HILOG_WARN(TAG, fmt, ...) #define HILOG_WARN(TAG, fmt, ...)
#define HILOG_ERROR(TAG, fmt, ...) #define HILOG_ERROR(TAG, fmt, ...)
#endif #endif
#endif // NATIVE_XCOMPONENT_COMMON_H #endif // NATIVE_XCOMPONENT_COMMON_H

View File

@ -14,8 +14,8 @@ export struct EventBtn {
if(this.eventBtn!=undefined){ if(this.eventBtn!=undefined){
if(this.modelType==1){ if(this.modelType==1){
Image($r('app.media.' + this.eventBtn.eIcon)) Image($r('app.media.' + this.eventBtn.eIcon))
.width(45) .width('45vp')
.height(35) .height('35vp')
.objectFit(ImageFit.Contain) .objectFit(ImageFit.Contain)
.onClick(()=>{ .onClick(()=>{
if(this.eventBtn?.eEvent=='Switch_Model_CAD'){ if(this.eventBtn?.eEvent=='Switch_Model_CAD'){
@ -28,20 +28,20 @@ export struct EventBtn {
}) })
}else{ }else{
Image($r('app.media.' + this.eventBtn.eIcon)) Image($r('app.media.' + this.eventBtn.eIcon))
.width(45) .width('45vp')
.height(35) .height('35vp')
.objectFit(ImageFit.Contain) .objectFit(ImageFit.Contain)
} }
Text(this.eventBtn.eName) Text(this.eventBtn.eName)
.fontSize(10) .fontSize('10fp')
.width(45) .width('45vp')
.height(10) .height('10vp')
.textAlign(TextAlign.Center) .textAlign(TextAlign.Center)
} }
} }
.height('50') .height('50vp')
.width('50') .width('50vp')
.padding('1') .padding('1vp')
} }
} }

View File

@ -12,22 +12,23 @@ struct Index {
//OpenCAX主界面整体布局,采用多行布局 //OpenCAX主界面整体布局,采用多行布局
Flex({ direction: FlexDirection.Column }) { Flex({ direction: FlexDirection.Column }) {
//头部导航功能区 //头部导航功能区
TitleTab().height('auto').borderWidth('1') TitleTab().height('auto').borderWidth('1vp')
Row() { Row() {
//左侧边导航区 //左侧边导航区
LeftSideTab().borderWidth('1').width('20%'); LeftSideTab().borderWidth('1vp').width('20%');
//中间操作区域 //中间操作区域
Row() { Row() {
ModelViewTab() ModelViewTab()
}.width('80%') }.width('80%')
.height('100%') .height('100%')
.borderWidth('1') .borderWidth('1vp')
.align(Alignment.Center) .align(Alignment.Center)
}.height('80%') }.height('80%')
.padding(1) .padding(1)
Column(){ Column(){
Text('状态栏').height('100%').width('100%') Text('状态栏').height('100%').width('100%')
}.height('5%').borderWidth('1') }.height('5%').borderWidth('1vp')
} }.width('100%')
.height('100%')
} }
} }

View File

@ -11,7 +11,7 @@ export struct ModelView {
private displayController: XComponentController = new XComponentController(); private displayController: XComponentController = new XComponentController();
private displayContrId: string = 'OCCTRender'; private displayContrId: string = 'OCCTRender';
@State modelPath: string = ''; @State modelPath: string = '';
@State modelName:string='model.step'; @State modelName:string='linkrods.step';
@State currentStatus: string = 'init'; @State currentStatus: string = 'init';
private nodeContent: NodeContent = new NodeContent(); private nodeContent: NodeContent = new NodeContent();
@ -60,7 +60,7 @@ export struct ModelView {
}.height('5%') }.height('5%')
Row(){ Row(){
ContentSlot(this.nodeContent); ContentSlot(this.nodeContent);
}.height('95%') }.layoutWeight(1)
} }
.width('100%') .width('100%')
.height('100%'); .height('100%');

File diff suppressed because it is too large Load Diff