Пример #1
0
        //#if Debug

        //static void dumpTriangles(ACTCEdge *e, FILE *fp)
        //{
        //    int i;
        //    int c;
        //    char v[12];

        //    c = fprintf(fp, "      %d triangles: ");
        //    for(i = 0; i < e.Triangles.Length; i++) {
        //    if (c + 1 + sprintf(v, "%u", e.Triangles[i].FinalVert) > 78) {
        //        fputs("\n", fp);
        //        c = fprintf(fp, "        ");
        //    }
        //    c += fprintf(fp, " %s", v);
        //    }
        //    fputs("\n", fp);
        //}

        //static void dumpEdges(ACTCVertex *vert, FILE *fp)
        //{
        //    int i;
        //    int c;
        //    char v[26]; /* two signed ints plus x plus NUL */

        //    for(i = 0; i < vert.Edges.Length; i++) {
        //    fprintf(fp, "    %u.%u (%d times)\n", vert.V, vert.Edges[i].V2.V,
        //        vert.Edges[i].Count);
        //    dumpTriangles(&vert.Edges[i], fp);
        //    }
        //    fputs("\n", fp);
        //}

        //static void dumpVertices(ACTCData *tc, FILE *fp)
        //{
        //    int i;
        //    ACTCVertex *v;

        //    if (!tc.UsingStaticVerts)
        //        tableResetIterator(tc.VertexIterator);

        //    fprintf(fp, "%d vertices in valences list\n", tc.VertexCount);
        //    if (tc.UsingStaticVerts) {
        //        for(i = 0; i < tc.VertRange; i++) {
        //        v = &tc.StaticVerts[i];
        //        if (v.Count > 0) {
        //        fprintf(fp, "  vertex %u, valence %d, %d edges\n", v.V,
        //            v.Count, v.Edges.Length);
        //        dumpEdges(v, fp);
        //        }
        //    }
        //    } else {
        //    for(i = 0; i < tc.VertexCount; i++) {
        //        if (tableIterate(tc.Vertices, tc.VertexIterator, null,
        //        (void **)&v) == 0) {
        //        fprintf(fp, "ACTC::dumpVertices : fewer vertices in the table "
        //            "than we expected!\n");
        //        fprintf(stderr, "ACTC::dumpVertices : fewer vertices in the table "
        //            "than we expected!\n");
        //        }
        //        if (v == null) {
        //        fprintf(fp, "ACTC::dumpVertices : did not expect to get a null"
        //            "Vertex from the table iterator!\n");
        //        fprintf(stderr, "ACTC::dumpVertices : did not expect to get a null"
        //            "Vertex from the table iterator!\n");
        //        }
        //        fprintf(fp, "  vertex %u, valence %d, %d edges\n", v.V, v.Count,
        //        v.Edges.Length);
        //        dumpEdges(v, fp);
        //    }
        //    }
        //}

        //static void dumpVertexBins(ACTCData *tc, FILE *fp)
        //{
        //    ACTCVertex *cur;
        //    int i;
        //    int c;
        //    char v[26]; /* two signed ints plus x plus NUL */

        //    fprintf(fp, "vertex bins:\n");
        //    if (tc.VertexBins == null) {
        //        fprintf(fp, "        empty.\n");
        //    return;
        //    }
        //    for(i = 1; i <= tc.CurMaxVertValence; i++) {
        //        cur = tc.VertexBins[i];
        //    c = fprintf(fp, "        bin %d . ", i);
        //    while(cur != null) {
        //        if (c + 1 + sprintf(v, "%ux%d", cur.V, cur.Count) > 78) {
        //        fputs("\n", fp);
        //        c = fprintf(fp, "          ");
        //        }
        //        c += fprintf(fp, " %s", v);
        //        cur = cur.Next;
        //    }
        //    fputs("\n", fp);
        //    }
        //}

        //void actcDumpState(ACTCData *tc, FILE *fp)
        //{
        //    dumpVertices(tc, fp);
        //    dumpVertexBins(tc, fp);
        //}

        //static int abortWithOptionalDump(ACTCData *tc)
        //{
        //    (int)ACTC_.INFO(actcDumpState(tc, stderr));
        //    abort();
        //}

        //#endif Debug

        static ACTC_var actcGetError(ACTCData tc)
        {
            ACTC_var error = tc.Error;

            tc.Error = ACTC_var.NO_ERROR;
            return(error);
        }
Пример #2
0
 static void actcDelete(ACTCData tc)
 {
     actcMakeEmpty(ref tc);
     tc.VertexIterator = null; //free(tc.VertexIterator);
     tc.Vertices       = null; //free(tc.Vertices);
     //tc = new ACTCData(); //free(tc);
 }
Пример #3
0
        static ACTC_var actcEndOutput(ref ACTCData tc)
        {
            if (tc.IsInputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcEndOutput : called within "
                //    "BeginInput/EndInput\n");)
                return(tc.Error = ACTC_var.DURING_INPUT);
            }

            if (tc.IsOutputting == 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcEndOutput : called outside "
                //    "BeginOutput/EndOutput\n");)
                return(tc.Error = ACTC_var.IDLE);
            }

            tc.IsOutputting = 0;

            if (tc.UsingStaticVerts != 0)
            {
                //free(tc.StaticVerts);
                tc.StaticVerts      = null;
                tc.UsingStaticVerts = 0;
            }

            //free(tc.VertexBins);
            tc.VertexBins = null;

            return(ACTC_var.NO_ERROR);
        }
Пример #4
0
        static ACTC_var unmapVertexEdge(ref ACTCData tc, ref ACTCVertex v1, ACTCVertex v2)
        {
            int i;

            for (i = 0; i < v1.Edges.Length; i++)
            {
                if (v1.Edges[i].V2 == v2)
                {
                    break;
                }
            }

            if (i == v1.Edges.Length)
            {
                //(int)ACTC_.DEBUG(
                //    fprintf(stderr, "ACTC::unmapVertexEdge : Couldn't find edge %d,%d"
                //        " from vertex in order to unmap it?!?\n", v1.V, v2.V);
                //    abortWithOptionalDump(tc);
                //)
                return(tc.Error = ACTC_var.DATABASE_CORRUPT);
            }

            v1.Edges[i].Count--;
            if (v1.Edges[i].Count == 0)
            {
                //if (v1.Edges[i].Triangles != null)
                //v1.Edges[i].Triangles = new ACTCTriangle[0];
                //free(v1.Edges[i].Triangles);
                v1.Edges[i] = v1.Edges[v1.Edges.Length - 1];
                //v1.Edges.Length--;
            }

            return(ACTC_var.NO_ERROR);
        }
Пример #5
0
        static ACTC_var unmapEdgeTriangle(ref ACTCData tc, ref ACTCEdge edge, ACTCVertex v3)
        {
            int i;

            for (i = 0; i < edge.Triangles.Length; i++)
            {
                if (edge.Triangles[i].FinalVert == v3)
                {
                    break;
                }
            }

            if (i == edge.Triangles.Length)
            {
                //(int)ACTC_.DEBUG(
                //    fprintf(stderr, "ACTC::unmapEdgeTriangle : Couldn't find third vertex"
                //        " from edge in order to delete it?!?\n");
                //    abortWithOptionalDump(tc);
                //)
                return(tc.Error = ACTC_var.DATABASE_CORRUPT);
            }

            edge.Triangles[i] = edge.Triangles[edge.Triangles.Length - 1];
            //Array.Resize<ACTCTriangle>(ref edge.Triangles, edge.Triangles.Length - 1);
            //edge.TriangleCount--;

            return(ACTC_var.NO_ERROR);
        }
Пример #6
0
        static ACTC_var decVertexValence(ref ACTCData tc, ref ACTCVertex v)
        {
            v.Count--;
            if (v.Count < 0)
            {
                //(int)ACTC_.DEBUG(
                //    fprintf(stderr, "ACTC::decVertexValence : Valence went "
                //    "negative?!?\n");
                //    abortWithOptionalDump(tc);
                //)
                return(tc.Error = ACTC_var.DATABASE_CORRUPT);
            }

            if (v.PointsToMe != null)
            {
                v.PointsToMe[0] = v.Next;
                if (v.Next != null)
                {
                    v.Next.PointsToMe = v.PointsToMe;
                }
                v.Next = null;
            }

            if (v.Count == 0)
            {
                tc.VertexCount--;
                if (v.Edges != null)
                {
                    //free(v.Edges);
                    //v.Edges = null;
                }
                if (tc.UsingStaticVerts == 0)
                {
                    ACTCVertex g = null;
                    tableRemove(v.V, ref tc.Vertices, ref g);
                    //free(v);
                }
                //v = null;
            }
            else
            {
                if (tc.VertexBins != null)
                {
                    v.Next          = tc.VertexBins[v.Count];
                    v.PointsToMe[0] = tc.VertexBins[v.Count];
                    if (v.Next != null)
                    {
                        v.Next.PointsToMe[0] = v.Next;
                    }
                    tc.VertexBins[v.Count] = v;
                    if (v.Count < tc.CurMinVertValence)
                    {
                        tc.CurMinVertValence = v.Count;
                    }
                }
            }

            return(ACTC_var.NO_ERROR);
        }
Пример #7
0
        //No need to use pointers.
        //static void *reallocAndAppend(void **ptr, uint *itemCount, uint itemBytes, void *append)
        //{
        //    void *t;

        //    t = (void*)Marshal.ReAllocCoTaskMem(new IntPtr(*ptr), (int)itemBytes * (int)(*itemCount + 1));
        //    if (t == null)
        //        return null;
        //    *ptr = t;

        //    //memcpy((unsigned char *)*ptr + *itemCount * itemBytes, append, itemBytes);
        //    (*itemCount) += 1;

        //    return *ptr;
        //}

        /*
         * Call only during input; changes vertices' valences and does not
         * fix the bins that are ordered by vertex valence.  (It's usually cheaper
         * to traverse the vertex list once after all are added, since that's
         * linear in the NUMBER OF UNIQUE VERTEX INDICES, which is almost always
         * going to be less than the number of vertices.)
         */
        static ACTC_var incVertexValence(ref ACTCData tc, uint v, out ACTCVertex found)
        {
            ACTCVertex vertex;

            found = null;
            if (tc.UsingStaticVerts == 1)
            {
                vertex = tc.StaticVerts[v];
                vertex.Count++;
                if (vertex.Count == 1)
                {
                    vertex.V = v;
                    tc.VertexCount++;
                }
            }
            else
            {
                if (tableRetrieve(v, tc.Vertices, out vertex) == 1)
                {
                    if (vertex.V != v)
                    {
                        //(int)ACTC_.DEBUG(
                        //    fprintf(stderr, "ACTC::incVertexValence : Got vertex %d when "
                        //    "looking for vertex %d?!?\n", vertex.V, v);
                        //    abortWithOptionalDump(tc);
                        //)
                        return(tc.Error = ACTC_var.DATABASE_CORRUPT);
                    }
                    vertex.Count++;
                }
                else
                {
                    ////chartedSetLabel("new Vertex");
                    vertex       = new ACTCVertex();
                    vertex.V     = v;
                    vertex.Count = 1;
                    vertex.Edges = new ACTCEdge[0];
                    //vertex.Edges.Length = 0;
                    if (tableInsert(v, ref tc.Vertices, vertex) == 0)
                    {
                        //(int)ACTC_.DEBUG(fprintf(stderr, "ACTC::incVertexValence : Failed "
                        //    "to insert vertex into table\n");)
                        return(tc.Error = ACTC_var.ALLOC_FAILED);
                    }
                    tc.VertexCount++;
                }
            }

            if (vertex.Count > tc.CurMaxVertValence)
            {
                tc.CurMaxVertValence = vertex.Count;
            }

            found = vertex;

            return(ACTC_var.NO_ERROR);
        }
Пример #8
0
 static ACTC_var actcParamu(ACTCData tc, ACTC_var param, uint value)
 {
     /*
      * XXX - yes, this is questionable, but I consulted industry
      * experts and we agreed that most common behavior is to copy the
      * bits directly, which is what I want.
      */
     return(actcParami(tc, param, (int)value));
 }
Пример #9
0
        static ACTC_var unmapEdgeTriangleByVerts(ref ACTCData tc, ACTCVertex v1, ACTCVertex v2, ACTCVertex v3)
        {
            ACTCEdge e;

            ACTC_CHECK(findEdge(v1, v2, out e));
            if (e != null)
            {
                unmapEdgeTriangle(ref tc, ref e, v3);
            }
            return(ACTC_var.NO_ERROR);
        }
Пример #10
0
 static ACTC_var actcMakeEmpty(ref ACTCData tc)
 {
     tc.VertexCount = 0;
     if (tc.UsingStaticVerts == 0)
     {
         tableDelete(tc.Vertices);
     }
     if (tc.VertexBins != null)
     {
         //tc.VertexBins = null;//free(tc.VertexBins);
         tc.VertexBins = null;
     }
     tc.IsOutputting = 0;
     tc.IsInputting  = 0;
     return(ACTC_var.NO_ERROR);
 }
Пример #11
0
        static ACTC_var actcGetParami(ACTCData tc, ACTC_var param, int *value)
        {
            switch (param)
            {
            case ACTC_var.MAJOR_VERSION:
                *value = 1;
                break;

            case ACTC_var.MINOR_VERSION:
                *value = 1;
                break;

            case ACTC_var.IN_MAX_VERT:
                *value = (int)tc.MaxInputVert;
                break;

            case ACTC_var.IN_MIN_VERT:
                *value = (int)tc.MinInputVert;
                break;

            case ACTC_var.IN_MAX_EDGE_SHARING:
                *value = tc.MaxEdgeShare;
                break;

            case ACTC_var.IN_MAX_VERT_SHARING:
                *value = tc.MaxVertShare;
                break;

            case ACTC_var.OUT_MIN_FAN_VERTS:
                *value = tc.MinFanVerts;
                break;

            case ACTC_var.OUT_HONOR_WINDING:
                *value = tc.HonorWinding;
                break;

            case ACTC_var.OUT_MAX_PRIM_VERTS:
                *value = tc.MaxPrimVerts;
                break;

            default:
                *value = 0;
                return(tc.Error = ACTC_var.INVALID_VALUE);
            }
            return(ACTC_var.NO_ERROR);
        }
Пример #12
0
 static ACTC_var findNextStripVertex(ref ACTCData tc, ref ACTCVertex vert)
 {
     while (tc.VertexBins[tc.CurMinVertValence] == null)
     {
         tc.CurMinVertValence++;
         if (tc.CurMinVertValence > tc.CurMaxVertValence)
         {
             if (tc.VertexCount > 0)
             {
                 //(int)ACTC_.DEBUG(fprintf(stderr, "tc::findNextStripVertex : no more "
                 //    "vertices in bins but VertexCount > 0\n");)
                 return(tc.Error = ACTC_var.DATABASE_CORRUPT);
             }
             return(ACTC_var.NO_MATCHING_VERT);
         }
     }
     vert = tc.VertexBins[tc.CurMinVertValence];
     return(ACTC_var.NO_ERROR);
 }
Пример #13
0
        static ACTC_var actcBeginInput(ref ACTCData tc)
        {
            if (tc.IsOutputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcBeginInput : called within "
                //    "BeginOutput/EndOutput\n");)
                return(tc.Error = ACTC_var.DURING_INPUT);
            }

            if (tc.IsInputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcBeginInput : called within "
                //    "BeginInput/EndInput\n");)
                return(tc.Error = ACTC_var.DURING_INPUT);
            }

            tc.IsInputting       = 1;
            tc.CurMaxVertValence = 0;

            if (tc.MaxInputVert < MAX_STATIC_VERTS - 1)
            {
                //uint byteCount;
                tc.UsingStaticVerts = 1;
                tc.VertRange        = tc.MaxInputVert + 1;
                //byteCount = (uint)sizeof(ACTCVertex) * tc.VertRange;

                ////chartedSetLabel("static verts");
                //fixed (ACTCVertex* t = new ACTCVertex[tc.VertRange])
                tc.StaticVerts = new ACTCVertex[tc.VertRange];
                if (tc.StaticVerts == null)
                {
                    //(int)ACTC_.INFO(printf("Couldn't allocate static %d vert block of %u "
                    //"bytes\n", tc.VertRange, byteCount);)
                    tc.UsingStaticVerts = 0;
                }
            }
            else
            {
                tc.UsingStaticVerts = 0;
            }

            return(ACTC_var.NO_ERROR);
        }
Пример #14
0
        static ACTC_var actcEndInput(ref ACTCData tc)
        {
            if (tc.IsOutputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcEndInput : called within "
                //    "BeginOutput/EndOutput\n");)
                return(tc.Error = ACTC_var.DURING_OUTPUT);
            }

            if (tc.IsInputting == 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcEndInput : called outside "
                //    "BeginInput/EndInput\n");)
                return(tc.Error = ACTC_var.IDLE);
            }

            tc.IsInputting = 0;

            return(ACTC_var.NO_ERROR);
        }
Пример #15
0
        public static ACTCData actcNew()
        {
            ACTCData tc = new ACTCData();

            //#if Debug
            //    static int didPrintVersion = 0;

            //    if (!didPrintVersion) {
            //    int verMinor, verMajor;
            //    didPrintVersion = 1;

            //        actcGetParami(tc, (int)ACTC_.MAJOR_VERSION, &verMajor);
            //        actcGetParami(tc, (int)ACTC_.MINOR_VERSION, &verMinor);
            //    fprintf(stderr, "TC Version %d.%d\n", verMajor, verMinor);
            //    }
            //#endif Debug

            //chartedSetLabel("the tc struct");

            //if (tc == null)
            //{
            //    //(int)ACTC_.DEBUG(fprintf(stderr, "actcNew : couldn't allocate %d bytes "
            //    //    "for new ACTCData\n", sizeof(*tc));)
            //    return null;
            //}

            tc.Vertices       = new TableRoot();
            tc.Vertices.Table = new TableLevel2[16384];
            tc.VertexIterator = new TableIterator();
            tc.MinFanVerts    = 3;
            tc.MaxPrimVerts   = int.MaxValue;
            tc.MaxInputVert   = int.MaxValue;
            tc.MaxEdgeShare   = int.MaxValue;
            tc.MaxVertShare   = int.MaxValue;
            tc.HonorWinding   = 1;

            /* seed = 0 handled by calloc */
            /* XXX grantham 20000615 - seed ignored for now */

            return(tc);
        }
Пример #16
0
        static ACTC_var actcParami(ACTCData tc, ACTC_var param, int value)
        {
            if (tc.IsInputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcParami : within BeginInput/"
                //    "EndInput\n");)
                return(tc.Error = ACTC_var.DURING_INPUT);
            }
            if (tc.IsOutputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcParami : within BeginOutput/"
                //    "EndOutput\n");)
                return(tc.Error = ACTC_var.DURING_OUTPUT);
            }

            switch (param)
            {
            case ACTC_var.OUT_MIN_FAN_VERTS:
                tc.MinFanVerts = value;
                break;

            case ACTC_var.IN_MAX_VERT:
                if (value < tc.MinInputVert)
                {
                    //(int)ACTC_.DEBUG(fprintf(stderr, "actcParami : tried to set "
                    //    "MAX_INPUT_VERT to %d, less than MIN_INPUT_VERT (%d)\n",
                    //    value, tc.MinInputVert);)
                    return(tc.Error = ACTC_var.INVALID_VALUE);
                }
                tc.MaxInputVert = (uint)value;
                break;

            case ACTC_var.IN_MIN_VERT:
                if (value > tc.MaxInputVert)
                {
                    //(int)ACTC_.DEBUG(fprintf(stderr, "actcParami : tried to set "
                    //    "MIN_INPUT_VERT to %d, greater than MAX_INPUT_VERT (%d)\n",
                    //    value, tc.MaxInputVert);)
                    return(tc.Error = ACTC_var.INVALID_VALUE);
                }
                tc.MinInputVert = (uint)value;
                break;

            case ACTC_var.IN_MAX_EDGE_SHARING:
                tc.MaxEdgeShare = value;
                break;

            case ACTC_var.IN_MAX_VERT_SHARING:
                tc.MaxVertShare = value;
                break;

            case ACTC_var.OUT_HONOR_WINDING:
                tc.HonorWinding = value;
                break;

            case ACTC_var.OUT_MAX_PRIM_VERTS:
                if (value < 3)
                {
                    //(int)ACTC_.DEBUG(fprintf(stderr, "actcParami : tried to set "
                    //    "MAX_PRIM_VERTS to %d (needed to be 3 or more)\n", value);)
                    return(tc.Error = ACTC_var.INVALID_VALUE);
                }
                tc.MaxPrimVerts = value;
                break;
            }
            return(ACTC_var.NO_ERROR);
        }
Пример #17
0
        static ACTC_var actcAddTriangle(ref ACTCData tc, uint v1, uint v2, uint v3)
        {
            ACTCVertex vertexRec1;
            ACTCVertex vertexRec2;
            ACTCVertex vertexRec3;

            ACTCEdge edge12;
            ACTCEdge edge23;
            ACTCEdge edge31;

            if (tc.IsOutputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcAddTriangle : inside "
                //    "BeginOutput/EndOutput\n");)
                return(tc.Error = ACTC_var.IDLE);
            }
            if (tc.IsInputting == 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcAddTriangle : outside "
                //    "BeginInput/EndInput\n");)
                return(tc.Error = ACTC_var.DURING_INPUT);
            }

            if (incVertexValence(ref tc, v1, out vertexRec1) != ACTC_var.NO_ERROR)
            {
                goto returnError1;
            }
            if (incVertexValence(ref tc, v2, out vertexRec2) != ACTC_var.NO_ERROR)
            {
                goto free1;
            }
            if (incVertexValence(ref tc, v3, out vertexRec3) != ACTC_var.NO_ERROR)
            {
                goto free2;
            }

            if (mapVertexEdge(vertexRec1, vertexRec2, out edge12) != ACTC_var.NO_ERROR)
            {
                goto free3;
            }
            if (mapVertexEdge(vertexRec2, vertexRec3, out edge23) != ACTC_var.NO_ERROR)
            {
                goto free4;
            }
            if (mapVertexEdge(vertexRec3, vertexRec1, out edge31) != ACTC_var.NO_ERROR)
            {
                goto free5;
            }

            if (mapEdgeTriangle(ref edge12, vertexRec3) != ACTC_var.NO_ERROR)
            {
                goto free6;
            }
            if (mapEdgeTriangle(ref edge23, vertexRec1) != ACTC_var.NO_ERROR)
            {
                goto free7;
            }
            if (mapEdgeTriangle(ref edge31, vertexRec2) != ACTC_var.NO_ERROR)
            {
                goto free8;
            }

            return(ACTC_var.NO_ERROR);

            /*
             * XXX Unfortunately, while backing out during the following
             * statements, we might encounter errors in the database which
             * will not get returned properly to the caller; I take heart in
             * the fact that if such an error occurs, TC is just a moment from
             * core dumping anyway. XXX grantham 20000615
             */

            free8        : unmapEdgeTriangle(ref tc, ref edge23, vertexRec1);
            free7        : unmapEdgeTriangle(ref tc, ref edge12, vertexRec3);
            free6        : unmapVertexEdge(ref tc, ref vertexRec3, vertexRec1);
            free5        : unmapVertexEdge(ref tc, ref vertexRec2, vertexRec3);
            free4        : unmapVertexEdge(ref tc, ref vertexRec1, vertexRec2);
            free3        : decVertexValence(ref tc, ref vertexRec3);
            free2        : decVertexValence(ref tc, ref vertexRec2);
            free1        : decVertexValence(ref tc, ref vertexRec1);
            returnError1 : return(tc.Error);
        }
Пример #18
0
        static ACTC_var actcStartNextPrim(ref ACTCData tc, out int v1Return, out int v2Return)
        {
            ACTCVertex v1 = null;
            ACTCVertex v2 = null;
            ACTC_var   findResult;

            v1Return = v2Return = -1;

            if (tc.IsInputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcStartNextPrim : within "
                //    "BeginInput/EndInput\n");)
                return(tc.Error = ACTC_var.DURING_INPUT);
            }
            if (tc.IsOutputting == 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcStartNextPrim : outside "
                //    "BeginOutput/EndOutput\n");)
                return(tc.Error = ACTC_var.IDLE);
            }

            findResult = findNextFanVertex(ref tc, ref v1);
            if (findResult == ACTC_var.NO_ERROR)
            {
                tc.PrimType = ACTC_var.PRIM_FAN;
            }
            else if (findResult != ACTC_var.NO_MATCHING_VERT)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcStartNextPrim : internal "
                //    "error finding next appropriate vertex\n");)
                return(tc.Error = findResult);
            }
            else
            {
                findResult = findNextStripVertex(ref tc, ref v1);
                if (findResult != ACTC_var.NO_ERROR && findResult != ACTC_var.NO_MATCHING_VERT)
                {
                    //(int)ACTC_.DEBUG(fprintf(stderr, "actcStartNextPrim : internal "
                    //"error finding next appropriate vertex\n");)
                    return(tc.Error = findResult);
                }
                tc.PrimType = ACTC_var.PRIM_STRIP;
            }

            if (findResult == ACTC_var.NO_MATCHING_VERT)
            {
                v1Return = -1;
                v2Return = -1;
                return(tc.Error = ACTC_var.DATABASE_EMPTY);
            }

            v2 = v1.Edges[0].V2;

            tc.CurWindOrder  = ACTC_var.FWD_ORDER;
            tc.VerticesSoFar = 2;

            tc.V1 = v1;
            tc.V2 = v2;

            v1Return = (int)v1.V;
            v2Return = (int)v2.V;

            //(int)ACTC_.INFO(printf("starting with edge %u, %u\n", tc.V1.V, tc.V2.V);)

            return(tc.PrimType);
        }
Пример #19
0
        static ACTC_var actcGetNextVert(ref ACTCData tc, out int vertReturn)
        {
            ACTCEdge   edge;
            int        wasEdgeFound = 0;
            ACTCVertex thirdVertex;
            int        wasFoundReversed;

            vertReturn = -1;

            if (tc.IsInputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcGetNextVert : within BeginInput/"
                //    "EndInput\n");)
                return(tc.Error = ACTC_var.DURING_INPUT);
            }
            if (tc.IsOutputting == 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcGetNextVert : outside BeginOutput/"
                //    "EndOutput\n");)
                return(tc.Error = ACTC_var.IDLE);
            }
            if (tc.PrimType == ACTC_var.NULL)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcGetNextVert : Asked for next vertex "
                //    "without a primitive (got last\n    vertex already?)\n");)
                return(tc.Error = ACTC_var.INVALID_VALUE);
            }

            if (tc.VerticesSoFar >= tc.MaxPrimVerts)
            {
                tc.PrimType = ACTC_var.NULL;
                return(tc.Error = ACTC_var.PRIM_COMPLETE);
            }

            if (tc.V1 == null || tc.V2 == null)
            {
                tc.PrimType = ACTC_var.NULL;
                return(tc.Error = ACTC_var.PRIM_COMPLETE);
            }

            //(int)ACTC_.INFO(printf("looking for edge %u, %u\n", tc.V1.V, tc.V2.V);)

            wasFoundReversed = 0;

            if (findEdge(tc.V1, tc.V2, out edge) != 0)
            {
                wasEdgeFound = 1;
            }
            else if (tc.HonorWinding == 0)
            {
                wasFoundReversed = 1;
                if (findEdge(tc.V2, tc.V1, out edge) != 0)
                {
                    wasEdgeFound = 1;
                }
            }

            if (wasEdgeFound == 0)
            {
                tc.PrimType = ACTC_var.NULL;
                return(tc.Error = ACTC_var.PRIM_COMPLETE);
            }

            thirdVertex = edge.Triangles[edge.Triangles.Length - 1].FinalVert;

            //(int)ACTC_.INFO(printf("third vertex = %u\n", thirdVertex.V);)
            vertReturn = (int)thirdVertex.V;

            if (wasFoundReversed != 0)
            {
                ACTC_CHECK(unmapEdgeTriangle(ref tc, ref edge, thirdVertex));
                ACTC_CHECK(unmapEdgeTriangleByVerts(ref tc, tc.V1, thirdVertex, tc.V2));
                ACTC_CHECK(unmapEdgeTriangleByVerts(ref tc, thirdVertex, tc.V2, tc.V1));
                ACTC_CHECK(unmapVertexEdge(ref tc, ref tc.V2, tc.V1));
                ACTC_CHECK(unmapVertexEdge(ref tc, ref tc.V1, thirdVertex));
                ACTC_CHECK(unmapVertexEdge(ref tc, ref thirdVertex, tc.V2));
            }
            else
            {
                ACTC_CHECK(unmapEdgeTriangle(ref tc, ref edge, thirdVertex));
                ACTC_CHECK(unmapEdgeTriangleByVerts(ref tc, tc.V2, thirdVertex, tc.V1));
                ACTC_CHECK(unmapEdgeTriangleByVerts(ref tc, thirdVertex, tc.V1, tc.V2));
                ACTC_CHECK(unmapVertexEdge(ref tc, ref tc.V1, tc.V2));
                ACTC_CHECK(unmapVertexEdge(ref tc, ref tc.V2, thirdVertex));
                ACTC_CHECK(unmapVertexEdge(ref tc, ref thirdVertex, tc.V1));
            }
            ACTC_CHECK(decVertexValence(ref tc, ref tc.V1));
            ACTC_CHECK(decVertexValence(ref tc, ref tc.V2));
            ACTC_CHECK(decVertexValence(ref tc, ref thirdVertex));

            if (tc.PrimType == ACTC_var.PRIM_FAN)
            {
                tc.V2 = thirdVertex;
            }
            else /* PRIM_STRIP */
            {
                if (tc.CurWindOrder == ACTC_var.FWD_ORDER)
                {
                    tc.V1 = thirdVertex;
                }
                else
                {
                    tc.V2 = thirdVertex;
                }
                tc.CurWindOrder = 1 - tc.CurWindOrder;
            }

            tc.VerticesSoFar++;
            return(ACTC_var.NO_ERROR);
        }
Пример #20
0
        static ACTC_var actcBeginOutput(ref ACTCData tc)
        {
            ACTCVertex v = new ACTCVertex();
            int        i;

            if (tc.IsInputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcBeginOutput : called within "
                //    "BeginInput/EndInput\n");)
                return(tc.Error = ACTC_var.DURING_INPUT);
            }

            if (tc.IsOutputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcBeginOutput : called within "
                //    "BeginOutput/EndOutput\n");)
                return(tc.Error = ACTC_var.DURING_OUTPUT);
            }

            tc.IsOutputting = 1;

            tc.CurMinVertValence = int.MaxValue;
            //chartedSetLabel("vertex bins");

            tc.VertexBins = new ACTCVertex[tc.CurMaxVertValence + 1];

            //if (tc.VertexBins == null)
            //{
            //    //(int)ACTC_.DEBUG(fprintf(stderr, "actcBeginOutput : couldn't allocate %d bytes "
            //    //    "for Vertex Bins\n",
            //    //    sizeof(ACTCVertex *) * tc.CurMaxVertValence);)
            //    return tc.Error = (int)ACTC_.ALLOC_FAILED;
            //}

            if (tc.UsingStaticVerts != 0)
            {
                double edgeTotal = 0;
                for (i = 0; i < tc.VertRange; i++)
                {
                    v = tc.StaticVerts[i];
                    if (v.Count > 0)
                    {
                        v.Next                 = tc.VertexBins[v.Count];
                        v.PointsToMe[0]        = tc.VertexBins[v.Count];
                        tc.VertexBins[v.Count] = v;

                        if (v.Next != null)
                        {
                            v.Next.PointsToMe[0] = v.Next;
                        }

                        if (v.Count < tc.CurMinVertValence)
                        {
                            tc.CurMinVertValence = v.Count;
                        }

                        edgeTotal += v.Edges.Length;
                    }
                }
            }
            else
            {
                tableResetIterator(ref tc.VertexIterator);
                for (i = 0; i < tc.VertexCount; i++)
                {
                    uint *g = null;
                    if (tableIterate(tc.Vertices, ref tc.VertexIterator, ref g, ref v) == 0)
                    {
                        //(int)ACTC_.DEBUG(fprintf(stderr, "actcBeginOutput : fewer vertices in "
                        //    "the table than we expected!\n");)
                        return(tc.Error = ACTC_var.DATABASE_CORRUPT);
                    }

                    v.Next = tc.VertexBins[v.Count];

                    ACTCVertex[] PointsToMe = new ACTCVertex[tc.VertexBins.Length - v.Count];
                    for (int x = v.Count; x < tc.VertexBins.Length; x++)
                    {
                        PointsToMe[x - v.Count] = tc.VertexBins[x];
                    }

                    v.PointsToMe           = PointsToMe;
                    tc.VertexBins[v.Count] = v;

                    if (v.Next != null)
                    {
                        if (v.Next.PointsToMe == null)
                        {
                            v.Next.PointsToMe = new ACTCVertex[1];
                        }
                        v.Next.PointsToMe[0] = v.Next;
                    }

                    if (v.Count < tc.CurMinVertValence)
                    {
                        tc.CurMinVertValence = v.Count;
                    }
                }
            }

            return(ACTC_var.NO_ERROR);
        }
Пример #21
0
 static int actcGetIsDuringOutput(ACTCData tc)
 {
     return(tc.IsOutputting);
 }
Пример #22
0
 static ACTC_var actcGetParamu(ACTCData tc, ACTC_var param, uint *value)
 {
     return(actcGetParami(tc, param, (int *)value));
 }
Пример #23
0
        public static int actcTrianglesToPrimitives(ACTCData tc, int triangleCount, uint[][] triangles, ACTC_var[] primTypes, int[] primLengths, uint[] vertices, int maxBatchSize)
        {
            ACTC_var r;
            int      curTriangle;
            int      curPrimitive;
            uint     curVertex;
            ACTC_var prim;
            int      v1 = -1, v2 = -1, v3 = -1;
            int      lastPrim;
            int      passesWithoutPrims;
            int      trisSoFar;

            if (tc.IsInputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcTrianglesToPrimitives : within BeginInput/"
                //    "EndInput\n");)
                return((int)(tc.Error = ACTC_var.DURING_INPUT));
            }
            if (tc.IsOutputting != 0)
            {
                //(int)ACTC_.DEBUG(fprintf(stderr, "actcTrianglesToPrimitives : within"
                //    "BeginOutput/EndOutput\n");)
                return((int)(tc.Error = ACTC_var.DURING_OUTPUT));
            }

            curTriangle        = 0;
            curPrimitive       = 0;
            curVertex          = 0;
            passesWithoutPrims = 0;

            actcMakeEmpty(ref tc);

            ACTC_CHECK(actcBeginInput(ref tc));
            trisSoFar = 0;

            while (curTriangle < triangleCount)
            {
                r = actcAddTriangle(ref tc, triangles[curTriangle][0],
                                    triangles[curTriangle][1], triangles[curTriangle][2]);

                trisSoFar++;
                curTriangle++;

                if ((trisSoFar >= maxBatchSize) ||
                    (r == ACTC_var.ALLOC_FAILED && curTriangle != triangleCount) ||
                    (r == ACTC_var.NO_ERROR && curTriangle == triangleCount))
                {
                    /* drain what we got */
                    trisSoFar = 0;

                    ACTC_CHECK(actcEndInput(ref tc));
                    ACTC_CHECK(actcBeginOutput(ref tc));

                    lastPrim = curPrimitive;

                    while ((prim = actcStartNextPrim(ref tc, out v1, out v2)) != ACTC_var.DATABASE_EMPTY)
                    {
                        ACTC_CHECK(prim);

                        primTypes[curPrimitive]   = prim;
                        primLengths[curPrimitive] = 2;

                        vertices[curVertex++] = (uint)v1;
                        vertices[curVertex++] = (uint)v2;

                        while ((r = actcGetNextVert(ref tc, out v3)) != ACTC_var.PRIM_COMPLETE)
                        {
                            ACTC_CHECK(r);
                            vertices[curVertex++] = (uint)v3;
                            primLengths[curPrimitive]++;
                        }

                        curPrimitive++;
                    }
                    ACTC_CHECK(actcEndOutput(ref tc));

                    if (r == ACTC_var.ALLOC_FAILED && curPrimitive == lastPrim)
                    {
                        if (passesWithoutPrims == 0)
                        {
                            //not enough memory to add a triangle and
                            //nothing in the database, better free everything
                            //and try again
                            actcMakeEmpty(ref tc);
                        }
                        else
                        {
                            //cleaned up and STILL couldn't get a triangle in;
                            //give up
                            return((int)(tc.Error = ACTC_var.ALLOC_FAILED));
                        }
                        passesWithoutPrims++;
                    }
                    ACTC_CHECK(actcBeginInput(ref tc));
                }
                else
                {
                    ACTC_CHECK(r);
                }

                if (r == ACTC_var.ALLOC_FAILED)
                {
                    curTriangle--;
                }
            }

            ACTC_CHECK(actcEndInput(ref tc));

            actcMakeEmpty(ref tc);

            return(curPrimitive);
        }