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)); } }
/// <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); }
/// <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 ); } }