private static void EndCap_DomeSoft(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingDome ring, double capHeight, bool isFirst) { // NOTE: There is one more than NumSegmentsPhi Point[] pointsPhi = ring.GetUnitPointsPhi(ring.NumSegmentsPhi); #region Positions/Normals //for (int phiCntr = 0; phiCntr < numSegmentsPhi; phiCntr++) // The top point will be added after this loop for (int phiCntr = pointsPhi.Length - 1; phiCntr > 0; phiCntr--) { if (!isFirst && ring.MergeNormalWithPrevIfSoft) { // Just reuse the points/normals from the previous ring continue; } for (int thetaCntr = 0; thetaCntr < pointsTheta.Length; thetaCntr++) { // Phi points are going from bottom to equator. // pointsTheta are already the length they are supposed to be (not nessassarily a unit circle) Point3D point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y, pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); if (ring.MergeNormalWithPrevIfSoft) { //TODO: Merge the normal with rotateAngleForPerp (see the GetCone method) throw new ApplicationException("finish this"); } else { geometry.Normals.Add(normalTransform.Transform(point).ToVector().ToUnit()); // the normal is the same as the point for a sphere (but no tranlate transform) } } } // This is north pole point geometry.Positions.Add(transform.Transform(new Point3D(0, 0, capHeight))); geometry.Normals.Add(normalTransform.Transform(new Vector3D(0, 0, capHeight < 0 ? -1 : 1))); // they can enter a negative height (which would make a bowl) #endregion #region Triangles - Rings int zOffsetBottom = pointOffset; int zOffsetTop; for (int phiCntr = 0; phiCntr < ring.NumSegmentsPhi - 1; phiCntr++) // The top cone will be added after this loop { zOffsetTop = zOffsetBottom + pointsTheta.Length; for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++) { // Top/Left triangle geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 0); geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 1); geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 0); // Bottom/Right triangle geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 0); geometry.TriangleIndices.Add(zOffsetBottom + thetaCntr + 1); geometry.TriangleIndices.Add(zOffsetTop + thetaCntr + 1); } // Connecting the last 2 points to the first 2 // Top/Left triangle geometry.TriangleIndices.Add(zOffsetBottom + (pointsTheta.Length - 1) + 0); geometry.TriangleIndices.Add(zOffsetTop); // wrapping back around geometry.TriangleIndices.Add(zOffsetTop + (pointsTheta.Length - 1) + 0); // Bottom/Right triangle geometry.TriangleIndices.Add(zOffsetBottom + (pointsTheta.Length - 1) + 0); geometry.TriangleIndices.Add(zOffsetBottom); geometry.TriangleIndices.Add(zOffsetTop); // Prep for the next ring zOffsetBottom = zOffsetTop; } #endregion #region Triangles - Cap int topIndex = geometry.Positions.Count - 1; for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++) { geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0); geometry.TriangleIndices.Add(zOffsetBottom + cntr + 1); geometry.TriangleIndices.Add(topIndex); } // The last triangle links back to zero geometry.TriangleIndices.Add(zOffsetBottom + pointsTheta.Length - 1 + 0); geometry.TriangleIndices.Add(zOffsetBottom + 0); geometry.TriangleIndices.Add(topIndex); //for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++) //{ // geometry.TriangleIndices.Add(zOffsetBottom + cntr + 0); // geometry.TriangleIndices.Add(topIndex); // geometry.TriangleIndices.Add(zOffsetBottom + cntr + 1); //} //// The last triangle links back to zero //geometry.TriangleIndices.Add(zOffsetBottom + pointsTheta.Length - 1 + 0); //geometry.TriangleIndices.Add(topIndex); //geometry.TriangleIndices.Add(zOffsetBottom + 0); #endregion pointOffset = geometry.Positions.Count; }
private static void EndCap_DomeHard(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingDome ring, double capHeight, bool isFirst) { // NOTE: There is one more than NumSegmentsPhi Point[] pointsPhi = ring.GetUnitPointsPhi(ring.NumSegmentsPhi); Point3D point; Vector3D normal; int zOffset = pointOffset; #region Triangles - Rings for (int phiCntr = 1; phiCntr < pointsPhi.Length - 1; phiCntr++) // The top cone will be added after this loop { for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++) { // Phi points are going from bottom to equator <----------- NO????????? // Phi points are going from the equator to the top // pointsTheta are already the length they are supposed to be (not nessassarily a unit circle) #region Top/Left triangle point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y, pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[phiCntr + 1].Y, pointsTheta[thetaCntr].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr + 1].Y, pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); #endregion zOffset += 3; #region Bottom/Right triangle point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[phiCntr].Y, pointsTheta[thetaCntr].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr + 1].Y, pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr + 1].X * pointsPhi[phiCntr].Y, pointsTheta[thetaCntr + 1].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); #endregion zOffset += 3; } // Connecting the last 2 points to the first 2 #region Top/Left triangle point = new Point3D( pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr].Y, pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr + 1].Y, pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[0].X * pointsPhi[phiCntr + 1].Y, // wrapping theta back around pointsTheta[0].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); #endregion zOffset += 3; #region Bottom/Right triangle point = new Point3D( pointsTheta[pointsTheta.Length - 1].X * pointsPhi[phiCntr].Y, pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[0].X * pointsPhi[phiCntr + 1].Y, pointsTheta[0].Y * pointsPhi[phiCntr + 1].Y, capHeight * pointsPhi[phiCntr + 1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[0].X * pointsPhi[phiCntr].Y, pointsTheta[0].Y * pointsPhi[phiCntr].Y, capHeight * pointsPhi[phiCntr].X); geometry.Positions.Add(transform.Transform(point)); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); #endregion zOffset += 3; } #endregion #region Triangles - Cap // This is basically the same idea as EndCap_ConeHard, except for the extra phi bits Point3D topPoint = transform.Transform(new Point3D(0, 0, capHeight)); for (int thetaCntr = 0; thetaCntr < pointsTheta.Length - 1; thetaCntr++) { point = new Point3D( pointsTheta[thetaCntr].X * pointsPhi[1].Y, pointsTheta[thetaCntr].Y * pointsPhi[1].Y, capHeight * pointsPhi[1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[thetaCntr + 1].X * pointsPhi[1].Y, pointsTheta[thetaCntr + 1].Y * pointsPhi[1].Y, capHeight * pointsPhi[1].X); geometry.Positions.Add(transform.Transform(point)); geometry.Positions.Add(topPoint); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); zOffset += 3; } // The last triangle links back to zero point = new Point3D( pointsTheta[pointsTheta.Length - 1].X * pointsPhi[1].Y, pointsTheta[pointsTheta.Length - 1].Y * pointsPhi[1].Y, capHeight * pointsPhi[1].X); geometry.Positions.Add(transform.Transform(point)); point = new Point3D( pointsTheta[0].X * pointsPhi[1].Y, pointsTheta[0].Y * pointsPhi[1].Y, capHeight * pointsPhi[1].X); geometry.Positions.Add(transform.Transform(point)); geometry.Positions.Add(topPoint); normal = GetNormal(geometry.Positions[zOffset + 0], geometry.Positions[zOffset + 1], geometry.Positions[zOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face geometry.Normals.Add(normal); geometry.Normals.Add(normal); geometry.TriangleIndices.Add(zOffset + 0); geometry.TriangleIndices.Add(zOffset + 1); geometry.TriangleIndices.Add(zOffset + 2); zOffset += 3; #endregion pointOffset = geometry.Positions.Count; }
private void RebuildCustom() { try { pnlCustomError.Visibility = Visibility.Collapsed; #region Fix the row numbers for (int cntr = 0; cntr < _customRows.Count; cntr++) { ((TextBlock)_customRows[cntr].Item2.Children[0]).Text = (cntr + 1).ToString(); } txtCustomInsertIndex.Text = (_customRows.Count + 1).ToString(); #endregion List<TubeRingBase> rings = new List<TubeRingBase>(); #region Parse the rows for (int cntr = 0; cntr < _customRows.Count; cntr++) { StackPanel panel = _customRows[cntr].Item2; // Distance double distance = double.Parse(((TextBox)panel.Children[2]).Text); switch (_customRows[cntr].Item1) { case "Poly": TubeRingRegularPolygon poly = new TubeRingRegularPolygon(distance, false, double.Parse(((TextBox)panel.Children[4]).Text), double.Parse(((TextBox)panel.Children[6]).Text), ((CheckBox)panel.Children[7]).IsChecked.Value); rings.Add(poly); break; case "Point": TubeRingPoint point = new TubeRingPoint(distance, false); rings.Add(point); break; case "Dome": TubeRingDome dome = new TubeRingDome(distance, false, int.Parse(((TextBox)panel.Children[4]).Text)); rings.Add(dome); break; default: throw new ApplicationException("Unknown type: " + _customRows[cntr].Item1); } } #endregion MeshGeometry3D mesh = UtilityWPF.GetMultiRingedTube(int.Parse(txtNumSides.Text), rings, chkSoftSides.IsChecked.Value, true); // Material MaterialGroup material = new MaterialGroup(); Color color = UtilityWPF.ColorFromHex(txtDiffuse.Text); material.Children.Add(new DiffuseMaterial(new SolidColorBrush(color))); if (chkSpecular.IsChecked.Value) { color = UtilityWPF.ColorFromHex(txtSpecular.Text); double power = double.Parse(txtSpecularPower.Text); material.Children.Add(new SpecularMaterial(new SolidColorBrush(color), power)); } if (chkEmissive.IsChecked.Value) { color = UtilityWPF.ColorFromHex(txtEmissive.Text); material.Children.Add(new EmissiveMaterial(new SolidColorBrush(color))); } // Geometry Model GeometryModel3D geometry = new GeometryModel3D(); geometry.Material = material; geometry.BackMaterial = material; geometry.Geometry = mesh; // Model Visual ModelVisual3D visual = new ModelVisual3D(); visual.Content = geometry; // Store it SetCurrentVisual(visual); } catch (Exception ex) { pnlCustomError.Visibility = Visibility.Visible; lblCustomError.Text = ex.Message; } }