MeshKit  1.0
AF2Binding.cpp
Go to the documentation of this file.
00001 #include "meshkit/AF2Binding.hpp"
00002 #include "meshkit/Error.hpp"
00003 
00004 typedef std::map<const AF2RuleExistEdge*,
00005     const AF2Edge2D*>::iterator EdgeBindMapItr;
00006 typedef std::map<const AF2RuleExistEdge*,
00007     const AF2Edge2D*>::const_iterator EdgeBindMapConstItr;
00008 
00009 AF2Binding::VtxBindRec::VtxBindRec() :
00010     pointPtr(NULL), numBoundEdges(0), xplctBound(false)
00011 {
00012   // do nothing beyond the initializers
00013 }
00014 
00015 void AF2Binding::bind(
00016     const AF2RuleExistEdge* ruleEdgePtr, const AF2Edge2D* ngbhdEdgePtr)
00017 {
00018   EdgeBindMapItr itr = edgeBindMap.find(ruleEdgePtr);
00019   if (itr == edgeBindMap.end())
00020   {
00021     // the rule edge is not bound to anything
00022     if (edgesInUse.find(ngbhdEdgePtr) == edgesInUse.end() &&
00023         isConsistent(ruleEdgePtr->getStart(), ngbhdEdgePtr->getStart()) &&
00024         isConsistent(ruleEdgePtr->getEnd(), ngbhdEdgePtr->getEnd()))
00025     {
00026       // nothing else is bound to the neighborhood edge
00027       // and binding the endpoints of the edge is consistent, so . . .
00028       // . . . bind the endpoints of the edge,
00029       bind(ruleEdgePtr->getStart(), ngbhdEdgePtr->getStart(), false);
00030       bind(ruleEdgePtr->getEnd(), ngbhdEdgePtr->getEnd(), false);
00031       // . . . bind the edge itself,
00032       edgeBindMap[ruleEdgePtr] = ngbhdEdgePtr;
00033       // . . . and mark the edge as being in use
00034       edgesInUse.insert(ngbhdEdgePtr);
00035     }
00036     else
00037     {
00038       // something else is bound to the neighborhood edge already or there
00039       // is an inconsistency in binding one or more of the endpoints
00040       throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "Binding the rule edge to the neighborhood edge is inconsistent with existing bindings.");
00041     }
00042   }
00043   else
00044   {
00045     if (itr->second == ngbhdEdgePtr)
00046     {
00047       // the rule edge is already bound to the neighborhood edge
00048       // this should imply that the endpoints of the rule edge are implicitly
00049       // bound to the endpoints of the neighborhood edge
00050 
00051       // There is nothing to do in this case.
00052     }
00053     else
00054     {
00055       // the rule edge is bound to some other neighborhood edge
00056       throw MeshKit::Error(MeshKit::MK_BAD_INPUT,
00057           "The rule edge is already bound to some other neighborhood edge.");
00058     }
00059   }
00060 }
00061 
00062 void AF2Binding::bind(
00063     const AF2RuleExistVertex* ruleVertexPtr, const AF2Point2D* ngbhdVertexPtr)
00064 {
00065   bind(ruleVertexPtr, ngbhdVertexPtr, true);
00066 }
00067 
00068 void AF2Binding::bind(const AF2RuleExistVertex* ruleVertexPtr,
00069     const AF2Point2D* ngbhdVertexPtr, bool isExplicit)
00070 {
00071   typedef std::map<const AF2RuleExistVertex*,
00072       AF2Binding::VtxBindRec>::iterator VertexBindMapItr;
00073   VertexBindMapItr itr = vertexBindMap.find(ruleVertexPtr);
00074   if (itr == vertexBindMap.end())
00075   {
00076     // the rule vertex was not previously bound
00077     if (verticesInUse.find(ngbhdVertexPtr) == verticesInUse.end())
00078     {
00079       // nothing else was bound to the neighborhood vertex
00080       // insert the binding from the rule vertex to the neighborhood vertex
00081       VtxBindRec* bindRecordPtr = &(vertexBindMap[ruleVertexPtr]);
00082       bindRecordPtr->pointPtr = ngbhdVertexPtr;
00083       if (isExplicit)
00084       {
00085         bindRecordPtr->xplctBound = true;
00086       }
00087       else
00088       {
00089         bindRecordPtr->numBoundEdges = 1;
00090       }
00091       // mark the neighborhood vertex as being in use
00092       verticesInUse.insert(ngbhdVertexPtr);
00093     }
00094     else
00095     {
00096       // something else is bound to the neighborhood vertex already
00097       throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "Some other rule vertex is already bound to the neighborhood vertex.");
00098     }
00099   }
00100   else
00101   {
00102     VtxBindRec* bindRecordPtr = &(itr->second);
00103     if (bindRecordPtr->pointPtr == ngbhdVertexPtr)
00104     {
00105       // the rule vertex is already bound to the correct neighborhood vertex
00106       if (isExplicit)
00107       {
00108         bindRecordPtr->xplctBound = true;
00109       }
00110       else
00111       {
00112         ++(bindRecordPtr->numBoundEdges);
00113       }
00114     }
00115     else
00116     {
00117       // the rule vertex is already bound to some other neighborhood vertex
00118       throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "The rule vertex is already bound to some other neighborhood vertex.");
00119     }
00120   }
00121 }
00122 
00123 const AF2Point2D* AF2Binding::getBoundValue(
00124     const AF2RuleExistVertex* ruleVertexPtr) const
00125 {
00126   typedef std::map<const AF2RuleExistVertex*,
00127       AF2Binding::VtxBindRec>::const_iterator VertexBindMapConstItr;
00128   VertexBindMapConstItr itr = vertexBindMap.find(ruleVertexPtr);
00129   if (itr == vertexBindMap.end())
00130   {
00131     // the rule vertex is not bound to anything
00132     return NULL;
00133   }
00134   else
00135   {
00136     return itr->second.pointPtr;
00137   }
00138 }
00139 
00140 bool AF2Binding::isConsistent(
00141     const AF2RuleExistEdge* ruleEdgePtr, const AF2Edge2D* ngbhdEdgePtr) const
00142 {
00143   EdgeBindMapConstItr itr = edgeBindMap.find(ruleEdgePtr);
00144   if (itr == edgeBindMap.end())
00145   {
00146     // the rule edge is not bound to anything
00147     if (edgesInUse.find(ngbhdEdgePtr) == edgesInUse.end())
00148     {
00149       // nothing else is bound to the neighborhood edge
00150       // check consistency of the endpoints of the edge
00151       return isConsistent(ruleEdgePtr->getStart(), ngbhdEdgePtr->getStart())
00152           && isConsistent(ruleEdgePtr->getEnd(), ngbhdEdgePtr->getEnd());
00153     }
00154     else
00155     {
00156       // something else is bound to the neighborhood edge already
00157       return false;
00158     }
00159   }
00160   else
00161   {
00162     if (itr->second == ngbhdEdgePtr)
00163     {
00164       // the rule edge is already bound to the neighborhood edge
00165       // this should imply that the endpoints of the rule edge are
00166       // bound to the endpoints of the neighborhood edge
00167       return true;
00168     }
00169     else
00170     {
00171       // the rule edge is bound to some other neighborhood edge
00172       return false;
00173     }
00174   }
00175 }
00176 
00177 bool AF2Binding::isConsistent(const AF2RuleExistVertex* ruleVertexPtr,
00178     const AF2Point2D* ngbhdVertexPtr) const
00179 {
00180   typedef std::map<const AF2RuleExistVertex*,
00181       AF2Binding::VtxBindRec>::const_iterator VertexBindMapConstItr;
00182   VertexBindMapConstItr itr = vertexBindMap.find(ruleVertexPtr);
00183   if (itr == vertexBindMap.end())
00184   {
00185     // the rule vertex is not bound to anything
00186     if (verticesInUse.find(ngbhdVertexPtr) == verticesInUse.end())
00187     {
00188       // nothing else is bound to the neighborhood vertex
00189       return true;
00190     }
00191     else
00192     {
00193       // something else is bound to the neighborhood vertex already
00194       return false;
00195     }
00196   }
00197   else
00198   {
00199     const VtxBindRec* bindRecordPtr = &(itr->second);
00200     if (bindRecordPtr->pointPtr == ngbhdVertexPtr)
00201     {
00202       // the rule vertex is already bound to the neighborhood vertex
00203       return true;
00204     }
00205     else
00206     {
00207       // the rule vertex is bound to some other neighborhood vertex
00208       return false;
00209     }
00210   }
00211 }
00212 
00213 void AF2Binding::release(const AF2RuleExistEdge* ruleEdgePtr)
00214 {
00215   EdgeBindMapItr itr = edgeBindMap.find(ruleEdgePtr);
00216   if (itr == edgeBindMap.end())
00217   {
00218     // the rule edge is not bound to anything
00219     throw MeshKit::Error(MeshKit::MK_BAD_INPUT,
00220         "The rule edge is not bound to any neighborhood edge.");
00221   }
00222   else
00223   {
00224     edgesInUse.erase(itr->second);
00225     edgeBindMap.erase(itr);
00226     release(ruleEdgePtr->getEnd(), false);
00227     release(ruleEdgePtr->getStart(), false);
00228   }
00229 }
00230 
00231 void AF2Binding::release(const AF2RuleExistVertex* ruleVertexPtr)
00232 {
00233   release(ruleVertexPtr, true);
00234 }
00235 
00236 void AF2Binding::release(
00237     const AF2RuleExistVertex* ruleVertexPtr, bool isExplicit)
00238 {
00239   typedef std::map<const AF2RuleExistVertex*,
00240       AF2Binding::VtxBindRec>::iterator VertexBindMapItr;
00241   VertexBindMapItr itr = vertexBindMap.find(ruleVertexPtr);
00242   if (itr == vertexBindMap.end())
00243   {
00244     // the rule vertex is not bound to anything
00245     throw MeshKit::Error(MeshKit::MK_BAD_INPUT,
00246         "The rule vertex is not bound to any neighborhood vertex.");
00247   }
00248   else
00249   {
00250     VtxBindRec* bindRecordPtr = &(itr->second);
00251     if (isExplicit)
00252     {
00253       if (!bindRecordPtr->xplctBound)
00254       {
00255         throw MeshKit::Error(MeshKit::MK_BAD_INPUT, "The rule vertex is not explicitly bound to a neighborhood vertex.  The binding is implicit.  Release the edge(s) instead.");
00256       }
00257       bindRecordPtr->xplctBound = false;
00258     }
00259     else
00260     {
00261       --(bindRecordPtr->numBoundEdges);
00262     }
00263 
00264     if (!(bindRecordPtr->xplctBound) && bindRecordPtr->numBoundEdges == 0)
00265     {
00266       // after performing the requested release operation, the vertex
00267       // is no longer bound either explicitly or implicitly
00268       verticesInUse.erase(bindRecordPtr->pointPtr);
00269       vertexBindMap.erase(itr);
00270     }
00271   }
00272 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines