示例#1
0
        public void SaveObject(int navId, string key, ObjFormat format, string data)
        {
            using (var db = new AdminDbContext())
            {
                var obj = db.Objs.FirstOrDefault(o => o.NavId == navId && o.Key.ToLower() == key.ToLower());
                if (obj != null)
                {
                    // update
                    obj.Format = format;
                    obj.Data = data;
                }
                else
                {
                    // add
                    db.Objs.Add(new Obj
                    {
                        NavId = navId,
                        Key = key,
                        Format = format,
                        Data = data,
                    });
                }

                db.SaveChanges();
            }
        }
        public void TestParseFace3()
        {
            // given
            var expected = new ObjFormat.Face();
            var obj      = new ObjFormat();

            expected.GeometricVertexReferences.AddRange(new List <int> {
                1, 2, 3, 4
            });
            expected.NormalVertexReferences.AddRange(new List <int> {
                1, 2, 3, 4
            });
            expected.TextureVertexReferences.AddRange(new List <int> {
                1, 2, 3, 4
            });
            var completeLayout = "1/1/1 2/2/2 3/3/3 4/4/4";

            // when
            var result = reader.ParseFace(completeLayout, obj);

            // then
            Assert.True(expected.GeometricVertexReferences.SequenceEqual(result.GeometricVertexReferences));
            Assert.True(expected.NormalVertexReferences.SequenceEqual(result.NormalVertexReferences));
            Assert.True(expected.TextureVertexReferences.SequenceEqual(result.TextureVertexReferences));
        }
        public void TestPerformEarClipping()
        {
            // given
            var vertices = new List <Vector4>()
            {
                new Vector4(-0.5f, -0.5f, 0.5f, 1.0f),
                new Vector4(-0.5f, -0.5f, -0.5f, 1.0f),
                new Vector4(-0.5f, 0.5f, -0.5f, 1.0f),
                new Vector4(-0.5f, 0.5f, 0.5f, 1.0f),

                new Vector4(0.5f, -0.5f, 0.5f, 1.0f),
                new Vector4(0.5f, -0.5f, -0.5f, 1.0f),
                new Vector4(0.5f, 0.5f, -0.5f, 1.0f),
                new Vector4(0.5f, 0.5f, 0.5f, 1.0f),
            };

            var vertexReferences = new List <int>()
            {
                4, 3, 2, 1
            };

            var expected = new List <Mesh.Triangle>()
            {
                new Mesh.Triangle(new []
                {
                    new Vector3(-0.5f, 0.5f, 0.5f),
                    new Vector3(-0.5f, 0.5f, -0.5f),
                    new Vector3(-0.5f, -0.5f, -0.5f)
                },
                                  new Vector3(-1f, 0f, 0f)),
                new Mesh.Triangle(new []
                {
                    new Vector3(-0.5f, 0.5f, 0.5f),
                    new Vector3(-0.5f, -0.5f, -0.5f),
                    new Vector3(-0.5f, -0.5f, 0.5f)
                },
                                  new Vector3(-1f, 0f, 0f))
            };

            // when
            var result = ObjFormat.PerformEarClipping(vertices, vertexReferences);

            // then
            Assert.AreEqual(expected.Count, result.Count);
            for (var i = 0; i < expected.Count; i++)
            {
                var t1 = expected[i];
                var t2 = result[i];
                for (var j = 0; j < 3; j++)
                {
                    TestUtils.AssertVector3sAreEqualWithPrecision(t1.Vertices[j], t2.Vertices[j]);
                    Assert.AreEqual(t1.Norm, t2.Norm);
                }
            }
        }
        public Mesh ReadFromStream(Stream inputStream)
        {
            var obj = new ObjFormat();

            using (var reader = new StreamReader(inputStream))
            {
                while (reader.Peek() > -1)
                {
                    var trimmedLine = reader.ReadLine()?.Trim();
                    if (string.IsNullOrEmpty(trimmedLine))
                    {
                        continue;
                    }

                    var isComment = trimmedLine[0] == '#';
                    if (isComment)
                    {
                        continue;
                    }

                    var wordEnd = trimmedLine.IndexOf(' ');
                    if (wordEnd > -1)
                    {
                        var firstWord    = trimmedLine.Substring(0, wordEnd);
                        var remainderLen = trimmedLine.Length - firstWord.Length;
                        var remainder    = trimmedLine.Substring(wordEnd, remainderLen).Trim();
                        switch (firstWord)
                        {
                        case "v":
                            obj.GeometricVertices.Add(ParseGeometricVertex(remainder));
                            break;

                        case "f":
                            obj.Faces.Add(ParseFace(remainder, obj));
                            break;

                        case "vt":
                            obj.TextureVertices.Add(ParseTextureVertex(remainder));
                            break;

                        case "vn":
                            obj.VertexNormals.Add(ParseVertexNormal(remainder));
                            break;
                        }
                    }
                }
            }
            return(ObjFormat.ToMesh(obj));
        }
        public void TestCalculateTriangleNormal()
        {
            // given
            const float delta    = 0.0001f;
            var         expected = new Vector3(0.4422141f, -0.1679461f, -0.8810453f);
            var         v1       = new Vector3(2.410367f, -0.777999f, -0.841105f);
            var         v2       = new Vector3(2.407309f, -0.97498f, -0.805091f);
            var         v3       = new Vector3(2.292449f, -0.871852f, -0.8824f);

            // when
            var result = ObjFormat.CalculateTriangleNormal(v1, v2, v3);

            // then
            TestUtils.AssertVector3sAreEqualWithPrecision(result, expected, delta);
        }
        public void TestParseFace1()
        {
            // given
            var expected = new ObjFormat.Face();
            var obj      = new ObjFormat();

            expected.GeometricVertexReferences.AddRange(new List <int> {
                3, 4, 25, 26
            });
            var onlyVertexLayout = "3 4 25 26";

            // when
            var result = reader.ParseFace(onlyVertexLayout, obj);

            // then
            Assert.True(expected.GeometricVertexReferences.SequenceEqual(result.GeometricVertexReferences));
        }
        internal ObjFormat.Face ParseFace(string str, ObjFormat obj)
        {
            var faceLayout          = DetermineFaceLayout(str);
            var faceElementsPerLine = str.Split(' ');
            var result = new ObjFormat.Face();

            foreach (var faceElement in faceElementsPerLine)
            {
                if (faceLayout != null && faceLayout.IsMatch(faceElement))
                {
                    if (faceLayout == OnlyVertices)
                    {
                        var vertexRef = ParseFaceElement(faceElement, obj.GeometricVertices.Count);
                        result.GeometricVertexReferences.Add(vertexRef);
                    }
                    else if (faceLayout == Complete)
                    {
                        var elements = faceElement.Split('/');
                        result.GeometricVertexReferences.Add(ParseFaceElement(elements[0], obj.GeometricVertices.Count));
                        result.TextureVertexReferences.Add(ParseFaceElement(elements[1], obj.TextureVertices.Count));
                        result.NormalVertexReferences.Add(ParseFaceElement(elements[2], obj.VertexNormals.Count));
                    }
                    else if (faceLayout == VerticesAndNormals)
                    {
                        var elements = faceElement.Split('/');
                        result.GeometricVertexReferences.Add(ParseFaceElement(elements[0], obj.GeometricVertices.Count));
                        result.NormalVertexReferences.Add(ParseFaceElement(elements[2], obj.VertexNormals.Count));
                    }
                    else if (faceLayout == VerticesAndTexture)
                    {
                        var elements = faceElement.Split('/');
                        result.GeometricVertexReferences.Add(ParseFaceElement(elements[0], obj.GeometricVertices.Count));
                        result.TextureVertexReferences.Add(ParseFaceElement(elements[1], obj.TextureVertices.Count));
                    }
                }
                else
                {
                    throw new FormatException($"Not recognizable .obj face element layout: {faceElement}");
                }
            }

            return(result);
        }
        public void TestParseFace2()
        {
            // given
            var expected = new ObjFormat.Face();
            var obj      = new ObjFormat();

            expected.GeometricVertexReferences.AddRange(new List <int> {
                1, 2, 3, 4
            });
            expected.NormalVertexReferences.AddRange(new List <int> {
                1, 2, 3, 4
            });
            var vertexAndNormalLayout = "1//1 2//2 3//3 4//4";

            // when
            var result = reader.ParseFace(vertexAndNormalLayout, obj);

            // then
            Assert.True(expected.GeometricVertexReferences.SequenceEqual(result.GeometricVertexReferences));
            Assert.True(expected.NormalVertexReferences.SequenceEqual(result.NormalVertexReferences));
        }
示例#9
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="navId"></param>
        /// <param name="key"></param>
        /// <param name="format"></param>
        /// <param name="obj"></param>
        /// <remarks>
        /// SaveObject takes care of serialization, you just pass your object over.
        /// </remarks>
        public static void SaveObject(int navId, string key, ObjFormat format, object obj)
        {
            string str = "";
            if (format == ObjFormat.Xml)
                str = Serializer.ConvertToString(obj);
            else if (format == ObjFormat.Html)
                str = (string)obj;

            Provider.SaveObject(navId, key, format, str);
        }
示例#10
0
        static void MainParallel(string[] args, MapProperties properties , string exportPath)
        {
            int max = 25;
            int current = 0;

            GaPSlabsVersion version = new GaPSlabsVersion("GaPSLabs 3D City Generator 1.0", 1, 0);

            if (!System.IO.Directory.Exists(exportPath))
                System.IO.Directory.CreateDirectory(exportPath);

            Random rand = new Random((int)DateTime.Now.Ticks);
            MapProperties mapboundaries = new MapProperties();
            if (properties != null)
                mapboundaries = properties;
            else
            {
                //mapboundaries.minLat = 59.3457;
                //mapboundaries.maxLat = 59.3527;
                //mapboundaries.minLon = 18.0609;
                //mapboundaries.maxLon = 18.0765;
                //mapboundaries.Name = "KTH Area";
                mapboundaries.minLat = 59.2294;
                mapboundaries.maxLat = 59.4800;
                mapboundaries.minLon = 17.7649;
                mapboundaries.maxLon = 18.2977;
                mapboundaries.Name = "KTH Area";
                mapboundaries.BuildingLineThickness = 0.6f;
                mapboundaries.RoadLineThickness = 0.2f;
                mapboundaries.Scale = new Vector2(16, 16);
                mapboundaries.BuildingColor = new Color(0, 255, 0);
                mapboundaries.LineColorStart = new Color(255, 255, 0);
                mapboundaries.LineColorEnd = new Color(255, 255, 0);
                mapboundaries.BuildingMaterial = null;
                mapboundaries.RoadMaterial = new Material("Route");
                mapboundaries.CycleWayMaterial = new Material("RouteCycleway");
                mapboundaries.FootWayMaterial = new Material("RouteFootway");
                mapboundaries.RailWayMaterial = null;
                mapboundaries.StepsMaterial = new Material("RouteSteps");
                mapboundaries.RoadWidth = 1;// 0.05f;
                mapboundaries.CyclewayWidth = 0.05f;
                mapboundaries.FootwayWidth = 0.05f;
                mapboundaries.BuildingHeight = 7.5f;
                mapboundaries.CombinationOptimizationSize = new Vector2(100, 100);
            }

            bool GenerateBuildingShapes = true;
            bool GenerateRoads = true;
            bool GenerateBuildings = true;
            bool CorrectAspectRatio = false;
            
            OSMPostgresqlSource source = new OSMPostgresqlSource(connPostGreSql);
            var bounds = source.Bounds;

            float[] minmaxX;
            float[] minmaxY;

            minmaxX = new float[] { 0, 5000 };
            minmaxY = new float[] { 0, 5000 };

            Bounds SelectedArea = new Bounds();
            float LineWidth = 0.4f;
            float BuildingWidth = 0.6f;

            float height;
            height = 7.5f;

            SelectedArea.minlat = mapboundaries.minLat;
            SelectedArea.maxlat = mapboundaries.maxLat;
            SelectedArea.minlon = mapboundaries.minLon;
            SelectedArea.maxlon = mapboundaries.maxLon;
            minmaxX = mapboundaries.minMaxX;
            minmaxY = mapboundaries.minMaxY;
            if (CorrectAspectRatio)
            {
                var aspectRatio = System.Math.Abs(SelectedArea.maxlat - SelectedArea.minlat) / System.Math.Abs(SelectedArea.maxlon - SelectedArea.minlon);
                minmaxY[1] = (float)(minmaxX[1] * aspectRatio);
            }

            LineWidth = mapboundaries.RoadLineThickness;
            BuildingWidth = mapboundaries.BuildingLineThickness;
            height = mapboundaries.BuildingHeight;
            if (height < 4)
                height = 4;

            string[] ways = null;
            if (!GenerateRoads)
            {
                string[][] buildingtag = new string[1][];
                buildingtag[0] = new string[] { "building", "" }; // NOTE: building tag in OSM is in lower case.
                ways = source.GetWayIdsWithTags(SelectedArea, buildingtag);
            }
            else
                if (!GenerateBuildings)
                {
                    string[][] roadtag = new string[1][];
                    roadtag[0] = new string[] { "highway", "" }; // NOTE: highway tag in OSM is in lower case.
                    ways = source.GetWayIdsWithTags(SelectedArea, roadtag);
                }
                else
                    ways = source.GetWayIdsInBound(SelectedArea);
            
            float[] MinPointOnArea = CoordinateConvertor.SimpleInterpolation((float)SelectedArea.minlat, (float)SelectedArea.minlon, bounds, minmaxX, minmaxY);

            int direction = -1;
            Vector3 MinPointOnMap = new Vector3(direction * MinPointOnArea[0], 0, MinPointOnArea[1]);
            mapboundaries.MinPointOnMap = MinPointOnMap;

            int totalWays = ways.Length;
            int progress = 0;
            //List<OsmNode> WayNodes;
            //List<Tag> WayTags;
            //Vector3[] tempPoints;
            //PolygonCuttingEar.CPolygonShape shp;
            Console.WriteLine("Started at " + DateTime.Now + " for " + ways.Length + " objects.");
            var duration = Stopwatch.StartNew();
            Parallel.ForEach<string>(ways, (FirstWay, state) =>
            //foreach (var FirstWay in ways)
            {
                var w = new Way(FirstWay);
                List<OsmNode> WayNodes;
                List<Tag> WayTags;
                using (Npgsql.NpgsqlConnection con = new Npgsql.NpgsqlConnection(connPostGreSql))
                {
                    con.Open();
                    WayNodes = w.GetNodesPostgreSQL(FirstWay, con);
                    WayTags = w.GetTagsPostgreSQL(FirstWay, con);
                    con.Close();
                }
                if (WayTags.Where(i => i.KeyValueSQL[0].ToLower() == "landuse" || i.KeyValueSQL[0].ToLower() == "building" || i.KeyValueSQL[0].ToLower() == "highway").Count() != 0)
                {
                    var tempPoints = new Vector3[WayNodes.Count];

                    int counter = 0;
                    foreach (var node in WayNodes)
                    {
                        var result = CoordinateConvertor.SimpleInterpolation((float)node.PositionSQL.Lat, (float)node.PositionSQL.Lon, bounds, minmaxX, minmaxY);
                        // Testing the correct direction
                        tempPoints[counter] = new Vector3(direction * (float)result[0], 0, (float)result[1]) - MinPointOnMap;
                        counter++;
                    }
                    WayNodes = null;
                    var building = WayTags.Where(i => i.KeyValueSQL[0].ToLower() == "building");
                    var highwayType = WayTags.Where(i => i.KeyValueSQL[0].ToLower() == "highway");
                    WayTags = null;
                    if (building.Count() != 0)
                    {
                        if (GenerateBuildings)
                        {
                            //Debug.Log("Current building: "+FirstWay);
                            if (GenerateBuildingShapes)
                            {
                                // Check if it has overlapping start and ending points.
                                // NOTE: Replaced with the code to remove all the duplicates, not only the endpoints.							
                                // Checking for duplicates:
                                tempPoints = tempPoints.ToArray().RemoveDuplicates();
                                var Skip = false;
                                if (tempPoints.Length <= 2)
                                {
                                    // Buildings that are too small to show such as 76844368
                                    // http://www.openstreetmap.org/browse/way/76844368
                                    // "A weird building were found and ignored. FirstWay \nRelated url: http://www.openstreetmap.org/browse/way/{0}"
                                    Skip = true; // continue;
                                }
                                if (!Skip)
                                {
                                    var p2d = tempPoints.ToCPoint2D();
                                    // TODO bug in the cpolygon, probably duplicates
                                    var shp = new PolygonCuttingEar.CPolygonShape(p2d);
                                    shp.CutEar();
                                    p2d = null;
                                    GC.Collect();
                                    // TODO:
                                    var randHeight = CoordinateConvertor.linear((float)rand.NextDouble(), 0, 1, -3f, height);
                                    var randMaterial = (randHeight > height / 2f) ? "BuildingTall" : randHeight < height / 2f ? "Building2" : "Building";
                                    var resultedGameObject = shp.GenerateShapeUVedWithWalls_Balanced(
                                            CoordinateConvertor.OSMType.Polygon, FirstWay,
                                            "Building", "Building", randMaterial,
                                            height + randHeight, height + 7, true);
                                    //Console.WriteLine("Generating building..id=" + FirstWay);

                                    // To file:
                                    // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));
                                    
                                    // To PostGreSql LargeObjects:
                                    var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                    var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                    AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                    // gc.id , gc is now set
                                }
                            }
                            else
                                Console.WriteLine("TODO");
                            // draw.Draw(tempPoints, buildingColor, buildingColor, BuildingWidth, BuildingWidth, LineDraw.OSMType.Line, FirstWay, "Building", "Building");
                        }
                    }
                    else
                    {
                        if (highwayType.Count() != 0)
                        {
                            if (GenerateRoads)
                            {
                                var hwtype = highwayType.First();
                                //Console.WriteLine("Generating roads..id=" + FirstWay);
                                switch (hwtype.KeyValueSQL[1])
                                {
                                    case "cycleway":
                                        {
                                            var resultedGameObject = CoordinateConvertor.MeshGenerationFilledCorners(tempPoints.ToSegmentedPoints(2f), mapboundaries.CyclewayWidth, CoordinateConvertor.OSMType.Line, FirstWay, hwtype.KeyValueSQL[1], "Line", mapboundaries.CycleWayMaterial.Name, -0.01f);
                                            // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));

                                            // To PostGreSql LargeObjects:
                                            var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                            var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                            AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                            // gc.id , gc is now set
                                            break;
                                        }
                                    case "footway":
                                    case "path":
                                    case "pedestrian":
                                        {
                                            var resultedGameObject = CoordinateConvertor.MeshGenerationFilledCorners(tempPoints.ToSegmentedPoints(4f), mapboundaries.FootwayWidth, CoordinateConvertor.OSMType.Line, FirstWay, hwtype.KeyValueSQL[1], "Line", mapboundaries.FootWayMaterial.Name, -0.01f);
                                            // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));

                                            // To PostGreSql LargeObjects:
                                            var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                            var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                            AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                            // gc.id , gc is now set
                                            break;
                                        }
                                    case "steps":
                                        {
                                            var resultedGameObject = CoordinateConvertor.MeshGenerationFilledCorners(tempPoints.ToSegmentedPoints(4f), mapboundaries.CyclewayWidth, CoordinateConvertor.OSMType.Line, FirstWay, hwtype.KeyValueSQL[1], "Line", mapboundaries.StepsMaterial.Name, -0.01f);
                                            // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));

                                            // To PostGreSql LargeObjects:
                                            var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                            var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                            AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                            // gc.id , gc is now set
                                            break;
                                        }
                                    case "motorway":
                                        {
                                            break;
                                        }
                                    default:
                                        {
                                            var resultedGameObject = CoordinateConvertor.MeshGenerationFilledCorners(tempPoints.ToSegmentedPoints(0.5f), mapboundaries.RoadWidth, CoordinateConvertor.OSMType.Line, FirstWay, hwtype.KeyValueSQL[1], "Line", mapboundaries.RoadMaterial.Name, 0f);
                                            // ObjFormat.MeshToFile(resultedGameObject,System.IO.Path.Combine( exportPath , resultedGameObject.Name.Replace("|", "-") + ".obj"));

                                            // To PostGreSql LargeObjects:
                                            var objData = ObjFormat.GameObjectToString(resultedGameObject);
                                            var binaryData = System.Text.Encoding.ASCII.GetBytes(objData);
                                            AddToDatabase(binaryData, FirstWay, resultedGameObject.Name, resultedGameObject, version, connPostGreSql);
                                            // gc.id , gc is now set
                                            break;
                                        }
                                }
                                //current++;
                                //if (current > max)
                                //    state.Break();
                            }
                        }
                    }
                }
            });
            duration.Stop();
            Console.WriteLine("Finished in " + duration.Elapsed.Minutes + " minutes, " + duration.Elapsed.Seconds + " seconds, " + duration.Elapsed.Milliseconds + " milliseconds.");
            Console.ReadLine();
        }