From 312f2b686d54d5e04621efce7fad574390f2b012 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 11 Jan 2012 16:10:41 +0000 Subject: [PATCH 01/15] 0000439: Improve STEP import to find colors attached to sub-shapes git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5396 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Import/Gui/AppImportGuiPy.cpp | 212 ++++++++++++++++++++++++++ 1 file changed, 212 insertions(+) diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index c429e5f5c..5da7a7dfa 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -37,6 +37,7 @@ # include # include # include +# include # include # include # include @@ -71,6 +72,191 @@ #include #include + + +class ImportOCAF +{ +public: + 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()); + } + + void loadShapes(); + +private: + void loadShapes(const TDF_Label& label, const TopLoc_Location&, const std::string& partname, 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, 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)) { + 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 + + TDF_Label ref; + if (aShapeTool->IsReference(label) && aShapeTool->GetReferredShape(label, ref)) { + loadShapes(ref, part_loc, part_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 (isRef) + createShape( label, loc, defaultname ); + else + createShape( label, part_loc, part_name ); + } + else { + for (TDF_ChildIterator it(label); it.More(); it.Next()) { + loadShapes(it.Value(), part_loc, part_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.Located(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) { + Gui::ViewProvider* vp = Gui::Application::Instance->getViewProvider(part); + if (vp && vp->isDerivedFrom(PartGui::ViewProviderPartExt::getClassTypeId())) { + static_cast(vp)->DiffuseColor.setValues(faceColors); + } + } +} + class ImportXCAF { public: @@ -190,6 +376,12 @@ private: { 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 @@ -248,6 +440,18 @@ private: 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()) { @@ -313,6 +517,9 @@ static PyObject * importer(PyObject *self, PyObject *args) 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; @@ -330,8 +537,13 @@ static PyObject * importer(PyObject *self, PyObject *args) return 0; } +#if 1 + ImportOCAF ocaf(hDoc, pcDoc, file.fileNamePure()); + ocaf.loadShapes(); +#else ImportXCAF xcaf(hDoc, pcDoc, file.fileNamePure()); xcaf.loadShapes(); +#endif pcDoc->recompute(); } From 054384b7565b75bb350750a8f35e73992de633a5 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 11 Jan 2012 16:11:30 +0000 Subject: [PATCH 02/15] + fix translation issue git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5397 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- .../Gui/Resources/translations/Part_de.qm | Bin 51502 -> 51513 bytes .../Gui/Resources/translations/Part_de.ts | 6 +++--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Mod/Part/Gui/Resources/translations/Part_de.qm b/src/Mod/Part/Gui/Resources/translations/Part_de.qm index 7238a8ce097c4f4c8fd4ecd55092c972a2cdd9cd..760a98acff3437c04b552aca9e55dc40b42be49b 100644 GIT binary patch delta 250 zcmZ2CiFxNF<_$GWjEb9Unamj_?=$k5PGw-w{l=)x_?3ZywT00r^c4fcwuO_=GK({I zO@7L(&L}#Wmqnj3ak4GTc}BO*ysZ3;j8`VhvZXUBOm1a+4`i3Jt8+H9>pon^z_4Te z&c#BdYg+w9_26=O%6NgD6Yo< qk}hUYV9;WKut7={CKn!3-hB38BojMS_h#KAjI8V(3=9lRjEn&8WlApq delta 232 zcmdlviFw^5<_$GWjIx_+namj_Z!_|lPGw-w{l=)x_?3ZywT00r^c4fcwz-qfGK({| zO@7L(&L}vUmqnj3cCszYc}AzrysZ3;j29-$vZXW1Om1a+4`i3Jt8><~>pon^z_4TW zCo;Y`2PX>1eSB78)O$KWQg~?KfbT=1;JkDXvn;dq~Q4k~< Y%%H%a#{gBfdCkE(CUzLd@CYL-0DP83A^-pY diff --git a/src/Mod/Part/Gui/Resources/translations/Part_de.ts b/src/Mod/Part/Gui/Resources/translations/Part_de.ts index 2100a5914..89b0b432d 100644 --- a/src/Mod/Part/Gui/Resources/translations/Part_de.ts +++ b/src/Mod/Part/Gui/Resources/translations/Part_de.ts @@ -1001,7 +1001,7 @@ Bitte wählen Sie eine gültige Form im Dropdown-Feld. IGES (*.igs *.iges);;All Files (*.*) - IGES (*.igs *.IGES); Alle Dateien (*.*) + IGES (*.igs *.iges);;Alle Dateien (*.*) @@ -1782,7 +1782,7 @@ Bitte wählen Sie eine gültige Form im Dropdown-Feld. All CAD Files (*.stp *.step *.igs *.iges *.brp *.brep) - Alle CAD-Dateien (*.stp *.step *IGS .IGES *.brp *.brep) + Alle CAD-Dateien (*.stp *.step *.igs *.iges *.brp *.brep) STEP (*.stp *.step) @@ -1790,7 +1790,7 @@ Bitte wählen Sie eine gültige Form im Dropdown-Feld. IGES (*.igs *.iges) - IGES (*.igs *.IGES) + IGES (*.igs *.iges) BREP (*.brp *.brep) From 048528b886587e30fc857aec7b6cefb75f5f8502 Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 11 Jan 2012 18:39:27 +0000 Subject: [PATCH 03/15] + handle Python's SystemExit exception when running script or macro git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5398 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/App/Application.cpp | 4 ++++ src/Base/Interpreter.cpp | 16 ++++++++++++---- src/Gui/Macro.cpp | 11 +++++++---- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 8c43039e5..4a7d79407 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -1190,6 +1190,10 @@ void Application::processCmdLineFiles(void) } } } + catch (const Base::SystemExitException&) { + Base::PyGILStateLocker locker; + Base::Interpreter().systemExit(); + } catch (const Base::Exception& e) { Console().Error("Exception while processing file: %s [%s]\n", File.filePath().c_str(), e.what()); } diff --git a/src/Base/Interpreter.cpp b/src/Base/Interpreter.cpp index e54da64af..a1bd56a9a 100644 --- a/src/Base/Interpreter.cpp +++ b/src/Base/Interpreter.cpp @@ -242,8 +242,12 @@ void InterpreterSingleton::runFile(const char*pxFileName, bool local) PyObject *result = PyRun_File(fp, pxFileName, Py_file_input, dict, dict); fclose(fp); Py_DECREF(dict); - if (!result) - throw PyException(); + if (!result) { + if (PyErr_ExceptionMatches(PyExc_SystemExit)) + throw SystemExitException(); + else + throw PyException(); + } Py_DECREF(result); } else { @@ -271,8 +275,12 @@ bool InterpreterSingleton::loadModule(const char* psModName) PyGILStateLocker locker; module = PP_Load_Module(psModName); - if (!module) - throw PyException(); + if (!module) { + if (PyErr_ExceptionMatches(PyExc_SystemExit)) + throw SystemExitException(); + else + throw PyException(); + } return true; } diff --git a/src/Gui/Macro.cpp b/src/Gui/Macro.cpp index 067f44fa1..f1b505fc2 100644 --- a/src/Gui/Macro.cpp +++ b/src/Gui/Macro.cpp @@ -216,15 +216,18 @@ namespace Gui { void MacroManager::run(MacroType eType,const char *sName) { - try - { + try { PythonRedirector std_out("stdout",new OutputStdout); PythonRedirector std_err("stderr",new OutputStderr); //The given path name is expected to be Utf-8 Base::Interpreter().runFile(sName, true); } - catch (const Base::Exception& e) - { + catch (const Base::SystemExitException&) { + Base::PyGILStateLocker lock; + PyErr_Clear(); + Base::Interpreter().systemExit(); + } + catch (const Base::Exception& e) { qWarning("%s",e.what()); } } From 604088221d73ad314900703afc7179c3dbe2444b Mon Sep 17 00:00:00 2001 From: wmayer Date: Wed, 11 Jan 2012 21:05:23 +0000 Subject: [PATCH 04/15] 0000439: Improve STEP import to find colors attached to sub-shapes git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5399 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Import/Gui/AppImportGuiPy.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index 5da7a7dfa..c47dd6b45 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -142,7 +142,10 @@ void ImportOCAF::loadShapes(const TDF_Label& label, const TopLoc_Location& loc, TopLoc_Location part_loc = loc; Handle(XCAFDoc_Location) hLoc; if (label.FindAttribute(XCAFDoc_Location::GetID(), hLoc)) { - part_loc = hLoc->Get(); + if (isRef) + part_loc = part_loc * hLoc->Get(); + else + part_loc = hLoc->Get(); } #ifdef FC_DEBUG @@ -206,7 +209,7 @@ void ImportOCAF::createShape(const TopoDS_Shape& aShape, const TopLoc_Location& { Part::Feature* part = static_cast(doc->addObject("Part::Feature")); if (!loc.IsIdentity()) - part->Shape.setValue(aShape.Located(loc)); + part->Shape.setValue(aShape.Moved(loc)); else part->Shape.setValue(aShape); part->Label.setValue(name); From db3e0cad432188faedffedf237d3b6ec0fbcc155 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 12 Jan 2012 09:59:28 +0000 Subject: [PATCH 05/15] 0000570: App::Document::_RecomputeFeature(): Unknown exception in Feature "Fusion" thrown git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5400 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/FeaturePartFuse.cpp | 29 +++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/src/Mod/Part/App/FeaturePartFuse.cpp b/src/Mod/Part/App/FeaturePartFuse.cpp index a44f323ef..d0f4a0e97 100644 --- a/src/Mod/Part/App/FeaturePartFuse.cpp +++ b/src/Mod/Part/App/FeaturePartFuse.cpp @@ -24,6 +24,7 @@ #include "PreCompiled.h" #ifndef _PreComp_ # include +# include #endif @@ -81,18 +82,24 @@ App::DocumentObjectExecReturn *MultiFuse::execute(void) } if (s.size() >= 2) { - TopoDS_Shape res = s.front(); - for (std::vector::iterator it = s.begin()+1; it != s.end(); ++it) { - // Let's call algorithm computing a fuse operation: - BRepAlgoAPI_Fuse mkFuse(res, *it); - // Let's check if the fusion has been successful - if (!mkFuse.IsDone()) - throw Base::Exception("Fusion failed"); - res = mkFuse.Shape(); + try { + TopoDS_Shape res = s.front(); + for (std::vector::iterator it = s.begin()+1; it != s.end(); ++it) { + // Let's call algorithm computing a fuse operation: + BRepAlgoAPI_Fuse mkFuse(res, *it); + // Let's check if the fusion has been successful + if (!mkFuse.IsDone()) + throw Base::Exception("Fusion failed"); + res = mkFuse.Shape(); + } + if (res.IsNull()) + throw Base::Exception("Resulting shape is invalid"); + this->Shape.setValue(res); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + return new App::DocumentObjectExecReturn(e->GetMessageString()); } - if (res.IsNull()) - throw Base::Exception("Resulting shape is invalid"); - this->Shape.setValue(res); } else { throw Base::Exception("Not enough shape objects linked"); From 7feebeb5a29b8b42d20d405f308ea7e418e6d0ee Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 12 Jan 2012 12:09:45 +0000 Subject: [PATCH 06/15] + attribute Tolerance added to vertex, edge and face + method 'add' added to wire git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5401 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/TopoShape.cpp | 9 +++--- src/Mod/Part/App/TopoShapeEdgePy.xml | 6 ++++ src/Mod/Part/App/TopoShapeEdgePyImp.cpp | 13 +++++++++ src/Mod/Part/App/TopoShapeFacePy.xml | 6 ++++ src/Mod/Part/App/TopoShapeFacePyImp.cpp | 35 ++++++++++++++++------- src/Mod/Part/App/TopoShapeVertexPy.xml | 6 ++++ src/Mod/Part/App/TopoShapeVertexPyImp.cpp | 13 +++++++++ src/Mod/Part/App/TopoShapeWirePy.xml | 7 ++++- src/Mod/Part/App/TopoShapeWirePyImp.cpp | 34 ++++++++++++++++++++++ 9 files changed, 113 insertions(+), 16 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index f81a04122..c17aa3b1a 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -1679,13 +1679,10 @@ TopoDS_Shape TopoShape::removeShape(const std::vector& s) const void TopoShape::sewShape() { - //ShapeFix_Shape fixer(this->_Shape); - //fixer.Perform(); BRepBuilderAPI_Sewing sew; - sew.Load(this->_Shape/*fixer.Shape()*/); + sew.Load(this->_Shape); sew.Perform(); - //shape = ShapeUpgrade_ShellSewing().ApplySewing(shape); this->_Shape = sew.SewedShape(); } @@ -1722,6 +1719,10 @@ bool TopoShape::fix(double precision, double mintol, double maxtol) fix.FixFaceTool()->Perform(); this->_Shape = fix.Shape(); } + else if (type == TopAbs_WIRE) { + fix.FixWireTool()->Perform(); + this->_Shape = fix.Shape(); + } else { this->_Shape = fix.Shape(); } diff --git a/src/Mod/Part/App/TopoShapeEdgePy.xml b/src/Mod/Part/App/TopoShapeEdgePy.xml index a7f314e79..7e01e5a42 100644 --- a/src/Mod/Part/App/TopoShapeEdgePy.xml +++ b/src/Mod/Part/App/TopoShapeEdgePy.xml @@ -59,6 +59,12 @@ Set the tolerance for the edge. + + + Set or get the tolerance of the vertex + + + Returns the length of the edge diff --git a/src/Mod/Part/App/TopoShapeEdgePyImp.cpp b/src/Mod/Part/App/TopoShapeEdgePyImp.cpp index b69049e6e..d33159b6f 100644 --- a/src/Mod/Part/App/TopoShapeEdgePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeEdgePyImp.cpp @@ -409,6 +409,19 @@ PyObject* TopoShapeEdgePy::setTolerance(PyObject *args) // ====== Attributes ====================================================================== +Py::Float TopoShapeEdgePy::getTolerance(void) const +{ + const TopoDS_Edge& e = TopoDS::Edge(getTopoShapePtr()->_Shape); + return Py::Float(BRep_Tool::Tolerance(e)); +} + +void TopoShapeEdgePy::setTolerance(Py::Float tol) +{ + BRep_Builder aBuilder; + const TopoDS_Edge& e = TopoDS::Edge(getTopoShapePtr()->_Shape); + aBuilder.UpdateEdge(e, (double)tol); +} + Py::Float TopoShapeEdgePy::getLength(void) const { const TopoDS_Edge& e = TopoDS::Edge(getTopoShapePtr()->_Shape); diff --git a/src/Mod/Part/App/TopoShapeFacePy.xml b/src/Mod/Part/App/TopoShapeFacePy.xml index 5c9c62691..f958d0440 100644 --- a/src/Mod/Part/App/TopoShapeFacePy.xml +++ b/src/Mod/Part/App/TopoShapeFacePy.xml @@ -64,6 +64,12 @@ Set the tolerance for the face. + + + Set or get the tolerance of the vertex + + + Returns a 4 tuple with the parameter range diff --git a/src/Mod/Part/App/TopoShapeFacePyImp.cpp b/src/Mod/Part/App/TopoShapeFacePyImp.cpp index 60a1e5e5d..9c65d51f2 100644 --- a/src/Mod/Part/App/TopoShapeFacePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeFacePyImp.cpp @@ -417,17 +417,6 @@ PyObject* TopoShapeFacePy::makeHalfSpace(PyObject *args) } } -PyObject* TopoShapeFacePy::setTolerance(PyObject *args) -{ - double tol; - if (!PyArg_ParseTuple(args, "d", &tol)) - return 0; - BRep_Builder aBuilder; - const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->_Shape); - aBuilder.UpdateFace(f, tol); - Py_Return; -} - Py::Object TopoShapeFacePy::getSurface() const { const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->_Shape); @@ -518,6 +507,30 @@ Py::Object TopoShapeFacePy::getSurface() const throw Py::TypeError("undefined surface type"); } +PyObject* TopoShapeFacePy::setTolerance(PyObject *args) +{ + double tol; + if (!PyArg_ParseTuple(args, "d", &tol)) + return 0; + BRep_Builder aBuilder; + const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->_Shape); + aBuilder.UpdateFace(f, tol); + Py_Return; +} + +Py::Float TopoShapeFacePy::getTolerance(void) const +{ + const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->_Shape); + return Py::Float(BRep_Tool::Tolerance(f)); +} + +void TopoShapeFacePy::setTolerance(Py::Float tol) +{ + BRep_Builder aBuilder; + const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->_Shape); + aBuilder.UpdateFace(f, (double)tol); +} + Py::Tuple TopoShapeFacePy::getParameterRange(void) const { const TopoDS_Face& f = TopoDS::Face(getTopoShapePtr()->_Shape); diff --git a/src/Mod/Part/App/TopoShapeVertexPy.xml b/src/Mod/Part/App/TopoShapeVertexPy.xml index a66f85f4d..38a3c141b 100644 --- a/src/Mod/Part/App/TopoShapeVertexPy.xml +++ b/src/Mod/Part/App/TopoShapeVertexPy.xml @@ -38,6 +38,12 @@ + + + Set or get the tolerance of the vertex + + + Set the tolerance for the vertex. diff --git a/src/Mod/Part/App/TopoShapeVertexPyImp.cpp b/src/Mod/Part/App/TopoShapeVertexPyImp.cpp index 4a0741268..013a5167c 100644 --- a/src/Mod/Part/App/TopoShapeVertexPyImp.cpp +++ b/src/Mod/Part/App/TopoShapeVertexPyImp.cpp @@ -130,6 +130,19 @@ PyObject* TopoShapeVertexPy::setTolerance(PyObject *args) Py_Return; } +Py::Float TopoShapeVertexPy::getTolerance(void) const +{ + const TopoDS_Vertex& v = TopoDS::Vertex(getTopoShapePtr()->_Shape); + return Py::Float(BRep_Tool::Tolerance(v)); +} + +void TopoShapeVertexPy::setTolerance(Py::Float tol) +{ + BRep_Builder aBuilder; + const TopoDS_Vertex& v = TopoDS::Vertex(getTopoShapePtr()->_Shape); + aBuilder.UpdateVertex(v, (double)tol); +} + Py::Float TopoShapeVertexPy::getX(void) const { const TopoDS_Vertex& v = TopoDS::Vertex(getTopoShapePtr()->_Shape); diff --git a/src/Mod/Part/App/TopoShapeWirePy.xml b/src/Mod/Part/App/TopoShapeWirePy.xml index d3a3780c8..21f6419d2 100644 --- a/src/Mod/Part/App/TopoShapeWirePy.xml +++ b/src/Mod/Part/App/TopoShapeWirePy.xml @@ -19,7 +19,12 @@ Offset the shape by a given ammount - + + + Add an edge to the wire + + + Make this and the given wire homogenous to have the same number of edges diff --git a/src/Mod/Part/App/TopoShapeWirePyImp.cpp b/src/Mod/Part/App/TopoShapeWirePyImp.cpp index 55bcb8b3e..839c75172 100644 --- a/src/Mod/Part/App/TopoShapeWirePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeWirePyImp.cpp @@ -42,6 +42,7 @@ #include "BSplineCurvePy.h" #include "TopoShape.h" #include "TopoShapeShellPy.h" +#include "TopoShapeEdgePy.h" #include "TopoShapeWirePy.h" #include "TopoShapeWirePy.cpp" @@ -135,6 +136,39 @@ int TopoShapeWirePy::PyInit(PyObject* args, PyObject* /*kwd*/) return -1; } +PyObject* TopoShapeWirePy::add(PyObject *args) +{ + PyObject* edge; + if (!PyArg_ParseTuple(args, "O!",&(TopoShapePy::Type), &edge)) + return 0; + const TopoDS_Wire& w = TopoDS::Wire(getTopoShapePtr()->_Shape); + BRepBuilderAPI_MakeWire mkWire(w); + + const TopoDS_Shape& sh = static_cast(edge)->getTopoShapePtr()->_Shape; + if (sh.IsNull()) { + PyErr_SetString(PyExc_TypeError, "given shape is invalid"); + return 0; + } + if (sh.ShapeType() == TopAbs_EDGE) + mkWire.Add(TopoDS::Edge(sh)); + else if (sh.ShapeType() == TopAbs_WIRE) + mkWire.Add(TopoDS::Wire(sh)); + else { + PyErr_SetString(PyExc_TypeError, "shape is neither edge nor wire"); + return 0; + } + + try { + getTopoShapePtr()->_Shape = mkWire.Wire(); + Py_Return; + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } +} + PyObject* TopoShapeWirePy::makeOffset(PyObject *args) { float dist; From d3af186c1cf2c0b3b7b57ee6bc4a2e455b8f2449 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 12 Jan 2012 14:04:19 +0000 Subject: [PATCH 07/15] + make try/catch block around sortEdges + set shape immutable when getting from feature + no use of tuples in removeShape git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5402 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/AppPartPy.cpp | 19 ++++++--- src/Mod/Part/App/PropertyTopoShape.cpp | 58 ++++++++++++++------------ src/Mod/Part/App/TopoShapePyImp.cpp | 3 +- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp index 3ef8072ac..1c601b31e 100644 --- a/src/Mod/Part/App/AppPartPy.cpp +++ b/src/Mod/Part/App/AppPartPy.cpp @@ -1320,14 +1320,21 @@ static PyObject * sortEdges(PyObject *self, PyObject *args) } } - std::list sorted = sort_Edges(Precision::Confusion(), edges); + try { + std::list sorted = sort_Edges(Precision::Confusion(), edges); - Py::List sorted_list; - for (std::list::iterator it = sorted.begin(); it != sorted.end(); ++it) { - sorted_list.append(Py::Object(new TopoShapeEdgePy(new TopoShape(*it)),true)); + Py::List sorted_list; + for (std::list::iterator it = sorted.begin(); it != sorted.end(); ++it) { + sorted_list.append(Py::Object(new TopoShapeEdgePy(new TopoShape(*it)),true)); + } + + return Py::new_reference_to(sorted_list); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; } - - return Py::new_reference_to(sorted_list); } static PyObject * cast_to_shape(PyObject *self, PyObject *args) diff --git a/src/Mod/Part/App/PropertyTopoShape.cpp b/src/Mod/Part/App/PropertyTopoShape.cpp index 76ec1f748..d0cc3981c 100644 --- a/src/Mod/Part/App/PropertyTopoShape.cpp +++ b/src/Mod/Part/App/PropertyTopoShape.cpp @@ -147,34 +147,40 @@ void PropertyPartShape::transformGeometry(const Base::Matrix4D &rclTrf) PyObject *PropertyPartShape::getPyObject(void) { + Base::PyObjectBase* prop; const TopoDS_Shape& sh = _Shape._Shape; - if (sh.IsNull()) - return new TopoShapePy(new TopoShape(sh)); - - TopAbs_ShapeEnum type = sh.ShapeType(); - switch (type) - { - case TopAbs_COMPOUND: - return new TopoShapeCompoundPy(new TopoShape(sh)); - case TopAbs_COMPSOLID: - return new TopoShapeCompSolidPy(new TopoShape(sh)); - case TopAbs_SOLID: - return new TopoShapeSolidPy(new TopoShape(sh)); - case TopAbs_SHELL: - return new TopoShapeShellPy(new TopoShape(sh)); - case TopAbs_FACE: - return new TopoShapeFacePy(new TopoShape(sh)); - case TopAbs_WIRE: - return new TopoShapeWirePy(new TopoShape(sh)); - case TopAbs_EDGE: - return new TopoShapeEdgePy(new TopoShape(sh)); - case TopAbs_VERTEX: - return new TopoShapeVertexPy(new TopoShape(sh)); - case TopAbs_SHAPE: - default: - return new TopoShapePy(new TopoShape(sh)); - break; + if (sh.IsNull()) { + prop = new TopoShapePy(new TopoShape(sh)); } + else { + TopAbs_ShapeEnum type = sh.ShapeType(); + switch (type) + { + case TopAbs_COMPOUND: + prop = new TopoShapeCompoundPy(new TopoShape(sh)); + case TopAbs_COMPSOLID: + prop = new TopoShapeCompSolidPy(new TopoShape(sh)); + case TopAbs_SOLID: + prop = new TopoShapeSolidPy(new TopoShape(sh)); + case TopAbs_SHELL: + prop = new TopoShapeShellPy(new TopoShape(sh)); + case TopAbs_FACE: + prop = new TopoShapeFacePy(new TopoShape(sh)); + case TopAbs_WIRE: + prop = new TopoShapeWirePy(new TopoShape(sh)); + case TopAbs_EDGE: + prop = new TopoShapeEdgePy(new TopoShape(sh)); + case TopAbs_VERTEX: + prop = new TopoShapeVertexPy(new TopoShape(sh)); + case TopAbs_SHAPE: + default: + prop = new TopoShapePy(new TopoShape(sh)); + break; + } + } + + if (prop) prop->setConst(); + return prop; } void PropertyPartShape::setPyObject(PyObject *value) diff --git a/src/Mod/Part/App/TopoShapePyImp.cpp b/src/Mod/Part/App/TopoShapePyImp.cpp index 598e7ad8b..8982a1792 100644 --- a/src/Mod/Part/App/TopoShapePyImp.cpp +++ b/src/Mod/Part/App/TopoShapePyImp.cpp @@ -208,8 +208,7 @@ PyObject* TopoShapePy::removeShape(PyObject *args) Py::List list(l); std::vector shapes; for (Py::List::iterator it = list.begin(); it != list.end(); ++it) { - Py::Tuple tuple(*it); - Py::TopoShape sh(tuple[0]); + Py::TopoShape sh(*it); shapes.push_back( sh.extensionObject()->getTopoShapePtr()->_Shape ); From d8109df4c711f034e12054f98581b29e01589390 Mon Sep 17 00:00:00 2001 From: logari81 Date: Thu, 12 Jan 2012 18:21:33 +0000 Subject: [PATCH 08/15] + support deletion of external geometries git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5403 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/App/SketchObject.cpp | 70 +++++++++++++++++----- src/Mod/Sketcher/App/SketchObject.h | 7 ++- src/Mod/Sketcher/App/SketchObjectPyImp.cpp | 14 ++++- 3 files changed, 72 insertions(+), 19 deletions(-) diff --git a/src/Mod/Sketcher/App/SketchObject.cpp b/src/Mod/Sketcher/App/SketchObject.cpp index 1bde4c70f..330ff5ca6 100644 --- a/src/Mod/Sketcher/App/SketchObject.cpp +++ b/src/Mod/Sketcher/App/SketchObject.cpp @@ -141,7 +141,7 @@ int SketchObject::setDatum(int ConstrId, double Datum) { // set the changed value for the constraint const std::vector &vals = this->Constraints.getValues(); - if (ConstrId < 0 || ConstrId >= (int)vals.size()) + if (ConstrId < 0 || ConstrId >= int(vals.size())) return -1; ConstraintType type = vals[ConstrId]->Type; if (type != Distance && @@ -303,7 +303,7 @@ int SketchObject::addGeometry(const Part::Geometry *geo) int SketchObject::delGeometry(int GeoId) { const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - if (GeoId < 0 || GeoId >= (int)vals.size()) + if (GeoId < 0 || GeoId >= int(vals.size())) return -1; std::vector< Part::Geometry * > newVals(vals); @@ -333,7 +333,7 @@ int SketchObject::delGeometry(int GeoId) int SketchObject::toggleConstruction(int GeoId) { const std::vector< Part::Geometry * > &vals = getInternalGeometry(); - if (GeoId < 0 || GeoId >= (int)vals.size()) + if (GeoId < 0 || GeoId >= int(vals.size())) return -1; std::vector< Part::Geometry * > newVals(vals); @@ -367,7 +367,7 @@ int SketchObject::addConstraint(const Constraint *constraint) int SketchObject::delConstraint(int ConstrId) { const std::vector< Constraint * > &vals = this->Constraints.getValues(); - if (ConstrId < 0 || ConstrId >= (int)vals.size()) + if (ConstrId < 0 || ConstrId >= int(vals.size())) return -1; std::vector< Constraint * > newVals(vals); @@ -1039,14 +1039,14 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName) std::vector Objects = ExternalGeometry.getValues(); std::vector SubElements = ExternalGeometry.getSubValues(); - std::vector originalObjects = Objects; - std::vector originalSubElements = SubElements; + const std::vector originalObjects = Objects; + const std::vector originalSubElements = SubElements; - std::vector ::iterator it; - it = std::find(originalSubElements.begin(), originalSubElements.end(), SubName); + std::vector::iterator it; + it = std::find(SubElements.begin(), SubElements.end(), SubName); // avoid duplicates - if (it != originalSubElements.end()) + if (it != SubElements.end()) return -1; // add the new ones @@ -1055,7 +1055,6 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName) // set the Link list. ExternalGeometry.setValues(Objects,SubElements); - try { rebuildExternalGeometry(); } @@ -1065,6 +1064,7 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName) ExternalGeometry.setValues(originalObjects,originalSubElements); return -1; } + Constraints.acceptGeometry(getCompleteGeometry()); rebuildVertexIndex(); return ExternalGeometry.getValues().size()-1; @@ -1072,9 +1072,51 @@ int SketchObject::addExternal(App::DocumentObject *Obj, const char* SubName) int SketchObject::delExternal(int ExtGeoId) { - // FIXME: still to implement - return 0; + // get the actual lists of the externals + std::vector Objects = ExternalGeometry.getValues(); + std::vector SubElements = ExternalGeometry.getSubValues(); + if (ExtGeoId < 0 || ExtGeoId >= int(SubElements.size())) + return -1; + + const std::vector originalObjects = Objects; + const std::vector originalSubElements = SubElements; + + Objects.erase(Objects.begin()+ExtGeoId); + SubElements.erase(SubElements.begin()+ExtGeoId); + + const std::vector< Constraint * > &constraints = Constraints.getValues(); + std::vector< Constraint * > newConstraints(0); + int GeoId = -3 - ExtGeoId; + for (std::vector::const_iterator it = constraints.begin(); + it != constraints.end(); ++it) { + if ((*it)->First != GeoId && (*it)->Second != GeoId) { + Constraint *copiedConstr = (*it)->clone(); + if (copiedConstr->First < GeoId && + copiedConstr->First != Constraint::GeoUndef) + copiedConstr->First += 1; + if (copiedConstr->Second < GeoId && + copiedConstr->Second != Constraint::GeoUndef) + copiedConstr->Second += 1; + newConstraints.push_back(copiedConstr); + } + } + + ExternalGeometry.setValues(Objects,SubElements); + try { + rebuildExternalGeometry(); + } + catch (const Base::Exception& e) { + Base::Console().Error("%s\n", e.what()); + // revert to original values + ExternalGeometry.setValues(originalObjects,originalSubElements); + return -1; + } + + Constraints.setValues(newConstraints); + Constraints.acceptGeometry(getCompleteGeometry()); + rebuildVertexIndex(); + return 0; } const Part::Geometry* SketchObject::getGeometry(int GeoId) const @@ -1095,8 +1137,6 @@ void SketchObject::rebuildExternalGeometry(void) // get the actual lists of the externals std::vector Objects = ExternalGeometry.getValues(); std::vector SubElements = ExternalGeometry.getSubValues(); - if (Objects.size() == 0) - return; Base::Placement Plm = Placement.getValue(); Base::Vector3d Pos = Plm.getPosition(); @@ -1403,7 +1443,7 @@ void SketchObject::onDocumentRestored() void SketchObject::getGeoVertexIndex(int VertexId, int &GeoId, PointPos &PosId) { - if (VertexId < 0 || VertexId >= (int)VertexId2GeoId.size()) { + if (VertexId < 0 || VertexId >= int(VertexId2GeoId.size())) { GeoId = Constraint::GeoUndef; PosId = none; return; diff --git a/src/Mod/Sketcher/App/SketchObject.h b/src/Mod/Sketcher/App/SketchObject.h index 84f2dd0c7..eef799bf7 100644 --- a/src/Mod/Sketcher/App/SketchObject.h +++ b/src/Mod/Sketcher/App/SketchObject.h @@ -76,14 +76,17 @@ public: int transferConstraints(int fromGeoId, PointPos fromPosId, int toGeoId, PointPos toPosId); /// add an external geometry reference int addExternal(App::DocumentObject *Obj, const char* SubName); - /// delete external + /** delete external + * ExtGeoId >= 0 with 0 corresponding to the first user defined + * external geometry + */ int delExternal(int ExtGeoId); /** returns a pointer to a given Geometry index, possible indexes are: * id>=0 for user defined geometries, * id==-1 for the horizontal sketch axis, * id==-2 for the vertical sketch axis - * id<=-3 for projected external geometries, + * id<=-3 for user defined projected external geometries, */ const Part::Geometry* getGeometry(int GeoId) const; /// returns a list of all internal geometries diff --git a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp index d7ecedd90..5f093872f 100644 --- a/src/Mod/Sketcher/App/SketchObjectPyImp.cpp +++ b/src/Mod/Sketcher/App/SketchObjectPyImp.cpp @@ -164,8 +164,18 @@ PyObject* SketchObjectPy::addExternal(PyObject *args) PyObject* SketchObjectPy::delExternal(PyObject *args) { - PyErr_SetString(PyExc_NotImplementedError, "Not yet implemented"); - return 0; + int Index; + if (!PyArg_ParseTuple(args, "i", &Index)) + return 0; + + if (this->getSketchObjectPtr()->delExternal(Index)) { + std::stringstream str; + str << "Not able to delete an external geometry with the given index: " << Index; + PyErr_SetString(PyExc_ValueError, str.str().c_str()); + return 0; + } + + Py_Return; } PyObject* SketchObjectPy::delConstraintOnPoint(PyObject *args) From e4eb1cefe9bc2d2a5c6e74e558f92bfc8d3a2fd6 Mon Sep 17 00:00:00 2001 From: wmayer Date: Thu, 12 Jan 2012 21:31:14 +0000 Subject: [PATCH 09/15] + add some repair functions for wires git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5404 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/TopoShapeCompoundPy.xml | 5 +++ src/Mod/Part/App/TopoShapeCompoundPyImp.cpp | 40 +++++++++++++++++++++ src/Mod/Part/App/TopoShapeWirePy.xml | 5 +++ src/Mod/Part/App/TopoShapeWirePyImp.cpp | 37 +++++++++++++++++++ 4 files changed, 87 insertions(+) diff --git a/src/Mod/Part/App/TopoShapeCompoundPy.xml b/src/Mod/Part/App/TopoShapeCompoundPy.xml index 54036576d..eebec76d5 100644 --- a/src/Mod/Part/App/TopoShapeCompoundPy.xml +++ b/src/Mod/Part/App/TopoShapeCompoundPy.xml @@ -19,5 +19,10 @@ Add a shape to the compound. + + + Build a compound of wires out of the edges of this compound. + + diff --git a/src/Mod/Part/App/TopoShapeCompoundPyImp.cpp b/src/Mod/Part/App/TopoShapeCompoundPyImp.cpp index 489abda5e..3b84d7b97 100644 --- a/src/Mod/Part/App/TopoShapeCompoundPyImp.cpp +++ b/src/Mod/Part/App/TopoShapeCompoundPyImp.cpp @@ -27,6 +27,10 @@ #include #include #include +#include +#include +#include +#include // inclusion of the generated files (generated out of TopoShapeCompoundPy.xml) #include "TopoShapeCompoundPy.h" @@ -103,6 +107,42 @@ PyObject* TopoShapeCompoundPy::add(PyObject *args) Py_Return; } +PyObject* TopoShapeCompoundPy::connectEdgesToWires(PyObject *args) +{ + PyObject *shared=Py_True; + double tol = Precision::Confusion(); + if (!PyArg_ParseTuple(args, "|O!d",&PyBool_Type,&shared,&tol)) + return 0; + + try { + const TopoDS_Shape& s = getTopoShapePtr()->_Shape; + + Handle(TopTools_HSequenceOfShape) hEdges = new TopTools_HSequenceOfShape(); + Handle(TopTools_HSequenceOfShape) hWires = new TopTools_HSequenceOfShape(); + for (TopExp_Explorer xp(s, TopAbs_EDGE); xp.More(); xp.Next()) + hEdges->Append(xp.Current()); + + ShapeAnalysis_FreeBounds::ConnectEdgesToWires(hEdges, tol, (shared==Py_True), hWires); + + TopoDS_Compound comp; + BRep_Builder builder; + builder.MakeCompound(comp); + + int len = hWires->Length(); + for(int i=1;i<=len;i++) { + builder.Add(comp, hWires->Value(i)); + } + + getTopoShapePtr()->_Shape = comp; + return new TopoShapeCompoundPy(new TopoShape(comp)); + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } +} + PyObject *TopoShapeCompoundPy::getCustomAttributes(const char* /*attr*/) const { return 0; diff --git a/src/Mod/Part/App/TopoShapeWirePy.xml b/src/Mod/Part/App/TopoShapeWirePy.xml index 21f6419d2..d1558e9a3 100644 --- a/src/Mod/Part/App/TopoShapeWirePy.xml +++ b/src/Mod/Part/App/TopoShapeWirePy.xml @@ -24,6 +24,11 @@ Add an edge to the wire + + + Fix wire + + Make this and the given wire homogenous to have the same number of edges diff --git a/src/Mod/Part/App/TopoShapeWirePyImp.cpp b/src/Mod/Part/App/TopoShapeWirePyImp.cpp index 839c75172..895b17dff 100644 --- a/src/Mod/Part/App/TopoShapeWirePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeWirePyImp.cpp @@ -28,6 +28,8 @@ # include # include # include +# include +# include # include # include # include @@ -42,6 +44,7 @@ #include "BSplineCurvePy.h" #include "TopoShape.h" #include "TopoShapeShellPy.h" +#include "TopoShapeFacePy.h" #include "TopoShapeEdgePy.h" #include "TopoShapeWirePy.h" #include "TopoShapeWirePy.cpp" @@ -169,6 +172,40 @@ PyObject* TopoShapeWirePy::add(PyObject *args) } } +PyObject* TopoShapeWirePy::fixWire(PyObject *args) +{ + PyObject* face=0; + double tol = Precision::Confusion(); + if (!PyArg_ParseTuple(args, "|O!d",&(TopoShapeFacePy::Type), &face, &tol)) + return 0; + + try { + ShapeFix_Wire aFix; + const TopoDS_Wire& w = TopoDS::Wire(getTopoShapePtr()->_Shape); + + if (face) { + const TopoDS_Face& f = TopoDS::Face(static_cast(face)->getTopoShapePtr()->_Shape); + aFix.Init(w, f, tol); + } + else { + aFix.SetPrecision(tol); + aFix.Load(w); + } + + aFix.FixReorder(); + aFix.FixConnected(); + aFix.FixClosed(); + getTopoShapePtr()->_Shape = aFix.Wire(); + + Py_Return; + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } +} + PyObject* TopoShapeWirePy::makeOffset(PyObject *args) { float dist; From 3ced7cba97a14e73df1336366c8b0c41b7927902 Mon Sep 17 00:00:00 2001 From: wmayer Date: Fri, 13 Jan 2012 18:27:51 +0000 Subject: [PATCH 10/15] + implement OCAF browser git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5405 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Import/Gui/AppImportGuiPy.cpp | 247 ++++++++++++++++++++++++++ src/Mod/Import/Gui/Makefile.am | 2 +- 2 files changed, 248 insertions(+), 1 deletion(-) diff --git a/src/Mod/Import/Gui/AppImportGuiPy.cpp b/src/Mod/Import/Gui/AppImportGuiPy.cpp index c47dd6b45..0c0a30360 100644 --- a/src/Mod/Import/Gui/AppImportGuiPy.cpp +++ b/src/Mod/Import/Gui/AppImportGuiPy.cpp @@ -675,11 +675,258 @@ static PyObject * exporter(PyObject *self, PyObject *args) Py_Return; } +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class OCAFBrowser +{ +public: + OCAFBrowser(Handle_TDocStd_Document h) + : pDoc(h) + { + myGroupIcon = QApplication::style()->standardIcon(QStyle::SP_DirIcon); + myTree = new QTreeWidget(); + myTree->setHeaderLabel(QString::fromAscii("OCAF Browser")); + + TDataStd::IDList(myList); + myList.Append(TDataStd_TreeNode::GetDefaultTreeID()); + myList.Append(TDataStd_Integer::GetID()); + myList.Append(TDocStd_Owner::GetID()); + myList.Append(TNaming_NamedShape::GetID()); + myList.Append(TNaming_UsedShapes::GetID()); + myList.Append(XCAFDoc_Color::GetID()); + myList.Append(XCAFDoc_ColorTool::GetID()); + myList.Append(XCAFDoc_LayerTool::GetID()); + myList.Append(XCAFDoc_ShapeTool::GetID()); + myList.Append(XCAFDoc_ShapeMapTool::GetID()); + myList.Append(XCAFDoc_Location::GetID()); + } + + void load(); + +private: + void load(const TDF_Label& label, QTreeWidgetItem* item, const QString&); + std::string toString(const TCollection_ExtendedString& extstr) const + { + char* str = new char[extstr.LengthOfCString()+1]; + extstr.ToUTF8CString(str); + std::string text(str); + delete [] str; + return text; + } + +private: + QIcon myGroupIcon; + QTreeWidget* myTree; + TDF_IDList myList; + Handle_TDocStd_Document pDoc; +}; + +void OCAFBrowser::load() +{ + myTree->clear(); + + QTreeWidgetItem* root = new QTreeWidgetItem(); + root->setText(0, QLatin1String("0")); + root->setIcon(0, myGroupIcon); + myTree->addTopLevelItem(root); + + load(pDoc->GetData()->Root(), root, QString::fromAscii("0")); + myTree->show(); +} + +void OCAFBrowser::load(const TDF_Label& label, QTreeWidgetItem* item, const QString& s) +{ + Handle(TDataStd_Name) name; + if (label.FindAttribute(TDataStd_Name::GetID(),name)) { + QString text = QString::fromAscii("%1 %2").arg(s).arg(QString::fromUtf8(toString(name->Get()).c_str())); + item->setText(0, text); + } + + for (TDF_ListIteratorOfIDList it(myList); it.More(); it.Next()) { + Handle(TDF_Attribute) attr; + if (label.FindAttribute(it.Value(), attr)) { + QTreeWidgetItem* child = new QTreeWidgetItem(); + item->addChild(child); + if (it.Value() == TDataStd_Name::GetID()) { + QString text; + QTextStream str(&text); + str << attr->DynamicType()->Name(); + str << " = " << toString(Handle_TDataStd_Name::DownCast(attr)->Get()).c_str(); + child->setText(0, text); + } + else if (it.Value() == TDF_TagSource::GetID()) { + QString text; + QTextStream str(&text); + str << attr->DynamicType()->Name(); + str << " = " << Handle_TDF_TagSource::DownCast(attr)->Get(); + child->setText(0, text); + } + else if (it.Value() == TDataStd_Integer::GetID()) { + QString text; + QTextStream str(&text); + str << attr->DynamicType()->Name(); + str << " = " << Handle_TDataStd_Integer::DownCast(attr)->Get(); + child->setText(0, text); + } + else if (it.Value() == TNaming_NamedShape::GetID()) { + TopoDS_Shape shape = Handle_TNaming_NamedShape::DownCast(attr)->Get(); + QString text; + QTextStream str(&text); + str << attr->DynamicType()->Name() << " = "; + if (!shape.IsNull()) { + switch (shape.ShapeType()) { + case TopAbs_COMPOUND: + str << "COMPOUND PRIMITIVE"; + break; + case TopAbs_COMPSOLID: + str << "COMPSOLID PRIMITIVE"; + break; + case TopAbs_SOLID: + str << "SOLID PRIMITIVE"; + break; + case TopAbs_SHELL: + str << "SHELL PRIMITIVE"; + break; + case TopAbs_FACE: + str << "FACE PRIMITIVE"; + break; + case TopAbs_WIRE: + str << "WIRE PRIMITIVE"; + break; + case TopAbs_EDGE: + str << "EDGE PRIMITIVE"; + break; + case TopAbs_VERTEX: + str << "VERTEX PRIMITIVE"; + break; + case TopAbs_SHAPE: + str << "SHAPE PRIMITIVE"; + break; + } + } + child->setText(0, text); + } + else { + child->setText(0, QLatin1String(attr->DynamicType()->Name())); + } + } + } + + //TDF_ChildIDIterator nodeIterator(label, XCAFDoc::ShapeRefGUID()); + //for (; nodeIterator.More(); nodeIterator.Next()) { + // Handle(TDataStd_TreeNode) node = Handle(TDataStd_TreeNode)::DownCast(nodeIterator.Value()); + // //if (node->HasFather()) + // // ; + // QTreeWidgetItem* child = new QTreeWidgetItem(); + // child->setText(0, QString::fromAscii("TDataStd_TreeNode")); + // item->addChild(child); + //} + + int i=1; + for (TDF_ChildIterator it(label); it.More(); it.Next(),i++) { + QString text = QString::fromAscii("%1:%2").arg(s).arg(i); + QTreeWidgetItem* child = new QTreeWidgetItem(); + child->setText(0, text); + child->setIcon(0, myGroupIcon); + item->addChild(child); + load(it.Value(), child, text); + } +} + +static PyObject * ocaf(PyObject *self, PyObject *args) +{ + const char* Name; + if (!PyArg_ParseTuple(args, "s",&Name)) + return 0; + + PY_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) { + PyErr_SetString(PyExc_Exception, "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(); + } + else if (file.hasExtension("igs") || file.hasExtension("iges")) { + 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(); + } + else { + PyErr_SetString(PyExc_Exception, "no supported file format"); + return 0; + } + + OCAFBrowser browse(hDoc); + browse.load(); + } + 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 ImportGui_Import_methods[] = { {"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 */ }; diff --git a/src/Mod/Import/Gui/Makefile.am b/src/Mod/Import/Gui/Makefile.am index 348856fe2..255e13e93 100644 --- a/src/Mod/Import/Gui/Makefile.am +++ b/src/Mod/Import/Gui/Makefile.am @@ -18,7 +18,7 @@ libImportGui_la_LDFLAGS = \ -L../../../Gui \ -L../../Part/App \ -L../../Part/Gui \ - -L$(OCC_LIB) $(QT4_CORE_LIBS) $(all_libraries) \ + -L$(OCC_LIB) $(QT_LIBS) $(all_libraries) \ -version-info @LIB_CURRENT@:@LIB_REVISION@:@LIB_AGE@ libImportGui_la_CPPFLAGS = -DAppPartExport= -DAppPartGuiExport= From 197f87537574e8aa282b7fbd554e6d7dc1e1f08c Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 14 Jan 2012 01:19:33 +0000 Subject: [PATCH 11/15] + handle case if each face has its own color and a face has no triangles + do not write out fields of SoFCUnifiedSelection node + show wait cursor when importing parts git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5406 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Gui/SoFCUnifiedSelection.cpp | 14 ++++++++++++++ src/Gui/SoFCUnifiedSelection.h | 1 + src/Mod/Part/Gui/Command.cpp | 2 ++ src/Mod/Part/Gui/SoBrepShape.cpp | 16 ++++++++++++++++ 4 files changed, 33 insertions(+) diff --git a/src/Gui/SoFCUnifiedSelection.cpp b/src/Gui/SoFCUnifiedSelection.cpp index 40025357b..77929a281 100644 --- a/src/Gui/SoFCUnifiedSelection.cpp +++ b/src/Gui/SoFCUnifiedSelection.cpp @@ -169,6 +169,20 @@ const char* SoFCUnifiedSelection::getFileFormatName(void) const return "Separator"; } +void SoFCUnifiedSelection::write(SoWriteAction * action) +{ + SoOutput * out = action->getOutput(); + if (out->getStage() == SoOutput::WRITE) { + // Do not write out the fields of this class + if (this->writeHeader(out, TRUE, FALSE)) return; + SoGroup::doAction((SoAction *)action); + this->writeFooter(out); + } + else { + inherited::write(action); + } +} + int SoFCUnifiedSelection::getPriority(const SoPickedPoint* p) { const SoDetail* detail = p->getDetail(); diff --git a/src/Gui/SoFCUnifiedSelection.h b/src/Gui/SoFCUnifiedSelection.h index 30216d668..491c2d2c1 100644 --- a/src/Gui/SoFCUnifiedSelection.h +++ b/src/Gui/SoFCUnifiedSelection.h @@ -72,6 +72,7 @@ public: }; const char* getFileFormatName(void) const; + void write(SoWriteAction * action); SoSFColor colorHighlight; SoSFColor colorSelection; diff --git a/src/Mod/Part/Gui/Command.cpp b/src/Mod/Part/Gui/Command.cpp index fdcfefc89..6bcce90fa 100644 --- a/src/Mod/Part/Gui/Command.cpp +++ b/src/Mod/Part/Gui/Command.cpp @@ -47,6 +47,7 @@ #include #include #include +#include #include "../App/PartFeature.h" #include "DlgPartImportStepImp.h" @@ -452,6 +453,7 @@ void CmdPartImport::activated(int iMsg) QString fn = Gui::FileDialog::getOpenFileName(Gui::getMainWindow(), QString(), QString(), filter.join(QLatin1String(";;"))); if (!fn.isEmpty()) { + Gui::WaitCursor wc; App::Document* pDoc = getDocument(); if (!pDoc) return; // no document openCommand("Import Part"); diff --git a/src/Mod/Part/Gui/SoBrepShape.cpp b/src/Mod/Part/Gui/SoBrepShape.cpp index 2b9fe5b2b..0f8dacbab 100644 --- a/src/Mod/Part/Gui/SoBrepShape.cpp +++ b/src/Mod/Part/Gui/SoBrepShape.cpp @@ -391,6 +391,14 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, int matnr = 0; int trinr = 0; pi = piptr < piendptr ? *piptr++ : -1; + while (pi == 0) { + // It may happen that a part has no triangles + pi = piptr < piendptr ? *piptr++ : -1; + if (mbind == PER_PART) + matnr++; + else if (mbind == PER_PART_INDEXED) + matindices++; + } glBegin(GL_TRIANGLES); while (viptr + 2 < viendptr) { @@ -503,6 +511,14 @@ void SoBrepFaceSet::renderShape(const SoGLCoordinateElement * const vertexlist, trinr++; if (pi == trinr) { pi = piptr < piendptr ? *piptr++ : -1; + while (pi == 0) { + // It may happen that a part has no triangles + pi = piptr < piendptr ? *piptr++ : -1; + if (mbind == PER_PART) + matnr++; + else if (mbind == PER_PART_INDEXED) + matindices++; + } trinr = 0; } } From b4c91af000b58251a41a6e67ad7764825e663c19 Mon Sep 17 00:00:00 2001 From: wmayer Date: Sat, 14 Jan 2012 15:44:05 +0000 Subject: [PATCH 12/15] + use UTF8-encoding of degree symbol git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5408 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Gui/Command.cpp | 12 ++++++------ src/Gui/CommandView.cpp | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/src/Gui/Command.cpp b/src/Gui/Command.cpp index db0bf9890..40fdb9557 100644 --- a/src/Gui/Command.cpp +++ b/src/Gui/Command.cpp @@ -504,26 +504,26 @@ void Command::applyCommandData(Action* action) { action->setText(QCoreApplication::translate( this->className(), sMenuText, 0, - QCoreApplication::CodecForTr)); + QCoreApplication::UnicodeUTF8)); action->setToolTip(QCoreApplication::translate( this->className(), sToolTipText, 0, - QCoreApplication::CodecForTr)); + QCoreApplication::UnicodeUTF8)); if (sStatusTip) action->setStatusTip(QCoreApplication::translate( this->className(), sStatusTip, 0, - QCoreApplication::CodecForTr)); + QCoreApplication::UnicodeUTF8)); else action->setStatusTip(QCoreApplication::translate( this->className(), sToolTipText, 0, - QCoreApplication::CodecForTr)); + QCoreApplication::UnicodeUTF8)); if (sWhatsThis) action->setWhatsThis(QCoreApplication::translate( this->className(), sWhatsThis, 0, - QCoreApplication::CodecForTr)); + QCoreApplication::UnicodeUTF8)); else action->setWhatsThis(QCoreApplication::translate( this->className(), sToolTipText, 0, - QCoreApplication::CodecForTr)); + QCoreApplication::UnicodeUTF8)); } const char* Command::keySequenceToAccel(int sk) const diff --git a/src/Gui/CommandView.cpp b/src/Gui/CommandView.cpp index c8d70a85f..e8c580ca4 100644 --- a/src/Gui/CommandView.cpp +++ b/src/Gui/CommandView.cpp @@ -1064,9 +1064,9 @@ StdCmdViewRotateLeft::StdCmdViewRotateLeft() { sGroup = QT_TR_NOOP("Standard-View"); sMenuText = QT_TR_NOOP("Rotate Left"); - sToolTipText = QT_TR_NOOP("Rotate the view by 90° counter-clockwise"); + sToolTipText = QT_TR_NOOP("Rotate the view by 90\xc2\xb0 counter-clockwise"); sWhatsThis = "Std_ViewXX"; - sStatusTip = QT_TR_NOOP("Rotate the view by 90° counter-clockwise"); + sStatusTip = QT_TR_NOOP("Rotate the view by 90\xc2\xb0 counter-clockwise"); sPixmap = "view-rotate-left"; //sAccel = "Shift Left"; eType = Alter3DView; @@ -1088,9 +1088,9 @@ StdCmdViewRotateRight::StdCmdViewRotateRight() { sGroup = QT_TR_NOOP("Standard-View"); sMenuText = QT_TR_NOOP("Rotate Right"); - sToolTipText = QT_TR_NOOP("Rotate the view by 90° clockwise"); + sToolTipText = QT_TR_NOOP("Rotate the view by 90\xc2\xb0 clockwise"); sWhatsThis = "Std_ViewXX"; - sStatusTip = QT_TR_NOOP("Rotate the view by 90° clockwise"); + sStatusTip = QT_TR_NOOP("Rotate the view by 90\xc2\xb0 clockwise"); sPixmap = "view-rotate-right"; //sAccel = "Shift Right"; eType = Alter3DView; From 0496df65383cc6bf0ea17dd8f22d08c4201a5d49 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 16 Jan 2012 14:45:48 +0000 Subject: [PATCH 13/15] + check if re-mapping causes cyclic dependency git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5409 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Sketcher/Gui/Command.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/Mod/Sketcher/Gui/Command.cpp b/src/Mod/Sketcher/Gui/Command.cpp index eeddfb858..6a5a5061d 100644 --- a/src/Mod/Sketcher/Gui/Command.cpp +++ b/src/Mod/Sketcher/Gui/Command.cpp @@ -215,6 +215,15 @@ void CmdSketcherMapSketch::activated(int iMsg) qApp->translate(className(),"You have to select a single face as support for a sketch!")); return; } + + std::vector input = part->getOutList(); + if (std::find(input.begin(), input.end(), sel[index]) != input.end()) { + QMessageBox::warning(Gui::getMainWindow(), + qApp->translate(className(),"Cyclic dependency"), + qApp->translate(className(),"You cannot choose a support object depending on the selected sketch!")); + return; + } + // get the selected sub shape (a Face) const Part::TopoShape &shape = part->Shape.getValue(); TopoDS_Shape sh = shape.getSubShape(sub[0].c_str()); From a75fb034073165420f91fd96f8e6eb1df4afef95 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 16 Jan 2012 20:23:26 +0000 Subject: [PATCH 14/15] 0000572: add a method to Part module to read BRep data from string git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5410 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Base/Stream.cpp | 53 +++++++++++++++++++++++++++++ src/Base/Stream.h | 16 +++++++++ src/Mod/Part/App/TopoShape.cpp | 26 ++++++++++++++ src/Mod/Part/App/TopoShape.h | 1 + src/Mod/Part/App/TopoShapePy.xml | 5 +++ src/Mod/Part/App/TopoShapePyImp.cpp | 24 +++++++++++++ 6 files changed, 125 insertions(+) diff --git a/src/Base/Stream.cpp b/src/Base/Stream.cpp index e962be914..009cf7e23 100644 --- a/src/Base/Stream.cpp +++ b/src/Base/Stream.cpp @@ -40,6 +40,7 @@ #include "Stream.h" #include "Swap.h" #include "FileInfo.h" +#include using namespace Base; @@ -533,6 +534,58 @@ IODeviceIStreambuf::seekpos(std::streambuf::pos_type pos, return seekoff(pos, std::ios_base::beg); } +// --------------------------------------------------------- + +PyStreambuf::PyStreambuf(PyObject* o) : inp(o) +{ + setg (buffer+pbSize, + buffer+pbSize, + buffer+pbSize); +} + +int PyStreambuf::underflow() +{ + if (gptr() < egptr()) { + return *gptr(); + } + + int numPutback; + numPutback = gptr() - eback(); + if (numPutback > pbSize) { + numPutback = pbSize; + } + + memcpy (buffer+(pbSize-numPutback), gptr()-numPutback, numPutback); + + int num=0; + for (int i=0; i(res)[0]; + num++; + buffer[pbSize+i] = c; + if (c == '\n') + break; + } + catch (Py::Exception& e) { + e.clear(); + if (num == 0) + return EOF; + break; + } + } + + setg (buffer+(pbSize-numPutback), + buffer+pbSize, + buffer+pbSize+num); + + return *gptr(); +} + // --------------------------------------------------------- Streambuf::Streambuf(const std::string& data) diff --git a/src/Base/Stream.h b/src/Base/Stream.h index 1836f2116..f083e1e58 100644 --- a/src/Base/Stream.h +++ b/src/Base/Stream.h @@ -35,6 +35,7 @@ class QByteArray; class QIODevice; class QBuffer; +typedef struct _object PyObject; namespace Base { @@ -232,6 +233,21 @@ protected: static const int bufSize = 1024; // size of the data buffer char buffer[bufSize+pbSize]; // data buffer }; + +class BaseExport PyStreambuf : public std::streambuf +{ +public: + PyStreambuf(PyObject* o); + +protected: + int underflow(); + +private: + static const int pbSize = 4; + static const int bufSize = 1024; + char buffer[bufSize+pbSize]; + PyObject* inp; +}; class BaseExport Streambuf : public std::streambuf { diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index c17aa3b1a..86e50b98e 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -609,6 +609,32 @@ void TopoShape::importBrep(const char *FileName) } } +void TopoShape::importBrep(std::istream& str) +{ + try { + // read brep-file + BRep_Builder aBuilder; + TopoDS_Shape aShape; +#if OCC_HEX_VERSION >= 0x060300 + Handle_Message_ProgressIndicator pi = new ProgressIndicator(100); + pi->NewScope(100, "Reading BREP file..."); + pi->Show(); + BRepTools::Read(aShape,str,aBuilder,pi); + pi->EndScope(); +#else + BRepTools::Read(aShape,str,aBuilder); +#endif + this->_Shape = aShape; + } + catch (Standard_Failure) { + Handle(Standard_Failure) aFail = Standard_Failure::Caught(); + throw Base::Exception(aFail->GetMessageString()); + } + catch (const std::exception& e) { + throw Base::Exception(e.what()); + } +} + void TopoShape::write(const char *FileName) const { Base::FileInfo File(FileName); diff --git a/src/Mod/Part/App/TopoShape.h b/src/Mod/Part/App/TopoShape.h index 389511d05..9f3b17562 100644 --- a/src/Mod/Part/App/TopoShape.h +++ b/src/Mod/Part/App/TopoShape.h @@ -120,6 +120,7 @@ public: void importIges(const char *FileName); void importStep(const char *FileName); void importBrep(const char *FileName); + void importBrep(std::istream&); void exportIges(const char *FileName) const; void exportStep(const char *FileName) const; void exportBrep(const char *FileName) const; diff --git a/src/Mod/Part/App/TopoShapePy.xml b/src/Mod/Part/App/TopoShapePy.xml index 1a953e2c6..f31f99f56 100644 --- a/src/Mod/Part/App/TopoShapePy.xml +++ b/src/Mod/Part/App/TopoShapePy.xml @@ -48,6 +48,11 @@ Sub-elements such as vertices, edges or faces are accessible as: Export the content of this shape to an STL mesh file. + + + Import the content to this shape of a string in BREP format. + + Extrude the shape along a direction. diff --git a/src/Mod/Part/App/TopoShapePyImp.cpp b/src/Mod/Part/App/TopoShapePyImp.cpp index 8982a1792..3aef9eab9 100644 --- a/src/Mod/Part/App/TopoShapePyImp.cpp +++ b/src/Mod/Part/App/TopoShapePyImp.cpp @@ -311,6 +311,30 @@ PyObject* TopoShapePy::exportBrep(PyObject *args) Py_Return; } +PyObject* TopoShapePy::importBrep(PyObject *args) +{ + PyObject* input; + if (!PyArg_ParseTuple(args, "O", &input)) + //char* input; + //if (!PyArg_ParseTuple(args, "s", &input)) + return NULL; + + try { + // read brep + Base::PyStreambuf buf(input); + std::istream str(0); + str.rdbuf(&buf); + //std::stringstream str(input); + getTopoShapePtr()->importBrep(str); + } + catch (const Base::Exception& e) { + PyErr_SetString(PyExc_Exception,e.what()); + return NULL; + } + + Py_Return; +} + PyObject* TopoShapePy::exportStl(PyObject *args) { char* filename; From f9f668f8fccce10bc6f460c164be96c9ba91f433 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 16 Jan 2012 21:58:58 +0000 Subject: [PATCH 15/15] + fix but that Angle has no effect after creation of revolve feature git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5411 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/FeatureRevolution.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Mod/Part/App/FeatureRevolution.cpp b/src/Mod/Part/App/FeatureRevolution.cpp index b9fb9ddde..dce8533fc 100644 --- a/src/Mod/Part/App/FeatureRevolution.cpp +++ b/src/Mod/Part/App/FeatureRevolution.cpp @@ -49,6 +49,7 @@ short Revolution::mustExecute() const { if (Base.isTouched() || Axis.isTouched() || + Angle.isTouched() || Source.isTouched()) return 1; return 0;