From df386cc3c1331bd701e98790842ef706f92fce5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Sun, 31 May 2015 18:29:59 +0200 Subject: [PATCH] make multisection work --- src/Mod/PartDesign/App/FeaturePipe.cpp | 39 +++++++++- .../PartDesign/Gui/TaskDatumParameters.cpp | 3 + src/Mod/PartDesign/Gui/TaskPipeParameters.cpp | 78 +++++++++++++++++++ 3 files changed, 117 insertions(+), 3 deletions(-) diff --git a/src/Mod/PartDesign/App/FeaturePipe.cpp b/src/Mod/PartDesign/App/FeaturePipe.cpp index 0f6d1beb6..f7a97b9d9 100644 --- a/src/Mod/PartDesign/App/FeaturePipe.cpp +++ b/src/Mod/PartDesign/App/FeaturePipe.cpp @@ -158,14 +158,47 @@ App::DocumentObjectExecReturn *Pipe::execute(void) buildPipePath(auxshape, auxsubedge, auxpath); } + //build up multisections + auto multisections = Sections.getValues(); + std::vector> wiresections; + for(TopoDS_Wire& wire : wires) + wiresections.push_back(std::vector(1, wire)); + + if(Transformation.getValue() == 1) { + + //we need to order the sections to prevent occ from crahsing, as makepieshell connects + //the sections in the order of adding + + + for(App::DocumentObject* obj : multisections) { + if(!obj->isDerivedFrom(Part::Feature::getClassTypeId())) + return new App::DocumentObjectExecReturn("All sections need to be part features"); + + TopExp_Explorer ex; + int i=0; + for (ex.Init(static_cast(obj)->Shape.getValue(), TopAbs_WIRE); ex.More(); ex.Next()) { + wiresections[i].push_back(TopoDS::Wire(ex.Current())); + if(i>=wiresections.size()) + return new App::DocumentObjectExecReturn("Multisections need to have the same amount of inner wires as the base section"); + + ++i; + } + if(i shells; std::vector frontwires, backwires; - for(TopoDS_Wire& wire : wires) { + for(std::vector& wires : wiresections) { BRepOffsetAPI_MakePipeShell mkPS(TopoDS::Wire(path)); setupAlgorithm(mkPS, auxpath); - mkPS.Add(wire); + + for(TopoDS_Wire& wire : wires) + mkPS.Add(wire); if (!mkPS.IsReady()) return new App::DocumentObjectExecReturn("pipe could not be build"); @@ -254,7 +287,7 @@ App::DocumentObjectExecReturn *Pipe::execute(void) return new App::DocumentObjectExecReturn(e->GetMessageString()); } catch (...) { - return new App::DocumentObjectExecReturn("A fatal error occurred when making the sweep"); + return new App::DocumentObjectExecReturn("A fatal error occurred when making the pipe"); } } diff --git a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp index 5b706e3a0..b53a605de 100644 --- a/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskDatumParameters.cpp @@ -473,6 +473,9 @@ void TaskDatumParameters::onButtonRef(const bool pressed, const int idx) { // Note: Even if there is no solid, App::Plane and Part::Datum can still be selected PartDesign::Body* activeBody = Gui::Application::Instance->activeView()->getActiveObject(PDBODYKEY); + if(!activeBody) + throw Base::Exception("No active body"); + App::DocumentObject* solid = activeBody->getPrevSolidFeature(); if (pressed) { diff --git a/src/Mod/PartDesign/Gui/TaskPipeParameters.cpp b/src/Mod/PartDesign/Gui/TaskPipeParameters.cpp index 2e40b95b3..9426a77f3 100644 --- a/src/Mod/PartDesign/Gui/TaskPipeParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPipeParameters.cpp @@ -366,10 +366,15 @@ void TaskPipeOrientation::onOrientationChanged(int idx) { void TaskPipeOrientation::clearButtons() { + ui->buttonRefAdd->setChecked(false); + ui->buttonRefRemove->setChecked(false); + ui->buttonProfileBase->setChecked(false); } void TaskPipeOrientation::exitSelectionMode() { + selectionMode = none; + Gui::Selection().clearSelection(); } void TaskPipeOrientation::onButtonRefAdd(bool checked) { @@ -547,18 +552,32 @@ TaskPipeScaling::~TaskPipeScaling() { void TaskPipeScaling::clearButtons() { + ui->buttonRefAdd->setChecked(false); + ui->buttonRefRemove->setChecked(false); } void TaskPipeScaling::exitSelectionMode() { + selectionMode = none; + Gui::Selection().clearSelection(); } void TaskPipeScaling::onButtonRefAdd(bool checked) { + if (checked) { + Gui::Selection().clearSelection(); + selectionMode = refAdd; + //static_cast(vp)->highlightReferences(true, true); + } } void TaskPipeScaling::onButtonRefRemove(bool checked) { + if (checked) { + Gui::Selection().clearSelection(); + selectionMode = refRemove; + //static_cast(vp)->highlightReferences(true, true); + } } void TaskPipeScaling::onScalingChanged(int idx) { @@ -569,10 +588,69 @@ void TaskPipeScaling::onScalingChanged(int idx) { void TaskPipeScaling::onSelectionChanged(const SelectionChanges& msg) { + if (selectionMode == none) + return; + + if (msg.Type == Gui::SelectionChanges::AddSelection) { + if (referenceSelected(msg)) { + if (selectionMode == refAdd) { + QString objn = QString::fromStdString(msg.pObjectName); + if(!objn.isEmpty()) + ui->listWidgetReferences->addItem(objn); + } + else if (selectionMode == refRemove) { + QString objn = QString::fromStdString(msg.pObjectName); + if(!objn.isEmpty()) + removeFromListWidget(ui->listWidgetReferences, objn); + } + clearButtons(); + //static_cast(vp)->highlightReferences(false, true); + recomputeFeature(); + } + clearButtons(); + exitSelectionMode(); + } } bool TaskPipeScaling::referenceSelected(const SelectionChanges& msg) const { + + if ((msg.Type == Gui::SelectionChanges::AddSelection) && ( + (selectionMode == refAdd) || (selectionMode == refRemove))) { + + if (strcmp(msg.pDocName, vp->getObject()->getDocument()->getName()) != 0) + return false; + + // not allowed to reference ourself + const char* fname = vp->getObject()->getNameInDocument(); + if (strcmp(msg.pObjectName, fname) == 0) + return false; + + //every selection needs to be a profile in itself, hence currently only full objects are + //supported, not individual edges of a part + + //change the references + std::vector refs = static_cast(vp->getObject())->Sections.getValues(); + App::DocumentObject* obj = vp->getObject()->getDocument()->getObject(msg.pObjectName); + std::vector::iterator f = std::find(refs.begin(), refs.end(), obj); + + if (selectionMode == refAdd) { + if (f == refs.end()) + refs.push_back(obj); + else + return false; // duplicate selection + } else { + if (f != refs.end()) + refs.erase(f); + else + return false; + } + + static_cast(vp->getObject())->Sections.setValues(refs); + return true; + } + + return false; } void TaskPipeScaling::removeFromListWidget(QListWidget* w, QString name) {