xBimTeam / XbimWindowsUI

The home of XbimXplorer and WPF components for your desktop BIM applications.
Other
252 stars 149 forks source link

Microsoft.Isam.Esent.Interop.EsentVersionStoreOutOfMemoryException #62

Closed Ajes1337 closed 6 years ago

Ajes1337 commented 7 years ago

Im getting the below exception, when I try to run CreateContext() on a 500megabyte .ifc file :/

Microsoft.Isam.Esent.Interop.EsentVersionStoreOutOfMemoryException: Version store out of memory (cleanup already attempted) at Microsoft.Isam.Esent.Interop.Api.Check(Int32 err) in c:\codeplex\EsentInterop\Api.cs:line 2937 at Microsoft.Isam.Esent.Interop.Api.JetUpdate(JET_SESID sesid, JET_TABLEID tableid, Byte[] bookmark, Int32 bookmarkSize, Int32& actualBookmarkSize) in c:\codeplex\EsentInterop\Api.cs:line 2561 at Microsoft.Isam.Esent.Interop.Update.Save(Byte[] bookmark, Int32 bookmarkSize, Int32& actualBookmarkSize) in c:\codeplex\EsentInterop\Update.cs:line 85 at Xbim.IO.Esent.EsentShapeGeometryCursor.AddGeometry(IXbimShapeGeometryData shapeGeom) in C:\BuildAgent\work\77d7b8e93613846d\Xbim.IO\Esent\EsentShapeGeometryCursor.cs:line 289 at Xbim.IO.Esent.EsentGeometryInitialiser.AddRegions(XbimRegionCollection regions) in C:\BuildAgent\work\77d7b8e93613846d\Xbim.IO\Esent\EsentGeometryInitialiser.cs:line 112 at Xbim.ModelGeometry.Scene.Xbim3DModelContext.WriteRegionsToStore(IIfcRepresentationContext context, IEnumerable`1 elementsToCluster, IGeometryStoreInitialiser txn) in c:\BuildAgent\work\860c3b913b6c647f\Xbim.ModelGeometry.Scene\Xbim3DModelContext.cs:line 1300 at Xbim.ModelGeometry.Scene.Xbim3DModelContext.CreateContext(ReportProgressDelegate progDelegate, Boolean adjustWcs) in c:\BuildAgent\work\860c3b913b6c647f\Xbim.ModelGeometry.Scene\Xbim3DModelContext.cs:line 698 at ConsoleApplication1.Program.ReadIfcFileAjesStyle(String ifcFilename) in C:\Users\Admin\Dropbox\BIMeVR\Prototyper\Runtime IFC import\XbimWindowsUI-master\ConsoleApplication1\Program.cs:line 110 at ConsoleApplication1.Program.Main(String[] args) in C:\Users\Admin\Dropbox\BIMeVR\Prototyper\Runtime IFC import\XbimWindowsUI-master\ConsoleApplication1\Program.cs:line 73

CBenghi commented 7 years ago

The way we mesh the model at the moment caches all the building geometries in order to perform faster. This is of course a problem for large models, but we don't have an alternative approach available. It seems odd that the code breaks at the very end of the meshing process when a lot of the memory could be released. If you can pass the model privately I'll have a look.

Ajes1337 commented 7 years ago

My Boss would sadly not allow to share it privately.. but I got the model to work without crashing! - after I had re-writting my own code :)

CBenghi commented 7 years ago

That sound nice. Can you share the code changes? Memory optimisation is on our wishlist. That would be great!

CBenghi commented 7 years ago

@Ajes1337, Ideally the process would be to create a branch in your repository and push your code there. The naming convention being feature/reducedMeshingMemory or something similar. Thanks, Claudio

Ajes1337 commented 7 years ago

Hmm, im not that used to github, or version control in general :D - but if I can help xBim along the way, while I use it, I will look into it :)

The code I have written only uses allready implemented xBim features (I haven't changed xBim code), what I have done is; take a .ifc file, converting it to .wexbim file, and then read/get the geometri information out of that, so that I can use that to render the model in Unity 💃

CBenghi commented 7 years ago

Surely you must CreateContext before you can write the wexbim is it not? If want me to show how to deal with github/git we can skype, you find me searching for Claudio Benghi or Bonghi on Skype. I'd be intereted in looking at what you have done. Heppy coding, Claudio

Ajes1337 commented 7 years ago

Im currently working on my exams at the moment, so maybe after that, or after summer :) - the company I did the work for, am I currently in a "study-job" at, where I will get more active after summer..

First I convert the ifc file with this:

            string fileName = "SampleHouse4.ifc";
            using (var model = IfcStore.Open(fileName, null, -1)) {
                var context = new Xbim3DModelContext(model);
                context.CreateContext();

                using (var wexBimFile = File.Create("test.wexbim")) {
                    using (var wexBimBinaryWriter = new BinaryWriter(wexBimFile)) {
                        model.SaveAsWexBim(wexBimBinaryWriter);
                        wexBimBinaryWriter.Close();
                    }
                    wexBimFile.Close();
                }
            }

And then, I pull out the info I need for Unity with this example I found in a 'test' somewhere:

    using (var fs = new FileStream(@"test.wexBIM", FileMode.Open, FileAccess.Read)) {
            using (var br = new BinaryReader(fs)) {
                var magicNumber = br.ReadInt32();
                //   Assert.IsTrue(magicNumber == IfcStore.WexBimId);
                var version = br.ReadByte();
                var shapeCount = br.ReadInt32();
                var vertexCount = br.ReadInt32();
                var triangleCount = br.ReadInt32();
                var matrixCount = br.ReadInt32();
                var productCount = br.ReadInt32();
                var styleCount = br.ReadInt32();
                var meter = br.ReadSingle();
                //    Assert.IsTrue(meter > 0);
                var regionCount = br.ReadInt16();
                for (int i = 0; i < regionCount; i++) {
                    var population = br.ReadInt32();
                    var centreX = br.ReadSingle();
                    var centreY = br.ReadSingle();
                    var centreZ = br.ReadSingle();
                    var boundsBytes = br.ReadBytes(6 * sizeof(float));
                    var modelBounds = XbimRect3D.FromArray(boundsBytes);
                }

                for (int i = 0; i < styleCount; i++) {
                    var styleId = br.ReadInt32();
                    var red = br.ReadSingle();
                    var green = br.ReadSingle();
                    var blue = br.ReadSingle();
                    var alpha = br.ReadSingle();
                }
                for (int i = 0; i < productCount; i++) {
                    var productLabel = br.ReadInt32();
                    var productType = br.ReadInt16();
                    var boxBytes = br.ReadBytes(6 * sizeof(float));
                    XbimRect3D bb = XbimRect3D.FromArray(boxBytes);
                }
                for (int i = 0; i < shapeCount; i++) {
                    var shapeRepetition = br.ReadInt32();
                    //   Assert.IsTrue(shapeRepetition > 0);
                    if (shapeRepetition > 1) {
                        for (int j = 0; j < shapeRepetition; j++) {
                            var ifcProductLabel = br.ReadInt32();
                            var instanceTypeId = br.ReadInt16();
                            var instanceLabel = br.ReadInt32();
                            var styleId = br.ReadInt32();
                            var transform = XbimMatrix3D.FromArray(br.ReadBytes(sizeof(double) * 16));
                        }
                        var triangulation = br.ReadShapeTriangulation();
                        //    Assert.IsTrue(triangulation.Vertices.Count > 0, "Number of vertices should be greater than zero");

                    } else if (shapeRepetition == 1) {
                        var ifcProductLabel = br.ReadInt32();
                        var instanceTypeId = br.ReadInt16();
                        var instanceLabel = br.ReadInt32();
                        var styleId = br.ReadInt32();
                        XbimShapeTriangulation triangulation = br.ReadShapeTriangulation();
                        //     Assert.IsTrue(triangulation.Vertices.Count > 0, "Number of vertices should be greater than zero");

                    }
                }
            }
        }

screenshot_77

Vizzr commented 6 years ago

@Ajes1337 I tested your code, but I can't get it working. The line "var context = new Xbim3DModelContext(model); context.CreateContext();" calls an error: "FileNotFoundException: Could not load file or assembly 'Xbim.Geometry.Engine64' or one of its dependencies"

How did you fix it? or where did you place the Xbim.Geometry.Engine64 file?

Ajes1337 commented 6 years ago

@Vizzr, Sorry, cannot remember :/

liszto commented 6 years ago

It's really odd. When I try to call just the first line from your code. I get this issue : `NotImplementedException: The method or operation is not implemented. System.Runtime.InteropServices.Marshal.GetExceptionPointers () (at <9c9f068c46c64ffd91fda7af157b4d15>:0)

.___CxxCallUnwindDtor (System.MonoFNPtrFakeClass pDtor, System.Void* pThis) (at <53dab193172641d196c7067894b3a595>:0) ..cctor () (at <53dab193172641d196c7067894b3a595>:0) Rethrow as TypeInitializationException: The type initializer for '' threw an exception. System.Reflection.MonoCMethod.InternalInvoke (System.Object obj, System.Object[] parameters) (at <9c9f068c46c64ffd91fda7af157b4d15>:0) Rethrow as TargetInvocationException: Exception has been thrown by the target of an invocation. Xbim.Geometry.Engine.Interop.XbimGeometryEngine..ctor () (at :0) Xbim.ModelGeometry.Scene.Xbim3DModelContext.get_Engine () (at :0) Xbim.ModelGeometry.Scene.Xbim3DModelContext.CreateContext (Xbim.Common.ReportProgressDelegate progDelegate, System.Boolean adjustWcs) (at :0)` Did you encountered this one during your building generation within unity ? My dll are maybe slightly different from yours ? Which was the xbim version for Geometry dll and common ones ? Did you switch your Unity version to scripting backend .NET 4.6 ? For this one I think you did cause otherwise there is a lot of issue from my side. :/ Any hint would be appreciate cause it helped me a lot to go further. :'(
liszto commented 6 years ago

@Ajes1337 I have some question for you :

Thanks in advance, those informations could help me to debug my issue I think ! :)

martin1cerny commented 6 years ago

Admin note: Would you mind guys to start a new issue/thread for Unity? The topic has changed a lot from the original issue and this makes it hard for other people to find relevant information about Unity. This should really go into XbimGeometry project.

luoyuke commented 6 years ago

@Vizzr I tested your code, but I can't get it working. The line "var context = new Xbim3DModelContext(model); context.CreateContext();" calls an error: "FileNotFoundException: Could not load file or assembly 'Xbim.Geometry.Engine64' or one of its dependencies"

got the same error, did you fix it?

liszto commented 6 years ago

@luoyuke You can check this issue : https://github.com/xBimTeam/XbimGeometry/issues/94 There is no solution currently to make it works in Unity at least for the xBimGeomtry part that create the ModelContext();

You have to generate it from an external project if you wanna create a "wexbim" file but once it's created you can use it in Unity directly.

;)

More information on Unity + xBim here : https://github.com/xBimTeam/XbimEssentials/issues/131

luoyuke commented 6 years ago

@liszto thanks alot, i'm struggling to get ifc data into unity for days, i'm currently writing M.Sc. thesis about thermo-physical Visualization in VR using ifc. Wexbim seems not containing enough infos for thermo-hygro and energy analysis.

liszto commented 6 years ago

I can help you maybe in a private conversation in any discussion chat you have instead of spam this topic with unrelated element ;)

Basically what I'm currently doing at my office :

The longer part currently is the runtime mesh generation function of the ifc complexity i could take 2seconds for a basic house to minutes for complex building with pipes furnitures etc... But the informations displaying takes no time (it's instant).

The ifcStore.Open takes more times in unity than in xBim viewer. I currently point something weird in unity with .dll files that's why I'm currently trying to get rid of the dll from xBim and load directly the script in unity. I'm facing one last issue in that process probably due to mono C# stuff and my test would be done. My expectations are to divide ifcstore.open generation time by 4 (which is quite good :D if my test is the good one)

If you need more explanation on my logic, don't heistate to contact me directly as I mentionned in the first line.

Vizzr commented 6 years ago

@luoyuke I am not using it in Unity since I couldn't fix the issues I had. I am currently generating and modifying the IFC file on an API and import this in Unity with assimp.