2

如何读取和解析一个大的 STL 文件?我编写了一个应用程序来查看 3D STL 文件。3D STL 文件可以是二进制文件或 ACSII。我需要从 sdcard 读取 STL 文件,然后解析数据以使用 OpenGL 进行渲染。但是当 3D STL 很大时,我会出现“内存不足”的情况。如何解决这个问题。我使用两个数组列表来存储刻面形式和顶点。

下面的代码实现了“读取和解析二进制 STL 文件”:

private void processBinarySTL(){
    Thread processThread =new Thread(new Runnable() {

        @Override
        public void run() {
            // TODO Auto-generated method stub
            File file=new File("/mnt/sdcard/3D/Lost_Pleiade_Ready.stl");

            InputStream inputStream = null;
            try {
                inputStream = mContext.getContentResolver().openInputStream(Uri.fromFile(file));
                int n = 0;
                byte[] buffer = new byte[4];
                inputStream.skip(80);
                n = inputStream.read(buffer);
                System.out.println("n=="+n);
                int size=getIntWithLittleEndian(buffer,0);
                System.out.println("size=="+size);
                List<Float> normalList=new ArrayList<Float>();
                List<Float> vertexList = new ArrayList<Float>();
                for (int i = 0; i < size; i++) {
                    //normal
                    for(int k=0;k<3;k++){
                    inputStream.read(buffer);
                    normalList.add(Float.intBitsToFloat(getIntWithLittleEndian(buffer, 0)));
                    }


                    for(int j=0;j<3;j++){
                    inputStream.read(buffer);
                    float x = Float.intBitsToFloat(getIntWithLittleEndian(buffer, 0));
                    inputStream.read(buffer);
                    float y = Float.intBitsToFloat(getIntWithLittleEndian(buffer, 0));
                    inputStream.read(buffer);
                    float z = Float.intBitsToFloat(getIntWithLittleEndian(buffer, 0));
                    adjustMaxMin(x, y, z);
                    vertexList.add(x);
                    vertexList.add(y);
                    vertexList.add(z);
                    }
                    inputStream.skip(2);

                }
                System.out.println("normalList size== "+normalList.size());
                System.out.println("vertexList size== "+vertexList.size());
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                if(inputStream!=null)
                    try {
                        inputStream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
            }

        }
    });
    processThread.start();
}
4

3 回答 3

1

在这种情况下解决内存不足问题的最简单方法是增加 JVM 的最大内存分配。这可以使用-Xmx命令行开关设置并指定更大的最大内存使用量。

例如。 java Main -Xmx 2G将程序 Main 的最大内存使用量设置为 2 GB。默认的最大内存分配是物理内存的 1/4。

见:http: //javarevisited.blogspot.sg/2011/11/hotspot-jvm-options-java-examples.html

于 2013-06-27T05:15:49.273 回答
0

我不知道你是否还需要解决你的问题。由于您的帖子通过开发小型 STL 二进制阅读器确实帮助了我,我想回馈您一些东西。我还用自己的应用程序发现了这些奇怪的 Out of Memorys。原因是默认情况下,android 只会为您提供非常少量的内存(取决于您的设备)。在 API 版本 11 之前,您必须手动增加内存。现在,通过使用 API 级别 11,您可以通过“largeHeap”避免这些问题。只需在您的 android 清单中添加一个声明,如下所示:

<application
        android:largeHeap="true"
                ....     >
                ....
</application>

您可以通过搜索“如何增加 android 应用程序的堆大小?”在 Stack Overflow 的其他线程中找到更多信息。

于 2013-11-22T11:12:12.750 回答
0

内存问题是由使用 arraylist 引起的。默认情况下,java初始化一个arraylist的大小为10,当你添加第11个元素时,数组被复制到一个新数组中并给定双倍的空间(所以大小为20),每次你传递数组的当前大小它被复制并加倍。您可以通过初始化 arraylist 来解决这个问题,使其具有足够大的大小来存储所有值而不会增长。

List<Float> normalList=new ArrayList<Float>(sizeOfArray);
List<Float> vertexList = new ArrayList<Float>(sizeOfOtherArray);
于 2016-06-01T18:20:04.143 回答