static Tri[] parseFace(int vertexCount, string[] indices) { MeshPoint[] p = new MeshPoint[indices.Length - 1]; for (int i = 0; i < p.Length; i++) { p[i] = parsePoint(vertexCount, indices[i + 1]); } return Triangulate(p); //return new Face(p); }
// Takes an array of points and returns an array of triangles. // The points form an arbitrary polygon. static Tri[] Triangulate(MeshPoint[] ps) { List<Tri> ts = new List<Tri>(); if (ps.Length < 3) { throw new Exception("Invalid shape! Must have >2 points"); } MeshPoint lastButOne = ps[1]; MeshPoint lastButTwo = ps[0]; for (int i = 2; i < ps.Length; i++) { Tri t = new Tri(lastButTwo, lastButOne, ps[i]); lastButOne = ps[i]; lastButTwo = ps[i - 1]; ts.Add(t); } return ts.ToArray(); }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { List <Point3d> P = new List <Point3d>(); if (!DA.GetDataList(0, P)) { return; } if (P.Count == 0 || P == null) { return; } Mesh M = new Mesh(); if (!DA.GetData(1, ref M)) { return; } if (!M.IsValid) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh is invalid"); } Point3d[] pts = P.Select(p => p).ToArray(); int[] vIndices = new int[pts.Length]; int[] vFIndices = new int[pts.Length]; int[] fIndices = new int[pts.Length]; Parallel.For(0, pts.Length, i => { MeshPoint Mp = M.ClosestMeshPoint(pts[i], 50); fIndices[i] = Mp.FaceIndex; double[] bary = Mp.T; double maxBar = bary[0]; vIndices[i] = 0; for (int j = 1; j < bary.Length; j++) { if (bary[j] > maxBar) { maxBar = bary[j]; vIndices[i] = j; } } vFIndices[i] = vIndices[i]; switch (vIndices[i]) { case 0: vIndices[i] = M.Faces[Mp.FaceIndex].A; break; case 1: vIndices[i] = M.Faces[Mp.FaceIndex].B; break; case 2: vIndices[i] = M.Faces[Mp.FaceIndex].C; break; case 3: vIndices[i] = M.Faces[Mp.FaceIndex].D; break; } }); DA.SetDataList(0, vIndices); DA.SetDataList(1, vFIndices); DA.SetDataList(2, fIndices); }
public Network(List <Line> NetworkLines, Mesh M = null, bool Branching = false) : this() { // Init variables Point3d[] RawPoints = new Point3d[NetworkLines.Count * 2]; int[] RawPointRemapping = new int[NetworkLines.Count * 2]; bool[] RemappingFlags = new bool[NetworkLines.Count * 2]; Tuple <int, int>[] RawEdges = new Tuple <int, int> [NetworkLines.Count]; // Fill raw data lists int ii; for (int i = 0; i < NetworkLines.Count; ++i) { ii = i * 2; RawPoints[ii] = NetworkLines[i].From; RawPoints[ii + 1] = NetworkLines[i].To; RawEdges[i] = new Tuple <int, int>(ii, ii + 1); } // TODO: speed up dupli matching w/ RTree //RTree tree = new RTree(); // Remap vertices to get rid of duplicates List <Point3d> Points = new List <Point3d>(); int Index = 0; for (int i = 0; i < RawPoints.Length; ++i) { if (RemappingFlags[i]) { RemappingFlags[i] = true; continue; } else { RawPointRemapping[i] = Index; Point3d p = RawPoints[i]; Points.Add(p); //MeshPoint mp = M.ClosestMeshPoint(p, 500.0); // Construct node for each point, using Mesh for // node frame construction Node n = new Node(); //n.Frame = new Plane(p, M.NormalAt(mp)); n.Frame = new Plane(p, Vector3d.ZAxis); Nodes.Add(n); } for (int j = i; j < RawPoints.Length; ++j) { if (RemappingFlags[j]) { continue; } if (RawPoints[j].DistanceTo(RawPoints[i]) < NodeMergeDistance) { RawPointRemapping[j] = Index; RemappingFlags[j] = true; } } ++Index; } // Remap edge indices for (int i = 0; i < RawEdges.Length; ++i) { RawEdges[i] = new Tuple <int, int>( RawPointRemapping[RawEdges[i].Item1], RawPointRemapping[RawEdges[i].Item2] ); } // Construct network edges List <Line> NewLines = new List <Line>(); //RawEdges = RawEdges.Distinct(new RawEdgeComparer()).ToArray(); for (int i = 0; i < RawEdges.Length; ++i) { int a = RawEdges[i].Item1; int b = RawEdges[i].Item2; Line l = new Line(Points[a], Points[b]); NewLines.Add(l); Edge e = new Edge(); e.Ends = new IndexPair(a, b); e.Curve = l.ToNurbsCurve(); Edges.Add(e); } if (M != null) { try { if (M.FaceNormals == null || M.FaceNormals.Count < 1) { M.FaceNormals.ComputeFaceNormals(); } if (M.Normals == null || M.Normals.Count < 1) { M.Normals.ComputeNormals(); } foreach (Node n in Nodes) { MeshPoint mp = M.ClosestMeshPoint(n.Frame.Origin, MeshMaxDistance); if (mp == null) { continue; } n.Frame = new Plane(n.Frame.Origin, M.NormalAt(mp)); } } catch { Debug.WriteLine("Something wrong with the mesh..."); } } BuildNodeData(false, true); if (Branching) { for (int i = 0; i < Nodes.Count; ++i) { if (Nodes[i].Edges.Count == 3) { BranchingNode bn = new BranchingNode(); bn.Edges = Nodes[i].Edges; bn.Frame = Nodes[i].Frame; bn.Chains = Nodes[i].Chains; //bn.SortEdgesLR(Nodes[i].Frame.ZAxis); Nodes[i] = bn; } } BuildBranchingData(); } }
public MeshPoint clone() { MeshPoint MP = new MeshPoint(this); return(MP); }
public void CanConvert_ToString() { var pt = new MeshPoint(1, 0.4, 0.5, 0.6); Assert.NotNull(pt.ToString()); }
/// <summary> /// Generates the vertex corresponding to the supplied ID /// </summary> /// <param name="mesh">The mesh for which the vertex shall be generated</param> /// <param name="vertexID">The ID of the vertex</param> /// <returns>The generated vertex</returns> private static MeshPoint GenerateVertex(MeshCube mesh, int vertexID) { // Initiate vertex point MeshPoint point = null; switch (vertexID) { case 0: { // Center point = new MeshPoint() { VertexID = 0, X = mesh.Length / 2.0, Y = mesh.Width / 2.0, Z = mesh.Height / 2.0 }; } break; case 1: { // Front left bottom point = new MeshPoint() { VertexID = 1, X = 0, Y = 0, Z = 0 }; } break; case 2: { // Front right bottom point = new MeshPoint() { VertexID = 2, X = mesh.Length, Y = 0, Z = 0 }; } break; case 3: { // Rear left bottom point = new MeshPoint() { VertexID = 3, X = 0, Y = mesh.Width, Z = 0 }; } break; case 4: { // Rear right bottom point = new MeshPoint() { VertexID = 4, X = mesh.Length, Y = mesh.Width, Z = 0 }; } break; case 5: { // Front left top point = new MeshPoint() { VertexID = 5, X = 0, Y = 0, Z = mesh.Height }; } break; case 6: { // Front right top point = new MeshPoint() { VertexID = 6, X = mesh.Length, Y = 0, Z = mesh.Height }; } break; case 7: { // Rear left top point = new MeshPoint() { VertexID = 7, X = 0, Y = mesh.Width, Z = mesh.Height }; } break; case 8: { // Rear right top point = new MeshPoint() { VertexID = 8, X = mesh.Length, Y = mesh.Width, Z = mesh.Height }; } break; default: throw new ArgumentException("No vertex with ID " + vertexID + " defined"); } return(point); }
void InitSFMesh() { meshPoints.Clear(); meshTriangles.Clear(); // // //First point // MeshPoint firstP = new MeshPoint(); // firstP.pos = Vector3.zero; // firstP.uv = Vector2.zero; // meshPoints.Add(firstP); //precomputed uvs, dummy vertices and normals for (int i = 0; i < xPoints; i++) { //double theta = ((double)i / xPoints) * Math.PI; for (int k = 0; k < yPoints; k++) { //double phi = ((double)k / (yPoints-1)) * Math.PI * 2.0; MeshPoint newPoint = new MeshPoint(); newPoint.uv = new Vector2((float)k / (yPoints - 1), 1f - ((float)i / xPoints)); newPoint.pos = Vector3.zero; newPoint.normalInt = Vector3Int.zero; meshPoints.Add(newPoint); } } //last point MeshPoint lastP = new MeshPoint(); lastP.pos = Vector3.zero; lastP.uv = Vector2.one; //lastP.normal = Vector3.zero; meshPoints.Add(lastP); // //add pole (top) // for(int k = 0; k < yPoints; k++ ) // { // meshTriangles.Add(k+2); // meshTriangles.Add(k+1); // meshTriangles.Add(k); // } //triangles for (int i = 0; i < xPoints - 1; i++) { for (int k = 0; k < yPoints; k++) { int current = (k + i * (yPoints)); //% (meshPoints.Count-1);// % nPoints; int next = (current + yPoints); // % (meshPoints.Count-1);// % nPoints; if (k != yPoints - 1) { meshTriangles.Add(current); meshTriangles.Add(current + 1); meshTriangles.Add(next + 1); meshTriangles.Add(current); meshTriangles.Add(next + 1); meshTriangles.Add(next); } else { meshTriangles.Add(current); meshTriangles.Add(current + 1); meshTriangles.Add(next + 1); meshTriangles.Add(current); meshTriangles.Add(next + 1); meshTriangles.Add(next); } } } //add pole (bottom) for (int k = 0; k < yPoints; k++) { meshTriangles.Add(meshPoints.Count - 1); meshTriangles.Add(meshPoints.Count - (k + 2) - 1); meshTriangles.Add(meshPoints.Count - (k + 1) - 1); } }
/// <summary> /// Generates the given vertex for the given component of a piece /// </summary> /// <param name="piece">The piece the component belongs to</param> /// <param name="vertexID">The ID of the vertex to generate</param> /// <param name="component">The component the vertex is generated for</param> /// <returns>The newly generated vertex</returns> public static MeshPoint GenerateVertex(int vertexID, MeshCube component, Piece piece) { // Initiate vertex point MeshPoint point = null; switch (vertexID) { case 0: { // Center point = new MeshPoint() { VertexID = 0, ParentPiece = piece, X = component.RelPosition.X + (component.Length / 2.0), Y = component.RelPosition.Y + (component.Width / 2.0), Z = component.RelPosition.Z + (component.Height / 2.0), }; } break; case 1: { // Front left bottom point = new MeshPoint() { VertexID = 1, ParentPiece = piece, X = component.RelPosition.X, Y = component.RelPosition.Y, Z = component.RelPosition.Z, }; } break; case 2: { // Front right bottom point = new MeshPoint() { VertexID = 2, ParentPiece = piece, X = component.RelPosition.X + component.Length, Y = component.RelPosition.Y, Z = component.RelPosition.Z, }; } break; case 3: { // Rear left bottom point = new MeshPoint() { VertexID = 3, ParentPiece = piece, X = component.RelPosition.X, Y = component.RelPosition.Y + component.Width, Z = component.RelPosition.Z, }; } break; case 4: { // Rear right bottom point = new MeshPoint() { VertexID = 4, ParentPiece = piece, X = component.RelPosition.X + component.Length, Y = component.RelPosition.Y + component.Width, Z = component.RelPosition.Z, }; } break; case 5: { // Front left top point = new MeshPoint() { VertexID = 5, ParentPiece = piece, X = component.RelPosition.X, Y = component.RelPosition.Y, Z = component.RelPosition.Z + component.Height, }; } break; case 6: { // Front right top point = new MeshPoint() { VertexID = 6, ParentPiece = piece, X = component.RelPosition.X + component.Length, Y = component.RelPosition.Y, Z = component.RelPosition.Z + component.Height, }; } break; case 7: { // Rear left top point = new MeshPoint() { VertexID = 7, ParentPiece = piece, X = component.RelPosition.X, Y = component.RelPosition.Y + component.Width, Z = component.RelPosition.Z + component.Height, }; } break; case 8: { // Rear right top point = new MeshPoint() { VertexID = 8, ParentPiece = piece, X = component.RelPosition.X + component.Length, Y = component.RelPosition.Y + component.Width, Z = component.RelPosition.Z + component.Height, }; } break; default: throw new ArgumentException("No vertex with ID " + vertexID + " defined"); } return(point); }
/// <summary> /// Generates the vertex information and side lengths for all components of a piece according to all orientations /// </summary> /// <param name="piece">The piece to generate the information for</param> private static void GenerateVertexInformation(Piece piece) { // Init IReadOnlyList <Matrix> rotationMatrices = RotationMatrices.GetRotationMatrices(); // Create vertex info for original foreach (var component in piece.Original.Components) { foreach (var vertexID in MeshConstants.VERTEX_IDS) { component[vertexID] = GenerateVertex(vertexID, component, piece); } } foreach (var vertexID in MeshConstants.VERTEX_IDS) { piece.Original.BoundingBox[vertexID] = GenerateVertex(piece.Original.BoundingBox, vertexID); } // Create clones for the different orientations foreach (var orientation in MeshConstants.ORIENTATIONS) { piece[orientation] = piece.Original.Clone(); } // Rotate vertices foreach (var orientation in MeshConstants.ORIENTATIONS) { foreach (var component in piece[orientation].Components) { // Calculate rotated sides Matrix referenceSidesVector = new Matrix(3, 1); referenceSidesVector[0, 0] = component.Length; referenceSidesVector[1, 0] = component.Width; referenceSidesVector[2, 0] = component.Height; Matrix rotatedSidesVector = rotationMatrices[orientation] * referenceSidesVector; double length = rotatedSidesVector[0, 0]; double width = rotatedSidesVector[1, 0]; double height = rotatedSidesVector[2, 0]; // Calculate rotated vertices Dictionary <int, MeshPoint> referencePoints = MeshConstants.VERTEX_IDS.ToDictionary(k => k, v => GenerateVertex(v, component, piece)); foreach (var vertexID in MeshConstants.VERTEX_IDS) { MeshPoint referencePoint = referencePoints[vertexID]; Matrix referencePointVector = new Matrix(3, 1); referencePointVector[0, 0] = referencePoint.X; referencePointVector[1, 0] = referencePoint.Y; referencePointVector[2, 0] = referencePoint.Z; Matrix rotatedPointVector = rotationMatrices[orientation] * referencePointVector; component[vertexID] = new MeshPoint() { ParentPiece = piece }; component[vertexID].X = rotatedPointVector[0, 0]; component[vertexID].Y = rotatedPointVector[1, 0]; component[vertexID].Z = rotatedPointVector[2, 0]; } // Set sides (keep them positive - these are lengths after all) component.Length = Math.Abs(length); component.Width = Math.Abs(width); component.Height = Math.Abs(height); } } // Transform all coordinates into the first octant (for all orientations) foreach (var orientation in MeshConstants.ORIENTATIONS) { // Determine offset double minVertexX = Math.Abs(piece[orientation].Components.Min(c => MeshConstants.VERTEX_IDS.Min(v => c[v].X))); double minVertexY = Math.Abs(piece[orientation].Components.Min(c => MeshConstants.VERTEX_IDS.Min(v => c[v].Y))); double minVertexZ = Math.Abs(piece[orientation].Components.Min(c => MeshConstants.VERTEX_IDS.Min(v => c[v].Z))); // Move all components to first octant by applying the offset foreach (var component in piece[orientation].Components) { // Move vertices foreach (var vertexID in MeshConstants.VERTEX_IDS) { component[vertexID].X += minVertexX; component[vertexID].Y += minVertexY; component[vertexID].Z += minVertexZ; } // Update relative position of component accordingly component.RelPosition.X = component.Vertices.Min(v => v.X); component.RelPosition.Y = component.Vertices.Min(v => v.Y); component.RelPosition.Z = component.Vertices.Min(v => v.Z); } } // Recalibrate vertex IDs foreach (var orientation in MeshConstants.ORIENTATIONS) { foreach (var component in piece[orientation].Components) { List <double> x = new List <double>(MeshConstants.VERTEX_IDS.Where(vid => vid != 0).Select(vid => component[vid].X)); List <double> y = new List <double>(MeshConstants.VERTEX_IDS.Where(vid => vid != 0).Select(vid => component[vid].Y)); List <double> z = new List <double>(MeshConstants.VERTEX_IDS.Where(vid => vid != 0).Select(vid => component[vid].Z)); // vid 1 component[1].VertexID = 1; component[1].X = x.Min(); component[1].Y = y.Min(); component[1].Z = z.Min(); // vid 2 component[2].VertexID = 2; component[2].X = x.Max(); component[2].Y = y.Min(); component[2].Z = z.Min(); // vid 3 component[3].VertexID = 3; component[3].X = x.Min(); component[3].Y = y.Max(); component[3].Z = z.Min(); // vid 4 component[4].VertexID = 4; component[4].X = x.Max(); component[4].Y = y.Max(); component[4].Z = z.Min(); // vid 5 component[5].VertexID = 5; component[5].X = x.Min(); component[5].Y = y.Min(); component[5].Z = z.Max(); // vid 6 component[6].VertexID = 6; component[6].X = x.Max(); component[6].Y = y.Min(); component[6].Z = z.Max(); // vid 7 component[7].VertexID = 7; component[7].X = x.Min(); component[7].Y = y.Max(); component[7].Z = z.Max(); // vid 8 component[8].VertexID = 8; component[8].X = x.Max(); component[8].Y = y.Max(); component[8].Z = z.Max(); } } // Seal the orientation clones foreach (var orientation in MeshConstants.ORIENTATIONS) { piece[orientation].Seal(); } // Create vertex info for bounding box of original foreach (var vertexID in MeshConstants.VERTEX_IDS) { piece.Original.BoundingBox[vertexID] = GenerateVertex(vertexID, piece.Original.BoundingBox, piece); } // Create vertex info for all orientations bounding boxes foreach (var orientation in MeshConstants.ORIENTATIONS) { foreach (var vertexID in MeshConstants.VERTEX_IDS) { piece[orientation].BoundingBox[vertexID] = GenerateVertex(vertexID, piece[orientation].BoundingBox, piece); } } }
// Use this for initialization void Start() { MeshFilter mf = this.GetComponentInChildren <MeshFilter>(); Vector2[] uvs = mf.mesh.uv; Debug.Log(mf.mesh.uv.Length); Debug.Log(mf.mesh.vertices.Length); for (int i = 0; i < uvs.Length; i++) { Debug.Log(uvs[i]); } //uvs[0] = new Vector2(0f, 0f); //uvs[1] = new Vector2(4f, 5f); //uvs[2] = new Vector2(4f, 0); //uvs[3] = new Vector2(0, 5f); //uvs[0] = new Vector2(2f, 0f); //uvs[1] = new Vector2(0f, 2f); //uvs[2] = new Vector2(0f, 0f); //uvs[3] = new Vector2(2f, 2f); uvs[0] = new Vector2(0f, 0f); uvs[1] = new Vector2(2f, 2f); uvs[2] = new Vector2(2f, 0f); uvs[3] = new Vector2(0f, 2f); mf.mesh.uv = uvs; //================================================ Debug.Log(">> ==========================================="); int[] triangles = mf.mesh.triangles; for (int i = 0; i < triangles.Length; i++) { Debug.Log(triangles[i]); } //================================================ Debug.Log(">> ==========================================="); Vector3[] vertices = mf.mesh.vertices; for (int i = 0; i < vertices.Length; i++) { Debug.Log(vertices[i]); } //vertices[2] = new Vector3(0.5f, 0, 0); //mf.mesh.vertices = vertices; return; Debug.Log(">> ==========================================="); Mesh mesh = new Mesh(); mesh.vertices = vertices; mesh.uv = uvs; mesh.triangles = triangles; Debug.Log(mf.mesh.tangents.Length); GameObject go = new GameObject("Temp"); go.transform.position = new Vector3(2, 2, 2); MeshFilter meshFilter = go.AddComponent <MeshFilter>(); meshFilter.mesh = mesh; MeshRenderer meshRenderer = go.AddComponent <MeshRenderer>(); meshRenderer.sharedMaterial = mf.GetComponent <MeshRenderer>().sharedMaterial; //Vector2[] uvs = mf.mesh.uv; //int[] triangles = mf.mesh.triangles; //Vector3[] vertices = mf.mesh.vertices; int vIndex = 0; for (; vIndex < triangles.Length; vIndex += 3) { int i0 = triangles[vIndex]; int i1 = triangles[vIndex + 1]; int i2 = triangles[vIndex + 2]; if (IsUVGreater(uvs[i0]) || IsUVGreater(uvs[i1]) || IsUVGreater(uvs[i2])) { } MeshPoint mp0 = new MeshPoint(); mp0.index = i0; mp0.uv = uvs[i0]; mp0.vertex = vertices[i0]; MeshPoint mp1 = new MeshPoint(); mp1.index = i1; mp1.uv = uvs[i1]; mp1.vertex = vertices[i1]; MeshPoint mp2 = new MeshPoint(); mp2.index = i2; mp2.uv = uvs[i2]; mp2.vertex = vertices[i2]; MeshTriangle meshTriangle = new MeshTriangle(); meshTriangle.p0 = mp0; meshTriangle.p1 = mp1; meshTriangle.p2 = mp2; HandleTriangle(meshTriangle); return; } }
/// <summary> /// 纠正UV /// </summary> private void CorrectMeshPoint(MeshPoint meshPoint) { meshPoint.isCorrectUV = true; meshPoint.correctUV = new Vector2(CorrectUV(meshPoint.uv.x), CorrectUV(meshPoint.uv.y)); }
public void CombineImprove(Mesh mesh) { if (!faceindex) { PrintMessage(3, "Combine improve"); for (faceindex = 1; faceindex <= mesh.GetNFD(); faceindex++) { CombineImprove(mesh); if (multithread.terminate) { throw new Exception("Meshing stopped"); } } faceindex = 0; return; } //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method: // static int timer = NgProfiler::CreateTimer("Combineimprove 2D"); NgProfiler.RegionTimer reg = new NgProfiler.RegionTimer(CombineImprove_timer); //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method: // static int timerstart = NgProfiler::CreateTimer("Combineimprove 2D start"); NgProfiler.StartTimer(CombineImprove_timerstart); //C++ TO C# CONVERTER NOTE: This static local variable declaration (not allowed in C#) has been moved just prior to the method: // static int timerstart1 = NgProfiler::CreateTimer("Combineimprove 2D start1"); NgProfiler.StartTimer(CombineImprove_timerstart1); // int i, j, k, l; // PointIndex pi; // SurfaceElementIndex sei; Array <SurfaceElementIndex> seia = new Array <SurfaceElementIndex>(); mesh.GetSurfaceElementsOfFace(faceindex, seia); for (int i = 0; i < seia.Size(); i++) { if (mesh[seia[i]].GetNP() != 3) { return; } } int surfnr = 0; if (faceindex) { surfnr = mesh.GetFaceDescriptor(faceindex).SurfNr(); } // PointIndex pi1, pi2; // MeshPoint p1, p2, pnew; double bad1; double bad2; Vec <3> nv; int np = mesh.GetNP(); //int nse = mesh.GetNSE(); TABLE <SurfaceElementIndex, PointIndex.BASE> elementsonnode = new TABLE <SurfaceElementIndex, PointIndex.BASE>(np); Array <SurfaceElementIndex> hasonepi = new Array <SurfaceElementIndex>(); Array <SurfaceElementIndex> hasbothpi = new Array <SurfaceElementIndex>(); for (int i = 0; i < seia.Size(); i++) { Element2d el = mesh[seia[i]]; for (int j = 0; j < el.GetNP(); j++) { elementsonnode.Add(el[j], seia[i]); } } Array <bool, PointIndex.BASE> @fixed = new Array <bool, PointIndex.BASE>(np); @fixed = false; NgProfiler.StopTimer(CombineImprove_timerstart1); /* * for (SegmentIndex si = 0; si < mesh.GetNSeg(); si++) * { * INDEX_2 i2(mesh[si][0], mesh[si][1]); * fixed[i2.I1()] = true; * fixed[i2.I2()] = true; * } */ for (int i = 0; i < seia.Size(); i++) { Element2d sel = mesh[seia[i]]; for (int j = 0; j < sel.GetNP(); j++) { PointIndex pi1 = sel.PNumMod(j + 2); PointIndex pi2 = sel.PNumMod(j + 3); if (mesh.IsSegment(pi1, pi2)) { @fixed[pi1] = true; @fixed[pi2] = true; } } } for (int i = 0; i < mesh.LockedPoints().Size(); i++) { @fixed[mesh.LockedPoints()[i]] = true; } Array <Vec <3>, PointIndex.BASE> normals = new Array <Vec <3>, PointIndex.BASE>(np); for (PointIndex pi = mesh.Points().Begin(); pi < mesh.Points().End(); pi++) { if (elementsonnode[pi].Size()) { Element2d hel = mesh[elementsonnode[pi][0]]; for (int k = 0; k < 3; k++) { if (hel[k] == pi) { SelectSurfaceOfPoint(mesh[pi], hel.GeomInfoPi(k + 1)); GetNormalVector(surfnr, mesh[pi], hel.GeomInfoPi(k + 1), normals[pi]); break; } } } } NgProfiler.StopTimer(CombineImprove_timerstart); for (int i = 0; i < seia.Size(); i++) { SurfaceElementIndex sei = seia[i]; Element2d elem = mesh[sei]; if (elem.IsDeleted()) { continue; } for (int j = 0; j < 3; j++) { PointIndex pi1 = elem[j]; PointIndex pi2 = elem[(j + 1) % 3]; if (pi1 < PointIndex.BASE || pi2 < PointIndex.BASE) { continue; } /* * INDEX_2 i2(pi1, pi2); * i2.Sort(); * if (segmentht.Used(i2)) * continue; */ bool debugflag = false; if (debugflag) { (*testout) << "Combineimprove, face = " << faceindex << "pi1 = " << pi1 << " pi2 = " << pi2 << "\n"; } /* * // save version: * if (fixed.Get(pi1) || fixed.Get(pi2)) * continue; * if (pi2 < pi1) swap (pi1, pi2); */ // more general if (@fixed[pi2]) { netgen.GlobalMembers.Swap(ref pi1, ref pi2); } if (@fixed[pi2]) { continue; } double loch = mesh.GetH(mesh[pi1]); INDEX_2 si2 = new INDEX_2(pi1, pi2); si2.Sort(); /* * if (edgetested.Used (si2)) * continue; * edgetested.Set (si2, 1); */ hasonepi.SetSize(0); hasbothpi.SetSize(0); for (int k = 0; k < elementsonnode[pi1].Size(); k++) { Element2d el2 = mesh[elementsonnode[pi1][k]]; if (el2.IsDeleted()) { continue; } if (el2[0] == pi2 || el2[1] == pi2 || el2[2] == pi2) { hasbothpi.Append(elementsonnode[pi1][k]); nv = netgen.GlobalMembers.Cross(new Vec3d(mesh[el2[0]], mesh[el2[1]]), new Vec3d(mesh[el2[0]], mesh[el2[2]])); } else { hasonepi.Append(elementsonnode[pi1][k]); } } Element2d hel = mesh[hasbothpi[0]]; for (int k = 0; k < 3; k++) { if (hel[k] == pi1) { SelectSurfaceOfPoint(mesh[pi1], hel.GeomInfoPi(k + 1)); GetNormalVector(surfnr, mesh[pi1], hel.GeomInfoPi(k + 1), nv); break; } } // nv = normals.Get(pi1); for (int k = 0; k < elementsonnode[pi2].Size(); k++) { Element2d el2 = mesh[elementsonnode[pi2][k]]; if (el2.IsDeleted()) { continue; } if (el2[0] == pi1 || el2[1] == pi1 || el2[2] == pi1) { ; } else { hasonepi.Append(elementsonnode[pi2][k]); } } bad1 = 0; int illegal1 = 0; int illegal2 = 0; for (int k = 0; k < hasonepi.Size(); k++) { Element2d el = mesh[hasonepi[k]]; bad1 += CalcTriangleBadness(mesh[el[0]], mesh[el[1]], mesh[el[2]], nv, -1, loch); illegal1 += 1 - mesh.LegalTrig(el); } for (int k = 0; k < hasbothpi.Size(); k++) { Element2d el = mesh[hasbothpi[k]]; bad1 += CalcTriangleBadness(mesh[el[0]], mesh[el[1]], mesh[el[2]], nv, -1, loch); illegal1 += 1 - mesh.LegalTrig(el); } bad1 /= (hasonepi.Size() + hasbothpi.Size()); MeshPoint p1 = mesh[pi1]; MeshPoint p2 = mesh[pi2]; MeshPoint pnew = new MeshPoint(p1); mesh[pi1] = pnew; mesh[pi2] = pnew; bad2 = 0; for (int k = 0; k < hasonepi.Size(); k++) { Element2d el = mesh[hasonepi[k]]; double err = CalcTriangleBadness(mesh[el[0]], mesh[el[1]], mesh[el[2]], nv, -1, loch); bad2 += err; Vec <3> hnv = netgen.GlobalMembers.Cross(new Vec3d(mesh[el[0]], mesh[el[1]]), new Vec3d(mesh[el[0]], mesh[el[2]])); if (hnv * nv < 0) { bad2 += 1e10; } for (int l = 0; l < 3; l++) { if ((normals[el[l]] * nv) < 0.5) { bad2 += 1e10; } } illegal2 += 1 - mesh.LegalTrig(el); } bad2 /= hasonepi.Size(); mesh[pi1] = p1; mesh[pi2] = p2; if (debugflag) { (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << "\n"; } bool should = (bad2 < bad1 && bad2 < 1e4); if (bad2 < 1e4) { if (illegal1 > illegal2) { should = true; } if (illegal2 > illegal1) { should = false; } } if (should) { /* * (*testout) << "combine !" << endl; * (*testout) << "bad1 = " << bad1 << ", bad2 = " << bad2 << endl; * (*testout) << "illegal1 = " << illegal1 << ", illegal2 = " << illegal2 << endl; * (*testout) << "loch = " << loch << endl; */ mesh[pi1] = pnew; PointGeomInfo gi = new PointGeomInfo(); // bool gi_set(false); Element2d el1p = new Element2d(null); int l = 0; while (mesh[elementsonnode[pi1][l]].IsDeleted() && l < elementsonnode.EntrySize(pi1)) { l++; } if (l < elementsonnode.EntrySize(pi1)) { el1p = mesh[elementsonnode[pi1][l]]; } else { cerr << "OOPS!" << "\n"; } for (l = 0; l < el1p.GetNP(); l++) { if (el1p[l] == pi1) { gi = el1p.GeomInfoPi(l + 1); // gi_set = true; } } // (*testout) << "Connect point " << pi2 << " to " << pi1 << "\n"; for (int k = 0; k < elementsonnode[pi2].Size(); k++) { Element2d el = mesh[elementsonnode[pi2][k]]; if (el.IsDeleted()) { continue; } elementsonnode.Add(pi1, elementsonnode[pi2][k]); bool haspi1 = false; for (l = 0; l < el.GetNP(); l++) { if (el[l] == pi1) { haspi1 = true; } } if (haspi1) { continue; } for (int l = 0; l < el.GetNP(); l++) { if (el[l] == pi2) { el[l] = pi1; el.GeomInfoPi(l + 1) = gi; } @fixed[el[l]] = true; } } /* * for (k = 0; k < hasbothpi.Size(); k++) * { * cout << mesh[hasbothpi[k]] << endl; * for (l = 0; l < 3; l++) * cout << mesh[mesh[hasbothpi[k]][l]] << " "; * cout << endl; * } */ for (int k = 0; k < hasbothpi.Size(); k++) { mesh[hasbothpi[k]].Delete(); /* * for (l = 0; l < 4; l++) * mesh[hasbothpi[k]][l] = PointIndex::BASE-1; */ } } } } // mesh.Compress(); mesh.SetNextTimeStamp(); }