Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/Geant4/tools/clist_contour is written in an unsupported language. File is not indexed.

0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003 
0004 #ifndef tools_clist_contour
0005 #define tools_clist_contour
0006 
0007 // G.Barrand : inline version of the one found in Lib of OSC 16.11.
0008 //             This code is not mine and I keep it "as it is".
0009 
0010 // Inheritance :
0011 #include "ccontour"
0012 
0013 #include <list>
0014 #include <ostream>
0015 #include <iomanip> //std::setprecision
0016 
0017 namespace tools {
0018 
0019 // a list of point index referring to the secondary grid
0020 // Let i the index of a point,
0021 typedef std::list<unsigned int> cline_strip;
0022 typedef std::list<cline_strip*> cline_strip_list;
0023 typedef std::vector<cline_strip_list> cline_strip_list_vector;
0024 
0025 class clist_contour : public ccontour
0026 {
0027 public: //ccontour
0028         // Adding segment to line strips
0029         // See ccontour::ExportLine for further details
0030         virtual void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
0031 
0032 public:
0033         clist_contour();
0034         virtual ~clist_contour(){CleanMemory();}
0035 protected: //G.Barrand
0036         clist_contour(const clist_contour& a_from):ccontour(a_from){}
0037 private: //G.Barrand
0038         clist_contour& operator=(const clist_contour&){return *this;}
0039 public:
0040         // retreiving list of line strip for the i-th contour
0041         cline_strip_list* get_lines(unsigned int iPlane);
0042         // Basic algorithm to concatanate line strip. Not optimized at all !
0043         bool compact_strips ();
0044         // generate contour strips
0045         virtual void generate();
0046 protected: //G.Barrand
0047 
0048         // Initializing memory
0049         virtual void InitMemory();
0050         // Cleaning memory and line strips
0051         virtual void CleanMemory();
0052 
0053         // Adding segment to line strips
0054         // See ccontour::ExportLine for further details
0055         //void ExportLine(int iPlane,int x1, int y1, int x2, int y2);
0056 
0057         /// debuggin
0058         void DumpPlane(unsigned int iPlane) const;
0059 
0060         // Area given by this function can be positive or negative depending on the winding direction of the contour.
0061         double Area(cline_strip* Line);
0062 
0063         double EdgeWeight(cline_strip* pLine, double R);
0064         //bool   PrintContour(std::ostream& a_out);
0065 protected:
0066         // Merges pStrip1 with pStrip2 if they have a common end point
0067         bool MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2);
0068         // Merges the two strips with a welding threshold.
0069         bool ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double);
0070         // returns true if contour is touching boundary
0071         bool OnBoundary(cline_strip* pStrip);
0072         // L.Garnier : check specials case for CompactStrip
0073         bool SpecialCompactStripCase(double,double,double,double,double);
0074 
0075 private:
0076         // array of line strips
0077         cline_strip_list_vector m_vStripLists;
0078         typedef unsigned int UINT;
0079 
0080 private:
0081         static const char* _TT(const char* what) {return what;}
0082 
0083         static void _TRACE_(const char* /*a_fmt*/,...) {
0084           //va_list args;
0085           //va_start(args,a_fmt);
0086           //::vprintf(s,a_fmt,args);
0087           //va_end(args);
0088         }
0089         static void _PROBLEM_(const char* what) {::printf("%s",what);}
0090 
0091         static bool _ASSERT_RET_(bool what,const char* cmt) {
0092           if(!(what)) {
0093             ::printf("debug : ListContour : assert failure in %s\n",cmt);
0094             return false;
0095           }
0096           return true;
0097         }
0098 
0099         static bool _ASSERT_MERGE_RET_(bool what,const char* cmt,cline_strip* pStrip2) {
0100           if(!(what)) {
0101             ::printf("debug : ListContour : assert failure in %s\n",cmt);
0102             pStrip2->clear();
0103             return false;
0104           }
0105           return true;
0106         }
0107 };
0108 
0109 
0110 // implementation :
0111 inline clist_contour::clist_contour()
0112 : ccontour()
0113 {
0114 }
0115 
0116 inline void clist_contour::generate()
0117 {
0118         // generate line strips
0119         ccontour::generate();
0120         // compact strips
0121         compact_strips ();
0122 }
0123 
0124 inline void clist_contour::InitMemory()
0125 {
0126         ccontour::InitMemory();
0127 
0128         cline_strip_list::iterator pos;
0129         cline_strip* pStrip;
0130 
0131         if (!m_vStripLists.empty())
0132         {
0133                 UINT i;
0134                 // reseting lists
0135                 _ASSERT_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::InitMemory::0");
0136                 for (i=0;i<get_number_of_planes();i++)
0137                 {
0138                         for (pos = m_vStripLists[i].begin(); pos!=m_vStripLists[i].end() ; pos++)
0139                         {
0140                                 pStrip=(*pos);
0141                                 _ASSERTP_(pStrip,"clist_contour::InitMemory::1");
0142 
0143                                 pStrip->clear();
0144                                 delete pStrip;
0145                         }
0146                         m_vStripLists[i].clear();
0147                 }
0148         }
0149         else
0150                 m_vStripLists.resize(get_number_of_planes());
0151 }
0152 
0153 inline void clist_contour::CleanMemory()
0154 {
0155         ccontour::CleanMemory();
0156 
0157         cline_strip_list::iterator pos;
0158         cline_strip* pStrip;
0159         UINT i;
0160 
0161         // reseting lists
0162         for (i=0;i<m_vStripLists.size();i++) //G.Barrand
0163         {
0164                 for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
0165                 {
0166                         pStrip=(*pos);
0167                         _ASSERTP_(pStrip,"clist_contour::CleanMemory");
0168                         pStrip->clear();
0169                         delete pStrip;
0170                 }
0171                 m_vStripLists[i].clear();
0172         }
0173 }
0174 
0175 inline void clist_contour::ExportLine(int iPlane,int x1, int y1, int x2, int y2)
0176 {
0177         _ASSERT_(iPlane>=0,"clist_contour::ExportLine::0");
0178         _ASSERT_(iPlane<(int)get_number_of_planes(),"clist_contour::ExportLine::1");
0179 
0180         // check that the two points are not at the beginning or end of the  some line strip
0181         UINT i1=y1*(m_iColSec+1)+x1;
0182         UINT i2=y2*(m_iColSec+1)+x2;
0183 
0184         cline_strip* pStrip;
0185 
0186         cline_strip_list::iterator pos;
0187         bool added = false;
0188         for(pos=m_vStripLists[iPlane].begin(); pos!=m_vStripLists[iPlane].end() && !added; pos++)
0189         {
0190                 pStrip=(*pos);
0191                 _ASSERTP_(pStrip,"clist_contour::ExportLine::2");
0192                 // check if points are appendable to this strip
0193                 if (i1==pStrip->front())
0194                 {
0195                         pStrip->insert(pStrip->begin(),i2);
0196                         return;
0197                 }
0198                 if (i1==pStrip->back())
0199                 {
0200                         pStrip->insert(pStrip->end(),i2);
0201                         return;
0202                 }
0203                 if (i2==pStrip->front())
0204                 {
0205                         pStrip->insert(pStrip->begin(),i1);
0206                         return;
0207                 }
0208                 if (i2==pStrip->back())
0209                 {
0210                         pStrip->insert(pStrip->end(),i1);
0211                         return;
0212                 }
0213         }
0214 
0215         // segment was not part of any line strip, creating new one
0216         pStrip=new cline_strip;
0217         pStrip->insert(pStrip->begin(),i1);
0218         pStrip->insert(pStrip->end(),i2);
0219         m_vStripLists[iPlane].insert(m_vStripLists[iPlane].begin(),pStrip);
0220 }
0221 
0222 inline bool clist_contour::ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double aHeight)
0223 {
0224 
0225         cline_strip::iterator pos;
0226         cline_strip::reverse_iterator rpos;
0227 
0228         if (pStrip2->empty())
0229                 return false;
0230 
0231         double x[4], y[4], weldDist;
0232         int index;
0233         index = pStrip1->front();
0234         x[0] = get_xi(index);
0235         y[0] = get_yi(index);
0236         index = pStrip1->back();
0237         x[1] = get_xi(index);
0238         y[1] = get_yi(index);
0239         index = pStrip2->front();
0240         x[2] = get_xi(index);
0241         y[2] = get_yi(index);
0242         index = pStrip2->back();
0243         x[3] = get_xi(index);
0244         y[3] = get_yi(index);
0245 
0246         weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
0247 
0248         if (((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2])< weldDist)
0249             || SpecialCompactStripCase(x[1],x[2],y[1],y[2],aHeight)) // L.Garnier
0250 
0251     {
0252                 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
0253                 {
0254                         index=(*pos);
0255                         if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::0")) return false;
0256                         pStrip1->insert(pStrip1->end(),index);
0257                 }
0258                 pStrip2->clear();
0259                 return true;
0260     }
0261 
0262         if (((x[3]-x[0])*(x[3]-x[0])+(y[3]-y[0])*(y[3]-y[0])< weldDist)
0263             || SpecialCompactStripCase(x[3],x[0],y[3],y[0],aHeight)) // L.Garnier
0264     {
0265                 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
0266                 {
0267                         index=(*rpos);
0268                         if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::1")) return false;
0269                         pStrip1->insert(pStrip1->begin(),index);
0270                 }
0271                 pStrip2->clear();
0272                 return true;
0273     }
0274 
0275         if (((x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3])< weldDist)
0276             || SpecialCompactStripCase(x[1],x[3],y[1],y[3],aHeight)) // L.Garnier
0277     {
0278                 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
0279                 {
0280                         index=(*rpos);
0281                         if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::2")) return false;
0282                         pStrip1->insert(pStrip1->end(),index);
0283                 }
0284                 pStrip2->clear();
0285                 return true;
0286     }
0287 
0288         if (((x[0]-x[2])*(x[0]-x[2])+(y[0]-y[2])*(y[0]-y[2])< weldDist)
0289             || SpecialCompactStripCase(x[0],x[2],y[0],y[2],aHeight)) // L.Garnier
0290     {
0291                 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
0292                 {
0293                         index=(*pos);
0294                         if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::3")) return false;
0295                         pStrip1->insert(pStrip1->begin(),index);
0296                 }
0297                 pStrip2->clear();
0298                 return true;
0299     }
0300 
0301         return false;
0302 }
0303 
0304 inline bool clist_contour::MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2)
0305 {
0306         cline_strip::iterator pos;
0307         cline_strip::reverse_iterator rpos;
0308         if (pStrip2->empty())
0309                 return false;
0310 
0311         int index;
0312 
0313         // debugging stuff
0314         if (pStrip2->front()==pStrip1->front())
0315     {
0316                 // retreiving first element
0317                 pStrip2->pop_front();
0318                 // adding the rest to strip1
0319                 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
0320                 {
0321                         index=(*pos);
0322                         if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::0",pStrip2)) return false;
0323                         pStrip1->insert(pStrip1->begin(),index);
0324                 }
0325                 pStrip2->clear();
0326                 return true;
0327     }
0328 
0329         if (pStrip2->front()==pStrip1->back())
0330     {
0331                 pStrip2->pop_front();
0332                 // adding the rest to strip1
0333                 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++)
0334                 {
0335                         index=(*pos);
0336                         if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::1",pStrip2)) return false;
0337                         pStrip1->insert(pStrip1->end(),index);
0338                 }
0339                 pStrip2->clear();
0340                 return true;
0341     }
0342 
0343         if (pStrip2->back()==pStrip1->front())
0344     {
0345                 pStrip2->pop_back();
0346                 // adding the rest to strip1
0347                 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
0348                 {
0349                         index=(*rpos);
0350                         if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::2",pStrip2)) return false;
0351                         pStrip1->insert(pStrip1->begin(),index);
0352                 }
0353                 pStrip2->clear();
0354                 return true;
0355     }
0356 
0357         if (pStrip2->back()==pStrip1->back())
0358     {
0359                 pStrip2->pop_back();
0360                 // adding the rest to strip1
0361                 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++)
0362                 {
0363                         index=(*rpos);
0364                         if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::3",pStrip2)) return false;
0365                         pStrip1->insert(pStrip1->end(),index);
0366                 }
0367                 pStrip2->clear();
0368                 return true;
0369     }
0370 
0371         return false;
0372 }
0373 
0374 inline bool clist_contour::compact_strips ()
0375 {
0376         cline_strip* pStrip;
0377         cline_strip* pStripBase = 0;
0378         UINT i;
0379         cline_strip_list::iterator pos,pos2;
0380         cline_strip_list newList;
0381         bool again, changed;
0382 
0383         const double weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy);
0384 
0385         if(!_ASSERT_RET_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::compact_strips ::0")) return false;
0386         for (i=0;i<get_number_of_planes();i++)
0387         {
0388                 double planeHeight = get_plane(i);
0389                 again=true;
0390                 while(again)
0391                 {
0392                         // REPEAT COMPACT PROCESS UNTILL LAST PROCESS MAKES NO CHANGE
0393 
0394                         again=false;
0395                         // building compacted list
0396                         if(!_ASSERT_RET_(newList.empty(),"clist_contour::compact_strips ::1")) return false;
0397                         for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++)
0398                         {
0399                                 pStrip=(*pos);
0400                                 for (pos2=newList.begin(); pos2!=newList.end();pos2++)
0401                                 {
0402                                         pStripBase=(*pos2);
0403                                         changed=MergeStrips(pStripBase,pStrip);
0404                                         if (changed)
0405                                                 again=true;
0406                                         if (pStrip->empty())
0407                                                 break;
0408                                 }
0409                                 if (pStrip->empty())
0410                                         delete pStrip;
0411                                 else
0412                                         newList.insert(newList.begin(),pStrip);
0413                         }
0414 
0415 
0416                         // deleting old list
0417                         m_vStripLists[i].clear();
0418                         cline_strip* pStrip2;
0419                         // Copying all
0420                         for (pos2=newList.begin(); pos2 != newList.end(); pos2++)
0421                         {
0422                                 pStrip2=(*pos2);
0423                                 cline_strip::iterator pos1 = pStrip2->begin(),pos3;
0424                                 while (pos1!=pStrip2->end())
0425                                 {
0426                                         pos3 = pos1;
0427                                         pos3++;
0428                                         if (pos3==pStrip2->end()) break; //G.Barrand
0429                                         if ( (*pos1) == (*pos3))
0430                                         {
0431                                           /*G.Barrand : we can't compare with pStrip2->end() content.
0432                                                 if ( (*pos3) != (*pStrip2->end()))
0433                                                         pStrip2->erase(pos3);
0434                                                 else
0435                                                 {
0436                                                         pStrip2->erase(pos3);
0437                                                         break;
0438                                                 }
0439                                           */
0440                                           pStrip2->erase(pos3); //G.Barrand.
0441                                         }
0442                                         else
0443                                                 pos1++;
0444                                 }
0445 
0446                                 //if (!(pStrip2->front()==pStrip2->back() && pStrip2->size()==2))
0447                                 if (pStrip2->size()!=1) 
0448                                         m_vStripLists[i].insert(m_vStripLists[i].begin(),pStrip2 );
0449                                 else
0450                                         delete pStrip2;
0451                         }
0452                         // emptying temp list
0453                         newList.clear();
0454 
0455                 } // OF WHILE(AGAIN) (LAST COMPACT PROCESS MADE NO CHANGES)
0456 
0457 
0458                 if (m_vStripLists[i].empty())
0459                         continue;
0460                 ///////////////////////////////////////////////////////////////////////
0461                 // compact more
0462                 int index,count;
0463                 size_t Nstrip,j;
0464 
0465                 Nstrip = m_vStripLists[i].size();
0466                 std::vector<bool> closed(Nstrip);
0467                 double x,y;
0468 
0469                 // First let's find the open and closed lists in m_vStripLists
0470                 for(pos2 = m_vStripLists[i].begin(), j=0, count=0; pos2 != m_vStripLists[i].end(); pos2++, j++)
0471                 {
0472                         pStrip = (*pos2);
0473 
0474                         // is it open ?
0475                         if (pStrip->front() != pStrip->back())
0476                         {
0477                                 index = pStrip->front();
0478                                 x = get_xi(index); y = get_yi(index);
0479                                 index = pStrip->back();
0480                                 x -= get_xi(index); y -= get_yi(index);
0481 
0482                                 // is it "almost closed" ?
0483                                 if ((x*x+y*y < weldDist) ||
0484                                     SpecialCompactStripCase(get_xi(pStrip->front()), // L.Garnier
0485                                                             get_xi(pStrip->back()),
0486                                                             get_yi(pStrip->front()),
0487                                                             get_yi(pStrip->back()),
0488                                                             planeHeight))
0489                                 {
0490                                         closed[j] = true;
0491                                         // close it !!! Added by L.Garnier
0492                                         pStrip->push_back(pStrip->front());
0493                                         //
0494                                 }
0495                                 else
0496                                 {
0497                                         closed[j] = false;
0498                                         // updating not closed counter...
0499                                         count ++;
0500                                 }
0501                         }
0502                         else
0503                                 closed[j] = true;
0504                 }
0505 
0506                 // is there any open strip ?
0507                 if (count > 1)
0508                 {
0509                         // Merge the open strips into NewList
0510                         pos = m_vStripLists[i].begin();
0511                         for(j=0;j<Nstrip;j++)
0512                         {
0513                                 if (closed[j] == false )
0514                                 {
0515                                         pStrip = (*pos);
0516                                         newList.insert(newList.begin(),pStrip);
0517                                         pos = m_vStripLists[i].erase(pos);
0518                                 }
0519                                 else
0520                                         pos ++;
0521                         }
0522 
0523                         // are they open strips to process ?
0524                         while(newList.size()>1)
0525                         {
0526                                 pStripBase = newList.front();
0527 
0528                                 // merge the rest to pStripBase
0529                                 again = true;
0530                                 while (again)
0531                                 {
0532                                         again = false;
0533                                         pos = newList.begin();
0534                                         for(pos++; pos!=newList.end();)
0535                                         {
0536                                                 pStrip = (*pos);
0537                                                 changed = ForceMerge(pStripBase,pStrip,planeHeight);
0538                                                 if (changed)
0539                                                 {
0540                                                         again = true;
0541                                                         delete pStrip;
0542                                                         pos = newList.erase(pos);
0543                                                 }
0544                                                 else
0545                                                         pos ++;
0546                                         }
0547                                 } // while(again)
0548 
0549                                 index = pStripBase->front();
0550                                 x = get_xi(index); y = get_yi(index);
0551                                 index = pStripBase->back();
0552                                 x -= get_xi(index); y -= get_yi(index);
0553                                 // if pStripBase is closed or not
0554 
0555                                 if ((x*x+y*y < weldDist) ||
0556                                     SpecialCompactStripCase(get_xi(pStripBase->front()), // L.Garnier
0557                                                             get_xi(pStripBase->back()),
0558                                                             get_yi(pStripBase->front()),
0559                                                             get_yi(pStripBase->back()),
0560                                                             planeHeight))
0561                                 {
0562 
0563                                   // close it !!! Added by L.Garnier
0564                                   if ((x!=0) || (y!=0)) {
0565                                     pStripBase->push_back(pStripBase->front());
0566                                   }
0567                                   //
0568                                   m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
0569                                   newList.pop_front();
0570                                 }
0571                                 else
0572                                 {
0573                                         if (OnBoundary(pStripBase))
0574                                         {
0575                                                 _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
0576                                                 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
0577                                                 newList.pop_front();
0578                                         }
0579                                         else
0580                                         {
0581                                                 _PROBLEM_(_TT("unpaird open strip at 1!\n"));
0582                                                 //exit(0);
0583                                                 return false;
0584                                         }
0585                                 }
0586                         } // while(newList.size()>1);
0587 
0588 
0589                         if (newList.size() ==1)
0590                         {
0591                                 pStripBase = newList.front();
0592                                 index = pStripBase->front(); // L.Garnier
0593                                 x = get_xi(index); y = get_yi(index); // L.Garnier
0594                                 index = pStripBase->back(); // L.Garnier
0595                                 x -= get_xi(index); y -= get_yi(index); // L.Garnier
0596 
0597                                 // is it "almost closed", give last chance...5*weldDist
0598                                 if (x*x+y*y < 3*weldDist) // L.Garnier
0599                                 {
0600                                         m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
0601                                         newList.pop_front();
0602                                 }
0603                                 else if (OnBoundary(pStripBase))
0604                                 {
0605                                         _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
0606                                         m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase);
0607                                         newList.pop_front();
0608                                 }
0609                                 else
0610                                 {
0611                                         _PROBLEM_(_TT("unpaird open strip at 2!\n"));
0612                                         DumpPlane(i);
0613                                         //exit(0);
0614                                         return false;
0615                                 }
0616                         }
0617 
0618                         newList.clear();
0619 
0620                 }
0621                 else if (count == 1)
0622                 {
0623                         pos = m_vStripLists[i].begin();
0624                         for(j=0;j<Nstrip;j++)
0625                         {
0626                                 if (closed[j] == false )
0627                                 {
0628                                         pStripBase = (*pos);
0629                                         break;
0630                                 }
0631                                 pos ++;
0632                         }
0633                         index = pStripBase->front(); // L.Garnier
0634                         x = get_xi(index); y = get_yi(index); // L.Garnier
0635                         index = pStripBase->back(); // L.Garnier
0636                         x -= get_xi(index); y -= get_yi(index); // L.Garnier
0637        
0638                         // is it "almost closed", give last chance...5*weldDist
0639                         if (x*x+y*y < 2*weldDist) // L.Garnier
0640                         {
0641                           //close it!!
0642                           pStripBase->push_back(pStripBase->front()); // L.Garnier
0643                         }
0644                         else if (OnBoundary(pStripBase))
0645                         {
0646                                 _TRACE_(_TT("# open strip ends on boundary, continue.\n"));
0647                                 pStripBase->push_back(pStripBase->front()); // L.Garnier
0648                         }
0649                         else
0650                         {
0651                                 _TRACE_(_TT("unpaird open strip at 3!"));
0652                                 DumpPlane(i);
0653                                 return false;  // L.Garnier
0654                                 //exit(0);
0655                         }
0656                         newList.clear();  // L.Garnier
0657                 }
0658         }
0659         return true;
0660 }
0661 
0662 
0663 inline bool clist_contour::OnBoundary(cline_strip* pStrip)
0664 {
0665         bool e1,e2;
0666 
0667         int index = pStrip->front();
0668         double x = get_xi(index), y = get_yi(index);
0669         if (x==m_pLimits[0] || x == m_pLimits[1] ||
0670                 y == m_pLimits[2] || y == m_pLimits[3])
0671                 e1 = true;
0672         else
0673                 e1 = false;
0674 
0675         index = pStrip->back();
0676         x = get_xi(index); y = get_yi(index);
0677         if (x==m_pLimits[0] || x == m_pLimits[1] ||
0678                 y == m_pLimits[2] || y == m_pLimits[3])
0679                 e2 = true;
0680         else
0681                 e2 = false;
0682 
0683         return (e1 && e2);
0684 }
0685 
0686 inline void clist_contour::DumpPlane(UINT iPlane) const
0687 {
0688         cline_strip_list::const_iterator pos;
0689         UINT i;
0690         cline_strip* pStrip;
0691 
0692         /*_ASSERT_(iPlane>=0,"clist_contour::DumpPlane");*/
0693         _ASSERT_(iPlane<get_number_of_planes(),"clist_contour::DumpPlane::0");
0694         _TRACE_(_TT("Level : %d"),get_plane(iPlane));
0695 
0696         _TRACE_(_TT("Number of strips : %d\r\n"),m_vStripLists[iPlane].size());
0697         _TRACE_(_TT("i np start end xstart ystart xend yend\r\n"));
0698         for (pos = m_vStripLists[iPlane].begin(), i=0; pos != m_vStripLists[iPlane].end(); pos++, i++)
0699         {
0700                 pStrip=*pos;
0701                 _ASSERTP_(pStrip,"clist_contour::DumpPlane::1");
0702                 _TRACE_(_TT("%d %d %d %d %g %g %g %g\r\n"),i,pStrip->size(),pStrip->front(),pStrip->back(),
0703                         get_xi(pStrip->front()),get_yi(pStrip->front()),
0704                         get_xi(pStrip->back()),get_yi(pStrip->back()) );
0705         }
0706 }
0707 
0708 inline double clist_contour::Area(cline_strip* Line)
0709 {
0710         // if Line is not closed, return 0;
0711 
0712         double Ar = 0, x, y, x0,y0,x1, y1;
0713         int index;
0714 
0715         cline_strip::iterator pos;
0716         pos = Line->begin();
0717         index = (*pos);
0718         x0 = x =  get_xi(index);
0719         y0 = y =  get_yi(index);
0720 
0721         pos ++;
0722 
0723         for(;pos!=Line->end();pos++)
0724         {
0725                 index = (*pos);
0726                 x1 = get_xi(index);
0727                 y1 = get_yi(index);
0728                 // Ar += (x1-x)*(y1+y);
0729                 Ar += (y1-y)*(x1+x)-(x1-x)*(y1+y);
0730                 x = x1;
0731                 y = y1;
0732 
0733         }
0734 
0735 
0736         //Ar += (x0-x)*(y0+y);
0737         Ar += (y0-y)*(x0+x)-(x0-x)*(y0+y);
0738         // if not closed curve, return 0;
0739         if ((x0-x)*(x0-x) + (y0-y)*(y0-y)>20*(m_dDx*m_dDx+m_dDy*m_dDy))
0740         {
0741                 Ar = 0;
0742                 _TRACE_(_TT("# open curve!\n"));
0743         }
0744         //else   Ar /= -2;
0745         else Ar/=4;
0746         // result is \int ydex/2 alone the implicit direction.
0747         return Ar;
0748 }
0749 
0750 inline double clist_contour:: EdgeWeight(cline_strip* pLine, double R)
0751 {
0752         cline_strip::iterator pos;
0753         int count = 0,index;
0754         double x,y;
0755         for(pos = pLine->begin(); pos!=pLine->end(); pos++)
0756         {
0757                 index = (*pos);
0758                 x = get_xi(index);
0759                 y = get_yi(index);
0760                 if (fabs(x) > R || fabs(y) > R)
0761                         count ++;
0762         }
0763         return (double)count/pLine->size();
0764 }
0765 
0766 /*
0767 inline bool clist_contour::PrintContour(std::ostream& a_out)
0768 {
0769         std::streamsize old_prec = a_out.precision(3);
0770         a_out << std::setprecision(10);
0771 
0772         UINT i, index;
0773         cline_strip* pStrip;
0774         cline_strip::iterator pos2;
0775         cline_strip_list::iterator pos;
0776 
0777         for(i=0;i<get_number_of_planes();i++) {
0778                 for(pos = m_vStripLists[i].begin();pos!=m_vStripLists[i].end();pos++)
0779                 {
0780                         pStrip = (*pos);
0781                         for(pos2 = pStrip->begin();pos2!=pStrip->end();pos2++)
0782                         {
0783                           index = (*pos2);
0784                           a_out << get_xi(index)<<"\t"<<get_yi(index)<<"\n";
0785                         }
0786                         a_out<<"\n";
0787                 }
0788         }
0789         a_out.precision(old_prec);
0790         return true;
0791 
0792 }
0793 */
0794 
0795 //G.Barrand : from .h to .cxx to avoid _ASSERT_ in .h
0796 inline cline_strip_list* clist_contour::get_lines(unsigned int iPlane)  {
0797   /*_ASSERT_(iPlane>=0);*/
0798   _ASSERT_(iPlane<get_number_of_planes(),"clist_contour::get_lines");
0799   return &m_vStripLists[iPlane];
0800 }
0801 
0802 // Added by L.Garnier
0803 inline bool clist_contour::SpecialCompactStripCase(double aXfront,double aXback,double aYfront,double aYback,double actualHeight)
0804 {
0805   // To solve the case of a list of strips
0806   // which appeared to be open but should correspond to a closed
0807   // contour.
0808   //  With the today generate() algorithm, it appears that we fall
0809   // on this case when the begin and end points
0810   // are on a horizontal or vertical line.
0811   // (case where front()->x == back()->x or front()->y == back()->y).
0812   //  We try to detect in this method this situation and decide to close
0813   // or not the line. To do that we check the heigth of intermediate
0814   // points to see if there are on the same contour; if so we close
0815   // the line (and return true), if not we do nothing (and return false).
0816 
0817   // check if we could realy close it
0818   float marge = 1; // *m_dDy or *m_dDx. 1 seems to be good and normal, but why
0819                    // not 2 in certain cases???
0820 
0821   double distToNext =0;
0822   // try to get the correct hight
0823   if (get_plane(0)>= actualHeight) {
0824     return false;
0825   }
0826   if (get_number_of_planes() >1){
0827     distToNext = get_plane(1)-get_plane(0);
0828   } else {
0829     return false;
0830   }
0831 
0832   if ((aYback-aYfront) == 0) {
0833     double temp;
0834     double av;
0835     double eg;
0836     double ap;
0837 
0838     if (aXfront==m_pLimits[0] && aXback == m_pLimits[1]) return false;
0839     if (aXfront==m_pLimits[1] && aXback == m_pLimits[0]) return false;
0840 
0841     if (aXfront > aXback ) {
0842       temp = aXfront;
0843       aXfront = aXback;
0844       aXback = temp;
0845     }
0846     for(double check=aXfront+m_dDx;
0847         check<aXback;
0848         check+=m_dDx) {
0849       av = ((*m_pFieldFcn)(check,aYback-marge*m_dDy,m_pFieldFcnData)-actualHeight);
0850       eg = ((*m_pFieldFcn)(check,aYback,m_pFieldFcnData)-actualHeight);
0851       ap = ((*m_pFieldFcn)(check,aYback+marge*m_dDy,m_pFieldFcnData)-actualHeight);
0852 
0853       if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
0854         return false;
0855       } else if ((av<0) && (ap<0) && (eg<0)) {
0856         return false;
0857       }
0858     }
0859     return true;
0860   } else if ((aXback-aXfront) == 0) {
0861     double temp;
0862     double av;
0863     double eg;
0864     double ap;
0865     if (aYfront==m_pLimits[3] && aYback == m_pLimits[2]) return false;
0866     if (aYfront==m_pLimits[2] && aYback == m_pLimits[3]) return false;
0867 
0868     if (aYfront > aYback ) {
0869       temp = aYfront;
0870       aYfront = aYback;
0871       aYback = temp;
0872     }
0873 
0874     for(double check=aYfront+m_dDy;
0875         check<aYback;
0876         check+=m_dDy) {
0877       av = ((*m_pFieldFcn)(aXback-marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
0878       eg = ((*m_pFieldFcn)(aXback,check,m_pFieldFcnData)-actualHeight);
0879       ap = ((*m_pFieldFcn)(aXback+marge*m_dDx,check,m_pFieldFcnData)-actualHeight);
0880       if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) {
0881         return false;
0882       } else if ((av<0) && (ap<0) && (eg<0)) {
0883         return false;
0884       }
0885     }
0886     return true;
0887   }
0888   return false;
0889 }
0890 
0891 }
0892 
0893 #endif