Changes in src/boundary.cpp [f66195:29812d]
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/boundary.cpp
rf66195 r29812d 1 /** \file boundary. cpp1 /** \file boundary.hpp 2 2 * 3 3 * Implementations and super-function for envelopes 4 4 */ 5 5 6 #include "atom.hpp" 7 #include "bond.hpp" 6 8 7 #include "boundary.hpp" 9 #include "config.hpp"10 #include "element.hpp"11 #include "helpers.hpp"12 #include "linkedcell.hpp"13 8 #include "memoryallocator.hpp" 14 #include "molecule.hpp"15 #include "tesselation.hpp"16 #include "tesselationhelpers.hpp"17 9 18 10 #include<gsl/gsl_poly.h> … … 29 21 * \return NDIM array of the diameters 30 22 */ 31 double *GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem) 23 double * 24 GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, 25 bool IsAngstroem) 32 26 { 33 27 // get points on boundary of NULL was given as parameter … … 119 113 ; 120 114 115 /** Creates the objects in a VRML file. 116 * \param *out output stream for debugging 117 * \param *vrmlfile output stream for tecplot data 118 * \param *Tess Tesselation structure with constructed triangles 119 * \param *mol molecule structure with atom positions 120 */ 121 void WriteVrmlFile(ofstream *out, ofstream *vrmlfile, class Tesselation *Tess, class molecule *mol) 122 { 123 atom *Walker = mol->start; 124 bond *Binder = mol->first; 125 int i; 126 Vector *center = mol->DetermineCenterOfAll(out); 127 if (vrmlfile != NULL) { 128 //cout << Verbose(1) << "Writing Raster3D file ... "; 129 *vrmlfile << "#VRML V2.0 utf8" << endl; 130 *vrmlfile << "#Created by molecuilder" << endl; 131 *vrmlfile << "#All atoms as spheres" << endl; 132 while (Walker->next != mol->end) { 133 Walker = Walker->next; 134 *vrmlfile << "Sphere {" << endl << " "; // 2 is sphere type 135 for (i=0;i<NDIM;i++) 136 *vrmlfile << Walker->x.x[i]-center->x[i] << " "; 137 *vrmlfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour 138 } 139 140 *vrmlfile << "# All bonds as vertices" << endl; 141 while (Binder->next != mol->last) { 142 Binder = Binder->next; 143 *vrmlfile << "3" << endl << " "; // 2 is round-ended cylinder type 144 for (i=0;i<NDIM;i++) 145 *vrmlfile << Binder->leftatom->x.x[i]-center->x[i] << " "; 146 *vrmlfile << "\t0.03\t"; 147 for (i=0;i<NDIM;i++) 148 *vrmlfile << Binder->rightatom->x.x[i]-center->x[i] << " "; 149 *vrmlfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour 150 } 151 152 *vrmlfile << "# All tesselation triangles" << endl; 153 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) { 154 *vrmlfile << "1" << endl << " "; // 1 is triangle type 155 for (i=0;i<3;i++) { // print each node 156 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates 157 *vrmlfile << TriangleRunner->second->endpoints[i]->node->node->x[j]-center->x[j] << " "; 158 *vrmlfile << "\t"; 159 } 160 *vrmlfile << "1. 0. 0." << endl; // red as colour 161 *vrmlfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object 162 } 163 } else { 164 cerr << "ERROR: Given vrmlfile is " << vrmlfile << "." << endl; 165 } 166 delete(center); 167 }; 168 169 /** Creates the objects in a raster3d file (renderable with a header.r3d). 170 * \param *out output stream for debugging 171 * \param *rasterfile output stream for tecplot data 172 * \param *Tess Tesselation structure with constructed triangles 173 * \param *mol molecule structure with atom positions 174 */ 175 void WriteRaster3dFile(ofstream *out, ofstream *rasterfile, class Tesselation *Tess, class molecule *mol) 176 { 177 atom *Walker = mol->start; 178 bond *Binder = mol->first; 179 int i; 180 Vector *center = mol->DetermineCenterOfAll(out); 181 if (rasterfile != NULL) { 182 //cout << Verbose(1) << "Writing Raster3D file ... "; 183 *rasterfile << "# Raster3D object description, created by MoleCuilder" << endl; 184 *rasterfile << "@header.r3d" << endl; 185 *rasterfile << "# All atoms as spheres" << endl; 186 while (Walker->next != mol->end) { 187 Walker = Walker->next; 188 *rasterfile << "2" << endl << " "; // 2 is sphere type 189 for (i=0;i<NDIM;i++) 190 *rasterfile << Walker->x.x[i]-center->x[i] << " "; 191 *rasterfile << "\t0.1\t1. 1. 1." << endl; // radius 0.05 and white as colour 192 } 193 194 *rasterfile << "# All bonds as vertices" << endl; 195 while (Binder->next != mol->last) { 196 Binder = Binder->next; 197 *rasterfile << "3" << endl << " "; // 2 is round-ended cylinder type 198 for (i=0;i<NDIM;i++) 199 *rasterfile << Binder->leftatom->x.x[i]-center->x[i] << " "; 200 *rasterfile << "\t0.03\t"; 201 for (i=0;i<NDIM;i++) 202 *rasterfile << Binder->rightatom->x.x[i]-center->x[i] << " "; 203 *rasterfile << "\t0.03\t0. 0. 1." << endl; // radius 0.05 and blue as colour 204 } 205 206 *rasterfile << "# All tesselation triangles" << endl; 207 *rasterfile << "8\n 25. -1. 1. 1. 1. 0.0 0 0 0 2\n SOLID 1.0 0.0 0.0\n BACKFACE 0.3 0.3 1.0 0 0\n"; 208 for (TriangleMap::iterator TriangleRunner = Tess->TrianglesOnBoundary.begin(); TriangleRunner != Tess->TrianglesOnBoundary.end(); TriangleRunner++) { 209 *rasterfile << "1" << endl << " "; // 1 is triangle type 210 for (i=0;i<3;i++) { // print each node 211 for (int j=0;j<NDIM;j++) // and for each node all NDIM coordinates 212 *rasterfile << TriangleRunner->second->endpoints[i]->node->node->x[j]-center->x[j] << " "; 213 *rasterfile << "\t"; 214 } 215 *rasterfile << "1. 0. 0." << endl; // red as colour 216 //*rasterfile << "18" << endl << " 0.5 0.5 0.5" << endl; // 18 is transparency type for previous object 217 } 218 *rasterfile << "9\n# terminating special property\n"; 219 } else { 220 cerr << "ERROR: Given rasterfile is " << rasterfile << "." << endl; 221 } 222 delete(center); 223 }; 224 225 /** This function creates the tecplot file, displaying the tesselation of the hull. 226 * \param *out output stream for debugging 227 * \param *tecplot output stream for tecplot data 228 * \param N arbitrary number to differentiate various zones in the tecplot format 229 */ 230 void WriteTecplotFile(ofstream *out, ofstream *tecplot, class Tesselation *TesselStruct, class molecule *mol, int N) 231 { 232 if ((tecplot != NULL) && (TesselStruct != NULL)) { 233 // write header 234 *tecplot << "TITLE = \"3D CONVEX SHELL\"" << endl; 235 *tecplot << "VARIABLES = \"X\" \"Y\" \"Z\" \"U\"" << endl; 236 *tecplot << "ZONE T=\"TRIANGLES" << N << "\", N=" << TesselStruct->PointsOnBoundary.size() << ", E=" << TesselStruct->TrianglesOnBoundary.size() << ", DATAPACKING=POINT, ZONETYPE=FETRIANGLE" << endl; 237 int *LookupList = new int[mol->AtomCount]; 238 for (int i = 0; i < mol->AtomCount; i++) 239 LookupList[i] = -1; 240 241 // print atom coordinates 242 *out << Verbose(2) << "The following triangles were created:"; 243 int Counter = 1; 244 TesselPoint *Walker = NULL; 245 for (PointMap::iterator target = TesselStruct->PointsOnBoundary.begin(); target != TesselStruct->PointsOnBoundary.end(); target++) { 246 Walker = target->second->node; 247 LookupList[Walker->nr] = Counter++; 248 *tecplot << Walker->node->x[0] << " " << Walker->node->x[1] << " " << Walker->node->x[2] << " " << target->second->value << endl; 249 } 250 *tecplot << endl; 251 // print connectivity 252 for (TriangleMap::iterator runner = TesselStruct->TrianglesOnBoundary.begin(); runner != TesselStruct->TrianglesOnBoundary.end(); runner++) { 253 *out << " " << runner->second->endpoints[0]->node->Name << "<->" << runner->second->endpoints[1]->node->Name << "<->" << runner->second->endpoints[2]->node->Name; 254 *tecplot << LookupList[runner->second->endpoints[0]->node->nr] << " " << LookupList[runner->second->endpoints[1]->node->nr] << " " << LookupList[runner->second->endpoints[2]->node->nr] << endl; 255 } 256 delete[] (LookupList); 257 *out << endl; 258 } 259 } 260 121 261 122 262 /** Determines the boundary points of a cluster. … … 397 537 398 538 // flip the line 399 if ( mol->TesselStruct->PickFarthestofTwoBaselines(out, line) == 0.)539 if (!mol->TesselStruct->PickFarthestofTwoBaselines(out, line)) 400 540 *out << Verbose(1) << "ERROR: Correction of concave baselines failed!" << endl; 401 else { 402 mol->TesselStruct->FlipBaseline(out, line); 541 else 403 542 *out << Verbose(1) << "INFO: Correction of concave baselines worked." << endl; 404 }405 543 } 406 544 } … … 439 577 440 578 cout << Verbose(1) << "End of FindConvexBorder" << endl; 441 };442 443 /** For testing removes one boundary point after another to check for leaks.444 * \param *out output stream for debugging445 * \param *TesselStruct Tesselation containing envelope with boundary points446 * \param *mol molecule447 * \param *filename name of file448 * \return true - all removed, false - something went wrong449 */450 bool RemoveAllBoundaryPoints(ofstream *out, class Tesselation *TesselStruct, molecule *mol, char *filename)451 {452 int i=0;453 char number[MAXSTRINGSIZE];454 455 if ((TesselStruct == NULL) || (TesselStruct->PointsOnBoundary.empty())) {456 *out << Verbose(2) << "ERROR: TesselStruct is empty." << endl;457 return false;458 }459 460 PointMap::iterator PointRunner;461 while (!TesselStruct->PointsOnBoundary.empty()) {462 *out << Verbose(2) << "Remaining points are: ";463 for (PointMap::iterator PointSprinter = TesselStruct->PointsOnBoundary.begin(); PointSprinter != TesselStruct->PointsOnBoundary.end(); PointSprinter++)464 *out << *(PointSprinter->second) << "\t";465 *out << endl;466 467 PointRunner = TesselStruct->PointsOnBoundary.begin();468 // remove point469 TesselStruct->RemovePointFromTesselatedSurface(out, PointRunner->second);470 471 // store envelope472 sprintf(number, "-%04d", i++);473 StoreTrianglesinFile(out, mol, filename, number);474 }475 476 return true;477 579 }; 478 580 … … 507 609 class BoundaryLineSet *line = NULL; 508 610 bool Concavity; 509 char dummy[MAXSTRINGSIZE];510 611 PointMap::iterator PointRunner, PointAdvance; 511 612 LineMap::iterator LineRunner, LineAdvance; … … 520 621 } 521 622 623 //CalculateConcavityPerBoundaryPoint(out, TesselStruct); 624 StoreTrianglesinFile(out, mol, filename, "-first"); 625 522 626 // First step: RemovePointFromTesselatedSurface 523 int run = 0;524 double tmp;525 627 do { 526 628 Concavity = false; 527 sprintf(dummy, "-first-%d", run);528 //CalculateConcavityPerBoundaryPoint(out, TesselStruct);529 StoreTrianglesinFile(out, mol, filename, dummy);530 531 629 PointRunner = TesselStruct->PointsOnBoundary.begin(); 532 630 PointAdvance = PointRunner; // we need an advanced point, as the PointRunner might get removed … … 538 636 line = LineRunner->second; 539 637 *out << Verbose(2) << "INFO: Current line of point " << *point << " is " << *line << "." << endl; 540 if (!line->CheckConvexityCriterion(out)) { 541 // remove the point if needed 542 *out << Verbose(1) << "... point " << *point << " cannot be on convex envelope." << endl; 543 volume += TesselStruct->RemovePointFromTesselatedSurface(out, point); 544 sprintf(dummy, "-first-%d", ++run); 545 StoreTrianglesinFile(out, mol, filename, dummy); 546 Concavity = true; 547 break; 548 } 638 } 639 if (!line->CheckConvexityCriterion(out)) { 640 *out << Verbose(1) << "... point " << *point << " cannot be on convex envelope." << endl; 641 // remove the point 642 Concavity = true; 643 TesselStruct->RemovePointFromTesselatedSurface(out, point); 549 644 } 550 645 PointRunner = PointAdvance; 551 646 } 552 647 553 sprintf(dummy, "-second-%d", run);554 648 //CalculateConcavityPerBoundaryPoint(out, TesselStruct); 555 StoreTrianglesinFile(out, mol, filename, dummy);649 //StoreTrianglesinFile(out, mol, filename, "-second"); 556 650 557 651 // second step: PickFarthestofTwoBaselines … … 564 658 // take highest of both lines 565 659 if (TesselStruct->IsConvexRectangle(out, line) == NULL) { 566 tmp = TesselStruct->PickFarthestofTwoBaselines(out, line); 567 volume += tmp; 568 if (tmp != 0) { 569 mol->TesselStruct->FlipBaseline(out, line); 570 Concavity = true; 571 } 660 TesselStruct->PickFarthestofTwoBaselines(out, line); 661 Concavity = true; 572 662 } 573 663 LineRunner = LineAdvance; 574 664 } 575 run++;576 665 } while (Concavity); 577 //CalculateConcavityPerBoundaryPoint(out, TesselStruct);578 //StoreTrianglesinFile(out, mol, filename, "-third");666 CalculateConcavityPerBoundaryPoint(out, TesselStruct); 667 StoreTrianglesinFile(out, mol, filename, "-third"); 579 668 580 669 // third step: IsConvexRectangle 581 //LineRunner = TesselStruct->LinesOnBoundary.begin();582 //LineAdvance = LineRunner; // we need an advanced line, as the LineRunner might get removed583 //while (LineRunner != TesselStruct->LinesOnBoundary.end()) {584 //LineAdvance++;585 //line = LineRunner->second;586 //*out << Verbose(1) << "INFO: Current line is " << *line << "." << endl;587 ////if (LineAdvance != TesselStruct->LinesOnBoundary.end())588 ////*out << Verbose(1) << "INFO: Next line will be " << *(LineAdvance->second) << "." << endl;589 //if (!line->CheckConvexityCriterion(out)) {590 //*out << Verbose(1) << "... line " << *line << " is concave, flipping it." << endl;591 // 592 //// take highest of both lines593 //point = TesselStruct->IsConvexRectangle(out, line);594 //if (point != NULL)595 // volume +=TesselStruct->RemovePointFromTesselatedSurface(out, point);596 //}597 //LineRunner = LineAdvance;598 //}670 LineRunner = TesselStruct->LinesOnBoundary.begin(); 671 LineAdvance = LineRunner; // we need an advanced line, as the LineRunner might get removed 672 while (LineRunner != TesselStruct->LinesOnBoundary.end()) { 673 LineAdvance++; 674 line = LineRunner->second; 675 *out << Verbose(1) << "INFO: Current line is " << *line << "." << endl; 676 //if (LineAdvance != TesselStruct->LinesOnBoundary.end()) 677 //*out << Verbose(1) << "INFO: Next line will be " << *(LineAdvance->second) << "." << endl; 678 if (!line->CheckConvexityCriterion(out)) { 679 *out << Verbose(1) << "... line " << *line << " is concave, flipping it." << endl; 680 681 // take highest of both lines 682 point = TesselStruct->IsConvexRectangle(out, line); 683 if (point != NULL) 684 TesselStruct->RemovePointFromTesselatedSurface(out, point); 685 } 686 LineRunner = LineAdvance; 687 } 599 688 600 689 CalculateConcavityPerBoundaryPoint(out, TesselStruct); 601 StoreTrianglesinFile(out, mol, filename, " ");690 StoreTrianglesinFile(out, mol, filename, "-fourth"); 602 691 603 692 // end 604 *out << Verbose(1) << "Volume is " << volume << "." << endl;605 693 *out << Verbose(0) << "End of ConvexizeNonconvexEnvelope" << endl; 606 694 return volume; 607 695 }; 608 696 697 /** Calculates the concavity for each of the BoundaryPointSet's in a Tesselation. 698 * Sets BoundaryPointSet::value equal to the number of connected lines that are not convex. 699 * \param *out output stream for debugging 700 * \param *TesselStruct pointer to Tesselation structure 701 */ 702 void CalculateConcavityPerBoundaryPoint(ofstream *out, class Tesselation *TesselStruct) 703 { 704 class BoundaryPointSet *point = NULL; 705 class BoundaryLineSet *line = NULL; 706 // calculate remaining concavity 707 for (PointMap::iterator PointRunner = TesselStruct->PointsOnBoundary.begin(); PointRunner != TesselStruct->PointsOnBoundary.end(); PointRunner++) { 708 point = PointRunner->second; 709 *out << Verbose(1) << "INFO: Current point is " << *point << "." << endl; 710 point->value = 0; 711 for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) { 712 line = LineRunner->second; 713 *out << Verbose(2) << "INFO: Current line of point " << *point << " is " << *line << "." << endl; 714 if (!line->CheckConvexityCriterion(out)) 715 point->value += 1; 716 } 717 } 718 }; 719 720 /** Stores triangles to file. 721 * \param *out output stream for debugging 722 * \param *mol molecule with atoms and bonds 723 * \param *filename prefix of filename 724 * \param *extraSuffix intermediate suffix 725 */ 726 void StoreTrianglesinFile(ofstream *out, molecule *mol, const char *filename, const char *extraSuffix) 727 { 728 // 4. Store triangles in tecplot file 729 if (filename != NULL) { 730 if (DoTecplotOutput) { 731 string OutputName(filename); 732 OutputName.append(extraSuffix); 733 OutputName.append(TecplotSuffix); 734 ofstream *tecplot = new ofstream(OutputName.c_str()); 735 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0); 736 tecplot->close(); 737 delete(tecplot); 738 } 739 if (DoRaster3DOutput) { 740 string OutputName(filename); 741 OutputName.append(extraSuffix); 742 OutputName.append(Raster3DSuffix); 743 ofstream *rasterplot = new ofstream(OutputName.c_str()); 744 WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol); 745 rasterplot->close(); 746 delete(rasterplot); 747 } 748 } 749 }; 609 750 610 751 /** Determines the volume of a cluster. … … 653 794 654 795 return volume; 655 }; 656 657 /** Stores triangles to file. 658 * \param *out output stream for debugging 659 * \param *mol molecule with atoms and bonds 660 * \param *filename prefix of filename 661 * \param *extraSuffix intermediate suffix 662 */ 663 void StoreTrianglesinFile(ofstream *out, molecule *mol, const char *filename, const char *extraSuffix) 664 { 665 // 4. Store triangles in tecplot file 666 if (filename != NULL) { 667 if (DoTecplotOutput) { 668 string OutputName(filename); 669 OutputName.append(extraSuffix); 670 OutputName.append(TecplotSuffix); 671 ofstream *tecplot = new ofstream(OutputName.c_str()); 672 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, 0); 673 tecplot->close(); 674 delete(tecplot); 675 } 676 if (DoRaster3DOutput) { 677 string OutputName(filename); 678 OutputName.append(extraSuffix); 679 OutputName.append(Raster3DSuffix); 680 ofstream *rasterplot = new ofstream(OutputName.c_str()); 681 WriteRaster3dFile(out, rasterplot, mol->TesselStruct, mol); 682 rasterplot->close(); 683 delete(rasterplot); 684 } 685 } 686 }; 796 } 797 ; 687 798 688 799 /** Creates multiples of the by \a *mol given cluster and suspends them in water with a given final density. … … 828 939 int N[NDIM]; 829 940 int n[NDIM]; 830 double *M = ReturnFullMatrixforSymmetric(filler->cell_size);941 double *M = filler->ReturnFullMatrixforSymmetric(filler->cell_size); 831 942 double Rotations[NDIM*NDIM]; 832 943 Vector AtomTranslations; … … 847 958 if ((*ListRunner)->TesselStruct == NULL) { 848 959 *out << Verbose(1) << "Pre-creating tesselation for molecule " << *ListRunner << "." << endl; 849 FindNonConvexBorder((ofstream *)&cout, (*ListRunner), LCList[i], 5., NULL);960 FindNonConvexBorder((ofstream *)&cout, (*ListRunner), LCList[i], NULL, 5.); 850 961 } 851 962 i++; … … 969 1080 * \param *Tess Tesselation filled with points, lines and triangles on boundary on return 970 1081 * \param *LCList atoms in LinkedCell list 971 * \param RADIUS radius of the virtual sphere972 1082 * \param *filename filename prefix for output of vertex data 973 */ 974 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const double RADIUS, const char *filename = NULL) 975 { 1083 * \para RADIUS radius of the virtual sphere 1084 */ 1085 void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const char *filename, const double RADIUS) 1086 { 1087 int N = 0; 976 1088 bool freeLC = false; 1089 ofstream *tempstream = NULL; 1090 char NumberName[255]; 1091 int TriangleFilesWritten = 0; 977 1092 978 1093 *out << Verbose(1) << "Entering search for non convex hull. " << endl; … … 988 1103 LineMap::iterator testline; 989 1104 *out << Verbose(0) << "Begin of FindNonConvexBorder\n"; 990 bool OneLoopWithoutSuccessFlag = false; // marks whether we went once through all baselines without finding any without two triangles 991 bool TesselationFailFlag = false; 992 993 // initialise Linked Cell 1105 bool flag = false; // marks whether we went once through all baselines without finding any without two triangles 1106 bool failflag = false; 1107 994 1108 if (LCList == NULL) { 995 1109 LCList = new LinkedCell(mol, 2.*RADIUS); … … 997 1111 } 998 1112 999 // 1. get starting triangle1000 1113 mol->TesselStruct->FindStartingTriangle(out, RADIUS, LCList); 1001 1114 1002 // 2. expand from there1003 1115 baseline = mol->TesselStruct->LinesOnBoundary.begin(); 1004 baseline++; // skip first line 1005 while ((baseline != mol->TesselStruct->LinesOnBoundary.end()) || (OneLoopWithoutSuccessFlag)) { 1116 // the outward most line is dangerous, as we may end up with wrapping up the starting triangle, hence 1117 // terminating the algorithm too early. 1118 if (baseline != mol->TesselStruct->LinesOnBoundary.end()) // skip first line as it its the outwardmost! 1119 baseline++; 1120 while ((baseline != mol->TesselStruct->LinesOnBoundary.end()) || (flag)) { 1006 1121 if (baseline->second->triangles.size() == 1) { 1007 // 3. find next triangle 1008 TesselationFailFlag = mol->TesselStruct->FindNextSuitableTriangle(out, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, LCList); //the line is there, so there is a triangle, but only one. 1009 OneLoopWithoutSuccessFlag = OneLoopWithoutSuccessFlag || TesselationFailFlag; 1010 if (!TesselationFailFlag) 1122 failflag = mol->TesselStruct->FindNextSuitableTriangle(out, *(baseline->second), *(((baseline->second->triangles.begin()))->second), RADIUS, N, LCList); //the line is there, so there is a triangle, but only one. 1123 flag = flag || failflag; 1124 if (!failflag) 1011 1125 cerr << "WARNING: FindNextSuitableTriangle failed." << endl; 1012 1013 1126 // write temporary envelope 1014 if (filename != NULL) { 1015 if ((DoSingleStepOutput && ((mol->TesselStruct->TrianglesOnBoundary.size() % SingleStepWidth == 0)))) { // if we have a new triangle and want to output each new triangle configuration 1016 mol->TesselStruct->Output(out, filename, mol); 1127 if ((DoSingleStepOutput && (mol->TesselStruct->TrianglesOnBoundaryCount % SingleStepWidth == 0))) { // if we have a new triangle and want to output each new triangle configuration 1128 TriangleMap::iterator runner = mol->TesselStruct->TrianglesOnBoundary.end(); 1129 runner--; 1130 class BoundaryTriangleSet *triangle = runner->second; 1131 if (triangle != NULL) { 1132 sprintf(NumberName, "-%04d-%s_%s_%s", TriangleFilesWritten, triangle->endpoints[0]->node->Name, triangle->endpoints[1]->node->Name, triangle->endpoints[2]->node->Name); 1133 if (DoTecplotOutput) { 1134 string NameofTempFile(filename); 1135 NameofTempFile.append(NumberName); 1136 for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos)) 1137 NameofTempFile.erase(npos, 1); 1138 NameofTempFile.append(TecplotSuffix); 1139 *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 1140 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 1141 WriteTecplotFile(out, tempstream, mol->TesselStruct, mol, TriangleFilesWritten); 1142 tempstream->close(); 1143 tempstream->flush(); 1144 delete(tempstream); 1145 } 1146 1147 if (DoRaster3DOutput) { 1148 string NameofTempFile(filename); 1149 NameofTempFile.append(NumberName); 1150 for(size_t npos = NameofTempFile.find_first_of(' '); npos != string::npos; npos = NameofTempFile.find(' ', npos)) 1151 NameofTempFile.erase(npos, 1); 1152 NameofTempFile.append(Raster3DSuffix); 1153 *out << Verbose(1) << "Writing temporary non convex hull to file " << NameofTempFile << ".\n"; 1154 tempstream = new ofstream(NameofTempFile.c_str(), ios::trunc); 1155 WriteRaster3dFile(out, tempstream, mol->TesselStruct, mol); 1156 // // include the current position of the virtual sphere in the temporary raster3d file 1157 // // make the circumsphere's center absolute again 1158 // helper.CopyVector(BaseRay->endpoints[0]->node->node); 1159 // helper.AddVector(BaseRay->endpoints[1]->node->node); 1160 // helper.Scale(0.5); 1161 // (*it)->OptCenter.AddVector(&helper); 1162 // Vector *center = mol->DetermineCenterOfAll(out); 1163 // (*it)->OptCenter.SubtractVector(center); 1164 // delete(center); 1165 // // and add to file plus translucency object 1166 // *tempstream << "# current virtual sphere\n"; 1167 // *tempstream << "8\n 25.0 0.6 -1.0 -1.0 -1.0 0.2 0 0 0 0\n"; 1168 // *tempstream << "2\n " << (*it)->OptCenter.x[0] << " " 1169 // << (*it)->OptCenter.x[1] << " " << (*it)->OptCenter.x[2] 1170 // << "\t" << RADIUS << "\t1 0 0\n"; 1171 // *tempstream << "9\n terminating special property\n"; 1172 tempstream->close(); 1173 tempstream->flush(); 1174 delete(tempstream); 1175 } 1017 1176 } 1177 if (DoTecplotOutput || DoRaster3DOutput) 1178 TriangleFilesWritten++; 1018 1179 } 1019 baseline = mol->TesselStruct->LinesOnBoundary.end();1020 *out << Verbose(2) << "Baseline set to end." << endl;1021 1180 } else { 1022 1181 //cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->triangles.size() << " triangles adjacent" << endl; … … 1025 1184 } 1026 1185 1027 if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (OneLoopWithoutSuccessFlag)) { 1186 N++; 1187 baseline++; 1188 if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (flag)) { 1028 1189 baseline = mol->TesselStruct->LinesOnBoundary.begin(); // restart if we reach end due to newly inserted lines 1029 OneLoopWithoutSuccessFlag = false; 1030 } 1031 baseline++; 1032 } 1033 // check envelope for consistency 1034 CheckListOfBaselines(out, mol->TesselStruct); 1035 1036 // look whether all points are inside of the convex envelope, otherwise add them via degenerated triangles 1037 //mol->TesselStruct->InsertStraddlingPoints(out, mol, LCList); 1038 // mol->GoToFirst(); 1039 // class TesselPoint *Runner = NULL; 1040 // while (!mol->IsEnd()) { 1041 // Runner = mol->GetPoint(); 1042 // *out << Verbose(1) << "Checking on " << Runner->Name << " ... " << endl; 1043 // if (!mol->TesselStruct->IsInnerPoint(out, Runner, LCList)) { 1044 // *out << Verbose(2) << Runner->Name << " is outside of envelope, adding via degenerated triangles." << endl; 1045 // mol->TesselStruct->AddBoundaryPointByDegeneratedTriangle(out, Runner, LCList); 1046 // } else { 1047 // *out << Verbose(2) << Runner->Name << " is inside of or on envelope." << endl; 1048 // } 1049 // mol->GoToNext(); 1050 // } 1190 flag = false; 1191 } 1192 } 1051 1193 1052 1194 // Purges surplus triangles. 1053 1195 mol->TesselStruct->RemoveDegeneratedTriangles(); 1054 1196 1055 // check envelope for consistency1056 CheckListOfBaselines(out, mol->TesselStruct);1057 1058 1197 // write final envelope 1059 CalculateConcavityPerBoundaryPoint(out, mol->TesselStruct); 1060 StoreTrianglesinFile(out, mol, filename, ""); 1198 if (filename != 0) { 1199 *out << Verbose(1) << "Writing final tecplot file\n"; 1200 if (DoTecplotOutput) { 1201 string OutputName(filename); 1202 OutputName.append(TecplotSuffix); 1203 ofstream *tecplot = new ofstream(OutputName.c_str()); 1204 WriteTecplotFile(out, tecplot, mol->TesselStruct, mol, -1); 1205 tecplot->close(); 1206 delete(tecplot); 1207 } 1208 if (DoRaster3DOutput) { 1209 string OutputName(filename); 1210 OutputName.append(Raster3DSuffix); 1211 ofstream *raster = new ofstream(OutputName.c_str()); 1212 WriteRaster3dFile(out, raster, mol->TesselStruct, mol); 1213 raster->close(); 1214 delete(raster); 1215 } 1216 } else { 1217 cerr << "ERROR: Could definitively not find all necessary triangles!" << endl; 1218 } 1219 1220 cout << Verbose(2) << "Check: List of Baselines with not two connected triangles:" << endl; 1221 int counter = 0; 1222 for (testline = mol->TesselStruct->LinesOnBoundary.begin(); testline != mol->TesselStruct->LinesOnBoundary.end(); testline++) { 1223 if (testline->second->triangles.size() != 2) { 1224 cout << Verbose(2) << *testline->second << "\t" << testline->second->triangles.size() << endl; 1225 counter++; 1226 } 1227 } 1228 if (counter == 0) 1229 *out << Verbose(2) << "None." << endl; 1230 1231 // // Tests the IsInnerAtom() function. 1232 // Vector x (0, 0, 0); 1233 // *out << Verbose(0) << "Point to check: " << x << endl; 1234 // *out << Verbose(0) << "Check: IsInnerPoint() returns " << mol->TesselStruct->IsInnerPoint(out, x, LCList) 1235 // << "for vector " << x << "." << endl; 1236 // TesselPoint* a = mol->TesselStruct->PointsOnBoundary.begin()->second->node; 1237 // *out << Verbose(0) << "Point to check: " << *a << " (on boundary)." << endl; 1238 // *out << Verbose(0) << "Check: IsInnerAtom() returns " << mol->TesselStruct->IsInnerPoint(out, a, LCList) 1239 // << "for atom " << a << " (on boundary)." << endl; 1240 // LinkedNodes *List = NULL; 1241 // for (int i=0;i<NDIM;i++) { // each axis 1242 // LCList->n[i] = LCList->N[i]-1; // current axis is topmost cell 1243 // for (LCList->n[(i+1)%NDIM]=0;LCList->n[(i+1)%NDIM]<LCList->N[(i+1)%NDIM];LCList->n[(i+1)%NDIM]++) 1244 // for (LCList->n[(i+2)%NDIM]=0;LCList->n[(i+2)%NDIM]<LCList->N[(i+2)%NDIM];LCList->n[(i+2)%NDIM]++) { 1245 // List = LCList->GetCurrentCell(); 1246 // //cout << Verbose(2) << "Current cell is " << LC->n[0] << ", " << LC->n[1] << ", " << LC->n[2] << " with No. " << LC->index << "." << endl; 1247 // if (List != NULL) { 1248 // for (LinkedNodes::iterator Runner = List->begin();Runner != List->end();Runner++) { 1249 // if (mol->TesselStruct->PointsOnBoundary.find((*Runner)->nr) == mol->TesselStruct->PointsOnBoundary.end()) { 1250 // a = *Runner; 1251 // i=3; 1252 // for (int j=0;j<NDIM;j++) 1253 // LCList->n[j] = LCList->N[j]; 1254 // break; 1255 // } 1256 // } 1257 // } 1258 // } 1259 // } 1260 // *out << Verbose(0) << "Check: IsInnerPoint() returns " << mol->TesselStruct->IsInnerPoint(out, a, LCList) 1261 // << "for atom " << a << " (inside)." << endl; 1061 1262 1062 1263 if (freeLC) … … 1065 1266 }; 1066 1267 1067 1068 1268 /** Finds a hole of sufficient size in \a this molecule to embed \a *srcmol into it. 1069 1269 * \param *out output stream for debugging
Note:
See TracChangeset
for help on using the changeset viewer.