diff --git a/src/Mod/Import/App/AppImport.cpp b/src/Mod/Import/App/AppImport.cpp index cd6c6e484..d08a3fc8c 100644 --- a/src/Mod/Import/App/AppImport.cpp +++ b/src/Mod/Import/App/AppImport.cpp @@ -32,17 +32,13 @@ #include "StepShapePy.h" #include "StepShape.h" +namespace Import { + extern PyObject* initModule(); +} -/* registration table */ -extern struct PyMethodDef Import_Import_methods[]; - -PyDoc_STRVAR(module_doc, -"This module is about import/export files formates.\n" -"\n"); -extern "C" { -void ImportExport initImport() +PyMODINIT_FUNC initImport() { - PyObject* importModule = Py_InitModule3("Import", Import_Import_methods, module_doc); /* mod name, table ptr */ + PyObject* importModule = Import::initModule(); try { Base::Interpreter().loadModule("Part"); @@ -53,13 +49,10 @@ void ImportExport initImport() } // add mesh elements - Base::Interpreter().addType(&Import::StepShapePy ::Type,importModule,"StepShape"); + Base::Interpreter().addType(&Import::StepShapePy ::Type, importModule, "StepShape"); // init Type system //Import::StepShape ::init(); Base::Console().Log("Loading Import module... done\n"); } - - -} // extern "C" { diff --git a/src/Mod/Import/App/AppImportPy.cpp b/src/Mod/Import/App/AppImportPy.cpp index a3326d1bf..05673a46c 100644 --- a/src/Mod/Import/App/AppImportPy.cpp +++ b/src/Mod/Import/App/AppImportPy.cpp @@ -48,6 +48,9 @@ # include #endif +#include +#include + #include "ImportOCAF.h" #include #include @@ -60,125 +63,250 @@ #include #include -/* module functions */ -static PyObject * importer(PyObject *self, PyObject *args) +namespace Import { +class Module : public Py::ExtensionModule { - char* Name; - char* DocName=0; - if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName)) - return NULL; - std::string Utf8Name = std::string(Name); - PyMem_Free(Name); - std::string name8bit = Part::encodeFilename(Utf8Name); +public: + Module() : Py::ExtensionModule("Import") + { + add_varargs_method("open",&Module::importer, + "open(string) -- Open the file and create a new document." + ); + add_varargs_method("insert",&Module::importer, + "insert(string,string) -- Insert the file into the given document." + ); + add_varargs_method("export",&Module::exporter, + "export(list,string) -- Export a list of objects into a single file." + ); + initialize("This module is the Import module."); // register with Python + } - PY_TRY { - //Base::Console().Log("Insert in Part with %s",Name); - Base::FileInfo file(Utf8Name.c_str()); + virtual ~Module() {} - App::Document *pcDoc = 0; - if (DocName) { - pcDoc = App::GetApplication().getDocument(DocName); - } - if (!pcDoc) { - pcDoc = App::GetApplication().newDocument("Unnamed"); - } +private: + Py::Object importer(const Py::Tuple& args) + { + char* Name; + char* DocName=0; + if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) + throw Py::Exception(); - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); + std::string Utf8Name = std::string(Name); + PyMem_Free(Name); + std::string name8bit = Part::encodeFilename(Utf8Name); - if (file.hasExtension("stp") || file.hasExtension("step")) { - try { - STEPCAFControl_Reader aReader; - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "cannot read STEP file"); - return 0; + try { + //Base::Console().Log("Insert in Part with %s",Name); + Base::FileInfo file(Utf8Name.c_str()); + + App::Document *pcDoc = 0; + if (DocName) { + pcDoc = App::GetApplication().getDocument(DocName); + } + if (!pcDoc) { + pcDoc = App::GetApplication().newDocument("Unnamed"); + } + + Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) hDoc; + hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); + + if (file.hasExtension("stp") || file.hasExtension("step")) { + try { + STEPCAFControl_Reader aReader; + aReader.SetColorMode(true); + aReader.SetNameMode(true); + aReader.SetLayerMode(true); + if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { + throw Py::Exception(PyExc_IOError, "cannot read STEP file"); + } + + Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); + aReader.Reader().WS()->MapReader()->SetProgress(pi); + pi->NewScope(100, "Reading STEP file..."); + pi->Show(); + aReader.Transfer(hDoc); + pi->EndScope(); } + catch (OSD_Exception) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + Base::Console().Error("%s\n", e->GetMessageString()); + Base::Console().Message("Try to load STEP file without colors...\n"); - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.Reader().WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading STEP file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load STEP file without colors...\n"); - - Part::ImportStepParts(pcDoc,Utf8Name.c_str()); - pcDoc->recompute(); - } - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES"); - - try { - IGESControl_Controller::Init(); - IGESCAFControl_Reader aReader; - // http://www.opencascade.org/org/forum/thread_20603/?forum=3 - aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true) - ? Standard_True : Standard_False); - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "cannot read IGES file"); - return 0; + Part::ImportStepParts(pcDoc,Utf8Name.c_str()); + pcDoc->recompute(); } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading IGES file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load IGES file without colors...\n"); + else if (file.hasExtension("igs") || file.hasExtension("iges")) { + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES"); - Part::ImportIgesParts(pcDoc,Utf8Name.c_str()); - pcDoc->recompute(); + try { + IGESControl_Controller::Init(); + IGESCAFControl_Reader aReader; + // http://www.opencascade.org/org/forum/thread_20603/?forum=3 + aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true) + ? Standard_True : Standard_False); + aReader.SetColorMode(true); + aReader.SetNameMode(true); + aReader.SetLayerMode(true); + if (aReader.ReadFile((Standard_CString)(name8bit.c_str())) != IFSelect_RetDone) { + throw Py::Exception(PyExc_IOError, "cannot read IGES file"); + } + + Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); + aReader.WS()->MapReader()->SetProgress(pi); + pi->NewScope(100, "Reading IGES file..."); + pi->Show(); + aReader.Transfer(hDoc); + pi->EndScope(); + } + catch (OSD_Exception) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + Base::Console().Error("%s\n", e->GetMessageString()); + Base::Console().Message("Try to load IGES file without colors...\n"); + + Part::ImportIgesParts(pcDoc,Utf8Name.c_str()); + pcDoc->recompute(); + } + } + else { + throw Py::Exception(Base::BaseExceptionFreeCADError, "no supported file format"); } - } - else { - PyErr_SetString(Base::BaseExceptionFreeCADError, "no supported file format"); - return 0; - } #if 1 - Import::ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure()); - ocaf.loadShapes(); + Import::ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure()); + ocaf.loadShapes(); #else - Import::ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure()); - xcaf.loadShapes(); + Import::ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure()); + xcaf.loadShapes(); #endif - pcDoc->recompute(); + pcDoc->recompute(); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Py::Exception(Base::BaseExceptionFreeCADError, e->GetMessageString()); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + return Py::None(); } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; + Py::Object exporter(const Py::Tuple& args) + { + PyObject* object; + char* Name; + if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name)) + throw Py::Exception(); + + std::string Utf8Name = std::string(Name); + PyMem_Free(Name); + std::string name8bit = Part::encodeFilename(Utf8Name); + + try { + Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) hDoc; + hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); + Import::ExportOCAF ocaf(hDoc); + + Py::Sequence list(object); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + PyObject* item = (*it).ptr(); + if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { + App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); + if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + Part::Feature* part = static_cast(obj); + std::vector colors; + ocaf.saveShape(part, colors); + } + else { + Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); + } + } + else if (PyTuple_Check(item) && PyTuple_Size(item) == 2) { + Py::Tuple tuple(*it); + Py::Object item0 = tuple.getItem(0); + Py::Object item1 = tuple.getItem(1); + if (PyObject_TypeCheck(item0.ptr(), &(App::DocumentObjectPy::Type))) { + App::DocumentObject* obj = static_cast(item0.ptr())->getDocumentObjectPtr(); + if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + Part::Feature* part = static_cast(obj); + App::PropertyColorList colors; + colors.setPyObject(item1.ptr()); + ocaf.saveShape(part, colors.getValues()); + } + else { + Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); + } + } + } + } + + Base::FileInfo file(Utf8Name.c_str()); + if (file.hasExtension("stp") || file.hasExtension("step")) { + //Interface_Static::SetCVal("write.step.schema", "AP214IS"); + STEPCAFControl_Writer writer; + writer.Transfer(hDoc, STEPControl_AsIs); + + // edit STEP header +#if OCC_VERSION_HEX >= 0x060500 + APIHeaderSection_MakeHeader makeHeader(writer.ChangeWriter().Model()); +#else + APIHeaderSection_MakeHeader makeHeader(writer.Writer().Model()); +#endif + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("STEP"); + + makeHeader.SetName(new TCollection_HAsciiString((const Standard_CString)Utf8Name.c_str())); + makeHeader.SetAuthorValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Author", "Author").c_str())); + makeHeader.SetOrganizationValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Company").c_str())); + makeHeader.SetOriginatingSystem(new TCollection_HAsciiString(App::GetApplication().getExecutableName())); + makeHeader.SetDescriptionValue(1, new TCollection_HAsciiString("FreeCAD Model")); + IFSelect_ReturnStatus ret = writer.Write(name8bit.c_str()); + if (ret == IFSelect_RetError || ret == IFSelect_RetFail || ret == IFSelect_RetStop) { + PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); + throw Py::Exception(); + } + } + else if (file.hasExtension("igs") || file.hasExtension("iges")) { + IGESControl_Controller::Init(); + IGESCAFControl_Writer writer; + IGESData_GlobalSection header = writer.Model()->GlobalSection(); + header.SetAuthorName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.author"))); + header.SetCompanyName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.company"))); + header.SetSendName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.product"))); + writer.Model()->SetGlobalSection(header); + writer.Transfer(hDoc); + Standard_Boolean ret = writer.Write(name8bit.c_str()); + if (!ret) { + PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); + throw Py::Exception(); + } + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Py::Exception(Base::BaseExceptionFreeCADError, e->GetMessageString()); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + + return Py::None(); } - PY_CATCH +}; - Py_Return; -} - -static PyObject * open(PyObject *self, PyObject *args) +PyObject* initModule() { - return importer(self, args); + return (new Module)->module().ptr(); } +} // namespace Import + +/* module functions */ + static PyObject * exporter(PyObject *self, PyObject *args) { PyObject* object; @@ -279,14 +407,3 @@ static PyObject * exporter(PyObject *self, PyObject *args) Py_Return; } - -/* registration table */ -struct PyMethodDef Import_Import_methods[] = { - {"open" ,open ,METH_VARARGS, - "open(string) -- Open the file and create a new document."}, - {"insert" ,importer ,METH_VARARGS, - "insert(string,string) -- Insert the file into the given document."}, - {"export" ,exporter ,METH_VARARGS, - "export(list,string) -- Export a list of objects into a single file."}, - {NULL, NULL} /* end of table marker */ -}; diff --git a/src/Mod/Import/Gui/AppImportGui.cpp b/src/Mod/Import/Gui/AppImportGui.cpp index 55cd2fae8..9c5bc6cfb 100644 --- a/src/Mod/Import/Gui/AppImportGui.cpp +++ b/src/Mod/Import/Gui/AppImportGui.cpp @@ -39,17 +39,17 @@ void CreateImportCommands(void); -/* registration table */ -extern struct PyMethodDef ImportGui_Import_methods[]; +namespace ImportGui { +extern PyObject* initModule(); +} -extern "C" { -void ImportGuiExport initImportGui() +PyMODINIT_FUNC initImportGui() { if (!Gui::Application::Instance) { PyErr_SetString(PyExc_ImportError, "Cannot load Gui module in console application."); return; } - (void) Py_InitModule("ImportGui", ImportGui_Import_methods); /* mod name, table ptr */ + (void)ImportGui::initModule(); Base::Console().Log("Loading GUI of Import module... done\n"); try { @@ -63,5 +63,3 @@ void ImportGuiExport initImportGui() CreateImportCommands(); ImportGui::Workbench::init(); } - -} // extern "C" { diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index 3321efe1e..57987b0e0 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -68,6 +68,9 @@ # endif #endif +#include +#include + #include #include #include @@ -83,228 +86,6 @@ #include #include -class ImportOCAFExt : public Import::ImportOCAF -{ -public: - ImportOCAFExt(Handle_TDocStd_Document h, App::Document* d, const std::string& name) - : ImportOCAF(h, d, name) - { - } - -private: - void applyColors(Part::Feature* part, const std::vector& colors) - { - Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); - if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { - static_cast(vp)->ShapeColor.setValue(colors.front()); - static_cast(vp)->DiffuseColor.setValues(colors); - } - } -}; - -/* module functions */ - -static PyObject * importer(PyObject *self, PyObject *args) -{ - char* Name; - char* DocName=0; - if (!PyArg_ParseTuple(args, "et|s","utf-8",&Name,&DocName)) - return 0; - std::string Utf8Name = std::string(Name); - PyMem_Free(Name); - std::string name8bit = Part::encodeFilename(Utf8Name); - - PY_TRY { - //Base::Console().Log("Insert in Part with %s",Name); - Base::FileInfo file(Utf8Name.c_str()); - - App::Document *pcDoc = 0; - if (DocName) { - pcDoc = App::GetApplication().getDocument(DocName); - } - if (!pcDoc) { - pcDoc = App::GetApplication().newDocument("Unnamed"); - } - - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - - if (file.hasExtension("stp") || file.hasExtension("step")) { - try { - STEPCAFControl_Reader aReader; - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((const char*)name8bit.c_str()) != IFSelect_RetDone) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "cannot read STEP file"); - return 0; - } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.Reader().WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading STEP file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load STEP file without colors...\n"); - - Part::ImportStepParts(pcDoc,Utf8Name.c_str()); - pcDoc->recompute(); - } - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES"); - - try { - IGESControl_Controller::Init(); - IGESCAFControl_Reader aReader; - // http://www.opencascade.org/org/forum/thread_20603/?forum=3 - aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true) - ? Standard_True : Standard_False); - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((const char*)name8bit.c_str()) != IFSelect_RetDone) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "cannot read IGES file"); - return 0; - } - - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading IGES file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - catch (OSD_Exception) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - Base::Console().Error("%s\n", e->GetMessageString()); - Base::Console().Message("Try to load IGES file without colors...\n"); - - Part::ImportIgesParts(pcDoc,Utf8Name.c_str()); - pcDoc->recompute(); - } - } - else { - PyErr_SetString(Base::BaseExceptionFreeCADError, "no supported file format"); - return 0; - } - - ImportOCAFExt ocaf(hDoc, pcDoc, file.fileNamePure()); - ocaf.loadShapes(); - pcDoc->recompute(); - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } - PY_CATCH - - Py_Return; -} - -static PyObject * open(PyObject *self, PyObject *args) -{ - return importer(self, args); -} - -static PyObject * exporter(PyObject *self, PyObject *args) -{ - PyObject* object; - char* Name; - if (!PyArg_ParseTuple(args, "Oet",&object,"utf-8",&Name)) - return NULL; - std::string Utf8Name = std::string(Name); - PyMem_Free(Name); - std::string name8bit = Part::encodeFilename(Utf8Name); - - PY_TRY { - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - Import::ExportOCAF ocaf(hDoc); - - Py::Sequence list(object); - for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { - PyObject* item = (*it).ptr(); - if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { - App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); - if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { - Part::Feature* part = static_cast(obj); - std::vector colors; - Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); - if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { - colors = static_cast(vp)->DiffuseColor.getValues(); - if (colors.empty()) - colors.push_back(static_cast(vp)->ShapeColor.getValue()); - } - ocaf.saveShape(part, colors); - } - else { - Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); - } - } - } - - Base::FileInfo file(Utf8Name.c_str()); - if (file.hasExtension("stp") || file.hasExtension("step")) { - //Interface_Static::SetCVal("write.step.schema", "AP214IS"); - STEPCAFControl_Writer writer; - writer.Transfer(hDoc, STEPControl_AsIs); - - // edit STEP header -#if OCC_VERSION_HEX >= 0x060500 - APIHeaderSection_MakeHeader makeHeader(writer.ChangeWriter().Model()); -#else - APIHeaderSection_MakeHeader makeHeader(writer.Writer().Model()); -#endif - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("STEP"); - - makeHeader.SetName(new TCollection_HAsciiString((const Standard_CString)(Utf8Name.c_str()))); - makeHeader.SetAuthorValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Author", "Author").c_str())); - makeHeader.SetOrganizationValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Company").c_str())); - makeHeader.SetOriginatingSystem(new TCollection_HAsciiString(App::GetApplication().getExecutableName())); - makeHeader.SetDescriptionValue(1, new TCollection_HAsciiString("FreeCAD Model")); - IFSelect_ReturnStatus ret = writer.Write((const char*)name8bit.c_str()); - if (ret == IFSelect_RetError || ret == IFSelect_RetFail || ret == IFSelect_RetStop) { - PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); - return 0; - } - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - IGESControl_Controller::Init(); - IGESCAFControl_Writer writer; - IGESData_GlobalSection header = writer.Model()->GlobalSection(); - header.SetAuthorName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.author"))); - header.SetCompanyName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.company"))); - header.SetSendName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.product"))); - writer.Model()->SetGlobalSection(header); - writer.Transfer(hDoc); - Standard_Boolean ret = writer.Write((const char*)name8bit.c_str()); - if (!ret) { - PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); - return 0; - } - } - } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } - PY_CATCH - - Py_Return; -} - #include #include #include @@ -483,109 +264,343 @@ void OCAFBrowser::load(const TDF_Label& label, QTreeWidgetItem* item, const QStr } } -static PyObject * ocaf(PyObject *self, PyObject *args) +class ImportOCAFExt : public Import::ImportOCAF { - const char* Name; - if (!PyArg_ParseTuple(args, "s",&Name)) - return 0; +public: + ImportOCAFExt(Handle_TDocStd_Document h, App::Document* d, const std::string& name) + : ImportOCAF(h, d, name) + { + } - PY_TRY { - //Base::Console().Log("Insert in Part with %s",Name); - Base::FileInfo file(Name); +private: + void applyColors(Part::Feature* part, const std::vector& colors) + { + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { + static_cast(vp)->ShapeColor.setValue(colors.front()); + static_cast(vp)->DiffuseColor.setValues(colors); + } + } +}; - Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); - Handle(TDocStd_Document) hDoc; - hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); +namespace ImportGui { +class Module : public Py::ExtensionModule +{ +public: + Module() : Py::ExtensionModule("ImportGui") + { + add_varargs_method("open",&Module::open, + "open(string) -- Open the file and create a new document." + ); + add_varargs_method("insert",&Module::insert, + "insert(string,string) -- Insert the file into the given document." + ); + add_varargs_method("export",&Module::exporter, + "export(list,string) -- Export a list of objects into a single file." + ); + add_varargs_method("ocaf",&Module::ocaf, + "ocaf(string) -- Browse the ocaf structure." + ); + initialize("This module is the ImportGui module."); // register with Python + } - if (file.hasExtension("stp") || file.hasExtension("step")) { - STEPCAFControl_Reader aReader; - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "cannot read STEP file"); - return 0; + virtual ~Module() {} + +private: + Py::Object open(const Py::Tuple& args) + { + return insert(args); + } + Py::Object insert(const Py::Tuple& args) + { + char* Name; + char* DocName=0; + if (!PyArg_ParseTuple(args.ptr(), "et|s","utf-8",&Name,&DocName)) + throw Py::Exception(); + + std::string Utf8Name = std::string(Name); + PyMem_Free(Name); + std::string name8bit = Part::encodeFilename(Utf8Name); + + try { + //Base::Console().Log("Insert in Part with %s",Name); + Base::FileInfo file(Utf8Name.c_str()); + + App::Document *pcDoc = 0; + if (DocName) { + pcDoc = App::GetApplication().getDocument(DocName); + } + if (!pcDoc) { + pcDoc = App::GetApplication().newDocument("Unnamed"); } - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.Reader().WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading STEP file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); - } - else if (file.hasExtension("igs") || file.hasExtension("iges")) { - Base::Reference hGrp = App::GetApplication().GetUserParameter() - .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES"); - IGESControl_Controller::Init(); - IGESCAFControl_Reader aReader; - // http://www.opencascade.org/org/forum/thread_20603/?forum=3 - aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true) - ? Standard_True : Standard_False); - aReader.SetColorMode(true); - aReader.SetNameMode(true); - aReader.SetLayerMode(true); - if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) { - PyErr_SetString(Base::BaseExceptionFreeCADError, "cannot read IGES file"); - return 0; + Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) hDoc; + hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); + + if (file.hasExtension("stp") || file.hasExtension("step")) { + try { + STEPCAFControl_Reader aReader; + aReader.SetColorMode(true); + aReader.SetNameMode(true); + aReader.SetLayerMode(true); + if (aReader.ReadFile((const char*)name8bit.c_str()) != IFSelect_RetDone) { + throw Py::Exception(PyExc_IOError, "cannot read STEP file"); + } + + Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); + aReader.Reader().WS()->MapReader()->SetProgress(pi); + pi->NewScope(100, "Reading STEP file..."); + pi->Show(); + aReader.Transfer(hDoc); + pi->EndScope(); + } + catch (OSD_Exception) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + Base::Console().Error("%s\n", e->GetMessageString()); + Base::Console().Message("Try to load STEP file without colors...\n"); + + Part::ImportStepParts(pcDoc,Utf8Name.c_str()); + pcDoc->recompute(); + } + } + else if (file.hasExtension("igs") || file.hasExtension("iges")) { + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES"); + + try { + IGESControl_Controller::Init(); + IGESCAFControl_Reader aReader; + // http://www.opencascade.org/org/forum/thread_20603/?forum=3 + aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true) + ? Standard_True : Standard_False); + aReader.SetColorMode(true); + aReader.SetNameMode(true); + aReader.SetLayerMode(true); + if (aReader.ReadFile((const char*)name8bit.c_str()) != IFSelect_RetDone) { + throw Py::Exception(Base::BaseExceptionFreeCADError, "cannot read IGES file"); + } + + Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); + aReader.WS()->MapReader()->SetProgress(pi); + pi->NewScope(100, "Reading IGES file..."); + pi->Show(); + aReader.Transfer(hDoc); + pi->EndScope(); + } + catch (OSD_Exception) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + Base::Console().Error("%s\n", e->GetMessageString()); + Base::Console().Message("Try to load IGES file without colors...\n"); + + Part::ImportIgesParts(pcDoc,Utf8Name.c_str()); + pcDoc->recompute(); + } + } + else { + throw Py::Exception(Base::BaseExceptionFreeCADError, "no supported file format"); } - Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); - aReader.WS()->MapReader()->SetProgress(pi); - pi->NewScope(100, "Reading IGES file..."); - pi->Show(); - aReader.Transfer(hDoc); - pi->EndScope(); + ImportOCAFExt ocaf(hDoc, pcDoc, file.fileNamePure()); + ocaf.loadShapes(); + pcDoc->recompute(); } - else { - PyErr_SetString(Base::BaseExceptionFreeCADError, "no supported file format"); - return 0; + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Py::Exception(Base::BaseExceptionFreeCADError, e->GetMessageString()); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); } - static QPointer dlg = 0; - if (!dlg) { - dlg = new QDialog(Gui::getMainWindow()); - QTreeWidget* tree = new QTreeWidget(); - tree->setHeaderLabel(QString::fromLatin1("OCAF Browser")); - - QVBoxLayout *layout = new QVBoxLayout; - layout->addWidget(tree); - dlg->setLayout(layout); - - QDialogButtonBox* btn = new QDialogButtonBox(dlg); - btn->setStandardButtons(QDialogButtonBox::Close); - QObject::connect(btn, SIGNAL(rejected()), dlg, SLOT(reject())); - QHBoxLayout *boxlayout = new QHBoxLayout; - boxlayout->addWidget(btn); - layout->addLayout(boxlayout); - } - - dlg->setWindowTitle(QString::fromUtf8(file.fileName().c_str())); - dlg->setAttribute(Qt::WA_DeleteOnClose); - dlg->show(); - - OCAFBrowser browse(hDoc); - browse.load(dlg->findChild()); + return Py::None(); } - catch (Standard_Failure) { - Handle_Standard_Failure e = Standard_Failure::Caught(); - PyErr_SetString(Base::BaseExceptionFreeCADError, e->GetMessageString()); - return 0; - } - PY_CATCH + Py::Object exporter(const Py::Tuple& args) + { + PyObject* object; + char* Name; + if (!PyArg_ParseTuple(args.ptr(), "Oet",&object,"utf-8",&Name)) + throw Py::Exception(); - Py_Return; + std::string Utf8Name = std::string(Name); + PyMem_Free(Name); + std::string name8bit = Part::encodeFilename(Utf8Name); + + try { + Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) hDoc; + hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); + Import::ExportOCAF ocaf(hDoc); + + Py::Sequence list(object); + for (Py::Sequence::iterator it = list.begin(); it != list.end(); ++it) { + PyObject* item = (*it).ptr(); + if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) { + App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); + if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { + Part::Feature* part = static_cast(obj); + std::vector colors; + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { + colors = static_cast(vp)->DiffuseColor.getValues(); + if (colors.empty()) + colors.push_back(static_cast(vp)->ShapeColor.getValue()); + } + ocaf.saveShape(part, colors); + } + else { + Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue()); + } + } + } + + Base::FileInfo file(Utf8Name.c_str()); + if (file.hasExtension("stp") || file.hasExtension("step")) { + //Interface_Static::SetCVal("write.step.schema", "AP214IS"); + STEPCAFControl_Writer writer; + writer.Transfer(hDoc, STEPControl_AsIs); + + // edit STEP header +#if OCC_VERSION_HEX >= 0x060500 + APIHeaderSection_MakeHeader makeHeader(writer.ChangeWriter().Model()); +#else + APIHeaderSection_MakeHeader makeHeader(writer.Writer().Model()); +#endif + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("STEP"); + + makeHeader.SetName(new TCollection_HAsciiString((const Standard_CString)(Utf8Name.c_str()))); + makeHeader.SetAuthorValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Author", "Author").c_str())); + makeHeader.SetOrganizationValue (1, new TCollection_HAsciiString(hGrp->GetASCII("Company").c_str())); + makeHeader.SetOriginatingSystem(new TCollection_HAsciiString(App::GetApplication().getExecutableName())); + makeHeader.SetDescriptionValue(1, new TCollection_HAsciiString("FreeCAD Model")); + IFSelect_ReturnStatus ret = writer.Write((const char*)name8bit.c_str()); + if (ret == IFSelect_RetError || ret == IFSelect_RetFail || ret == IFSelect_RetStop) { + PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); + throw Py::Exception(); + } + } + else if (file.hasExtension("igs") || file.hasExtension("iges")) { + IGESControl_Controller::Init(); + IGESCAFControl_Writer writer; + IGESData_GlobalSection header = writer.Model()->GlobalSection(); + header.SetAuthorName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.author"))); + header.SetCompanyName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.company"))); + header.SetSendName(new TCollection_HAsciiString(Interface_Static::CVal("write.iges.header.product"))); + writer.Model()->SetGlobalSection(header); + writer.Transfer(hDoc); + Standard_Boolean ret = writer.Write((const char*)name8bit.c_str()); + if (!ret) { + PyErr_Format(PyExc_IOError, "Cannot open file '%s'", Utf8Name.c_str()); + throw Py::Exception(); + } + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Py::Exception(Base::BaseExceptionFreeCADError, e->GetMessageString()); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + return Py::None(); + } + Py::Object ocaf(const Py::Tuple& args) + { + const char* Name; + if (!PyArg_ParseTuple(args.ptr(), "s",&Name)) + throw Py::Exception(); + + try { + //Base::Console().Log("Insert in Part with %s",Name); + Base::FileInfo file(Name); + + Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) hDoc; + hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); + + if (file.hasExtension("stp") || file.hasExtension("step")) { + STEPCAFControl_Reader aReader; + aReader.SetColorMode(true); + aReader.SetNameMode(true); + aReader.SetLayerMode(true); + if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) { + throw Py::Exception(PyExc_IOError, "cannot read STEP file"); + } + + Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); + aReader.Reader().WS()->MapReader()->SetProgress(pi); + pi->NewScope(100, "Reading STEP file..."); + pi->Show(); + aReader.Transfer(hDoc); + pi->EndScope(); + } + else if (file.hasExtension("igs") || file.hasExtension("iges")) { + Base::Reference hGrp = App::GetApplication().GetUserParameter() + .GetGroup("BaseApp")->GetGroup("Preferences")->GetGroup("Mod/Part")->GetGroup("IGES"); + IGESControl_Controller::Init(); + IGESCAFControl_Reader aReader; + // http://www.opencascade.org/org/forum/thread_20603/?forum=3 + aReader.SetReadVisible(hGrp->GetBool("SkipBlankEntities", true) + ? Standard_True : Standard_False); + aReader.SetColorMode(true); + aReader.SetNameMode(true); + aReader.SetLayerMode(true); + if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) { + throw Py::Exception(PyExc_IOError, "cannot read IGES file"); + } + + Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100); + aReader.WS()->MapReader()->SetProgress(pi); + pi->NewScope(100, "Reading IGES file..."); + pi->Show(); + aReader.Transfer(hDoc); + pi->EndScope(); + } + else { + throw Py::Exception(Base::BaseExceptionFreeCADError, "no supported file format"); + } + + static QPointer dlg = 0; + if (!dlg) { + dlg = new QDialog(Gui::getMainWindow()); + QTreeWidget* tree = new QTreeWidget(); + tree->setHeaderLabel(QString::fromLatin1("OCAF Browser")); + + QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(tree); + dlg->setLayout(layout); + + QDialogButtonBox* btn = new QDialogButtonBox(dlg); + btn->setStandardButtons(QDialogButtonBox::Close); + QObject::connect(btn, SIGNAL(rejected()), dlg, SLOT(reject())); + QHBoxLayout *boxlayout = new QHBoxLayout; + boxlayout->addWidget(btn); + layout->addLayout(boxlayout); + } + + dlg->setWindowTitle(QString::fromUtf8(file.fileName().c_str())); + dlg->setAttribute(Qt::WA_DeleteOnClose); + dlg->show(); + + OCAFBrowser browse(hDoc); + browse.load(dlg->findChild()); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + throw Py::Exception(Base::BaseExceptionFreeCADError, e->GetMessageString()); + } + catch (const Base::Exception& e) { + throw Py::RuntimeError(e.what()); + } + + return Py::None(); + } +}; + +PyObject* initModule() +{ + return (new Module)->module().ptr(); } -/* registration table */ -struct PyMethodDef ImportGui_Import_methods[] = { - {"open" ,open ,METH_VARARGS, - "open(string) -- Open the file and create a new document."}, - {"insert" ,importer ,METH_VARARGS, - "insert(string,string) -- Insert the file into the given document."}, - {"export" ,exporter ,METH_VARARGS, - "export(list,string) -- Export a list of objects into a single file."}, - {"ocaf" ,ocaf ,METH_VARARGS, - "ocaf(string) -- Browse the ocaf structure."}, - {NULL, NULL} /* end of table marker */ -}; +} // namespace ImportGui