Beispiel #1
0
        public void Initialize(
            ICrossSectionOfLine crossSection,
            double thickness1,
            double thickness2,
            ILineCap startCap,
            ILineCap endCap,
            VectorD3D westVector,
            VectorD3D northVector,
            LineD3D line)
        {
            _crossSection                  = crossSection;
            _crossSectionVertexCount       = crossSection.NumberOfVertices;
            _crossSectionNormalCount       = crossSection.NumberOfNormals;
            _dashStartCap                  = startCap;
            _dashStartCapBaseInsetAbsolute = null == _dashStartCap ? 0 : _dashStartCap.GetAbsoluteBaseInset(thickness1, thickness2);
            _dashEndCap = endCap;
            _dashEndCapBaseInsetAbsolute = null == _dashEndCap ? 0 : _dashEndCap.GetAbsoluteBaseInset(thickness1, thickness2);
            _westVector                    = westVector;
            _northVector                   = northVector;
            _forwardVector                 = line.LineVectorNormalized;
            _lastNormalsTransformed        = new VectorD3D[_crossSectionNormalCount];
            _lastPositionsTransformedStart = new PointD3D[_crossSectionVertexCount];
            _lastPositionsTransformedEnd   = new PointD3D[_crossSectionVertexCount];

            // Get the matrix for the start plane
            var matrix = Math3D.Get2DProjectionToPlane(westVector, northVector, PointD3D.Empty);

            // note: for a single line segment, the normals need to be calculated only once

            for (int i = 0; i < _lastNormalsTransformed.Length; ++i)
            {
                _lastNormalsTransformed[i] = matrix.Transform(crossSection.Normals(i));
            }
        }
Beispiel #2
0
        /// <inheritdoc />
        public void AddGeometry(
            Action <PointD3D, VectorD3D> AddPositionAndNormal,
            Action <int, int, int, bool> AddIndices,
            ref int vertexIndexOffset,
            bool isStartCap,
            PointD3D basePoint,
            VectorD3D eastVector,
            VectorD3D northVector,
            VectorD3D forwardVectorNormalized,
            ICrossSectionOfLine lineCrossSection,
            PointD3D[] baseCrossSectionPositions,
            VectorD3D[] baseCrossSectionNormals,
            ref object temporaryStorageSpace)
        {
            var crossSectionVertexCount = lineCrossSection.NumberOfVertices;
            var crossSectionNormalCount = lineCrossSection.NumberOfNormals;

            var capCrossSectionPositions = baseCrossSectionPositions ?? (PointD3D[])temporaryStorageSpace ?? (PointD3D[])(temporaryStorageSpace = new PointD3D[crossSectionVertexCount]);

            if (null == baseCrossSectionPositions) // if null the positions were not provided
            {
                var matrix = Math3D.Get2DProjectionToPlane(eastVector, northVector, basePoint);
                for (int i = 0, j = 0; i < crossSectionVertexCount; ++i, ++j)
                {
                    capCrossSectionPositions[i] = matrix.Transform(lineCrossSection.Vertices(i));
                }
            }

            AddGeometry(AddPositionAndNormal, AddIndices, ref vertexIndexOffset, isStartCap, basePoint, forwardVectorNormalized, capCrossSectionPositions);
        }
Beispiel #3
0
        /// <summary>
        /// Adds the triangle geometry. Here, the position of the startcap base and of the endcap base is already calculated and provided in the arguments.
        /// </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.</param>
        /// <param name="lineStart">The line start. This is the precalculated base of the start line cap.</param>
        /// <param name="lineEnd">The line end. Here, this is the precalculated base of the end line cap.</param>
        /// <param name="drawLine">If this parameter is true, the line segment between lineStart and lineEnd is drawn. If false, the line segment itself is not drawn, but the start end end caps are drawn.</param>
        /// <param name="overrideStartCap">If not null, this parameter override the start cap that is stored in this class.</param>
        /// <param name="overrideEndCap">If not null, this parameter overrides the end cap that is stored in this class.</param>
        /// <exception cref="System.InvalidProgramException">The structure is not initialized yet. Call Initialize before using it!</exception>
        public void AddGeometry(
            Action <PointD3D, VectorD3D> AddPositionAndNormal,
            Action <int, int, int, bool> AddIndices,
            ref int vertexIndexOffset,
            PointD3D lineStart,
            PointD3D lineEnd,
            bool drawLine,
            ILineCap overrideStartCap,
            ILineCap overrideEndCap
            )
        {
            if (null == _lastNormalsTransformed)
            {
                throw new InvalidProgramException("The structure is not initialized yet. Call Initialize before using it!");
            }

            var resultingStartCap = overrideStartCap ?? _dashStartCap;
            var resultingEndCap   = overrideEndCap ?? _dashEndCap;

            // draw the straight line if the remaining line length is >0
            if (drawLine)
            {
                // Get the matrix for the start plane
                var matrix = Math3D.Get2DProjectionToPlane(_westVector, _northVector, lineStart);
                for (int i = 0; i < _crossSectionVertexCount; ++i)
                {
                    _lastPositionsTransformedStart[i] = matrix.Transform(_crossSection.Vertices(i));
                }

                matrix = Math3D.Get2DProjectionToPlane(_westVector, _northVector, lineEnd);
                for (int i = 0; i < _crossSectionVertexCount; ++i)
                {
                    _lastPositionsTransformedEnd[i] = matrix.Transform(_crossSection.Vertices(i));
                }

                // draw the line segment now
                var currIndex = vertexIndexOffset;
                for (int i = 0, j = 0; i < _crossSectionVertexCount; ++i, ++j)
                {
                    if (j == 0)
                    {
                        AddIndices(currIndex, currIndex + 1, currIndex + 2 * _crossSectionNormalCount - 2, false);
                        AddIndices(currIndex + 2 * _crossSectionNormalCount - 2, currIndex + 1, currIndex + 2 * _crossSectionNormalCount - 1, false);
                    }
                    else
                    {
                        AddIndices(currIndex, currIndex + 1, currIndex - 2, false);
                        AddIndices(currIndex - 2, currIndex + 1, currIndex - 1, false);
                    }

                    AddPositionAndNormal(_lastPositionsTransformedStart[i], _lastNormalsTransformed[j]);
                    AddPositionAndNormal(_lastPositionsTransformedEnd[i], _lastNormalsTransformed[j]);
                    currIndex += 2;

                    if (_crossSection.IsVertexSharp(i))
                    {
                        ++j;
                        AddPositionAndNormal(_lastPositionsTransformedStart[i], _lastNormalsTransformed[j]);
                        AddPositionAndNormal(_lastPositionsTransformedEnd[i], _lastNormalsTransformed[j]);
                        currIndex += 2;
                    }
                }
                vertexIndexOffset = currIndex;
            }

            // now the start cap
            if (null != resultingStartCap)
            {
                resultingStartCap.AddGeometry(
                    AddPositionAndNormal,
                    AddIndices,
                    ref vertexIndexOffset,
                    true,
                    lineStart,
                    _westVector,
                    _northVector,
                    _forwardVector,
                    _crossSection,
                    drawLine ? _lastPositionsTransformedStart : null,
                    _lastNormalsTransformed,
                    ref _startCapTemporaryStorageSpace);
            }
            else if (drawLine)
            {
                LineCaps.Flat.AddGeometry(
                    AddPositionAndNormal,
                    AddIndices,
                    ref vertexIndexOffset,
                    true,
                    lineStart,
                    _forwardVector,
                    _lastPositionsTransformedStart
                    );
            }

            if (null != resultingEndCap)
            {
                resultingEndCap.AddGeometry(
                    AddPositionAndNormal,
                    AddIndices,
                    ref vertexIndexOffset,
                    false,
                    lineEnd,
                    _westVector,
                    _northVector,
                    _forwardVector,
                    _crossSection,
                    drawLine ? _lastPositionsTransformedEnd : null,
                    _lastNormalsTransformed,
                    ref _endCapTemporaryStorageSpace);
            }
            else if (drawLine)
            {
                LineCaps.Flat.AddGeometry(
                    AddPositionAndNormal,
                    AddIndices,
                    ref vertexIndexOffset,
                    false,
                    lineEnd,
                    _forwardVector,
                    _lastPositionsTransformedEnd
                    );
            }
        }