From efd61d256ddd679962f18eaf7ffd8c6d32771f1f Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 4 Nov 2012 16:48:52 +0100 Subject: [PATCH 1/4] Algorithm to remap support shape, fix bugs in pad/pocket --- src/Mod/PartDesign/App/FeaturePocket.cpp | 1 + src/Mod/PartDesign/App/FeatureSketchBased.cpp | 104 ++++++++++++++++++ src/Mod/PartDesign/App/FeatureSketchBased.h | 3 + src/Mod/PartDesign/Gui/TaskPadParameters.cpp | 6 +- .../PartDesign/Gui/TaskPocketParameters.cpp | 6 +- 5 files changed, 114 insertions(+), 6 deletions(-) diff --git a/src/Mod/PartDesign/App/FeaturePocket.cpp b/src/Mod/PartDesign/App/FeaturePocket.cpp index 5779e32a1..351fb512d 100644 --- a/src/Mod/PartDesign/App/FeaturePocket.cpp +++ b/src/Mod/PartDesign/App/FeaturePocket.cpp @@ -168,6 +168,7 @@ App::DocumentObjectExecReturn *Pocket::execute(void) TopoDS_Shape solRes = this->getSolid(result); if (solRes.IsNull()) return new App::DocumentObjectExecReturn("Pocket: Resulting shape is not a solid"); + remapSupportShape(solRes); this->Shape.setValue(solRes); } diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index c09b1425b..a636cc788 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -46,6 +46,7 @@ # include # include # include +# include # include # include # include @@ -519,4 +520,107 @@ const bool SketchBased::checkWireInsideFace(const TopoDS_Wire& wire, const TopoD return (proj.More() && proj.Current().Closed()); } +void SketchBased::remapSupportShape(const TopoDS_Shape& newShape) +{ + std::vector refs = this->getInList(); + for (std::vector::iterator it = refs.begin(); it != refs.end(); ++it) { + if ((*it)->isDerivedFrom(Part::Part2DObject::getClassTypeId())) { + Part::Part2DObject* part = static_cast(*it); + Part::TopoShape shape = this->Shape.getValue(); + // here we must reset the placement otherwise the geometric matching doesn't work + shape._Shape.Location(TopLoc_Location()); + std::vector subValues = part->Support.getSubValues(); + std::vector newSubValues; + TopTools_IndexedMapOfShape faceMap; + TopExp::MapShapes(newShape, TopAbs_FACE, faceMap); + + for (std::vector::iterator it = subValues.begin(); it != subValues.end(); ++it) { + std::string shapetype; + if (it->size() > 4 && it->substr(0,4) == "Face") { + shapetype = "Face"; + } + else if (it->size() > 4 && it->substr(0,4) == "Edge") { + shapetype = "Edge"; + } + else if (it->size() > 6 && it->substr(0,6) == "Vertex") { + shapetype = "Vertex"; + } + else { + continue; + } + + TopoDS_Shape element = shape.getSubShape(it->c_str()); + bool success = false; + for (int i=1; iSupport.setValue(this, newSubValues); + } + } +} + +struct gp_Pnt_Less : public std::binary_function +{ + bool operator()(const gp_Pnt& p1, + const gp_Pnt& p2) const + { + if (fabs(p1.X() - p2.X()) > Precision::Confusion()) + return p1.X() < p2.X(); + if (fabs(p1.Y() - p2.Y()) > Precision::Confusion()) + return p1.Y() < p2.Y(); + if (fabs(p1.Z() - p2.Z()) > Precision::Confusion()) + return p1.Z() < p2.Z(); + return false; // points are considered to be equal + } +}; + +bool SketchBased::isQuasiEqual(const TopoDS_Shape& s1, const TopoDS_Shape& s2) const +{ + if (s1.ShapeType() != s2.ShapeType()) + return false; + TopTools_IndexedMapOfShape map1, map2; + TopExp::MapShapes(s1, TopAbs_VERTEX, map1); + TopExp::MapShapes(s2, TopAbs_VERTEX, map2); + if (map1.Extent() != map2.Extent()) + return false; + + std::vector p1; + for (int i=1; i<=map1.Extent(); i++) { + const TopoDS_Vertex& v = TopoDS::Vertex(map1.FindKey(i)); + p1.push_back(BRep_Tool::Pnt(v)); + } + std::vector p2; + for (int i=1; i<=map2.Extent(); i++) { + const TopoDS_Vertex& v = TopoDS::Vertex(map2.FindKey(i)); + p2.push_back(BRep_Tool::Pnt(v)); + } + + std::sort(p1.begin(), p1.end(), gp_Pnt_Less()); + std::sort(p2.begin(), p2.end(), gp_Pnt_Less()); + + if (p1.size() != p2.size()) + return false; + + std::vector::iterator it = p1.begin(), jt = p2.begin(); + for (; it != p1.end(); ++it, ++jt) { + if (!(*it).IsEqual(*jt, Precision::Confusion())) + return false; + } + + return true; +} + } diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.h b/src/Mod/PartDesign/App/FeatureSketchBased.h index 726461ec0..c6c3ca277 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.h +++ b/src/Mod/PartDesign/App/FeatureSketchBased.h @@ -28,6 +28,7 @@ #include #include "Feature.h" +class TopoDS_Shape; class TopoDS_Face; class TopoDS_Wire; class gp_Dir; @@ -76,6 +77,8 @@ protected: TopoDS_Shape makeFace(const std::vector&) const; TopoDS_Shape makeFace(std::list&) const; // for internal use only bool isInside(const TopoDS_Wire&, const TopoDS_Wire&) const; + bool isQuasiEqual(const TopoDS_Shape&, const TopoDS_Shape&) const; + void remapSupportShape(const TopoDS_Shape&); /// Extract a face from a given LinkSub static void getUpToFaceFromLinkSub(TopoDS_Face& upToFace, diff --git a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp index 13a3b36cc..adaff69b8 100644 --- a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp @@ -446,14 +446,14 @@ bool TaskDlgPadParameters::accept() Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Midplane = %i",name.c_str(),parameter->getMidplane()?1:0); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Length2 = %f",name.c_str(),parameter->getLength2()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Type = %u",name.c_str(),parameter->getMode()); - const char* facename = parameter->getFaceName().data(); + QByteArray facename = parameter->getFaceName(); PartDesign::Pad* pcPad = static_cast(PadView->getObject()); Part::Feature* support = pcPad->getSupport(); - if (support != NULL && facename && facename[0] != '\0') { + if (support != NULL && !facename.isEmpty()) { QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); buf = buf.arg(QString::fromUtf8(support->getNameInDocument())); - buf = buf.arg(QString::fromUtf8(facename)); + buf = buf.arg(QString::fromUtf8(facename.data())); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = %s", name.c_str(), buf.toStdString().c_str()); } else Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = None", name.c_str()); diff --git a/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp b/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp index b29be9fab..e1becf68a 100644 --- a/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp @@ -407,13 +407,13 @@ bool TaskDlgPocketParameters::accept() //Gui::Command::openCommand("Pocket changed"); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Length = %f",name.c_str(),parameter->getLength()); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Type = %u",name.c_str(),parameter->getMode()); - const char* facename = parameter->getFaceName().data(); + QByteArray facename = parameter->getFaceName(); PartDesign::Pocket* pcPocket = static_cast(PocketView->getObject()); Part::Feature* support = pcPocket->getSupport(); - if (support != NULL && facename && facename[0] != '\0') { + if (support != NULL && !facename.isEmpty()) { QString buf = QString::fromUtf8("(App.ActiveDocument.%1,[\"%2\"])"); buf = buf.arg(QString::fromUtf8(support->getNameInDocument())); - buf = buf.arg(QString::fromUtf8(facename)); + buf = buf.arg(QString::fromUtf8(facename.data())); Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = %s", name.c_str(), buf.toStdString().c_str()); } else Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.UpToFace = None", name.c_str()); From 0149742d62984d9e29e9ef308ed29c24fb51c6e3 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 5 Nov 2012 10:57:52 +0100 Subject: [PATCH 2/4] Fix problems when chaning language while pad/pocket panel is open --- src/Mod/PartDesign/Gui/TaskPadParameters.cpp | 26 +++++++++++++++++++ .../PartDesign/Gui/TaskPocketParameters.cpp | 23 ++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp index adaff69b8..7d181de8c 100644 --- a/src/Mod/PartDesign/Gui/TaskPadParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPadParameters.cpp @@ -399,7 +399,33 @@ void TaskPadParameters::changeEvent(QEvent *e) { TaskBox::changeEvent(e); if (e->type() == QEvent::LanguageChange) { + ui->doubleSpinBox->blockSignals(true); + ui->doubleSpinBox2->blockSignals(true); + ui->lineFaceName->blockSignals(true); + ui->changeMode->blockSignals(true); + int index = ui->changeMode->currentIndex(); ui->retranslateUi(proxy); + ui->changeMode->clear(); + ui->changeMode->addItem(tr("Dimension")); + ui->changeMode->addItem(tr("To last")); + ui->changeMode->addItem(tr("To first")); + ui->changeMode->addItem(tr("Up to face")); + ui->changeMode->addItem(tr("Two dimensions")); + ui->changeMode->setCurrentIndex(index); + + QByteArray upToFace = this->getFaceName(); + int faceId = -1; + bool ok = false; + if (upToFace.indexOf("Face") == 0) { + faceId = upToFace.remove(0,4).toInt(&ok); + } + ui->lineFaceName->setText(ok ? + tr("Face") + QString::number(faceId) : + tr("No face selected")); + ui->doubleSpinBox->blockSignals(false); + ui->doubleSpinBox2->blockSignals(false); + ui->lineFaceName->blockSignals(false); + ui->changeMode->blockSignals(false); } } diff --git a/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp b/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp index e1becf68a..e465f2aaf 100644 --- a/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPocketParameters.cpp @@ -363,7 +363,30 @@ void TaskPocketParameters::changeEvent(QEvent *e) { TaskBox::changeEvent(e); if (e->type() == QEvent::LanguageChange) { + ui->doubleSpinBox->blockSignals(true); + ui->lineFaceName->blockSignals(true); + ui->changeMode->blockSignals(true); + int index = ui->changeMode->currentIndex(); ui->retranslateUi(proxy); + ui->changeMode->clear(); + ui->changeMode->addItem(tr("Dimension")); + ui->changeMode->addItem(tr("Through all")); + ui->changeMode->addItem(tr("To first")); + ui->changeMode->addItem(tr("Up to face")); + ui->changeMode->setCurrentIndex(index); + + QByteArray upToFace = this->getFaceName(); + int faceId = -1; + bool ok = false; + if (upToFace.indexOf("Face") == 0) { + faceId = upToFace.remove(0,4).toInt(&ok); + } + ui->lineFaceName->setText(ok ? + tr("Face") + QString::number(faceId) : + tr("No face selected")); + ui->doubleSpinBox->blockSignals(false); + ui->lineFaceName->blockSignals(false); + ui->changeMode->blockSignals(false); } } From e432930f216692779783cec99a520926cd74dec2 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 5 Nov 2012 14:50:02 +0100 Subject: [PATCH 3/4] Algorithm to do a geometric matching (planes only) --- src/Mod/PartDesign/App/FeatureSketchBased.cpp | 41 +++++++++++++++++++ src/Mod/PartDesign/App/FeatureSketchBased.h | 1 + 2 files changed, 42 insertions(+) diff --git a/src/Mod/PartDesign/App/FeatureSketchBased.cpp b/src/Mod/PartDesign/App/FeatureSketchBased.cpp index a636cc788..490447184 100644 --- a/src/Mod/PartDesign/App/FeatureSketchBased.cpp +++ b/src/Mod/PartDesign/App/FeatureSketchBased.cpp @@ -41,6 +41,7 @@ # include # include # include +# include # include # include # include @@ -551,6 +552,7 @@ void SketchBased::remapSupportShape(const TopoDS_Shape& newShape) TopoDS_Shape element = shape.getSubShape(it->c_str()); bool success = false; + // first try an exact matching for (int i=1; i&) const; TopoDS_Shape makeFace(std::list&) const; // for internal use only bool isInside(const TopoDS_Wire&, const TopoDS_Wire&) const; + bool isEqualGeometry(const TopoDS_Shape&, const TopoDS_Shape&); bool isQuasiEqual(const TopoDS_Shape&, const TopoDS_Shape&) const; void remapSupportShape(const TopoDS_Shape&); From 0f6365ee4a4a805e27db499e224187ee588a5ea9 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 5 Nov 2012 16:42:11 +0100 Subject: [PATCH 4/4] Use own signal handler only on Windows with MSVC --- src/App/Application.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/App/Application.cpp b/src/App/Application.cpp index 948748fcc..b8ca0f770 100644 --- a/src/App/Application.cpp +++ b/src/App/Application.cpp @@ -941,10 +941,12 @@ void Application::init(int argc, char ** argv) #endif // if an unexpected crash occurs we can install a handler function to // write some additional information +#ifdef _MSC_VER // Microsoft compiler std::signal(SIGSEGV,segmentation_fault_handler); std::signal(SIGABRT,segmentation_fault_handler); std::set_terminate(unhandled_exception_handler); std::set_unexpected(unexpection_error_handler); +#endif initTypes();