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));
539 CH_FLOAT* points_cf, *points_s;
540 int* visible_ind, *visible, *nonvisible_faces, *f0, *face_s, *u, *gVec, *horizon, *hVec, *pp, *hVec_mem_face;
541 int num_visible_ind, num_nonvisible_faces, n_newfaces, count, vis;
542 int f0_sum, u_len,
start, num_p, index, horizon_size1;
547 visible_ind = (
int*)malloc(nFaces*
sizeof(
int));
548 points_cf = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
549 points_s = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
550 face_s = (
int*)malloc(d*
sizeof(
int));
551 gVec = (
int*)malloc(d*
sizeof(
int));
552 while( (num_pleft>0) ){
557 for(j=0; j<num_pleft-1; j++)
558 pleft[j] = pleft[j+1];
563 pleft = (
int*)realloc(pleft, num_pleft*
sizeof(
int));
567 points_s[j] = points[i*(d+1)+j];
568 points_cf = (CH_FLOAT*)realloc(points_cf, nFaces*
sizeof(CH_FLOAT));
569 visible_ind = (
int*)realloc(visible_ind, nFaces*
sizeof(
int));
570#ifdef CONVHULL_3D_USE_CBLAS
571 #ifdef CONVHULL_3D_USE_FLOAT_PRECISION
572 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 1, nFaces, d, 1.0f,
577 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 1, nFaces, d, 1.0,
583 for (j = 0; j < nFaces; j++) {
585 for (k = 0; k < d; k++)
586 points_cf[j] += points_s[k]*cf[j*d+k];
590 for(j=0; j<nFaces; j++){
591 if(points_cf[j] + df[j] > 0.0){
598 num_nonvisible_faces = nFaces - num_visible_ind;
601 if(num_visible_ind!=0){
603 visible = (
int*)malloc(num_visible_ind*
sizeof(
int));
604 for(j=0, k=0; j<nFaces; j++){
605 if(visible_ind[j]==1){
612 nonvisible_faces = (
int*)malloc(num_nonvisible_faces*d*
sizeof(
int));
613 f0 = (
int*)malloc(num_nonvisible_faces*d*
sizeof(
int));
614 for(j=0, k=0; j<nFaces; j++){
615 if(visible_ind[j]==0){
617 nonvisible_faces[k*d+l]= faces[j*d+l];
624 for(j=0; j<num_visible_ind; j++){
628 face_s[k] = faces[vis*d+k];
629 sort_int(face_s, NULL, NULL, d, 0);
630 ismember(nonvisible_faces, face_s, f0, num_nonvisible_faces*d, d);
634 for(k=0; k<num_nonvisible_faces; k++){
637 f0_sum += f0[k*d + l];
641 u = (
int*)malloc(u_len*
sizeof(
int));
643 u = (
int*)realloc(u, u_len*
sizeof(
int));
647 for(k=0; k<u_len; k++){
651 horizon = (
int*)malloc(count*(d-1)*
sizeof(
int));
653 horizon = (
int*)realloc(horizon, count*(d-1)*
sizeof(
int));
655 gVec[l] = nonvisible_faces[u[k]*d+l];
656 for(l=0, h=0; l<d; l++){
658 horizon[(count-1)*(d-1)+h] = gVec[l];
666 horizon_size1 = count;
667 for(j=0, l=0; j<nFaces; j++){
671 faces[l*d+k] = faces[j*d+k];
675 cf[l*d+k] = cf[j*d+k];
682 nFaces = nFaces-num_visible_ind;
683 faces = (
int*)realloc(faces, nFaces*d*
sizeof(
int));
684 cf = (CH_FLOAT*)realloc(cf, nFaces*d*
sizeof(CH_FLOAT));
685 df = (CH_FLOAT*)realloc(df, nFaces*
sizeof(CH_FLOAT));
691 n_newfaces = horizon_size1;
692 for(j=0; j<n_newfaces; j++){
694 faces = (
int*)realloc(faces, nFaces*d*
sizeof(
int));
695 cf = (CH_FLOAT*)realloc(cf, nFaces*d*
sizeof(CH_FLOAT));
696 df = (CH_FLOAT*)realloc(df, nFaces*
sizeof(CH_FLOAT));
698 faces[(nFaces-1)*d+k] = horizon[j*(d-1)+k];
699 faces[(nFaces-1)*d+(d-1)] = i;
704 p_s[k*d+l] = points[(faces[(nFaces-1)*d+k])*(d+1) + l];
705 plane_3d(p_s, cfi, &dfi);
707 cf[(nFaces-1)*d+k] = cfi[k];
708 df[(nFaces-1)] = dfi;
709 if(nFaces > CH_MAX_NUM_FACES){
717 hVec = (
int*)malloc( nFaces*
sizeof(
int));
718 hVec_mem_face = (
int*)malloc( nFaces*
sizeof(
int));
719 for(j=0; j<nFaces; j++)
721 for(k=
start; k<nFaces; k++){
723 face_s[j] = faces[k*d+j];
724 sort_int(face_s, NULL, NULL, d, 0);
725 ismember(hVec, face_s, hVec_mem_face, nFaces, d);
727 for(j=0; j<nFaces; j++)
728 if(!hVec_mem_face[j])
730 pp = (
int*)malloc(num_p*
sizeof(
int));
731 for(j=0, l=0; j<nFaces; j++){
732 if(!hVec_mem_face[j]){
744 A[j*(d+1)+l] = points[(faces[k*d+j])*(d+1) + l];
747 A[j*(d+1)+l] = points[pp[index]*(d+1)+l];
756 face_tmp[j] = faces[k*d+d-j-1];
758 faces[k*d+d-j-1] = face_tmp[1-j];
762 cf[k*d+j] = -cf[k*d+j];
766 A[l*(d+1)+j] = points[(faces[k*d+l])*(d+1) + j];
769 A[l*(d+1)+j] = points[pp[index]*(d+1)+j];
776 free(nonvisible_faces);
796 (*out_faces) = (
int*)malloc(nFaces*d*
sizeof(
int));
797 memcpy((*out_faces),faces, nFaces*d*
sizeof(
int));
798 (*nOut_faces) = nFaces;
800 (*out_cf) = (CH_FLOAT*)malloc(nFaces*d*
sizeof(CH_FLOAT));
801 memcpy((*out_cf),cf, nFaces*d*
sizeof(CH_FLOAT));
804 (*out_df) = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
805 memcpy((*out_df),df, nFaces*
sizeof(CH_FLOAT));
844 CH_FLOAT*
const in_vertices,
856 CH_FLOAT dfi, v, max_p, min_p;
857 CH_FLOAT* points, *cf, *cfi, *df, *p_s, *span;
859 assert(d<=CONVHULL_ND_MAX_DIMENSIONS);
862 if(nVert<=d || in_vertices==NULL){
873 points = (CH_FLOAT*)malloc(nVert*(d+1)*
sizeof(CH_FLOAT));
874 for(i=0; i<nVert; i++){
876 points[i*(d+1)+j] = in_vertices[i*d+j] + CH_NOISE_VAL*(CH_FLOAT)rand()/(CH_FLOAT)RAND_MAX;
877 points[i*(d+1)+d] = 1.0;
881 span = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
883 max_p = -2.23e+13; min_p = 2.23e+13;
884 for(i=0; i<nVert; i++){
885 max_p = MAX(max_p, points[i*(d+1)+j]);
886 min_p = MIN(min_p, points[i*(d+1)+j]);
888 span[j] = max_p - min_p;
889 assert(span[j]>0.000000001);
894 faces = (
int*)calloc(nFaces*d,
sizeof(
int));
895 aVec = (
int*)malloc(nFaces*
sizeof(
int));
896 for(i=0; i<nFaces; i++)
900 cf = (CH_FLOAT*)malloc(nFaces*d*
sizeof(CH_FLOAT));
901 cfi = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
902 df = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
903 p_s = (CH_FLOAT*)malloc(d*d*
sizeof(CH_FLOAT));
904 for(i=0; i<nFaces; i++){
906 for(j=0, k=0; j<(d+1); j++){
908 faces[i*d+k] = aVec[j];
916 p_s[j*d+k] = points[(faces[i*d+j])*(d+1) + k];
919 plane_nd(d, p_s, cfi, &dfi);
929 bVec = (
int*)malloc((d+1)*
sizeof(
int));
934 A = (CH_FLOAT*)calloc((d+1)*(d+1),
sizeof(CH_FLOAT));
935 fVec = (
int*)malloc((d+1)*
sizeof(
int));
936 for(k=0; k<(d+1); k++){
939 fVec[i] = faces[k*d+i];
940 sort_int(fVec, NULL, NULL, d, 0);
943 for(j=0; j<(d+1); j++)
944 A[i*(d+1)+j] = points[(faces[k*d+i])*(d+1) + j];
946 for(j=0; j<(d+1); j++)
947 A[i*(d+1)+j] = points[p*(d+1)+j];
959 face_tmp[j] = faces[k*d+d-j-1];
961 faces[k*d+d-j-1] = face_tmp[1-j];
965 cf[k*d+j] = -cf[k*d+j];
968 for(j=0; j<(d+1); j++)
969 A[i*(d+1)+j] = points[(faces[k*d+i])*(d+1) + j];
971 for(j=0; j<(d+1); j++)
972 A[i*(d+1)+j] = points[p*(d+1)+j];
977 CH_FLOAT* meanp, *reldist, *desReldist, *absdist;
978 meanp = (CH_FLOAT*)calloc(d,
sizeof(CH_FLOAT));
979 for(i=d+1; i<nVert; i++)
981 meanp[j] += points[i*(d+1)+j];
983 meanp[j] = meanp[j]/(CH_FLOAT)(nVert-d-1);
986 absdist = (CH_FLOAT*)malloc((nVert-d-1)*d *
sizeof(CH_FLOAT));
987 for(i=d+1, k=0; i<nVert; i++, k++)
989 absdist[k*d+j] = (points[i*(d+1)+j] - meanp[j])/span[j];
992 reldist = (CH_FLOAT*)calloc((nVert-d-1),
sizeof(CH_FLOAT));
993 desReldist = (CH_FLOAT*)malloc((nVert-d-1) *
sizeof(CH_FLOAT));
994 for(i=0; i<(nVert-d-1); i++)
996 reldist[i] += pow(absdist[i*d+j], 2.0);
1001 ind = (
int*)malloc((nVert-d-1) *
sizeof(
int));
1002 pleft = (
int*)malloc((nVert-d-1) *
sizeof(
int));
1003 sort_float(reldist, desReldist, ind, (nVert-d-1), 1);
1007 num_pleft = (nVert-d-1);
1008 for(i=0; i<num_pleft; i++)
1009 pleft[i] = ind[i]+d+1;
1013 memset(A, 0, (d+1)*(d+1) *
sizeof(CH_FLOAT));
1017 CH_FLOAT* points_cf, *points_s;
1018 int* visible_ind, *visible, *nonvisible_faces, *f0, *face_s, *u, *gVec, *horizon, *hVec, *pp, *hVec_mem_face;
1019 int num_visible_ind, num_nonvisible_faces, n_newfaces, count, vis;
1020 int f0_sum, u_len,
start, num_p, index, horizon_size1;
1025 visible_ind = (
int*)malloc(nFaces*
sizeof(
int));
1026 points_cf = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
1027 points_s = (CH_FLOAT*)malloc(d*
sizeof(CH_FLOAT));
1028 face_s = (
int*)malloc(d*
sizeof(
int));
1029 gVec = (
int*)malloc(d*
sizeof(
int));
1030 while( (num_pleft>0) ){
1035 for(j=0; j<num_pleft-1; j++)
1036 pleft[j] = pleft[j+1];
1041 pleft = (
int*)realloc(pleft, num_pleft*
sizeof(
int));
1045 points_s[j] = points[i*(d+1)+j];
1046 points_cf = (CH_FLOAT*)realloc(points_cf,nFaces*
sizeof(CH_FLOAT));
1047 visible_ind = (
int*)realloc(visible_ind, nFaces*
sizeof(
int));
1048#ifdef CONVHULL_3D_USE_CBLAS
1049 #ifdef CONVHULL_3D_USE_FLOAT_PRECISION
1050 cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 1, nFaces, d, 1.0f,
1055 cblas_dgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 1, nFaces, d, 1.0,
1061 for (j = 0; j < nFaces; j++) {
1063 for (k = 0; k < d; k++)
1064 points_cf[j] += points_s[k]*cf[j*d+k];
1067 num_visible_ind = 0;
1068 for(j=0; j<nFaces; j++){
1069 if(points_cf[j] + df[j] > 0.0){
1076 num_nonvisible_faces = nFaces - num_visible_ind;
1079 if(num_visible_ind!=0){
1081 visible = (
int*)malloc(num_visible_ind*
sizeof(
int));
1082 for(j=0, k=0; j<nFaces; j++){
1083 if(visible_ind[j]==1){
1090 nonvisible_faces = (
int*)malloc(num_nonvisible_faces*d*
sizeof(
int));
1091 f0 = (
int*)malloc(num_nonvisible_faces*d*
sizeof(
int));
1092 for(j=0, k=0; j<nFaces; j++){
1093 if(visible_ind[j]==0){
1095 nonvisible_faces[k*d+l] = faces[j*d+l];
1102 for(j=0; j<num_visible_ind; j++){
1106 face_s[k] = faces[vis*d+k];
1107 sort_int(face_s, NULL, NULL, d, 0);
1108 ismember(nonvisible_faces, face_s, f0, num_nonvisible_faces*d, d);
1112 for(k=0; k<num_nonvisible_faces; k++){
1115 f0_sum += f0[k*d + l];
1119 u = (
int*)malloc(u_len*
sizeof(
int));
1121 u = (
int*)realloc(u, u_len*
sizeof(
int));
1125 for(k=0; k<u_len; k++){
1129 horizon = (
int*)malloc(count*(d-1)*
sizeof(
int));
1131 horizon = (
int*)realloc(horizon, count*(d-1)*
sizeof(
int));
1133 gVec[l] = nonvisible_faces[u[k]*d+l];
1134 for(l=0, h=0; l<d; l++){
1136 horizon[(count-1)*(d-1)+h] = gVec[l];
1144 horizon_size1 = count;
1145 for(j=0, l=0; j<nFaces; j++){
1146 if(!visible_ind[j]){
1149 faces[l*d+k] = faces[j*d+k];
1153 cf[l*d+k] = cf[j*d+k];
1160 nFaces = nFaces-num_visible_ind;
1161 faces = (
int*)realloc(faces, nFaces*d*
sizeof(
int));
1162 cf = (CH_FLOAT*)realloc(cf, nFaces*d*
sizeof(CH_FLOAT));
1163 df = (CH_FLOAT*)realloc(df, nFaces*
sizeof(CH_FLOAT));
1169 n_newfaces = horizon_size1;
1170 for(j=0; j<n_newfaces; j++){
1172 faces = (
int*)realloc(faces, nFaces*d*
sizeof(
int));
1173 cf = (CH_FLOAT*)realloc(cf, nFaces*d*
sizeof(CH_FLOAT));
1174 df = (CH_FLOAT*)realloc(df, nFaces*
sizeof(CH_FLOAT));
1175 for(k=0; k<d-1; k++)
1176 faces[(nFaces-1)*d+k] = horizon[j*(d-1)+k];
1177 faces[(nFaces-1)*d+(d-1)] = i;
1182 p_s[k*d+l] = points[(faces[(nFaces-1)*d+k])*(d+1) + l];
1183 plane_nd(d, p_s, cfi, &dfi);
1185 cf[(nFaces-1)*d+k] = cfi[k];
1186 df[(nFaces-1)] = dfi;
1187 if(nFaces > CH_MAX_NUM_FACES){
1195 hVec = (
int*)malloc( nFaces*
sizeof(
int));
1196 hVec_mem_face = (
int*)malloc( nFaces*
sizeof(
int));
1197 for(j=0; j<nFaces; j++)
1199 for(k=
start; k<nFaces; k++){
1201 face_s[j] = faces[k*d+j];
1202 sort_int(face_s, NULL, NULL, d, 0);
1203 ismember(hVec, face_s, hVec_mem_face, nFaces, d);
1205 for(j=0; j<nFaces; j++)
1206 if(!hVec_mem_face[j])
1208 pp = (
int*)malloc(num_p*
sizeof(
int));
1209 for(j=0, l=0; j<nFaces; j++){
1210 if(!hVec_mem_face[j]){
1221 for(l=0; l<d+1; l++)
1222 A[j*(d+1)+l] = points[(faces[k*d+j])*(d+1) + l];
1224 for(l=0; l<d+1; l++)
1225 A[j*(d+1)+l] = points[pp[index]*(d+1)+l];
1230 detA = det_NxN((CH_FLOAT*)A, d+1);
1237 face_tmp[j] = faces[k*d+d-j-1];
1239 faces[k*d+d-j-1] = face_tmp[1-j];
1243 cf[k*d+j] = -cf[k*d+j];
1246 for(j=0; j<d+1; j++)
1247 A[l*(d+1)+j] = points[(faces[k*d+l])*(d+1) + j];
1249 for(j=0; j<d+1; j++)
1250 A[l*(d+1)+j] = points[pp[index]*(d+1)+j];
1256 detA = det_NxN((CH_FLOAT*)A, d+1);
1265 free(nonvisible_faces);
1268 free(hVec_mem_face);
1277 (*out_faces) = NULL;
1285 (*out_faces) = (
int*)malloc(nFaces*d*
sizeof(
int));
1286 memcpy((*out_faces),faces, nFaces*d*
sizeof(
int));
1287 (*nOut_faces) = nFaces;
1289 (*out_cf) = (CH_FLOAT*)malloc(nFaces*d*
sizeof(CH_FLOAT));
1290 memcpy((*out_cf), cf, nFaces*d*
sizeof(CH_FLOAT));
1293 (*out_df) = (CH_FLOAT*)malloc(nFaces*
sizeof(CH_FLOAT));
1294 memcpy((*out_df), df, nFaces*
sizeof(CH_FLOAT));
1328 const int keepOnlyUsedVerticesFLAG,
1329 char*
const obj_filename
1333 char path[256] =
"\0";
1334 memcpy(path, obj_filename, strlen(obj_filename));
1336#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
1337 CV_STRCAT(path,
".obj");
1338 fopen_s(&obj_file, path,
"wt");
1340 obj_file = fopen(strcat(path,
".obj"),
"wt");
1342 fprintf(obj_file,
"o\n");
1344 ch_vec3 v1, v2, normal;
1347 if(keepOnlyUsedVerticesFLAG){
1348 for (i = 0; i < nFaces; i++)
1350 fprintf(obj_file,
"v %f %f %f\n", vertices[faces[i*3+j]].x,
1351 vertices[faces[i*3+j]].y, vertices[faces[i*3+j]].z);
1354 for (i = 0; i < nVert; i++)
1355 fprintf(obj_file,
"v %f %f %f\n", vertices[i].x,
1356 vertices[i].y, vertices[i].z);
1360 for (i = 0; i < nFaces; i++){
1362 v1 = vertices[faces[i*3+1]];
1363 v2 = vertices[faces[i*3+2]];
1364 v1.x -= vertices[faces[i*3]].x;
1365 v1.y -= vertices[faces[i*3]].y;
1366 v1.z -= vertices[faces[i*3]].z;
1367 v2.x -= vertices[faces[i*3]].x;
1368 v2.y -= vertices[faces[i*3]].y;
1369 v2.z -= vertices[faces[i*3]].z;
1370 normal = cross(&v1, &v2);
1373 scale = 1.0/(sqrt(pow(normal.x, 2.0)+pow(normal.y, 2.0)+pow(normal.z, 2.0))+2.23e-9);
1377 fprintf(obj_file,
"vn %f %f %f\n", normal.x, normal.y, normal.z);
1381 if(keepOnlyUsedVerticesFLAG){
1382 for (i = 0; i < nFaces; i++){
1384 fprintf(obj_file,
"f %u//%u %u//%u %u//%u\n",
1392 for (i = 0; i < nFaces; i++){
1393 fprintf(obj_file,
"f %u//%u %u//%u %u//%u\n",
1394 faces[i*3] + 1, i + 1,
1395 faces[i*3+1] + 1, i + 1,
1396 faces[i*3+2] + 1, i + 1);