Example #1
0
    private static Vector3[] RefineVertexPositions(Geometry geometry, RefinementResult refinementResult)
    {
        var stencils = refinementResult.Mesh.Stencils.Map(stencil => new WeightedIndex(stencil.Index, stencil.Weight));

        Vector3[] refinedVertexPositions = new Subdivider(stencils).Refine(geometry.VertexPositions, new Vector3Operators());
        return(refinedVertexPositions);
    }
Example #2
0
    public static AutomorpherRecipe Make(Geometry parentGeometry, Geometry childGeometry)
    {
        var parentLimit0Stencils        = parentGeometry.MakeStencils(StencilKind.LimitStencils, 0);
        var subdivider                  = new Subdivider(parentLimit0Stencils);
        var parentLimit0VertexPositions = subdivider.Refine(parentGeometry.VertexPositions, new Vector3Operators());

        List <(List <WeightedIndex>, Vector3)> resultPairs =
            Enumerable.Range(0, childGeometry.VertexCount)
            .AsParallel().AsOrdered()
            .Select(childVertexIdx => {
            Vector3 graftVertex = childGeometry.VertexPositions[childVertexIdx];
            ClosestPoint.PointOnMesh closestPointOnBaseMesh = ClosestPoint.FindClosestPointOnMesh(parentGeometry.Faces, parentLimit0VertexPositions, graftVertex);

            var merger = new WeightedIndexMerger();
            merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxA), closestPointOnBaseMesh.BarycentricWeights.X);
            merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxB), closestPointOnBaseMesh.BarycentricWeights.Y);
            merger.Merge(parentLimit0Stencils.GetElements(closestPointOnBaseMesh.VertexIdxC), closestPointOnBaseMesh.BarycentricWeights.Z);

            var cloestPointAsVector = closestPointOnBaseMesh.AsPosition(parentLimit0VertexPositions);

            return(merger.GetResult(), cloestPointAsVector);
        })
            .ToList();
        List <List <WeightedIndex> > baseDeltaWeights = resultPairs.Select(t => t.Item1).ToList();

        Vector3[] parentSurfacePositions = resultPairs.Select(t => t.Item2).ToArray();

        var packedBaseDeltaWeights = PackedLists <WeightedIndex> .Pack(baseDeltaWeights);

        return(new AutomorpherRecipe(packedBaseDeltaWeights, parentSurfacePositions));
    }
Example #3
0
    public void Dump(string name, UvSet uvSet)
    {
        DirectoryInfo uvSetDirectory = uvSetsDirectory.Subdirectory(name);

        if (uvSetDirectory.Exists)
        {
            return;
        }

        Console.WriteLine($"Dumping uv-set {name}...");

        MultisurfaceQuadTopology spatialTopology         = figure.Geometry.AsTopology();
        MultisurfaceQuadTopology texturedControlTopology = ExtractTexturedTopology(spatialTopology, uvSet);
        var texturedRefinementResult = texturedControlTopology.Refine(surfaceProperties.SubdivisionLevel);
        var texturedTopology         = texturedRefinementResult.Mesh.Topology;
        var texturedTopologyInfo     = texturedRefinementResult.TopologyInfo;
        var derivStencils            = texturedRefinementResult.Mesh.Stencils;

        var stencils   = derivStencils.Map(stencil => new WeightedIndex(stencil.Index, stencil.Weight));
        var duStencils = derivStencils.Map(stencil => new WeightedIndex(stencil.Index, stencil.DuWeight));
        var dvStencils = derivStencils.Map(stencil => new WeightedIndex(stencil.Index, stencil.DvWeight));

        Vector2[] controlTextureCoords = uvSet.Uvs;
        Vector2[] textureCoords        = new Subdivider(stencils).Refine(controlTextureCoords, new Vector2Operators());
        Vector2[] textureCoordDus      = new Subdivider(duStencils).Refine(controlTextureCoords, new Vector2Operators());
        Vector2[] textureCoordDvs      = new Subdivider(dvStencils).Refine(controlTextureCoords, new Vector2Operators());

        int[] spatialIdxMap = CalculateTextureToSpatialIndexMap(texturedTopology, spatialFaces);

        TexturedVertexInfo[] texturedVertexInfos = Enumerable.Range(0, textureCoords.Length)
                                                   .Select(idx => {
            int spatialVertexIdx = spatialIdxMap[idx];
            Vector2 textureCoord = textureCoords[idx];
            Vector2 du           = textureCoordDus[idx];
            Vector2 dv           = textureCoordDvs[idx];

            List <int> spatialNeighbours = spatialTopologyInfo.AdjacentVertices.GetElements(spatialVertexIdx).ToList();
            var spatialVertexRule        = spatialTopologyInfo.VertexRules[spatialVertexIdx];

            List <int> neighbours = texturedTopologyInfo.AdjacentVertices.GetElements(idx).Select(i => spatialIdxMap[i]).ToList();
            var vertexRule        = texturedTopologyInfo.VertexRules[idx];

            Tuple <Vector2, Vector2> remappedTangents = RemapTangents(spatialNeighbours, spatialVertexRule, neighbours, vertexRule, du, dv);

            return(new TexturedVertexInfo(
                       spatialVertexIdx,
                       textureCoord,
                       remappedTangents.Item1,
                       remappedTangents.Item2));
        })
                                                   .ToArray();

        uvSetDirectory.CreateWithParents();
        uvSetDirectory.File("textured-faces.array").WriteArray(texturedTopology.Faces);
        uvSetDirectory.File("textured-vertex-infos.array").WriteArray(texturedVertexInfos);
    }
Example #4
0
        public IEnumerable <Parcel> CreateParcels(Parcel shape, Func <double> random, INamedDataCollection metadata)
        {
            Contract.Requires(shape != null);
            Contract.Requires(random != null);
            Contract.Requires(metadata != null);
            Contract.Ensures(Contract.Result <IEnumerable <Parcel> >() != null);

            //Generate parcels from shape
            var parcels = Subdivider.GenerateParcels(shape, random, metadata);

            //Adjust parcels
            foreach (var adjustment in _adjustments)
            {
                parcels = adjustment.Adjust(shape, parcels, random);
            }

            return(parcels);
        }
        public static MeshData CreateGeosphere(float radius, SubdivisionCount numSubdivisions)
        {
            var tempMesh = new MeshData();

            tempMesh.Vertices = IcosahedronVertices.Select(p => new Vertex {
                Position = p
            }).ToList();
            tempMesh.Indices = IcosahedronIndices;

            var mh = new Subdivider();

            for (var i = 0; i < (int)numSubdivisions; i++)
            {
                mh.Subdivide4(tempMesh);
            }

            // Project vertices onto sphere and scale.
            for (var i = 0; i < tempMesh.Vertices.Count; i++)
            {
                // Project onto unit sphere.
                var n = Vector3.Normalize(tempMesh.Vertices[i].Position);
                // Project onto sphere.
                var p = radius * n;

                // Derive texture coordinates from spherical coordinates.
                var theta = MathF.AngleFromXY(tempMesh.Vertices[i].Position.X, tempMesh.Vertices[i].Position.Z);
                var phi   = MathF.Acos(tempMesh.Vertices[i].Position.Y / radius);
                var texC  = new Vector2(theta / (2 * MathF.PI), phi / MathF.PI);

                // Partial derivative of P with respect to theta
                var tangent = new Vector3(
                    -radius * MathF.Sin(phi) * MathF.Sin(theta),
                    0,
                    radius * MathF.Sin(phi) * MathF.Cos(theta)
                    );
                tangent.Normalize();

                tempMesh.Vertices[i] = new Vertex(p, n, tangent, texC);
            }
            return(tempMesh);
        }
Example #6
0
        public static MeshData CreateGeosphere(float radius, SubdivisionCount numSubdivisions)
        {
            var tempMesh = new MeshData();

            tempMesh.Vertices = IcosahedronVertices.Select(p => new Vertex { Position = p }).ToList();
            tempMesh.Indices = IcosahedronIndices;

            var mh = new Subdivider();

            for (var i = 0; i < (int)numSubdivisions; i++)
            {
                mh.Subdivide4(tempMesh);
            }

            // Project vertices onto sphere and scale.
            for (var i = 0; i < tempMesh.Vertices.Count; i++)
            {
                // Project onto unit sphere.
                var n = Vector3.Normalize(tempMesh.Vertices[i].Position);
                // Project onto sphere.
                var p = radius * n;

                // Derive texture coordinates from spherical coordinates.
                var theta = MathF.AngleFromXY(tempMesh.Vertices[i].Position.X, tempMesh.Vertices[i].Position.Z);
                var phi = MathF.Acos(tempMesh.Vertices[i].Position.Y / radius);
                var texC = new Vector2(theta / (2 * MathF.PI), phi / MathF.PI);

                // Partial derivative of P with respect to theta
                var tangent = new Vector3(
                    -radius * MathF.Sin(phi) * MathF.Sin(theta),
                    0,
                    radius * MathF.Sin(phi) * MathF.Cos(theta)
                );
                tangent.Normalize();

                tempMesh.Vertices[i] = new Vertex(p, n, tangent, texC);
            }
            return tempMesh;
        }
Example #7
0
 public HdCorrectionMorphSynthesizer(string figureName, Geometry geometry)
 {
     this.figureName  = figureName;
     this.geometry    = geometry;
     limit0Subdivider = new Subdivider(geometry.MakeStencils(StencilKind.LimitStencils, 0));
 }
        private static ContourVertex[] CreateContourFromFigure([CanBeNull] Matrix3x2?transform, float flatteningTolerance, Figure figure)
        {
            if (figure.FigureEnd == FigureEnd.Open)
            {
                throw new InvalidOperationException("Cannot create a contour, which may be filled, from an open figure.");
            }

            var vertices = new List <ContourVertex>();

            var origin    = figure.Origin;
            var lastPoint = origin;

            AddPoint(transform, origin, vertices);

            foreach (var element in figure.Elements)
            {
                switch (element.Type)
                {
                case GeometryElementType.Line: {
                    AddPoint(transform, element.LineSegment, vertices);
                    lastPoint = element.LineSegment;
                    break;
                }

                case GeometryElementType.Arc: {
                    var arc = element.ArcSegment;
                    // The unit in ArcSegment is degrees, not radians;
                    // positive value means clockwise rotation (https://msdn.microsoft.com/en-us/library/windows/desktop/dd370900.aspx).

                    var divided = Subdivider.DivideSvgArc(lastPoint.X, lastPoint.Y, arc.Point.X, arc.Point.Y,
                                                          arc.Size.X, arc.Size.Y, -MathHelper.ToRadians(arc.RotationAngle),
                                                          arc.ArcSize == ArcSize.Large, arc.SweepDirection == SweepDirection.Clockwise,
                                                          flatteningTolerance);

                    AddPoints(transform, divided, vertices);
                    lastPoint = arc.Point;
                    break;
                }

                case GeometryElementType.Bezier: {
                    var bezier  = element.BezierSegment;
                    var divided = Subdivider.DivideBezier(lastPoint.X, lastPoint.Y, bezier.Point1.X, bezier.Point1.Y,
                                                          bezier.Point2.X, bezier.Point2.Y, bezier.Point3.X, bezier.Point3.Y, flatteningTolerance);

                    AddPoints(transform, divided, vertices);
                    lastPoint = bezier.Point3;
                    break;
                }

                case GeometryElementType.QuadraticBezier: {
                    var bezier  = element.QuadraticBezierSegment;
                    var divided = Subdivider.DivideQuadraticBezier(lastPoint.X, lastPoint.Y,
                                                                   bezier.Point1.X, bezier.Point1.Y, bezier.Point2.X, bezier.Point2.Y, flatteningTolerance);

                    AddPoints(transform, divided, vertices);
                    lastPoint = bezier.Point2;
                    break;
                }

                case GeometryElementType.MathArc: {
                    var mathArc = element.MathArcSegment;
                    var divided = Subdivider.DivideArc(mathArc.Center.X, mathArc.Center.Y, mathArc.Radius.X, mathArc.Radius.Y,
                                                       MathHelper.ToRadians(mathArc.StartAngle), MathHelper.ToRadians(mathArc.SweepAngle), MathHelper.ToRadians(mathArc.RotationAngle),
                                                       flatteningTolerance);

                    AddPoints(transform, divided, vertices);
                    // Not setting lastPoint because we don't need it. See notes of MathArcSegment.
                    break;
                }

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            AddPoint(transform, origin, vertices);

            return(vertices.ToArray());
        }