Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/boundary.cpp

    r29812d rf66195  
    1 /** \file boundary.hpp
     1/** \file boundary.cpp
    22 *
    33 * Implementations and super-function for envelopes
    44 */
    55
    6 
     6#include "atom.hpp"
     7#include "bond.hpp"
    78#include "boundary.hpp"
     9#include "config.hpp"
     10#include "element.hpp"
     11#include "helpers.hpp"
     12#include "linkedcell.hpp"
    813#include "memoryallocator.hpp"
     14#include "molecule.hpp"
     15#include "tesselation.hpp"
     16#include "tesselationhelpers.hpp"
    917
    1018#include<gsl/gsl_poly.h>
     
    2129 * \return NDIM array of the diameters
    2230 */
    23 double *
    24 GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol,
    25     bool IsAngstroem)
     31double *GetDiametersOfCluster(ofstream *out, Boundaries *BoundaryPtr, molecule *mol, bool IsAngstroem)
    2632{
    2733  // get points on boundary of NULL was given as parameter
     
    113119;
    114120
    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 
    261121
    262122/** Determines the boundary points of a cluster.
     
    537397
    538398        // flip the line
    539         if (!mol->TesselStruct->PickFarthestofTwoBaselines(out, line))
     399        if (mol->TesselStruct->PickFarthestofTwoBaselines(out, line) == 0.)
    540400          *out << Verbose(1) << "ERROR: Correction of concave baselines failed!" << endl;
    541         else
     401        else {
     402          mol->TesselStruct->FlipBaseline(out, line);
    542403          *out << Verbose(1) << "INFO: Correction of concave baselines worked." << endl;
     404        }
    543405      }
    544406    }
     
    577439
    578440  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 */
     450bool 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;
    579477};
    580478
     
    609507  class BoundaryLineSet *line = NULL;
    610508  bool Concavity;
     509  char dummy[MAXSTRINGSIZE];
    611510  PointMap::iterator PointRunner, PointAdvance;
    612511  LineMap::iterator LineRunner, LineAdvance;
     
    621520  }
    622521
    623   //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    624   StoreTrianglesinFile(out, mol, filename, "-first");
    625 
    626522  // First step: RemovePointFromTesselatedSurface
     523  int run = 0;
     524  double tmp;
    627525  do {
    628526    Concavity = false;
     527    sprintf(dummy, "-first-%d", run);
     528    //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
     529    StoreTrianglesinFile(out, mol, filename, dummy);
     530
    629531    PointRunner = TesselStruct->PointsOnBoundary.begin();
    630532    PointAdvance = PointRunner; // we need an advanced point, as the PointRunner might get removed
     
    636538        line = LineRunner->second;
    637539        *out << Verbose(2) << "INFO: Current line of point " << *point << " is " << *line << "." << endl;
    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);
     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        }
    644549      }
    645550      PointRunner = PointAdvance;
    646551    }
    647552
     553    sprintf(dummy, "-second-%d", run);
    648554    //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    649     //StoreTrianglesinFile(out, mol, filename, "-second");
     555    StoreTrianglesinFile(out, mol, filename, dummy);
    650556
    651557    // second step: PickFarthestofTwoBaselines
     
    658564      // take highest of both lines
    659565      if (TesselStruct->IsConvexRectangle(out, line) == NULL) {
    660         TesselStruct->PickFarthestofTwoBaselines(out, line);
    661         Concavity = true;
     566        tmp = TesselStruct->PickFarthestofTwoBaselines(out, line);
     567        volume += tmp;
     568        if (tmp != 0) {
     569          mol->TesselStruct->FlipBaseline(out, line);
     570          Concavity = true;
     571        }
    662572      }
    663573      LineRunner = LineAdvance;
    664574    }
     575    run++;
    665576  } while (Concavity);
     577  //CalculateConcavityPerBoundaryPoint(out, TesselStruct);
     578  //StoreTrianglesinFile(out, mol, filename, "-third");
     579
     580  // 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//  }
     599
    666600  CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    667   StoreTrianglesinFile(out, mol, filename, "-third");
    668 
    669   // third step: IsConvexRectangle
    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   }
    688 
    689   CalculateConcavityPerBoundaryPoint(out, TesselStruct);
    690   StoreTrianglesinFile(out, mol, filename, "-fourth");
     601  StoreTrianglesinFile(out, mol, filename, "");
    691602
    692603  // end
     604  *out << Verbose(1) << "Volume is " << volume << "." << endl;
    693605  *out << Verbose(0) << "End of ConvexizeNonconvexEnvelope" << endl;
    694606  return volume;
    695607};
    696608
    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 };
    750609
    751610/** Determines the volume of a cluster.
     
    794653
    795654  return volume;
    796 }
    797 ;
     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 */
     663void 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};
    798687
    799688/** Creates multiples of the by \a *mol given cluster and suspends them in water with a given final density.
     
    939828  int N[NDIM];
    940829  int n[NDIM];
    941   double *M =  filler->ReturnFullMatrixforSymmetric(filler->cell_size);
     830  double *M =  ReturnFullMatrixforSymmetric(filler->cell_size);
    942831  double Rotations[NDIM*NDIM];
    943832  Vector AtomTranslations;
     
    958847    if ((*ListRunner)->TesselStruct == NULL) {
    959848      *out << Verbose(1) << "Pre-creating tesselation for molecule " << *ListRunner << "." << endl;
    960       FindNonConvexBorder((ofstream *)&cout, (*ListRunner), LCList[i], NULL, 5.);
     849      FindNonConvexBorder((ofstream *)&cout, (*ListRunner), LCList[i], 5., NULL);
    961850    }
    962851    i++;
     
    1080969 * \param *Tess Tesselation filled with points, lines and triangles on boundary on return
    1081970 * \param *LCList atoms in LinkedCell list
     971 * \param RADIUS radius of the virtual sphere
    1082972 * \param *filename filename prefix for output of vertex data
    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)
     973 */
     974void FindNonConvexBorder(ofstream *out, molecule* mol, class LinkedCell *LCList, const double RADIUS, const char *filename = NULL)
    1086975{
    1087   int N = 0;
    1088976  bool freeLC = false;
    1089   ofstream *tempstream = NULL;
    1090   char NumberName[255];
    1091   int TriangleFilesWritten = 0;
    1092977
    1093978  *out << Verbose(1) << "Entering search for non convex hull. " << endl;
     
    1103988  LineMap::iterator testline;
    1104989  *out << Verbose(0) << "Begin of FindNonConvexBorder\n";
    1105   bool flag = false;  // marks whether we went once through all baselines without finding any without two triangles
    1106   bool failflag = false;
    1107 
     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
    1108994  if (LCList == NULL) {
    1109995    LCList = new LinkedCell(mol, 2.*RADIUS);
     
    1111997  }
    1112998
     999  // 1. get starting triangle
    11131000  mol->TesselStruct->FindStartingTriangle(out, RADIUS, LCList);
    11141001
     1002  // 2. expand from there
    11151003  baseline = mol->TesselStruct->LinesOnBoundary.begin();
    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)) {
     1004  baseline++; // skip first line
     1005  while ((baseline != mol->TesselStruct->LinesOnBoundary.end()) || (OneLoopWithoutSuccessFlag)) {
    11211006    if (baseline->second->triangles.size() == 1) {
    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)
     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)
    11251011        cerr << "WARNING: FindNextSuitableTriangle failed." << endl;
     1012
    11261013      // write temporary envelope
    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           }
    1176         }
    1177         if (DoTecplotOutput || DoRaster3DOutput)
    1178           TriangleFilesWritten++;
     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);
     1017        }
    11791018      }
     1019      baseline = mol->TesselStruct->LinesOnBoundary.end();
     1020      *out << Verbose(2) << "Baseline set to end." << endl;
    11801021    } else {
    11811022      //cout << Verbose(1) << "Line " << *baseline->second << " has " << baseline->second->triangles.size() << " triangles adjacent" << endl;
     
    11841025    }
    11851026
    1186     N++;
     1027    if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (OneLoopWithoutSuccessFlag)) {
     1028      baseline = mol->TesselStruct->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
     1029      OneLoopWithoutSuccessFlag = false;
     1030    }
    11871031    baseline++;
    1188     if ((baseline == mol->TesselStruct->LinesOnBoundary.end()) && (flag)) {
    1189       baseline = mol->TesselStruct->LinesOnBoundary.begin();   // restart if we reach end due to newly inserted lines
    1190       flag = false;
    1191     }
    1192   }
     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//  }
    11931051
    11941052  // Purges surplus triangles.
    11951053  mol->TesselStruct->RemoveDegeneratedTriangles();
    11961054
     1055  // check envelope for consistency
     1056  CheckListOfBaselines(out, mol->TesselStruct);
     1057
    11971058  // write final envelope
    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;
     1059  CalculateConcavityPerBoundaryPoint(out, mol->TesselStruct);
     1060  StoreTrianglesinFile(out, mol, filename, "");
    12621061
    12631062  if (freeLC)
     
    12651064  *out << Verbose(0) << "End of FindNonConvexBorder\n";
    12661065};
     1066
    12671067
    12681068/** Finds a hole of sufficient size in \a this molecule to embed \a *srcmol into it.
Note: See TracChangeset for help on using the changeset viewer.