public List <SMeshBoundary> BoundaryListSMeshTest(string meshPath) { string fileName = Path.GetFileName(meshPath); Stopwatch timer; SMeshData mesh; if (Path.GetExtension(meshPath) == ".dfsu") { DfsuFile file = DfsFileFactory.DfsuFileOpen(meshPath); timer = MeshExtensions.StartTimer(); mesh = new SMeshData(file.Projection.WKTString, file.NodeIds, file.X, file.Y, file.Z.ToDoubleArray(), file.Code, file.ElementIds, file.ElementType, file.ElementTable.ToZeroBased()); file.Close(); } else { MeshFile meshFile = MeshFile.ReadMesh(meshPath); timer = MeshExtensions.StartTimer(); mesh = meshFile.ToSMeshData(); } Console.Out.WriteLine("(#nodes,#elmts)=({0},{1}) ({2})", mesh.NumberOfNodes, mesh.NumberOfElements, mesh.NumberOfNodes + mesh.NumberOfElements); timer.ReportAndRestart("Create"); List <SMeshBoundary> boundaries = mesh.BuildBoundaryList(); timer.ReportAndRestart("Time "); string gpFileName = UnitTestHelper.TestDataDir + "test_" + fileName + "-bndscode.txt"; GnuPlotWriteBoundaryList(mesh, gpFileName, boundaries); return(boundaries); }
public ColladaMeshExporter(IRepository repository, MeshFile meshFile, ExportDDSToPngFileDelegate exportDDSToPngFile = null) { Repository = repository; MeshFile = meshFile; ExportDDSToPngFile = exportDDSToPngFile ?? DefaultExportDDSToPngFileDelegate; TNS = TemplateNameSpace; }
public Geometry BoundaryPolygonSMeshTest(string meshPath, bool alwaysMultiPolygon = true, string extra = "") { string fileName = Path.GetFileName(meshPath); Stopwatch timer; SMeshData mesh; if (Path.GetExtension(meshPath) == ".dfsu") { DfsuFile file = DfsFileFactory.DfsuFileOpen(meshPath); timer = MeshExtensions.StartTimer(); mesh = new SMeshData(file.Projection.WKTString, file.NodeIds, file.X, file.Y, file.Z.ToDoubleArray(), file.Code, file.ElementIds, file.ElementType, file.ElementTable.ToZeroBased()); file.Close(); } else { MeshFile meshFile = MeshFile.ReadMesh(meshPath); timer = MeshExtensions.StartTimer(); mesh = meshFile.ToSMeshData(); } Console.Out.WriteLine("(#nodes,#elmts)=({0},{1}) ({2})", mesh.NumberOfNodes, mesh.NumberOfElements, mesh.NumberOfNodes + mesh.NumberOfElements); timer.ReportAndRestart("Create "); Geometry boundaryGeom = mesh.BuildBoundaryGeometry(alwaysMultiPolygon); timer.ReportAndRestart("Build "); BoundaryPolygonWriter(fileName, "-sbnd" + extra, boundaryGeom, timer); return(boundaryGeom); }
private static void WriteMesh(MeshDef def, string path) { using (Stream s = File.OpenWrite(path)) { MeshFile.Save(s, def); } }
private static void DfsuBuildGeometry(string targetMeshFilename, DfsuBuilder builder) { DfsFactory factory = new DfsFactory(); if (targetMeshFilename.EndsWith(".mesh", StringComparison.OrdinalIgnoreCase)) { MeshFile target = MeshFile.ReadMesh(targetMeshFilename); // Setup header and geometry, copy from source file builder.SetNodes(target.X, target.Y, target.Z.ToFloatArray(), target.Code); builder.SetElements(target.ElementTable); builder.SetProjection(factory.CreateProjection(target.Projection)); builder.SetZUnit(eumUnit.eumUmeter); } else { DfsuFile target = DfsFileFactory.DfsuFileOpen(targetMeshFilename); // Setup header and geometry, copy from source file builder.SetNodes(target.X, target.Y, target.Z, target.Code); builder.SetElements(target.ElementTable); builder.SetProjection(target.Projection); builder.SetZUnit(eumUnit.eumUmeter); target.Close(); } }
public void InterpolateNodeTest() { string triMesh = UnitTestHelper.TestDataDir + "odense_rough.mesh"; string quadMesh = UnitTestHelper.TestDataDir + "odense_rough_quads.mesh"; // Source mesh MeshFile sourcemeshFile = MeshFile.ReadMesh(triMesh); SMeshData sourcemesh = sourcemeshFile.ToSMeshData(); sourcemesh.BuildDerivedData(); // Target mesh MeshFile targetMeshFile = MeshFile.ReadMesh(quadMesh); SMeshData targetmesh = targetMeshFile.ToSMeshData(); targetmesh.BuildDerivedData(); MeshInterpolator2D interpolator = new MeshInterpolator2D(sourcemesh, MeshValueType.Nodes); interpolator.SetTarget(targetmesh, MeshValueType.Nodes); double[] target = new double[targetmesh.NumberOfNodes]; interpolator.InterpolateNodeToTarget(sourcemesh.Z, target); Assert.False(target.Any(vv => vv == interpolator.DeleteValue)); targetMeshFile.Z = target; targetMeshFile.Write(UnitTestHelper.TestDataDir + "test_odense_rough_quads-fromTri.mesh"); }
public void SMeshDataOdenseQuadsTest() { string quadMesh = UnitTestHelper.TestDataDir + "odense_rough_quads.mesh"; MeshFile meshFile = MeshFile.ReadMesh(quadMesh); SMeshData mesh = meshFile.ToSMeshData(); Assert.AreEqual(535, mesh.NumberOfNodes); Assert.AreEqual(5, mesh.NodeIds[4]); Assert.AreEqual(212827.81746849261, mesh.X[4]); Assert.AreEqual(6156804.9152286667, mesh.Y[4]); Assert.AreEqual(-0.42102556956959569, mesh.Z[4]); Assert.AreEqual(1, mesh.Code[5]); Assert.AreEqual(724, mesh.NumberOfElements); Assert.AreEqual(5, mesh.ElementIds[4]); Assert.AreEqual(3, mesh.ElementTable[4].Length); Assert.AreEqual(62, mesh.ElementTable[4][0]); // Remember: Index here is zero based, while mesh file is one-based Assert.AreEqual(367, mesh.ElementTable[4][1]); Assert.AreEqual(358, mesh.ElementTable[4][2]); mesh.BuildNodeElements(); Assert.AreEqual(4, mesh.NodesElmts[4].Count); Assert.AreEqual(33, mesh.NodesElmts[4][0] + 1); Assert.AreEqual(36, mesh.NodesElmts[4][1] + 1); Assert.AreEqual(43, mesh.NodesElmts[4][2] + 1); Assert.AreEqual(58, mesh.NodesElmts[4][3] + 1); //mesh.BuildFaces(true, true, false); //int reverts = FaceRevert(mesh, mesh.Faces); //Console.Out.WriteLine("reverts: " + reverts); //mesh.Faces.Sort(FaceSortComparer); //List<MeshFace> facesOld = mesh.Faces; //mesh.BuildFaces(true, true, true); //reverts = FaceRevert(mesh, mesh.Faces); //Console.Out.WriteLine("reverts: " + reverts); //mesh.Faces.Sort(FaceSortComparer); //List<MeshFace> facesNew = mesh.Faces; //for (int i = 0; i < facesOld.Count; i++) //{ // bool ok = FaceEquals(facesOld[i], facesNew[i]); // Assert.IsTrue(ok, "Face " + i); //} //Assert.AreEqual(1259, mesh.Faces.Count); //Assert.AreEqual(1, mesh.Faces[0].FromNode.Id); //Assert.AreEqual(42, mesh.Faces[0].ToNode.Id); //Assert.AreEqual(1, mesh.Faces[1].FromNode.Id); //Assert.AreEqual(251, mesh.Faces[1].ToNode.Id); //Assert.AreEqual(1, mesh.Faces[2].FromNode.Id); //Assert.AreEqual(309, mesh.Faces[2].ToNode.Id); //int ind = mesh.Faces.FindIndex(mf => mf.FromNode.Id == 68); //Assert.AreEqual(202, ind); //Assert.AreEqual(68, mesh.Faces[ind].FromNode.Id); //Assert.AreEqual(43, mesh.Faces[ind].ToNode.Id); //Assert.AreEqual(1, mesh.Faces[ind].Code); //Assert.AreEqual(366, mesh.Faces[ind].LeftElement.Id); //Assert.AreEqual(null, mesh.Faces[ind].RightElement); }
public void NodeInterpolationTest(string meshFileName, CircularValueTypes cvt = CircularValueTypes.Normal) { // Source mesh MeshFile meshFile = MeshFile.ReadMesh(meshFileName); MeshData mesh = meshFile.ToMeshData(); // Allow for extrapolation on boundary nodes (disable clipping) MeshNodeInterpolation interpolation = new MeshNodeInterpolation(mesh) { AllowExtrapolation = true, }; interpolation.Setup(); Interpolator nodeInterpolator = interpolation.NodeInterpolator; nodeInterpolator.CircularType = cvt; // Find reference x and y value as the smallest x and y value double xMin = mesh.Nodes.Select(mn => mn.X).Min(); double xMax = mesh.Nodes.Select(mn => mn.X).Max(); double yMin = mesh.Nodes.Select(mn => mn.Y).Min(); double yMax = mesh.Nodes.Select(mn => mn.Y).Max(); // Function over the (x,y) plane. Func <double, double, double> function = ValueFunction(cvt, xMin, yMin, xMax, yMax); // Calculate element center values double[] elmtVals = new double[mesh.Elements.Count]; for (int i = 0; i < mesh.Elements.Count; i++) { MeshElement elmt = mesh.Elements[i]; elmtVals[i] = function(elmt.XCenter, elmt.YCenter); } // Write out bounds, to check we got things right Console.Out.WriteLine("{0,10} (min,max) = ({1},{2})", cvt, elmtVals.Min(), elmtVals.Max()); // Interpolate to nodes double[] nodeValues = new double[mesh.Nodes.Count]; nodeInterpolator.Interpolate(elmtVals, nodeValues); // Check node values for (int i = 0; i < mesh.Nodes.Count; i++) { MeshNode node = mesh.Nodes[i]; double exactValue = function(node.X, node.Y); double interpValue = nodeValues[i]; double diff = exactValue - interpValue; // It can only extrapolate when there is at least three elements per node. // When there is two or less elements, the inverse distance weighting takes over // and the results are not correct, so we skip the check here. if (node.Elements.Count > 2 && diff > 1e-6) { string msg = string.Format("{0,2} {6}: {1}-{2}={3} ({4},{5})", i, exactValue, interpValue, diff, node.X, node.Y, node.Elements.Count); Console.Out.WriteLine(msg); Assert.Fail(msg); } } }
protected override void ProcessValidation() { if (string.IsNullOrEmpty(this.MeshFile)) { base.ValidationCollection.AddValidation(DataStrings.MeshFile, ValidationValue.IsError, string.Format(CultureInfo.CurrentCulture, AMLResources.Properties.Resources.IsRequired, AMLResources.Properties.Resources.MeshFile)); } else if (!MeshFile.EndsWith(DataStrings.DXSExtension, StringComparison.OrdinalIgnoreCase)) { base.ValidationCollection.AddValidation(DataStrings.MeshFile, ValidationValue.IsWarnState, AMLResources.Properties.Resources.MeshFileExtensionValidation); } if (string.IsNullOrEmpty(this.DiffuseFile)) { base.ValidationCollection.AddValidation(DataStrings.DiffuseFile, ValidationValue.IsError, string.Format(CultureInfo.CurrentCulture, AMLResources.Properties.Resources.IsRequired, AMLResources.Properties.Resources.DiffuseFile)); } else if (!FileHelper.IsImageFile(DiffuseFile)) { base.ValidationCollection.AddValidation(DataStrings.DiffuseFile, ValidationValue.IsError, AMLResources.Properties.Resources.NotAnImageFile); } if (string.IsNullOrEmpty(this.GlowFile)) { base.ValidationCollection.AddValidation(DataStrings.GlowFile, ValidationValue.IsError, string.Format(CultureInfo.CurrentCulture, AMLResources.Properties.Resources.IsRequired, AMLResources.Properties.Resources.GlowFile)); } else if (!FileHelper.IsImageFile(GlowFile)) { base.ValidationCollection.AddValidation(DataStrings.GlowFile, ValidationValue.IsError, AMLResources.Properties.Resources.NotAnImageFile); } if (string.IsNullOrEmpty(this.SpecularFile)) { base.ValidationCollection.AddValidation(DataStrings.SpecularFile, ValidationValue.IsError, string.Format(CultureInfo.CurrentCulture, AMLResources.Properties.Resources.IsRequired, AMLResources.Properties.Resources.SpecularFile)); } else if (!FileHelper.IsImageFile(SpecularFile)) { base.ValidationCollection.AddValidation(DataStrings.SpecularFile, ValidationValue.IsError, AMLResources.Properties.Resources.NotAnImageFile); } if (Scale <= 0) { base.ValidationCollection.AddValidation(DataStrings.Scale, ValidationValue.IsError, AMLResources.Properties.Resources.ScaleValidation); } if (PushRadius <= 0) { base.ValidationCollection.AddValidation(DataStrings.PushRadius, ValidationValue.IsWarnState, AMLResources.Properties.Resources.PushRadiusValidation); } }
/// <summary> /// Create <see cref="IMeshDataInfo"/>, depending on <paramref name="smesh"/> flag. /// </summary> public static IMeshDataInfo ToMeshData(this MeshFile file, bool smesh) { if (smesh) { return(file.ToSMeshData()); } return(file.ToMeshData()); }
public override string ValidateInternally() { var sb = new StringBuilder(); if (MeshFile.FindFileExtension(_filePath) is null) { sb.AppendLine("The used file extension is invalid."); } return(sb.ToString()); }
private Model.Ndfbin.NdfBinary ReadTextureBindings(Stream s, MeshFile file) { var buffer = new byte[file.SubHeader.MeshMaterial.Size]; s.Seek(file.SubHeader.MeshMaterial.Offset, SeekOrigin.Begin); s.Read(buffer, 0, buffer.Length); var ndfReader = new NdfbinReader(); return(ndfReader.Read(buffer)); }
public MeshFile Read(Stream s) { var file = new MeshFile(); file.Header = ReadHeader(s); file.SubHeader = ReadSubHeader(s); file.MultiMaterialMeshFiles = ReadMeshDictionary(s, file); file.TextureBindings = ReadTextureBindings(s, file); return(file); }
public void MeshDataOdenseQuadsTest() { string quadMesh = UnitTestHelper.TestDataDir + "odense_rough_quads.mesh"; MeshFile meshFile = MeshFile.ReadMesh(quadMesh); MeshData mesh = meshFile.ToMeshData(); Assert.AreEqual(535, mesh.Nodes.Count); Assert.AreEqual(4, mesh.Nodes[4].Index); Assert.AreEqual(5, mesh.Nodes[4].Id); Assert.AreEqual(212827.81746849261, mesh.Nodes[4].X); Assert.AreEqual(6156804.9152286667, mesh.Nodes[4].Y); Assert.AreEqual(-0.42102556956959569, mesh.Nodes[4].Z); Assert.AreEqual(1, mesh.Nodes[5].Code); Assert.AreEqual(724, mesh.Elements.Count); Assert.AreEqual(4, mesh.Elements[4].Index); Assert.AreEqual(5, mesh.Elements[4].Id); Assert.AreEqual(3, mesh.Elements[4].Nodes.Count); Assert.AreEqual(62, mesh.Elements[4].Nodes[0].Index); // Remember: Index here is zero based, while mesh file is one-based Assert.AreEqual(367, mesh.Elements[4].Nodes[1].Index); Assert.AreEqual(358, mesh.Elements[4].Nodes[2].Index); mesh.BuildNodeElements(); Assert.AreEqual(4, mesh.Nodes[4].Elements.Count); Assert.AreEqual(33, mesh.Nodes[4].Elements[0].Id); Assert.AreEqual(36, mesh.Nodes[4].Elements[1].Id); Assert.AreEqual(43, mesh.Nodes[4].Elements[2].Id); Assert.AreEqual(58, mesh.Nodes[4].Elements[3].Id); mesh.BuildFaces(true); FaceRevert(mesh, mesh.Faces); mesh.Faces.Sort(FaceSortComparer); Assert.AreEqual(1259, mesh.Faces.Count); Assert.AreEqual(1, mesh.Faces[0].FromNode.Id); Assert.AreEqual(42, mesh.Faces[0].ToNode.Id); Assert.AreEqual(1, mesh.Faces[1].FromNode.Id); Assert.AreEqual(251, mesh.Faces[1].ToNode.Id); Assert.AreEqual(1, mesh.Faces[2].FromNode.Id); Assert.AreEqual(309, mesh.Faces[2].ToNode.Id); int ind = mesh.Faces.FindIndex(mf => mf.FromNode.Id == 68); Assert.AreEqual(202, ind); Assert.AreEqual(68, mesh.Faces[ind].FromNode.Id); Assert.AreEqual(43, mesh.Faces[ind].ToNode.Id); Assert.AreEqual(1, mesh.Faces[ind].Code); Assert.AreEqual(366, mesh.Faces[ind].LeftElement.Id); Assert.AreEqual(null, mesh.Faces[ind].RightElement); }
private void selectMesh() { if (dImportDialog.ShowDialog() == DialogResult.OK) { string basefile = Path.GetDirectoryName(dImportDialog.FileName); string filename = Path.GetFileName(dImportDialog.FileName); FileSystem fs = new FileSystem(); fs.addRoot(basefile); dAnimations.DropDownItems.Clear(); ToolStripButton btn = new ToolStripButton("Add animations"); btn.Click += new EventHandler(btn_Click); dAnimations.DropDownItems.Add(btn); string extent = Path.GetExtension(filename); if (extent == ".act") { anim = null; Actor act = ActorFile.Load(fs, filename); def = act.Mesh; mesh = null; foreach (KeyValuePair <string, Animation> an in act.Animations) { addAnimation(an.Key, an.Value); } } else { def = MeshFile.Load(fs, filename); anim = null; } newMesh(fs); updatePose(); dModelActions.Text = filename; dMeshInfo.Text = string.Format("{0} points, {1} texcoords {2} tris, {3}/{4} bones", def.points.Count, def.uvs.Count, def.TriCount, def.bones.Count, new List <MeshDef.Bone>(def.RootBones).Count); forceRedraw(); } }
public static PartWrapper GetPartFromLif(LifFile lif, int partID, bool loadMeshes) { var primitiveFolder = lif.GetFolder("Primitives"); var meshesFolder = primitiveFolder.GetFolder("LOD0"); var primitiveEntry = primitiveFolder.GetFile($"{partID}.xml"); if (primitiveEntry == null) { throw new FileNotFoundException($"Primitive file not found. ({partID}.xml)"); } var surfaces = new List <PartSurfaceMesh>(); foreach (var meshEntry in meshesFolder.GetFiles($"{partID}.g*")) { if (!PartSurfaceMesh.ParseSurfaceID(meshEntry.Name, out int surfID)) { surfID = surfaces.Count; } var surfaceInfo = new PartSurfaceMesh(partID, surfID, loadMeshes ? MeshFile.Read(meshEntry.GetStream()) : null); surfaces.Add(surfaceInfo); } if (!surfaces.Any()) { throw new FileNotFoundException($"Mesh file not found. ({partID}.g)"); } var primitive = Primitive.Load(primitiveEntry.GetStream()); primitive.ID = partID; return(new PartWrapper(primitive, surfaces) { PartID = partID }); }
public void MeshBoundaryToFileTest() { string triMesh = UnitTestHelper.TestDataDir + "odense_rough.mesh"; MeshFile meshFile = MeshFile.ReadMesh(triMesh); MeshData mesh = meshFile.ToMeshData(); List <MeshBoundary> boundaries = MeshBoundary.BuildBoundaryList(mesh); Assert.AreEqual(2, boundaries.Count); Assert.AreEqual(1, boundaries[0].Code); Assert.AreEqual(2, boundaries[1].Code); Assert.AreEqual(2, boundaries[0].Segments.Count); Assert.AreEqual(1, boundaries[1].Segments.Count); Assert.AreEqual(9, boundaries[1].Segments[0].Count); // First node of the first code-1 boundary segment is the last node of the code-2 boundary segment Assert.IsTrue(boundaries[0].Segments[0][0].FromNode == boundaries[1].Segments[0].Last().ToNode); Assert.IsTrue(boundaries[0].Segments[0].Last().ToNode == boundaries[1].Segments[0][0].FromNode); StreamWriter writer = new StreamWriter(UnitTestHelper.TestDataDir + "out_odense_rough-bnd.txt"); foreach (MeshBoundary meshBoundary in boundaries) { writer.WriteLine("# " + meshBoundary.Code); foreach (List <MeshFace> segment in meshBoundary.Segments) { writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} {1}", segment[0].FromNode.X, segment[0].FromNode.Y)); foreach (MeshFace face in segment) { writer.WriteLine(string.Format(CultureInfo.InvariantCulture, "{0} {1}", face.ToNode.X, face.ToNode.Y)); } writer.WriteLine(""); } writer.WriteLine(""); } writer.Close(); }
public void InterpolateElementValuesToXYExample() { // Source mesh string triMesh = UnitTestHelper.TestDataDir + "odense_rough.mesh"; MeshFile meshFile = MeshFile.ReadMesh(triMesh); MeshData mesh = meshFile.ToMeshData(); mesh.BuildDerivedData(); // Element center values - usually read from dfsu file - here // we just calculate some arbitrary linear function of (x,y) double[] sourceValues = new double[meshFile.NumberOfElements]; for (int i = 0; i < meshFile.NumberOfElements; i++) { sourceValues[i] = 2 * mesh.Elements[i].XCenter + mesh.Elements[i].YCenter; } // Mesh interpolator MeshInterpolator2D interpolator = new MeshInterpolator2D(mesh, MeshValueType.Elements); // Coordinates to interpolate values to interpolator.SetTargetSize(3); interpolator.AddTarget(216600, 6159900); interpolator.AddTarget(216700, 6159900); interpolator.AddTarget(216700, 6160000); // Array to interpolate values to double[] targetValues = new double[3]; // Interpolate element values to target values interpolator.InterpolateElmtToTarget(sourceValues, targetValues); // Test that values are really 2*x+y Assert.AreEqual(2 * 216600 + 6159900, targetValues[0], 1e-6); Assert.AreEqual(2 * 216700 + 6159900, targetValues[1], 1e-6); Assert.AreEqual(2 * 216700 + 6160000, targetValues[2], 1e-6); }
public static PartWrapper GetPartFromDirectory(string path, int partID, bool loadMeshes) { //var primitivesDir = Path.Combine(path, "db\\Primitives"); //var meshesDir = Path.Combine(path, "db\\Primitives\\LOD0"); var primitivesDir = path; var meshesDir = Path.Combine(path, "LOD0"); var primitiveFile = Path.Combine(primitivesDir, $"{partID}.xml"); if (!File.Exists(primitiveFile)) { throw new FileNotFoundException($"Primitive file not found. ({partID}.xml)"); } var surfaces = new List <PartSurfaceMesh>(); foreach (string meshPath in Directory.GetFiles(meshesDir, $"{partID}.g*")) { if (!PartSurfaceMesh.ParseSurfaceID(meshPath, out int surfID)) { surfID = surfaces.Count; } surfaces.Add(new PartSurfaceMesh(partID, surfID, loadMeshes ? MeshFile.Read(meshPath) : null)); } if (!surfaces.Any()) { throw new FileNotFoundException($"Mesh file not found. ({partID}.g)"); } return(new PartWrapper(Primitive.Load(primitiveFile), surfaces) { PartID = partID }); }
public static MeshData Create(MeshFile mesh) { return(MeshData.CreateMesh(mesh.Projection, mesh.NodeIds, mesh.X, mesh.Y, mesh.Z, mesh.Code, mesh.ElementIds, mesh.ElementType, mesh.ElementTable)); }
public void InterpolationTest(string sourceMeshFileName, string targetMeshFileName, CircularValueTypes cvt = CircularValueTypes.Normal) { // Source mesh MeshFile meshFile = MeshFile.ReadMesh(sourceMeshFileName); MeshData mesh = meshFile.ToMeshData(); mesh.BuildDerivedData(); // Mesh to interpolate to MeshFile targetFile = MeshFile.ReadMesh(targetMeshFileName); MeshData targetmesh = targetFile.ToMeshData(); // Setup interpolator MeshInterpolator2D interpolator = new MeshInterpolator2D(mesh) { CircularType = cvt, AllowExtrapolation = true }; interpolator.SetupNodeInterpolation(); interpolator.SetTarget(targetmesh); // Find reference x and y value as the smallest x and y value double xMin = mesh.Nodes.Select(mn => mn.X).Min(); double xMax = mesh.Nodes.Select(mn => mn.X).Max(); double yMin = mesh.Nodes.Select(mn => mn.Y).Min(); double yMax = mesh.Nodes.Select(mn => mn.Y).Max(); // Function over the (x,y) plane. Func <double, double, double> function = ValueFunction(cvt, xMin, yMin, xMax, yMax); // Calculate element center values of function double[] elmtVals = new double[mesh.Elements.Count]; for (int i = 0; i < mesh.Elements.Count; i++) { MeshElement elmt = mesh.Elements[i]; elmtVals[i] = function(elmt.XCenter, elmt.YCenter); } // Write out bounds, to check we got things right Console.Out.WriteLine("{0,10} (min,max) = ({1},{2})", cvt, elmtVals.Min(), elmtVals.Max()); // Interpolate to nodes double[] targetValues = new double[targetmesh.Elements.Count]; interpolator.InterpolateToTarget(elmtVals, targetValues); // Check node values for (int i = 0; i < targetmesh.Elements.Count; i++) { MeshElement targetElmt = targetmesh.Elements[i]; double exactValue = function(targetElmt.XCenter, targetElmt.YCenter); double interpValue = targetValues[i]; double diff = exactValue - interpValue; // Check if target element has a boundary node. // Nodes on the boundary may not have correctly interpolated value due to // inverse distance interpolation on the boundary, and hence also interpolation // to target element value will not be exact. So only check on those elements that are // fully internal (no boundary nodes). bool internalElmt = targetElmt.Nodes.Select(node => node.Code).All(code => code == 0); if (internalElmt && diff > 1e-6 * Math.Max(Math.Abs(exactValue), 1)) { string msg = string.Format("{0,2} : {1}-{2}={3} ({4},{5})", i, exactValue, interpValue, diff, targetElmt.XCenter, targetElmt.YCenter); Console.Out.WriteLine(msg); Assert.Fail(msg); } } }
public static void CreateLDDPackages() { string lddDir = Environment.ExpandEnvironmentVariables(@"%appdata%\LEGO Company\LEGO Digital Designer\"); string primitiveDir = Path.Combine(lddDir, "db\\Primitives"); string meshDir = Path.Combine(lddDir, "db\\Primitives\\LOD0"); string decorationDir = Path.Combine(lddDir, "db\\Decorations"); var lddPalette = PaletteFile.FromLif(Path.Combine(lddDir, "Palettes\\LDD.lif")).Palettes[0]; var xmlDecMap = XDocument.Load(Path.Combine(lddDir, "db\\DecorationMapping.xml")); var decMappings = new List <LDD.Data.DecorationMapping>(); foreach (var elem in xmlDecMap.Root.Elements("Mapping")) { decMappings.Add(XmlHelper.DefaultDeserialize <LDD.Data.DecorationMapping>(elem)); } foreach (var primitivePath in Directory.GetFiles(primitiveDir, "*.xml") .OrderBy(x => int.Parse(Path.GetFileNameWithoutExtension(x)))) { var primitive = Primitive.Load(primitivePath); var package = new PartPackage() { PartID = int.Parse(Path.GetFileNameWithoutExtension(primitivePath)), Primitive = primitive }; var myDecorations = decMappings.Where(x => x.DesignID == package.PartID); if (myDecorations.Any()) { package.DecorationMappings.AddRange( myDecorations.Select(x => new LDD.Palettes.Decoration(x.SurfaceID, x.DecorationID))); foreach (string decID in package.DecorationMappings.Select(x => x.DecorationID).Distinct()) { var imagePath = Directory.EnumerateFiles(decorationDir, decID + ".*").FirstOrDefault(); if (string.IsNullOrEmpty(imagePath)) { continue; } var img = Image.FromFile(imagePath); package.DecorationImages.Add(new DecorationImage(decID, img)); } } var myElements = lddPalette.Bricks.Where(x => x.DesignID == package.PartID); if (myElements.Any()) { package.Configurations.AddRange(myElements); } int surfaceId = 0; foreach (var meshPath in Directory.GetFiles(meshDir, package.PartID + ".g*").OrderBy(x => x)) { var mesh = MeshFile.Read(meshPath); package.Meshes.Add(new PartMesh(package.PartID, surfaceId++, mesh)); } string folderName = package.PartID.ToString()[0].ToString().PadRight(package.PartID.ToString().Length, '0'); package.Save($"LPI TEST\\{folderName}\\{package.PartID}.lpi"); package.Dispose(); } }
public PartMesh(int partID, int surfaceID, MeshFile mesh) { PartID = partID; SurfaceID = surfaceID; Mesh = mesh; }
private void AddMesh(MeshFile mesh, List <int> boundaryCodesToRemove = null) { // node numbers in new mesh for each node in provided mesh int[] renumberNodes = new int[mesh.NumberOfNodes]; // Reused variables Extent e = new Extent(); List <QuadSearchTree.Point> points = new List <QuadSearchTree.Point>(); // Index of first new node int newMeshFirstNodeIndex = _x.Count; // Add nodes of current mesh to merged mesh, find which nodes should be merged for (int i = 0; i < mesh.NumberOfNodes; i++) { double x = mesh.X[i]; double y = mesh.Y[i]; double z = mesh.Z[i]; int code = mesh.Code[i]; bool boundaryNode = code != 0; if (boundaryCodesToRemove != null && boundaryCodesToRemove.Contains(code)) { code = 0; } // This criteria selects which nodes to try to merge on, i.e. // when to try to find a "duplicate" in merged mesh. if (TryMergeAllNodes || boundaryNode) { // Check if this current node already "exists" in the merged mesh // i.e. if the current node is "close to" a node in the merged mesh. // "Close to" is decided by the NodeTolerance // Find all nodes within NodeTolerance of (x,y) in search tree UpdatePointExtent(e, x, y, NodeTolerance); points.Clear(); _nodeSearchTree.Find(e, points); if (points.Count > 0) { // find the point closest to (x,y), and witin NodeTolerance distance QuadSearchTree.Point closest = null; // Distance must be less than NodeTolerance in order to reuse existing node // Comparing on squared distances, to avoid taking a lot of square roots double minDistSq = NodeTolerance * NodeTolerance; foreach (QuadSearchTree.Point point in points) { double dx = point.X - x; double dy = point.Y - y; double distSq = dx * dx + dy * dy; if (distSq < minDistSq) { closest = point; minDistSq = distSq; } } if (closest != null) { // Node already exist at/close to coordinate, use existing node // and disregard the current node, remember node number (1-based) // for renumbering when adding elements from current mesh. renumberNodes[i] = closest.No; // Update boundary code if (_code[closest.No - 1] == 0 && code != 0) { _code[closest.No - 1] = code; } // Store some statistics NodeMergeCount++; // Skip from here, since the current node should not be added // to the merged mesh. continue; } } } // Add node to merged mesh _x.Add(x); _y.Add(y); _z.Add(z); _code.Add(code); // Number of node (1-based) in new mesh int nodeNum = _x.Count; // remember new node number, for renumbering when adding elements from current mesh renumberNodes[i] = nodeNum; } // Add all new nodes to the quad search tree. New nodes are first added to the search tree // now, such that the merge routine never merges two nodes from the same mesh. for (int i = newMeshFirstNodeIndex; i < _x.Count; i++) { // Add to search tree QuadSearchTree.Point p = new QuadSearchTree.Point() { No = i + 1, X = _x[i], Y = _y[i], }; _nodeSearchTree.Add(p); } // Add all elements for (int i = 0; i < mesh.NumberOfElements; i++) { _elementType.Add(mesh.ElementType[i]); // Renumber the nodes of each element to the new node numbers int[] meshElmt = mesh.ElementTable[i]; int[] newelmt = new int[meshElmt.Length]; for (int j = 0; j < meshElmt.Length; j++) { newelmt[j] = renumberNodes[meshElmt[j] - 1]; } _connectivity.Add(newelmt); } }
/// <summary> /// Process the incoming mesh file names /// </summary> /// <param name="files">List of mesh file names to merge</param> /// <param name="fileBoundaryCodesToRemove">List of boundary codes to remove for each mesh. Must match the size of the files argument</param> public void Process(List <string> files, List <List <int> > fileBoundaryCodesToRemove = null) { // Extent of entire domain, all meshes Extent extent = new Extent(); // Load all meshes List <MeshFile> meshes = new List <MeshFile>(files.Count); for (int i = 0; i < files.Count; i++) { MeshFile mesh = MeshFile.ReadMesh(files[i]); meshes.Add(mesh); for (int j = 0; j < mesh.NumberOfNodes; j++) { extent.Include(mesh.X[j], mesh.Y[j]); } } // grow it a littl bit, in case of rounding errors extent.XMin = extent.XMin - NodeTolerance; extent.XMax = extent.XMax + NodeTolerance; extent.YMin = extent.YMin - NodeTolerance; extent.YMax = extent.YMax + NodeTolerance; // Initialize search tree _nodeSearchTree = new QuadSearchTree(extent); // Create new mesh nodes and elements for (int i = 0; i < files.Count; i++) { int prevNodeMergeCount = NodeMergeCount; List <int> boundaryCodesToRemove = fileBoundaryCodesToRemove != null ? fileBoundaryCodesToRemove[i] : null; AddMesh(meshes[i], boundaryCodesToRemove); if (i > 0) { Console.Out.WriteLine("Mesh {0}, number of nodes merged in: {1}", i + 1, NodeMergeCount - prevNodeMergeCount); } } Console.Out.WriteLine("Total number of nodes merged in : {0}", NodeMergeCount); RemoveInternalBoundaryCodes(_code, _connectivity); // Create new mesh file string projection = meshes[0].ProjectionString; eumQuantity eumQuantity = meshes[0].EumQuantity; MeshBuilder builder = new MeshBuilder(); builder.SetNodes(_x.ToArray(), _y.ToArray(), _z.ToArray(), _code.ToArray()); builder.SetElements(_connectivity.ToArray()); builder.SetProjection(projection); builder.SetEumQuantity(eumQuantity); MeshFile newMesh = builder.CreateMesh(); MeshValidator meshValidator = new MeshValidator(); meshValidator.ValidateMesh(newMesh.X, newMesh.Y, newMesh.Code, newMesh.ElementTable); foreach (string error in meshValidator.Errors) { Console.Out.WriteLine(error); } newMesh.Write(_newMeshFileName); //------------------------------------- // Do some statistics on the mesh: // collect number of face codes for each mesh SortedDictionary <int, int[]> bcCodesStats = new SortedDictionary <int, int[]>(); List <MeshValidator> validators = new List <MeshValidator>(); for (int meshIndex = 0; meshIndex < meshes.Count; meshIndex++) { MeshFile meshFile = meshes[meshIndex]; MeshValidator validator = new MeshValidator(); validator.ValidateMesh(meshFile.X, meshFile.Y, meshFile.Code, meshFile.ElementTable); validators.Add(validator); UpdateStatistics(meshes.Count + 1, meshIndex, bcCodesStats, validator.GetFaceCodeStatistics()); } UpdateStatistics(meshes.Count + 1, meshes.Count, bcCodesStats, meshValidator.GetFaceCodeStatistics()); Console.Out.Write("---------------------"); Console.Out.Write(" Statistics of faces "); Console.Out.Write("---------------------"); Console.Out.WriteLine(""); Console.Out.Write("FaceCode |"); for (int i = 0; i < meshes.Count; i++) { Console.Out.Write(" mesh {0,2} ", i + 1); } Console.Out.Write(" | total | new mesh"); Console.Out.WriteLine(""); int[] totals = new int[meshes.Count + 2]; foreach (KeyValuePair <int, int[]> keyValuePair in bcCodesStats) { Console.Out.Write(" {0,4} |", keyValuePair.Key); int total = 0; for (int index = 0; index < keyValuePair.Value.Length - 1; index++) { int meshCodeCount = keyValuePair.Value[index]; total += meshCodeCount; totals[index] += meshCodeCount; Console.Out.Write(" {0,7} ", meshCodeCount); } totals[meshes.Count] += total; totals[meshes.Count + 1] += keyValuePair.Value.Last(); Console.Out.Write(" |{0,7} | ", total); Console.Out.Write(" {0,7} ", keyValuePair.Value.Last()); Console.Out.WriteLine(""); } Console.Out.Write(" total |"); for (int index = 0; index < meshes.Count; index++) { Console.Out.Write(" {0,7} ", totals[index]); } Console.Out.Write(" |{0,7} | ", totals[meshes.Count]); Console.Out.Write(" {0,7} ", totals[meshes.Count + 1]); Console.Out.WriteLine(""); Console.Out.Write("---------------------"); Console.Out.Write("---------------------"); Console.Out.Write("---------------------"); Console.Out.WriteLine(""); }
public static SMeshData SCreate(MeshFile mesh) { return(new SMeshData(mesh.Projection, mesh.NodeIds, mesh.X, mesh.Y, mesh.Z, mesh.Code, mesh.ElementIds, mesh.ElementType, mesh.ElementTable.ToZeroBased())); }
public MeshEditorViewModel(MeshFile file) { MeshFile = file; EditTextureBindingsCommand = new ActionCommand(EditTextureBindingsExecute); }
/// <summary> /// Example of how to plot a mesh file. A mesh contains bottom levels in each node. /// </summary> public static void MeshTest(bool makeBmp) { DHI.Chart.Map.Chart.Init(); // Load mesh data string pathName = Path.Combine(UnitTestHelper.TestDataRoot, @"oresund.mesh"); MeshFile meshFile = MeshFile.ReadMesh(pathName); // FemGridData is data for the bottom levels, a value in each element node, used for coloring FemGridData data = new FemGridData(); data.CreateNodesAndElements(meshFile.NumberOfNodes, meshFile.NumberOfElements, meshFile.X, meshFile.Y, meshFile.Z.ToFloatArray(), meshFile.ElementTable); // Create chart DHI.Chart.Map.Chart chart = new DHI.Chart.Map.Chart(); // Add overlay that plots the bottom levels FemGridOverlay overlay = new FemGridOverlay(); overlay.SetGridData(data); overlay.EnableNiceValue = true; overlay.CreateAutoScaledRainbowPalette(); overlay.EnableIsoline = true; overlay.ColoringType = MapOverlay.EColoringType.ContinuousColoring; overlay.SetFeathering(true, 0.5f); overlay.EnableIsolineLabel = true; chart.AddOverlay(overlay); // Grab map projection of meshfile MapProjection mapProj = new MapProjection(meshFile.ProjectionString); double lonOrigin, latOrigin, eastOrigin, northOrigin; mapProj.GetOrigin(out lonOrigin, out latOrigin); mapProj.Geo2Proj(lonOrigin, latOrigin, out eastOrigin, out northOrigin); double convergence = mapProj.GetConvergence(lonOrigin, latOrigin); // Overlay adding geographical lines // Mesh is drawn in map projection coordinates GeoGridOverlay ggOverlay = new GeoGridOverlay(); ggOverlay.ReferenceProjection = meshFile.ProjectionString; ggOverlay.DisplayProjection = meshFile.ProjectionString; // Origin for mesh data is the origin of the projection ggOverlay.SetGeoOrigin(lonOrigin, latOrigin); ggOverlay.SetOrigin(eastOrigin, northOrigin); // Mesh overlay draws in map projection coordinates, so north-Y rotation is the convergence (which is zero) ggOverlay.SetNYCRotation(convergence); ggOverlay.EnableLonLatGrid = true; ggOverlay.EnableMapProjGrid = true; // DataValid must be set after changing in GeoGridOverlay ggOverlay.DataValid = true; chart.AddOverlay(ggOverlay); // Select rectangle to plot, by default the full data area MzRectangle wrect = new MzRectangle(); data.GetDataArea(wrect); // Here you may limit the area to be plotted //wrect.X0 = wrect.X0 + 20000; //wrect.Y0 = wrect.Y0 + 20000; //wrect.X1 = wrect.X0 + 30000; //wrect.Y1 = wrect.Y0 + 30000; chart.SetDataArea(wrect); chart.SetView(wrect); //chart.GetActiveCoordinateSystem().SetDrawAxis(true, true); //chart.GetActiveCoordinateSystem().EnableBorder(true); //chart.DrawGrid = true; //chart.DrawTitle = true; // Draw to bitmap double ratio = wrect.Width / (double)wrect.Height; Bitmap bmp = new Bitmap(((int)(ratio * 1024)) + 10, 1024); chart.Draw(bmp); chart.Dispose(); if (makeBmp) { string pngFilepath = Path.Combine(UnitTestHelper.TestDataRoot, @"oresundMesh.png"); bmp.Save(pngFilepath); System.Diagnostics.Process.Start(pngFilepath); } }
public void AddSurfaceMesh(int surfaceID, MeshFile meshFile) { Surfaces.Add(new PartSurfaceMesh(PartID, surfaceID, meshFile)); }
public void InterpolateToXYExample(bool nodeInterp) { // Source mesh string triMesh = UnitTestHelper.TestDataDir + "small.mesh"; MeshFile meshFile = MeshFile.ReadMesh(triMesh); SMeshData mesh = meshFile.ToSMeshData(); // Build derived data, required for the interpolation routines mesh.BuildDerivedData(); // Create element center Z values array double[] elmtZ = new double[meshFile.NumberOfElements]; Array.Copy(mesh.ElementZCenter, elmtZ, mesh.NumberOfElements); // Make a strong peak at element 5 - in the center of the mesh elmtZ[4] = -6; // Set up so source can be both element values and node values MeshValueType sourceType = MeshValueType.Elements | MeshValueType.Nodes; // Mesh interpolator MeshInterpolator2D interpolator = new MeshInterpolator2D(mesh, sourceType); if (nodeInterp) { // Simpler interpolation type interpolator.ElementValueInterpolationType = MeshInterpolator2D.ElmtValueInterpolationType.NodeValues; } // Interpolate elmtZ to nodeZ double[] nodeZInterp = new double[mesh.NumberOfNodes]; interpolator.SetupElmtToNodeInterpolation(); interpolator.NodeInterpolator.Interpolate(elmtZ, nodeZInterp); // Interpolation of values one-by-one, no storing of interpolation weights Assert.AreEqual(-5.999, interpolator.InterpolateElmtToXY(0.7833, 0.531, elmtZ, nodeZInterp), 1e-3); Assert.AreEqual(-3.543, interpolator.InterpolateNodeToXY(0.7833, 0.531, nodeZInterp), 1e-3); // Add targets, to store interpolation weights interpolator.SetTargetSize(mesh.NumberOfElements + 1); interpolator.AddTarget(0.7833, 0.531); // Target at (almost) center of element 5 for (int i = 0; i < mesh.NumberOfElements; i++) { interpolator.AddTarget(mesh.ElementXCenter[i], mesh.ElementYCenter[i]); } // Array to interpolate values to double[] targetValues = new double[mesh.NumberOfElements + 1]; // Interpolate to all target points interpolator.InterpolateElmtToTarget(elmtZ, targetValues); if (!nodeInterp) { // When element+node values are used, close to peak value of 6 Assert.AreEqual(-5.999, targetValues[0], 1e-3); Assert.AreEqual(-3.8225, targetValues[1], 1e-3); for (int i = 0; i < mesh.NumberOfElements; i++) { Assert.AreEqual(elmtZ[i], targetValues[i + 1]); } } else // Using only node interpolation, the value is cut off { Assert.AreEqual(-3.543, targetValues[0], 1e-3); Assert.AreEqual(-3.649, targetValues[1], 1e-3); } // Interpolating in node Z values, matching to box center value of element. interpolator.InterpolateNodeToTarget(mesh.Z, targetValues); Assert.AreEqual(-4.376, targetValues[0], 1e-3); Assert.AreEqual(-4.376, mesh.ElementZCenter[4], 1e-3); }