From 59425257ee05855e41f71f43ce5bcebf179c904f Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 16 Jul 2013 14:41:30 +0200 Subject: [PATCH] 0001182: Preserve names and colors on console mode export to STEP --- src/Mod/Import/App/AppImport.cpp | 42 +- src/Mod/Import/App/AppImportPy.cpp | 286 ++++++++++---- src/Mod/Import/App/CMakeLists.txt | 82 ++-- src/Mod/Import/App/ImportOCAF.cpp | 548 ++++++++++++++++++++++++++ src/Mod/Import/App/ImportOCAF.h | 117 ++++++ src/Mod/Import/App/PreCompiled.h | 209 +--------- src/Mod/Import/CMakeLists.txt | 2 +- src/Mod/Import/Gui/AppImportGuiPy.cpp | 483 +---------------------- src/Mod/Import/Gui/CMakeLists.txt | 1 + src/Mod/Import/Gui/PreCompiled.h | 4 +- 10 files changed, 974 insertions(+), 800 deletions(-) create mode 100644 src/Mod/Import/App/ImportOCAF.cpp create mode 100644 src/Mod/Import/App/ImportOCAF.h diff --git a/src/Mod/Import/App/AppImport.cpp b/src/Mod/Import/App/AppImport.cpp index 77b44caa4c..c21b306b2e 100644 --- a/src/Mod/Import/App/AppImport.cpp +++ b/src/Mod/Import/App/AppImport.cpp @@ -25,47 +25,29 @@ #include "PreCompiled.h" #ifndef _PreComp_ -# include -# if defined (_POSIX_C_SOURCE) -# undef _POSIX_C_SOURCE -# endif // (re-)defined in pyconfig.h -# include #endif #include #include -#include -#include - -#include "FeatureImportStep.h" -#include "FeatureImportIges.h" - /* registration table */ -extern struct PyMethodDef Import_methods[]; +extern struct PyMethodDef Import_Import_methods[]; - -// python entry -#ifdef FC_OS_WIN32 -# define ModuleExport __declspec(dllexport) -#else -# define ModuleExport -#endif extern "C" { -void ModuleExport initImport() { +void ImportExport initImport() +{ + (void) Py_InitModule("Import", Import_Import_methods); /* mod name, table ptr */ - (void) Py_InitModule("Import", Import_methods); /* mod name, table ptr */ + try { + Base::Interpreter().loadModule("Part"); + } + catch(const Base::Exception& e) { + PyErr_SetString(PyExc_ImportError, e.what()); + return; + } - // load dependend module - Base::Interpreter().loadModule("Part"); - - App::AbstractFeatureFactory().AddProducer("ImportStep",new App::AbstractFeatureProducer); - App::AbstractFeatureFactory().AddProducer("ImportIges",new App::AbstractFeatureProducer); - - Base::Console().Log("Import loaded\n"); - - return; + Base::Console().Log("Loading Import module... done\n"); } diff --git a/src/Mod/Import/App/AppImportPy.cpp b/src/Mod/Import/App/AppImportPy.cpp index da82ca508e..4399f17ba8 100644 --- a/src/Mod/Import/App/AppImportPy.cpp +++ b/src/Mod/Import/App/AppImportPy.cpp @@ -1,118 +1,264 @@ /*************************************************************************** - * (c) Jürgen Riegel (juergen.riegel@web.de) 2002 * + * Copyright (c) 2013 Werner Mayer * * * * 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 Library 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. * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * * * - * FreeCAD is distributed in the hope that it will be useful, * + * This library 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 Library 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 * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * * * - * Juergen Riegel 2002 * ***************************************************************************/ #include "PreCompiled.h" +#if defined(__MINGW32__) +# define WNT // avoid conflict with GUID +#endif #ifndef _PreComp_ -# include -# if defined (_POSIX_C_SOURCE) -# undef _POSIX_C_SOURCE -# endif // (re-)defined in pyconfig.h -# include -# include -# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include #endif +#include "ImportOCAF.h" +#include #include -#include - #include #include -#include -#include -#include +#include +#include +#include +#include +#include /* module functions */ -static PyObject * -open(PyObject *self, PyObject *args) + +static PyObject * importer(PyObject *self, PyObject *args) { - const char* Name; - if (! PyArg_ParseTuple(args, "s",&Name)) - return NULL; + char* Name; + char* DocName=0; + if (!PyArg_ParseTuple(args, "s|s",&Name,&DocName)) + return 0; - Base::Console().Log("Open in Import with %s",Name); + PY_TRY { + //Base::Console().Log("Insert in Part with %s",Name); + Base::FileInfo file(Name); - // extract ending - std::string cEnding(Name); - unsigned int pos = cEnding.find_last_of('.'); - if(pos == cEnding.size()) - Py_Error(PyExc_Exception,"no file ending"); - cEnding.erase(0,pos+1); + App::Document *pcDoc = 0; + if (DocName) { + pcDoc = App::GetApplication().getDocument(DocName); + } + if (!pcDoc) { + pcDoc = App::GetApplication().newDocument("Unnamed"); + } - if(cEnding == "stp" || cEnding == "step") - { - // create new document and add Import feature - App::Document *pcDoc = App::GetApplication().newDocument(); - App::AbstractFeature *pcFeature = pcDoc->addFeature("ImportStep","Step Import"); - pcFeature->setPropertyString (Name,"FileName"); - pcFeature->TouchProperty("FileName"); - pcDoc->recompute(); + Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) hDoc; + hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - }else if(cEnding == "igs" || cEnding == "iges") - { - // create new document and add Import feature - App::Document *pcDoc = App::GetApplication().newDocument(); - App::AbstractFeature *pcFeature = pcDoc->addFeature("ImportIges","Iges Import"); -assert(0); -// pcFeature->GetProperty("FileName").Set(Name); - pcFeature->TouchProperty("FileName"); - pcDoc->recompute(); + 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)Name) != IFSelect_RetDone) { + PyErr_SetString(PyExc_Exception, "cannot read STEP file"); + return 0; + } - }else + 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"); - Py_Error(PyExc_Exception,"unknown file ending"); + Part::ImportStepParts(pcDoc,Name); + pcDoc->recompute(); + } + } + else if (file.hasExtension("igs") || file.hasExtension("iges")) { + try { + IGESControl_Controller::Init(); + Interface_Static::SetIVal("read.surfacecurve.mode",3); + IGESCAFControl_Reader aReader; + aReader.SetColorMode(true); + aReader.SetNameMode(true); + aReader.SetLayerMode(true); + if (aReader.ReadFile((Standard_CString)Name) != IFSelect_RetDone) { + PyErr_SetString(PyExc_Exception, "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"); - Py_Return; + Part::ImportIgesParts(pcDoc,Name); + pcDoc->recompute(); + } + } + else { + PyErr_SetString(PyExc_Exception, "no supported file format"); + return 0; + } + +#if 1 + Import::ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure()); + ocaf.loadShapes(); +#else + Import::ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure()); + xcaf.loadShapes(); +#endif + pcDoc->recompute(); + + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + PY_CATCH + + Py_Return; } -/* module functions */ -static PyObject * -save(PyObject *self, PyObject *args) +static PyObject * open(PyObject *self, PyObject *args) { - char* str; + return importer(self, args); +} - if (! PyArg_ParseTuple(args, "s",&str)) +static PyObject * exporter(PyObject *self, PyObject *args) +{ + PyObject* object; + const char* filename; + if (!PyArg_ParseTuple(args, "Os",&object,&filename)) return NULL; - TopoDS_Shape ResultShape; - BRep_Builder aBuilder; + PY_TRY { + Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); + Handle(TDocStd_Document) hDoc; + hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); + Import::ExportOCAF ocaf(hDoc); - BRepTools::Read(ResultShape,(const Standard_CString)str,aBuilder); + Py::List list(object); + for (Py::List::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()); + } + } + } + } - return new Part::TopoShapePy(ResultShape); /* convert C -> Python */ + Base::FileInfo file(filename); + 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 + makeHeader.SetName(new TCollection_HAsciiString((const Standard_CString)filename)); + makeHeader.SetAuthorValue (1, new TCollection_HAsciiString("FreeCAD")); + makeHeader.SetOrganizationValue (1, new TCollection_HAsciiString("FreeCAD")); + makeHeader.SetOriginatingSystem(new TCollection_HAsciiString("FreeCAD")); + makeHeader.SetDescriptionValue(1, new TCollection_HAsciiString("FreeCAD Model")); + writer.Write(filename); + } + else if (file.hasExtension("igs") || file.hasExtension("iges")) { + IGESControl_Controller::Init(); + IGESCAFControl_Writer writer; + writer.Transfer(hDoc); + writer.Write(filename); + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + PY_CATCH + + Py_Return; } - - /* registration table */ -struct PyMethodDef Import_methods[] = { - {"open", open, 1}, /* method name, C func ptr, always-tuple */ - {"save", save, 1}, - +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/App/CMakeLists.txt b/src/Mod/Import/App/CMakeLists.txt index 1ac7c717ab..e89a76a2db 100644 --- a/src/Mod/Import/App/CMakeLists.txt +++ b/src/Mod/Import/App/CMakeLists.txt @@ -1,49 +1,55 @@ -add_definitions(-DFCAppImport -DFC_DEBUG) +if(MSVC) + add_definitions(-DFCAppImport -DHAVE_ACOSH -DHAVE_ASINH -DHAVE_ATANH) +else(MSVC) + add_definitions(-DHAVE_LIMITS_H -DHAVE_CONFIG_H) +endif(MSVC) + include_directories( -# ${CMAKE_SOURCE_DIR}/src -# ${OPENCV_INCLUDE_DIR} - ${OCC_INCLUDE_DIR} -# ${PYTHON_INCLUDE_PATH} - ${ZLIB_INCLUDE_DIR} - ${XERCES_INCLUDE_DIR}) - -if(WIN32) - set(Import_LIBS -# ${OPENCV_LIBRARIES} -# -lTKIGES \ -# -lTKSTEP \ - Part - FreeCADApp) -else(WIN32) - set(Import_LIBS -# -lTKIGES \ -# -lTKSTEP \ -# -lFreeCADBase \ -# -lFreeCADApp \ -# -lPart + ${CMAKE_CURRENT_BINARY_DIR} + ${Boost_INCLUDE_DIRS} + ${OCC_INCLUDE_DIR} + ${ZLIB_INCLUDE_DIR} + ${PYTHON_INCLUDE_PATH} + ${XERCESC_INCLUDE_DIR} ) -endif(WIN32) -set(Import_SRCS - AppImport.cpp - AppImportPy.cpp - FeatureImportIges.cpp - FeatureImportIges.h - FeatureImportStep.cpp - FeatureImportStep.h - PreCompiled.cpp - PreCompiled.h +link_directories(${OCC_LIBRARY_DIR}) + +set(Import_LIBS + Part + ${OCC_OCAF_LIBRARIES} + ${OCC_OCAF_DEBUG_LIBRARIES} +) + +SET(Import_SRCS + AppImport.cpp + AppImportPy.cpp + ImportOCAF.cpp + ImportOCAF.h + PreCompiled.cpp + PreCompiled.h ) add_library(Import SHARED ${Import_SRCS}) - target_link_libraries(Import ${Import_LIBS}) -set_target_properties(Import PROPERTIES SUFFIX ".pyd") - -if(UNIX) +if(MSVC) + set_target_properties(Import PROPERTIES SUFFIX ".pyd") + set_target_properties(Import PROPERTIES DEBUG_OUTPUT_NAME "Import_d") + set_target_properties(Import PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Import) + set_target_properties(Import PROPERTIES PREFIX "../") + # Set special compiler flag to convert a SIGSEV into an exception + set_target_properties(Import PROPERTIES COMPILE_FLAGS "/EHa") +elseif(MINGW) + set_target_properties(Import PROPERTIES SUFFIX ".pyd") + set_target_properties(Import PROPERTIES DEBUG_OUTPUT_NAME "Import_d") + set_target_properties(Import PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Import) + set_target_properties(Import PROPERTIES PREFIX "") +else(MSVC) + set_target_properties(Import PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/Mod/Import) + set_target_properties(Import PROPERTIES PREFIX "") set_target_properties(Import PROPERTIES INSTALL_RPATH ${INSTALL_RPATH}) -endif(UNIX) +endif(MSVC) -install(TARGETS Import DESTINATION lib) +INSTALL(TARGETS Import DESTINATION lib) diff --git a/src/Mod/Import/App/ImportOCAF.cpp b/src/Mod/Import/App/ImportOCAF.cpp new file mode 100644 index 0000000000..ace94ec0c0 --- /dev/null +++ b/src/Mod/Import/App/ImportOCAF.cpp @@ -0,0 +1,548 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" +#if defined(__MINGW32__) +# define WNT // avoid conflict with GUID +#endif +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#if OCC_VERSION_HEX >= 0x060500 +# include +# else +# include +# endif +#endif + +#include "ImportOCAF.h" +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace Import; + + +ImportOCAF::ImportOCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name) + : pDoc(h), doc(d), default_name(name) +{ + aShapeTool = XCAFDoc_DocumentTool::ShapeTool (pDoc->Main()); + aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main()); +} + +ImportOCAF::~ImportOCAF() +{ +} + +void ImportOCAF::loadShapes() +{ + myRefShapes.clear(); + loadShapes(pDoc->Main(), TopLoc_Location(), default_name, "", false); +} + +void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc, const std::string& defaultname, const std::string& assembly, bool isRef) +{ + int hash = 0; + TopoDS_Shape aShape; + if (aShapeTool->GetShape(label,aShape)) { + hash = aShape.HashCode(HashUpper); + } + + Handle(TDataStd_Name) name; + std::string part_name = defaultname; + if (label.FindAttribute(TDataStd_Name::GetID(),name)) { + TCollection_ExtendedString extstr = name->Get(); + char* str = new char[extstr.LengthOfCString()+1]; + extstr.ToUTF8CString(str); + part_name = str; + delete [] str; + if (part_name.empty()) { + part_name = defaultname; + } + else { + bool ws=true; + for (std::string::iterator it = part_name.begin(); it != part_name.end(); ++it) { + if (*it != ' ') { + ws = false; + break; + } + } + if (ws) + part_name = defaultname; + } + } + + TopLoc_Location part_loc = loc; + Handle(XCAFDoc_Location) hLoc; + if (label.FindAttribute(XCAFDoc_Location::GetID(), hLoc)) { + if (isRef) + part_loc = part_loc * hLoc->Get(); + else + part_loc = hLoc->Get(); + } + +#ifdef FC_DEBUG + Base::Console().Message("H:%d, N:%s, T:%d, A:%d, S:%d, C:%d, SS:%d, F:%d, R:%d, C:%d, SS:%d\n", + hash, + part_name.c_str(), + aShapeTool->IsTopLevel(label), + aShapeTool->IsAssembly(label), + aShapeTool->IsShape(label), + aShapeTool->IsCompound(label), + aShapeTool->IsSimpleShape(label), + aShapeTool->IsFree(label), + aShapeTool->IsReference(label), + aShapeTool->IsComponent(label), + aShapeTool->IsSubShape(label) + ); +#endif + + std::string asm_name = assembly; + if (aShapeTool->IsAssembly(label)) { + asm_name = part_name; + } + + TDF_Label ref; + if (aShapeTool->IsReference(label) && aShapeTool->GetReferredShape(label, ref)) { + loadShapes(ref, part_loc, part_name, asm_name, true); + } + + if (isRef || myRefShapes.find(hash) == myRefShapes.end()) { + TopoDS_Shape aShape; + if (isRef && aShapeTool->GetShape(label, aShape)) + myRefShapes.insert(aShape.HashCode(HashUpper)); + + if (aShapeTool->IsSimpleShape(label) && (isRef || aShapeTool->IsFree(label))) { + if (!asm_name.empty()) + part_name = asm_name; + if (isRef) + createShape(label, loc, part_name); + else + createShape(label, part_loc, part_name); + } + else { + for (TDF_ChildIterator it(label); it.More(); it.Next()) { + loadShapes(it.Value(), part_loc, part_name, asm_name, isRef); + } + } + } +} + +void ImportOCAF::createShape(const TDF_Label& label, const TopLoc_Location& loc, const std::string& name) +{ + const TopoDS_Shape& aShape = aShapeTool->GetShape(label); + if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND) { + TopExp_Explorer xp; + int ctSolids = 0, ctShells = 0; + for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++) + createShape(xp.Current(), loc, name); + for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++) + createShape(xp.Current(), loc, name); + if (ctSolids > 0 || ctShells > 0) + return; + } + + createShape(aShape, loc, name); +} + +void ImportOCAF::createShape(const TopoDS_Shape& aShape, const TopLoc_Location& loc, const std::string& name) +{ + Part::Feature* part = static_cast(doc->addObject("Part::Feature")); + if (!loc.IsIdentity()) + part->Shape.setValue(aShape.Moved(loc)); + else + part->Shape.setValue(aShape); + part->Label.setValue(name); + + Quantity_Color aColor; + App::Color color(0.8f,0.8f,0.8f); + if (aColorTool->GetColor(aShape, XCAFDoc_ColorGen, aColor) || + aColorTool->GetColor(aShape, XCAFDoc_ColorSurf, aColor) || + aColorTool->GetColor(aShape, XCAFDoc_ColorCurv, aColor)) { + color.r = aColor.Red(); + color.g = aColor.Green(); + color.b = aColor.Blue(); + std::vector colors; + colors.push_back(color); + applyColors(part, colors); +#if 0//TODO + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) { + color.r = aColor.Red(); + color.g = aColor.Green(); + color.b = aColor.Blue(); + static_cast(vp)->ShapeColor.setValue(color); + } +#endif + } + + TopTools_IndexedMapOfShape faces; + TopExp_Explorer xp(aShape,TopAbs_FACE); + while (xp.More()) { + faces.Add(xp.Current()); + xp.Next(); + } + bool found_face_color = false; + std::vector faceColors; + faceColors.resize(faces.Extent(), color); + xp.Init(aShape,TopAbs_FACE); + while (xp.More()) { + if (aColorTool->GetColor(xp.Current(), XCAFDoc_ColorGen, aColor) || + aColorTool->GetColor(xp.Current(), XCAFDoc_ColorSurf, aColor) || + aColorTool->GetColor(xp.Current(), XCAFDoc_ColorCurv, aColor)) { + int index = faces.FindIndex(xp.Current()); + color.r = aColor.Red(); + color.g = aColor.Green(); + color.b = aColor.Blue(); + faceColors[index-1] = color; + found_face_color = true; + } + xp.Next(); + } + + if (found_face_color) { + applyColors(part, faceColors); +#if 0//TODO + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { + static_cast(vp)->DiffuseColor.setValues(faceColors); + } +#endif + } +} + +// ---------------------------------------------------------------------------- + +ExportOCAF::ExportOCAF(Handle_TDocStd_Document h) + : pDoc(h) +{ + aShapeTool = XCAFDoc_DocumentTool::ShapeTool(pDoc->Main()); + aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main()); + rootLabel = TDF_TagSource::NewChild(pDoc->Main()); +} + +void ExportOCAF::saveShape(Part::Feature* part, const std::vector& colors) +{ + const TopoDS_Shape& shape = part->Shape.getValue(); + + // Add shape and name + //TDF_Label shapeLabel = hShapeTool->AddShape(shape, Standard_False); + TDF_Label shapeLabel= TDF_TagSource::NewChild(rootLabel); +#if OCC_VERSION_HEX >= 0x060500 + TDataXtd_Shape::Set(shapeLabel, shape); +#else + TDataStd_Shape::Set(shapeLabel, shape); +#endif + TDataStd_Name::Set(shapeLabel, TCollection_ExtendedString(part->Label.getValue(), 1)); + + // Add color information + Quantity_Color col; + + std::set face_index; + TopTools_IndexedMapOfShape faces; + TopExp_Explorer xp(shape,TopAbs_FACE); + while (xp.More()) { + face_index.insert(faces.Add(xp.Current())); + xp.Next(); + } + + // define color per face? + if (colors.size() == face_index.size()) { + xp.Init(shape,TopAbs_FACE); + while (xp.More()) { + int index = faces.FindIndex(xp.Current()); + if (face_index.find(index) != face_index.end()) { + face_index.erase(index); + TDF_Label faceLabel= TDF_TagSource::NewChild(shapeLabel); +#if OCC_VERSION_HEX >= 0x060500 + TDataXtd_Shape::Set(faceLabel, xp.Current()); +#else + TDataStd_Shape::Set(faceLabel, xp.Current()); +#endif + const App::Color& color = colors[index-1]; + Quantity_Parameter mat[3]; + mat[0] = color.r; + mat[1] = color.g; + mat[2] = color.b; + col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB); + aColorTool->SetColor(faceLabel, col, XCAFDoc_ColorSurf); + } + xp.Next(); + } + } + else if (!colors.empty()) { + App::Color color = colors.front(); + Quantity_Parameter mat[3]; + mat[0] = color.r; + mat[1] = color.g; + mat[2] = color.b; + col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB); + aColorTool->SetColor(shapeLabel, col, XCAFDoc_ColorGen); + } +} + +// ---------------------------------------------------------------------------- + +ImportXCAF::ImportXCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name) + : hdoc(h), doc(d), default_name(name) +{ + aShapeTool = XCAFDoc_DocumentTool::ShapeTool (hdoc->Main()); + hColors = XCAFDoc_DocumentTool::ColorTool(hdoc->Main()); +} + +ImportXCAF::~ImportXCAF() +{ +} + +void ImportXCAF::loadShapes() +{ + // collect sequence of labels to display + TDF_LabelSequence shapeLabels, colorLabels; + aShapeTool->GetFreeShapes (shapeLabels); + hColors->GetColors(colorLabels); + + // set presentations and show + for (Standard_Integer i=1; i <= shapeLabels.Length(); i++ ) { + // get the shapes and attributes + const TDF_Label& label = shapeLabels.Value(i); + loadShapes(label); + } + std::map::iterator it; + // go through solids + for (it = mySolids.begin(); it != mySolids.end(); ++it) { + createShape(it->second, true, true); + } + // go through shells + for (it = myShells.begin(); it != myShells.end(); ++it) { + createShape(it->second, true, true); + } + // go through compounds + for (it = myCompds.begin(); it != myCompds.end(); ++it) { + createShape(it->second, true, true); + } + // do the rest + if (!myShapes.empty()) { + BRep_Builder builder; + TopoDS_Compound comp; + builder.MakeCompound(comp); + for (it = myShapes.begin(); it != myShapes.end(); ++it) { + builder.Add(comp, it->second); + } + createShape(comp, true, false); + } +} + +void ImportXCAF::createShape(const TopoDS_Shape& shape, bool perface, bool setname) const +{ + Part::Feature* part; + part = static_cast(doc->addObject("Part::Feature", default_name.c_str())); + part->Shape.setValue(shape); + std::map::const_iterator jt; + jt = myColorMap.find(shape.HashCode(INT_MAX)); + + App::Color partColor(0.8f,0.8f,0.8f); +#if 0//TODO + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) { + if (jt != myColorMap.end()) { + App::Color color; + color.r = jt->second.Red(); + color.g = jt->second.Green(); + color.b = jt->second.Blue(); + static_cast(vp)->ShapeColor.setValue(color); + } + + partColor = static_cast(vp)->ShapeColor.getValue(); + } +#endif + + // set label name if defined + if (setname && !myNameMap.empty()) { + std::map::const_iterator jt; + jt = myNameMap.find(shape.HashCode(INT_MAX)); + if (jt != myNameMap.end()) { + part->Label.setValue(jt->second); + } + } + + // check for colors per face + if (perface && !myColorMap.empty()) { + TopTools_IndexedMapOfShape faces; + TopExp_Explorer xp(shape,TopAbs_FACE); + while (xp.More()) { + faces.Add(xp.Current()); + xp.Next(); + } + + bool found_face_color = false; + std::vector faceColors; + faceColors.resize(faces.Extent(), partColor); + xp.Init(shape,TopAbs_FACE); + while (xp.More()) { + jt = myColorMap.find(xp.Current().HashCode(INT_MAX)); + if (jt != myColorMap.end()) { + int index = faces.FindIndex(xp.Current()); + App::Color color; + color.r = jt->second.Red(); + color.g = jt->second.Green(); + color.b = jt->second.Blue(); + faceColors[index-1] = color; + found_face_color = true; + } + xp.Next(); + } + + if (found_face_color) { +#if 0//TODO + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { + static_cast(vp)->DiffuseColor.setValues(faceColors); + } +#endif + } + } +} + +void ImportXCAF::loadShapes(const TDF_Label& label) +{ + TopoDS_Shape aShape; + if (aShapeTool->GetShape(label,aShape)) { + //if (aShapeTool->IsReference(label)) { + // TDF_Label reflabel; + // if (aShapeTool->GetReferredShape(label, reflabel)) { + // loadShapes(reflabel); + // } + //} + if (aShapeTool->IsTopLevel(label)) { + int ctSolids = 0, ctShells = 0, ctComps = 0; + // add the shapes + TopExp_Explorer xp; + for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++) + this->mySolids[xp.Current().HashCode(INT_MAX)] = (xp.Current()); + for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++) + this->myShells[xp.Current().HashCode(INT_MAX)] = (xp.Current()); + // if no solids and no shells were found then go for compounds + if (ctSolids == 0 && ctShells == 0) { + for (xp.Init(aShape, TopAbs_COMPOUND); xp.More(); xp.Next(), ctComps++) + this->myCompds[xp.Current().HashCode(INT_MAX)] = (xp.Current()); + } + if (ctComps == 0) { + for (xp.Init(aShape, TopAbs_FACE, TopAbs_SHELL); xp.More(); xp.Next()) + this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current()); + for (xp.Init(aShape, TopAbs_WIRE, TopAbs_FACE); xp.More(); xp.Next()) + this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current()); + for (xp.Init(aShape, TopAbs_EDGE, TopAbs_WIRE); xp.More(); xp.Next()) + this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current()); + for (xp.Init(aShape, TopAbs_VERTEX, TopAbs_EDGE); xp.More(); xp.Next()) + this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current()); + } + } + + // getting color + Quantity_Color col; + if (hColors->GetColor(label, XCAFDoc_ColorGen, col) || + hColors->GetColor(label, XCAFDoc_ColorSurf, col) || + hColors->GetColor(label, XCAFDoc_ColorCurv, col)) { + // add defined color + myColorMap[aShape.HashCode(INT_MAX)] = col; + } + else { + // http://www.opencascade.org/org/forum/thread_17107/ + TopoDS_Iterator it; + for (it.Initialize(aShape);it.More(); it.Next()) { + if (hColors->GetColor(it.Value(), XCAFDoc_ColorGen, col) || + hColors->GetColor(it.Value(), XCAFDoc_ColorSurf, col) || + hColors->GetColor(it.Value(), XCAFDoc_ColorCurv, col)) { + // add defined color + myColorMap[it.Value().HashCode(INT_MAX)] = col; + } + } + } + + // getting names + Handle(TDataStd_Name) name; + if (label.FindAttribute(TDataStd_Name::GetID(),name)) { + TCollection_ExtendedString extstr = name->Get(); + char* str = new char[extstr.LengthOfCString()+1]; + extstr.ToUTF8CString(str); + std::string label(str); + if (!label.empty()) + myNameMap[aShape.HashCode(INT_MAX)] = label; + delete [] str; + } + +#if 0 + // http://www.opencascade.org/org/forum/thread_15174/ + if (aShapeTool->IsAssembly(label)) { + TDF_LabelSequence shapeLabels; + aShapeTool->GetComponents(label, shapeLabels); + Standard_Integer nbShapes = shapeLabels.Length(); + for (Standard_Integer i = 1; i <= nbShapes; i++) { + loadShapes(shapeLabels.Value(i)); + } + } +#endif + + if (label.HasChild()) { + TDF_ChildIterator it; + for (it.Initialize(label); it.More(); it.Next()) { + loadShapes(it.Value()); + } + } + } +} diff --git a/src/Mod/Import/App/ImportOCAF.h b/src/Mod/Import/App/ImportOCAF.h new file mode 100644 index 0000000000..50b91bdf8c --- /dev/null +++ b/src/Mod/Import/App/ImportOCAF.h @@ -0,0 +1,117 @@ +/*************************************************************************** + * Copyright (c) 2013 Werner Mayer * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library 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 Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#ifndef IMPORT_IMPORTOCAF_H +#define IMPORT_IMPORTOCAF_H + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class TDF_Label; +class TopLoc_Location; + +namespace App { +class Document; +class DocumentObject; +} +namespace Part { +class Feature; +} + +namespace Import { + +class ImportExport ImportOCAF +{ +public: + ImportOCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name); + virtual ~ImportOCAF(); + void loadShapes(); + +private: + void loadShapes(const TDF_Label& label, const TopLoc_Location&, const std::string& partname, const std::string& assembly, bool isRef); + void createShape(const TDF_Label& label, const TopLoc_Location&, const std::string&); + void createShape(const TopoDS_Shape& label, const TopLoc_Location&, const std::string&); + virtual void applyColors(Part::Feature*, const std::vector&){} + +private: + Handle_TDocStd_Document pDoc; + App::Document* doc; + Handle_XCAFDoc_ShapeTool aShapeTool; + Handle_XCAFDoc_ColorTool aColorTool; + std::string default_name; + std::set myRefShapes; + static const int HashUpper = INT_MAX; +}; + +class ImportExport ExportOCAF +{ +public: + ExportOCAF(Handle_TDocStd_Document h); + void saveShape(Part::Feature* part, const std::vector&); + +private: + Handle_TDocStd_Document pDoc; + Handle_XCAFDoc_ShapeTool aShapeTool; + Handle_XCAFDoc_ColorTool aColorTool; + TDF_Label rootLabel; +}; + + +class ImportXCAF +{ +public: + ImportXCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name); + virtual ~ImportXCAF(); + void loadShapes(); + +private: + void createShape(const TopoDS_Shape& shape, bool perface=false, bool setname=false) const; + void loadShapes(const TDF_Label& label); + virtual void applyColors(Part::Feature*, const std::vector&){} + +private: + Handle_TDocStd_Document hdoc; + App::Document* doc; + Handle_XCAFDoc_ShapeTool aShapeTool; + Handle_XCAFDoc_ColorTool hColors; + std::string default_name; + std::map mySolids; + std::map myShells; + std::map myCompds; + std::map myShapes; + std::map myColorMap; + std::map myNameMap; +}; + +} + +#endif //IMPORT_IMPORTOCAF_H diff --git a/src/Mod/Import/App/PreCompiled.h b/src/Mod/Import/App/PreCompiled.h index b1b36952f3..8940377120 100644 --- a/src/Mod/Import/App/PreCompiled.h +++ b/src/Mod/Import/App/PreCompiled.h @@ -25,25 +25,32 @@ #define __PRECOMPILED__ #include -#ifdef _PreComp_ - -/// here get the warnings of to long specifieres disabled (needet for VC6) -#ifdef _MSC_VER -# pragma warning( disable : 4251 ) -# pragma warning( disable : 4503 ) -# pragma warning( disable : 4786 ) // specifier longer then 255 chars -#endif - // Importing of App classes - #ifdef FC_OS_WIN32 +# define ImportExport __declspec(dllexport) +# define PartExport __declspec(dllimport) # define AppPartExport __declspec(dllimport) #else // for Linux +# define ImportExport +# define PartExport # define AppPartExport #endif +/// here get the warnings of to long specifieres disabled (needet for VC6) +#ifdef _MSC_VER +# pragma warning( disable : 4251 ) +# pragma warning( disable : 4503 ) +# pragma warning( disable : 4786 ) // specifier longer then 255 chars +#endif + + +#ifdef _PreComp_ + +// Python +#include + // standard #include #include @@ -60,188 +67,8 @@ // OpenCasCade ===================================================================================== // Base -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#include -#include -#include -// OCAF -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// OCAF -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// IO -#include -#include -#include -#include -#include - +#include "OpenCascadeAll.h" #endif //_PreComp_ - #endif diff --git a/src/Mod/Import/CMakeLists.txt b/src/Mod/Import/CMakeLists.txt index ec05f46d18..c5d848810d 100644 --- a/src/Mod/Import/CMakeLists.txt +++ b/src/Mod/Import/CMakeLists.txt @@ -1,5 +1,5 @@ -#add_subdirectory(App) +add_subdirectory(App) if(FREECAD_BUILD_GUI) add_subdirectory(Gui) endif(FREECAD_BUILD_GUI) diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index 054ce96d56..65e8af25fc 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -77,418 +77,26 @@ #include #include #include +#include -class ImportOCAF +class ImportOCAFExt : public Import::ImportOCAF { public: - ImportOCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name) - : pDoc(h), doc(d), default_name(name) + ImportOCAFExt(Handle_TDocStd_Document h, App::Document* d, const std::string& name) + : ImportOCAF(h, d, name) { - aShapeTool = XCAFDoc_DocumentTool::ShapeTool (pDoc->Main()); - aColorTool = XCAFDoc_DocumentTool::ColorTool(pDoc->Main()); } - void loadShapes(); - private: - void loadShapes(const TDF_Label& label, const TopLoc_Location&, const std::string& partname, const std::string& assembly, bool isRef); - void createShape(const TDF_Label& label, const TopLoc_Location&, const std::string&); - void createShape(const TopoDS_Shape& label, const TopLoc_Location&, const std::string&); - -private: - Handle_TDocStd_Document pDoc; - App::Document* doc; - Handle_XCAFDoc_ShapeTool aShapeTool; - Handle_XCAFDoc_ColorTool aColorTool; - std::string default_name; - std::set myRefShapes; - static const int HashUpper = INT_MAX; -}; - -void ImportOCAF::loadShapes() -{ - myRefShapes.clear(); - loadShapes(pDoc->Main(), TopLoc_Location(), default_name, "", false); -} - -void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc, const std::string& defaultname, const std::string& assembly, bool isRef) -{ - int hash = 0; - TopoDS_Shape aShape; - if (aShapeTool->GetShape(label,aShape)) { - hash = aShape.HashCode(HashUpper); - } - - Handle(TDataStd_Name) name; - std::string part_name = defaultname; - if (label.FindAttribute(TDataStd_Name::GetID(),name)) { - TCollection_ExtendedString extstr = name->Get(); - char* str = new char[extstr.LengthOfCString()+1]; - extstr.ToUTF8CString(str); - part_name = str; - delete [] str; - if (part_name.empty()) { - part_name = defaultname; - } - else { - bool ws=true; - for (std::string::iterator it = part_name.begin(); it != part_name.end(); ++it) { - if (*it != ' ') { - ws = false; - break; - } - } - if (ws) - part_name = defaultname; - } - } - - TopLoc_Location part_loc = loc; - Handle(XCAFDoc_Location) hLoc; - if (label.FindAttribute(XCAFDoc_Location::GetID(), hLoc)) { - if (isRef) - part_loc = part_loc * hLoc->Get(); - else - part_loc = hLoc->Get(); - } - -#ifdef FC_DEBUG - Base::Console().Message("H:%d, N:%s, T:%d, A:%d, S:%d, C:%d, SS:%d, F:%d, R:%d, C:%d, SS:%d\n", - hash, - part_name.c_str(), - aShapeTool->IsTopLevel(label), - aShapeTool->IsAssembly(label), - aShapeTool->IsShape(label), - aShapeTool->IsCompound(label), - aShapeTool->IsSimpleShape(label), - aShapeTool->IsFree(label), - aShapeTool->IsReference(label), - aShapeTool->IsComponent(label), - aShapeTool->IsSubShape(label) - ); -#endif - - std::string asm_name = assembly; - if (aShapeTool->IsAssembly(label)) { - asm_name = part_name; - } - - TDF_Label ref; - if (aShapeTool->IsReference(label) && aShapeTool->GetReferredShape(label, ref)) { - loadShapes(ref, part_loc, part_name, asm_name, true); - } - - if (isRef || myRefShapes.find(hash) == myRefShapes.end()) { - TopoDS_Shape aShape; - if (isRef && aShapeTool->GetShape(label, aShape)) - myRefShapes.insert(aShape.HashCode(HashUpper)); - - if (aShapeTool->IsSimpleShape(label) && (isRef || aShapeTool->IsFree(label))) { - if (!asm_name.empty()) - part_name = asm_name; - if (isRef) - createShape(label, loc, part_name); - else - createShape(label, part_loc, part_name); - } - else { - for (TDF_ChildIterator it(label); it.More(); it.Next()) { - loadShapes(it.Value(), part_loc, part_name, asm_name, isRef); - } - } - } -} - -void ImportOCAF::createShape(const TDF_Label& label, const TopLoc_Location& loc, const std::string& name) -{ - const TopoDS_Shape& aShape = aShapeTool->GetShape(label); - if (!aShape.IsNull() && aShape.ShapeType() == TopAbs_COMPOUND) { - TopExp_Explorer xp; - int ctSolids = 0, ctShells = 0; - for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++) - createShape(xp.Current(), loc, name); - for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++) - createShape(xp.Current(), loc, name); - if (ctSolids > 0 || ctShells > 0) - return; - } - - createShape(aShape, loc, name); -} - -void ImportOCAF::createShape(const TopoDS_Shape& aShape, const TopLoc_Location& loc, const std::string& name) -{ - Part::Feature* part = static_cast(doc->addObject("Part::Feature")); - if (!loc.IsIdentity()) - part->Shape.setValue(aShape.Moved(loc)); - else - part->Shape.setValue(aShape); - part->Label.setValue(name); - - Quantity_Color aColor; - App::Color color(0.8f,0.8f,0.8f); - if (aColorTool->GetColor(aShape, XCAFDoc_ColorGen, aColor) || - aColorTool->GetColor(aShape, XCAFDoc_ColorSurf, aColor) || - aColorTool->GetColor(aShape, XCAFDoc_ColorCurv, aColor)) { - Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); - if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) { - color.r = aColor.Red(); - color.g = aColor.Green(); - color.b = aColor.Blue(); - static_cast(vp)->ShapeColor.setValue(color); - } - } - - TopTools_IndexedMapOfShape faces; - TopExp_Explorer xp(aShape,TopAbs_FACE); - while (xp.More()) { - faces.Add(xp.Current()); - xp.Next(); - } - bool found_face_color = false; - std::vector faceColors; - faceColors.resize(faces.Extent(), color); - xp.Init(aShape,TopAbs_FACE); - while (xp.More()) { - if (aColorTool->GetColor(xp.Current(), XCAFDoc_ColorGen, aColor) || - aColorTool->GetColor(xp.Current(), XCAFDoc_ColorSurf, aColor) || - aColorTool->GetColor(xp.Current(), XCAFDoc_ColorCurv, aColor)) { - int index = faces.FindIndex(xp.Current()); - color.r = aColor.Red(); - color.g = aColor.Green(); - color.b = aColor.Blue(); - faceColors[index-1] = color; - found_face_color = true; - } - xp.Next(); - } - - if (found_face_color) { + 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)->DiffuseColor.setValues(faceColors); + static_cast(vp)->DiffuseColor.setValues(colors); } } -} - -class ImportXCAF -{ -public: - ImportXCAF(Handle_TDocStd_Document h, App::Document* d, const std::string& name) - : hdoc(h), doc(d), default_name(name) - { - aShapeTool = XCAFDoc_DocumentTool::ShapeTool (hdoc->Main()); - hColors = XCAFDoc_DocumentTool::ColorTool(hdoc->Main()); - } - - void loadShapes() - { - // collect sequence of labels to display - TDF_LabelSequence shapeLabels, colorLabels; - aShapeTool->GetFreeShapes (shapeLabels); - hColors->GetColors(colorLabels); - - // set presentations and show - for (Standard_Integer i=1; i <= shapeLabels.Length(); i++ ) { - // get the shapes and attributes - const TDF_Label& label = shapeLabels.Value(i); - loadShapes(label); - } - std::map::iterator it; - // go through solids - for (it = mySolids.begin(); it != mySolids.end(); ++it) { - createShape(it->second, true, true); - } - // go through shells - for (it = myShells.begin(); it != myShells.end(); ++it) { - createShape(it->second, true, true); - } - // go through compounds - for (it = myCompds.begin(); it != myCompds.end(); ++it) { - createShape(it->second, true, true); - } - // do the rest - if (!myShapes.empty()) { - BRep_Builder builder; - TopoDS_Compound comp; - builder.MakeCompound(comp); - for (it = myShapes.begin(); it != myShapes.end(); ++it) { - builder.Add(comp, it->second); - } - createShape(comp, true, false); - } - } - -private: - void createShape(const TopoDS_Shape& shape, bool perface=false, bool setname=false) const - { - Part::Feature* part; - part = static_cast(doc->addObject("Part::Feature", default_name.c_str())); - part->Shape.setValue(shape); - std::map::const_iterator jt; - jt = myColorMap.find(shape.HashCode(INT_MAX)); - - App::Color partColor(0.8f,0.8f,0.8f); - Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); - if (vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) { - if (jt != myColorMap.end()) { - App::Color color; - color.r = jt->second.Red(); - color.g = jt->second.Green(); - color.b = jt->second.Blue(); - static_cast(vp)->ShapeColor.setValue(color); - } - - partColor = static_cast(vp)->ShapeColor.getValue(); - } - - // set label name if defined - if (setname && !myNameMap.empty()) { - std::map::const_iterator jt; - jt = myNameMap.find(shape.HashCode(INT_MAX)); - if (jt != myNameMap.end()) { - part->Label.setValue(jt->second); - } - } - - // check for colors per face - if (perface && !myColorMap.empty()) { - TopTools_IndexedMapOfShape faces; - TopExp_Explorer xp(shape,TopAbs_FACE); - while (xp.More()) { - faces.Add(xp.Current()); - xp.Next(); - } - - bool found_face_color = false; - std::vector faceColors; - faceColors.resize(faces.Extent(), partColor); - xp.Init(shape,TopAbs_FACE); - while (xp.More()) { - jt = myColorMap.find(xp.Current().HashCode(INT_MAX)); - if (jt != myColorMap.end()) { - int index = faces.FindIndex(xp.Current()); - App::Color color; - color.r = jt->second.Red(); - color.g = jt->second.Green(); - color.b = jt->second.Blue(); - faceColors[index-1] = color; - found_face_color = true; - } - xp.Next(); - } - - if (found_face_color) { - Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); - if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { - static_cast(vp)->DiffuseColor.setValues(faceColors); - } - } - } - } - void loadShapes(const TDF_Label& label) - { - TopoDS_Shape aShape; - if (aShapeTool->GetShape(label,aShape)) { - //if (aShapeTool->IsReference(label)) { - // TDF_Label reflabel; - // if (aShapeTool->GetReferredShape(label, reflabel)) { - // loadShapes(reflabel); - // } - //} - if (aShapeTool->IsTopLevel(label)) { - int ctSolids = 0, ctShells = 0, ctComps = 0; - // add the shapes - TopExp_Explorer xp; - for (xp.Init(aShape, TopAbs_SOLID); xp.More(); xp.Next(), ctSolids++) - this->mySolids[xp.Current().HashCode(INT_MAX)] = (xp.Current()); - for (xp.Init(aShape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next(), ctShells++) - this->myShells[xp.Current().HashCode(INT_MAX)] = (xp.Current()); - // if no solids and no shells were found then go for compounds - if (ctSolids == 0 && ctShells == 0) { - for (xp.Init(aShape, TopAbs_COMPOUND); xp.More(); xp.Next(), ctComps++) - this->myCompds[xp.Current().HashCode(INT_MAX)] = (xp.Current()); - } - if (ctComps == 0) { - for (xp.Init(aShape, TopAbs_FACE, TopAbs_SHELL); xp.More(); xp.Next()) - this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current()); - for (xp.Init(aShape, TopAbs_WIRE, TopAbs_FACE); xp.More(); xp.Next()) - this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current()); - for (xp.Init(aShape, TopAbs_EDGE, TopAbs_WIRE); xp.More(); xp.Next()) - this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current()); - for (xp.Init(aShape, TopAbs_VERTEX, TopAbs_EDGE); xp.More(); xp.Next()) - this->myShapes[xp.Current().HashCode(INT_MAX)] = (xp.Current()); - } - } - - // getting color - Quantity_Color col; - if (hColors->GetColor(label, XCAFDoc_ColorGen, col) || - hColors->GetColor(label, XCAFDoc_ColorSurf, col) || - hColors->GetColor(label, XCAFDoc_ColorCurv, col)) { - // add defined color - myColorMap[aShape.HashCode(INT_MAX)] = col; - } - else { - // http://www.opencascade.org/org/forum/thread_17107/ - TopoDS_Iterator it; - for (it.Initialize(aShape);it.More(); it.Next()) { - if (hColors->GetColor(it.Value(), XCAFDoc_ColorGen, col) || - hColors->GetColor(it.Value(), XCAFDoc_ColorSurf, col) || - hColors->GetColor(it.Value(), XCAFDoc_ColorCurv, col)) { - // add defined color - myColorMap[it.Value().HashCode(INT_MAX)] = col; - } - } - } - - // getting names - Handle(TDataStd_Name) name; - if (label.FindAttribute(TDataStd_Name::GetID(),name)) { - TCollection_ExtendedString extstr = name->Get(); - char* str = new char[extstr.LengthOfCString()+1]; - extstr.ToUTF8CString(str); - std::string label(str); - if (!label.empty()) - myNameMap[aShape.HashCode(INT_MAX)] = label; - delete [] str; - } - -#if 0 - // http://www.opencascade.org/org/forum/thread_15174/ - if (aShapeTool->IsAssembly(label)) { - TDF_LabelSequence shapeLabels; - aShapeTool->GetComponents(label, shapeLabels); - Standard_Integer nbShapes = shapeLabels.Length(); - for (Standard_Integer i = 1; i <= nbShapes; i++) { - loadShapes(shapeLabels.Value(i)); - } - } -#endif - - if (label.HasChild()) { - TDF_ChildIterator it; - for (it.Initialize(label); it.More(); it.Next()) { - loadShapes(it.Value()); - } - } - } - } - -private: - Handle_TDocStd_Document hdoc; - App::Document* doc; - Handle_XCAFDoc_ShapeTool aShapeTool; - Handle_XCAFDoc_ColorTool hColors; - std::string default_name; - std::map mySolids; - std::map myShells; - std::map myCompds; - std::map myShapes; - std::map myColorMap; - std::map myNameMap; }; /* module functions */ @@ -577,15 +185,9 @@ static PyObject * importer(PyObject *self, PyObject *args) return 0; } -#if 1 - ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure()); + ImportOCAFExt ocaf(hDoc, pcDoc, file.fileNamePure()); ocaf.loadShapes(); -#else - ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure()); - xcaf.loadShapes(); -#endif pcDoc->recompute(); - } catch (Standard_Failure) { Handle_Standard_Failure e = Standard_Failure::Caught(); @@ -613,10 +215,7 @@ static PyObject * exporter(PyObject *self, PyObject *args) Handle(XCAFApp_Application) hApp = XCAFApp_Application::GetApplication(); Handle(TDocStd_Document) hDoc; hApp->NewDocument(TCollection_ExtendedString("MDTV-CAF"), hDoc); - Handle_XCAFDoc_ShapeTool hShapeTool = XCAFDoc_DocumentTool::ShapeTool(hDoc->Main()); - Handle_XCAFDoc_ColorTool hColors = XCAFDoc_DocumentTool::ColorTool(hDoc->Main()); - - TDF_Label rootLabel= TDF_TagSource::NewChild(hDoc->Main()); + Import::ExportOCAF ocaf(hDoc); Py::List list(object); for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { @@ -625,68 +224,14 @@ static PyObject * exporter(PyObject *self, PyObject *args) App::DocumentObject* obj = static_cast(item)->getDocumentObjectPtr(); if (obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) { Part::Feature* part = static_cast(obj); - const TopoDS_Shape& shape = part->Shape.getValue(); - - // Add shape and name - //TDF_Label shapeLabel = hShapeTool->AddShape(shape, Standard_False); - TDF_Label shapeLabel= TDF_TagSource::NewChild(rootLabel); -#if OCC_VERSION_HEX >= 0x060500 - TDataXtd_Shape::Set(shapeLabel, shape); -#else - TDataStd_Shape::Set(shapeLabel, shape); -#endif - TDataStd_Name::Set(shapeLabel, TCollection_ExtendedString(part->Label.getValue(), 1)); - - // Add color information - Quantity_Color col; + std::vector colors; Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); - bool per_face = false; if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { - const std::vector& c = static_cast - (vp)->DiffuseColor.getValues(); - // define color per face - if (c.size() > 1) { - per_face = true; - std::set face_index; - TopTools_IndexedMapOfShape faces; - TopExp_Explorer xp(shape,TopAbs_FACE); - while (xp.More()) { - face_index.insert(faces.Add(xp.Current())); - xp.Next(); - } - - xp.Init(shape,TopAbs_FACE); - while (xp.More()) { - int index = faces.FindIndex(xp.Current()); - if (face_index.find(index) != face_index.end()) { - face_index.erase(index); - TDF_Label faceLabel= TDF_TagSource::NewChild(shapeLabel); -#if OCC_VERSION_HEX >= 0x060500 - TDataXtd_Shape::Set(faceLabel, xp.Current()); -#else - TDataStd_Shape::Set(faceLabel, xp.Current()); -#endif - const App::Color& color = c[index-1]; - Quantity_Parameter mat[3]; - mat[0] = color.r; - mat[1] = color.g; - mat[2] = color.b; - col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB); - hColors->SetColor(faceLabel, col, XCAFDoc_ColorSurf); - } - xp.Next(); - } - } - } - if (!per_face && vp && vp->isDerivedFrom(PartGui::ViewProviderPart::getClassTypeId())) { - App::Color color = static_cast(vp)->ShapeColor.getValue(); - Quantity_Parameter mat[3]; - mat[0] = color.r; - mat[1] = color.g; - mat[2] = color.b; - col.SetValues(mat[0],mat[1],mat[2],Quantity_TOC_RGB); - hColors->SetColor(shapeLabel, col, XCAFDoc_ColorGen); + 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()); diff --git a/src/Mod/Import/Gui/CMakeLists.txt b/src/Mod/Import/Gui/CMakeLists.txt index 39193982c8..412682401b 100644 --- a/src/Mod/Import/Gui/CMakeLists.txt +++ b/src/Mod/Import/Gui/CMakeLists.txt @@ -22,6 +22,7 @@ link_directories(${OCC_LIBRARY_DIR}) set(ImportGui_LIBS FreeCADGui PartGui + Import ${OCC_OCAF_LIBRARIES} ${OCC_OCAF_DEBUG_LIBRARIES} ) diff --git a/src/Mod/Import/Gui/PreCompiled.h b/src/Mod/Import/Gui/PreCompiled.h index a1aa90f328..98ea64a5b1 100644 --- a/src/Mod/Import/Gui/PreCompiled.h +++ b/src/Mod/Import/Gui/PreCompiled.h @@ -28,11 +28,13 @@ // Importing of App classes #ifdef FC_OS_WIN32 -# define ImportGuiExport __declspec(dllexport) +# define ImportGuiExport __declspec(dllexport) +# define ImportExport __declspec(dllimport) # define PartExport __declspec(dllimport) # define PartGuiExport __declspec(dllimport) #else // for Linux # define ImportGuiExport +# define ImportExport # define PartExport # define PartGuiExport #endif