/// <summary>
        /// Recursively traverses supplied subPatchMap dictionary and build up a PatchTree.
        /// </summary>
        /// <param name="subPatchMap">form of [patchName, List[subPatchName]]</param>
        private static PatchTree PatchTreeFromPatchName(string patchName, string patchesSubdir, Dictionary <string, IEnumerable <string> > subPatchMap)
        {
            IEnumerable <string> subPatches = null;
            var path = Path.Combine(patchesSubdir, patchName);

            //read patchfileinfo
            var info = new PatchFileInfo();

            try
            {
                info         = PatchFileInfo.FromFile(path);
                info.IsValid = true;
            }
            catch (Exception e)
            {
                Report.Warn("PatchHierarchyXML: Parsing of patch.xml of path {0} threw an exception {1}", path, e.Message.ToString());
                info.IsValid = false;
            }

            //if name does not exist in subPatchMap a leaf is reached
            if (!subPatchMap.TryGetValue(patchName, out subPatches))
            {
                return(new PatchTree(patchName, info));
            }

            //if subnodes exist recurse
            return(new PatchTree(patchName, info,
                                 subPatches.Select(x => PatchTreeFromPatchName(x, patchesSubdir, subPatchMap))
                                 .Where(x => x.Info.IsValid)
                                 .ToList()));
        }
        /// <summary>
        /// Takes first OPC in opcDirectory and returns its root patch info. This
        /// is typically needed to retrieve rendering offsets to prevent rounding errors.
        /// </summary>
        public static PatchFileInfo GetFirstPatchFileInfo(string opcDirectory, PositionsType posType)
        {
            var paths         = OpcFileUtils.OpcPathsFromFolder(opcDirectory);
            var rootPatchPath = OpcFileUtils.GetRootPatchPath(paths.First());

            return(PatchFileInfo.FromFile(rootPatchPath));
        }
        /// <summary>
        /// Loads VertexGeometry from aara files. Beware: add Local2Global node for global space.
        /// </summary>
        /// <returns>Vertex Geometry in local OPC space.</returns>
        public static VertexGeometry LoadPatch(PatchFileInfo info, string basePath, PositionsType posType,
                                               bool loadNormals = true, bool loadTexCoords = true, bool loadDiffTex = true, bool loadHueTex = true, float maxTriangleSize = float.PositiveInfinity, bool loadAsDoubles = false)
        {
            Array  positions;
            Symbol dataType;

            return(LoadPatch(info, basePath, posType, out positions, out dataType,
                             loadNormals, loadTexCoords, loadDiffTex, loadHueTex, maxTriangleSize, loadAsDoubles));
        }
        public VertexGeometry Load(PatchFileInfo info, string basePath, PositionsType posType,
                                   bool loadTextures = true, bool loadNormals = true, bool loadTexCoords = true, float maxTriangleSize = float.PositiveInfinity)
        {
            //Array positions;
            //Symbol dataType;
            bool loadDiffTex = loadTextures ? LoadDiffTex : false;
            bool loadHueTex  = loadTextures ? LoadHueTex : false;

            return(LoadPatch(info, basePath, posType, //out positions, out dataType,
                             loadNormals, loadTexCoords, loadDiffTex, loadHueTex, maxTriangleSize));
        }
Example #5
0
        public PatchTree(string id, PatchFileInfo info, List <PatchTree> subNodes = null)
        {
            if (subNodes == null)
            {
                subNodes = new List <PatchTree>();
            }

            m_id       = id;
            m_subNodes = subNodes;
            m_info     = info;
        }
        /// <summary>
        /// Reads full patch.xml into and returns a PatchFileInfo
        /// </summary>
        public static PatchFileInfo FromFile(string patchFilePath)
        {
            if (Path.GetFileName(patchFilePath) != "patch.xml")
            {
                patchFilePath = Path.Combine(patchFilePath, "patch.xml");
            }

            //var patch = XElement.Load(patchFilePath, LoadOptions.None).Element("Patch");
            var patch = XElement.Load(Load.AsMemoryStream(patchFilePath)).Element("Patch");

            var info = new PatchFileInfo()
            {
                TagList             = ReadStringList(patch, "TagList"),
                GeometryType        = ReadString(patch, "GeometryType"),
                QuadVertexSortOrder = ReadString(patch, "QuadVertexSortOrder", PatchFileInfo.QuadVertexSortOrderType.ColumnMajor),

                Local2Global      = ReadM44d(patch, "Local2Global"),
                GlobalBoundingBox = ReadBox3d(patch, "GlobalBoundingBox"),
                LocalBoundingBox  = ReadBox3d(patch, "LocalBoundingBox"),

                Positions = ReadString(patch, "Positions"),

                Coordinates = ReadStringList(patch, "Coordinates"),
                Textures    = ReadStringList(patch, "Textures"),
            };

            if (HasNormalsAndOffsets(patch))
            {
                info.Normals = ReadString(patch, "Normals");
                info.Offsets = ReadString(patch, "Offsets");
            }

            //var x = patch.Element("Local2Global2D");
            //Report.Line(x.ToString());
            //   //e.Element("GlobalBoundingBox2d") != null &&
            //   //e.Element("LocalBoundingBox2d") != null &&
            //   //e.Element("Positions2d") != null;

            if (XmlHas2dData(patch))
            {
                info.Local2Global2d      = ReadM44d(patch, "Local2Global2D");
                info.GlobalBoundingBox2d = ReadBox3d(patch, "GlobalBoundingBox2D");
                info.LocalBoundingBox2d  = ReadBox3d(patch, "LocalBoundingBox2D");
                info.Positions2d         = ReadString(patch, "Positions2D");
            }

            if (!info.LocalBoundingBox2d.IsValid)
            {
                Report.Warn("LocalBoundingBox2d is not valid");
            }

            return(info);
        }
Example #7
0
        //static volatile int patchCounter = 0;

        /// <summary>
        /// Represents a single patch of ordered positions including coords, textures, etc.
        /// </summary>
        public Patch(PatchFileInfo info, string patchPath, int level, int maxLevel, PositionsType posType, bool invertZ = false, float maxTriangleSize = float.PositiveInfinity)
            : base(Identifier)
        {
            PatchFilePath   = patchPath;
            Level           = level;
            PatchFileInfo   = info;
            MaxLevel        = maxLevel;
            PositionsType   = posType;
            InvertZ         = invertZ;
            MaxTriangleSize = maxTriangleSize;
            //patchCounter++;
            //Report.Line("++" + patchCounter);
        }
        /// <summary>
        /// Gets Triangle Set loaded from AaraData and transformed to global space.
        /// </summary>
        public static TriangleSet LoadPatchTriangleSet(PatchFileInfo info, string basePath, PositionsType posType)
        {
            var vg = LoadPatch(info, basePath, posType, false, false, false, false, loadAsDoubles: false);

            if (vg == null)
            {
                return(new TriangleSet());
            }

            var trafo = posType == PositionsType.V3dPositions ? info.Local2Global : info.Local2Global2d;

            vg.TransformV3d(trafo);

            var triangles = vg.Triangles
                            .Where(x => !x.Point0.Position.IsNaN &&
                                   !x.Point1.Position.IsNaN &&
                                   !x.Point2.Position.IsNaN)
                            .Select(x => x.ToTriangle3d());

            return(new TriangleSet(triangles));
        }
        /// <summary>
        /// Gets Triangle Set loaded from AaraData and transformed to global space.
        /// Triangles side length < maxTriiangleSize
        /// </summary>
        public static TriangleSet LoadPatchTriangleSetWithoutOversizedTriangles(PatchFileInfo info, string basePath, PositionsType posType, float maxTriangleSize = float.PositiveInfinity)
        {
            var vg = LoadPatch(info, basePath, posType, false, false, false, false);

            if (vg == null)
            {
                return(new TriangleSet());
            }

            vg.Transform(
                posType == PositionsType.V3dPositions ?
                info.Local2Global : info.Local2Global2d);

            var triangles = vg.Triangles
                            .Where(x => !x.Point0.Position.IsNaN &&
                                   !x.Point1.Position.IsNaN &&
                                   !x.Point2.Position.IsNaN &&
                                   (V3d.Distance(x.Point0.Position, x.Point1.Position) < maxTriangleSize) &&
                                   (V3d.Distance(x.Point0.Position, x.Point2.Position) < maxTriangleSize) &&
                                   (V3d.Distance(x.Point1.Position, x.Point2.Position) < maxTriangleSize))
                            .Select(x => x.ToTriangle3d());

            return(new TriangleSet(triangles));
        }
Example #10
0
        //~Patch()
        //{
        //    patchCounter--;
        //    Report.Line("--" + patchCounter);
        //}

        public static Patch FromFile(string patchXmlPath, int level, int maxLevel, PositionsType posType)
        {
            return(new Patch(PatchFileInfo.FromFile(patchXmlPath), patchXmlPath, level, maxLevel, posType));
        }
        /// <summary>
        /// Loads VertexGeometry from aara files. Beware: add Local2Global node for global space.
        /// </summary>
        /// <param name="positions">Raw positions, read from aara files for possible further processing.</param>
        /// <param name="dataType">DataType of positions.</param>
        /// <returns>Vertex Geometry in local OPC space.</returns>
        public static VertexGeometry LoadPatch(PatchFileInfo info, string basePath, PositionsType posType, out Array positions, out Symbol dataType,
                                               bool loadNormals = true, bool loadTexCoords = true, bool loadDiffTex = true, bool loadHueTex = true, float maxTriangleSize = float.PositiveInfinity, bool loadAsDoubles = false)
        {
            var vg = new VertexGeometry(GeometryMode.TriangleList);

            positions = null;

            // load metadata
            var aara3dPos = AaraData.FromFile(
                Path.Combine(basePath, posType == PositionsType.V3dPositions
                ? info.Positions : info.Positions2d));

            dataType = aara3dPos.DataTypeAsSymbol;

            var resolution = new V2i(aara3dPos.Size);

            if (resolution.AnySmaller(2))
            {
                Report.Warn("ignoring patch {0} due to invalid gridresolution {1}", basePath, resolution);
                return(null);
            }

            // load positions
            positions = aara3dPos.LoadElements();
            var positions3d = loadAsDoubles ? positions : AaraData.ConvertArrayToV3fs[aara3dPos.DataTypeAsSymbol](positions);

            //var positionsV3 = loadAsDoubles ?
            //    (Array)AaraData.ConvertArrayToV3ds[aara3dPos.DataTypeAsSymbol](positions) :
            //    (Array);

            vg.Positions = positions3d;

            var p = AaraData.ConvertArrayToV3fs[aara3dPos.DataTypeAsSymbol](positions);

            // calculate indices
            var invalidPoints = OpcIndices.GetInvalidPositions(p);

            // limit triangle size
            if ((maxTriangleSize < float.PositiveInfinity) && (maxTriangleSize > 0.000001f))
            {
                vg.Indices = OpcIndices.ComputeIndexArray(resolution, invalidPoints.ToList(), p, maxTriangleSize);
            }
            else
            {
                vg.Indices = OpcIndices.ComputeIndexArray(resolution, invalidPoints.ToList());
            }

            // load normals
            if (loadNormals)
            {
                var normalPath = Path.Combine(basePath, "Normals.aara");
                if (StorageConfig.FileExists(normalPath))
                {
                    var normals   = AaraData.FromFile(normalPath);
                    var normals3d = AaraData.ConvertArrayToV3fs[normals.DataTypeAsSymbol](normals.LoadElements());
                    vg.Normals = normals3d;
                }
            }

            // load coordinates
            vg.Coordinates = new CoordinatesMap();
            if (loadTexCoords)
            {
                var coordPath   = Path.Combine(basePath, info.Coordinates.First());
                var coordinates = AaraData.FromFile(coordPath).LoadElements() as V2f[];
                vg.Coordinates[VertexGeometry.Property.DiffuseColorCoordinates] = coordinates;
            }

            // load textures
            vg.Textures = new TexturesMap();
            if (loadDiffTex)
            {
                var texFile = Path.ChangeExtension(info.Textures.First(), ".dds");
                var texPath = Path.GetFullPath(Path.Combine(basePath, @"..\..\images", texFile));

                if (StorageConfig.FileExists(texPath))
                {
                    var img = Convertible.FromFile(texPath);

                    vg.Textures[VertexGeometry.Property.DiffuseColorTexture] =
                        new Aardvark.Rendering.Texture(img)
                    {
                        ForceImmediateUpload = false
                    };
                }
            }
            if (loadHueTex)
            {
                vg.Textures[VertexGeometry.Property.LightMapTexture] =
                    new Aardvark.Rendering.Texture(Resources.HueColorMap.Convertible());
            }

            return(vg);
        }