allow to add faces to fillet and chamfer

This commit is contained in:
Stefan Tröger 2015-05-20 21:51:19 +02:00
parent 329064d671
commit fc1e8b8d17
13 changed files with 551 additions and 517 deletions

View File

@ -32,6 +32,7 @@
# include <TopTools_IndexedMapOfShape.hxx>
# include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
# include <TopTools_ListOfShape.hxx>
#include <BRep_Tool.hxx>
#endif
#include <Base/Console.h>
@ -74,8 +75,10 @@ App::DocumentObjectExecReturn *Chamfer::execute(void)
return new App::DocumentObjectExecReturn(e.what());
}
const std::vector<std::string>& SubVals = Base.getSubValuesStartsWith("Edge");
if (SubVals.size() == 0)
std::vector<std::string> SubNames = std::vector<std::string>(Base.getSubValues());
getContiniusEdges(TopShape, SubNames);
if (SubNames.size() == 0)
return new App::DocumentObjectExecReturn("No edges specified");
double size = Size.getValue();
@ -92,7 +95,7 @@ App::DocumentObjectExecReturn *Chamfer::execute(void)
TopExp::MapShapesAndAncestors(baseShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
TopExp::MapShapes(baseShape._Shape, TopAbs_EDGE, mapOfEdges);
for (std::vector<std::string>::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) {
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str()));
const TopoDS_Face& face = TopoDS::Face(mapEdgeFace.FindFromKey(edge).First());
mkChamfer.Add(size, edge, face);
@ -106,11 +109,11 @@ App::DocumentObjectExecReturn *Chamfer::execute(void)
if (shape.IsNull())
return new App::DocumentObjectExecReturn("Resulting shape is null");
TopTools_ListOfShape aLarg;
aLarg.Append(baseShape._Shape);
if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) {
return new App::DocumentObjectExecReturn("Resulting shape is invalid");
}
TopTools_ListOfShape aLarg;
aLarg.Append(baseShape._Shape);
if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) {
return new App::DocumentObjectExecReturn("Resulting shape is invalid");
}
this->Shape.setValue(shape);
return App::DocumentObject::StdReturn;

View File

@ -28,6 +28,12 @@
#include "FeatureDressUp.h"
#include <Base/Exception.h>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopExp.hxx>
#include <TopoDS.hxx>
#include <BRep_Tool.hxx>
#include <TopoDS_Edge.hxx>
using namespace PartDesign;
@ -74,6 +80,72 @@ Part::TopoShape DressUp::getBaseShape()
return shape;
}
void DressUp::getContiniusEdges(Part::TopoShape TopShape, std::vector< std::string >& SubNames) {
TopTools_IndexedMapOfShape mapOfEdges;
TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges);
unsigned int i = 0;
while(i < SubNames.size())
{
std::string aSubName = static_cast<std::string>(SubNames.at(i));
if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") {
TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str()));
const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge);
if(los.Extent() != 2)
{
SubNames.erase(SubNames.begin()+i);
continue;
}
const TopoDS_Shape& face1 = los.First();
const TopoDS_Shape& face2 = los.Last();
GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge),
TopoDS::Face(face1),
TopoDS::Face(face2));
if (cont != GeomAbs_C0) {
SubNames.erase(SubNames.begin()+i);
continue;
}
i++;
}
else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") {
TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str()));
TopTools_IndexedMapOfShape mapOfFaces;
TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces);
for(int j = 1; j <= mapOfFaces.Extent(); ++j) {
TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j));
int id = mapOfEdges.FindIndex(edge);
std::stringstream buf;
buf << "Edge";
buf << id;
if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end())
{
SubNames.push_back(buf.str());
}
}
SubNames.erase(SubNames.begin()+i);
}
// empty name or any other sub-element
else {
SubNames.erase(SubNames.begin()+i);
}
}
}
void DressUp::onChanged(const App::Property* prop)
{
if (prop == &BaseFeature) {

View File

@ -43,6 +43,9 @@ public:
/// updates the Placement property from the Placement of the BaseFeature
void positionByBaseFeature(void);
Part::TopoShape getBaseShape();
/// extracts all edges from the subshapes (inkluding face edges) and furthermore adds
/// all C0 continius edges to the vector
void getContiniusEdges(Part::TopoShape, std::vector< std::string >&);
protected:
void onChanged(const App::Property* prop);

View File

@ -29,6 +29,9 @@
# include <TopoDS.hxx>
# include <TopoDS_Edge.hxx>
# include <TopTools_ListOfShape.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopExp.hxx>
#include <BRep_Tool.hxx>
#endif
#include <Base/Console.h>
@ -68,11 +71,12 @@ App::DocumentObjectExecReturn *Fillet::execute(void)
} catch (Base::Exception& e) {
return new App::DocumentObjectExecReturn(e.what());
}
std::vector<std::string> SubNames = std::vector<std::string>(Base.getSubValues());
getContiniusEdges(TopShape, SubNames);
const std::vector<std::string>& SubVals = Base.getSubValuesStartsWith("Edge");
if (SubVals.size() == 0)
return new App::DocumentObjectExecReturn("No edges specified");
if (SubNames.size() == 0)
return new App::DocumentObjectExecReturn("Fillet not possible on selected shapes");
double radius = Radius.getValue();
this->positionByBaseFeature();
@ -83,7 +87,7 @@ App::DocumentObjectExecReturn *Fillet::execute(void)
try {
BRepFilletAPI_MakeFillet mkFillet(baseShape._Shape);
for (std::vector<std::string>::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) {
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str()));
mkFillet.Add(radius, edge);
}
@ -96,11 +100,11 @@ App::DocumentObjectExecReturn *Fillet::execute(void)
if (shape.IsNull())
return new App::DocumentObjectExecReturn("Resulting shape is null");
TopTools_ListOfShape aLarg;
aLarg.Append(baseShape._Shape);
if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) {
return new App::DocumentObjectExecReturn("Resulting shape is invalid");
}
TopTools_ListOfShape aLarg;
aLarg.Append(baseShape._Shape);
if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) {
return new App::DocumentObjectExecReturn("Resulting shape is invalid");
}
this->Shape.setValue(shape);
return App::DocumentObject::StdReturn;

View File

@ -23,18 +23,23 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <BRepAlgo.hxx>
# include <BRepFilletAPI_MakeFillet.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <TopoDS_Edge.hxx>
<<<<<<< 2c7cc8276bd6dd4ccc4aa28daa809a688bd493c5
# include <TopTools_ListOfShape.hxx>
=======
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopExp.hxx>
#include <BRep_Tool.hxx>
>>>>>>> allow to add faces to fillet and chamfer
#endif
<<<<<<< 50287516b47694e57429cc98f6d5596a06a635d6
#include <Base/Console.h>
#include <Base/Reader.h>
=======
#include <Base/Exception.h>
>>>>>>> Some code unification for DressUp features
#include <Base/Reader.h>
#include <Mod/Part/App/TopoShape.h>
#include "FeatureFillet.h"
@ -69,11 +74,12 @@ App::DocumentObjectExecReturn *Fillet::execute(void)
} catch (Base::Exception& e) {
return new App::DocumentObjectExecReturn(e.what());
}
std::vector<std::string> SubNames = std::vector<std::string>(Base.getSubValues());
getContiniusEdges(TopShape, SubNames);
const std::vector<std::string>& SubVals = Base.getSubValuesStartsWith("Edge");
if (SubVals.size() == 0)
return new App::DocumentObjectExecReturn("No edges specified");
if (SubNames.size() == 0)
return new App::DocumentObjectExecReturn("Fillet not possible on selected shapes");
double radius = Radius.getValue();
this->positionByBaseFeature();
@ -84,7 +90,7 @@ App::DocumentObjectExecReturn *Fillet::execute(void)
try {
BRepFilletAPI_MakeFillet mkFillet(baseShape._Shape);
for (std::vector<std::string>::const_iterator it=SubVals.begin(); it != SubVals.end(); ++it) {
for (std::vector<std::string>::const_iterator it=SubNames.begin(); it != SubNames.end(); ++it) {
TopoDS_Edge edge = TopoDS::Edge(baseShape.getSubShape(it->c_str()));
mkFillet.Add(radius, edge);
}
@ -97,6 +103,12 @@ App::DocumentObjectExecReturn *Fillet::execute(void)
if (shape.IsNull())
return new App::DocumentObjectExecReturn("Resulting shape is null");
TopTools_ListOfShape aLarg;
aLarg.Append(baseShape._Shape);
if (!BRepAlgo::IsValid(aLarg, shape, Standard_False, Standard_False)) {
return new App::DocumentObjectExecReturn("Resulting shape is invalid");
}
this->Shape.setValue(shape);
return App::DocumentObject::StdReturn;
}

View File

@ -1269,78 +1269,7 @@ void makeChamferOrFillet(Gui::Command* cmd, const std::string& which)
return;
}
const Part::TopoShape& TopShape = base->Shape.getShape();
if (TopShape._Shape.IsNull()){
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QObject::tr("Shape of selected part is empty."));
return;
}
TopTools_IndexedMapOfShape mapOfEdges;
TopTools_IndexedDataMapOfShapeListOfShape mapEdgeFace;
TopExp::MapShapesAndAncestors(TopShape._Shape, TopAbs_EDGE, TopAbs_FACE, mapEdgeFace);
TopExp::MapShapes(TopShape._Shape, TopAbs_EDGE, mapOfEdges);
std::vector<std::string> SubNames = std::vector<std::string>(selection[0].getSubNames());
unsigned int i = 0;
while(i < SubNames.size())
{
std::string aSubName = static_cast<std::string>(SubNames.at(i));
if (aSubName.size() > 4 && aSubName.substr(0,4) == "Edge") {
TopoDS_Edge edge = TopoDS::Edge(TopShape.getSubShape(aSubName.c_str()));
const TopTools_ListOfShape& los = mapEdgeFace.FindFromKey(edge);
if(los.Extent() != 2)
{
SubNames.erase(SubNames.begin()+i);
continue;
}
const TopoDS_Shape& face1 = los.First();
const TopoDS_Shape& face2 = los.Last();
GeomAbs_Shape cont = BRep_Tool::Continuity(TopoDS::Edge(edge),
TopoDS::Face(face1),
TopoDS::Face(face2));
if (cont != GeomAbs_C0) {
SubNames.erase(SubNames.begin()+i);
continue;
}
i++;
}
else if(aSubName.size() > 4 && aSubName.substr(0,4) == "Face") {
TopoDS_Face face = TopoDS::Face(TopShape.getSubShape(aSubName.c_str()));
TopTools_IndexedMapOfShape mapOfFaces;
TopExp::MapShapes(face, TopAbs_EDGE, mapOfFaces);
for(int j = 1; j <= mapOfFaces.Extent(); ++j) {
TopoDS_Edge edge = TopoDS::Edge(mapOfFaces.FindKey(j));
int id = mapOfEdges.FindIndex(edge);
std::stringstream buf;
buf << "Edge";
buf << id;
if(std::find(SubNames.begin(),SubNames.end(),buf.str()) == SubNames.end())
{
SubNames.push_back(buf.str());
}
}
SubNames.erase(SubNames.begin()+i);
}
// empty name or any other sub-element
else {
SubNames.erase(SubNames.begin()+i);
}
}
if (SubNames.size() == 0) {
QMessageBox::warning(Gui::getMainWindow(), QObject::tr("Wrong selection"),
QString::fromStdString(which) + QObject::tr(" not possible on selected faces/edges."));

File diff suppressed because it is too large Load Diff

View File

@ -51,7 +51,7 @@ using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskChamferParameters */
TaskChamferParameters::TaskChamferParameters(ViewProviderDressUp *DressUpView,QWidget *parent)
: TaskDressUpParameters(DressUpView, parent)
: TaskDressUpParameters(DressUpView, true, true, parent)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);

View File

@ -51,7 +51,7 @@ using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskDraftParameters */
TaskDraftParameters::TaskDraftParameters(ViewProviderDressUp *DressUpView,QWidget *parent)
: TaskDressUpParameters(DressUpView, parent)
: TaskDressUpParameters(DressUpView, false, true, parent)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);

View File

@ -50,8 +50,9 @@ using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskDressUpParameters */
TaskDressUpParameters::TaskDressUpParameters(ViewProviderDressUp *DressUpView,QWidget *parent)
: TaskBox(Gui::BitmapFactory().pixmap((std::string("PartDesign_") + DressUpView->featureName).c_str()),
TaskDressUpParameters::TaskDressUpParameters(ViewProviderDressUp *DressUpView, bool selectEdges, bool selectFaces, QWidget *parent)
: allowFaces(selectFaces), allowEdges(selectEdges),
TaskBox(Gui::BitmapFactory().pixmap((std::string("PartDesign_") + DressUpView->featureName).c_str()),
QString::fromAscii((DressUpView->featureName + " parameters").c_str()),
true,
parent),
@ -113,9 +114,7 @@ void TaskDressUpParameters::onButtonRefAdd(bool checked)
hideObject();
selectionMode = refAdd;
Gui::Selection().clearSelection();
bool edge = (DressUpView->featureName != "Draft");
bool face = (DressUpView->featureName == "Draft");
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), edge, face, false));
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allowEdges, allowFaces, false));
DressUpView->highlightReferences(true);
}
}
@ -127,9 +126,7 @@ void TaskDressUpParameters::onButtonRefRemove(const bool checked)
hideObject();
selectionMode = refRemove;
Gui::Selection().clearSelection();
bool edge = (DressUpView->featureName != "Draft");
bool face = (DressUpView->featureName == "Draft");
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), edge, face, false));
Gui::Selection().addSelectionGate(new ReferenceSelection(this->getBase(), allowEdges, allowFaces, false));
DressUpView->highlightReferences(true);
}
}

View File

@ -39,7 +39,7 @@ class TaskDressUpParameters : public Gui::TaskView::TaskBox, public Gui::Selecti
Q_OBJECT
public:
TaskDressUpParameters(ViewProviderDressUp *DressUpView, QWidget *parent=0);
TaskDressUpParameters(ViewProviderDressUp *DressUpView, bool selectEdges, bool selectFaces, QWidget* parent = 0);
virtual ~TaskDressUpParameters();
const std::vector<std::string> getReferences(void) const;
@ -73,6 +73,7 @@ protected:
QWidget* proxy;
ViewProviderDressUp *DressUpView;
bool allowFaces, allowEdges;
selectionModes selectionMode;
};

View File

@ -51,7 +51,7 @@ using namespace Gui;
/* TRANSLATOR PartDesignGui::TaskFilletParameters */
TaskFilletParameters::TaskFilletParameters(ViewProviderDressUp *DressUpView,QWidget *parent)
: TaskDressUpParameters(DressUpView, parent)
: TaskDressUpParameters(DressUpView, true, true, parent)
{
// we need a separate container widget to add all controls to
proxy = new QWidget(this);

View File

@ -115,7 +115,8 @@ void ViewProviderDressUp::highlightReferences(const bool on)
colors[idx] = App::Color(1.0,0.0,1.0); // magenta
}
vp->DiffuseColor.setValues(colors);
} else if (!edges.empty() && originalLineColors.empty()) {
}
if (!edges.empty() && originalLineColors.empty()) {
TopTools_IndexedMapOfShape eMap;
TopExp::MapShapes(base->Shape.getValue(), TopAbs_EDGE, eMap);
originalLineColors = vp->LineColorArray.getValues();
@ -133,7 +134,8 @@ void ViewProviderDressUp::highlightReferences(const bool on)
if (!faces.empty() && !originalFaceColors.empty()) {
vp->DiffuseColor.setValues(originalFaceColors);
originalFaceColors.clear();
} else if (!edges.empty() && !originalLineColors.empty()) {
}
if (!edges.empty() && !originalLineColors.empty()) {
vp->LineColorArray.setValues(originalLineColors);
originalLineColors.clear();
}