00001
00012 #include "TriBrep.h"
00013
00014
00015 using namespace jbxl;
00016
00017
00024 DllExport void jbxl::CreateContoursList(BREP_SOLID* solid)
00025 {
00026 solid->contours.clear();
00027
00028 BREP_SHELL_LIST shells = solid->shells;
00029 BREP_SHELL_LIST::iterator ishell;
00030 for (ishell=shells.begin(); ishell!=shells.end(); ishell++){
00031 BREP_FACET* pbfc;
00032 BREP_FACET_LIST::iterator ifacet;
00033 for (ifacet =(*ishell)->facets.begin(); ifacet!=(*ishell)->facets.end(); ifacet++){
00034 if ((*ifacet)->deletable && !(*ifacet)->notdelete) {
00035 pbfc = *ifacet;
00036 ifacet = (*ishell)->facets.erase(ifacet);
00037 ifacet--;
00038 pbfc->shell = NULL;
00039 delete(pbfc);
00040 }
00041 else {
00042 BREP_CONTOUR_LIST::iterator icon;
00043 for (icon=(*ifacet)->outer_contours.begin(); icon!=(*ifacet)->outer_contours.end(); icon++) {
00044 (*ifacet)->deletable = false;
00045 solid->contours.push_back(*icon);
00046 }
00047 }
00048 }
00049 }
00050 solid->facetno = (int)solid->contours.size();
00051 }
00052
00053
00054
00061 DllExport void jbxl::CreateWingsList(BREP_SOLID* solid)
00062 {
00063 solid->wings.clear();
00064
00065 BREP_CONTOUR_LIST::iterator icon;
00066 for (icon=solid->contours.begin(); icon!=solid->contours.end(); icon++) {
00067 BREP_WING* first = (*icon)->wing;
00068 if (first!=NULL) {
00069 BREP_WING* next = first;
00070 do {
00071 BREP_WING* wing = next;
00072 next = wing->next;
00073 solid->wings.push_back(wing);
00074 if (!wing->edge->complete) solid->wings.push_back(GetWingOtherSide(wing));
00075 } while(next!=first);
00076 }
00077 }
00078 }
00079
00080
00081
00088 DllExport void jbxl::CreateSurplusContoursList(BREP_SOLID* solid)
00089 {
00090
00091 solid->surplus_contours.clear();
00092
00093 BREP_CONTOUR_LIST::iterator icon;
00094 for (icon=solid->contours.begin(); icon!=solid->contours.end(); icon++){
00095 if (DupEdgeNumber(*icon)>0) {
00096 solid->surplus_contours.push_back(*icon);
00097 }
00098 }
00099
00100 }
00101
00102
00103
00110 DllExport void jbxl::CreateShortageWingsList(BREP_SOLID* solid)
00111 {
00112 solid->shortage_wings.clear();
00113
00114 BREP_WING_LIST::iterator iwing;
00115 for (iwing=solid->wings.begin(); iwing!=solid->wings.end(); iwing++){
00116 if ((*iwing)->contour==NULL) solid->shortage_wings.push_back(*iwing);
00117 }
00118 }
00119
00120
00121
00122
00124
00125
00146 DllExport void jbxl::DeleteSurplusContours(BREP_SOLID* solid)
00147 {
00148 if (solid->surplus_contours.empty()) return;
00149
00150
00151 CVCounter* counter = NULL;
00152 if (solid->counter!=NULL) counter = solid->counter->GetUsableCounter();
00153 if (counter!=NULL) counter->SetMax((int)solid->surplus_contours.size()*3);
00154
00155 BREP_CONTOUR_LIST::iterator icon;
00156
00157 for (icon=solid->surplus_contours.begin(); icon!=solid->surplus_contours.end(); icon++){
00158 if ((*icon)->dup_edge==3) (*icon)->facet->deletable = true;
00159 if (counter!=NULL) counter->StepIt();
00160 }
00161 ReverseContours(solid);
00162 CreateShortageWingsList(solid);
00163 JoinShortageWings(solid);
00164
00165 CreateSurplusContoursList(solid);
00166 if (solid->surplus_contours.empty()) {
00167
00168 return;
00169 }
00170
00171
00172 for (icon=solid->surplus_contours.begin(); icon!=solid->surplus_contours.end(); icon++){
00173 if ((*icon)->dup_edge==2) (*icon)->facet->deletable = true;
00174 if (counter!=NULL) counter->StepIt();
00175 }
00176 ReverseContours(solid);
00177 CreateShortageWingsList(solid);
00178 JoinShortageWings(solid);
00179
00180 CreateSurplusContoursList(solid);
00181 if (solid->surplus_contours.empty()) {
00182
00183 return;
00184 }
00185
00186
00187 for (icon=solid->surplus_contours.begin(); icon!=solid->surplus_contours.end(); icon++){
00188 if ((*icon)->dup_edge==1) (*icon)->facet->deletable = true;
00189 if (counter!=NULL) counter->StepIt();
00190 }
00191 ReverseContours(solid);
00192 CreateShortageWingsList(solid);
00193 JoinShortageWings(solid);
00194
00195 CreateSurplusContoursList(solid);
00196 if (!solid->surplus_contours.empty()) {
00197
00198 }
00199
00200 return;
00201 }
00202
00203
00204
00217 DllExport void jbxl::DeleteStraightEdges(BREP_SOLID* solid)
00218 {
00219 if (solid->shortage_wings.empty()) return;
00220
00221
00222 CVCounter* counter = NULL;
00223 if (solid->counter!=NULL) counter = solid->counter->GetUsableCounter();
00224 if (counter!=NULL) counter->SetMax((int)solid->shortage_wings.size());
00225
00226 BREP_WING_LIST::iterator wing1;
00227 for (wing1=solid->shortage_wings.begin(); wing1!=solid->shortage_wings.end(); wing1++){
00228 BREP_VERTEX* vert[3];
00229 vert[0] = (*wing1)->vertex;
00230 BREP_WING_LIST::iterator wing2;
00231 for (wing2=solid->shortage_wings.begin(); wing2!=solid->shortage_wings.end(); wing2++){
00232 if (IsConnectEdges(*wing1, *wing2)) {
00233 vert[1] = (*wing2)->vertex;
00234 vert[2] = GetWingOtherSide(*wing2)->vertex;
00235 IsForbiddenEdge(vert);
00236 }
00237 }
00238 if (counter!=NULL) counter->StepIt();
00239 }
00240 CreateContoursList(solid);
00241 CreateWingsList(solid);
00242
00243
00244 return;
00245 }
00246
00247
00248
00258 DllExport void jbxl::DeleteShortageWings(BREP_SOLID* solid)
00259 {
00260 if (solid->shortage_wings.empty()) return;
00261
00262
00263 CVCounter* counter = NULL;
00264 if (solid->counter!=NULL) counter = solid->counter->GetUsableCounter();
00265 if (counter!=NULL) counter->SetMax((int)solid->shortage_wings.size());
00266
00267 BREP_WING_LIST::iterator iwing;
00268 for (iwing=solid->shortage_wings.begin(); iwing!=solid->shortage_wings.end(); iwing++){
00269 if ((*iwing)->contour!=NULL) (*iwing)->contour->facet->deletable = true;
00270 BREP_WING* othwing = GetWingOtherSide(*iwing);
00271 if (othwing->contour!=NULL) othwing->contour->facet->deletable = true;
00272 if (counter!=NULL) counter->StepIt();
00273 }
00274
00275 CreateContoursList(solid);
00276 CreateWingsList(solid);
00277
00278 return;
00279 }
00280
00281
00282
00283 #define JBXL_BREP_MAX_LOOPCNT 20
00284
00285
00301 DllExport void jbxl::FillShortageWings(BREP_SOLID* solid, int method, bool mode)
00302 {
00303 if (solid->shortage_wings.empty()) return;
00304
00305
00306 int wmax = (int)solid->shortage_wings.size();
00307 CVCounter* counter = NULL;
00308 if (solid->counter!=NULL) counter = solid->counter->GetUsableCounter();
00309 if (counter!=NULL) counter->SetMax(wmax);
00310
00311 int lpc = 0;
00312 int pno = 1;
00313 while (solid->shortage_wings.size()>1 && pno!=0 && lpc<JBXL_BREP_MAX_LOOPCNT) {
00314 if (method==1) pno = FillShortageWings_Next(solid, mode);
00315 else if (method==2) pno = FillShortageWings_Near(solid, mode);
00316 else {
00317
00318
00319 return;
00320 }
00321 CreateShortageWingsList(solid);
00322
00323 lpc++;
00324 }
00325
00326
00327 return;
00328 }
00329
00330
00331
00347 DllExport int jbxl::FillShortageWings_Next(BREP_SOLID* solid, bool mode)
00348 {
00349 int patchno = 0;
00350
00351 BREP_WING_LIST::iterator wing1;
00352 for (wing1=solid->shortage_wings.begin(); wing1!=solid->shortage_wings.end(); wing1++){
00353 if (!IsIncludeCompleteEdge(*wing1)) {
00354 BREP_VERTEX* vert[3];
00355
00356 vert[0] = (*wing1)->vertex;
00357 BREP_WING_LIST::iterator wing2;
00358 for (wing2=solid->shortage_wings.begin(); wing2!=solid->shortage_wings.end(); wing2++){
00359 if (!IsIncludeCompleteEdge(*wing2) && IsConnectEdges(*wing1, *wing2)) {
00360 vert[1] = (*wing2)->vertex;
00361 vert[2] = GetWingOtherSide(*wing2)->vertex;
00362 BREP_SHELL* shell = GetWingOtherSide(*wing1)->contour->facet->shell;
00363 if (PatchupContour(shell, vert, mode)) patchno++;
00364 }
00365 }
00366 }
00367 }
00368 CreateContoursList(solid);
00369 CreateWingsList(solid);
00370
00371 return patchno;
00372 }
00373
00374
00375
00376 #define JBXL_BREP_MAX_QUEUESIZE 1
00377
00378
00394 DllExport int jbxl::FillShortageWings_Near(BREP_SOLID* solid, bool mode)
00395 {
00396 int patchno = 0;
00397 BREP_VERTEX_LIST vertex_list;
00398
00399 BREP_WING_LIST::iterator wing1;
00400 for (wing1=solid->shortage_wings.begin(); wing1!=solid->shortage_wings.end(); wing1++){
00401 if (!IsIncludeCompleteEdge(*wing1)) {
00402 BREP_VERTEX* vert[3];
00403 vert[0] = (*wing1)->vertex;
00404 vert[1] = GetWingOtherSide(*wing1)->vertex;
00405 vert[2] = NULL;
00406 vertex_list.clear();
00407
00408 BREP_WING_LIST::iterator wing2;
00409 for (wing2=solid->shortage_wings.begin(); wing2!=solid->shortage_wings.end(); wing2++){
00410 if (wing1!=wing2) {
00411 BREP_VERTEX* vrtx = (*wing2)->vertex;
00412 if (vrtx!=vert[0] && vrtx!=vert[1]) {
00413
00414
00415
00416
00417
00418
00419
00420
00421 Vector<double> vect = (*wing1)->edge->center - vrtx->point;
00422 vrtx->distance2 = vect.norm2();
00423 SetMinVertex(&vertex_list, vrtx);
00424
00425 }
00426 }
00427 }
00428
00429 int cnt=0;
00430 BREP_SHELL* shell = GetWingOtherSide(*wing1)->contour->facet->shell;
00431 BREP_VERTEX_LIST::iterator ivert;
00432 for (ivert=vertex_list.begin(); ivert!=vertex_list.end(); ivert++){
00433 vert[2] = *ivert;
00434 if (PatchupContour(shell, vert, mode)) {
00435 patchno++;
00436 break;
00437 }
00438 cnt++;
00439 if (cnt>=JBXL_BREP_MAX_QUEUESIZE) break;
00440 }
00441
00442 }
00443 }
00444 CreateContoursList(solid);
00445 CreateWingsList(solid);
00446
00447 return patchno;
00448 }
00449
00450
00451
00457 DllExport void jbxl::SetMinVertex(BREP_VERTEX_LIST* list, BREP_VERTEX* vrtx)
00458 {
00459 BREP_VERTEX_LIST::iterator ivert;
00460 for (ivert=list->begin(); ivert!=list->end(); ivert++){
00461 if (vrtx==(*ivert)) return;
00462 if (vrtx->distance2 < (*ivert)->distance2) {
00463 list->insert(ivert, vrtx);
00464 return;
00465 }
00466 }
00467 if (ivert==list->end()) list->push_back(vrtx);
00468 return;
00469 }
00470
00471
00472
00478 DllExport BREP_VERTEX* jbxl::FindConnectEdgeVertex(BREP_VERTEX* vert)
00479 {
00480 BREP_WING_LIST::iterator iwing;
00481 for (iwing=vert->wing_list.begin(); iwing!=vert->wing_list.end(); iwing++){
00482 if ((*iwing)->contour==NULL) {
00483 return GetWingOtherSide(*iwing)->vertex;
00484 }
00485 }
00486 return NULL;
00487 }
00488
00489
00490
00501 DllExport bool jbxl::PatchupContour(BREP_SHELL* shell, BREP_VERTEX** vert, bool mode)
00502 {
00503 if (vert[0]->forbidden_list!=NULL) {
00504 BREP_VERTEX_LIST::iterator vertex;
00505 vertex = std::find(vert[0]->forbidden_list->begin(), vert[0]->forbidden_list->end(), vert[2]);
00506 if (vertex!=vert[0]->forbidden_list->end()) return false;
00507 }
00508
00509 BREP_SOLID* solid = shell->solid;
00510 CVCounter* counter = NULL;
00511 if (solid->counter!=NULL) counter = solid->counter->GetUsableCounter();
00512
00513 BREP_FACET* facet = new BREP_FACET(shell);
00514 BREP_CONTOUR* contour = CreateContourByVertex(facet, vert);
00515 if (contour!=NULL) {
00516 if (DupEdgeNumber(contour)==0 || mode) {
00517 BREP_CONTOUR* collision;
00518 facet->CloseData();
00519 if (!IsCollisionContours(solid, contour, &collision)) {
00520 solid->contours.push_back(contour);
00521
00522 if (counter!=NULL) counter->StepIt();
00523 return true;
00524 }
00525 else FastDeleteFacet(facet);
00526 }
00527 else FastDeleteFacet(facet);
00528 }
00529 else FastDeleteFacet(facet);
00530
00531 return false;
00532 }
00533
00534
00535
00545 DllExport void jbxl::ReverseContours(BREP_SOLID* solid)
00546 {
00547
00548 BREP_SHELL_LIST shells = solid->shells;
00549 BREP_SHELL_LIST::iterator ishell;
00550 for (ishell=shells.begin(); ishell!=shells.end(); ishell++){
00551 BREP_FACET_LIST::iterator ifacet;
00552 for (ifacet =(*ishell)->facets.begin(); ifacet!=(*ishell)->facets.end(); ifacet++){
00553
00554 if ((*ifacet)->deletable && !(*ifacet)->notdelete) {
00555
00556 BREP_VERTEX* v[3];
00557 BREP_FACET* pbfc;
00558 BREP_CONTOUR* pbcn;
00559 BREP_CONTOUR_LIST::iterator icon;
00560 for (icon=(*ifacet)->outer_contours.begin(); icon!=(*ifacet)->outer_contours.end(); icon++) {
00561 BREP_WING* wing = (*icon)->wing;
00562 for (int i=0; i<3; i++) {
00563 v[i] = wing->vertex;
00564 wing = wing->prev;
00565 }
00566 }
00567
00568
00569 pbfc = *ifacet;
00570 ifacet = (*ishell)->facets.erase(ifacet);
00571 ifacet--;
00572 pbfc->shell = NULL;
00573 delete(pbfc);
00574
00575
00576 pbfc = new BREP_FACET(*ishell);
00577 pbcn = CreateContourByVertex(pbfc, v);
00578 if (pbcn!=NULL) {
00579 if (DupEdgeNumber(pbcn)==0) {
00580 pbfc->CloseData();
00581 }
00582 else {
00583 FastDeleteFacet(pbfc);
00584 }
00585 }
00586 else {
00587 FastDeleteFacet(pbfc);
00588 }
00589 }
00590 }
00591 }
00592
00593 CreateContoursList(solid);
00594 CreateWingsList(solid);
00595 }
00596
00597
00598
00608 DllExport void jbxl::JoinShortageWings(BREP_SOLID* solid)
00609 {
00610 if (solid->shortage_wings.empty()) return;
00611
00612
00613 BREP_WING_LIST::iterator iwing;
00614 for (iwing=solid->shortage_wings.begin(); iwing!=solid->shortage_wings.end(); iwing++){
00615 BREP_WING* wingA = (*iwing);
00616
00617 if (GetWingOtherSide(wingA)->contour==NULL) {
00618 delete (wingA->edge);
00619 continue;
00620 }
00621
00622 if (wingA->edge->edge_list!=NULL) {
00623 BREP_EDGE_LIST* edge_list = wingA->edge->edge_list;
00624 BREP_EDGE_LIST::iterator iedge;
00625 for (iedge=edge_list->begin(); iedge!=edge_list->end(); iedge++){
00626 if (wingA==(*iedge)->wing1 || wingA==(*iedge)->wing2) continue;
00627 if ((*iedge)->wing1->contour!=NULL && (*iedge)->wing2->contour!=NULL) continue;
00628
00629 BREP_WING* wingB;
00630 if ((*iedge)->wing1->contour!=NULL) wingB = (*iedge)->wing1;
00631 else if ((*iedge)->wing2->contour!=NULL) wingB = (*iedge)->wing2;
00632 else continue;
00633
00634 if (wingA->vertex==wingB->vertex) {
00635 if (wingA->edge->wing1==wingA) wingA->edge->wing1 = wingB;
00636 else if (wingA->edge->wing2==wingA) wingA->edge->wing2 = wingB;
00637 if (wingB->edge->wing1==wingB) wingB->edge->wing1 = wingA;
00638 else if (wingB->edge->wing2==wingB) wingB->edge->wing2 = wingA;
00639
00640 BREP_EDGE* sedge = wingB->edge;
00641 wingB->edge = wingA->edge;
00642 wingA->edge = sedge;
00643 wingB->edge->complete = true;
00644 wingA->edge->complete = false;
00645 break;
00646 }
00647 }
00648 }
00649 }
00650 CreateContoursList(solid);
00651 CreateWingsList(solid);
00652
00653
00654 return;
00655 }
00656
00657
00658
00659
00661
00662
00668 DllExport int jbxl::DupEdgeNumber(BREP_CONTOUR* contour)
00669 {
00670 contour->dup_edge = 0;
00671
00672 BREP_WING* first = contour->wing;
00673 if (first!=NULL) {
00674 BREP_WING* next = first;
00675 do {
00676 BREP_WING* wing = next;
00677 next = wing->next;
00678 if (wing->edge->edge_list!=NULL) contour->dup_edge++;
00679 } while(next!=first);
00680 }
00681 return contour->dup_edge;
00682 }
00683
00684
00685
00701 DllExport BREP_CONTOUR* jbxl::CreateContourByVector(BREP_FACET* facet, Vector<double>* vect, Vector<double>* nrml, UVMap<double>* uvmp, bool dupli)
00702 {
00703 BREP_SOLID* solid;
00704 BREP_CONTOUR* contour;
00705 BREP_VERTEX* vertex[3];
00706
00707 solid = facet->shell->solid;
00708
00709
00710 for (int i=0; i<3; i++) {
00711 vertex[i] = new BREP_VERTEX();
00712 vertex[i]->point = vect[i];
00713 if (nrml!=NULL) {
00714 vertex[i]->calc_normal = false;
00715 vertex[i]->normal = nrml[i];
00716 }
00717 if (uvmp!=NULL) {
00718 vertex[i]->uvmap = uvmp[i];
00719 }
00720 vertex[i]->CloseData();
00721 }
00722
00723
00724 if (vertex[0]==vertex[1] || vertex[1]==vertex[2] || vertex[0]==vertex[2]) return NULL;
00725 if (IsForbiddenEdge(vertex)) return NULL;
00726
00727
00728 BREP_VERTEX* vert;
00729 for (int i=0; i<3; i++) {
00730 vert = AddVertex2Octree(vertex[i], solid->octree, dupli);
00731 if (vert!=vertex[i]) {
00732 delete vertex[i];
00733 vertex[i] = vert;
00734 }
00735 }
00736
00737 contour = CreateContourByVertex(facet, vertex);
00738
00739 return contour;
00740 }
00741
00742
00743
00750 DllExport BREP_CONTOUR* jbxl::CreateContourByVertex(BREP_FACET* facet, BREP_VERTEX** vertex)
00751 {
00752
00753 if (vertex[0]==vertex[1] || vertex[1]==vertex[2] || vertex[0]==vertex[2]) return NULL;
00754 if (IsForbiddenEdge(vertex)) return NULL;
00755
00756 BREP_CONTOUR* contour = new BREP_CONTOUR(facet);
00757
00758
00759 BREP_WING* wing = contour->CreateWing(vertex[0], vertex[1]);
00760 if (wing!=NULL) wing = contour->CreateWing(vertex[1], vertex[2]);
00761 if (wing!=NULL) wing = contour->CreateWing(vertex[2], vertex[0]);
00762 if (wing!=NULL) {
00763 contour->CloseData();
00764 }
00765 else {
00766 delete(contour);
00767 contour = NULL;
00768 }
00769
00770 return contour;
00771 }
00772
00773
00774
00781 DllExport bool jbxl::IsIncludeCompleteEdge(BREP_WING* wing)
00782 {
00783 BREP_EDGE* edge = wing->edge;
00784 if (edge->complete) return true;
00785 if (edge->edge_list!=NULL) {
00786 BREP_EDGE_LIST::iterator iedge;
00787 for (iedge=edge->edge_list->begin(); iedge!=edge->edge_list->end(); iedge++){
00788 if ((*iedge)->complete) return true;
00789 }
00790 }
00791 return false;
00792 }
00793
00794
00795
00804 DllExport void jbxl::FastDeleteFacet(BREP_FACET* facet)
00805 {
00806 if (facet==NULL) return;
00807 if (facet->shell!=NULL) {
00808 facet->shell->facets.pop_back();
00809 facet->shell = NULL;
00810 }
00811
00812
00813 BREP_CONTOUR* bpcn;
00814 BREP_CONTOUR_LIST::iterator contour = facet->outer_contours.begin();
00815
00816 while (contour!=facet->outer_contours.end()) {
00817 bpcn = *contour;
00818 contour = facet->outer_contours.erase(contour);
00819 bpcn->facet = NULL;
00820 delete (bpcn);
00821 }
00822 free(facet);
00823
00824 return;
00825 }
00826
00827
00828
00834 DllExport void jbxl::SetDeletableContoursByEdge(BREP_EDGE* edge)
00835 {
00836 if (edge->edge_list!=NULL) {
00837 BREP_EDGE_LIST::iterator iedge;
00838 for (iedge=edge->edge_list->begin(); iedge!=edge->edge_list->end(); iedge++){
00839 if ((*iedge)->wing1->contour!=NULL) {
00840 (*iedge)->wing1->contour->facet->deletable = true;
00841 }
00842 if ((*iedge)->wing2->contour!=NULL) {
00843 (*iedge)->wing2->contour->facet->deletable = true;
00844 }
00845 }
00846 }
00847 else {
00848 if (edge->wing1->contour!=NULL) {
00849 edge->wing1->contour->facet->deletable = true;
00850 }
00851 if (edge->wing2->contour!=NULL) {
00852 edge->wing2->contour->facet->deletable = true;
00853 }
00854 }
00855 }
00856
00857
00858
00859
00861
00862
00863
00864
00865
00866
00867
00868
00869
00870
00871 DllExport int jbxl::IsAtLine(BREP_VERTEX** v)
00872 {
00873 TVector<double> vect = Vertex2TVector(v[0]);
00874 TVector<double> vect1 = Vertex2TVector(v[1]);
00875 TVector<double> vect2 = Vertex2TVector(v[2]) - vect;
00876 TVector<double> vect3 = Vertex2TVector(v[2]) - vect1;
00877 vect1 = vect1 - vect;
00878
00879 int mode = 0;
00880 double tt;
00881 double th = ProportionVector(vect2, vect1, tt);
00882 tt = Max(tt, Zero_Eps);
00883 if (th>1.-tt) mode = 1;
00884 else {
00885 th = ProportionVector(vect1, vect2, tt);
00886 tt = Max(tt, Zero_Eps);
00887 if (th>1.-tt) mode = 2;
00888 else {
00889 th = ProportionVector(vect3, vect2, tt);
00890 tt = Max(tt, Zero_Eps);
00891 if (th>1.-tt) mode = 3;
00892 }
00893 }
00894 return mode;
00895 }
00896
00897
00898
00905 DllExport bool jbxl::IsForbiddenEdge(BREP_VERTEX** vert)
00906 {
00907 BREP_EDGE* edge = NULL;
00908 int mode = IsAtLine(vert);
00909 if (mode==1) {
00910 if (vert[0]->forbidden_list==NULL) vert[0]->forbidden_list = new BREP_VERTEX_LIST();
00911 if (vert[2]->forbidden_list==NULL) vert[2]->forbidden_list = new BREP_VERTEX_LIST();
00912 vert[0]->forbidden_list->push_back(vert[2]);
00913 vert[2]->forbidden_list->push_back(vert[0]);
00914 edge = FindEdge(vert[0], vert[2]);
00915 }
00916 else if (mode==2) {
00917 if (vert[0]->forbidden_list==NULL) vert[0]->forbidden_list = new BREP_VERTEX_LIST();
00918 if (vert[1]->forbidden_list==NULL) vert[1]->forbidden_list = new BREP_VERTEX_LIST();
00919 vert[0]->forbidden_list->push_back(vert[1]);
00920 vert[1]->forbidden_list->push_back(vert[0]);
00921 edge = FindEdge(vert[0], vert[1]);
00922 }
00923 else if (mode==3) {
00924 if (vert[1]->forbidden_list==NULL) vert[1]->forbidden_list = new BREP_VERTEX_LIST();
00925 if (vert[2]->forbidden_list==NULL) vert[2]->forbidden_list = new BREP_VERTEX_LIST();
00926 vert[1]->forbidden_list->push_back(vert[2]);
00927 vert[2]->forbidden_list->push_back(vert[1]);
00928 edge = FindEdge(vert[1], vert[2]);
00929 }
00930 if (edge!=NULL) SetDeletableContoursByEdge(edge);
00931
00932 if (mode==0) return false;
00933 return true;
00934 }
00935
00936
00937
00938
00940
00941
00950 DllExport bool jbxl::IsCollisionContours(BREP_SOLID* solid, BREP_CONTOUR* contour, BREP_CONTOUR** collision)
00951 {
00952 *collision = NULL;
00953
00954 BREP_CONTOUR_LIST::iterator icon;
00955 for (icon=solid->contours.begin(); icon!=solid->contours.end(); icon++){
00956 if (!disJunctBounds(contour->facet->rbound, (*icon)->facet->rbound)) {
00957 if (!(*icon)->facet->deletable || (*icon)->facet->notdelete) {
00958 int svrtx = CommonVertex(*icon, contour);
00959 if (svrtx==3) {
00960 *collision = *icon;
00961 return true;
00962 }
00963
00964 int lineno;
00965 if (SamePlaneContour(*icon, contour, lineno)) {
00966
00967 if (!contour->hasCollisionVector) contour->ComputeDirectRS();
00968 if (IsInTriangle(*icon, contour)) {
00969 *collision = *icon;
00970 return true;
00971 }
00972 if (!(*icon)->hasCollisionVector) (*icon)->ComputeDirectRS();
00973 if (IsInTriangle(contour, *icon)) {
00974 *collision = *icon;
00975 return true;
00976 }
00977
00978
00979 if (CollisionTriContour2D(*icon, contour)) {
00980 *collision = *icon;
00981 return true;
00982 }
00983 }
00984 else {
00985 if (lineno==1) continue;
00986
00987 if (!contour->hasCollisionVector) contour->ComputeDirectRS();
00988 if (CollisionTriContour3D(*icon, contour)) {
00989 *collision = *icon;
00990 return true;
00991 }
00992 if (!(*icon)->hasCollisionVector) (*icon)->ComputeDirectRS();
00993 if (CollisionTriContour3D(contour, *icon)) {
00994 *collision = *icon;
00995 return true;
00996 }
00997 }
00998 }
00999 }
01000 }
01001 return false;
01002 }
01003
01004
01005
01012 DllExport bool jbxl::CollisionTriContour3D(BREP_CONTOUR* contour1, BREP_CONTOUR* contour2)
01013 {
01014 double tc, uc, vc, tm, um, ut, vt, tt, tmt, umt;
01015 BREP_WING* wing = contour1->wing;
01016 TVector<double> directR = contour2->directR;
01017 TVector<double> directS = contour2->directS;
01018 TVector<double> directRS = contour2->directRS;
01019 TVector<double> directT;
01020 TVector<double> directB;
01021 TVector<double> directQB;
01022 TVector<double> directN;
01023
01024
01025 for (int i=0; i<3; i++) {
01026 TVector<double> point = Vertex2TVector(wing->vertex);
01027 TVector<double> directQ = Vertex2TVector(contour2->wing->vertex) - point;
01028
01029 for (int j=0; j<2; j++) {
01030 directN = Vertex2TVector(wing->next->vertex);
01031 if (j==0) directB = directN - point;
01032 else directB = directB + (Vertex2TVector(wing->next->next->vertex) - directN)*0.5;
01033 directQB = directQ^directB;
01034
01035 um = directRS*directB;
01036 tm = directQB*directS;
01037 umt = TVectorMultiTolerance(directRS, directB);
01038 tmt = TVectorMultiTolerance(directQB, directS);
01039
01040 if (Xabs(um)>Max(umt, Zero_Eps) && Xabs(tm)>Max(tmt, Zero_Eps)) {
01041 uc = tm;
01042 tc = -directQB*directR;
01043 vc = directRS*directQ;
01044 ut = tmt;
01045 tt = TVectorMultiTolerance(directQB, directR);
01046 vt = TVectorMultiTolerance(directRS, directQ);
01047
01048 ut = Max(Collision_Tolerance, (um*ut+umt*uc)/(um*um));
01049 tt = Max(Collision_Tolerance, (tm*tt+tmt*tc)/(tm*tm));
01050 vt = Max(Collision_Tolerance, (um*vt+umt*vc)/(um*um));
01051 uc = uc/um;
01052 tc = tc/tm;
01053 vc = vc/um;
01054 directT = directR + tc*directS;
01055
01056 if (uc>ut && 1.-uc>ut && tc>tt && 1.-tc>tt && vc>vt && 1.-vc>vt &&
01057 uc*directT.n>directT.t && (1.-uc)*directT.n>directT.t &&
01058 tc*directS.n>directS.t && (1.-tc)*directS.n>directS.t &&
01059 vc*directB.n>directB.t && (1.-vc)*directB.n>directB.t) {
01060
01061
01062
01063 return true;
01064 }
01065 }
01066 }
01067 wing = wing->next;
01068 }
01069
01070 return false;
01071 }
01072
01073
01074
01075 DllExport bool jbxl::CollisionTriContour2D(BREP_CONTOUR* contour1, BREP_CONTOUR* contour2)
01076 {
01077 double uc, vc, tm, um, ut, vt, tmt, umt;
01078 BREP_WING* wing = contour1->wing;
01079 TVector<double> directR = contour2->directR;
01080 TVector<double> directS = contour2->directS;
01081 TVector<double> directRS = contour2->directRS;
01082
01083 wing = contour1->wing;
01084 for (int i=0; i<3; i++) {
01085 TVector<double> point = Vertex2TVector(wing->vertex);
01086 TVector<double> directB = Vertex2TVector(wing->next->vertex) - point;
01087 TVector<double> directQ = Vertex2TVector(contour2->wing->vertex) - point;
01088 TVector<double> directQB = directQ^directB;
01089 directB.norm();
01090
01091 tm = directQB*directS;
01092 um = directRS*directB;
01093 tmt = TVectorMultiTolerance(directQB, directS);
01094 umt = TVectorMultiTolerance(directRS, directB);
01095
01096 if (Xabs(tm)<=Max(tmt, Zero_Eps) || Xabs(um)<=Max(umt, Zero_Eps)) {
01097 TVector<double> directBR = directB^directR;
01098 TVector<double> directQR = directQ^directR;
01099 TVector<double> directQB = directQ^directB;
01100 uc = ProportionVector(directQB, directBR, ut);
01101 vc = ProportionVector(directQR, directBR, vt);
01102 ut = Max(ut, Collision_Tolerance);
01103 vt = Max(vt, Collision_Tolerance);
01104 if (uc>ut && 1.-uc>ut && vc>vt && 1.-vc>vt &&
01105 uc*directR.n>directR.t && (1.-uc)*directR.n>directR.t &&
01106 vc*directB.n>directB.t && (1.-vc)*directB.n>directB.t) {
01107
01108
01109
01110 return true;
01111 }
01112
01113 directBR = directB^directS;
01114 directQR = (directQ+directR)^directS;
01115 directQB = (directQ+directR)^directB;
01116 uc = ProportionVector(directQB, directBR, ut);
01117 vc = ProportionVector(directQR, directBR, vt);
01118 ut = Max(ut, Collision_Tolerance);
01119 vt = Max(vt, Collision_Tolerance);
01120 if (uc>ut && 1.-uc>ut && vc>vt && 1.-vc>vt &&
01121 uc*directS.n>directS.t && (1.-uc)*directS.n>directS.t &&
01122 vc*directB.n>directB.t && (1.-vc)*directB.n>directB.t) {
01123
01124
01125
01126 return true;
01127 }
01128
01129 TVector<double> directT = directR + directS;
01130 directBR = directB^directT;
01131 directQR = directQ^directT;
01132 directQB = directQ^directB;
01133 uc = ProportionVector(directQB, directBR, ut);
01134 vc = ProportionVector(directQR, directBR, vt);
01135 ut = Max(ut, Collision_Tolerance);
01136 vt = Max(vt, Collision_Tolerance);
01137 if (uc>ut && 1.-uc>ut && vc>vt && 1.-vc>vt &&
01138 uc*directT.n>directT.t && (1.-uc)*directT.n>directT.t &&
01139 vc*directB.n>directB.t && (1.-vc)*directB.n>directB.t) {
01140
01141
01142
01143 return true;
01144 }
01145 }
01146
01147 wing = wing->next;
01148 }
01149
01150 return false;
01151 }
01152
01153
01154
01155 DllExport bool jbxl::IsInTriangle(BREP_CONTOUR* contour1, BREP_CONTOUR* contour2)
01156 {
01157 double tc, uc, tt, ut;
01158 TVector<double> directS = contour2->directS;
01159 TVector<double> directRS = contour2->directRS;
01160 TVector<double> directQ, directT, directN;
01161 BREP_WING* wing = contour1->wing;
01162
01163 for (int i=0; i<3; i++) {
01164 for (int j=0; j<2; j++) {
01165 directN = Vertex2TVector(wing->vertex);
01166 if (j==0) directQ = Vertex2TVector(contour2->wing->vertex) - directN;
01167 else directQ = directQ - (Vertex2TVector(wing->next->vertex) - directN)*0.5;
01168
01169 TVector<double> directSQ = directS^directQ;
01170 TVector<double> directQR = directQ^contour2->directR;
01171 tc = ProportionVector(directQR, directSQ, tt);
01172 uc = ProportionVector(directSQ, directRS, ut);
01173 directT = contour2->directR + tc*directS;
01174 ut = Max(ut, Collision_Tolerance);
01175 tt = Max(tt, Collision_Tolerance);
01176 if (tc>tt && 1.-tc>tt && uc>ut && 1.-uc>ut &&
01177 tc*directS.n>directS.t && (1.-tc)*directS.n>directS.t &&
01178 uc*directT.n>directT.t && (1.-uc)*directT.n>directT.t) {
01179
01180
01181
01182 return true;
01183 }
01184 }
01185 }
01186 return false;
01187 }
01188
01189
01190
01191 DllExport bool jbxl::SamePlaneContour(BREP_CONTOUR* contour1, BREP_CONTOUR* contour2, int& lineno)
01192 {
01193 double um, umt, tm, tmt;
01194 BREP_WING* wing = contour1->wing;
01195 TVector<double> directB, directQ;
01196
01197 lineno = 0;
01198 for (int i=0; i<3; i++) {
01199 directB = Vertex2TVector(wing->next->vertex) - Vertex2TVector(wing->vertex);
01200 directQ = Vertex2TVector(contour2->wing->vertex) - Vertex2TVector(wing->vertex);
01201 um = contour2->directRS*directB;
01202 tm = contour2->directRS*directQ;
01203 umt = TVectorMultiTolerance(contour2->directRS, directB);
01204 tmt = TVectorMultiTolerance(contour2->directRS, directQ);
01205 if (Xabs(um)<Max(umt, Zero_Eps) && Xabs(tm)<Max(tmt, Zero_Eps)) {
01206 lineno++;
01207 }
01208 }
01209
01210 if (lineno>=2) return true;
01211 return false;
01212 }
01213
01214
01215
01216 DllExport int jbxl::CommonVertex(BREP_CONTOUR* contour1, BREP_CONTOUR* contour2)
01217 {
01218 BREP_VERTEX_LIST vertex_list;
01219
01220 int cnt = 0;
01221 BREP_WING* wing1 = contour1->wing;
01222 for (int i=0; i<3; i++) {
01223 bool common = false;
01224 BREP_WING* wing2 = contour2->wing;
01225 for (int j=0; j<3; j++) {
01226 if (wing1->vertex==wing2->vertex) {
01227 cnt++;
01228 common = true;
01229 break;
01230 }
01231 wing2 = wing2->next;
01232 }
01233 if (!common) vertex_list.push_back(wing1->vertex);
01234 wing1 = wing1->next;
01235 }
01236 return cnt;
01237 }
01238
01239
01240
01256 DllExport int jbxl::CreateTriSolidFromSTL(BREP_SOLID* solid, STLData* stldata, int fno, bool check)
01257 {
01258 BREP_SHELL* shell;
01259 BREP_FACET* facet;
01260 BREP_CONTOUR* contour;
01261 CVCounter* counter = NULL;
01262 Vector<double> v[4];
01263
01264 if (solid==NULL || stldata==NULL) return -1;
01265 if (solid->octree==NULL) return -1;
01266
01267 solid->contours.clear();
01268
01269
01270 int intvl = 1;
01271 if (solid->counter!=NULL) {
01272 counter = solid->counter->GetUsableCounter();
01273 if (counter!=NULL) {
01274 counter->SetMax(100);
01275 counter->ResetRate(80, 100);
01276 intvl = Max(1, fno/100);
01277 }
01278 }
01279
01280 shell = new BREP_SHELL(solid);
01281 for (int i=0; i<fno; i++) {
01282
01283 v[0].x = stldata[i].vect[3]; v[0].y = stldata[i].vect[4]; v[0].z = stldata[i].vect[5];
01284 v[1].x = stldata[i].vect[6]; v[1].y = stldata[i].vect[7]; v[1].z = stldata[i].vect[8];
01285 v[2].x = stldata[i].vect[9]; v[2].y = stldata[i].vect[10]; v[2].z = stldata[i].vect[11];
01286
01287
01288 facet = new BREP_FACET(shell);
01289 contour = CreateContourByVector(facet, v, NULL, NULL, false);
01290 if (contour!=NULL) {
01291
01292
01293
01294
01295
01296
01297
01298
01299
01300
01301
01302
01303
01304
01305
01306 solid->contours.push_back(contour);
01307 }
01308 else {
01309 deleteNull(facet);
01310 }
01311
01312 if (counter!=NULL && i%intvl==0) {
01313 counter->StepIt();
01314 if (counter->isCanceled()) {
01315 deleteNull(facet);
01316 return -3;
01317 }
01318 }
01319 }
01320 if (counter!=NULL) counter->PutFill();
01321
01322
01323 fno = CloseTriSolid(solid, check, counter);
01324
01325 return fno;
01326 }
01327
01328
01329
01347 DllExport int jbxl::CreateTriSolidFromVector(BREP_SOLID* solid, int vno, Vector<double>* vect, Vector<double>* nrml, UVMap<double>* uvmp, bool dupli, bool check)
01348 {
01349 BREP_SHELL* shell;
01350 BREP_FACET* facet;
01351 BREP_CONTOUR* contour;
01352 CVCounter* counter = NULL;
01353 int fno = vno/3;
01354
01355 if (solid==NULL || vect==NULL) return -1;
01356 if (solid->octree==NULL) return -1;
01357
01358 solid->contours.clear();
01359
01360
01361 int intvl = 1;
01362 if (solid->counter!=NULL) {
01363 counter = solid->counter->GetUsableCounter();
01364 if (counter!=NULL) {
01365 counter->SetMax(100);
01366 counter->ResetRate(80, 100);
01367 intvl = Max(1, fno/100);
01368 }
01369 }
01370
01371 Vector<double>* normal = NULL;
01372 UVMap<double>* uvmap = NULL;
01373 shell = new BREP_SHELL(solid);
01374
01375 for (int i=0; i<fno; i++) {
01376 facet = new BREP_FACET(shell);
01377 if (nrml!=NULL) normal = nrml + i*3;
01378 if (uvmp!=NULL) uvmap = uvmp + i*3;
01379 contour = CreateContourByVector(facet, vect+i*3, normal, uvmap, dupli);
01380
01381 if (contour!=NULL) {
01382
01383
01384
01385
01386
01387
01388
01389
01390
01391
01392
01393
01394
01395
01396
01397 solid->contours.push_back(contour);
01398 }
01399 else {
01400 deleteNull(facet);
01401 }
01402
01403 if (counter!=NULL && i%intvl==0) {
01404 counter->StepIt();
01405 if (counter->isCanceled()) {
01406 deleteNull(facet);
01407 return -3;
01408 }
01409 }
01410 }
01411 if (counter!=NULL) counter->PutFill();
01412
01413
01414 fno = CloseTriSolid(solid, check, counter);
01415
01416 return fno;
01417 }
01418
01419
01420
01436 DllExport void jbxl::AddVector2TriSolid(BREP_SOLID* solid, BREP_SHELL* shell, Vector<double>* vect, Vector<double>* nrml, UVMap<double>* uvmp, bool dupli)
01437 {
01438 BREP_FACET* facet;
01439 BREP_CONTOUR* contour;
01440
01441 if (solid==NULL || shell==NULL || vect==NULL) return;
01442 if (solid->octree==NULL) return;
01443
01444 facet = new BREP_FACET(shell);
01445 contour = CreateContourByVector(facet, vect, nrml, uvmp, dupli);
01446 if (contour!=NULL) {
01447
01448
01449
01450
01451
01452
01453
01454
01455
01456
01457
01458
01459
01460
01461
01462 solid->contours.push_back(contour);
01463 }
01464 else {
01465 deleteNull(facet);
01466 }
01467
01468 return;
01469 }
01470
01471
01472
01484 DllExport int jbxl::CloseTriSolid(BREP_SOLID* solid, bool check, CVCounter* counter)
01485 {
01486 if (solid==NULL) return -1;
01487
01488
01489 CreateContoursList(solid);
01490 CreateWingsList(solid);
01491
01492 if (check) {
01493
01494 CreateSurplusContoursList(solid);
01495 if (counter!=NULL) counter->MakeChildCounter(10);
01496 DeleteSurplusContours(solid);
01497 if (counter!=NULL) counter->DeleteChildCounter();
01498
01499 CreateShortageWingsList(solid);
01500 if (counter!=NULL) counter->MakeChildCounter(10);
01501 DeleteStraightEdges(solid);
01502 if (counter!=NULL) counter->DeleteChildCounter();
01503 }
01504
01505 CreateSurplusContoursList(solid);
01506 CreateShortageWingsList(solid);
01507 solid->vcount = 3;
01508 solid->CloseData();
01509
01510 return (int)solid->contours.size();
01511 }
01512
01513
01514
01515 DllExport bool jbxl::IsConnectEdges(BREP_WING* wing1, BREP_WING* wing2)
01516 {
01517 if (GetWingOtherSide(wing1)->vertex==wing2->vertex) return true;
01518 return false;
01519 }
01520
01521