eFace Class Reference

#include <eTess2.h>

Inheritance diagram for eFace:

Inheritance graph
[legend]
Collaboration diagram for eFace:

Collaboration graph
[legend]

List of all members.

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
eFaceFindReplacement (const eCoord &coord, const eCoord &direction, const eCoord &lastDirection) const
eFaceFindReplacement (const eCoord &coord, const eCoord &direction) const
eFaceFindReplacement (const eCoord &coord) const
bool CorrectArea ()
eReplacementStorageGetReplacementStorage () const

Public Attributes

eFacenextProcessed

Private Member Functions

 ~eFace ()

Private Attributes

eReplacementStoragereplacementStorage

Friends

class tReferencable< eFace >


Detailed Description

Definition at line 284 of file eTess2.h.


Constructor & Destructor Documentation

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 }

Here is the call graph for this function:

eFace::eFace ( eHalfEdge a,
eHalfEdge b,
eHalfEdge c 
)

Definition at line 465 of file eGrid.cpp.

References Create().

00466         :replacementStorage( 0 )
00467 {
00468     Create( e1, e2, e3 );
00469 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:


Member Function Documentation

void eFace::Create ( eHalfEdge a,
eHalfEdge b,
eHalfEdge c 
)

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

bool eFace::Check (  )  [inline]

Definition at line 304 of file eTess2.h.

References eDual::Check().

00304 {return eDual::Check(1);}

Here is the call graph for this function:

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() << "]"; }

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

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 }

Here is the call graph for this function:

Here is the caller graph for this function:

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 }

Here is the caller graph for this function:


Friends And Related Function Documentation

friend class tReferencable< eFace > [friend]

Definition at line 285 of file eTess2.h.


Member Data Documentation

eFace* eFace::nextProcessed

Definition at line 339 of file eTess2.h.

Referenced by Create(), eGrid::ProcessWallsInRange(), and ProcessWallsRecursive().

eReplacementStorage* eFace::replacementStorage [mutable, private]

Definition at line 352 of file eTess2.h.

Referenced by GetReplacementStorage(), and ~eFace().


The documentation for this class was generated from the following files:
Generated on Sat Mar 15 23:22:34 2008 for Armagetron Advanced by  doxygen 1.5.4