Merge branch 'master' of git://free-cad.git.sourceforge.net/gitroot/free-cad/free-cad

This commit is contained in:
jrheinlaender 2012-11-06 20:47:39 +04:30
commit 16bd5f0dca
6 changed files with 207 additions and 6 deletions

View File

@ -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();

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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,

View File

@ -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());

View File

@ -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());