private static void EndCap_ConeSoft(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, Transform3D normalTransform, TubeRingPoint ring, double capHeight, 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)); geometry.Normals.Add(normalTransform.Transform(point).ToVector().ToUnit()); // the normal is the same as the point for a sphere (but no tranlate transform) } } // Cone tip geometry.Positions.Add(transform.Transform(new Point3D(0, 0, capHeight))); geometry.Normals.Add(transform.Transform(new Vector3D(0, 0, capHeight < 0 ? -1 : 1))); // they can pass in a negative cap height #endregion #region Triangles int topIndex = geometry.Positions.Count - 1; for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++) { geometry.TriangleIndices.Add(pointOffset + cntr + 0); geometry.TriangleIndices.Add(pointOffset + cntr + 1); geometry.TriangleIndices.Add(topIndex); } // The last triangle links back to zero geometry.TriangleIndices.Add(pointOffset + pointsTheta.Length - 1 + 0); geometry.TriangleIndices.Add(pointOffset + 0); geometry.TriangleIndices.Add(topIndex); #endregion pointOffset = geometry.Positions.Count; }
private static void EndCap_ConeHard(ref int pointOffset, ref double[] rotateAnglesForPerp, MeshGeometry3D geometry, Point[] pointsTheta, Transform3D transform, TubeRingPoint ring, double capHeight, bool isFirst) { Point3D tipPosition = transform.Transform(new Point3D(0, 0, capHeight)); int localOffset = 0; for (int cntr = 0; cntr < pointsTheta.Length - 1; cntr++) { geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[cntr].X, pointsTheta[cntr].Y, 0d))); geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[cntr + 1].X, pointsTheta[cntr + 1].Y, 0d))); geometry.Positions.Add(tipPosition); Vector3D normal = GetNormal(geometry.Positions[pointOffset + localOffset + 0], geometry.Positions[pointOffset + localOffset + 1], geometry.Positions[pointOffset + localOffset + 2]); geometry.Normals.Add(normal); // the normals point straight out of the face 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); localOffset += 3; } // The last triangle links back to zero geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[pointsTheta.Length - 1].X, pointsTheta[pointsTheta.Length - 1].Y, 0d))); geometry.Positions.Add(transform.Transform(new Point3D(pointsTheta[0].X, pointsTheta[0].Y, 0d))); geometry.Positions.Add(tipPosition); Vector3D normal2 = GetNormal(geometry.Positions[pointOffset + localOffset + 0], geometry.Positions[pointOffset + localOffset + 1], geometry.Positions[pointOffset + localOffset + 2]); geometry.Normals.Add(normal2); // the normals point straight out of the face geometry.Normals.Add(normal2); geometry.Normals.Add(normal2); geometry.TriangleIndices.Add(pointOffset + localOffset + 0); geometry.TriangleIndices.Add(pointOffset + localOffset + 1); geometry.TriangleIndices.Add(pointOffset + localOffset + 2); // Update ref param 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; } }