private Matrix4X4 GetCenteringTransformVisualCenter(IEnumerable <IObject3D> items, double goalRadius) { IEnumerable <(Vector2, Vector2, Vector2)> GetPolygons() { foreach (var item in items) { foreach (var meshItem in item.VisibleMeshes()) { var worldMatrix = meshItem.WorldMatrix(this); var faces = meshItem.Mesh.Faces; var vertices = meshItem.Mesh.Vertices; foreach (var face in faces) { if (face.normal.TransformNormal(worldMatrix).Z > 0) { yield return( new Vector2(vertices[face.v0].Transform(worldMatrix)), new Vector2(vertices[face.v1].Transform(worldMatrix)), new Vector2(vertices[face.v2].Transform(worldMatrix)) ); } } } } } var outsidePolygons = new List <List <IntPoint> >(); var projection = new Polygons(); // remove all holes from the polygons so we only center the major outlines var polygons = OrthographicZProjection.GetClipperPolygons(GetPolygons()); foreach (var polygon in polygons) { if (polygon.GetWindingDirection() == 1) { outsidePolygons.Add(polygon); } } IVertexSource outsideSource = outsidePolygons.CreateVertexStorage(); Vector2 center = outsideSource.GetWeightedCenter(); outsideSource = new VertexSourceApplyTransform(outsideSource, Affine.NewTranslation(-center)); double radius = MaxXyDistFromCenter(outsideSource); double scale = goalRadius / radius; var scalling = Matrix4X4.CreateScale(scale, scale, 1); var centering = Matrix4X4.CreateTranslation(-center.X, -center.Y, 0); return(centering * scalling); }
private void LoadStl_Click(object sender, EventArgs e) { OpenFileDialogParams opeParams = new OpenFileDialogParams("STL Files|*.stl"); FileDialog.OpenFileDialog(opeParams, (openParams) => { var streamToLoadFrom = File.Open(openParams.FileName, FileMode.Open); if (streamToLoadFrom != null) { var loadedFileName = openParams.FileName; meshToRender = StlProcessing.Load(streamToLoadFrom); ImageBuffer plateInventory = new ImageBuffer((int)(300 * 8.5), 300 * 11, 32, new BlenderBGRA()); Graphics2D plateGraphics = plateInventory.NewGraphics2D(); plateGraphics.Clear(RGBA_Bytes.White); double inchesPerMm = 0.0393701; double pixelsPerInch = 300; double pixelsPerMm = inchesPerMm * pixelsPerInch; AxisAlignedBoundingBox aabb = meshToRender.GetAxisAlignedBoundingBox(); Vector2 lowerLeftInMM = new Vector2(-aabb.minXYZ.x, -aabb.minXYZ.y); Vector3 centerInMM = (aabb.maxXYZ - aabb.minXYZ) / 2; Vector2 offsetInMM = new Vector2(20, 30); { RectangleDouble bounds = new RectangleDouble(offsetInMM.x * pixelsPerMm, offsetInMM.y * pixelsPerMm, (offsetInMM.x + aabb.maxXYZ.x - aabb.minXYZ.x) * pixelsPerMm, (offsetInMM.y + aabb.maxXYZ.y - aabb.minXYZ.y) * pixelsPerMm); bounds.Inflate(3 * pixelsPerMm); RoundedRect rect = new RoundedRect(bounds, 3 * pixelsPerMm); plateGraphics.Render(rect, RGBA_Bytes.LightGray); Stroke rectOutline = new Stroke(rect, .5 * pixelsPerMm); plateGraphics.Render(rectOutline, RGBA_Bytes.DarkGray); } OrthographicZProjection.DrawTo(plateGraphics, meshToRender, lowerLeftInMM + offsetInMM, pixelsPerMm); plateGraphics.DrawString(Path.GetFileName(openParams.FileName), (offsetInMM.x + centerInMM.x) * pixelsPerMm, (offsetInMM.y - 10) * pixelsPerMm, 50, Agg.Font.Justification.Center); //ImageBuffer logoImage = new ImageBuffer(); //ImageIO.LoadImageData("Logo.png", logoImage); //plateGraphics.Render(logoImage, (plateInventory.Width - logoImage.Width) / 2, plateInventory.Height - logoImage.Height - 10 * pixelsPerMm); //ImageIO.SaveImageData("plate Inventory.jpeg", plateInventory); } }); }