LCOV - code coverage report
Current view: top level - algs/AdvFront - AF2Algorithm.cpp (source / functions) Hit Total Coverage
Test: coverage_sk.info Lines: 95 140 67.9 %
Date: 2020-07-01 15:24:36 Functions: 9 12 75.0 %
Branches: 115 350 32.9 %

           Branch data     Line data    Source code
       1                 :            : #include "meshkit/AF2Algorithm.hpp"
       2                 :            : 
       3                 :            : // C++
       4                 :            : #include <cstddef>
       5                 :            : #include <vector>
       6                 :            : #include <map>
       7                 :            : 
       8                 :            : // MeshKit
       9                 :            : #include "meshkit/AF2DfltRuleAppVisitor.hpp"
      10                 :            : #include "meshkit/AF2Edge3D.hpp"
      11                 :            : #include "meshkit/AF2RuleApplication.hpp"
      12                 :            : #include "meshkit/Error.hpp"
      13                 :            : 
      14                 :            : // for debugging
      15                 :            : #include <iostream>
      16                 :            : 
      17                 :         14 : AF2Algorithm::AF2Algorithm(const std::list<const AF2Rule*> & ruleListArg) :
      18                 :         14 :     ruleList(ruleListArg)
      19                 :            : {
      20                 :            :   // do nothing beyond copying the list of rules in initialization
      21                 :         14 : }
      22                 :            : 
      23                 :         28 : AF2Algorithm::~AF2Algorithm()
      24                 :            : {
      25                 :            :   // do nothing, the standard deletion of the rule list is sufficient,
      26                 :            :   // since this does not take ownership of the rules
      27                 :         14 : }
      28                 :            : 
      29                 :          0 : AF2Algorithm::AF2Algorithm(const AF2Algorithm & toCopy)
      30                 :            : {
      31                 :            :   // Note: the default implementation would work at this point, but
      32                 :            :   //   might not in the future, and there shouldn't be much need to
      33                 :            :   //   copy this.
      34         [ #  # ]:          0 :   MeshKit::Error notImpl(MeshKit::MK_NOT_IMPLEMENTED);
      35         [ #  # ]:          0 :   notImpl.set_string("AF2Algorithm copy construction is not supported.");
      36         [ #  # ]:          0 :   throw notImpl;
      37                 :            : }
      38                 :            : 
      39                 :          0 : AF2Algorithm& AF2Algorithm::operator=(const AF2Algorithm & rhs)
      40                 :            : {
      41                 :            :   // Note: the default implementation would work at this point, but
      42                 :            :   //   might not in the future, and there shouldn't be much need to
      43                 :            :   //   assign this.
      44         [ #  # ]:          0 :   MeshKit::Error notImpl(MeshKit::MK_NOT_IMPLEMENTED);
      45         [ #  # ]:          0 :   notImpl.set_string("AF2Algorithm assignment operator is not supported.");
      46         [ #  # ]:          0 :   throw notImpl;
      47                 :            : }
      48                 :            : 
      49                 :         35 : AF2AlgorithmResult* AF2Algorithm::execute(
      50                 :            :     const AF2LocalTransformMaker* const & transformMaker,
      51                 :            :     const double* coords, unsigned int numPoints,
      52                 :            :     const unsigned int* edges, unsigned int numEdges,
      53                 :            :     const moab::EntityHandle* vertexHandles, int debug) const
      54                 :            : {
      55                 :            :   typedef std::list<const AF2Rule*>::const_iterator RuleConstItr;
      56                 :            : 
      57                 :            :   // these are used for debugging
      58                 :            :   static int face=0;
      59                 :         35 :   face++;
      60                 :            : 
      61                 :         35 :   unsigned long int nextPointId = 0ul;
      62         [ +  - ]:         35 :   std::list<AF2Point3D*> allPoints;
      63         [ +  - ]:         70 :   std::list<const AF2Polygon3D*> allFaces;
      64         [ +  - ]:         70 :   AF2Front front;
      65                 :            : 
      66                 :            :   // initialize the front
      67                 :            :   initFront(front, allPoints, nextPointId,
      68         [ +  - ]:         35 :       coords, numPoints, edges, numEdges, vertexHandles);
      69         [ -  + ]:         35 :   if (debug>1)
      70                 :            :   {
      71 [ #  # ][ #  # ]:          0 :     std::cout<<" On surface " << face << " initial front " << allPoints.size() << " points and " << numEdges << " edges.\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
      72                 :            :   }
      73                 :         35 :   int step = 0;
      74                 :            :   // while the front is not empty and there is still progress
      75 [ +  - ][ +  + ]:      10016 :   while (!front.isEmpty() && front.getMaximumQuality() < 50u)
         [ +  - ][ +  + ]
                 [ +  + ]
      76                 :            :   {
      77                 :            :     // select a neighborhood on the advancing front
      78         [ +  - ]:       9981 :     AF2Neighborhood* ngbhd = front.selectNeighborhood(transformMaker);
      79         [ +  - ]:       9981 :     AF2Edge3D* baselineEdge = ngbhd->getBaselineEdge3D();
      80                 :            : 
      81                 :            :     // attempt to apply each of the rules to the neighborhood
      82         [ +  - ]:       9981 :     AF2DfltRuleAppVisitor ruleAppVisitor;
      83 [ +  - ][ +  - ]:     127413 :     for (RuleConstItr itr = ruleList.begin(); itr != ruleList.end(); ++itr)
                 [ +  + ]
      84                 :            :     {
      85         [ +  - ]:     117432 :       (*itr)->applyRule(*ngbhd,
      86 [ +  - ][ +  - ]:     234864 :           baselineEdge->getQualityLevel(), ruleAppVisitor);
      87                 :            :     }
      88                 :            : 
      89                 :            :     // process the results of attempting to apply rules
      90                 :            :     const AF2RuleApplication* bestRuleApp =
      91         [ +  - ]:       9981 :         ruleAppVisitor.getBestRuleApplication();
      92         [ +  + ]:       9981 :     if (bestRuleApp == NULL)
      93                 :            :     {
      94                 :            :       // there were no successful rule applications, so decrease the quality
      95         [ +  - ]:       3438 :       baselineEdge->decreaseQuality();
      96                 :            :     }
      97                 :            :     else
      98                 :            :     {
      99                 :            :       // there was a successful rule application, so process it and advance
     100                 :            : 
     101                 :            :       // add any new points added by the rule application
     102         [ +  - ]:       6543 :       std::map<const AF2Point2D*, AF2Point3D*> newPointsMap;
     103 [ +  - ][ +  + ]:      10594 :       for (unsigned int npi = 0; npi < bestRuleApp->getNumNewPoints(); ++npi)
     104                 :            :       {
     105                 :            :         processNewPoint(bestRuleApp->getNewPoint(npi), nextPointId,
     106 [ +  - ][ +  - ]:       4051 :             ngbhd, newPointsMap, allPoints, front);
     107                 :            :       }
     108                 :            : 
     109                 :            :       // add the faces added by the rule application
     110 [ +  - ][ +  + ]:      15807 :       for (unsigned int nfi = 0; nfi < bestRuleApp->getNumNewFaces(); ++nfi)
     111                 :            :       {
     112                 :            :         processNewFace(bestRuleApp->getNewFace(nfi),
     113 [ +  - ][ +  - ]:       9264 :             ngbhd, newPointsMap, allFaces, front);
     114                 :            :       }
     115                 :            :       // at a successful application, dump the content if we want to
     116                 :       6543 :       step++;
     117         [ -  + ]:       6543 :       if (debug>2)
     118                 :            :       {
     119         [ #  # ]:          0 :         output_intermediate_result(allPoints, allFaces, face, step);
     120                 :       6543 :       }
     121                 :            :     }
     122                 :       9981 :   }
     123                 :            : 
     124 [ +  - ][ +  + ]:         35 :   if (front.isEmpty())
     125                 :            :   {
     126                 :            :     // the advancing front algorithm successfully completed
     127         [ -  + ]:         34 :     if (debug>0)
     128                 :            :     {
     129 [ #  # ][ #  # ]:          0 :       std::cout<<" On surface " << face << " generated " << allPoints.size() << " points and " << allFaces.size() << " triangles\n";
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     130                 :            :     }
     131 [ +  - ][ +  - ]:         34 :     return new AF2AlgorithmResult(allPoints, allFaces);
     132                 :            :   }
     133                 :            : 
     134                 :            :   // the advancing front algorithm failed
     135         [ +  - ]:          1 :   release(allPoints, allFaces);
     136 [ +  - ][ +  - ]:         36 :   return new AF2AlgorithmResult();
     137                 :            : }
     138                 :            : 
     139                 :         35 : void AF2Algorithm::initFront(AF2Front & front, std::list<AF2Point3D*> & pntList,
     140                 :            :     unsigned long & pntId,
     141                 :            :     const double* coords, unsigned int numPoints,
     142                 :            :     const unsigned int* edges, unsigned int numEdges,
     143                 :            :     const moab::EntityHandle* vertexHandles) const
     144                 :            : {
     145                 :            :   // make the point objects and add them to the front
     146         [ +  - ]:         35 :   std::vector<AF2Point3D*> pntVector;
     147         [ +  - ]:         35 :   pntVector.reserve(numPoints);
     148         [ +  + ]:       1243 :   for (unsigned int pi = 0; pi < numPoints; ++pi)
     149                 :            :   {
     150                 :            :     AF2Point3D* point = new AF2Point3D(pntId,
     151 [ +  - ][ +  - ]:       1208 :         coords[3*pi], coords[3*pi + 1], coords[3*pi + 2]);
     152                 :       1208 :     ++pntId;
     153         [ +  + ]:       1208 :     if (vertexHandles != NULL)
     154                 :            :     {
     155         [ +  - ]:       1142 :       point->setCommittedHandle(vertexHandles[pi]);
     156                 :            :     }
     157         [ +  - ]:       1208 :     pntVector.push_back(point);
     158         [ +  - ]:       1208 :     pntList.push_back(point);
     159         [ +  - ]:       1208 :     front.addPoint(point);
     160                 :            :   }
     161                 :            : 
     162                 :            :   // make the edge objects and gather them in a list of edges
     163         [ +  - ]:         70 :   std::list<AF2Edge3D*> edgeList;
     164         [ +  + ]:       1243 :   for (unsigned int ei = 0; ei < numEdges; ++ei)
     165                 :            :   {
     166 [ +  - ][ -  + ]:       1208 :     if (edges[2*ei] >= numPoints || edges[2*ei + 1] >= numPoints)
     167                 :            :     {
     168         [ #  # ]:          0 :       MeshKit::Error badArg(MeshKit::MK_BAD_INPUT);
     169         [ #  # ]:          0 :       badArg.set_string("An edge index exceeds the number of points.");
     170         [ #  # ]:          0 :       throw badArg;
     171                 :            :     }
     172         [ +  - ]:       1208 :     AF2Point3D* edgeStart = pntVector[edges[2*ei]];
     173         [ +  - ]:       1208 :     AF2Point3D* edgeEnd = pntVector[edges[2*ei + 1]];
     174                 :            :     // mark the endpoints of the edges as on the initial boundary
     175                 :            :     // Note: This is not done for isolated points, since the front
     176                 :            :     //   does not start to advance from them.
     177         [ +  - ]:       1208 :     edgeStart->limitDistanceToBoundary(0);
     178         [ +  - ]:       1208 :     edgeEnd->limitDistanceToBoundary(0);
     179 [ +  - ][ +  - ]:       1208 :     AF2Edge3D* edge = new AF2Edge3D(edgeStart, edgeEnd);
     180         [ +  - ]:       1208 :     edgeList.push_back(edge);
     181                 :            :   }
     182                 :            : 
     183                 :            :   // initialize the front with the edges
     184 [ +  - ][ +  - ]:         70 :   front.advanceFront(edgeList);
     185                 :         35 : }
     186                 :            : 
     187                 :       9264 : void AF2Algorithm::processNewFace(const AF2Polygon2D* newFace2D,
     188                 :            :     AF2Neighborhood* & ngbhd,
     189                 :            :     std::map<const AF2Point2D*, AF2Point3D*> & newPointsMap,
     190                 :            :     std::list<const AF2Polygon3D*> & allFaces, AF2Front & front) const
     191                 :            : {
     192         [ +  - ]:       9264 :   std::list<const AF2Point3D*> facePoints3D;
     193         [ +  - ]:      18528 :   std::list<AF2Edge3D*> edgeList;
     194                 :            : 
     195                 :       9264 :   AF2Point3D* firstVertex = NULL;
     196                 :       9264 :   AF2Point3D* prevVertex = NULL;
     197                 :       9264 :   AF2Point3D* curVertex = NULL;
     198 [ +  - ][ +  + ]:      37056 :   for (unsigned int fvi = 0; fvi < newFace2D->getNumVertices(); ++fvi)
     199                 :            :   {
     200                 :            :     // get the 3-D point corresponding to the 2-D point . . .
     201         [ +  - ]:      27792 :     const AF2Point2D* faceVertex2D = newFace2D->getVertex(fvi);
     202                 :            :     // . . . either from the neighborhood . . .
     203         [ +  - ]:      27792 :     curVertex = ngbhd->getCorrespondingPoint(faceVertex2D);
     204                 :            :     // . . . or from the map of new points that were added.
     205         [ +  + ]:      27792 :     if (curVertex == NULL)
     206                 :            :     {
     207         [ +  - ]:       6772 :       curVertex = newPointsMap[faceVertex2D];
     208                 :            :     }
     209                 :            : 
     210                 :            :     // add it to the list of points for future creation of the 3-D face
     211         [ +  - ]:      27792 :     facePoints3D.push_back(curVertex);
     212                 :            : 
     213                 :            :     // process the edge
     214         [ +  + ]:      27792 :     if (firstVertex == NULL)
     215                 :            :     {
     216                 :            :       // at the first vertex just store the first vertex and what will be
     217                 :            :       // the previous vertex
     218                 :       9264 :       firstVertex = curVertex;
     219                 :       9264 :       prevVertex = curVertex;
     220                 :            :     }
     221                 :            :     else
     222                 :            :     {
     223                 :            :       // create and store an edge from the current to the previous vertex
     224 [ +  - ][ +  - ]:      18528 :       edgeList.push_back(new AF2Edge3D(curVertex, prevVertex));
                 [ +  - ]
     225                 :            :       // update what will be the previous vertex
     226                 :      18528 :       prevVertex = curVertex;
     227                 :            :     }
     228                 :            :   }
     229                 :            :   // create and store an edge from the first vertex to the last vertex
     230 [ +  - ][ +  - ]:       9264 :   edgeList.push_back(new AF2Edge3D(firstVertex, curVertex));
                 [ +  - ]
     231                 :            : 
     232                 :            :   // create the three-dimensional face and add it to the list of faces
     233 [ +  - ][ +  - ]:       9264 :   allFaces.push_back(new AF2Polygon3D(facePoints3D));
                 [ +  - ]
     234                 :            : 
     235                 :            :   // advance the front with the edges
     236 [ +  - ][ +  - ]:      18528 :   front.advanceFront(edgeList);
     237                 :       9264 : }
     238                 :            : 
     239                 :       4051 : void AF2Algorithm::processNewPoint(const AF2Point2D* newPoint2D,
     240                 :            :     unsigned long & pntId,
     241                 :            :     AF2Neighborhood* & ngbhd,
     242                 :            :     std::map<const AF2Point2D*, AF2Point3D*> & newPointsMap,
     243                 :            :     std::list<AF2Point3D*> & allPoints, AF2Front & front) const
     244                 :            : {
     245         [ +  - ]:       4051 :   AF2Point3D* newPoint3D = ngbhd->transformPoint(newPoint2D, pntId);
     246                 :       4051 :   ++pntId;
     247         [ +  - ]:       4051 :   newPointsMap[newPoint2D] = newPoint3D;
     248         [ +  - ]:       4051 :   allPoints.push_back(newPoint3D);
     249         [ +  - ]:       4051 :   front.addPoint(newPoint3D);
     250                 :       4051 : }
     251                 :            : 
     252                 :          1 : void AF2Algorithm::release(std::list<AF2Point3D*> & allPoints,
     253                 :            :     std::list<const AF2Polygon3D*> & allFaces) const
     254                 :            : {
     255                 :            :   typedef std::list<const AF2Polygon3D*>::iterator FaceItr;
     256                 :            :   typedef std::list<AF2Point3D*>::iterator PointItr;
     257                 :            : 
     258 [ +  - ][ +  - ]:          3 :   for (FaceItr itr = allFaces.begin(); itr != allFaces.end(); ++itr)
                 [ +  + ]
     259                 :            :   {
     260 [ +  - ][ +  - ]:          2 :     delete (*itr);
     261                 :            :   }
     262                 :            : 
     263 [ +  - ][ +  - ]:          7 :   for (PointItr itr = allPoints.begin(); itr != allPoints.end(); ++itr)
                 [ +  + ]
     264                 :            :   {
     265         [ +  - ]:          6 :     delete (*itr);
     266                 :            :   }
     267                 :          1 : }
     268                 :            : 
     269                 :            : #include "moab/Core.hpp"
     270                 :            : #include "moab/ReadUtilIface.hpp"
     271                 :          0 : void AF2Algorithm::output_intermediate_result (std::list<AF2Point3D*> & allPoints,
     272                 :            :         std::list<const AF2Polygon3D*> & allFaces,int face,  int step) const
     273                 :            : {
     274         [ #  # ]:          0 :   moab::Core mb;
     275                 :          0 :   int num_nodes = (int) allPoints.size();
     276         [ #  # ]:          0 :   std::vector<double> newPointCoords;
     277                 :            :   typedef std::list<AF2Point3D*>::const_iterator ConstPointItr;
     278 [ #  # ][ #  # ]:          0 :   for (ConstPointItr pItr = allPoints.begin();
         [ #  # ][ #  # ]
     279         [ #  # ]:          0 :       pItr != allPoints.end(); ++pItr)
     280                 :            :   {
     281 [ #  # ][ #  # ]:          0 :     newPointCoords.push_back((*pItr)->getX());
                 [ #  # ]
     282 [ #  # ][ #  # ]:          0 :     newPointCoords.push_back((*pItr)->getY());
                 [ #  # ]
     283 [ #  # ][ #  # ]:          0 :     newPointCoords.push_back((*pItr)->getZ());
                 [ #  # ]
     284                 :            :   }
     285                 :            :   // Commit the new points to MOAB
     286         [ #  # ]:          0 :   moab::Range newPointsRange;
     287                 :            :   mb.create_vertices(
     288 [ #  # ][ #  # ]:          0 :       &newPointCoords[0], num_nodes, newPointsRange);
     289                 :            :   // Set the map between local ID and moab handle
     290         [ #  # ]:          0 :   std::map<long, moab::EntityHandle> idToHandle;
     291         [ #  # ]:          0 :   ConstPointItr np3dItr = allPoints.begin();
     292 [ #  # ][ #  # ]:          0 :   for (moab::Range::const_iterator nphItr = newPointsRange.begin();
         [ #  # ][ #  # ]
     293         [ #  # ]:          0 :       nphItr != newPointsRange.end(); ++nphItr)
     294                 :            :   {
     295                 :            : 
     296 [ #  # ][ #  # ]:          0 :     long localID = (*np3dItr)->getLocalId();
     297 [ #  # ][ #  # ]:          0 :     idToHandle[localID]=*nphItr;
     298         [ #  # ]:          0 :     ++np3dItr;
     299                 :            :   }
     300                 :            : 
     301                 :          0 :   int numTriangles = allFaces.size();
     302                 :            : 
     303                 :            :   // pre-allocate connectivity memory to store the triangles
     304                 :            :   moab::ReadUtilIface* readInterface;
     305         [ #  # ]:          0 :   mb.query_interface(readInterface);
     306                 :            : 
     307                 :            :   moab::EntityHandle firstHandle;
     308                 :            :   moab::EntityHandle* triConnectAry;
     309                 :            :   readInterface->get_element_connect(
     310         [ #  # ]:          0 :       numTriangles, 3, moab::MBTRI, 0, firstHandle, triConnectAry);
     311                 :            : 
     312                 :          0 :   unsigned int caIndex = 0u;
     313                 :            :   typedef std::list<const AF2Polygon3D*>::const_iterator ConstTriangleItr;
     314 [ #  # ][ #  # ]:          0 :   for (ConstTriangleItr tItr = allFaces.begin();
         [ #  # ][ #  # ]
     315         [ #  # ]:          0 :       tItr != allFaces.end(); ++tItr)
     316                 :            :   {
     317         [ #  # ]:          0 :     for (unsigned int vi = 0; vi < 3; ++vi)
     318                 :            :     {
     319 [ #  # ][ #  # ]:          0 :       triConnectAry[caIndex + vi] = idToHandle[(*tItr)->getVertex(vi)->getLocalId()];
         [ #  # ][ #  # ]
     320                 :            :     }
     321                 :          0 :     caIndex += 3;
     322                 :            :   }
     323                 :            : 
     324 [ #  # ][ #  # ]:          0 :   std::stringstream tempStep;
     325 [ #  # ][ #  # ]:          0 :   tempStep<<"Face_"<< face << "_Step" <<step<<  ".vtk";
         [ #  # ][ #  # ]
                 [ #  # ]
     326 [ #  # ][ #  # ]:          0 :   mb.write_file(tempStep.str().c_str());
     327                 :            : 
     328                 :            : 
     329                 :          0 :   return;
     330 [ +  - ][ +  - ]:        156 : }
     331                 :            : 

Generated by: LCOV version 1.11