private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); using (RebuildLock()) { var aabb = this.GetAxisAlignedBoundingBox(); var path = new VertexStorage(); path.MoveTo(Width / 2, 0); for (int i = 1; i < Sides; i++) { var angle = MathHelper.Tau * i / 2 / (Sides - 1); path.LineTo(Math.Cos(angle) * Width / 2, Math.Sin(angle) * Width / 2); } var mesh = VertexSourceToMesh.Extrude(path, Depth); mesh.Transform(Matrix4X4.CreateRotationX(MathHelper.Tau / 4)); Mesh = mesh; if (aabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); }
private void CreateBase(List <MeshGroup> meshesList, List <Matrix4X4> meshTransforms, List <PlatingMeshGroupData> platingDataList) { if (meshesList.Count > 0) { AxisAlignedBoundingBox bounds = meshesList[0].GetAxisAlignedBoundingBox(meshTransforms[0]); for (int i = 1; i < meshesList.Count; i++) { bounds = AxisAlignedBoundingBox.Union(bounds, meshesList[i].GetAxisAlignedBoundingBox(meshTransforms[i])); } double roundingScale = 20; RectangleDouble baseRect = new RectangleDouble(bounds.minXYZ.x, bounds.minXYZ.y, bounds.maxXYZ.x, bounds.maxXYZ.y); baseRect.Inflate(2); baseRect *= roundingScale; RoundedRect baseRoundedRect = new RoundedRect(baseRect, 1 * roundingScale); Mesh baseMeshResult = VertexSourceToMesh.Extrude(baseRoundedRect, unscaledBaseHeight / 2 * roundingScale * sizeScrollBar.Value * heightScrollBar.Value); baseMeshResult.Transform(Matrix4X4.CreateScale(1 / roundingScale)); meshesList.Add(new MeshGroup(baseMeshResult)); platingDataList.Add(new PlatingMeshGroupData()); meshTransforms.Add(Matrix4X4.CreateTranslation(0, 0, 0)); PlatingHelper.CreateITraceableForMeshGroup(platingDataList, meshesList, meshesList.Count - 1, null); } }
private void AddCharacterMeshes(string currentText, TypeFacePrinter printer) { int newIndex = asynchMeshGroups.Count; StyledTypeFace typeFace = printer.TypeFaceStyle; for (int i = 0; i < currentText.Length; i++) { string letter = currentText[i].ToString(); TypeFacePrinter letterPrinter = new TypeFacePrinter(letter, typeFace); if (CharacterHasMesh(letterPrinter, letter)) { Mesh textMesh = VertexSourceToMesh.Extrude(letterPrinter, unscaledLetterHeight / 2); asynchMeshGroups.Add(new MeshGroup(textMesh)); PlatingMeshGroupData newMeshInfo = new PlatingMeshGroupData(); newMeshInfo.spacing = printer.GetOffsetLeftOfCharacterIndex(i); asynchPlatingDatas.Add(newMeshInfo); asynchMeshGroupTransforms.Add(ScaleRotateTranslate.Identity()); PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, newIndex, null); ScaleRotateTranslate moved = asynchMeshGroupTransforms[newIndex]; moved.translation *= Matrix4X4.CreateTranslation(new Vector3(0, 0, unscaledLetterHeight / 2)); asynchMeshGroupTransforms[newIndex] = moved; newIndex++; } processingProgressControl.PercentComplete = ((i + 1) * 95 / currentText.Length); } }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; using (RebuildLock()) { var sides = Sides.ClampIfNotCalculated(this, 3, 180, ref valuesChanged); using (new CenterAndHeightMaintainer(this)) { var path = new VertexStorage(); path.MoveTo(Width.Value(this) / 2, 0); for (int i = 1; i < sides; i++) { var angle = MathHelper.Tau * i / 2 / (sides - 1); path.LineTo(Math.Cos(angle) * Width.Value(this) / 2, Math.Sin(angle) * Width.Value(this) / 2); } var mesh = VertexSourceToMesh.Extrude(path, Depth.Value(this)); mesh.Transform(Matrix4X4.CreateRotationX(MathHelper.Tau / 4)); Mesh = mesh; } } Invalidate(InvalidateType.DisplayValues); Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return(Task.CompletedTask); }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); bool changed = false; using (RebuildLock()) { InnerDiameter = agg_basics.Clamp(InnerDiameter, 0, OuterDiameter - .1, ref changed); Sides = agg_basics.Clamp(Sides, 3, 360, ref changed); RingSides = agg_basics.Clamp(RingSides, 3, 360, ref changed); var ringSides = RingSides; var startingAngle = StartingAngle; var endingAngle = EndingAngle; var ringPhaseAngle = RingPhaseAngle; if (!Advanced) { ringSides = Math.Max(3, (int)(Sides / 2)); startingAngle = 0; endingAngle = 360; ringPhaseAngle = 0; } var innerDiameter = Math.Min(OuterDiameter - .1, InnerDiameter); var aabb = this.GetAxisAlignedBoundingBox(); var poleRadius = (OuterDiameter / 2 - innerDiameter / 2) / 2; var toroidRadius = innerDiameter / 2 + poleRadius; var path = new VertexStorage(); var angleDelta = MathHelper.Tau / ringSides; var ringStartAngle = MathHelper.DegreesToRadians(ringPhaseAngle); var ringAngle = ringStartAngle; var circleCenter = new Vector2(toroidRadius, 0); path.MoveTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringStartAngle), poleRadius * Math.Sin(ringStartAngle))); for (int i = 0; i < ringSides - 1; i++) { ringAngle += angleDelta; path.LineTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringAngle), poleRadius * Math.Sin(ringAngle))); } path.LineTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringStartAngle), poleRadius * Math.Sin(ringStartAngle))); var startAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(startingAngle)); var endAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(endingAngle)); Mesh = VertexSourceToMesh.Revolve(path, Sides, startAngle, endAngle); if (aabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); if (changed) { base.OnInvalidate(new InvalidateArgs(this, InvalidateType.Properties)); } }
protected IObject3D CreateReach(double reach, double innerDiameter) { var finWidth = 4.0; var finLength = innerDiameter; var pattern = new VertexStorage(); pattern.MoveTo(0, 0); pattern.LineTo(finLength / 2, 0); pattern.LineTo(finLength / 2, reach - finLength / 8); pattern.LineTo(finLength / 2 - finLength / 8, reach); pattern.LineTo(-finLength / 2 + finLength / 8, reach); pattern.LineTo(-finLength / 2, reach - finLength / 8); pattern.LineTo(-finLength / 2, 0); var fin1 = new Object3D() { Mesh = VertexSourceToMesh.Extrude(pattern, finWidth) }; fin1 = new TranslateObject3D(fin1, 0, 0, -finWidth / 2); //fin1.ChamferEdge(Face.Top | Face.Back, finLength / 8); //fin1.ChamferEdge(Face.Top | Face.Front, finLength / 8); fin1 = new RotateObject3D(fin1, -MathHelper.Tau / 4); var fin2 = new SetCenterObject3D(new RotateObject3D(fin1, 0, 0, MathHelper.Tau / 4), fin1.GetCenter()); return(new Object3D().SetChildren(new List <IObject3D>() { fin1, fin2 })); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; using (RebuildLock()) { InnerDiameter = agg_basics.Clamp(InnerDiameter, 0, OuterDiameter - .1, ref valuesChanged); Sides = agg_basics.Clamp(Sides, 3, 360, ref valuesChanged); RingSides = agg_basics.Clamp(RingSides, 3, 360, ref valuesChanged); StartingAngle = agg_basics.Clamp(StartingAngle, 0, 360 - .01, ref valuesChanged); EndingAngle = agg_basics.Clamp(EndingAngle, StartingAngle + .01, 360, ref valuesChanged); var ringSides = RingSides; var startingAngle = StartingAngle; var endingAngle = EndingAngle; var ringPhaseAngle = RingPhaseAngle; if (!Advanced) { ringSides = Math.Max(3, (int)(Sides / 2)); startingAngle = 0; endingAngle = 360; ringPhaseAngle = 0; } var innerDiameter = Math.Min(OuterDiameter - .1, InnerDiameter); using (new CenterAndHeightMaintainer(this)) { var poleRadius = (OuterDiameter / 2 - innerDiameter / 2) / 2; var toroidRadius = innerDiameter / 2 + poleRadius; var path = new VertexStorage(); var angleDelta = MathHelper.Tau / ringSides; var ringStartAngle = MathHelper.DegreesToRadians(ringPhaseAngle); var ringAngle = ringStartAngle; var circleCenter = new Vector2(toroidRadius, 0); path.MoveTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringStartAngle), poleRadius * Math.Sin(ringStartAngle))); for (int i = 0; i < ringSides - 1; i++) { ringAngle += angleDelta; path.LineTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringAngle), poleRadius * Math.Sin(ringAngle))); } path.LineTo(circleCenter + new Vector2(poleRadius * Math.Cos(ringStartAngle), poleRadius * Math.Sin(ringStartAngle))); var startAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(startingAngle)); var endAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(endingAngle)); Mesh = VertexSourceToMesh.Revolve(path, Sides, startAngle, endAngle); } } if (valuesChanged) { Invalidate(InvalidateType.DisplayValues); } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return(Task.CompletedTask); }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); bool changed = false; using (RebuildLock()) { Sides = agg_basics.Clamp(Sides, 3, 360, ref changed); var aabb = this.GetAxisAlignedBoundingBox(); var path = new VertexStorage(); path.MoveTo(0, 0); path.LineTo(Diameter / 2, 0); path.LineTo(0, Height); Mesh = VertexSourceToMesh.Revolve(path, Sides); if (aabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); if (changed) { base.OnInvalidate(new InvalidateArgs(this, InvalidateType.Properties)); } }
private void insertTextBackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; BackgroundWorker backgroundWorker = (BackgroundWorker)sender; asynchMeshGroups.Clear(); asynchMeshGroupTransforms.Clear(); asynchPlatingDatas.Clear(); string currentText = (string)e.Argument; TypeFacePrinter printer = new TypeFacePrinter(currentText, new StyledTypeFace(boldTypeFace, 12)); Vector2 size = printer.GetSize(currentText); double centerOffset = -size.x / 2; double ratioPerMeshGroup = 1.0 / currentText.Length; double currentRatioDone = 0; for (int i = 0; i < currentText.Length; i++) { int newIndex = asynchMeshGroups.Count; TypeFacePrinter letterPrinter = new TypeFacePrinter(currentText[i].ToString(), new StyledTypeFace(boldTypeFace, 12)); Mesh textMesh = VertexSourceToMesh.Extrude(letterPrinter, 10 + (i % 2)); if (textMesh.Faces.Count > 0) { asynchMeshGroups.Add(new MeshGroup(textMesh)); PlatingMeshGroupData newMeshInfo = new PlatingMeshGroupData(); newMeshInfo.xSpacing = printer.GetOffsetLeftOfCharacterIndex(i).x + centerOffset; asynchPlatingDatas.Add(newMeshInfo); asynchMeshGroupTransforms.Add(ScaleRotateTranslate.Identity()); PlatingHelper.CreateITraceableForMeshGroup(asynchPlatingDatas, asynchMeshGroups, newIndex, (double progress0To1, string processingState, out bool continueProcessing) => { continueProcessing = true; int nextPercent = (int)((currentRatioDone + ratioPerMeshGroup * progress0To1) * 100); backgroundWorker.ReportProgress(nextPercent); }); currentRatioDone += ratioPerMeshGroup; PlatingHelper.PlaceMeshGroupOnBed(asynchMeshGroups, asynchMeshGroupTransforms, newIndex); } backgroundWorker.ReportProgress((i + 1) * 95 / currentText.Length); } SetWordSpacing(asynchMeshGroups, asynchMeshGroupTransforms, asynchPlatingDatas); SetWordSize(asynchMeshGroups, asynchMeshGroupTransforms); SetWordHeight(asynchMeshGroups, asynchMeshGroupTransforms); if (createUnderline.Checked) { CreateUnderline(asynchMeshGroups, asynchMeshGroupTransforms, asynchPlatingDatas); } backgroundWorker.ReportProgress(95); }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); using (RebuildLock()) { var aabb = this.GetAxisAlignedBoundingBox(); var radius = Diameter / 2; var angleDelta = MathHelper.Tau / 4 / LatitudeSides; var angle = 0.0; var path = new VertexStorage(); path.MoveTo(0, 0); path.LineTo(new Vector2(radius * Math.Cos(angle), radius * Math.Sin(angle))); for (int i = 0; i < LatitudeSides; i++) { angle += angleDelta; path.LineTo(new Vector2(radius * Math.Cos(angle), radius * Math.Sin(angle))); } Mesh = VertexSourceToMesh.Revolve(path, LongitudeSides); if (aabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); }
public void GenerateBase(Polygons polygonShape, double bottomWithoutBase) { if (polygonShape != null && polygonShape.Select(p => p.Count).Sum() > 3) { Polygons polysToOffset = new Polygons(); switch (BaseType) { case BaseTypes.Rectangle: polysToOffset.Add(GetBoundingPolygon(polygonShape)); break; case BaseTypes.Circle: polysToOffset.Add(GetBoundingCircle(polygonShape)); break; case BaseTypes.Outline: PolyTree polyTreeForBase = GetPolyTree(polygonShape); foreach (PolyNode polyToOffset in polyTreeForBase.Childs) { polysToOffset.Add(polyToOffset.Contour); } break; } if (polysToOffset.Count > 0) { Polygons basePolygons; if (BaseType == BaseTypes.Outline && InfillAmount > 0) { basePolygons = Offset(polysToOffset, (BaseSize + InfillAmount) * scalingForClipper); basePolygons = Offset(basePolygons, -InfillAmount * scalingForClipper); } else { basePolygons = Offset(polysToOffset, BaseSize * scalingForClipper); } basePolygons = ClipperLib.Clipper.CleanPolygons(basePolygons, 10); VertexStorage rawVectorShape = basePolygons.PolygonToPathStorage(); var vectorShape = new VertexSourceApplyTransform(rawVectorShape, Affine.NewScaling(1.0 / scalingForClipper)); var baseObject = new Object3D() { Mesh = VertexSourceToMesh.Extrude(vectorShape, zHeight: ExtrusionHeight) }; Children.Add(baseObject); baseObject.Mesh.Translate(new Vector3(0, 0, -ExtrusionHeight + bottomWithoutBase)); } else { // clear the mesh Mesh = null; } } }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); using (RebuildLock()) { var aabb = this.GetAxisAlignedBoundingBox(); var path = new VertexStorage(); path.MoveTo(0, 0); path.LineTo(Math.Sqrt(2), 0); path.LineTo(0, Height); var mesh = VertexSourceToMesh.Revolve(path, 4); mesh.Transform(Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(45)) * Matrix4X4.CreateScale(Width / 2, Depth / 2, 1)); Mesh = mesh; if (aabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); var rebuildLock = RebuildLock(); bool valuesChanged = false; var height = Height.Value(this); #if DEBUG var bevelSteps = BevelSteps.ClampIfNotCalculated(this, 1, 32, ref valuesChanged); var bevelStart = BevelStart.ClampIfNotCalculated(this, 0, height, ref valuesChanged); var aabb = this.GetAxisAlignedBoundingBox(); var bevelInset = BevelInset.ClampIfNotCalculated(this, 0, Math.Min(aabb.XSize / 2, aabb.YSize / 2), ref valuesChanged); #endif // now create a long running task to do the extrusion return(ApplicationController.Instance.Tasks.Execute( "Linear Extrude".Localize(), null, (reporter, cancellationToken) => { var vertexSource = this.VertexSource; List <(double height, double inset)> bevel = null; #if DEBUG if (BevelTop) { bevel = new List <(double height, double inset)>(); for (int i = 0; i < bevelSteps; i++) { var heightRatio = i / (double)bevelSteps; height = heightRatio * (height - bevelStart) + bevelStart; var insetRatio = (i + 1) / (double)bevelSteps; var inset = Easing.Sinusoidal.In(insetRatio) * -bevelInset; bevel.Add((height, inset)); } } #endif Mesh = VertexSourceToMesh.Extrude(this.VertexSource, height, bevel); if (Mesh.Vertices.Count == 0) { Mesh = null; } UiThread.RunOnIdle(() => { rebuildLock.Dispose(); if (valuesChanged) { Invalidate(InvalidateType.DisplayValues); } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); }); return Task.CompletedTask; })); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); var rebuildLock = RebuildLock(); return(Task.Run(() => { using (new CenterAndHeightMaintainer(this)) { bool valuesChanged = false; var height = Height.ClampIfNotCalculated(this, .01, 1000000, ref valuesChanged); var nameToWrite = NameToWrite.Value(this); if (string.IsNullOrWhiteSpace(nameToWrite)) { Mesh = PlatonicSolids.CreateCube(20, 10, height); } else { Mesh = null; this.Children.Modify(list => { list.Clear(); var offest = 0.0; double pointsToMm = 0.352778; foreach (var letter in nameToWrite.ToCharArray()) { var style = new StyledTypeFace(ApplicationController.GetTypeFace(this.Font), PointSize.Value(this)); var letterPrinter = new TypeFacePrinter(letter.ToString(), style) { ResolutionScale = 10 }; var scaledLetterPrinter = new VertexSourceApplyTransform(letterPrinter, Affine.NewScaling(pointsToMm)); list.Add(new Object3D() { Mesh = VertexSourceToMesh.Extrude(scaledLetterPrinter, this.Height.Value(this)), Matrix = Matrix4X4.CreateTranslation(offest, 0, 0), Name = letter.ToString() }); offest += letterPrinter.GetSize(letter.ToString()).X *pointsToMm; } }); } } UiThread.RunOnIdle(() => { rebuildLock.Dispose(); Invalidate(InvalidateType.DisplayValues); Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children)); }); })); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged); var endingAngle = EndingAngle.ClampIfNotCalculated(this, startingAngle + .01, 360, ref valuesChanged); var sides = Sides.Value(this); var axisPosition = AxisPosition.Value(this); if (startingAngle > 0 || endingAngle < 360) { Sides = agg_basics.Clamp(sides, 1, 360, ref valuesChanged); } else { Sides = agg_basics.Clamp(sides, 3, 360, ref valuesChanged); } Invalidate(InvalidateType.DisplayValues); var rebuildLock = RebuildLock(); // now create a long running task to process the image return(ApplicationController.Instance.Tasks.Execute( "Revolve".Localize(), null, (reporter, cancellationToken) => { var vertexSource = this.VertexSource; var pathBounds = vertexSource.GetBounds(); vertexSource = vertexSource.Translate(-pathBounds.Left - axisPosition, 0); Mesh mesh = VertexSourceToMesh.Revolve(vertexSource, sides, MathHelper.DegreesToRadians(360 - endingAngle), MathHelper.DegreesToRadians(360 - startingAngle), false); // take the axis offset out mesh.Transform(Matrix4X4.CreateTranslation(pathBounds.Left + axisPosition, 0, 0)); if (mesh.Vertices.Count == 0) { mesh = null; } Mesh = mesh; UiThread.RunOnIdle(() => { rebuildLock.Dispose(); Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children)); }); return Task.CompletedTask; })); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; StartingAngle = agg_basics.Clamp(StartingAngle, 0, 360 - .01, ref valuesChanged); EndingAngle = agg_basics.Clamp(EndingAngle, StartingAngle + .01, 360, ref valuesChanged); if (StartingAngle > 0 || EndingAngle < 360) { Sides = agg_basics.Clamp(Sides, 1, 360, ref valuesChanged); } else { Sides = agg_basics.Clamp(Sides, 3, 360, ref valuesChanged); } if (valuesChanged) { Invalidate(InvalidateType.DisplayValues); } var rebuildLock = RebuildLock(); // now create a long running task to process the image return(ApplicationController.Instance.Tasks.Execute( "Revolve".Localize(), null, (reporter, cancellationToken) => { var vertexSource = this.VertexSource.Transform(Matrix); var pathBounds = vertexSource.GetBounds(); vertexSource = vertexSource.Translate(-pathBounds.Left - AxisPosition, 0); Mesh mesh = VertexSourceToMesh.Revolve(vertexSource, Sides, MathHelper.DegreesToRadians(360 - EndingAngle), MathHelper.DegreesToRadians(360 - StartingAngle), false); // take the axis offset out mesh.Transform(Matrix4X4.CreateTranslation(pathBounds.Left + AxisPosition, 0, 0)); // move back to object space mesh.Transform(this.Matrix.Inverted); if (mesh.Vertices.Count == 0) { mesh = null; } Mesh = mesh; rebuildLock.Dispose(); Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return Task.CompletedTask; })); }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); bool changed = false; using (RebuildLock()) { Sides = agg_basics.Clamp(Sides, 3, 360, ref changed); LatitudeSides = agg_basics.Clamp(LatitudeSides, 3, 360, ref changed); var aabb = this.GetAxisAlignedBoundingBox(); var startingAngle = StartingAngle; var endingAngle = EndingAngle; var latitudeSides = LatitudeSides; if (!Advanced) { startingAngle = 0; endingAngle = 360; latitudeSides = Sides; } var path = new VertexStorage(); var angleDelta = MathHelper.Tau / 2 / latitudeSides; var angle = -MathHelper.Tau / 4; var radius = Diameter / 2; path.MoveTo(new Vector2(radius * Math.Cos(angle), radius * Math.Sin(angle))); for (int i = 0; i < latitudeSides; i++) { angle += angleDelta; path.LineTo(new Vector2(radius * Math.Cos(angle), radius * Math.Sin(angle))); } var startAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(startingAngle)); var endAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(endingAngle)); var steps = Math.Max(1, (int)(Sides * MathHelper.Tau / Math.Abs(MathHelper.GetDeltaAngle(startAngle, endAngle)) + .5)); Mesh = VertexSourceToMesh.Revolve(path, steps, startAngle, endAngle); if (aabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); if (changed) { base.OnInvalidate(new InvalidateArgs(this, InvalidateType.Properties)); } }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; if (BevelTop) { BevelSteps = agg_basics.Clamp(BevelSteps, 1, 32, ref valuesChanged); BevelStart = agg_basics.Clamp(BevelStart, 0, Height, ref valuesChanged); var aabb = this.GetAxisAlignedBoundingBox(); BevelInset = agg_basics.Clamp(BevelInset, 0, Math.Min(aabb.XSize / 2, aabb.YSize / 2), ref valuesChanged); } var rebuildLock = RebuildLock(); // now create a long running task to process the image return(ApplicationController.Instance.Tasks.Execute( "Linear Extrude".Localize(), null, (reporter, cancellationToken) => { var vertexSource = this.VertexSource; List <(double height, double inset)> bevel = null; if (BevelTop) { bevel = new List <(double height, double inset)>(); for (int i = 0; i < BevelSteps; i++) { var heightRatio = i / (double)BevelSteps; var height = heightRatio * (Height - BevelStart) + BevelStart; var insetRatio = (i + 1) / (double)BevelSteps; var inset = Easing.Sinusoidal.In(insetRatio) * -BevelInset; bevel.Add((height, inset)); } } Mesh = VertexSourceToMesh.Extrude(this.VertexSource, Height, bevel); if (Mesh.Vertices.Count == 0) { Mesh = null; } rebuildLock.Dispose(); if (valuesChanged) { Invalidate(InvalidateType.DisplayValues); } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return Task.CompletedTask; })); }
// TODO: EditorTools owns this, move to more general location private static Mesh CreateCylinder(double height = 20, double radius = 10, int rotationCount = 30) { var path = new VertexStorage(); path.MoveTo(0, 0); path.LineTo(radius, 0); path.LineTo(radius, height); path.LineTo(0, height); return(VertexSourceToMesh.Revolve(path, rotationCount)); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); var rebuildLock = RebuildLock(); return(ApplicationController.Instance.Tasks.Execute( "Generating Text Meshes".Localize(), null, (reporter, cancellationToken) => { using (new CenterAndHeightMaintainer(this)) { if (string.IsNullOrWhiteSpace(NameToWrite)) { Mesh = PlatonicSolids.CreateCube(20, 10, Height); } else { Mesh = null; this.Children.Modify(list => { list.Clear(); var offest = 0.0; double pointsToMm = 0.352778; foreach (var letter in this.NameToWrite.ToCharArray()) { var letterPrinter = new TypeFacePrinter(letter.ToString(), new StyledTypeFace(ApplicationController.GetTypeFace(this.Font), this.PointSize)) { ResolutionScale = 10 }; var scaledLetterPrinter = new VertexSourceApplyTransform(letterPrinter, Affine.NewScaling(pointsToMm)); list.Add(new Object3D() { Mesh = VertexSourceToMesh.Extrude(scaledLetterPrinter, this.Height), Matrix = Matrix4X4.CreateTranslation(offest, 0, 0), Name = letter.ToString() }); offest += letterPrinter.GetSize(letter.ToString()).X *pointsToMm; } }); } } rebuildLock.Dispose(); Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children)); return Task.CompletedTask; })); }
private void AddCharacterMeshes(string currentText, TypeFacePrinter printer) { int newIndex = asyncMeshGroups.Count; StyledTypeFace typeFace = printer.TypeFaceStyle; for (int i = 0; i < currentText.Length; i++) { string letter = currentText[i].ToString(); TypeFacePrinter letterPrinter = new TypeFacePrinter(letter, typeFace); if (CharacterHasMesh(letterPrinter, letter)) { #if true Mesh textMesh = VertexSourceToMesh.Extrude(letterPrinter, unscaledLetterHeight / 2); #else Mesh textMesh = VertexSourceToMesh.Extrude(letterPrinter, unscaledLetterHeight / 2); // this is the code to make rounded tops // convert the letterPrinter to clipper polygons List <List <IntPoint> > insetPoly = VertexSourceToPolygon.CreatePolygons(letterPrinter); // inset them ClipperOffset clipper = new ClipperOffset(); clipper.AddPaths(insetPoly, JoinType.jtMiter, EndType.etClosedPolygon); List <List <IntPoint> > solution = new List <List <IntPoint> >(); clipper.Execute(solution, 5.0); // convert them back into a vertex source // merge both the inset and original vertex sources together // convert the new vertex source into a mesh (trianglulate them) // offset the inner loop in z // create the polygons from the inner loop to a center point so that there is the rest of an approximation of the bubble // make the mesh for the bottom // add the top and bottom together // done #endif asyncMeshGroups.Add(new MeshGroup(textMesh)); PlatingMeshGroupData newMeshInfo = new PlatingMeshGroupData(); newMeshInfo.spacing = printer.GetOffsetLeftOfCharacterIndex(i); asyncPlatingDatas.Add(newMeshInfo); asyncMeshGroupTransforms.Add(ScaleRotateTranslate.Identity()); PlatingHelper.CreateITraceableForMeshGroup(asyncPlatingDatas, asyncMeshGroups, newIndex, null); ScaleRotateTranslate moved = asyncMeshGroupTransforms[newIndex]; moved.translation *= Matrix4X4.CreateTranslation(new Vector3(0, 0, unscaledLetterHeight / 2)); asyncMeshGroupTransforms[newIndex] = moved; newIndex++; } processingProgressControl.PercentComplete = ((i + 1) * 95 / currentText.Length); } }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; var roundSegments = RoundSegments.ClampIfNotCalculated(this, 2, 90, ref valuesChanged); Invalidate(InvalidateType.DisplayValues); using (RebuildLock()) { var height = Height.Value(this); var width = Width.Value(this); using (new CenterAndHeightMaintainer(this)) { var path = new VertexStorage(); path.MoveTo(0, 0); path.LineTo(width, 0); var range = 360 / 4.0; switch (Round) { case RoundTypes.Up: for (int i = 1; i < roundSegments - 1; i++) { var angle = range / (roundSegments - 1) * i; var rad = MathHelper.DegreesToRadians(angle); path.LineTo(Math.Cos(rad) * width, Math.Sin(rad) * height); } break; case RoundTypes.Down: for (int i = 1; i < roundSegments - 1; i++) { var angle = range / (roundSegments - 1) * i; var rad = MathHelper.DegreesToRadians(angle); path.LineTo(width - Math.Sin(rad) * width, height - Math.Cos(rad) * height); } break; } path.LineTo(0, height); Mesh = VertexSourceToMesh.Extrude(path, Depth.Value(this)); Mesh.Transform(Matrix4X4.CreateRotationX(MathHelper.Tau / 4)); } } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return(Task.CompletedTask); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; using (RebuildLock()) { Sides = agg_basics.Clamp(Sides, 3, 360, ref valuesChanged); LatitudeSides = agg_basics.Clamp(LatitudeSides, 3, 360, ref valuesChanged); using (new CenterAndHeightMaintainer(this)) { var startingAngle = StartingAngle; var endingAngle = EndingAngle; var latitudeSides = LatitudeSides; if (!Advanced) { startingAngle = 0; endingAngle = 360; latitudeSides = Sides; } var path = new VertexStorage(); var angleDelta = MathHelper.Tau / 2 / latitudeSides; var angle = -MathHelper.Tau / 4; var radius = Diameter / 2; path.MoveTo(new Vector2(radius * Math.Cos(angle), radius * Math.Sin(angle))); for (int i = 0; i < latitudeSides; i++) { angle += angleDelta; path.LineTo(new Vector2(radius * Math.Cos(angle), radius * Math.Sin(angle))); } var startAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(startingAngle)); var endAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(endingAngle)); var steps = Math.Max(1, (int)(Sides * MathHelper.Tau / Math.Abs(MathHelper.GetDeltaAngle(startAngle, endAngle)) + .5)); Mesh = VertexSourceToMesh.Revolve(path, steps, startAngle, endAngle); } } if (valuesChanged) { Invalidate(InvalidateType.DisplayValues); } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return(Task.CompletedTask); }
protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider) { if (windowService == null) { throw new ArgumentNullException("windowService"); } if (objectProvider == null) { throw new ArgumentNullException("objectProvider"); } if (objectProvider.GetObject() is List <List <IntPoint> > polygons) { var vertexStorage = PlatingHelper.PolygonToVertexStorage(polygons); var polygonsMesh = VertexSourceToMesh.Extrude(vertexStorage, zHeight: 30); // Position var aabb = polygonsMesh.GetAxisAlignedBoundingBox(); polygonsMesh.Transform(Matrix4X4.CreateTranslation(-aabb.Center)); polygonsMesh.Transform(Matrix4X4.CreateScale(1.6 / aabb.XSize)); var systemWindow = new SystemWindow(800, 600); var lighting = new LightingData(); //Debugger.Launch(); systemWindow.AfterDraw += (s, e) => { var screenSpaceBounds = systemWindow.TransformToScreenSpace(systemWindow.LocalBounds); WorldView world = new WorldView(screenSpaceBounds.Width, screenSpaceBounds.Height); //world.Translate(new Vector3(0, 0, 0)); //world.Rotate(Quaternion.FromEulerAngles(new Vector3(rotateX, 0, 0))); GLHelper.SetGlContext(world, screenSpaceBounds, lighting); GLHelper.Render(polygonsMesh, Color.White); GLHelper.UnsetGlContext(); }; using (var displayForm = new OpenGLSystemWindow() { AggSystemWindow = systemWindow }) { //System.Diagnostics.Debugger.Launch(); windowService.ShowDialog(displayForm); } } }
private void Rebuild(UndoBuffer undoBuffer) { using (RebuildLock()) { var vertexSource = this.VertexSource; Mesh = VertexSourceToMesh.Extrude(this.VertexSource, Height); if (Mesh.Vertices.Count == 0) { Mesh = null; } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); }
public VertexStorageObject3D(VertexStorage vertexStorage) { this.vertexStorage = vertexStorage; this.Children.Modify(children => { int i = 0; foreach (var v in vertexStorage.Vertices()) { if (!v.IsMoveTo && !v.IsLineTo) { continue; } var localVertex = v; var localIndex = i++; var item = new Object3D() { Mesh = CreateCylinder(1, 1), Matrix = Matrix4X4.CreateTranslation(v.position.X, v.position.Y, 0), Color = Color.Green }; item.Invalidated += (s, e) => { System.Diagnostics.Debugger.Break(); //vertexStorage.modify_vertex(localIndex, item.Matrix.Position.X, localVertex.position.Y = item.Matrix.Position.Y); }; children.Add(item); } children.Add(generatedMesh = new Object3D() { Mesh = VertexSourceToMesh.Extrude(vertexStorage, 0.5), Color = new Color("#93CEFF99") }); }); this.Invalidated += (s, e) => { // Recompute path from content generatedMesh.Mesh = VertexSourceToMesh.Extrude(vertexStorage, 0.5); //VertexSourceToMesh.Revolve(vertexStorage)); }; }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; double height = Height.ClampIfNotCalculated(this, .01, 1000000, ref valuesChanged); var diameter = Diameter.ClampIfNotCalculated(this, .01, 1000000, ref valuesChanged); var diameterTop = DiameterTop.ClampIfNotCalculated(this, .01, 1000000, ref valuesChanged); var sides = Sides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged); var startingAngle = StartingAngle.ClampIfNotCalculated(this, 0, 360 - .01, ref valuesChanged); var endingAngle = EndingAngle.ClampIfNotCalculated(this, StartingAngle.Value(this) + .01, 360, ref valuesChanged); if (valuesChanged) { Invalidate(InvalidateType.DisplayValues); } using (RebuildLock()) { using (new CenterAndHeightMaintainer(this)) { if (!Advanced) { var path = new VertexStorage(); path.MoveTo(0, -height / 2); path.LineTo(diameter / 2, -height / 2); path.LineTo(diameter / 2, height / 2); path.LineTo(0, height / 2); Mesh = VertexSourceToMesh.Revolve(path, sides); } else { var path = new VertexStorage(); path.MoveTo(0, -height / 2); path.LineTo(diameter / 2, -height / 2); path.LineTo(diameterTop / 2, height / 2); path.LineTo(0, height / 2); Mesh = VertexSourceToMesh.Revolve(path, sides, MathHelper.DegreesToRadians(startingAngle), MathHelper.DegreesToRadians(endingAngle)); } } } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return(Task.CompletedTask); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; using (RebuildLock()) { var latitudeSides = LatitudeSides.ClampIfNotCalculated(this, 3, 180, ref valuesChanged); var longitudeSides = LongitudeSides.ClampIfNotCalculated(this, 3, 360, ref valuesChanged); var diameter = Diameter.Value(this); using (new CenterAndHeightMaintainer(this)) { if (longitudeSides != lastLongitudeSides || latitudeSides != lastLatitudeSides || diameter != lastDiameter) { var radius = diameter / 2; var angleDelta = MathHelper.Tau / 4 / latitudeSides; var angle = 0.0; var path = new VertexStorage(); path.MoveTo(0, 0); path.LineTo(new Vector2(radius * Math.Cos(angle), radius * Math.Sin(angle))); for (int i = 0; i < latitudeSides; i++) { angle += angleDelta; path.LineTo(new Vector2(radius * Math.Cos(angle), radius * Math.Sin(angle))); } Mesh = VertexSourceToMesh.Revolve(path, longitudeSides); } lastDiameter = diameter; lastLongitudeSides = longitudeSides; lastLatitudeSides = latitudeSides; } } if (valuesChanged) { Invalidate(InvalidateType.DisplayValues); } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return(Task.CompletedTask); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); bool valuesChanged = false; Sides = agg_basics.Clamp(Sides, 3, 360, ref valuesChanged); Height = agg_basics.Clamp(Height, .01, 1000000, ref valuesChanged); Diameter = agg_basics.Clamp(Diameter, .01, 1000000, ref valuesChanged); StartingAngle = agg_basics.Clamp(StartingAngle, 0, 360 - .01, ref valuesChanged); EndingAngle = agg_basics.Clamp(EndingAngle, StartingAngle + .01, 360, ref valuesChanged); if (valuesChanged) { Invalidate(InvalidateType.DisplayValues); } using (RebuildLock()) { using (new CenterAndHeightMaintainer(this)) { if (!Advanced) { var path = new VertexStorage(); path.MoveTo(0, -Height / 2); path.LineTo(Diameter / 2, -Height / 2); path.LineTo(Diameter / 2, Height / 2); path.LineTo(0, Height / 2); Mesh = VertexSourceToMesh.Revolve(path, Sides); } else { var path = new VertexStorage(); path.MoveTo(0, -Height / 2); path.LineTo(Diameter / 2, -Height / 2); path.LineTo(DiameterTop / 2, Height / 2); path.LineTo(0, Height / 2); Mesh = VertexSourceToMesh.Revolve(path, Sides, MathHelper.DegreesToRadians(StartingAngle), MathHelper.DegreesToRadians(EndingAngle)); } } } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return(Task.CompletedTask); }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); bool changed = false; using (RebuildLock()) { InnerDiameter = agg_basics.Clamp(InnerDiameter, 0, OuterDiameter - .1, ref changed); Sides = agg_basics.Clamp(Sides, 3, 360, ref changed); var aabb = this.GetAxisAlignedBoundingBox(); var startingAngle = StartingAngle; var endingAngle = EndingAngle; if (!Advanced) { startingAngle = 0; endingAngle = 360; } var innerDiameter = Math.Min(OuterDiameter - .1, InnerDiameter); var path = new VertexStorage(); path.MoveTo(OuterDiameter / 2, -Height / 2); path.LineTo(OuterDiameter / 2, Height / 2); path.LineTo(innerDiameter / 2, Height / 2); path.LineTo(innerDiameter / 2, -Height / 2); path.LineTo(OuterDiameter / 2, -Height / 2); var startAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(startingAngle)); var endAngle = MathHelper.Range0ToTau(MathHelper.DegreesToRadians(endingAngle)); Mesh = VertexSourceToMesh.Revolve(path, Sides, startAngle, endAngle); if (aabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); if (changed) { base.OnInvalidate(new InvalidateArgs(this, InvalidateType.Properties)); } }