Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/boundary.cpp

    rf66195 r29812d  
    1 /** \file boundary.cpp
     1/** \file boundary.hpp
    22 *
    33 * Implementations and super-function for envelopes
    44 */
    55
    6 #include "atom.hpp"
    7 #include "bond.hpp"
     6
    87#include "boundary.hpp"
    9 #include "config.hpp"
    10 #include "element.hpp"
    11 #include "helpers.hpp"
    12 #include "linkedcell.hpp"
    138#include "memoryallocator.hpp"
    14 #include "molecule.hpp"
    15 #include "tesselation.hpp"
    16 #include "tesselationhelpers.hpp"
    179
    1810#include<gsl/gsl_poly.h>
     
    2921 * \return NDIM array of the diameters
    3022 */
    31 double *GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem)
     23double *
     24GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol,
     25    bool IsAngstroem)
    3226{
    3327  // get points on boundary of NULL was given as parameter
     
    119113;
    120114
     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 */
     121void 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 */
     175void 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 */
     230void 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
    121261
    122262/** Determines the boundary points of a cluster.
     
    397537
    398538        // flip the line
    399         if (mol->TesselStruct->PickFarthestofTwoBaselines(out, line) == 0.)
     539        if (!mol->TesselStruct->PickFarthestofTwoBaselines(out, line))
    400540          *out << Verbose(1) << "ERROR: Correction of concave baselines failed!" << endl;
    401         else {
    402           mol->TesselStruct->FlipBaseline(out, line);
     541        else
    403542          *out << Verbose(1) << "INFO: Correction of concave baselines worked." << endl;
    404         }
    405543      }
    406544    }
     
    439577
    440578  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 debugging
    445  * \param *TesselStruct Tesselation containing envelope with boundary points
    446  * \param *mol molecule
    447  * \param *filename name of file
    448  * \return true - all removed, false - something went wrong
    449  */
    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 point
    469     TesselStruct->RemovePointFromTesselatedSurface(out, PointRunner->second);
    470 
    471     // store envelope
    472     sprintf(number, "-%04d", i++);
    473     StoreTrianglesinFile(out, mol, filename, number);
    474   }
    475 
    476   return true;
    477579};
    478580
     
    507609  class BoundaryLineSet *line = NULL;
    508610  bool Concavity;
    509   char dummy[MAXSTRINGSIZE];
    510611  PointMap::iterator PointRunner, PointAdvance;
    511612  LineMap::iterator LineRunner, LineAdvance;
     
    520621  }
    521622
     623  //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
     624  StoreTrianglesinFile(out, mol, filename, "-first");
     625
    522626  // First step: RemovePointFromTesselatedSurface
    523   int run = 0;
    524   double tmp;
    525627  do {
    526628    Concavity = false;
    527     sprintf(dummy, "-first-%d", run);
    528     //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    529     StoreTrianglesinFile(out, mol, filename, dummy);
    530 
    531629    PointRunner = TesselStruct->PointsOnBoundary.begin();
    532630    PointAdvance = PointRunner; // we need an advanced point, as the PointRunner might get removed
     
    538636        line = LineRunner->second;
    539637        *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);
    549644      }
    550645      PointRunner = PointAdvance;
    551646    }
    552647
    553     sprintf(dummy, "-second-%d", run);
    554648    //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    555     StoreTrianglesinFile(out, mol, filename, dummy);
     649    //StoreTrianglesinFile(out, mol, filename, "-second");
    556650
    557651    // second step: PickFarthestofTwoBaselines
     
    564658      // take highest of both lines
    565659      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;
    572662      }
    573663      LineRunner = LineAdvance;
    574664    }
    575     run++;
    576665  } while (Concavity);
    577   //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    578   //StoreTrianglesinFile(out, mol, filename, "-third");
     666  CalculateConcavityPerBoundaryPoint(out, TesselStruct);
     667  StoreTrianglesinFile(out, mol, filename, "-third");
    579668
    580669  // third step: IsConvexRectangle
    581 //  LineRunner = TesselStruct->LinesOnBoundary.begin();
    582 //  LineAdvance = LineRunner;  // we need an advanced line, as the LineRunner might get removed
    583 //  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 lines
    593 //      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  }
    599688
    600689  CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    601   StoreTrianglesinFile(out, mol, filename, "");
     690  StoreTrianglesinFile(out, mol, filename, "-fourth");
    602691
    603692  // end
    604   *out << Verbose(1) << "Volume is " << volume << "." << endl;
    605693  *out << Verbose(0) << "End of ConvexizeNonconvexEnvelope" << endl;
    606694  return volume;
    607695};
    608696
     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 */
     702void 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 */
     726void 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};
    609750
    610751/** Determines the volume of a cluster.
     
    653794
    654795  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;
    687798
    688799/** Creates multiples of the by \a *mol given cluster and suspends them in water with a given final density.
     
    828939  int N[NDIM];
    829940  int n[NDIM];
    830   double *M =  ReturnFullMatrixforSymmetric(filler->cell_size);
     941  double *M =  filler->ReturnFullMatrixforSymmetric(filler->cell_size);
    831942  double Rotations[NDIM*NDIM];
    832943  Vector AtomTranslations;
     
    847958    if ((*ListRunner)->TesselStruct == NULL) {
    848959      *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.);
    850961    }
    851962    i++;
     
    9691080 * \param *Tess Tesselation filled with points, lines and triangles on boundary on return
    9701081 * \param *LCList atoms in LinkedCell list
    971  * \param RADIUS radius of the virtual sphere
    9721082 * \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 */
     1085void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const char *filename, const double RADIUS)
     1086{
     1087  int N = 0;
    9761088  bool freeLC = false;
     1089  ofstream *tempstream = NULL;
     1090  char NumberName[255];
     1091  int TriangleFilesWritten = 0;
    9771092
    9781093  *out << Verbose(1) << "Entering search for non convex hull. " << endl;
     
    9881103  LineMap::iterator testline;
    9891104  *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
    9941108  if (LCList == NULL) {
    9951109    LCList = new LinkedCell(mol, 2.*RADIUS);
     
    9971111  }
    9981112
    999   // 1. get starting triangle
    10001113  mol->TesselStruct->FindStartingTriangle(out, RADIUS, LCList);
    10011114
    1002   // 2. expand from there
    10031115  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)) {
    10061121    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)
    10111125        cerr << "WARNING: FindNextSuitableTriangle failed." << endl;
    1012 
    10131126      // 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          }
    10171176        }
     1177        if (DoTecplotOutput || DoRaster3DOutput)
     1178          TriangleFilesWritten++;
    10181179      }
    1019       baseline = mol->TesselStruct->LinesOnBoundary.end();
    1020       *out << Verbose(2) << "Baseline set to end." << endl;
    10211180    } else {
    10221181      //cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->triangles.size() << " triangles adjacent" << endl;
     
    10251184    }
    10261185
    1027     if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (OneLoopWithoutSuccessFlag)) {
     1186    N++;
     1187    baseline++;
     1188    if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (flag)) {
    10281189      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  }
    10511193
    10521194  // Purges surplus triangles.
    10531195  mol->TesselStruct->RemoveDegeneratedTriangles();
    10541196
    1055   // check envelope for consistency
    1056   CheckListOfBaselines(out, mol->TesselStruct);
    1057 
    10581197  // 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;
    10611262
    10621263  if (freeLC)
     
    10651266};
    10661267
    1067 
    10681268/** Finds a hole of sufficient size in \a this molecule to embed \a *srcmol into it.
    10691269 * \param *out output stream for debugging
Note: See TracChangeset for help on using the changeset viewer.