Class with utility method for generating meshes for shapeways models.
Beispiel #1
0
        private static void HopfFibration(Tiling tiling)
        {
            int       segDivisions = 10;
            Shapeways mesh         = new Shapeways();

            HashSet <Vector3D> done = new HashSet <Vector3D>();

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (Segment seg in tile.Boundary.Segments)
                {
                    if (done.Contains(seg.Midpoint))
                    {
                        continue;
                    }

                    // Subdivide the segment, and project points to S2.
                    Vector3D[] points = seg.Subdivide(segDivisions).Select(v => Spherical2D.PlaneToSphere(v)).ToArray();
                    foreach (Vector3D point in points)
                    {
                        Vector3D[] circlePoints = OneHopfCircle(point);
                        ProjectAndAddS3Points(mesh, circlePoints, shrink: false);
                    }

                    done.Add(seg.Midpoint);
                }
            }

            STL.SaveMeshToSTL(mesh.Mesh, @"D:\p4\R3\sample\out1.stl");
        }
Beispiel #2
0
        public static void EdgesToStl( H3.Cell.Edge[] edges )
        {
            Shapeways mesh = new Shapeways();

            int divisions = 10;
            foreach( H3.Cell.Edge edge in edges )
            {
                Segment seg = Segment.Line(
                    Sterographic.R3toS3( edge.Start ),
                    Sterographic.R3toS3( edge.End ) );
                Vector3D[] points = seg.Subdivide( divisions );

                ProjectAndAddS3Points( mesh, points );
            }

            for( int i = 0; i < mesh.Mesh.Triangles.Count; i++ )
            {
                mesh.Mesh.Triangles[i] = new Mesh.Triangle(
                    SphericalModels.GnomonicToStereo( mesh.Mesh.Triangles[i].a ),
                    SphericalModels.GnomonicToStereo( mesh.Mesh.Triangles[i].b ),
                    SphericalModels.GnomonicToStereo( mesh.Mesh.Triangles[i].c ) );
            }

            STL.SaveMeshToSTL( mesh.Mesh, @"output.stl" );
        }
Beispiel #3
0
        public static void GenEuclidean()
        {
            Shapeways mesh = new Shapeways();
            HashSet <H3.Cell.Edge> completed = new HashSet <H3.Cell.Edge>();

            int count = 5;

            for (int i = -count; i < count; i++)
            {
                for (int j = -count; j < count; j++)
                {
                    for (int k = -count; k < count; k++)
                    {
                        // Offset
                        double io = i + 0.5;
                        double jo = j + 0.5;
                        double ko = k + 0.5;

                        // Do every edge emanating from this point.
                        AddEuclideanEdge(mesh, completed, new Vector3D(io, jo, ko), new Vector3D(io + 1, jo, ko));
                        AddEuclideanEdge(mesh, completed, new Vector3D(io, jo, ko), new Vector3D(io - 1, jo, ko));
                        AddEuclideanEdge(mesh, completed, new Vector3D(io, jo, ko), new Vector3D(io, jo + 1, ko));
                        AddEuclideanEdge(mesh, completed, new Vector3D(io, jo, ko), new Vector3D(io, jo - 1, ko));
                        AddEuclideanEdge(mesh, completed, new Vector3D(io, jo, ko), new Vector3D(io, jo, ko + 1));
                        AddEuclideanEdge(mesh, completed, new Vector3D(io, jo, ko), new Vector3D(io, jo, ko - 1));
                    }
                }
            }

            STL.SaveMeshToSTL(mesh.Mesh, "d:\\temp\\434.stl");
        }
Beispiel #4
0
        private static void HopfFibration(Tiling tiling)
        {
            int       segDivisions    = 10;
            int       circleDivisions = 125;
            Shapeways mesh            = new Shapeways();

            HashSet <Vector3D> done = new HashSet <Vector3D>();

            foreach (Tile tile in tiling.Tiles)
            {
                foreach (Segment seg in tile.Boundary.Segments)
                {
                    if (done.Contains(seg.Midpoint))
                    {
                        continue;
                    }

                    // Subdivide the segment, and project points to S2.
                    Vector3D[] points = seg.Subdivide(segDivisions).Select(v => Spherical2D.PlaneToSphere(v)).ToArray();
                    foreach (Vector3D point in points)
                    {
                        // Get the hopf circle and add to mesh.
                        // http://en.wikipedia.org/wiki/Hopf_fibration#Explicit_formulae
                        double a      = point.X;
                        double b      = point.Y;
                        double c      = point.Z;
                        double factor = 1 / (Math.Sqrt(1 + c));
                        if (Tolerance.Equal(c, -1))
                        {
                            continue;
                        }

                        List <Vector3D> circlePoints = new List <Vector3D>();
                        double          angleInc     = 2 * Math.PI / circleDivisions;
                        double          angle        = 0;
                        for (int i = 0; i <= circleDivisions; i++)
                        {
                            double sinTheta = Math.Sin(angle);
                            double cosTheta = Math.Cos(angle);
                            circlePoints.Add(new Vector3D(
                                                 (1 + c) * cosTheta,
                                                 a * sinTheta - b * cosTheta,
                                                 a * cosTheta + b * sinTheta,
                                                 (1 + c) * sinTheta));

                            angle += angleInc;
                        }

                        bool shrink = false;
                        ProjectAndAddS3Points(mesh, circlePoints.ToArray(), shrink);
                    }

                    done.Add(seg.Midpoint);
                }
            }

            STL.SaveMeshToSTL(mesh.Mesh, @"D:\p4\R3\sample\out1.stl");
        }
Beispiel #5
0
        /// <summary>
        /// Add a finite (truncated) banana to our mesh.  Passed in edge should be in Ball model.
        /// </summary>
        public static void AddBanana( Shapeways mesh, Vector3D e1, Vector3D e2, H3.Settings settings )
        {
            Vector3D e1UHS = H3Models.BallToUHS( e1 );
            Vector3D e2UHS = H3Models.BallToUHS( e2 );

            // Endpoints of the goedesic on the z=0 plane.
            Vector3D z1, z2;
            H3Models.UHS.GeodesicIdealEndpoints( e1UHS, e2UHS, out z1, out z2 );

            // XXX - Do we want to do a better job worrying about rotation here?
            // (multiply by complex number with certain imaginary part as well)
            //Vector3D z3 = ( z1 + z2 ) / 2;
            //if( Infinity.IsInfinite( z3 ) )
            //	z3 = new Vector3D( 1, 0 );
            Vector3D z3 = new Vector3D( Math.E, Math.PI );	// This should vary the rotations a bunch.

            // Find the Mobius we need.
            // We'll do this in two steps.
            // (1) Find a mobius taking z1,z2 to origin,inf
            // (2) Deal with scaling e1 to a height of 1.
            Mobius m1 = new Mobius( z1, z3, z2 );
            Vector3D e1UHS_transformed = m1.ApplyToQuaternion( e1UHS );
            double scale = 1.0 / e1UHS_transformed.Z;
            Mobius m2 = Mobius.Scale( scale );
            Mobius m = m2 * m1;	// Compose them (multiply in reverse order).
            Vector3D e2UHS_transformed = m.ApplyToQuaternion( e2UHS );

            // Make our truncated cone.
            // For regular tilings, we really would only need to do this once for a given LOD.
            List<Vector3D> points = new List<Vector3D>();
            double logHeight = Math.Log( e2UHS_transformed.Z );
            if( logHeight < 0 )
                throw new System.Exception( "impl issue" );
            int div1, div2;
            H3Models.Ball.LOD_Finite( e1, e2, out div1, out div2, settings );
            double increment = logHeight / div1;
            for( int i=0; i<=div1; i++ )
            {
                double h = increment * i;

                // This is to keep different bananas from sharing exactly coincident vertices.
                double tinyOffset = 0.001;
                if( i == 0 )
                    h -= tinyOffset;
                if( i == div1 )
                    h += tinyOffset;

                Vector3D point = new Vector3D( 0, 0, Math.Exp( h ) );
                points.Add( point );
            }
            Shapeways tempMesh = new Shapeways();
            tempMesh.Div = div2;
            tempMesh.AddCurve( points.ToArray(), v => H3Models.UHS.SizeFunc( v, settings.AngularThickness ) );

            // Unwind the transforms.
            TakePointsBack( tempMesh.Mesh, m.Inverse(), settings );
            mesh.Mesh.Triangles.AddRange( tempMesh.Mesh.Triangles );
        }
Beispiel #6
0
        /// <summary>
        /// Function I was using for lamp project, probably a bit out of date.
        /// </summary>
        public static void AddToMeshLamp( Shapeways mesh, Vector3D v1, Vector3D v2 )
        {
            // need to get these from CalcBallArc
            Vector3D center = Vector3D.DneVector();
            double radius = double.NaN;
            Vector3D normal = Vector3D.DneVector();
            double angleTot = double.NaN;

            double length1 = Scale( 2.1 );	// 12-end piece
            //double length1 = Scale( 1.6 );	// 6-end piece
            //double length1 = Scale( 1.4 );	// 4-end piece
            double length2 = Scale( 0.5 );

            double outerRadStart = Scale( 0.0625 / 2 );
            double outerRadEnd = Scale( 0.25 / 2 );

            System.Func<Vector3D, double> outerSizeFunc = v =>
            {
                double angle = (v1 - center).AngleTo( v - center );
                double len = radius * angle;
                return outerRadStart + (outerRadEnd - outerRadStart) * (len / length1);
            };

            System.Func<Vector3D, double> outerSizeFunc2 = v =>
            {
                double angle = (v2 - center).AngleTo( v - center );
                double len = radius * angle;
                return outerRadStart + (outerRadEnd - outerRadStart) * (len / length1);
            };

            System.Func<Vector3D, double> innerSizeFunc = v =>
            {
                // Very slightly bigger than 1/8 inch OD.
                return Scale( 0.13 / 2 );
            };

            Vector3D[] outerPoints = Shapeways.CalcArcPoints( center, radius, v1, normal, length1 / radius );
            Vector3D[] innerPoints = Shapeways.CalcArcPoints( center, radius, outerPoints[outerPoints.Length - 1], normal * -1, length2 / radius );
            mesh.AddCornucopia( outerPoints, outerSizeFunc, innerPoints, innerSizeFunc );

            outerPoints = Shapeways.CalcArcPoints( center, radius, v2, normal * -1, length1 / radius );
            innerPoints = Shapeways.CalcArcPoints( center, radius, outerPoints[outerPoints.Length - 1], normal, length2 / radius );
            mesh.AddCornucopia( outerPoints, outerSizeFunc2, innerPoints, innerSizeFunc );

            m_inventory.AddRod( Rod.Create( radius, angleTot ) );
        }
Beispiel #7
0
        /// <summary>
        /// Helper to project points from S3 -> S2, then add an associated curve.
        /// </summary>
        private static void ProjectAndAddS3Points(Shapeways mesh, Vector3D[] pointsS3, bool shrink)
        {
            // Project to S3, then to R3.
            List <Vector3D> projected = new List <Vector3D>();

            foreach (Vector3D v in pointsS3)
            {
                v.Normalize();
                Vector3D c = v.ProjectTo3DSafe(1.0);

                // Pull R3 into a smaller open disk.
                if (shrink)
                {
                    double mag = Math.Atan(c.Abs());
                    c.Normalize();
                    c *= mag;
                }

                projected.Add(c);
            }

            System.Func <Vector3D, double> sizeFunc = v =>
            {
                // Constant thickness.
                // return 0.08;

                double sphericalThickness = 0.002;

                double abs = v.Abs();
                if (shrink)
                {
                    abs = Math.Tan(abs);                        // The unshrunk abs.
                }
                // The thickness at this vector location.
                double result = Spherical2D.s2eNorm(Spherical2D.e2sNorm(abs) + sphericalThickness) - abs;

                if (shrink)
                {
                    result *= Math.Atan(abs) / abs;                             // shrink it back down.
                }
                return(result);
            };

            mesh.AddCurve(projected.ToArray(), sizeFunc);
        }
Beispiel #8
0
        private static void AddEuclideanEdge(Shapeways mesh, HashSet <H3.Cell.Edge> completed, Vector3D start, Vector3D end)
        {
            double cutoff = 1.75;

            if (Math.Abs(start.X) > cutoff || Math.Abs(start.Y) > cutoff || Math.Abs(start.Z) > cutoff ||
                Math.Abs(end.X) > cutoff || Math.Abs(end.Y) > cutoff || Math.Abs(end.Z) > cutoff)
            {
                return;
            }

            if (mesh != null)
            {
                AddEuclideanEdgeToMesh(mesh, completed, start, end);
                return;
            }

            completed.Add(new H3.Cell.Edge(start, end));
        }
Beispiel #9
0
        public static void GenEuclidean()
        {
            Shapeways mesh = new Shapeways();
            HashSet <H3.Cell.Edge> completed = new HashSet <H3.Cell.Edge>(new H3.Cell.EdgeEqualityComparer());

            int count = 2;

            for (int i = -count; i < count; i++)
            {
                for (int j = -count; j < count; j++)
                {
                    for (int k = -count; k < count; k++)
                    {
                        // Offset
                        double   io = i + 0.5;
                        double   jo = j + 0.5;
                        double   ko = k + 0.5;
                        Vector3D p  = new Vector3D(io, jo, ko);

                        // Add a sphere for this point.
                        Sphere s = new Sphere()
                        {
                            Center = p, Radius = 0.05
                        };
                        mesh.AddSphere(s.Center, s.Radius);

                        // Do every edge emanating from this point.
                        AddEuclideanEdge(mesh, completed, p, new Vector3D(io + 1, jo, ko));
                        AddEuclideanEdge(mesh, completed, p, new Vector3D(io - 1, jo, ko));
                        AddEuclideanEdge(mesh, completed, p, new Vector3D(io, jo + 1, ko));
                        AddEuclideanEdge(mesh, completed, p, new Vector3D(io, jo - 1, ko));
                        AddEuclideanEdge(mesh, completed, p, new Vector3D(io, jo, ko + 1));
                        AddEuclideanEdge(mesh, completed, p, new Vector3D(io, jo, ko - 1));
                    }
                }
            }

            STL.SaveMeshToSTL(mesh.Mesh, "434.stl");
            //PovRay.WriteEdges( new PovRay.Parameters() { AngularThickness = .05 }, Geometry.Euclidean, completed.ToArray(), "434.pov", append: false );
        }
Beispiel #10
0
        private static void AddEuclideanEdge(Shapeways mesh, HashSet <H3.Cell.Edge> completed, Vector3D start, Vector3D end)
        {
            H3.Cell.Edge edge = new H3.Cell.Edge(start, end);
            if (completed.Contains(edge))
            {
                return;
            }

            Shapeways tempMesh = new Shapeways();
            Segment   seg      = Segment.Line(start, end);

            int div = 20 - (int)(start.Abs() * 4);

            if (div < 1)
            {
                div = 1;
            }

            tempMesh.AddCurve(seg.Subdivide(div), .05);
            Transform(tempMesh.Mesh);

            mesh.Mesh.Triangles.AddRange(tempMesh.Mesh.Triangles);
            completed.Add(edge);
        }
Beispiel #11
0
        private static void ShapewaysPolytopes()
        {
            VEF loader = new VEF();
            loader.Load( @"C:\Users\roice\Documents\projects\vZome\VefProjector\data\24cell-cellFirst.vef" );

            int divisions = 25;

            Shapeways mesh = new Shapeways();
            //int count = 0;
            foreach( Edge edge in loader.Edges )
            {
                Segment seg = Segment.Line(
                    loader.Vertices[edge.V1].ConvertToReal(),
                    loader.Vertices[edge.V2].ConvertToReal() );
                Vector3D[] points = seg.Subdivide( divisions );

                bool shrink = true;
                ProjectAndAddS3Points( mesh, points, shrink );

                //if( count++ > 10 )
                //	break;
            }

            STL.SaveMeshToSTL( mesh.Mesh, @"D:\p4\R3\sample\out1.stl" );
        }
Beispiel #12
0
        /// <summary>
        /// Helper to project points from S3 -> S2, then add an associated curve.
        /// XXX - Not completely correct.
        /// </summary>
        private static void ProjectAndAddS3Points( Shapeways mesh, Vector3D[] pointsS3, bool shrink )
        {
            List<Vector3D> projected = new List<Vector3D>();
            foreach( Vector3D v in pointsS3 )
            {
                v.Normalize();
                Vector3D c = v.ProjectTo3DSafe( 1.0 );

                // Pull R3 into a smaller open disk.
                if( shrink )
                {
                    double mag = Math.Atan( c.Abs() );
                    c.Normalize();
                    c *= mag;
                }

                projected.Add( c );
            }

            System.Func<Vector3D, double> sizeFunc = v =>
            {
                // Constant thickness.
                // return 0.08;

                double sphericalThickness = 0.05;

                double abs = v.Abs();
                if( shrink )
                    abs = Math.Tan( abs );	// The unshrunk abs.

                // The thickness at this vector location.
                double result = Spherical2D.s2eNorm( Spherical2D.e2sNorm( abs ) + sphericalThickness ) - abs;

                if( shrink )
                    result *= Math.Atan( abs ) / abs;	// shrink it back down.

                return result;
            };

            mesh.AddCurve( projected.ToArray(), sizeFunc );
        }
Beispiel #13
0
        private static void ProjectAndAddS3Points( Shapeways mesh, Vector3D[] pointsS3 )
        {
            double r = 0.02;

            List<Vector3D> projected = new List<Vector3D>();
            List<double> radii = new List<double>();
            foreach( Vector3D v in pointsS3 )
            {
                v.Normalize();
                Vector3D c = v.ProjectTo3DSafe( 1.0 );

                Vector3D p;
                double d;
                H3Models.Ball.DupinCyclideSphere( c, r, Geometry.Spherical, out p, out d );
                projected.Add( p );
                radii.Add( d );
            }

            mesh.AddCurve( projected.ToArray(), radii.ToArray() );
        }
Beispiel #14
0
        /// <summary>
        /// Our approach will be:
        /// (1) Generate a portion of one cell.
        /// (2) Reflect all facets in the central facet, to get things filled-in inside the central facet.  (Trim small edges here?)
        /// (3) Copy this region around the plane, and go back to step (2) if density is not high enough.
        /// (4) Map to Ball, trimming edges that become too small.
        /// NOTE: All verts are on the boundary, so we can reflect around 
        //          in circles on the plane at infinity, rather than spheres.
        /// </summary>
        public static void GenerateExotic( EHoneycomb honeycomb, H3.Settings settings )
        {
            settings.AngularThickness = 0.17;

            Tiling tiling;
            Tile baseTile;
            GetAssociatedTiling( honeycomb, out tiling, out baseTile );

            List<H3.Cell.Edge> edges = new List<H3.Cell.Edge>();
            foreach( Segment seg in baseTile.Boundary.Segments )
                edges.Add( new H3.Cell.Edge( seg.P1, seg.P2 ) );

            settings.Position = Polytope.Projection.FaceCentered;
            double scale = 1;
            Vector3D offset = new Vector3D();
            if( settings.Position == Polytope.Projection.FaceCentered )
            {
                scale = FaceCenteredScale( baseTile.VertexCircle );
                offset = new Vector3D();
            }
            else if( settings.Position == Polytope.Projection.EdgeCentered )
            {
                scale = EdgeCenteredScale( baseTile );
                offset = baseTile.Boundary.Segments[0].Midpoint;
            }

            int iterations = m_params.Iterations;
            for( int i=0; i<iterations; i++ )
                edges = DoOneStep( edges, tiling, baseTile.VertexCircle );
            edges = CopyAndProject( edges, tiling, scale, offset );

            if( m_params.RemoveDangling )
            {
                Dictionary<H3.Cell.Edge,int> edgeDict = edges.ToDictionary( e => e, e => 1 );
                H3.RemoveDanglingEdgesRecursive( edgeDict );
                edges = edgeDict.Keys.ToList();
            }

            string outputFileName = H3.m_baseDir + Honeycomb.String( honeycomb, false );
            System.IO.File.Delete( outputFileName );

            if( m_params.Output == H3.Output.STL )
            {
                outputFileName += ".stl";

                // Now mesh the edges.
                Shapeways mesh = new Shapeways();
                foreach( H3.Cell.Edge edge in edges )
                {
                    // Append to the file vs. writing out all at once because I was running out of memory otherwise.
                    mesh = new Shapeways();
                    int div;
                    H3Models.Ball.LODThin( edge.Start, edge.End, out div );
                    mesh.Div = div;
                    H3.Util.AddToMeshInternal( mesh, edge.Start, edge.End );
                    mesh.Mesh.Scale( settings.Scale );
                    STL.AppendMeshToSTL( mesh.Mesh, outputFileName );
                }
            }
            else
            {
                outputFileName += ".pov";
                PovRay.WriteH3Edges( new PovRay.Parameters()
                    {
                        AngularThickness = settings.AngularThickness,
                        Halfspace = settings.Halfspace,
                        ThinEdges = settings.ThinEdges,
                    },
                    edges.ToArray(), outputFileName );
            }
        }
Beispiel #15
0
        private static void HopfFibration( Tiling tiling )
        {
            int segDivisions = 10;
            Shapeways mesh = new Shapeways();

            HashSet<Vector3D> done = new HashSet<Vector3D>();
            foreach( Tile tile in tiling.Tiles )
            foreach( Segment seg in tile.Boundary.Segments )
            {
                if( done.Contains( seg.Midpoint ) )
                    continue;

                // Subdivide the segment, and project points to S2.
                Vector3D[] points = seg.Subdivide( segDivisions ).Select( v => Spherical2D.PlaneToSphere( v ) ).ToArray();
                foreach( Vector3D point in points )
                {
                    Vector3D[] circlePoints = OneHopfCircle( point );
                    ProjectAndAddS3Points( mesh, circlePoints, shrink: false );
                }

                done.Add( seg.Midpoint );
            }

            STL.SaveMeshToSTL( mesh.Mesh, @"D:\p4\R3\sample\out1.stl" );
        }
Beispiel #16
0
        public static void Generate(EHoneycomb honeycomb, H3.Settings settings)
        {
            // XXX - Block the same as in H3.  Share code better.
            H3.Cell template = null;
            {
                int p, q, r;
                Honeycomb.PQR(honeycomb, out p, out q, out r);

                // Get data we need to generate the honeycomb.
                Polytope.Projection projection = Polytope.Projection.FaceCentered;
                double phi, chi, psi;
                H3.HoneycombData(honeycomb, out phi, out chi, out psi);

                H3.SetupCentering(honeycomb, settings, phi, chi, psi, ref projection);

                Tiling       tiling = new Tiling();
                TilingConfig config = new TilingConfig(p, q);
                tiling.GenerateInternal(config, projection);

                H3.Cell first = new H3.Cell(p, H3.GenFacets(tiling));
                first.ToSphere();                       // Work in ball model.
                first.ScaleToCircumSphere(1.0);
                first.ApplyMobius(settings.Mobius);

                template = first;
            }

            // Center
            Vector3D center = template.Center;

            // Face
            H3.Cell.Facet facet = template.Facets[0];
            Sphere        s     = H3Models.Ball.OrthogonalSphereInterior(facet.Verts[0], facet.Verts[1], facet.Verts[2]);
            Vector3D      face  = s.Center;

            face.Normalize();
            face *= DistOriginToOrthogonalSphere(s.Radius);

            // Edge
            Circle3D c;

            H3Models.Ball.OrthogonalCircleInterior(facet.Verts[0], facet.Verts[1], out c);
            Vector3D edge = c.Center;

            edge.Normalize();
            edge *= DistOriginToOrthogonalSphere(c.Radius);

            // Vertex
            Vector3D vertex = facet.Verts[0];

            Tet fundamental = new Tet(center, face, edge, vertex);

            // Recurse.
            int level = 1;
            Dictionary <Tet, int> completedTets = new Dictionary <Tet, int>(new TetEqualityComparer());

            completedTets.Add(fundamental, level);
            List <Tet> tets = new List <Tet>();

            tets.Add(fundamental);
            ReflectRecursive(level, tets, completedTets, settings);

            Shapeways mesh = new Shapeways();

            foreach (KeyValuePair <Tet, int> kvp in completedTets)
            {
                if (Utils.Odd(kvp.Value))
                {
                    continue;
                }

                Tet tet = kvp.Key;

                // XXX - really want sphere surfaces here.
                mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[1], tet.Verts[2]));
                mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[3], tet.Verts[1]));
                mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[0], tet.Verts[2], tet.Verts[3]));
                mesh.Mesh.Triangles.Add(new Mesh.Triangle(tet.Verts[1], tet.Verts[3], tet.Verts[2]));
            }

            mesh.Mesh.Scale(settings.Scale);
            STL.SaveMeshToSTL(mesh.Mesh, H3.m_baseDir + "fundamental" + ".stl");
        }
Beispiel #17
0
        /// <summary>
        /// Add an ideal banana to our mesh.  Passed in edge should be in Ball model.
        /// </summary>
        public static void AddIdealBanana( Shapeways mesh, Vector3D e1, Vector3D e2, H3.Settings settings )
        {
            Vector3D z1 = H3Models.BallToUHS( e1 );
            Vector3D z2 = H3Models.BallToUHS( e2 );

            // Mobius taking z1,z2 to origin,inf
            Complex dummy = new Complex( Math.E, Math.PI );
            Mobius m = new Mobius( z1, dummy, z2 );

            // Make our truncated cone.  We need to deal with the two ideal endpoints specially.
            List<Vector3D> points = new List<Vector3D>();
            double logHeight = 2;	// XXX - magic number, and going to cause problems for infinity checks if too big.
            int div1, div2;
            H3Models.Ball.LOD_Ideal( e1, e2, out div1, out div2, settings );
            double increment = logHeight / div1;
            for( int i=-div1; i<=div1; i+=2 )
                points.Add( new Vector3D( 0, 0, Math.Exp( increment * i ) ) );

            Shapeways tempMesh = new Shapeways();
            tempMesh.Div = div2;
            System.Func<Vector3D, double> sizeFunc = v => H3Models.UHS.SizeFunc( v, settings.AngularThickness );
            //Mesh.OpenCylinder...  pass in two ideal endpoints?
            tempMesh.AddCurve( points.ToArray(), sizeFunc, new Vector3D(), Infinity.InfinityVector );

            // Unwind the transforms.
            TakePointsBack( tempMesh.Mesh, m.Inverse(), settings );
            mesh.Mesh.Triangles.AddRange( tempMesh.Mesh.Triangles );
        }
Beispiel #18
0
        /// <summary>
        /// A helper for adding a sphere.  center should be passed in the ball model.
        /// The approach is similar to how we do the bananas below.
        /// </summary>
        public static void AddSphere( Shapeways mesh, Vector3D center, H3.Settings settings )
        {
            Vector3D centerUHS = H3Models.BallToUHS( center );

            // Find the Mobius we need.
            // We'll do this in two steps.
            // (1) Find a mobius taking center to (0,0,h).
            // (2) Deal with scaling to a height of 1.
            Vector3D flattened = centerUHS;
            flattened.Z = 0;
            Mobius m1 = new Mobius( flattened, Complex.One, Infinity.InfinityVector );
            Vector3D centerUHS_transformed = m1.ApplyToQuaternion( centerUHS );
            double scale = 1.0 / centerUHS_transformed.Z;
            Mobius m2 = new Mobius( scale, Complex.Zero, Complex.Zero, Complex.One );
            Mobius m = m2 * m1;	// Compose them (multiply in reverse order).

            // Add the sphere at the Ball origin.
            // It will *always* be generated with the same radius.
            Shapeways tempMesh = new Shapeways();
            tempMesh.AddSphere( new Vector3D(), H3Models.Ball.SizeFunc( new Vector3D(), settings.AngularThickness ) );

            // Unwind the transforms.
            for( int i=0; i<tempMesh.Mesh.Triangles.Count; i++ )
            {
                tempMesh.Mesh.Triangles[i] = new Mesh.Triangle(
                    H3Models.BallToUHS( tempMesh.Mesh.Triangles[i].a ),
                    H3Models.BallToUHS( tempMesh.Mesh.Triangles[i].b ),
                    H3Models.BallToUHS( tempMesh.Mesh.Triangles[i].c ) );
            }

            Banana.TakePointsBack( tempMesh.Mesh, m.Inverse(), settings );
            mesh.Mesh.Triangles.AddRange( tempMesh.Mesh.Triangles );
        }