MeshKit
1.0
|
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 }