Esempio n. 1
0
        RenderPointsStructureDLE GenerateCalculatedStructure(RenderPointsStructure renderPointsStructure)
        {
            var tick   = Environment.TickCount;
            var result = new RenderPointsStructureDLE();

            foreach (var obj in this.scene.Objects)
            {
                foreach (var face in obj.Faces)
                {
                    if (face.Material.Reflectance == null)
                    {
                        continue;
                    }

                    if (!renderPointsStructure.FaceRenderPoints.ContainsKey(face))
                    {
                        continue;
                    }

                    var a = new TriangleFaceDLE(face, renderPointsStructure.FaceRenderPoints[face]);
                    GenerateRenderPointsFace(a, result);
                }
            }


            // Generate center points && set shadow points to vertexes
            foreach (var face in result.RenderPointsFace)
            {
                var center    = (face.Vertexes[0].Position + face.Vertexes[1].Position + face.Vertexes[2].Position) / 3;
                var direction = (face.Vertexes[0].Direction + face.Vertexes[1].Direction + face.Vertexes[2].Direction) / 3;
                direction.Normalize();
                var vertexCenter = new TriangleVertexDLE(face.Face, center, direction, face);
                face.Center = vertexCenter;
                result.RenderPointsVertexes.Add(vertexCenter);
            }


            if (this.Log != null)
            {
                tick = Environment.TickCount - tick;
                this.Log.Message(string.Format("GiDoubleLocalEstimation. GenerateCalculatedStructure: SubMeshes = {0}, CalcPoints = {1}, Time = {2}", result.RenderPointsFace.Count, result.RenderPointsVertexes.Count, tick));
            }
            return(result);
        }
Esempio n. 2
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;
        }
    }