380 CH_FLOAT dfi, v, max_p, min_p;
381 CH_FLOAT* points, *cf, *cfi, *df, *p_s, *span;
383 if(nVert<=3 || in_vertices==NULL){
397 points = (CH_FLOAT*)malloc(nVert*(d+1)*
sizeof(CH_FLOAT));
398 for(i=0; i<nVert; i++){
400 points[i*(d+1)+j] = in_vertices[i].v[j] + CH_NOISE_VAL*(CH_FLOAT)rand()/(CH_FLOAT)RAND_MAX;
401 points[i*(d+1)+d] = 1.0f;
405 span = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
407 max_p = -2.23e+13; min_p = 2.23e+13;
408 for(i=0; i<nVert; i++){
409 max_p = MAX(max_p, points[i*(d+1)+j]);
410 min_p = MIN(min_p, points[i*(d+1)+j]);
412 span[j] = max_p - min_p;
413 assert(span[j]>0.0000001f);
418 faces = (
int*)calloc(nFaces*d,
sizeof(
int));
419 aVec = (
int*)malloc(nFaces*
sizeof(
int));
420 for(i=0; i<nFaces; i++)
424 cf = (CH_FLOAT*)malloc(nFaces*d*
sizeof(CH_FLOAT));
425 cfi = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
426 df = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
427 p_s = (CH_FLOAT*)malloc(d*d*
sizeof(CH_FLOAT));
428 for(i=0; i<nFaces; i++){
430 for(j=0, k=0; j<(d+1); j++){
432 faces[i*d+k] = aVec[j];
440 p_s[j*d+k] = points[(faces[i*d+j])*(d+1) + k];
443 plane_3d(p_s, cfi, &dfi);
449 int *bVec, *fVec, *asfVec;
453 bVec = (
int*)malloc((d+1)*
sizeof(int));
458 A = (CH_FLOAT*)calloc((d+1)*(d+1),
sizeof(CH_FLOAT));
459 fVec = (
int*)malloc((d+1)*
sizeof(int));
460 asfVec = (
int*)malloc((d+1)*
sizeof(int));
461 for(k=0; k<(d+1); k++){
464 fVec[i] = faces[k*d+i];
465 sort_int(fVec, NULL, NULL, d, 0);
468 for(j=0; j<(d+1); j++)
469 A[i*(d+1)+j] = points[(faces[k*d+i])*(d+1) + j];
471 for(j=0; j<(d+1); j++)
472 A[i*(d+1)+j] = points[p*(d+1)+j];
481 face_tmp[j] = faces[k*d+d-j-1];
483 faces[k*d+d-j-1] = face_tmp[1-j];
487 cf[k*d+j] = -cf[k*d+j];
490 for(j=0; j<(d+1); j++)
491 A[i*(d+1)+j] = points[(faces[k*d+i])*(d+1) + j];
493 for(j=0; j<(d+1); j++)
494 A[i*(d+1)+j] = points[p*(d+1)+j];
499 CH_FLOAT* meanp, *absdist, *reldist, *desReldist;
500 meanp = (CH_FLOAT*)calloc(d,
sizeof(CH_FLOAT));
501 for(i=d+1; i<nVert; i++)
503 meanp[j] += points[i*(d+1)+j];
505 meanp[j] = meanp[j]/(CH_FLOAT)(nVert-d-1);
508 absdist = (CH_FLOAT*)malloc((nVert-d-1)*d *
sizeof(CH_FLOAT));
509 for(i=d+1, k=0; i<nVert; i++, k++)
511 absdist[k*d+j] = (points[i*(d+1)+j] - meanp[j])/span[j];
514 reldist = (CH_FLOAT*)calloc((nVert-d-1),
sizeof(CH_FLOAT));
515 desReldist = (CH_FLOAT*)malloc((nVert-d-1) *
sizeof(CH_FLOAT));
516 for(i=0; i<(nVert-d-1); i++)
518 reldist[i] += pow(absdist[i*d+j], 2.0);
523 ind = (
int*)malloc((nVert-d-1) *
sizeof(int));
524 pleft = (
int*)malloc((nVert-d-1) *
sizeof(int));
525 sort_float(reldist, desReldist, ind, (nVert-d-1), 1);
529 num_pleft = (nVert-d-1);
530 for(i=0; i<num_pleft; i++)
531 pleft[i] = ind[i]+d+1;
535 memset(A, 0, (d+1)*(d+1) *
sizeof(CH_FLOAT));
543 CH_FLOAT* points_cf, *points_s;
544 int* visible_ind, *visible, *nonvisible_faces, *f0, *face_s, *u, *gVec, *horizon, *hVec, *pp, *hVec_mem_face;
545 int num_visible_ind, num_nonvisible_faces, n_newfaces, count, vis;
546 int f0_sum, u_len,
start, num_p, index, horizon_size1;
551 visible_ind = (
int*)malloc(nFaces*
sizeof(
int));
552 points_cf = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
553 points_s = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
554 face_s = (
int*)malloc(d*
sizeof(
int));
555 gVec = (
int*)malloc(d*
sizeof(
int));
556 while( (num_pleft>0) ){
561 for(j=0; j<num_pleft-1; j++)
562 pleft[j] = pleft[j+1];
567 pleft = (
int*)realloc(pleft, num_pleft*
sizeof(
int));
574 points_s[j] = points[i*(d+1)+j];
575 points_cf = (CH_FLOAT*)realloc(points_cf, nFaces*
sizeof(CH_FLOAT));
576 visible_ind = (
int*)realloc(visible_ind, nFaces*
sizeof(
int));
577#ifdef CONVHULL_3D_USE_CBLAS
578 #ifdef CONVHULL_3D_USE_FLOAT_PRECISION
579 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 1, nFaces, d, 1.0f,
584 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 1, nFaces, d, 1.0,
590 for (j = 0; j < nFaces; j++) {
592 for (k = 0; k < d; k++)
593 points_cf[j] += points_s[k]*cf[j*d+k];
597 for(j=0; j<nFaces; j++){
598 if(points_cf[j] + df[j] > 0.0){
605 num_nonvisible_faces = nFaces - num_visible_ind;
608 if(num_visible_ind!=0){
610 visible = (
int*)malloc(num_visible_ind*
sizeof(
int));
611 for(j=0, k=0; j<nFaces; j++){
612 if(visible_ind[j]==1){
619 nonvisible_faces = (
int*)malloc(num_nonvisible_faces*d*
sizeof(
int));
620 f0 = (
int*)malloc(num_nonvisible_faces*d*
sizeof(
int));
621 for(j=0, k=0; j<nFaces; j++){
622 if(visible_ind[j]==0){
624 nonvisible_faces[k*d+l]= faces[j*d+l];
631 for(j=0; j<num_visible_ind; j++){
635 face_s[k] = faces[vis*d+k];
636 sort_int(face_s, NULL, NULL, d, 0);
637 ismember(nonvisible_faces, face_s, f0, num_nonvisible_faces*d, d);
641 for(k=0; k<num_nonvisible_faces; k++){
644 f0_sum += f0[k*d + l];
648 u = (
int*)malloc(u_len*
sizeof(
int));
650 u = (
int*)realloc(u, u_len*
sizeof(
int));
654 for(k=0; k<u_len; k++){
658 horizon = (
int*)malloc(count*(d-1)*
sizeof(int));
660 horizon = (
int*)realloc(horizon, count*(d-1)*
sizeof(int));
662 gVec[l] = nonvisible_faces[u[k]*d+l];
663 for(l=0, h=0; l<d; l++){
665 horizon[(count-1)*(d-1)+h] = gVec[l];
673 horizon_size1 = count;
674 for(j=0, l=0; j<nFaces; j++){
678 faces[l*d+k] = faces[j*d+k];
682 cf[l*d+k] = cf[j*d+k];
689 nFaces = nFaces-num_visible_ind;
690 faces = (
int*)realloc(faces, nFaces*d*
sizeof(
int));
691 cf = (CH_FLOAT*)realloc(cf, nFaces*d*
sizeof(CH_FLOAT));
692 df = (CH_FLOAT*)realloc(df, nFaces*
sizeof(CH_FLOAT));
698 n_newfaces = horizon_size1;
699 for(j=0; j<n_newfaces; j++){
701 faces = (
int*)realloc(faces, nFaces*d*
sizeof(
int));
702 cf = (CH_FLOAT*)realloc(cf, nFaces*d*
sizeof(CH_FLOAT));
703 df = (CH_FLOAT*)realloc(df, nFaces*
sizeof(CH_FLOAT));
705 faces[(nFaces-1)*d+k] = horizon[j*(d-1)+k];
706 faces[(nFaces-1)*d+(d-1)] = i;
711 p_s[k*d+l] = points[(faces[(nFaces-1)*d+k])*(d+1) + l];
712 plane_3d(p_s, cfi, &dfi);
714 cf[(nFaces-1)*d+k] = cfi[k];
715 df[(nFaces-1)] = dfi;
716 if(nFaces > CH_MAX_NUM_FACES){
724 hVec = (
int*)malloc( nFaces*
sizeof(
int));
725 hVec_mem_face = (
int*)malloc( nFaces*
sizeof(
int));
726 for(j=0; j<nFaces; j++)
728 for(k=
start; k<nFaces; k++){
730 face_s[j] = faces[k*d+j];
731 sort_int(face_s, NULL, NULL, d, 0);
732 ismember(hVec, face_s, hVec_mem_face, nFaces, d);
734 for(j=0; j<nFaces; j++)
735 if(!hVec_mem_face[j])
737 pp = (
int*)malloc(num_p*
sizeof(
int));
738 for(j=0, l=0; j<nFaces; j++){
739 if(!hVec_mem_face[j]){
751 A[j*(d+1)+l] = points[(faces[k*d+j])*(d+1) + l];
754 A[j*(d+1)+l] = points[pp[index]*(d+1)+l];
763 face_tmp[j] = faces[k*d+d-j-1];
765 faces[k*d+d-j-1] = face_tmp[1-j];
769 cf[k*d+j] = -cf[k*d+j];
773 A[l*(d+1)+j] = points[(faces[k*d+l])*(d+1) + j];
776 A[l*(d+1)+j] = points[pp[index]*(d+1)+j];
783 free(nonvisible_faces);
803 (*out_faces) = (
int*)malloc(nFaces*d*
sizeof(
int));
804 memcpy((*out_faces),faces, nFaces*d*
sizeof(
int));
805 (*nOut_faces) = nFaces;
807 (*out_cf) = (CH_FLOAT*)malloc(nFaces*d*
sizeof(CH_FLOAT));
808 memcpy((*out_cf),cf, nFaces*d*
sizeof(CH_FLOAT));
811 (*out_df) = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
812 memcpy((*out_df),df, nFaces*
sizeof(CH_FLOAT));
851 CH_FLOAT*
const in_vertices,
863 CH_FLOAT dfi, v, max_p, min_p;
864 CH_FLOAT* points, *cf, *cfi, *df, *p_s, *span;
866 assert(d<=CONVHULL_ND_MAX_DIMENSIONS);
869 if(nVert<=d || in_vertices==NULL){
880 points = (CH_FLOAT*)malloc(nVert*(d+1)*
sizeof(CH_FLOAT));
881 for(i=0; i<nVert; i++){
883 points[i*(d+1)+j] = in_vertices[i*d+j] + CH_NOISE_VAL*(CH_FLOAT)rand()/(CH_FLOAT)RAND_MAX;
884 points[i*(d+1)+d] = 1.0;
888 span = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
890 max_p = -2.23e+13; min_p = 2.23e+13;
891 for(i=0; i<nVert; i++){
892 max_p = MAX(max_p, points[i*(d+1)+j]);
893 min_p = MIN(min_p, points[i*(d+1)+j]);
895 span[j] = max_p - min_p;
896 assert(span[j]>0.000000001);
901 faces = (
int*)calloc(nFaces*d,
sizeof(
int));
902 aVec = (
int*)malloc(nFaces*
sizeof(
int));
903 for(i=0; i<nFaces; i++)
907 cf = (CH_FLOAT*)malloc(nFaces*d*
sizeof(CH_FLOAT));
908 cfi = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
909 df = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
910 p_s = (CH_FLOAT*)malloc(d*d*
sizeof(CH_FLOAT));
911 for(i=0; i<nFaces; i++){
913 for(j=0, k=0; j<(d+1); j++){
915 faces[i*d+k] = aVec[j];
923 p_s[j*d+k] = points[(faces[i*d+j])*(d+1) + k];
926 plane_nd(d, p_s, cfi, &dfi);
936 bVec = (
int*)malloc((d+1)*
sizeof(int));
941 A = (CH_FLOAT*)calloc((d+1)*(d+1),
sizeof(CH_FLOAT));
942 fVec = (
int*)malloc((d+1)*
sizeof(int));
943 for(k=0; k<(d+1); k++){
946 fVec[i] = faces[k*d+i];
947 sort_int(fVec, NULL, NULL, d, 0);
950 for(j=0; j<(d+1); j++)
951 A[i*(d+1)+j] = points[(faces[k*d+i])*(d+1) + j];
953 for(j=0; j<(d+1); j++)
954 A[i*(d+1)+j] = points[p*(d+1)+j];
966 face_tmp[j] = faces[k*d+d-j-1];
968 faces[k*d+d-j-1] = face_tmp[1-j];
972 cf[k*d+j] = -cf[k*d+j];
975 for(j=0; j<(d+1); j++)
976 A[i*(d+1)+j] = points[(faces[k*d+i])*(d+1) + j];
978 for(j=0; j<(d+1); j++)
979 A[i*(d+1)+j] = points[p*(d+1)+j];
984 CH_FLOAT* meanp, *reldist, *desReldist, *absdist;
985 meanp = (CH_FLOAT*)calloc(d,
sizeof(CH_FLOAT));
986 for(i=d+1; i<nVert; i++)
988 meanp[j] += points[i*(d+1)+j];
990 meanp[j] = meanp[j]/(CH_FLOAT)(nVert-d-1);
993 absdist = (CH_FLOAT*)malloc((nVert-d-1)*d *
sizeof(CH_FLOAT));
994 for(i=d+1, k=0; i<nVert; i++, k++)
996 absdist[k*d+j] = (points[i*(d+1)+j] - meanp[j])/span[j];
999 reldist = (CH_FLOAT*)calloc((nVert-d-1),
sizeof(CH_FLOAT));
1000 desReldist = (CH_FLOAT*)malloc((nVert-d-1) *
sizeof(CH_FLOAT));
1001 for(i=0; i<(nVert-d-1); i++)
1003 reldist[i] += pow(absdist[i*d+j], 2.0);
1008 ind = (
int*)malloc((nVert-d-1) *
sizeof(int));
1009 pleft = (
int*)malloc((nVert-d-1) *
sizeof(int));
1010 sort_float(reldist, desReldist, ind, (nVert-d-1), 1);
1014 num_pleft = (nVert-d-1);
1015 for(i=0; i<num_pleft; i++)
1016 pleft[i] = ind[i]+d+1;
1020 memset(A, 0, (d+1)*(d+1) *
sizeof(CH_FLOAT));
1028 CH_FLOAT* points_cf, *points_s;
1029 int* visible_ind, *visible, *nonvisible_faces, *f0, *face_s, *u, *gVec, *horizon, *hVec, *pp, *hVec_mem_face;
1030 int num_visible_ind, num_nonvisible_faces, n_newfaces, count, vis;
1031 int f0_sum, u_len,
start, num_p, index, horizon_size1;
1036 visible_ind = (
int*)malloc(nFaces*
sizeof(
int));
1037 points_cf = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
1038 points_s = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
1039 face_s = (
int*)malloc(d*
sizeof(
int));
1040 gVec = (
int*)malloc(d*
sizeof(
int));
1041 while( (num_pleft>0) ){
1046 for(j=0; j<num_pleft-1; j++)
1047 pleft[j] = pleft[j+1];
1052 pleft = (
int*)realloc(pleft, num_pleft*
sizeof(
int));
1059 points_s[j] = points[i*(d+1)+j];
1060 points_cf = (CH_FLOAT*)realloc(points_cf,nFaces*
sizeof(CH_FLOAT));
1061 visible_ind = (
int*)realloc(visible_ind, nFaces*
sizeof(
int));
1062#ifdef CONVHULL_3D_USE_CBLAS
1063 #ifdef CONVHULL_3D_USE_FLOAT_PRECISION
1064 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 1, nFaces, d, 1.0f,
1069 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 1, nFaces, d, 1.0,
1075 for (j = 0; j < nFaces; j++) {
1077 for (k = 0; k < d; k++)
1078 points_cf[j] += points_s[k]*cf[j*d+k];
1081 num_visible_ind = 0;
1082 for(j=0; j<nFaces; j++){
1083 if(points_cf[j] + df[j] > 0.0){
1090 num_nonvisible_faces = nFaces - num_visible_ind;
1093 if(num_visible_ind!=0){
1095 visible = (
int*)malloc(num_visible_ind*
sizeof(
int));
1096 for(j=0, k=0; j<nFaces; j++){
1097 if(visible_ind[j]==1){
1104 nonvisible_faces = (
int*)malloc(num_nonvisible_faces*d*
sizeof(
int));
1105 f0 = (
int*)malloc(num_nonvisible_faces*d*
sizeof(
int));
1106 for(j=0, k=0; j<nFaces; j++){
1107 if(visible_ind[j]==0){
1109 nonvisible_faces[k*d+l] = faces[j*d+l];
1116 for(j=0; j<num_visible_ind; j++){
1120 face_s[k] = faces[vis*d+k];
1121 sort_int(face_s, NULL, NULL, d, 0);
1122 ismember(nonvisible_faces, face_s, f0, num_nonvisible_faces*d, d);
1126 for(k=0; k<num_nonvisible_faces; k++){
1129 f0_sum += f0[k*d + l];
1133 u = (
int*)malloc(u_len*
sizeof(
int));
1135 u = (
int*)realloc(u, u_len*
sizeof(
int));
1139 for(k=0; k<u_len; k++){
1143 horizon = (
int*)malloc(count*(d-1)*
sizeof(int));
1145 horizon = (
int*)realloc(horizon, count*(d-1)*
sizeof(int));
1147 gVec[l] = nonvisible_faces[u[k]*d+l];
1148 for(l=0, h=0; l<d; l++){
1150 horizon[(count-1)*(d-1)+h] = gVec[l];
1158 horizon_size1 = count;
1159 for(j=0, l=0; j<nFaces; j++){
1160 if(!visible_ind[j]){
1163 faces[l*d+k] = faces[j*d+k];
1167 cf[l*d+k] = cf[j*d+k];
1174 nFaces = nFaces-num_visible_ind;
1175 faces = (
int*)realloc(faces, nFaces*d*
sizeof(
int));
1176 cf = (CH_FLOAT*)realloc(cf, nFaces*d*
sizeof(CH_FLOAT));
1177 df = (CH_FLOAT*)realloc(df, nFaces*
sizeof(CH_FLOAT));
1183 n_newfaces = horizon_size1;
1184 for(j=0; j<n_newfaces; j++){
1186 faces = (
int*)realloc(faces, nFaces*d*
sizeof(
int));
1187 cf = (CH_FLOAT*)realloc(cf, nFaces*d*
sizeof(CH_FLOAT));
1188 df = (CH_FLOAT*)realloc(df, nFaces*
sizeof(CH_FLOAT));
1189 for(k=0; k<d-1; k++)
1190 faces[(nFaces-1)*d+k] = horizon[j*(d-1)+k];
1191 faces[(nFaces-1)*d+(d-1)] = i;
1196 p_s[k*d+l] = points[(faces[(nFaces-1)*d+k])*(d+1) + l];
1197 plane_nd(d, p_s, cfi, &dfi);
1199 cf[(nFaces-1)*d+k] = cfi[k];
1200 df[(nFaces-1)] = dfi;
1201 if(nFaces > CH_MAX_NUM_FACES){
1209 hVec = (
int*)malloc( nFaces*
sizeof(
int));
1210 hVec_mem_face = (
int*)malloc( nFaces*
sizeof(
int));
1211 for(j=0; j<nFaces; j++)
1213 for(k=
start; k<nFaces; k++){
1215 face_s[j] = faces[k*d+j];
1216 sort_int(face_s, NULL, NULL, d, 0);
1217 ismember(hVec, face_s, hVec_mem_face, nFaces, d);
1219 for(j=0; j<nFaces; j++)
1220 if(!hVec_mem_face[j])
1222 pp = (
int*)malloc(num_p*
sizeof(
int));
1223 for(j=0, l=0; j<nFaces; j++){
1224 if(!hVec_mem_face[j]){
1235 for(l=0; l<d+1; l++)
1236 A[j*(d+1)+l] = points[(faces[k*d+j])*(d+1) + l];
1238 for(l=0; l<d+1; l++)
1239 A[j*(d+1)+l] = points[pp[index]*(d+1)+l];
1244 detA = det_NxN((CH_FLOAT*)A, d+1);
1251 face_tmp[j] = faces[k*d+d-j-1];
1253 faces[k*d+d-j-1] = face_tmp[1-j];
1257 cf[k*d+j] = -cf[k*d+j];
1260 for(j=0; j<d+1; j++)
1261 A[l*(d+1)+j] = points[(faces[k*d+l])*(d+1) + j];
1263 for(j=0; j<d+1; j++)
1264 A[l*(d+1)+j] = points[pp[index]*(d+1)+j];
1270 detA = det_NxN((CH_FLOAT*)A, d+1);
1279 free(nonvisible_faces);
1282 free(hVec_mem_face);
1291 (*out_faces) = NULL;
1299 (*out_faces) = (
int*)malloc(nFaces*d*
sizeof(
int));
1300 memcpy((*out_faces),faces, nFaces*d*
sizeof(
int));
1301 (*nOut_faces) = nFaces;
1303 (*out_cf) = (CH_FLOAT*)malloc(nFaces*d*
sizeof(CH_FLOAT));
1304 memcpy((*out_cf), cf, nFaces*d*
sizeof(CH_FLOAT));
1307 (*out_df) = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
1308 memcpy((*out_df), df, nFaces*
sizeof(CH_FLOAT));
1342 const int keepOnlyUsedVerticesFLAG,
1343 char*
const obj_filename
1347 char path[256] =
"\0";
1348 memcpy(path, obj_filename, strlen(obj_filename));
1350#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
1351 CV_STRCAT(path,
".obj");
1352 fopen_s(&obj_file, path,
"wt");
1354 obj_file = fopen(strcat(path,
".obj"),
"wt");
1356 fprintf(obj_file,
"o\n");
1361 if(keepOnlyUsedVerticesFLAG){
1362 for (i = 0; i < nFaces; i++)
1364 fprintf(obj_file,
"v %f %f %f\n", vertices[faces[i*3+j]].x,
1365 vertices[faces[i*3+j]].y, vertices[faces[i*3+j]].z);
1368 for (i = 0; i < nVert; i++)
1369 fprintf(obj_file,
"v %f %f %f\n", vertices[i].x,
1370 vertices[i].y, vertices[i].z);
1374 for (i = 0; i < nFaces; i++){
1376 v1 = vertices[faces[i*3+1]];
1377 v2 = vertices[faces[i*3+2]];
1378 v1.x -= vertices[faces[i*3]].x;
1379 v1.y -= vertices[faces[i*3]].y;
1380 v1.z -= vertices[faces[i*3]].z;
1381 v2.x -= vertices[faces[i*3]].x;
1382 v2.y -= vertices[faces[i*3]].y;
1383 v2.z -= vertices[faces[i*3]].z;
1384 normal = cross(&v1, &v2);
1387 scale = 1.0/(sqrt(pow(normal.x, 2.0)+pow(normal.y, 2.0)+pow(normal.z, 2.0))+2.23e-9);
1391 fprintf(obj_file,
"vn %f %f %f\n", normal.x, normal.y, normal.z);
1395 if(keepOnlyUsedVerticesFLAG){
1396 for (i = 0; i < nFaces; i++){
1398 fprintf(obj_file,
"f %u//%u %u//%u %u//%u\n",
1406 for (i = 0; i < nFaces; i++){
1407 fprintf(obj_file,
"f %u//%u %u//%u %u//%u\n",
1408 faces[i*3] + 1, i + 1,
1409 faces[i*3+1] + 1, i + 1,
1410 faces[i*3+2] + 1, i + 1);