2

大きな STL ファイルを読み込んで解析する方法は? 3D STL ファイルを表示するアプリケーションを作成します。3D STL ファイルは、バイナリまたは ACSII にすることができます。Sdcard から STL ファイルを読み取り、データを解析して OpenGL を使用してレンダリングする必要があります。しかし、3D STL が大きいと「メモリ不足」になります。この問題を解決する方法。2 つの配列リストを使用して、ファセット フォーマルと頂点を格納します。

以下のコードは、「バイナリ 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

0

メモリの問題は、arraylist を使用することによって発生します。デフォルトでは、Java は arraylist のサイズを 10 に初期化します。11 番目の要素を追加すると、配列は新しい配列にコピーされ、現在の配列のサイズを渡すたびに 2 倍の部屋 (サイズは 20) が与えられます。コピーされ、サイズが 2 倍になります。これを解決するには、配列リストを初期化して、すべての値を大きくせずに格納するのに十分な大きさにします。

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

問題の解決策がまだ必要かどうかはわかりません。あなたの投稿が小さな STL-Binary Reader を開発するのに本当に役立ったので、何かお返ししたいと思います。また、自分のアプリでこれらの奇妙なメモリ不足を発見しました。その理由は、android がデフォルトで非常に少量のメモリしか提供しないためです (デバイスによって異なります)。API バージョン 11 より前は、メモリを手動で増やす必要がありました。現在、API レベル 11 を使用することで、これらの問題を「largeHeap」によって回避できます。Android マニフェストに次のように宣言するだけです。

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

詳細については、「Android アプリケーションのヒープ サイズを増やすにはどうすればよいですか?」を検索して、スタック オーバーフローの他のスレッドを参照してください。

于 2013-11-22T11:12:12.750 に答える