private void AddCustomLine(int vertex1Index, int vertex2Index, int vertex3Index, Vector3[] meshVertices, List <MeshLine> customLines) { Vector3 point1 = meshVertices[vertex1Index]; Vector3 point2 = meshVertices[vertex2Index]; MeshLine customLine = new MeshLine(point1, point2); if (!customLines.Contains(customLine)) { customLine.degraded_rectangle = new DegradedRectangle(); customLine.degraded_rectangle.vertex1 = vertex1Index; customLine.degraded_rectangle.vertex2 = vertex2Index; customLine.degraded_rectangle.triangle1_vertex3 = vertex3Index; customLine.degraded_rectangle.triangle2_vertex3 = -1; customLines.Add(customLine); } else { int i = customLines.IndexOf(customLine); var rectangle = customLines[i].degraded_rectangle; if (rectangle.triangle2_vertex3 == -1) { rectangle.triangle2_vertex3 = vertex3Index; customLines[i].degraded_rectangle = rectangle; } } }
public void get_lines_Acut(Vector3 CP1, Vector3 CP2) { Vector3 CP1_relative; Vector3 CP2_relative; Transform temp_TRANS; MeshLine cut_line; foreach (MeshData mesh_data in RC.IS.MD_TRANS_DICT.Keys.ToArray()) { temp_TRANS = RC.IS.MD_TRANS_DICT[mesh_data]; CP1_relative = CP1 - temp_TRANS.position; CP2_relative = CP2 - temp_TRANS.position; cut_line = new MeshLine(); cut_line.line_cal(new MeshPoint(CP1_relative, true), new MeshPoint(CP2_relative, true)); cut_line.infinite = true; Debug.Log(cut_line.VarToString()); if (cut(mesh_data, cut_line)) { mesh_data.clean_destroy(); Destroy(temp_TRANS.gameObject); } } Debug.Log("================================"); }
public MeshPoint[] line_inter_cal(MeshLine CL) { List <MeshPoint> mesh_points = new List <MeshPoint>(); Vector3 pos; bool cornor = false; HashSet <Vector3> pos_set = new HashSet <Vector3>(); foreach (MeshLine mesh_line in Mesh_lines) { pos = MeshLine.line_inter_cal(mesh_line, CL, out cornor); if (!(pos == RC.NANVector3)) { if (cornor) { if (pos_set.Contains(pos)) { create_cut_p(ref mesh_points, pos); } else { pos_set.Add(pos); } } else { create_cut_p(ref mesh_points, pos); } } } return(mesh_points.ToArray()); }
/// <summary> /// 添加三角面v1、v2构成退化四边形,存储到临时的customLines中. /// </summary> /// <param name="vertex1Index">相同边顶点1</param> /// <param name="vertex2Index">相同边顶点2</param> /// <param name="vertex3Index">三角面顶点3</param> /// <param name="meshVertices">网格顶点坐标数组</param> /// <param name="customLines">退化四边形集合</param> private void AddCustomLine(int vertex1Index, int vertex2Index, int vertex3Index, Vector3[] meshVertices, List <MeshLine> customLines) { Vector3 point1 = meshVertices[vertex1Index]; Vector3 point2 = meshVertices[vertex2Index]; MeshLine customLine = new MeshLine(point1, point2); if (!customLines.Contains(customLine)) //集合中没有对应的相同边. { customLine.degraded_rectangle = new DegradedRectangle(); customLine.degraded_rectangle.vertex1 = vertex1Index; customLine.degraded_rectangle.vertex2 = vertex2Index; customLine.degraded_rectangle.triangle1_vertex3 = vertex3Index; customLine.degraded_rectangle.triangle2_vertex3 = -1; //没有相同边的退化四边形v2_3值就是-1.(该边叫做 边界边缘) customLines.Add(customLine); } else //集合中有相同边. { int i = customLines.IndexOf(customLine); DegradedRectangle rectangle = customLines[i].degraded_rectangle; //退化四边形的第二个三角面 顶点3 存储到triangle2_vertex3. if (rectangle.triangle2_vertex3 == -1) { rectangle.triangle2_vertex3 = vertex3Index; customLines[i].degraded_rectangle = rectangle; } } }
public static Vector3 line_inter_cal(MeshLine ML1, MeshLine ML2, out bool cornor) { cornor = false; Vector3 pos = new Vector3(); if ((ML1.vert_line && ML2.vert_line) || (ML1.k == ML2.k)) { return(RC.NANVector3); } if (ML1.vert_line) { pos = ML2.point_calx(ML1.vert_x); } else if (ML2.vert_line) { pos = ML1.point_calx(ML2.vert_x); } else { float x = -(ML2.b - ML1.b) / (ML2.k - ML1.k); pos = ML1.point_calx(x); } Debug.Log("##### " + pos.ToString("F2")); if (ML1.infinite && !ML2.infinite) { int result = ML2.point_in_cal(pos); //Debug.Log("result " + result + " pos "+ pos.ToString("F2")); if (result == 0) { cornor = true; } if (result >= 0) { return(pos); } } else if (!ML1.infinite && ML2.infinite) { int result = ML1.point_in_cal(pos); //Debug.Log("ML1 " + ML1.VarToString()); //Debug.Log("result " + result + " pos " + pos.ToString("F2")); if (result == 0) { cornor = true; } if (result >= 0) { return(pos); } } return(RC.NANVector3); }
public MeshData[] cut(MeshPoint MP1, MeshPoint MP2) { //Debug.Log("cut1 " + MP1.pos); //Debug.Log("cut2 " + MP2.pos); MeshLine cut_line = new MeshLine(); cut_line.line_cal(MP1, MP2); MP1.uv_cal(); MP2.uv_cal(); return(points_cal(cut_line, MP1, MP2)); }
void Start() { // mesh line meshLine = gameObject.AddComponent <MeshLine>(); meshLine.Init(); //InitDebugPoints(); GenerateRotations(); if (autoDraw) { StartCoroutine(DrawInfiniteLoop()); } }
private static Point2[] CreatePointsAlongLine(MeshLine line, double unitLength, IReadOnlyList <Point2> points) { var p1 = points[line.V1]; var p2 = points[line.V2]; var num = (int)Math.Ceiling(Math.Sqrt(line.SqrLength) / unitLength); var p = new Point2[num - 1]; for (var i = 1; i < num; i++) { p[i - 1] = new Point2(p1.X + i * (p2.X - p1.X) / num, p1.Y + i * (p2.Y - p1.Y) / num); } return(p); }
/// <summary> /// vertices need to be sorted first; /// </summary> private void line_regener() { Mesh_lines = new List <MeshLine>(); MeshLine mesh_line; for (int i = 0; i < Verticies.Count - 1; i++) { mesh_line = new MeshLine(); mesh_line.line_cal(Verticies[i], Verticies[i + 1]); Mesh_lines.Add(mesh_line); } mesh_line = new MeshLine(); mesh_line.line_cal(Verticies[Verticies.Count - 1], Verticies[0]); Mesh_lines.Add(mesh_line); }
// 初始化 public void Init(Material material) { this.material = material; render_object = RenderObject.Create(null, null, Vector3.zero, Quaternion.identity); render_object.mesh_render.material = material; render_object.mesh_render.castShadows = true; render_object.mesh_render.receiveShadows = true; render_object.go.name = "Build"; flag = MeshEnableFlag.Vertice | MeshEnableFlag.Normal | MeshEnableFlag.Triangle | MeshEnableFlag.Color | MeshEnableFlag.UV; segment_mesh = new RepeatSegmentMesh(3, 3, 100, flag); segment_mesh.SegmentData.MarkTriangleTopology(); segment_mesh.ProcedureMesher.SetMesh32(); mesh_line = new MeshLine(); }
private MeshData[] points_cal(MeshLine cut_line, MeshPoint p1, MeshPoint p2) { MeshData Fhalf = new MeshData(); MeshData Shalf = new MeshData(); List <MeshPoint> FHMP = new List <MeshPoint>(); List <MeshPoint> SHMP = new List <MeshPoint>(); foreach (MeshPoint vert in Verticies) { int pos_cal = cut_line.position_cal(vert); if (pos_cal == 1) { FHMP.Add(vert); } else if (pos_cal == 0) { FHMP.Add(vert.clone()); SHMP.Add(vert); } else { SHMP.Add(vert); } } MeshPoint p1C = p1.clone(); MeshPoint p2C = p2.clone(); FHMP.Add(p1C); FHMP.Add(p2C); SHMP.Add(p1); SHMP.Add(p2); Fhalf.Verticies = FHMP; Shalf.Verticies = SHMP; Fhalf.MD_regener(); Shalf.MD_regener(); Fhalf.set_init_UVs(this.UV_poss); Shalf.set_init_UVs(this.UV_poss); return(new MeshData[] { Fhalf, Shalf }); }
public override bool Equals(object obj) { if (obj == null || GetType() != obj.GetType()) { return(false); } MeshLine line2 = (MeshLine)obj; if (point1 == line2.point1 && point2 == line2.point2) { return(true); } if (point1 == line2.point2 && point2 == line2.point1) { return(true); } return(false); }
private bool cut(MeshData mesh_data, MeshLine cut_line) { MeshPoint[] cut_points = mesh_data.line_inter_cal(cut_line); if (cut_points.Length < 2) { return(false); } Vector3 random_vec = new Vector3(Random.Range(0.0f, 1.0f), Random.Range(0.0f, 1.0f), 0.0f); MeshData[] cut_meshs = mesh_data.cut(cut_points[0], cut_points[1]); Transform NM1_TRANS = MeshCreater.IS.create_mesh(cut_meshs[0], false, trans_pos: RC.IS.MD_TRANS_DICT[mesh_data].localPosition + random_vec); Transform NM2_TRANS = MeshCreater.IS.create_mesh(cut_meshs[1], false, trans_pos: RC.IS.MD_TRANS_DICT[mesh_data].localPosition - random_vec); Debug.Log("mesh1 " + cut_meshs[0].VarToString()); Debug.Log("mesh2 " + cut_meshs[1].VarToString()); return(true); }
/// <summary> /// Asks the mesher to interatively build the mesh, generating improvements in every pass /// </summary> /// <returns></returns> public Model TriangulateIteratively(IProgress <TaskProgress> progressReport) { var elementSizeSquared = ElementSize * ElementSize; TriangulateInternal(); // can'transform continue if no faces if (_faces.First == null) { return(null); } var lines = new List <MeshLine>(); _improvement.Capacity = 10000; const float improveFactor = 0.86f; int numImprovements; var iteration = 0; do { lines.Clear(); var first = _faces.First; while (first != null) { var face = first.Value; var v1 = face.v1; var v2 = face.v2; var v3 = face.v3; var meshLine1 = new MeshLine(v1, v2, _vertices); var meshLine2 = new MeshLine(v2, v3, _vertices); var meshLine3 = new MeshLine(v3, v1, _vertices); if (meshLine1.SqrLength > elementSizeSquared && !lines.Contains(meshLine1)) { lines.Add(meshLine1); } if (meshLine2.SqrLength > elementSizeSquared && !lines.Contains(meshLine2)) { lines.Add(meshLine2); } if (meshLine3.SqrLength > elementSizeSquared && !lines.Contains(meshLine3)) { lines.Add(meshLine3); } first = first.Next; } // determine if any improvements can be made numImprovements = 0; foreach (var meshLine in lines) { // see if this line can be broken down into smaller elements var points = CreatePointsAlongLine(meshLine, ElementSize, _vertices); //test every hypothetical point generated along the line to see if it is a viable improvement foreach (var t in points) { var length = TestImprovement(ElementSize, t, _vertices[meshLine.V1], _vertices[meshLine.V2]); if (length > ElementSize * improveFactor) { _improvement.Add(t); numImprovements++; } } } // add the improvements to the mesh now var verticeCount = _vertices.Count; _vertices.AddRange(_improvement); _improvement.Clear(); // iterate over this mesh to join the vertices up based on delauny triangulation if (!IterateMesh(verticeCount, iteration + 1, progressReport)) { return(null); } iteration++; }while (numImprovements > 0 && iteration < SmoothingPasses); // make smoothing passes enabled this mesh if (SmoothingPasses > 0) { var lastProgress = 0; var loopPointsCount = _loops.Sum(points => points.Count); for (var smoothingIteration = 0; smoothingIteration < SmoothingPasses; smoothingIteration++) { for (var i = loopPointsCount; i < _vertices.Count; i++) { float x = 0; float y = 0; float factor = 0; var triangleNode = _faces.First; while (triangleNode != null) { var face = triangleNode.Value; var v1 = face.v1; var v2 = face.v2; var v3 = face.v3; if (v1 == i || v2 == i || v3 == i) { var p1 = _vertices[v1]; var p2 = _vertices[v2]; var p3 = _vertices[v3]; switch (SmoothingMode) { case SmoothingMode.Points: if (v1 != i) { x += p1.X; y += p1.Y; factor++; } if (v2 != i) { x += p2.X; y += p2.Y; factor++; } if (v3 != i) { x += p3.X; y += p3.Y; factor++; } break; case SmoothingMode.Area: var centroid = new Point2((p1.X + p2.X + p3.X) / 3f, (p1.Y + p2.Y + p3.Y) / 3f); var area = Area2D(p1, p2, p3); if (v1 != i) { x += area * centroid.X; y += area * centroid.Y; factor += area; } if (v2 != i) { x += area * centroid.X; y += area * centroid.Y; factor += area; } if (v3 != i) { x += area * centroid.X; y += area * centroid.Y; factor += area; } break; } } triangleNode = triangleNode.Next; } // add the vertice _vertices[i] = new Point2(x / factor, y / factor); // report progress to date var progress = (int)(100f * (i - loopPointsCount) / (_vertices.Count - loopPointsCount)); if (progress > lastProgress) { lastProgress = progress; progressReport.Report(new TaskProgress { ProgressPercentage = progress, Text = "Smoothing / Iteration " + (smoothingIteration + 1) + " ..." }); } } } } CalculateQuality(); //now returns model return(BuildModel()); }