Exemplo n.º 1
0
            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;
            }
Exemplo n.º 2
0
            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;
            }
        }