Fem: Constraint symbol scaling (#13274)

* Fem: Constraint symbols rescaling

* Fem: Add constraint symbol .iv files

* Fem: Fix contact constraint symbol rescaling

* Fem: Fix displacement constraint symbol rescaling

* Fem: Fix fixed constraint symbol rescaling

* Fem: Fix force constraint symbol rescaling

* Fem: Fix heat flux constraint symbol rescaling

* Fem: Fix plane rotation constraint symbol rescaling

* Fem: Fix pressure constraint symbol rescaling

* Fem: Fix spring constraint symbol rescaling

* Fem: Fix temperature constraint symbol rescaling

* Fem: Add tie constraint symbol
This commit is contained in:
marioalexis84
2024-04-22 12:49:13 -03:00
committed by GitHub
parent 5b81da0965
commit 7d4d5eddf5
32 changed files with 768 additions and 952 deletions

View File

@@ -74,9 +74,12 @@ using Adaptor3d_HSurface = Adaptor3d_Surface;
using BRepAdaptor_HSurface = BRepAdaptor_Surface;
#endif
static const App::PropertyFloatConstraint::Constraints scaleConstraint = {0.0, DBL_MAX, 0.1};
PROPERTY_SOURCE(Fem::Constraint, App::DocumentObject)
Constraint::Constraint()
: sizeFactor {1}
{
ADD_PROPERTY_TYPE(References,
(nullptr, nullptr),
@@ -90,10 +93,9 @@ Constraint::Constraint()
"Normal direction pointing outside of solid");
ADD_PROPERTY_TYPE(Scale,
(1),
"Base",
App::PropertyType(App::Prop_Output),
"Scale used for drawing constraints"); // OvG: Add scale parameter inherited
// by all derived constraints
"Constraint",
App::PropertyType(App::Prop_None),
"Scale used for drawing constraints");
ADD_PROPERTY_TYPE(Points,
(Base::Vector3d()),
"Constraint",
@@ -105,6 +107,8 @@ Constraint::Constraint()
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output | App::Prop_Hidden),
"Normals where symbols are drawn");
Scale.setConstraints(&scaleConstraint);
Points.setValues(std::vector<Base::Vector3d>());
Normals.setValues(std::vector<Base::Vector3d>());
@@ -128,23 +132,28 @@ App::DocumentObjectExecReturn* Constraint::execute()
}
// OvG: Provide the ability to determine how big to draw constraint arrows etc.
int Constraint::calcDrawScaleFactor(double lparam) const
unsigned int Constraint::calcSizeFactor(double lparam) const
{
return (static_cast<int>(round(log(lparam) * log(lparam) * log(lparam) / 10)) > 1)
? (static_cast<int>(round(log(lparam) * log(lparam) * log(lparam) / 10)))
: 1;
}
int Constraint::calcDrawScaleFactor(double lvparam, double luparam) const
unsigned int Constraint::calcSizeFactor(double lvparam, double luparam) const
{
return calcDrawScaleFactor((lvparam + luparam) / 2.0);
return calcSizeFactor((lvparam + luparam) / 2.0);
}
int Constraint::calcDrawScaleFactor() const
unsigned int Constraint::calcSizeFactor() const
{
return 1;
}
float Constraint::getScaleFactor() const
{
return Scale.getValue() * sizeFactor;
}
void setSubShapeLocation(const Part::Feature* feat, TopoDS_Shape& sh)
{
// subshape placement is not necessarily the same as the
@@ -200,11 +209,9 @@ void Constraint::onChanged(const App::Property* prop)
std::vector<Base::Vector3d> points;
std::vector<Base::Vector3d> normals;
int scale = 1;
if (getPoints(points, normals, &scale)) {
if (getPoints(points, normals, &sizeFactor)) {
Points.setValues(points);
Normals.setValues(normals);
Scale.setValue(scale);
Points.touch();
}
}
@@ -250,6 +257,19 @@ void Constraint::onDocumentRestored()
App::DocumentObject::onDocumentRestored();
}
void Constraint::handleChangedPropertyType(Base::XMLReader& reader,
const char* TypeName,
App::Property* prop)
{
// Old integer Scale is equal to sizeFactor, now Scale*sizeFactor is used to scale the symbol
if (prop == &Scale && strcmp(TypeName, "App::PropertyInteger") == 0) {
Scale.setValue(1.0f);
}
else {
App::DocumentObject::handleChangedPropertyType(reader, TypeName, prop);
}
}
bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
std::vector<Base::Vector3d>& normals,
int* scale) const
@@ -285,7 +305,7 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
BRepGProp::VolumeProperties(toposhape.getShape(), props);
double lx = props.Mass();
// OvG: setup draw scale for constraint
*scale = this->calcDrawScaleFactor(sqrt(lx) * 0.5);
*scale = this->calcSizeFactor(sqrt(lx) * 0.5);
}
else if (sh.ShapeType() == TopAbs_EDGE) {
BRepAdaptor_Curve curve(TopoDS::Edge(sh));
@@ -299,17 +319,17 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
int steps;
// OvG: Increase 10 units distance proportionately to l for larger objects.
if (l >= 30) {
*scale = this->calcDrawScaleFactor(l); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(l); // OvG: setup draw scale for constraint
steps = static_cast<int>(round(l / (10 * (*scale))));
steps = steps < 3 ? 3 : steps;
}
else if (l >= 20) {
steps = static_cast<int>(round(l / 10));
*scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
}
else {
steps = 1;
*scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
}
// OvG: Place upper limit on number of steps
@@ -387,19 +407,19 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
// OvG: Increase 10 units distance proportionately to lv for larger objects.
int stepsv;
if (lv >= 30) {
*scale = this->calcDrawScaleFactor(lv, lu); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(lv, lu); // OvG: setup draw scale for constraint
stepsv = static_cast<int>(round(lv / (10 * (*scale))));
stepsv = stepsv < 3 ? 3 : stepsv;
}
else if (lv >= 20.0) {
stepsv = static_cast<int>(round(lv / 10));
*scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
}
else {
// Minimum of three arrows to ensure (as much as possible) that at
// least one is displayed
stepsv = 2;
*scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
}
// OvG: Place upper limit on number of steps
@@ -407,17 +427,17 @@ bool Constraint::getPoints(std::vector<Base::Vector3d>& points,
int stepsu;
// OvG: Increase 10 units distance proportionately to lu for larger objects.
if (lu >= 30) {
*scale = this->calcDrawScaleFactor(lv, lu); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(lv, lu); // OvG: setup draw scale for constraint
stepsu = static_cast<int>(round(lu / (10 * (*scale))));
stepsu = stepsu < 3 ? 3 : stepsu;
}
else if (lu >= 20.0) {
stepsu = static_cast<int>(round(lu / 10));
*scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
}
else {
stepsu = 2;
*scale = this->calcDrawScaleFactor(); // OvG: setup draw scale for constraint
*scale = this->calcSizeFactor(); // OvG: setup draw scale for constraint
}
// OvG: Place upper limit on number of steps

View File

@@ -101,7 +101,7 @@ public:
* View Provider but it's always 1. It isn't updated when @ref References
* changes.
*/
App::PropertyInteger Scale;
App::PropertyFloatConstraint Scale;
// Read-only (calculated values). These trigger changes in the ViewProvider
App::PropertyVectorList Points;
@@ -133,7 +133,7 @@ public:
* This method does a really crazy calculation that I didn't dare to try
* to understand.
*/
int calcDrawScaleFactor(double lparam) const;
unsigned int calcSizeFactor(double lparam) const;
/**
* @brief Calculates scale factor based on size of face.
@@ -146,7 +146,7 @@ public:
* This method does a really crazy calculation that I didn't dare to try
* to understand.
*/
int calcDrawScaleFactor(double lvparam, double luparam) const;
unsigned int calcSizeFactor(double lvparam, double luparam) const;
/**
* @brief Returns default scale factor of 1.
@@ -159,13 +159,18 @@ public:
*
* @return always the integer 1
*/
int calcDrawScaleFactor() const;
unsigned int calcSizeFactor() const;
const char* getViewProviderName() const override
{
return "FemGui::ViewProviderFemConstraint";
}
/**
* @brief Returns Scale * sizeFactor.
*/
float getScaleFactor() const;
protected:
/**
* @brief Updates NormalDirection if References change.
@@ -182,6 +187,9 @@ protected:
void onDocumentRestored() override;
void onSettingDocument() override;
void unsetupObject() override;
void handleChangedPropertyType(Base::XMLReader& reader,
const char* TypeName,
App::Property* prop) override;
/**
* @brief Returns data based on References relevant for rendering widgets.
@@ -252,6 +260,11 @@ protected:
const Base::Vector3d getDirection(const App::PropertyLinkSub& direction);
private:
/**
* @brief Symbol size factor determined from the size of the shape.
*/
int sizeFactor;
void slotChangedObject(const App::DocumentObject& Obj, const App::Property& Prop);
boost::signals2::connection connDocChangedObject;
};

View File

@@ -63,12 +63,3 @@ void ConstraintPressure::handleChangedPropertyType(Base::XMLReader& reader,
Constraint::handleChangedPropertyType(reader, TypeName, prop);
}
}
void ConstraintPressure::onChanged(const App::Property* prop)
{
Constraint::onChanged(prop);
if (prop == &Reversed) {
Points.touch();
}
}

View File

@@ -50,7 +50,6 @@ protected:
void handleChangedPropertyType(Base::XMLReader& reader,
const char* TypeName,
App::Property* prop) override;
void onChanged(const App::Property* prop) override;
};
} // namespace Fem

View File

@@ -346,12 +346,27 @@ SET(FemGuiIcon_SVG
Resources/icons/FemWorkbench.svg
)
add_library(FemGui SHARED ${FemGui_SRCS} ${FemGuiIcon_SVG})
SET(FemGuiSymbol_IV
Resources/symbols/ConstraintContact.iv
Resources/symbols/ConstraintDisplacement.iv
Resources/symbols/ConstraintFixed.iv
Resources/symbols/ConstraintForce.iv
Resources/symbols/ConstraintHeatFlux.iv
Resources/symbols/ConstraintPlaneRotation.iv
Resources/symbols/ConstraintPressure.iv
Resources/symbols/ConstraintSpring.iv
Resources/symbols/ConstraintTemperature.iv
Resources/symbols/ConstraintTie.iv
)
add_library(FemGui SHARED ${FemGui_SRCS} ${FemGuiIcon_SVG} ${FemGuiSymbol_IV})
target_link_libraries(FemGui ${FemGui_LIBS} ${VTK_LIBRARIES})
fc_copy_sources(FemGui "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Fem" ${FemGuiIcon_SVG})
fc_copy_sources(FemGui "${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_DATADIR}/Mod/Fem" ${FemGuiSymbol_IV})
INSTALL(FILES ${FemGuiIcon_SVG} DESTINATION "${CMAKE_INSTALL_DATADIR}/Mod/Fem/Resources/icons")
INSTALL(FILES ${FemGuiSymbol_IV} DESTINATION "${CMAKE_INSTALL_DATADIR}/Mod/Fem/Resources/symbols")
# Python modules ui files, they are copied as they are, thus the need not to be added to Fem.qrc
# see https://forum.freecad.org/viewtopic.php?f=10&t=25833

View File

@@ -0,0 +1,19 @@
#Inventor V2.1 ascii
Separator {
Separator {
Translation {
translation 0 0.0625 0
}
Cube {
width 0.375
height 0.125
depth 0.75
}
}
}

View File

@@ -0,0 +1,93 @@
#Inventor V2.1 ascii
Separator {
Separator {
DEF X_DISPLACEMENT Switch {
Separator {
Rotation {
rotation 0 0 1 1.5707964
}
DEF DISPLACEMENT Separator {
Translation {
translation 0 -2 0
}
Cone {
bottomRadius 0.3
height 4
}
}
}
}
DEF Y_DISPLACEMENT Switch {
Separator {
Rotation {
rotation 0 0 1 3.1415927
}
USE DISPLACEMENT
}
}
DEF Z_DISPLACEMENT Switch {
Separator {
Rotation {
rotation -1 0 0 1.5707964
}
USE DISPLACEMENT
}
}
DEF X_ROTATION Switch {
Separator {
Rotation {
rotation 0 0 1 1.5707964
}
DEF ROTATION Separator {
Cylinder {
radius 2
height 0.15
}
}
}
}
DEF Y_ROTATION Switch {
Separator {
Rotation {
rotation 0 0 1 0
}
USE ROTATION
}
}
DEF Z_ROTATION Switch {
Separator {
Rotation {
rotation 1 0 0 1.5707964
}
USE ROTATION
}
}
}
}

View File

@@ -0,0 +1,32 @@
#Inventor V2.1 ascii
Separator {
Separator {
Rotation {
rotation 1 0 0 3.1415927
}
Translation {
translation 0 -0.25 0
}
Cone {
bottomRadius 0.5
height 0.5
}
Translation {
translation 0 -0.525 0
}
Cube {
width 2
height 0.5
depth 2
}
}
}

View File

@@ -0,0 +1,26 @@
#Inventor V2.1 ascii
Separator {
Separator {
Translation {
translation 0 3.3333334 0
}
Cone {
bottomRadius 0.66666669
height 1.3333334
}
Translation {
translation 0 -2 0
}
Cylinder {
radius 0.26666668
height 2.6666667
}
}
}

View File

@@ -0,0 +1,48 @@
#Inventor V2.1 ascii
Separator {
Separator {
Translation {
translation 0 0.225 0
}
Sphere {
radius 0.225
}
Translation {
translation 0 0.5625 0
}
Cylinder {
radius 0.1125
height 0.75
}
Translation {
translation 0 0.5625 0
}
Material {
diffuseColor 1 1 1
}
Cylinder {
radius 0.1125
height 0.375
}
Translation {
translation 0 -0.5625 0
}
Cylinder {
radius 0.3
height 0.075
}
}
}

View File

@@ -0,0 +1,18 @@
#Inventor V2.1 ascii
Separator {
Separator {
Translation {
translation 0 0.125 0
}
Cylinder {
radius 1.25
height 0.25
}
}
}

View File

@@ -0,0 +1,30 @@
#Inventor V2.1 ascii
Separator {
Separator {
Rotation {
rotation 1 0 0 3.1415927
}
Translation {
translation 0 -0.66666669 0
}
Cone {
bottomRadius 0.66666669
height 1.3333334
}
Translation {
translation 0 -2 0
}
Cylinder {
radius 0.26666668
height 2.6666667
}
}
}

View File

@@ -0,0 +1,28 @@
#Inventor V2.1 ascii
Separator {
Separator {
Translation {
translation 0 0.5 0
}
Cube {
width 1
height 1
depth 1
}
Translation {
translation 0 1 0
}
Cylinder {
radius 0.25
height 1
}
}
}

View File

@@ -0,0 +1,39 @@
#Inventor V2.1 ascii
Separator {
Separator {
Translation {
translation 0 0.225 0
}
Sphere {
radius 0.225
}
Translation {
translation 0 0.5625 0
}
Cylinder {
radius 0.1125
height 0.75
}
Translation {
translation 0 0.5625 0
}
Material {
diffuseColor 1 1 1
}
Cylinder {
radius 0.1125
height 0.375
}
}
}

View File

@@ -0,0 +1,18 @@
#Inventor V2.1 ascii
Separator {
Separator {
Translation {
translation 0 0.0625 0
}
Cylinder {
radius 0.375
height 0.125
}
}
}

View File

@@ -29,6 +29,7 @@
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoFontStyle.h>
#include <Inventor/nodes/SoMultipleCopy.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoShapeHints.h>
@@ -40,10 +41,12 @@
#include <QStackedWidget>
#endif
#include "App/Application.h"
#include "Gui/Command.h"
#include "Gui/Control.h"
#include "Gui/Document.h"
#include "Gui/MainWindow.h"
#include "Mod/Fem/App/FemConstraint.h"
#include "TaskFemConstraint.h"
#include "ViewProviderFemConstraint.h"
@@ -56,6 +59,13 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraint, Gui::ViewProviderGeometryObje
ViewProviderFemConstraint::ViewProviderFemConstraint()
: rotateSymbol(true)
, pSymbol(nullptr)
, pExtraSymbol(nullptr)
, ivFile(nullptr)
, wizardWidget(nullptr)
, wizardSubLayout(nullptr)
, constraintDialog(nullptr)
{
ADD_PROPERTY(TextColor, (0.0f, 0.0f, 0.0f));
ADD_PROPERTY(FaceColor, (1.0f, 0.0f, 0.2f));
@@ -69,22 +79,19 @@ ViewProviderFemConstraint::ViewProviderFemConstraint()
pLabel->ref();
pTextColor = new SoBaseColor();
pTextColor->ref();
pShapeSep = new SoSeparator();
pShapeSep->ref();
pMultCopy = new SoMultipleCopy();
pMultCopy->ref();
pMaterials = new SoBaseColor();
pMaterials->ref();
pMaterials->rgb.setValue(1.0f, 0.0f, 0.2f);
pShapeSep = new SoSeparator();
pShapeSep->ref();
TextColor.touch();
FontSize.touch();
FaceColor.touch();
wizardWidget = nullptr;
wizardSubLayout = nullptr;
constraintDialog = nullptr;
Gui::ViewProviderSuppressibleExtension::initExtension(this);
}
@@ -94,6 +101,7 @@ ViewProviderFemConstraint::~ViewProviderFemConstraint()
pLabel->unref();
pTextColor->unref();
pMaterials->unref();
pMultCopy->unref();
pShapeSep->unref();
}
@@ -115,6 +123,41 @@ void ViewProviderFemConstraint::attach(App::DocumentObject* pcObject)
addDisplayMaskMode(sep, "Base");
}
std::string ViewProviderFemConstraint::resourceSymbolDir =
App::Application::getResourceDir() + "Mod/Fem/Resources/symbols/";
void ViewProviderFemConstraint::loadSymbol(const char* fileName)
{
ivFile = fileName;
SoInput in;
if (!in.openFile(ivFile)) {
std::stringstream str;
str << "Error opening symbol file " << fileName;
throw Base::ImportError(str.str());
}
SoSeparator* nodes = SoDB::readAll(&in);
if (!nodes) {
std::stringstream str;
str << "Error reading symbol file " << fileName;
throw Base::ImportError(str.str());
}
nodes->ref();
pSymbol = dynamic_cast<SoSeparator*>(nodes->getChild(0));
pShapeSep->addChild(pMultCopy);
if (pSymbol) {
pMultCopy->addChild(pSymbol);
}
if (nodes->getNumChildren() == 2) {
pExtraSymbol = dynamic_cast<SoSeparator*>(nodes->getChild(1));
if (pExtraSymbol) {
pShapeSep->addChild(pExtraSymbol);
}
}
pMultCopy->matrix.setNum(0);
nodes->unref();
}
std::vector<std::string> ViewProviderFemConstraint::getDisplayModes() const
{
// add modes
@@ -148,7 +191,7 @@ void ViewProviderFemConstraint::setupContextMenu(QMenu* menu, QObject* receiver,
void ViewProviderFemConstraint::onChanged(const App::Property* prop)
{
if (prop == &Mirror || prop == &DistFactor) {
if (prop == &Mirror) {
updateData(prop);
}
else if (prop == &TextColor) {
@@ -167,6 +210,51 @@ void ViewProviderFemConstraint::onChanged(const App::Property* prop)
}
}
void ViewProviderFemConstraint::updateData(const App::Property* prop)
{
auto pcConstraint = static_cast<const Fem::Constraint*>(this->getObject());
if (prop == &pcConstraint->Points || prop == &pcConstraint->Normals
|| prop == &pcConstraint->Scale) {
updateSymbol();
}
else {
ViewProviderGeometryObject::updateData(prop);
}
}
void ViewProviderFemConstraint::updateSymbol()
{
auto obj = static_cast<const Fem::Constraint*>(this->getObject());
const std::vector<Base::Vector3d>& points = obj->Points.getValue();
const std::vector<Base::Vector3d>& normals = obj->Normals.getValue();
pMultCopy->matrix.setNum(points.size());
SbMatrix* mat = pMultCopy->matrix.startEditing();
for (size_t i = 0; i < points.size(); ++i) {
transformSymbol(points[i], normals[i], mat[i]);
}
pMultCopy->matrix.finishEditing();
}
void ViewProviderFemConstraint::transformSymbol(const Base::Vector3d& point,
const Base::Vector3d& normal,
SbMatrix& mat) const
{
auto obj = static_cast<const Fem::Constraint*>(this->getObject());
SbVec3f axisY(0, 1, 0);
float s = obj->getScaleFactor();
SbVec3f scale(s, s, s);
SbVec3f norm = rotateSymbol ? SbVec3f(normal.x, normal.y, normal.z) : axisY;
SbRotation rot(axisY, norm);
SbVec3f tra(static_cast<float>(point.x),
static_cast<float>(point.y),
static_cast<float>(point.z));
mat.setTransform(tra, rot, scale);
}
// OvG: Visibility automation show parts and hide meshes on activation of a constraint
std::string ViewProviderFemConstraint::gethideMeshShowPartStr(const std::string showConstr)
{

View File

@@ -34,12 +34,12 @@
#include <Gui/ViewProviderSuppressibleExtension.h>
class SbRotation;
class SoFontStyle;
class SoText2;
class SoBaseColor;
class SoTranslation;
class SbRotation;
class SoMaterial;
class SoMultipleCopy;
namespace FemGui
{
@@ -64,10 +64,7 @@ public:
App::PropertyBool Mirror;
void attach(App::DocumentObject*) override;
void updateData(const App::Property* prop) override
{
Gui::ViewProviderGeometryObject::updateData(prop);
}
void updateData(const App::Property* prop) override;
std::vector<std::string> getDisplayModes() const override;
void setDisplayMode(const char* ModeName) override;
@@ -80,10 +77,19 @@ public:
virtual void highlightReferences(const bool /* on */)
{}
SoSeparator* getSymbolSeparator() const
{
return pShapeSep;
}
SoSeparator* getSymbolSeparator() const;
SoSeparator* getExtraSymbolSeparator() const;
// Apply rotation on copies of the constraint symbol
void setRotateSymbol(bool rotate);
bool getRotateSymbol() const;
/** Load constraint symbol from Open Inventor file
* The file structure should be as follows:
* A separator containing a separator with the symbol used in multiple
* copies at points on the surface and an optional separator with a symbol
* excluded from multiple copies.
*/
void loadSymbol(const char* fileName);
static std::string gethideMeshShowPartStr();
static std::string gethideMeshShowPartStr(const std::string showConstr);
@@ -93,6 +99,10 @@ protected:
bool setEdit(int ModNum) override;
void unsetEdit(int ModNum) override;
void updateSymbol();
virtual void
transformSymbol(const Base::Vector3d& point, const Base::Vector3d& normal, SbMatrix& mat) const;
static void createPlacement(SoSeparator* sep, const SbVec3f& base, const SbRotation& r);
static void updatePlacement(const SoSeparator* sep,
const int idx,
@@ -159,9 +169,16 @@ private:
SoText2* pLabel;
SoBaseColor* pTextColor;
SoBaseColor* pMaterials;
bool rotateSymbol;
protected:
SoSeparator* pShapeSep;
SoSeparator* pSymbol;
SoSeparator* pExtraSymbol;
SoMultipleCopy* pMultCopy;
const char* ivFile;
static std::string resourceSymbolDir;
// Shaft design wizard integration
protected:
@@ -174,6 +191,27 @@ protected:
static QObject* findChildByName(const QObject* parent, const QString& name);
};
inline SoSeparator* ViewProviderFemConstraint::getSymbolSeparator() const
{
return pSymbol;
}
inline SoSeparator* ViewProviderFemConstraint::getExtraSymbolSeparator() const
{
return pExtraSymbol;
}
inline bool ViewProviderFemConstraint::getRotateSymbol() const
{
return rotateSymbol;
}
inline void ViewProviderFemConstraint::setRotateSymbol(bool rotate)
{
rotateSymbol = rotate;
}
using ViewProviderFemConstraintPython = Gui::ViewProviderPythonFeatureT<ViewProviderFemConstraint>;

View File

@@ -26,11 +26,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/nodes/SoCube.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoTranslation.h>
#endif
#include "Mod/Fem/App/FemConstraintContact.h"
@@ -46,6 +41,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintContact, FemGui::ViewProviderFe
ViewProviderFemConstraintContact::ViewProviderFemConstraintContact()
{
sPixmap = "FEM_ConstraintContact";
loadSymbol((resourceSymbolDir + "ConstraintContact.iv").c_str());
// Note change "Contact" in line above to new constraint name, make sure it is the same as in
// taskFem* cpp file
ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f));
@@ -93,75 +89,7 @@ bool ViewProviderFemConstraintContact::setEdit(int ModNum)
}
}
#define HEIGHT (0.5)
#define LENGTH (1.5)
#define WIDTH (0.5)
// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing -
// so disable
void ViewProviderFemConstraintContact::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintContact* pcConstraint = static_cast<Fem::ConstraintContact*>(this->getObject());
float scaledlength =
LENGTH * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
float scaledheight = HEIGHT * pcConstraint->Scale.getValue();
float scaledwidth = WIDTH * pcConstraint->Scale.getValue();
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
if (points.size() != normals.size()) {
return;
}
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
// Points and Normals are always updated together
Gui::coinRemoveAllChildren(pShapeSep);
for (const auto& point : points) {
// Define base and normal directions
SbVec3f base(point.x, point.y, point.z);
SbVec3f dir(n->x, n->y, n->z); // normal
/// Visual indication
// define separator
SoSeparator* sep = new SoSeparator();
// first move to correct position
SoTranslation* trans = new SoTranslation();
SbVec3f newPos = base + scaledheight * dir * 0.12f;
trans->translation.setValue(newPos);
sep->addChild(trans);
// adjust orientation
SoRotation* rot = new SoRotation();
rot->rotation.setValue(SbRotation(SbVec3f(0, 1, 0), dir));
sep->addChild(rot);
// define color of shape
SoMaterial* myMaterial = new SoMaterial;
myMaterial->diffuseColor.set1Value(0, SbColor(1, 1, 1)); // RGB
// myMaterial->diffuseColor.set1Value(1,SbColor(0,0,1));//possible to adjust sides
// separately
sep->addChild(myMaterial);
// draw a cube
SoCube* cbe = new SoCube();
cbe->depth.setValue(scaledlength * 0.5);
cbe->height.setValue(scaledheight * 0.25);
cbe->width.setValue(scaledwidth * 0.75);
sep->addChild(cbe);
// translate position
SoTranslation* trans2 = new SoTranslation();
trans2->translation.setValue(SbVec3f(0, 0, 0));
sep->addChild(trans2);
pShapeSep->addChild(sep);
n++;
}
}
// Gets called whenever a property of the attached object changes
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -26,10 +26,8 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/SbRotation.h>
#include <Inventor/SbVec3f.h>
#include <Inventor/nodes/SoMultipleCopy.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSwitch.h>
#endif
#include "Mod/Fem/App/FemConstraintDisplacement.h"
@@ -46,7 +44,11 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintDisplacement,
ViewProviderFemConstraintDisplacement::ViewProviderFemConstraintDisplacement()
{
sPixmap = "FEM_ConstraintDisplacement";
loadSymbol((resourceSymbolDir + "ConstraintDisplacement.iv").c_str());
ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f));
// do not rotate symbol according to boundary normal
setRotateSymbol(false);
}
ViewProviderFemConstraintDisplacement::~ViewProviderFemConstraintDisplacement() = default;
@@ -92,211 +94,36 @@ bool ViewProviderFemConstraintDisplacement::setEdit(int ModNum)
}
}
#define HEIGHT (4)
#define WIDTH (0.3)
// #define USE_MULTIPLE_COPY
// OvG: MULTICOPY fails to update scaled display on initial drawing - so disable
void ViewProviderFemConstraintDisplacement::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintDisplacement* pcConstraint =
static_cast<Fem::ConstraintDisplacement*>(this->getObject());
// OvG: Calculate scaled values once only
float scaledwidth = WIDTH * pcConstraint->Scale.getValue();
float scaledheight = HEIGHT * pcConstraint->Scale.getValue();
bool xFree = pcConstraint->xFree.getValue();
bool yFree = pcConstraint->yFree.getValue();
bool zFree = pcConstraint->zFree.getValue();
bool rotxFree = pcConstraint->rotxFree.getValue();
bool rotyFree = pcConstraint->rotyFree.getValue();
bool rotzFree = pcConstraint->rotzFree.getValue();
#ifdef USE_MULTIPLE_COPY
// OvG: always need access to cp for scaling
SoMultipleCopy* cpx = new SoMultipleCopy();
SoMultipleCopy* cpy = new SoMultipleCopy();
SoMultipleCopy* cpz = new SoMultipleCopy();
SoMultipleCopy* cprotx = new SoMultipleCopy();
SoMultipleCopy* cproty = new SoMultipleCopy();
SoMultipleCopy* cprotz = new SoMultipleCopy();
if (pShapeSep->getNumChildren() == 0) {
// Set up the nodes
cpx->matrix.setNum(0);
cpx->addChild((SoNode*)createDisplacement(scaledheight, scaledwidth)); // OvG: Scaling
cpy->matrix.setNum(0);
cpy->addChild((SoNode*)createDisplacement(scaledheight, scaledwidth)); // OvG: Scaling
cpz->matrix.setNum(0);
cpz->addChild((SoNode*)createDisplacement(scaledheight, scaledwidth)); // OvG: Scaling
cprotx->matrix.setNum(0);
cprotx->addChild((SoNode*)createRotation(scaledheight, scaledwidth)); // OvG: Scaling
cproty->matrix.setNum(0);
cproty->addChild((SoNode*)createRotation(scaledheight, scaledwidth)); // OvG: Scaling
cprotz->matrix.setNum(0);
cprotz->addChild((SoNode*)createRotation(scaledheight, scaledwidth)); // OvG: Scaling
pShapeSep->addChild(cpx);
pShapeSep->addChild(cpy);
pShapeSep->addChild(cpz);
pShapeSep->addChild(cprotx);
pShapeSep->addChild(cproty);
pShapeSep->addChild(cprotz;
if (prop == &pcConstraint->xFree) {
auto sw = static_cast<SoSwitch*>(getSymbolSeparator()->getChild(0));
sw->whichChild.setValue((pcConstraint->xFree.getValue() ? -1 : 0));
}
#endif
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
if (points.size() != normals.size()) {
return;
}
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
#ifdef USE_MULTIPLE_COPY
cpx = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
cpx->matrix.setNum(points.size());
SbMatrix* matricesx = cpx->matrix.startEditing();
cpy = static_cast<SoMultipleCopy*>(pShapeSep->getChild(1));
cpy->matrix.setNum(points.size());
SbMatrix* matricesy = cpy->matrix.startEditing();
cpz = static_cast<SoMultipleCopy*>(pShapeSep->getChild(2));
cpz->matrix.setNum(points.size());
SbMatrix* matricesz = cpz->matrix.startEditing();
cprotx = static_cast<SoMultipleCopy*>(pShapeSep->getChild(3));
cprotx->matrix.setNum(points.size());
SbMatrix* matricesrotx = cprotx->matrix.startEditing();
cproty = static_cast<SoMultipleCopy*>(pShapeSep->getChild(4));
cproty->matrix.setNum(points.size());
SbMatrix* matricesroty = cproty->matrix.startEditing();
cprotz = static_cast<SoMultipleCopy*>(pShapeSep->getChild(5));
cprotz->matrix.setNum(points.size());
SbMatrix* matricesrotz = cprotz->matrix.startEditing();
int idx = 0;
int idy = 0;
int idz = 0;
int idrotx = 0;
int idroty = 0;
int idrotz = 0;
#else
// Note: Points and Normals are always updated together
Gui::coinRemoveAllChildren(pShapeSep);
#endif
for (const auto& point : points) {
SbVec3f base(point.x, point.y, point.z);
SbVec3f dirx(1, 0, 0); // OvG: Make relevant to global axes
SbVec3f diry(0, 1, 0); // OvG: Make relevant to global axes
SbVec3f dirz(0, 0, 1); // OvG: Make relevant to global axes
SbRotation rotx(SbVec3f(0, -1, 0), dirx); // OvG Tri-cones
SbRotation roty(SbVec3f(0, -1, 0), diry);
SbRotation rotz(SbVec3f(0, -1, 0), dirz);
#ifdef USE_MULTIPLE_COPY
SbMatrix mx;
SbMatrix my;
SbMatrix mz;
// OvG: Translation indication
if (!xFree) {
SbMatrix mx;
mx.setTransform(base, rotx, SbVec3f(1, 1, 1));
matricesx[idx] = mx;
idx++;
}
if (!yFree) {
SbMatrix my;
my.setTransform(base, roty, SbVec3f(1, 1, 1));
matricesy[idy] = my;
idy++;
}
if (!zFree) {
SbMatrix mz;
mz.setTransform(base, rotz, SbVec3f(1, 1, 1));
matricesz[idz] = mz;
idz++;
}
// OvG: Rotation indication
if (!rotxFree) {
SbMatrix mrotx;
mrotx.setTransform(base, rotx, SbVec3f(1, 1, 1));
matricesrotx[idrotx] = mrotx;
idrotx++;
}
if (!rotyFree) {
SbMatrix mroty;
mroty.setTransform(base, roty, SbVec3f(1, 1, 1));
matricesroty[idroty] = mroty;
idroty++;
}
if (!rotzFree) {
SbMatrix mrotz;
mrotz.setTransform(base, rotz, SbVec3f(1, 1, 1));
matricesrotz[idrotz] = mrotz;
idrotz++;
}
#else
// OvG: Translation indication
if (!xFree) {
SoSeparator* sepx = new SoSeparator();
createPlacement(sepx, base, rotx);
createDisplacement(sepx, scaledheight, scaledwidth); // OvG: Scaling
pShapeSep->addChild(sepx);
}
if (!yFree) {
SoSeparator* sepy = new SoSeparator();
createPlacement(sepy, base, roty);
createDisplacement(sepy, scaledheight, scaledwidth); // OvG: Scaling
pShapeSep->addChild(sepy);
}
if (!zFree) {
SoSeparator* sepz = new SoSeparator();
createPlacement(sepz, base, rotz);
createDisplacement(sepz, scaledheight, scaledwidth); // OvG: Scaling
pShapeSep->addChild(sepz);
}
// OvG: Rotation indication
if (!rotxFree) {
SoSeparator* sepx = new SoSeparator();
createPlacement(sepx, base, rotx);
createRotation(sepx, scaledheight, scaledwidth); // OvG: Scaling
pShapeSep->addChild(sepx);
}
if (!rotyFree) {
SoSeparator* sepy = new SoSeparator();
createPlacement(sepy, base, roty);
createRotation(sepy, scaledheight, scaledwidth); // OvG: Scaling
pShapeSep->addChild(sepy);
}
if (!rotzFree) {
SoSeparator* sepz = new SoSeparator();
createPlacement(sepz, base, rotz);
createRotation(sepz, scaledheight, scaledwidth); // OvG: Scaling
pShapeSep->addChild(sepz);
}
#endif
n++;
}
#ifdef USE_MULTIPLE_COPY
cpx->matrix.finishEditing();
cpy->matrix.finishEditing();
cpz->matrix.finishEditing();
cprotx->matrix.finishEditing();
cproty->matrix.finishEditing();
cprotz->matrix.finishEditing();
#endif
else if (prop == &pcConstraint->yFree) {
auto sw = static_cast<SoSwitch*>(getSymbolSeparator()->getChild(1));
sw->whichChild.setValue((pcConstraint->yFree.getValue() ? -1 : 0));
}
else if (prop == &pcConstraint->zFree) {
auto sw = static_cast<SoSwitch*>(getSymbolSeparator()->getChild(2));
sw->whichChild.setValue((pcConstraint->zFree.getValue() ? -1 : 0));
}
else if (prop == &pcConstraint->rotxFree) {
auto sw = static_cast<SoSwitch*>(getSymbolSeparator()->getChild(3));
sw->whichChild.setValue((pcConstraint->rotxFree.getValue() ? -1 : 0));
}
else if (prop == &pcConstraint->rotyFree) {
auto sw = static_cast<SoSwitch*>(getSymbolSeparator()->getChild(4));
sw->whichChild.setValue((pcConstraint->rotyFree.getValue() ? -1 : 0));
}
else if (prop == &pcConstraint->rotzFree) {
auto sw = static_cast<SoSwitch*>(getSymbolSeparator()->getChild(5));
sw->whichChild.setValue((pcConstraint->rotzFree.getValue() ? -1 : 0));
}
else {
ViewProviderFemConstraint::updateData(prop);
}
// Gets called whenever a property of the attached object changes
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -46,6 +46,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintFixed, FemGui::ViewProviderFemC
ViewProviderFemConstraintFixed::ViewProviderFemConstraintFixed()
{
sPixmap = "FEM_ConstraintFixed";
loadSymbol((resourceSymbolDir + "ConstraintFixed.iv").c_str());
}
ViewProviderFemConstraintFixed::~ViewProviderFemConstraintFixed() = default;
@@ -108,69 +109,7 @@ bool ViewProviderFemConstraintFixed::setEdit(int ModNum)
}
}
#define WIDTH (2)
#define HEIGHT (1)
// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing -
// so disable
void ViewProviderFemConstraintFixed::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintFixed* pcConstraint = static_cast<Fem::ConstraintFixed*>(this->getObject());
float scaledwidth =
WIDTH * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
float scaledheight = HEIGHT * pcConstraint->Scale.getValue();
#ifdef USE_MULTIPLE_COPY
// OvG: always need access to cp for scaling
SoMultipleCopy* cp = new SoMultipleCopy();
if (pShapeSep->getNumChildren() == 0) {
// Set up the nodes
cp->matrix.setNum(0);
cp->addChild((SoNode*)createFixed(scaledheight, scaledwidth)); // OvG: Scaling
pShapeSep->addChild(cp);
}
#endif
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
if (points.size() != normals.size()) {
return;
}
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
#ifdef USE_MULTIPLE_COPY
cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
cp->matrix.setNum(points.size());
SbMatrix* matrices = cp->matrix.startEditing();
int idx = 0;
#else
// Note: Points and Normals are always updated together
Gui::coinRemoveAllChildren(pShapeSep);
#endif
for (const auto& point : points) {
SbVec3f base(point.x, point.y, point.z);
SbVec3f dir(n->x, n->y, n->z);
SbRotation rot(SbVec3f(0, -1, 0), dir);
#ifdef USE_MULTIPLE_COPY
SbMatrix m;
m.setTransform(base, rot, SbVec3f(1, 1, 1));
matrices[idx] = m;
idx++;
#else
SoSeparator* sep = new SoSeparator();
createPlacement(sep, base, rot);
createFixed(sep, scaledheight, scaledwidth); // OvG: Scaling
pShapeSep->addChild(sep);
#endif
n++;
}
#ifdef USE_MULTIPLE_COPY
cp->matrix.finishEditing();
#endif
}
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -24,11 +24,9 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/SbMatrix.h>
#include <Inventor/SbRotation.h>
#include <Inventor/SbVec3f.h>
#include <Inventor/nodes/SoMultipleCopy.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Precision.hxx>
#include <QMessageBox>
#endif
@@ -47,6 +45,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintForce, FemGui::ViewProviderFemC
ViewProviderFemConstraintForce::ViewProviderFemConstraintForce()
{
sPixmap = "FEM_ConstraintForce";
loadSymbol((resourceSymbolDir + "ConstraintForce.iv").c_str());
}
ViewProviderFemConstraintForce::~ViewProviderFemConstraintForce() = default;
@@ -109,117 +108,41 @@ bool ViewProviderFemConstraintForce::setEdit(int ModNum)
}
}
#define ARROWLENGTH (4)
#define ARROWHEADRADIUS (ARROWLENGTH / 3.0f)
// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so
// disable
void ViewProviderFemConstraintForce::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintForce* pcConstraint = static_cast<Fem::ConstraintForce*>(this->getObject());
float scaledheadradius =
ARROWHEADRADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue();
auto pcConstraint = static_cast<Fem::ConstraintForce*>(this->getObject());
#ifdef USE_MULTIPLE_COPY
// OvG: need access to cp for scaling
SoMultipleCopy* cp = new SoMultipleCopy();
if (pShapeSep->getNumChildren() == 0) {
// Set up the nodes
cp->matrix.setNum(0);
cp->addChild((SoNode*)createArrow(scaledlength, scaledheadradius)); // OvG: Scaling
pShapeSep->addChild(cp);
if (prop == &pcConstraint->Reversed || prop == &pcConstraint->DirectionVector) {
updateSymbol();
}
#endif
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
#ifdef USE_MULTIPLE_COPY
cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
cp->matrix.setNum(points.size());
SbMatrix* matrices = cp->matrix.startEditing();
int idx = 0;
#else
// Redraw all arrows
Gui::coinRemoveAllChildren(pShapeSep);
#endif
// This should always point outside of the solid
Base::Vector3d normal = pcConstraint->NormalDirection.getValue();
// Get default direction (on first call to method)
Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue();
if (forceDirection.Length() < Precision::Confusion()) {
forceDirection = normal;
}
SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z);
SbRotation rot(SbVec3f(0, 1, 0), dir);
for (const auto& point : points) {
SbVec3f base(point.x, point.y, point.z);
if (forceDirection.GetAngle(normal)
< M_PI_2) { // Move arrow so it doesn't disappear inside the solid
base = base + dir * scaledlength; // OvG: Scaling
}
#ifdef USE_MULTIPLE_COPY
SbMatrix m;
m.setTransform(base, rot, SbVec3f(1, 1, 1));
matrices[idx] = m;
idx++;
#else
SoSeparator* sep = new SoSeparator();
createPlacement(sep, base, rot);
createArrow(sep, scaledlength, scaledheadradius); // OvG: Scaling
pShapeSep->addChild(sep);
#endif
}
#ifdef USE_MULTIPLE_COPY
cp->matrix.finishEditing();
#endif
else {
ViewProviderFemConstraint::updateData(prop);
}
else if (prop == &pcConstraint->DirectionVector) {
// Note: "Reversed" also triggers "DirectionVector"
// Re-orient all arrows
Base::Vector3d normal = pcConstraint->NormalDirection.getValue();
Base::Vector3d forceDirection = pcConstraint->DirectionVector.getValue();
if (forceDirection.Length() < Precision::Confusion()) {
forceDirection = normal;
}
SbVec3f dir(forceDirection.x, forceDirection.y, forceDirection.z);
SbRotation rot(SbVec3f(0, 1, 0), dir);
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
#ifdef USE_MULTIPLE_COPY
SoMultipleCopy* cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0));
cp->matrix.setNum(points.size());
SbMatrix* matrices = cp->matrix.startEditing();
#endif
int idx = 0;
for (const auto& point : points) {
SbVec3f base(point.x, point.y, point.z);
if (forceDirection.GetAngle(normal) < M_PI_2) {
base = base + dir * scaledlength; // OvG: Scaling
}
#ifdef USE_MULTIPLE_COPY
SbMatrix m;
m.setTransform(base, rot, SbVec3f(1, 1, 1));
matrices[idx] = m;
#else
SoSeparator* sep = static_cast<SoSeparator*>(pShapeSep->getChild(idx));
updatePlacement(sep, 0, base, rot);
updateArrow(sep, 2, scaledlength, scaledheadradius); // OvG: Scaling
#endif
idx++;
}
#ifdef USE_MULTIPLE_COPY
cp->matrix.finishEditing();
#endif
}
ViewProviderFemConstraint::updateData(prop);
}
void ViewProviderFemConstraintForce::transformSymbol(const Base::Vector3d& point,
const Base::Vector3d& normal,
SbMatrix& mat) const
{
auto obj = static_cast<const Fem::ConstraintForce*>(this->getObject());
bool rev = obj->Reversed.getValue();
float s = obj->getScaleFactor();
// Symbol length from .iv file
float symLen = 4.0f;
// Place each symbol outside the boundary
Base::Vector3d dir = (rev ? -1.0 : 1.0) * obj->DirectionVector.getValue();
float symTraY = dir.Dot(normal) < 0 ? -1 * symLen : 0.0f;
float rotAngle = rev ? F_PI : 0.0f;
SbMatrix mat0, mat1;
mat0.setTransform(SbVec3f(0, symTraY, 0),
SbRotation(SbVec3f(0, 0, 1), rotAngle),
SbVec3f(1, 1, 1),
SbRotation(SbVec3f(0, 0, 1), 0),
SbVec3f(0, symLen / 2.0f, 0));
mat1.setTransform(SbVec3f(point.x, point.y, point.z),
SbRotation(SbVec3f(0, 1, 0), SbVec3f(dir.x, dir.y, dir.z)),
SbVec3f(s, s, s));
mat = mat0 * mat1;
}

View File

@@ -44,6 +44,9 @@ public:
protected:
bool setEdit(int ModNum) override;
void transformSymbol(const Base::Vector3d& point,
const Base::Vector3d& normal,
SbMatrix& mat) const override;
private:
/// Direction of the force

View File

@@ -26,12 +26,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoTranslation.h>
#endif
#include "Mod/Fem/App/FemConstraintHeatflux.h"
@@ -49,7 +43,9 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintHeatflux,
ViewProviderFemConstraintHeatflux::ViewProviderFemConstraintHeatflux()
{
sPixmap = "FEM_ConstraintHeatflux";
ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f));
loadSymbol((resourceSymbolDir + "ConstraintHeatFlux.iv").c_str());
FaceColor.setValue(1.0f, 0.0f, 0.0f);
}
ViewProviderFemConstraintHeatflux::~ViewProviderFemConstraintHeatflux() = default;
@@ -94,103 +90,7 @@ bool ViewProviderFemConstraintHeatflux::setEdit(int ModNum)
}
}
#define HEIGHT (1.5)
#define RADIUS (0.3)
// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing -
// so disable
void ViewProviderFemConstraintHeatflux::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintHeatflux* pcConstraint =
static_cast<Fem::ConstraintHeatflux*>(this->getObject());
float scaledradius =
RADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
float scaledheight = HEIGHT * pcConstraint->Scale.getValue();
// float ambienttemp = pcConstraint->AmbientTemp.getValue();
// //float facetemp = pcConstraint->FaceTemp.getValue();
// float filmcoef = pcConstraint->FilmCoef.getValue();
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
if (points.size() != normals.size()) {
return;
}
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
// Note: Points and Normals are always updated together
Gui::coinRemoveAllChildren(pShapeSep);
for (const auto& point : points) {
// Define base and normal directions
SbVec3f base(point.x, point.y, point.z);
SbVec3f dir(n->x, n->y, n->z); // normal
/// Temperature indication
// define separator
SoSeparator* sep = new SoSeparator();
/// draw a temp gauge,with sphere and a cylinder
// first move to correct position
SoTranslation* trans = new SoTranslation();
SbVec3f newPos = base + scaledradius * dir * 0.7f;
trans->translation.setValue(newPos);
sep->addChild(trans);
// adjust orientation
SoRotation* rot = new SoRotation();
rot->rotation.setValue(SbRotation(SbVec3f(0, 1, 0), dir));
sep->addChild(rot);
// define color of shape
SoMaterial* myMaterial = new SoMaterial;
myMaterial->diffuseColor.set1Value(0, SbColor(0.65f, 0.1f, 0.25f)); // RGB
// myMaterial->diffuseColor.set1Value(1,SbColor(.1,.1,.1));//possible to adjust sides
// separately
sep->addChild(myMaterial);
// draw a sphere
SoSphere* sph = new SoSphere();
sph->radius.setValue(scaledradius * 0.75);
sep->addChild(sph);
// translate position
SoTranslation* trans2 = new SoTranslation();
trans2->translation.setValue(SbVec3f(0, scaledheight * 0.375, 0));
sep->addChild(trans2);
// draw a cylinder
SoCylinder* cyl = new SoCylinder();
cyl->height.setValue(scaledheight * 0.5);
cyl->radius.setValue(scaledradius * 0.375);
sep->addChild(cyl);
// translate position
SoTranslation* trans3 = new SoTranslation();
trans3->translation.setValue(SbVec3f(0, scaledheight * 0.375, 0));
sep->addChild(trans3);
// define color of shape
SoMaterial* myMaterial2 = new SoMaterial;
myMaterial2->diffuseColor.set1Value(0, SbColor(1, 1, 1)); // RGB
sep->addChild(myMaterial2);
// draw a cylinder
SoCylinder* cyl2 = new SoCylinder();
cyl2->height.setValue(scaledheight * 0.25);
cyl2->radius.setValue(scaledradius * 0.375);
sep->addChild(cyl2);
// translate position
SoTranslation* trans4 = new SoTranslation();
trans4->translation.setValue(SbVec3f(0, -scaledheight * 0.375, 0));
sep->addChild(trans4);
// draw a cylinder
SoCylinder* cyl3 = new SoCylinder();
cyl3->height.setValue(scaledheight * 0.05);
cyl3->radius.setValue(scaledradius * 1);
sep->addChild(cyl3);
pShapeSep->addChild(sep);
n++;
}
}
// Gets called whenever a property of the attached object changes
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -26,12 +26,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoTranslation.h>
#endif
#include "Mod/Fem/App/FemConstraintPlaneRotation.h"
@@ -48,6 +42,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintPlaneRotation, FemGui::ViewProv
ViewProviderFemConstraintPlaneRotation::ViewProviderFemConstraintPlaneRotation()
{
sPixmap = "FEM_ConstraintPlaneRotation";
loadSymbol((resourceSymbolDir + "ConstraintPlaneRotation.iv").c_str());
// Note change "planerotation" in line above to new constraint name, make sure it is the same as
// in taskFem* cpp file
ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f));
@@ -96,98 +91,7 @@ bool ViewProviderFemConstraintPlaneRotation::setEdit(int ModNum)
}
}
#define HEIGHT (0.5)
#define RADIUS (5)
// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing -
// so disable
void ViewProviderFemConstraintPlaneRotation::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintPlaneRotation* pcConstraint =
static_cast<Fem::ConstraintPlaneRotation*>(this->getObject());
float scaledradius =
RADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
float scaledheight = HEIGHT * pcConstraint->Scale.getValue();
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
if (points.size() != normals.size()) {
return;
}
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
// Points and Normals are always updated together
Gui::coinRemoveAllChildren(pShapeSep);
for (const auto& point : points) {
// Define base and normal directions
SbVec3f base(point.x, point.y, point.z);
SbVec3f dir(n->x, n->y, n->z); // normal
/* Note:
* This next part draws a temperature gauge in 3D to indicate the constraint visually.
* This serves as an example. Change or remove as needs be.
* It is possible to draw almost any basic 3D shape. See inventor's documentation
* This gets drawn at every point.
* */
/// Visual indication
// define separator
SoSeparator* sep = new SoSeparator();
/// draw a temp gauge,with sphere and a cylinder
// first move to correct position
SoTranslation* trans = new SoTranslation();
SbVec3f newPos = base + scaledradius * dir * 0.08f;
trans->translation.setValue(newPos);
sep->addChild(trans);
// adjust orientation
SoRotation* rot = new SoRotation();
rot->rotation.setValue(SbRotation(SbVec3f(1, 0, 0), dir));
sep->addChild(rot);
// define color of shape
SoMaterial* myMaterial = new SoMaterial;
myMaterial->diffuseColor.set1Value(0, SbColor(0, 1, 0)); // RGB
// myMaterial->diffuseColor.set1Value(1,SbColor(0,0,1));//possible to adjust sides
// separately
sep->addChild(myMaterial);
// draw a sphere
// SoSphere* sph = new SoSphere();
// sph->radius.setValue(scaledradius*0.75);
// sep->addChild(sph);
// translate position
// SoTranslation* trans2 = new SoTranslation();
// trans2->translation.setValue(SbVec3f(0,scaledheight*0.375,0));
// sep->addChild(trans2);
// draw a cylinder
SoCylinder* cyl = new SoCylinder();
cyl->height.setValue(scaledheight * 0.5);
cyl->radius.setValue(scaledradius * 0.375);
sep->addChild(cyl);
// translate position
// SoTranslation* trans3 = new SoTranslation();
// trans3->translation.setValue(SbVec3f(0,scaledheight*0.05,0));
// sep->addChild(trans3);
// define color of shape
SoMaterial* myMaterial2 = new SoMaterial;
myMaterial2->diffuseColor.set1Value(0, SbColor(1, 1, 1)); // RGB
sep->addChild(myMaterial2);
// draw a cylinder
// SoCylinder* cyl2 = new SoCylinder();
// cyl2->height.setValue(scaledheight*0.25);
// cyl2->radius.setValue(scaledradius*0.375);
// sep->addChild(cyl2);
pShapeSep->addChild(sep);
n++;
}
}
// Gets called whenever a property of the attached object changes
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -24,10 +24,9 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/SbMatrix.h>
#include <Inventor/SbRotation.h>
#include <Inventor/SbVec3f.h>
#include <Inventor/nodes/SoMultipleCopy.h>
#include <Inventor/nodes/SoSeparator.h>
#endif
#include "Mod/Fem/App/FemConstraintPressure.h"
@@ -45,6 +44,8 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintPressure,
ViewProviderFemConstraintPressure::ViewProviderFemConstraintPressure()
{
sPixmap = "FEM_ConstraintPressure";
loadSymbol((resourceSymbolDir + "ConstraintPressure.iv").c_str());
ADD_PROPERTY(FaceColor, (0.0f, 0.2f, 0.8f));
}
@@ -90,78 +91,37 @@ bool ViewProviderFemConstraintPressure::setEdit(int ModNum)
}
}
#define ARROWLENGTH (4)
#define ARROWHEADRADIUS (ARROWLENGTH / 3.0f)
// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so
// disable
void ViewProviderFemConstraintPressure::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintPressure* pcConstraint =
static_cast<Fem::ConstraintPressure*>(this->getObject());
float scaledheadradius =
ARROWHEADRADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
float scaledlength = ARROWLENGTH * pcConstraint->Scale.getValue();
auto pcConstraint = static_cast<Fem::ConstraintPressure*>(this->getObject());
#ifdef USE_MULTIPLE_COPY
// OvG: always need access to cp for scaling
SoMultipleCopy* cp = new SoMultipleCopy();
if (pShapeSep->getNumChildren() == 0) {
// Set up the nodes
cp->matrix.setNum(0);
cp->addChild((SoNode*)createArrow(scaledlength, scaledheadradius)); // OvG: Scaling
pShapeSep->addChild(cp);
if (prop == &pcConstraint->Reversed) {
updateSymbol();
}
#endif
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
if (points.size() != normals.size()) {
return;
}
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
#ifdef USE_MULTIPLE_COPY
cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0)); // OvG: Use top cp
cp->matrix.setNum(points.size());
SbMatrix* matrices = cp->matrix.startEditing();
int idx = 0;
#else
// Redraw all arrows
Gui::coinRemoveAllChildren(pShapeSep);
#endif
for (const auto& point : points) {
SbVec3f base(point.x, point.y, point.z);
SbVec3f dir(n->x, n->y, n->z);
double rev;
if (pcConstraint->Reversed.getValue()) {
base = base + dir * scaledlength; // OvG: Scaling
rev = 1;
}
else {
rev = -1;
}
SbRotation rot(SbVec3f(0, rev, 0), dir);
#ifdef USE_MULTIPLE_COPY
SbMatrix m;
m.setTransform(base, rot, SbVec3f(1, 1, 1));
matrices[idx] = m;
idx++;
#else
SoSeparator* sep = new SoSeparator();
createPlacement(sep, base, rot);
createArrow(sep, scaledlength, scaledheadradius); // OvG: Scaling
pShapeSep->addChild(sep);
#endif
n++;
}
#ifdef USE_MULTIPLE_COPY
cp->matrix.finishEditing();
#endif
else {
ViewProviderFemConstraint::updateData(prop);
}
ViewProviderFemConstraint::updateData(prop);
}
void ViewProviderFemConstraintPressure::transformSymbol(const Base::Vector3d& point,
const Base::Vector3d& normal,
SbMatrix& mat) const
{
auto obj = static_cast<const Fem::ConstraintPressure*>(this->getObject());
float rotAngle = obj->Reversed.getValue() ? F_PI : 0.0f;
float s = obj->getScaleFactor();
// Symbol length from .iv file
float symLen = 4.0f;
SbMatrix mat0, mat1;
mat0.setTransform(SbVec3f(0, 0, 0),
SbRotation(SbVec3f(0, 0, 1), rotAngle),
SbVec3f(1, 1, 1),
SbRotation(SbVec3f(0, 0, 1), 0),
SbVec3f(0, symLen / 2.0f, 0));
mat1.setTransform(SbVec3f(point.x, point.y, point.z),
SbRotation(SbVec3f(0, 1, 0), SbVec3f(normal.x, normal.y, normal.z)),
SbVec3f(s, s, s));
mat = mat0 * mat1;
}

View File

@@ -41,6 +41,9 @@ public:
protected:
bool setEdit(int ModNum) override;
void transformSymbol(const Base::Vector3d& point,
const Base::Vector3d& normal,
SbMatrix& mat) const override;
};
} // namespace FemGui

View File

@@ -13,11 +13,37 @@
<Author Licence="LGPL" Name="Mario Passaglia" EMail="mpassaglia@cbc.uba.ar" />
<UserDocu>This is the ViewProviderFemConstraint class</UserDocu>
</Documentation>
<Methode Name="loadSymbol">
<Documentation>
<UserDocu>loadSymbol(filename) -> None
Load constraint symbol from Open Inventor file.
The file structure should be as follows:
A separator containing a separator with the symbol used in
multiple copies at points on the surface and an optional
separator with a symbol excluded from multiple copies.
filename : str
Open Inventor file.</UserDocu>
</Documentation>
</Methode>
<Attribute Name="SymbolNode" ReadOnly="true">
<Documentation>
<UserDocu>A pivy SoSeparator with the nodes of the constraint symbols</UserDocu>
</Documentation>
<Parameter Name="SymbolNode" Type="Object" />
</Attribute>
<Attribute Name="ExtraSymbolNode" ReadOnly="true">
<Documentation>
<UserDocu>A pivy SoSeparator with the nodes of the constraint extra symbols</UserDocu>
</Documentation>
<Parameter Name="ExtraSymbolNode" Type="Object" />
</Attribute>
<Attribute Name="RotateSymbol">
<Documentation>
<UserDocu>Apply rotation on copies of the constraint symbol</UserDocu>
</Documentation>
<Parameter Name="SymbolNode" Type="Boolean" />
</Attribute>
</PythonExport>
</GenerateModel>

View File

@@ -43,23 +43,68 @@ std::string ViewProviderFemConstraintPy::representation() const
return str.str();
}
PyObject* ViewProviderFemConstraintPy::loadSymbol(PyObject* args)
{
const char* name;
if (!PyArg_ParseTuple(args, "s", &name)) {
return nullptr;
}
getViewProviderFemConstraintPtr()->loadSymbol(name);
Py_Return;
}
Py::Object ViewProviderFemConstraintPy::getSymbolNode() const
{
try {
SoSeparator* sep = getViewProviderFemConstraintPtr()->getSymbolSeparator();
PyObject* Ptr =
Base::Interpreter().createSWIGPointerObj("pivy.coin", "_p_SoSeparator", sep, 1);
if (sep) {
PyObject* Ptr =
Base::Interpreter().createSWIGPointerObj("pivy.coin", "_p_SoSeparator", sep, 1);
sep->ref();
sep->ref();
return Py::Object(Ptr, true);
return Py::Object(Ptr, true);
}
else {
return Py::None();
}
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
}
Py::Object ViewProviderFemConstraintPy::getExtraSymbolNode() const
{
try {
SoSeparator* sep = getViewProviderFemConstraintPtr()->getExtraSymbolSeparator();
if (sep) {
PyObject* Ptr =
Base::Interpreter().createSWIGPointerObj("pivy.coin", "_p_SoSeparator", sep, 1);
sep->ref();
return Py::Object(Ptr, true);
}
else {
return Py::None();
}
}
catch (const Base::Exception& e) {
throw Py::RuntimeError(e.what());
}
}
Py::Boolean ViewProviderFemConstraintPy::getRotateSymbol() const
{
return Py::Boolean(getViewProviderFemConstraintPtr()->getRotateSymbol());
}
void ViewProviderFemConstraintPy::setRotateSymbol(Py::Boolean arg)
{
getViewProviderFemConstraintPtr()->setRotateSymbol((arg));
}
PyObject* ViewProviderFemConstraintPy::getCustomAttributes(const char* /*attr*/) const
{
return nullptr;

View File

@@ -24,10 +24,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/SbRotation.h>
#include <Inventor/SbVec3f.h>
#include <Inventor/nodes/SoMultipleCopy.h>
#include <Inventor/nodes/SoSeparator.h>
#endif
#include "Mod/Fem/App/FemConstraintSpring.h"
@@ -45,6 +41,7 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintSpring,
ViewProviderFemConstraintSpring::ViewProviderFemConstraintSpring()
{
sPixmap = "FEM_ConstraintSpring";
loadSymbol((resourceSymbolDir + "ConstraintSpring.iv").c_str());
ADD_PROPERTY(FaceColor, (0.0f, 0.2f, 0.8f));
}
@@ -91,69 +88,7 @@ bool ViewProviderFemConstraintSpring::setEdit(int ModNum)
}
}
#define WIDTH (1)
#define LENGTH (2)
// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled arrows on initial drawing - so
// disable
void ViewProviderFemConstraintSpring::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintSpring* pcConstraint = static_cast<Fem::ConstraintSpring*>(this->getObject());
float scaledwidth =
WIDTH * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
float scaledlength = LENGTH * pcConstraint->Scale.getValue();
#ifdef USE_MULTIPLE_COPY
// OvG: always need access to cp for scaling
SoMultipleCopy* cp = new SoMultipleCopy();
if (pShapeSep->getNumChildren() == 0) {
// Set up the nodes
cp->matrix.setNum(0);
cp->addChild((SoNode*)createSpring(scaledlength, scaledwidth)); // OvG: Scaling
pShapeSep->addChild(cp);
}
#endif
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
if (points.size() != normals.size()) {
return;
}
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
#ifdef USE_MULTIPLE_COPY
cp = static_cast<SoMultipleCopy*>(pShapeSep->getChild(0)); // OvG: Use top cp
cp->matrix.setNum(points.size());
SbMatrix* matrices = cp->matrix.startEditing();
int idx = 0;
#else
// Redraw all cylinders
Gui::coinRemoveAllChildren(pShapeSep);
#endif
for (const auto& point : points) {
SbVec3f base(point.x, point.y, point.z);
SbVec3f dir(n->x, n->y, n->z);
SbRotation rot(SbVec3f(0, -1.0, 0), dir);
#ifdef USE_MULTIPLE_COPY
SbMatrix m;
m.setTransform(base, rot, SbVec3f(1, 1, 1));
matrices[idx] = m;
idx++;
#else
SoSeparator* sep = new SoSeparator();
createPlacement(sep, base, rot);
createSpring(sep, scaledlength, scaledwidth); // OvG: Scaling
pShapeSep->addChild(sep);
#endif
n++;
}
#ifdef USE_MULTIPLE_COPY
cp->matrix.finishEditing();
#endif
}
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -26,12 +26,6 @@
#include "PreCompiled.h"
#ifndef _PreComp_
#include <Inventor/nodes/SoCylinder.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoRotation.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSphere.h>
#include <Inventor/nodes/SoTranslation.h>
#endif
#include "Mod/Fem/App/FemConstraintTemperature.h"
@@ -48,7 +42,9 @@ PROPERTY_SOURCE(FemGui::ViewProviderFemConstraintTemperature,
ViewProviderFemConstraintTemperature::ViewProviderFemConstraintTemperature()
{
sPixmap = "FEM_ConstraintTemperature";
ADD_PROPERTY(FaceColor, (0.2f, 0.3f, 0.2f));
loadSymbol((resourceSymbolDir + "ConstraintTemperature.iv").c_str());
FaceColor.setValue(1.0f, 0.0f, 0.0f);
}
ViewProviderFemConstraintTemperature::~ViewProviderFemConstraintTemperature() = default;
@@ -94,92 +90,7 @@ bool ViewProviderFemConstraintTemperature::setEdit(int ModNum)
}
}
#define HEIGHT (1.5)
#define RADIUS (0.3)
// #define USE_MULTIPLE_COPY //OvG: MULTICOPY fails to update scaled display on initial drawing -
// so disable
void ViewProviderFemConstraintTemperature::updateData(const App::Property* prop)
{
// Gets called whenever a property of the attached object changes
Fem::ConstraintTemperature* pcConstraint =
static_cast<Fem::ConstraintTemperature*>(this->getObject());
float scaledradius =
RADIUS * pcConstraint->Scale.getValue(); // OvG: Calculate scaled values once only
float scaledheight = HEIGHT * pcConstraint->Scale.getValue();
// float temperature = pcConstraint->temperature.getValue();
if (prop == &pcConstraint->Points) {
const std::vector<Base::Vector3d>& points = pcConstraint->Points.getValues();
const std::vector<Base::Vector3d>& normals = pcConstraint->Normals.getValues();
if (points.size() != normals.size()) {
return;
}
std::vector<Base::Vector3d>::const_iterator n = normals.begin();
// Note: Points and Normals are always updated together
Gui::coinRemoveAllChildren(pShapeSep);
for (const auto& point : points) {
// Define base and normal directions
SbVec3f base(point.x, point.y, point.z);
SbVec3f dir(n->x, n->y, n->z); // normal
/// Temperature indication
// define separator
SoSeparator* sep = new SoSeparator();
/// draw a temp gauge,with sphere and a cylinder
// first move to correct position
SoTranslation* trans = new SoTranslation();
SbVec3f newPos = base + scaledradius * dir * 0.7f;
trans->translation.setValue(newPos);
sep->addChild(trans);
// adjust orientation
SoRotation* rot = new SoRotation();
rot->rotation.setValue(SbRotation(SbVec3f(0, 1, 0), dir));
sep->addChild(rot);
// define color of shape
SoMaterial* myMaterial = new SoMaterial;
myMaterial->diffuseColor.set1Value(0, SbColor(1, 0, 0)); // RGB
// myMaterial->diffuseColor.set1Value(1,SbColor(.1,.1,.1));//possible to adjust sides
// separately
sep->addChild(myMaterial);
// draw a sphere
SoSphere* sph = new SoSphere();
sph->radius.setValue(scaledradius * 0.75);
sep->addChild(sph);
// translate position
SoTranslation* trans2 = new SoTranslation();
trans2->translation.setValue(SbVec3f(0, scaledheight * 0.375, 0));
sep->addChild(trans2);
// draw a cylinder
SoCylinder* cyl = new SoCylinder();
cyl->height.setValue(scaledheight * 0.5);
cyl->radius.setValue(scaledradius * 0.375);
sep->addChild(cyl);
// translate position
SoTranslation* trans3 = new SoTranslation();
trans3->translation.setValue(SbVec3f(0, scaledheight * 0.375, 0));
sep->addChild(trans3);
// define color of shape
SoMaterial* myMaterial2 = new SoMaterial;
myMaterial2->diffuseColor.set1Value(0, SbColor(1, 1, 1)); // RGB
sep->addChild(myMaterial2);
// draw a cylinder
SoCylinder* cyl2 = new SoCylinder();
cyl2->height.setValue(scaledheight * 0.25);
cyl2->radius.setValue(scaledradius * 0.375);
sep->addChild(cyl2);
pShapeSep->addChild(sep);
n++;
}
}
// Gets called whenever a property of the attached object changes
ViewProviderFemConstraint::updateData(prop);
}

View File

@@ -32,25 +32,15 @@ __url__ = "https://www.freecad.org"
from pivy import coin
from FreeCAD import getResourceDir
from femviewprovider import view_base_femobject
class VPBaseFemConstraint(view_base_femobject.VPBaseFemObject):
"""Proxy View Provider for Pythons base constraint."""
resource_symbol_dir = getResourceDir() + "Mod/Fem/Resources/symbols/"
def attach(self, vobj):
default = coin.SoGroup()
vobj.addDisplayMode(default, "Default")
self.Object = vobj.Object # used on various places, claim childreens, get icon, etc.
# self.ViewObject = vobj # not used ATM
def getDisplayModes(self, obj):
"Return a list of display modes."
modes = ["Default"]
return modes
def getDefaultDisplayMode(self):
return "Default"
def setDisplayMode(self, mode):
return mode
# used on various places, claim childreens, get icon, etc.
self.Object = vobj.Object

View File

@@ -38,6 +38,9 @@ class VPConstraintTie(view_base_femconstraint.VPBaseFemConstraint):
A View Provider for the ConstraintTie object
"""
def __init__(self, vobj):
super().__init__(vobj)
def setEdit(self, vobj, mode=0):
view_base_femconstraint.VPBaseFemConstraint.setEdit(
self,
@@ -45,3 +48,7 @@ class VPConstraintTie(view_base_femconstraint.VPBaseFemConstraint):
mode,
task_constraint_tie._TaskPanel
)
def attach(self, vobj):
super().attach(vobj)
vobj.loadSymbol(self.resource_symbol_dir + "ConstraintTie.iv")