xBimTeam / XbimWindowsUI

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

Out of Memory #55

Open theebow opened 7 years ago

theebow commented 7 years ago

Hi Team

Have an OutOfMemoryException reading this huge ifc file (i don't remember where i found them) memoryexception

As the goal was to check the xBim OnlineViewer perfomance on loading huge wexbim file, i have modified the buildScene on windowsUI to SaveAsWexBim the IfcStore just before the crash...and xViewer not able to read the generated wexbim file.

You can donwload the 2 ifc files here :

https://we.tl/zSeiVLIKH7

Tell me if you want the wexbim one

😉

TadeuszWilczek commented 7 years ago

Collections of Positions, TriangeIndices and Normals grows very fast when loading huge projects. Solution is use not very fast growing List<..> but List<List<>>. In class WpfMeshGeometry3D instead of: private List _unfrozenPositions; private List _unfrozenIndices; private List _unfrozenNormals; You can use private ListVectors _unfrozenPositions; private ListVectors _unfrozenIndices; private ListVectors _unfrozenNormals; ....

internal class ListVectors<T> : IEnumerable<T>, IEnumerable
{
    List<List<T>> vektory = new List<List<T>>();
    public ListVectors()
    {
        vektory.Add(new List<T>());
    }
    public ListVectors(int capacity)
    {
        vektory.Add(new List<T>(capacity));
    }
    public ListVectors(IEnumerable<T> collection)
    {
        vektory.Add(new List<T>(collection));
    }
    public T this[int index]
    {
        get
        {
            List<T> v = Vector(ref index);
            return v[index];
        }
        set
        {
            List<T> v = Vector(ref index);
            v[index] = value;
        }
    }
    public int Count
    {
        get
        {
            int count = 0;
            foreach (var v in vektory)
                count += v.Count;
            return count;
        }

    }
    public void Add(T item)
    {
        List<T> last = vektory[vektory.Count - 1];
        last.Add(item);
    }
    public void AddRange(List<T> vector)
    {
        List<T> last = vektory[vektory.Count - 1];
        if (last.Count == 0)
            vektory[vektory.Count - 1] = vector;
        else
            vektory.Add(vector);
    }
    public void AddRange(IEnumerable<T> vector)
    {
        List<T> last = vektory[vektory.Count - 1];
        if (last.Count == 0)
            last.AddRange(vector);
        else
            vektory.Add(new List<T>(vector));
    }
    IEnumerator IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    List<T> Vector(ref int index)
    {
        if (index < 0)
            throw new System.ArgumentOutOfRangeException();
        for (int i = 0; i < vektory.Count; i++)
        {
            List<T> vector = vektory[i];
            if (index < vector.Count)
                return vector;
            index -= vector.Count;
        }
        throw new System.ArgumentOutOfRangeException();
    }

    IEnumerable<T> CreateEnumerable()
    {
        foreach (var v in vektory)
            foreach (T t in v)
                yield return t;
    }
    public IEnumerator<T> GetEnumerator()
    {
        return CreateEnumerable().GetEnumerator();
    }
}
theebow commented 7 years ago

@TadeuszWilczek

Thanks for reply, it seem to be work (no more crash in wpfMeshGeometry), unfortunately the problem has been pushed further

capture

CBenghi commented 7 years ago

Hi all, I'm working to reduce the memory footprint of the visual component. There's a lot of room for improvement, it seems. Will keep you posted. Claudio

CBenghi commented 7 years ago

@theebow, I've put in some improvements to the memory usage of the Xbim.Presentation. Have a look, if you wish, we know it has its limits, but until we move to a new presentation 3D viewer we'll live with them. I've put a more robust fix in roadmap for 4.2 (somewhere down the line). Best, Claudio