212 lines
7.8 KiB
Python
212 lines
7.8 KiB
Python
# PlmXmlParser
|
|
# ***************************************************************************
|
|
# * Copyright (c) 2015 Juergen Riegel <FreeCAD@juergen-riegel.net> *
|
|
# * *
|
|
# * This file is part of the FreeCAD CAx development system. *
|
|
# * *
|
|
# * This program is free software; you can redistribute it and/or modify *
|
|
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
|
# * as published by the Free Software Foundation; either version 2 of *
|
|
# * the License, or (at your option) any later version. *
|
|
# * for detail see the LICENCE text file. *
|
|
# * *
|
|
# * FreeCAD is distributed in the hope that it will be useful, *
|
|
# * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
# * GNU Lesser General Public License for more details. *
|
|
# * *
|
|
# * You should have received a copy of the GNU Library General Public *
|
|
# * License along with FreeCAD; if not, write to the Free Software *
|
|
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
|
# * USA *
|
|
# * *
|
|
# ***************************************************************************/
|
|
|
|
|
|
import xml.etree.ElementTree as ET
|
|
|
|
FreeCAD_On = False
|
|
FreeCAD_Doc = None
|
|
FreeCAD_ObjList = []
|
|
|
|
|
|
def ParseUserData(element):
|
|
res = {}
|
|
for i in element.findall("{http://www.plmxml.org/Schemas/PLMXMLSchema}UserData"):
|
|
for value in i.findall("{http://www.plmxml.org/Schemas/PLMXMLSchema}UserValue"):
|
|
res[value.attrib["title"]] = value.attrib["value"]
|
|
return res
|
|
|
|
|
|
def addPart(partElement):
|
|
global FreeCAD_On, FreeCAD_Doc, FreeCAD_ObjList
|
|
print("=== Part ======================================================")
|
|
name = partElement.attrib["name"]
|
|
id = partElement.attrib["id"]
|
|
userData = ParseUserData(partElement)
|
|
|
|
bound = partElement.find("{http://www.plmxml.org/Schemas/PLMXMLSchema}Bound")
|
|
print(bound.attrib["values"])
|
|
|
|
representation = partElement.find("{http://www.plmxml.org/Schemas/PLMXMLSchema}Representation")
|
|
format = representation.attrib["format"]
|
|
location = representation.attrib["location"]
|
|
|
|
print(id, name, userData, format, location)
|
|
if FreeCAD_On:
|
|
import FreeCAD, Assembly
|
|
|
|
print("Create Reference")
|
|
partObject = FreeCAD_Doc.addObject("App::Part", id)
|
|
FreeCAD_ObjList.append(partObject)
|
|
partObject.Label = name
|
|
partObject.Meta = userData
|
|
|
|
|
|
def addAssembly(asmElement):
|
|
global FreeCAD_On, FreeCAD_Doc, FreeCAD_ObjList
|
|
print("=== Assembly ======================================================")
|
|
userData = ParseUserData(asmElement)
|
|
name = asmElement.attrib["name"]
|
|
id = asmElement.attrib["id"]
|
|
instanceRefs = asmElement.attrib["instanceRefs"]
|
|
userData["instanceRefs"] = instanceRefs
|
|
|
|
print(id, name, instanceRefs, userData)
|
|
if FreeCAD_On:
|
|
import FreeCAD, Assembly
|
|
|
|
print("Create Reference")
|
|
admObject = FreeCAD_Doc.addObject("Assembly::Product", id)
|
|
FreeCAD_ObjList.append(admObject)
|
|
admObject.Label = name
|
|
admObject.Meta = userData
|
|
|
|
|
|
def addReference(refElement):
|
|
global FreeCAD_On, FreeCAD_Doc, FreeCAD_ObjList
|
|
print("=== Reference ======================================================")
|
|
userData = ParseUserData(refElement)
|
|
partRef = refElement.attrib["partRef"][1:]
|
|
userData["partRef"] = partRef
|
|
id = refElement.attrib["id"]
|
|
name = refElement.attrib["name"]
|
|
transform = refElement.find("{http://www.plmxml.org/Schemas/PLMXMLSchema}Transform")
|
|
mtrx = [float(i) for i in transform.text.split(" ")]
|
|
print(mtrx)
|
|
print(id, name, partRef)
|
|
|
|
if FreeCAD_On:
|
|
import FreeCAD, Assembly
|
|
|
|
print("Create Reference")
|
|
refObject = FreeCAD_Doc.addObject("Assembly::ProductRef", id)
|
|
FreeCAD_ObjList.append(refObject)
|
|
refObject.Label = name
|
|
refObject.Meta = userData
|
|
|
|
|
|
def resolveRefs():
|
|
global FreeCAD_On, FreeCAD_Doc, FreeCAD_ObjList
|
|
print("=== Resolve References ======================================================")
|
|
if FreeCAD_On:
|
|
for i in FreeCAD_ObjList:
|
|
if i.TypeId == "Assembly::Product":
|
|
objectList = []
|
|
for l in i.Meta["instanceRefs"].split(" "):
|
|
objectList.append(FreeCAD_Doc.getObject(l))
|
|
i.Items = objectList
|
|
if i.TypeId == "Assembly::ProductRef":
|
|
i.Item = FreeCAD_Doc.getObject(i.Meta["partRef"])
|
|
|
|
|
|
def open(fileName):
|
|
"""called when freecad opens an PlmXml file"""
|
|
global FreeCAD_On, FreeCAD_Doc
|
|
import FreeCAD, os
|
|
|
|
docname = os.path.splitext(os.path.basename(fileName))[0]
|
|
doc = FreeCAD.newDocument(docname)
|
|
message = 'Started with opening of "' + fileName + '" file\n'
|
|
FreeCAD.Console.PrintMessage(message)
|
|
FreeCAD_Doc = doc
|
|
FreeCAD_On = True
|
|
parse(fileName)
|
|
resolveRefs()
|
|
|
|
|
|
def insert(filename, docname):
|
|
"""called when freecad imports an PlmXml file"""
|
|
global FreeCAD_On, FreeCAD_Doc
|
|
import FreeCAD
|
|
|
|
FreeCAD.setActiveDocument(docname)
|
|
doc = FreeCAD.getDocument(docname)
|
|
FreeCAD.Console.PrintMessage('Started import of "' + filename + '" file')
|
|
FreeCAD_Doc = doc
|
|
FreeCAD_On = True
|
|
parse(fileName)
|
|
resolveRefs()
|
|
|
|
|
|
def main():
|
|
parse("../../../../data/tests/Jt/Engine/2_Cylinder_Engine3.plmxml")
|
|
|
|
|
|
def parse(fileName):
|
|
|
|
tree = ET.parse(fileName)
|
|
root = tree.getroot()
|
|
ProductDef = root.find("{http://www.plmxml.org/Schemas/PLMXMLSchema}ProductDef")
|
|
|
|
res = ParseUserData(ProductDef.find("{http://www.plmxml.org/Schemas/PLMXMLSchema}UserData"))
|
|
|
|
InstanceGraph = ProductDef.find("{http://www.plmxml.org/Schemas/PLMXMLSchema}InstanceGraph")
|
|
|
|
# get all the special elements we can read
|
|
Instances = InstanceGraph.findall("{http://www.plmxml.org/Schemas/PLMXMLSchema}Instance")
|
|
Parts = InstanceGraph.findall("{http://www.plmxml.org/Schemas/PLMXMLSchema}Part")
|
|
ProductInstances = InstanceGraph.findall(
|
|
"{http://www.plmxml.org/Schemas/PLMXMLSchema}ProductInstance"
|
|
)
|
|
ProductRevisionViews = InstanceGraph.findall(
|
|
"{http://www.plmxml.org/Schemas/PLMXMLSchema}ProductRevisionView"
|
|
)
|
|
|
|
instanceTypesSet = set()
|
|
for child in InstanceGraph:
|
|
instanceTypesSet.add(child.tag)
|
|
print("All types below the InstanceGraph:")
|
|
for i in instanceTypesSet:
|
|
print(i)
|
|
print("")
|
|
|
|
print(len(Instances), "\t{http://www.plmxml.org/Schemas/PLMXMLSchema}Instance")
|
|
print(len(Parts), "\t{http://www.plmxml.org/Schemas/PLMXMLSchema}Part")
|
|
print(len(ProductInstances), "\t{http://www.plmxml.org/Schemas/PLMXMLSchema}ProductInstance")
|
|
print(
|
|
len(ProductRevisionViews),
|
|
"\t{http://www.plmxml.org/Schemas/PLMXMLSchema}ProductRevisionView",
|
|
)
|
|
|
|
# handle all instances
|
|
for child in Instances:
|
|
addReference(child)
|
|
|
|
# handle the parts and assemblies
|
|
for child in Parts:
|
|
if "type" in child.attrib:
|
|
if child.attrib["type"] == "solid":
|
|
addPart(child)
|
|
continue
|
|
if child.attrib["type"] == "assembly":
|
|
addAssembly(child)
|
|
continue
|
|
print("Unknown Part type:", child)
|
|
else:
|
|
print("not Type in Part", child)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|