Exemplo n.º 1
0
        static void GenerateRenderPointsFace(TriangleFaceDLE face, RenderPointsStructureDLE giRenderPointsStructure)
        {
            // TODO: переменная будет использована просто для поддержки цикла, но лучше переделать на нормальный while ( newFace != null )
            var result = new List <TriangleFaceDLE> {
                face
            };

            // добавляем грань в расчетные грани и добавляем 3 вершины грани в расчетные вершины,
            // далее будем добавлять только новую грань и вершину
            giRenderPointsStructure.RenderPointsFace.Add(face);


            giRenderPointsStructure.RenderPointsVertexes.AddRange(face.Vertexes);
            //foreach (var vertex in face.Vertexes)
            //{
            //    if ( !giRenderPointsStructure.RenderPointsVertexes.Contains( vertex ) )
            //        giRenderPointsStructure.RenderPointsVertexes.Add( vertex );
            //    else
            //        throw new Exception("xx");
            //}



            for (int i = 0; i < result.Count; i++)
            {
                var currentFace = result[i];

                //if ( currentFace.RenderPoints.Count > 1000 )
                while (currentFace.RenderPoints.Count > 64)
                {
                    // divide face
                    // Ищем самую длинную сторону
                    Point3D v12 = currentFace.Vertexes[0].Position - currentFace.Vertexes[1].Position;
                    Point3D v23 = currentFace.Vertexes[1].Position - currentFace.Vertexes[2].Position;
                    Point3D v31 = currentFace.Vertexes[2].Position - currentFace.Vertexes[0].Position;

                    int[] k;
                    if (v12.Length2 > v23.Length2 && v12.Length2 > v31.Length2)
                    {
                        k = new int[] { 0, 1, 2 }
                    }
                    ;
                    else if (v23.Length2 > v12.Length2 && v23.Length2 > v31.Length2)
                    {
                        k = new int[] { 1, 2, 0 }
                    }
                    ;
                    else
                    {
                        k = new int[] { 2, 0, 1 }
                    };

                    // Вычисляю координату новой вершины - центра гиппотренузы
                    Point3D p = (currentFace.Vertexes[k[0]].Position - currentFace.Vertexes[k[1]].Position) / 2
                                + currentFace.Vertexes[k[1]].Position;
                    var newVertexDirection      = TriangleFaceDLE.GetNearestRenderPoint(currentFace.RenderPoints, p).Direction;
                    TriangleVertexDLE newVertex = new TriangleVertexDLE(currentFace.Face, p, newVertexDirection, currentFace);

                    // Создаю клон разбиваемого элемента
                    //MeshFace mf = (MeshFace)this[index].Clone();


                    // Меняем вершину у делимого элемента


                    var newPoints = new TriangleVertexDLE[3];
                    newPoints[k[1]] = currentFace.Vertexes[k[2]];
                    newPoints[k[2]] = currentFace.Vertexes[k[0]];
                    newPoints[k[0]] = newVertex;

                    // changed vertex
                    var changedVertex = currentFace.Vertexes[k[0]];
                    changedVertex.GIFaces.Remove(currentFace);

                    currentFace.Vertexes[k[0]] = newVertex;

                    var newFace = new TriangleFaceDLE(currentFace.Face, newPoints, currentFace.Face.Normal);
                    newPoints[0].GIFaces.Add(newFace);
                    newPoints[1].GIFaces.Add(newFace);
                    newPoints[2].GIFaces.Add(newFace);

                    IList <RenderPoint> oldPoints = new List <RenderPoint>();
                    foreach (var renderPoint in currentFace.RenderPoints)
                    {
                        if (!currentFace.IsPointInTriangleFace2(renderPoint))
                        {
                            //currentFace.RenderPoints.Remove( renderPoint );
                            newFace.RenderPoints.Add(renderPoint);
                        }
                        else
                        {
                            oldPoints.Add(renderPoint);
                        }
                    }

                    currentFace.RenderPoints = oldPoints;

                    //foreach ( var renderPoint in newFace.RenderPoints )
                    //    currentFace.RenderPoints.Remove( renderPoint );

                    if (newFace.RenderPoints.Count > 0)
                    {
                        // новая грань пригодна для расчетов, так как в ней есть расчетные точки
                        result.Add(newFace);
                        giRenderPointsStructure.RenderPointsFace.Add(newFace);
                        giRenderPointsStructure.RenderPointsVertexes.Add(newVertex);
                    }
                }
            }

            //return result;
        }
    }