private void TestTopologyAssumptions() { using (var refinement = new Refinement(controlTopology, 2)) { var level1Topology = refinement.GetTopology(1); var level2Topology = refinement.GetTopology(2); AssertTopologyAssumptions(controlTopology, level1Topology); AssertTopologyAssumptions(level1Topology, level2Topology); } }
public void DumpShared() { var texturedFacesFile = uvSetsDirectory.File("textured-faces.array"); var textureToSpatialIdxMapFile = uvSetsDirectory.File("textured-to-spatial-idx-map.array"); if (texturedFacesFile.Exists && textureToSpatialIdxMapFile.Exists) { return; } int subdivisionLevel = surfaceProperties.SubdivisionLevel; var geometry = figure.Geometry; var spatialControlTopology = new QuadTopology(geometry.VertexCount, geometry.Faces); QuadTopology spatialTopology; using (var refinement = new Refinement(spatialControlTopology, subdivisionLevel)) { spatialTopology = refinement.GetTopology(); } var uvSet = figure.DefaultUvSet; var texturedControlTopology = new QuadTopology(uvSet.Uvs.Length, uvSet.Faces); QuadTopology texturedTopology; using (var refinement = new Refinement(texturedControlTopology, surfaceProperties.SubdivisionLevel, BoundaryInterpolation.EdgeAndCorner)) { texturedTopology = refinement.GetTopology(); } int[] texturedToSpatialIndexMap = QuadTopology.CalculateVertexIndexMap(texturedTopology, spatialTopology.Faces); uvSetsDirectory.CreateWithParents(); texturedFacesFile.WriteArray(texturedTopology.Faces); textureToSpatialIdxMapFile.WriteArray(texturedToSpatialIndexMap); }
public void Run() { int controlVertexCount = 6; Quad[] controlFaces = new [] { new Quad(0, 1, 2, 3), new Quad(1, 4, 5, 2) }; QuadTopology controlTopology = new QuadTopology(controlVertexCount, controlFaces); int refinementLevel = 1; using (Refinement refinement = new Refinement(controlTopology, refinementLevel)) { QuadTopology topology = refinement.GetTopology(); int[] faceMap = refinement.GetFaceMap(); for (int faceIdx = 0; faceIdx < topology.Faces.Length; ++faceIdx) { Console.WriteLine(topology.Faces[faceIdx] + " -> " + faceMap[faceIdx]); } Console.WriteLine(); PackedLists <WeightedIndex> stencils = refinement.GetStencils(StencilKind.LimitStencils); Console.WriteLine("stencils: "); for (int vertexIdx = 0; vertexIdx < stencils.Count; ++vertexIdx) { Console.WriteLine(vertexIdx + ":"); foreach (WeightedIndex weightedIndex in stencils.GetElements(vertexIdx)) { Console.WriteLine("\t" + weightedIndex.Index + " -> " + weightedIndex.Weight); } } } }
private static (QuadTopology, Vector3[]) ApplyHdMorph(HdMorph hdMorph, QuadTopology controlTopology, Vector3[] controlPositions, Refinement refinement) { var applier = HdMorphApplier.Make(controlTopology, controlPositions); var topology = controlTopology; var positions = controlPositions; for (int levelIdx = 1; levelIdx <= hdMorph.MaxLevel; ++levelIdx) { topology = refinement.GetTopology(levelIdx); positions = refinement.Refine(levelIdx, positions); applier.Apply(hdMorph, 1, levelIdx, topology, positions); } return(topology, positions); }
public static RefinementResult Make(QuadTopology controlTopology, int[] controlSurfaceMap, int refinementLevel, bool derivativesOnly) { if (controlTopology.Faces.Length == 0 && controlTopology.VertexCount == 0) { return(RefinementResult.Empty); } PackedLists <WeightedIndex> limitStencils, limitDuStencils, limitDvStencils; QuadTopology refinedTopology; SubdivisionTopologyInfo refinedTopologyInfo; int[] controlFaceMap; using (var refinement = new Refinement(controlTopology, refinementLevel)) { limitStencils = refinement.GetStencils(StencilKind.LimitStencils); limitDuStencils = refinement.GetStencils(StencilKind.LimitDuStencils); limitDvStencils = refinement.GetStencils(StencilKind.LimitDvStencils); refinedTopology = refinement.GetTopology(); var adjacentVertices = refinement.GetAdjacentVertices(); var rules = refinement.GetVertexRules(); refinedTopologyInfo = new SubdivisionTopologyInfo(adjacentVertices, rules); controlFaceMap = refinement.GetFaceMap(); } if (derivativesOnly) { if (refinementLevel != 0) { throw new InvalidOperationException("derivatives-only mode can only be used at refinement level 0"); } limitStencils = PackedLists <WeightedIndex> .Pack(Enumerable.Range(0, controlTopology.VertexCount) .Select(vertexIdx => { var selfWeight = new WeightedIndex(vertexIdx, 1); return(new List <WeightedIndex> { selfWeight }); }).ToList()); } PackedLists <WeightedIndexWithDerivatives> stencils = WeightedIndexWithDerivatives.Merge(limitStencils, limitDuStencils, limitDvStencils); var refinedMesh = new SubdivisionMesh(controlTopology.VertexCount, refinedTopology, stencils); return(new RefinementResult(refinedMesh, refinedTopologyInfo, controlFaceMap)); }
public NormalMapRenderer MakeNormalMapRenderer(ChannelInputs ldChannelInputs, ChannelInputs hdChannelInputs, UvSet uvSet) { var ldChannelOutputs = figure.Evaluate(null, ldChannelInputs); var hdChannelOutputs = figure.Evaluate(null, hdChannelInputs); var ldControlPositions = figure.Geometry.VertexPositions.Select(p => p).ToArray(); figure.Morpher.Apply(ldChannelOutputs, ldControlPositions); var hdControlPositions = figure.Geometry.VertexPositions.Select(p => p).ToArray(); figure.Morpher.Apply(hdChannelOutputs, hdControlPositions); var activeHdMorphs = figure.Morpher.LoadActiveHdMorphs(hdChannelOutputs); int maxLevel = activeHdMorphs.Max(morph => morph.Morph.MaxLevel) + ExtraRefinementLevels; var controlTopology = new QuadTopology(figure.Geometry.VertexCount, figure.Geometry.Faces); var applier = HdMorphApplier.Make(controlTopology, hdControlPositions); var controlUvTopology = new QuadTopology(uvSet.Uvs.Length, uvSet.Faces); var controlUvs = uvSet.Uvs; var refinement = new Refinement(controlTopology, maxLevel); var uvRefinement = new Refinement(controlUvTopology, maxLevel, BoundaryInterpolation.EdgeAndCorner); var topology = controlTopology; var ldPositions = ldControlPositions; var hdPositions = hdControlPositions; var uvTopology = controlUvTopology; var uvs = controlUvs; var texturedLdPositions = ExtractTexturedPositions(topology, uvTopology, ldPositions); for (int levelIdx = 1; levelIdx <= maxLevel; ++levelIdx) { topology = refinement.GetTopology(levelIdx); ldPositions = refinement.Refine(levelIdx, ldPositions); hdPositions = refinement.Refine(levelIdx, hdPositions); foreach (var activeHdMorph in activeHdMorphs) { applier.Apply(activeHdMorph.Morph, activeHdMorph.Weight, levelIdx, topology, hdPositions); } uvTopology = uvRefinement.GetTopology(levelIdx); uvs = uvRefinement.Refine(levelIdx, uvs); texturedLdPositions = uvRefinement.Refine(levelIdx, texturedLdPositions); } var ldLimit = refinement.Limit(ldPositions); var hdLimit = refinement.Limit(hdPositions); var uvLimit = uvRefinement.Limit(uvs); var texturedLdLimit = uvRefinement.Limit(texturedLdPositions); int[] faceMap = refinement.GetFaceMap(); refinement.Dispose(); uvRefinement.Dispose(); var hdNormals = CalculateNormals(hdLimit); var ldNormals = CalculateNormals(ldLimit); var ldTangents = CalculateTangents(uvLimit, texturedLdLimit); int[] controlSurfaceMap = figure.Geometry.SurfaceMap; int[] surfaceMap = faceMap .Select(controlFaceIdx => controlSurfaceMap[controlFaceIdx]) .ToArray(); var renderer = new NormalMapRenderer(device, shaderCache, hdNormals, ldNormals, topology.Faces, uvLimit.values, ldTangents, uvTopology.Faces, surfaceMap); return(renderer); }
public void Dump(string name, UvSet uvSet) { DirectoryInfo uvSetDirectory = uvSetsDirectory.Subdirectory(name); if (uvSetDirectory.Exists) { return; } Console.WriteLine($"Dumping uv-set {name}..."); int subdivisionLevel = surfaceProperties.SubdivisionLevel; var geometry = figure.Geometry; var spatialControlTopology = new QuadTopology(geometry.VertexCount, geometry.Faces); var spatialControlPositions = geometry.VertexPositions; QuadTopology spatialTopology; LimitValues <Vector3> spatialLimitPositions; using (var refinement = new Refinement(spatialControlTopology, subdivisionLevel)) { spatialTopology = refinement.GetTopology(); spatialLimitPositions = refinement.LimitFully(spatialControlPositions); } uvSet = RemapToDefault(uvSet); var texturedControlTopology = new QuadTopology(uvSet.Uvs.Length, uvSet.Faces); Vector2[] controlTextureCoords = uvSet.Uvs; int[] controlSpatialIdxMap = QuadTopology.CalculateVertexIndexMap(texturedControlTopology, spatialControlTopology.Faces); Vector3[] texturedControlPositions = controlSpatialIdxMap .Select(spatialIdx => spatialControlPositions[spatialIdx]) .ToArray(); QuadTopology texturedTopology; LimitValues <Vector3> texturedLimitPositions; LimitValues <Vector2> limitTextureCoords; using (var refinement = new Refinement(texturedControlTopology, surfaceProperties.SubdivisionLevel, BoundaryInterpolation.EdgeAndCorner)) { texturedTopology = refinement.GetTopology(); texturedLimitPositions = refinement.LimitFully(texturedControlPositions); limitTextureCoords = refinement.LimitFully(controlTextureCoords); } Vector2[] textureCoords; if (geometry.Type == GeometryType.SubdivisionSurface) { textureCoords = limitTextureCoords.values; } else { if (subdivisionLevel != 0) { throw new InvalidOperationException("polygon meshes cannot be subdivided"); } Debug.Assert(limitTextureCoords.values.Length == controlTextureCoords.Length); textureCoords = controlTextureCoords; } int[] spatialIdxMap = QuadTopology.CalculateVertexIndexMap(texturedTopology, spatialTopology.Faces); TexturedVertexInfo[] texturedVertexInfos = Enumerable.Range(0, textureCoords.Length) .Select(idx => { int spatialVertexIdx = spatialIdxMap[idx]; Vector2 textureCoord = textureCoords[idx]; Vector3 positionDu = TangentSpaceUtilities.CalculatePositionDu( limitTextureCoords.tangents1[idx], limitTextureCoords.tangents2[idx], texturedLimitPositions.tangents1[idx], texturedLimitPositions.tangents2[idx]); Vector3 spatialPositionTan1 = spatialLimitPositions.tangents1[spatialVertexIdx]; Vector3 spatialPositionTan2 = spatialLimitPositions.tangents2[spatialVertexIdx]; Vector2 tangentUCoeffs = TangentSpaceUtilities.CalculateTangentSpaceRemappingCoeffs(spatialPositionTan1, spatialPositionTan2, positionDu); DebugUtilities.AssertFinite(tangentUCoeffs.X); DebugUtilities.AssertFinite(tangentUCoeffs.Y); return(new TexturedVertexInfo( textureCoord, tangentUCoeffs)); }) .ToArray(); uvSetDirectory.CreateWithParents(); uvSetDirectory.File("textured-vertex-infos.array").WriteArray(texturedVertexInfos); }