Algorithm to remap support shape, fix bugs in pad/pocket
This commit is contained in:
parent
77144681ef
commit
efd61d256d
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
# include <ShapeFix_Wire.hxx>
|
||||
# include <ShapeAnalysis.hxx>
|
||||
# include <TopTools_IndexedMapOfShape.hxx>
|
||||
# include <TopExp.hxx>
|
||||
# include <IntTools_FClass2d.hxx>
|
||||
# include <ShapeAnalysis_Surface.hxx>
|
||||
# include <ShapeFix_Shape.hxx>
|
||||
|
@ -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<App::DocumentObject*> refs = this->getInList();
|
||||
for (std::vector<App::DocumentObject*>::iterator it = refs.begin(); it != refs.end(); ++it) {
|
||||
if ((*it)->isDerivedFrom(Part::Part2DObject::getClassTypeId())) {
|
||||
Part::Part2DObject* part = static_cast<Part::Part2DObject*>(*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<std::string> subValues = part->Support.getSubValues();
|
||||
std::vector<std::string> newSubValues;
|
||||
TopTools_IndexedMapOfShape faceMap;
|
||||
TopExp::MapShapes(newShape, TopAbs_FACE, faceMap);
|
||||
|
||||
for (std::vector<std::string>::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; i<faceMap.Extent(); i++) {
|
||||
if (isQuasiEqual(element, faceMap.FindKey(i))) {
|
||||
std::stringstream str;
|
||||
str << shapetype << i;
|
||||
newSubValues.push_back(str.str());
|
||||
success = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// the new shape couldn't be found so keep the old sub-name
|
||||
if (!success)
|
||||
newSubValues.push_back(*it);
|
||||
}
|
||||
|
||||
part->Support.setValue(this, newSubValues);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct gp_Pnt_Less : public std::binary_function<const gp_Pnt&,
|
||||
const gp_Pnt&, bool>
|
||||
{
|
||||
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<gp_Pnt> 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<gp_Pnt> 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<gp_Pnt>::iterator it = p1.begin(), jt = p2.begin();
|
||||
for (; it != p1.end(); ++it, ++jt) {
|
||||
if (!(*it).IsEqual(*jt, Precision::Confusion()))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <Mod/Part/App/Part2DObject.h>
|
||||
#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<TopoDS_Wire>&) const;
|
||||
TopoDS_Shape makeFace(std::list<TopoDS_Wire>&) 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,
|
||||
|
|
|
@ -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<PartDesign::Pad*>(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());
|
||||
|
|
|
@ -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<PartDesign::Pocket*>(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());
|
||||
|
|
Loading…
Reference in New Issue
Block a user