Ejemplo n.º 1
0
        private static void ProcessFaces(ref CMesh lCMesh, Plane lPlane)
        {
            CFace lNewFace = new CFace();

            lNewFace.Plane   = lPlane;
            lNewFace.Visible = true;

            int lNewFaceIndex = lCMesh.F.Length;

            for (int i = 0; i < lCMesh.F.Length; i++)
            {
                CFace lF = lCMesh.F[i];

                if (lF.Visible)
                {
                    for (int j = 0; j < lF.Edges.Length; j++)
                    {
                        int lEdgeIndex = lF.Edges[j];

                        lCMesh.V[lCMesh.E[lEdgeIndex].Vertices[0]].Occurs = 0;
                        lCMesh.V[lCMesh.E[lEdgeIndex].Vertices[1]].Occurs = 0;
                    }

                    int lStart, lEnd;
                    if (GetOpenPolyline(lCMesh, lF, out lStart, out lEnd))
                    {
                        CEdge lNewEdge      = new CEdge();
                        int   lNewEdgeIndex = lCMesh.E.Length;

                        lNewEdge.Vertices    = new int[2];
                        lNewEdge.Vertices[0] = lStart;
                        lNewEdge.Vertices[1] = lEnd;

                        lNewEdge.AddFace(i);
                        lNewEdge.AddFace(lNewFaceIndex);

                        lNewEdge.Visible = true;

                        lF.AddEdge(lNewEdgeIndex);
                        lNewFace.AddEdge(lNewEdgeIndex);

                        lCMesh.AppendEdge(lNewEdge);
                    }

                    lCMesh.F[i] = lF;
                }
            }

            lCMesh.AppendFace(lNewFace);
        }
Ejemplo n.º 2
0
        private static ClipOperationResult Clip(ref CMesh lCMesh, Plane lPlane)
        {
            ClipOperationResult lResult = ProcessVertices(ref lCMesh, lPlane);

            if (lResult != ClipOperationResult.Mixed)
            {
                return(lResult);
            }

            ProcessEdges(ref lCMesh, lPlane);

            ProcessFaces(ref lCMesh, lPlane);

            return(lResult);
        }
Ejemplo n.º 3
0
        private static bool GetOpenPolyline(CMesh lCMesh, CFace lF, out int lStart, out int lEnd)
        {
            for (int i = 0; i < lF.Edges.Length; i++)
            {
                int lEdgeIndex = lF.Edges[i];

                lCMesh.V[lCMesh.E[lEdgeIndex].Vertices[0]].Occurs++;
                lCMesh.V[lCMesh.E[lEdgeIndex].Vertices[1]].Occurs++;
            }

            lStart = -1;
            lEnd   = -1;

            for (int i = 0; i < lF.Edges.Length; i++)
            {
                int lEdgeIndex = lF.Edges[i];

                int lI0 = lCMesh.E[lEdgeIndex].Vertices[0];
                int lI1 = lCMesh.E[lEdgeIndex].Vertices[1];
                if (lCMesh.V[lI0].Occurs == 1)
                {
                    if (lStart == -1)
                    {
                        lStart = lI0;
                    }
                    else if (lEnd == -1)
                    {
                        lEnd = lI0;
                    }
                }

                if (lCMesh.V[lI1].Occurs == 1)
                {
                    if (lStart == -1)
                    {
                        lStart = lI1;
                    }
                    else if (lEnd == -1)
                    {
                        lEnd = lI1;
                    }
                }
            }

            return(lStart != -1);
        }
Ejemplo n.º 4
0
        public static CMesh CreateConvexPolyhedron(Plane[] lPlanes, Vector3 lCentre, Vector3 lSize)
        {
            AMesh lMeshToClip = CreateAMeshBox(lCentre, lSize);

            CMesh lClippedMesh = new CMesh(lMeshToClip);

            for (int i = 0; i < lPlanes.Length; i++)
            {
                ClipOperationResult lResult = Clip(ref lClippedMesh, lPlanes[i]);

                if (lResult == ClipOperationResult.AllNegative)
                {
                    break;
                }
            }

            return(lClippedMesh);
        }
Ejemplo n.º 5
0
        private static ClipOperationResult ProcessVertices(ref CMesh lCMesh, Plane lPlane)
        {
            int lPosCount = 0;
            int lNegCount = 0;

            for (int i = 0; i < lCMesh.V.Length; i++)
            {
                CVertex lV = lCMesh.V[i];

                if (lV.Visible)
                {
                    lV.Distance = Vector3.Dot(lPlane.Normal, lCMesh.V[i].Position) - lPlane.C;

                    if (lV.Distance >= s_Epsilon)
                    {
                        lPosCount++;
                    }
                    else if (lV.Distance <= -s_Epsilon)
                    {
                        lNegCount++;
                        lV.Visible = false;
                    }
                    else
                    {
                        lV.Distance = 0f;
                    }

                    lCMesh.V[i] = lV;
                }
            }

            if (lNegCount == 0)
            {
                return(ClipOperationResult.AllPositive);
            }

            if (lPosCount == 0)
            {
                return(ClipOperationResult.AllNegative);
            }

            return(ClipOperationResult.Mixed);
        }
Ejemplo n.º 6
0
        public static void ConvertMapToUnityObjects(ConvertMapSettings lSettings)
        {
            s_Settings = lSettings;

            //EditorGUI.BeginChangeCheck();

            if (s_Settings.UsingHDRPMaterials)
            {
                s_BaseColourMapID    = Shader.PropertyToID("_BaseColorMap");
                s_EmissionMapID      = Shader.PropertyToID("_EmissiveColorMap");
                s_EmissionColorID    = Shader.PropertyToID("_EmissiveColor");
                s_EmissionColorLDRID = Shader.PropertyToID("_EmissiveColor");
                s_CutoffEnabledID    = Shader.PropertyToID("_EmissiveColor");
                s_CutoffAlphaID      = Shader.PropertyToID("_AlphaCutoff");
            }
            else
            {
                s_BaseColourMapID = Shader.PropertyToID("_MainTex");
                s_EmissionMapID   = Shader.PropertyToID("_EmissionMap");
                s_EmissionColorID = Shader.PropertyToID("_EmissionColor");
                s_CutoffEnabledID = Shader.PropertyToID("_EmissiveColor");
                s_CutoffAlphaID   = Shader.PropertyToID("_Cutoff");
            }

            s_MaterialDic  = new Dictionary <string, Material>(s_Settings.TexDefs.Textures.Length);
            s_MaterialList = new List <Material>(s_Settings.TexDefs.Textures.Length);

            QMapLevel[] lCurrentLevels = GameObject.FindObjectsOfType <QMapLevel>();

            for (int i = 0; i < lCurrentLevels.Length; i++)
            {
                GameObject.DestroyImmediate(lCurrentLevels[i].gameObject);
            }

            GameObject lLevelObject = new GameObject(s_Settings.MapFile.name);
            QMapLevel  lQMap        = lLevelObject.AddComponent <QMapLevel>();

            lQMap.EntDefs = s_Settings.EntDefs;

            lLevelObject.isStatic = true;

            LevelData lLevelData = MapParser.ParseMapToLevelData(s_Settings.MapFile);

            int lBrushCount   = 0;
            int lTotalBrushes = 0;

            for (int i = 0; i < lLevelData.Entities.Length; i++)
            {
                lTotalBrushes += lLevelData.Entities[i].Brushes.Length;
            }

            List <UEntity> lUEnts = new List <UEntity>(lLevelData.Entities.Length);

            List <Vector3> lAllVerts = new List <Vector3>(10000);

            for (int i = 0; i < lLevelData.Entities.Length; i++)
            {
                List <Vector3> lEntityVerts = new List <Vector3>(1000);

                QEntity lQEnt   = lLevelData.Entities[i];
                EntDef  lEntDef = s_Settings.EntDefs.GetDefinition(lQEnt.Classname);

                GameObject lEntGO = null;
                UEntity    lUEnt  = null;

                if (lEntDef.Classname == null)
                {
                    lEntGO = new GameObject(i + " NULL Classname");
                    lUEnt  = lEntGO.AddComponent <UEmptyEntity>();
                }
                else if (lEntDef.ConvertedPrefab != null)
                {
                    lEntGO      = GameObject.Instantiate(lEntDef.ConvertedPrefab).gameObject;
                    lEntGO.name = i + " " + lQEnt.Classname;
                    lUEnt       = lEntGO.GetComponent <UEntity>();
                }
                else if (lEntDef.RuntimePrefab != null)
                {
                    lEntGO = new GameObject(i + " " + lQEnt.Classname);
                    lUEnt  = lEntGO.AddComponent <UEntity>();
                }
                else
                {
                    lEntGO = new GameObject(i + " " + lQEnt.Classname);
                    lUEnt  = lEntGO.AddComponent <UEmptyEntity>();
                }

                lUEnts.Add(lUEnt);

                lEntGO.isStatic = lEntDef.IsStatic;
                lEntGO.layer    = lEntDef.EntLayer.LayerIndex;

                lEntGO.transform.parent = lLevelObject.transform;

                List <GameObject>     lBrushes         = new List <GameObject>();
                List <ConvexMeshData> lConvexMeshDatas = new List <ConvexMeshData>();

                for (int j = 0; j < lQEnt.Brushes.Length; j++)
                {
                    QBrush lBrush = lQEnt.Brushes[j];

                    lBrushCount++;

                    CMesh lCMesh = ClipMesh.CreateConvexPolyhedron(lBrush.Planes);

                    List <Vector3> lBrushVertList = new List <Vector3>();

                    for (int v = 0; v < lCMesh.V.Length; v++)
                    {
                        if (lCMesh.V[v].Visible)
                        {
                            lBrushVertList.Add(lCMesh.V[v].Position);
                        }
                    }

                    Vector3 lMin;
                    Vector3 lMax;

                    GetMinMax(lBrushVertList.ToArray(), out lMin, out lMax);

                    Vector3 lSize          = lMax - lMin;
                    Vector3 lMidPointDelta = lMin + lSize * 0.5f;

                    lCMesh = ClipMesh.CreateConvexPolyhedron(lBrush.Planes, lMidPointDelta, lSize + Vector3.one * 0.2f);

                    lBrushVertList.Clear();

                    for (int v = 0; v < lCMesh.V.Length; v++)
                    {
                        if (lCMesh.V[v].Visible)
                        {
                            lBrushVertList.Add(lCMesh.V[v].Position);
                        }
                    }

                    GetMinMax(lBrushVertList.ToArray(), out lMin, out lMax);

                    lAllVerts.AddRange(lBrushVertList);
                    lEntityVerts.AddRange(lBrushVertList);

                    lSize          = lMax - lMin;
                    lMidPointDelta = lMin + lSize * 0.5f;

                    UMeshData lMeshData = lCMesh.GetMeshInformation(lMidPointDelta);

                    Texture[] lTextures = FetchTextures(lMeshData);

                    UpdateMaterials(lTextures);

                    UpdateMeshData(ref lMeshData, lTextures);

                    lConvexMeshDatas.Add(new ConvexMeshData(lMeshData, lMidPointDelta));

                    Mesh[] lNewMeshes = UMeshCreator.ConvertToMeshes(lMeshData);

#if UNITY_EDITOR
                    if (s_Settings.AutoGenerateUV2s)
                    {
                        for (int m = 1; m < lNewMeshes.Length; m++)
                        {
                            UnwrapParam lParam = new UnwrapParam();
                            lParam.angleError = 0.05f;
                            lParam.areaError  = 0.05f;
                            lParam.hardAngle  = 85f;
                            lParam.packMargin = 2f;

                            Unwrapping.GenerateSecondaryUVSet(lNewMeshes[m], lParam);
                        }
                    }
#endif
                    if (lEntDef.HasCollider || lEntDef.HasMesh)
                    {
                        GameObject lColliderGO = new GameObject("Brush " + j);

                        lBrushes.Add(lColliderGO);

                        if (lEntDef.HasCollider)
                        {
                            lColliderGO.transform.position = lMidPointDelta;
                            lColliderGO.transform.parent   = lEntGO.transform;

                            lColliderGO.isStatic = lEntDef.IsStatic;
                            lColliderGO.layer    = lEntDef.ColLayer.LayerIndex;

                            MeshCollider lMCollider = lColliderGO.AddComponent <MeshCollider>();
                            lMCollider.sharedMesh = lNewMeshes[0];
                            lMCollider.convex     = true;
                            lMCollider.isTrigger  = lEntDef.IsTrigger;

                            //if (s_Settings.SaveLevelAsAsset)
                            //AssetDatabase.CreateAsset(lNewMeshes[0], GetAssetPath(lEntGO.name, lColliderGO.name, lNewMeshes[0].name));
                        }

                        if (lEntDef.HasMesh)
                        {
                            for (int m = 1; m < lNewMeshes.Length; m++)
                            {
                                GameObject lMeshGO = new GameObject("Mesh " + (m - 1));

                                lMeshGO.transform.position = lMidPointDelta;
                                lMeshGO.transform.parent   = lColliderGO.transform;

                                lMeshGO.isStatic = lEntDef.IsStatic;
                                lMeshGO.layer    = lEntDef.MeshLayer.LayerIndex;

                                MeshFilter   lMFilter = lMeshGO.AddComponent <MeshFilter>();
                                MeshRenderer lMRender = lMeshGO.AddComponent <MeshRenderer>();

                                lMRender.sharedMaterial             = s_MaterialDic[lTextures[m - 1].name];
                                lMRender.receiveShadows             = true;
                                lMRender.shadowCastingMode          = UnityEngine.Rendering.ShadowCastingMode.On;
                                lMRender.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;

                                lMFilter.mesh = lNewMeshes[m];

                                //if (s_Settings.SaveLevelAsAsset)
                                //AssetDatabase.CreateAsset(lNewMeshes[m], GetAssetPath(lEntGO.name, lColliderGO.name, lMeshGO.name, lNewMeshes[m].name));

                                /**
                                 *
                                 *  Add Area Lights
                                 *
                                 **/

                                TexDef lTexDef;
                                if (s_Settings.TexDefs.HasDefinition(lTextures[m - 1].name, out lTexDef) && lTexDef.HasAreaLight)
                                {
                                    GameObject lAreaLightGO = new GameObject("AreaLight " + (m - 1));
                                    lAreaLightGO.transform.position = lMidPointDelta;
                                    lAreaLightGO.transform.parent   = lMeshGO.transform;

                                    lAreaLightGO.isStatic = lEntDef.IsStatic;
                                    //lAreaLightGO.layer = LayerMask.NameToLayer("AreaLight");

                                    lAreaLightGO.AddComponent <DestroyObjectOnSpawn>();

                                    MeshFilter   lALMFilter = lAreaLightGO.AddComponent <MeshFilter>();
                                    MeshRenderer lALMRender = lAreaLightGO.AddComponent <MeshRenderer>();

                                    lALMRender.sharedMaterial             = s_MaterialDic[lTextures[m - 1].name + "_AreaLightMAT"];
                                    lALMRender.receiveShadows             = false;
                                    lALMRender.shadowCastingMode          = UnityEngine.Rendering.ShadowCastingMode.Off;
                                    lALMRender.motionVectorGenerationMode = MotionVectorGenerationMode.ForceNoMotion;

                                    Mesh lAreaLightMesh = new Mesh();

                                    FaceInfo[] lFaceInfos = lMeshData.MeshFaceInfos[m];

                                    int lVertCount = 0;
                                    int lTriCount  = 0;

                                    for (int f = 0; f < lFaceInfos.Length; f++)
                                    {
                                        lVertCount += lFaceInfos[f].Indices.Length;

                                        if (lFaceInfos[f].Indices.Length > 2)
                                        {
                                            lTriCount += lFaceInfos[f].Indices.Length - 2;
                                        }
                                    }

                                    int lTriIndex = 0;

                                    Vector3[] lNewVerts   = new Vector3[lVertCount];
                                    Vector3[] lNormals    = new Vector3[lVertCount];
                                    int[]     lTriangles  = new int[lTriCount * 3];
                                    int[][]   lNewIndices = new int[lFaceInfos.Length][];

                                    int lVertIndex = 0;

                                    Vector3[] lPosVerts = lMeshData.PosVertices;
                                    Vector3[] lUVVerts  = lMeshData.UVVertices;

                                    for (int f = 0; f < lFaceInfos.Length; f++)
                                    {
                                        FaceInfo lFaceInfo = lFaceInfos[f];
                                        Plane    lPlane    = lFaceInfo.Plane;
                                        int[]    lIndices  = lFaceInfo.Indices;

                                        lNewIndices[f] = new int[lIndices.Length];

                                        for (int v = 0; v < lIndices.Length; v++)
                                        {
                                            Vector3 lVertPos = lPosVerts[lIndices[v]];
                                            Vector3 lVertUV  = lUVVerts[lIndices[v]];

                                            lNewVerts[lVertIndex] = (lVertPos * lTexDef.AreaSizeScale) - lPlane.Normal * lTexDef.AreaDisplacement;
                                            lNormals[lVertIndex]  = -lPlane.Normal;

                                            lNewIndices[f][v] = lVertIndex;

                                            lVertIndex++;
                                        }

                                        for (int v = 0; v < lNewIndices[f].Length - 2; v++)
                                        {
                                            lTriangles[lTriIndex++] = lNewIndices[f][0];
                                            lTriangles[lTriIndex++] = lNewIndices[f][v + 1];
                                            lTriangles[lTriIndex++] = lNewIndices[f][v + 2];
                                        }
                                    }

                                    lAreaLightMesh.vertices  = lNewVerts;
                                    lAreaLightMesh.triangles = lTriangles;
                                    lAreaLightMesh.normals   = lNormals;

                                    lAreaLightMesh.RecalculateTangents();
                                    lAreaLightMesh.RecalculateBounds();

                                    lAreaLightMesh.name = "Area Light Mesh";
#if UNITY_EDITOR
                                    Unwrapping.GenerateSecondaryUVSet(lAreaLightMesh); // TODO May be always needed
#endif
                                    lALMFilter.mesh = lAreaLightMesh;

                                    //if (s_Settings.SaveLevelAsAsset)
                                    //AssetDatabase.CreateAsset(lAreaLightMesh, GetAssetPath(lEntGO.name, lColliderGO.name, lMeshGO.name, lAreaLightMesh.name));
                                }
                            }
                        }
                    }
                }

                {
                    List <Vector3>  lConvexVertList = new List <Vector3>();
                    List <FaceInfo> lFaceList       = new List <FaceInfo>();

                    int lIndexShift = 0;

                    for (int c = 0; c < lConvexMeshDatas.Count; c++)
                    {
                        int     lVertCount = lConvexMeshDatas[c].MeshData.PosVertices.Length;
                        Vector3 lDeltaPos  = lConvexMeshDatas[c].DeltaPos;

                        for (int v = 0; v < lVertCount; v++)
                        {
                            lConvexVertList.Add(lConvexMeshDatas[c].MeshData.PosVertices[v] + lDeltaPos);
                        }

                        for (int f = 0; f < lConvexMeshDatas[c].MeshData.FaceInfos.Length; f++)
                        {
                            FaceInfo lInfo = lConvexMeshDatas[c].MeshData.FaceInfos[f];

                            for (int fi = 0; fi < lInfo.Indices.Length; fi++)
                            {
                                lInfo.Indices[fi] += lIndexShift;
                            }

                            lFaceList.Add(lInfo);
                        }

                        lIndexShift += lVertCount;
                    }

                    Vector3 lMin, lMax;

                    GetMinMax(lConvexVertList.ToArray(), out lMin, out lMax);

                    Vector3 lSize     = lMax - lMin;
                    Vector3 lMidPoint = lMin + lSize * 0.5f;

                    for (int v = 0; v < lConvexVertList.Count; v++)
                    {
                        lConvexVertList[v] -= lMidPoint;
                    }

                    UMeshData lConvexData = new UMeshData();
                    lConvexData.PosVertices = lConvexData.UVVertices = lConvexVertList.ToArray();

                    lConvexData.MeshFaceInfos    = new FaceInfo[1][];
                    lConvexData.MeshFaceInfos[0] = lFaceList.ToArray();

                    if (lEntDef.HasConvexCollider && lConvexMeshDatas.Count > 0)
                    {
                        Mesh[] lConvexMesh = UMeshCreator.ConvertToMeshes(lConvexData);

                        //if (!AssetDatabase.IsValidFolder("Assets/" + s_Settings.MapFile.name))
                        //AssetDatabase.CreateFolder("Assets", s_Settings.MapFile.name);

                        //AssetDatabase.CreateAsset(lConvexMesh[0], "Assets/" + s_Settings.MapFile.name + "/OriginalMesh.asset");

                        MeshCollider lMCollider = lUEnt.gameObject.AddComponent <MeshCollider>();
                        lMCollider.sharedMesh = lConvexMesh[0];
                        lMCollider.convex     = true;
                        lMCollider.isTrigger  = lEntDef.IsConvexTrigger;

                        //if (s_Settings.SaveLevelAsAsset)
                        //AssetDatabase.CreateAsset(lConvexMesh[0], GetAssetPath(lEntGO.name, "CONVEX", lConvexMesh[0].name));
                    }

                    if (lQEnt.Classname == "volume_enemy_spawn")
                    {
                        bool lWhat = true;
                    }

                    lUEnt.Extents = new Extents3D(lMidPoint, lSize);

                    lUEnt.SetupEntity(lQEnt);

                    Vector3 lValue;
                    if (lUEnt.GetValue("origin", out lValue))
                    {
                        lUEnt.transform.position = lValue;
                    }
                    else if (lBrushes.Count > 0)
                    {
                        for (int b = 0; b < lBrushes.Count; b++)
                        {
                            lBrushes[b].transform.localPosition = lBrushes[b].transform.position - lMidPoint;
                        }

                        lUEnt.transform.position = lMidPoint;
                    }
                }
            }

            Vector3 lAllMin, lAllMax;

            GetMinMax(lAllVerts.ToArray(), out lAllMin, out lAllMax);

            Vector3 lAllSize   = lAllMax - lAllMin;
            Vector3 lAllCenter = lAllMin + lAllSize * 0.5f;

            lQMap.Extents = new Extents3D(lAllCenter, lAllSize);

            //var lSO = new SerializedObject(lLevelObject);

            //if (lSO.ApplyModifiedProperties())
            //{
            //    bool lBreakpoint = false;
            //}

            //if (s_Settings.SaveLevelAsAsset)
            //{
            bool lSuccess;


            //for (int i = 0; i < s_MaterialList.Count; i++)
            //AssetDatabase.CreateAsset(s_MaterialList[i], "Assets/" + s_Settings.MapFile.name + "_MAT " + i + ".asset");

            //PrefabUtility.SaveAsPrefabAsset(lLevelObject, "Assets/" + s_Settings.MapFile.name + ".prefab", out lSuccess);
            //AssetDatabase.Refresh();
            //AssetDatabase.SaveAssets();
            //}

            //if (EditorGUI.EndChangeCheck())
            //{
            //    bool lBreakpoint = false;
            //}

#if UNITY_EDITOR
            EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
#endif
        }
Ejemplo n.º 7
0
        private static void ProcessEdges(ref CMesh lCMesh, Plane lPlane)
        {
            for (int i = 0; i < lCMesh.E.Length; i++)
            {
                CEdge lE = lCMesh.E[i];

                if (lE.Visible)
                {
                    float lD0 = lCMesh.V[lE.Vertices[0]].Distance;
                    float lD1 = lCMesh.V[lE.Vertices[1]].Distance;

                    if (lD0 <= 0f && lD1 <= 0f)
                    {
                        for (int j = 0; j < lE.Faces.Length; j++)
                        {
                            CFace lF = lCMesh.F[lE.Faces[j]];
                            lF.RemoveEdge(i);
                            if (lF.Edges.Length == 0)
                            {
                                lF.Visible = false;
                            }

                            lCMesh.F[lE.Faces[j]] = lF;
                        }

                        lE.Visible  = false;
                        lCMesh.E[i] = lE;

                        continue;
                    }

                    if (lD0 >= 0f && lD1 >= 0f)
                    {
                        lCMesh.E[i] = lE;
                        continue;
                    }

                    float   lT         = lD0 / (lD0 - lD1);
                    Vector3 lDelta0    = (1f - lT) * lCMesh.V[lE.Vertices[0]].Position;
                    Vector3 lDelta1    = lT * lCMesh.V[lE.Vertices[1]].Position;
                    Vector3 lIntersect = lDelta0 + lDelta1;

                    int lIndex = lCMesh.V.Length;

                    CVertex lNewVertex = new CVertex(lIntersect);

                    lCMesh.AppendVertex(lNewVertex);

                    if (lD0 > 0)
                    {
                        lE.Vertices[1] = lIndex;
                    }
                    else
                    {
                        lE.Vertices[0] = lIndex;
                    }

                    lCMesh.E[i] = lE;
                }
            }
        }