检查库的连接路径 #1
@ -17,7 +17,7 @@
|
||||
"arkOptions": {
|
||||
"runtimeOnly" : {
|
||||
"packages": [
|
||||
"libOCCTRender.so"
|
||||
"libocctrender.so"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,13 +6,13 @@
|
||||
"lockfileVersion": 3,
|
||||
"ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.",
|
||||
"specifiers": {
|
||||
"libOCCTRender.so@src/main/cpp/types/libOCCTRender": "libOCCTRender.so@src/main/cpp/types/libOCCTRender"
|
||||
"libocctrender.so@src/main/cpp/types/libocctrender": "libocctrender.so@src/main/cpp/types/libocctrender"
|
||||
},
|
||||
"packages": {
|
||||
"libOCCTRender.so@src/main/cpp/types/libOCCTRender": {
|
||||
"name": "libOCCTRender.so",
|
||||
"libocctrender.so@src/main/cpp/types/libocctrender": {
|
||||
"name": "libocctrender.so",
|
||||
"version": "1.0.0",
|
||||
"resolved": "src/main/cpp/types/libOCCTRender",
|
||||
"resolved": "src/main/cpp/types/libocctrender",
|
||||
"registryType": "local"
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,6 +6,6 @@
|
||||
"author": "",
|
||||
"license": "",
|
||||
"dependencies": {
|
||||
"libOCCTRender.so": "file:./src/main/cpp/types/libOCCTRender"
|
||||
"libocctrender.so": "file:./src/main/cpp/types/libocctrender"
|
||||
}
|
||||
}
|
||||
@ -14,31 +14,8 @@ include_directories(${NATIVERENDER_ROOT_PATH}
|
||||
${NATIVERENDER_ROOT_PATH}/include)
|
||||
|
||||
# OCCT库配置
|
||||
set(OCCT_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/opencascade)
|
||||
set(OCCT_LIB_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${OHOS_ARCH})
|
||||
|
||||
# 添加OCCT库
|
||||
link_directories(${OCCT_LIB_DIR})
|
||||
include_directories(${OCCT_INCLUDE_DIR})
|
||||
|
||||
# 添加源文件
|
||||
add_library(OCCTRender SHARED
|
||||
napi_init.cpp
|
||||
#Header
|
||||
EGLCore/EGLCore.h
|
||||
OCCTRender/OCCTRender.h
|
||||
OCCTRenderThread/OCCTRenderThread.h
|
||||
#Cpp Src
|
||||
EGLCore/EGLCore.cpp
|
||||
OCCTRender/OCCTRender.cpp
|
||||
OCCTRenderThread/OCCTRenderThread.cpp
|
||||
)
|
||||
|
||||
find_library(EGL-lib EGL)
|
||||
find_library(GLES-lib GLESv3)
|
||||
find_library(hilog-lib hilog_ndk.z)
|
||||
find_library(libace-lib ace_ndk.z)
|
||||
find_library(libuv-lib uv)
|
||||
|
||||
set(OCCT_LIBS
|
||||
${OCCT_LIB_DIR}/libTKernel.so.7.9
|
||||
@ -77,8 +54,26 @@ set(OCCT_LIBS
|
||||
${OCCT_LIB_DIR}/libbrotlidec.so.1
|
||||
${OCCT_LIB_DIR}/libbrotlienc.so.1
|
||||
)
|
||||
# 添加源文件
|
||||
add_library(occtrender SHARED
|
||||
napi_init.cpp
|
||||
#Header
|
||||
EGLCore/EGLCore.h
|
||||
OCCTRender/OCCTRender.h
|
||||
OCCTRenderThread/OCCTRenderThread.h
|
||||
#Cpp Src
|
||||
EGLCore/EGLCore.cpp
|
||||
OCCTRender/OCCTRender.cpp
|
||||
OCCTRenderThread/OCCTRenderThread.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(OCCTRender PUBLIC
|
||||
find_library(EGL-lib EGL)
|
||||
find_library(GLES-lib GLESv3)
|
||||
find_library(hilog-lib hilog_ndk.z)
|
||||
find_library(libace-lib ace_ndk.z)
|
||||
find_library(libuv-lib uv)
|
||||
|
||||
target_link_libraries(occtrender PUBLIC
|
||||
# OCCT核心库
|
||||
${OCCT_LIBS}
|
||||
#EGL Hilog库
|
||||
|
||||
12
entry/src/main/cpp/OCCT方案.txt
Normal file
12
entry/src/main/cpp/OCCT方案.txt
Normal file
@ -0,0 +1,12 @@
|
||||
按照下面要求生成实现代码:
|
||||
1-HarmonyOS API 版本:22
|
||||
2-OpenGL ES 版本:3.0
|
||||
3-OCCT 版本:7.9.3
|
||||
4-分别用类名字为EGLCore OCCTRenderThread OCCTRender实现
|
||||
5-实现主线程和渲染线程分离.渲染线程循环渲染
|
||||
6-实现通过loadmodel加载step文件进行渲染step模型
|
||||
7-实现鼠标旋转相机观察渲染的模型.
|
||||
8-Arkui通过XComponent的Native进行调用实现.
|
||||
9-不得使用android的实现代码.使用鸿蒙原生API实现
|
||||
10-在napi_init.cpp文件中写出给arkui调用的函数.包括回调函数
|
||||
11-在Index.d.ts文件中写出暴露给arkui调用的代码
|
||||
@ -1,140 +1,115 @@
|
||||
#include "napi/native_api.h"
|
||||
//#include "OCCTRenderThread/OCCTRenderThread.h"
|
||||
#include "OCCTRenderThread/OCCTRenderThread.h"
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
//#define LOG_TAG "NAPI_INIT"
|
||||
//#define LOGI(...) (LOG_TAG, __VA_ARGS__)
|
||||
//
|
||||
////存储 XComponent ID 到 OCCTRenderThread 实例的映射
|
||||
//static std::map<std::string, OCCTRenderThread*> g_renderThreads;
|
||||
//
|
||||
////NAPI: 初始化渲染器(绑定 XComponent)
|
||||
//static napi_value InitRenderer(napi_env env, napi_callback_info info) {
|
||||
// size_t argc = 3;
|
||||
// napi_value args[3];
|
||||
// napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
//
|
||||
// // 参数1: xcomponentId (string)
|
||||
// char xcompId[256];
|
||||
// size_t xcompIdLen;
|
||||
// napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &xcompIdLen);
|
||||
//
|
||||
// // 参数2: nativeWindow (EGLNativeWindowType, 实际是 void*)
|
||||
// EGLNativeWindowType window = nullptr;
|
||||
// napi_get_value_external(env, args[1], reinterpret_cast<void**>(&window));
|
||||
//
|
||||
// // 参数3: { width, height }
|
||||
// int32_t width = 0, height = 0;
|
||||
// napi_valuetype type;
|
||||
// napi_typeof(env, args[2], &type);
|
||||
// if (type == napi_object) {
|
||||
// napi_value w, h;
|
||||
// napi_get_named_property(env, args[2], "width", &w);
|
||||
// napi_get_named_property(env, args[2], "height", &h);
|
||||
// napi_get_value_int32(env, w, &width);
|
||||
// napi_get_value_int32(env, h, &height);
|
||||
// }
|
||||
//
|
||||
// // 创建渲染线程
|
||||
// LOGI('Init RenderThread');
|
||||
// auto* renderThread = new OCCTRenderThread(window, width, height);
|
||||
// renderThread->start();
|
||||
// LOGI('Deno Init RenderThread');
|
||||
// g_renderThreads[std::string(xcompId)] = renderThread;
|
||||
//
|
||||
// return nullptr;
|
||||
//}
|
||||
//
|
||||
//// NAPI: 加载 STEP 模型
|
||||
//static napi_value LoadModel(napi_env env, napi_callback_info info) {
|
||||
// LOGI('Start LoadModel');
|
||||
// size_t argc = 2;
|
||||
// napi_value args[2];
|
||||
// napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
//
|
||||
// char xcompId[256];
|
||||
// size_t len;
|
||||
// napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len);
|
||||
//
|
||||
// char modelPath[1024];
|
||||
// size_t pathLen;
|
||||
// napi_get_value_string_utf8(env, args[1], modelPath, sizeof(modelPath), &pathLen);
|
||||
// LOGI('Find RenderThread');
|
||||
// auto it = g_renderThreads.find(std::string(xcompId));
|
||||
// if (it != g_renderThreads.end()) {
|
||||
// LOGI('LoadModel Began');
|
||||
// it->second->loadModel(modelPath);
|
||||
// }
|
||||
//
|
||||
// return nullptr;
|
||||
//}
|
||||
//
|
||||
//// NAPI: 鼠标/触摸事件(可选,用于旋转)
|
||||
//static napi_value OnMouseEvent(napi_env env, napi_callback_info info) {
|
||||
// size_t argc = 3;
|
||||
// napi_value args[3];
|
||||
// napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
//
|
||||
// char xcompId[256];
|
||||
// size_t len;
|
||||
// napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len);
|
||||
//
|
||||
// double dx, dy;
|
||||
// napi_get_value_double(env, args[1], &dx);
|
||||
// napi_get_value_double(env, args[2], &dy);
|
||||
//
|
||||
// auto it = g_renderThreads.find(std::string(xcompId));
|
||||
// if (it != g_renderThreads.end()) {
|
||||
// it->second->onMouseEvent(static_cast<float>(dx), static_cast<float>(dy));
|
||||
// }
|
||||
//
|
||||
// return nullptr;
|
||||
//}
|
||||
//
|
||||
//// NAPI: 销毁渲染器
|
||||
//static napi_value DestroyRenderer(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);
|
||||
//
|
||||
// char xcompId[256];
|
||||
// size_t len;
|
||||
// napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len);
|
||||
//
|
||||
// auto it = g_renderThreads.find(std::string(xcompId));
|
||||
// if (it != g_renderThreads.end()) {
|
||||
// it->second->stop();
|
||||
// delete it->second;
|
||||
// g_renderThreads.erase(it);
|
||||
// }
|
||||
//
|
||||
// return nullptr;
|
||||
//}
|
||||
#define LOG_TAG "NAPI_INIT"
|
||||
#define LOGI(...) (LOG_TAG, __VA_ARGS__)
|
||||
|
||||
static napi_value Add(napi_env env, napi_callback_info info)
|
||||
{
|
||||
size_t argc = 2;
|
||||
napi_value args[2] = {nullptr};
|
||||
//存储 XComponent ID 到 OCCTRenderThread 实例的映射
|
||||
static std::map<std::string, OCCTRenderThread*> g_renderThreads;
|
||||
|
||||
//NAPI: 初始化渲染器(绑定 XComponent)
|
||||
static napi_value InitRenderer(napi_env env, napi_callback_info info) {
|
||||
size_t argc = 3;
|
||||
napi_value args[3];
|
||||
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
|
||||
napi_valuetype valuetype0;
|
||||
napi_typeof(env, args[0], &valuetype0);
|
||||
// 参数1: xcomponentId (string)
|
||||
char xcompId[256];
|
||||
size_t xcompIdLen;
|
||||
napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &xcompIdLen);
|
||||
|
||||
napi_valuetype valuetype1;
|
||||
napi_typeof(env, args[1], &valuetype1);
|
||||
// 参数2: nativeWindow (EGLNativeWindowType, 实际是 void*)
|
||||
EGLNativeWindowType window = nullptr;
|
||||
napi_get_value_external(env, args[1], reinterpret_cast<void**>(&window));
|
||||
|
||||
double value0;
|
||||
napi_get_value_double(env, args[0], &value0);
|
||||
// 参数3: { width, height }
|
||||
int32_t width = 0, height = 0;
|
||||
napi_valuetype type;
|
||||
napi_typeof(env, args[2], &type);
|
||||
if (type == napi_object) {
|
||||
napi_value w, h;
|
||||
napi_get_named_property(env, args[2], "width", &w);
|
||||
napi_get_named_property(env, args[2], "height", &h);
|
||||
napi_get_value_int32(env, w, &width);
|
||||
napi_get_value_int32(env, h, &height);
|
||||
}
|
||||
|
||||
double value1;
|
||||
napi_get_value_double(env, args[1], &value1);
|
||||
// 创建渲染线程
|
||||
LOGI('Init RenderThread');
|
||||
auto* renderThread = new OCCTRenderThread(window, width, height);
|
||||
renderThread->start();
|
||||
LOGI('Deno Init RenderThread');
|
||||
g_renderThreads[std::string(xcompId)] = renderThread;
|
||||
|
||||
napi_value sum;
|
||||
napi_create_double(env, value0 + value1, &sum);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return sum;
|
||||
// NAPI: 加载 STEP 模型
|
||||
static napi_value LoadModel(napi_env env, napi_callback_info info) {
|
||||
LOGI('Start LoadModel');
|
||||
size_t argc = 2;
|
||||
napi_value args[2];
|
||||
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
|
||||
char xcompId[256];
|
||||
size_t len;
|
||||
napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len);
|
||||
|
||||
char modelPath[1024];
|
||||
size_t pathLen;
|
||||
napi_get_value_string_utf8(env, args[1], modelPath, sizeof(modelPath), &pathLen);
|
||||
LOGI('Find RenderThread');
|
||||
auto it = g_renderThreads.find(std::string(xcompId));
|
||||
if (it != g_renderThreads.end()) {
|
||||
LOGI('LoadModel Began');
|
||||
it->second->loadModel(modelPath);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NAPI: 鼠标/触摸事件(可选,用于旋转)
|
||||
static napi_value OnMouseEvent(napi_env env, napi_callback_info info) {
|
||||
size_t argc = 3;
|
||||
napi_value args[3];
|
||||
napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);
|
||||
|
||||
char xcompId[256];
|
||||
size_t len;
|
||||
napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len);
|
||||
|
||||
double dx, dy;
|
||||
napi_get_value_double(env, args[1], &dx);
|
||||
napi_get_value_double(env, args[2], &dy);
|
||||
|
||||
auto it = g_renderThreads.find(std::string(xcompId));
|
||||
if (it != g_renderThreads.end()) {
|
||||
it->second->onMouseEvent(static_cast<float>(dx), static_cast<float>(dy));
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// NAPI: 销毁渲染器
|
||||
static napi_value DestroyRenderer(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);
|
||||
|
||||
char xcompId[256];
|
||||
size_t len;
|
||||
napi_get_value_string_utf8(env, args[0], xcompId, sizeof(xcompId), &len);
|
||||
|
||||
auto it = g_renderThreads.find(std::string(xcompId));
|
||||
if (it != g_renderThreads.end()) {
|
||||
it->second->stop();
|
||||
delete it->second;
|
||||
g_renderThreads.erase(it);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
EXTERN_C_START
|
||||
@ -143,11 +118,10 @@ static napi_value Init(napi_env env, napi_value exports) {
|
||||
return nullptr;
|
||||
}
|
||||
napi_property_descriptor desc[] = {
|
||||
//{"initRenderer", nullptr, InitRenderer,nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
//{"loadModel", nullptr, LoadModel,nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
//{"onMouseEvent", nullptr, OnMouseEvent,nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
//{"destroyRenderer", nullptr, DestroyRenderer,nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
{ "add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr }
|
||||
{"initRenderer", nullptr, InitRenderer,nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
{"loadModel", nullptr, LoadModel,nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
{"onMouseEvent", nullptr, OnMouseEvent,nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
{"destroyRenderer", nullptr, DestroyRenderer,nullptr, nullptr, nullptr, napi_default, nullptr},
|
||||
};
|
||||
|
||||
if (napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc) != napi_ok) {
|
||||
@ -158,17 +132,17 @@ static napi_value Init(napi_env env, napi_value exports) {
|
||||
EXTERN_C_END
|
||||
|
||||
// 编写接口的描述信息,根据实际需要可以修改对应参数
|
||||
static napi_module OCCTModel = {
|
||||
static napi_module occtmodel = {
|
||||
.nm_version = 1,
|
||||
.nm_flags = 0,
|
||||
.nm_filename = nullptr,
|
||||
.nm_register_func = Init,
|
||||
.nm_modname = "OCCTRender",
|
||||
.nm_modname = "occtrender",
|
||||
.nm_priv = ((void*)0),
|
||||
.reserved = { 0 }
|
||||
};
|
||||
|
||||
extern "C" __attribute__((constructor)) void RegisterModule(void)
|
||||
{
|
||||
napi_module_register(&OCCTModel);
|
||||
napi_module_register(&occtmodel);
|
||||
}
|
||||
@ -2,7 +2,7 @@ import { hilog } from '@kit.PerformanceAnalysisKit';
|
||||
import fs from '@ohos.file.fs';
|
||||
import fileIO from '@ohos.fileio';
|
||||
import { Context } from '@kit.AbilityKit';
|
||||
//import OCCTRender from 'libOCCTRender.so';
|
||||
import OCCTRender from 'libocctrender.so';
|
||||
|
||||
const DOMAIN = 0x0000;
|
||||
|
||||
@ -46,6 +46,7 @@ export struct ModelView {
|
||||
}
|
||||
build() {
|
||||
Flex({ direction: FlexDirection.Column }) {
|
||||
Row(){
|
||||
Button('加载模型').onClick(()=>{
|
||||
try {
|
||||
// 调用 native 初始化渲染器
|
||||
@ -56,53 +57,53 @@ export struct ModelView {
|
||||
// 复制模型文件并获取路径
|
||||
console.info('Model copied to:', this.modelPath);
|
||||
// 调用 native 加载
|
||||
//OCCTRender.loadModel(this.displayContrId, this.modelPath);
|
||||
OCCTRender.loadModel(this.displayContrId, this.modelPath);
|
||||
} catch (e) {
|
||||
hilog.error(0x0000, 'ModelView', `LoadModel Failed: ${JSON.stringify(e)}`);
|
||||
}
|
||||
})
|
||||
Button('日志测试').onClick(async()=>{
|
||||
//NAPI日志接口测试
|
||||
let OCCTRender = await import("libOCCTRender.so")
|
||||
hilog.info(DOMAIN, 'testTag', 'Test NAPI 2 + 3 = %{public}d', OCCTRender.add(2, 3));
|
||||
let OCCTRender = await import("libocctrender.so")
|
||||
})
|
||||
// XComponent({
|
||||
// id: this.displayContrId,
|
||||
// type: 'surface',
|
||||
// controller: this.displayController
|
||||
// })
|
||||
// .onLoad(() => {
|
||||
// // 获取 native window(必须在 onLoad 后才能获取)
|
||||
// this.nativeWindow = this.displayController.getXComponentSurfaceId();
|
||||
// if (this.nativeWindow === undefined || this.nativeWindow === '') {
|
||||
// hilog.error(0x0000, 'ModelView', 'Failed to get native window');
|
||||
// return;
|
||||
// }
|
||||
// // 获取 XComponent 尺寸
|
||||
// let width = 0;
|
||||
// let height = 0;
|
||||
// try {
|
||||
// //OCCTRender.initRenderer(this.displayContrId, this.nativeWindow, { width: 800, height: 600 });
|
||||
// console.info('Init Render Good');
|
||||
// }catch(e){
|
||||
// console.info('Init Render Faile');
|
||||
// }
|
||||
// })
|
||||
// .onDestroy(() => {
|
||||
// // 销毁时清理资源
|
||||
// //OCCTRender.destroyRenderer(this.displayContrId);
|
||||
// })
|
||||
// .onTouch((event) => {
|
||||
// // 简单鼠标/触摸拖拽旋转
|
||||
// if (event.type === TouchType.Move) {
|
||||
// const dx = event.tiltX;
|
||||
// const dy = event.tiltY;
|
||||
// //occt.onMouseEvent(this.xcomponentId, dx, dy);
|
||||
// }
|
||||
// })
|
||||
// .width('100%')
|
||||
// .height('100%')
|
||||
// .backgroundColor('#333333');
|
||||
}
|
||||
XComponent({
|
||||
id: this.displayContrId,
|
||||
type: 'surface',
|
||||
controller: this.displayController
|
||||
})
|
||||
.onLoad(() => {
|
||||
// 获取 native window(必须在 onLoad 后才能获取)
|
||||
this.nativeWindow = this.displayController.getXComponentSurfaceId();
|
||||
if (this.nativeWindow === undefined || this.nativeWindow === '') {
|
||||
hilog.error(0x0000, 'ModelView', 'Failed to get native window');
|
||||
return;
|
||||
}
|
||||
// 获取 XComponent 尺寸
|
||||
let width = 0;
|
||||
let height = 0;
|
||||
try {
|
||||
OCCTRender.initRenderer(this.displayContrId, this.nativeWindow, { width: 800, height: 600 });
|
||||
console.info('Init Render Good');
|
||||
}catch(e){
|
||||
console.info('Init Render Faile');
|
||||
}
|
||||
})
|
||||
.onDestroy(() => {
|
||||
// 销毁时清理资源
|
||||
OCCTRender.destroyRenderer(this.displayContrId);
|
||||
})
|
||||
.onTouch((event) => {
|
||||
// 简单鼠标/触摸拖拽旋转
|
||||
if (event.type === TouchType.Move) {
|
||||
const dx = event.tiltX;
|
||||
const dy = event.tiltY;
|
||||
//occt.onMouseEvent(this.xcomponentId, dx, dy);
|
||||
}
|
||||
})
|
||||
.width('100%')
|
||||
.height('100%')
|
||||
.backgroundColor('#333333');
|
||||
}
|
||||
.width('100%')
|
||||
.height('100%');
|
||||
|
||||
Loading…
Reference in New Issue
Block a user