refractory.cc

Go to the documentation of this file.
00001 #include "refractory.h"
00002 
00003 #include <cmath>
00004 #include <iostream>
00005 
00006 #include "container.h"
00007 #include "edge.h"
00008 #include "face.h"
00009 #include "gain_schedule.h"
00010 #include "intersecting_faces.h"
00011 #include "object.h"
00012 #include "state.h"
00013 #include "vertex.h"
00014 #include "vertex_schedule.h"
00015 
00016 using std::cout;
00017 using std::endl;
00018 
00019 Refractory * Refractory::only_one = NULL;
00020 
00021 Refractory & Refractory::instance()
00022 {
00023   // Not thread-safe.
00024   // -- lock mutex
00025   if (only_one == NULL)
00026     only_one = new Refractory();
00027   // -- unlock mutex
00028   return *only_one;
00029 }
00030 
00031 Refractory::Refractory (const Refractory& rhs)
00032   :refrac_s(),refrac_l(),pun_n(),pun_int(),
00033   pun_ang(),pun_com(),touch_map()
00034 {
00035   cout << "Copy constructor prohibited on instances of Refractory class.\n";
00036   cout << "Refractory " << rhs.touch_map.size() << endl;
00037   exit(0);
00038 }
00039 
00040 Refractory::Refractory (void)
00041   :refrac_s(),refrac_l(),pun_n(),pun_int(),
00042   pun_ang(),pun_com(),touch_map()
00043 {
00044 }
00045 
00046 Refractory& Refractory::operator= (const Refractory& rhs)
00047 {
00048   cout << "Copy assignment operator prohibited on instances of Refractory class.\n";
00049   cout << "Refractory " << rhs.touch_map.size() << endl;
00050   exit(0);
00051 }
00052 
00053 bool Refractory::isPunished (Vertex * const v)
00054 {
00055   return (pun_n.find(v)!=pun_n.end() ||
00056           pun_int.find(v)!=pun_int.end() ||
00057           pun_com.find(v)!=pun_com.end() || 
00058           pun_ang.find(v)!=pun_ang.end());
00059 }
00060 
00061 void Refractory::punishN (Vertex * const v,int const time_out)
00062 {
00063   pun_n[v]=time_out;
00064 }
00065 
00066 void Refractory::punishInt (Vertex * const v,int const time_out)
00067 {
00068   pun_int[v]=time_out;
00069 }
00070 
00071 void Refractory::punishCom (Vertex * const v,int const time_out)
00072 {
00073   pun_com[v]=time_out;
00074 }
00075 
00076 void Refractory::punishAng (Vertex *v,int time_out)
00077 {
00078   pun_ang[v]=time_out;
00079 }
00080 
00081 void Refractory::updateTouchMap (Vertex * const v)
00082 {
00083   // if vertex in touch_map, then increment
00084   if(touch_map.find(v)!=touch_map.end()){ touch_map[v]++; }
00085   // else init to one touch
00086   else { touch_map[v]=1; }
00087 }
00088 
00089 void Refractory::punishIfOverTouched (Vertex * const v)
00090 {
00091   // if vertex touched too much
00092   if(touch_map[v]>MAX_TOUCHES){punishN(v,static_cast<int>(GROUP_SIZE));}
00093 }
00094 
00095 void Refractory::initRefrac (void)
00096 {
00097   refrac_s.clear();
00098   refrac_l.clear();
00099 }
00100 
00101 bool Refractory::Refracted (Vertex * const v)
00102 {
00103   if (refrac_s.find(v)!=refrac_s.end()){return true;}
00104   else  {return false;}
00105 }
00106 
00107 void Refractory::updateRefractoryWindow (Vertex * const v)
00108 {
00110   if(refrac_l.size()==REFRACTORY_PERIOD)
00111   {
00112     refrac_s.erase(refrac_l.front());
00113     refrac_l.pop_front();
00114   }
00116   refrac_l.push_back(v);
00117   refrac_s.insert(v);
00118 }
00119 
00120 bool Refractory::vertexIsMoveCandidate (Vertex * const v)
00121 {
00122   // if vertex is candidate, i.e. closest point was found for vertex
00123   // and vertex not found in refractory list of vertices
00124   // i.e. list of last REFRACTORY_PERIOD (e.g. 1000) vertices moved
00125   // and vertex is not in gate, i.e. failed to move and punished for extent of w group
00126   return (v->getFace()!=NULL) && (isPunished(v)==false) && !Refracted(v)
00127         && (Container::instance().vertexIsFrozen(v)==false);
00128 }
00129 
00130 void Refractory::screenDisp (Vertex * const ccvv,vec_d & PT)
00131 {
00132   // square of displacement
00133   double d[3]={PT[0]-ccvv->getCoord(0),PT[1]-ccvv->getCoord(1),PT[2]-ccvv->getCoord(2)};
00134   //double sqdisp = d[0]*d[0]+d[1]*d[1]+d[2]*d[2];
00135   double disp = sqrt(d[0]*d[0]+d[1]*d[1]+d[2]*d[2]);
00136   // compute max allowed displacement
00137   double min_edge_length = 1e30;
00138   // for each adjacent face
00139   for(fp_cit i=ccvv->begin();i!=ccvv->end();i++)
00140   {
00141     // find shortest edge
00142     for(int j=0;j<3;j++)
00143     {
00144       if((*i)->getEdge(j)->getOriginalLength() < min_edge_length)
00145       {
00146         min_edge_length = (*i)->getEdge(j)->getOriginalLength();
00147       }
00148     }
00149   }
00150   double MAX_ACTUAL_DISPL = min_edge_length*MAX_ACTUAL_DISPL_FRACTION;
00151   // if too big
00152   if(disp>MAX_ACTUAL_DISPL)
00153   {
00154     double a = MAX_ACTUAL_DISPL/disp;
00155     for(int k=0;k<3;k++)
00156     {
00157       PT[k] = ccvv->getCoord(k)+a*d[k];
00158     }
00159   }
00160 }
00161 
00162 vp_cit Refractory::detectPunishableVertex (vp_cit i,bool const int_flag,bool const ang_flag)
00163 {
00164   if(State::instance().getVD2()<MIN_DISPLACEMENT_SQ*SCALE*SCALE)
00165   {
00166     cout << "\nvertex: " << Vertex_Schedule::instance().getCurrentVertex()->getObject()->getName() << "->" << Vertex_Schedule::instance().getCurrentVertex()->getIndex() << " was punished.\n"
00167           << "virtual displacement sqd(" << State::instance().getVD2() << ")"
00168           << " < threshold(" << MIN_DISPLACEMENT_SQ*SCALE*SCALE << ")\n";
00169     Vertex_Schedule::instance().getCurrentVertex()->print(std::cout);
00170     cout << endl;
00171     // vertex is effectively immovable, so punish vertex
00172     if     (int_flag==true){ punishInt(Vertex_Schedule::instance().getCurrentVertex(),static_cast<int>(GROUP_SIZE));}
00173     else if(ang_flag==true){ punishAng(Vertex_Schedule::instance().getCurrentVertex(),static_cast<int>(GROUP_SIZE));}
00174     else                   { punishCom(Vertex_Schedule::instance().getCurrentVertex(),static_cast<int>(GROUP_SIZE));}
00175     // reset gain
00176     Gain_Schedule::instance().resetGain();
00177     // move on to next vertex in set
00178     i++;
00179   }
00180   else
00181   {
00182     // try halving gain to halve attempted virtual displacement and try again
00183     Gain_Schedule::instance().halveGain();
00184   }
00185   return i;
00186 }
00187 
00188 void Refractory::updateStats (void)
00189 {
00190   // automatically strict face intersection prevention
00191   if(STRICT_FACE_INTERSECTION_PREVENTION==false)
00192   {
00193     if(DETECT_COMPLETE_SEPARATION==true)
00194     {
00195       if(Intersecting_Faces::instance().getCountOfIntFaces(false)==0){STRICT_FACE_INTERSECTION_PREVENTION=true;}
00196     }
00197   }
00198   // increment number of times current vertex has been moved
00199   updateTouchMap(Vertex_Schedule::instance().getCurrentVertex());
00200   // punish vertex if moved too many time
00201   punishIfOverTouched(Vertex_Schedule::instance().getCurrentVertex());
00202   // update list of vertices in refractory period
00203   updateRefractoryWindow(Vertex_Schedule::instance().getCurrentVertex());
00204 }
00205 
00206 void Refractory::groupInit (void)
00207 {
00208   // instantiate list of vertices moved small distance (gate)
00209   // and instantiate refractory period list
00210   initRefrac();
00211   // clear punished vertex lists
00212   pun_n.clear();
00213   pun_int.clear();
00214   pun_com.clear();
00215   pun_ang.clear();
00216   // initialize map used to track how many times each vertex was moved
00217   touch_map.clear();
00218 }
00219 
00220 vhm_it Refractory::findVertexInTouchMap (Vertex *v)
00221 {
00222   return touch_map.find(v);
00223 }
00224 
00225 bool Refractory::vertexInTouchMap (Vertex *v)
00226 {
00227   return touch_map.find(v)!=touch_map.end();
00228 }
00229 
00230 int Refractory::numVertexTouches (Vertex * v)
00231 {
00232   return touch_map[v];
00233 }
00234 
00235 int Refractory::numPunishedN (void) const
00236 {
00237   return pun_n.size();
00238 }
00239 
00240 vhm_cit Refractory::beginN (void) const
00241 {
00242   return pun_n.begin();
00243 }
00244 
00245 vhm_cit Refractory::endN (void) const
00246 {
00247   return pun_n.end();
00248 }
00249 
00250 int Refractory::numPunishedInt (void) const
00251 {
00252   return pun_int.size();
00253 }
00254 
00255 vhm_cit Refractory::beginInt (void) const
00256 {
00257   return pun_int.begin();
00258 }
00259 
00260 vhm_cit Refractory::endInt (void) const
00261 {
00262   return pun_int.end();
00263 }
00264 
00265 int Refractory::numPunishedAng (void) const
00266 {
00267   return pun_ang.size();
00268 }
00269 
00270 vhm_cit Refractory::beginAng (void) const
00271 {
00272   return pun_ang.begin();
00273 }
00274 
00275 vhm_cit Refractory::endAng (void) const
00276 {
00277   return pun_ang.end();
00278 }
00279 
00280 int Refractory::numPunishedCom (void) const
00281 {
00282   return pun_com.size();
00283 }
00284 
00285 vhm_cit Refractory::beginCom (void) const
00286 {
00287   return pun_com.begin();
00288 }
00289 
00290 vhm_cit Refractory::endCom (void) const
00291 {
00292   return pun_com.end();
00293 }
00294 

Generated on Fri Jul 18 19:43:40 2008 for meshmorph by  doxygen 1.5.1