Geant4 Cross Reference |
1 // Copyright (C) 2010, Guy Barrand. All rights reserved. 2 // See the file tools.license for terms. 3 4 #ifndef tools_clist_contour 5 #define tools_clist_contour 6 7 // G.Barrand : inline version of the one found in Lib of OSC 16.11. 8 // This code is not mine and I keep it "as it is". 9 10 // Inheritance : 11 #include "ccontour" 12 13 #include <list> 14 #include <ostream> 15 #include <iomanip> //std::setprecision 16 17 namespace tools { 18 19 // a list of point index referring to the secondary grid 20 // Let i the index of a point, 21 typedef std::list<unsigned int> cline_strip; 22 typedef std::list<cline_strip*> cline_strip_list; 23 typedef std::vector<cline_strip_list> cline_strip_list_vector; 24 25 class clist_contour : public ccontour 26 { 27 public: //ccontour 28 // Adding segment to line strips 29 // See ccontour::ExportLine for further details 30 virtual void ExportLine(int iPlane,int x1, int y1, int x2, int y2); 31 32 public: 33 clist_contour(); 34 virtual ~clist_contour(){CleanMemory();} 35 protected: //G.Barrand 36 clist_contour(const clist_contour& a_from):ccontour(a_from){} 37 private: //G.Barrand 38 clist_contour& operator=(const clist_contour&){return *this;} 39 public: 40 // retreiving list of line strip for the i-th contour 41 cline_strip_list* get_lines(unsigned int iPlane); 42 // Basic algorithm to concatanate line strip. Not optimized at all ! 43 bool compact_strips (); 44 // generate contour strips 45 virtual void generate(); 46 protected: //G.Barrand 47 48 // Initializing memory 49 virtual void InitMemory(); 50 // Cleaning memory and line strips 51 virtual void CleanMemory(); 52 53 // Adding segment to line strips 54 // See ccontour::ExportLine for further details 55 //void ExportLine(int iPlane,int x1, int y1, int x2, int y2); 56 57 /// debuggin 58 void DumpPlane(unsigned int iPlane) const; 59 60 // Area given by this function can be positive or negative depending on the winding direction of the contour. 61 double Area(cline_strip* Line); 62 63 double EdgeWeight(cline_strip* pLine, double R); 64 //bool PrintContour(std::ostream& a_out); 65 protected: 66 // Merges pStrip1 with pStrip2 if they have a common end point 67 bool MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2); 68 // Merges the two strips with a welding threshold. 69 bool ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double); 70 // returns true if contour is touching boundary 71 bool OnBoundary(cline_strip* pStrip); 72 // L.Garnier : check specials case for CompactStrip 73 bool SpecialCompactStripCase(double,double,double,double,double); 74 75 private: 76 // array of line strips 77 cline_strip_list_vector m_vStripLists; 78 typedef unsigned int UINT; 79 80 private: 81 static const char* _TT(const char* what) {return what;} 82 83 static void _TRACE_(const char* /*a_fmt*/,...) { 84 //va_list args; 85 //va_start(args,a_fmt); 86 //::vprintf(s,a_fmt,args); 87 //va_end(args); 88 } 89 static void _PROBLEM_(const char* what) {::printf("%s",what);} 90 91 static bool _ASSERT_RET_(bool what,const char* cmt) { 92 if(!(what)) { 93 ::printf("debug : ListContour : assert failure in %s\n",cmt); 94 return false; 95 } 96 return true; 97 } 98 99 static bool _ASSERT_MERGE_RET_(bool what,const char* cmt,cline_strip* pStrip2) { 100 if(!(what)) { 101 ::printf("debug : ListContour : assert failure in %s\n",cmt); 102 pStrip2->clear(); 103 return false; 104 } 105 return true; 106 } 107 }; 108 109 110 // implementation : 111 inline clist_contour::clist_contour() 112 : ccontour() 113 { 114 } 115 116 inline void clist_contour::generate() 117 { 118 // generate line strips 119 ccontour::generate(); 120 // compact strips 121 compact_strips (); 122 } 123 124 inline void clist_contour::InitMemory() 125 { 126 ccontour::InitMemory(); 127 128 cline_strip_list::iterator pos; 129 cline_strip* pStrip; 130 131 if (!m_vStripLists.empty()) 132 { 133 UINT i; 134 // reseting lists 135 _ASSERT_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::InitMemory::0"); 136 for (i=0;i<get_number_of_planes();i++) 137 { 138 for (pos = m_vStripLists[i].begin(); pos!=m_vStripLists[i].end() ; pos++) 139 { 140 pStrip=(*pos); 141 _ASSERTP_(pStrip,"clist_contour::InitMemory::1"); 142 143 pStrip->clear(); 144 delete pStrip; 145 } 146 m_vStripLists[i].clear(); 147 } 148 } 149 else 150 m_vStripLists.resize(get_number_of_planes()); 151 } 152 153 inline void clist_contour::CleanMemory() 154 { 155 ccontour::CleanMemory(); 156 157 cline_strip_list::iterator pos; 158 cline_strip* pStrip; 159 UINT i; 160 161 // reseting lists 162 for (i=0;i<m_vStripLists.size();i++) //G.Barrand 163 { 164 for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++) 165 { 166 pStrip=(*pos); 167 _ASSERTP_(pStrip,"clist_contour::CleanMemory"); 168 pStrip->clear(); 169 delete pStrip; 170 } 171 m_vStripLists[i].clear(); 172 } 173 } 174 175 inline void clist_contour::ExportLine(int iPlane,int x1, int y1, int x2, int y2) 176 { 177 _ASSERT_(iPlane>=0,"clist_contour::ExportLine::0"); 178 _ASSERT_(iPlane<(int)get_number_of_planes(),"clist_contour::ExportLine::1"); 179 180 // check that the two points are not at the beginning or end of the some line strip 181 UINT i1=y1*(m_iColSec+1)+x1; 182 UINT i2=y2*(m_iColSec+1)+x2; 183 184 cline_strip* pStrip; 185 186 cline_strip_list::iterator pos; 187 bool added = false; 188 for(pos=m_vStripLists[iPlane].begin(); pos!=m_vStripLists[iPlane].end() && !added; pos++) 189 { 190 pStrip=(*pos); 191 _ASSERTP_(pStrip,"clist_contour::ExportLine::2"); 192 // check if points are appendable to this strip 193 if (i1==pStrip->front()) 194 { 195 pStrip->insert(pStrip->begin(),i2); 196 return; 197 } 198 if (i1==pStrip->back()) 199 { 200 pStrip->insert(pStrip->end(),i2); 201 return; 202 } 203 if (i2==pStrip->front()) 204 { 205 pStrip->insert(pStrip->begin(),i1); 206 return; 207 } 208 if (i2==pStrip->back()) 209 { 210 pStrip->insert(pStrip->end(),i1); 211 return; 212 } 213 } 214 215 // segment was not part of any line strip, creating new one 216 pStrip=new cline_strip; 217 pStrip->insert(pStrip->begin(),i1); 218 pStrip->insert(pStrip->end(),i2); 219 m_vStripLists[iPlane].insert(m_vStripLists[iPlane].begin(),pStrip); 220 } 221 222 inline bool clist_contour::ForceMerge(cline_strip* pStrip1, cline_strip* pStrip2,double aHeight) 223 { 224 225 cline_strip::iterator pos; 226 cline_strip::reverse_iterator rpos; 227 228 if (pStrip2->empty()) 229 return false; 230 231 double x[4], y[4], weldDist; 232 int index; 233 index = pStrip1->front(); 234 x[0] = get_xi(index); 235 y[0] = get_yi(index); 236 index = pStrip1->back(); 237 x[1] = get_xi(index); 238 y[1] = get_yi(index); 239 index = pStrip2->front(); 240 x[2] = get_xi(index); 241 y[2] = get_yi(index); 242 index = pStrip2->back(); 243 x[3] = get_xi(index); 244 y[3] = get_yi(index); 245 246 weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy); 247 248 if (((x[1]-x[2])*(x[1]-x[2])+(y[1]-y[2])*(y[1]-y[2])< weldDist) 249 || SpecialCompactStripCase(x[1],x[2],y[1],y[2],aHeight)) // L.Garnier 250 251 { 252 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++) 253 { 254 index=(*pos); 255 if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::0")) return false; 256 pStrip1->insert(pStrip1->end(),index); 257 } 258 pStrip2->clear(); 259 return true; 260 } 261 262 if (((x[3]-x[0])*(x[3]-x[0])+(y[3]-y[0])*(y[3]-y[0])< weldDist) 263 || SpecialCompactStripCase(x[3],x[0],y[3],y[0],aHeight)) // L.Garnier 264 { 265 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++) 266 { 267 index=(*rpos); 268 if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::1")) return false; 269 pStrip1->insert(pStrip1->begin(),index); 270 } 271 pStrip2->clear(); 272 return true; 273 } 274 275 if (((x[1]-x[3])*(x[1]-x[3])+(y[1]-y[3])*(y[1]-y[3])< weldDist) 276 || SpecialCompactStripCase(x[1],x[3],y[1],y[3],aHeight)) // L.Garnier 277 { 278 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++) 279 { 280 index=(*rpos); 281 if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::2")) return false; 282 pStrip1->insert(pStrip1->end(),index); 283 } 284 pStrip2->clear(); 285 return true; 286 } 287 288 if (((x[0]-x[2])*(x[0]-x[2])+(y[0]-y[2])*(y[0]-y[2])< weldDist) 289 || SpecialCompactStripCase(x[0],x[2],y[0],y[2],aHeight)) // L.Garnier 290 { 291 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++) 292 { 293 index=(*pos); 294 if(!_ASSERT_RET_(index>=0,"clist_contour::ForceMerge::3")) return false; 295 pStrip1->insert(pStrip1->begin(),index); 296 } 297 pStrip2->clear(); 298 return true; 299 } 300 301 return false; 302 } 303 304 inline bool clist_contour::MergeStrips(cline_strip* pStrip1, cline_strip* pStrip2) 305 { 306 cline_strip::iterator pos; 307 cline_strip::reverse_iterator rpos; 308 if (pStrip2->empty()) 309 return false; 310 311 int index; 312 313 // debugging stuff 314 if (pStrip2->front()==pStrip1->front()) 315 { 316 // retreiving first element 317 pStrip2->pop_front(); 318 // adding the rest to strip1 319 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++) 320 { 321 index=(*pos); 322 if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::0",pStrip2)) return false; 323 pStrip1->insert(pStrip1->begin(),index); 324 } 325 pStrip2->clear(); 326 return true; 327 } 328 329 if (pStrip2->front()==pStrip1->back()) 330 { 331 pStrip2->pop_front(); 332 // adding the rest to strip1 333 for (pos=pStrip2->begin(); pos!=pStrip2->end();pos++) 334 { 335 index=(*pos); 336 if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::1",pStrip2)) return false; 337 pStrip1->insert(pStrip1->end(),index); 338 } 339 pStrip2->clear(); 340 return true; 341 } 342 343 if (pStrip2->back()==pStrip1->front()) 344 { 345 pStrip2->pop_back(); 346 // adding the rest to strip1 347 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++) 348 { 349 index=(*rpos); 350 if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::2",pStrip2)) return false; 351 pStrip1->insert(pStrip1->begin(),index); 352 } 353 pStrip2->clear(); 354 return true; 355 } 356 357 if (pStrip2->back()==pStrip1->back()) 358 { 359 pStrip2->pop_back(); 360 // adding the rest to strip1 361 for (rpos=pStrip2->rbegin(); rpos!=pStrip2->rend();rpos++) 362 { 363 index=(*rpos); 364 if(!_ASSERT_MERGE_RET_(index>=0,"clist_contour::MergeStrips::3",pStrip2)) return false; 365 pStrip1->insert(pStrip1->end(),index); 366 } 367 pStrip2->clear(); 368 return true; 369 } 370 371 return false; 372 } 373 374 inline bool clist_contour::compact_strips () 375 { 376 cline_strip* pStrip; 377 cline_strip* pStripBase = 0; 378 UINT i; 379 cline_strip_list::iterator pos,pos2; 380 cline_strip_list newList; 381 bool again, changed; 382 383 const double weldDist = 10*(m_dDx*m_dDx+m_dDy*m_dDy); 384 385 if(!_ASSERT_RET_(m_vStripLists.size() == get_number_of_planes(),"clist_contour::compact_strips ::0")) return false; 386 for (i=0;i<get_number_of_planes();i++) 387 { 388 double planeHeight = get_plane(i); 389 again=true; 390 while(again) 391 { 392 // REPEAT COMPACT PROCESS UNTILL LAST PROCESS MAKES NO CHANGE 393 394 again=false; 395 // building compacted list 396 if(!_ASSERT_RET_(newList.empty(),"clist_contour::compact_strips ::1")) return false; 397 for (pos=m_vStripLists[i].begin(); pos!=m_vStripLists[i].end();pos++) 398 { 399 pStrip=(*pos); 400 for (pos2=newList.begin(); pos2!=newList.end();pos2++) 401 { 402 pStripBase=(*pos2); 403 changed=MergeStrips(pStripBase,pStrip); 404 if (changed) 405 again=true; 406 if (pStrip->empty()) 407 break; 408 } 409 if (pStrip->empty()) 410 delete pStrip; 411 else 412 newList.insert(newList.begin(),pStrip); 413 } 414 415 416 // deleting old list 417 m_vStripLists[i].clear(); 418 cline_strip* pStrip2; 419 // Copying all 420 for (pos2=newList.begin(); pos2 != newList.end(); pos2++) 421 { 422 pStrip2=(*pos2); 423 cline_strip::iterator pos1 = pStrip2->begin(),pos3; 424 while (pos1!=pStrip2->end()) 425 { 426 pos3 = pos1; 427 pos3++; 428 if (pos3==pStrip2->end()) break; //G.Barrand 429 if ( (*pos1) == (*pos3)) 430 { 431 /*G.Barrand : we can't compare with pStrip2->end() content. 432 if ( (*pos3) != (*pStrip2->end())) 433 pStrip2->erase(pos3); 434 else 435 { 436 pStrip2->erase(pos3); 437 break; 438 } 439 */ 440 pStrip2->erase(pos3); //G.Barrand. 441 } 442 else 443 pos1++; 444 } 445 446 //if (!(pStrip2->front()==pStrip2->back() && pStrip2->size()==2)) 447 if (pStrip2->size()!=1) 448 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStrip2 ); 449 else 450 delete pStrip2; 451 } 452 // emptying temp list 453 newList.clear(); 454 455 } // OF WHILE(AGAIN) (LAST COMPACT PROCESS MADE NO CHANGES) 456 457 458 if (m_vStripLists[i].empty()) 459 continue; 460 /////////////////////////////////////////////////////////////////////// 461 // compact more 462 int index,count; 463 size_t Nstrip,j; 464 465 Nstrip = m_vStripLists[i].size(); 466 std::vector<bool> closed(Nstrip); 467 double x,y; 468 469 // First let's find the open and closed lists in m_vStripLists 470 for(pos2 = m_vStripLists[i].begin(), j=0, count=0; pos2 != m_vStripLists[i].end(); pos2++, j++) 471 { 472 pStrip = (*pos2); 473 474 // is it open ? 475 if (pStrip->front() != pStrip->back()) 476 { 477 index = pStrip->front(); 478 x = get_xi(index); y = get_yi(index); 479 index = pStrip->back(); 480 x -= get_xi(index); y -= get_yi(index); 481 482 // is it "almost closed" ? 483 if ((x*x+y*y < weldDist) || 484 SpecialCompactStripCase(get_xi(pStrip->front()), // L.Garnier 485 get_xi(pStrip->back()), 486 get_yi(pStrip->front()), 487 get_yi(pStrip->back()), 488 planeHeight)) 489 { 490 closed[j] = true; 491 // close it !!! Added by L.Garnier 492 pStrip->push_back(pStrip->front()); 493 // 494 } 495 else 496 { 497 closed[j] = false; 498 // updating not closed counter... 499 count ++; 500 } 501 } 502 else 503 closed[j] = true; 504 } 505 506 // is there any open strip ? 507 if (count > 1) 508 { 509 // Merge the open strips into NewList 510 pos = m_vStripLists[i].begin(); 511 for(j=0;j<Nstrip;j++) 512 { 513 if (closed[j] == false ) 514 { 515 pStrip = (*pos); 516 newList.insert(newList.begin(),pStrip); 517 pos = m_vStripLists[i].erase(pos); 518 } 519 else 520 pos ++; 521 } 522 523 // are they open strips to process ? 524 while(newList.size()>1) 525 { 526 pStripBase = newList.front(); 527 528 // merge the rest to pStripBase 529 again = true; 530 while (again) 531 { 532 again = false; 533 pos = newList.begin(); 534 for(pos++; pos!=newList.end();) 535 { 536 pStrip = (*pos); 537 changed = ForceMerge(pStripBase,pStrip,planeHeight); 538 if (changed) 539 { 540 again = true; 541 delete pStrip; 542 pos = newList.erase(pos); 543 } 544 else 545 pos ++; 546 } 547 } // while(again) 548 549 index = pStripBase->front(); 550 x = get_xi(index); y = get_yi(index); 551 index = pStripBase->back(); 552 x -= get_xi(index); y -= get_yi(index); 553 // if pStripBase is closed or not 554 555 if ((x*x+y*y < weldDist) || 556 SpecialCompactStripCase(get_xi(pStripBase->front()), // L.Garnier 557 get_xi(pStripBase->back()), 558 get_yi(pStripBase->front()), 559 get_yi(pStripBase->back()), 560 planeHeight)) 561 { 562 563 // close it !!! Added by L.Garnier 564 if ((x!=0) || (y!=0)) { 565 pStripBase->push_back(pStripBase->front()); 566 } 567 // 568 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase); 569 newList.pop_front(); 570 } 571 else 572 { 573 if (OnBoundary(pStripBase)) 574 { 575 _TRACE_(_TT("# open strip ends on boundary, continue.\n")); 576 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase); 577 newList.pop_front(); 578 } 579 else 580 { 581 _PROBLEM_(_TT("unpaird open strip at 1!\n")); 582 //exit(0); 583 return false; 584 } 585 } 586 } // while(newList.size()>1); 587 588 589 if (newList.size() ==1) 590 { 591 pStripBase = newList.front(); 592 index = pStripBase->front(); // L.Garnier 593 x = get_xi(index); y = get_yi(index); // L.Garnier 594 index = pStripBase->back(); // L.Garnier 595 x -= get_xi(index); y -= get_yi(index); // L.Garnier 596 597 // is it "almost closed", give last chance...5*weldDist 598 if (x*x+y*y < 3*weldDist) // L.Garnier 599 { 600 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase); 601 newList.pop_front(); 602 } 603 else if (OnBoundary(pStripBase)) 604 { 605 _TRACE_(_TT("# open strip ends on boundary, continue.\n")); 606 m_vStripLists[i].insert(m_vStripLists[i].begin(),pStripBase); 607 newList.pop_front(); 608 } 609 else 610 { 611 _PROBLEM_(_TT("unpaird open strip at 2!\n")); 612 DumpPlane(i); 613 //exit(0); 614 return false; 615 } 616 } 617 618 newList.clear(); 619 620 } 621 else if (count == 1) 622 { 623 pos = m_vStripLists[i].begin(); 624 for(j=0;j<Nstrip;j++) 625 { 626 if (closed[j] == false ) 627 { 628 pStripBase = (*pos); 629 break; 630 } 631 pos ++; 632 } 633 index = pStripBase->front(); // L.Garnier 634 x = get_xi(index); y = get_yi(index); // L.Garnier 635 index = pStripBase->back(); // L.Garnier 636 x -= get_xi(index); y -= get_yi(index); // L.Garnier 637 638 // is it "almost closed", give last chance...5*weldDist 639 if (x*x+y*y < 2*weldDist) // L.Garnier 640 { 641 //close it!! 642 pStripBase->push_back(pStripBase->front()); // L.Garnier 643 } 644 else if (OnBoundary(pStripBase)) 645 { 646 _TRACE_(_TT("# open strip ends on boundary, continue.\n")); 647 pStripBase->push_back(pStripBase->front()); // L.Garnier 648 } 649 else 650 { 651 _TRACE_(_TT("unpaird open strip at 3!")); 652 DumpPlane(i); 653 return false; // L.Garnier 654 //exit(0); 655 } 656 newList.clear(); // L.Garnier 657 } 658 } 659 return true; 660 } 661 662 663 inline bool clist_contour::OnBoundary(cline_strip* pStrip) 664 { 665 bool e1,e2; 666 667 int index = pStrip->front(); 668 double x = get_xi(index), y = get_yi(index); 669 if (x==m_pLimits[0] || x == m_pLimits[1] || 670 y == m_pLimits[2] || y == m_pLimits[3]) 671 e1 = true; 672 else 673 e1 = false; 674 675 index = pStrip->back(); 676 x = get_xi(index); y = get_yi(index); 677 if (x==m_pLimits[0] || x == m_pLimits[1] || 678 y == m_pLimits[2] || y == m_pLimits[3]) 679 e2 = true; 680 else 681 e2 = false; 682 683 return (e1 && e2); 684 } 685 686 inline void clist_contour::DumpPlane(UINT iPlane) const 687 { 688 cline_strip_list::const_iterator pos; 689 UINT i; 690 cline_strip* pStrip; 691 692 /*_ASSERT_(iPlane>=0,"clist_contour::DumpPlane");*/ 693 _ASSERT_(iPlane<get_number_of_planes(),"clist_contour::DumpPlane::0"); 694 _TRACE_(_TT("Level : %d"),get_plane(iPlane)); 695 696 _TRACE_(_TT("Number of strips : %d\r\n"),m_vStripLists[iPlane].size()); 697 _TRACE_(_TT("i np start end xstart ystart xend yend\r\n")); 698 for (pos = m_vStripLists[iPlane].begin(), i=0; pos != m_vStripLists[iPlane].end(); pos++, i++) 699 { 700 pStrip=*pos; 701 _ASSERTP_(pStrip,"clist_contour::DumpPlane::1"); 702 _TRACE_(_TT("%d %d %d %d %g %g %g %g\r\n"),i,pStrip->size(),pStrip->front(),pStrip->back(), 703 get_xi(pStrip->front()),get_yi(pStrip->front()), 704 get_xi(pStrip->back()),get_yi(pStrip->back()) ); 705 } 706 } 707 708 inline double clist_contour::Area(cline_strip* Line) 709 { 710 // if Line is not closed, return 0; 711 712 double Ar = 0, x, y, x0,y0,x1, y1; 713 int index; 714 715 cline_strip::iterator pos; 716 pos = Line->begin(); 717 index = (*pos); 718 x0 = x = get_xi(index); 719 y0 = y = get_yi(index); 720 721 pos ++; 722 723 for(;pos!=Line->end();pos++) 724 { 725 index = (*pos); 726 x1 = get_xi(index); 727 y1 = get_yi(index); 728 // Ar += (x1-x)*(y1+y); 729 Ar += (y1-y)*(x1+x)-(x1-x)*(y1+y); 730 x = x1; 731 y = y1; 732 733 } 734 735 736 //Ar += (x0-x)*(y0+y); 737 Ar += (y0-y)*(x0+x)-(x0-x)*(y0+y); 738 // if not closed curve, return 0; 739 if ((x0-x)*(x0-x) + (y0-y)*(y0-y)>20*(m_dDx*m_dDx+m_dDy*m_dDy)) 740 { 741 Ar = 0; 742 _TRACE_(_TT("# open curve!\n")); 743 } 744 //else Ar /= -2; 745 else Ar/=4; 746 // result is \int ydex/2 alone the implicit direction. 747 return Ar; 748 } 749 750 inline double clist_contour:: EdgeWeight(cline_strip* pLine, double R) 751 { 752 cline_strip::iterator pos; 753 int count = 0,index; 754 double x,y; 755 for(pos = pLine->begin(); pos!=pLine->end(); pos++) 756 { 757 index = (*pos); 758 x = get_xi(index); 759 y = get_yi(index); 760 if (fabs(x) > R || fabs(y) > R) 761 count ++; 762 } 763 return (double)count/pLine->size(); 764 } 765 766 /* 767 inline bool clist_contour::PrintContour(std::ostream& a_out) 768 { 769 std::streamsize old_prec = a_out.precision(3); 770 a_out << std::setprecision(10); 771 772 UINT i, index; 773 cline_strip* pStrip; 774 cline_strip::iterator pos2; 775 cline_strip_list::iterator pos; 776 777 for(i=0;i<get_number_of_planes();i++) { 778 for(pos = m_vStripLists[i].begin();pos!=m_vStripLists[i].end();pos++) 779 { 780 pStrip = (*pos); 781 for(pos2 = pStrip->begin();pos2!=pStrip->end();pos2++) 782 { 783 index = (*pos2); 784 a_out << get_xi(index)<<"\t"<<get_yi(index)<<"\n"; 785 } 786 a_out<<"\n"; 787 } 788 } 789 a_out.precision(old_prec); 790 return true; 791 792 } 793 */ 794 795 //G.Barrand : from .h to .cxx to avoid _ASSERT_ in .h 796 inline cline_strip_list* clist_contour::get_lines(unsigned int iPlane) { 797 /*_ASSERT_(iPlane>=0);*/ 798 _ASSERT_(iPlane<get_number_of_planes(),"clist_contour::get_lines"); 799 return &m_vStripLists[iPlane]; 800 } 801 802 // Added by L.Garnier 803 inline bool clist_contour::SpecialCompactStripCase(double aXfront,double aXback,double aYfront,double aYback,double actualHeight) 804 { 805 // To solve the case of a list of strips 806 // which appeared to be open but should correspond to a closed 807 // contour. 808 // With the today generate() algorithm, it appears that we fall 809 // on this case when the begin and end points 810 // are on a horizontal or vertical line. 811 // (case where front()->x == back()->x or front()->y == back()->y). 812 // We try to detect in this method this situation and decide to close 813 // or not the line. To do that we check the heigth of intermediate 814 // points to see if there are on the same contour; if so we close 815 // the line (and return true), if not we do nothing (and return false). 816 817 // check if we could realy close it 818 float marge = 1; // *m_dDy or *m_dDx. 1 seems to be good and normal, but why 819 // not 2 in certain cases??? 820 821 double distToNext =0; 822 // try to get the correct hight 823 if (get_plane(0)>= actualHeight) { 824 return false; 825 } 826 if (get_number_of_planes() >1){ 827 distToNext = get_plane(1)-get_plane(0); 828 } else { 829 return false; 830 } 831 832 if ((aYback-aYfront) == 0) { 833 double temp; 834 double av; 835 double eg; 836 double ap; 837 838 if (aXfront==m_pLimits[0] && aXback == m_pLimits[1]) return false; 839 if (aXfront==m_pLimits[1] && aXback == m_pLimits[0]) return false; 840 841 if (aXfront > aXback ) { 842 temp = aXfront; 843 aXfront = aXback; 844 aXback = temp; 845 } 846 for(double check=aXfront+m_dDx; 847 check<aXback; 848 check+=m_dDx) { 849 av = ((*m_pFieldFcn)(check,aYback-marge*m_dDy,m_pFieldFcnData)-actualHeight); 850 eg = ((*m_pFieldFcn)(check,aYback,m_pFieldFcnData)-actualHeight); 851 ap = ((*m_pFieldFcn)(check,aYback+marge*m_dDy,m_pFieldFcnData)-actualHeight); 852 853 if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) { 854 return false; 855 } else if ((av<0) && (ap<0) && (eg<0)) { 856 return false; 857 } 858 } 859 return true; 860 } else if ((aXback-aXfront) == 0) { 861 double temp; 862 double av; 863 double eg; 864 double ap; 865 if (aYfront==m_pLimits[3] && aYback == m_pLimits[2]) return false; 866 if (aYfront==m_pLimits[2] && aYback == m_pLimits[3]) return false; 867 868 if (aYfront > aYback ) { 869 temp = aYfront; 870 aYfront = aYback; 871 aYback = temp; 872 } 873 874 for(double check=aYfront+m_dDy; 875 check<aYback; 876 check+=m_dDy) { 877 av = ((*m_pFieldFcn)(aXback-marge*m_dDx,check,m_pFieldFcnData)-actualHeight); 878 eg = ((*m_pFieldFcn)(aXback,check,m_pFieldFcnData)-actualHeight); 879 ap = ((*m_pFieldFcn)(aXback+marge*m_dDx,check,m_pFieldFcnData)-actualHeight); 880 if ((av>distToNext) && (ap>distToNext) && (eg>distToNext)) { 881 return false; 882 } else if ((av<0) && (ap<0) && (eg<0)) { 883 return false; 884 } 885 } 886 return true; 887 } 888 return false; 889 } 890 891 } 892 893 #endif