Extend task panel for filling function

This commit is contained in:
wmayer
2017-04-23 16:12:27 +02:00
parent b0eed05a73
commit b47805dcc6
4 changed files with 104 additions and 65 deletions

View File

@@ -46,42 +46,52 @@ PROPERTY_SOURCE(Surface::Filling, Part::Spline)
Filling::Filling()
{
ADD_PROPERTY_TYPE(Border,(0,""), "Filling", App::Prop_None, "Border Edges (C0 is required for edges without a corresponding face)");
ADD_PROPERTY_TYPE(BorderFaces,(0,""), "Filling", App::Prop_None, "Border Faces");
ADD_PROPERTY_TYPE(OrderBorderFaces,(-1), "Filling", App::Prop_None, "Order of constraint on border faces (C0, G1 and G2 are possible)");
ADD_PROPERTY_TYPE(BoundaryEdges,(0,""), "Filling", App::Prop_None, "Boundary Edges (C0 is required for edges without a corresponding face)");
ADD_PROPERTY_TYPE(BoundaryFaces,(""), "Filling", App::Prop_None, "Boundary Faces");
ADD_PROPERTY_TYPE(BoundaryOrder,(-1), "Filling", App::Prop_None, "Order of constraint on boundary faces (C0, G1 and G2 are possible)");
ADD_PROPERTY_TYPE(Curves,(0,""), "Filling", App::Prop_None, "Other Constraint Curves (C0 is required for edges without a corresponding face)");
ADD_PROPERTY_TYPE(CurveFaces,(0,""), "Filling", App::Prop_None, "Curve Faces");
ADD_PROPERTY_TYPE(OrderCurveFaces,(-1), "Filling", App::Prop_None, "Order of constraint on curve faces (C0, G1 and G2 are possible)");
ADD_PROPERTY_TYPE(UnboundEdges,(0,""), "Filling", App::Prop_None, "Unbound constraint edges (C0 is required for edges without a corresponding face)");
ADD_PROPERTY_TYPE(UnboundFaces,(""), "Filling", App::Prop_None, "Unbound constraint faces");
ADD_PROPERTY_TYPE(UnboundOrder,(-1), "Filling", App::Prop_None, "Order of constraint on curve faces (C0, G1 and G2 are possible)");
ADD_PROPERTY_TYPE(FreeFaces,(0,""), "Filling", App::Prop_None, "Free constraint on a face");
ADD_PROPERTY_TYPE(OrderFreeFaces,(0), "Filling", App::Prop_None, "Order of constraint on free faces");
ADD_PROPERTY_TYPE(FreeOrder,(0), "Filling", App::Prop_None, "Order of constraint on free faces");
ADD_PROPERTY_TYPE(Points,(0,""), "Filling", App::Prop_None, "Constraint Points (on Surface)");
ADD_PROPERTY_TYPE(InitialFace,(0), "Filling", App::Prop_None, "Initial surface to use");
ADD_PROPERTY_TYPE(Degree,(3), "Filling", App::Prop_None, "Starting degree");
ADD_PROPERTY_TYPE(PointsOnCurve,(3), "Filling", App::Prop_None, "Number of points on an edge for constraint");
ADD_PROPERTY_TYPE(PointsOnCurve,(15), "Filling", App::Prop_None, "Number of points on an edge for constraint");
ADD_PROPERTY_TYPE(Iterations,(2), "Filling", App::Prop_None, "Number of iterations");
ADD_PROPERTY_TYPE(Anisotropy,(false), "Filling", App::Prop_None, "Anisotropy");
ADD_PROPERTY_TYPE(Tolerance2d,(0.00001), "Filling", App::Prop_None, "2D Tolerance");
ADD_PROPERTY_TYPE(Tolerance3d,(0.0001), "Filling", App::Prop_None, "3D Tolerance");
ADD_PROPERTY_TYPE(TolAngular,(0.001), "Filling", App::Prop_None, "G1 tolerance");
ADD_PROPERTY_TYPE(TolCurvature,(0.01), "Filling", App::Prop_None, "G2 tolerance");
ADD_PROPERTY_TYPE(TolAngular,(0.01), "Filling", App::Prop_None, "G1 tolerance");
ADD_PROPERTY_TYPE(TolCurvature,(0.1), "Filling", App::Prop_None, "G2 tolerance");
ADD_PROPERTY_TYPE(MaximumDegree,(8), "Filling", App::Prop_None, "Maximum curve degree");
ADD_PROPERTY_TYPE(MaximumSegments,(10000), "Filling", App::Prop_None, "Maximum number of segments");
ADD_PROPERTY_TYPE(MaximumSegments,(9), "Filling", App::Prop_None, "Maximum number of segments");
BoundaryEdges.setSize(0);
BoundaryFaces.setSize(0);
BoundaryOrder.setSize(0);
UnboundEdges.setSize(0);
UnboundFaces.setSize(0);
UnboundOrder.setSize(0);
FreeFaces.setSize(0);
FreeOrder.setSize(0);
Points.setSize(0);
}
short Filling::mustExecute() const
{
if (Border.isTouched() ||
BorderFaces.isTouched() ||
OrderBorderFaces.isTouched() ||
Curves.isTouched() ||
CurveFaces.isTouched() ||
OrderCurveFaces.isTouched() ||
if (BoundaryEdges.isTouched() ||
BoundaryFaces.isTouched() ||
BoundaryOrder.isTouched() ||
UnboundEdges.isTouched() ||
UnboundFaces.isTouched() ||
UnboundOrder.isTouched() ||
FreeFaces.isTouched() ||
OrderFreeFaces.isTouched() ||
FreeOrder.isTouched() ||
Points.isTouched() ||
InitialFace.isTouched() ||
Degree.isTouched() ||
@@ -100,39 +110,61 @@ short Filling::mustExecute() const
void Filling::addConstraints(BRepFill_Filling& builder,
const App::PropertyLinkSubList& edges,
const App::PropertyLinkSubList& faces,
const App::PropertyStringList& faces,
const App::PropertyIntegerList& orders,
Standard_Boolean bnd)
{
auto edge_obj = edges.getValues();
auto edge_sub = edges.getSubValues();
auto face_obj = faces.getValues();
auto face_sub = faces.getSubValues();
auto face_sub = faces.getValues();
auto contvals = orders.getValues();
// tmp. workaround
if (edge_obj.size() != contvals.size()) {
contvals.resize(edge_obj.size());
// if the number of continuities doesn't match then fall back to C0
if (edge_sub.size() != contvals.size()) {
contvals.resize(edge_sub.size());
std::fill(contvals.begin(), contvals.end(), static_cast<long>(GeomAbs_C0));
}
if (edge_obj.size() == edge_sub.size() &&
edge_obj.size() == contvals.size()) {
// if the number of faces doesn't match then fall back to empty strings
// an empty face string indicates that there is no face associated to an edge
if (face_sub.size() != edge_sub.size()) {
face_sub.resize(edge_obj.size());
std::fill(face_sub.begin(), face_sub.end(), std::string());
}
if (edge_obj.size() == edge_sub.size()) {
for (std::size_t index = 0; index < edge_obj.size(); index++) {
// get the part object
App::DocumentObject* obj = edge_obj[index];
const std::string& sub = edge_sub[index];
if (obj && obj->getTypeId().isDerivedFrom(Part::Feature::getClassTypeId())) {
// get the sub-edge of the part's shape
const Part::TopoShape& shape = static_cast<Part::Feature*>(obj)->Shape.getShape();
TopoDS_Shape edge = shape.getSubShape(sub.c_str());
if (!edge.IsNull() && edge.ShapeType() == TopAbs_EDGE) {
GeomAbs_Shape cont = static_cast<GeomAbs_Shape>(contvals[index]);
if (cont == GeomAbs_C0) {
// check for an adjacent face of the edge
std::string subFace = face_sub[index];
// edge doesn't have set an adjacent face
if (subFace.empty()) {
builder.Add(TopoDS::Edge(edge), cont, bnd);
}
else {
builder.Add(TopoDS::Edge(edge), cont, bnd);
TopoDS_Shape face = shape.getSubShape(subFace.c_str());
if (!face.IsNull() && face.ShapeType() == TopAbs_FACE) {
builder.Add(TopoDS::Edge(edge), TopoDS::Face(face), cont, bnd);
}
else {
Standard_Failure::Raise("Sub-shape is not a face");
}
}
}
else {
Standard_Failure::Raise("Sub-shape is not an edge");
}
}
}
}
@@ -141,6 +173,7 @@ void Filling::addConstraints(BRepFill_Filling& builder,
}
}
// Add free support faces with their continuities
void Filling::addConstraints(BRepFill_Filling& builder,
const App::PropertyLinkSubList& faces,
const App::PropertyIntegerList& orders)
@@ -161,6 +194,9 @@ void Filling::addConstraints(BRepFill_Filling& builder,
GeomAbs_Shape cont = static_cast<GeomAbs_Shape>(contvals[index]);
builder.Add(TopoDS::Face(face), cont);
}
else {
Standard_Failure::Raise("Sub-shape is not a face");
}
}
}
}
@@ -207,7 +243,7 @@ App::DocumentObjectExecReturn *Filling::execute(void)
BRepFill_Filling builder(degree, ptsoncurve, numIter, anisotropy, tol2d,
tol3d, tolG1, tolG2, maxdeg, maxseg);
if ((Border.getSize()) < 1) {
if ((BoundaryEdges.getSize()) < 1) {
return new App::DocumentObjectExecReturn("Border must have at least one curve defined.");
}
@@ -226,16 +262,16 @@ App::DocumentObjectExecReturn *Filling::execute(void)
}
// Add the constraints of border curves/faces (bound)
addConstraints(builder, Border, BorderFaces, OrderBorderFaces, Standard_True);
addConstraints(builder, BoundaryEdges, BoundaryFaces, BoundaryOrder, Standard_True);
// Add additional curves constraints if available (unbound)
if (Curves.getSize() > 0) {
addConstraints(builder, Curves, CurveFaces, OrderCurveFaces, Standard_False);
// Add additional edge constraints if available (unbound)
if (UnboundEdges.getSize() > 0) {
addConstraints(builder, UnboundEdges, UnboundFaces, UnboundOrder, Standard_False);
}
// Add additional constraint on free faces
if (FreeFaces.getSize() > 0) {
addConstraints(builder, FreeFaces, OrderFreeFaces);
addConstraints(builder, FreeFaces, FreeOrder);
}
// App point constraints

View File

@@ -41,14 +41,14 @@ public:
Filling();
//Properties of Curves
App::PropertyLinkSubList Border; // Border Edges (C0 is required for edges without a corresponding face)
App::PropertyLinkSubList BorderFaces; // Border Faces (C0, G1 and G2 are possible)
App::PropertyIntegerList OrderBorderFaces; // Order of constraint on border faces
App::PropertyLinkSubList Curves; // Other Constraint Curves (C0 is required for edges without a corresponding face)
App::PropertyLinkSubList CurveFaces; // Curve Faces (C0, G1 and G2 are possible)
App::PropertyIntegerList OrderCurveFaces; // Order of constraint on curve faces
App::PropertyLinkSubList FreeFaces; // Free constraint on a face
App::PropertyIntegerList OrderFreeFaces; // Order of constraint on free faces
App::PropertyLinkSubList BoundaryEdges; // Boundary Edges (C0 is required for edges without a corresponding face)
App::PropertyStringList BoundaryFaces; // Boundary Faces (C0, G1 and G2 are possible)
App::PropertyIntegerList BoundaryOrder; // Order of constraint on border faces
App::PropertyLinkSubList UnboundEdges; // Unbound constraint edges (C0 is required for edges without a corresponding face)
App::PropertyStringList UnboundFaces; // Unbound constraint faces (C0, G1 and G2 are possible)
App::PropertyIntegerList UnboundOrder; // Order of constraint on curve faces
App::PropertyLinkSubList FreeFaces; // Free constraint faces
App::PropertyIntegerList FreeOrder; // Order of constraint on free faces
App::PropertyLinkSubList Points; // Constraint Points (on Surface)
App::PropertyLinkSub InitialFace; // Initial Face to use
@@ -75,7 +75,7 @@ public:
private:
void addConstraints(BRepFill_Filling& builder,
const App::PropertyLinkSubList& edges,
const App::PropertyLinkSubList& faces,
const App::PropertyStringList& faces,
const App::PropertyIntegerList& orders,
Standard_Boolean bnd);
void addConstraints(BRepFill_Filling& builder,

View File

@@ -107,7 +107,7 @@ QIcon ViewProviderFilling::getIcon(void) const
void ViewProviderFilling::highlightReferences(bool on)
{
Surface::Filling* surface = static_cast<Surface::Filling*>(getObject());
auto bounds = surface->Border.getSubListValues();
auto bounds = surface->BoundaryEdges.getSubListValues();
for (auto it : bounds) {
Part::Feature* base = dynamic_cast<Part::Feature*>(it.first);
if (base) {
@@ -187,7 +187,7 @@ private:
if (element.substr(0,4) != "Edge")
return false;
auto links = editedObject->Border.getSubListValues();
auto links = editedObject->BoundaryEdges.getSubListValues();
for (auto it : links) {
if (it.first == pObj) {
for (auto jt : it.second) {
@@ -249,8 +249,8 @@ void FillingPanel::setEditedObject(Surface::Filling* obj)
ui->lineInitFaceName->setText(text);
}
auto objects = editedObject->Border.getValues();
auto element = editedObject->Border.getSubValues();
auto objects = editedObject->BoundaryEdges.getValues();
auto element = editedObject->BoundaryEdges.getSubValues();
auto it = objects.begin();
auto jt = element.begin();
@@ -405,7 +405,7 @@ void FillingPanel::on_listBoundary_itemDoubleClicked(QListWidgetItem* item)
ui->statusLabel->setText(tr("Edge has %n adjacent face(s)", 0, n));
// fill up the combo boxes
modifyBorder(true);
modifyBoundary(true);
ui->comboBoxFaces->addItem(tr("None"), QByteArray("None"));
ui->comboBoxCont->addItem(QString::fromLatin1("C0"), static_cast<int>(GeomAbs_C0));
ui->comboBoxCont->addItem(QString::fromLatin1("G1"), static_cast<int>(GeomAbs_G1));
@@ -478,11 +478,11 @@ void FillingPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
data << QByteArray(msg.pSubName);
item->setData(Qt::UserRole, data);
auto objects = editedObject->Border.getValues();
auto objects = editedObject->BoundaryEdges.getValues();
objects.push_back(sel.getObject());
auto element = editedObject->Border.getSubValues();
auto element = editedObject->BoundaryEdges.getSubValues();
element.push_back(msg.pSubName);
editedObject->Border.setValues(objects, element);
editedObject->BoundaryEdges.setValues(objects, element);
this->vp->highlightReferences(true);
}
else if (selectionMode == RemoveEdge) {
@@ -502,15 +502,15 @@ void FillingPanel::onSelectionChanged(const Gui::SelectionChanges& msg)
this->vp->highlightReferences(false);
App::DocumentObject* obj = sel.getObject();
std::string sub = msg.pSubName;
auto objects = editedObject->Border.getValues();
auto element = editedObject->Border.getSubValues();
auto objects = editedObject->BoundaryEdges.getValues();
auto element = editedObject->BoundaryEdges.getSubValues();
auto it = objects.begin();
auto jt = element.begin();
for (; it != objects.end() && jt != element.end(); ++it, ++jt) {
if (*it == obj && *jt == sub) {
objects.erase(it);
element.erase(jt);
editedObject->Border.setValues(objects, element);
editedObject->BoundaryEdges.setValues(objects, element);
break;
}
}
@@ -536,8 +536,8 @@ void FillingPanel::onDeleteEdge()
App::Document* doc = App::GetApplication().getDocument(data[0].toByteArray());
App::DocumentObject* obj = doc ? doc->getObject(data[1].toByteArray()) : nullptr;
std::string sub = data[2].toByteArray().constData();
auto objects = editedObject->Border.getValues();
auto element = editedObject->Border.getSubValues();
auto objects = editedObject->BoundaryEdges.getValues();
auto element = editedObject->BoundaryEdges.getSubValues();
auto it = objects.begin();
auto jt = element.begin();
this->vp->highlightReferences(false);
@@ -545,7 +545,7 @@ void FillingPanel::onDeleteEdge()
if (*it == obj && *jt == sub) {
objects.erase(it);
element.erase(jt);
editedObject->Border.setValues(objects, element);
editedObject->BoundaryEdges.setValues(objects, element);
break;
}
}
@@ -559,19 +559,22 @@ void FillingPanel::on_buttonAccept_clicked()
if (item) {
QList<QVariant> data;
data = item->data(Qt::UserRole).toList();
QVariant face = ui->comboBoxFaces->itemData(ui->comboBoxFaces->currentIndex());
QVariant cont = ui->comboBoxCont->itemData(ui->comboBoxCont->currentIndex());
if (data.size() == 5) {
data[3] = ui->comboBoxFaces->itemData(ui->comboBoxFaces->currentIndex());
data[4] = ui->comboBoxCont->itemData(ui->comboBoxCont->currentIndex());
data[3] = face;
data[4] = cont;
}
else {
data << ui->comboBoxFaces->itemData(ui->comboBoxFaces->currentIndex());
data << ui->comboBoxCont->itemData(ui->comboBoxCont->currentIndex());
data << face;
data << cont;
}
item->setData(Qt::UserRole, data);
}
modifyBorder(false);
modifyBoundary(false);
ui->comboBoxFaces->clear();
ui->comboBoxCont->clear();
ui->statusLabel->clear();
@@ -579,13 +582,13 @@ void FillingPanel::on_buttonAccept_clicked()
void FillingPanel::on_buttonIgnore_clicked()
{
modifyBorder(false);
modifyBoundary(false);
ui->comboBoxFaces->clear();
ui->comboBoxCont->clear();
ui->statusLabel->clear();
}
void FillingPanel::modifyBorder(bool on)
void FillingPanel::modifyBoundary(bool on)
{
ui->buttonInitFace->setDisabled(on);
ui->lineInitFaceName->setDisabled(on);

View File

@@ -83,7 +83,7 @@ protected:
virtual void slotUndoDocument(const Gui::Document& Doc);
/** Notifies on redo */
virtual void slotRedoDocument(const Gui::Document& Doc);
void modifyBorder(bool);
void modifyBoundary(bool);
private Q_SLOTS:
void on_buttonInitFace_clicked();