private static void EndCap_PlateSoft(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingBase ring, bool isFirst) { #region Positions/Normals if (isFirst || !ring.MergeNormalWithPrevIfSoft) { for (int thetaCntr = 0; thetaCntr < pointsTheta.Length; thetaCntr++) { Point3D point = new Point3D(pointsTheta[thetaCntr].X, pointsTheta[thetaCntr].Y, 0d); geometry.Positions.Add(transform.Transform(point)); Vector3D normal; if (ring.MergeNormalWithPrevIfSoft) { //normal = point.ToVector(); // this isn't right throw new ApplicationException("finish this"); } else { normal = new Vector3D(0, 0, 1); } geometry.Normals.Add(normalTransform.Transform(normal).ToUnit()); } } #endregion #region Add the triangles // Start with 0,1,2 geometry.TriangleIndices.Add(pointOffset + 0); geometry.TriangleIndices.Add(pointOffset + 1); geometry.TriangleIndices.Add(pointOffset + 2); int lowerIndex = 2; int upperIndex = pointsTheta.Length - 1; int lastUsedIndex = 0; bool shouldBumpLower = true; // Do the rest of the triangles while (lowerIndex < upperIndex) { geometry.TriangleIndices.Add(pointOffset + lowerIndex); geometry.TriangleIndices.Add(pointOffset + upperIndex); geometry.TriangleIndices.Add(pointOffset + lastUsedIndex); if (shouldBumpLower) { lastUsedIndex = lowerIndex; lowerIndex++; } else { lastUsedIndex = upperIndex; upperIndex--; } shouldBumpLower = !shouldBumpLower; } #endregion pointOffset = geometry.Positions.Count; }
private static Point[] EndCap_GetPoints(TubeRingBase ringPrev, TubeRingBase ringNext, int numSides, bool isFirst) { // Figure out which ring to pull from TubeRingBase ring = null; if (isFirst) { ring = ringNext; } else { ring = ringPrev; } // Get the points Point[] retVal = null; if (ring != null && ring is TubeRingRegularPolygon) { retVal = GetPointsRegPoly(numSides, (TubeRingRegularPolygon)ring); } if (retVal == null) { throw new ApplicationException("The points are null for dome/point. Validation should have caught this before now"); } // Exit Function return retVal; }
private static double EndCap_GetCapHeight(TubeRingBase ringCurrent, TubeRingBase ringNext, bool isFirst) { if (isFirst) { // ringCurrent.DistFromPrevRing is ignored (because there is no previous). So the cap's height is the next ring's dist from prev return ringNext.DistFromPrevRing; } else { // This is the last, so dist from prev has meaning return ringCurrent.DistFromPrevRing; } }
private static void EndCap(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, int numSides, TubeRingBase ringPrev, TubeRingBase ringCurrent, TubeRingBase ringNext, Transform3D transform, bool isFirst, double z, bool softSides) { if (ringCurrent is TubeRingDome) { #region Dome Point[] domePointsTheta = EndCap_GetPoints(ringPrev, ringNext, numSides, isFirst); double capHeight = EndCap_GetCapHeight(ringCurrent, ringNext, isFirst); Transform3D domeTransform = EndCap_GetTransform(transform, isFirst, z, capHeight); Transform3D domeTransformNormal = EndCap_GetNormalTransform(domeTransform); if (softSides) { EndCap_DomeSoft(ref pointOffset, ref rotateAnglesForPerp, geometry, domePointsTheta, domeTransform, domeTransformNormal, (TubeRingDome)ringCurrent, capHeight, isFirst); } else { EndCap_DomeHard(ref pointOffset, ref rotateAnglesForPerp, geometry, domePointsTheta, domeTransform, domeTransformNormal, (TubeRingDome)ringCurrent, capHeight, isFirst); } #endregion } else if (ringCurrent is TubeRingPoint) { #region Point Point[] conePointsTheta = EndCap_GetPoints(ringPrev, ringNext, numSides, isFirst); double capHeight = EndCap_GetCapHeight(ringCurrent, ringNext, isFirst); Transform3D coneTransform = EndCap_GetTransform(transform, isFirst, z, capHeight); if (softSides) { Transform3D coneTransformNormal = EndCap_GetNormalTransform(coneTransform); // only need the transform for soft, because it cheats and has a hardcode normal (hard calculates the normal for each triangle) EndCap_ConeSoft(ref pointOffset, ref rotateAnglesForPerp, geometry, conePointsTheta, coneTransform, coneTransformNormal, (TubeRingPoint)ringCurrent, capHeight, isFirst); } else { EndCap_ConeHard(ref pointOffset, ref rotateAnglesForPerp, geometry, conePointsTheta, coneTransform, (TubeRingPoint)ringCurrent, capHeight, isFirst); } #endregion } else if (ringCurrent is TubeRingRegularPolygon) { #region Regular Polygon TubeRingRegularPolygon ringCurrentCast = (TubeRingRegularPolygon)ringCurrent; if (ringCurrentCast.IsClosedIfEndCap) // if it's open, there is nothing to do for the end cap { Point[] polyPointsTheta = GetPointsRegPoly(numSides, ringCurrentCast); Transform3D polyTransform = EndCap_GetTransform(transform, isFirst, z); Transform3D polyTransformNormal = EndCap_GetNormalTransform(polyTransform); if (softSides) { EndCap_PlateSoft(ref pointOffset, ref rotateAnglesForPerp, geometry, polyPointsTheta, polyTransform, polyTransformNormal, ringCurrent, isFirst); } else { EndCap_PlateHard(ref pointOffset, ref rotateAnglesForPerp, geometry, polyPointsTheta, polyTransform, polyTransformNormal, ringCurrent, isFirst); } } #endregion } else { throw new ApplicationException("Unknown tube ring type: " + ringCurrent.GetType().ToString()); } }
private static void Middle(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Transform3D transform, int numSides, TubeRingBase ring1, TubeRingBase ring2, double curZ, bool softSides) { if (ring1 is TubeRingRegularPolygon && ring2 is TubeRingRegularPolygon) { #region Tube if (softSides) { Middle_TubeSoft(ref pointOffset, ref rotateAnglesForPerp, geometry, transform, numSides, (TubeRingRegularPolygon)ring1, (TubeRingRegularPolygon)ring2, curZ); } else { Middle_TubeHard(ref pointOffset, ref rotateAnglesForPerp, geometry, transform, numSides, (TubeRingRegularPolygon)ring1, (TubeRingRegularPolygon)ring2, curZ); } #endregion } else { // There are no other combos that need to show a visual right now (eventually, I'll have a definition for // a non regular polygon - low in fiber) } }
private static void EndCap_PlateHard(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingBase ring, bool isFirst) { Vector3D normal = normalTransform.Transform(new Vector3D(0, 0, 1)).ToUnit(); // Start with 0,1,2 geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[0].X, pointsTheta[0].Y, 0d))); geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[1].X, pointsTheta[1].Y, 0d))); geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[2].X, pointsTheta[2].Y, 0d))); geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(pointOffset + 0); geometry.TriangleIndices.Add(pointOffset + 1); geometry.TriangleIndices.Add(pointOffset + 2); int lowerIndex = 2; int upperIndex = pointsTheta.Length - 1; int lastUsedIndex = 0; bool shouldBumpLower = true; int localOffset = 3; // Do the rest of the triangles while (lowerIndex < upperIndex) { geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[lowerIndex].X, pointsTheta[lowerIndex].Y, 0d))); geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[upperIndex].X, pointsTheta[upperIndex].Y, 0d))); geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[lastUsedIndex].X, pointsTheta[lastUsedIndex].Y, 0d))); geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(pointOffset + localOffset + 0); geometry.TriangleIndices.Add(pointOffset + localOffset + 1); geometry.TriangleIndices.Add(pointOffset + localOffset + 2); if (shouldBumpLower) { lastUsedIndex = lowerIndex; lowerIndex++; } else { lastUsedIndex = upperIndex; upperIndex--; } shouldBumpLower = !shouldBumpLower; localOffset += 3; } // Update ref param pointOffset = geometry.Positions.Count; }