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); }
public TriangleVertexDLE(IFace face, Point3D position, Vector direction, TriangleFaceDLE giFace) : this(face, position, direction) { this.GIFaces.Add(giFace); }
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; } }