正则表达式解析OBJ

package edu.btbu.TDSearch.util.file;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import edu.btbu.TDSearch.util.shape.Face;
import edu.btbu.TDSearch.util.shape.Mesh;
import edu.btbu.TDSearch.util.shape.Point3D;
import edu.btbu.TDSearch.util.statistics.ModelInfo;
/**
 * 解析obj文件
 * @author 3L5M53X
 *
 */
public class ObjParse {
	// v float float float
	private final static String vetexReg ="v( +[\\d|\\.|\\+|\\-|e]+)( +[\\d|\\.|\\+|\\-|e]+)( +[\\d|\\.|\\+|\\-|e]+)";
	//vt float float
	private final static String vtReg = "vt( +[\\d|\\.|\\+|\\-|e]+)( +[\\d|\\.|\\+|\\-|e]+)";
	//vn float float
	private final static String vnReg ="vn( +[\\d|\\.|\\+|\\-|e]+)( +[\\d|\\.|\\+|\\-|e]+)";
	
	// f vertex vertex vertex ...
	private final static String faceReg = "f( +[\\d]+)( [\\d]+)( [\\d]+)( [\\d]+)?";
	
	// f vertex/uv vertex/uv vertex/uv ...
	private final static String faceReg_v_uv="f( +([\\d]+)/([\\d]+))( ([\\d]+)/([\\d]+))( ([\\d]+)/([\\d]+))( ([\\d]+)/([\\d]+))?";
	
	// f vertex/uv/normal vertex/uv/normal vertex/uv/normal ...
	private final static String  faceReg_v_uv_n="f( +([\\d]+)/([\\d]+)/([\\d]+))( ([\\d]+)/([\\d]+)/([\\d]+))( ([\\d]+)/([\\d]+)/([\\d]+))( ([\\d]+)/([\\d]+)/([\\d]+))?";

	// f vertex//normal vertex//normal vertex//normal ...
	private final static String faceReg_v_n="f( +([\\d]+)//([\\d]+))( ([\\d]+)//([\\d]+))( ([\\d]+)//([\\d]+))( ([\\d]+)/\\/([d]+))?";
	
	
	
	public static Mesh getMesh(String url) throws IOException{
		
		Mesh mesh = null;
		ArrayList<Point3D> vetexList = new ArrayList<Point3D>();
		ArrayList<Face> faceList = new ArrayList<Face>();
		File file = new File(url);
		String fileName= file.getName();
		int position = fileName.lastIndexOf(".");
		String meshID = fileName.substring(0,position);
		
		if(!Pattern.matches(".+\\.obj$",fileName)){
			System.out.println("The file type should be .obj,please check your file Type");
			return null;	
		}
		//vetex
		CharSequence cs = fromFile(file);
		Matcher matcher_v = Pattern.compile(vetexReg).matcher(cs);
		while(matcher_v.find()){
			Point3D point = new Point3D(Double.parseDouble(matcher_v.group(1)),Double.parseDouble(matcher_v.group(2)),Double.parseDouble(matcher_v.group(3)));
			vetexList.add(point);
		}
		
		// face
		Matcher matcher_f = Pattern.compile(faceReg).matcher(cs);
		while(matcher_f.find()){
			Point3D a = vetexList.get(Integer.parseInt(matcher_f.group(1).trim())-1);
			Point3D b = vetexList.get(Integer.parseInt(matcher_f.group(2).trim())-1);
			Point3D c = vetexList.get(Integer.parseInt(matcher_f.group(3).trim())-1);
			Face face = new Face(a,b,c);
			faceList.add(face);
		}
		Matcher matcher_fvuv = Pattern.compile(faceReg_v_uv).matcher(cs);
		while(matcher_fvuv.find()){
			System.out.println(matcher_fvuv.group(1));
		}
		
		mesh = new Mesh(meshID,vetexList.size(),faceList.size());
		
		Point3D[] points = new Point3D[vetexList.size()];
		vetexList.toArray(points);
		mesh.setPointArray(points);
		
		Face[] faces = new Face[faceList.size()];
		faceList.toArray(faces);
		mesh.setFaceArray(faces);
		
		return mesh;
	}
	
	/**
	 * get the basic info,name \file size \num of vetex \num of face \bpv\bpf
	 * @param url
	 * @throws IOException 
	 */
	public static ModelInfo getInfo(File file) throws IOException{
		ModelInfo info = new ModelInfo();
		info.setF_name(file.getName());
		long f_size = file.length();
		info.setF_size(file.length());
		long v_size = 0;//vetex part size
		long p_size = 0;//polygons part size
		long vt_size = 0;
		long vn_size = 0;
		long v_num = 0;
		long vt_num = 0;
		long nt_num = 0;
		long f_num = 0;
		//vetex
		CharSequence cs = FileIn.fromFile(file);
		Matcher matcher_v = Pattern.compile(vetexReg).matcher(cs);
		matcher_v.find();
		while(matcher_v.find()){
			v_size+=matcher_v.group().length()+1;
			v_num++;
		}
/*		Matcher matcher_vt = Pattern.compile(vtReg).matcher(cs);
		while(matcher_vt.find()){
			v_size+=matcher_vt.group().length()+1;
		}
		Matcher matcher_vn = Pattern.compile(vnReg).matcher(cs);
		while(matcher_vn.find()){
			v_size+=matcher_vn.group().length()+1;
		}*/
		// face
		Matcher matcher_f = Pattern.compile(faceReg).matcher(cs);
		while(matcher_f.find()){
			p_size+=matcher_f.group().length()+1;
			f_num++;
		}
		Matcher matcher_fvuv = Pattern.compile(faceReg_v_uv).matcher(cs);
		while(matcher_fvuv.find()){
			p_size+=matcher_fvuv.group().length()+1;
			f_num++;
/*			
			System.out.print(matcher_fvuv.group(0)+" ");//f 9/1 5/2 10/3
			System.out.print(matcher_fvuv.group(1)+" ");// 9/1
			System.out.print(matcher_fvuv.group(2)+" ");//9
			System.out.print(matcher_fvuv.group(3)+" ");//1
			*/
		}
		Matcher matcher_f_vn = Pattern.compile(faceReg_v_n).matcher(cs);
		while(matcher_f_vn.find()){
			p_size+=matcher_f_vn.group().length()+1;
			f_num++;
			System.out.print(matcher_f_vn.group(0)+" ");//f 998//1455 989//1446 990//1447  
			System.out.print(matcher_f_vn.group(1)+" ");// 998//1455
			System.out.print(matcher_f_vn.group(2)+" ");// 998
			System.out.print(matcher_f_vn.group(3)+" ");//1455
			
			System.out.println();//2
		}
		Matcher matcher_f_v_uv_n = Pattern.compile(faceReg_v_uv_n).matcher(cs);
		while(matcher_f_v_uv_n.find()){
			p_size+=matcher_f_v_uv_n.group().length()+1;
			f_num++;
		}
		info.setV_num(v_num);
		info.setF_num(f_num);
		System.out.println(v_size);
		System.out.println(p_size);
		System.out.println(v_size+p_size);
		DecimalFormat format = new DecimalFormat("#.00");
		info.setFpv(format.format(1.0*f_num/v_num)); 
		info.setBpf(format.format(8.0*p_size/f_num));
		info.setBpv(format.format(8.0*v_size/v_num));
		return info;
		
	}
	
	// Converts the contents of a file into a CharSequence
    // suitable for use by the regex package.
    public static CharSequence fromFile(File filename) throws IOException {
        FileInputStream fis = new FileInputStream(filename);
        FileChannel fc = fis.getChannel();
        long size =  fc.size();
        // Create a read-only CharBuffer on the file
        ByteBuffer bbuf = fc.map(FileChannel.MapMode.READ_ONLY,size);
        CharBuffer cbuf = Charset.forName("UTF-8").newDecoder().decode(bbuf);
        return cbuf;
    	/*  FileInputStream fis = new FileInputStream(filename);
          FileChannel fc = fis.getChannel();
          long size =  fc.size();
          // Create a read-only CharBuffer on the file
          ByteBuffer bbuf = fc.map(FileChannel.MapMode.READ_ONLY,size);
          
          CharBuffer cbuf = Charset.forName("ISO-8859-1").newDecoder().decode(bbuf);
          return cbuf;*/
    }
	/**
	 * @param args
	 * @throws IOException F:\paper\3d\NTU3D\NTU3D.v1_0-999
	 */
	public static void main(String[] args) throws IOException {
		System.out.println(getInfo(new File("F:\\Work\\数据压缩\\result\\obj\\hand.obj")));
		//Y5001_R_hand.obj 51049 799 1606 2.0100125156445556 63.89111389236545 31.78642590286426
		//System.out.println("192.168.69.84".hashCode());
	}

}

相关文章

jquery.validate使用攻略(表单校验) 目录 jquery.validate...
/\s+/g和/\s/g的区别 正则表达式/\s+/g...
自整理几个jquery.Validate验证正则: 1. 只能输入数字和字母...
this.optional(element)的用法 this.optional(element)是jqu...
jQuery.validate 表单动态验证 实际上jQuery.validate提供了...
自定义验证之这能输入数字(包括小数 负数 ) &lt;script ...