From 3933c6b109381c131bcb2e2f637d17bdb9b6a8c2 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 24 Jan 2012 15:23:58 +0000 Subject: [PATCH 1/4] + implement Python interface to discretize wires or edge with given deflection or number of points git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5423 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/GeometryCurvePy.xml | 2 +- src/Mod/Part/App/GeometryCurvePyImp.cpp | 25 +++++++++---- src/Mod/Part/App/TopoShapeEdgePy.xml | 5 +++ src/Mod/Part/App/TopoShapeEdgePyImp.cpp | 47 +++++++++++++++++++++++++ src/Mod/Part/App/TopoShapeWirePy.xml | 17 +++++---- src/Mod/Part/App/TopoShapeWirePyImp.cpp | 47 +++++++++++++++++++++++++ 6 files changed, 129 insertions(+), 14 deletions(-) diff --git a/src/Mod/Part/App/GeometryCurvePy.xml b/src/Mod/Part/App/GeometryCurvePy.xml index eaae3fb190..78090909c6 100644 --- a/src/Mod/Part/App/GeometryCurvePy.xml +++ b/src/Mod/Part/App/GeometryCurvePy.xml @@ -23,7 +23,7 @@ - Discretizes the curve using a given deflection and returns a list of points + Discretizes the curve using a given deflection or number of points and returns a list of points diff --git a/src/Mod/Part/App/GeometryCurvePyImp.cpp b/src/Mod/Part/App/GeometryCurvePyImp.cpp index 2c9deb4e69..01f91500a1 100644 --- a/src/Mod/Part/App/GeometryCurvePyImp.cpp +++ b/src/Mod/Part/App/GeometryCurvePyImp.cpp @@ -108,22 +108,33 @@ PyObject* GeometryCurvePy::toShape(PyObject *args) PyObject* GeometryCurvePy::discretize(PyObject *args) { - double d; - if (!PyArg_ParseTuple(args, "d", &d)) + PyObject* defl_or_num; + if (!PyArg_ParseTuple(args, "O", &defl_or_num)) return 0; - Handle_Geom_Geometry g = getGeometryPtr()->handle(); - Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g); try { + Handle_Geom_Geometry g = getGeometryPtr()->handle(); + Handle_Geom_Curve c = Handle_Geom_Curve::DownCast(g); if (!c.IsNull()) { - GeomAdaptor_Curve curve_adaptator(c); + GeomAdaptor_Curve adapt(c); GCPnts_UniformAbscissa discretizer; - discretizer.Initialize (curve_adaptator, d); + if (PyInt_Check(defl_or_num)) { + int num = PyInt_AsLong(defl_or_num); + discretizer.Initialize (adapt, num); + } + else if (PyFloat_Check(defl_or_num)) { + double defl = PyFloat_AsDouble(defl_or_num); + discretizer.Initialize (adapt, defl); + } + else { + PyErr_SetString(PyExc_TypeError, "Either int or float expected"); + return 0; + } if (discretizer.IsDone () && discretizer.NbPoints () > 0) { Py::List points; int nbPoints = discretizer.NbPoints (); for (int i=1; i<=nbPoints; i++) { - gp_Pnt p = curve_adaptator.Value (discretizer.Parameter (i)); + gp_Pnt p = adapt.Value (discretizer.Parameter (i)); points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z()))); } diff --git a/src/Mod/Part/App/TopoShapeEdgePy.xml b/src/Mod/Part/App/TopoShapeEdgePy.xml index 7e01e5a422..873b3fb726 100644 --- a/src/Mod/Part/App/TopoShapeEdgePy.xml +++ b/src/Mod/Part/App/TopoShapeEdgePy.xml @@ -59,6 +59,11 @@ Set the tolerance for the edge. + + + Discretizes the edge using a given deflection or number of points and returns a list of points + + Set or get the tolerance of the vertex diff --git a/src/Mod/Part/App/TopoShapeEdgePyImp.cpp b/src/Mod/Part/App/TopoShapeEdgePyImp.cpp index d33159b6fc..ec5bc09054 100644 --- a/src/Mod/Part/App/TopoShapeEdgePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeEdgePyImp.cpp @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -396,6 +397,52 @@ PyObject* TopoShapeEdgePy::derivative3At(PyObject *args) } } +PyObject* TopoShapeEdgePy::discretize(PyObject *args) +{ + PyObject* defl_or_num; + if (!PyArg_ParseTuple(args, "O", &defl_or_num)) + return 0; + + try { + BRepAdaptor_Curve adapt(TopoDS::Edge(getTopoShapePtr()->_Shape)); + GCPnts_UniformAbscissa discretizer; + if (PyInt_Check(defl_or_num)) { + int num = PyInt_AsLong(defl_or_num); + discretizer.Initialize (adapt, num); + } + else if (PyFloat_Check(defl_or_num)) { + double defl = PyFloat_AsDouble(defl_or_num); + discretizer.Initialize (adapt, defl); + } + else { + PyErr_SetString(PyExc_TypeError, "Either int or float expected"); + return 0; + } + if (discretizer.IsDone () && discretizer.NbPoints () > 0) { + Py::List points; + int nbPoints = discretizer.NbPoints (); + for (int i=1; i<=nbPoints; i++) { + gp_Pnt p = adapt.Value (discretizer.Parameter (i)); + points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z()))); + } + + return Py::new_reference_to(points); + } + else { + PyErr_SetString(PyExc_Exception, "Descretization of curve failed"); + return 0; + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PyExc_Exception, "Geometry is not a curve"); + return 0; +} + PyObject* TopoShapeEdgePy::setTolerance(PyObject *args) { double tol; diff --git a/src/Mod/Part/App/TopoShapeWirePy.xml b/src/Mod/Part/App/TopoShapeWirePy.xml index d1558e9a36..057bfc9c99 100644 --- a/src/Mod/Part/App/TopoShapeWirePy.xml +++ b/src/Mod/Part/App/TopoShapeWirePy.xml @@ -45,13 +45,18 @@ - - Approximate B-Spline-curve from this wire - - - - Returns the center of mass of the current system. + Approximate B-Spline-curve from this wire + + + + + Discretizes the wire using a given deflection or number of points and returns a list of points + + + + + Returns the center of mass of the current system. If the gravitational field is uniform, it is the center of gravity. The coordinates returned for the center of mass are expressed in the absolute Cartesian coordinate system. diff --git a/src/Mod/Part/App/TopoShapeWirePyImp.cpp b/src/Mod/Part/App/TopoShapeWirePyImp.cpp index 895b17dff6..0011e21984 100644 --- a/src/Mod/Part/App/TopoShapeWirePyImp.cpp +++ b/src/Mod/Part/App/TopoShapeWirePyImp.cpp @@ -37,6 +37,7 @@ #include #include +#include #include #include @@ -320,6 +321,52 @@ PyObject* TopoShapeWirePy::approximate(PyObject *args) } } +PyObject* TopoShapeWirePy::discretize(PyObject *args) +{ + PyObject* defl_or_num; + if (!PyArg_ParseTuple(args, "O", &defl_or_num)) + return 0; + + try { + BRepAdaptor_CompCurve adapt(TopoDS::Wire(getTopoShapePtr()->_Shape)); + GCPnts_UniformAbscissa discretizer; + if (PyInt_Check(defl_or_num)) { + int num = PyInt_AsLong(defl_or_num); + discretizer.Initialize (adapt, num); + } + else if (PyFloat_Check(defl_or_num)) { + double defl = PyFloat_AsDouble(defl_or_num); + discretizer.Initialize (adapt, defl); + } + else { + PyErr_SetString(PyExc_TypeError, "Either int or float expected"); + return 0; + } + if (discretizer.IsDone () && discretizer.NbPoints () > 0) { + Py::List points; + int nbPoints = discretizer.NbPoints (); + for (int i=1; i<=nbPoints; i++) { + gp_Pnt p = adapt.Value (discretizer.Parameter (i)); + points.append(Py::Vector(Base::Vector3d(p.X(),p.Y(),p.Z()))); + } + + return Py::new_reference_to(points); + } + else { + PyErr_SetString(PyExc_Exception, "Descretization of wire failed"); + return 0; + } + } + catch (Standard_Failure) { + Handle_Standard_Failure e = Standard_Failure::Caught(); + PyErr_SetString(PyExc_Exception, e->GetMessageString()); + return 0; + } + + PyErr_SetString(PyExc_Exception, "Geometry is not a curve"); + return 0; +} + Py::Object TopoShapeWirePy::getCenterOfMass(void) const { GProp_GProps props; From b57ca9ad6441cc8a68796c0579454e8803ef2d22 Mon Sep 17 00:00:00 2001 From: wmayer Date: Tue, 24 Jan 2012 16:38:06 +0000 Subject: [PATCH 2/4] + patch: improve face union (tanderson69) git-svn-id: https://free-cad.svn.sourceforge.net/svnroot/free-cad/trunk@5424 e8eeb9e2-ec13-0410-a4a9-efa5cf37419d --- src/Mod/Part/App/TopoShape.cpp | 46 +++++++++++++++++++++----------- src/Mod/Part/App/modelRefine.cpp | 19 ++----------- src/Mod/Part/App/modelRefine.h | 4 +-- 3 files changed, 34 insertions(+), 35 deletions(-) diff --git a/src/Mod/Part/App/TopoShape.cpp b/src/Mod/Part/App/TopoShape.cpp index 86e50b98e6..490ba3c78c 100644 --- a/src/Mod/Part/App/TopoShape.cpp +++ b/src/Mod/Part/App/TopoShape.cpp @@ -1771,17 +1771,24 @@ TopoDS_Shape TopoShape::removeSplitter() const Standard_Failure::Raise("Cannot remove splitter from empty shape"); if (_Shape.ShapeType() == TopAbs_SOLID) { - const TopoDS_Solid& solid = TopoDS::Solid(_Shape); - ModelRefine::FaceUniter uniter(solid); - if (uniter.process()) { - TopoDS_Solid solidMod; - if (!uniter.getSolid(solidMod)) - Standard_Failure::Raise("Getting solid failed"); - return solidMod; - } - else { - Standard_Failure::Raise("Removing splitter failed"); + const TopoDS_Solid &solid = TopoDS::Solid(_Shape); + BRepTools_ReShape reshape; + TopExp_Explorer it; + for (it.Init(solid, TopAbs_SHELL); it.More(); it.Next()) { + const TopoDS_Shell ¤tShell = TopoDS::Shell(it.Current()); + ModelRefine::FaceUniter uniter(currentShell); + if (uniter.process()) { + if (uniter.isModified()) { + const TopoDS_Shell &newShell = uniter.getShell(); + reshape.Replace(currentShell, newShell); + } + } + else { + Standard_Failure::Raise("Removing splitter failed"); + return _Shape; + } } + return reshape.Apply(solid); } else if (_Shape.ShapeType() == TopAbs_SHELL) { const TopoDS_Shell& shell = TopoDS::Shell(_Shape); @@ -1801,13 +1808,20 @@ TopoDS_Shape TopoShape::removeSplitter() const TopExp_Explorer xp; // solids for (xp.Init(_Shape, TopAbs_SOLID); xp.More(); xp.Next()) { - const TopoDS_Solid& solid = TopoDS::Solid(xp.Current()); - ModelRefine::FaceUniter uniter(solid); - if (uniter.process()) { - TopoDS_Solid solidMod; - if (uniter.getSolid(solidMod)) - builder.Add(comp, solidMod); + const TopoDS_Solid &solid = TopoDS::Solid(xp.Current()); + BRepTools_ReShape reshape; + TopExp_Explorer it; + for (it.Init(solid, TopAbs_SHELL); it.More(); it.Next()) { + const TopoDS_Shell ¤tShell = TopoDS::Shell(it.Current()); + ModelRefine::FaceUniter uniter(currentShell); + if (uniter.process()) { + if (uniter.isModified()) { + const TopoDS_Shell &newShell = uniter.getShell(); + reshape.Replace(currentShell, newShell); + } + } } + builder.Add(comp, reshape.Apply(solid)); } // free shells for (xp.Init(_Shape, TopAbs_SHELL, TopAbs_SOLID); xp.More(); xp.Next()) { diff --git a/src/Mod/Part/App/modelRefine.cpp b/src/Mod/Part/App/modelRefine.cpp index 72b6c6486b..1b66050c26 100644 --- a/src/Mod/Part/App/modelRefine.cpp +++ b/src/Mod/Part/App/modelRefine.cpp @@ -436,19 +436,11 @@ FaceTypedCylinder& ModelRefine::getCylinderObject() ///////////////////////////////////////////////////////////////////////////////////////////////////////// -FaceUniter::FaceUniter(const TopoDS_Shell &shellIn) +FaceUniter::FaceUniter(const TopoDS_Shell &shellIn) : modifiedSignal(false) { workShell = shellIn; } -FaceUniter::FaceUniter(const TopoDS_Solid &solidIn) -{ - //get first shell - TopExp_Explorer it; - it.Init(solidIn, TopAbs_SHELL); - workShell = TopoDS::Shell(it.Current()); -} - bool FaceUniter::process() { if (workShell.IsNull()) @@ -495,6 +487,7 @@ bool FaceUniter::process() } if (facesToSew.size() > 0) { + modifiedSignal = true; workShell = ModelRefine::removeFaces(workShell, facesToRemove); TopExp_Explorer xp; bool emptyShell = true; @@ -537,11 +530,3 @@ bool FaceUniter::process() } return true; } - -bool FaceUniter::getSolid(TopoDS_Solid &outSolid) const -{ - BRepBuilderAPI_MakeSolid solidMaker; - solidMaker.Add(workShell); - outSolid = solidMaker.Solid(); - return solidMaker.IsDone() ? true : false; -} diff --git a/src/Mod/Part/App/modelRefine.h b/src/Mod/Part/App/modelRefine.h index 1f51b8deda..c008b3053d 100644 --- a/src/Mod/Part/App/modelRefine.h +++ b/src/Mod/Part/App/modelRefine.h @@ -151,14 +151,14 @@ namespace ModelRefine FaceUniter(){} public: FaceUniter(const TopoDS_Shell &shellIn); - FaceUniter(const TopoDS_Solid &solidIn);//get first shell bool process(); const TopoDS_Shell& getShell() const {return workShell;} - bool getSolid(TopoDS_Solid &outSolid) const;//tries to make solid from shell. + bool isModified(){return modifiedSignal;} private: TopoDS_Shell workShell; std::vector typeObjects; + bool modifiedSignal; }; } From b82602a6b6e522868938e6b693fcef8faf44cd16 Mon Sep 17 00:00:00 2001 From: tanderson Date: Sun, 15 Jan 2012 11:45:16 -0500 Subject: [PATCH 3/4] changing Gui/BitmapFactory default pixmap size Allows toolbar pixmaps to scale correctly --- src/Gui/BitmapFactory.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Gui/BitmapFactory.cpp b/src/Gui/BitmapFactory.cpp index 21b6dead5b..bbf130914c 100644 --- a/src/Gui/BitmapFactory.cpp +++ b/src/Gui/BitmapFactory.cpp @@ -202,7 +202,7 @@ QPixmap BitmapFactoryInst::pixmap(const char* name) const // first check if it's an SVG because Qt's qsvg4 module shouldn't be used therefore if (icon.isNull()) { - icon = pixmapFromSvg(name, QSize(24,24)); + icon = pixmapFromSvg(name, QSize(64,64)); } // try to find it in the given directories From 450be825dac83cdd63187db5b1360a42315eea96 Mon Sep 17 00:00:00 2001 From: tanderson Date: Sun, 15 Jan 2012 14:08:07 -0500 Subject: [PATCH 4/4] changing customize dialog icon settings --- src/Gui/DlgActionsImp.cpp | 7 +++---- src/Gui/DlgCommandsImp.cpp | 4 ++-- src/Gui/DlgKeyboardImp.cpp | 6 +++--- src/Gui/DlgToolbarsImp.cpp | 7 +++---- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/src/Gui/DlgActionsImp.cpp b/src/Gui/DlgActionsImp.cpp index f717278257..6c392426b9 100644 --- a/src/Gui/DlgActionsImp.cpp +++ b/src/Gui/DlgActionsImp.cpp @@ -66,6 +66,9 @@ DlgCustomActionsImp::DlgCustomActionsImp( QWidget* parent ) QStringList labels; labels << tr("Icons") << tr("Macros"); actionListWidget->setHeaderLabels(labels); actionListWidget->header()->hide(); + actionListWidget->setIconSize(QSize(32, 32)); + actionListWidget->header()->setResizeMode(0, QHeaderView::ResizeToContents); + showActions(); } @@ -149,12 +152,9 @@ void DlgCustomActionsImp::showActions() item->setData(1, Qt::UserRole, actionName); item->setText(1, QString::fromUtf8((*it)->getMenuText())); item->setSizeHint(0, QSize(32, 32)); - item->setBackgroundColor(0, Qt::lightGray); if ( (*it)->getPixmap() ) item->setIcon(0, BitmapFactory().pixmap((*it)->getPixmap())); } - - actionListWidget->resizeColumnToContents(0); } void DlgCustomActionsImp::on_actionListWidget_itemActivated(QTreeWidgetItem *item) @@ -232,7 +232,6 @@ void DlgCustomActionsImp::on_buttonAddAction_clicked() item->setData(1, Qt::UserRole, actionName); item->setText(1, actionMenu->text()); item->setSizeHint(0, QSize(32, 32)); - item->setBackgroundColor(0, Qt::lightGray); if (pixmapLabel->pixmap()) item->setIcon(0, *pixmapLabel->pixmap()); diff --git a/src/Gui/DlgCommandsImp.cpp b/src/Gui/DlgCommandsImp.cpp index a1675cdd92..4697e9f3f0 100644 --- a/src/Gui/DlgCommandsImp.cpp +++ b/src/Gui/DlgCommandsImp.cpp @@ -112,6 +112,8 @@ DlgCustomCommandsImp::DlgCustomCommandsImp( QWidget* parent ) labels << tr("Icon") << tr("Command"); commandTreeWidget->setHeaderLabels(labels); commandTreeWidget->header()->hide(); + commandTreeWidget->setIconSize(QSize(32, 32)); + commandTreeWidget->header()->setResizeMode(0, QHeaderView::ResizeToContents); categoryTreeWidget->setCurrentItem(categoryTreeWidget->topLevelItem(0)); } @@ -148,13 +150,11 @@ void DlgCustomCommandsImp::onGroupActivated(QTreeWidgetItem* item) item->setToolTip(1, qApp->translate((*it)->className(), (*it)->getToolTipText())); item->setData(1, Qt::UserRole, QByteArray((*it)->getName())); item->setSizeHint(0, QSize(32, 32)); - item->setBackgroundColor(0, Qt::lightGray); if ((*it)->getPixmap()) item->setIcon(0, BitmapFactory().pixmap((*it)->getPixmap())); } textLabel->setText(QString()); - commandTreeWidget->resizeColumnToContents(0); } void DlgCustomCommandsImp::onAddMacroAction(const QByteArray& macro) diff --git a/src/Gui/DlgKeyboardImp.cpp b/src/Gui/DlgKeyboardImp.cpp index 0e0b3af4bb..e36d3bdf99 100644 --- a/src/Gui/DlgKeyboardImp.cpp +++ b/src/Gui/DlgKeyboardImp.cpp @@ -101,6 +101,9 @@ DlgCustomKeyboardImp::DlgCustomKeyboardImp( QWidget* parent ) labels << tr("Icon") << tr("Command"); commandTreeWidget->setHeaderLabels(labels); commandTreeWidget->header()->hide(); + commandTreeWidget->setIconSize(QSize(32, 32)); + commandTreeWidget->header()->setResizeMode(0, QHeaderView::ResizeToContents); + assignedTreeWidget->setHeaderLabels(labels); assignedTreeWidget->header()->hide(); } @@ -177,12 +180,9 @@ void DlgCustomKeyboardImp::on_categoryBox_activated(int index) item->setToolTip(1, qApp->translate((*it)->className(), (*it)->getToolTipText())); item->setData(1, Qt::UserRole, QByteArray((*it)->getName())); item->setSizeHint(0, QSize(32, 32)); - item->setBackgroundColor(0, Qt::lightGray); if ((*it)->getPixmap()) item->setIcon(0, BitmapFactory().pixmap((*it)->getPixmap())); } - - commandTreeWidget->resizeColumnToContents(0); } /** Assigns a new accelerator to the selected command. */ diff --git a/src/Gui/DlgToolbarsImp.cpp b/src/Gui/DlgToolbarsImp.cpp index 3a5811fb85..4b51f06f2e 100644 --- a/src/Gui/DlgToolbarsImp.cpp +++ b/src/Gui/DlgToolbarsImp.cpp @@ -117,6 +117,9 @@ DlgCustomToolbars::DlgCustomToolbars(DlgCustomToolbars::Type t, QWidget* parent) labels << tr("Icon") << tr("Command"); commandTreeWidget->setHeaderLabels(labels); commandTreeWidget->header()->hide(); + commandTreeWidget->setIconSize(QSize(32, 32)); + commandTreeWidget->header()->setResizeMode(0, QHeaderView::ResizeToContents); + labels.clear(); labels << tr("Command"); toolbarTreeWidget->setHeaderLabels(labels); toolbarTreeWidget->header()->hide(); @@ -187,19 +190,15 @@ void DlgCustomToolbars::on_categoryBox_activated(int index) sepitem->setText(1, tr("")); sepitem->setData(1, Qt::UserRole, QByteArray("Separator")); sepitem->setSizeHint(0, QSize(32, 32)); - sepitem->setBackgroundColor(0, Qt::lightGray); for (std::vector::iterator it = aCmds.begin(); it != aCmds.end(); ++it) { QTreeWidgetItem* item = new QTreeWidgetItem(commandTreeWidget); item->setText(1, qApp->translate((*it)->className(), (*it)->getMenuText())); item->setToolTip(1, qApp->translate((*it)->className(), (*it)->getToolTipText())); item->setData(1, Qt::UserRole, QByteArray((*it)->getName())); item->setSizeHint(0, QSize(32, 32)); - item->setBackgroundColor(0, Qt::lightGray); if ((*it)->getPixmap()) item->setIcon(0, BitmapFactory().pixmap((*it)->getPixmap())); } - - commandTreeWidget->resizeColumnToContents(0); } void DlgCustomToolbars::on_workbenchBox_activated(int index)