2013-06-27 28 views
1

如何讀取和解析一個大的STL文件?我編寫了一個應用程序來查看3D STL文件。 3D STL文件可以是二進制或ACSII。我需要從SD卡讀取STL文件,然後解析數據以使用OpenGL進行渲染。但是,當3D STL很大時,我有「內存不足」。如何解決這個問題。我使用兩個數組列表來存儲方面的形式和頂點。如何讀取和解析一個大的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(); 
} 
+1

是你尋找http://code.j3d.org/javadoc/org/j3d/loaders/stl/STLFileReader.html –

+0

@KarthikT謝謝您的答覆。我不知道這個資源。我會研究它。 – Judy

+0

@KarthikT我看看j3d。但這不是我的解決方案。我需要在Android應用程序中實現「查看3D STL文件」。 – Judy

回答

1

解決內存不足問題的情況下這樣是增加JVM的最大內存分配的最簡單方法。這可以使用-Xmx命令行開關進行設置,並指定較大的最大內存使用量。

例如。 java Main -Xmx 2G會將程序Main的最大內存使用量設置爲2 GB。默認的最大內存分配是物理內存的1/4。

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

0

我不知道,如果你還需要爲你的問題的解決方案。正如你的帖子通過開發一個小型的STL二進制閱讀器真正幫助了我,我想給你一個回覆。我也用自己的應用程序發現了這些奇怪的記憶。原因是android默認只給你一個非常少量的內存(取決於你的設備)。在API版本11之前,您必須手動增加內存。現在,通過使用API​​級別11,您可以通過「largeHeap」避免這些問題。 只要把申報您的Android清單看起來像這樣:「?如何增加Android應用程序的堆大小」

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

您可以在其他線程通過搜索發現這裏的堆棧溢出的更多信息。

0

內存問題是由使用數組列表造成的。默認情況下,java會初始化一個數組列表大小爲10,因爲您添加第11個元素時,數組將被複制到一個新數組中,並且給定空間的兩倍(因此大小爲20),每次您傳遞數組的當前大小它被複制並且大小加倍。你可以通過初始化ArrayList來獲得足夠大的尺寸來存儲所有值而不增加。

List<Float> normalList=new ArrayList<Float>(sizeOfArray); 
List<Float> vertexList = new ArrayList<Float>(sizeOfOtherArray);