コード例 #1
0
            public override IGripManipulationHandle[] GetGrips(int gripLevel)
            {
                if (gripLevel <= 1)
                {
                    var ls  = (LineShape)_hitobject;
                    var pts = new PointD3D[] { PointD3D.Empty, (PointD3D)ls.Size };
                    for (int i = 0; i < pts.Length; i++)
                    {
                        var pt = ls._transformation.Transform(pts[i]);
                        pt     = Transformation.Transform(pt);
                        pts[i] = pt;
                    }

                    var grips = new IGripManipulationHandle[gripLevel == 0 ? 1 : 3];

                    // Translation grips
                    var bounds         = ls.Bounds;
                    var wn             = PolylineMath3D.GetWestNorthVectors(bounds.Size);
                    var transformation = Matrix4x3.NewFromBasisVectorsAndLocation(wn.Item1, wn.Item2, bounds.Size.Normalized, PointD3D.Empty);

                    transformation.AppendTransform(ls._transformation);
                    transformation.AppendTransform(Transformation);

                    double t1            = 0.55 * ls._linePen.Thickness1;
                    double t2            = 0.55 * ls._linePen.Thickness2;
                    var    rect          = new RectangleD3D(-t1, -t2, 0, 2 * t1, 2 * t2, bounds.Size.Length);
                    var    objectOutline = new RectangularObjectOutline(rect, transformation);
                    grips[0] = new MovementGripHandle(this, objectOutline, null);

                    // PathNode grips
                    if (gripLevel == 1)
                    {
                        grips[2] = grips[0]; // put the movement grip to the background, the two NodeGrips need more priority
                        var gripRadius = Math.Max(t1, t2);
                        grips[0] = new PathNodeGripHandle(this, new VectorD3D(0, 0, 0), pts[0], gripRadius);
                        grips[1] = new PathNodeGripHandle(this, new VectorD3D(1, 1, 1), pts[1], gripRadius);
                    }
                    return(grips);
                }
                else
                {
                    return(base.GetGrips(gripLevel));
                }
            }
コード例 #2
0
ファイル: Flat.cs プロジェクト: olesar/Altaxo
        /// <summary>
        /// Adds the triangle geometry for this cap.
        /// </summary>
        /// <param name="AddPositionAndNormal">The procedure to add a vertex position and normal.</param>
        /// <param name="AddIndices">The procedure to add vertex indices for one triangle.</param>
        /// <param name="vertexIndexOffset">The vertex index offset. Must be actualized during this call.</param>
        /// <param name="isStartCap">If set to <c>true</c>, a start cap is drawn; otherwise, an end cap is drawn.</param>
        /// <param name="basePoint">The location of the middle point of the line at the cap's location.</param>
        /// <param name="westVector">The west vector for orientation of the cross section.</param>
        /// <param name="northVector">The north vector for orientation of the cross section.</param>
        /// <param name="forwardVector">The forward vector for orientation of the cross section.</param>
        /// <param name="crossSection">The cross section of the line.</param>
        public static void AddGeometry(
            Action <PointD3D, VectorD3D> AddPositionAndNormal,
            Action <int, int, int, bool> AddIndices,
            ref int vertexIndexOffset,
            bool isStartCap,
            PointD3D basePoint,
            VectorD3D westVector,
            VectorD3D northVector,
            VectorD3D forwardVector,
            ICrossSectionOfLine crossSection
            )
        {
            if (isStartCap)
            {
                forwardVector = -forwardVector;
            }

            var matrix = Matrix4x3.NewFromBasisVectorsAndLocation(westVector, northVector, forwardVector, basePoint);

            int currIndex = vertexIndexOffset;
            int crossSectionPositionCount = crossSection.NumberOfVertices;

            // Add the midpoint
            // add the middle point of the end cap and the normal of the end cap
            AddPositionAndNormal(basePoint, forwardVector);
            ++currIndex;

            for (int i = 0; i < crossSectionPositionCount; ++i)
            {
                var sp = matrix.Transform(crossSection.Vertices(i));
                AddPositionAndNormal(sp, forwardVector);

                AddIndices(
                    currIndex - 1, // mid point of the end cap
                    currIndex + i,
                    currIndex + (1 + i) % crossSectionPositionCount,
                    isStartCap);
            }

            currIndex        += crossSectionPositionCount;
            vertexIndexOffset = currIndex;
        }
コード例 #3
0
        public static void Add(
            Action <PointD3D, VectorD3D> AddPositionAndNormal,
            Action <int, int, int, bool> AddIndices,
            ref int vertexIndexOffset,
            bool isStartCap,
            PointD3D basePoint,
            VectorD3D westVector,
            VectorD3D northVector,
            VectorD3D forwardVectorNormalized,
            ICrossSectionOfLine lineCrossSection,
            PointD3D[] crossSectionPositions,
            VectorD3D[] crossSectionNormals,
            ref object temporaryStorageSpace,
            ILineCapContour capContour
            )
        {
            var crossSectionVertexCount = lineCrossSection.NumberOfVertices;
            var crossSectionNormalCount = lineCrossSection.NumberOfNormals;
            var contourZScale           = 0.5 * Math.Max(lineCrossSection.Size1, lineCrossSection.Size2);

            // do we need a flat end at the beginning of the cap?
            if (null == crossSectionPositions &&         // if lineCrossSectionPositions are null, it means that our cap is not connected to the line and needs a flat end
                capContour.Vertices(0) == _pointD2D_0_1) // furthermore the cap assumes to be started at the cross section
            {
                // the parameter isStartCap must be negated, because this flat cap is the "counterpart" of our cap to draw
                Flat.AddGeometry(
                    AddPositionAndNormal,
                    AddIndices,
                    ref vertexIndexOffset,
                    !isStartCap,
                    basePoint,
                    westVector,
                    northVector,
                    forwardVectorNormalized,
                    lineCrossSection);
            }

            if (isStartCap)
            {
                forwardVectorNormalized = -forwardVectorNormalized;
            }

            var contourVertexCount = capContour.NumberOfVertices;
            var contourNormalCount = capContour.NumberOfNormals;

            // now the calculation can start

            CrossSectionCases previousCrossSectionType = CrossSectionCases.MiddlePointSmooth;
            int  previousGeneratedPoints            = 0;
            int  previousContourVertexIndex         = 0;
            bool isOnSecondSideOfContourVertexSharp = true;

            for (int contourVertexIndex = 0, contourNormalIndex = 0; contourVertexIndex < contourVertexCount; ++contourVertexIndex, ++contourNormalIndex)
            {
                // we have 4 different situations here:
                // 1st) the crossSection.Y is zero, thus this is the middle point (the normal should then go in z-direction) -> we need only one single vertex and normal for that
                // 2nd) the countour normal is in x-direction  -> we need only a point for each crossSection vertex, but not for each crossSectionNormal
                // 3rd) the regular case -> we need a point for each crossSection normal

                var capContourVertex = capContour.Vertices(contourVertexIndex);
                var capContourNormal = capContour.Normals(contourNormalIndex);

                CrossSectionCases currentCrossSectionType;
                if (capContourVertex.Y == 0 && capContourNormal.Y == 0)
                {
                    currentCrossSectionType = CrossSectionCases.MiddlePointSmooth;
                }
                else if (capContourVertex.Y == 0)
                {
                    currentCrossSectionType = CrossSectionCases.MiddlePointSharp;
                }
                else if (0 == capContourNormal.Y)
                {
                    currentCrossSectionType = CrossSectionCases.VerticesOnly;
                }
                else
                {
                    currentCrossSectionType = CrossSectionCases.Regular;
                }

                var currentLocation = basePoint + forwardVectorNormalized * capContourVertex.X * contourZScale;
                var matrix          = Matrix4x3.NewFromBasisVectorsAndLocation(westVector, northVector, forwardVectorNormalized, currentLocation);

                int currentGeneratedPoints = 0;
                switch (currentCrossSectionType)
                {
                case CrossSectionCases.MiddlePointSmooth:
                {
                    var position = matrix.Transform(PointD2D.Empty);
                    var normal   = matrix.Transform(new VectorD3D(0, 0, capContourNormal.X));
                    AddPositionAndNormal(position, normal);
                    currentGeneratedPoints = 1;
                }
                break;

                case CrossSectionCases.MiddlePointSharp:
                {
                    for (int i = 0, j = 0; i < crossSectionVertexCount; ++i, ++j)
                    {
                        var normal1  = (i == 0) ? lineCrossSection.Normals(crossSectionNormalCount - 1) : lineCrossSection.Normals(j - 1);
                        var normal2  = lineCrossSection.Normals(j);
                        var sn       = (normal1 + normal2).Normalized;
                        var utNormal = GetNormalVector(lineCrossSection.Vertices(i), sn, capContourNormal, contourZScale);
                        AddPositionAndNormal(currentLocation, matrix.Transform(utNormal)); // store the tip point with the averaged normal
                        if (lineCrossSection.IsVertexSharp(i))
                        {
                            ++j;
                        }
                    }
                    currentGeneratedPoints = crossSectionVertexCount;
                }
                break;

                case CrossSectionCases.VerticesOnly:
                {
                    var commonNormal = matrix.Transform(new VectorD3D(0, 0, capContourNormal.X));
                    for (int i = 0; i < crossSectionVertexCount; ++i)
                    {
                        var position = matrix.Transform(lineCrossSection.Vertices(i) * capContourVertex.Y);
                        AddPositionAndNormal(position, commonNormal);
                    }
                    currentGeneratedPoints = crossSectionVertexCount;
                }
                break;

                case CrossSectionCases.Regular:
                {
                    for (int i = 0, j = 0; i < crossSectionVertexCount; ++i, ++j)
                    {
                        var sp       = lineCrossSection.Vertices(i);
                        var sn       = lineCrossSection.Normals(j);
                        var utNormal = GetNormalVector(sp, sn, capContourNormal, contourZScale);
                        var position = matrix.Transform(sp * capContourVertex.Y);
                        var normal   = matrix.Transform(utNormal);

                        AddPositionAndNormal(position, normal);

                        if (lineCrossSection.IsVertexSharp(i))
                        {
                            ++j;
                            sn       = lineCrossSection.Normals(j);
                            utNormal = GetNormalVector(sp, sn, capContourNormal, contourZScale);
                            normal   = matrix.Transform(utNormal);
                            AddPositionAndNormal(position, normal);
                        }
                    }
                    currentGeneratedPoints = crossSectionNormalCount;
                }
                break;

                default:
                    throw new NotImplementedException();
                }
                vertexIndexOffset += currentGeneratedPoints;

                // now we start generating triangles

                if (contourVertexIndex > previousContourVertexIndex)
                {
                    int voffset1 = vertexIndexOffset - currentGeneratedPoints;
                    int voffset0 = voffset1 - previousGeneratedPoints;
                    switch (previousCrossSectionType)
                    {
                    case CrossSectionCases.MiddlePointSmooth:
                    {
                        switch (currentCrossSectionType)
                        {
                        case CrossSectionCases.MiddlePointSmooth: // Middle point to middle point
                        {
                            // no triangles, since from middle point to middle point we have an infinity thin line
                        }
                        break;

                        case CrossSectionCases.MiddlePointSharp: // Middle point to middle point
                        {
                            // no triangles, since from middle point to middle point we have an infinity thin line
                        }
                        break;

                        case CrossSectionCases.VerticesOnly: // Middle point to vertices only
                        {
                            for (int i = 0; i < crossSectionVertexCount; ++i)
                            {
                                AddIndices(voffset0, voffset1 + i, voffset1 + (i + 1) % crossSectionVertexCount, isStartCap);
                            }
                        }
                        break;

                        case CrossSectionCases.Regular: // Middle point to regular
                        {
                            for (int i = 0; i < crossSectionNormalCount; ++i)
                            {
                                AddIndices(voffset0, voffset1 + i, voffset1 + (i + 1) % crossSectionNormalCount, isStartCap);
                            }
                        }
                        break;

                        default:
                            throw new NotImplementedException();
                        }
                    }
                    break;

                    case CrossSectionCases.MiddlePointSharp:
                    {
                        switch (currentCrossSectionType)
                        {
                        case CrossSectionCases.MiddlePointSmooth: // Middle point to middle point
                        {
                            // no triangles, since from middle point to middle point we have an infinity thin line
                        }
                        break;

                        case CrossSectionCases.MiddlePointSharp: // Middle point to middle point
                        {
                            // no triangles, since from middle point to middle point we have an infinity thin line
                        }
                        break;

                        case CrossSectionCases.VerticesOnly: // MiddlePointSharp to VerticesOnly
                        {
                            for (int i = 0; i < crossSectionVertexCount; ++i)
                            {
                                AddIndices(voffset0, voffset1 + i, voffset1 + (i + 1) % crossSectionVertexCount, isStartCap);
                            }
                        }
                        break;

                        case CrossSectionCases.Regular: // MiddlePointSharp to Regular
                        {
                            for (int i = 0, j = 0; i < crossSectionNormalCount; ++i, ++j)
                            {
                                AddIndices(voffset0 + i, voffset1 + i, voffset1 + (i + 1) % crossSectionNormalCount, isStartCap);
                            }
                        }
                        break;

                        default:
                            throw new NotImplementedException();
                        }
                    }
                    break;

                    case CrossSectionCases.VerticesOnly:
                    {
                        switch (currentCrossSectionType)
                        {
                        case CrossSectionCases.MiddlePointSmooth: // VerticesOnly to MiddlePoint
                        {
                            for (int i = 0; i < crossSectionVertexCount; ++i)
                            {
                                AddIndices(voffset1, voffset0 + i, voffset0 + (i + 1) % crossSectionVertexCount, isStartCap);
                            }
                        }
                        break;

                        case CrossSectionCases.VerticesOnly: // VerticesOnly to VerticesOnly
                        {
                            for (int i = 0; i < crossSectionVertexCount; ++i)
                            {
                                AddIndices(voffset0 + ((i == 0) ? crossSectionVertexCount - 1 : i - 1), voffset0 + i, voffset1 + i, isStartCap);
                                AddIndices(voffset0 + ((i == 0) ? crossSectionVertexCount - 1 : i - 1), voffset1 + i, voffset1 + ((i == 0) ? crossSectionVertexCount - 1 : i - 1), isStartCap);
                            }
                        }
                        break;

                        case CrossSectionCases.Regular: // VerticesOnly to regular
                        {
                            throw new NotImplementedException();
                        }
                        //break;

                        default:
                            throw new NotImplementedException();
                        }
                    }
                    break;

                    case CrossSectionCases.Regular:
                    {
                        switch (currentCrossSectionType)
                        {
                        case CrossSectionCases.MiddlePointSmooth: // Regular to MiddlePointOnly
                        {
                            for (int i = 0, j = 0; i < crossSectionVertexCount; ++i, ++j)
                            {
                                AddIndices(voffset0 + ((j == 0) ? crossSectionNormalCount - 1 : j - 1), voffset0 + j, voffset1, isStartCap);

                                if (lineCrossSection.IsVertexSharp(i))
                                {
                                    ++j;
                                }
                            }
                        }
                        break;

                        case CrossSectionCases.MiddlePointSharp: // Regular to MiddlePointSharp
                        {
                            for (int i = 0, j = 0; i < crossSectionVertexCount; ++i, ++j)
                            {
                                AddIndices(voffset0 + ((j == 0) ? crossSectionNormalCount - 1 : j - 1), voffset0 + j, voffset1 + i, isStartCap);

                                if (lineCrossSection.IsVertexSharp(i))
                                {
                                    ++j;
                                }
                            }
                        }
                        break;

                        case CrossSectionCases.VerticesOnly: // Regular to VerticesOnly
                        {
                            for (int i = 0, j = 0; i < crossSectionVertexCount; ++i, ++j)
                            {
                                AddIndices(voffset0 + ((j == 0) ? crossSectionNormalCount - 1 : j - 1), voffset0 + j, voffset1 + i, isStartCap);
                                AddIndices(voffset0 + ((j == 0) ? crossSectionNormalCount - 1 : j - 1), voffset1 + i, voffset1 + ((i == 0) ? crossSectionVertexCount - 1 : i - 1), isStartCap);

                                if (lineCrossSection.IsVertexSharp(i))
                                {
                                    ++j;
                                }
                            }
                        }
                        break;

                        case CrossSectionCases.Regular: // Regular to Regular
                        {
                            for (int i = 0, j = 0; i < crossSectionVertexCount; ++i, ++j)
                            {
                                AddIndices(voffset0 + ((j == 0) ? crossSectionNormalCount - 1 : j - 1), voffset0 + j, voffset1 + j, isStartCap);
                                AddIndices(voffset0 + ((j == 0) ? crossSectionNormalCount - 1 : j - 1), voffset1 + j, voffset1 + ((j == 0) ? crossSectionNormalCount - 1 : j - 1), isStartCap);

                                if (lineCrossSection.IsVertexSharp(i))
                                {
                                    ++j;
                                }
                            }
                        }
                        break;

                        default:
                            throw new NotImplementedException();
                        }
                    }
                    break;

                    default:
                        throw new NotImplementedException();
                    }
                }

                if (!isOnSecondSideOfContourVertexSharp && capContour.IsVertexSharp(contourVertexIndex) && contourVertexIndex < (contourVertexCount - 1))
                {
                    previousContourVertexIndex = contourVertexIndex;
                    --contourVertexIndex; // trick: decrement the vertex index, it is incremented then again in the following for loop, so that contourVertexIndex stays constant
                    isOnSecondSideOfContourVertexSharp = true;
                    continue;
                }
                isOnSecondSideOfContourVertexSharp = false;

                // now we switch the current calculated positions and normals with the old ones
                previousCrossSectionType   = currentCrossSectionType;
                previousGeneratedPoints    = currentGeneratedPoints;
                previousContourVertexIndex = contourVertexIndex;
            }
        }
コード例 #4
0
        protected override IGripManipulationHandle[] GetGrips(IHitTestObject hitTest, GripKind gripKind)
        {
            var list = new List <IGripManipulationHandle>();

            /*
             *
             * const double gripNominalSize = 10; // 10 Points nominal size on the screen
             *                if ((GripKind.Resize & gripKind) != 0)
             *                {
             *                        double gripSize = gripNominalSize / pageScale; // 10 Points, but we have to consider the current pageScale
             *                        for (int i = 1; i < _gripRelPositions.Length; i++)
             *                        {
             *                                PointD2D outVec, pos;
             *                                if (1 == i % 2)
             *                                        GetCornerOutVector(_gripRelPositions[i], hitTest, out outVec, out pos);
             *                                else
             *                                        GetMiddleRayOutVector(_gripRelPositions[i], hitTest, out outVec, out pos);
             *
             *                                outVec *= (gripSize / outVec.VectorLength);
             *                                PointD2D altVec = outVec.Get90DegreeRotated();
             *                                PointD2D ptStart = pos;
             *                                list.Add(new ResizeGripHandle(hitTest, _gripRelPositions[i], new MatrixD2D(outVec.X, outVec.Y, altVec.X, altVec.Y, ptStart.X, ptStart.Y)));
             *                        }
             *                }
             */

            /*
             *                if ((GripKind.Rotate & gripKind) != 0)
             *                {
             *                        double gripSize = 10 / pageScale;
             *                        // Rotation grips
             *                        for (int i = 1; i < _gripRelPositions.Length; i += 2)
             *                        {
             *                                PointD2D outVec, pos;
             *                                GetCornerOutVector(_gripRelPositions[i], hitTest, out outVec, out pos);
             *
             *                                outVec *= (gripSize / outVec.VectorLength);
             *                                PointD2D altVec = outVec.Get90DegreeRotated();
             *                                PointD2D ptStart = pos;
             *                                list.Add(new RotationGripHandle(hitTest, _gripRelPositions[i], new MatrixD2D(outVec.X, outVec.Y, altVec.X, altVec.Y, ptStart.X, ptStart.Y)));
             *                        }
             *                }
             */

            /*
             *                if ((GripKind.Rescale & gripKind) != 0)
             *                {
             *                        double gripSize = 10 / pageScale; // 10 Points, but we have to consider the current pageScale
             *                        for (int i = 1; i < _gripRelPositions.Length; i++)
             *                        {
             *                                PointD2D outVec, pos;
             *                                if (1 == i % 2)
             *                                        GetCornerOutVector(_gripRelPositions[i], hitTest, out outVec, out pos);
             *                                else
             *                                        GetMiddleRayOutVector(_gripRelPositions[i], hitTest, out outVec, out pos);
             *
             *                                outVec *= (gripSize / outVec.VectorLength);
             *                                PointD2D altVec = outVec.Get90DegreeRotated();
             *                                PointD2D ptStart = pos;
             *                                list.Add(new RescaleGripHandle(hitTest, _gripRelPositions[i], new MatrixD2D(outVec.X, outVec.Y, altVec.X, altVec.Y, ptStart.X, ptStart.Y)));
             *                        }
             *                }
             */

            /*
             *                if ((GripKind.Shear & gripKind) != 0)
             *                {
             *                        double gripSize = 10 / pageScale; // 10 Points, but we have to consider the current pageScale
             *                        for (int i = 2; i < _gripRelPositions.Length; i += 2)
             *                        {
             *                                PointD2D outVec, pos;
             *                                GetEdgeOutVector(_gripRelPositions[i], hitTest, out outVec, out pos);
             *
             *                                outVec *= (gripSize / outVec.VectorLength);
             *                                PointD2D altVec = outVec.Get90DegreeRotated();
             *                                PointD2D ptStart = pos;
             *                                list.Add(new ShearGripHandle(hitTest, _gripRelPositions[i], new MatrixD2D(outVec.X, outVec.Y, altVec.X, altVec.Y, ptStart.X, ptStart.Y)));
             *                        }
             *                }
             */

            if ((GripKind.Move & gripKind) != 0)
            {
                var bounds         = Bounds;
                var wn             = PolylineMath3D.GetWestNorthVectors(bounds.Size);
                var transformation = Matrix4x3.NewFromBasisVectorsAndLocation(wn.Item1, wn.Item2, bounds.Size.Normalized, PointD3D.Empty);

                transformation.AppendTransform(_transformation);
                transformation.AppendTransform(hitTest.Transformation);

                double t1            = 0.55 * _linePen.Thickness1;
                double t2            = 0.55 * _linePen.Thickness2;
                var    rect          = new RectangleD3D(-t1, -t2, 0, 2 * t1, 2 * t2, bounds.Size.Length);
                var    objectOutline = new RectangularObjectOutline(rect, transformation);
                list.Add(new MovementGripHandle(hitTest, objectOutline, null));
            }

            return(list.ToArray());
        }