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