Пример #1
0
        /// <summary>
        ///     Eliminar un vertice
        /// </summary>
        private void deleteVertex(EditPolyVertex v)
        {
            //Quitar referencia de todas las aristas que lo usan
            foreach (var edge in v.edges)
            {
                edge.a = null;
                edge.b = null;
            }

            //Eliminar aristas
            foreach (var edge in v.edges)
            {
                deleteEdge(edge);
            }

            //Quitar vertice de lista de vertices
            Vertices.RemoveAt(v.vbIndex);

            //Shift de vertex buffer
            for (var i = 0; i < Vertices.Count; i++)
            {
                Vertices[i].vbIndex = i;
            }

            //Ajustar indices en index buffer
            for (var i = 0; i < IndexBuffer.Length; i++)
            {
                if (IndexBuffer[i] >= v.vbIndex)
                {
                    IndexBuffer[i]--;
                }
            }
        }
Пример #2
0
        /// <summary>
        ///     Obtener la lista de vertices originales del mesh
        /// </summary>
        private List <EditPolyVertex> getMeshOriginalVertexData(TgcMesh origMesh)
        {
            var origVertices = new List <EditPolyVertex>();

            switch (origMesh.RenderType)
            {
            case TgcMesh.MeshRenderType.VERTEX_COLOR:
                var verts1 = (TgcSceneLoader.VertexColorVertex[])origMesh.D3dMesh.LockVertexBuffer(
                    typeof(TgcSceneLoader.VertexColorVertex), LockFlags.ReadOnly, origMesh.D3dMesh.NumberVertices);
                for (var i = 0; i < verts1.Length; i++)
                {
                    var v = new EditPolyVertex();
                    v.position = verts1[i].Position;

                    /*v.normal = verts1[i].Normal;
                     * v.color = verts1[i].Color;*/
                    origVertices.Add(v);
                }
                origMesh.D3dMesh.UnlockVertexBuffer();
                break;

            case TgcMesh.MeshRenderType.DIFFUSE_MAP:
                var verts2 = (TgcSceneLoader.DiffuseMapVertex[])origMesh.D3dMesh.LockVertexBuffer(
                    typeof(TgcSceneLoader.DiffuseMapVertex), LockFlags.ReadOnly, origMesh.D3dMesh.NumberVertices);
                for (var i = 0; i < verts2.Length; i++)
                {
                    var v = new EditPolyVertex();
                    v.position = verts2[i].Position;

                    /*v.normal = verts2[i].Normal;
                     * v.texCoords = new TGCVector2(verts2[i].Tu, verts2[i].Tv);
                     * v.color = verts2[i].Color;*/
                    origVertices.Add(v);
                }
                origMesh.D3dMesh.UnlockVertexBuffer();
                break;

            case TgcMesh.MeshRenderType.DIFFUSE_MAP_AND_LIGHTMAP:
                var verts3 = (TgcSceneLoader.DiffuseMapAndLightmapVertex[])origMesh.D3dMesh.LockVertexBuffer(
                    typeof(TgcSceneLoader.DiffuseMapAndLightmapVertex), LockFlags.ReadOnly,
                    origMesh.D3dMesh.NumberVertices);
                for (var i = 0; i < verts3.Length; i++)
                {
                    var v = new EditPolyVertex();
                    v.position = verts3[i].Position;

                    /*v.normal = verts3[i].Normal;
                     * v.texCoords = new TGCVector2(verts3[i].Tu0, verts3[i].Tv0);
                     * v.color = verts3[i].Color;
                     * v.texCoords2 = new TGCVector2(verts3[i].Tu1, verts3[i].Tv1);*/
                    origVertices.Add(v);
                }
                origMesh.D3dMesh.UnlockVertexBuffer();
                break;
            }

            return(origVertices);
        }
Пример #3
0
 /// <summary>
 /// Agrega un nuevo vertice a la lista si es que ya no hay otro igual.
 /// Devuelve el indice del nuevo vertice o del que ya estaba.
 /// </summary>
 public static int addVertexToListIfUnique(List <EditPolyVertex> vertices, EditPolyVertex v)
 {
     for (int i = 0; i < vertices.Count; i++)
     {
         if (EditablePolyUtils.sameVextex(vertices[i], v))
         {
             return(i);
         }
     }
     v.vbIndex = vertices.Count;
     v.edges   = new List <EditPolyEdge>();
     vertices.Add(v);
     return(v.vbIndex);
 }
Пример #4
0
        /// <summary>
        /// Actualizar estructuras internas en base a mesh original.
        /// Cuando se vuelve a entrar al modo EditablePoly luego de la primera vez.
        /// </summary>
        public void updateValuesFromMesh(TgcMesh mesh)
        {
            this.mesh = mesh;
            List <EditPolyVertex> origVertices = getMeshOriginalVertexData(mesh);

            for (int i = 0; i < origVertices.Count; i++)
            {
                EditPolyVertex origV = origVertices[i];
                EditPolyVertex v     = vertices[indexBuffer[i]];
                v.position = origV.position;

                /*v.normal = origV.normal;
                 * v.color = origV.color;
                 * v.texCoords = origV.texCoords;
                 * v.texCoords2 = origV.texCoords2;*/
            }
            dirtyValues = true;
        }
Пример #5
0
 /// <summary>
 /// Indica si dos vertices son iguales
 /// </summary>
 /// <returns></returns>
 public static bool sameVextex(EditPolyVertex a, EditPolyVertex b)
 {
     return(equalsVector3(a.position, b.position));
 }
Пример #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;
                }
            }
        }
Пример #7
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);
        }