diff --git a/src/Mod/Fem/App/AppFem.cpp b/src/Mod/Fem/App/AppFem.cpp index 426e1b142..1de53aae3 100644 --- a/src/Mod/Fem/App/AppFem.cpp +++ b/src/Mod/Fem/App/AppFem.cpp @@ -57,6 +57,7 @@ #include "FemConstraintPlaneRotation.h" #include "FemConstraintContact.h" #include "FemConstraintFluidBoundary.h" +#include "FemConstraintTransform.h" #include "FemResultObject.h" #include "FemSolverObject.h" @@ -159,6 +160,7 @@ PyMODINIT_FUNC initFem() Fem::ConstraintPlaneRotation ::init(); Fem::ConstraintContact ::init(); Fem::ConstraintFluidBoundary ::init(); + Fem::ConstraintTransform ::init(); Fem::FemResultObject ::init(); Fem::FemResultObjectPython ::init(); diff --git a/src/Mod/Fem/App/CMakeLists.txt b/src/Mod/Fem/App/CMakeLists.txt index fd57fa0de..7b1661122 100755 --- a/src/Mod/Fem/App/CMakeLists.txt +++ b/src/Mod/Fem/App/CMakeLists.txt @@ -219,6 +219,8 @@ SET(FemConstraints_SRCS FemConstraintPlaneRotation.h FemConstraintContact.cpp FemConstraintContact.h + FemConstraintTransform.cpp + FemConstraintTransform.h ) SOURCE_GROUP("Constraints" FILES ${FemConstraints_SRCS}) diff --git a/src/Mod/Fem/App/FemConstraintTransform.cpp b/src/Mod/Fem/App/FemConstraintTransform.cpp new file mode 100644 index 000000000..9e775c7d7 --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintTransform.cpp @@ -0,0 +1,104 @@ +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +#include +#include +#include +#include +#include +#include +#include +#endif + +#include "FemConstraintTransform.h" + +using namespace Fem; + +PROPERTY_SOURCE(Fem::ConstraintTransform, Fem::Constraint); + +static const char* TransformTypes[] = {"Cylindrical","Rectangular", NULL}; + +ConstraintTransform::ConstraintTransform() +{ + ADD_PROPERTY(X_rot,(0.0)); //numeric value, 0.0 + ADD_PROPERTY(Y_rot,(0.0)); + ADD_PROPERTY(Z_rot,(0.0)); + ADD_PROPERTY_TYPE(TransformType,(1),"ConstraintTransform",(App::PropertyType)(App::Prop_None), + "Type of transform, rectangular or cylindrical"); + TransformType.setEnums(TransformTypes); + ADD_PROPERTY_TYPE(RefDispl,(0,0),"ConstraintTransform",(App::PropertyType)(App::Prop_None),"Elements where the constraint is applied"); + ADD_PROPERTY_TYPE(NameDispl,(0),"ConstraintTransform",(App::PropertyType)(App::Prop_None),"Elements where the constraint is applied"); + ADD_PROPERTY_TYPE(BasePoint,(Base::Vector3d(0,0,0)),"ConstraintTransform",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Base point of cylindrical surface"); + ADD_PROPERTY_TYPE(Axis,(Base::Vector3d(0,1,0)),"ConstraintTransform",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Axis of cylindrical surface"); + ADD_PROPERTY_TYPE(Points,(Base::Vector3d()),"ConstraintTransform",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Points where symbols are drawn"); + ADD_PROPERTY_TYPE(Normals,(Base::Vector3d()),"ConstraintTransform",App::PropertyType(App::Prop_ReadOnly|App::Prop_Output), + "Normals where symbols are drawn"); + Points.setValues(std::vector()); + Normals.setValues(std::vector()); +} + +App::DocumentObjectExecReturn *ConstraintTransform::execute(void) +{ + return Constraint::execute(); +} + +const char* ConstraintTransform::getViewProviderName(void) const +{ + return "FemGui::ViewProviderFemConstraintTransform"; +} + +void ConstraintTransform::onChanged(const App::Property* prop) +{ + Constraint::onChanged(prop); + + if (prop == &References) { + std::vector points; + std::vector normals; + int scale = 1; //OvG: Enforce use of scale + if (getPoints(points, normals, &scale)) { + Points.setValues(points); + Normals.setValues(normals); + Scale.setValue(scale); //OvG: Scale + Points.touch(); // This triggers ViewProvider::updateData() + std::string transform_type = TransformType.getValueAsString(); + if (transform_type == "Cylindrical") { + // Find data of cylinder + double radius, height; + Base::Vector3d base, axis; + if (!getCylinder(radius, height, base, axis)) + return; + Axis.setValue(axis); + // Update base point + base = base + axis * height/2; + BasePoint.setValue(base); + BasePoint.touch(); // This triggers ViewProvider::updateData() + } + } + } +} diff --git a/src/Mod/Fem/App/FemConstraintTransform.h b/src/Mod/Fem/App/FemConstraintTransform.h new file mode 100644 index 000000000..815f1bf8f --- /dev/null +++ b/src/Mod/Fem/App/FemConstraintTransform.h @@ -0,0 +1,67 @@ +/*************************************************************************** + * Copyright (c) 2013 Jan Rheinländer * + * * + * 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 * + * * + ***************************************************************************/ + +#ifndef FEM_CONSTRAINTTransform_H +#define FEM_CONSTRAINTTransform_H + +#include "FemConstraint.h" + +namespace Fem +{ + +class AppFemExport ConstraintTransform : public Fem::Constraint +{ + PROPERTY_HEADER(Fem::ConstraintTransform); + +public: + /// Constructor + ConstraintTransform(void); + + // Read-only (calculated values). These trigger changes in the ViewProvider + App::PropertyLinkSubList RefDispl; + App::PropertyLinkList NameDispl; + App::PropertyVectorList Points; + App::PropertyVectorList Normals; + App::PropertyVector BasePoint; + App::PropertyVector Axis; + App::PropertyFloat X_rot; + App::PropertyFloat Y_rot; + App::PropertyFloat Z_rot; + App::PropertyEnumeration TransformType; + //etc +/* */ + + /// recalculate the object + virtual App::DocumentObjectExecReturn *execute(void); + + /// returns the type name of the ViewProvider + const char* getViewProviderName(void) const; + +protected: + virtual void onChanged(const App::Property* prop); + +}; + +} //namespace Fem + + +#endif // FEM_CONSTRAINTTransform_H diff --git a/src/Mod/Fem/Gui/AppFemGui.cpp b/src/Mod/Fem/Gui/AppFemGui.cpp index 4d399cd7d..ee950db3a 100644 --- a/src/Mod/Fem/Gui/AppFemGui.cpp +++ b/src/Mod/Fem/Gui/AppFemGui.cpp @@ -59,6 +59,7 @@ #include "ViewProviderFemConstraintInitialTemperature.h" #include "ViewProviderFemConstraintPlaneRotation.h" #include "ViewProviderFemConstraintContact.h" +#include "ViewProviderFemConstraintTransform.h" #include "ViewProviderResult.h" #include "Workbench.h" @@ -130,6 +131,7 @@ PyMODINIT_FUNC initFemGui() FemGui::ViewProviderFemConstraintInitialTemperature ::init(); FemGui::ViewProviderFemConstraintPlaneRotation::init(); FemGui::ViewProviderFemConstraintContact ::init(); + FemGui::ViewProviderFemConstraintTransform ::init(); FemGui::ViewProviderResult ::init(); FemGui::ViewProviderResultPython ::init(); FemGui::PropertyFemMeshItem ::init(); diff --git a/src/Mod/Fem/Gui/CMakeLists.txt b/src/Mod/Fem/Gui/CMakeLists.txt index cec8d7878..b30490ac6 100755 --- a/src/Mod/Fem/Gui/CMakeLists.txt +++ b/src/Mod/Fem/Gui/CMakeLists.txt @@ -72,6 +72,7 @@ set(FemGui_MOC_HDRS TaskFemConstraintInitialTemperature.h TaskFemConstraintPlaneRotation.h TaskFemConstraintContact.h + TaskFemConstraintTransform.h TaskTetParameter.h TaskAnalysisInfo.h TaskDriver.h @@ -106,6 +107,7 @@ set(FemGui_UIC_SRCS TaskFemConstraintInitialTemperature.ui TaskFemConstraintPlaneRotation.ui TaskFemConstraintContact.ui + TaskFemConstraintTransform.ui TaskTetParameter.ui TaskAnalysisInfo.ui TaskDriver.ui @@ -175,6 +177,9 @@ SET(FemGui_DLG_SRCS TaskFemConstraintContact.ui TaskFemConstraintContact.cpp TaskFemConstraintContact.h + TaskFemConstraintTransform.ui + TaskFemConstraintTransform.cpp + TaskFemConstraintTransform.h ) SOURCE_GROUP("Constraint-Dialogs" FILES ${FemGui_DLG_SRCS}) @@ -231,6 +236,8 @@ SET(FemGui_SRCS_ViewProvider ViewProviderFemConstraintPlaneRotation.h ViewProviderFemConstraintContact.cpp ViewProviderFemConstraintContact.h + ViewProviderFemConstraintTransform.cpp + ViewProviderFemConstraintTransform.h ViewProviderResult.cpp ViewProviderResult.h ) diff --git a/src/Mod/Fem/Gui/Command.cpp b/src/Mod/Fem/Gui/Command.cpp index 958b520bd..9243b5f85 100644 --- a/src/Mod/Fem/Gui/Command.cpp +++ b/src/Mod/Fem/Gui/Command.cpp @@ -437,6 +437,50 @@ bool CmdFemConstraintContact::isActive(void) return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); } +//===================================================================================== +DEF_STD_CMD_A(CmdFemConstraintTransform); + +CmdFemConstraintTransform::CmdFemConstraintTransform() + : Command("Fem_ConstraintTransform") +{ + sAppModule = "Fem"; + sGroup = QT_TR_NOOP("Fem"); + sMenuText = QT_TR_NOOP("Create FEM transform constraint"); + sToolTipText = QT_TR_NOOP("Create FEM constraint for transforming a face"); + sWhatsThis = "Fem_ConstraintTransform"; + sStatusTip = sToolTipText; + sPixmap = "fem-constraint-transform"; +} + +void CmdFemConstraintTransform::activated(int iMsg) +{ + Fem::FemAnalysis *Analysis; + + if(getConstraintPrerequisits(&Analysis)) + return; + + std::string FeatName = getUniqueObjectName("FemConstraintTransform"); + + openCommand("Make FEM constraint transform on face"); + doCommand(Doc,"App.activeDocument().addObject(\"Fem::ConstraintTransform\",\"%s\")",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.X_rot = 0.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Y_rot = 0.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Z_rot = 0.0",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Scale = 1",FeatName.c_str()); + doCommand(Doc,"App.activeDocument().%s.Member = App.activeDocument().%s.Member + [App.activeDocument().%s]", + Analysis->getNameInDocument(),Analysis->getNameInDocument(),FeatName.c_str()); + + doCommand(Doc,"%s",gethideMeshShowPartStr(FeatName).c_str()); //OvG: Hide meshes and show parts + + updateActive(); + + doCommand(Gui,"Gui.activeDocument().setEdit('%s')",FeatName.c_str()); +} + +bool CmdFemConstraintTransform::isActive(void) +{ + return FemGui::ActiveAnalysisObserver::instance()->hasActiveObject(); +} //===================================================================================== DEF_STD_CMD_A(CmdFemConstraintHeatflux); @@ -1409,6 +1453,7 @@ void CreateFemCommands(void) rcCmdMgr.addCommand(new CmdFemConstraintPlaneRotation()); rcCmdMgr.addCommand(new CmdFemConstraintContact()); rcCmdMgr.addCommand(new CmdFemConstraintFluidBoundary()); + rcCmdMgr.addCommand(new CmdFemConstraintTransform()); #ifdef FC_USE_VTK rcCmdMgr.addCommand(new CmdFemPostCreateClipFilter); rcCmdMgr.addCommand(new CmdFemPostCreateScalarClipFilter); diff --git a/src/Mod/Fem/Gui/TaskFemConstraintTransform.cpp b/src/Mod/Fem/Gui/TaskFemConstraintTransform.cpp new file mode 100644 index 000000000..71e26ae86 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintTransform.cpp @@ -0,0 +1,545 @@ +/*************************************************************************** + * Copyright (c) 2015 FreeCAD Developers * + * Authors: Michael Hindley * + * Ruan Olwagen * + * Oswald van Ginkel * + * Ofentse Kgoa * + * Based on Force constraint by Jan Rheinländer * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif + +#include "Mod/Fem/App/FemConstraintTransform.h" +#include "TaskFemConstraintTransform.h" +#include "ui_TaskFemConstraintTransform.h" +#include +#include +#include +#include +#include + +#include +#include + +#include +#define PI (3.141592653589793238462643383279502884L) + +using namespace FemGui; +using namespace Gui; + +/* TRANSLATOR FemGui::TaskFemConstraintTransform */ + +TaskFemConstraintTransform::TaskFemConstraintTransform(ViewProviderFemConstraintTransform *ConstraintView,QWidget *parent) + : TaskFemConstraint(ConstraintView, parent, "fem-constraint-transform") +{ + proxy = new QWidget(this); + ui = new Ui_TaskFemConstraintTransform(); + ui->setupUi(proxy); + QMetaObject::connectSlotsByName(this); + + QAction* actionRect = new QAction(tr("Delete"), ui->lw_Rect); + actionRect->connect(actionRect, SIGNAL(triggered()), this, SLOT(onReferenceDeleted())); + ui->lw_Rect->addAction(actionRect); + ui->lw_Rect->setContextMenuPolicy(Qt::ActionsContextMenu); + + connect(ui->lw_Rect, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + + this->groupLayout()->addWidget(proxy); + + connect(ui->rb_rect, SIGNAL(clicked(bool)), this, SLOT(Rect())); + connect(ui->rb_cylin, SIGNAL(clicked(bool)), this, SLOT(Cyl())); + + connect(ui->sp_X, SIGNAL(valueChanged(int)), this, SLOT(x_Changed(int))); + connect(ui->sp_Y, SIGNAL(valueChanged(int)), this, SLOT(y_Changed(int))); + connect(ui->sp_Z, SIGNAL(valueChanged(int)), this, SLOT(z_Changed(int))); + +/* Note: */ + // Get the feature data + Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); + + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + // Fill data into dialog elements + ui->sp_X->setValue(pcConstraint->X_rot.getValue()); + ui->sp_Y->setValue(pcConstraint->Y_rot.getValue()); + ui->sp_Z->setValue(pcConstraint->Z_rot.getValue()); + std::string transform_type = pcConstraint->TransformType.getValueAsString(); + if (transform_type == "Rectangular") { + ui->sw_transform->setCurrentIndex(0); + ui->rb_rect->setChecked(1); + ui->rb_cylin->setChecked(0); + } else if (transform_type == "Cylindrical") { + ui->sw_transform->setCurrentIndex(1); + ui->rb_rect->setChecked(0); + ui->rb_cylin->setChecked(1); + } + +/* */ + + ui->lw_Rect->clear(); + + //Transformable surfaces + Gui::Command::doCommand(Gui::Command::Doc,TaskFemConstraintTransform::getDisplcementReferences((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); + std::vector ObjDispl = pcConstraint->RefDispl.getValues(); + std::vector nDispl = pcConstraint->NameDispl.getValues(); + std::vector SubElemDispl = pcConstraint->RefDispl.getSubValues(); + + for (std::size_t i = 0; i < ObjDispl.size(); i++) { + ui->lw_displobj_rect->addItem(makeRefText(ObjDispl[i], SubElemDispl[i])); + ui->lw_displobj_cylin->addItem(makeRefText(ObjDispl[i], SubElemDispl[i])); + ui->lw_dis_rect->addItem(makeText(nDispl[i])); + ui->lw_dis_cylin->addItem(makeText(nDispl[i])); + } + + if (Objects.size() > 0) { + for (std::size_t i = 0; i < Objects.size(); i++) { + ui->lw_Rect->addItem(makeRefText(Objects[i], SubElements[i])); + } + } + int p = 0; + for (std::size_t i = 0; i < ObjDispl.size(); i++) { + for (std::size_t j = 0; j < Objects.size(); j++) { + if ((makeRefText(ObjDispl[i], SubElemDispl[i]))==(makeRefText(Objects[j], SubElements[j]))){ + p++; + } + } + } + //Selection buttons + connect(ui->btnAdd, SIGNAL(clicked()), this, SLOT(addToSelection())); + connect(ui->btnRemove, SIGNAL(clicked()), this, SLOT(removeFromSelection())); + + updateUI(); + if ((p==0) && (Objects.size() > 0)) { + QMessageBox::warning(this, tr("Constraint update error"), tr("The transformable faces have changed. Please add only the transformable faces and remove non-transformable faces!")); + return; + } +} + +TaskFemConstraintTransform::~TaskFemConstraintTransform() +{ + delete ui; +} + +const QString TaskFemConstraintTransform::makeText(const App::DocumentObject* obj) const +{ + return QString::fromUtf8((std::string(obj->getNameInDocument())).c_str()); +} + +void TaskFemConstraintTransform::updateUI() +{ + if (ui->lw_Rect->model()->rowCount() == 0) { + // Go into reference selection mode if no reference has been selected yet + onButtonReference(true); + return; + } +} + +void TaskFemConstraintTransform::x_Changed(int i){ + Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); + double x = i; + pcConstraint->X_rot.setValue(x); + std::string name = ConstraintView->getObject()->getNameInDocument(); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.X_rot = %f", name.c_str(), x); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + pcConstraint->References.setValues(Objects,SubElements); +} + +void TaskFemConstraintTransform::y_Changed(int i){ + Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); + double y = i; + pcConstraint->Y_rot.setValue(y); + std::string name = ConstraintView->getObject()->getNameInDocument(); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Y_rot = %f", name.c_str(), y); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + pcConstraint->References.setValues(Objects,SubElements); +} + +void TaskFemConstraintTransform::z_Changed(int i){ + Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); + double z = i; + pcConstraint->Z_rot.setValue(z); + std::string name = ConstraintView->getObject()->getNameInDocument(); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Z_rot = %f", name.c_str(), z); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + pcConstraint->References.setValues(Objects,SubElements); +} + +void TaskFemConstraintTransform::Rect(){ + ui->sw_transform->setCurrentIndex(0); + std::string name = ConstraintView->getObject()->getNameInDocument(); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TransformType = %s",name.c_str(), get_transform_type().c_str()); + Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + if (Objects.size() > 0) { + setSelection(ui->lw_Rect->item(0)); + removeFromSelection(); + } +} + +void TaskFemConstraintTransform::Cyl(){ + ui->sw_transform->setCurrentIndex(1); + ui->sp_X->setValue(0); + ui->sp_Y->setValue(0); + ui->sp_Z->setValue(0); + std::string name = ConstraintView->getObject()->getNameInDocument(); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TransformType = %s",name.c_str(), get_transform_type().c_str()); + Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + if (Objects.size() > 0) { + setSelection(ui->lw_Rect->item(0)); + removeFromSelection(); + } +} + + +void TaskFemConstraintTransform::addToSelection() +{ + int rows = ui->lw_Rect->model()->rowCount(); + std::vector selection = Gui::Selection().getSelectionEx(); //gets vector of selected objects of active document + if (selection.size()==0){ + QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!")); + return; + } + + if (rows==1){ + QMessageBox::warning(this, tr("Selection error"), tr("Only one face for rectangular transform constraint!")); + Gui::Selection().clearSelection(); + return; + } + + if ((rows==0) && (selection.size()>=2)){ + QMessageBox::warning(this, tr("Selection error"), tr("Only one face for rectangular transform constraint!")); + Gui::Selection().clearSelection(); + return; + } + + Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + + std::vector ObjDispl = pcConstraint->RefDispl.getValues(); + std::vector SubElemDispl = pcConstraint->RefDispl.getSubValues(); + for (std::vector::iterator it = selection.begin(); it != selection.end(); ++it){//for every selected object + if (static_cast(it->getTypeName()).substr(0,4).compare(std::string("Part"))!=0){ + QMessageBox::warning(this, tr("Selection error"),tr("Selected object is not a part!")); + return; + } + + std::vector subNames=it->getSubNames(); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(it->getFeatName()); + if (subNames.size()!=1){ + QMessageBox::warning(this, tr("Selection error"), tr("Only one face for transform constraint!")); + Gui::Selection().clearSelection(); + return; + } + for (unsigned int subIt=0;subIt<(subNames.size());++subIt){// for every selected sub element + bool addMe=true; + if (subNames[subIt].substr(0,4) != "Face") { + QMessageBox::warning(this, tr("Selection error"), tr("Only faces or edges can be picked")); + return; + } + if (subNames[subIt].substr(0,4) == "Face") { + if (ui->rb_cylin->isChecked()) { + Part::Feature* feat = static_cast(obj); + TopoDS_Shape ref = feat->Shape.getShape().getSubShape(subNames[subIt].c_str()); + BRepAdaptor_Surface surface(TopoDS::Face(ref)); + if (surface.GetType() != GeomAbs_Cylinder) { + QMessageBox::warning(this, tr("Selection error"), tr("Only cylindrical faces can be picked")); + return; + } + } + } + for (std::vector::iterator itr=std::find(SubElements.begin(),SubElements.end(),subNames[subIt]); + itr!= SubElements.end(); + itr = std::find(++itr,SubElements.end(),subNames[subIt])) + {// for every sub element in selection that matches one in old list + if (obj==Objects[std::distance(SubElements.begin(),itr)]){//if selected sub element's object equals the one in old list then it was added before so don't add + addMe=false; + } + } + if (addMe){ + disconnect(ui->lw_Rect, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + for (std::size_t i = 0; i < ObjDispl.size(); i++) { + if ((makeRefText(ObjDispl[i], SubElemDispl[i]))==(makeRefText(obj, subNames[subIt]))){ + Objects.push_back(obj); + SubElements.push_back(subNames[subIt]); + ui->lw_Rect->addItem(makeRefText(obj, subNames[subIt])); + connect(ui->lw_Rect, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + } + } + if (Objects.size() == 0){ + QMessageBox::warning(this, tr("Selection error"), tr("Only transformable faces can be selected! Apply displacement constraint to surface first then apply constraint to surface")); + Gui::Selection().clearSelection(); + return; + } + } + } + } + //Update UI + pcConstraint->References.setValues(Objects,SubElements); + updateUI(); + if (ui->rb_rect->isChecked()) { + Base::Vector3d normal = pcConstraint->NormalDirection.getValue(); + double n = normal.x; + double m = normal.y; + double l = normal.z; + //about Z-axis + double about_z; + double mag_norm_z = sqrt(n*n +m*m) ; //normal vector mapped onto XY plane + if (mag_norm_z ==0) { + about_z = 0; + } else { + about_z = (-1*(acos(m/mag_norm_z) * 180/PI) +180); + } + if (n>0) { + about_z = about_z*(-1); + } + //rotation to ZY plane + double m_p = n*sin(about_z*PI/180) + m*cos(about_z*PI/180); + double l_p = l; + //about X-axis + double about_x; + double mag_norm_x = sqrt(m_p*m_p + l_p*l_p); + if (mag_norm_x ==0){ + about_x = 0; + } else { + about_x = -(acos(l_p/mag_norm_x) * 180/PI); //rotation to the Z axis + } + ui->sp_X->setValue(round(about_x)); + ui->sp_Z->setValue(round(about_z)); + } +} + +void TaskFemConstraintTransform::removeFromSelection() +{ + std::vector selection = Gui::Selection().getSelectionEx(); //gets vector of selected objects of active document + if (selection.size()==0){ + QMessageBox::warning(this, tr("Selection error"), tr("Nothing selected!")); + return; + } + + Fem::ConstraintTransform* pcConstraint = static_cast(ConstraintView->getObject()); + std::vector Objects = pcConstraint->References.getValues(); + std::vector SubElements = pcConstraint->References.getSubValues(); + std::vector itemsToDel; + for (std::vector::iterator it = selection.begin(); it != selection.end(); ++it){//for every selected object + if (static_cast(it->getTypeName()).substr(0,4).compare(std::string("Part"))!=0){ + QMessageBox::warning(this, tr("Selection error"),tr("Selected object is not a part!")); + return; + } + + std::vector subNames=it->getSubNames(); + App::DocumentObject* obj = ConstraintView->getObject()->getDocument()->getObject(it->getFeatName()); + + for (unsigned int subIt=0;subIt<(subNames.size());++subIt){// for every selected sub element + for (std::vector::iterator itr=std::find(SubElements.begin(),SubElements.end(),subNames[subIt]); + itr!= SubElements.end(); + itr = std::find(++itr,SubElements.end(),subNames[subIt])) + {// for every sub element in selection that matches one in old list + if (obj==Objects[std::distance(SubElements.begin(),itr)]){//if selected sub element's object equals the one in old list then it was added before so mark for deletion + itemsToDel.push_back(std::distance(SubElements.begin(),itr)); + } + } + } + } + + std::sort(itemsToDel.begin(),itemsToDel.end()); + while (itemsToDel.size()>0){ + Objects.erase(Objects.begin()+itemsToDel.back()); + SubElements.erase(SubElements.begin()+itemsToDel.back()); + itemsToDel.pop_back(); + } + //Update UI + disconnect(ui->lw_Rect, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + + ui->lw_Rect->clear(); + connect(ui->lw_Rect, SIGNAL(currentItemChanged(QListWidgetItem*,QListWidgetItem*)), + this, SLOT(setSelection(QListWidgetItem*))); + + pcConstraint->References.setValues(Objects,SubElements); + updateUI(); + ui->sp_X->setValue(0); + ui->sp_Y->setValue(0); + ui->sp_Z->setValue(0); +} + +void TaskFemConstraintTransform::setSelection(QListWidgetItem* item){ + std::string docName=ConstraintView->getObject()->getDocument()->getName(); + + std::string s = item->text().toStdString(); + std::string delimiter = ":"; + + size_t pos = 0; + std::string objName; + std::string subName; + pos = s.find(delimiter); + objName = s.substr(0, pos); + s.erase(0, pos + delimiter.length()); + subName=s; + + Gui::Selection().clearSelection(); + Gui::Selection().addSelection(docName.c_str(),objName.c_str(),subName.c_str(),0,0,0); +} + +const std::string TaskFemConstraintTransform::getReferences() const +{ + std::vector items; + int rowsRect = ui->lw_Rect->model()->rowCount(); + for (int r = 0; r < rowsRect; r++) { + items.push_back(ui->lw_Rect->item(r)->text().toStdString()); + } + return TaskFemConstraint::getReferences(items); +} + +void TaskFemConstraintTransform::onReferenceDeleted() { + TaskFemConstraintTransform::removeFromSelection(); +} + +std::string TaskFemConstraintTransform::getDisplcementReferences(std::string showConstr="") +{ + return "members=FreeCAD.ActiveDocument.Analysis.Member\n\ +A = []\n\ +i = 0\n\ +ss = []\n\ +for member in members:\n\ + if member.isDerivedFrom(\"Fem::ConstraintDisplacement\"):\n\ + m = member.References\n\ + A.append(m)\n\ + if i >0:\n\ + p = p + m[0][1]\n\ + x = (A[0][0][0],p)\n\ + for t in range(len(m[0][1])):\n\ + ss.append(member)\n\ + else:\n\ + p = A[i][0][1]\n\ + x = (A[0][0][0],p)\n\ + for t in range(len(m[0][1])):\n\ + ss.append(member)\n\ + i = i+1\n\ +if i>0:\n\ + App.ActiveDocument."+showConstr+".RefDispl = [x]\n\ + App.ActiveDocument."+showConstr+".NameDispl = ss\n"; +} + +/* Note: */ +double TaskFemConstraintTransform::get_X_rot() const{return ui->sp_X->value();} +double TaskFemConstraintTransform::get_Y_rot() const{return ui->sp_Y->value();} +double TaskFemConstraintTransform::get_Z_rot() const{return ui->sp_Z->value();} + +std::string TaskFemConstraintTransform::get_transform_type(void) const { + std::string transform; + if (ui->rb_rect->isChecked()) { + transform = "\"Rectangular\""; + } else if (ui->rb_cylin->isChecked()) { + transform = "\"Cylindrical\""; + } + return transform; +} + +void TaskFemConstraintTransform::changeEvent(QEvent *e){ +} + +//************************************************************************** +// TaskDialog +//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +TaskDlgFemConstraintTransform::TaskDlgFemConstraintTransform(ViewProviderFemConstraintTransform *ConstraintView) +{ + this->ConstraintView = ConstraintView; + assert(ConstraintView); + this->parameter = new TaskFemConstraintTransform(ConstraintView);; + + Content.push_back(parameter); +} + +//==== calls from the TaskView =============================================================== + +void TaskDlgFemConstraintTransform::open() +{ + // a transaction is already open at creation time of the panel + if (!Gui::Command::hasPendingCommand()) { + QString msg = QObject::tr("Constraint transform"); + Gui::Command::openCommand((const char*)msg.toUtf8()); + ConstraintView->setVisible(true); + Gui::Command::doCommand(Gui::Command::Doc,ViewProviderFemConstraint::gethideMeshShowPartStr((static_cast(ConstraintView->getObject()))->getNameInDocument()).c_str()); //OvG: Hide meshes and show parts + } +} + +bool TaskDlgFemConstraintTransform::accept() +{ +/* Note: */ + std::string name = ConstraintView->getObject()->getNameInDocument(); + const TaskFemConstraintTransform* parameters = static_cast(parameter); + + try { + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.X_rot = %f", + name.c_str(), parameters->get_X_rot()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Y_rot = %f", + name.c_str(), parameters->get_Y_rot()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Z_rot = %f", + name.c_str(), parameters->get_Z_rot()); + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.TransformType = %s", + name.c_str(), parameters->get_transform_type().c_str()); + std::string scale = parameters->getScale(); //OvG: determine modified scale + Gui::Command::doCommand(Gui::Command::Doc,"App.ActiveDocument.%s.Scale = %s", name.c_str(), scale.c_str()); //OvG: implement modified scale + + } + catch (const Base::Exception& e) { + QMessageBox::warning(parameter, tr("Input error"), QString::fromLatin1(e.what())); + return false; + } +/* */ + return TaskDlgFemConstraint::accept(); +} + +bool TaskDlgFemConstraintTransform::reject() +{ + Gui::Command::abortCommand(); + Gui::Command::doCommand(Gui::Command::Gui,"Gui.activeDocument().resetEdit()"); + Gui::Command::updateActive(); + + return true; +} + +#include "moc_TaskFemConstraintTransform.cpp" diff --git a/src/Mod/Fem/Gui/TaskFemConstraintTransform.h b/src/Mod/Fem/Gui/TaskFemConstraintTransform.h new file mode 100644 index 000000000..ac2da9857 --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintTransform.h @@ -0,0 +1,94 @@ +/*************************************************************************** + * Copyright (c) 2015 FreeCAD Developers * + * Authors: Michael Hindley * + * Ruan Olwagen * + * Oswald van Ginkel * + * Ofentse Kgoa * + * Based on Force constraint by Jan Rheinländer * + * 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 * + * * + ***************************************************************************/ + +#ifndef GUI_TASKVIEW_TaskFemConstraintTransform_H +#define GUI_TASKVIEW_TaskFemConstraintTransform_H + +#include +#include +#include +#include + +#include "TaskFemConstraint.h" +#include "ViewProviderFemConstraintTransform.h" + +#include +#include +#include +#include + +class Ui_TaskFemConstraintTransform; + +namespace FemGui { +class TaskFemConstraintTransform : public TaskFemConstraint +{ + Q_OBJECT + +public: + TaskFemConstraintTransform(ViewProviderFemConstraintTransform *ConstraintView,QWidget *parent = 0); + ~TaskFemConstraintTransform(); + const std::string getReferences() const; + double get_X_rot()const; + double get_Y_rot()const; + double get_Z_rot()const; + std::string get_transform_type(void) const; + static std::string getDisplcementReferences(const std::string showConstr); + +private Q_SLOTS: + void onReferenceDeleted(void); + void Rect(); + void Cyl(); + void addToSelection(); + void removeFromSelection(); + void setSelection(QListWidgetItem* item); + void x_Changed(int x); + void y_Changed(int y); + void z_Changed(int z); + +protected: + void changeEvent(QEvent *e); + const QString makeText(const App::DocumentObject* obj) const; + +private: + //void onSelectionChanged(const Gui::SelectionChanges& msg); + void updateUI(); + Ui_TaskFemConstraintTransform* ui; +}; + +class TaskDlgFemConstraintTransform : public TaskDlgFemConstraint +{ + Q_OBJECT + +public: + TaskDlgFemConstraintTransform(ViewProviderFemConstraintTransform *ConstraintView); + void open(); + bool accept(); + bool reject(); +}; + +} //namespace FemGui + +#endif // GUI_TASKVIEW_TaskFemConstraintTransform_H diff --git a/src/Mod/Fem/Gui/TaskFemConstraintTransform.ui b/src/Mod/Fem/Gui/TaskFemConstraintTransform.ui new file mode 100644 index 000000000..8c0583abf --- /dev/null +++ b/src/Mod/Fem/Gui/TaskFemConstraintTransform.ui @@ -0,0 +1,194 @@ + + + TaskFemConstraintTransform + + + + 0 + 0 + 382 + 491 + + + + Form + + + + + + + + Rectangular transform + + + true + + + + + + + Cylindrical transform + + + true + + + + + + + + + Select a face, click Add or Remove + + + + + + + + + Add + + + + + + + Remove + + + + + + + + + + 0 + 0 + + + + + 16777215 + 31 + + + + + + + + 0 + + + + + + + + + Rotation about X-Axis + + + + + + + -360 + + + 360 + + + + + + + + + + + Rotation about Y-Axis + + + + + + + -360 + + + 360 + + + + + + + + + + + Rotation about Z-Axis + + + + + + + -360 + + + 360 + + + + + + + + + Transformable surfaces + + + + + + + + + + + + + + + + + + + Transformable surfaces + + + + + + + + + + + + + + + + + + + + diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.cpp b/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.cpp new file mode 100644 index 000000000..3ecaa03b3 --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.cpp @@ -0,0 +1,314 @@ +/*************************************************************************** + * Copyright (c) 2015 FreeCAD Developers * + * Authors: Michael Hindley * + * Ruan Olwagen * + * Oswald van Ginkel * + * Ofentse Kgoa * + * Based on Force constraint by Jan Rheinländer * + * This file is part of the FreeCAD CAx development system. * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Library General Public * + * License as published by the Free Software Foundation; either * + * version 2 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU Library General Public License for more details. * + * * + * You should have received a copy of the GNU Library General Public * + * License along with this library; see the file COPYING.LIB. If not, * + * write to the Free Software Foundation, Inc., 59 Temple Place, * + * Suite 330, Boston, MA 02111-1307, USA * + * * + ***************************************************************************/ + + +#include "PreCompiled.h" + +#ifndef _PreComp_ +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#endif +#include + +#include "Mod/Fem/App/FemConstraintTransform.h" +#include "TaskFemConstraintTransform.h" +#include "ViewProviderFemConstraintTransform.h" +#include +#include + +#include +#define PI (3.141592653589793238462643383279502884L) + +using namespace FemGui; + +PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintTransform, FemGui::ViewProviderFemConstraint) + +ViewProviderFemConstraintTransform::ViewProviderFemConstraintTransform() +{ + sPixmap = "fem-constraint-transform"; + // + //ADD_PROPERTY(FaceColor,(0.0f,0.2f,0.8f)); +} + +ViewProviderFemConstraintTransform::~ViewProviderFemConstraintTransform() +{ +} + +//FIXME setEdit needs a careful review +bool ViewProviderFemConstraintTransform::setEdit(int ModNum) +{ + if (ModNum == ViewProvider::Default) { + // When double-clicking on the item for this constraint the + // object unsets and sets its edit mode without closing + // the task panel + Gui::TaskView::TaskDialog *dlg = Gui::Control().activeDialog(); + TaskDlgFemConstraintTransform *constrDlg = qobject_cast(dlg); + if (constrDlg && constrDlg->getConstraintView() != this) + constrDlg = 0; // another constraint left open its task panel + if (dlg && !constrDlg) { + if (constraintDialog != NULL) { + // Ignore the request to open another dialog + return false; + } else { + constraintDialog = new TaskFemConstraintTransform(this); + return true; + } + } + + // clear the selection (convenience) + Gui::Selection().clearSelection(); + + // start the edit dialog + if (constrDlg) + Gui::Control().showDialog(constrDlg); + else + Gui::Control().showDialog(new TaskDlgFemConstraintTransform(this)); + return true; + } + else { + return ViewProviderDocumentObject::setEdit(ModNum); + } +} + +#define HEIGHTAXIS (20) +#define RADIUSAXIS (0.8) +#define ARROWLENGTH (3) +#define ARROWHEADRADIUS (ARROWLENGTH/3) +#define LENGHTDISC (0.25) +#define RADIUSDISC (0.8) + +void ViewProviderFemConstraintTransform::updateData(const App::Property* prop) +{ + // Gets called whenever a property of the attached object changes + Fem::ConstraintTransform* pcConstraint = static_cast(this->getObject()); + float scaledradiusaxis = RADIUSAXIS * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only + float scaledheightaxis = HEIGHTAXIS * pcConstraint->Scale.getValue(); + float scaledheadradiusA = ARROWHEADRADIUS * pcConstraint->Scale.getValue(); //OvG: Calculate scaled values once only + float scaledlengthA = ARROWLENGTH * pcConstraint->Scale.getValue(); + std::string transform_type = pcConstraint->TransformType.getValueAsString(); + if (transform_type == "Rectangular") { + + if (strcmp(prop->getName(),"Points") == 0) { + const std::vector& points = pcConstraint->Points.getValues(); + const std::vector& normals = pcConstraint->Normals.getValues(); + if (points.size() != normals.size()) + return; + std::vector::const_iterator n = normals.begin(); + + // Points and Normals are always updated together + pShapeSep->removeAllChildren(); + + for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { + SbVec3f base(p->x, p->y, p->z); + SbVec3f basex(p->x, p->y, p->z); + SbVec3f basey(p->x, p->y, p->z); + + double x_axis_x = 1; + double x_axis_y = 0; + double x_axis_z = 0; + + double y_axis_x = 0; + double y_axis_y = 1; + double y_axis_z = 0; + + double z_axis_x = 0; + double z_axis_y = 0; + double z_axis_z = 1; + + double rot_x = (pcConstraint->X_rot.getValue() * (PI/180)); + double rot_y = (pcConstraint->Y_rot.getValue() * (PI/180)); + double rot_z = (pcConstraint->Z_rot.getValue() * (PI/180)); + + double x_axis_x_p; + double x_axis_y_p; + double x_axis_z_p; + + double y_axis_x_p; + double y_axis_y_p; + double y_axis_z_p; + + double z_axis_x_p; + double z_axis_y_p; + double z_axis_z_p; + + if (rot_x!=0){ + x_axis_z_p = x_axis_z*cos(rot_x) - x_axis_y*sin(rot_x); + x_axis_y_p = x_axis_y*cos(rot_x) + x_axis_z*sin(rot_x); + x_axis_z = x_axis_z_p; + x_axis_y = x_axis_y_p; + + y_axis_z_p = y_axis_z*cos(rot_x) - y_axis_y*sin(rot_x); + y_axis_y_p = y_axis_y*cos(rot_x) + y_axis_z*sin(rot_x); + y_axis_z = y_axis_z_p; + y_axis_y = y_axis_y_p; + + z_axis_z_p = z_axis_z*cos(rot_x) - z_axis_y*sin(rot_x); + z_axis_y_p = z_axis_y*cos(rot_x) + z_axis_z*sin(rot_x); + z_axis_z = z_axis_z_p; + z_axis_y = z_axis_y_p; + } + if (rot_y != 0){ + x_axis_z_p = x_axis_z*cos(rot_y) + x_axis_x*sin(rot_y); + x_axis_x_p = x_axis_x*cos(rot_y) - x_axis_z*sin(rot_y); + x_axis_z = x_axis_z_p; + x_axis_x = x_axis_x_p; + + y_axis_z_p = y_axis_z*cos(rot_y) + y_axis_x*sin(rot_y); + y_axis_x_p = y_axis_x*cos(rot_y) - y_axis_z*sin(rot_y); + y_axis_z = y_axis_z_p; + y_axis_x = y_axis_x_p; + + z_axis_z_p = z_axis_z*cos(rot_y) + z_axis_x*sin(rot_y); + z_axis_x_p = z_axis_x*cos(rot_y) - z_axis_z*sin(rot_y); + z_axis_z = z_axis_z_p; + z_axis_x = z_axis_x_p; + } + if (rot_z !=0){ + x_axis_x_p = x_axis_x*cos(rot_z) + x_axis_y*sin(rot_z); + x_axis_y_p = x_axis_y*cos(rot_z) - x_axis_x*sin(rot_z); + x_axis_x = x_axis_x_p; + x_axis_y = x_axis_y_p; + + y_axis_x_p = y_axis_x*cos(rot_z) + y_axis_y*sin(rot_z); + y_axis_y_p = y_axis_y*cos(rot_z) - y_axis_x*sin(rot_z); + y_axis_x = y_axis_x_p; + y_axis_y = y_axis_y_p; + + z_axis_x_p = z_axis_x*cos(rot_z) + z_axis_y*sin(rot_z); + z_axis_y_p = z_axis_y*cos(rot_z) - z_axis_x*sin(rot_z); + z_axis_x = z_axis_x_p; + z_axis_y = z_axis_y_p; + } + + SbVec3f dirz(z_axis_x, z_axis_y ,z_axis_z); + SbRotation rot(SbVec3f(0, 1, 0), dirz); + + SbVec3f dirx(x_axis_x, x_axis_y ,x_axis_z); + SbRotation rotx(SbVec3f(0, 1, 0), dirx); + + SbVec3f diry(y_axis_x, y_axis_y ,y_axis_z); + SbRotation roty(SbVec3f(0, 1, 0), diry); + + base = base + dirz * scaledlengthA *0.75; + basex = basex + dirx * scaledlengthA*0.65; + basey = basey + diry * scaledlengthA*0.65; + + SoSeparator* sep = new SoSeparator(); + + SoMaterial* myMaterial = new SoMaterial; + myMaterial->diffuseColor.set1Value(0,SbColor(0,0,1));//RGB + sep->addChild(myMaterial); + + createPlacement(sep, base, rot); + createArrow(sep, scaledlengthA*0.75 , scaledheadradiusA*0.9); //OvG: Scaling + pShapeSep->addChild(sep); + + SoSeparator* sepx = new SoSeparator(); + + SoMaterial* myMaterialx = new SoMaterial; + myMaterialx->diffuseColor.set1Value(0,SbColor(1,0,0));//RGB + sepx->addChild(myMaterialx); + + createPlacement(sepx, basex, rotx); + createArrow(sepx, scaledlengthA*0.65 , scaledheadradiusA*0.65); //OvG: Scaling + pShapeSep->addChild(sepx); + + SoSeparator* sepy = new SoSeparator(); + + SoMaterial* myMaterialy = new SoMaterial; + myMaterialy->diffuseColor.set1Value(0,SbColor(0,1,0));//RGB + sepy->addChild(myMaterialy); + + createPlacement(sepy, basey, roty); + createArrow(sepy, scaledlengthA*0.65 , scaledheadradiusA*0.65); //OvG: Scaling + pShapeSep->addChild(sepy); + + n++; + } + + } + } else if (transform_type == "Cylindrical") { + + // Points and Normals are always updated together + pShapeSep->removeAllChildren(); + + const std::vector& points = pcConstraint->Points.getValues(); + const std::vector& normals = pcConstraint->Normals.getValues(); + + if (points.size() != normals.size()) + return; + std::vector::const_iterator n = normals.begin(); + + if (points.size() > 0) { + Base::Vector3d base = pcConstraint->BasePoint.getValue(); + Base::Vector3d axis = pcConstraint->Axis.getValue(); + + SbVec3f b(base.x, base.y, base.z); + SbVec3f ax(axis.x, axis.y, axis.z); + SbRotation rots(SbVec3f(0,-1,0), ax); + + b = b - ax * scaledheightaxis/2; + SoSeparator* sepAx = new SoSeparator(); + SoMaterial* myMaterial = new SoMaterial; + myMaterial->diffuseColor.set1Value(0,SbColor(0,0,1));//RGB + sepAx->addChild(myMaterial); + createPlacement(sepAx, b, rots); + createArrow(sepAx, scaledheightaxis, scaledradiusaxis); + pShapeSep->addChild(sepAx); + } + + for (std::vector::const_iterator p = points.begin(); p != points.end(); p++) { + SbVec3f base(p->x, p->y, p->z); + SbVec3f dir(n->x, n->y, n->z); + base = base + dir * scaledlengthA; //OvG: Scaling + SbRotation rot(SbVec3f(0, 1, 0), dir); + + SoSeparator* sep = new SoSeparator(); + SoMaterial* myMaterials = new SoMaterial; + myMaterials->diffuseColor.set1Value(0,SbColor(1,0,0));//RGB + sep->addChild(myMaterials); + createPlacement(sep, base, rot); + createArrow(sep, scaledlengthA , scaledheadradiusA); //OvG: Scaling + pShapeSep->addChild(sep); + n++; + } + } + + // Gets called whenever a property of the attached object changes + ViewProviderFemConstraint::updateData(prop); +} diff --git a/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.h b/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.h new file mode 100644 index 000000000..4fa00e1cc --- /dev/null +++ b/src/Mod/Fem/Gui/ViewProviderFemConstraintTransform.h @@ -0,0 +1,49 @@ +/*************************************************************************** + * Copyright (c) 2015 FreeCAD Developers * + * Authors: Michael Hindley * + * Ruan Olwagen * + * Oswald van Ginkel * + * Ofentse Kgoa * + * Based on Force constraint by Jan Rheinländer * + * 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 * + * * + ***************************************************************************/ + +#ifndef GUI_VIEWPROVIDERFEMCONSTRAINTTransform_H +#define GUI_VIEWPROVIDERFEMCONSTRAINTTransform_H + +#include "ViewProviderFemConstraint.h" + +namespace FemGui { + +class FemGuiExport ViewProviderFemConstraintTransform : public FemGui::ViewProviderFemConstraint +{ + PROPERTY_HEADER(FemGui::ViewProviderFemConstraintTransform); + +public: + ViewProviderFemConstraintTransform(); + virtual ~ViewProviderFemConstraintTransform(); + virtual void updateData(const App::Property*); + +protected: + virtual bool setEdit(int ModNum); +}; + +} + +#endif // GUI_VIEWPROVIDERFEMCONSTRAINTTransform_H diff --git a/src/Mod/Fem/Gui/Workbench.cpp b/src/Mod/Fem/Gui/Workbench.cpp index aaf82f115..95b449b5d 100755 --- a/src/Mod/Fem/Gui/Workbench.cpp +++ b/src/Mod/Fem/Gui/Workbench.cpp @@ -69,6 +69,7 @@ Gui::ToolBarItem* Workbench::setupToolBars() const << "Fem_ConstraintDisplacement" << "Fem_ConstraintPlaneRotation" << "Fem_ConstraintContact" + << "Fem_ConstraintTransform" << "Separator" << "Fem_ConstraintSelfWeight" << "Fem_ConstraintForce" @@ -128,6 +129,7 @@ Gui::MenuItem* Workbench::setupMenuBar() const << "Fem_ConstraintDisplacement" << "Fem_ConstraintPlaneRotation" << "Fem_ConstraintContact" + << "Fem_ConstraintTransform" << "Separator" << "Fem_ConstraintSelfWeight" << "Fem_ConstraintForce"