diff --git a/src/Mod/PartDesign/App/FeatureTransformed.cpp b/src/Mod/PartDesign/App/FeatureTransformed.cpp index 2ac20f93b..f3b70dcd6 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.cpp +++ b/src/Mod/PartDesign/App/FeatureTransformed.cpp @@ -56,7 +56,7 @@ namespace PartDesign { PROPERTY_SOURCE(PartDesign::Transformed, PartDesign::Feature) -Transformed::Transformed() : rejected(0) +Transformed::Transformed() { ADD_PROPERTY(Originals,(0)); Originals.setSize(0); @@ -202,8 +202,10 @@ App::DocumentObjectExecReturn *Transformed::execute(void) supportShape.setTransform(Base::Matrix4D()); TopoDS_Shape support = supportShape._Shape; - std::set::const_iterator> nointersect_trsfms; - std::set::const_iterator> overlapping_trsfms; + typedef std::set::const_iterator> trsf_it; + typedef std::map rej_it_map; + rej_it_map nointersect_trsfms; + rej_it_map overlapping_trsfms; // NOTE: It would be possible to build a compound from all original addShapes/subShapes and then // transform the compounds as a whole. But we choose to apply the transformations to each @@ -233,7 +235,8 @@ App::DocumentObjectExecReturn *Transformed::execute(void) } // Transform the add/subshape and collect the resulting shapes for overlap testing - std::vector::const_iterator> v_transformations; + typedef std::vector::const_iterator> trsf_it_vec; + trsf_it_vec v_transformations; std::vector v_transformedShapes; std::vector::const_iterator t = transformations.begin(); @@ -244,7 +247,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void) BRepBuilderAPI_Copy copy(shape); shape = copy.Shape(); if (shape.IsNull()) - throw Base::Exception("Transformed: Linked shape object is empty"); + return new App::DocumentObjectExecReturn("Transformed: Linked shape object is empty"); BRepBuilderAPI_Transform mkTrf(shape, *t, false); // No need to copy, now if (!mkTrf.IsDone()) @@ -256,7 +259,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void) #ifdef FC_DEBUG // do not write this in release mode because a message appears already in the task view Base::Console().Warning("Transformed shape does not intersect support %s: Removed\n", (*o)->getNameInDocument()); #endif - nointersect_trsfms.insert(t); + nointersect_trsfms[*o].insert(t); } else { v_transformations.push_back(t); v_transformedShapes.push_back(mkTrf.Shape()); @@ -274,7 +277,7 @@ App::DocumentObjectExecReturn *Transformed::execute(void) } if (v_transformedShapes.empty()) - break; // Skip the overlap check and go on to next original + continue; // Skip the overlap check and go on to next original // Check for overlapping of the original and the transformed shapes, and remove the overlapping transformations if (this->getTypeId() != PartDesign::MultiTransform::getClassTypeId()) { @@ -283,34 +286,35 @@ App::DocumentObjectExecReturn *Transformed::execute(void) if (v_transformedShapes.size() > 1) if (Part::checkIntersection(shape, v_transformedShapes.front(), false, false)) { // For single transformations, if one overlaps, all overlap, as long as we have uniform increments - overlapping_trsfms.insert(v_transformations.begin(),v_transformations.end()); + for (trsf_it_vec::const_iterator v = v_transformations.begin(); v != v_transformations.end(); v++) + overlapping_trsfms[*o].insert(*v); v_transformedShapes.clear(); } } else { // For MultiTransform, just checking the first transformed shape is not sufficient - any two // features might overlap, even if the original and the first shape don't overlap! - - std::set::iterator> rejected_iterators; + typedef std::set::iterator> shape_it_set; + shape_it_set rejected_iterators; std::vector::iterator s1 = v_transformedShapes.begin(); std::vector::iterator s2 = s1; ++s2; - std::vector::const_iterator>::const_iterator t1 = v_transformations.begin(); - std::vector::const_iterator>::const_iterator t2 = t1; + trsf_it_vec::const_iterator t1 = v_transformations.begin(); + trsf_it_vec::const_iterator t2 = t1; ++t2; for (; s2 != v_transformedShapes.end();) { // Check intersection with the original if (Part::checkIntersection(shape, *s1, false, false)) { rejected_iterators.insert(s1); - overlapping_trsfms.insert(*t1); + overlapping_trsfms[*o].insert(*t1); } // Check intersection with other transformations for (; s2 != v_transformedShapes.end(); ++s2, ++t2) if (Part::checkIntersection(*s1, *s2, false, false)) { rejected_iterators.insert(s1); rejected_iterators.insert(s2); - overlapping_trsfms.insert(*t1); - overlapping_trsfms.insert(*t2); + overlapping_trsfms[*o].insert(*t1); + overlapping_trsfms[*o].insert(*t2); } ++s1; s2 = s1; @@ -322,16 +326,16 @@ App::DocumentObjectExecReturn *Transformed::execute(void) // Check intersection of last transformation with the original if (Part::checkIntersection(shape, *s1, false, false)) { rejected_iterators.insert(s1); - overlapping_trsfms.insert(*t1); + overlapping_trsfms[*o].insert(*t1); } - for (std::set::iterator>::reverse_iterator it = rejected_iterators.rbegin(); + for (shape_it_set::reverse_iterator it = rejected_iterators.rbegin(); it != rejected_iterators.rend(); ++it) v_transformedShapes.erase(*it); } if (v_transformedShapes.empty()) - break; // Skip the boolean operation and go on to next original + continue; // Skip the boolean operation and go on to next original // Build a compound from all the valid transformations BRep_Builder builder; @@ -366,13 +370,13 @@ App::DocumentObjectExecReturn *Transformed::execute(void) if (!overlapping_trsfms.empty()) // Concentrate on overlapping shapes since they are more serious - for (std::set::const_iterator>::const_iterator it = overlapping_trsfms.begin(); - it != overlapping_trsfms.end(); ++it) - rejected.push_back(**it); + for (rej_it_map::const_iterator it = overlapping_trsfms.begin(); it != overlapping_trsfms.end(); ++it) + for (trsf_it::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) + rejected[it->first].push_back(**it2); else - for (std::set::const_iterator>::const_iterator it = nointersect_trsfms.begin(); - it != nointersect_trsfms.end(); ++it) - rejected.push_back(**it); + for (rej_it_map::const_iterator it = nointersect_trsfms.begin(); it != nointersect_trsfms.end(); ++it) + for (trsf_it::const_iterator it2 = it->second.begin(); it2 != it->second.end(); ++it2) + rejected[it->first].push_back(**it2); this->Shape.setValue(support); if (!overlapping_trsfms.empty()) diff --git a/src/Mod/PartDesign/App/FeatureTransformed.h b/src/Mod/PartDesign/App/FeatureTransformed.h index fe077931d..cd837f312 100644 --- a/src/Mod/PartDesign/App/FeatureTransformed.h +++ b/src/Mod/PartDesign/App/FeatureTransformed.h @@ -77,14 +77,15 @@ public: /** returns a list of the transformations that where rejected during the last execute * because they did not ovelap with the support */ - const std::list getRejectedTransformations(void) { return rejected; } + typedef std::map > rejectedMap; + const rejectedMap getRejectedTransformations(void) { return rejected; } protected: void Restore(Base::XMLReader &reader); virtual void positionBySupport(void); TopoDS_Shape refineShapeIfActive(const TopoDS_Shape&) const; - std::list rejected; + rejectedMap rejected; }; } //namespace PartDesign diff --git a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp index 7cb465735..10f01c2a9 100644 --- a/src/Mod/PartDesign/Gui/ReferenceSelection.cpp +++ b/src/Mod/PartDesign/Gui/ReferenceSelection.cpp @@ -123,6 +123,9 @@ namespace PartDesignGui void getReferencedSelection(const App::DocumentObject* thisObj, const Gui::SelectionChanges& msg, App::DocumentObject*& selObj, std::vector& selSub) { + if (strcmp(thisObj->getDocument()->getName(), msg.pDocName) != 0) + return; + selObj = thisObj->getDocument()->getObject(msg.pObjectName); if (selObj == thisObj) return; diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp index 300c3f8ce..ad2c75785 100644 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp @@ -68,7 +68,7 @@ TaskLinearPatternParameters::TaskLinearPatternParameters(ViewProviderTransformed ui->buttonOK->hide(); ui->checkBoxUpdateView->setEnabled(true); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -87,11 +87,12 @@ TaskLinearPatternParameters::TaskLinearPatternParameters(TaskMultiTransformParam layout->addWidget(proxy); ui->buttonOK->setEnabled(true); - ui->labelOriginal->hide(); - ui->lineOriginal->hide(); + ui->buttonAddFeature->hide(); + ui->buttonRemoveFeature->hide(); + ui->listWidgetFeatures->hide(); ui->checkBoxUpdateView->hide(); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -99,6 +100,14 @@ TaskLinearPatternParameters::TaskLinearPatternParameters(TaskMultiTransformParam void TaskLinearPatternParameters::setupUI() { + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + updateViewTimer = new QTimer(this); updateViewTimer->setSingleShot(true); updateViewTimer->setInterval(getUpdateViewTimeout()); @@ -121,13 +130,10 @@ void TaskLinearPatternParameters::setupUI() std::vector originals = pcLinearPattern->Originals.getValues(); // Fill data into dialog elements - ui->lineOriginal->setEnabled(false); for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) { - if ((*i) != NULL) { // find the first valid original - ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); - break; - } + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1((*i)->getNameInDocument())); } // --------------------- @@ -196,7 +202,7 @@ void TaskLinearPatternParameters::updateUI() undefined = true; } - if (referenceSelectionMode) { + if (selectionMode == reference) { ui->comboDirection->addItem(tr("Select an edge/face or datum line/plane")); ui->comboDirection->setCurrentIndex(ui->comboDirection->count() - 1); } else if (undefined) { @@ -227,13 +233,14 @@ void TaskLinearPatternParameters::kickUpdateViewTimer() const void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges& msg) { if (msg.Type == Gui::SelectionChanges::AddSelection) { - - if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) - return; - if (originalSelected(msg)) { - ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode) { + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + + exitSelectionMode(); + } else if (selectionMode == reference) { // Note: ReferenceSelection has already checked the selection for validity exitSelectionMode(); if (!blockUpdate) { @@ -266,6 +273,12 @@ void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges } } +void TaskLinearPatternParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + void TaskLinearPatternParameters::onCheckReverse(const bool on) { if (blockUpdate) return; @@ -339,7 +352,7 @@ void TaskLinearPatternParameters::onDirectionChanged(int num) { // enter reference selection mode hideObject(); showBase(); - referenceSelectionMode = true; + selectionMode = reference; Gui::Selection().clearSelection(); addReferenceSelectionGate(true, true); } @@ -368,6 +381,16 @@ void TaskLinearPatternParameters::onUpdateView(bool on) } } +void TaskLinearPatternParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + void TaskLinearPatternParameters::getDirection(App::DocumentObject*& obj, std::vector& sub) const { obj = getSketchObject(); diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig index 0a982a4a8..8357e5423 100644 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.cpp.orig @@ -32,6 +32,7 @@ #include "TaskLinearPatternParameters.h" #include "TaskMultiTransformParameters.h" #include "Workbench.h" +#include "ReferenceSelection.h" #include #include #include @@ -67,7 +68,7 @@ TaskLinearPatternParameters::TaskLinearPatternParameters(ViewProviderTransformed ui->buttonOK->hide(); ui->checkBoxUpdateView->setEnabled(true); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -86,11 +87,12 @@ TaskLinearPatternParameters::TaskLinearPatternParameters(TaskMultiTransformParam layout->addWidget(proxy); ui->buttonOK->setEnabled(true); - ui->labelOriginal->hide(); - ui->lineOriginal->hide(); + ui->buttonAddFeature->hide(); + ui->buttonRemoveFeature->hide(); + ui->listWidgetFeatures->hide(); ui->checkBoxUpdateView->hide(); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -98,6 +100,14 @@ TaskLinearPatternParameters::TaskLinearPatternParameters(TaskMultiTransformParam void TaskLinearPatternParameters::setupUI() { + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + updateViewTimer = new QTimer(this); updateViewTimer->setSingleShot(true); updateViewTimer->setInterval(getUpdateViewTimeout()); @@ -120,13 +130,17 @@ void TaskLinearPatternParameters::setupUI() std::vector originals = pcLinearPattern->Originals.getValues(); // Fill data into dialog elements - ui->lineOriginal->setEnabled(false); for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) { +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 if ((*i) != NULL) { // find the first valid original ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); break; } +======= + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii((*i)->getNameInDocument())); +>>>>>>> Enable multiple originals for the transformed features } // --------------------- @@ -167,11 +181,7 @@ void TaskLinearPatternParameters::updateUI() for (int i=ui->comboDirection->count()-1; i >= 5; i--) ui->comboDirection->removeItem(i); for (int i=ui->comboDirection->count(); i < maxcount; i++) -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 - ui->comboDirection->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); -======= - ui->comboDirection->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); ->>>>>>> Allow datum lines and planes for Transformed features' references + ui->comboDirection->addItem(QString::fromLatin1("Sketch axis %1").arg(i-5)); bool undefined = false; if (directionFeature != NULL && !directions.empty()) { @@ -191,20 +201,15 @@ void TaskLinearPatternParameters::updateUI() ui->comboDirection->setCurrentIndex(pos); else undefined = true; -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 - } else if (directionFeature != NULL && !directions.empty()) { - ui->comboDirection->addItem(QString::fromLatin1(directions.front().c_str())); -======= } else { ui->comboDirection->addItem(getRefStr(directionFeature, directions)); ->>>>>>> Allow datum lines and planes for Transformed features' references ui->comboDirection->setCurrentIndex(maxcount); } } else { undefined = true; } - if (referenceSelectionMode) { + if (selectionMode == reference) { ui->comboDirection->addItem(tr("Select an edge/face or datum line/plane")); ui->comboDirection->setCurrentIndex(ui->comboDirection->count() - 1); } else if (undefined) { @@ -235,31 +240,26 @@ void TaskLinearPatternParameters::kickUpdateViewTimer() const void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges& msg) { if (msg.Type == Gui::SelectionChanges::AddSelection) { - - if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) - return; - if (originalSelected(msg)) { -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode && - ((subName.size() > 4 && subName.substr(0,4) == "Edge") || - (subName.size() > 4 && subName.substr(0,4) == "Face"))) { - - if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) - return; - -======= - ui->lineOriginal->setText(QString::fromAscii(msg.pObjectName)); } else if (referenceSelectionMode) { +======= + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + + exitSelectionMode(); + } else if (selectionMode == reference) { +>>>>>>> Enable multiple originals for the transformed features // Note: ReferenceSelection has already checked the selection for validity ->>>>>>> Allow datum lines and planes for Transformed features' references exitSelectionMode(); if (!blockUpdate) { std::vector directions; App::DocumentObject* selObj; - getReferencedSelection(msg, selObj, directions); PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + getReferencedSelection(pcLinearPattern, msg, selObj, directions); pcLinearPattern->Direction.setValue(selObj, directions); recomputeFeature(); @@ -273,14 +273,11 @@ void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges for (int i=ui->comboDirection->count()-1; i >= maxcount; i--) ui->comboDirection->removeItem(i); -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 - ui->comboDirection->addItem(QString::fromLatin1(subName.c_str())); -======= std::vector directions; App::DocumentObject* selObj; - getReferencedSelection(msg, selObj, directions); + PartDesign::LinearPattern* pcLinearPattern = static_cast(getObject()); + getReferencedSelection(pcLinearPattern, msg, selObj, directions); ui->comboDirection->addItem(getRefStr(selObj, directions)); ->>>>>>> Allow datum lines and planes for Transformed features' references ui->comboDirection->setCurrentIndex(maxcount); ui->comboDirection->addItem(tr("Select reference...")); } @@ -288,6 +285,12 @@ void TaskLinearPatternParameters::onSelectionChanged(const Gui::SelectionChanges } } +void TaskLinearPatternParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + void TaskLinearPatternParameters::onCheckReverse(const bool on) { if (blockUpdate) return; @@ -355,12 +358,13 @@ void TaskLinearPatternParameters::onDirectionChanged(int num) { QString buf = QString::fromUtf8("Axis%1").arg(num-5); std::string str = buf.toStdString(); pcLinearPattern->Direction.setValue(pcSketch, std::vector(1,str)); + exitSelectionMode(); } else if (num == ui->comboDirection->count() - 1) { // enter reference selection mode hideObject(); - showOriginals(); - referenceSelectionMode = true; + showBase(); + selectionMode = reference; Gui::Selection().clearSelection(); addReferenceSelectionGate(true, true); } @@ -389,6 +393,16 @@ void TaskLinearPatternParameters::onUpdateView(bool on) } } +void TaskLinearPatternParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + void TaskLinearPatternParameters::getDirection(App::DocumentObject*& obj, std::vector& sub) const { obj = getSketchObject(); diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.h b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.h index 5bf80e256..ccf266feb 100644 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.h +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.h @@ -66,10 +66,12 @@ private Q_SLOTS: void onLength(const double l); void onOccurrences(const uint n); virtual void onUpdateView(bool); + virtual void onFeatureDeleted(void); protected: virtual void changeEvent(QEvent *e); virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + virtual void clearButtons(); void getDirection(App::DocumentObject*& obj, std::vector& sub) const; const bool getReverse(void) const; const double getLength(void) const; diff --git a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui index dff273eb8..578aa266d 100644 --- a/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskLinearPatternParameters.ui @@ -7,7 +7,7 @@ 0 0 266 - 402 + 333 @@ -15,19 +15,32 @@ - + - + - Original feature + Add feature + + + true - + + + Remove feature + + + true + + + + + diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp index 4812f2f9f..e99932399 100644 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp @@ -65,7 +65,7 @@ TaskMirroredParameters::TaskMirroredParameters(ViewProviderTransformed *Transfor ui->buttonOK->hide(); ui->checkBoxUpdateView->setEnabled(true); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -84,11 +84,12 @@ TaskMirroredParameters::TaskMirroredParameters(TaskMultiTransformParameters *par layout->addWidget(proxy); ui->buttonOK->setEnabled(true); - ui->labelOriginal->hide(); - ui->lineOriginal->hide(); + ui->buttonAddFeature->hide(); + ui->buttonRemoveFeature->hide(); + ui->listWidgetFeatures->hide(); ui->checkBoxUpdateView->hide(); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -96,6 +97,14 @@ TaskMirroredParameters::TaskMirroredParameters(TaskMultiTransformParameters *par void TaskMirroredParameters::setupUI() { + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + connect(ui->comboPlane, SIGNAL(activated(int)), this, SLOT(onPlaneChanged(int))); connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), @@ -106,13 +115,10 @@ void TaskMirroredParameters::setupUI() std::vector originals = pcMirrored->Originals.getValues(); // Fill data into dialog elements - ui->lineOriginal->setEnabled(false); for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) { - if ((*i) != NULL) { // find the first valid original - ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); - break; - } + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1((*i)->getNameInDocument())); } // --------------------- @@ -168,7 +174,7 @@ void TaskMirroredParameters::updateUI() undefined = true; } - if (referenceSelectionMode) { + if (selectionMode == reference) { ui->comboPlane->addItem(tr("Select a face or datum plane")); ui->comboPlane->setCurrentIndex(ui->comboPlane->count() - 1); } else if (undefined) { @@ -184,12 +190,13 @@ void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg { if (msg.Type == Gui::SelectionChanges::AddSelection) { - if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) - return; - if (originalSelected(msg)) { - ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode) { + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + exitSelectionMode(); + } else if (selectionMode == reference) { // Note: ReferenceSelection has already checked the selection for validity exitSelectionMode(); if (!blockUpdate) { @@ -222,6 +229,12 @@ void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg } } +void TaskMirroredParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + void TaskMirroredParameters::onPlaneChanged(int num) { if (blockUpdate) return; @@ -265,7 +278,7 @@ void TaskMirroredParameters::onPlaneChanged(int num) { // enter reference selection mode hideObject(); showBase(); - referenceSelectionMode = true; + selectionMode = reference; Gui::Selection().clearSelection(); addReferenceSelectionGate(false, true); } @@ -291,6 +304,16 @@ void TaskMirroredParameters::onUpdateView(bool on) } } +void TaskMirroredParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + void TaskMirroredParameters::getMirrorPlane(App::DocumentObject*& obj, std::vector& sub) const { obj = getSketchObject(); diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig index c3ae4235c..37fc6cf74 100644 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.cpp.orig @@ -31,6 +31,7 @@ #include "TaskMirroredParameters.h" #include "TaskMultiTransformParameters.h" #include "Workbench.h" +#include "ReferenceSelection.h" #include #include #include @@ -64,7 +65,7 @@ TaskMirroredParameters::TaskMirroredParameters(ViewProviderTransformed *Transfor ui->buttonOK->hide(); ui->checkBoxUpdateView->setEnabled(true); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -83,11 +84,12 @@ TaskMirroredParameters::TaskMirroredParameters(TaskMultiTransformParameters *par layout->addWidget(proxy); ui->buttonOK->setEnabled(true); - ui->labelOriginal->hide(); - ui->lineOriginal->hide(); + ui->buttonAddFeature->hide(); + ui->buttonRemoveFeature->hide(); + ui->listWidgetFeatures->hide(); ui->checkBoxUpdateView->hide(); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -95,6 +97,14 @@ TaskMirroredParameters::TaskMirroredParameters(TaskMultiTransformParameters *par void TaskMirroredParameters::setupUI() { + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + connect(ui->comboPlane, SIGNAL(activated(int)), this, SLOT(onPlaneChanged(int))); connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), @@ -105,13 +115,17 @@ void TaskMirroredParameters::setupUI() std::vector originals = pcMirrored->Originals.getValues(); // Fill data into dialog elements - ui->lineOriginal->setEnabled(false); for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) { +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 if ((*i) != NULL) { // find the first valid original ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); break; } +======= + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii((*i)->getNameInDocument())); +>>>>>>> Enable multiple originals for the transformed features } // --------------------- @@ -139,11 +153,7 @@ void TaskMirroredParameters::updateUI() for (int i=ui->comboPlane->count()-1; i >= 5; i--) ui->comboPlane->removeItem(i); for (int i=ui->comboPlane->count(); i < maxcount; i++) -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 - ui->comboPlane->addItem(QString::fromLatin1("Sketch axis %1").arg(i-2)); -======= - ui->comboPlane->addItem(QString::fromAscii("Sketch axis %1").arg(i-5)); ->>>>>>> Allow datum lines and planes for Transformed features' references + ui->comboPlane->addItem(QString::fromLatin1("Sketch axis %1").arg(i-5)); bool undefined = false; if (mirrorPlaneFeature != NULL && !mirrorPlanes.empty()) { @@ -163,21 +173,15 @@ void TaskMirroredParameters::updateUI() ui->comboPlane->setCurrentIndex(pos); else undefined = true; -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 - } else if (mirrorPlaneFeature != NULL && !mirrorPlanes.empty()) { - ui->comboPlane->addItem(QString::fromLatin1(mirrorPlanes.front().c_str())); - ui->comboPlane->setCurrentIndex(maxcount); -======= } else { ui->comboPlane->addItem(getRefStr(mirrorPlaneFeature, mirrorPlanes)); ui->comboPlane->setCurrentIndex(maxcount); ->>>>>>> Allow datum lines and planes for Transformed features' references } } else { undefined = true; } - if (referenceSelectionMode) { + if (selectionMode == reference) { ui->comboPlane->addItem(tr("Select a face or datum plane")); ui->comboPlane->setCurrentIndex(ui->comboPlane->count() - 1); } else if (undefined) { @@ -193,29 +197,25 @@ void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg { if (msg.Type == Gui::SelectionChanges::AddSelection) { - if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) - return; - if (originalSelected(msg)) { -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode && - (subName.size() > 4 && subName.substr(0,4) == "Face")) { - - if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) - return; - -======= - ui->lineOriginal->setText(QString::fromAscii(msg.pObjectName)); } else if (referenceSelectionMode) { +======= + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + exitSelectionMode(); + } else if (selectionMode == reference) { +>>>>>>> Enable multiple originals for the transformed features // Note: ReferenceSelection has already checked the selection for validity ->>>>>>> Allow datum lines and planes for Transformed features' references exitSelectionMode(); if (!blockUpdate) { std::vector mirrorPlanes; App::DocumentObject* selObj; - getReferencedSelection(msg, selObj, mirrorPlanes); PartDesign::Mirrored* pcMirrored = static_cast(getObject()); + getReferencedSelection(pcMirrored, msg, selObj, mirrorPlanes); pcMirrored->MirrorPlane.setValue(selObj, mirrorPlanes); recomputeFeature(); @@ -229,14 +229,11 @@ void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg for (int i=ui->comboPlane->count()-1; i >= maxcount; i--) ui->comboPlane->removeItem(i); -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 - ui->comboPlane->addItem(QString::fromLatin1(subName.c_str())); -======= std::vector mirrorPlanes; App::DocumentObject* selObj; - getReferencedSelection(msg, selObj, mirrorPlanes); + PartDesign::Mirrored* pcMirrored = static_cast(getObject()); + getReferencedSelection(pcMirrored, msg, selObj, mirrorPlanes); ui->comboPlane->addItem(getRefStr(selObj, mirrorPlanes)); ->>>>>>> Allow datum lines and planes for Transformed features' references ui->comboPlane->setCurrentIndex(maxcount); ui->comboPlane->addItem(tr("Select reference...")); } @@ -244,6 +241,12 @@ void TaskMirroredParameters::onSelectionChanged(const Gui::SelectionChanges& msg } } +void TaskMirroredParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + void TaskMirroredParameters::onPlaneChanged(int num) { if (blockUpdate) return; @@ -281,12 +284,13 @@ void TaskMirroredParameters::onPlaneChanged(int num) { QString buf = QString::fromUtf8("Axis%1").arg(num-5); std::string str = buf.toStdString(); pcMirrored->MirrorPlane.setValue(pcSketch, std::vector(1,str)); + exitSelectionMode(); } else if (num == ui->comboPlane->count() - 1) { // enter reference selection mode hideObject(); - showOriginals(); - referenceSelectionMode = true; + showBase(); + selectionMode = reference; Gui::Selection().clearSelection(); addReferenceSelectionGate(false, true); } @@ -312,6 +316,16 @@ void TaskMirroredParameters::onUpdateView(bool on) } } +void TaskMirroredParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + void TaskMirroredParameters::getMirrorPlane(App::DocumentObject*& obj, std::vector& sub) const { obj = getSketchObject(); @@ -390,7 +404,7 @@ bool TaskDlgMirroredParameters::accept() std::vector mirrorPlanes; App::DocumentObject* obj; mirrorParameter->getMirrorPlane(obj, mirrorPlanes); - std::string mirrorPlane = mirrorParameter->getPythonStr(obj, mirrorPlanes); + std::string mirrorPlane = getPythonStr(obj, mirrorPlanes); if (!mirrorPlane.empty()) { Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.MirrorPlane = %s", name.c_str(), mirrorPlane.c_str()); } else diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.h b/src/Mod/PartDesign/Gui/TaskMirroredParameters.h index fa56829ed..a27a873fe 100644 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.h +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.h @@ -64,10 +64,12 @@ public: private Q_SLOTS: void onPlaneChanged(int num); virtual void onUpdateView(bool); + virtual void onFeatureDeleted(void); protected: virtual void changeEvent(QEvent *e); virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + virtual void clearButtons(); private: void setupUI(); diff --git a/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui b/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui index 461ca5e07..db0b364ce 100644 --- a/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskMirroredParameters.ui @@ -6,8 +6,8 @@ 0 0 - 242 - 290 + 253 + 235 @@ -15,19 +15,32 @@ - + - + - Original feature + Add feature + + + true - + + + Remove feature + + + true + + + + + diff --git a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp index ec818a961..98a2f4635 100644 --- a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp @@ -67,8 +67,16 @@ TaskMultiTransformParameters::TaskMultiTransformParameters(ViewProviderTransform QMetaObject::connectSlotsByName(this); this->groupLayout()->addWidget(proxy); + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + // Create a context menu for the listview of transformation features - QAction* action = new QAction(tr("Edit"), ui->listTransformFeatures); + action = new QAction(tr("Edit"), ui->listTransformFeatures); action->connect(action, SIGNAL(triggered()), this, SLOT(onTransformEdit())); ui->listTransformFeatures->addAction(action); @@ -131,13 +139,10 @@ TaskMultiTransformParameters::TaskMultiTransformParameters(ViewProviderTransform std::vector originals = pcMultiTransform->Originals.getValues(); // Fill data into dialog elements - ui->lineOriginal->setEnabled(false); // This is never enabled since it is for optical feed-back only for (std::vector::const_iterator i = originals.begin(); i != originals.end(); i++) { - if ((*i) != NULL) { // find the first valid original - ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); - break; - } + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1((*i)->getNameInDocument())); } // --------------------- } @@ -145,11 +150,30 @@ TaskMultiTransformParameters::TaskMultiTransformParameters(ViewProviderTransform void TaskMultiTransformParameters::onSelectionChanged(const Gui::SelectionChanges& msg) { if (originalSelected(msg)) { - App::DocumentObject* selectedObject = TransformedView->getObject()->getDocument()->getActiveObject(); - ui->lineOriginal->setText(QString::fromLatin1(selectedObject->getNameInDocument())); + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + exitSelectionMode(); } } +void TaskMultiTransformParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + +void TaskMultiTransformParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + void TaskMultiTransformParameters::closeSubTask() { if (subTask) { diff --git a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp.orig new file mode 100644 index 000000000..ba9a802e0 --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.cpp.orig @@ -0,0 +1,512 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +#endif + +#include "ui_TaskMultiTransformParameters.h" +#include "TaskMultiTransformParameters.h" +#include "TaskMirroredParameters.h" +#include "TaskLinearPatternParameters.h" +#include "TaskPolarPatternParameters.h" +#include "TaskScaledParameters.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskMultiTransformParameters */ + +TaskMultiTransformParameters::TaskMultiTransformParameters(ViewProviderTransformed *TransformedView,QWidget *parent) + : TaskTransformedParameters(TransformedView, parent), subTask(NULL) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskMultiTransformParameters(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + this->groupLayout()->addWidget(proxy); + + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + + // Create a context menu for the listview of transformation features + action = new QAction(tr("Edit"), ui->listTransformFeatures); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onTransformEdit())); + ui->listTransformFeatures->addAction(action); + action = new QAction(tr("Delete"), ui->listTransformFeatures); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onTransformDelete())); + ui->listTransformFeatures->addAction(action); + action = new QAction(tr("Add mirrored transformation"), ui->listTransformFeatures); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onTransformAddMirrored())); + ui->listTransformFeatures->addAction(action); + action = new QAction(tr("Add linear pattern"), ui->listTransformFeatures); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onTransformAddLinearPattern())); + ui->listTransformFeatures->addAction(action); + action = new QAction(tr("Add polar pattern"), ui->listTransformFeatures); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onTransformAddPolarPattern())); + ui->listTransformFeatures->addAction(action); + action = new QAction(tr("Add scaled transformation"), ui->listTransformFeatures); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onTransformAddScaled())); + ui->listTransformFeatures->addAction(action); + action = new QAction(tr("Move up"), ui->listTransformFeatures); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onMoveUp())); + ui->listTransformFeatures->addAction(action); + action = new QAction(tr("Move down"), ui->listTransformFeatures); + action->connect(action, SIGNAL(triggered()), + this, SLOT(onMoveDown())); + ui->listTransformFeatures->addAction(action); + ui->listTransformFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), + this, SLOT(onUpdateView(bool))); + + connect(ui->listTransformFeatures, SIGNAL(activated(QModelIndex)), + this, SLOT(onTransformActivated(QModelIndex))); + + // Get the transformFeatures data + PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); + std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); + + // Fill data into dialog elements + ui->listTransformFeatures->setEnabled(true); + ui->listTransformFeatures->clear(); + for (std::vector::const_iterator i = transformFeatures.begin(); i != transformFeatures.end(); i++) + { + if ((*i) != NULL) + ui->listTransformFeatures->addItem(QString::fromLatin1((*i)->Label.getValue())); + } + if (transformFeatures.size() > 0) { + ui->listTransformFeatures->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); + editHint = false; + } else { + ui->listTransformFeatures->addItem(tr("Right-click to add")); + editHint = true; + } + + // Get the Originals data + std::vector originals = pcMultiTransform->Originals.getValues(); + + // Fill data into dialog elements + for (std::vector::const_iterator i = originals.begin(); i != originals.end(); i++) + { +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 + if ((*i) != NULL) { // find the first valid original + ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); + break; + } +======= + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii((*i)->getNameInDocument())); +>>>>>>> Enable multiple originals for the transformed features + } + // --------------------- +} + +void TaskMultiTransformParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (originalSelected(msg)) { +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 + App::DocumentObject* selectedObject = TransformedView->getObject()->getDocument()->getActiveObject(); + ui->lineOriginal->setText(QString::fromLatin1(selectedObject->getNameInDocument())); +======= + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + exitSelectionMode(); +>>>>>>> Enable multiple originals for the transformed features + } +} + +void TaskMultiTransformParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + +void TaskMultiTransformParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + +void TaskMultiTransformParameters::closeSubTask() +{ + if (subTask) { + exitSelectionMode(); + disconnect(ui->checkBoxUpdateView, 0, subTask, 0); + delete subTask; + subTask = NULL; + } +} + +void TaskMultiTransformParameters::onTransformDelete() +{ + if (editHint) return; // Can't delete the hint... + int row = ui->listTransformFeatures->currentIndex().row(); + PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); + std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); + + App::DocumentObject* feature = transformFeatures[row]; + pcMultiTransform->getDocument()->remObject(feature->getNameInDocument()); + closeSubTask(); + + transformFeatures.erase(transformFeatures.begin() + row); + pcMultiTransform->Transformations.setValues(transformFeatures); + // Note: When the last transformation is deleted, recomputeFeature does nothing, because Transformed::execute() + // says: "No transformations defined, exit silently" + recomputeFeature(); + + ui->listTransformFeatures->model()->removeRow(row); + ui->listTransformFeatures->setCurrentRow(0, QItemSelectionModel::ClearAndSelect); +} + +void TaskMultiTransformParameters::onTransformEdit() +{ + if (editHint) return; // Can't edit the hint... + closeSubTask(); // For example if user is editing one subTask and then double-clicks on another without OK'ing first + ui->listTransformFeatures->currentItem()->setSelected(true); + int row = ui->listTransformFeatures->currentIndex().row(); + PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); + std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); + + subFeature = static_cast(transformFeatures[row]); + if (transformFeatures[row]->getTypeId() == PartDesign::Mirrored::getClassTypeId()) + subTask = new TaskMirroredParameters(this, ui->verticalLayout); + else if (transformFeatures[row]->getTypeId() == PartDesign::LinearPattern::getClassTypeId()) + subTask = new TaskLinearPatternParameters(this, ui->verticalLayout); + else if (transformFeatures[row]->getTypeId() == PartDesign::PolarPattern::getClassTypeId()) + subTask = new TaskPolarPatternParameters(this, ui->verticalLayout); + else if (transformFeatures[row]->getTypeId() == PartDesign::Scaled::getClassTypeId()) + subTask = new TaskScaledParameters(this, ui->verticalLayout); + else + return; // TODO: Show an error? + + connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), + subTask, SLOT(onUpdateView(bool))); +} + +void TaskMultiTransformParameters::onTransformActivated(const QModelIndex& index) { + onTransformEdit(); +} + +void TaskMultiTransformParameters::onTransformAddMirrored() +{ + closeSubTask(); + std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("Mirrored"); + + Gui::Command::openCommand("Mirrored"); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::Mirrored\",\"%s\")",newFeatName.c_str()); + //Gui::Command::updateActive(); + App::DocumentObject* sketch = getSketchObject(); + if (sketch) + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.MirrorPlane = (App.activeDocument().%s, [\"V_Axis\"])", + newFeatName.c_str(), sketch->getNameInDocument()); + + finishAdd(newFeatName); +} + +void TaskMultiTransformParameters::onTransformAddLinearPattern() +{ + closeSubTask(); + std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("LinearPattern"); + + Gui::Command::openCommand("LinearPattern"); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::LinearPattern\",\"%s\")",newFeatName.c_str()); + //Gui::Command::updateActive(); + App::DocumentObject* sketch = getSketchObject(); + if (sketch) + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Direction = (App.activeDocument().%s, [\"H_Axis\"])", + newFeatName.c_str(), sketch->getNameInDocument()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Length = 100", newFeatName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str()); + + finishAdd(newFeatName); +} + +void TaskMultiTransformParameters::onTransformAddPolarPattern() +{ + closeSubTask(); + std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("PolarPattern"); + + Gui::Command::openCommand("PolarPattern"); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::PolarPattern\",\"%s\")",newFeatName.c_str()); + //Gui::Command::updateActive(); + App::DocumentObject* sketch = getSketchObject(); + if (sketch) + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Axis = (App.activeDocument().%s, [\"N_Axis\"])", + newFeatName.c_str(), sketch->getNameInDocument()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Angle = 360", newFeatName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str()); + + finishAdd(newFeatName); +} + +void TaskMultiTransformParameters::onTransformAddScaled() +{ + closeSubTask(); + std::string newFeatName = TransformedView->getObject()->getDocument()->getUniqueObjectName("Scaled"); + + Gui::Command::openCommand("Scaled"); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().addObject(\"PartDesign::Scaled\",\"%s\")",newFeatName.c_str()); + //Gui::Command::updateActive(); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Factor = 2", newFeatName.c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.activeDocument().%s.Occurrences = 2", newFeatName.c_str()); + + finishAdd(newFeatName); +} + +void TaskMultiTransformParameters::finishAdd(std::string &newFeatName) +{ + //Gui::Command::updateActive(); + //Gui::Command::copyVisual(newFeatName.c_str(), "ShapeColor", getOriginals().front()->getNameInDocument().c_str()); + //Gui::Command::copyVisual(newFeatName.c_str(), "DisplayMode", getOriginals().front()->getNameInDocument().c_str()); + + PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); + if (editHint) { + // Remove hint, first feature is being added + ui->listTransformFeatures->model()->removeRow(0); + } + int row = ui->listTransformFeatures->currentIndex().row(); + if (row < 0) { + // Happens when first row (first transformation) is created + // Hide all the originals now (hiding them in Command.cpp presents the user with an empty screen!) + hideBase(); + } + + // Insert new transformation after the selected row + // This means that in order to insert at the beginning, the user has to use "Move Up" in the menu + App::DocumentObject* newFeature = pcMultiTransform->getDocument()->getObject(newFeatName.c_str()); + std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); + if (row == ui->listTransformFeatures->model()->rowCount() - 1) { + // Note: Inserts always happen before the specified iterator so in order to append at the + // end we need to use push_back() and append() + transformFeatures.push_back(newFeature); + ui->listTransformFeatures->addItem(QString::fromLatin1(newFeature->Label.getValue())); + ui->listTransformFeatures->setCurrentRow(row+1, QItemSelectionModel::ClearAndSelect); + } else { + // Note: The feature tree always seems to append to the end, no matter what we say here + transformFeatures.insert(transformFeatures.begin() + row + 1, newFeature); + ui->listTransformFeatures->insertItem(row + 1, QString::fromLatin1(newFeature->Label.getValue())); + ui->listTransformFeatures->setCurrentRow(row + 1, QItemSelectionModel::ClearAndSelect); + } + pcMultiTransform->Transformations.setValues(transformFeatures); + + recomputeFeature(); + + // Set state to hidden - only the MultiTransform should be visible + Gui::Command::doCommand( + Gui::Command::Doc,"Gui.activeDocument().getObject(\"%s\").Visibility=False", newFeatName.c_str()); + editHint = false; + + onTransformEdit(); +} + +void TaskMultiTransformParameters::moveTransformFeature(const int increment) +{ + int row = ui->listTransformFeatures->currentIndex().row(); + PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); + std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); + + App::DocumentObject* feature = transformFeatures[row]; + transformFeatures.erase(transformFeatures.begin() + row); + QListWidgetItem* item = new QListWidgetItem(*(ui->listTransformFeatures->item(row))); + ui->listTransformFeatures->model()->removeRow(row); + // After this operation, if we were to insert at index row again, things will remain unchanged + + row += increment; + + if (row < 0) + row = 0; + + if (row >= ui->listTransformFeatures->model()->rowCount()) { + // Note: Inserts always happen before the specified iterator so in order to append at the + // end we need to use push_back() and append() + transformFeatures.push_back(feature); + ui->listTransformFeatures->addItem(item); + ui->listTransformFeatures->setCurrentRow(row, QItemSelectionModel::ClearAndSelect); + } else { + transformFeatures.insert(transformFeatures.begin() + row, feature); + ui->listTransformFeatures->insertItem(row, item); + ui->listTransformFeatures->setCurrentRow(row, QItemSelectionModel::ClearAndSelect); + } + + pcMultiTransform->Transformations.setValues(transformFeatures); + recomputeFeature(); +} + +void TaskMultiTransformParameters::onMoveUp() +{ + moveTransformFeature(-1); +} + +void TaskMultiTransformParameters::onMoveDown() +{ + moveTransformFeature(+1); +} + +void TaskMultiTransformParameters::onSubTaskButtonOK() { + closeSubTask(); +} + +void TaskMultiTransformParameters::onUpdateView(bool on) +{ + blockUpdate = !on; + if (on) + recomputeFeature(); +} + +const std::vector TaskMultiTransformParameters::getTransformFeatures(void) const +{ + PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); + return pcMultiTransform->Transformations.getValues(); +} + +void TaskMultiTransformParameters::apply() +{ +} + +TaskMultiTransformParameters::~TaskMultiTransformParameters() +{ + closeSubTask(); + delete ui; + if (proxy) + delete proxy; +} + +void TaskMultiTransformParameters::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgMultiTransformParameters::TaskDlgMultiTransformParameters(ViewProviderMultiTransform *MultiTransformView) + : TaskDlgTransformedParameters(MultiTransformView) +{ + parameter = new TaskMultiTransformParameters(MultiTransformView); + + Content.push_back(parameter); +} +//==== calls from the TaskView =============================================================== + +bool TaskDlgMultiTransformParameters::accept() +{ + std::string name = TransformedView->getObject()->getNameInDocument(); + + try { + //Gui::Command::openCommand("MultiTransform changed"); + // Handle Originals + if (!TaskDlgTransformedParameters::accept()) + return false; + + TaskMultiTransformParameters* mtParameter = static_cast(parameter); + std::vector transformFeatures = mtParameter->getTransformFeatures(); + std::stringstream str; + str << "App.ActiveDocument." << name.c_str() << ".Transformations = ["; + for (std::vector::const_iterator it = transformFeatures.begin(); it != transformFeatures.end(); it++) + { + if ((*it) != NULL) + str << "App.ActiveDocument." << (*it)->getNameInDocument() << ","; + } + str << "]"; + Gui::Command::runCommand(Gui::Command::Doc,str.str().c_str()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (!TransformedView->getObject()->isValid()) + throw Base::Exception(TransformedView->getObject()->getStatusString()); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return true; +} + +bool TaskDlgMultiTransformParameters::reject() +{ + // Get objects before view is invalidated + // For the same reason we can't delegate showing the originals to TaskDlgTransformedParameters::reject() + PartDesign::MultiTransform* pcMultiTransform = static_cast(TransformedView->getObject()); + std::vector transformFeatures = pcMultiTransform->Transformations.getValues(); + + // Delete the transformation features - must happen before abortCommand()! + for (std::vector::const_iterator it = transformFeatures.begin(); it != transformFeatures.end(); ++it) + { + if ((*it) != NULL) + Gui::Command::doCommand( + Gui::Command::Doc,"App.ActiveDocument.removeObject(\"%s\")", (*it)->getNameInDocument()); + } + + // roll back the done things + Gui::Command::abortCommand(); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + + return TaskDlgTransformedParameters::reject(); +} + +#include "moc_TaskMultiTransformParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.h b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.h index 4b1317658..e9a256498 100644 --- a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.h +++ b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.h @@ -80,10 +80,12 @@ private Q_SLOTS: // Note: There is no Cancel button because I couldn't work out how to save the state of // a subFeature so as to revert the changes of an edit operation virtual void onUpdateView(bool); + virtual void onFeatureDeleted(void); protected: virtual void changeEvent(QEvent *e); virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + virtual void clearButtons(); private: void updateUI(); diff --git a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.ui b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.ui index ad44059e6..026986173 100644 --- a/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskMultiTransformParameters.ui @@ -6,8 +6,8 @@ 0 0 - 225 - 182 + 256 + 266 @@ -15,21 +15,34 @@ - + - + - Original feature + Add feature + + + true - + + + Remove feature + + + true + + - + + + + Transformations diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp index bb0591a21..16faa793d 100644 --- a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp @@ -67,7 +67,7 @@ TaskPolarPatternParameters::TaskPolarPatternParameters(ViewProviderTransformed * ui->buttonOK->hide(); ui->checkBoxUpdateView->setEnabled(true); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -86,11 +86,12 @@ TaskPolarPatternParameters::TaskPolarPatternParameters(TaskMultiTransformParamet layout->addWidget(proxy); ui->buttonOK->setEnabled(true); - ui->labelOriginal->hide(); - ui->lineOriginal->hide(); + ui->buttonAddFeature->hide(); + ui->buttonRemoveFeature->hide(); + ui->listWidgetFeatures->hide(); ui->checkBoxUpdateView->hide(); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -98,6 +99,14 @@ TaskPolarPatternParameters::TaskPolarPatternParameters(TaskMultiTransformParamet void TaskPolarPatternParameters::setupUI() { + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + updateViewTimer = new QTimer(this); updateViewTimer->setSingleShot(true); updateViewTimer->setInterval(getUpdateViewTimeout()); @@ -120,13 +129,10 @@ void TaskPolarPatternParameters::setupUI() std::vector originals = pcPolarPattern->Originals.getValues(); // Fill data into dialog elements - ui->lineOriginal->setEnabled(false); for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) { - if ((*i) != NULL) { // find the first valid original - ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); - break; - } + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1((*i)->getNameInDocument())); } // --------------------- @@ -169,7 +175,7 @@ void TaskPolarPatternParameters::updateUI() // Error message? } - if (referenceSelectionMode) { + if (selectionMode == reference) { ui->comboAxis->addItem(tr("Select an edge or datum line")); ui->comboAxis->setCurrentIndex(ui->comboAxis->count() - 1); } else @@ -198,12 +204,13 @@ void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& { if (msg.Type == Gui::SelectionChanges::AddSelection) { - if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) - return; - if (originalSelected(msg)) { - ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode) { + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + exitSelectionMode(); + } else if (selectionMode == reference) { // Note: ReferenceSelection has already checked the selection for validity exitSelectionMode(); if (!blockUpdate) { @@ -232,6 +239,12 @@ void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& } } +void TaskPolarPatternParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + void TaskPolarPatternParameters::onCheckReverse(const bool on) { if (blockUpdate) return; @@ -275,7 +288,7 @@ void TaskPolarPatternParameters::onAxisChanged(int num) { // enter reference selection mode hideObject(); showBase(); - referenceSelectionMode = true; + selectionMode = reference; Gui::Selection().clearSelection(); addReferenceSelectionGate(true, false); } @@ -304,6 +317,16 @@ void TaskPolarPatternParameters::onUpdateView(bool on) } } +void TaskPolarPatternParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + void TaskPolarPatternParameters::getAxis(App::DocumentObject*& obj, std::vector& sub) const { obj = getSketchObject(); diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig index 085ed2d81..5ab4878fc 100644 --- a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig +++ b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.cpp.orig @@ -32,6 +32,7 @@ #include "TaskPolarPatternParameters.h" #include "TaskMultiTransformParameters.h" #include "Workbench.h" +#include "ReferenceSelection.h" #include #include #include @@ -66,7 +67,7 @@ TaskPolarPatternParameters::TaskPolarPatternParameters(ViewProviderTransformed * ui->buttonOK->hide(); ui->checkBoxUpdateView->setEnabled(true); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -85,11 +86,12 @@ TaskPolarPatternParameters::TaskPolarPatternParameters(TaskMultiTransformParamet layout->addWidget(proxy); ui->buttonOK->setEnabled(true); - ui->labelOriginal->hide(); - ui->lineOriginal->hide(); + ui->buttonAddFeature->hide(); + ui->buttonRemoveFeature->hide(); + ui->listWidgetFeatures->hide(); ui->checkBoxUpdateView->hide(); - referenceSelectionMode = false; + selectionMode = none; blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! setupUI(); @@ -97,6 +99,14 @@ TaskPolarPatternParameters::TaskPolarPatternParameters(TaskMultiTransformParamet void TaskPolarPatternParameters::setupUI() { + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + updateViewTimer = new QTimer(this); updateViewTimer->setSingleShot(true); updateViewTimer->setInterval(getUpdateViewTimeout()); @@ -119,13 +129,17 @@ void TaskPolarPatternParameters::setupUI() std::vector originals = pcPolarPattern->Originals.getValues(); // Fill data into dialog elements - ui->lineOriginal->setEnabled(false); for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) { +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 if ((*i) != NULL) { // find the first valid original ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); break; } +======= + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii((*i)->getNameInDocument())); +>>>>>>> Enable multiple originals for the transformed features } // --------------------- @@ -160,20 +174,15 @@ void TaskPolarPatternParameters::updateUI() if (axisFeature != NULL && !axes.empty()) { if (axes.front() == "N_Axis") ui->comboAxis->setCurrentIndex(0); -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 - else if (axisFeature != NULL && !axes.empty()) { - ui->comboAxis->addItem(QString::fromLatin1(axes.front().c_str())); -======= else { ui->comboAxis->addItem(getRefStr(axisFeature, axes)); ->>>>>>> Allow datum lines and planes for Transformed features' references ui->comboAxis->setCurrentIndex(1); } } else { // Error message? } - if (referenceSelectionMode) { + if (selectionMode == reference) { ui->comboAxis->addItem(tr("Select an edge or datum line")); ui->comboAxis->setCurrentIndex(ui->comboAxis->count() - 1); } else @@ -202,29 +211,25 @@ void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& { if (msg.Type == Gui::SelectionChanges::AddSelection) { - if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) - return; - if (originalSelected(msg)) { -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 ui->lineOriginal->setText(QString::fromLatin1(msg.pObjectName)); - } else if (referenceSelectionMode && - (subName.size() > 4 && subName.substr(0,4) == "Edge")) { - - if (strcmp(msg.pObjectName, getSupportObject()->getNameInDocument()) != 0) - return; - -======= - ui->lineOriginal->setText(QString::fromAscii(msg.pObjectName)); } else if (referenceSelectionMode) { +======= + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + exitSelectionMode(); + } else if (selectionMode == reference) { +>>>>>>> Enable multiple originals for the transformed features // Note: ReferenceSelection has already checked the selection for validity ->>>>>>> Allow datum lines and planes for Transformed features' references exitSelectionMode(); if (!blockUpdate) { std::vector axes; App::DocumentObject* selObj; - getReferencedSelection(msg, selObj, axes); PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + getReferencedSelection(pcPolarPattern, msg, selObj, axes); pcPolarPattern->Axis.setValue(selObj, axes); recomputeFeature(); @@ -234,14 +239,11 @@ void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& for (int i=ui->comboAxis->count()-1; i >= 1; i--) ui->comboAxis->removeItem(i); -<<<<<<< 9c07d220e78d49c084d7ec2cec90f1df0572e044 - ui->comboAxis->addItem(QString::fromLatin1(subName.c_str())); -======= std::vector axes; App::DocumentObject* selObj; - getReferencedSelection(msg, selObj, axes); + PartDesign::PolarPattern* pcPolarPattern = static_cast(getObject()); + getReferencedSelection(pcPolarPattern, msg, selObj, axes); ui->comboAxis->addItem(getRefStr(selObj, axes)); ->>>>>>> Allow datum lines and planes for Transformed features' references ui->comboAxis->setCurrentIndex(1); ui->comboAxis->addItem(tr("Select reference...")); } @@ -249,6 +251,12 @@ void TaskPolarPatternParameters::onSelectionChanged(const Gui::SelectionChanges& } } +void TaskPolarPatternParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + void TaskPolarPatternParameters::onCheckReverse(const bool on) { if (blockUpdate) return; @@ -291,8 +299,8 @@ void TaskPolarPatternParameters::onAxisChanged(int num) { else if (num == ui->comboAxis->count() - 1) { // enter reference selection mode hideObject(); - showOriginals(); - referenceSelectionMode = true; + showBase(); + selectionMode = reference; Gui::Selection().clearSelection(); addReferenceSelectionGate(true, false); } @@ -321,6 +329,16 @@ void TaskPolarPatternParameters::onUpdateView(bool on) } } +void TaskPolarPatternParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + void TaskPolarPatternParameters::getAxis(App::DocumentObject*& obj, std::vector& sub) const { obj = getSketchObject(); diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.h b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.h index 531105cbb..90a5ca16d 100644 --- a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.h +++ b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.h @@ -65,10 +65,12 @@ private Q_SLOTS: void onAngle(const double a); void onOccurrences(const uint n); virtual void onUpdateView(bool); + virtual void onFeatureDeleted(void); protected: virtual void changeEvent(QEvent *e); virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + virtual void clearButtons(); void getAxis(App::DocumentObject*& obj, std::vector& sub) const; const std::string getStdAxis(void) const; //const std::string getAxis(void) const; diff --git a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.ui b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.ui index 8257825db..651ec335f 100644 --- a/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskPolarPatternParameters.ui @@ -6,8 +6,8 @@ 0 0 - 225 - 400 + 253 + 333 @@ -15,19 +15,32 @@ - + - + - Original feature + Add feature + + + true - + + + Remove feature + + + true + + + + + diff --git a/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp b/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp index ec2a58658..fd5995794 100644 --- a/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp @@ -80,8 +80,9 @@ TaskScaledParameters::TaskScaledParameters(TaskMultiTransformParameters *parentT layout->addWidget(proxy); ui->buttonOK->setEnabled(true); - ui->labelOriginal->hide(); - ui->lineOriginal->hide(); + ui->buttonAddFeature->hide(); + ui->buttonRemoveFeature->hide(); + ui->listWidgetFeatures->hide(); ui->checkBoxUpdateView->hide(); blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! @@ -90,6 +91,14 @@ TaskScaledParameters::TaskScaledParameters(TaskMultiTransformParameters *parentT void TaskScaledParameters::setupUI() { + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + connect(ui->spinFactor, SIGNAL(valueChanged(double)), this, SLOT(onFactor(double))); connect(ui->spinOccurrences, SIGNAL(valueChanged(uint)), @@ -102,13 +111,10 @@ void TaskScaledParameters::setupUI() std::vector originals = pcScaled->Originals.getValues(); // Fill data into dialog elements - ui->lineOriginal->setEnabled(false); for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) { - if ((*i) != NULL) { // find the first valid original - ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); - break; - } + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1((*i)->getNameInDocument())); } // --------------------- @@ -142,11 +148,20 @@ void TaskScaledParameters::updateUI() void TaskScaledParameters::onSelectionChanged(const Gui::SelectionChanges& msg) { if (originalSelected(msg)) { - App::DocumentObject* selectedObject = TransformedView->getObject()->getDocument()->getActiveObject(); - ui->lineOriginal->setText(QString::fromLatin1(selectedObject->getNameInDocument())); + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromLatin1(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + exitSelectionMode(); } } +void TaskScaledParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + void TaskScaledParameters::onFactor(const double f) { if (blockUpdate) @@ -177,6 +192,16 @@ void TaskScaledParameters::onUpdateView(bool on) } } +void TaskScaledParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + const double TaskScaledParameters::getFactor(void) const { return ui->spinFactor->value().getValue(); diff --git a/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp.orig b/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp.orig new file mode 100644 index 000000000..5729ca98d --- /dev/null +++ b/src/Mod/PartDesign/Gui/TaskScaledParameters.cpp.orig @@ -0,0 +1,287 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +#endif + +#include "ui_TaskScaledParameters.h" +#include "TaskScaledParameters.h" +#include "TaskMultiTransformParameters.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace PartDesignGui; +using namespace Gui; + +/* TRANSLATOR PartDesignGui::TaskScaledParameters */ + +TaskScaledParameters::TaskScaledParameters(ViewProviderTransformed *TransformedView,QWidget *parent) + : TaskTransformedParameters(TransformedView, parent) +{ + // we need a separate container widget to add all controls to + proxy = new QWidget(this); + ui = new Ui_TaskScaledParameters(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + this->groupLayout()->addWidget(proxy); + + ui->buttonOK->hide(); + ui->checkBoxUpdateView->setEnabled(true); + + blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! + setupUI(); +} + +TaskScaledParameters::TaskScaledParameters(TaskMultiTransformParameters *parentTask, QLayout *layout) + : TaskTransformedParameters(parentTask) +{ + proxy = new QWidget(parentTask); + ui = new Ui_TaskScaledParameters(); + ui->setupUi(proxy); + connect(ui->buttonOK, SIGNAL(pressed()), + parentTask, SLOT(onSubTaskButtonOK())); + QMetaObject::connectSlotsByName(this); + + layout->addWidget(proxy); + + ui->buttonOK->setEnabled(true); + ui->buttonAddFeature->hide(); + ui->buttonRemoveFeature->hide(); + ui->listWidgetFeatures->hide(); + ui->checkBoxUpdateView->hide(); + + blockUpdate = false; // Hack, sometimes it is NOT false although set to false in Transformed::Transformed()!! + setupUI(); +} + +void TaskScaledParameters::setupUI() +{ + connect(ui->buttonAddFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonAddFeature(bool))); + connect(ui->buttonRemoveFeature, SIGNAL(toggled(bool)), this, SLOT(onButtonRemoveFeature(bool))); + // Create context menu + QAction* action = new QAction(tr("Remove"), this); + ui->listWidgetFeatures->addAction(action); + connect(action, SIGNAL(triggered()), this, SLOT(onFeatureDeleted())); + ui->listWidgetFeatures->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->spinFactor, SIGNAL(valueChanged(double)), + this, SLOT(onFactor(double))); + connect(ui->spinOccurrences, SIGNAL(valueChanged(uint)), + this, SLOT(onOccurrences(uint))); + connect(ui->checkBoxUpdateView, SIGNAL(toggled(bool)), + this, SLOT(onUpdateView(bool))); + + // Get the feature data + PartDesign::Scaled* pcScaled = static_cast(getObject()); + std::vector originals = pcScaled->Originals.getValues(); + + // Fill data into dialog elements + for (std::vector::const_iterator i = originals.begin(); i != originals.end(); ++i) + { +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 + if ((*i) != NULL) { // find the first valid original + ui->lineOriginal->setText(QString::fromLatin1((*i)->getNameInDocument())); + break; + } +======= + if ((*i) != NULL) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii((*i)->getNameInDocument())); +>>>>>>> Enable multiple originals for the transformed features + } + // --------------------- + + ui->spinFactor->bind(pcScaled->Factor); + ui->spinOccurrences->setMaximum(INT_MAX); + ui->spinOccurrences->bind(pcScaled->Occurrences); + ui->spinFactor->setEnabled(true); + ui->spinOccurrences->setEnabled(true); + //ui->spinFactor->setDecimals(Base::UnitsApi::getDecimals()); + + updateUI(); +} + +void TaskScaledParameters::updateUI() +{ + if (blockUpdate) + return; + blockUpdate = true; + + PartDesign::Scaled* pcScaled = static_cast(getObject()); + + double factor = pcScaled->Factor.getValue(); + unsigned occurrences = pcScaled->Occurrences.getValue(); + + ui->spinFactor->setValue(factor); + ui->spinOccurrences->setValue(occurrences); + + blockUpdate = false; +} + +void TaskScaledParameters::onSelectionChanged(const Gui::SelectionChanges& msg) +{ + if (originalSelected(msg)) { +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 + App::DocumentObject* selectedObject = TransformedView->getObject()->getDocument()->getActiveObject(); + ui->lineOriginal->setText(QString::fromLatin1(selectedObject->getNameInDocument())); +======= + if (selectionMode == addFeature) + ui->listWidgetFeatures->insertItem(0, QString::fromAscii(msg.pObjectName)); + else + removeItemFromListWidget(ui->listWidgetFeatures, msg.pObjectName); + exitSelectionMode(); +>>>>>>> Enable multiple originals for the transformed features + } +} + +void TaskScaledParameters::clearButtons() +{ + ui->buttonAddFeature->setChecked(false); + ui->buttonRemoveFeature->setChecked(false); +} + +void TaskScaledParameters::onFactor(const double f) +{ + if (blockUpdate) + return; + PartDesign::Scaled* pcScaled = static_cast(getObject()); + pcScaled->Factor.setValue(f); + recomputeFeature(); +} + +void TaskScaledParameters::onOccurrences(const uint n) +{ + if (blockUpdate) + return; + PartDesign::Scaled* pcScaled = static_cast(getObject()); + pcScaled->Occurrences.setValue(n); + recomputeFeature(); +} + +void TaskScaledParameters::onUpdateView(bool on) +{ + blockUpdate = !on; + if (on) { + // Do the same like in TaskDlgScaledParameters::accept() but without doCommand + PartDesign::Scaled* pcScaled = static_cast(getObject()); + pcScaled->Factor.setValue(getFactor()); + pcScaled->Occurrences.setValue(getOccurrences()); + recomputeFeature(); + } +} + +void TaskScaledParameters::onFeatureDeleted(void) +{ + PartDesign::Transformed* pcTransformed = getObject(); + std::vector originals = pcTransformed->Originals.getValues(); + originals.erase(originals.begin() + ui->listWidgetFeatures->currentRow()); + pcTransformed->Originals.setValues(originals); + ui->listWidgetFeatures->model()->removeRow(ui->listWidgetFeatures->currentRow()); + recomputeFeature(); +} + +const double TaskScaledParameters::getFactor(void) const +{ + return ui->spinFactor->value().getValue(); +} + +const unsigned TaskScaledParameters::getOccurrences(void) const +{ + return ui->spinOccurrences->value(); +} + +TaskScaledParameters::~TaskScaledParameters() +{ + delete ui; + if (proxy) + delete proxy; +} + +void TaskScaledParameters::changeEvent(QEvent *e) +{ + TaskBox::changeEvent(e); + if (e->type() == QEvent::LanguageChange) { + ui->retranslateUi(proxy); + } +} + +void TaskScaledParameters::apply() +{ + std::string name = TransformedView->getObject()->getNameInDocument(); + + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Factor = %f",name.c_str(), getFactor()); + ui->spinOccurrences->apply(); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.recompute()"); + if (!TransformedView->getObject()->isValid()) + throw Base::Exception(TransformedView->getObject()->getStatusString()); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::commitCommand(); +} + +//************************************************************************** +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgScaledParameters::TaskDlgScaledParameters(ViewProviderScaled *ScaledView) + : TaskDlgTransformedParameters(ScaledView) +{ + parameter = new TaskScaledParameters(ScaledView); + + Content.push_back(parameter); +} +//==== calls from the TaskView =============================================================== + +bool TaskDlgScaledParameters::accept() +{ + try { + //Gui::Command::openCommand("Scaled changed"); + // Handle Originals + if (!TaskDlgTransformedParameters::accept()) + return false; + + parameter->apply(); + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } + + return true; +} + +#include "moc_TaskScaledParameters.cpp" diff --git a/src/Mod/PartDesign/Gui/TaskScaledParameters.h b/src/Mod/PartDesign/Gui/TaskScaledParameters.h index f591fde90..df8e763a1 100644 --- a/src/Mod/PartDesign/Gui/TaskScaledParameters.h +++ b/src/Mod/PartDesign/Gui/TaskScaledParameters.h @@ -62,10 +62,12 @@ private Q_SLOTS: void onFactor(const double f); void onOccurrences(const uint n); virtual void onUpdateView(bool); + virtual void onFeatureDeleted(void); protected: virtual void changeEvent(QEvent *e); virtual void onSelectionChanged(const Gui::SelectionChanges& msg); + virtual void clearButtons(); const double getFactor(void) const; const unsigned getOccurrences(void) const; diff --git a/src/Mod/PartDesign/Gui/TaskScaledParameters.ui b/src/Mod/PartDesign/Gui/TaskScaledParameters.ui index e8182a7b6..14c622c34 100644 --- a/src/Mod/PartDesign/Gui/TaskScaledParameters.ui +++ b/src/Mod/PartDesign/Gui/TaskScaledParameters.ui @@ -6,8 +6,8 @@ 0 0 - 225 - 305 + 253 + 270 @@ -15,19 +15,32 @@ - + - + - Original feature + Add feature + + + true - + + + Remove feature + + + true + + + + + diff --git a/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp b/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp index 3cd7331bd..803266391 100644 --- a/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp +++ b/src/Mod/PartDesign/Gui/TaskTransformedParameters.cpp @@ -24,6 +24,7 @@ #ifndef _PreComp_ # include +# include # include # include # include @@ -64,7 +65,7 @@ TaskTransformedParameters::TaskTransformedParameters(ViewProviderTransformed *Tr insideMultiTransform(false), blockUpdate(false) { - originalSelectionMode = false; + selectionMode = none; } TaskTransformedParameters::TaskTransformedParameters(TaskMultiTransformParameters *parentTask) @@ -75,7 +76,7 @@ TaskTransformedParameters::TaskTransformedParameters(TaskMultiTransformParameter blockUpdate(false) { // Original feature selection makes no sense inside a MultiTransform - originalSelectionMode = false; + selectionMode = none; } TaskTransformedParameters::~TaskTransformedParameters() @@ -96,9 +97,10 @@ int TaskTransformedParameters::getUpdateViewTimeout() const const bool TaskTransformedParameters::originalSelected(const Gui::SelectionChanges& msg) { - if (msg.Type == Gui::SelectionChanges::AddSelection && originalSelectionMode) { + if (msg.Type == Gui::SelectionChanges::AddSelection && ( + (selectionMode == addFeature) || (selectionMode == removeFeature))) { - if ((msg.pDocName, getObject()->getDocument()->getName()) != 0) + if (strcmp(msg.pDocName, getObject()->getDocument()->getName()) != 0) return false; PartDesign::Transformed* pcTransformed = getObject(); @@ -107,11 +109,22 @@ const bool TaskTransformedParameters::originalSelected(const Gui::SelectionChang selectedObject->isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) { // Do the same like in TaskDlgTransformedParameters::accept() but without doCommand - std::vector originals(1,selectedObject); + std::vector originals = pcTransformed->Originals.getValues(); + std::vector::iterator o = std::find(originals.begin(), originals.end(), selectedObject); + if (selectionMode == addFeature) { + if (o == originals.end()) + originals.push_back(selectedObject); + else + return false; // duplicate selection + } else { + if (o != originals.end()) + originals.erase(o); + else + return false; + } pcTransformed->Originals.setValues(originals); recomputeFeature(); - originalSelectionMode = false; return true; } } @@ -119,6 +132,41 @@ const bool TaskTransformedParameters::originalSelected(const Gui::SelectionChang return false; } +void TaskTransformedParameters::onButtonAddFeature(bool checked) +{ + if (checked) { + hideObject(); + showBase(); + selectionMode = addFeature; + Gui::Selection().clearSelection(); + } else { + exitSelectionMode(); + } +} + +void TaskTransformedParameters::onButtonRemoveFeature(bool checked) +{ + if (checked) { + hideObject(); + showBase(); + selectionMode = removeFeature; + Gui::Selection().clearSelection(); + } else { + exitSelectionMode(); + } +} + +void TaskTransformedParameters::removeItemFromListWidget(QListWidget* widget, const char* itemstr) +{ + QList items = widget->findItems(QString::fromAscii(itemstr), Qt::MatchExactly); + if (!items.empty()) { + for (QList::const_iterator i = items.begin(); i != items.end(); i++) { + QListWidgetItem* it = widget->takeItem(widget->row(*i)); + delete it; + } + } +} + PartDesign::Transformed *TaskTransformedParameters::getObject() const { @@ -228,8 +276,8 @@ void TaskTransformedParameters::showBase() void TaskTransformedParameters::exitSelectionMode() { - originalSelectionMode = false; - referenceSelectionMode = false; + clearButtons(); + selectionMode = none; Gui::Selection().rmvSelectionGate(); showObject(); hideBase(); diff --git a/src/Mod/PartDesign/Gui/TaskTransformedParameters.h b/src/Mod/PartDesign/Gui/TaskTransformedParameters.h index cbb9d93b6..e4170064f 100644 --- a/src/Mod/PartDesign/Gui/TaskTransformedParameters.h +++ b/src/Mod/PartDesign/Gui/TaskTransformedParameters.h @@ -31,6 +31,8 @@ #include "TaskTransformedMessages.h" #include "ViewProviderTransformed.h" +class QListWidget; + namespace PartDesign { class Transformed; } @@ -71,6 +73,9 @@ public: protected Q_SLOTS: /// Connect the subTask OK button to the MultiTransform task virtual void onSubTaskButtonOK() {} + void onButtonAddFeature(const bool checked); + void onButtonRemoveFeature(const bool checked); + virtual void onFeatureDeleted(void)=0; protected: const bool originalSelected(const Gui::SelectionChanges& msg); @@ -94,13 +99,15 @@ protected: protected: virtual void changeEvent(QEvent *e) = 0; virtual void onSelectionChanged(const Gui::SelectionChanges& msg) = 0; + virtual void clearButtons()=0; + static void removeItemFromListWidget(QListWidget* widget, const char* itemstr); protected: QWidget* proxy; ViewProviderTransformed *TransformedView; - bool originalSelectionMode; - bool referenceSelectionMode; + enum selectionModes { none, addFeature, removeFeature, reference }; + selectionModes selectionMode; /// The MultiTransform parent task of this task TaskMultiTransformParameters* parentTask; diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp index 249b22972..b7228e827 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp @@ -77,18 +77,6 @@ bool ViewProviderTransformed::setEdit(int ModNum) pcRejectedRoot = new SoSeparator(); pcRejectedRoot->ref(); - rejectedTrfms = new SoMultipleCopy(); - rejectedTrfms->ref(); - - rejectedCoords = new SoCoordinate3(); - rejectedCoords->ref(); - - rejectedNorms = new SoNormal(); - rejectedNorms->ref(); - - rejectedFaceSet = new SoIndexedFaceSet(); - rejectedFaceSet->ref(); - SoPickStyle* rejectedPickStyle = new SoPickStyle(); rejectedPickStyle->style = SoPickStyle::UNPICKABLE; @@ -118,12 +106,7 @@ bool ViewProviderTransformed::setEdit(int ModNum) pcRejectedRoot->addChild(rejectedMaterial); pcRejectedRoot->addChild(rejectedHints); pcRejectedRoot->addChild(rejectedFaceStyle); - pcRejectedRoot->addChild(rejectedCoords); - pcRejectedRoot->addChild(rejectedNorms); - pcRejectedRoot->addChild(rejectedNormb); - pcRejectedRoot->addChild(rejectedTrfms); - rejectedTrfms->addChild(rejectedFaceSet); - + pcRejectedRoot->addChild(rejectedNormb); // NOTE: The code relies on the last child added here being index 6 pcRoot->addChild(pcRejectedRoot); recomputeFeature(); @@ -151,16 +134,19 @@ void ViewProviderTransformed::unsetEdit(int ModNum) PartGui::ViewProviderPart::unsetEdit(ModNum); } - rejectedTrfms->removeAllChildren(); + while (pcRejectedRoot->getNumChildren() > 7) { + SoSeparator* sep = static_cast(pcRejectedRoot->getChild(7)); + SoMultipleCopy* rejectedTrfms = static_cast(sep->getChild(2)); + rejectedTrfms ->removeAllChildren(); + sep->removeChild(1); + sep->removeChild(0); + pcRejectedRoot ->removeChild(7); + } pcRejectedRoot->removeAllChildren(); pcRoot->removeChild(pcRejectedRoot); pcRejectedRoot->unref(); - rejectedTrfms->unref(); - rejectedCoords->unref(); - rejectedNorms->unref(); - rejectedFaceSet->unref(); } bool ViewProviderTransformed::onDelete(const std::vector &s) @@ -203,8 +189,11 @@ void ViewProviderTransformed::recomputeFeature(void) PartDesign::Transformed* pcTransformed = static_cast(getObject()); pcTransformed->getDocument()->recomputeFeature(pcTransformed); const std::vector log = pcTransformed->getDocument()->getRecomputeLog(); - unsigned rejected = pcTransformed->getRejectedTransformations().size(); - QString msg = QString::fromLatin1("%1"); + PartDesign::Transformed::rejectedMap rejected_trsf = pcTransformed->getRejectedTransformations(); + unsigned rejected = 0; + for (PartDesign::Transformed::rejectedMap::const_iterator r = rejected_trsf.begin(); r != rejected_trsf.end(); r++) + rejected += r->second.size(); + QString msg = QString::fromAscii("%1"); if (rejected > 0) { msg = QString::fromLatin1("%1
\r\n%2"); if (rejected == 1) @@ -223,25 +212,30 @@ void ViewProviderTransformed::recomputeFeature(void) } signalDiagnosis(msg); - TopoDS_Shape shape; - if (rejected != 0) { - // FIXME: create a compound if there are more than one originals - App::DocumentObject* original = pcTransformed->Originals.getValues().front(); - if (original->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) { - PartDesign::Additive* addFeature = static_cast(original); - shape = addFeature->AddShape.getShape()._Shape; - } else if (original->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) { - PartDesign::Subtractive* subFeature = static_cast(original); - shape = subFeature->SubShape.getShape()._Shape; - } + // Clear all the rejected stuff + while (pcRejectedRoot->getNumChildren() > 7) { + SoSeparator* sep = static_cast(pcRejectedRoot->getChild(7)); + SoMultipleCopy* rejectedTrfms = static_cast(sep->getChild(2)); + rejectedTrfms ->removeAllChildren(); + sep->removeChild(1); + sep->removeChild(0); + pcRejectedRoot ->removeChild(7); } - if (rejected == 0 || shape.IsNull()) { - rejectedCoords ->point .setNum(0); - rejectedNorms ->vector .setNum(0); - rejectedFaceSet ->coordIndex .setNum(0); - rejectedTrfms ->matrix .setNum(0); - } else { + for (PartDesign::Transformed::rejectedMap::const_iterator o = rejected_trsf.begin(); o != rejected_trsf.end(); o++) { + if (o->second.empty()) continue; + + TopoDS_Shape shape; + if ((o->first)->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) { + PartDesign::Additive* addFeature = static_cast(o->first); + shape = addFeature->AddShape.getShape()._Shape; + } else if ((o->first)->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) { + PartDesign::Subtractive* subFeature = static_cast(o->first); + shape = subFeature->SubShape.getShape()._Shape; + } + + if (shape.IsNull()) continue; + // Display the rejected transformations in red TopoDS_Shape cShape(shape); @@ -257,6 +251,7 @@ void ViewProviderTransformed::recomputeFeature(void) Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue(); // create or use the mesh on the data structure + // Note: This DOES have an effect on cShape #if OCC_VERSION_HEX >= 0x060600 Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI; BRepMesh_IncrementalMesh(cShape,deflection,Standard_False, @@ -282,8 +277,11 @@ void ViewProviderTransformed::recomputeFeature(void) } // create memory for the nodes and indexes + SoCoordinate3* rejectedCoords = new SoCoordinate3(); rejectedCoords ->point .setNum(nbrNodes); + SoNormal* rejectedNorms = new SoNormal(); rejectedNorms ->vector .setNum(nbrNodes); + SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet(); rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4); // get the raw memory for fast fill up @@ -379,17 +377,23 @@ void ViewProviderTransformed::recomputeFeature(void) rejectedFaceSet ->coordIndex .finishEditing(); // fill in the transformation matrices - rejectedTrfms->matrix.setNum(rejected); + SoMultipleCopy* rejectedTrfms = new SoMultipleCopy(); + rejectedTrfms->matrix.setNum((o->second).size()); SbMatrix* mats = rejectedTrfms->matrix.startEditing(); - std::list rejected_trsf = pcTransformed->getRejectedTransformations(); - std::list::const_iterator trsf = rejected_trsf.begin(); - for (unsigned int i=0; i < rejected; i++,trsf++) { + std::list::const_iterator trsf = (o->second).begin(); + for (unsigned int i=0; i < (o->second).size(); i++,trsf++) { Base::Matrix4D mat; Part::TopoShape::convertToMatrix(*trsf,mat); mats[i] = convert(mat); } rejectedTrfms->matrix.finishEditing(); + rejectedTrfms->addChild(rejectedFaceSet); + SoSeparator* sep = new SoSeparator(); + sep->addChild(rejectedCoords); + sep->addChild(rejectedNorms); + sep->addChild(rejectedTrfms); + pcRejectedRoot->addChild(sep); } catch (...) { Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n", diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp.orig b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp.orig new file mode 100644 index 000000000..efe35658d --- /dev/null +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.cpp.orig @@ -0,0 +1,410 @@ +/****************************************************************************** + * Copyright (c)2012 Jan Rheinlaender * + * * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ******************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "Workbench.h" +#include "ViewProviderTransformed.h" +#include "TaskTransformedParameters.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace PartDesignGui; + +PROPERTY_SOURCE(PartDesignGui::ViewProviderTransformed,PartDesignGui::ViewProvider) + +void ViewProviderTransformed::setupContextMenu(QMenu* menu, QObject* receiver, const char* member) +{ + QAction* act; + act = menu->addAction(QObject::tr((std::string("Edit ") + featureName + " feature").c_str()), receiver, member); + act->setData(QVariant((int)ViewProvider::Default)); + PartGui::ViewProviderPart::setupContextMenu(menu, receiver, member); +} + +bool ViewProviderTransformed::setEdit(int ModNum) +{ + pcRejectedRoot = new SoSeparator(); + pcRejectedRoot->ref(); + + SoPickStyle* rejectedPickStyle = new SoPickStyle(); + rejectedPickStyle->style = SoPickStyle::UNPICKABLE; + + SoShapeHints* rejectedHints = new SoShapeHints(); + rejectedHints->vertexOrdering = SoShapeHints::COUNTERCLOCKWISE; + rejectedHints->shapeType = SoShapeHints::UNKNOWN_SHAPE_TYPE; + + SoMaterialBinding* rejectedBind = new SoMaterialBinding(); + + SoTransparencyType* rejectedTransparencyType = new SoTransparencyType(); + rejectedTransparencyType->value.setValue(SoGLRenderAction::BLEND); + + SoMaterial* rejectedMaterial = new SoMaterial(); + rejectedMaterial->diffuseColor.set1Value(0,SbColor(1.f,0.f,0.f)); + rejectedMaterial->transparency.setValue(0.6f); + + SoDrawStyle* rejectedFaceStyle = new SoDrawStyle(); + rejectedFaceStyle->style = SoDrawStyle::FILLED; + + SoNormalBinding* rejectedNormb = new SoNormalBinding(); + rejectedNormb->value = SoNormalBinding::PER_VERTEX_INDEXED; + + // just faces with no edges or points + pcRejectedRoot->addChild(rejectedPickStyle); + pcRejectedRoot->addChild(rejectedTransparencyType); + pcRejectedRoot->addChild(rejectedBind); + pcRejectedRoot->addChild(rejectedMaterial); + pcRejectedRoot->addChild(rejectedHints); + pcRejectedRoot->addChild(rejectedFaceStyle); + pcRejectedRoot->addChild(rejectedNormb); // NOTE: The code relies on the last child added here being index 6 + pcRoot->addChild(pcRejectedRoot); + + recomputeFeature(); + return true; +} + +void ViewProviderTransformed::unsetEdit(int ModNum) +{ + // return to the WB we were in before editing the PartDesign feature + Gui::Command::assureWorkbench(oldWb.c_str()); + + if (ModNum == ViewProvider::Default) { + // when pressing ESC make sure to close the dialog + Gui::Control().closeDialog(); + if ((PartDesignGui::ActivePartObject != NULL) && (oldTip != NULL)) { + Gui::Selection().clearSelection(); + Gui::Selection().addSelection(oldTip->getDocument()->getName(), oldTip->getNameInDocument()); + Gui::Command::doCommand(Gui::Command::Gui,"FreeCADGui.runCommand('PartDesign_MoveTip')"); + oldTip = NULL; + } else { + oldTip = NULL; + } + } + else { + PartGui::ViewProviderPart::unsetEdit(ModNum); + } + + while (pcRejectedRoot->getNumChildren() > 7) { + SoSeparator* sep = static_cast(pcRejectedRoot->getChild(7)); + SoMultipleCopy* rejectedTrfms = static_cast(sep->getChild(2)); + rejectedTrfms ->removeAllChildren(); + sep->removeChild(1); + sep->removeChild(0); + pcRejectedRoot ->removeChild(7); + } + pcRejectedRoot->removeAllChildren(); + + pcRoot->removeChild(pcRejectedRoot); + + pcRejectedRoot->unref(); +} + +bool ViewProviderTransformed::onDelete(const std::vector &s) +{ + return ViewProvider::onDelete(s); +} + +const bool ViewProviderTransformed::checkDlgOpen(TaskDlgTransformedParameters* transformedDlg) { + // When double-clicking on the item for this feature the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + transformedDlg = qobject_cast(dlg); + + if ((transformedDlg != NULL) && (transformedDlg->getTransformedView() != this)) + transformedDlg = NULL; // another transformed feature left open its task panel + + if ((dlg != NULL) && (transformedDlg == NULL)) { + QMessageBox msgBox; + msgBox.setText(QObject::tr("A dialog is already open in the task panel")); + msgBox.setInformativeText(QObject::tr("Do you want to close this dialog?")); + msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No); + msgBox.setDefaultButton(QMessageBox::Yes); + int ret = msgBox.exec(); + if (ret == QMessageBox::Yes) + Gui::Control().reject(); + else + return false; + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // Continue (usually in virtual method setEdit()) + return true; +} + +void ViewProviderTransformed::recomputeFeature(void) +{ + PartDesign::Transformed* pcTransformed = static_cast(getObject()); + pcTransformed->getDocument()->recomputeFeature(pcTransformed); + const std::vector log = pcTransformed->getDocument()->getRecomputeLog(); +<<<<<<< eb9a4ab96f8703de819cdc5e405217b784ccff90 + unsigned rejected = pcTransformed->getRejectedTransformations().size(); + QString msg = QString::fromLatin1("%1"); +======= + PartDesign::Transformed::rejectedMap rejected_trsf = pcTransformed->getRejectedTransformations(); + unsigned rejected = 0; + for (PartDesign::Transformed::rejectedMap::const_iterator r = rejected_trsf.begin(); r != rejected_trsf.end(); r++) + rejected += r->second.size(); + QString msg = QString::fromAscii("%1"); +>>>>>>> Enable multiple originals for the transformed features + if (rejected > 0) { + msg = QString::fromLatin1("%1
\r\n%2"); + if (rejected == 1) + msg = msg.arg(QObject::tr("One transformed shape does not intersect support")); + else { + msg = msg.arg(QObject::tr("%1 transformed shapes do not intersect support")); + msg = msg.arg(rejected); + } + } + if (log.size() > 0) { + msg = msg.arg(QString::fromLatin1("%1
")); + msg = msg.arg(QString::fromStdString(log.back()->Why)); + } else { + msg = msg.arg(QString::fromLatin1("%1
")); + msg = msg.arg(QObject::tr("Transformation succeeded")); + } + signalDiagnosis(msg); + + // Clear all the rejected stuff + while (pcRejectedRoot->getNumChildren() > 7) { + SoSeparator* sep = static_cast(pcRejectedRoot->getChild(7)); + SoMultipleCopy* rejectedTrfms = static_cast(sep->getChild(2)); + rejectedTrfms ->removeAllChildren(); + sep->removeChild(1); + sep->removeChild(0); + pcRejectedRoot ->removeChild(7); + } + + for (PartDesign::Transformed::rejectedMap::const_iterator o = rejected_trsf.begin(); o != rejected_trsf.end(); o++) { + if (o->second.empty()) continue; + + TopoDS_Shape shape; + if ((o->first)->getTypeId().isDerivedFrom(PartDesign::Additive::getClassTypeId())) { + PartDesign::Additive* addFeature = static_cast(o->first); + shape = addFeature->AddShape.getShape()._Shape; + } else if ((o->first)->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) { + PartDesign::Subtractive* subFeature = static_cast(o->first); + shape = subFeature->SubShape.getShape()._Shape; + } + + if (shape.IsNull()) continue; + + // Display the rejected transformations in red + TopoDS_Shape cShape(shape); + + try { + // calculating the deflection value + Standard_Real xMin, yMin, zMin, xMax, yMax, zMax; + { + Bnd_Box bounds; + BRepBndLib::Add(cShape, bounds); + bounds.SetGap(0.0); + bounds.Get(xMin, yMin, zMin, xMax, yMax, zMax); + } + Standard_Real deflection = ((xMax-xMin)+(yMax-yMin)+(zMax-zMin))/300.0 * Deviation.getValue(); + + // create or use the mesh on the data structure + // Note: This DOES have an effect on cShape +#if OCC_VERSION_HEX >= 0x060600 + Standard_Real AngDeflectionRads = AngularDeflection.getValue() / 180.0 * M_PI; + BRepMesh_IncrementalMesh(cShape,deflection,Standard_False, + AngDeflectionRads,Standard_True); +#else + BRepMesh_IncrementalMesh(cShape,deflection); +#endif + // We must reset the location here because the transformation data + // are set in the placement property + TopLoc_Location aLoc; + cShape.Location(aLoc); + + // count triangles and nodes in the mesh + int nbrTriangles=0, nbrNodes=0; + TopExp_Explorer Ex; + for (Ex.Init(cShape,TopAbs_FACE);Ex.More();Ex.Next()) { + Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(TopoDS::Face(Ex.Current()), aLoc); + // Note: we must also count empty faces + if (!mesh.IsNull()) { + nbrTriangles += mesh->NbTriangles(); + nbrNodes += mesh->NbNodes(); + } + } + + // create memory for the nodes and indexes + SoCoordinate3* rejectedCoords = new SoCoordinate3(); + rejectedCoords ->point .setNum(nbrNodes); + SoNormal* rejectedNorms = new SoNormal(); + rejectedNorms ->vector .setNum(nbrNodes); + SoIndexedFaceSet* rejectedFaceSet = new SoIndexedFaceSet(); + rejectedFaceSet ->coordIndex .setNum(nbrTriangles*4); + + // get the raw memory for fast fill up + SbVec3f* verts = rejectedCoords ->point .startEditing(); + SbVec3f* norms = rejectedNorms ->vector .startEditing(); + int32_t* index = rejectedFaceSet ->coordIndex .startEditing(); + + // preset the normal vector with null vector + for (int i=0; i < nbrNodes; i++) + norms[i]= SbVec3f(0.0,0.0,0.0); + + int ii = 0,FaceNodeOffset=0,FaceTriaOffset=0; + for (Ex.Init(cShape, TopAbs_FACE); Ex.More(); Ex.Next(),ii++) { + TopLoc_Location aLoc; + const TopoDS_Face &actFace = TopoDS::Face(Ex.Current()); + // get the mesh of the shape + Handle (Poly_Triangulation) mesh = BRep_Tool::Triangulation(actFace,aLoc); + if (mesh.IsNull()) continue; + + // getting the transformation of the shape/face + gp_Trsf myTransf; + Standard_Boolean identity = true; + if (!aLoc.IsIdentity()) { + identity = false; + myTransf = aLoc.Transformation(); + } + + // getting size of node and triangle array of this face + int nbNodesInFace = mesh->NbNodes(); + int nbTriInFace = mesh->NbTriangles(); + // check orientation + TopAbs_Orientation orient = actFace.Orientation(); + + // cycling through the poly mesh + const Poly_Array1OfTriangle& Triangles = mesh->Triangles(); + const TColgp_Array1OfPnt& Nodes = mesh->Nodes(); + for (int g=1; g <= nbTriInFace; g++) { + // Get the triangle + Standard_Integer N1,N2,N3; + Triangles(g).Get(N1,N2,N3); + + // change orientation of the triangle if the face is reversed + if ( orient != TopAbs_FORWARD ) { + Standard_Integer tmp = N1; + N1 = N2; + N2 = tmp; + } + + // get the 3 points of this triangle + gp_Pnt V1(Nodes(N1)), V2(Nodes(N2)), V3(Nodes(N3)); + + // transform the vertices to the place of the face + if (!identity) { + V1.Transform(myTransf); + V2.Transform(myTransf); + V3.Transform(myTransf); + } + + // calculating per vertex normals + // Calculate triangle normal + gp_Vec v1(V1.X(),V1.Y(),V1.Z()),v2(V2.X(),V2.Y(),V2.Z()),v3(V3.X(),V3.Y(),V3.Z()); + gp_Vec Normal = (v2-v1)^(v3-v1); + + // add the triangle normal to the vertex normal for all points of this triangle + norms[FaceNodeOffset+N1-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); + norms[FaceNodeOffset+N2-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); + norms[FaceNodeOffset+N3-1] += SbVec3f(Normal.X(),Normal.Y(),Normal.Z()); + + // set the vertices + verts[FaceNodeOffset+N1-1].setValue((float)(V1.X()),(float)(V1.Y()),(float)(V1.Z())); + verts[FaceNodeOffset+N2-1].setValue((float)(V2.X()),(float)(V2.Y()),(float)(V2.Z())); + verts[FaceNodeOffset+N3-1].setValue((float)(V3.X()),(float)(V3.Y()),(float)(V3.Z())); + + // set the index vector with the 3 point indexes and the end delimiter + index[FaceTriaOffset*4+4*(g-1)] = FaceNodeOffset+N1-1; + index[FaceTriaOffset*4+4*(g-1)+1] = FaceNodeOffset+N2-1; + index[FaceTriaOffset*4+4*(g-1)+2] = FaceNodeOffset+N3-1; + index[FaceTriaOffset*4+4*(g-1)+3] = SO_END_FACE_INDEX; + } + + // counting up the per Face offsets + FaceNodeOffset += nbNodesInFace; + FaceTriaOffset += nbTriInFace; + } + + // normalize all normals + for (int i=0; i < nbrNodes; i++) + norms[i].normalize(); + + // end the editing of the nodes + rejectedCoords ->point .finishEditing(); + rejectedNorms ->vector .finishEditing(); + rejectedFaceSet ->coordIndex .finishEditing(); + + // fill in the transformation matrices + SoMultipleCopy* rejectedTrfms = new SoMultipleCopy(); + rejectedTrfms->matrix.setNum((o->second).size()); + SbMatrix* mats = rejectedTrfms->matrix.startEditing(); + + std::list::const_iterator trsf = (o->second).begin(); + for (unsigned int i=0; i < (o->second).size(); i++,trsf++) { + Base::Matrix4D mat; + Part::TopoShape::convertToMatrix(*trsf,mat); + mats[i] = convert(mat); + } + rejectedTrfms->matrix.finishEditing(); + rejectedTrfms->addChild(rejectedFaceSet); + SoSeparator* sep = new SoSeparator(); + sep->addChild(rejectedCoords); + sep->addChild(rejectedNorms); + sep->addChild(rejectedTrfms); + pcRejectedRoot->addChild(sep); + } + catch (...) { + Base::Console().Error("Cannot compute Inventor representation for the rejected transformations of shape of %s.\n", + pcTransformed->getNameInDocument()); + } + } + +} + diff --git a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h index 601df79b6..8ecd67e7d 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderTransformed.h +++ b/src/Mod/PartDesign/Gui/ViewProviderTransformed.h @@ -64,12 +64,8 @@ protected: const bool checkDlgOpen(TaskDlgTransformedParameters* transformedDlg); - // nodes for the representation of rejected repetitions + // node for the representation of rejected repetitions SoGroup * pcRejectedRoot; - SoMultipleCopy * rejectedTrfms; - SoCoordinate3 * rejectedCoords; - SoNormal * rejectedNorms; - SoIndexedFaceSet * rejectedFaceSet; public: void recomputeFeature();