Merge branch 'master' of git://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad
This commit is contained in:
commit
16bd5f0dca
|
@ -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();
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -41,11 +41,13 @@
|
|||
# include <TopoDS_Wire.hxx>
|
||||
# include <TopoDS_Vertex.hxx>
|
||||
# include <TopExp_Explorer.hxx>
|
||||
# include <gp_Ax1.hxx>
|
||||
# include <gp_Pln.hxx>
|
||||
# include <ShapeFix_Face.hxx>
|
||||
# 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 +521,147 @@ 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;
|
||||
// first try an exact matching
|
||||
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;
|
||||
}
|
||||
}
|
||||
// if an exact matching fails then try to compare only the geometries
|
||||
if (!success) {
|
||||
for (int i=1; i<faceMap.Extent(); i++) {
|
||||
if (isEqualGeometry(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;
|
||||
}
|
||||
|
||||
bool SketchBased::isEqualGeometry(const TopoDS_Shape& s1, const TopoDS_Shape& s2)
|
||||
{
|
||||
if (s1.ShapeType() == TopAbs_FACE && s2.ShapeType() == TopAbs_FACE) {
|
||||
BRepAdaptor_Surface a1(TopoDS::Face(s1));
|
||||
BRepAdaptor_Surface a2(TopoDS::Face(s2));
|
||||
if (a1.GetType() == GeomAbs_Plane && a2.GetType() == GeomAbs_Plane) {
|
||||
gp_Pln p1 = a1.Plane();
|
||||
gp_Pln p2 = a2.Plane();
|
||||
if (p1.Distance(p2.Location()) < Precision::Confusion()) {
|
||||
const gp_Dir& d1 = p1.Axis().Direction();
|
||||
const gp_Dir& d2 = p2.Axis().Direction();
|
||||
if (d1.IsParallel(d2, Precision::Confusion()))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (s1.ShapeType() == TopAbs_EDGE && s2.ShapeType() == TopAbs_EDGE) {
|
||||
}
|
||||
else if (s1.ShapeType() == TopAbs_VERTEX && s2.ShapeType() == TopAbs_VERTEX) {
|
||||
gp_Pnt p1 = BRep_Tool::Pnt(TopoDS::Vertex(s1));
|
||||
gp_Pnt p2 = BRep_Tool::Pnt(TopoDS::Vertex(s2));
|
||||
return p1.Distance(p2) < Precision::Confusion();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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,9 @@ 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 isEqualGeometry(const TopoDS_Shape&, const TopoDS_Shape&);
|
||||
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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -446,14 +472,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());
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,13 +430,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