Enable multiple originals for the transformed features

This commit is contained in:
jrheinlaender 2013-09-28 16:17:55 +02:00 committed by Stefan Tröger
parent a59901ee4b
commit fcea39b0d8
28 changed files with 1804 additions and 293 deletions

View File

@ -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<std::vector<gp_Trsf>::const_iterator> nointersect_trsfms;
std::set<std::vector<gp_Trsf>::const_iterator> overlapping_trsfms;
typedef std::set<std::vector<gp_Trsf>::const_iterator> trsf_it;
typedef std::map<App::DocumentObject*, trsf_it> 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<std::vector<gp_Trsf>::const_iterator> v_transformations;
typedef std::vector<std::vector<gp_Trsf>::const_iterator> trsf_it_vec;
trsf_it_vec v_transformations;
std::vector<TopoDS_Shape> v_transformedShapes;
std::vector<gp_Trsf>::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<std::vector<TopoDS_Shape>::iterator> rejected_iterators;
typedef std::set<std::vector<TopoDS_Shape>::iterator> shape_it_set;
shape_it_set rejected_iterators;
std::vector<TopoDS_Shape>::iterator s1 = v_transformedShapes.begin();
std::vector<TopoDS_Shape>::iterator s2 = s1;
++s2;
std::vector<std::vector<gp_Trsf>::const_iterator>::const_iterator t1 = v_transformations.begin();
std::vector<std::vector<gp_Trsf>::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<std::vector<TopoDS_Shape>::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<std::vector<gp_Trsf>::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<std::vector<gp_Trsf>::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())

View File

@ -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<gp_Trsf> getRejectedTransformations(void) { return rejected; }
typedef std::map<App::DocumentObject*, std::list<gp_Trsf> > 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<gp_Trsf> rejected;
rejectedMap rejected;
};
} //namespace PartDesign

View File

@ -123,6 +123,9 @@ namespace PartDesignGui
void getReferencedSelection(const App::DocumentObject* thisObj, const Gui::SelectionChanges& msg,
App::DocumentObject*& selObj, std::vector<std::string>& selSub)
{
if (strcmp(thisObj->getDocument()->getName(), msg.pDocName) != 0)
return;
selObj = thisObj->getDocument()->getObject(msg.pObjectName);
if (selObj == thisObj)
return;

View File

@ -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<App::DocumentObject*> originals = pcLinearPattern->Originals.getValues();
// Fill data into dialog elements
ui->lineOriginal->setEnabled(false);
for (std::vector<App::DocumentObject*>::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<App::DocumentObject*> 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<std::string>& sub) const
{
obj = getSketchObject();

View File

@ -32,6 +32,7 @@
#include "TaskLinearPatternParameters.h"
#include "TaskMultiTransformParameters.h"
#include "Workbench.h"
#include "ReferenceSelection.h"
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>
@ -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<App::DocumentObject*> originals = pcLinearPattern->Originals.getValues();
// Fill data into dialog elements
ui->lineOriginal->setEnabled(false);
for (std::vector<App::DocumentObject*>::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<std::string> directions;
App::DocumentObject* selObj;
getReferencedSelection(msg, selObj, directions);
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(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<std::string> directions;
App::DocumentObject* selObj;
getReferencedSelection(msg, selObj, directions);
PartDesign::LinearPattern* pcLinearPattern = static_cast<PartDesign::LinearPattern*>(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<std::string>(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<App::DocumentObject*> 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<std::string>& sub) const
{
obj = getSketchObject();

View File

@ -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<std::string>& sub) const;
const bool getReverse(void) const;
const double getLength(void) const;

View File

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>266</width>
<height>402</height>
<height>333</height>
</rect>
</property>
<property name="windowTitle">
@ -15,19 +15,32 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayoutOriginal">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="labelOriginal">
<widget class="QPushButton" name="buttonAddFeature">
<property name="text">
<string>Original feature</string>
<string>Add feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineOriginal"/>
<widget class="QPushButton" name="buttonRemoveFeature">
<property name="text">
<string>Remove feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="listWidgetFeatures"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>

View File

@ -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<App::DocumentObject*> originals = pcMirrored->Originals.getValues();
// Fill data into dialog elements
ui->lineOriginal->setEnabled(false);
for (std::vector<App::DocumentObject*>::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<App::DocumentObject*> 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<std::string>& sub) const
{
obj = getSketchObject();

View File

@ -31,6 +31,7 @@
#include "TaskMirroredParameters.h"
#include "TaskMultiTransformParameters.h"
#include "Workbench.h"
#include "ReferenceSelection.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
@ -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<App::DocumentObject*> originals = pcMirrored->Originals.getValues();
// Fill data into dialog elements
ui->lineOriginal->setEnabled(false);
for (std::vector<App::DocumentObject*>::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<std::string> mirrorPlanes;
App::DocumentObject* selObj;
getReferencedSelection(msg, selObj, mirrorPlanes);
PartDesign::Mirrored* pcMirrored = static_cast<PartDesign::Mirrored*>(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<std::string> mirrorPlanes;
App::DocumentObject* selObj;
getReferencedSelection(msg, selObj, mirrorPlanes);
PartDesign::Mirrored* pcMirrored = static_cast<PartDesign::Mirrored*>(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<std::string>(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<App::DocumentObject*> 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<std::string>& sub) const
{
obj = getSketchObject();
@ -390,7 +404,7 @@ bool TaskDlgMirroredParameters::accept()
std::vector<std::string> 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

View File

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

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>242</width>
<height>290</height>
<width>253</width>
<height>235</height>
</rect>
</property>
<property name="windowTitle">
@ -15,19 +15,32 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayoutOriginal">
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QLabel" name="labelOriginal">
<widget class="QPushButton" name="buttonAddFeature">
<property name="text">
<string>Original feature</string>
<string>Add feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineOriginal"/>
<widget class="QPushButton" name="buttonRemoveFeature">
<property name="text">
<string>Remove feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="listWidgetFeatures"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>

View File

@ -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<App::DocumentObject*> 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<App::DocumentObject*>::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<App::DocumentObject*> 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) {

View File

@ -0,0 +1,512 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 <QMessageBox>
#endif
#include "ui_TaskMultiTransformParameters.h"
#include "TaskMultiTransformParameters.h"
#include "TaskMirroredParameters.h"
#include "TaskLinearPatternParameters.h"
#include "TaskPolarPatternParameters.h"
#include "TaskScaledParameters.h"
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Gui/Control.h>
#include <Mod/PartDesign/App/FeatureMultiTransform.h>
#include <Mod/PartDesign/App/FeatureMirrored.h>
#include <Mod/PartDesign/App/FeatureLinearPattern.h>
#include <Mod/PartDesign/App/FeaturePolarPattern.h>
#include <Mod/PartDesign/App/FeatureScaled.h>
#include <Mod/Sketcher/App/SketchObject.h>
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<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
// Fill data into dialog elements
ui->listTransformFeatures->setEnabled(true);
ui->listTransformFeatures->clear();
for (std::vector<App::DocumentObject*>::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<App::DocumentObject*> originals = pcMultiTransform->Originals.getValues();
// Fill data into dialog elements
for (std::vector<App::DocumentObject*>::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<App::DocumentObject*> 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<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> 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<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
subFeature = static_cast<PartDesign::Transformed*>(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<PartDesign::MultiTransform*>(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<App::DocumentObject*> 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<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> 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<App::DocumentObject*> TaskMultiTransformParameters::getTransformFeatures(void) const
{
PartDesign::MultiTransform* pcMultiTransform = static_cast<PartDesign::MultiTransform*>(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<TaskMultiTransformParameters*>(parameter);
std::vector<App::DocumentObject*> transformFeatures = mtParameter->getTransformFeatures();
std::stringstream str;
str << "App.ActiveDocument." << name.c_str() << ".Transformations = [";
for (std::vector<App::DocumentObject*>::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<PartDesign::MultiTransform*>(TransformedView->getObject());
std::vector<App::DocumentObject*> transformFeatures = pcMultiTransform->Transformations.getValues();
// Delete the transformation features - must happen before abortCommand()!
for (std::vector<App::DocumentObject*>::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"

View File

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

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>225</width>
<height>182</height>
<width>256</width>
<height>266</height>
</rect>
</property>
<property name="windowTitle">
@ -15,21 +15,34 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayoutOriginal">
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QLabel" name="labelOriginal">
<widget class="QPushButton" name="buttonAddFeature">
<property name="text">
<string>Original feature</string>
<string>Add feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineOriginal"/>
<widget class="QPushButton" name="buttonRemoveFeature">
<property name="text">
<string>Remove feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QLabel" name="label_2">
<widget class="QListWidget" name="listWidgetFeatures"/>
</item>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Transformations</string>
</property>

View File

@ -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<App::DocumentObject*> originals = pcPolarPattern->Originals.getValues();
// Fill data into dialog elements
ui->lineOriginal->setEnabled(false);
for (std::vector<App::DocumentObject*>::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<App::DocumentObject*> 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<std::string>& sub) const
{
obj = getSketchObject();

View File

@ -32,6 +32,7 @@
#include "TaskPolarPatternParameters.h"
#include "TaskMultiTransformParameters.h"
#include "Workbench.h"
#include "ReferenceSelection.h"
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>
@ -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<App::DocumentObject*> originals = pcPolarPattern->Originals.getValues();
// Fill data into dialog elements
ui->lineOriginal->setEnabled(false);
for (std::vector<App::DocumentObject*>::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<std::string> axes;
App::DocumentObject* selObj;
getReferencedSelection(msg, selObj, axes);
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(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<std::string> axes;
App::DocumentObject* selObj;
getReferencedSelection(msg, selObj, axes);
PartDesign::PolarPattern* pcPolarPattern = static_cast<PartDesign::PolarPattern*>(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<App::DocumentObject*> 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<std::string>& sub) const
{
obj = getSketchObject();

View File

@ -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<std::string>& sub) const;
const std::string getStdAxis(void) const;
//const std::string getAxis(void) const;

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>225</width>
<height>400</height>
<width>253</width>
<height>333</height>
</rect>
</property>
<property name="windowTitle">
@ -15,19 +15,32 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayoutOriginal">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="labelOriginal">
<widget class="QPushButton" name="buttonAddFeature">
<property name="text">
<string>Original feature</string>
<string>Add feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineOriginal"/>
<widget class="QPushButton" name="buttonRemoveFeature">
<property name="text">
<string>Remove feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="listWidgetFeatures"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<item>

View File

@ -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<App::DocumentObject*> originals = pcScaled->Originals.getValues();
// Fill data into dialog elements
ui->lineOriginal->setEnabled(false);
for (std::vector<App::DocumentObject*>::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<App::DocumentObject*> 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();

View File

@ -0,0 +1,287 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 <QMessageBox>
#endif
#include "ui_TaskScaledParameters.h"
#include "TaskScaledParameters.h"
#include "TaskMultiTransformParameters.h"
#include <Base/UnitsApi.h>
#include <App/Application.h>
#include <App/Document.h>
#include <Gui/Application.h>
#include <Gui/Document.h>
#include <Gui/BitmapFactory.h>
#include <Gui/ViewProvider.h>
#include <Gui/WaitCursor.h>
#include <Base/Console.h>
#include <Gui/Selection.h>
#include <Gui/Command.h>
#include <Mod/PartDesign/App/FeatureScaled.h>
#include <Mod/Sketcher/App/SketchObject.h>
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<PartDesign::Scaled*>(getObject());
std::vector<App::DocumentObject*> originals = pcScaled->Originals.getValues();
// Fill data into dialog elements
for (std::vector<App::DocumentObject*>::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<PartDesign::Scaled*>(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<PartDesign::Scaled*>(getObject());
pcScaled->Factor.setValue(f);
recomputeFeature();
}
void TaskScaledParameters::onOccurrences(const uint n)
{
if (blockUpdate)
return;
PartDesign::Scaled* pcScaled = static_cast<PartDesign::Scaled*>(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<PartDesign::Scaled*>(getObject());
pcScaled->Factor.setValue(getFactor());
pcScaled->Occurrences.setValue(getOccurrences());
recomputeFeature();
}
}
void TaskScaledParameters::onFeatureDeleted(void)
{
PartDesign::Transformed* pcTransformed = getObject();
std::vector<App::DocumentObject*> 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"

View File

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

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>225</width>
<height>305</height>
<width>253</width>
<height>270</height>
</rect>
</property>
<property name="windowTitle">
@ -15,19 +15,32 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<layout class="QHBoxLayout" name="horizontalLayoutOriginal">
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<widget class="QLabel" name="labelOriginal">
<widget class="QPushButton" name="buttonAddFeature">
<property name="text">
<string>Original feature</string>
<string>Add feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="lineOriginal"/>
<widget class="QPushButton" name="buttonRemoveFeature">
<property name="text">
<string>Remove feature</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QListWidget" name="listWidgetFeatures"/>
</item>
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>

View File

@ -24,6 +24,7 @@
#ifndef _PreComp_
# include <QMessageBox>
# include <QListWidgetItem>
# include <TopoDS_Shape.hxx>
# include <TopoDS_Face.hxx>
# include <TopoDS.hxx>
@ -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<App::DocumentObject*> originals(1,selectedObject);
std::vector<App::DocumentObject*> originals = pcTransformed->Originals.getValues();
std::vector<App::DocumentObject*>::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<QListWidgetItem*> items = widget->findItems(QString::fromAscii(itemstr), Qt::MatchExactly);
if (!items.empty()) {
for (QList<QListWidgetItem*>::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();

View File

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

View File

@ -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);
}
while (pcRejectedRoot->getNumChildren() > 7) {
SoSeparator* sep = static_cast<SoSeparator*>(pcRejectedRoot->getChild(7));
SoMultipleCopy* rejectedTrfms = static_cast<SoMultipleCopy*>(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<std::string> &s)
@ -203,8 +189,11 @@ void ViewProviderTransformed::recomputeFeature(void)
PartDesign::Transformed* pcTransformed = static_cast<PartDesign::Transformed*>(getObject());
pcTransformed->getDocument()->recomputeFeature(pcTransformed);
const std::vector<App::DocumentObjectExecReturn*> 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("<font color='orange'>%1<br/></font>\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<PartDesign::Additive*>(original);
shape = addFeature->AddShape.getShape()._Shape;
} else if (original->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) {
PartDesign::Subtractive* subFeature = static_cast<PartDesign::Subtractive*>(original);
shape = subFeature->SubShape.getShape()._Shape;
}
// Clear all the rejected stuff
while (pcRejectedRoot->getNumChildren() > 7) {
SoSeparator* sep = static_cast<SoSeparator*>(pcRejectedRoot->getChild(7));
SoMultipleCopy* rejectedTrfms = static_cast<SoMultipleCopy*>(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<PartDesign::Additive*>(o->first);
shape = addFeature->AddShape.getShape()._Shape;
} else if ((o->first)->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) {
PartDesign::Subtractive* subFeature = static_cast<PartDesign::Subtractive*>(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<gp_Trsf> rejected_trsf = pcTransformed->getRejectedTransformations();
std::list<gp_Trsf>::const_iterator trsf = rejected_trsf.begin();
for (unsigned int i=0; i < rejected; i++,trsf++) {
std::list<gp_Trsf>::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",

View File

@ -0,0 +1,410 @@
/******************************************************************************
* Copyright (c)2012 Jan Rheinlaender <jrheinlaender@users.sourceforge.net> *
* *
* 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 <Bnd_Box.hxx>
# include <BRep_Tool.hxx>
# include <BRepBndLib.hxx>
# include <BRepMesh_IncrementalMesh.hxx>
# include <Standard_Version.hxx>
# include <TopExp_Explorer.hxx>
# include <TopoDS.hxx>
# include <Poly_Triangulation.hxx>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoIndexedFaceSet.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoMultipleCopy.h>
# include <Inventor/nodes/SoNormal.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoShapeHints.h>
# include <Inventor/nodes/SoTransparencyType.h>
# include <QAction>
# include <QMenu>
# include <QMessageBox>
#endif
#include "Workbench.h"
#include "ViewProviderTransformed.h"
#include "TaskTransformedParameters.h"
#include <Base/Console.h>
#include <Gui/Control.h>
#include <Gui/Command.h>
#include <Gui/Application.h>
#include <Gui/Command.h>
#include <Mod/Part/App/TopoShape.h>
#include <Mod/PartDesign/App/FeatureAdditive.h>
#include <Mod/PartDesign/App/FeatureSubtractive.h>
#include <Mod/PartDesign/App/FeatureTransformed.h>
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<SoSeparator*>(pcRejectedRoot->getChild(7));
SoMultipleCopy* rejectedTrfms = static_cast<SoMultipleCopy*>(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<std::string> &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<TaskDlgTransformedParameters *>(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<PartDesign::Transformed*>(getObject());
pcTransformed->getDocument()->recomputeFeature(pcTransformed);
const std::vector<App::DocumentObjectExecReturn*> 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("<font color='orange'>%1<br/></font>\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("<font color='red'>%1<br/></font>"));
msg = msg.arg(QString::fromStdString(log.back()->Why));
} else {
msg = msg.arg(QString::fromLatin1("<font color='green'>%1<br/></font>"));
msg = msg.arg(QObject::tr("Transformation succeeded"));
}
signalDiagnosis(msg);
// Clear all the rejected stuff
while (pcRejectedRoot->getNumChildren() > 7) {
SoSeparator* sep = static_cast<SoSeparator*>(pcRejectedRoot->getChild(7));
SoMultipleCopy* rejectedTrfms = static_cast<SoMultipleCopy*>(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<PartDesign::Additive*>(o->first);
shape = addFeature->AddShape.getShape()._Shape;
} else if ((o->first)->getTypeId().isDerivedFrom(PartDesign::Subtractive::getClassTypeId())) {
PartDesign::Subtractive* subFeature = static_cast<PartDesign::Subtractive*>(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<gp_Trsf>::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());
}
}
}

View File

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