diff --git a/src/App/Part.cpp b/src/App/Part.cpp index def6bdd090..fe7ced3753 100644 --- a/src/App/Part.cpp +++ b/src/App/Part.cpp @@ -50,6 +50,20 @@ const char* Part::BaseplaneTypes[3] = {"XY-Plane", "XZ-Plane", "YZ-Plane"}; Part::Part(void) { ADD_PROPERTY(Type,("")); + ADD_PROPERTY_TYPE(Material, (), 0, App::Prop_None, "Map with material properties"); + ADD_PROPERTY_TYPE(Meta, (), 0, App::Prop_None, "Map with additional meta information"); + + // create the uuid for the document + Base::Uuid id; + ADD_PROPERTY_TYPE(Id, (""), 0, App::Prop_None, "ID (Part-Number) of the Item"); + ADD_PROPERTY_TYPE(Uid, (id), 0, App::Prop_None, "UUID of the Item"); + + // license stuff + ADD_PROPERTY_TYPE(License, ("CC BY 3.0"), 0, App::Prop_None, "License string of the Item"); + ADD_PROPERTY_TYPE(LicenseURL, ("http://creativecommons.org/licenses/by/3.0/"), 0, App::Prop_None, "URL to the license text/contract"); + // color and apperance + ADD_PROPERTY(Color, (1.0, 1.0, 1.0, 1.0)); // set transparent -> not used + } Part::~Part(void) diff --git a/src/App/Part.h b/src/App/Part.h index c65dc6c6ba..6f95ff92be 100644 --- a/src/App/Part.h +++ b/src/App/Part.h @@ -40,8 +40,43 @@ class AppExport Part : public App::GeoFeatureGroup PROPERTY_HEADER(App::Part); public: + /// type of the part PropertyString Type; + /** @name base properties of all Assembly Items + * This properties corospond mostly to the meta information + * in the App::Document class + */ + //@{ + /// Id e.g. Part number + App::PropertyString Id; + /// unique identifier of the Item + App::PropertyUUID Uid; + /// material descriptons + App::PropertyMap Material; + /// Meta descriptons + App::PropertyMap Meta; + + + /** License string + * Holds the short license string for the Item, e.g. CC-BY + * for the Creative Commons license suit. + */ + App::PropertyString License; + /// License descripton/contract URL + App::PropertyString LicenseURL; + //@} + + /** @name Visual properties */ + //@{ + /** Base color of the Item + If the transparency value is 1.0 + the color or the next hirachy is used + */ + App::PropertyColor Color; + //@} + + /// Constructor Part(void); virtual ~Part(); diff --git a/src/Base/RotationPyImp.cpp b/src/Base/RotationPyImp.cpp index d9bc2f9cef..d5d9687f9a 100644 --- a/src/Base/RotationPyImp.cpp +++ b/src/Base/RotationPyImp.cpp @@ -77,9 +77,16 @@ int RotationPy::PyInit(PyObject* args, PyObject* /*kwd*/) PyErr_Clear(); double angle; if (PyArg_ParseTuple(args, "O!d", &(Base::VectorPy::Type), &o, &angle)) { - // NOTE: The last parameter defines the rotation angle in degree. - getRotationPtr()->setValue(static_cast(o)->value(), Base::toRadians(angle)); - return 0; + // NOTE: The last parameter defines the rotation angle in degree. + getRotationPtr()->setValue(static_cast(o)->value(), Base::toRadians(angle)); + return 0; + } + + PyErr_Clear(); + if (PyArg_ParseTuple(args, "O!d", &(Base::MatrixPy::Type), &o, &angle)) { + // NOTE: The last parameter defines the rotation angle in degree. + getRotationPtr()->setValue(static_cast(o)->value()); + return 0; } PyErr_Clear(); @@ -96,6 +103,43 @@ int RotationPy::PyInit(PyObject* args, PyObject* /*kwd*/) return 0; } + double a11 = 1.0, a12 = 0.0, a13 = 0.0, a14 = 0.0; + double a21 = 0.0, a22 = 1.0, a23 = 0.0, a24 = 0.0; + double a31 = 0.0, a32 = 0.0, a33 = 1.0, a34 = 0.0; + double a41 = 0.0, a42 = 0.0, a43 = 0.0, a44 = 1.0; + + // try read a 4x4 matrix + PyErr_Clear(); + if (PyArg_ParseTuple(args, "dddddddddddddddd", + &a11, &a12, &a13, &a14, + &a21, &a22, &a23, &a24, + &a31, &a32, &a33, &a34, + &a41, &a42, &a43, &a44)) + { + Matrix4D mtx(a11, a12, a13, a14, + a21, a22, a23, a24, + a31, a32, a33, a34, + a41, a42, a43, a44); + getRotationPtr()->setValue(mtx); + return 0; + } + + // try read a 3x3 matrix + PyErr_Clear(); + if (PyArg_ParseTuple(args, "ddddddddd", + &a11, &a12, &a13, + &a21, &a22, &a23, + &a31, &a32, &a33)) + { + Matrix4D mtx(a11, a12, a13, a14, + a21, a22, a23, a24, + a31, a32, a33, a34, + a41, a42, a43, a44); + getRotationPtr()->setValue(mtx); + return 0; + } + + PyErr_Clear(); PyObject *v1, *v2; if (PyArg_ParseTuple(args, "O!O!", &(Base::VectorPy::Type), &v1, @@ -112,7 +156,11 @@ int RotationPy::PyInit(PyObject* args, PyObject* /*kwd*/) "-- four floats (a quaternion)\n" "-- three floats (yaw, pitch, roll)" "-- Vector (rotation axis) and float (rotation angle)\n" - "-- two Vectors (two axes)"); + "-- two Vectors (two axes)\n" + "-- Matrix object\n" + "-- 16 floats (4x4 matrix)\n" + "-- 9 floats (3x3 matrix)\n" + ); return -1; } diff --git a/src/Gui/Tree.cpp b/src/Gui/Tree.cpp index f71de515f1..c56e959642 100644 --- a/src/Gui/Tree.cpp +++ b/src/Gui/Tree.cpp @@ -897,18 +897,20 @@ void DocumentItem::slotResetEdit(const Gui::ViewProviderDocumentObject& v) void DocumentItem::slotNewObject(const Gui::ViewProviderDocumentObject& obj) { - std::string displayName = obj.getObject()->Label.getValue(); - std::string objectName = obj.getObject()->getNameInDocument(); - std::map::iterator it = ObjectMap.find(objectName); - if (it == ObjectMap.end()) { - // cast to non-const object - DocumentObjectItem* item = new DocumentObjectItem( - const_cast(&obj), this); - item->setIcon(0, obj.getIcon()); - item->setText(0, QString::fromUtf8(displayName.c_str())); - ObjectMap[objectName] = item; - } else { - Base::Console().Warning("DocumentItem::slotNewObject: Cannot add view provider twice.\n"); + if (obj.showInTree()){ + std::string displayName = obj.getObject()->Label.getValue(); + std::string objectName = obj.getObject()->getNameInDocument(); + std::map::iterator it = ObjectMap.find(objectName); + if (it == ObjectMap.end()) { + // cast to non-const object + DocumentObjectItem* item = new DocumentObjectItem( + const_cast(&obj), this); + item->setIcon(0, obj.getIcon()); + item->setText(0, QString::fromUtf8(displayName.c_str())); + ObjectMap[objectName] = item; + }else { + Base::Console().Warning("DocumentItem::slotNewObject: Cannot add view provider twice.\n"); + } } } diff --git a/src/Gui/ViewProvider.h b/src/Gui/ViewProvider.h index 694d72b271..02e8f89c54 100644 --- a/src/Gui/ViewProvider.h +++ b/src/Gui/ViewProvider.h @@ -108,7 +108,7 @@ public: { return std::vector(); } /** @name Selection handling - * This group of methodes do the selection handling. + * This group of methods do the selection handling. * Here you can define how the selection for your ViewProfider * works. */ @@ -165,6 +165,11 @@ public: /** Check whether the object can be removed from the view provider by drag and drop */ virtual bool canDragObject(App::DocumentObject*) const { return true; } + /** Tell the tree view if this object should apear there */ + virtual bool showInTree() const + { + return true; + } /** Remove a child from the view provider by drag and drop */ virtual void dragObject(App::DocumentObject*) { } @@ -190,7 +195,7 @@ public: //@} /** update the content of the ViewProvider - * this method have to implement the recalcualtion + * this method have to implement the recalculation * of the ViewProvider. There are different reasons to * update. E.g. only the view attribute has changed, or * the data has manipulated. diff --git a/src/Mod/Assembly/App/Item.cpp b/src/Mod/Assembly/App/Item.cpp index 3abef9e775..b9b743a6e1 100644 --- a/src/Mod/Assembly/App/Item.cpp +++ b/src/Mod/Assembly/App/Item.cpp @@ -43,6 +43,8 @@ PROPERTY_SOURCE_ABSTRACT(Assembly::Item, App::GeoFeature) Item::Item() { + ADD_PROPERTY_TYPE(Meta, (), 0, App::Prop_None, "Map with additional meta information"); + } short Item::mustExecute() const diff --git a/src/Mod/Assembly/App/Item.h b/src/Mod/Assembly/App/Item.h index ac9a619417..7a9fe978ab 100644 --- a/src/Mod/Assembly/App/Item.h +++ b/src/Mod/Assembly/App/Item.h @@ -39,7 +39,10 @@ class AssemblyExport Item : public App::GeoFeature public: Item(); - ~Item() {}; + ~Item() {}; + + /// Meta descriptons + App::PropertyMap Meta; /** @name methods override feature */ //@{ diff --git a/src/Mod/Assembly/App/Product.cpp b/src/Mod/Assembly/App/Product.cpp index 1e81443728..7702f17ca6 100644 --- a/src/Mod/Assembly/App/Product.cpp +++ b/src/Mod/Assembly/App/Product.cpp @@ -45,13 +45,6 @@ PROPERTY_SOURCE(Assembly::Product, Assembly::Item) Product::Product() { ADD_PROPERTY(Items,(0)); - ADD_PROPERTY_TYPE(CreatedBy,(""),0,App::Prop_None,"The creator of the Item"); - ADD_PROPERTY_TYPE(CreationDate,(Base::TimeInfo::currentDateTimeString()),0,App::Prop_ReadOnly,"Date of creation"); - ADD_PROPERTY_TYPE(LastModifiedBy,(""),0,App::Prop_None,0); - ADD_PROPERTY_TYPE(LastModifiedDate,("Unknown"),0,App::Prop_ReadOnly,"Date of last modification"); - ADD_PROPERTY_TYPE(Company,(""),0,App::Prop_None,"Additional tag to save the the name of the company"); - ADD_PROPERTY_TYPE(Comment,(""),0,App::Prop_None,"Additional tag to save a comment"); - ADD_PROPERTY_TYPE(Meta,(),0,App::Prop_None,"Map with additional meta information"); ADD_PROPERTY_TYPE(Material,(),0,App::Prop_None,"Map with material properties"); // create the uuid for the document Base::Uuid id; diff --git a/src/Mod/Assembly/App/Product.h b/src/Mod/Assembly/App/Product.h index d71cab2965..cee0291ebb 100644 --- a/src/Mod/Assembly/App/Product.h +++ b/src/Mod/Assembly/App/Product.h @@ -52,29 +52,16 @@ public: App::PropertyString Id; /// unique identifier of the Item App::PropertyUUID Uid; - /// long description of the Item - App::PropertyString Description ; - /// creators name (utf-8) - App::PropertyString CreatedBy; - App::PropertyString CreationDate; - /// user last modified the document - App::PropertyString LastModifiedBy; - App::PropertyString LastModifiedDate; - /// company name UTF8(optional) - App::PropertyString Company; - /// long comment or description (UTF8 with line breaks) - App::PropertyString Comment; + /// material descriptons + App::PropertyMap Material; + /** License string - * Holds the short license string for the Item, e.g. CC-BY - * for the Creative Commons license suit. - */ + * Holds the short license string for the Item, e.g. CC-BY + * for the Creative Commons license suit. + */ App::PropertyString License; /// License descripton/contract URL App::PropertyString LicenseURL; - /// Meta descriptons - App::PropertyMap Meta; - /// Meta descriptons - App::PropertyMap Material; //@} /** @name Visual properties */ diff --git a/src/Mod/Assembly/Gui/ViewProviderProduct.cpp b/src/Mod/Assembly/Gui/ViewProviderProduct.cpp index 7b7a8217d4..61ac27ad7a 100644 --- a/src/Mod/Assembly/Gui/ViewProviderProduct.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderProduct.cpp @@ -35,7 +35,7 @@ #include #include -#include +#include //#include using namespace AssemblyGui; @@ -94,9 +94,26 @@ std::vector ViewProviderProduct::getDisplayModes(void) const std::vector ViewProviderProduct::claimChildren(void)const { - std::vector temp(static_cast(getObject())->Items.getValues()); - return temp; + std::vector returnVector; + + // do not adopt the ref-objects as child, rather use the target objects if any + // that makes the ProductRefs invisibly in the tree! + const std::vector &items = static_cast(getObject())->Items.getValues(); + for (std::vector::const_iterator it = items.begin(); it != items.end(); ++it) + { + if ((*it)->getTypeId() == Assembly::ProductRef::getClassTypeId()) + { + App::DocumentObject *obj = static_cast (*it)->Item.getValue(); + if (obj) + { + returnVector.push_back(obj); + } + } + + } + + return returnVector; } std::vector ViewProviderProduct::claimChildren3D(void)const diff --git a/src/Mod/Assembly/Gui/ViewProviderProductRef.cpp b/src/Mod/Assembly/Gui/ViewProviderProductRef.cpp index 482af0991c..d87127bfec 100644 --- a/src/Mod/Assembly/Gui/ViewProviderProductRef.cpp +++ b/src/Mod/Assembly/Gui/ViewProviderProductRef.cpp @@ -94,9 +94,15 @@ std::vector ViewProviderProductRef::getDisplayModes(void) const std::vector ViewProviderProductRef::claimChildren(void)const { + App::DocumentObject * obj = static_cast(getObject())->Item.getValue(); + if (obj){ std::vector ret(1); - ret[0] = static_cast(getObject())->Item.getValue(); + ret[0] = obj; return ret; + } + else{ + return std::vector(); + } } std::vector ViewProviderProductRef::claimChildren3D(void)const diff --git a/src/Mod/Assembly/Gui/ViewProviderProductRef.h b/src/Mod/Assembly/Gui/ViewProviderProductRef.h index cd73902a96..200b780a5d 100644 --- a/src/Mod/Assembly/Gui/ViewProviderProductRef.h +++ b/src/Mod/Assembly/Gui/ViewProviderProductRef.h @@ -50,6 +50,10 @@ public: virtual std::vector claimChildren(void)const; virtual std::vector claimChildren3D(void)const; + virtual bool showInTree() const + { + return false; + } virtual void setupContextMenu(QMenu* menu, QObject* receiver, const char* member); virtual bool setEdit(int ModNum); diff --git a/src/Mod/Import/App/CMakeLists.txt b/src/Mod/Import/App/CMakeLists.txt index 6e89fe0ab7..2672c135cd 100644 --- a/src/Mod/Import/App/CMakeLists.txt +++ b/src/Mod/Import/App/CMakeLists.txt @@ -61,6 +61,7 @@ SET(SCL_Resources automotive_design.py # AP214e3 ifc2x3.py # IFC ifc4.py # IFC 4 + PlmXmlParser.py ) SOURCE_GROUP("SCL" FILES ${SCL_Resources}) diff --git a/src/Mod/Import/App/PlmXmlParser.py b/src/Mod/Import/App/PlmXmlParser.py index ae8b2e116b..32a392366e 100644 --- a/src/Mod/Import/App/PlmXmlParser.py +++ b/src/Mod/Import/App/PlmXmlParser.py @@ -20,40 +20,133 @@ #* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * #* USA * #* * -#* Juergen Riegel 2002 * +#* Juergen Riegel 2015 * #***************************************************************************/ import xml.etree.ElementTree as ET +FreeCAD_On = False +FreeCAD_Doc = None +FreeCAD_ObjList = [] + def ParseUserData(element): - if element: - res = {} - for value in element.findall('{http://www.plmxml.org/Schemas/PLMXMLSchema}UserValue'): + 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 - return None + return res def addPart(partElement): - #print partElement.attrib - pass + 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): - #print asmElement.attrib - pass + 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): - #print refElement.attrib - pass + 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') - tree = ET.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') - ParseUserData(ProductDef.find('{http://www.plmxml.org/Schemas/PLMXMLSchema}UserData')) + res = ParseUserData(ProductDef.find('{http://www.plmxml.org/Schemas/PLMXMLSchema}UserData')) InstanceGraph = ProductDef.find('{http://www.plmxml.org/Schemas/PLMXMLSchema}InstanceGraph') @@ -87,7 +180,7 @@ def main(): addPart(child) continue if child.attrib['type'] == 'assembly' : - addPart(child) + addAssembly(child) continue print "Unknown Part type:",child else: diff --git a/src/Mod/Import/Init.py b/src/Mod/Import/Init.py index 653466da3e..510bf10b15 100644 --- a/src/Mod/Import/Init.py +++ b/src/Mod/Import/Init.py @@ -31,4 +31,4 @@ #FreeCAD.addImportType("STEP 214 (*.step *.stp)","ImportGui") #FreeCAD.addExportType("STEP 214 (*.step *.stp)","ImportGui") #FreeCAD.addExportType("IGES files (*.iges *.igs)","ImportGui") -FreeCAD.addExportType("PLMXML files (*.plmxml)","Import") +FreeCAD.addImportType("PLMXML files (*.plmxml)","PlmXmlParser")