增加对多例的支持(未开发完)

This commit is contained in:
JackLee 2026-04-01 18:26:02 +08:00
parent f65b6ed3f9
commit 68a4979a93
29 changed files with 174 additions and 248 deletions

Binary file not shown.

View File

@ -11,7 +11,6 @@ set(CMAKE_CXX_STANDARD 17)
include_directories(${NATIVERENDER_ROOT_PATH}
${NATIVERENDER_ROOT_PATH}/include
${NATIVERENDER_ROOT_PATH}/include/opencascade
${NATIVERENDER_ROOT_PATH}/include/Add
)
# OCCT
@ -43,7 +42,7 @@ add_library(opencax SHARED
NativeEGLOCCT/EGLCore.h
NativeEGLOCCT/NativeRender.h
NativeEGLOCCT/NativeRenderThread.h
NativeEGLOCCT/NativeManager.h
NativeEGLOCCT/NativeMgr.h
NativeEGLOCCT/V3d/V3dOGD/V3dOGD.h
NativeEGLOCCT/V3d/V3dViewer/V3dViewer.h
NativeEGLOCCT/V3d/V3dCtx/V3dCtx.h
@ -58,7 +57,7 @@ add_library(opencax SHARED
NativeEGLOCCT/EGLCore.cpp
NativeEGLOCCT/NativeRender.cpp
NativeEGLOCCT/NativeRenderThread.cpp
NativeEGLOCCT/NativeManager.cpp
NativeEGLOCCT/NativeMgr.cpp
NativeEGLOCCT/V3d/V3dOGD/V3dOGD.cpp
NativeEGLOCCT/V3d/V3dViewer/V3dViewer.cpp
NativeEGLOCCT/V3d/V3dCtx/V3dCtx.cpp
@ -89,6 +88,5 @@ target_link_libraries(opencax PUBLIC
${GLES-lib}
#OCCT
${OCCT_IMPORTED_LIBS}
${OCCT_LIB_DIR}/libNativeAdd.so
)

View File

@ -1,4 +1,4 @@
#include "NativeManager.h"
#include "NativeMgr.h"
#include <ace/xcomponent/native_interface_xcomponent.h>
#include <cstdint>
#include <cstdio>
@ -15,50 +15,28 @@
#define XC_HEIGHT 600
#define ARG_CNT 2
#ifndef NATIVE_TAG
#define NATIVE_TAG "NativeManager"
#define NATIVE_TAG "NativeMgr"
#endif
#include "arkui/ui_input_event.h"
namespace NativeOpenCAX {
// [Start plugin_manager_cpp]
// plugin_manager.cpp
std::unordered_map<std::string, ArkUI_NodeHandle> NativeManager::nodeHandleMap_;
std::unordered_map<void *, OH_ArkUI_SurfaceCallback *> NativeManager::callbackMap_;
std::unordered_map<void *, OH_ArkUI_SurfaceHolder *> NativeManager::surfaceHolderMap_;
ArkUI_AccessibilityProvider *NativeManager::provider_ = nullptr;
ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(
OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
std::unordered_map<std::string, ArkUI_NodeHandle> NativeMgr::nodeHandleMap_;
std::unordered_map<void *, OH_ArkUI_SurfaceCallback *> NativeMgr::callbackMap_;
ArkUI_NativeNodeAPI_1 *nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
// [StartExclude plugin_manager_cpp]
NativeManager NativeManager::pluginManager_;
OH_NativeXComponent_Callback NativeManager::xSurfaceTouchEventCallBack;
OH_NativeXComponent_MouseEvent_Callback NativeManager::xMouseEventCallBack;
NativeMgr NativeMgr::pluginManager_;
OH_NativeXComponent_Callback NativeMgr::xSurfaceTouchEventCallBack;
OH_NativeXComponent_MouseEvent_Callback NativeMgr::xMouseEventCallBack;
std::string comId;
std::string nodeId;
int32_t NativeManager::hasDraw_ = 0;
int32_t NativeManager::hasChangeColor_ = 0;
int32_t NativeMgr::hasDraw_ = 0;
int32_t NativeMgr::hasChangeColor_ = 0;
static std::map<int64_t, std::shared_ptr<NativeRenderThread>> renderThreadMap;
static std::mutex mapMutex;
NativeManager::~NativeManager() {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "~NativeManager");
nativeXComponentMap_.clear();
int64_t id = 0;
std::lock_guard<std::mutex> lock(mapMutex);
if (renderThreadMap.find(id) != renderThreadMap.end()) {
renderThreadMap[id]->stop();
renderThreadMap.erase(id);
}
for (auto iter = pluginManagerMap_.begin(); iter != pluginManagerMap_.end(); ++iter) {
if (iter->second != nullptr) {
delete iter->second;
iter->second = nullptr;
}
}
pluginManagerMap_.clear();
}
std::string uuid_v4() {
// 使用当前时间戳和随机数生成UUID
auto timestamp = std::chrono::high_resolution_clock::now().time_since_epoch().count();
@ -79,8 +57,28 @@ std::string uuid_v4() {
return ss.str();
}
NativeMgr::~NativeMgr() {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "Callback", "~NativeMgr");
nativeXComponentMap_.clear();
int64_t id = 0;
std::lock_guard<std::mutex> lock(mapMutex);
if (renderThreadMap.find(id) != renderThreadMap.end()) {
renderThreadMap[id]->stop();
renderThreadMap.erase(id);
}
for (auto iter = pluginManagerMap_.begin(); iter != pluginManagerMap_.end(); ++iter) {
if (iter->second != nullptr) {
delete iter->second;
iter->second = nullptr;
}
}
pluginManagerMap_.clear();
}
void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
// [StartExclude plugin_on_surface_created]
// [StartExclude plugin_on_surface_created]
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "OnSurfaceCreatedCB");
//主动关闭CPU访问窗口缓冲区数据降低功耗
uint64_t usage = 0;
@ -99,8 +97,9 @@ void OnSurfaceCreatedCB(OH_NativeXComponent *component, void *window) {
id.c_str());
// [EndExclude plugin_on_surface_created]
// 初始化环境与绘制背景
auto *pluginManger = NativeManager::GetInstance();
auto *pluginManger = NativeMgr::GetInstance();
pluginManger->OnSurfaceCreated(component, window);
}
void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) {
// [StartExclude plugin_on_surface_changed]
@ -114,7 +113,7 @@ void OnSurfaceChangedCB(OH_NativeXComponent *component, void *window) {
}
std::string id(idStr);
// [EndExclude plugin_on_surface_changed]
auto *pluginManger = NativeManager::GetInstance();
auto *pluginManger = NativeMgr::GetInstance();
// 封装OnSurfaceChanged方法
pluginManger->OnSurfaceChanged(component, window);
}
@ -130,11 +129,11 @@ void OnSurfaceDestroyedCB(OH_NativeXComponent *component, void *window) {
}
std::string id(idStr);
// [EndExclude plugin_on_surface_destroyed]
auto *pluginManger = NativeManager::GetInstance();
auto *pluginManger = NativeMgr::GetInstance();
pluginManger->OnSurfaceDestroyed(component, window);
}
//NativeManager回调
void NativeManager::OnSurfaceCreated(OH_NativeXComponent *component, void *window) {
//NativeMgr回调
void NativeMgr::OnSurfaceCreated(OH_NativeXComponent *component, void *window) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceCreated");
if (!window) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native",
@ -153,7 +152,7 @@ void NativeManager::OnSurfaceCreated(OH_NativeXComponent *component, void *windo
renderThread->start(reinterpret_cast<OHNativeWindow*>(window));
}
}
void NativeManager::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window) {
void NativeMgr::OnSurfaceDestroyed(OH_NativeXComponent *component, void *window) {
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "XComponent_Native", "PluginManager::OnSurfaceDestroyed");
int64_t id = 0;
{
@ -165,7 +164,7 @@ void NativeManager::OnSurfaceDestroyed(OH_NativeXComponent *component, void *win
}
}
void NativeManager::OnSurfaceChanged(OH_NativeXComponent *component, void *window) {
void NativeMgr::OnSurfaceChanged(OH_NativeXComponent *component, void *window) {
OH_NativeXComponent_GetXComponentSize(component, window, &afWidth, &afHeight);
int64_t id = 0;
@ -182,26 +181,16 @@ void NativeManager::OnSurfaceChanged(OH_NativeXComponent *component, void *windo
}
}
}
void onEvent(ArkUI_NodeEvent *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");
if (eventType == NODE_TOUCH_EVENT) {
ArkUI_NodeHandle handle = OH_ArkUI_NodeEvent_GetNodeHandle(event); // 获取触发该事件的组件对象
auto holder = NativeManager::surfaceHolderMap_[handle];
EGLCore *render = reinterpret_cast<EGLCore *>(OH_ArkUI_SurfaceHolder_GetUserData(holder));
OH_LOG_Print(LOG_APP, LOG_ERROR, LOG_PRINT_DOMAIN, "onBind", "on touch");
}
}
void OnMouseEventCB(OH_NativeXComponent* component, void* window) {
auto* pluginManager = NativeManager::GetInstance();
auto* pluginManager = NativeMgr::GetInstance();
if (!pluginManager || !window) {
return;
}
auto *pluginManger = NativeManager::GetInstance();
auto *pluginManger = NativeMgr::GetInstance();
pluginManger->OnMouseEvent(component, window);
}
void NativeManager::OnMouseEvent(OH_NativeXComponent *comp, void *win) {
void NativeMgr::OnMouseEvent(OH_NativeXComponent *comp, void *win) {
int32_t ret;
OH_NativeXComponent_MouseEvent mouseEvent;
ret = OH_NativeXComponent_GetMouseEvent(comp, win, &mouseEvent);
@ -219,10 +208,10 @@ void NativeManager::OnMouseEvent(OH_NativeXComponent *comp, void *win) {
//HILOG_WARN(NATIVE_TAG, "ExtraMouseEventInfo:%{public}s",extra);
std::lock_guard<std::mutex> lock(mapMutex);
//通过时间戳判断事件唯一性.保证单一时间戳只触发一次事件
if(mouseEvent.timestamp==NativeManager::timestamp){
if(mouseEvent.timestamp==NativeMgr::timestamp){
return;
}
NativeManager::timestamp=mouseEvent.timestamp;
NativeMgr::timestamp=mouseEvent.timestamp;
int64_t id = 0;
auto it = renderThreadMap.find(id);
if (it == renderThreadMap.end()) {
@ -251,23 +240,23 @@ void NativeManager::OnMouseEvent(OH_NativeXComponent *comp, void *win) {
//鼠标按下并且事件为鼠标中键
if(mouseEvent.button==OH_NATIVEXCOMPONENT_LEFT_BUTTON&&mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_PRESS){
if(NativeManager::isMouseMiddleBtnPressed){
NativeManager::isMouseMiddleBtnPressed=false;
if(NativeMgr::isMouseMiddleBtnPressed){
NativeMgr::isMouseMiddleBtnPressed=false;
return;
}
//记录按下时候的X.Y坐标
NativeManager::lastMouseX_=mouseEvent.x;
NativeManager::lastMouseY_=mouseEvent.y;
NativeManager::isMouseMiddleBtnPressed = true;
//HILOG_WARN(NATIVE_TAG, "AtlastMouseX:%{public}d",NativeManager::lastMouseX_);
//HILOG_WARN(NATIVE_TAG, "AtlastMouseY:%{public}d",NativeManager::lastMouseY_);
NativeMgr::lastMouseX_=mouseEvent.x;
NativeMgr::lastMouseY_=mouseEvent.y;
NativeMgr::isMouseMiddleBtnPressed = true;
//HILOG_WARN(NATIVE_TAG, "AtlastMouseX:%{public}d",NativeMgr::lastMouseX_);
//HILOG_WARN(NATIVE_TAG, "AtlastMouseY:%{public}d",NativeMgr::lastMouseY_);
//HILOG_WARN(NATIVE_TAG, "AtButton:%{public}d",mouseEvent.button);
//HILOG_WARN(NATIVE_TAG, "AtButtonAction:%{public}d",mouseEvent.action);
//HILOG_WARN(NATIVE_TAG, "AtisMouseMiddleBtnPressed:%{public}d",NativeManager::isMouseMiddleBtnPressed);
}else if(mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_MOVE&&NativeManager::isMouseMiddleBtnPressed){
//HILOG_WARN(NATIVE_TAG, "AtisMouseMiddleBtnPressed:%{public}d",NativeMgr::isMouseMiddleBtnPressed);
}else if(mouseEvent.action==OH_NATIVEXCOMPONENT_MOUSE_MOVE&&NativeMgr::isMouseMiddleBtnPressed){
// 计算鼠标移动距离
float deltaX = curtX - NativeManager::lastMouseX_;
float deltaY = curtY - NativeManager::lastMouseY_;
float deltaX = curtX - NativeMgr::lastMouseX_;
float deltaY = curtY - NativeMgr::lastMouseY_;
// 将像素移动量映射到旋转角度
// 这里的系数可以根据需要调整灵敏度
float rotationSpeed = 0.001f;
@ -277,13 +266,13 @@ void NativeManager::OnMouseEvent(OH_NativeXComponent *comp, void *win) {
// 由于渲染在线程里,需要通过命令队列发送指令
renderThread->setRotation(angleX, angleY);
// 更新最后的位置
//NativeManager::lastMouseX_ = deltaX;
//NativeManager::lastMouseY_ = deltaY;
//NativeMgr::lastMouseX_ = deltaX;
//NativeMgr::lastMouseY_ = deltaY;
//HILOG_WARN(NATIVE_TAG, "MoveAngleX:%{public}d",angleX);
//HILOG_WARN(NATIVE_TAG, "MoveAngleY:%{public}d",angleY);
//HILOG_WARN(NATIVE_TAG, "MoveButton:%{public}d",mouseEvent.button);
//HILOG_WARN(NATIVE_TAG, "MoveButtonAction:%{public}d",mouseEvent.action);
//HILOG_WARN(NATIVE_TAG, "MoveIsMouseMiddleBtnPressed:%{public}d",NativeManager::isMouseMiddleBtnPressed);
//HILOG_WARN(NATIVE_TAG, "MoveIsMouseMiddleBtnPressed:%{public}d",NativeMgr::isMouseMiddleBtnPressed);
}
}
@ -306,7 +295,7 @@ struct AxisEvent {
};
// XComponent回调事件
NativeManager::NativeManager() {
NativeMgr::NativeMgr() {
xSurfaceTouchEventCallBack.OnSurfaceCreated = OnSurfaceCreatedCB;
xSurfaceTouchEventCallBack.OnSurfaceChanged = OnSurfaceChangedCB;
xSurfaceTouchEventCallBack.OnSurfaceDestroyed = OnSurfaceDestroyedCB;
@ -314,7 +303,7 @@ NativeManager::NativeManager() {
}
// 创建节点组件
ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
nodeId=tag;
nodeId=tag;
// 创建Node也名创建ROW Column等容器
ArkUI_NodeHandle nodeHandel = nodeAPI->createNode(ARKUI_NODE_RELATIVE_CONTAINER);
// 节点默认宽度or高度
@ -326,7 +315,7 @@ ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
ArkUI_AttributeItem nodeMarginItem = {nodeMarginData, 2};
// 设置Node宽度or高度
nodeAPI->setAttribute(nodeHandel, NODE_MARGIN, &nodeMarginItem);
NativeManager::nodeHandleMap_[tag]=nodeHandel;
NativeMgr::nodeHandleMap_[tag]=nodeHandel;
// 创建XComponent组件
// 组件类型Item
ArkUI_NumberValue comTypeData[] = {ARKUI_XCOMPONENT_TYPE_SURFACE};
@ -357,9 +346,9 @@ ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
return nodeHandel;
}
// 注册XComponent回调函数
OH_NativeXComponent_RegisterCallback(nativeXComponent, &NativeManager::xSurfaceTouchEventCallBack);
OH_NativeXComponent_RegisterCallback(nativeXComponent, &NativeMgr::xSurfaceTouchEventCallBack);
//注册XComponent组件鼠标回调事件
OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &NativeManager::xMouseEventCallBack);
OH_NativeXComponent_RegisterMouseEventCallback(nativeXComponent, &NativeMgr::xMouseEventCallBack);
// nodeAPI->registerNodeEvent(xc, NODE_ON_MOUSE, 1, &xc);
// nodeAPI->registerNodeEvent(xc, NODE_ON_AXIS, 1, &xc);
// nodeAPI->addNodeEventReceiver(xc, [](ArkUI_NodeEvent *event) {
@ -406,22 +395,23 @@ ArkUI_NodeHandle CreateNodeHandle(const std::string &tag) {
// 增加组件到节点
nodeAPI->addChild(nodeHandel, xc);
return nodeHandel;
}
// Native侧创建Node
napi_value NativeManager::createNativeNode(napi_env env, napi_callback_info info) {
napi_value NativeMgr::initNativeNode(napi_env env, napi_callback_info info) {
if ((env == nullptr) || (info == nullptr)) {
HILOG_ERROR(NATIVE_TAG,"CreateNativeNode env or info is null");
return nullptr;
}
//获取传入NodeContent实例
size_t argCnt = 1;
napi_value args[1] = {nullptr};
size_t argCnt = 3;
napi_value args[3] = {nullptr,nullptr,nullptr};
if (napi_get_cb_info(env, info, &argCnt, args, nullptr, nullptr) != napi_ok) {
HILOG_ERROR(NATIVE_TAG,"CreateNativeNode napi_get_cb_info failed");
}
ArkUI_NodeContentHandle _nodeContentHandle = nullptr;
// 获取ArkTS侧创建的NodeContent对象映射到Native侧的
OH_ArkUI_GetNodeContentFromNapiValue(env, args[0], &_nodeContentHandle);
OH_ArkUI_GetNodeContentFromNapiValue(env, args[2], &_nodeContentHandle);
// 查询指定的模块接口名
nodeAPI = reinterpret_cast<ArkUI_NativeNodeAPI_1 *>(OH_ArkUI_QueryModuleInterfaceByName(ARKUI_NATIVE_NODE, "ArkUI_NativeNodeAPI_1"));
//下面的代码主要用于创建一个Native侧和arkui侧绑定数据的结构传递传输的操作
@ -457,8 +447,9 @@ napi_value NativeManager::createNativeNode(napi_env env, napi_callback_info info
}
return nullptr;
}
//设置期望帧率
napi_value NativeManager::SetFrameRate(napi_env env, napi_callback_info info) {
napi_value NativeMgr::SetFrameRate(napi_env env, napi_callback_info info) {
size_t argc = 4;
napi_value args[4] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
@ -477,7 +468,7 @@ napi_value NativeManager::SetFrameRate(napi_env env, napi_callback_info info) {
OH_ArkUI_XComponent_SetExpectedFrameRateRange(node, range); // 设置期望帧率
return nullptr;
}
napi_value NativeManager::SetNeedSoftKeyboard(napi_env env, napi_callback_info info) {
napi_value NativeMgr::SetNeedSoftKeyboard(napi_env env, napi_callback_info info) {
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
@ -494,7 +485,7 @@ napi_value NativeManager::SetNeedSoftKeyboard(napi_env env, napi_callback_info i
OH_ArkUI_XComponent_SetNeedSoftKeyboard(node, needSoftKeyboard); // 设置是否需要软键盘
return nullptr;
}
napi_value NativeManager::NapiLoadModel(napi_env env, napi_callback_info info) {
napi_value NativeMgr::NapiLoadModel(napi_env env, napi_callback_info info) {
size_t argc = 1;
napi_value args[1];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
@ -510,7 +501,7 @@ napi_value NativeManager::NapiLoadModel(napi_env env, napi_callback_info info) {
}
//切换视图
napi_value NativeManager::SwitchView(napi_env env, napi_callback_info info){
napi_value NativeMgr::SwitchView(napi_env env, napi_callback_info info){
size_t argc = 1;
napi_value args[1];
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
@ -526,15 +517,15 @@ napi_value NativeManager::SwitchView(napi_env env, napi_callback_info info){
}
//显示模型边界
napi_value NativeManager::displayModelEdges(napi_env env, napi_callback_info info){
napi_value NativeMgr::displayModelEdges(napi_env env, napi_callback_info info){
}
//显示模型线框
napi_value NativeManager::displayHLR(napi_env env, napi_callback_info info){
napi_value NativeMgr::displayHLR(napi_env env, napi_callback_info info){
}
//显示隐藏线
napi_value NativeManager::displayHL(napi_env env, napi_callback_info info){
napi_value NativeMgr::displayHL(napi_env env, napi_callback_info info){
}

View File

@ -41,21 +41,21 @@ constexpr const int THIRD_ARG = 3;
constexpr const int FRAME_COUNT = 50;
class NativeManager {
class NativeMgr {
public:
static OH_NativeXComponent_Callback xSurfaceTouchEventCallBack;
//鼠标事件回调
static OH_NativeXComponent_MouseEvent_Callback xMouseEventCallBack;
NativeManager();
~NativeManager();
NativeMgr();
~NativeMgr();
static NativeManager* GetInstance()
static NativeMgr* GetInstance()
{
return &NativeManager::pluginManager_;
return &NativeMgr::pluginManager_;
}
static napi_value createNativeNode(napi_env env, napi_callback_info info);
static napi_value initNativeNode(napi_env env, napi_callback_info info);
static napi_value SetFrameRate(napi_env env, napi_callback_info info);
static napi_value SetNeedSoftKeyboard(napi_env env, napi_callback_info info);
static napi_value NapiLoadModel(napi_env env, napi_callback_info info);
@ -75,9 +75,9 @@ public:
void OnSurfaceCreated(OH_NativeXComponent* component, void* window);
void OnMouseEvent(OH_NativeXComponent *component, void *window);
private:
static NativeManager pluginManager_;
static NativeMgr pluginManager_;
std::unordered_map<std::string, OH_NativeXComponent*> nativeXComponentMap_;
std::unordered_map<std::string, NativeManager*> pluginManagerMap_;
std::unordered_map<std::string, NativeMgr*> pluginManagerMap_;
public:
// [StartExclude plugin_manager_h_part]
OH_NativeXComponent_TouchEvent touchEvent_;
@ -100,7 +100,6 @@ public:
bool isMouseMiddleBtnPressed;
static std::unordered_map<std::string, ArkUI_NodeHandle> nodeHandleMap_;
static std::unordered_map<void *, OH_ArkUI_SurfaceCallback *> callbackMap_;
static std::unordered_map<void *, OH_ArkUI_SurfaceHolder *> surfaceHolderMap_;
static ArkUI_AccessibilityProvider *provider_;
};
}

View File

@ -39,7 +39,7 @@ bool V3dTriCube::InitV3dTriCube(Handle(AIS_InteractiveContext)& ctx){
triCube->SetBoxSideLabel(V3d_Zneg, TCollection_AsciiString(bottomCube.c_str()));
triCube->SetSize(100, true);
triCube->SetFontHeight(30);
triCube->AcceptDisplayMode(true);
triCube->SetZLayer(Graphic3d_ZLayerId_TopOSD);
ctx->Display(triCube, true);
HILOG_INFO(NATIVE_TAG, "Init V3dTriCube Done");
return true;

View File

@ -1,10 +0,0 @@
//
// Created on 2024/10/12.
//
// Node APIs are not fully supported. To solve the compilation error of the interface cannot be found,
// please include "napi/native_api.h".
#ifndef NATIVESOINTEGRATION_ADD_H
#define NATIVESOINTEGRATION_ADD_H
double Add(double a, double b);
#endif // NATIVESOINTEGRATION_ADD_H

View File

@ -1,34 +1,7 @@
#include "napi/native_api.h"
#include "hilog/log.h"
#include "Add/Add.h"
#include "NativeEGLOCCT/common.h"
#include "NativeEGLOCCT/NativeManager.h"
static napi_value NativeLoadSoTest(napi_env env, napi_callback_info info)
{
size_t argc = 2;
napi_value args[2] = {nullptr};
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
napi_valuetype valuetype0;
napi_typeof(env, args[0], &valuetype0);
napi_valuetype valuetype1;
napi_typeof(env, args[1], &valuetype1);
double value0;
napi_get_value_double(env, args[0], &value0);
double value1;
napi_get_value_double(env, args[1], &value1);
auto _sum=Add(value0,value1);
napi_value sum;
napi_create_double(env, _sum, &sum);
return sum;
}
#include "NativeEGLOCCT/NativeMgr.h"
namespace NativeOpenCAX {
EXTERN_C_START
@ -40,13 +13,12 @@ static napi_value Init(napi_env env, napi_value exports) {
}
napi_property_descriptor desc[] = {
// [StartExclude napi_init_part]
{"createNativeNode", nullptr, NativeManager::createNativeNode, nullptr, nullptr, nullptr,napi_default, nullptr },
{"loadModel", nullptr, NativeManager::NapiLoadModel, nullptr, nullptr, nullptr, napi_default, nullptr},
{"setFrameRate", nullptr, NativeManager::SetFrameRate, nullptr, nullptr, nullptr, napi_default, nullptr},
{"setNeedSoftKeyboard", nullptr, NativeManager::SetNeedSoftKeyboard, nullptr, nullptr, nullptr, napi_default,nullptr},
{"nativeLoadTest", nullptr, NativeLoadSoTest, nullptr, nullptr, nullptr, napi_default, nullptr},
{"InitNativeNode", nullptr, NativeMgr::initNativeNode, nullptr, nullptr, nullptr,napi_default, nullptr },
{"loadModel", nullptr, NativeMgr::NapiLoadModel, nullptr, nullptr, nullptr, napi_default, nullptr},
{"setFrameRate", nullptr, NativeMgr::SetFrameRate, nullptr, nullptr, nullptr, napi_default, nullptr},
{"setNeedSoftKeyboard", nullptr, NativeMgr::SetNeedSoftKeyboard, nullptr, nullptr, nullptr, napi_default,nullptr},
//切换视图
{"switchView", nullptr, NativeManager::SwitchView, nullptr, nullptr, nullptr,napi_default, nullptr },
{"switchView", nullptr, NativeMgr::SwitchView, nullptr, nullptr, nullptr,napi_default, nullptr },
};
napi_status status = napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
if (status != napi_ok) {

View File

@ -2,6 +2,6 @@ export interface NativeXOpenCAX {
setFrameRate(nodeId: string, min: number, max: number, expected: number): void;
setNeedSoftKeyboard(nodeId: string, need: boolean): void;
}
export function createNativeNode(nodeContent: any): void;
export function InitNativeNode(xId:string,initType:boolean,nodeContent: any): void;
export function loadModel(stepFilePath: string): void;
export function switchView(viewName: string): void;

View File

@ -1,5 +1,5 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { ExecuteCommand } from '../EventSubWindow/ExecuteCommand';
import { ExecuteCommand } from '../EventSubWin/ExCom';
import { TitleButton } from "../LayoutInterface/Interface/ButtonInterface";
import { TitleModel } from "../LayoutInterface/Interface/ModelInterface";
import { TitleTabData } from '../LayoutInterface/Layout/TitleTabData';

View File

@ -1,5 +1,5 @@
import { mwInfo } from "../AppStorageV2Class";
import { ExecuteCommand } from "../EventSubWindow/ExecuteCommand";
import { ExecuteCommand } from "../EventSubWin/ExCom";
import { TitleButton } from "../LayoutInterface/Interface/ButtonInterface";
import {SwitchView} from "../LayoutInterface/Layout/SwitchView"

View File

@ -1,6 +1,6 @@
import { TitleGroup } from "../LayoutInterface/Interface/GroupInterface";
import { TitleButton } from "../LayoutInterface/Interface/ButtonInterface";
import { ExecuteCommand } from "../EventSubWindow/ExecuteCommand";
import { ExecuteCommand } from "../EventSubWin/ExCom";
import { mwInfo } from "../AppStorageV2Class";
import { BaseMenuData } from "../LayoutInterface/Interface/MenuInterface";

View File

@ -1,15 +1,63 @@
import { TitleButton } from '../LayoutInterface/Interface/ButtonInterface';
import { OCCTLoadModel } from '../modelView';
import { CloseSubWindow, CreateAndShowSubWindow, WinInfo} from './SWBase';
import NativeOpenCAX from 'libopencax.so';
import { mwInfo } from '../AppStorageV2Class';
import {NodeContent} from '@kit.ArkUI';
export interface XComp{
xId?:string;
name?:string;
icon?:string;
node?:NodeContent;
}
export let XComps:Array<XComp>=[];
export let currentXComp:XComp={};
function XNRandomId(): string {
// 获取当前时间戳(毫秒)
const now = Date.now();
// 取时间戳的最后几位例如4位作为基础部分
const timePart = parseInt(now.toString().slice(-4));
// 生成剩余的4位随机数
const randomPart = Math.floor(Math.random() * 10000);
// 组合两部分并取模和偏移以确保在8位数范围内
// 例如: timePart (0-9999) + randomPart (0-9999) -> sum (0-19998)
// 需要将其映射到 [10000000, 99999999]
// 结果在 [0, 89999999]
const combined = (timePart * 10000 + randomPart) % 90000000;
// 调整范围到 [10000000, 99999999]
return (combined + 10000000).toString();
}
export function InitXCompNode(name:string){
//数组为0表示初始化,Native侧这初始化主上下文,否则Native侧初始化共享上下文
let ncInfo:XComp={};
ncInfo.xId=XNRandomId();
ncInfo.name=name+XNRandomId();
ncInfo.node=new NodeContent();
if(XComps.length==0)
{
NativeOpenCAX.InitNativeNode(ncInfo.xId,true,ncInfo.node);
}else{
NativeOpenCAX.InitNativeNode(ncInfo.xId,false,ncInfo.node);
}
XComps.push(ncInfo);
console.log(`ArkUI XComp ID: ${ncInfo.xId}`);
}
export function CurrentXCompIndex(id:number):XComp{
return currentXComp=XComps[id];
}
export function ExecuteCommand(event:TitleButton){
//事件处理
if(event?.eEvent=='Execute_LoadModel'){
OCCTLoadModel(undefined,undefined)
//NativeOpenCAX.loadModel(undefined,undefined);
}
if(event?.eEvent=='Create_New'){
InitXCompNode("nullptr");
}
//窗体打开
if(event?.eEvent=='Execute_CreateSubWindow'){
const winInfo:WinInfo=new WinInfo(event.eName,event.ePage,mwInfo.mWinWidth*0.3,mwInfo.mWinHeight*0.9);

View File

@ -2,7 +2,7 @@ import { hilog } from '@kit.PerformanceAnalysisKit';
import { edgeColors, display, AppStorageV2 } from '@kit.ArkUI';
import { TitleTab } from './TitleLayout/TitleTab'
import { LeftSideTab } from './LeftSideLayout/LeftSideTab'
import { ModelViewTab } from './modelViewTab'
import { ModelViewTab } from './ModelViewTab'
import { TitleColumnSub } from './TitleLayout/TitleColumnSub'
import { mwInfo } from './AppStorageV2Class'
import fs from '@ohos.file.fs';

View File

@ -17,6 +17,7 @@ export let MatrixModel:TitleModel= {
export let DevModel:TitleModel= {
cmName:"开发模式",cmPage:"",cmTips:"",cmEvents:[
[[{grpName:'工具矩阵',grpBtn:[
{eModel:[ModelType.BASE],eName:"新建实例",eNamed:"",ePage:'',eIcon:"base_new_file",eTips:"",eEvent:"Create_New"},
{eModel:[ModelType.BASE],eName:"加载模型",eNamed:"",ePage:'',eIcon:"base_new_file",eTips:"",eEvent:"Execute_LoadModel"},
{eModel:[ModelType.BASE],eName:"正等轴测图",eNamed:"",ePage:'',eIcon:"base_new_file",eTips:"",eEvent:"CMD_VIEW_ISO"},
{eModel:[ModelType.BASE],eName:"正二等轴测图",eNamed:"",ePage:'',eIcon:"base_new_file",eTips:"",eEvent:"CMD_VIEW_DIM"},

View File

@ -1,38 +1,31 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import { MainWindowInfo } from './AppStorageV2Class';
import {ModelView} from './modelView'
import { AppStorageV2 } from '@kit.ArkUI';
class TaskTab{
icon:string=''
str:string='default model'
event:string=''
}
let dTab:Array<TaskTab>=[
{icon:'',str:'默认任务',event:''}
]
import {InitXCompNode,XComps, XComp,CurrentXCompIndex} from './EventSubWin/ExCom'
@ComponentV2
export struct ModelViewTab {
@Local mwInfo: MainWindowInfo = AppStorageV2.connect<MainWindowInfo>(MainWindowInfo, () => new MainWindowInfo())!;
//顶部导航组件
private modelViewBarTabs: TabsController = new TabsController();
private barTabs: TabsController = new TabsController();
//当前的顶部导航选择页
@Local modelViewBarFocusIndex: number = 0;
@Local modelFilePath:string='';
@Local barFocusIndex: number = 0;
aboutToAppear(): void {
InitXCompNode('测试')
}
build() {
Flex({ direction: FlexDirection.Column }) {
Scroll() {
Row() {
ForEach(dTab, (item: TaskTab, index: number) => {
ForEach(XComps, (item: XComp, index: number) => {
Row({ space: 0 }) {
Image($r('app.media.startIcon'))
.width(this.mwInfo.mWinWidth*0.012)
.height(this.mwInfo.mWinWidth*0.012)
.objectFit(ImageFit.Contain)
Button(item.str)
.fontWeight(index === this.modelViewBarFocusIndex ? FontWeight.Bold : FontWeight.Normal)
Button(item.name)
.fontWeight(index === this.barFocusIndex ? FontWeight.Bold : FontWeight.Normal)
.width('auto')
.height(this.mwInfo.mWinWidth*0.012)
.type(ButtonType.Normal)
@ -43,8 +36,9 @@ export struct ModelViewTab {
.type(ButtonType.Normal)
.align(Alignment.Center)
}.onClick(() => {
this.modelViewBarTabs.changeIndex(index);
this.modelViewBarFocusIndex = index;
this.barTabs.changeIndex(index);
this.barFocusIndex = index;
CurrentXCompIndex(index);
})
})
}
@ -54,11 +48,13 @@ export struct ModelViewTab {
.width('100%')
//分割线
Divider().vertical(false).strokeWidth(1).color(0x000000).lineCap(LineCapStyle.Round).width('100%').backgroundColor(Color.Gray)
Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.modelViewBarTabs }) {
TabContent() {
ModelView()
}.align(Alignment.Start)
.padding(1)
Tabs({ barPosition: BarPosition.Start, index: 0, controller: this.barTabs }) {
ForEach(XComps,(item:XComp, index: number)=>{
TabContent() {
ContentSlot(item.node);
}.align(Alignment.Start)
.padding(1)
})
}.scrollable(false)
.barHeight(0)
.height('auto')

View File

@ -1,69 +0,0 @@
import { hilog } from '@kit.PerformanceAnalysisKit';
import fs from '@ohos.file.fs';
import fileIO from '@ohos.fileio';
import {NodeContent} from '@kit.ArkUI';
import NativeOpenCAX from 'libopencax.so';
const DOMAIN = 0x0000;
let modelPath: string = '';
export function OCCTLoadModel(Command: undefined, Param:undefined) {
try {
NativeOpenCAX.loadModel(modelPath);
console.info('Model copied to:', modelPath);
} catch (e) {
hilog.error(0x0000, 'ModelView', `LoadModel Failed: ${JSON.stringify(e)}`);
}
}
@Component
export struct ModelView {
private displayController: XComponentController = new XComponentController();
private displayContrId: string = 'OCCTRender';
@State modelName:string='2027.stp';
@State currentStatus: string = 'init';
private nodeContent: NodeContent = new NodeContent();
aboutToAppear() {
NativeOpenCAX.createNativeNode(this.nodeContent);
this.copyRawFileToSandbox();
}
async copyRawFileToSandbox() {
try {
const context = getContext(this);
modelPath = `${context.filesDir}/${this.modelName}`;
const arrayBuffer:Uint8Array = await context.resourceManager.getRawFileContent(this.modelName);
const buffer = arrayBuffer.buffer;
console.log('Raw file size:', arrayBuffer.byteLength);
if (fs.accessSync(modelPath)) {
fs.unlinkSync(modelPath);
}
const fd = fileIO.openSync(modelPath, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE,0o666);
const bytesWritten = fileIO.writeSync(fd, buffer);
console.log('Bytes written:', bytesWritten);
fileIO.closeSync(fd);
console.log('SanBox File:', arrayBuffer.byteLength);
console.log('WriteModelPath:', modelPath);
} catch (err) {
let msg = 'Unknown error';
if (err instanceof Error) {
msg = err.message;
} else if (typeof err === 'string') {
msg = err;
}
console.error(`Copy failed: ${msg}`);
throw new Error(`Failed to copy ${this.modelName} to sandbox: ${msg}`);
}
}
build() {
Flex({ direction: FlexDirection.Column }) {
Row(){
ContentSlot(this.nodeContent);
}.layoutWeight(1)
}.backgroundColor('#f3f3f0')
.width('100%')
.height('100%');
}
}

View File

@ -1,8 +1,8 @@
{
"src": [
"pages/Index",
"pages/EventSubWindow/SWLine",
"pages/EventSubWindow/SWExtrude",
"pages/EventSubWindow/Options"
"pages/EventSubWin/SWLine",
"pages/EventSubWin/SWExtrude",
"pages/EventSubWin/Options"
]
}