package edu.stanford.rsl.conrad.phantom.forbild; import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Scanner; import edu.stanford.rsl.conrad.geometry.AbstractShape; import edu.stanford.rsl.conrad.physics.PhysicalObject; import edu.stanford.rsl.conrad.physics.materials.database.MaterialsDB; import edu.stanford.rsl.conrad.rendering.AbstractScene; import edu.stanford.rsl.conrad.rendering.PrioritizableScene; import edu.stanford.rsl.conrad.utils.parsers.SceneFileParser; /** * <p>This class adds objects defined in <a href = "http://www.imp.uni-erlangen.de/forbild/">forbild</a> format into a scene that can be used to create a phantom. </p> * * @author Rotimi X Ojo */ public class ForbildParser implements SceneFileParser { private String directoryPath; private ArrayList<String> objectDefs = new ArrayList<String>(); private HashMap<String,ArrayList<String>> templatePlaceholders = new HashMap<String, ArrayList<String>>(); private AbstractScene scene = new PrioritizableScene(); public ForbildParser(File file) { this(file, null); } public ForbildParser(File file, HashMap<String,String> placeHoldersMap) { try { directoryPath = file.getParent() + "\\"; preProcessing(new Scanner(file), placeHoldersMap); } catch (Exception e) { e.printStackTrace(); } createObjects(); } private void preProcessing(Scanner scanner, HashMap<String,String> placeHoldersMap) throws FileNotFoundException { while (scanner.hasNextLine()) { parseLine(scanner.nextLine().trim(), placeHoldersMap); } } private String lastObjectName = ""; private void parseLine(String currLine, HashMap<String,String> varMap) throws FileNotFoundException { if(currLine == null || currLine.isEmpty()|| (currLine.indexOf("//")==0)){ return; } currLine=currLine.trim(); if (currLine.substring(0, currLine.indexOf(" ")).equals("#Prototype")) { String name = currLine.substring(currLine.indexOf(" "), currLine.indexOf('(')).trim(); templatePlaceholders.put(name, getTemplatePlaceHolders(currLine)); } else if (currLine.substring(0, currLine.indexOf(" ")).equals( "Phantom")) { scene.setName(currLine.substring(currLine.indexOf('"') + 1, currLine.length()-1)); } else if(currLine.contains("Object ")){ lastObjectName = currLine.substring(currLine.indexOf(" ") + 1).trim(); }else if (currLine.charAt(0) == '{') { currLine = lastObjectName + ";" + currLine.substring(1,currLine.length()-1); objectDefs.add(replacePlaceHolders(currLine,varMap)); } else if (currLine.substring(0, currLine.indexOf(" ")).equals("#include") && currLine.contains(".pha")) { String filename = currLine.substring(currLine.indexOf('"')+1, currLine.length() - 1); scene.addAll((new ForbildParser(new File(directoryPath + filename)) .getScene())); } else if (currLine.substring(0, currLine.indexOf(" ")).equals("func")) { String name = currLine.substring(currLine.indexOf(" "), currLine.indexOf('(')).trim(); String fileName = name + ".pha"; HashMap<String, String> buff = new HashMap<String, String>(); ArrayList<String> placeHolders = templatePlaceholders.get(name); ArrayList<String> parameters = getFunctionParameters(currLine); for(int i =0; i < placeHolders.size();i++){ buff.put(placeHolders.get(i), parameters.get(i)); } scene.addAll(new ForbildParser(new File(directoryPath + fileName.trim()),buff).getScene()); } } private ArrayList<String> getTemplatePlaceHolders(String currLine) { return getFunctionParameters(currLine); } private void createObjects() { Iterator<String> it = objectDefs.iterator(); Scanner sc; int textLine = 0; while (it.hasNext()) { String line = it.next(); textLine++; PhysicalObject basicobj = new PhysicalObject(); if(line.contains("[") && line.contains("]")){ try{ AbstractShape shape = ForbildShapeFactory.getShape(line.substring(line.indexOf("["),line.indexOf("]")+ 1)); if (shape== null){ throw new RuntimeException("Error in Parsing"); } basicobj.setShape(shape); }catch (Exception e) { //e.printStackTrace(); throw new RuntimeException("Parsing Error at line: " + textLine + "\n" + line); } basicobj.setNameString(line.substring(line.indexOf("[")+1, line.indexOf(":"))); } String nline = line.substring(line.indexOf("]") + 1); sc = new Scanner(nline.substring(1).trim()); sc.useDelimiter(";"); while(sc.hasNext()){ String property = sc.next(); if(property.toLowerCase().contains("rho")){ try{ basicobj.setMaterial(MaterialsDB.getMaterial(property.substring(property.indexOf("=")+1))); }catch (Exception e) { throw new RuntimeException("Parsing Error at line: " + textLine + "\n" + line); } } } scene.add(basicobj); } } private String replacePlaceHolders(String currLine, HashMap<String, String> varMap) { if (varMap == null || varMap.size() == 0) { return currLine; } Iterator<String> pit = varMap.keySet().iterator(); while (pit.hasNext()) { String placeHolder = pit.next(); String geometryDef = currLine.substring(0,currLine.indexOf(']') + 1); currLine = geometryDef.replace(placeHolder, varMap.get(placeHolder))+ currLine.substring(currLine.indexOf(']') + 1); } return currLine; } private ArrayList<String> getFunctionParameters(String functionCall) { ArrayList<String> param = new ArrayList<String>(4); String parameters = functionCall.substring(functionCall.indexOf('(') + 1, functionCall.indexOf(')')); Scanner temp = new Scanner(parameters); temp.useDelimiter(","); while (temp.hasNext()) { param.add(temp.next().trim()); } return param; } @Override public AbstractScene getScene() { return scene; } } /* * Copyright (C) 2010-2014 Rotimi X Ojo * CONRAD is developed as an Open Source project under the GNU General Public License (GPL). */