00001
00008 #include "MeshObjectData.h"
00009
00010
00011 using namespace jbxl;
00012
00013
00014
00016
00017
00018
00019 void MeshObjectNode::init(void)
00020 {
00021 same_material= false;
00022 material_id = init_Buffer();
00023 facet_no = -1;
00024 material_param.init();
00025
00026 num_vertex = 0;
00027 num_texcrd = 0;
00028 num_polygon = 0;
00029 num_index = 0;
00030
00031 data_index = NULL;
00032 vertex_value = NULL;
00033 normal_value = NULL;
00034 texcrd_value = NULL;
00035
00036 next = NULL;
00037 prev = NULL;
00038 }
00039
00040
00041
00045 void MeshObjectNode::setMaterialParam(MaterialParam mparam)
00046 {
00047 material_param.free();
00048 material_param.dup(mparam);
00049 material_param.enable = true;
00050
00051 MeshObjectNode* node = prev;
00052 while (node!=NULL) {
00053 if (isSameMaterial(material_param, node->material_param)) {
00054 setMaterialID(_tochar(node->material_id.buf));
00055 same_material = true;
00056 return;
00057 }
00058 node = node->prev;
00059 }
00060
00061 node = next;
00062 while (node!=NULL) {
00063 if (isSameMaterial(material_param, node->material_param)) {
00064 setMaterialID(_tochar(node->material_id.buf));
00065 same_material = true;
00066 return;
00067 }
00068 node = node->next;
00069 }
00070
00071 return;
00072 }
00073
00074
00075
00076 void MeshObjectNode::setMaterialID(const char* str)
00077 {
00078 free_Buffer(&material_id);
00079
00080 if (str!=NULL) {
00081 if (str[0]=='#') {
00082 material_id = make_Buffer_str(str);
00083 }
00084 else {
00085 Buffer randomstr = make_Buffer_randomstr(MOBJN_MTERIALID_RAND_LEN);
00086 material_id = make_Buffer_str("#MATERIAL_");
00087 cat_Buffer(&randomstr, &material_id);
00088 free_Buffer(&randomstr);
00089 cat_s2Buffer("_", &material_id);
00090 cat_s2Buffer(str, &material_id);
00091 }
00092 }
00093
00094 else {
00095 Buffer randomstr = make_Buffer_randomstr(MOBJN_MTERIALID_RAND_LEN);
00096 material_id = make_Buffer_str("#MATERIAL_");
00097 cat_Buffer(&randomstr, &material_id);
00098 free_Buffer(&randomstr);
00099 }
00100
00101 return;
00102 }
00103
00104
00105
00106 void MeshObjectNode::set(int vertex, int polygon, int vcount)
00107 {
00108 num_vertex = vertex;
00109 num_texcrd = num_vertex;
00110 num_polygon = polygon;
00111 num_index = num_polygon*vcount;
00112
00113 return;
00114 }
00115
00116
00117
00118 void MeshObjectNode::free(void)
00119 {
00120 delMaterialParam();
00121 free_Buffer(&material_id);
00122
00123 free_value();
00124 }
00125
00126
00127
00128 void MeshObjectNode::free_value(void)
00129 {
00130 freeNull(data_index);
00131 freeNull(vertex_value);
00132 freeNull(normal_value);
00133 freeNull(texcrd_value);
00134 }
00135
00136
00137
00138 void MeshObjectNode::clear(void)
00139 {
00140 this->free();
00141 init();
00142 }
00143
00144
00145
00159 bool MeshObjectNode::getm(int vertex, int polygon, int vcount)
00160 {
00161 free_value();
00162
00163 if (vertex >0) num_vertex = vertex;
00164 if (polygon>0) num_polygon = polygon;
00165 if (vcount >0) num_index = num_polygon*vcount;
00166
00167 if (num_vertex<=0 || num_polygon<=0) return false;
00168 num_texcrd = num_vertex;
00169
00170 vertex_value = (Vector<double>*)malloc(num_vertex*sizeof(Vector<double>));
00171 normal_value = (Vector<double>*)malloc(num_vertex*sizeof(Vector<double>));
00172 texcrd_value = (UVMap<double>*) malloc(num_texcrd*sizeof(UVMap<double>));
00173 data_index = (int*)malloc(num_index*sizeof(int));
00174
00175 if (data_index==NULL || vertex_value==NULL || normal_value==NULL || texcrd_value==NULL) {
00176 this->free();
00177 return false;
00178 }
00179
00180 return true;
00181 }
00182
00183
00184
00188 bool MeshObjectNode::computeVertexDirect(FacetBaseData* facetdata)
00189 {
00190 if (facetdata==NULL) return false;
00191 if (facetdata->index==NULL || facetdata->vertex==NULL || facetdata->normal==NULL) return false;
00192
00193 set(facetdata->num_data, facetdata->num_index/facetdata->vcount, facetdata->vcount);
00194 if (!getm()) return false;
00195
00196 for (int i=0; i<facetdata->num_index; i++) {
00197 data_index[i] = facetdata->index[i];
00198 }
00199 for (int i=0; i<num_vertex; i++) {
00200 normal_value[i] = facetdata->normal[i];
00201 vertex_value[i] = facetdata->vertex[i];
00202 }
00203
00204 if (facetdata->texcrd!=NULL) {
00205 for (int i=0; i<num_texcrd; i++) {
00206 texcrd_value[i] = facetdata->texcrd[i];
00207 }
00208 }
00209
00210 return true;
00211 }
00212
00213
00214
00228 bool MeshObjectNode::computeVertexDirect(Vector<double>* impvtx, Vector<double>* impnrm, UVMap<double>* impmap, int impnum, int vcount)
00229 {
00230 if (impvtx==NULL || impnrm==NULL) return false;
00231
00232 set(impnum, impnum/vcount, vcount);
00233 if (!getm()) return false;
00234
00235 for (int i=0; i<num_vertex; i++) {
00236 vertex_value[i] = impvtx[i];
00237 normal_value[i] = impnrm[i];
00238 data_index[i] = i;
00239 }
00240
00241 if (impmap!=NULL) {
00242 for (int i=0; i<num_vertex; i++) {
00243 texcrd_value[i] = impmap[i];
00244 }
00245 }
00246
00247 return true;
00248 }
00249
00250
00251
00268 bool MeshObjectNode::computeVertexByBREP(Vector<double>* impvtx, Vector<double>* impnrm, UVMap<double>* impmap, int impnum, int vcount)
00269 {
00270 if (impvtx==NULL) return false;
00271
00272 BREP_SOLID* brep = new BREP_SOLID();
00273 if (brep==NULL) return false;
00274 CreateTriSolidFromVector(brep, impnum, impvtx, impnrm, impmap, false, false);
00275
00276 long int vnum;
00277 BREP_VERTEX** vertex_data = GetOctreeVertices(brep->octree, &vnum);
00278 if (vertex_data==NULL) {
00279 freeBrepSolid(brep);
00280 return false;
00281 }
00282
00283
00284 set((int)vnum, brep->facetno, vcount);
00285 if (!getm()) {
00286 ::free(vertex_data);
00287 freeBrepSolid(brep);
00288 return false;
00289 }
00290
00291
00292 for (int i=0; i<num_vertex; i++) {
00293 vertex_value[i] = vertex_data[i]->point;
00294 normal_value[i] = vertex_data[i]->normal;
00295 texcrd_value[i] = vertex_data[i]->uvmap;
00296 }
00297
00298
00299 int polyn = 0;
00300 BREP_CONTOUR_LIST::iterator icon;
00301 for (icon=brep->contours.begin(); icon!=brep->contours.end(); icon++){
00302 BREP_WING* wing = (*icon)->wing;
00303 for (int i=0; i<vcount; i++) {
00304 BREP_VERTEX* vertex = wing->vertex;
00305 if (vertex!=NULL) {
00306 data_index[polyn*vcount+i] = vertex->index;
00307 }
00308 wing = wing->next;
00309 }
00310 polyn++;
00311 }
00312
00313 ::free(vertex_data);
00314 freeBrepSolid(brep);
00315
00316 return true;
00317 }
00318
00319
00320 void MeshObjectNode::execAffineTrans(UVMap<double>* uvmap, int uvnum)
00321 {
00322 if (uvmap==NULL) uvmap = texcrd_value;
00323 if (uvnum==-1) uvnum = num_texcrd;
00324
00325 material_param.execTrans(uvmap, uvnum);
00326
00327 return;
00328 }
00329
00330
00331
00342 UVMap<double>* MeshObjectNode::generatePlanarUVMap(Vector<double> scale, UVMap<double>* uvmap)
00343 {
00344 if (num_texcrd!=num_vertex) return NULL;
00345
00346 if (uvmap==NULL) {
00347 size_t len = num_texcrd*sizeof(UVMap<double>);
00348 uvmap = (UVMap<double>*)malloc(len);
00349 }
00350
00351 for (int i=0; i<num_texcrd; i++) {
00352
00353 Vector<double> binormal;
00354
00355 if (normal_value[i].x>=0.5 || normal_value[i].x<=-0.5) {
00356 binormal.set(0.0, 1.0, 0.0);
00357 if (normal_value[i].x<0.0) binormal = - binormal;
00358 }
00359 else {
00360 binormal.set(1.0, 0.0, 0.0);
00361 if (normal_value[i].y>0.0) binormal = - binormal;
00362 }
00363
00364 Vector<double> tangent = binormal^normal_value[i];
00365 Vector<double> pos(vertex_value[i].x*scale.x, vertex_value[i].y*scale.y, vertex_value[i].z*scale.z);
00366
00367 uvmap[i].u = 0.5 + (binormal*pos)*2.0;
00368 uvmap[i].v = 0.5 - (tangent *pos)*2.0;
00369 }
00370
00371 return uvmap;
00372 }
00373
00374
00375
00376
00378
00379 void jbxl::freeMeshObjectList(MeshObjectNode*& node)
00380 {
00381 if (node==NULL) return;
00382
00383 MeshObjectNode* next = node->next;
00384 if (next!=NULL) freeMeshObjectList(next);
00385
00386 freeMeshObjectNode(node);
00387
00388 return;
00389 }
00390
00391
00392
00393
00394 MeshObjectNode* jbxl::DelMeshObjectNode(MeshObjectNode* node)
00395 {
00396 if (node==NULL) return NULL;
00397
00398 if (node->prev!=NULL) node->prev->next = node->next;
00399 if (node->next!=NULL) node->next->prev = node->prev;
00400
00401 MeshObjectNode* next = node->next;
00402 freeMeshObjectNode(node);
00403
00404 return next;
00405 }
00406
00407
00408
00409 MeshObjectNode* jbxl::AddMeshObjectNode(MeshObjectNode* list, MeshObjectNode* node)
00410 {
00411 if (list==NULL) return node;
00412 if (node==NULL) return list;
00413
00414 node->prev = list;
00415 node->next = list->next;
00416
00417 if (list->next!=NULL) list->next->prev = node;
00418 list->next = node;
00419
00420 return node;
00421 }
00422
00423
00424
00425
00427
00428
00429
00430 void MeshObjectData::init(const char* name)
00431 {
00432 data_name = make_Buffer_str(name);
00433
00434 ttl_index = 0;
00435 ttl_vertex = 0;
00436 ttl_texcrd = 0;
00437 num_node = 0;
00438 num_vcount = 3;
00439
00440 nodelist = NULL;
00441 endplist = NULL;
00442 affine_trans = NULL;
00443
00444 num_import = 0;
00445 impvtx_value = NULL;
00446 impnrm_value = NULL;
00447 impmap_value = NULL;
00448 }
00449
00450
00451
00452 void MeshObjectData::free(void)
00453 {
00454 free_Buffer(&data_name);
00455 free_value();
00456
00457 delAffineTrans();
00458
00459 freeMeshObjectList(nodelist);
00460 nodelist = endplist = NULL;
00461 }
00462
00463
00464
00465 void MeshObjectData::free_value(void)
00466 {
00467 freeNull(impvtx_value);
00468 freeNull(impnrm_value);
00469 freeNull(impmap_value);
00470 }
00471
00472
00473
00474 void MeshObjectData::clear(void)
00475 {
00476 this->free();
00477 init();
00478 }
00479
00480
00481
00490 bool MeshObjectData::addData(FacetBaseData* facetdata, MaterialParam* param)
00491 {
00492 char* name = NULL;
00493 if (param!=NULL) name = param->getAdditionalName();
00494
00495 bool ret = addNode(facetdata, name);
00496 if (ret && param!=NULL) endplist->setMaterialParam(*param);
00497
00498 return ret;
00499 }
00500
00501
00502
00519 bool MeshObjectData::addData(Vector<double>* vct, Vector<double>* nrm, UVMap<double>* map, int vnum, MaterialParam* param, bool useBrep)
00520 {
00521 bool ret = importTriData(vct, nrm, map, vnum);
00522 if (ret) {
00523 char* name = NULL;
00524 if (param!=NULL) name = param->getAdditionalName();
00525 ret = addNode(name, useBrep);
00526 }
00527
00528 if (ret && param!=NULL) endplist->setMaterialParam(*param);
00529
00530 return ret;
00531 }
00532
00533
00534
00545 bool MeshObjectData::addData(TriPolyData* tridata, int tnum, int fnum, MaterialParam* param, bool useBrep)
00546 {
00547 bool ret = importTriData(tridata, tnum, fnum);
00548 if (ret) {
00549 char* name = NULL;
00550 if (param!=NULL) name = param->getAdditionalName();
00551 ret = addNode(name, useBrep);
00552 }
00553
00554 if (ret) {
00555 if (fnum>=0) endplist->setFacetNo(fnum);
00556 if (param!=NULL) endplist->setMaterialParam(*param);
00557 }
00558
00559 return ret;
00560 }
00561
00562
00563
00573 bool MeshObjectData::importTriData(Vector<double>* vct, Vector<double>* nrm, UVMap<double>* map, int vnum)
00574 {
00575 if (vct==NULL) return false;
00576
00577 free_value();
00578
00579 int lsize = sizeof(Vector<double>)*vnum;
00580 impvtx_value = (Vector<double>*)malloc(lsize);
00581 if (impvtx_value!=NULL) memcpy(impvtx_value, vct, lsize);
00582 else return false;
00583
00584 if (nrm!=NULL) {
00585 impnrm_value = (Vector<double>*)malloc(lsize);
00586 if (impnrm_value!=NULL) {
00587 memcpy(impnrm_value, nrm, lsize);
00588 }
00589 else {
00590 freeNull(impvtx_value);
00591 return false;
00592 }
00593 }
00594
00595 if (map!=NULL) {
00596 int msize = sizeof(UVMap<double>)*vnum;
00597 impmap_value = (UVMap<double>*)malloc(msize);
00598 if (impmap_value!=NULL) {
00599 memcpy(impmap_value, map, msize);
00600 }
00601 else {
00602 freeNull(impvtx_value);
00603 freeNull(impnrm_value);
00604 return false;
00605 }
00606 }
00607
00608 num_vcount = 3;
00609 num_import = vnum;
00610
00611 return true;
00612 }
00613
00614
00615
00624 bool MeshObjectData::importTriData(TriPolyData* tridata, int tnum, int fnum)
00625 {
00626 if (tridata==NULL) return false;
00627
00628 free_value();
00629
00630 int pnum = 0;
00631 if (fnum>=0) {
00632 for (int i=0; i<tnum; i++) {
00633 if (tridata[i].facetNum==fnum) pnum++;
00634 }
00635 if (pnum==0) return false;
00636 }
00637 else pnum = tnum;
00638
00639 int vnum = pnum*3;
00640 int lsize = sizeof(Vector<double>)*vnum;
00641
00642 impvtx_value = (Vector<double>*)malloc(lsize);
00643 if (impvtx_value!=NULL) {
00644 for (int i=0, n=0; i<tnum; i++) {
00645 if (tridata[i].facetNum==fnum || fnum<0) {
00646 impvtx_value[n*3] = tridata[i].vertex[0];
00647 impvtx_value[n*3+1] = tridata[i].vertex[1];
00648 impvtx_value[n*3+2] = tridata[i].vertex[2];
00649 n++;
00650 }
00651 }
00652 }
00653 else return false;
00654
00655 impnrm_value = NULL;
00656 if (tridata[0].has_normal) {
00657 impnrm_value = (Vector<double>*)malloc(lsize);
00658 if (impnrm_value!=NULL) {
00659 for (int i=0, n=0; i<tnum; i++) {
00660 if (tridata[i].facetNum==fnum || fnum<0) {
00661 impnrm_value[n*3] = tridata[i].normal[0];
00662 impnrm_value[n*3+1] = tridata[i].normal[1];
00663 impnrm_value[n*3+2] = tridata[i].normal[2];
00664 n++;
00665 }
00666 }
00667 }
00668 else {
00669 freeNull(impvtx_value);
00670 return false;
00671 }
00672 }
00673
00674 impmap_value = NULL;
00675 if (tridata[0].has_texcrd) {
00676 int msize = sizeof(UVMap<double>)*vnum;
00677 impmap_value = (UVMap<double>*)malloc(msize);
00678 if (impmap_value!=NULL) {
00679 for (int i=0, n=0; i<tnum; i++) {
00680 if (tridata[i].facetNum==fnum || fnum<0) {
00681 impmap_value[n*3] = tridata[i].texcrd[0];
00682 impmap_value[n*3+1] = tridata[i].texcrd[1];
00683 impmap_value[n*3+2] = tridata[i].texcrd[2];
00684 n++;
00685 }
00686 }
00687 }
00688 else {
00689 freeNull(impvtx_value);
00690 freeNull(impnrm_value);
00691 return false;
00692 }
00693 }
00694
00695 num_vcount = 3;
00696 num_import = vnum;
00697
00698 return true;
00699 }
00700
00701
00702
00703 bool MeshObjectData::addNode(FacetBaseData* facetdata, const char* name)
00704 {
00705 bool ret = false;
00706
00707 MeshObjectNode* node = new MeshObjectNode();
00708 if (node==NULL) return ret;
00709 node->setMaterialID(name);
00710
00711 ret = node->computeVertexDirect(facetdata);
00712
00713 if (ret) {
00714 if (nodelist==NULL) nodelist = endplist = node;
00715 else endplist = AddMeshObjectNode(endplist, node);
00716 num_node++;
00717 ttl_index += node->num_index;
00718 ttl_vertex += node->num_vertex;
00719 ttl_texcrd += node->num_texcrd;
00720 }
00721
00722 return ret;
00723 }
00724
00725
00726
00732 bool MeshObjectData::addNode(const char* name, bool useBrep)
00733 {
00734 bool ret = false;
00735 if (impvtx_value==NULL) return ret;
00736
00737 MeshObjectNode* node = new MeshObjectNode();
00738 if (node==NULL) return ret;
00739 node->setMaterialID(name);
00740
00741 if (useBrep) {
00742 ret = node->computeVertexByBREP(impvtx_value, impnrm_value, impmap_value, num_import, num_vcount);
00743 }
00744 else {
00745 ret = node->computeVertexDirect(impvtx_value, impnrm_value, impmap_value, num_import, num_vcount);
00746 }
00747
00748 if (ret) {
00749 if (nodelist==NULL) nodelist = endplist = node;
00750 else endplist = AddMeshObjectNode(endplist, node);
00751 num_node++;
00752 ttl_index += node->num_index;
00753 ttl_vertex += node->num_vertex;
00754 ttl_texcrd += node->num_texcrd;
00755 }
00756
00757 freeNull(impvtx_value);
00758 freeNull(impnrm_value);
00759 freeNull(impmap_value);
00760
00761 return ret;
00762 }
00763
00764
00765
00772 void MeshObjectData::setMaterialParam(MaterialParam param, int num)
00773 {
00774 MeshObjectNode* node = nodelist;
00775
00776 if (num>=0) {
00777 while (node!=NULL) {
00778 if (node->facet_no==num) {
00779 node->setMaterialParam(param);
00780 return;
00781 }
00782 node = node->next;
00783 }
00784 }
00785 else {
00786 while (node!=NULL) {
00787 if (!node->material_param.enable) {
00788 node->setMaterialParam(param);
00789 return;
00790 }
00791 node = node->next;
00792 }
00793 }
00794
00795 return;
00796 }
00797
00798
00799
00805 void MeshObjectData::joinData(MeshObjectData*& data)
00806 {
00807 if (data==NULL) return;
00808
00809 ttl_index += data->ttl_index;
00810 ttl_vertex += data->ttl_vertex;
00811 ttl_texcrd += data->ttl_texcrd;
00812 num_node += data->num_node;
00813
00814 if (endplist==NULL) {
00815 setAffineTrans(*data->affine_trans);
00816 nodelist = data->nodelist;
00817 endplist = data->endplist;
00818 }
00819 else if (data->nodelist!=NULL) {
00820 endplist->next = data->nodelist;
00821 data->nodelist->prev = endplist;
00822 endplist = data->endplist;
00823 }
00824
00825 data->nodelist = NULL;
00826 freeMeshObjectData(data);
00827
00828 return;
00829 }
00830
00831
00832