/// <summary> /// Generates a row of cylinders tessellated w/ different chord lengths /// eg 10x1cm : CalibrationModelGenerator.MakePrintStepSizeTest(10.0f, 10.0f, 0.1, 1.0, 10); /// </summary> public static DMesh3 MakePrintStepSizeTest(double cylDiam, double cylHeight, double lowStep, double highStep, int nSteps) { double spacing = 2.0f; float r = (float)cylDiam * 0.5f; double cx = 0.5 * (nSteps * cylDiam + (nSteps - 1) * spacing); DMesh3 accumMesh = new DMesh3(); double cur_x = -cx + cylDiam / 2; for (int k = 0; k < nSteps; ++k) { double t = (double)k / (double)(nSteps - 1); double chord_len = (1.0 - t) * lowStep + (t) * highStep; int slices = (int)((MathUtil.TwoPI * r) / chord_len); CappedCylinderGenerator cylgen = new CappedCylinderGenerator() { BaseRadius = r, TopRadius = r, Height = (float)cylHeight, Slices = slices, NoSharedVertices = false }; DMesh3 cylMesh = cylgen.Generate().MakeDMesh(); MeshTransforms.Translate(cylMesh, -cylMesh.CachedBounds.Min.y * Vector3d.AxisY); MeshTransforms.Translate(cylMesh, cur_x * Vector3d.AxisX); cur_x += cylDiam + spacing; MeshEditor.Append(accumMesh, cylMesh); } MeshTransforms.ConvertYUpToZUp(accumMesh); return(accumMesh); }
static void Main(string[] args) { CappedCylinderGenerator cylgen = new CappedCylinderGenerator() { BaseRadius = 10, TopRadius = 5, Height = 20, Slices = 32 }; DMesh3 mesh = cylgen.Generate().MakeDMesh(); MeshTransforms.ConvertYUpToZUp(mesh); // g3 meshes are usually Y-up // center mesh above origin AxisAlignedBox3d bounds = mesh.CachedBounds; Vector3d baseCenterPt = bounds.Center - bounds.Extents.z * Vector3d.AxisZ; MeshTransforms.Translate(mesh, -baseCenterPt); // create print mesh set PrintMeshAssembly meshes = new PrintMeshAssembly(); meshes.AddMesh(mesh, PrintMeshOptions.Default()); // create settings //MakerbotSettings settings = new MakerbotSettings(Makerbot.Models.Replicator2); //PrintrbotSettings settings = new PrintrbotSettings(Printrbot.Models.Plus); //MonopriceSettings settings = new MonopriceSettings(Monoprice.Models.MP_Select_Mini_V2); RepRapSettings settings = new RepRapSettings(RepRap.Models.Unknown); // do slicing MeshPlanarSlicer slicer = new MeshPlanarSlicer() { LayerHeightMM = settings.LayerHeightMM }; slicer.Add(meshes); PlanarSliceStack slices = slicer.Compute(); // run print generator SingleMaterialFFFPrintGenerator printGen = new SingleMaterialFFFPrintGenerator(meshes, slices, settings); if (printGen.Generate()) { // export gcode GCodeFile gcode = printGen.Result; using (StreamWriter w = new StreamWriter("c:\\demo\\cone.gcode")) { StandardGCodeWriter writer = new StandardGCodeWriter(); writer.WriteFile(gcode, w); } } }
public IOWriteResult RunBackgroundWrite() { // transform meshes gParallel.ForEach(Interval1i.Range(ExportMeshes.Length), (i) => { if (MeshFrames[i].Origin != Vector3f.Zero || MeshFrames[i].Rotation != Quaternionf.Identity) { MeshTransforms.FromFrame(ExportMeshes[i], MeshFrames[i]); } MeshTransforms.FlipLeftRightCoordSystems(ExportMeshes[i]); if (ExportYUp == false) { MeshTransforms.ConvertYUpToZUp(ExportMeshes[i]); } }); List <WriteMesh> writeMeshes = new List <WriteMesh>(); for (int i = 0; i < ExportMeshes.Length; ++i) { writeMeshes.Add(new WriteMesh(ExportMeshes[i])); } WriteOptions options = WriteOptions.Defaults; options.bWriteBinary = true; options.ProgressFunc = BackgroundProgressFunc; StandardMeshWriter writer = new StandardMeshWriter(); IOWriteResult result = writer.Write(WritePath, writeMeshes, options); return(result); }
public void Compute() { int N = meshToScene.Length; slicer = new MeshPlanarSlicerPro() { LayerHeightMM = CC.Settings.LayerHeightMM, // [RMS] 1.5 here is a hack. If we don't leave a bit of space then often the filament gets squeezed right at // inside/outside transitions, which is bad. Need a better way to handle. OpenPathDefaultWidthMM = CC.Settings.NozzleDiameterMM * 1.5, SetMinZValue = 0, SliceFactoryF = PlanarSlicePro.FactoryF }; if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Clipped) { slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Clipped; } else if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Embedded) { slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Embedded; } else if (CC.Settings.OpenMode == PrintSettings.OpenMeshMode.Ignored) { slicer.DefaultOpenPathMode = PrintMeshOptions.OpenPathsModes.Ignored; } if (CC.Settings.StartLayers > 0) { int start_layers = CC.Settings.StartLayers; double std_layer_height = CC.Settings.LayerHeightMM; double start_layer_height = CC.Settings.StartLayerHeightMM; slicer.LayerHeightF = (layer_i) => { return((layer_i < start_layers) ? start_layer_height : std_layer_height); }; } try { assembly = new PrintMeshAssembly(); for (int k = 0; k < N; ++k) { DMesh3 mesh = meshCopies[k]; Frame3f mapF = meshToScene[k]; PrintMeshSettings settings = meshSettings[k]; PrintMeshOptions options = new PrintMeshOptions(); options.IsSupport = (settings.ObjectType == PrintMeshSettings.ObjectTypes.Support); options.IsCavity = (settings.ObjectType == PrintMeshSettings.ObjectTypes.Cavity); options.IsCropRegion = (settings.ObjectType == PrintMeshSettings.ObjectTypes.CropRegion); options.IsOpen = false; if (settings.OuterShellOnly) { options.IsOpen = true; } options.OpenPathMode = PrintMeshSettings.Convert(settings.OpenMeshMode); options.Extended = new ExtendedPrintMeshOptions() { ClearanceXY = settings.Clearance, OffsetXY = settings.OffsetXY }; Vector3f scale = localScale[k]; MeshTransforms.Scale(mesh, scale.x, scale.y, scale.z); MeshTransforms.FromFrame(mesh, mapF); MeshTransforms.FlipLeftRightCoordSystems(mesh); MeshTransforms.ConvertYUpToZUp(mesh); MeshAssembly decomposer = new MeshAssembly(mesh); decomposer.HasNoVoids = settings.NoVoids; decomposer.Decompose(); assembly.AddMeshes(decomposer.ClosedSolids, options); PrintMeshOptions openOptions = options.Clone(); assembly.AddMeshes(decomposer.OpenMeshes, openOptions); } if (slicer.Add(assembly) == false) { throw new Exception("error adding PrintMeshAssembly to Slicer!!"); } // set clip box Box2d clip_box = new Box2d(Vector2d.Zero, new Vector2d(CC.Settings.BedSizeXMM / 2, CC.Settings.BedSizeYMM / 2)); slicer.ValidRegions = new List <GeneralPolygon2d>() { new GeneralPolygon2d(new Polygon2d(clip_box.ComputeVertices())) }; result = slicer.Compute(); Success = true; } catch (Exception e) { DebugUtil.Log("GeometrySlicer.Compute: exception: " + e.Message); Success = false; } Finished = true; }
public static void test_uv_insert_segment() { DMesh3 mesh = TestUtil.LoadTestInputMesh("plane_250v.obj"); mesh.EnableVertexUVs(Vector2f.Zero); MeshTransforms.ConvertYUpToZUp(mesh); DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh); spatial.Build(); int tid = spatial.FindNearestTriangle(Vector3d.Zero); //Polygon2d poly = Polygon2d.MakeRectangle(Vector2d.Zero, 5, 5); Polygon2d poly = Polygon2d.MakeCircle(5, 13); //PolyLine2d poly = new PolyLine2d( new Vector2d[] { -5 * Vector2d.One, 5 * Vector2d.One }); //int tri_edge0 = mesh.GetTriEdge(tid, 0); //Index2i edge0_tris = mesh.GetEdgeT(tri_edge0); //Index2i edge0_verts = mesh.GetEdgeV(tri_edge0); //Vector3d v0 = mesh.GetVertex(edge0_verts.a), v1 = mesh.GetVertex(edge0_verts.b); //Vector3d c = mesh.GetTriCentroid(tid); //Polygon2d poly = new Polygon2d(new Vector2d[] { // Vector2d.Lerp(v0.xy, v1.xy, -0.25), // Vector2d.Lerp(v0.xy, v1.xy, 1.5), // c.xy //}); MeshInsertUVPolyCurve insert = new MeshInsertUVPolyCurve(mesh, poly); insert.Apply(); Polygon2d test_poly = new Polygon2d(); List <double> distances = new List <double>(); List <int> nearests = new List <int>(); for (int i = 0; i < insert.Loops[0].VertexCount; ++i) { Vector2d v = mesh.GetVertex(insert.Loops[0].Vertices[i]).xy; test_poly.AppendVertex(v); int iNear; double fNear; distances.Add(poly.DistanceSquared(v, out iNear, out fNear)); nearests.Add(iNear); } System.Console.WriteLine("inserted loop poly has {0} edges", insert.Loops[0].EdgeCount); // find a triangle connected to loop that is inside the polygon // [TODO] maybe we could be a bit more robust about this? at least // check if triangle is too degenerate... int seed_tri = -1; for (int i = 0; i < insert.Loops[0].EdgeCount; ++i) { Index2i et = mesh.GetEdgeT(insert.Loops[0].Edges[i]); Vector3d ca = mesh.GetTriCentroid(et.a); bool in_a = poly.Contains(ca.xy); Vector3d cb = mesh.GetTriCentroid(et.b); bool in_b = poly.Contains(cb.xy); if (in_a && in_b == false) { seed_tri = et.a; break; } else if (in_b && in_a == false) { seed_tri = et.b; break; } } Util.gDevAssert(seed_tri != -1); // flood-fill inside loop HashSet <int> loopEdges = new HashSet <int>(insert.Loops[0].Edges); MeshFaceSelection sel = new MeshFaceSelection(mesh); sel.FloodFill(seed_tri, null, (eid) => { return(loopEdges.Contains(eid) == false); }); // delete inside loop MeshEditor editor = new MeshEditor(mesh); editor.RemoveTriangles(sel, true); MeshTransforms.ConvertZUpToYUp(mesh); TestUtil.WriteTestOutputMesh(mesh, "insert_uv_segment.obj"); //OBJWriter writer = new OBJWriter(); //var s = new System.IO.StreamWriter(Program.TEST_OUTPUT_PATH + "mesh_local_param.obj", false); //List<WriteMesh> wm = new List<WriteMesh>() { new WriteMesh(mesh) }; //WriteOptions opt = new WriteOptions() { // bCombineMeshes = false, bWriteGroups = false, bPerVertexColors = true, bPerVertexUVs = true, // AsciiHeaderFunc = () => { return "mttllib checkerboard.mtl\r\nusemtl checkerboard\r\n"; } //}; //writer.Write(s, wm, opt); //s.Close(); }