예제 #1
0
 /// <summary>
 /// Quitar poligono de la lista
 /// </summary>
 public void removePolygon(EditPolyPolygon p)
 {
     for (int i = 0; i < faces.Count; i++)
     {
         if (faces[i] == p)
         {
             faces.RemoveAt(i);
             break;
         }
     }
 }
예제 #2
0
 /// <summary>
 /// Quitar poligono de la lista
 /// </summary>
 public void removePolygon(EditPolyPolygon p)
 {
     for (int i = 0; i < faces.Count; i++)
     {
         if (faces[i] == p)
         {
             faces.RemoveAt(i);
             break;
         }
     }
 }
예제 #3
0
        /// <summary>
        /// Tomar un mesh cargar todas las estructuras internas necesarias para poder editarlo
        /// </summary>
        private void loadMesh(TgcMesh origMesh)
        {
            //Obtener vertices del mesh
            this.mesh = origMesh;
            List<EditPolyVertex> origVertices = getMeshOriginalVertexData(origMesh);
            int origTriCount = origVertices.Count / 3;

            //Iterar sobre los triangulos y generar data auxiliar unificada
            vertices = new List<EditPolyVertex>();
            edges = new List<EditPolyEdge>();
            polygons = new List<EditPolyPolygon>();
            indexBuffer = new short[origTriCount * 3];
            int[] attributeBuffer = origMesh.D3dMesh.LockAttributeBufferArray(LockFlags.ReadOnly);
            origMesh.D3dMesh.UnlockAttributeBuffer(attributeBuffer);
            for (int i = 0; i < origTriCount; i++)
            {
                EditPolyVertex v1 = origVertices[i * 3];
                EditPolyVertex v2 = origVertices[i * 3 + 1];
                EditPolyVertex v3 = origVertices[i * 3 + 2];

                //Agregar vertices a la lista, si es que son nuevos
                int v1Idx = EditablePolyUtils.addVertexToListIfUnique(vertices, v1);
                int v2Idx = EditablePolyUtils.addVertexToListIfUnique(vertices, v2);
                int v3Idx = EditablePolyUtils.addVertexToListIfUnique(vertices, v3);
                v1 = vertices[v1Idx];
                v2 = vertices[v2Idx];
                v3 = vertices[v3Idx];

                //Crear edges
                EditPolyEdge e1 = new EditPolyEdge();
                e1.a = v1;
                e1.b = v2;
                EditPolyEdge e2 = new EditPolyEdge();
                e2.a = v2;
                e2.b = v3;
                EditPolyEdge e3 = new EditPolyEdge();
                e3.a = v3;
                e3.b = v1;

                //Crear poligono para este triangulo
                EditPolyPolygon p = new EditPolyPolygon();
                p.vertices = new List<EditPolyVertex>();
                p.vertices.Add(v1);
                p.vertices.Add(v2);
                p.vertices.Add(v3);
                p.edges = new List<EditPolyEdge>();
                p.edges.Add(e1);
                p.edges.Add(e2);
                p.edges.Add(e3);
                p.vbTriangles = new List<int>();
                p.vbTriangles.Add(i * 3);
                p.plane = Plane.FromPoints(v1.position, v2.position, v3.position);
                p.plane.Normalize();
                p.matId = attributeBuffer[i];

                //Agregar triangulo al index buffer
                indexBuffer[i * 3] = (short)v1Idx;
                indexBuffer[i * 3 + 1] = (short)v2Idx;
                indexBuffer[i * 3 + 2] = (short)v3Idx;

                //Agregar a lista de poligonos
                polygons.Add(p);

                /*
                //Buscar si hay un poligono ya existente al cual sumarnos (coplanar y que compartan una arista)
                EditPolyPolygon coplanarP = null;
                for (int j = 0; j < polygons.Count; j++)
                {
                    //Coplanares y con igual material ID
                    EditPolyPolygon p0 = polygons[j];
                    if (p0.matId == p.matId && EditablePolyUtils.samePlane(p0.plane, p.plane))
                    {
                        //Buscar si tienen una arista igual
                        int p0SharedEdgeIdx;
                        int pSharedEdgeIdx;
                        if (EditablePolyUtils.findShareEdgeBetweenPolygons(p0, p, out p0SharedEdgeIdx, out pSharedEdgeIdx))
                        {
                            //Obtener el tercer vertice del triangulo que no es parte de la arista compartida
                            EditPolyEdge sharedEdge = p0.edges[p0SharedEdgeIdx];
                            EditPolyVertex thirdVert;
                            if (p.vertices[0] != sharedEdge.a && p.vertices[0] != sharedEdge.b)
                                thirdVert = p.vertices[0];
                            else if (p.vertices[1] != sharedEdge.a && p.vertices[1] != sharedEdge.b)
                                thirdVert = p.vertices[1];
                            else
                                thirdVert = p.vertices[2];

                            //Agregar el tercer vertice al poligno existente
                            EditablePolyUtils.addVertexToPolygon(p0, sharedEdge, thirdVert);

                            //Quitar arista compartida
                            p0.edges.Remove(sharedEdge);

                            //Agregar al poligono dos nuevas aristas que conectar los extremos de la arista compartida hacia el tercer vertice
                            EditPolyEdge newPolEdge1 = new EditPolyEdge();
                            newPolEdge1.a = sharedEdge.a;
                            newPolEdge1.b = thirdVert;
                            p0.edges.Add(newPolEdge1);

                            EditPolyEdge newPolEdge2 = new EditPolyEdge();
                            newPolEdge2.a = thirdVert;
                            newPolEdge2.b = sharedEdge.b;
                            p0.edges.Add(newPolEdge2);

                            //Agregar indice de triangulo del vertexBuffer que se sumo al poligono
                            p0.vbTriangles.Add(p.vbTriangles[0]);

                            coplanarP = p0;
                        }
                    }
                }
                //Es un nuevo poligono, agregarlo
                if (coplanarP == null)
                {
                    polygons.Add(p);
                }
                 */
            }

            //Unificar aristas de los poligonos
            foreach (EditPolyPolygon p in polygons)
            {
                for (int i = 0; i < p.edges.Count; i++)
                {
                    bool newEdgeAdded;
                    int eIdx = EditablePolyUtils.addEdgeToListIfUnique(edges, p.edges[i], out newEdgeAdded);
                    EditPolyEdge e = edges[eIdx];

                    //Nueva arista incorporada a la lista
                    if (newEdgeAdded)
                    {
                        e.faces = new List<EditPolyPolygon>();

                        //Agregar referencia a vertices que usan la arista
                        e.a.edges.Add(e);
                        e.b.edges.Add(e);
                    }
                    //Se usa arista existente de la lista
                    else
                    {
                        //Reemplazar en poligono por la nueva
                        p.edges[i] = e;
                    }

                    //Indicar a la arista que pertenece al poligono actual
                    e.faces.Add(p);
                }
            }

            setDirtyValues(false);
        }
예제 #4
0
        /// <summary>
        /// Eliminar poligono
        /// </summary>
        private void deletePolygon(EditPolyPolygon p)
        {
            //Quitar triangulos de index buffer
            int vertexToDelete = p.vbTriangles.Count * 3;
            short[] newIndexBuffer = new short[indexBuffer.Length - vertexToDelete];
            int w = 0;
            for (int i = 0; i < indexBuffer.Length; i += 3)
            {
                bool toDelete = false;
                for (int j = 0; j < p.vbTriangles.Count; j++)
                {
                    if (i == p.vbTriangles[j])
                    {
                        toDelete = true;
                        break;
                    }
                }
                if(toDelete)
                {
                    //Ajustar todos los indices de triangulos del resto de los poligonos existentes
                    foreach (EditPolyPolygon poly in polygons)
                    {
                        if(poly != p)
                        {
                            for (int j = 0; j < poly.vbTriangles.Count; j++)
                            {
                                if(poly.vbTriangles[j] >= i)
                                {
                                    poly.vbTriangles[j] -= 3;
                                }
                            }
                        }
                    }
                }
                else
                {
                    newIndexBuffer[w++] = indexBuffer[i];
                    newIndexBuffer[w++] = indexBuffer[i + 1];
                    newIndexBuffer[w++] = indexBuffer[i + 2];
                }
            }
            indexBuffer = newIndexBuffer;

            //Quitar referencia a aristas
            foreach (EditPolyEdge edge in p.edges)
            {
                edge.removePolygon(p);
            }

            //Eliminar aristas que quedaron aisladas
            foreach (EditPolyEdge edge in p.edges)
            {
                if (edge.faces.Count == 0)
                {
                    deleteEdge(edge);
                }
            }

            //Quitar de lista de poligonos
            for (int i = 0; i < polygons.Count; i++)
            {
                if (polygons[i] == p)
                {
                    polygons.RemoveAt(i);
                    break;
                }
            }

            //Registrar triangulos que se eliminaron (apuntando al indice del primer vertice de cada triangulo)
            //Se registran el valor original al que apuntaba el triangulo antes de haber borrado nada
            int currentDeletedCount = deletedTriangles.Count;
            for (int i = 0; i < p.vbTriangles.Count; i++)
            {
                int triDelIdx = p.vbTriangles[i];
                for (int j = 0; j < currentDeletedCount; j++)
                {
                    if (triDelIdx < deletedTriangles[j])
                    {
                        break;
                    }
                    triDelIdx += 3;
                }
                deletedTriangles.Add(triDelIdx);
            }
            deletedTriangles.Sort();
        }
예제 #5
0
 /// <summary>
 /// Busca si ambos poligonos tienen una arista igual.
 /// Si encontro retorna el indice de la arista igual de cada poligono.
 /// </summary>
 public static bool findShareEdgeBetweenPolygons(EditPolyPolygon p1, EditPolyPolygon p2, out int p1Edge, out int p2Edge)
 {
     for (int i = 0; i < p1.edges.Count; i++)
     {
         for (int j = 0; j < p2.edges.Count; j++)
         {
             if (EditablePolyUtils.sameEdge(p1.edges[i], p2.edges[j]))
             {
                 p1Edge = i;
                 p2Edge = j;
                 return true;
             }
         }
     }
     p1Edge = -1;
     p2Edge = -1;
     return false;
 }
예제 #6
0
        /*
        /// <summary>
        /// Filtrar todas las aristas que tiene un poligono y dejarle solo las que son parte del borde del poligono
        /// (Se quitan todas las aristas interiores)
        /// </summary>
        public static void computePolygonExternalEdges(Polygon p)
        {
            if (p.vertices.Count == 3)
                return;

            Vector3 planeNorm = p.getNormal();
            List<Edge> externalEdges = new List<Edge>();
            foreach (Edge e in p.edges)
            {
                //Half-plane entre la arista y la normal del poligono
                Vector3 vec = e.b.position - e.a.position;
                Vector3 n = Vector3.Cross(planeNorm, vec);
                Plane halfPlane = Plane.FromPointNormal(e.a.position, n);

                //Checkear el signo de todos los demas vertices del poligono
                bool first = true;
                TgcCollisionUtils.PointPlaneResult lastR = TgcCollisionUtils.PointPlaneResult.COINCIDENT;
                bool inside = false;
                foreach (Vertex v in p.vertices)
                {
                    if(v.vbIndex != e.a.vbIndex && v.vbIndex != e.b.vbIndex )
                    {
                        TgcCollisionUtils.PointPlaneResult r = TgcCollisionUtils.classifyPointPlane(v.position, halfPlane);
                        if(first)
                        {
                            first = false;
                            lastR = r;
                        } 
                        else if(r != lastR)
                        {
                            inside = true;
                            break;
                        }
                    }
                }
                if(!inside)
                {
                    externalEdges.Add(e);
                }
            }
            p.edges = externalEdges;
        }

        /// <summary>
        /// Ordenar los vertices del poligono en base al recorrido de sus aristas externas
        /// </summary>
        public static void sortPolygonVertices(Polygon p)
        {
            if (p.vertices.Count == 3)
                return;

            List<Vertex> sortedVertices = new List<Vertex>();
            Edge lastEdge = p.edges[0];
            for (int i = 1; i < p.edges.Count; i++)
            {
                sortedVertices.Add(lastEdge.a);
                bool found = false;
                foreach (Edge e in p.edges)
                {
                    if(lastEdge.b.vbIndex == e.a.vbIndex)
                    {
                        lastEdge = e;
                        found = true;
                        break;
                    }
                }
                if(!found)
                    throw new Exception("No se pudo recorrer aristas de poligono en loop. Poligono: " + p);
                
            }
            sortedVertices.Add(lastEdge.a);
            p.vertices = sortedVertices;
        }
        */


        /// <summary>
        /// Agregar un vertice a un poligono existente, ubicandolo en el medio de los dos vertices de la arista que compartian entre si
        /// </summary>
        public static void addVertexToPolygon(EditPolyPolygon p, EditPolyEdge sharedEdge, EditPolyVertex newV)
        {
            for (int i = 0; i < p.vertices.Count; i++)
            {
                if (p.vertices[i].vbIndex == sharedEdge.a.vbIndex)
                {
                    p.vertices.Add(null);
                    for (int j = p.vertices.Count - 2; j >= i + 1 ; j--)
                    {
                        p.vertices[j + 1] = p.vertices[j];
                    }
                    p.vertices[i + 1] = newV;
                    break;
                }
            }
        }