Esempio n. 1
0
//----------------------------------------------------------------------------
void MTMesh::AttachTriangleToEdge (int t, MTTriangle& triangle, int i, int e,
                                   MTEdge& edge)
{
	if (edge.Triangle(0) == -1)
	{
		edge.Triangle(0) = t;
	}
	else
	{
		int a = edge.Triangle(0);
		MTTriangle& adjacent = mTriangles[a];
		triangle.Adjacent(i) = a;
		for (int j = 0; j < 3; ++j)
		{
			if (adjacent.Edge(j) == e)
			{
				adjacent.Adjacent(j) = t;
				break;
			}
		}

		if (edge.Triangle(1) == -1)
		{
			edge.Triangle(1) = t;
		}
		else
		{
			assertion(false, "The mesh is not manifold.\n");
		}
	}

	triangle.Edge(i) = e;
}
Esempio n. 2
0
//----------------------------------------------------------------------------
void MTMesh::AttachTriangleToEdge (int iT, MTTriangle& rkT, int i, int iE,
    MTEdge& rkE)
{
    if ( rkE.Triangle(0) == -1 )
    {
        rkE.Triangle(0) = iT;
    }
    else
    {
        int iTAdj = rkE.Triangle(0);
        MTTriangle& rkTAdj = m_akTriangle[iTAdj];
        rkT.Adjacent(i) = iTAdj;
        for (int j = 0; j < 3; j++)
        {
            if ( rkTAdj.Edge(j) == iE )
            {
                rkTAdj.Adjacent(j) = iT;
                break;
            }
        }

        if ( rkE.Triangle(1) == -1 )
        {
            rkE.Triangle(1) = iT;
        }
        else
        {
            // mesh is not manifold
            assert( false );
        }
    }

    rkT.Edge(i) = iE;
}
Esempio n. 3
0
//----------------------------------------------------------------------------
void MTMesh::DetachTriangleFromEdge (int t, MTTriangle& triangle, int i,
                                     int e, MTEdge& edge)
{
	// This function leaves T only partially complete.  The edge E is no
	// longer referenced by T, even though the vertices of T reference the
	// end points of E.  If T has an adjacent triangle A that shares E, then
	// A is a complete triangle.

	if (edge.Triangle(0) == t)
	{
		int a = edge.Triangle(1);
		if (a != -1)
		{
			// T and TAdj share E, update adjacency information for both
			MTTriangle& adjacent = mTriangles[a];
			for (int j = 0; j < 3; ++j)
			{
				if (adjacent.Edge(j) == e)
				{
					adjacent.Adjacent(j) = -1;
					break;
				}
			}
		}
		edge.Triangle(0) = a;
	}
	else if (edge.Triangle(1) == t)
	{
		// T and TAdj share E, update adjacency information for both
		MTTriangle& adjacent = mTriangles[edge.Triangle(0)];
		for (int j = 0; j < 3; ++j)
		{
			if (adjacent.Edge(j) == e)
			{
				adjacent.Adjacent(j) = -1;
				break;
			}
		}
	}
	else
	{
		// Should not get here.  The specified edge must share the input
		// triangle.
		assertion(false, "Unexpected condition.\n");
	}

	edge.Triangle(1) = -1;
	triangle.Edge(i) = -1;
	triangle.Adjacent(i) = -1;
}
Esempio n. 4
0
//----------------------------------------------------------------------------
void MTMesh::DetachTriangleFromEdge (int iT, MTTriangle& rkT, int i, int iE,
    MTEdge& rkE)
{
    // This function leaves T only partially complete.  The edge E is no
    // longer referenced by T, even though the vertices of T reference the
    // end points of E.  If T has an adjacent triangle A that shares E, then
    // A is a complete triangle.

    if ( rkE.Triangle(0) == iT )
    {
        int iTAdj = rkE.Triangle(1);
        if ( iTAdj != -1 )
        {
            // T and TAdj share E, update adjacency information for both
            MTTriangle& rkTAdj = m_akTriangle[iTAdj];
            for (int j = 0; j < 3; j++)
            {
                if ( rkTAdj.Edge(j) == iE )
                {
                    rkTAdj.Adjacent(j) = -1;
                    break;
                }
            }
        }
        rkE.Triangle(0) = iTAdj;
    }
    else if ( rkE.Triangle(1) == iT )
    {
        // T and TAdj share E, update adjacency information for both
        MTTriangle& rkTAdj = m_akTriangle[rkE.Triangle(0)];
        for (int j = 0; j < 3; j++)
        {
            if ( rkTAdj.Edge(j) == iE )
            {
                rkTAdj.Adjacent(j) = -1;
                break;
            }
        }
    }
    else
    {
        // Should not get here.  The specified edge must share the input
        // triangle.
        assert( false );
    }

    rkE.Triangle(1) = -1;
    rkT.Edge(i) = -1;
    rkT.Adjacent(i) = -1;
}
//----------------------------------------------------------------------------
void ConvexPolyhedron::ComputeTerminator (const Vector3& rkEye,
        vector<Vector3>& rkTerminator)
{
    // temporary storage for signed distances from eye to triangles
    int iTQuantity = m_akTriangle.GetQuantity();
    vector<Real> afDistance(iTQuantity);
    int i, j;
    for (i = 0; i < iTQuantity; i++)
        afDistance[i] = Math::MAX_REAL;

    // Start a search for a front-facing triangle that has an adjacent
    // back-facing triangle or for a back-facing triangle that has an
    // adjacent front-facing triangle.
    int iTCurrent = 0;
    MTTriangle* pkTCurrent = &m_akTriangle[iTCurrent];
    Real fTriDist = GetDistance(rkEye,iTCurrent,afDistance);
    int iEFirst = -1;
    for (i = 0; i < iTQuantity; i++)
    {
        // Check adjacent neighbors for edge of terminator.  Such an
        // edge occurs if the signed distance changes sign.
        int iMinIndex = -1;
        Real fMinAbsDist = Math::MAX_REAL;
        Real afAdjDist[3];
        for (j = 0; j < 3; j++)
        {
            afAdjDist[j] = GetDistance(rkEye,pkTCurrent->Adjacent(j),
                                       afDistance);
            if ( IsNegativeProduct(fTriDist,afAdjDist[j]) )
            {
                iEFirst = pkTCurrent->Edge(j);
                break;
            }

            Real fAbsDist = Math::FAbs(afAdjDist[j]);
            if ( fAbsDist < fMinAbsDist )
            {
                fMinAbsDist = fAbsDist;
                iMinIndex = j;
            }
        }
        if ( j < 3 )
            break;

        // First edge not found during this iteration.  Move to adjacent
        // triangle whose distance is smallest of all adjacent triangles.
        iTCurrent = pkTCurrent->Adjacent(iMinIndex);
        pkTCurrent = &m_akTriangle[iTCurrent];
        fTriDist = afAdjDist[iMinIndex];
    }
    assert( i < iTQuantity );

    MTEdge& rkEFirst = m_akEdge[iEFirst];
    rkTerminator.push_back(m_akPoint[GetVLabel(rkEFirst.Vertex(0))]);
    rkTerminator.push_back(m_akPoint[GetVLabel(rkEFirst.Vertex(1))]);

    // walk along the terminator
    int iVFirst = rkEFirst.Vertex(0);
    int iV = rkEFirst.Vertex(1);
    int iE = iEFirst;
    int iEQuantity = m_akEdge.GetQuantity();
    for (i = 0; i < iEQuantity; i++)
    {
        // search all edges sharing the vertex for another terminator edge
        int j, jMax = m_akVertex[iV].GetEdgeQuantity();
        for (j = 0; j < m_akVertex[iV].GetEdgeQuantity(); j++)
        {
            int iENext = m_akVertex[iV].GetEdge(j);
            if ( iENext == iE )
                continue;

            Real fDist0 = GetDistance(rkEye,m_akEdge[iENext].GetTriangle(0),
                                      afDistance);
            Real fDist1 = GetDistance(rkEye,m_akEdge[iENext].GetTriangle(1),
                                      afDistance);
            if ( IsNegativeProduct(fDist0,fDist1) )
            {
                if ( m_akEdge[iENext].GetVertex(0) == iV )
                {
                    iV = m_akEdge[iENext].GetVertex(1);
                    rkTerminator.push_back(m_akPoint[GetVLabel(iV)]);
                    if ( iV == iVFirst )
                        return;
                }
                else
                {
                    iV = m_akEdge[iENext].GetVertex(0);
                    rkTerminator.push_back(m_akPoint[GetVLabel(iV)]);
                    if ( iV == iVFirst )
                        return;
                }

                iE = iENext;
                break;
            }
        }
        assert( j < jMax );
    }
    assert( i < iEQuantity );
}