📄 mesh.h
字号:
ASSERT ( pEdgeProx->pEdgeProx == pedge );
pEdgeProx->pEdgeProx = this;
pedge->pEdgeProx = NULL;
}
return TRUE;
}
else if ( ( pTri21 == NULL ) && ( pedge->pTri12 == NULL ) &&
( ( pEdgeProx == NULL ) || ( pedge->pEdgeProx == NULL ) ) )
{
// Merge them.
pTri21 = pedge->pTri21;
if ( pTri21 != NULL )
{
if ( pTri21->pEdge12 == pedge )
{
pTri21->pEdge12 = this;
}
else if ( pTri21->pEdge23 == pedge )
{
pTri21->pEdge23 = this;
}
else
{
ASSERT ( pTri21->pEdge31 == pedge );
pTri21->pEdge31 = this;
}
}
pedge->pTri21 = NULL;
if ( pedge->pEdgeProx != NULL )
{
ASSERT ( pEdgeProx == NULL );
pEdgeProx = pedge->pEdgeProx;
ASSERT ( pEdgeProx->pEdgeProx == pedge );
pEdgeProx->pEdgeProx = this;
pedge->pEdgeProx = NULL;
}
return TRUE;
}
else
{
// Nope - they don't match.
return ( FALSE );
}
}
else
{
ASSERT ( pPt1 == pedge->pPt2 );
ASSERT ( pPt2 == pedge->pPt1 );
if ( ( pTri12 == NULL ) && ( pedge->pTri12 == NULL ) &&
( ( pEdgeProx == NULL ) || ( pedge->pEdgeProx == NULL ) ) )
{
// Merge them.
pTri12 = pedge->pTri21;
if ( pTri12 != NULL )
{
if ( pTri12->pEdge12 == pedge )
{
pTri12->pEdge12 = this;
}
else if ( pTri12->pEdge23 == pedge )
{
pTri12->pEdge23 = this;
}
else
{
ASSERT ( pTri12->pEdge31 == pedge );
pTri12->pEdge31 = this;
}
}
pedge->pTri21 = NULL;
if ( pedge->pEdgeProx != NULL )
{
ASSERT ( pEdgeProx == NULL );
pEdgeProx = pedge->pEdgeProx;
ASSERT ( pEdgeProx->pEdgeProx == pedge );
pEdgeProx->pEdgeProx = this;
pedge->pEdgeProx = NULL;
}
return TRUE;
}
else if ( ( pTri21 == NULL ) && ( pedge->pTri21 == NULL ) &&
( ( pEdgeProx == NULL ) || ( pedge->pEdgeProx == NULL ) ) )
{
// Merge them.
pTri21 = pedge->pTri12;
if ( pTri21 != NULL )
{
if ( pTri21->pEdge12 == pedge )
{
pTri21->pEdge12 = this;
}
else if ( pTri21->pEdge23 == pedge )
{
pTri21->pEdge23 = this;
}
else
{
ASSERT ( pTri21->pEdge31 == pedge );
pTri21->pEdge31 = this;
}
}
pedge->pTri12 = NULL;
if ( pedge->pEdgeProx != NULL )
{
ASSERT ( pEdgeProx == NULL );
pEdgeProx = pedge->pEdgeProx;
ASSERT ( pEdgeProx->pEdgeProx == pedge );
pEdgeProx->pEdgeProx = this;
pedge->pEdgeProx = NULL;
}
return TRUE;
}
else
{
// Nope - they don't match.
return ( FALSE );
}
}
}
inline MeshEdge *MeshEdge::QueryList ( void )
{
MeshEdge *pListRoot = ListFindFirst();
if ( pListRoot == this )
{
ASSERT ( ListFindLast() == this );
pListRoot = NULL;
}
return ( pListRoot );
}
inline void MeshEdge::SetList ( MeshEdge *pListRoot )
{
ListDel();
if ( pListRoot != NULL )
{
ListAddAfter ( pListRoot );
}
}
// Makes these two edges prox.
// The point prox data must agree.
// Returns TRUE on success, or FALSE if it failed.
inline bool MeshEdge::AddProx ( MeshEdge *pEdge )
{
ASSERT ( pEdge != NULL );
if ( pEdgeProx != NULL )
{
// Already got prox.
return ( FALSE );
}
else if ( pEdge->pEdgeProx != NULL )
{
// Already got prox.
return ( FALSE );
}
else
{
// Check that the pts agree.
// Either pPt1<->pPt1 and pPt2<->pPt2, or the other way round.
if ( pEdge->pPt1->CheckProx ( pPt1 ) )
{
if ( !pEdge->pPt2->CheckProx ( pPt2 ) )
{
return ( FALSE );
}
}
else if ( pEdge->pPt1->CheckProx ( pPt2 ) )
{
if ( !pEdge->pPt2->CheckProx ( pPt1 ) )
{
return ( FALSE );
}
}
else
{
return ( FALSE );
}
// OK, must have passed.
pEdgeProx = pEdge;
pEdge->pEdgeProx = this;
return ( TRUE );
}
}
// Find the proximity edge, if any.
// Relies on the point proximity values having been set up.
// If one is found, it is returned.
inline MeshEdge *MeshEdge::DoProxMatch ( void )
{
// Loop through all the prox pts to pPt1
// Loop through all their edges.
// If the other pt is prox to pPt2, then we found a prox edge.
int i;
MeshPt **ppPt = pPt1->ProxPtList.Ptr();
for ( i = 0; i < pPt1->ProxPtList.Size(); i++ )
{
MeshPt *pPtProx = ppPt[i];
ASSERT ( pPtProx != NULL );
MeshEdge *pEdgeOther = pPtProx->FirstEdge();
while ( pEdgeOther != NULL )
{
MeshPt *pPtOther = pEdgeOther->OtherPt ( pPtProx );
if ( pPtOther->CheckProx ( pPt2 ) )
{
// Yes - this is prox.
bool bRes = AddProx ( pEdgeOther );
if ( bRes )
{
pPtProx->EndEdge();
return pEdgeOther;
}
else
{
// Too many edges trying to be prox!
pPtProx->EndEdge();
return NULL;
}
}
pEdgeOther = pPtProx->NextEdge();
}
}
return NULL;
}
// Removes any edge prox data.
// Returns TRUE if there was some.
// The pt prox data can still agree - it is not touched.
inline bool MeshEdge::RemoveProx ( void )
{
if ( pEdgeProx == NULL )
{
return ( FALSE );
}
else
{
ASSERT ( pEdgeProx->pEdgeProx == this );
pEdgeProx->pEdgeProx = NULL;
pEdgeProx = NULL;
return ( TRUE );
}
}
inline bool MeshEdge::ConsistencyCheck ( MeshPt *pPtRoot, MeshEdge *pEdgeRoot, MeshTri *pTriRoot )
{
bool bRes = TRUE;
if ( ( pEdgeRoot != NULL ) && ( QueryList() != pEdgeRoot ) )
{
FAIL_CHECK();
}
if ( pEdgeProx != NULL )
{
if ( pEdgeProx->pEdgeProx != this )
{
FAIL_CHECK();
}
if ( ( pEdgeRoot != NULL ) && ( pEdgeProx->QueryList() != pEdgeRoot ) )
{
FAIL_CHECK();
}
// Either pPt1<->pPt1 and pPt2<->pPt2, or the other way round.
if ( pEdgeProx->pPt1->CheckProx ( pPt1 ) )
{
if ( !pEdgeProx->pPt2->CheckProx ( pPt2 ) )
{
FAIL_CHECK();
}
}
else if ( pEdgeProx->pPt1->CheckProx ( pPt2 ) )
{
if ( !pEdgeProx->pPt2->CheckProx ( pPt1 ) )
{
FAIL_CHECK();
}
}
else
{
FAIL_CHECK();
}
}
if ( pTri12 != NULL )
{
if ( ( pTriRoot != NULL ) && ( pTri12->QueryList() != pTriRoot ) )
{
FAIL_CHECK();
}
if ( pTri12->pEdge12 == this )
{
if ( ( pTri12->pPt1 != pPt1 ) || ( pTri12->pPt2 != pPt2 ) )
{
FAIL_CHECK();
}
}
else if ( pTri12->pEdge23 == this )
{
if ( ( pTri12->pPt2 != pPt1 ) || ( pTri12->pPt3 != pPt2 ) )
{
FAIL_CHECK();
}
}
else if ( pTri12->pEdge31 == this )
{
if ( ( pTri12->pPt3 != pPt1 ) || ( pTri12->pPt1 != pPt2 ) )
{
FAIL_CHECK();
}
}
else
{
FAIL_CHECK();
}
}
if ( pTri21 != NULL )
{
if ( ( pTriRoot != NULL ) && ( pTri21->QueryList() != pTriRoot ) )
{
FAIL_CHECK();
}
if ( pTri21->pEdge12 == this )
{
if ( ( pTri21->pPt1 != pPt2 ) || ( pTri21->pPt2 != pPt1 ) )
{
FAIL_CHECK();
}
}
else if ( pTri21->pEdge23 == this )
{
if ( ( pTri21->pPt2 != pPt2 ) || ( pTri21->pPt3 != pPt1 ) )
{
FAIL_CHECK();
}
}
else if ( pTri21->pEdge31 == this )
{
if ( ( pTri21->pPt3 != pPt2 ) || ( pTri21->pPt1 != pPt1 ) )
{
FAIL_CHECK();
}
}
else
{
FAIL_CHECK();
}
}
if ( ( pPt1 == NULL ) || ( pPt2 == NULL ) )
{
FAIL_CHECK();
}
else
{
if ( pPtRoot != NULL )
{
if ( pPt1->QueryList() != pPtRoot )
{
FAIL_CHECK();
}
if ( pPt2->QueryList() != pPtRoot )
{
FAIL_CHECK();
}
}
#if 0
if ( pPt1->FindEdge ( pPt2 ) != this )
{
FAIL_CHECK();
}
if ( pPt2->FindEdge ( pPt1 ) != this )
{
FAIL_CHECK();
}
#endif
// Should update to use FirstTri/NextTri until a verdict is reached.
#if 0
// Note that pTri12 can be NULL, but if and only if
// the FindTri is NULL, so this is a valid test.
// Either both are NULL, or both are the same.
if ( pPt1->FindTri ( pPt2 ) != pTri12 )
{
FAIL_CHECK();
}
if ( pPt2->FindTri ( pPt1 ) != pTri21 )
{
FAIL_CHECK();
}
#endif
}
return ( bRes );
}
inline MeshPt::MeshPt ( MeshPt *pListRoot )
{
iCurEdgeNum = -1;
iCurTriNum = -1;
iCurProxNum = -1;
ListInit();
if ( pListRoot != NULL )
{
ListAddAfter ( pListRoot );
}
}
inline MeshPt::~MeshPt ( void )
{
#if !MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_TRIS || !MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_EDGES
int i;
#endif
// Can't just do a simple loop - RemoveProx modifies the list.
while ( ProxPtList.Size() > 0 )
{
bool bRes = RemoveProx ( ProxPtList.Ptr()[0] );
ASSERT ( bRes );
}
#if MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_TRIS
// Should not be any tris.
ASSERT ( TriList.Size() == 0 );
#else
MeshTri **ppTri = TriList.Ptr();
for ( i = 0; i < TriList.Size(); i++ )
{
ASSERT ( ppTri[i] != NULL );
ppTri[i]->RemovePt ( this );
}
#endif
#if MESHCTRL_PTS_ALWAYS_ADDED_BEFORE_EDGES
// Should not be any edges.
ASSERT ( EdgeList.Size() == 0 );
#else
MeshEdge **ppEdge = EdgeList.Ptr();
for ( i = 0; i < EdgeList.Size(); i++ )
{
ASSERT ( ppEdge[i] != NULL );
ppEdge[i]->RemovePt ( this );
}
#endif
ListDel();
}
inline void MeshPt::RemoveEdge ( MeshEdge *pEdge )
{
ASSERT ( pEdge != NULL );
MeshEdge **ppEdgeList = EdgeList.Ptr();
int i;
for ( i = 0; i < EdgeList.Size(); i++ )
{
if ( ppEdgeList[i] == pEdge )
{
break;
}
}
ASSERT ( i < EdgeList.Size() );
// Bin this entry.
EdgeList.RemoveItem ( i );
}
inline void MeshPt::RemoveTri ( MeshTri *pTri )
{
ASSERT ( pTri != NULL );
MeshTri **ppTriList = TriList.Ptr();
int i;
for ( i = 0; i < TriList.Size(); i++ )
{
if ( ppTriList[i] == pTri )
{
break;
}
}
ASSERT ( i < TriList.Size() );
// Bin this entry with the last entry.
TriList.RemoveItem ( i );
}
inline void MeshPt::AddTri ( MeshTri *pTri )
{
ASSERT ( pTri != NULL );
#ifdef DEBUG
// Make sure this hasn't been added already.
MeshTri **ppTriList = TriList.Ptr();
int i;
for ( i = 0; i < TriList.Size(); i++ )
{
ASSERT ( ppTriList[i] != NULL );
ASSERT ( ppTriList[i] != pTri );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -