Ignore:
Timestamp:
Oct 19, 2014, 5:13:11 PM (10 years ago)
Author:
Frederik Heber <heber@…>
Branches:
Action_Thermostats, Add_AtomRandomPerturbation, Add_FitFragmentPartialChargesAction, Add_RotateAroundBondAction, Add_SelectAtomByNameAction, Added_ParseSaveFragmentResults, AddingActions_SaveParseParticleParameters, Adding_Graph_to_ChangeBondActions, Adding_MD_integration_tests, Adding_ParticleName_to_Atom, Adding_StructOpt_integration_tests, AtomFragments, Automaking_mpqc_open, AutomationFragmentation_failures, Candidate_v1.5.4, Candidate_v1.6.0, Candidate_v1.6.1, ChangeBugEmailaddress, ChangingTestPorts, ChemicalSpaceEvaluator, CombiningParticlePotentialParsing, Combining_Subpackages, Debian_Package_split, Debian_package_split_molecuildergui_only, Disabling_MemDebug, Docu_Python_wait, EmpiricalPotential_contain_HomologyGraph, EmpiricalPotential_contain_HomologyGraph_documentation, Enable_parallel_make_install, Enhance_userguide, Enhanced_StructuralOptimization, Enhanced_StructuralOptimization_continued, Example_ManyWaysToTranslateAtom, Exclude_Hydrogens_annealWithBondGraph, FitPartialCharges_GlobalError, Fix_BoundInBox_CenterInBox_MoleculeActions, Fix_ChargeSampling_PBC, Fix_ChronosMutex, Fix_FitPartialCharges, Fix_FitPotential_needs_atomicnumbers, Fix_ForceAnnealing, Fix_IndependentFragmentGrids, Fix_ParseParticles, Fix_ParseParticles_split_forward_backward_Actions, Fix_PopActions, Fix_QtFragmentList_sorted_selection, Fix_Restrictedkeyset_FragmentMolecule, Fix_StatusMsg, Fix_StepWorldTime_single_argument, Fix_Verbose_Codepatterns, Fix_fitting_potentials, Fixes, ForceAnnealing_goodresults, ForceAnnealing_oldresults, ForceAnnealing_tocheck, ForceAnnealing_with_BondGraph, ForceAnnealing_with_BondGraph_continued, ForceAnnealing_with_BondGraph_continued_betteresults, ForceAnnealing_with_BondGraph_contraction-expansion, FragmentAction_writes_AtomFragments, FragmentMolecule_checks_bonddegrees, GeometryObjects, Gui_Fixes, Gui_displays_atomic_force_velocity, ImplicitCharges, IndependentFragmentGrids, IndependentFragmentGrids_IndividualZeroInstances, IndependentFragmentGrids_IntegrationTest, IndependentFragmentGrids_Sole_NN_Calculation, JobMarket_RobustOnKillsSegFaults, JobMarket_StableWorkerPool, JobMarket_unresolvable_hostname_fix, MoreRobust_FragmentAutomation, ODR_violation_mpqc_open, PartialCharges_OrthogonalSummation, PdbParser_setsAtomName, PythonUI_with_named_parameters, QtGui_reactivate_TimeChanged_changes, Recreated_GuiChecks, Rewrite_FitPartialCharges, RotateToPrincipalAxisSystem_UndoRedo, SaturateAtoms_findBestMatching, SaturateAtoms_singleDegree, StoppableMakroAction, Subpackage_CodePatterns, Subpackage_JobMarket, Subpackage_LinearAlgebra, Subpackage_levmar, Subpackage_mpqc_open, Subpackage_vmg, Switchable_LogView, ThirdParty_MPQC_rebuilt_buildsystem, TrajectoryDependenant_MaxOrder, TremoloParser_IncreasedPrecision, TremoloParser_MultipleTimesteps, TremoloParser_setsAtomName, Ubuntu_1604_changes, stable
Children:
81ffd8
Parents:
6da9e9
git-author:
Frederik Heber <heber@…> (10/04/14 14:34:41)
git-committer:
Frederik Heber <heber@…> (10/19/14 17:13:11)
Message:

Rewrote ConvexizeNonconvexEnvelope().

  • now works for some sphere radii on amylose (e.g. 40 and 50).
  • we first remove all points that are only attached to concave lines.
  • also, we always flip the baseline (i.e. add a general tetraeder to the non-convex volume) for concave lines when the tetraeder does not intersect with present triangles.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Tesselation/boundary.cpp

    r6da9e9 rd289c6  
    538538      << " convex ...");
    539539
    540   // First step: RemovePointFromTesselatedSurface
    541540  do {
    542541    Concavity = false;
    543     sprintf(dummy, "-first-%d", run);
     542
     543    sprintf(dummy, "-%d", run++);
    544544    //CalculateConcavityPerBoundaryPoint(TesselStruct);
    545545    StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, dummy);
    546546
     547    // first step: remove all full-concave point
    547548    PointRunner = TesselStruct->PointsOnBoundary.begin();
    548549    PointAdvance = PointRunner; // we need an advanced point, as the PointRunner might get removed
     
    551552      point = PointRunner->second;
    552553      LOG(2, "INFO: Current point is " << *point << ".");
     554      bool all_lines_concave = true;
    553555      for (LineMap::iterator LineRunner = point->lines.begin(); LineRunner != point->lines.end(); LineRunner++) {
    554556        line = LineRunner->second;
    555557        LOG(3, "INFO: Current line of point " << *point << " is " << *line << ".");
    556         if (!line->CheckConvexityCriterion()) {
    557           // remove the point if needed
    558           LOG(1, "... point " << *point << " cannot be on convex envelope.");
    559           volume += TesselStruct->RemovePointFromTesselatedSurface(point);
    560           sprintf(dummy, "-first-%d", ++run);
    561           StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, dummy);
    562           Concavity = true;
    563           break;
    564         }
     558        all_lines_concave &= !line->CheckConvexityCriterion();
     559      }
     560      if (all_lines_concave) {
     561        // remove the point if needed
     562        LOG(1, "... point " << *point << " cannot be on convex envelope, all lines concave.");
     563        volume += TesselStruct->RemovePointFromTesselatedSurface(point);
     564        Concavity = true;
    565565      }
    566566      PointRunner = PointAdvance;
    567567    }
    568568
    569     sprintf(dummy, "-second-%d", run);
     569    sprintf(dummy, "-%d", run++);
    570570    //CalculateConcavityPerBoundaryPoint(TesselStruct);
    571571    StoreTrianglesinFile(mol, (const Tesselation *&)TesselStruct, filename, dummy);
    572572
    573     // second step: PickFarthestofTwoBaselines
     573    // second step: flip baselines, i.e. add general tetraeder at concave lines
     574    // when the tetraeder does not intersect with other already present triangles
    574575    LineRunner = TesselStruct->LinesOnBoundary.begin();
    575576    LineAdvance = LineRunner;  // we need an advanced line, as the LineRunner might get removed
     577    std::map<double, BoundaryLineSet *> GainMap;
    576578    while (LineRunner != TesselStruct->LinesOnBoundary.end()) {
    577579      LineAdvance++;
    578580      line = LineRunner->second;
    579       LOG(1, "INFO: Picking farthest baseline for line is " << *line << ".");
    580       // take highest of both lines
    581       if (TesselStruct->IsConvexRectangle(line) == NULL) {
    582         const double tmp = TesselStruct->PickFarthestofTwoBaselines(line);
    583         volume += tmp;
    584         if (tmp != 0.) {
    585           TesselStruct->FlipBaseline(line);
    586           Concavity = true;
     581      if (!line->CheckConvexityCriterion()) {
     582        LOG(2, "INFO: concave line is " << *line << ".");
     583        // gather the other points
     584        BoundaryPointSet *BPS[4];
     585        int m = 0;
     586        {
     587          for (TriangleMap::iterator runner = line->triangles.begin(); runner != line->triangles.end(); runner++)
     588            for (int j = 0; j < 3; j++) // all of their endpoints and baselines
     589              if (!line->ContainsBoundaryPoint(runner->second->endpoints[j])) // and neither of its endpoints
     590                BPS[m++] = runner->second->endpoints[j];
     591        }
     592        BPS[2] = line->endpoints[0];
     593        BPS[3] = line->endpoints[1];
     594        LOG(3, "DEBUG: other line would consist of " << *BPS[0] << " and "
     595            << *BPS[1] << ".");
     596
     597        // check for already present (third) side of the tetraeder as we then
     598        // would create a degenerate triangle
     599        bool TetraederSidePresent = false;
     600        {
     601          class TesselPoint *TriangleCandidates[3];
     602          TriangleCandidates[0] = BPS[0]->node;
     603          TriangleCandidates[1] = BPS[1]->node;
     604          TriangleCandidates[2] = BPS[2]->node;
     605          if ((TesselStruct->GetPresentTriangle(TriangleCandidates) != NULL)) {
     606            LOG(2, "REJECT: Triangle side " << *TriangleCandidates[0] << ","
     607                << *TriangleCandidates[1] << "," << *TriangleCandidates[2] << " present.");
     608            TetraederSidePresent = true;
     609          }
     610          TriangleCandidates[2] = BPS[3]->node;
     611          if ((TesselStruct->GetPresentTriangle(TriangleCandidates) != NULL)) {
     612            LOG(2, "REJECT: Triangle side " << *TriangleCandidates[0] << ","
     613                << *TriangleCandidates[1] << "," << *TriangleCandidates[2] << " present.");
     614            TetraederSidePresent = true;
     615          }
     616        }
     617
     618        if ((BPS[0] != BPS[1]) && (m == 2) && (!TetraederSidePresent)) {
     619          // check whether all adjacent triangles do not intersect with new line
     620          bool no_line_intersects = true;
     621          Vector Intersection;
     622          TriangleSet triangles;
     623          TriangleSet *firsttriangles = TesselStruct->GetAllTriangles(line->endpoints[0]);
     624          TriangleSet *secondtriangles = TesselStruct->GetAllTriangles(line->endpoints[1]);
     625          triangles.insert( firsttriangles->begin(), firsttriangles->end() );
     626          triangles.insert( secondtriangles->begin(), secondtriangles->end() );
     627          delete firsttriangles;
     628          delete secondtriangles;
     629          for (TriangleSet::const_iterator triangleiter = triangles.begin();
     630              triangleiter != triangles.end(); ++triangleiter) {
     631            const BoundaryTriangleSet * triangle = *triangleiter;
     632            bool line_intersects = triangle->GetIntersectionInsideTriangle(
     633                BPS[0]->node->getPosition(),
     634                BPS[1]->node->getPosition(),
     635                Intersection);
     636            // switch result when coinciding with endpoint
     637            bool concave_adjacent_line = false;
     638            bool intersection_is_endnode = false;
     639            for (int j=0;j<2;++j) {
     640              if (Intersection.DistanceSquared(BPS[j]->node->getPosition()) < MYEPSILON) {
     641                intersection_is_endnode = true;
     642                // check whether its an adjacent triangle and if it's concavely connected
     643                // only then are we in danger of cutting through it and need to check
     644                // sign of normal vector and intersecting line
     645                for (int i=0;i<2;++i)
     646                  for (int lineindex=0;lineindex < 3;++lineindex)
     647                    if ((triangle->lines[lineindex]->ContainsBoundaryPoint(line->endpoints[i]))
     648                        && (triangle->lines[lineindex]->ContainsBoundaryPoint(BPS[j]))) {
     649                      concave_adjacent_line = !triangle->lines[lineindex]->CheckConvexityCriterion();
     650                  }
     651                if (concave_adjacent_line) {
     652                  const Vector intersector =
     653                      BPS[(j+1)%2]->node->getPosition() - Intersection;
     654                  if (triangle->NormalVector.ScalarProduct(intersector) >= -MYEPSILON) {
     655                    LOG(4, "ACCEPT: Intersection coincides with first endpoint "
     656                        << *BPS[j] << ".");
     657                    line_intersects = false;
     658                  } else {
     659                    LOG(4, "REJECT: Intersection ends on wrong side of triangle.");
     660                  }
     661                } else {
     662                  LOG(4, "ACCEPT: Intersection coincides with first endpoint "
     663                      << *BPS[j] << ".");
     664                  line_intersects = false;
     665                }
     666              }
     667            }
     668            // if we have an intersection, check that it is within either
     669            // endpoint, i.e. check that scalar product between vectors going
     670            // from intersction to either endpoint has negative sign (both
     671            // vectors point in opposite directions)
     672            if (!intersection_is_endnode && line_intersects) {
     673              const Vector firstvector = BPS[0]->node->getPosition() - Intersection;
     674              const Vector secondvector = BPS[1]->node->getPosition() - Intersection;
     675              if (firstvector.ScalarProduct(secondvector) >= 0)
     676                line_intersects = false;
     677            }
     678            no_line_intersects &= !line_intersects;
     679          }
     680
     681          if (no_line_intersects) {
     682            // calculate the volume
     683            const double tmp =
     684                CalculateVolumeofGeneralTetraeder(
     685                    BPS[0]->node->getPosition(),
     686                    BPS[1]->node->getPosition(),
     687                    BPS[2]->node->getPosition(),
     688                    BPS[3]->node->getPosition());
     689            GainMap.insert(std::make_pair(tmp, line));
     690            LOG(2, "DEBUG: Adding concave line " << *line << " with gain of "
     691                << tmp << ".");
     692          } else {
     693            // if 2 or 3 don't
     694            LOG(2, "DEBUG: We don't added concave line " << *line
     695                << " as other line intersects with adjacent triangles.");
     696          }
    587697        }
    588698      }
    589699      LineRunner = LineAdvance;
    590700    }
    591     run++;
    592   } while (Concavity);
    593   //CalculateConcavityPerBoundaryPoint(TesselStruct);
    594   //StoreTrianglesinFile(mol, filename, "-third");
    595 
    596   // third step: IsConvexRectangle
    597 //  LineRunner = TesselStruct->LinesOnBoundary.begin();
    598 //  LineAdvance = LineRunner;  // we need an advanced line, as the LineRunner might get removed
    599 //  while (LineRunner != TesselStruct->LinesOnBoundary.end()) {
    600 //    LineAdvance++;
    601 //    line = LineRunner->second;
    602 //    LOG(1, "INFO: Current line is " << *line << ".");
    603 //    //if (LineAdvance != TesselStruct->LinesOnBoundary.end())
    604 //      //LOG(1, "INFO: Next line will be " << *(LineAdvance->second) << ".");
    605 //    if (!line->CheckConvexityCriterion(out)) {
    606 //      LOG(1, "INFO: ... line " << *line << " is concave, flipping it.");
    607 //
    608 //      // take highest of both lines
    609 //      point = TesselStruct->IsConvexRectangle(line);
    610 //      if (point != NULL)
    611 //        volume += TesselStruct->RemovePointFromTesselatedSurface(point);
    612 //    }
    613 //    LineRunner = LineAdvance;
    614 //  }
     701    // flip line with most gain
     702    if (!GainMap.empty()) {
     703      line = GainMap.rbegin()->second;
     704      const double tmp = GainMap.rbegin()->first;
     705      volume += tmp;
     706//      GainMap.clear();
     707
     708      // and flip the line
     709      LOG(1, "INFO: Flipping concave line " << *line << " with gain of "
     710          << tmp << ".");
     711      TesselStruct->FlipBaseline(line);
     712      Concavity = true;
     713    }
     714  } while ((Concavity)); // && (run < 100)
    615715
    616716  CalculateConcavityPerBoundaryPoint(TesselStruct);
     
    618718
    619719  // end
    620   LOG(0, "Volume is " << volume << ".");
     720  LOG(0, "RESULT: Added volume in convexization is " << volume << ".");
    621721  return volume;
    622722};
Note: See TracChangeset for help on using the changeset viewer.