private ToolpathPreviewJoint GenerateRightBevel(Segment3d segBefore, Segment3d segAfter, TPrintVertex printVertex, ToolpathPreviewMesh mesh)
        {
            CreateFrames(segBefore, segAfter, out var frameMiter, out var frameSegBefore, out var frameSegAfter);

            var joint = new ToolpathPreviewJoint();

            joint.InTop = joint.OutTop = mesh.AddVertex(vertexFactory(printVertex,
                                                                      frameMiter.FromFrameP(DiamondCrossSection.Top(printVertex.Dimensions)), brightnessMax));

            if (CornerIsInsideTube(segBefore, segAfter, printVertex.Dimensions.x))
            {
                AddLeftSquare(mesh, printVertex, ref frameSegBefore, ref frameSegAfter, joint);
            }
            else
            {
                AddLeftMiter(mesh, printVertex, ref frameMiter, ref frameSegBefore, joint);
            }

            joint.InBottom = joint.OutBottom = mesh.AddVertex(vertexFactory(printVertex,
                                                                            frameMiter.FromFrameP(DiamondCrossSection.Bottom(printVertex.Dimensions)), brightnessMax));

            double bevelDistance = GetBevelDistance(ref segBefore, ref segAfter, printVertex.Dimensions);

            joint.InRight = mesh.AddVertex(vertexFactory(printVertex,
                                                         frameSegBefore.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions, 1, bevelDistance)), brightnessMin));

            joint.OutRight = mesh.AddVertex(vertexFactory(printVertex,
                                                          frameSegAfter.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions, 1, -bevelDistance)), brightnessMin));

            mesh.AddTriangle(joint.InRight, joint.OutRight, joint.InTop);
            mesh.AddTriangle(joint.InRight, joint.InBottom, joint.OutRight);

            return(joint);
        }
        protected virtual ToolpathPreviewJoint GenerateMiterJoint(Segment3d segmentBefore, Segment3d segmentAfter, TPrintVertex printVertex, ToolpathPreviewMesh mesh)
        {
            var averageDirection = (segmentBefore.Direction + segmentAfter.Direction).Normalized;
            var scaleFactor      = 1 / segmentBefore.Direction.Dot(averageDirection);

            var frame = new Frame3f(printVertex.Position);

            frame.AlignAxis(1, ToVector3f(averageDirection));

            var joint = new ToolpathPreviewJoint();

            joint.InTop = joint.OutTop = mesh.AddVertex(vertexFactory(printVertex,
                                                                      frame.FromFrameP(DiamondCrossSection.Top(printVertex.Dimensions)), brightnessMax));

            joint.InRight = joint.OutRight = mesh.AddVertex(vertexFactory(printVertex,
                                                                          frame.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions)), brightnessMin));

            joint.InBottom = joint.OutBottom = mesh.AddVertex(vertexFactory(printVertex,
                                                                            frame.FromFrameP(DiamondCrossSection.Bottom(printVertex.Dimensions)), brightnessMax));

            joint.InLeft = joint.OutLeft = mesh.AddVertex(vertexFactory(printVertex,
                                                                        frame.FromFrameP(DiamondCrossSection.Left(printVertex.Dimensions)), brightnessMin));

            return(joint);
        }
        private void AddRightSquare(TPrintVertex printVertex, ToolpathPreviewMesh mesh, ref Frame3f frameSegBefore, ref Frame3f frameSegAfter, ToolpathPreviewJoint joint)
        {
            joint.InRight = mesh.AddVertex(vertexFactory(printVertex,
                                                         frameSegBefore.FromFrameP(DiamondCrossSection.Left(printVertex.Dimensions)), brightnessMin));

            joint.OutRight = mesh.AddVertex(vertexFactory(printVertex,
                                                          frameSegAfter.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions)), brightnessMin));
        }
        private void AddRightMiter(TPrintVertex printVertex, ToolpathPreviewMesh mesh, ref Frame3f frameMiter, ref Frame3f frameSegBefore, ToolpathPreviewJoint joint)
        {
            double miterScaleFactor = GetMiterScaleFactor(ref frameMiter, ref frameSegBefore);

            joint.InRight = joint.OutRight = mesh.AddVertex(vertexFactory(printVertex,
                                                                          frameMiter.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions, miterScaleFactor)), brightnessMin));
        }
        private void AddCapBeforeJoint(Vector3d segmentDirection, TPrintVertex printVertex, ToolpathPreviewJoint joint, ToolpathPreviewMesh mesh)
        {
            var frame = new Frame3f(printVertex.Position);

            frame.AlignAxis(1, ToVector3f(segmentDirection));

            joint.InTop = mesh.AddVertex(vertexFactory(printVertex,
                                                       frame.FromFrameP(DiamondCrossSection.Top(printVertex.Dimensions)), brightnessMax));

            joint.InRight = mesh.AddVertex(vertexFactory(printVertex,
                                                         frame.FromFrameP(DiamondCrossSection.Right(printVertex.Dimensions)), brightnessMin));

            joint.InBottom = mesh.AddVertex(vertexFactory(printVertex,
                                                          frame.FromFrameP(DiamondCrossSection.Bottom(printVertex.Dimensions)), brightnessMax));

            joint.InLeft = mesh.AddVertex(vertexFactory(printVertex,
                                                        frame.FromFrameP(DiamondCrossSection.Left(printVertex.Dimensions)), brightnessMin));

            mesh.AddTriangle(joint.InBottom, joint.InLeft, joint.InTop);
            mesh.AddTriangle(joint.InBottom, joint.InTop, joint.InRight);
        }