参考 https://blog.youkuaiyun.com/time_hunter/article/details/8740758
下面是一些项目应用
#include "Config.h"
#include "Format.h"
#define LOG_TAG "CADTrack_Jni"
#include "Log.h"
#include <jni.h>
#include <android/log.h>
#include "stdio_fl.h"
#include "stdlib_fl.h"
#include "string_fl.h"
#include "memory_fl.h"
#include "AndroidHelper.h"
#include "CadInterface.h"
#ifndef CLASSNAME
#error CLASSNAME was not define, please define CLASSNAME first like -DCLASSNAME=com_alvasystems_CADTrack
#endif
#define JNIFUNC_NOTUSE2(CLZ, FUN) JNIEXPORT JNICALL Java_##CLZ##_##FUN
#define JNIFUNC_NOTUSE1(CLZ, FUN) JNIFUNC_NOTUSE2(CLZ, FUN)
#define JNIFUNC(FUNCNAME) JNIFUNC_NOTUSE1(CLASSNAME, FUNCNAME)
extern "C" {
/**
* @brief 初始化Cad
* @param width: 图像的宽
* @param height: 图像的高
* @param format: 图像的格式
* @return: 句柄,用于后面所有函数的输入
*/
jlong JNIFUNC(CadInit)(JNIEnv* env, jobject obj, jint iwidth, jint iheight, jint format) {
void* cadInfo = CadInit(iwidth, iheight, format);
intptr_t ptr = (intptr_t)cadInfo;
return (jlong)ptr;
}
/**
* @brief 加入模板数据
* @param ptrCad: CadInit的返回值
* @param modelPath: 模型路径
* @param ftFlag: 0代表从Android的Asset文件(仅限Android平台) 1代表 存储器中的文件
* @return: 返回一个合适的值,相机到模板的值,这个值使物体在屏幕上有合适的大小
*/
jfloat JNIFUNC(CadLoadModel)(JNIEnv* env, jobject obj, jlong cadInfo, jstring dxfModelPath, jint ftFlag) {
char* cadmodelpath = Jstring2CStr(dxfModelPath);
float ret = 0;
char * objPtr = NULL;
int objLength = 0;
ret = CadLoadModel((void *)cadInfo, cadmodelpath, ftFlag, &objLength);
return ret;
}
/**
* @brief 传入初始的位姿
* @param ptrCad: CadInit的返回值
* @param Rx: x方向的旋转角度,单位是度
* @param Ry: y方向的旋转角度,单位是度
* @param Rz: z方向的旋转角度,单位是度
* @param Tx: x方向的平移
* @param Tx: y方向的平移
* @param Tx: z方向的平移
* @return: 0成功
*/
jint JNIFUNC(CadSetInitRT)(JNIEnv* env, jobject obj, jlong cadInfo, jfloat xAngle, jfloat yAngle, jfloat zAngle, jfloat xTrans, jfloat yTrans, jfloat zTrans) {
int ret = 0;
ret = CadSetInitRT((void *)cadInfo, xAngle, yAngle, zAngle, xTrans, yTrans, zTrans);
return ret;
}
/**
* @brief 释放整个句柄
* @param ptrCad: CadInit的返回值
* @return: 0成功
*/
jint JNIFUNC(CadUnit)(JNIEnv* env, jobject obj, jlong cadInfo) {
return CadUnit((void *)cadInfo);
}
/**
* @brief 释放加载的模型
* @param ptrCad: CadInit的返回值
* @return: 0成功
*/
jint JNIFUNC(CadUnloadCadModel)(JNIEnv* env, jobject obj, jlong cadInfo) {
return CadUnloadCadModel((void *)cadInfo);
}
/**
* @brief 获取三角面片的数量
* @param ptrCad: CadInit的返回值
* @return: 返回三角面片的数量
*/
jint JNIFUNC(CadGetModelFaceNum)(JNIEnv* env, jobject obj, jlong cadInfo) {
return CadGetModelFaceNum((void *)cadInfo);
}
/**
* @brief 获取所有三角面片的数值
* @param ptrCad: CadInit的返回值
* @param model3dFace: 外部开空间,字节大小为(CadGetModelFaceNum的返回值)* 3 * 3 * sizeof(float) 三角面片的值,第一个三角面的值x0,y0,z0,x1,y1,z1,x2,y2,z2 如此依次排列
* @return: 返回三角面片的数量
*/
jint JNIFUNC(CadGetModelFaceData)(JNIEnv* env, jobject obj, jlong cadInfo, jfloatArray model3dFace) {
int numFace = CadGetModelFaceNum((void *)cadInfo);
float * cModel3dFace = NULL;
if (model3dFace)
cModel3dFace = (float*)env->GetFloatArrayElements(model3dFace, 0);
if (cModel3dFace)
env->ReleaseFloatArrayElements(model3dFace, (jfloat*)cModel3dFace, JNI_COMMIT );
return 0;
}
/**
* @brief 获取模型线条的个数
* @param ptrCad: CadInit的返回值
* @return: 0成功
*/
jint JNIFUNC(CadGetModelLineNum)(JNIEnv* env, jobject obj, jlong cadInfo) {
return CadGetModelLineNum((void *)cadInfo);
}
/**
* @brief 获取模型线条的数据
* @param ptrCad: CadInit的返回值
* @return: float *类型的地址 如:第一个线的两个端点 x0,y0,z0,x1,y1,z1如此依次排列
*/
jint JNIFUNC(CadGetModelLine)(JNIEnv* env, jobject obj, jlong cadInfo, jfloatArray ThreeDimsCoords) {
float* cThreeDimsCoords = NULL;
int ret = 0;
if (ThreeDimsCoords)
cThreeDimsCoords = (float*)env->GetFloatArrayElements(ThreeDimsCoords, 0);
int lineNum = CadGetModelLineNum((void *)cadInfo);
CadGetModelLine((void *)cadInfo, cThreeDimsCoords);
if (cThreeDimsCoords)
env->ReleaseFloatArrayElements(ThreeDimsCoords, (jfloat*)cThreeDimsCoords, JNI_COMMIT );
return ret;
}
/**
* @brief 获取状态,识别还是跟踪
* @param ptrCad: CadInit的返回值
* @return: 0代表识别,1代表跟踪
*/
jint JNIFUNC(CadGetStatus)(JNIEnv* env, jobject obj, jlong cadInfo) {
return CadGetStatus((void *)cadInfo);
}
/**
* @brief 获取RTS矩阵和线可见否的标志位,如果想在一个地方同时获取两个结果就可以不用分别调用下面
* 两个函数,如果TRS和Flag在不同的位置用,那么TRS= NULL, Flag=NULL,之后再调用CadGetRTS(),和CadGetModelLineFlag()
* @param ptrCad: CadInit的返回值
* @param TRS 返回一个float[16]的数组,4*4矩阵,内存横向存储
* @param Flag: 一个int类型数组,外部开空间,1代表可见,0代表不可见
* @return: 0
*/
jint JNIFUNC(CadUpdataResult)(JNIEnv* env, jobject obj, jlong cadInfo, jfloatArray TRS, jintArray Flag) {
CadUpdataResult((void *) cadInfo);
return 0;
}
/**
* @brief 获取RTS矩阵
* @param ptrCad: CadInit的返回值
* @return: 返回一个float[16]的数组,4*4矩阵,内存横向存储
*/
jint JNIFUNC(CadGetRTS)(JNIEnv* env, jobject obj, jlong cadInfo, jfloatArray rtsMatrix) {
int ret = 0;
float* crts = NULL;
if (rtsMatrix)
crts = env->GetFloatArrayElements(rtsMatrix, 0);
ret = CadGetRTS((void *)cadInfo, crts);
if (crts)
env->ReleaseFloatArrayElements(rtsMatrix, (jfloat*)crts, JNI_COMMIT );//JNI_ABORT
return ret;
}
/**
* @brief 获取三维线条是否可见
* @param ptrCad: CadInit的返回值
* @param Flag: 一个int类型数组,外部开空间,1代表可见,0代表不可见
* @return: 返回 0成功
*/
jint JNIFUNC(CadGetModelLineFlag)(JNIEnv* env, jobject obj, jlong cadInfo, jintArray Flag) {
int ret = 0;
int* cFlag = NULL;
if (Flag)
cFlag = env->GetIntArrayElements(Flag, 0);
ret = CadGetModelLineFlag((void *)cadInfo, cFlag);
if (cFlag)
env->ReleaseIntArrayElements(Flag, (jint*)cFlag, JNI_ABORT);
return ret;
}
/**
* @brief 获取所有三角面片的数值
* @param ptrCad: CadInit的返回值
* @param fov: 相机的夹角
* @param nearDis: 相机的近平面
* @param farDis: 相机的远平面
* @return: 返回三角面片的数量
*/
jint JNIFUNC(CadSetFovNearFar)(JNIEnv* env, jobject obj, jlong cadInfo, jfloat fov, jfloat nearDis, jfloat farDis) {
int ret = 0;
ret = CadSetFovNearFar((void *)cadInfo, fov, nearDis, farDis);
return ret;
}
}