#include <eTess2.h>
Public Member Functions | |
eFace (eHalfEdge *a, eHalfEdge *b, eHalfEdge *c) | |
eFace (eHalfEdge *a, eHalfEdge *b, eHalfEdge *c, tControlledPTR< eFace > &old) | |
eFace (eHalfEdge *a, eHalfEdge *b, eHalfEdge *c, tControlledPTR< eFace > &old1, tControlledPTR< eFace > &old2) | |
void | Create (eHalfEdge *a, eHalfEdge *b, eHalfEdge *c) |
bool | Check () |
void | Print (std::ostream &s) const |
void | Unlink () |
bool | IsInside (const eCoord &coord) const |
REAL | Insideness (const eCoord &coord, const eCoord &direction, const eCoord &lastDirection) const |
REAL | Insideness (const eCoord &coord, const eCoord &direction) const |
REAL | Insideness (const eCoord &coord) const |
eFace * | FindReplacement (const eCoord &coord, const eCoord &direction, const eCoord &lastDirection) const |
eFace * | FindReplacement (const eCoord &coord, const eCoord &direction) const |
eFace * | FindReplacement (const eCoord &coord) const |
bool | CorrectArea () |
eReplacementStorage & | GetReplacementStorage () const |
Public Attributes | |
eFace * | nextProcessed |
Private Member Functions | |
~eFace () | |
Private Attributes | |
eReplacementStorage * | replacementStorage |
Friends | |
class | tReferencable< eFace > |
Definition at line 284 of file eTess2.h.
eFace::~eFace | ( | ) | [private] |
Definition at line 457 of file eGrid.cpp.
References replacementStorage, and Unlink().
00458 { 00459 Unlink(); 00460 // se_EraseFace( this ); 00461 00462 delete replacementStorage; 00463 }
Definition at line 465 of file eGrid.cpp.
References Create().
00466 :replacementStorage( 0 ) 00467 { 00468 Create( e1, e2, e3 ); 00469 }
eFace::eFace | ( | eHalfEdge * | a, | |
eHalfEdge * | b, | |||
eHalfEdge * | c, | |||
tControlledPTR< eFace > & | old | |||
) |
Definition at line 471 of file eGrid.cpp.
References Create(), and se_LinkFaces().
00472 :replacementStorage( 0 ) 00473 { 00474 Create( e1, e2, e3 ); 00475 se_LinkFaces( old, this ); 00476 }
eFace::eFace | ( | eHalfEdge * | a, | |
eHalfEdge * | b, | |||
eHalfEdge * | c, | |||
tControlledPTR< eFace > & | old1, | |||
tControlledPTR< eFace > & | old2 | |||
) |
Definition at line 478 of file eGrid.cpp.
References Create(), and se_LinkFaces().
00479 :replacementStorage( 0 ) 00480 { 00481 Create( e1, e2, e3 ); 00482 se_LinkFaces( old1, this ); 00483 se_LinkFaces( old2, this ); 00484 }
Definition at line 486 of file eGrid.cpp.
References con, eDual::edge, EPS, eHalfEdge::next, nextProcessed, NULL, eHalfEdge::other, eHalfEdge::Point(), eHalfEdge::prev, REAL, se_maxGridSize, eHalfEdge::SetFace(), and tASSERT.
Referenced by eFace().
00487 { 00488 #ifdef DEBUG 00489 tASSERT( edge == 0 ); 00490 00491 tASSERT(e1->other); 00492 tASSERT(e2->other); 00493 tASSERT(e3->other); 00494 00495 tASSERT(e1->Point() == e3->other->Point()); 00496 tASSERT(e2->Point() == e1->other->Point()); 00497 tASSERT(e3->Point() == e2->other->Point()); 00498 00499 // tASSERT(*e1->Point() != *e2->Point()); 00500 // tASSERT(*e3->Point() != *e2->Point()); 00501 // tASSERT(*e1->Point() != *e3->Point()); 00502 00503 tASSERT((*e1->Point() - *e2->Point()).NormSquared() < se_maxGridSize*100); 00504 tASSERT((*e3->Point() - *e2->Point()).NormSquared() < se_maxGridSize*100); 00505 tASSERT((*e1->Point() - *e3->Point()).NormSquared() < se_maxGridSize*100); 00506 #endif 00507 00508 nextProcessed = NULL; 00509 00510 e1->SetFace(this); 00511 e2->SetFace(this); 00512 e3->SetFace(this); 00513 00514 e1->next = e2; 00515 e2->next = e3; 00516 e3->next = e1; 00517 e1->prev = e3; 00518 e2->prev = e1; 00519 e3->prev = e2; 00520 00521 e1->Point()->edge = e1; 00522 e2->Point()->edge = e2; 00523 e3->Point()->edge = e3; 00524 00525 edge = e1; 00526 00527 #ifdef DEBUG 00528 REAL area = -(*e1->Point() - *e2->Point()) * (*e1->Point() - *e3->Point()); 00529 if( area <= -EPS ) 00530 { 00531 con << "Face " << *this << " has wrong orientation (area: " << area << ").\n"; 00532 } 00533 #endif 00534 }
bool eFace::Check | ( | ) | [inline] |
Definition at line 304 of file eTess2.h.
References eDual::Check().
00304 {return eDual::Check(1);}
void eFace::Print | ( | std::ostream & | s | ) | const |
Definition at line 653 of file eGrid.cpp.
References eDual::edge.
Referenced by operator<<().
00653 { s << "[" << *edge->Point() << "->" << *edge->next->Point() << "->" << *edge->next->next->Point() << "]"; }
void eFace::Unlink | ( | ) |
Definition at line 536 of file eGrid.cpp.
References eDual::edge, eHalfEdge::Face(), eHalfEdge::next, NULL, eHalfEdge::SetFace(), and tASSERT.
Referenced by eGrid::KillFace(), eGrid::ZombifyFace(), and ~eFace().
00536 { 00537 if (edge) 00538 { 00539 eHalfEdge *run = edge; 00540 const eHalfEdge *stop = run; 00541 00542 do 00543 { 00544 tASSERT(run->Face() == this); 00545 run->SetFace(NULL); 00546 00547 run = run->next; 00548 } 00549 while (stop != run); 00550 00551 edge = NULL; 00552 } 00553 }
bool eFace::IsInside | ( | const eCoord & | coord | ) | const |
Definition at line 609 of file eGrid.cpp.
References eCoord, eDual::edge, EPS, eHalfEdge::Face(), eHalfEdge::next, eHalfEdge::Point(), and tASSERT.
Referenced by eGrid::FindSurroundingFace().
00610 { 00611 // flags storing whether there is a point of the triangle with bigger/smaller coordinates 00612 // than the test coords 00613 bool xLower=false, xHigher=false, yLower=false, yHigher=false; 00614 00615 eHalfEdge *run = edge; 00616 if (!run) 00617 return false; 00618 00619 eCoord *last_p = run->Point(); 00620 run = run->next; 00621 const eHalfEdge *stop = run; 00622 00623 do 00624 { 00625 tASSERT(run && run->Face() == this); 00626 eCoord *p = run->Point(); 00627 eCoord ed=*last_p - *p; 00628 eCoord cc= c - *p; 00629 00630 if ( p->x <= c.x + EPS ) 00631 xLower = true; 00632 if ( p->x >= c.x - EPS ) 00633 xHigher = true; 00634 if ( p->y <= c.y + EPS ) 00635 yLower = true; 00636 if ( p->y >= c.y - EPS ) 00637 yHigher = true; 00638 00639 if (ed*cc<-EPS) 00640 return false; 00641 00642 last_p = p; 00643 run = run->next; 00644 } 00645 while (run && stop != run); 00646 00647 // test if the point is in the bounding rectangle of the triangle 00648 return xLower && xHigher && yLower && yHigher; 00649 }
REAL eFace::Insideness | ( | const eCoord & | coord, | |
const eCoord & | direction, | |||
const eCoord & | lastDirection | |||
) | const |
Definition at line 556 of file eGrid.cpp.
References eCoord, eDual::edge, EPS, eHalfEdge::Face(), max(), eHalfEdge::next, eHalfEdge::Point(), REAL, and tASSERT.
Referenced by Insideness(), and se_FindBestReplacement().
00557 { 00558 // TODO: bounding box check 00559 00560 eCoord min, max; 00561 00562 eHalfEdge *run = edge; 00563 if (!run) 00564 return -1000000000; 00565 00566 REAL ret = 1000000000; 00567 00568 eCoord *last_p = run->Point(); 00569 run = run->next; 00570 const eHalfEdge *stop = run; 00571 00572 do 00573 { 00574 tASSERT(run && run->Face() == this); 00575 eCoord *p = run->Point(); 00576 eCoord ed=*last_p - *p; 00577 eCoord cc= pos - *p; 00578 00579 REAL val = ed*cc; 00580 // REAL tol = 10 * EPS/(ed.Norm() + EPS*1000); 00581 REAL tol = 10 * EPS; 00582 REAL retDir = direction*ed; 00583 REAL retLastDir = lastDirection*ed; 00584 val += tol*(retDir + tol*retLastDir); 00585 if ( val < ret ) 00586 { 00587 ret = val; 00588 } 00589 00590 last_p = p; 00591 run = run->next; 00592 } 00593 while (run && stop != run); 00594 00595 return ret; 00596 }
REAL eFace::Insideness | ( | const eCoord & | coord, | |
const eCoord & | direction | |||
) | const |
Definition at line 598 of file eGrid.cpp.
References eCoord, and Insideness().
00599 { 00600 return Insideness( c, direction, eCoord() ); 00601 }
REAL eFace::Insideness | ( | const eCoord & | coord | ) | const |
Definition at line 603 of file eGrid.cpp.
References eCoord, and Insideness().
00604 { 00605 return Insideness( c, eCoord(), eCoord() ); 00606 }
eFace * eFace::FindReplacement | ( | const eCoord & | coord, | |
const eCoord & | direction, | |||
const eCoord & | lastDirection | |||
) | const |
Definition at line 415 of file eGrid.cpp.
References arg(), se_FindBestReplacement(), and tASSERT.
00416 { 00417 // check if we don't need an replacement 00418 tASSERT( !this->IsInGrid() ); 00419 00420 // set of already visited faces 00421 eFaceReplacementArgument arg; 00422 arg.coord = coord; 00423 arg.direction = direction; 00424 arg.lastDirection = lastDirection; 00425 00426 // delegate search to recursive function 00427 return se_FindBestReplacement( this, arg ).first; 00428 }
eFace * eFace::FindReplacement | ( | const eCoord & | coord, | |
const eCoord & | direction | |||
) | const |
Definition at line 430 of file eGrid.cpp.
References arg(), se_FindBestReplacement(), and tASSERT.
00431 { 00432 // check if we don't need an replacement 00433 tASSERT( !this->IsInGrid() ); 00434 00435 // set of already visited faces 00436 eFaceReplacementArgument arg; 00437 arg.coord = coord; 00438 arg.direction = direction; 00439 00440 // delegate search to recursive function 00441 return se_FindBestReplacement( this, arg ).first; 00442 }
eFace * eFace::FindReplacement | ( | const eCoord & | coord | ) | const |
Definition at line 444 of file eGrid.cpp.
References arg(), se_FindBestReplacement(), and tASSERT.
00445 { 00446 // check if we don't need an replacement 00447 tASSERT( !this->IsInGrid() ); 00448 00449 // set of already visited faces 00450 eFaceReplacementArgument arg; 00451 arg.coord = coord; 00452 00453 // delegate search to recursive function 00454 return se_FindBestReplacement( this, arg ).first; 00455 }
bool eFace::CorrectArea | ( | ) |
Definition at line 1751 of file eGrid.cpp.
References ClampMovement(), eCoord, eDual::edge, eHalfEdge::Movable(), Movable(), eHalfEdge::next, NULL, eHalfEdge::Point(), REAL, st_Breakpoint(), tASSERT, and eHalfEdge::Vec().
Referenced by eGrid::AddFace(), and eGrid::DrawLine().
01752 { 01753 REAL area = edge->next->Vec() * edge->Vec(); 01754 if (area >= 0) 01755 return false; 01756 01757 eHalfEdge *run = edge; 01758 01759 // find the longest edge ( preferably with wall ) 01760 eHalfEdge *longest = NULL; 01761 REAL length = -1; 01762 bool wall = false; 01763 01764 for (int i=2; i>=0; i--) 01765 { 01766 REAL runLength = run->Vec().NormSquared(); 01767 01768 // test if moving the point opposite to run would move walls 01769 if (!Movable( run->next->next->Point() ) ) 01770 continue; 01771 01772 bool runWall = !run->Movable(); 01773 if ( runLength > length || runWall ) 01774 { 01775 // abort if the triangle has two walled sides 01776 if ( wall && runWall ) 01777 { 01778 // however, this should never, ever happen. 01779 st_Breakpoint(); 01780 return false; 01781 } 01782 01783 wall = runWall; 01784 length = runLength; 01785 longest = run; 01786 } 01787 run = run->next; 01788 } 01789 01790 // no luck? 01791 if ( !longest ) 01792 return false; 01793 01794 run = longest; 01795 eCoord &A = *run->Point(); 01796 run = run->next; 01797 eCoord &B = *run->Point(); 01798 run = run->next; 01799 eCoord &C = *run->Point(); 01800 ePoint* pC = run->Point(); 01801 01802 // now, C is the point opposite to the longest edge. 01803 eCoord MoveDir = (B-A); 01804 MoveDir = MoveDir.Turn(0, -area * 1.01/MoveDir.NormSquared() ); 01805 01806 // move C as little as possible into the desired direction 01807 if ( MoveDir.NormSquared() > 0 ) 01808 { 01809 eCoord Cnew = C + MoveDir; 01810 01811 while ( Cnew.x == C.x && Cnew.y == C.y ) 01812 { 01813 // try displacing by MoveDir and enlarge MoveDir 01814 Cnew = C + MoveDir; 01815 MoveDir = MoveDir * 2; 01816 } 01817 01818 // clamp the movement so it does not make the situation worse 01819 // for other faces 01820 ClampMovement( pC, MoveDir ); 01821 01822 // store result 01823 C = C + MoveDir; 01824 } 01825 else // give up 01826 return false; 01827 01828 REAL newarea = edge->next->Vec() * edge->Vec(); 01829 tASSERT(newarea >= area); 01830 01831 // check if treatment was successful 01832 return newarea > area; 01833 }
eReplacementStorage & eFace::GetReplacementStorage | ( | ) | const |
Definition at line 407 of file eGrid.cpp.
References replacementStorage, and tNEW.
Referenced by se_FindBestReplacement().
00408 { 00409 if ( !replacementStorage ) 00410 replacementStorage = tNEW( eReplacementStorage ); 00411 00412 return *replacementStorage; 00413 }
friend class tReferencable< eFace > [friend] |
Definition at line 339 of file eTess2.h.
Referenced by Create(), eGrid::ProcessWallsInRange(), and ProcessWallsRecursive().
eReplacementStorage* eFace::replacementStorage [mutable, private] |