void EdgeAdjacency::CreateTriangle(int32 startingI)
{
	int32 i = startingI;

	int32 i0, i1, i2;
	polygonGroup->GetIndex(i, i0);
	polygonGroup->GetIndex(i+1, i1);
	polygonGroup->GetIndex(i+2, i2);

	Vector3 p0, p1, p2;
	polygonGroup->GetCoord(i0, p0);
	polygonGroup->GetCoord(i1, p1);
	polygonGroup->GetCoord(i2, p2);

	Edge edge0;
	FillEdge(edge0, i0, i1);
	int32 edgeIndex0 = GetEdgeIndex(edge0);

	Edge edge1;
	FillEdge(edge1, i1, i2);
	int32 edgeIndex1 = GetEdgeIndex(edge1);

	Edge edge2;
	FillEdge(edge2, i2, i0);
	int32 edgeIndex2 = GetEdgeIndex(edge2);

	TriangleData triangleData;
	triangleData.i0 = i0;
	triangleData.i1 = i1;
	triangleData.i2 = i2;

	if(edges[edgeIndex0].sharedTriangles.size() < 2)
	{
		edges[edgeIndex0].sharedTriangles.push_back(triangleData);
	}
	if(edges[edgeIndex1].sharedTriangles.size() < 2)
	{
		edges[edgeIndex1].sharedTriangles.push_back(triangleData);
	}
	if(edges[edgeIndex2].sharedTriangles.size() < 2)
	{
		edges[edgeIndex2].sharedTriangles.push_back(triangleData);
	}
}
Beispiel #2
0
int IRefiner::
get_local_edge_mark(Face* f, Edge* e) const
{
	const int edgeInd = GetEdgeIndex(f, e);
	UG_COND_THROW(edgeInd == -1, "Given edge is not an edge of the given face.");

	if(marked_local(f)){
		const int faceLocalMark = get_local_mark(f);
		return (faceLocalMark >> edgeInd) & 1;
	}
	else if(marked_full(f)){
Beispiel #3
0
	void HACD::CreateGraph()
    {
		// vertex to triangle adjacency information
		std::vector< std::set<long> >  vertexToTriangles;
		vertexToTriangles.resize(m_nPoints);
		for(size_t t = 0; t < m_nTriangles; ++t)
		{
			vertexToTriangles[m_triangles[t].X()].insert(static_cast<long>(t));
			vertexToTriangles[m_triangles[t].Y()].insert(static_cast<long>(t));
			vertexToTriangles[m_triangles[t].Z()].insert(static_cast<long>(t));
		}

		m_graph.Clear();
		m_graph.Allocate(m_nTriangles, 5 * m_nTriangles);
		unsigned long long tr1[3];
		unsigned long long tr2[3];
        long i1, j1, k1, i2, j2, k2;
        long t1, t2;
        for (size_t v = 0; v < m_nPoints; v++)
		{
			std::set<long>::const_iterator it1(vertexToTriangles[v].begin()), itEnd(vertexToTriangles[v].end());
			for(; it1 != itEnd; ++it1)
			{
                t1 = *it1;
                i1 = m_triangles[t1].X();
                j1 = m_triangles[t1].Y();
                k1 = m_triangles[t1].Z();
				tr1[0] = GetEdgeIndex(i1, j1);
				tr1[1] = GetEdgeIndex(j1, k1);
				tr1[2] = GetEdgeIndex(k1, i1);
				std::set<long>::const_iterator it2(it1);
				for(++it2; it2 != itEnd; ++it2)
				{
                    t2 = *it2;
                    i2 = m_triangles[t2].X();
                    j2 = m_triangles[t2].Y();
                    k2 = m_triangles[t2].Z();
					tr2[0] = GetEdgeIndex(i2, j2);
					tr2[1] = GetEdgeIndex(j2, k2);
					tr2[2] = GetEdgeIndex(k2, i2);
					int shared = 0;
					for(int i = 0; i < 3; ++i)
					{
						for(int j = 0; j < 3; ++j)
						{
							if (tr1[i] == tr2[j])
							{
								shared++;
							}
						}
					}
					if (shared == 1) // two triangles are connected if they share exactly one edge
					{
						m_graph.AddEdge(t1, t2);
					}
				}
			}
        }
        if (m_ccConnectDist >= 0.0)
        {
            m_graph.ExtractCCs();
            if (m_callBack)
            {
                char msg[1024];
                sprintf(msg, "nCC %lu\n", static_cast<long unsigned int>(m_graph.m_nCCs));
                (*m_callBack)(msg, 0.0, 0.0,  m_graph.GetNVertices());

            }

            if (m_graph.m_nCCs > 1)
            {
                std::vector< std::set<long> > cc2V;
                cc2V.resize(m_graph.m_nCCs);
                long cc;
                for(size_t t = 0; t < m_nTriangles; ++t)
                {
                    cc = m_graph.m_vertices[t].m_cc;
                    cc2V[cc].insert(m_triangles[t].X());
                    cc2V[cc].insert(m_triangles[t].Y());
                    cc2V[cc].insert(m_triangles[t].Z());
                }

                for(size_t cc1 = 0; cc1 < m_graph.m_nCCs; ++cc1)
                {
                    for(size_t cc2 = cc1+1; cc2 < m_graph.m_nCCs; ++cc2)
                    {
                        std::set<long>::const_iterator itV1(cc2V[cc1].begin()), itVEnd1(cc2V[cc1].end());
                        for(; itV1 != itVEnd1; ++itV1)
                        {
							double distC1C2 = std::numeric_limits<double>::max();
                            double dist;
                            t1 = -1;
                            t2 = -1;
                            std::set<long>::const_iterator itV2(cc2V[cc2].begin()), itVEnd2(cc2V[cc2].end());
                            for(; itV2 != itVEnd2; ++itV2)
                            {
                                dist = (m_points[*itV1] - m_points[*itV2]).GetNorm();
                                if (dist < distC1C2)
                                {
                                    distC1C2 = dist;
                                    t1 = *vertexToTriangles[*itV1].begin();

									std::set<long>::const_iterator it2(vertexToTriangles[*itV2].begin()),
																   it2End(vertexToTriangles[*itV2].end());
									t2 = -1;
									for(; it2 != it2End; ++it2)
									{
										if (*it2 != t1)
										{
											t2 = *it2;
											break;
										}
									}
                                }
                            }
                            if (distC1C2 <= m_ccConnectDist && t1 >= 0 && t2 >= 0)
                            {
                                m_graph.AddEdge(t1, t2);
                            }
                        }
                    }
                }
            }
        }
    }
Beispiel #4
0
    void HACD::InitializeDualGraph()
    {
        long i, j, k;
        Vec3<Real> u, v, w, normal;
		delete [] m_normals;
		m_normals = new Vec3<Real>[m_nPoints];
        if (m_addFacesPoints)
        {
            delete [] m_facePoints;
            delete [] m_faceNormals;

			m_facePoints = new Vec3<Real>[m_nTriangles];
            m_faceNormals = new Vec3<Real>[m_nTriangles];
/*
            m_facePoints = new Vec3<Real>[4*m_nTriangles];
            m_faceNormals = new Vec3<Real>[4*m_nTriangles];
*/
        }
		memset(m_normals, 0, sizeof(Vec3<Real>) * m_nPoints);

        RaycastMesh rm;
        if (m_addExtraDistPoints)
        {
            rm.Initialize(m_nPoints, m_nTriangles, m_points, m_triangles, 15);
            m_extraDistPoints = new Vec3<Real>[m_nTriangles];
            m_extraDistNormals = new Vec3<Real>[m_nTriangles];
        }
        double progressOld = -1.0;
        double progress = 0.0;
		char msg[1024];
		double ptgStep = 1.0;
		m_area = 0.0;
		for(unsigned long f = 0; f < m_nTriangles; f++)
        {
            progress = f * 100.0 / m_nTriangles;
            if (fabs(progress-progressOld) > ptgStep && m_callBack)
            {
				sprintf(msg, "%3.2f %% \t \t \r", progress);
				(*m_callBack)(msg, progress, 0.0,  m_nTriangles);
                progressOld = progress;
            }

			i = m_triangles[f].X();
            j = m_triangles[f].Y();
            k = m_triangles[f].Z();
			m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(i, 0, false, false));
			m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(j, 0, false, false));
			m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(k, 0, false, false));

            ICHull  * ch = new ICHull(m_heapManager);
            m_graph.m_vertices[f].m_convexHull = ch;
            ch->AddPoint(m_points[i], i);
            ch->AddPoint(m_points[j], j);
            ch->AddPoint(m_points[k], k);
			ch->SetDistPoints(0);

			u = m_points[j] - m_points[i];
			v = m_points[k] - m_points[i];
			w = m_points[k] - m_points[j];
			normal = u ^ v;

			m_normals[i] += normal;
			m_normals[j] += normal;
			m_normals[k] += normal;

			m_graph.m_vertices[f].m_surf = normal.GetNorm();
			m_area += m_graph.m_vertices[f].m_surf;
            normal.Normalize();
			m_graph.m_vertices[f].m_boudaryEdges.Insert(GetEdgeIndex(i,j));
			m_graph.m_vertices[f].m_boudaryEdges.Insert(GetEdgeIndex(j,k));
			m_graph.m_vertices[f].m_boudaryEdges.Insert(GetEdgeIndex(k,i));
            if(m_addFacesPoints)
            {
                m_faceNormals[f] = normal;
                m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0;
				m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(-static_cast<long>(f)-1, 0, false, true));
            }
        }

		// Now we have all the points in the KD tree, optimize the distance points insertion by running them in parallel
		// if possible.
		if (m_addExtraDistPoints)
        {
			if (m_callBack)
				(*m_callBack)("++ Also adding distance points\n", 0.0, 0.0, 0);

	        progressOld = -1.0;
			progress = 0.0;
			long completed = 0;

#ifdef THREAD_DIST_POINTS
#pragma omp parallel for
#endif
			for(long f = 0; f < (long)m_nTriangles; f++)
			{
				Vec3<Real> seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0);
				Vec3<Real> hitPoint;
				Vec3<Real> hitNormal;
				normal = -normal;
                size_t faceIndex = m_nTriangles;

				Float dist;
				long hitTriangle;
				if (rm.Raycast(seedPoint,normal,hitTriangle,dist, hitPoint, hitNormal))
				{
					faceIndex = hitTriangle;
				}

                if (faceIndex < m_nTriangles )
                {
					m_extraDistPoints[f] = hitPoint;
					m_extraDistNormals[f] = hitNormal;
					m_graph.m_vertices[f].m_distPoints.PushBack(DPoint(m_nPoints+f, 0, false, true));
				}

				// Atomic update of the progress
				#ifdef THREAD_DIST_POINTS
				#pragma omp critical
				#endif
				{
					completed++;

					progress = completed * 100.0 / m_nTriangles;
					if (fabs(progress-progressOld) > ptgStep && m_callBack)
					{
						sprintf(msg, "%3.2f %% \t \t \r", progress);
						(*m_callBack)(msg, progress, 0.0,  m_nTriangles);
						progressOld = progress;
					}
				}
			}
		}

        for (size_t v = 0; v < m_nPoints; v++)
		{
			m_normals[v].Normalize();
		}
    }
Beispiel #5
0
StrBuf* GenLynxSprite (const Bitmap* B, const Collection* A)
/* Generate binary output in Lynx sprite format for the bitmap B. The output
 * is stored in a string buffer (which is actually a dynamic char array) and
 * returned.
 *
 * The Lynx will draw 4 quadrants:
 * - Down right
 * - Up right
 * - Up left
 * - Down left
 *
 * The sprite will end with a byte 0.
 */
{
    enum Mode M;
    StrBuf* D;
    signed X, Y;
    unsigned OX, OY;
    char ColorBits;
    char ColorMask;
    char EdgeIndex;

    /* Get EdgeIndex */
    EdgeIndex = GetEdgeIndex (A);

    /* Action point of the sprite */
    OX = GetActionPointX (A);
    OY = GetActionPointY (A);
    if (OX >= GetBitmapWidth (B)) {
        Error ("Action point X cannot be larger than bitmap width");
    }
    if (OY >= GetBitmapHeight (B)) {
        Error ("Action point Y cannot be larger than bitmap height");
    }
    printf("OX = %d OY = %d\n", OX, OY);

    /* Output the image properties */
    Print (stdout, 1, "Image is %ux%u with %u colors%s\n",
           GetBitmapWidth (B), GetBitmapHeight (B), GetBitmapColors (B),
           BitmapIsIndexed (B)? " (indexed)" : "");

    /* Get the sprite mode */
    M = GetMode (A);

    /* Now check if bitmap indexes are ok */
    if (GetBitmapColors (B) > 16) {
        Error ("Too many colors for a Lynx sprite");
    }
    ColorBits = 4;
    ColorMask = 0x0f;
    if (GetBitmapColors (B) < 9) {
        ColorBits = 3;
        ColorMask = 0x07;
    }
    if (GetBitmapColors (B) < 5) {
        ColorBits = 2;
        ColorMask = 0x03;
    }
    if (GetBitmapColors (B) < 3) {
        ColorBits = 1;
        ColorMask = 0x01;
    }

    /* Create the output buffer and resize it to the required size. */
    D = NewStrBuf ();
    SB_Realloc (D, 63);

    /* Convert the image for quadrant bottom right */
    for (Y = OY; Y < (signed)GetBitmapHeight (B); ++Y) {
        signed i = 0;
        signed LastOpaquePixel = -1;
        char LineBuffer[512]; /* The maximum size is 508 pixels */

        /* Fill the LineBuffer for easier optimisation */
        for (X = OX; X < (signed)GetBitmapWidth (B); ++X) {

            /* Fetch next bit into byte buffer */
            LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;

            if (LineBuffer[i] != EdgeIndex) {
                LastOpaquePixel = i;
            }
            ++i;
        }

        encodeSprite(D, M, ColorBits, ColorMask, LineBuffer, i, LastOpaquePixel);
    }

    if ((OY == 0) && (OX == 0)) {
        /* Trivial case only one quadrant */

        /* Mark end of sprite */
        SB_AppendChar (D, 0);

        /* Return the converted bitmap */
        return D;
    }

    /* Next quadrant */
    SB_AppendChar (D, 1);

    /* Convert the image for quadrant top right */
    for (Y = OY - 1; Y >= 0; --Y) {
        signed i = 0;
        signed LastOpaquePixel = -1;
        char LineBuffer[512]; /* The maximum size is 508 pixels */

        /* Fill the LineBuffer for easier optimisation */
        for (X = OX; X < (signed)GetBitmapWidth (B); ++X) {

            /* Fetch next bit into byte buffer */
            LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;

            if (LineBuffer[i] != EdgeIndex) {
                LastOpaquePixel = i;
            }
            ++i;
        }

        encodeSprite(D, M, ColorBits, ColorMask, LineBuffer, i, LastOpaquePixel);
    }

    if (OX == 0) {
        /* Special case only two quadrants */

        /* Mark end of sprite */
        SB_AppendChar (D, 0);

        /* Return the converted bitmap */
        return D;
    }

    /* Next quadrant */
    SB_AppendChar (D, 1);

    /* Convert the image for quadrant top left */
    for (Y = OY - 1; Y >= 0; --Y) {
        signed i = 0;
        signed LastOpaquePixel = -1;
        char LineBuffer[512]; /* The maximum size is 508 pixels */

        /* Fill the LineBuffer for easier optimisation */
        for (X = OX - 1; X >= 0; --X) {

            /* Fetch next bit into byte buffer */
            LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;

            if (LineBuffer[i] != EdgeIndex) {
                LastOpaquePixel = i;
            }
            ++i;
        }

        encodeSprite(D, M, ColorBits, ColorMask, LineBuffer, i, LastOpaquePixel);
    }

    /* Next quadrant */
    SB_AppendChar (D, 1);

    /* Convert the image for quadrant bottom left */
    for (Y = OY; Y < (signed)GetBitmapHeight (B); ++Y) {
        signed i = 0;
        signed LastOpaquePixel = -1;
        char LineBuffer[512]; /* The maximum size is 508 pixels */

        /* Fill the LineBuffer for easier optimisation */
        for (X = OX - 1; X >= 0; --X) {

            /* Fetch next bit into byte buffer */
            LineBuffer[i] = GetPixel (B, X, Y).Index & ColorMask;

            if (LineBuffer[i] != EdgeIndex) {
                LastOpaquePixel = i;
            }
            ++i;
        }

        encodeSprite(D, M, ColorBits, ColorMask, LineBuffer, i, LastOpaquePixel);
    }

    /* End sprite */
    SB_AppendChar (D, 0);

    /* Return the converted bitmap */
    return D;
}
Beispiel #6
0
    void HACD::InitializeDualGraph()
    {
        long i, j, k;
        Vec3<Real> u, v, w, normal;
		delete [] m_normals;
		m_normals = new Vec3<Real>[m_nPoints];
        if (m_addFacesPoints)
        {
            delete [] m_facePoints;
            delete [] m_faceNormals;
            m_facePoints = new Vec3<Real>[m_nTriangles];
            m_faceNormals = new Vec3<Real>[m_nTriangles];
        }
		memset(m_normals, 0, sizeof(Vec3<Real>) * m_nPoints);
        for(unsigned long f = 0; f < m_nTriangles; f++)
        {
			if (m_callBack) (*m_callBack)("+ InitializeDualGraph\n", f, m_nTriangles, 0);
			
			if (gCancelRequest)
				return;

            i = m_triangles[f].X();
            j = m_triangles[f].Y();
            k = m_triangles[f].Z();
		
			m_graph.m_vertices[f].m_distPoints[i].m_distOnly = false;
			m_graph.m_vertices[f].m_distPoints[j].m_distOnly = false;
			m_graph.m_vertices[f].m_distPoints[k].m_distOnly = false;
            
            ICHull  * ch = new ICHull;
            m_graph.m_vertices[f].m_convexHull = ch;
            ch->AddPoint(m_points[i], i);
            ch->AddPoint(m_points[j], j);
            ch->AddPoint(m_points[k], k);
			ch->SetDistPoints(&m_graph.m_vertices[f].m_distPoints);

			u = m_points[j] - m_points[i];
			v = m_points[k] - m_points[i];
			w = m_points[k] - m_points[j];
			normal = u ^ v;

			m_normals[i] += normal;
			m_normals[j] += normal;
			m_normals[k] += normal;

			m_graph.m_vertices[f].m_surf = normal.GetNorm();
			m_graph.m_vertices[f].m_perimeter = u.GetNorm() + v.GetNorm() + w.GetNorm();
            
            normal.Normalize();

			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(i,j));
			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(j,k));
			m_graph.m_vertices[f].m_boudaryEdges.insert(GetEdgeIndex(k,i));
            if(m_addFacesPoints)
            {
                m_faceNormals[f] = normal;
                m_facePoints[f] = (m_points[i] + m_points[j] + m_points[k]) / 3.0;
                m_graph.m_vertices[f].m_distPoints[-static_cast<long>(f)-1].m_distOnly = true;
            }
            if (m_addExtraDistPoints)	
            {// we need a kd-tree structure to accelerate this part!
                long i1, j1, k1;
                Vec3<Real> u1, v1, normal1;
				normal = -normal;
                double distance = 0.0;
                double distMin = 0.0;
                size_t faceIndex = m_nTriangles;
                Vec3<Real> seedPoint((m_points[i] + m_points[j] + m_points[k]) / 3.0);
                long nhit = 0;
                for(size_t f1 = 0; f1 < m_nTriangles; f1++)
                {
                    i1 = m_triangles[f1].X();
                    j1 = m_triangles[f1].Y();
                    k1 = m_triangles[f1].Z();
                    u1 = m_points[j1] - m_points[i1];
                    v1 = m_points[k1] - m_points[i1];
                    normal1 = (u1 ^ v1);
                    if (normal * normal1 > 0.0)
                    {
                        nhit = IntersectRayTriangle(Vec3<double>(seedPoint.X(), seedPoint.Y(), seedPoint.Z()),
													Vec3<double>(normal.X(), normal.Y(), normal.Z()),
													Vec3<double>(m_points[i1].X(), m_points[i1].Y(), m_points[i1].Z()),
													Vec3<double>(m_points[j1].X(), m_points[j1].Y(), m_points[j1].Z()),
													Vec3<double>(m_points[k1].X(), m_points[k1].Y(), m_points[k1].Z()),
													distance);
                        if ((nhit==1) && ((distMin > distance) || (faceIndex == m_nTriangles)))
                        {
                            distMin = distance;
                            faceIndex = f1;
                        }

                    }
                }
                if (faceIndex < m_nTriangles )
                {
                    i1 = m_triangles[faceIndex].X();
                    j1 = m_triangles[faceIndex].Y();
                    k1 = m_triangles[faceIndex].Z();
                    m_graph.m_vertices[f].m_distPoints[i1].m_distOnly = true;
                    m_graph.m_vertices[f].m_distPoints[j1].m_distOnly = true;
                    m_graph.m_vertices[f].m_distPoints[k1].m_distOnly = true;
					if (m_addFacesPoints)
					{
						m_graph.m_vertices[f].m_distPoints[-static_cast<long>(faceIndex)-1].m_distOnly = true;
					}
				}
            }
        }
        for (size_t v = 0; v < m_nPoints; v++) 
		{
			m_normals[v].Normalize();
		}
    }
Beispiel #7
0
void MakeContourFaces(Mesh * mesh, ContourPoint * v0, ContourPoint * v1, FlowLinePoint *v0child, FlowLinePoint *v1child)
{
    if (v0 == NULL || v1 == NULL || v0child == NULL || v1child == NULL ||
            v0child->stitchTarget == NULL || v1child->stitchTarget == NULL)
        return;

    // check if the flowlines cross
    if (!ParamPointCC::ConvexInChart(v0->vertex->GetData().sourceLoc, v0child->vertex->GetData().sourceLoc, v1child->vertex->GetData().sourceLoc, v1->vertex->GetData().sourceLoc))
        //  if (!ParamPointCC::SameSide(v0->vertex->GetData().sourceLoc, v0child->vertex->GetData().sourceLoc,
        //			    v1->vertex->GetData().sourceLoc, v1child->vertex->GetData().sourceLoc) &&
        //      !ParamPointCC::SameSide(v1->vertex->GetData().sourceLoc, v1child->vertex->GetData().sourceLoc,
        //			    v0->vertex->GetData().sourceLoc, v0child->vertex->GetData().sourceLoc))
    {
        printf("WARNING: CROSSING FLOWLINES/NON-CONVEX FLOWLINE QUAD\n");
        return;
    }

    assert(v0->vertex->GetData().facing == CONTOUR && v1->vertex->GetData().facing == CONTOUR &&
           v0child->vertex->GetData().facing != CONTOUR && v1child->vertex->GetData().facing != CONTOUR);

    // find the common face that they came from
    MeshFace * commonFace = NULL;
    if (v0->sourceEdge->GetLeftFace() != NULL && (v0->sourceEdge->GetLeftFace() == v1->sourceEdge->GetLeftFace() ||
            v0->sourceEdge->GetLeftFace() == v1->sourceEdge->GetRightFace()))
        commonFace = v0->sourceEdge->GetLeftFace();
    else if (v0->sourceEdge->GetRightFace() != NULL && (v0->sourceEdge->GetRightFace() == v1->sourceEdge->GetLeftFace() ||
             v0->sourceEdge->GetRightFace() == v1->sourceEdge->GetRightFace()))
        commonFace = v0->sourceEdge->GetRightFace();

    assert(commonFace != NULL);

    double v0ind = GetEdgeIndex(commonFace, v0);
    double v1ind = GetEdgeIndex(commonFace, v1);
    int v0Cind = GetVertexIndex(commonFace, v0child->stitchTarget);
    int v1Cind = GetVertexIndex(commonFace, v1child->stitchTarget);

    for(int i=0; i<4; i++)
        printf("v[%d] = %s\n", i, FacingToString(commonFace->GetVertex(i)->GetData().facing));

    assert(v0ind != v1ind);
    assert(v0Cind >= 0 && v0Cind <= 3 && v1Cind >= 0 && v1Cind <= 3);

    if (v0ind == 3.5 && v0Cind == 0)
        v0Cind = 4;
    if (v1ind == 3.5 && v1Cind == 0)
        v1Cind = 4;


    printf("v0: %08X, v1: %08X, v0ind: %f, v1ind: %f, v0Cind: %d, v1Cind: %d\n",
           v0, v1, v0ind, v1ind, v0Cind, v1Cind);

    assert(v0child->vertex->GetEdge(v1child->vertex) == NULL &&
           v1child->vertex->GetEdge(v0child->vertex) == NULL);


    if (v0ind > v0Cind)
    {
        if ( v1ind < v1Cind)
        {
            printf("A: %08X, B: %08X\n", v0->vertex->GetEdge(v1->vertex), v1->vertex->GetEdge(v0->vertex));
            NewFaceDebug(mesh, v0->vertex, v1->vertex, v1child->vertex);
            NewFaceDebug(mesh, v0->vertex, v1child->vertex, v0child->vertex);

            //	  int vIDa[3] = { v0->vertex->GetID(), v1->vertex->GetID(), v1child->vertex->GetID() };
            //	  int vIDb[3] = { v0->vertex->GetID(), v1child->vertex->GetID(), v0child->vertex->GetID() };
            //	  NewFaceDebug(mesh, 3, vIDa);
            //	  NewFaceDebug(mesh, 3, vIDb);
            //	  newFaces.push_back(FaceRec(v0->vertex, v1->vertex, v1child->vertex));
            //	  newFaces.push_back(FaceRec(v0->vertex, v1child->vertex, v0child->vertex));
        }
        else
            printf("WARNING: SKIPPING MESSED-UP TRIANGLE\n");
    }
    else
    {
        if (v1ind > v1Cind)
        {
            printf("C: %08X, D: %08X\n", v0->vertex->GetEdge(v1->vertex), v1->vertex->GetEdge(v0->vertex));
            NewFaceDebug(mesh, v1->vertex, v0->vertex, v0child->vertex);
            NewFaceDebug(mesh, v1->vertex, v0child->vertex, v1child->vertex);

            //	  int vIDa[3] = { v1->vertex->GetID(), v0->vertex->GetID(), v0child->vertex->GetID() };
            //	  int vIDb[3] = { v1->vertex->GetID(), v0child->vertex->GetID(), v1child->vertex->GetID() };
            //	  NewFaceDebug(mesh, 3, vIDa);
            //	  NewFaceDebug(mesh, 3, vIDb);
            //	  newFaces.push_back(FaceRec(v1->vertex, v0->vertex, v0child->vertex));
            //	  newFaces.push_back(FaceRec(v1->vertex, v0child->vertex, v1child->vertex));
        }
        else
            printf("WARNING: SKIPPING MESSED-UP TRIANGLE\n");
    }
}
BOOL CSSolid::SplitFaceByVertices(CSSVertex *pVertex1, CSSVertex *pVertex2)
{
	if(GetEdgeIndex(pVertex1->id, pVertex2->id) != -1)
		return FALSE;	// already an edge there!

	// find the face, first - get a list of affected edges and find
	//  two with a common face
	int iNumEdges1, iNumEdges2;
	SSHANDLE hFace = 0;
	CSSEdge *pEdges1[64], *pEdges2[64], **pTmp;

	pTmp = FindAffectedEdges(&pVertex1->id, 1, iNumEdges1);
	memcpy(pEdges1, pTmp, iNumEdges1 * sizeof(CSSEdge*));
	pTmp = FindAffectedEdges(&pVertex2->id, 1, iNumEdges2);
	memcpy(pEdges2, pTmp, iNumEdges2 * sizeof(CSSEdge*));

	for(int i = 0; i < iNumEdges1; i++)
	{
		SSHANDLE hFace0 = pEdges1[i]->Faces[0];
		SSHANDLE hFace1 = pEdges1[i]->Faces[1];
		for(int i2 = 0; i2 < iNumEdges2; i2++)
		{
			if(hFace0 == pEdges2[i2]->Faces[0] ||
				hFace0 == pEdges2[i2]->Faces[1])
			{
				hFace = hFace0;
				break;
			}
			else if(hFace1 == pEdges2[i2]->Faces[0] ||
				hFace1 == pEdges2[i2]->Faces[1])
			{
				hFace = hFace1;
				break;
			}
		}
	}

	// couldn't find a common face
	if(hFace == 0)
		return FALSE;

	CSSFace *pFace = (CSSFace*) GetHandleData(hFace);

	// create a new face
	CSSFace *pNewFace = AddFace();
	memcpy(&pNewFace->texture, &pFace->texture, sizeof(TEXTURE));

	// create a new edge between two vertices
	CSSEdge *pNewEdge = AddEdge();
	pNewEdge->hvStart = pVertex1->id;
	pNewEdge->hvEnd = pVertex2->id;
	CalcEdgeCenter(pNewEdge);

	// assign face ids to the new edge
	AssignFace(pNewEdge, pFace->id);
	AssignFace(pNewEdge, pNewFace->id);

	// set up edges - start with newvertex1 
	SSHANDLE hNewEdges[64];
	int nNewEdges;
	BOOL bFirst = TRUE;
	CSSFace *pStoreFace = pFace;

	SSHANDLE *phVertexList = CreatePointHandleList(*pFace);
	int nVertices = pFace->nEdges;

	int v1index, v2index;

	// find where the vertices are and
	//  kill face references in edges first
	for(i = 0; i < nVertices; i++)
	{
		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], 
			phVertexList[iNextVertex]);
		CSSEdge *pEdge = &m_Edges[iEdgeIndex];
		AssignFace(pEdge, pFace->id, TRUE);

		if(phVertexList[i] == pVertex1->id)
			v1index = i;
		else if(phVertexList[i] == pVertex2->id)
			v2index = i;
	}

DoNextFace:
	nNewEdges = 0;
	for(i = v1index; ; i++)
	{
		if(i == nVertices)
			i = 0;

		if(i == v2index)
			break;

		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]);
		ASSERT(iEdgeIndex != -1);

		hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id;

		AssignFace(&m_Edges[iEdgeIndex], pFace->id);
	}
	// now add the middle edge
	hNewEdges[nNewEdges++] = pNewEdge->id;
	// now set up in face
	pStoreFace->nEdges = nNewEdges;
	memcpy(pStoreFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges);

	if(bFirst)
	{
		int tmp = v1index;
		v1index = v2index;
		v2index = tmp;
		pStoreFace = pNewFace;
		bFirst = FALSE;
		goto DoNextFace;
	}

	delete phVertexList;

	return(TRUE);
}
void CSSolid::FromMapSolid(CMapSolid *p, bool bSkipDisplacementFaces)
{
	// so we can pass NULL (default) or another solid (to copy):
	CMapSolid *pSolid;
	if(p)
		pSolid = p;
	else
		pSolid = m_pMapSolid;

	m_nFaces = 0;
	m_nEdges = 0;
	m_nVertices = 0;

	// Create vertices, edges, faces.
	int nSolidFaces = pSolid->GetFaceCount();
	for(int i = 0; i < nSolidFaces; i++)
	{
		CMapFace *pSolidFace = pSolid->GetFace(i);

		if (bSkipDisplacementFaces)
		{
			if (pSolidFace->HasDisp())
				continue;
		}

		// Add a face
		CSSFace *pFace = AddFace();

		memcpy(pFace->PlanePts, pSolidFace->plane.planepts, sizeof(Vector) * 3);
		pFace->texture = pSolidFace->texture;
		pFace->normal = pSolidFace->plane.normal;
		pFace->m_nFaceID = pSolidFace->GetFaceID();

		// Displacement.
		if ( pSolidFace->HasDisp() )
		{
			pFace->m_hDisp = EditDispMgr()->Create();
			CMapDisp *pDisp = EditDispMgr()->GetDisp( pFace->m_hDisp );
			CMapDisp *pSolidDisp = EditDispMgr()->GetDisp( pSolidFace->GetDisp() );
			pDisp->CopyFrom( pSolidDisp, false );
		}

		// Convert vertices and edges
		int nFacePoints = pSolidFace->nPoints;
		Vector *pFacePoints = pSolidFace->Points;
		SSHANDLE hLastVertex = 0;	// valid IDs start at 1
		SSHANDLE hThisVertex, hFirstVertex;
		for(int pt = 0; pt <= nFacePoints; pt++)
		{
			int iVertex;
			
			if(pt < nFacePoints)
			{
				// YWB:  Change leniency from 1.0 down to 0.1
				iVertex = GetVertexIndex(pFacePoints[pt], 0.1f);
				if (iVertex == -1)
				{
					// not found - add the vertex
					CSSVertex *pVertex = AddVertex(&iVertex);
					pVertex->pos = pFacePoints[pt];
				}

				// assign this vertex handle
				hThisVertex = m_Vertices[iVertex].id;

				if (pt == 0)
					hFirstVertex = hThisVertex;
			}
			else
			{
				// connect last to first
				hThisVertex = hFirstVertex;
			}

			if (hLastVertex)
			{
				// create the edge from the last vertex to current vertex.
				//  first check to see if this edge already exists.. 
				int iEdge = GetEdgeIndex(hLastVertex, hThisVertex);
				CSSEdge *pEdge;
				if (iEdge == -1)
				{
					// not found - add new edge
					pEdge = AddEdge(&iEdge);
					pEdge->hvStart = hLastVertex;
					pEdge->hvEnd   = hThisVertex;

					// make sure edge center is valid:
					CalcEdgeCenter(pEdge);
				}
				else
				{
					pEdge = &m_Edges[iEdge];
				}

				// add the edge to the face
				pFace->Edges[pFace->nEdges++] = pEdge->id;

				// set edge's face array
				if(!pEdge->Faces[0])
					pEdge->Faces[0] = pFace->id;
				else if(!pEdge->Faces[1])
					pEdge->Faces[1] = pFace->id;
				else
				{
					// YWB try filling in front side
					//  rather than ASSERT(0) crash
					pEdge->Faces[0] = pFace->id;
					AfxMessageBox("Edge with both face id's already filled, skipping...");
				}
			}

			hLastVertex = hThisVertex;
		}
	}
}
Beispiel #10
0
BOOL CSSolid::SplitFaceByEdges(CSSEdge *pEdge1, CSSEdge *pEdge2)
{
	SSHANDLE hFace;

	// find the handle of the face
	if(pEdge1->Faces[0] == pEdge2->Faces[0] || 
		pEdge1->Faces[0] == pEdge2->Faces[1])
	{
		hFace = pEdge1->Faces[0];
	}
	else if(pEdge1->Faces[1] == pEdge2->Faces[0] || 
		pEdge1->Faces[1] == pEdge2->Faces[1])
	{
		hFace = pEdge1->Faces[1];
	}
	else return FALSE;	// not the same face

	// get pointer to face
	CSSFace *pFace = (CSSFace*) GetHandleData(hFace);

	// create new objects
	CSSFace *pNewFace = AddFace();
	CSSEdge *pNewEdgeMid = AddEdge();
	int iNewVertex1, iNewVertex2;
	CSSVertex *pNewVertex1 = AddVertex(&iNewVertex1);
	CSSVertex *pNewVertex2 = AddVertex(&iNewVertex2);

	// assign faces to new edge
	AssignFace(pNewEdgeMid, pFace->id);
	AssignFace(pNewEdgeMid, pNewFace->id);

	// copy texture info from one face to the other
	memcpy(&pNewFace->texture, &pFace->texture, sizeof(TEXTURE));

	// set vertex positions
	m_Vertices[iNewVertex1].pos = pEdge1->ptCenter;
	m_Vertices[iNewVertex2].pos = pEdge2->ptCenter;

	// set up middle edge
	pNewEdgeMid->hvStart = pNewVertex1->id;
	pNewEdgeMid->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pNewEdgeMid);

	// set up new side edges
	CSSEdge *pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge1->hvStart;
	pEdgeTmp->hvEnd = pNewVertex1->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge1->hvEnd;
	pEdgeTmp->hvEnd = pNewVertex1->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge2->hvStart;
	pEdgeTmp->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pEdgeTmp);

	pEdgeTmp = AddEdge();
	pEdgeTmp->hvStart = pEdge2->hvEnd;
	pEdgeTmp->hvEnd = pNewVertex2->id;
	CalcEdgeCenter(pEdgeTmp);

/*
	FILE *fp = fopen("split", "w");
	for(i = 0; i < nVertices; i++)
	{
		fprintf(fp, "%lu\n", phVertexList[i]);
	}
	fclose(fp);
*/

	// set up edges - start with newvertex1 
	SSHANDLE hNewEdges[64];
	int nNewEdges;
	BOOL bFirst = TRUE;
	CSSFace *pStoreFace = pFace;

	// ** do two new faces first **

	int nv1index, nv2index;
	SSHANDLE *phVertexList = CreateNewVertexList(pFace, pEdge1, pEdge2, 
		nv1index, nv2index, pNewVertex1, pNewVertex2);
	int nVertices = pFace->nEdges;
	if(nv1index != -1)
		++nVertices;
	if(nv2index != -1)
		++nVertices;

	// kill face references in edges first
	for(int i = 0; i < nVertices; i++)
	{
		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], 
			phVertexList[iNextVertex]);
		CSSEdge *pEdge = &m_Edges[iEdgeIndex];
		ASSERT(pEdge->id != pEdge1->id);
		ASSERT(pEdge->id != pEdge2->id);
		AssignFace(pEdge, pFace->id, TRUE);
	}

DoNextFace:
	nNewEdges = 0;
	for(i = nv1index; ; i++)
	{
		if(i == nVertices)
			i = 0;

		if(i == nv2index)
			break;

		int iNextVertex = GetNext(i, 1, nVertices);
		int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]);
		ASSERT(iEdgeIndex != -1);

		hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id;

		AssignFace(&m_Edges[iEdgeIndex], pStoreFace->id);
	}
	// now add the middle edge
	hNewEdges[nNewEdges++] = pNewEdgeMid->id;
	// now set up in face
	pStoreFace->nEdges = nNewEdges;
	memcpy(pStoreFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges);

	if(bFirst)
	{
		int tmp = nv1index;
		nv1index = nv2index;
		nv2index = tmp;
		pStoreFace = pNewFace;
		bFirst = FALSE;
		goto DoNextFace;
	}

	delete phVertexList;

	// ** now regular faces **
	for(int iFace = 0; iFace < m_nFaces; iFace++)
	{
		CSSFace *pUpdFace = &m_Faces[iFace];

		if(pUpdFace == pNewFace || pUpdFace == pFace)
			continue;
		
		SSHANDLE *phVertexList = CreateNewVertexList(pUpdFace, pEdge1, pEdge2,
			nv1index, nv2index, pNewVertex1, pNewVertex2);

		if(phVertexList == NULL)	// don't need to update this face
			continue;
	
		nNewEdges = 0;
		nVertices = pUpdFace->nEdges;
		if(nv1index != -1)
			++nVertices;
		if(nv2index != -1)
			++nVertices;
		for(i = 0; i < nVertices; i++)
		{
			int iNextVertex = GetNext(i, 1, nVertices);
			int iEdgeIndex = GetEdgeIndex(phVertexList[i], phVertexList[iNextVertex]);
			ASSERT(iEdgeIndex != -1);

			AssignFace(&m_Edges[iEdgeIndex], pUpdFace->id);
			hNewEdges[nNewEdges++] = m_Edges[iEdgeIndex].id;
		}

		// now set up in face
		pUpdFace->nEdges = nNewEdges;
		memcpy(pUpdFace->Edges, hNewEdges, sizeof(SSHANDLE) * nNewEdges);

		delete phVertexList;
	}

	SSHANDLE id1 = pEdge1->id;
	SSHANDLE id2 = pEdge2->id;

	// delete old edges
	for(i = 0; i < m_nEdges; i++)
	{
		if(m_Edges[i].id == id1 || m_Edges[i].id == id2)
		{
			DeleteEdge(i);
			--i;
		}
	}

	return TRUE;
}
 int GetIncorrectEdgeIndex(EdgeId edge) const {
     return GetEdgeIndex(edge, not_out_edges_);
 }
 int GetOutEdgeIndex(EdgeId edge) const {
     return GetEdgeIndex(edge, out_edges_);
 }