AppImportGuiPy.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (c) 2011 Werner Mayer <wmayer[at]users.sourceforge.net>     *
00003  *                                                                         *
00004  *   This file is part of the FreeCAD CAx development system.              *
00005  *                                                                         *
00006  *   This library is free software; you can redistribute it and/or         *
00007  *   modify it under the terms of the GNU Library General Public           *
00008  *   License as published by the Free Software Foundation; either          *
00009  *   version 2 of the License, or (at your option) any later version.      *
00010  *                                                                         *
00011  *   This library  is distributed in the hope that it will be useful,      *
00012  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00013  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00014  *   GNU Library General Public License for more details.                  *
00015  *                                                                         *
00016  *   You should have received a copy of the GNU Library General Public     *
00017  *   License along with this library; see the file COPYING.LIB. If not,    *
00018  *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
00019  *   Suite 330, Boston, MA  02111-1307, USA                                *
00020  *                                                                         *
00021  ***************************************************************************/
00022 
00023 
00024 #include "PreCompiled.h"
00025 #if defined(__MINGW32__)
00026 # define WNT // avoid conflict with GUID
00027 #endif
00028 #ifndef _PreComp_
00029 # include <climits>
00030 # include <Python.h>
00031 # include <Standard_Version.hxx>
00032 # include <BRep_Builder.hxx>
00033 # include <Handle_TDocStd_Document.hxx>
00034 # include <Handle_XCAFApp_Application.hxx>
00035 # include <TDocStd_Document.hxx>
00036 # include <XCAFApp_Application.hxx>
00037 # include <XCAFDoc_DocumentTool.hxx>
00038 # include <XCAFDoc_ShapeTool.hxx>
00039 # include <XCAFDoc_ColorTool.hxx>
00040 # include <TDF_Label.hxx>
00041 # include <TDF_LabelSequence.hxx>
00042 # include <TDF_ChildIterator.hxx>
00043 # include <TDataStd_Name.hxx>
00044 # include <Quantity_Color.hxx>
00045 # include <STEPCAFControl_Reader.hxx>
00046 # include <STEPCAFControl_Writer.hxx>
00047 # include <IGESCAFControl_Reader.hxx>
00048 # include <IGESCAFControl_Writer.hxx>
00049 # include <IGESControl_Controller.hxx>
00050 # include <Interface_Static.hxx>
00051 # include <Transfer_TransientProcess.hxx>
00052 # include <XSControl_WorkSession.hxx>
00053 # include <TopTools_IndexedMapOfShape.hxx>
00054 # include <TopTools_MapOfShape.hxx>
00055 # include <TopExp_Explorer.hxx>
00056 # include <TopoDS_Iterator.hxx>
00057 #if OCC_VERSION_HEX >= 0x060500
00058 # include <TDataXtd_Shape.hxx>
00059 # else
00060 # include <TDataStd_Shape.hxx>
00061 # endif
00062 #endif
00063 
00064 #include <Base/PyObjectBase.h>
00065 #include <Base/Console.h>
00066 #include <App/Application.h>
00067 #include <App/Document.h>
00068 #include <App/DocumentObjectPy.h>
00069 #include <Gui/Application.h>
00070 #include <Mod/Part/Gui/ViewProvider.h>
00071 #include <Mod/Part/App/PartFeature.h>
00072 #include <Mod/Part/App/ProgressIndicator.h>
00073 
00074 class ImportXCAF
00075 {
00076 public:
00077     ImportXCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name)
00078         : hdoc(h), doc(d), default_name(name)
00079     {
00080         aShapeTool = XCAFDoc_DocumentTool::ShapeTool (hdoc->Main());
00081         hColors = XCAFDoc_DocumentTool::ColorTool(hdoc->Main());
00082     }
00083 
00084     void loadShapes()
00085     {
00086         // collect sequence of labels to display
00087         TDF_LabelSequence shapeLabels, colorLabels;
00088         aShapeTool->GetFreeShapes (shapeLabels);
00089         hColors->GetColors(colorLabels);
00090 
00091         // set presentations and show
00092         for (Standard_Integer i=1; i <= shapeLabels.Length(); i++ ) {
00093             // get the shapes and attributes
00094             const TDF_Label& label = shapeLabels.Value(i);
00095             loadShapes(label);
00096         }
00097         std::map<Standard_Integer, TopoDS_Shape>::iterator it;
00098         // go through solids
00099         for (it = mySolids.begin(); it != mySolids.end(); ++it) {
00100             createShape(it->second, true, true);
00101         }
00102         // go through shells
00103         for (it = myShells.begin(); it != myShells.end(); ++it) {
00104             createShape(it->second, true, true);
00105         }
00106         // go through compounds
00107         for (it = myCompds.begin(); it != myCompds.end(); ++it) {
00108             createShape(it->second, true, true);
00109         }
00110         // do the rest
00111         if (!myShapes.empty()) {
00112             BRep_Builder builder;
00113             TopoDS_Compound comp;
00114             builder.MakeCompound(comp);
00115             for (it = myShapes.begin(); it != myShapes.end(); ++it) {
00116                 builder.Add(comp, it->second);
00117             }
00118             createShape(comp, true, false);
00119         }
00120     }
00121 
00122 private:
00123     void createShape(const TopoDS_Shape& shape, bool perface=false, bool setname=false) const
00124     {
00125         Part::Feature* part;
00126         part = static_cast<Part::Feature*>(doc->addObject("Part::Feature", default_name.c_str()));
00127         part->Shape.setValue(shape);
00128         std::map<Standard_Integer, Quantity_Color>::const_iterator jt;
00129         jt = myColorMap.find(shape.HashCode(INT_MAX));
00130         if (jt != myColorMap.end()) {
00131             Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
00132             if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) {
00133                 App::Color color;
00134                 color.r = jt->second.Red();
00135                 color.g = jt->second.Green();
00136                 color.b = jt->second.Blue();
00137                 static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.setValue(color);
00138             }
00139         }
00140 
00141         // set label name if defined
00142         if (setname && !myNameMap.empty()) {
00143             std::map<Standard_Integer, std::string>::const_iterator jt;
00144             jt = myNameMap.find(shape.HashCode(INT_MAX));
00145             if (jt != myNameMap.end()) {
00146                 part->Label.setValue(jt->second);
00147             }
00148         }
00149 
00150         // check for colors per face
00151         if (perface && !myColorMap.empty()) {
00152             TopTools_IndexedMapOfShape faces;
00153             TopExp_Explorer xp(shape,TopAbs_FACE);
00154             while (xp.More()) {
00155                 faces.Add(xp.Current());
00156                 xp.Next();
00157             }
00158 
00159             bool found_face_color = false;
00160             std::vector<App::Color> faceColors;
00161             faceColors.resize(faces.Extent(), App::Color(0.8f,0.8f,0.8f));
00162             xp.Init(shape,TopAbs_FACE);
00163             while (xp.More()) {
00164                 jt = myColorMap.find(xp.Current().HashCode(INT_MAX));
00165                 if (jt != myColorMap.end()) {
00166                     int index = faces.FindIndex(xp.Current());
00167                     App::Color color;
00168                     color.r = jt->second.Red();
00169                     color.g = jt->second.Green();
00170                     color.b = jt->second.Blue();
00171                     faceColors[index-1] = color;
00172                     found_face_color = true;
00173                 }
00174                 xp.Next();
00175             }
00176 
00177             if (found_face_color) {
00178                 Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
00179                 if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
00180                     static_cast<PartGui::ViewProviderPartExt*>(vp)->DiffuseColor.setValues(faceColors);
00181                 }
00182             }
00183         }
00184     }
00185     void loadShapes(const TDF_Label& label)
00186     {
00187         TopoDS_Shape aShape;
00188         if (aShapeTool->GetShape(label,aShape)) {
00189             if (aShapeTool->IsTopLevel(label)) {
00190                 int ctSolids = 0, ctShells = 0, ctComps = 0;
00191                 // add the shapes
00192                 TopExp_Explorer xp;
00193                 for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++)
00194                     this->mySolids[xp.Current().HashCode(INT_MAX)] = (xp.Current());
00195                 for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++)
00196                     this->myShells[xp.Current().HashCode(INT_MAX)] = (xp.Current());
00197                 // if no solids and no shells were found then go for compounds
00198                 if (ctSolids == 0 && ctShells == 0) {
00199                     for (xp.Init(aShape, TopAbs_COMPOUND); xp.More(); xp.Next(), ctComps++)
00200                         this->myCompds[xp.Current().HashCode(INT_MAX)] = (xp.Current());
00201                 }
00202                 if (ctComps == 0) {
00203                     for (xp.Init(aShape, TopAbs_FACE, TopAbs_SHELL); xp.More(); xp.Next())
00204                         this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
00205                     for (xp.Init(aShape, TopAbs_WIRE, TopAbs_FACE); xp.More(); xp.Next())
00206                         this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
00207                     for (xp.Init(aShape, TopAbs_EDGE, TopAbs_WIRE); xp.More(); xp.Next())
00208                         this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
00209                     for (xp.Init(aShape, TopAbs_VERTEX, TopAbs_EDGE); xp.More(); xp.Next())
00210                         this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current());
00211                 }
00212             }
00213 
00214             // getting color
00215             Quantity_Color col;
00216             if (hColors->GetColor(label, XCAFDoc_ColorGen, col) ||
00217                 hColors->GetColor(label, XCAFDoc_ColorSurf, col) ||
00218                 hColors->GetColor(label, XCAFDoc_ColorCurv, col)) {
00219                 // add defined color
00220                 myColorMap[aShape.HashCode(INT_MAX)] = col;
00221             }
00222             else {
00223                 // http://www.opencascade.org/org/forum/thread_17107/
00224                 TopoDS_Iterator it;
00225                 for (it.Initialize(aShape);it.More(); it.Next()) {
00226                     if (hColors->GetColor(it.Value(), XCAFDoc_ColorGen, col) ||
00227                         hColors->GetColor(it.Value(), XCAFDoc_ColorSurf, col) ||
00228                         hColors->GetColor(it.Value(), XCAFDoc_ColorCurv, col)) {
00229                         // add defined color
00230                         myColorMap[it.Value().HashCode(INT_MAX)] = col;
00231                     }
00232                 }
00233             }
00234 
00235             // getting names
00236             Handle(TDataStd_Name) name;
00237             if (label.FindAttribute(TDataStd_Name::GetID(),name)) {
00238                 TCollection_ExtendedString extstr = name->Get();
00239                 char* str = new char[extstr.LengthOfCString()+1];
00240                 extstr.ToUTF8CString(str);
00241                 std::string label(str);
00242                 if (!label.empty())
00243                     myNameMap[aShape.HashCode(INT_MAX)] = label;
00244                 delete [] str;
00245             }
00246 
00247             if (label.HasChild()) {
00248                 TDF_ChildIterator it;
00249                 for (it.Initialize(label); it.More(); it.Next()) {
00250                     loadShapes(it.Value());
00251                 }
00252             }
00253         }
00254     }
00255 
00256 private:
00257     Handle_TDocStd_Document hdoc;
00258     App::Document* doc;
00259     Handle_XCAFDoc_ShapeTool aShapeTool;
00260     Handle_XCAFDoc_ColorTool hColors;
00261     std::string default_name;
00262     std::map<Standard_Integer, TopoDS_Shape> mySolids;
00263     std::map<Standard_Integer, TopoDS_Shape> myShells;
00264     std::map<Standard_Integer, TopoDS_Shape> myCompds;
00265     std::map<Standard_Integer, TopoDS_Shape> myShapes;
00266     std::map<Standard_Integer, Quantity_Color> myColorMap;
00267     std::map<Standard_Integer, std::string> myNameMap;
00268 };
00269 
00270 /* module functions */
00271 static PyObject * importer(PyObject *self, PyObject *args)
00272 {
00273     const char* Name;
00274     const char* DocName;
00275     if (!PyArg_ParseTuple(args, "ss",&Name,&DocName))
00276         return 0;
00277 
00278     PY_TRY {
00279         //Base::Console().Log("Insert in Part with %s",Name);
00280         Base::FileInfo file(Name);
00281 
00282         App::Document *pcDoc = App::GetApplication().getDocument(DocName);
00283         if (!pcDoc) {
00284             pcDoc = App::GetApplication().newDocument(DocName);
00285         }
00286 
00287         Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication();
00288         Handle(TDocStd_Document) hDoc;
00289         hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc);
00290 
00291         if (file.hasExtension("stp") || file.hasExtension("step")) {
00292             STEPCAFControl_Reader aReader;
00293             aReader.SetColorMode(true);
00294             aReader.SetNameMode(true);
00295             aReader.SetLayerMode(true);
00296             if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) {
00297                 PyErr_SetString(PyExc_Exception, "cannot read STEP file");
00298                 return 0;
00299             }
00300 
00301             Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100);
00302             aReader.Reader().WS()->MapReader()->SetProgress(pi);
00303             pi->NewScope(100, "Reading STEP file...");
00304             pi->Show();
00305             aReader.Transfer(hDoc);
00306             pi->EndScope();
00307         }
00308         else if (file.hasExtension("igs") || file.hasExtension("iges")) {
00309             IGESControl_Controller::Init();
00310             Interface_Static::SetIVal("read.surfacecurve.mode",3);
00311             IGESCAFControl_Reader aReader;
00312             if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) {
00313                 PyErr_SetString(PyExc_Exception, "cannot read IGES file");
00314                 return 0;
00315             }
00316 
00317             Handle_Message_ProgressIndicator pi = new Part::ProgressIndicator(100);
00318             aReader.WS()->MapReader()->SetProgress(pi);
00319             pi->NewScope(100, "Reading IGES file...");
00320             pi->Show();
00321             aReader.Transfer(hDoc);
00322             pi->EndScope();
00323         }
00324         else {
00325             PyErr_SetString(PyExc_Exception, "no supported file format");
00326             return 0;
00327         }
00328 
00329         ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure());
00330         xcaf.loadShapes();
00331         pcDoc->recompute();
00332 
00333     }
00334     catch (Standard_Failure) {
00335         Handle_Standard_Failure e = Standard_Failure::Caught();
00336         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00337         return 0;
00338     }
00339     PY_CATCH
00340 
00341     Py_Return;
00342 }
00343 
00344 static PyObject * exporter(PyObject *self, PyObject *args)
00345 {
00346     PyObject* object;
00347     const char* filename;
00348     if (!PyArg_ParseTuple(args, "Os",&object,&filename))
00349         return NULL;
00350 
00351     PY_TRY {
00352         Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication();
00353         Handle(TDocStd_Document) hDoc;
00354         hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc);
00355         Handle_XCAFDoc_ShapeTool hShapeTool = XCAFDoc_DocumentTool::ShapeTool(hDoc->Main());
00356         Handle_XCAFDoc_ColorTool hColors = XCAFDoc_DocumentTool::ColorTool(hDoc->Main());
00357 
00358         TDF_Label rootLabel= TDF_TagSource::NewChild(hDoc->Main());
00359 
00360         Py::List list(object);
00361         for (Py::List::iterator it = list.begin(); it != list.end(); ++it) {
00362             PyObject* item = (*it).ptr();
00363             if (PyObject_TypeCheck(item, &(App::DocumentObjectPy::Type))) {
00364                 App::DocumentObject* obj = static_cast<App::DocumentObjectPy*>(item)->getDocumentObjectPtr();
00365                 if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
00366                     Part::Feature* part = static_cast<Part::Feature*>(obj);
00367                     const TopoDS_Shape& shape = part->Shape.getValue();
00368 
00369                     // Add shape and name
00370                     //TDF_Label shapeLabel = hShapeTool->AddShape(shape, Standard_False);
00371                     TDF_Label shapeLabel= TDF_TagSource::NewChild(rootLabel);
00372 #if OCC_VERSION_HEX >= 0x060500
00373                     TDataXtd_Shape::Set(shapeLabel, shape);
00374 #else
00375                     TDataStd_Shape::Set(shapeLabel, shape);
00376 #endif
00377                     TDataStd_Name::Set(shapeLabel, TCollection_ExtendedString(part->Label.getValue(), 1));
00378 
00379                     // Add color information
00380                     Quantity_Color col;
00381                     Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part);
00382                     bool per_face = false;
00383                     if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) {
00384                         const std::vector<App::Color>& c = static_cast<PartGui::ViewProviderPartExt*>
00385                             (vp)->DiffuseColor.getValues();
00386                         // define color per face
00387                         if (c.size() > 1) {
00388                             per_face = true;
00389                             std::set<int> face_index;
00390                             TopTools_IndexedMapOfShape faces;
00391                             TopExp_Explorer xp(shape,TopAbs_FACE);
00392                             while (xp.More()) {
00393                                 face_index.insert(faces.Add(xp.Current()));
00394                                 xp.Next();
00395                             }
00396 
00397                             xp.Init(shape,TopAbs_FACE);
00398                             while (xp.More()) {
00399                                 int index = faces.FindIndex(xp.Current());
00400                                 if (face_index.find(index) != face_index.end()) {
00401                                     face_index.erase(index);
00402                                     TDF_Label faceLabel= TDF_TagSource::NewChild(shapeLabel);
00403 #if OCC_VERSION_HEX >= 0x060500
00404                                     TDataXtd_Shape::Set(faceLabel, xp.Current());
00405 #else
00406                                     TDataStd_Shape::Set(faceLabel, xp.Current());
00407 #endif
00408                                     const App::Color& color = c[index-1];
00409                                     Quantity_Parameter mat[3];
00410                                     mat[0] = color.r;
00411                                     mat[1] = color.g;
00412                                     mat[2] = color.b;
00413                                     col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB);
00414                                     hColors->SetColor(faceLabel, col, XCAFDoc_ColorSurf);
00415                                 }
00416                                 xp.Next();
00417                             }
00418                         }
00419                     }
00420                     if (!per_face && vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) {
00421                         App::Color color = static_cast<PartGui::ViewProviderPart*>(vp)->ShapeColor.getValue();
00422                         Quantity_Parameter mat[3];
00423                         mat[0] = color.r;
00424                         mat[1] = color.g;
00425                         mat[2] = color.b;
00426                         col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB);
00427                         hColors->SetColor(shapeLabel, col, XCAFDoc_ColorGen);
00428                     }
00429                 }
00430                 else {
00431                     Base::Console().Message("'%s' is not a shape, export will be ignored.\n", obj->Label.getValue());
00432                 }
00433             }
00434         }
00435 
00436         Base::FileInfo file(filename);
00437         if (file.hasExtension("stp") || file.hasExtension("step")) {
00438             STEPCAFControl_Writer writer;
00439             writer.Transfer(hDoc, STEPControl_AsIs);
00440             writer.Write(filename);
00441         }
00442         else if (file.hasExtension("igs") || file.hasExtension("iges")) {
00443             IGESControl_Controller::Init();
00444             IGESCAFControl_Writer writer;
00445             writer.Transfer(hDoc);
00446             writer.Write(filename);
00447         }
00448     }
00449     catch (Standard_Failure) {
00450         Handle_Standard_Failure e = Standard_Failure::Caught();
00451         PyErr_SetString(PyExc_Exception, e->GetMessageString());
00452         return 0;
00453     }
00454     PY_CATCH
00455 
00456     Py_Return;
00457 }
00458 
00459 /* registration table  */
00460 struct PyMethodDef ImportGui_Import_methods[] = {
00461     {"insert"     ,importer  ,METH_VARARGS,
00462      "insert(string,string) -- Insert the file into the given document."},
00463     {"export"     ,exporter  ,METH_VARARGS,
00464      "export(list,string) -- Export a list of objects into a single file."},
00465     {NULL, NULL}                   /* end of table marker */
00466 };

Generated on Wed Nov 23 18:59:55 2011 for FreeCAD by  doxygen 1.6.1