From efd61d256ddd679962f18eaf7ffd8c6d32771f1f Mon Sep 17 00:00:00 2001 From: wmayer Date: Sun, 4 Nov 2012 16:48:52 +0100 Subject: [PATCH] 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());