00001
00002 import sys
00003 import xml.dom.minidom
00004 import math
00005 import optparse
00006
00007 maxDist = 0.0001
00008
00009
00010 def readFractions(fileName, materialMap):
00011 result = {}
00012 file = open(fileName,"r")
00013 name = None
00014 dens = None
00015 fractions = {}
00016 for line in file:
00017 line = line.strip("\n")
00018 if len(line.split("\""))==3:
00019 contentName = line.split("\"")[1]
00020 content = line.split("\"")[2].split()
00021 if len(content) == 2:
00022 if not name == None:
00023 result[name] = dens,fractions
00024 name = contentName
00025 dens = content[1]
00026 fractions = {}
00027 elif len(content) == 1:
00028
00029 fractions[getMaterial(contentName,materialMap)] = float(content[0][1:])*0.01
00030
00031 if not name == None:
00032 result[name] = dens,fractions
00033
00034 for material in result:
00035 sum = 0
00036 for fraction in result[material][1]:
00037 sum+= result[material][1][fraction]
00038 if math.fabs(sum - 1.0) > maxDist:
00039 raise StandardError, "Material Fractions do not add up to 100%: "+ material+" "+str(sum)
00040 return result
00041
00042
00043 def getMaterial(material, fileName):
00044 materialMap ={}
00045 file = open(fileName,"r")
00046 for line in file:
00047 line = line.strip("\n")
00048 content = line.split()
00049 if len(content) == 2:
00050 materialMap[content[0]] = content[1]
00051 if material in materialMap:
00052 result = materialMap[material]+":"+material
00053 else:
00054 result = "materials:"+material
00055 return result
00056
00057
00058 def readXML(fileName):
00059 file = open(fileName,'r')
00060 dom = xml.dom.minidom.parse(file)
00061 file.close()
00062 return dom
00063
00064
00065 def getSection(rootNode, name):
00066 result = None
00067 for node in rootNode.childNodes:
00068 if node.nodeName == name:
00069 result = node
00070 if result == None:
00071 raise StandardError, "Could not find: \""+name+"\" in childnodes of the rootNode!"
00072 return result
00073
00074
00075 def getNodes(rootNode, name):
00076 result = {}
00077 for node in rootNode.childNodes:
00078 if node.nodeName == name and node.nodeType == node.ELEMENT_NODE:
00079 for i in range(0,node.attributes.length):
00080 if node.attributes.item(i).name == "name":
00081 result[node.attributes.item(i).nodeValue] = node
00082 return result
00083
00084 def prettierprint(dom):
00085 result = ""
00086 output = dom.toprettyxml()
00087 for line in output.splitlines():
00088 if not line.strip(" \t") == "":
00089 result+= line+"\n"
00090 return result
00091
00092
00093
00094 def getAttributes(node):
00095 result = {};
00096 for i in range(0,node.attributes.length):
00097
00098 result[node.attributes.item(i).name] = node.attributes.item(i).nodeValue
00099 return result
00100
00101
00102
00103 def dokument(domina):
00104 for node in domina.childNodes:
00105 print "NodeName:", node.nodeName,
00106 if node.nodeType == node.ELEMENT_NODE:
00107 print "Typ ELEMENT_NODE"
00108 print getAttributes(node)
00109 elif node.nodeType == node.TEXT_NODE:
00110 print "Typ TEXT_NODE, Content: ", node.nodeValue.strip()
00111 elif node.nodeType == node.COMMENT_NODE:
00112 print "Typ COMMENT_NODE, "
00113
00114
00115
00116
00117 def printMaterials(rootNode):
00118 matNodes = getNodes(rootNode,"CompositeMaterial")
00119 for name in matNodes:
00120 print " "+name+" (dens = "+getAttributes(matNodes[name])["density"]+")"
00121 for fractionNode in matNodes[name].childNodes:
00122 if fractionNode.nodeName == "MaterialFraction":
00123 fractionString = getAttributes(fractionNode)["fraction"]
00124 for materialNode in fractionNode.childNodes:
00125 if materialNode.nodeName == "rMaterial":
00126 fractionString += "\tof "+getAttributes(materialNode)["name"].split(":")[1]
00127 fractionString += "\tfrom "+getAttributes(materialNode)["name"].split(":")[0]
00128 print " |-- "+fractionString
00129
00130
00131 def getMaterialSection(rootNode):
00132 dddef = getSection(rootNode,'DDDefinition')
00133 matSec = getSection(dddef,'MaterialSection')
00134 return matSec
00135
00136
00137
00138
00139 def createCompositeMaterial(doc,rootNode,name, density,fractions,method="mixture by weight", symbol=" "):
00140 newMaterial = doc.createElement("CompositeMaterial")
00141 newMaterial.setAttribute("name",name)
00142 newMaterial.setAttribute("density",density)
00143 newMaterial.setAttribute("method",method)
00144 newMaterial.setAttribute("symbol",symbol)
00145
00146 for fracMaterialName in fractions:
00147 fraction = doc.createElement("MaterialFraction")
00148 fraction.setAttribute("fraction",str(fractions[fracMaterialName]))
00149 newMaterial.appendChild(fraction)
00150 fracMaterial = doc.createElement("rMaterial")
00151 fracMaterial.setAttribute("name",fracMaterialName)
00152 fraction.appendChild(fracMaterial)
00153
00154 exMaterials = getNodes(rootNode,"CompositeMaterial")
00155 if name in exMaterials:
00156 rootNode.replaceChild(newMaterial,exMaterials[name])
00157 else:
00158 rootNode.appendChild(newMaterial)
00159
00160
00161 def main():
00162 optParser = optparse.OptionParser()
00163 optParser.add_option("-t", "--titles", dest="titlesFile",
00164 help="the .titles file to parse (as generated by mixture)", metavar="TITLES")
00165 optParser.add_option("-x", "--xml", dest="xmlFile",
00166 help="the .xml file to parse (must be DDD complient)", metavar="XML")
00167 optParser.add_option("-o", "--output", dest="output",
00168 help="the file to write the new materials into default: materialOutput.xml", metavar="XMLOUT")
00169 optParser.add_option("-m", "--materialMap", dest="materialMap",
00170 help="file containing map of materials not defined in materials.xml. default: material.map", metavar="MMAP")
00171
00172 (options, args) = optParser.parse_args()
00173
00174 if options.titlesFile == None:
00175 raise StandardError, "no .titles File given!"
00176 if options.xmlFile == None:
00177 raise StandardError, "no .xml File given!"
00178 if options.output == None:
00179 options.output = "materialOutput.xml"
00180 if options.materialMap == None:
00181 options.materialMap = "material.map"
00182 theOptions = options
00183
00184 materials = readFractions(options.titlesFile, options.materialMap)
00185
00186 dom = readXML(options.xmlFile)
00187 matSec = getMaterialSection(dom)
00188
00189
00190
00191
00192 for material in materials:
00193 createCompositeMaterial(dom,matSec,material,str(materials[material][0])+"*g/cm3",materials[material][1])
00194
00195
00196
00197 outFile = open(options.output,"w")
00198 outFile.write(prettierprint(dom))
00199 outFile.close()
00200
00201 main()
00202