diff --git a/src/Base/Interpreter.cpp b/src/Base/Interpreter.cpp
index 52c47168af..f9853c1659 100644
--- a/src/Base/Interpreter.cpp
+++ b/src/Base/Interpreter.cpp
@@ -125,6 +125,8 @@ void PyException::ReportException () const
{
if (!_isReported) {
_isReported = true;
+ // set sys.last_vars to make post-mortem debugging work
+ PySys_SetObject("last_traceback", PP_last_traceback);
Base::Console().DeveloperError("pyException","%s%s: %s\n",
_stackTrace.c_str(), _errorType.c_str(), what());
}
diff --git a/src/Gui/PreferencePages/DlgSettingsNavigation.ui b/src/Gui/PreferencePages/DlgSettingsNavigation.ui
index 2e7879bdd9..3902e04e7a 100644
--- a/src/Gui/PreferencePages/DlgSettingsNavigation.ui
+++ b/src/Gui/PreferencePages/DlgSettingsNavigation.ui
@@ -267,16 +267,16 @@
1
- 1.0
+ 1.0
- 100.0
+ 100.0
- 0.5
+ 0.5
- 5.0
+ 5.0
RotationCenterSize
@@ -634,7 +634,7 @@ The value is the diameter of the sphere to fit on the screen.
-
-
+
Qt::Horizontal
diff --git a/src/Gui/SoFCCSysDragger.cpp b/src/Gui/SoFCCSysDragger.cpp
index e78fbc11a6..ea828a5aa7 100644
--- a/src/Gui/SoFCCSysDragger.cpp
+++ b/src/Gui/SoFCCSysDragger.cpp
@@ -87,19 +87,24 @@ SO_KIT_SOURCE(TDragger)
void TDragger::initClass()
{
- SO_KIT_INIT_CLASS(TDragger, SoDragger, "Dragger");
+ SO_KIT_INIT_CLASS(TDragger, SoDragger, "Dragger");
}
TDragger::TDragger()
{
SO_KIT_CONSTRUCTOR(TDragger);
+#if defined(Q_OS_MAC)
+ this->ref();
+#endif
+
SO_KIT_ADD_CATALOG_ENTRY(translatorSwitch, SoSwitch, TRUE, geomSeparator, "", TRUE);
SO_KIT_ADD_CATALOG_ENTRY(translator, SoSeparator, TRUE, translatorSwitch, "", TRUE);
SO_KIT_ADD_CATALOG_ENTRY(translatorActive, SoSeparator, TRUE, translatorSwitch, "", TRUE);
- if (SO_KIT_IS_FIRST_INSTANCE())
+ if (SO_KIT_IS_FIRST_INSTANCE()) {
buildFirstInstance();
+ }
SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0));
SO_KIT_ADD_FIELD(translationIncrement, (1.0));
@@ -114,7 +119,7 @@ TDragger::TDragger()
this->setPartAsDefault("translator", "CSysDynamics_TDragger_Translator");
this->setPartAsDefault("translatorActive", "CSysDynamics_TDragger_TranslatorActive");
- SoSwitch *sw = SO_GET_ANY_PART(this, "translatorSwitch", SoSwitch);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "translatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 0);
this->addStartCallback(&TDragger::startCB);
@@ -143,7 +148,7 @@ TDragger::~TDragger()
void TDragger::buildFirstInstance()
{
- SoGroup *geometryGroup = buildGeometry();
+ SoGroup* geometryGroup = buildGeometry();
auto localTranslator = new SoSeparator();
localTranslator->setName("CSysDynamics_TDragger_Translator");
@@ -161,12 +166,12 @@ void TDragger::buildFirstInstance()
SoGroup* TDragger::buildGeometry()
{
- //this builds one leg in the Y+ direction because of default done direction.
- //the location anchor for shapes is the center of shape.
+ // this builds one leg in the Y+ direction because of default done direction.
+ // the location anchor for shapes is the center of shape.
auto root = new SoGroup();
- //cylinder
+ // cylinder
float cylinderHeight = 10.0;
float cylinderRadius = 0.1f;
auto cylinderSeparator = new SoSeparator();
@@ -185,7 +190,7 @@ SoGroup* TDragger::buildGeometry()
cylinder->height.setValue(cylinderHeight);
cylinderSeparator->addChild(cylinder);
- //cone
+ // cone
float coneBottomRadius = 0.8F;
float coneHeight = 2.5;
auto coneSeparator = new SoSeparator();
@@ -212,66 +217,68 @@ SoGroup* TDragger::buildGeometry()
return root;
}
-void TDragger::startCB(void *, SoDragger *d)
+void TDragger::startCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->dragStart();
}
-void TDragger::motionCB(void *, SoDragger *d)
+void TDragger::motionCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->drag();
}
-void TDragger::finishCB(void *, SoDragger *d)
+void TDragger::finishCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->dragFinish();
}
-void TDragger::fieldSensorCB(void *f, SoSensor *)
+void TDragger::fieldSensorCB(void* f, SoSensor*)
{
- auto sudoThis = static_cast(f);
+ auto sudoThis = static_cast(f);
- if(!f)
- return;
+ if (!f) {
+ return;
+ }
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
sudoThis->workFieldsIntoTransform(matrix);
sudoThis->setMotionMatrix(matrix);
}
-void TDragger::valueChangedCB(void *, SoDragger *d)
+void TDragger::valueChangedCB(void*, SoDragger* d)
{
- auto sudoThis = dynamic_cast(d);
+ auto sudoThis = dynamic_cast(d);
assert(sudoThis);
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
- //all this just to get the translation?
+ // all this just to get the translation?
SbVec3f trans, scaleDummy;
SbRotation rotationDummy, scaleOrientationDummy;
matrix.getTransform(trans, rotationDummy, scaleDummy, scaleOrientationDummy);
sudoThis->fieldSensor.detach();
- if (sudoThis->translation.getValue() != trans)
+ if (sudoThis->translation.getValue() != trans) {
sudoThis->translation = trans;
+ }
sudoThis->fieldSensor.attach(&sudoThis->translation);
}
void TDragger::dragStart()
{
- SoSwitch *sw;
+ SoSwitch* sw;
sw = SO_GET_ANY_PART(this, "translatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 1);
- //do an initial projection to eliminate discrepancies
- //in arrow head pick. we define the arrow in the y+ direction
- //and we know local space will be relative to this. so y vector
- //line projection will work.
+ // do an initial projection to eliminate discrepancies
+ // in arrow head pick. we define the arrow in the y+ direction
+ // and we know local space will be relative to this. so y vector
+ // line projection will work.
projector.setViewVolume(this->getViewVolume());
projector.setWorkingSpace(this->getLocalToWorldMatrix());
projector.setLine(SbLine(SbVec3f(0.0, 0.0, 0.0), SbVec3f(0.0, 1.0, 0.0)));
@@ -295,76 +302,79 @@ void TDragger::drag()
SbVec3f startingPoint = getLocalStartingPoint();
SbVec3f localMovement = hitPoint - startingPoint;
- //scale the increment to match local space.
- float scaledIncrement = static_cast(translationIncrement.getValue()) / autoScaleResult.getValue();
+ // scale the increment to match local space.
+ float scaledIncrement =
+ static_cast(translationIncrement.getValue()) / autoScaleResult.getValue();
localMovement = roundTranslation(localMovement, scaledIncrement);
- //when the movement vector is null either the appendTranslation or
- //the setMotionMatrix doesn't work. either way it stops translating
- //back to its initial starting point.
- if (localMovement.equals(SbVec3f(0.0, 0.0, 0.0), 0.00001f))
- {
+ // when the movement vector is null either the appendTranslation or
+ // the setMotionMatrix doesn't work. either way it stops translating
+ // back to its initial starting point.
+ if (localMovement.equals(SbVec3f(0.0, 0.0, 0.0), 0.00001f)) {
setMotionMatrix(getStartMotionMatrix());
- //don't know why I need the following but if I don't have it
- //it won't return to original position.
+ // don't know why I need the following but if I don't have it
+ // it won't return to original position.
this->valueChanged();
}
- else
+ else {
setMotionMatrix(appendTranslation(getStartMotionMatrix(), localMovement));
+ }
- Base::Quantity quantity(
- static_cast(translationIncrementCount.getValue()) * translationIncrement.getValue(), Base::Unit::Length);
+ Base::Quantity quantity(static_cast(translationIncrementCount.getValue())
+ * translationIncrement.getValue(),
+ Base::Unit::Length);
- QString message = QString::fromLatin1("%1 %2")
- .arg(QObject::tr("Translation:"), quantity.getUserString());
+ QString message =
+ QString::fromLatin1("%1 %2").arg(QObject::tr("Translation:"), quantity.getUserString());
getMainWindow()->showMessage(message, 3000);
}
void TDragger::dragFinish()
{
- SoSwitch *sw;
+ SoSwitch* sw;
sw = SO_GET_ANY_PART(this, "translatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 0);
}
SbBool TDragger::setUpConnections(SbBool onoff, SbBool doitalways)
{
- if (!doitalways && this->connectionsSetUp == onoff)
- return onoff;
+ if (!doitalways && this->connectionsSetUp == onoff) {
+ return onoff;
+ }
- SbBool oldval = this->connectionsSetUp;
+ SbBool oldval = this->connectionsSetUp;
- if (onoff)
- {
- inherited::setUpConnections(onoff, doitalways);
- TDragger::fieldSensorCB(this, nullptr);
- if (this->fieldSensor.getAttachedField() != &this->translation)
- this->fieldSensor.attach(&this->translation);
- }
- else
- {
- if (this->fieldSensor.getAttachedField())
- this->fieldSensor.detach();
- inherited::setUpConnections(onoff, doitalways);
- }
- this->connectionsSetUp = onoff;
- return oldval;
+ if (onoff) {
+ inherited::setUpConnections(onoff, doitalways);
+ TDragger::fieldSensorCB(this, nullptr);
+ if (this->fieldSensor.getAttachedField() != &this->translation) {
+ this->fieldSensor.attach(&this->translation);
+ }
+ }
+ else {
+ if (this->fieldSensor.getAttachedField()) {
+ this->fieldSensor.detach();
+ }
+ inherited::setUpConnections(onoff, doitalways);
+ }
+ this->connectionsSetUp = onoff;
+ return oldval;
}
-SbVec3f TDragger::roundTranslation(const SbVec3f &vecIn, float incrementIn)
+SbVec3f TDragger::roundTranslation(const SbVec3f& vecIn, float incrementIn)
{
- //everything is transformed into local space. That means we only have
- //worry about the y-value.
+ // everything is transformed into local space. That means we only have
+ // worry about the y-value.
int yCount = 0;
float yValue = vecIn[1];
- if (fabs(yValue) > (incrementIn / 2.0))
- {
+ if (fabs(yValue) > (incrementIn / 2.0)) {
yCount = static_cast(yValue / incrementIn);
float remainder = fmod(yValue, incrementIn);
- if (remainder >= (incrementIn / 2.0))
+ if (remainder >= (incrementIn / 2.0)) {
yCount++;
+ }
}
translationIncrementCount.setValue(yCount);
@@ -382,19 +392,28 @@ SO_KIT_SOURCE(TPlanarDragger)
void TPlanarDragger::initClass()
{
- SO_KIT_INIT_CLASS(TPlanarDragger, SoDragger, "Dragger");
+ SO_KIT_INIT_CLASS(TPlanarDragger, SoDragger, "Dragger");
}
TPlanarDragger::TPlanarDragger()
{
SO_KIT_CONSTRUCTOR(TPlanarDragger);
+#if defined(Q_OS_MAC)
+ this->ref();
+#endif
SO_KIT_ADD_CATALOG_ENTRY(planarTranslatorSwitch, SoSwitch, TRUE, geomSeparator, "", TRUE);
SO_KIT_ADD_CATALOG_ENTRY(planarTranslator, SoSeparator, TRUE, planarTranslatorSwitch, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(planarTranslatorActive, SoSeparator, TRUE, planarTranslatorSwitch, "", TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(planarTranslatorActive,
+ SoSeparator,
+ TRUE,
+ planarTranslatorSwitch,
+ "",
+ TRUE);
- if (SO_KIT_IS_FIRST_INSTANCE())
+ if (SO_KIT_IS_FIRST_INSTANCE()) {
buildFirstInstance();
+ }
SO_KIT_ADD_FIELD(translation, (0.0, 0.0, 0.0));
SO_KIT_ADD_FIELD(translationIncrement, (1.0));
@@ -408,9 +427,10 @@ TPlanarDragger::TPlanarDragger()
// first is from 'SO_KIT_CATALOG_ENTRY_HEADER' macro
// second is unique name from buildFirstInstance().
this->setPartAsDefault("planarTranslator", "CSysDynamics_TPlanarDragger_Translator");
- this->setPartAsDefault("planarTranslatorActive", "CSysDynamics_TPlanarDragger_TranslatorActive");
+ this->setPartAsDefault("planarTranslatorActive",
+ "CSysDynamics_TPlanarDragger_TranslatorActive");
- SoSwitch *sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 0);
this->addStartCallback(&TPlanarDragger::startCB);
@@ -439,7 +459,7 @@ TPlanarDragger::~TPlanarDragger()
void TPlanarDragger::buildFirstInstance()
{
- SoGroup *geometryGroup = buildGeometry();
+ SoGroup* geometryGroup = buildGeometry();
auto localTranslator = new SoSeparator();
localTranslator->setName("CSysDynamics_TPlanarDragger_Translator");
@@ -484,65 +504,68 @@ SoGroup* TPlanarDragger::buildGeometry()
return root;
}
-void TPlanarDragger::startCB(void *, SoDragger *d)
+void TPlanarDragger::startCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->dragStart();
}
-void TPlanarDragger::motionCB(void *, SoDragger *d)
+void TPlanarDragger::motionCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->drag();
}
-void TPlanarDragger::finishCB(void *, SoDragger *d)
+void TPlanarDragger::finishCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->dragFinish();
}
-void TPlanarDragger::fieldSensorCB(void *f, SoSensor *)
+void TPlanarDragger::fieldSensorCB(void* f, SoSensor*)
{
- auto sudoThis = static_cast(f);
+ auto sudoThis = static_cast(f);
- if(!f)
- return;
+ if (!f) {
+ return;
+ }
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
sudoThis->workFieldsIntoTransform(matrix);
sudoThis->setMotionMatrix(matrix);
}
-void TPlanarDragger::valueChangedCB(void *, SoDragger *d)
+void TPlanarDragger::valueChangedCB(void*, SoDragger* d)
{
- auto sudoThis = dynamic_cast(d);
+ auto sudoThis = dynamic_cast(d);
assert(sudoThis);
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
- //all this just to get the translation?
+ // all this just to get the translation?
SbVec3f trans, scaleDummy;
SbRotation rotationDummy, scaleOrientationDummy;
matrix.getTransform(trans, rotationDummy, scaleDummy, scaleOrientationDummy);
sudoThis->fieldSensor.detach();
- if (sudoThis->translation.getValue() != trans)
+ if (sudoThis->translation.getValue() != trans) {
sudoThis->translation = trans;
+ }
sudoThis->fieldSensor.attach(&sudoThis->translation);
}
void TPlanarDragger::dragStart()
{
- SoSwitch *sw;
+ SoSwitch* sw;
sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 1);
projector.setViewVolume(this->getViewVolume());
projector.setWorkingSpace(this->getLocalToWorldMatrix());
- projector.setPlane(SbPlane(SbVec3f(0.0, 0.0, 0.0), SbVec3f(1.0, 0.0, 0.0), SbVec3f(0.0, 1.0, 0.0)));
+ projector.setPlane(
+ SbPlane(SbVec3f(0.0, 0.0, 0.0), SbVec3f(1.0, 0.0, 0.0), SbVec3f(0.0, 1.0, 0.0)));
SbVec3f hitPoint = projector.project(getNormalizedLocaterPosition());
SbMatrix localToWorld = getLocalToWorldMatrix();
@@ -562,75 +585,81 @@ void TPlanarDragger::drag()
SbVec3f startingPoint = getLocalStartingPoint();
SbVec3f localMovement = hitPoint - startingPoint;
- //scale the increment to match local space.
- float scaledIncrement = static_cast(translationIncrement.getValue()) / autoScaleResult.getValue();
+ // scale the increment to match local space.
+ float scaledIncrement =
+ static_cast(translationIncrement.getValue()) / autoScaleResult.getValue();
localMovement = roundTranslation(localMovement, scaledIncrement);
- //when the movement vector is null either the appendTranslation or
- //the setMotionMatrix doesn't work. either way it stops translating
- //back to its initial starting point.
- if (localMovement.equals(SbVec3f(0.0, 0.0, 0.0), 0.00001f))
- {
+ // when the movement vector is null either the appendTranslation or
+ // the setMotionMatrix doesn't work. either way it stops translating
+ // back to its initial starting point.
+ if (localMovement.equals(SbVec3f(0.0, 0.0, 0.0), 0.00001f)) {
setMotionMatrix(getStartMotionMatrix());
- //don't know why I need the following but if I don't have it
- //it won't return to original position.
+ // don't know why I need the following but if I don't have it
+ // it won't return to original position.
this->valueChanged();
}
- else
+ else {
setMotionMatrix(appendTranslation(getStartMotionMatrix(), localMovement));
+ }
- Base::Quantity quantityX(
- static_cast(translationIncrementXCount.getValue()) * translationIncrement.getValue(), Base::Unit::Length);
- Base::Quantity quantityY(
- static_cast(translationIncrementYCount.getValue()) * translationIncrement.getValue(), Base::Unit::Length);
+ Base::Quantity quantityX(static_cast(translationIncrementXCount.getValue())
+ * translationIncrement.getValue(),
+ Base::Unit::Length);
+ Base::Quantity quantityY(static_cast(translationIncrementYCount.getValue())
+ * translationIncrement.getValue(),
+ Base::Unit::Length);
QString message = QString::fromLatin1("%1 %2, %3")
- .arg(QObject::tr("Translation XY:"), quantityX.getUserString(), quantityY.getUserString());
+ .arg(QObject::tr("Translation XY:"),
+ quantityX.getUserString(),
+ quantityY.getUserString());
getMainWindow()->showMessage(message, 3000);
}
void TPlanarDragger::dragFinish()
{
- SoSwitch *sw;
+ SoSwitch* sw;
sw = SO_GET_ANY_PART(this, "planarTranslatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 0);
}
SbBool TPlanarDragger::setUpConnections(SbBool onoff, SbBool doitalways)
{
- if (!doitalways && this->connectionsSetUp == onoff)
- return onoff;
+ if (!doitalways && this->connectionsSetUp == onoff) {
+ return onoff;
+ }
- SbBool oldval = this->connectionsSetUp;
+ SbBool oldval = this->connectionsSetUp;
- if (onoff)
- {
- inherited::setUpConnections(onoff, doitalways);
- TPlanarDragger::fieldSensorCB(this, nullptr);
- if (this->fieldSensor.getAttachedField() != &this->translation)
- this->fieldSensor.attach(&this->translation);
- }
- else
- {
- if (this->fieldSensor.getAttachedField())
- this->fieldSensor.detach();
- inherited::setUpConnections(onoff, doitalways);
- }
- this->connectionsSetUp = onoff;
- return oldval;
+ if (onoff) {
+ inherited::setUpConnections(onoff, doitalways);
+ TPlanarDragger::fieldSensorCB(this, nullptr);
+ if (this->fieldSensor.getAttachedField() != &this->translation) {
+ this->fieldSensor.attach(&this->translation);
+ }
+ }
+ else {
+ if (this->fieldSensor.getAttachedField()) {
+ this->fieldSensor.detach();
+ }
+ inherited::setUpConnections(onoff, doitalways);
+ }
+ this->connectionsSetUp = onoff;
+ return oldval;
}
-SbVec3f TPlanarDragger::roundTranslation(const SbVec3f &vecIn, float incrementIn)
+SbVec3f TPlanarDragger::roundTranslation(const SbVec3f& vecIn, float incrementIn)
{
int xCount = 0;
float xValue = vecIn[0];
- if (fabs(xValue) > (incrementIn / 2.0))
- {
+ if (fabs(xValue) > (incrementIn / 2.0)) {
xCount = static_cast(xValue / incrementIn);
float remainder = fmod(xValue, incrementIn);
- if (remainder >= (incrementIn / 2.0))
+ if (remainder >= (incrementIn / 2.0)) {
xCount++;
+ }
}
translationIncrementXCount.setValue(xCount);
@@ -638,12 +667,12 @@ SbVec3f TPlanarDragger::roundTranslation(const SbVec3f &vecIn, float incrementIn
int yCount = 0;
float yValue = vecIn[1];
- if (fabs(yValue) > (incrementIn / 2.0))
- {
+ if (fabs(yValue) > (incrementIn / 2.0)) {
yCount = static_cast(yValue / incrementIn);
float remainder = fmod(yValue, incrementIn);
- if (remainder >= (incrementIn / 2.0))
+ if (remainder >= (incrementIn / 2.0)) {
yCount++;
+ }
}
translationIncrementYCount.setValue(yCount);
@@ -661,12 +690,15 @@ SO_KIT_SOURCE(RDragger)
void RDragger::initClass()
{
- SO_KIT_INIT_CLASS(RDragger, SoDragger, "Dragger");
+ SO_KIT_INIT_CLASS(RDragger, SoDragger, "Dragger");
}
RDragger::RDragger()
{
SO_KIT_CONSTRUCTOR(RDragger);
+#if defined(Q_OS_MAC)
+ this->ref();
+#endif
SO_KIT_ADD_CATALOG_ENTRY(rotatorSwitch, SoSwitch, TRUE, geomSeparator, "", TRUE);
SO_KIT_ADD_CATALOG_ENTRY(rotator, SoSeparator, TRUE, rotatorSwitch, "", TRUE);
@@ -674,8 +706,9 @@ RDragger::RDragger()
arcRadius = 8.0;
- if (SO_KIT_IS_FIRST_INSTANCE())
+ if (SO_KIT_IS_FIRST_INSTANCE()) {
buildFirstInstance();
+ }
SO_KIT_ADD_FIELD(rotation, (SbVec3f(0.0, 0.0, 1.0), 0.0));
SO_KIT_ADD_FIELD(rotationIncrement, (M_PI / 8.0));
@@ -689,7 +722,7 @@ RDragger::RDragger()
this->setPartAsDefault("rotator", "CSysDynamics_RDragger_Rotator");
this->setPartAsDefault("rotatorActive", "CSysDynamics_RDragger_RotatorActive");
- SoSwitch *sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 0);
this->addStartCallback(&RDragger::startCB);
@@ -718,7 +751,7 @@ RDragger::~RDragger()
void RDragger::buildFirstInstance()
{
- SoGroup *geometryGroup = buildGeometry();
+ SoGroup* geometryGroup = buildGeometry();
auto localRotator = new SoSeparator();
localRotator->setName("CSysDynamics_RDragger_Rotator");
@@ -738,7 +771,7 @@ SoGroup* RDragger::buildGeometry()
{
auto root = new SoGroup();
- //arc
+ // arc
auto coordinates = new SoCoordinate3();
unsigned int segments = 15;
@@ -746,8 +779,7 @@ SoGroup* RDragger::buildGeometry()
float angleIncrement = static_cast(M_PI / 2.0) / static_cast(segments);
SbRotation rotation(SbVec3f(0.0, 0.0, 1.0), angleIncrement);
SbVec3f point(arcRadius, 0.0, 0.0);
- for (unsigned int index = 0; index <= segments; ++index)
- {
+ for (unsigned int index = 0; index <= segments; ++index) {
coordinates->point.set1Value(index, point);
rotation.multVec(point, point);
}
@@ -770,7 +802,7 @@ SoGroup* RDragger::buildGeometry()
pickStyle->setOverride(TRUE);
root->addChild(pickStyle);
- //sphere.
+ // sphere.
SbVec3f origin(1.0, 1.0, 0.0);
origin.normalize();
origin *= arcRadius;
@@ -785,59 +817,61 @@ SoGroup* RDragger::buildGeometry()
return root;
}
-void RDragger::startCB(void *, SoDragger *d)
+void RDragger::startCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->dragStart();
}
-void RDragger::motionCB(void *, SoDragger *d)
+void RDragger::motionCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->drag();
}
-void RDragger::finishCB(void *, SoDragger *d)
+void RDragger::finishCB(void*, SoDragger* d)
{
- auto sudoThis = static_cast(d);
+ auto sudoThis = static_cast(d);
assert(sudoThis);
sudoThis->dragFinish();
}
-void RDragger::fieldSensorCB(void *f, SoSensor *)
+void RDragger::fieldSensorCB(void* f, SoSensor*)
{
- auto sudoThis = static_cast(f);
+ auto sudoThis = static_cast(f);
- if(!f)
- return;
+ if (!f) {
+ return;
+ }
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
sudoThis->workFieldsIntoTransform(matrix);
sudoThis->setMotionMatrix(matrix);
}
-void RDragger::valueChangedCB(void *, SoDragger *d)
+void RDragger::valueChangedCB(void*, SoDragger* d)
{
- auto sudoThis = dynamic_cast(d);
+ auto sudoThis = dynamic_cast(d);
assert(sudoThis);
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
- //all this just to get the translation?
+ // all this just to get the translation?
SbVec3f translationDummy, scaleDummy;
SbRotation localRotation, scaleOrientationDummy;
matrix.getTransform(translationDummy, localRotation, scaleDummy, scaleOrientationDummy);
sudoThis->fieldSensor.detach();
- if (sudoThis->rotation.getValue() != localRotation)
+ if (sudoThis->rotation.getValue() != localRotation) {
sudoThis->rotation = localRotation;
+ }
sudoThis->fieldSensor.attach(&sudoThis->rotation);
}
void RDragger::dragStart()
{
- SoSwitch *sw;
+ SoSwitch* sw;
sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 1);
@@ -846,8 +880,9 @@ void RDragger::dragStart()
projector.setPlane(SbPlane(SbVec3f(0.0, 0.0, 1.0), 0.0));
SbVec3f hitPoint;
- if (!projector.tryProject(getNormalizedLocaterPosition(), 0.0, hitPoint))
+ if (!projector.tryProject(getNormalizedLocaterPosition(), 0.0, hitPoint)) {
return;
+ }
hitPoint.normalize();
SbMatrix localToWorld = getLocalToWorldMatrix();
@@ -863,90 +898,93 @@ void RDragger::drag()
projector.setWorkingSpace(this->getLocalToWorldMatrix());
SbVec3f hitPoint;
- if (!projector.tryProject(getNormalizedLocaterPosition(), 0.0, hitPoint))
+ if (!projector.tryProject(getNormalizedLocaterPosition(), 0.0, hitPoint)) {
return;
+ }
hitPoint.normalize();
SbVec3f startingPoint = getLocalStartingPoint();
startingPoint.normalize();
SbRotation localRotation(startingPoint, hitPoint);
- //getting some slop from this. grab vector and put it absolute.
+ // getting some slop from this. grab vector and put it absolute.
SbVec3f tempVec;
float tempRadians;
localRotation.getValue(tempVec, tempRadians);
tempVec[0] = 0.0;
tempVec[1] = 0.0;
tempVec.normalize();
- if (tempVec[2] < 0.0)
- {
+ if (tempVec[2] < 0.0) {
tempRadians *= -1.0;
tempVec.negate();
}
int incrementCount = roundIncrement(tempRadians);
rotationIncrementCount.setValue(incrementCount);
- localRotation = SbRotation(tempVec, incrementCount * static_cast(rotationIncrement.getValue()));
+ localRotation =
+ SbRotation(tempVec, incrementCount * static_cast(rotationIncrement.getValue()));
- //same problem as described in tDragger::drag.
- if (localRotation.equals(SbRotation(SbVec3f(0.0, 0.0, 1.0), 0.0), 0.00001f))
- {
+ // same problem as described in tDragger::drag.
+ if (localRotation.equals(SbRotation(SbVec3f(0.0, 0.0, 1.0), 0.0), 0.00001f)) {
setMotionMatrix(getStartMotionMatrix());
this->valueChanged();
}
- else
- setMotionMatrix(appendRotation(getStartMotionMatrix(), localRotation, SbVec3f(0.0, 0.0, 0.0)));
+ else {
+ setMotionMatrix(
+ appendRotation(getStartMotionMatrix(), localRotation, SbVec3f(0.0, 0.0, 0.0)));
+ }
- Base::Quantity quantity(
- static_cast(rotationIncrementCount.getValue()) * (180.0 / M_PI) *
- rotationIncrement.getValue(), Base::Unit::Angle);
+ Base::Quantity quantity(static_cast(rotationIncrementCount.getValue()) * (180.0 / M_PI)
+ * rotationIncrement.getValue(),
+ Base::Unit::Angle);
- QString message = QString::fromLatin1("%1 %2")
- .arg(QObject::tr("Rotation:"), quantity.getUserString());
+ QString message =
+ QString::fromLatin1("%1 %2").arg(QObject::tr("Rotation:"), quantity.getUserString());
getMainWindow()->showMessage(message, 3000);
}
void RDragger::dragFinish()
{
- SoSwitch *sw;
+ SoSwitch* sw;
sw = SO_GET_ANY_PART(this, "rotatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, 0);
}
SbBool RDragger::setUpConnections(SbBool onoff, SbBool doitalways)
{
- if (!doitalways && this->connectionsSetUp == onoff)
- return onoff;
+ if (!doitalways && this->connectionsSetUp == onoff) {
+ return onoff;
+ }
- SbBool oldval = this->connectionsSetUp;
+ SbBool oldval = this->connectionsSetUp;
- if (onoff)
- {
- inherited::setUpConnections(onoff, doitalways);
- RDragger::fieldSensorCB(this, nullptr);
- if (this->fieldSensor.getAttachedField() != &this->rotation)
- this->fieldSensor.attach(&this->rotation);
- }
- else
- {
- if (this->fieldSensor.getAttachedField())
- this->fieldSensor.detach();
- inherited::setUpConnections(onoff, doitalways);
- }
- this->connectionsSetUp = onoff;
- return oldval;
+ if (onoff) {
+ inherited::setUpConnections(onoff, doitalways);
+ RDragger::fieldSensorCB(this, nullptr);
+ if (this->fieldSensor.getAttachedField() != &this->rotation) {
+ this->fieldSensor.attach(&this->rotation);
+ }
+ }
+ else {
+ if (this->fieldSensor.getAttachedField()) {
+ this->fieldSensor.detach();
+ }
+ inherited::setUpConnections(onoff, doitalways);
+ }
+ this->connectionsSetUp = onoff;
+ return oldval;
}
-int RDragger::roundIncrement(const float &radiansIn)
+int RDragger::roundIncrement(const float& radiansIn)
{
int rCount = 0;
auto increment = static_cast(rotationIncrement.getValue());
- if (fabs(radiansIn) > (increment / 2.0))
- {
+ if (fabs(radiansIn) > (increment / 2.0)) {
rCount = static_cast(radiansIn / increment);
float remainder = fmod(radiansIn, increment);
- if (remainder >= (increment / 2.0))
+ if (remainder >= (increment / 2.0)) {
rCount++;
+ }
}
return rCount;
@@ -964,7 +1002,7 @@ void SoFCCSysDragger::initClass()
}
SoFCCSysDragger::SoFCCSysDragger()
- : axisScale(1.0f,1.0f,1.0f)
+ : axisScale(1.0f, 1.0f, 1.0f)
{
SO_KIT_CONSTRUCTOR(SoFCCSysDragger);
@@ -999,21 +1037,81 @@ SoFCCSysDragger::SoFCCSysDragger()
SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE);
SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorSwitch, SoSwitch, TRUE, annotation, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorSeparator, SoSeparator, TRUE, xyPlanarTranslatorSwitch, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorSeparator, SoSeparator, TRUE, yzPlanarTranslatorSwitch, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorSeparator, SoSeparator, TRUE, zxPlanarTranslatorSwitch, "", TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorSeparator,
+ SoSeparator,
+ TRUE,
+ xyPlanarTranslatorSwitch,
+ "",
+ TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorSeparator,
+ SoSeparator,
+ TRUE,
+ yzPlanarTranslatorSwitch,
+ "",
+ TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorSeparator,
+ SoSeparator,
+ TRUE,
+ zxPlanarTranslatorSwitch,
+ "",
+ TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorColor, SoBaseColor, TRUE, xyPlanarTranslatorSeparator, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorColor, SoBaseColor, TRUE, yzPlanarTranslatorSeparator, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorColor, SoBaseColor, TRUE, zxPlanarTranslatorSeparator, "", TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorColor,
+ SoBaseColor,
+ TRUE,
+ xyPlanarTranslatorSeparator,
+ "",
+ TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorColor,
+ SoBaseColor,
+ TRUE,
+ yzPlanarTranslatorSeparator,
+ "",
+ TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorColor,
+ SoBaseColor,
+ TRUE,
+ zxPlanarTranslatorSeparator,
+ "",
+ TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorRotation, SoRotation, TRUE, xyPlanarTranslatorSeparator, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorRotation, SoRotation, TRUE, yzPlanarTranslatorSeparator, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorRotation, SoRotation, TRUE, zxPlanarTranslatorSeparator, "", TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorRotation,
+ SoRotation,
+ TRUE,
+ xyPlanarTranslatorSeparator,
+ "",
+ TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorRotation,
+ SoRotation,
+ TRUE,
+ yzPlanarTranslatorSeparator,
+ "",
+ TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorRotation,
+ SoRotation,
+ TRUE,
+ zxPlanarTranslatorSeparator,
+ "",
+ TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorDragger, TPlanarDragger, TRUE, xyPlanarTranslatorSeparator, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorDragger, TPlanarDragger, TRUE, yzPlanarTranslatorSeparator, "", TRUE);
- SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorDragger, TPlanarDragger, TRUE, zxPlanarTranslatorSeparator, "", TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(xyPlanarTranslatorDragger,
+ TPlanarDragger,
+ TRUE,
+ xyPlanarTranslatorSeparator,
+ "",
+ TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(yzPlanarTranslatorDragger,
+ TPlanarDragger,
+ TRUE,
+ yzPlanarTranslatorSeparator,
+ "",
+ TRUE);
+ SO_KIT_ADD_CATALOG_ENTRY(zxPlanarTranslatorDragger,
+ TPlanarDragger,
+ TRUE,
+ zxPlanarTranslatorSeparator,
+ "",
+ TRUE);
// Rotator
@@ -1057,16 +1155,14 @@ SoFCCSysDragger::SoFCCSysDragger()
SO_KIT_INIT_INSTANCE();
// Colors
- setAxisColors(
- SbColor(1.0, 0, 0).getPackedValue(0.0f),
- SbColor(0, 1.0, 0).getPackedValue(0.0f),
- SbColor(0, 0, 1.0).getPackedValue(0.0f)
- );
+ setAxisColors(SbColor(1.0, 0, 0).getPackedValue(0.0f),
+ SbColor(0, 1.0, 0).getPackedValue(0.0f),
+ SbColor(0, 0, 1.0).getPackedValue(0.0f));
// Increments
// Translator
- TDragger *tDragger;
+ TDragger* tDragger;
tDragger = SO_GET_ANY_PART(this, "xTranslatorDragger", TDragger);
tDragger->translationIncrement.connectFrom(&this->translationIncrement);
tDragger->autoScaleResult.connectFrom(&this->autoScaleResult);
@@ -1080,7 +1176,7 @@ SoFCCSysDragger::SoFCCSysDragger()
tDragger->autoScaleResult.connectFrom(&this->autoScaleResult);
translationIncrementCountZ.connectFrom(&tDragger->translationIncrementCount);
// Planar Translator
- TPlanarDragger *tPlanarDragger;
+ TPlanarDragger* tPlanarDragger;
tPlanarDragger = SO_GET_ANY_PART(this, "xyPlanarTranslatorDragger", TPlanarDragger);
tPlanarDragger->translationIncrement.connectFrom(&this->translationIncrement);
tPlanarDragger->autoScaleResult.connectFrom(&this->autoScaleResult);
@@ -1097,7 +1193,7 @@ SoFCCSysDragger::SoFCCSysDragger()
translationIncrementCountX.appendConnection(&tPlanarDragger->translationIncrementXCount);
translationIncrementCountZ.appendConnection(&tPlanarDragger->translationIncrementYCount);
// Rotator
- RDragger *rDragger;
+ RDragger* rDragger;
rDragger = SO_GET_ANY_PART(this, "xRotatorDragger", RDragger);
rDragger->rotationIncrement.connectFrom(&this->rotationIncrement);
rotationIncrementCountX.connectFrom(&rDragger->rotationIncrementCount);
@@ -1111,7 +1207,7 @@ SoFCCSysDragger::SoFCCSysDragger()
// Switches
// Translator
- SoSwitch *sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
@@ -1134,7 +1230,7 @@ SoFCCSysDragger::SoFCCSysDragger()
// Rotations
- SoRotation *localRotation;
+ SoRotation* localRotation;
SbRotation tempRotation;
auto angle = static_cast(M_PI / 2.0);
// Translator
@@ -1163,13 +1259,13 @@ SoFCCSysDragger::SoFCCSysDragger()
localRotation = SO_GET_ANY_PART(this, "zRotatorRotation", SoRotation);
localRotation->rotation.setValue(SbRotation::identity());
- //this is for non-autoscale mode. this will be disconnected for autoscale
- //and won't be used. see setUpAutoScale.
- auto scaleEngine = new SoComposeVec3f(); //uses coin ref scheme.
+ // this is for non-autoscale mode. this will be disconnected for autoscale
+ // and won't be used. see setUpAutoScale.
+ auto scaleEngine = new SoComposeVec3f(); // uses coin ref scheme.
scaleEngine->x.connectFrom(&draggerSize);
scaleEngine->y.connectFrom(&draggerSize);
scaleEngine->z.connectFrom(&draggerSize);
- SoScale *localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale);
+ SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale);
localScaleNode->scaleFactor.connectFrom(&scaleEngine->vector);
autoScaleResult.connectFrom(&draggerSize);
@@ -1212,21 +1308,24 @@ SoFCCSysDragger::~SoFCCSysDragger()
SbBool SoFCCSysDragger::setUpConnections(SbBool onoff, SbBool doitalways)
{
- if (!doitalways && (connectionsSetUp == onoff))
+ if (!doitalways && (connectionsSetUp == onoff)) {
return onoff;
+ }
- TDragger *tDraggerX = SO_GET_ANY_PART(this, "xTranslatorDragger", TDragger);
- TDragger *tDraggerY = SO_GET_ANY_PART(this, "yTranslatorDragger", TDragger);
- TDragger *tDraggerZ = SO_GET_ANY_PART(this, "zTranslatorDragger", TDragger);
- TPlanarDragger *tPlanarDraggerXZ = SO_GET_ANY_PART(this, "xyPlanarTranslatorDragger", TPlanarDragger);
- TPlanarDragger *tPlanarDraggerYZ = SO_GET_ANY_PART(this, "yzPlanarTranslatorDragger", TPlanarDragger);
- TPlanarDragger *tPlanarDraggerZX = SO_GET_ANY_PART(this, "zxPlanarTranslatorDragger", TPlanarDragger);
- RDragger *rDraggerX = SO_GET_ANY_PART(this, "xRotatorDragger", RDragger);
- RDragger *rDraggerY = SO_GET_ANY_PART(this, "yRotatorDragger", RDragger);
- RDragger *rDraggerZ = SO_GET_ANY_PART(this, "zRotatorDragger", RDragger);
+ TDragger* tDraggerX = SO_GET_ANY_PART(this, "xTranslatorDragger", TDragger);
+ TDragger* tDraggerY = SO_GET_ANY_PART(this, "yTranslatorDragger", TDragger);
+ TDragger* tDraggerZ = SO_GET_ANY_PART(this, "zTranslatorDragger", TDragger);
+ TPlanarDragger* tPlanarDraggerXZ =
+ SO_GET_ANY_PART(this, "xyPlanarTranslatorDragger", TPlanarDragger);
+ TPlanarDragger* tPlanarDraggerYZ =
+ SO_GET_ANY_PART(this, "yzPlanarTranslatorDragger", TPlanarDragger);
+ TPlanarDragger* tPlanarDraggerZX =
+ SO_GET_ANY_PART(this, "zxPlanarTranslatorDragger", TPlanarDragger);
+ RDragger* rDraggerX = SO_GET_ANY_PART(this, "xRotatorDragger", RDragger);
+ RDragger* rDraggerY = SO_GET_ANY_PART(this, "yRotatorDragger", RDragger);
+ RDragger* rDraggerZ = SO_GET_ANY_PART(this, "zRotatorDragger", RDragger);
- if (onoff)
- {
+ if (onoff) {
inherited::setUpConnections(onoff, doitalways);
registerChildDragger(tDraggerX);
@@ -1240,15 +1339,16 @@ SbBool SoFCCSysDragger::setUpConnections(SbBool onoff, SbBool doitalways)
registerChildDragger(rDraggerZ);
translationSensorCB(this, nullptr);
- if (this->translationSensor.getAttachedField() != &this->translation)
- this->translationSensor.attach(&this->translation);
+ if (this->translationSensor.getAttachedField() != &this->translation) {
+ this->translationSensor.attach(&this->translation);
+ }
rotationSensorCB(this, nullptr);
- if (this->rotationSensor.getAttachedField() != &this->rotation)
+ if (this->rotationSensor.getAttachedField() != &this->rotation) {
this->rotationSensor.attach(&this->rotation);
+ }
}
- else
- {
+ else {
unregisterChildDragger(tDraggerX);
unregisterChildDragger(tDraggerY);
unregisterChildDragger(tDraggerZ);
@@ -1261,98 +1361,104 @@ SbBool SoFCCSysDragger::setUpConnections(SbBool onoff, SbBool doitalways)
inherited::setUpConnections(onoff, doitalways);
- if (this->translationSensor.getAttachedField())
- this->translationSensor.detach();
+ if (this->translationSensor.getAttachedField()) {
+ this->translationSensor.detach();
+ }
- if (this->rotationSensor.getAttachedField())
+ if (this->rotationSensor.getAttachedField()) {
this->rotationSensor.detach();
+ }
}
return !(this->connectionsSetUp = onoff);
}
-void SoFCCSysDragger::translationSensorCB(void *f, SoSensor *)
+void SoFCCSysDragger::translationSensorCB(void* f, SoSensor*)
{
- auto sudoThis = static_cast(f);
- if(!f)
- return;
+ auto sudoThis = static_cast(f);
+ if (!f) {
+ return;
+ }
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
sudoThis->workFieldsIntoTransform(matrix);
sudoThis->setMotionMatrix(matrix);
}
-void SoFCCSysDragger::rotationSensorCB(void *f, SoSensor *)
+void SoFCCSysDragger::rotationSensorCB(void* f, SoSensor*)
{
- auto sudoThis = static_cast(f);
- if(!f)
- return;
+ auto sudoThis = static_cast(f);
+ if (!f) {
+ return;
+ }
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
sudoThis->workFieldsIntoTransform(matrix);
sudoThis->setMotionMatrix(matrix);
}
-void SoFCCSysDragger::valueChangedCB(void *, SoDragger *d)
+void SoFCCSysDragger::valueChangedCB(void*, SoDragger* d)
{
- auto sudoThis = dynamic_cast(d);
+ auto sudoThis = dynamic_cast(d);
assert(sudoThis);
- SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
+ SbMatrix matrix = sudoThis->getMotionMatrix(); // clazy:exclude=rule-of-two-soft
- //all this just to get the translation?
+ // all this just to get the translation?
SbVec3f localTranslation, scaleDummy;
SbRotation localRotation, scaleOrientationDummy;
matrix.getTransform(localTranslation, localRotation, scaleDummy, scaleOrientationDummy);
sudoThis->translationSensor.detach();
- if (sudoThis->translation.getValue() != localTranslation)
+ if (sudoThis->translation.getValue() != localTranslation) {
sudoThis->translation = localTranslation;
+ }
sudoThis->translationSensor.attach(&sudoThis->translation);
sudoThis->rotationSensor.detach();
- if (sudoThis->rotation.getValue() != localRotation)
+ if (sudoThis->rotation.getValue() != localRotation) {
sudoThis->rotation = localRotation;
+ }
sudoThis->rotationSensor.attach(&sudoThis->rotation);
}
-void SoFCCSysDragger::setUpAutoScale(SoCamera *cameraIn)
+void SoFCCSysDragger::setUpAutoScale(SoCamera* cameraIn)
{
- //note: sofieldsensor checks if the current sensor is already attached
- //and takes appropriate action. So it is safe to attach to a field without
- //checking current attachment state.
- if (cameraIn->getTypeId() == SoOrthographicCamera::getClassTypeId())
- {
- auto localCamera = dynamic_cast(cameraIn);
+ // note: sofieldsensor checks if the current sensor is already attached
+ // and takes appropriate action. So it is safe to attach to a field without
+ // checking current attachment state.
+ if (cameraIn->getTypeId() == SoOrthographicCamera::getClassTypeId()) {
+ auto localCamera = dynamic_cast(cameraIn);
assert(localCamera);
cameraSensor.attach(&localCamera->height);
- SoScale *localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale);
+ SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale);
localScaleNode->scaleFactor.disconnect();
autoScaleResult.disconnect(&draggerSize);
cameraCB(this, nullptr);
}
- else if (cameraIn->getTypeId() == SoPerspectiveCamera::getClassTypeId())
- {
- auto localCamera = dynamic_cast(cameraIn);
+ else if (cameraIn->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
+ auto localCamera = dynamic_cast(cameraIn);
assert(localCamera);
cameraSensor.attach(&localCamera->position);
- SoScale *localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale);
+ SoScale* localScaleNode = SO_GET_ANY_PART(this, "scaleNode", SoScale);
localScaleNode->scaleFactor.disconnect();
autoScaleResult.disconnect(&draggerSize);
cameraCB(this, nullptr);
}
}
-void SoFCCSysDragger::cameraCB(void *data, SoSensor *)
+void SoFCCSysDragger::cameraCB(void* data, SoSensor*)
{
- auto sudoThis = static_cast(data);
- if (!sudoThis)
- return;
- if (!sudoThis->idleSensor.isScheduled())
+ auto sudoThis = static_cast(data);
+ if (!sudoThis) {
+ return;
+ }
+ if (!sudoThis->idleSensor.isScheduled()) {
sudoThis->idleSensor.schedule();
+ }
}
-void SoFCCSysDragger::GLRender(SoGLRenderAction * action)
+void SoFCCSysDragger::GLRender(SoGLRenderAction* action)
{
- if(!scaleInited) {
+ if (!scaleInited) {
scaleInited = true;
updateDraggerCache(action->getCurPath());
updateAxisScale();
@@ -1361,24 +1467,25 @@ void SoFCCSysDragger::GLRender(SoGLRenderAction * action)
inherited::GLRender(action);
}
-void SoFCCSysDragger::updateAxisScale() {
+void SoFCCSysDragger::updateAxisScale()
+{
SbMatrix localToWorld = getLocalToWorldMatrix();
SbVec3f origin;
localToWorld.multVecMatrix(SbVec3f(0.0, 0.0, 0.0), origin);
- SbVec3f vx,vy,vz;
+ SbVec3f vx, vy, vz;
localToWorld.multVecMatrix(SbVec3f(1.0f, 0.0f, 0.0f), vx);
localToWorld.multVecMatrix(SbVec3f(0.0f, 1.0f, 0.0f), vy);
localToWorld.multVecMatrix(SbVec3f(0.0f, 0.0f, 1.0f), vz);
- float x = std::max((vx-origin).length(),1e-7f);
- float y = std::max((vy-origin).length(),1e-7f);
- float z = std::max((vz-origin).length(),1e-7f);
- if(!axisScale.equals(SbVec3f(x,y,z),1e-7f)) {
- axisScale.setValue(x,y,z);
- idleCB(this,&idleSensor);
+ float x = std::max((vx - origin).length(), 1e-7f);
+ float y = std::max((vy - origin).length(), 1e-7f);
+ float z = std::max((vz - origin).length(), 1e-7f);
+ if (!axisScale.equals(SbVec3f(x, y, z), 1e-7f)) {
+ axisScale.setValue(x, y, z);
+ idleCB(this, &idleSensor);
}
}
-void SoFCCSysDragger::handleEvent(SoHandleEventAction * action)
+void SoFCCSysDragger::handleEvent(SoHandleEventAction* action)
{
this->ref();
@@ -1388,14 +1495,14 @@ void SoFCCSysDragger::handleEvent(SoHandleEventAction * action)
this->unref();
}
-void SoFCCSysDragger::idleCB(void *data, SoSensor *)
+void SoFCCSysDragger::idleCB(void* data, SoSensor*)
{
- auto sudoThis = static_cast(data);
- if (!data)
- return;
+ auto sudoThis = static_cast(data);
+ if (!data) {
+ return;
+ }
SoField* field = sudoThis->cameraSensor.getAttachedField();
- if (field)
- {
+ if (field) {
auto camera = static_cast(field->getContainer());
SbMatrix localToWorld = sudoThis->getLocalToWorldMatrix();
SbVec3f origin;
@@ -1404,29 +1511,29 @@ void SoFCCSysDragger::idleCB(void *data, SoSensor *)
SbViewVolume viewVolume = camera->getViewVolume();
float radius = sudoThis->draggerSize.getValue() / 2.0;
float localScale = viewVolume.getWorldToScreenScale(origin, radius);
- float sx,sy,sz;
- sudoThis->axisScale.getValue(sx,sy,sz);
- SbVec3f scaleVector(localScale/sx, localScale/sy, localScale/sz);
- SoScale *localScaleNode = SO_GET_ANY_PART(sudoThis, "scaleNode", SoScale);
+ float sx, sy, sz;
+ sudoThis->axisScale.getValue(sx, sy, sz);
+ SbVec3f scaleVector(localScale / sx, localScale / sy, localScale / sz);
+ SoScale* localScaleNode = SO_GET_ANY_PART(sudoThis, "scaleNode", SoScale);
localScaleNode->scaleFactor.setValue(scaleVector);
sudoThis->autoScaleResult.setValue(localScale);
}
}
-void SoFCCSysDragger::finishDragCB(void *data, SoDragger *)
+void SoFCCSysDragger::finishDragCB(void* data, SoDragger*)
{
- auto sudoThis = static_cast(data);
+ auto sudoThis = static_cast(data);
assert(sudoThis);
// note: when creating a second view of the document and then closing
// the first viewer it deletes the camera. However, the attached field
// of the cameraSensor will be detached automatically.
SoField* field = sudoThis->cameraSensor.getAttachedField();
- if (field)
- {
+ if (field) {
auto camera = static_cast(field->getContainer());
- if (camera->getTypeId() == SoPerspectiveCamera::getClassTypeId())
+ if (camera->getTypeId() == SoPerspectiveCamera::getClassTypeId()) {
cameraCB(sudoThis, nullptr);
+ }
}
}
@@ -1440,7 +1547,8 @@ void SoFCCSysDragger::clearIncrementCounts()
rotationIncrementCountZ.setValue(0);
}
-void SoFCCSysDragger::setAxisColors(unsigned long x, unsigned long y, unsigned long z) {
+void SoFCCSysDragger::setAxisColors(unsigned long x, unsigned long y, unsigned long z)
+{
SbColor colorX;
SbColor colorY;
SbColor colorZ;
@@ -1480,194 +1588,194 @@ void SoFCCSysDragger::setAxisColors(unsigned long x, unsigned long y, unsigned l
// Translator
void SoFCCSysDragger::showTranslationX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::showTranslationY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::showTranslationZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::hideTranslationX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
void SoFCCSysDragger::hideTranslationY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
void SoFCCSysDragger::hideTranslationZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isShownTranslationX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isShownTranslationY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isShownTranslationZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isHiddenTranslationX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isHiddenTranslationY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isHiddenTranslationZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
// Planar Translator
void SoFCCSysDragger::showPlanarTranslationXY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::showPlanarTranslationYZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::showPlanarTranslationZX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::hidePlanarTranslationXY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
void SoFCCSysDragger::hidePlanarTranslationYZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
void SoFCCSysDragger::hidePlanarTranslationZX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isShownPlanarTranslationXY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isShownPlanarTranslationYZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isShownPlanarTranslationZX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isHiddenPlanarTranslationXY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xyPlanarTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isHiddenPlanarTranslationYZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yzPlanarTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isHiddenPlanarTranslationZX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zxPlanarTranslatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
// Rotator
void SoFCCSysDragger::showRotationX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::showRotationY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::showRotationZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_ALL);
}
void SoFCCSysDragger::hideRotationX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
void SoFCCSysDragger::hideRotationY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
void SoFCCSysDragger::hideRotationZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch);
- SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch);
+ SoInteractionKit::setSwitchValue(sw, SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isShownRotationX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isShownRotationY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isShownRotationZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_ALL);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_ALL);
}
bool SoFCCSysDragger::isHiddenRotationX()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "xRotatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isHiddenRotationY()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "yRotatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
bool SoFCCSysDragger::isHiddenRotationZ()
{
- SoSwitch *sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch);
- return (sw->whichChild.getValue() == SO_SWITCH_NONE);
+ SoSwitch* sw = SO_GET_ANY_PART(this, "zRotatorSwitch", SoSwitch);
+ return (sw->whichChild.getValue() == SO_SWITCH_NONE);
}
diff --git a/src/Mod/Arch/ArchWindow.py b/src/Mod/Arch/ArchWindow.py
index 0ee9d6def2..115fddcccb 100644
--- a/src/Mod/Arch/ArchWindow.py
+++ b/src/Mod/Arch/ArchWindow.py
@@ -987,9 +987,9 @@ class _Window(ArchComponent.Component):
if not obj.Subvolume.Shape.isNull():
sh = obj.Subvolume.Shape.copy()
pl = FreeCAD.Placement(sh.Placement)
- pl = pl.multiply(obj.Placement)
+ pl = obj.Placement.multiply(pl)
if plac:
- pl = pl.multiply(plac)
+ pl = plac.multiply(pl)
sh.Placement = pl
return sh
diff --git a/src/Mod/Draft/WorkingPlane.py b/src/Mod/Draft/WorkingPlane.py
index 985292d620..c1791d8fc8 100644
--- a/src/Mod/Draft/WorkingPlane.py
+++ b/src/Mod/Draft/WorkingPlane.py
@@ -1750,8 +1750,8 @@ def get_working_plane(update=True):
wp = PlaneGui()
if FreeCAD.GuiUp:
+ wp._view = view # Update _view before call to set_to_default, set_to_auto requires a 3D view.
wp.set_to_default()
- wp._view = view
if view is not None:
FreeCAD.draft_working_planes[0].append(view)
FreeCAD.draft_working_planes[1].append(wp)
diff --git a/src/Mod/Draft/draftfunctions/dxf.py b/src/Mod/Draft/draftfunctions/dxf.py
index c5ec52ae69..1236c4fdef 100644
--- a/src/Mod/Draft/draftfunctions/dxf.py
+++ b/src/Mod/Draft/draftfunctions/dxf.py
@@ -77,8 +77,8 @@ def get_dxf(obj, direction=None):
if direction and isinstance(direction, App.Vector):
if direction != App.Vector(0, 0, 0):
- plane = WorkingPlane.Plane()
- plane.alignToPointAndAxis(App.Vector(0, 0, 0), direction)
+ plane = WorkingPlane.PlaneBase()
+ plane.align_to_point_and_axis(App.Vector(0, 0, 0), direction)
if utils.get_type(obj) in ("Dimension", "LinearDimension"):
p1 = _get_proj(obj.Start, plane=plane)
diff --git a/src/Mod/Draft/draftfunctions/mirror.py b/src/Mod/Draft/draftfunctions/mirror.py
index 206cd5dce2..ba62fde797 100644
--- a/src/Mod/Draft/draftfunctions/mirror.py
+++ b/src/Mod/Draft/draftfunctions/mirror.py
@@ -33,9 +33,10 @@ It just creates a `Part::Mirroring` object, and sets the appropriate
## \addtogroup draftfunctions
# @{
import FreeCAD as App
-import draftutils.utils as utils
-import draftutils.gui_utils as gui_utils
+import WorkingPlane
+from draftutils import gui_utils
+from draftutils import utils
from draftutils.messages import _err
from draftutils.translate import translate
@@ -48,14 +49,7 @@ def mirror(objlist, p1, p2):
It creates a `Part::Mirroring` object from the given `objlist` using
a plane that is defined by the two given points `p1` and `p2`,
- and either
-
- - the Draft working plane normal, or
- - the negative normal provided by the camera direction
- if the working plane normal does not exist and the graphical interface
- is available.
-
- If neither of these two is available, it uses as normal the +Z vector.
+ and the Draft working plane normal.
Parameters
----------
@@ -67,7 +61,7 @@ def mirror(objlist, p1, p2):
of the resulting object.
p2: Base::Vector3
- Point 1 of the mirror plane.
+ Point 2 of the mirror plane.
Returns
-------
@@ -97,13 +91,7 @@ def mirror(objlist, p1, p2):
if not isinstance(objlist, list):
objlist = [objlist]
- if hasattr(App, "DraftWorkingPlane"):
- norm = App.DraftWorkingPlane.getNormal()
- elif App.GuiUp:
- norm = Gui.ActiveDocument.ActiveView.getViewDirection().negative()
- else:
- norm = App.Vector(0, 0, 1)
-
+ norm = WorkingPlane.get_working_plane(update=False).axis
pnorm = p2.sub(p1).cross(norm).normalize()
result = []
diff --git a/src/Mod/Draft/draftfunctions/svg.py b/src/Mod/Draft/draftfunctions/svg.py
index 2a900f9231..cc55fef12c 100644
--- a/src/Mod/Draft/draftfunctions/svg.py
+++ b/src/Mod/Draft/draftfunctions/svg.py
@@ -396,7 +396,7 @@ def get_svg(obj,
direction: Base::Vector3, optional
It defaults to `None`.
- It is an arbitrary projection vector or a `WorkingPlane.Plane`
+ It is an arbitrary projection vector or a `WorkingPlane.PlaneBase`
instance.
linestyle: optional
@@ -462,13 +462,13 @@ def get_svg(obj,
if direction:
if isinstance(direction, App.Vector):
if direction != App.Vector(0, 0, 0):
- plane = WorkingPlane.plane()
- plane.alignToPointAndAxis_SVG(App.Vector(0, 0, 0),
- direction.negative().negative(),
- 0)
+ plane = WorkingPlane.PlaneBase()
+ plane.align_to_point_and_axis_svg(App.Vector(0, 0, 0),
+ direction.negative().negative(),
+ 0)
else:
raise ValueError("'direction' cannot be: Vector(0, 0, 0)")
- elif isinstance(direction, WorkingPlane.plane):
+ elif isinstance(direction, WorkingPlane.PlaneBase):
plane = direction
stroke = "#000000"
diff --git a/src/Mod/Draft/draftfunctions/svgshapes.py b/src/Mod/Draft/draftfunctions/svgshapes.py
index 33df138a70..eace6c12c1 100644
--- a/src/Mod/Draft/draftfunctions/svgshapes.py
+++ b/src/Mod/Draft/draftfunctions/svgshapes.py
@@ -32,6 +32,7 @@ import lazy_loader.lazy_loader as lz
import FreeCAD as App
import DraftVecUtils
+import WorkingPlane
import draftutils.utils as utils
from draftutils.messages import _msg, _wrn
@@ -58,8 +59,8 @@ def get_proj(vec, plane=None):
vec: Base::Vector3
An arbitrary vector that will be projected on the U and V directions.
- plane: WorkingPlane.Plane
- An object of type `WorkingPlane`.
+ plane: WorkingPlane.PlaneBase
+ Working plane.
"""
if not plane:
return vec
@@ -124,13 +125,10 @@ def _get_path_circ_ellipse(plane, edge, verts, edata,
iscircle, isellipse,
fill, stroke, linewidth, lstyle):
"""Get the edge data from a path that is a circle or ellipse."""
- if hasattr(App, "DraftWorkingPlane"):
- drawing_plane_normal = App.DraftWorkingPlane.axis
- else:
- drawing_plane_normal = App.Vector(0, 0, 1)
-
if plane:
drawing_plane_normal = plane.axis
+ else:
+ drawing_plane_normal = WorkingPlane.get_working_plane(update=False).axis
center = edge.Curve
ax = center.Axis
@@ -272,13 +270,10 @@ def get_circle(plane,
cen = get_proj(edge.Curve.Center, plane)
rad = edge.Curve.Radius
- if hasattr(App, "DraftWorkingPlane"):
- drawing_plane_normal = App.DraftWorkingPlane.axis
- else:
- drawing_plane_normal = App.Vector(0, 0, 1)
-
if plane:
drawing_plane_normal = plane.axis
+ else:
+ drawing_plane_normal = WorkingPlane.get_working_plane(update=False).axis
if round(edge.Curve.Axis.getAngle(drawing_plane_normal), 2) in [0, 3.14]:
# Perpendicular projection: circle
diff --git a/src/Mod/Draft/draftgeoutils/wires.py b/src/Mod/Draft/draftgeoutils/wires.py
index 45dec6d4bc..751f29de52 100644
--- a/src/Mod/Draft/draftgeoutils/wires.py
+++ b/src/Mod/Draft/draftgeoutils/wires.py
@@ -35,6 +35,7 @@ import WorkingPlane
from draftgeoutils.general import geomType, vec, precision
from draftgeoutils.geometry import get_normal
+from draftgeoutils.geometry import project_point_on_plane
from draftgeoutils.edges import findMidpoint, isLine
# Delay import of module until first use because it is heavy
@@ -169,9 +170,7 @@ def flattenWire(wire, origin=None, normal=None):
if origin is None:
origin = wire.Vertexes[0].Point
- plane = WorkingPlane.plane()
- plane.alignToPointAndAxis(origin, normal, 0)
- points = [plane.projectPoint(vert.Point) for vert in wire.Vertexes]
+ points = [project_point_on_plane(vert.Point, origin, normal) for vert in wire.Vertexes]
if wire.isClosed():
points.append(points[0])
new_wire = Part.makePolygon(points)
diff --git a/src/Mod/Draft/draftguitools/__init__.py b/src/Mod/Draft/draftguitools/__init__.py
index a269186771..e5ae062e57 100644
--- a/src/Mod/Draft/draftguitools/__init__.py
+++ b/src/Mod/Draft/draftguitools/__init__.py
@@ -46,19 +46,16 @@ as they normally require graphical input in the task panel or a selection
in the 3D view (`Gui.Selection`).
Most of these GUI tools require certain components of Draft to exist
-like the `gui_snapper.Snapper`, the `WorkingPlane.Plane`,
-and the `DraftGui.DraftToolBar` classes.
-These classes are normally installed in the global `App` or `Gui`
-namespaces, so they are accessible at all times.
+like the `gui_snapper.Snapper`and the `DraftGui.DraftToolBar` classes.
+These classes are normally installed in the global `Gui` namespace,
+so they are accessible at all times.
::
import DraftGui
import draftguitools.gui_snapper
- import WorkingPlane
Gui.draftToolBar = DraftGui.DraftToolBar()
Gui.Snapper = draftguitools.gui_snapper.Snapper()
- App.DraftWorkingPlane = WorkingPlane.Plane()
These classes can be imported and initialized individually
but it is easier to set them up just by importing `DraftTools`.
diff --git a/src/Mod/Draft/draftguitools/gui_snapper.py b/src/Mod/Draft/draftguitools/gui_snapper.py
index f631b4780b..a541b3aebd 100644
--- a/src/Mod/Draft/draftguitools/gui_snapper.py
+++ b/src/Mod/Draft/draftguitools/gui_snapper.py
@@ -189,6 +189,10 @@ class Snapper:
('special', ':/icons/Draft_Snap_Special.svg')])
+ def _get_wp(self):
+ return App.DraftWorkingPlane
+
+
def init_active_snaps(self):
"""
set self.active_snaps according to user prefs
@@ -512,8 +516,7 @@ class Snapper:
def toWP(self, point):
"""Project the given point on the working plane, if needed."""
if self.isEnabled("WorkingPlane"):
- if hasattr(App, "DraftWorkingPlane"):
- return App.DraftWorkingPlane.projectPoint(point)
+ return self._get_wp().project_point(point)
return point
@@ -522,14 +525,13 @@ class Snapper:
view = Draft.get3DView()
pt = view.getPoint(x, y)
if self.mask != "z":
- if hasattr(App,"DraftWorkingPlane"):
- if view.getCameraType() == "Perspective":
- camera = view.getCameraNode()
- p = camera.getField("position").getValue()
- dv = pt.sub(App.Vector(p[0], p[1], p[2]))
- else:
- dv = view.getViewDirection()
- return App.DraftWorkingPlane.projectPoint(pt, dv)
+ if view.getCameraType() == "Perspective":
+ camera = view.getCameraNode()
+ p = camera.getField("position").getValue()
+ dv = pt.sub(App.Vector(p[0], p[1], p[2]))
+ else:
+ dv = view.getViewDirection()
+ return self._get_wp().project_point(pt, dv)
return pt
@@ -696,14 +698,8 @@ class Snapper:
if self.isEnabled('Ortho') and (not self.mask):
if last:
vecs = []
- if hasattr(App,"DraftWorkingPlane"):
- ax = [App.DraftWorkingPlane.u,
- App.DraftWorkingPlane.v,
- App.DraftWorkingPlane.axis]
- else:
- ax = [App.Vector(1, 0, 0),
- App.Vector(0, 1, 0),
- App.Vector(0, 0, 1)]
+ wp = self._get_wp()
+ ax = [wp.u, wp.v, wp.axis]
for a in self.polarAngles:
if a == 90:
vecs.extend([ax[0], ax[0].negative()])
@@ -892,12 +888,9 @@ class Snapper:
"""
if not self.holdPoints:
return None
- if hasattr(App, "DraftWorkingPlane"):
- u = App.DraftWorkingPlane.u
- v = App.DraftWorkingPlane.v
- else:
- u = App.Vector(1, 0, 0)
- v = App.Vector(0, 1, 0)
+ wp = self._get_wp()
+ u = wp.u
+ v = wp.v
if len(self.holdPoints) > 1:
# first try mid points
if self.isEnabled("Midpoint"):
@@ -1285,10 +1278,6 @@ class Snapper:
must be constrained. If no basepoint is given, the current point is
used as basepoint.
"""
- # without the Draft module fully loaded, no axes system!"
- if not hasattr(App, "DraftWorkingPlane"):
- return point
-
point = App.Vector(point)
# setup trackers if needed
@@ -1307,25 +1296,26 @@ class Snapper:
delta = point.sub(self.basepoint)
# setting constraint axis
+ wp = self._get_wp()
if self.mask:
self.affinity = self.mask
if not self.affinity:
- self.affinity = App.DraftWorkingPlane.getClosestAxis(delta)
+ self.affinity = wp.get_closest_axis(delta)
if isinstance(axis, App.Vector):
self.constraintAxis = axis
elif axis == "x":
- self.constraintAxis = App.DraftWorkingPlane.u
+ self.constraintAxis = wp.u
elif axis == "y":
- self.constraintAxis = App.DraftWorkingPlane.v
+ self.constraintAxis = wp.v
elif axis == "z":
- self.constraintAxis = App.DraftWorkingPlane.axis
+ self.constraintAxis = wp.axis
else:
if self.affinity == "x":
- self.constraintAxis = App.DraftWorkingPlane.u
+ self.constraintAxis = wp.u
elif self.affinity == "y":
- self.constraintAxis = App.DraftWorkingPlane.v
+ self.constraintAxis = wp.v
elif self.affinity == "z":
- self.constraintAxis = App.DraftWorkingPlane.axis
+ self.constraintAxis = wp.axis
elif isinstance(self.affinity, App.Vector):
self.constraintAxis = self.affinity
else:
@@ -1411,10 +1401,9 @@ class Snapper:
shift = event.wasShiftDown()
self.pt = Gui.Snapper.snap(mousepos, lastpoint=last,
active=ctrl, constrain=shift)
- if hasattr(App, "DraftWorkingPlane"):
- self.ui.displayPoint(self.pt, last,
- plane=App.DraftWorkingPlane,
- mask=Gui.Snapper.affinity)
+ self.ui.displayPoint(self.pt, last,
+ plane=self._get_wp(),
+ mask=Gui.Snapper.affinity)
if movecallback:
movecallback(self.pt, self.snapInfo)
@@ -1422,9 +1411,10 @@ class Snapper:
"""Get the global coordinates from a point."""
# Same algorithm as in validatePoint in DraftGui.py.
ref = App.Vector(0, 0, 0)
- if global_mode is False and hasattr(App, "DraftWorkingPlane"):
- point = App.DraftWorkingPlane.getGlobalRot(point)
- ref = App.DraftWorkingPlane.getGlobalCoords(ref)
+ if global_mode is False:
+ wp = self._get_wp()
+ point = wp.get_global_coords(point, as_vector=True)
+ ref = wp.get_global_coords(ref)
if relative_mode is True and last is not None:
ref = last
self.pt = point + ref
diff --git a/src/Mod/Draft/draftguitools/gui_trackers.py b/src/Mod/Draft/draftguitools/gui_trackers.py
index a3d1fc8903..a54ffed8ba 100644
--- a/src/Mod/Draft/draftguitools/gui_trackers.py
+++ b/src/Mod/Draft/draftguitools/gui_trackers.py
@@ -140,6 +140,9 @@ class Tracker:
sg.removeChild(self.switch)
sg.insertChild(self.switch, 0)
+ def _get_wp(self):
+ return FreeCAD.DraftWorkingPlane
+
class snapTracker(Tracker):
"""Define Snap Mark tracker, used by tools that support snapping."""
@@ -237,8 +240,9 @@ class rectangleTracker(Tracker):
super().__init__(dotted, scolor, swidth,
[self.coords, line],
name="rectangleTracker")
- self.u = FreeCAD.DraftWorkingPlane.u
- self.v = FreeCAD.DraftWorkingPlane.v
+ wp = self._get_wp()
+ self.u = wp.u
+ self.v = wp.v
def setorigin(self, point):
"""Set the base point of the rectangle."""
@@ -265,7 +269,7 @@ class rectangleTracker(Tracker):
if v:
self.v = v
else:
- norm = FreeCAD.DraftWorkingPlane.u.cross(FreeCAD.DraftWorkingPlane.v)
+ norm = self._get_wp().axis
self.v = self.u.cross(norm)
def p1(self, point=None):
@@ -538,7 +542,7 @@ class arcTracker(Tracker):
self.trans.translation.setValue([0, 0, 0])
self.sep = coin.SoSeparator()
self.autoinvert = True
- self.normal = FreeCAD.DraftWorkingPlane.axis
+ self.normal = self._get_wp().axis
self.recompute()
super().__init__(dotted, scolor, swidth,
[self.trans, self.sep], name="arcTracker")
@@ -922,11 +926,9 @@ class PlaneTracker(Tracker):
def set(self, pos=None):
"""Set the translation to the position."""
- if pos:
- Q = FreeCAD.DraftWorkingPlane.getRotation().Rotation.Q
- else:
- plm = FreeCAD.DraftWorkingPlane.getPlacement()
- Q = plm.Rotation.Q
+ plm = self._get_wp().get_placement()
+ Q = plm.Rotation.Q
+ if pos is None:
pos = plm.Base
self.trans.translation.setValue([pos.x, pos.y, pos.z])
self.trans.rotation.setValue([Q[0], Q[1], Q[2], Q[3]])
@@ -1162,10 +1164,8 @@ class gridTracker(Tracker):
self.coords3.point.setValues(apts)
#self.lines3.numVertices.setValues(aidx)
self.pts = pts
- self.displayHumanFigure()
- self.setAxesColor()
- def displayHumanFigure(self):
+ def displayHumanFigure(self, wp):
""" Display the human figure at the grid corner.
The silhouette is displayed only if:
- BIM Workbench is available;
@@ -1178,7 +1178,7 @@ class gridTracker(Tracker):
pidx = []
param = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
if param.GetBool("gridShowHuman", True) and \
- FreeCAD.DraftWorkingPlane.axis.getAngle(FreeCAD.Vector(0,0,1)) < 0.001:
+ wp.axis.getAngle(FreeCAD.Vector(0,0,1)) < 0.001:
try:
import BimProject
loc = FreeCAD.Vector(-bound+self.space/2,-bound+self.space/2,0)
@@ -1192,11 +1192,10 @@ class gridTracker(Tracker):
self.coords_human.point.setValues(pts)
self.human.numVertices.setValues(pidx)
- def setAxesColor(self):
+ def setAxesColor(self, wp):
"""set axes color"""
cols = [0,0]
- if Draft.getParam("coloredGridAxes",True) and hasattr(FreeCAD,"DraftWorkingPlane"):
- wp = FreeCAD.DraftWorkingPlane
+ if Draft.getParam("coloredGridAxes",True):
if round(wp.u.getAngle(FreeCAD.Vector(1,0,0)),2) in (0,3.14):
cols[0] = 1
elif round(wp.u.getAngle(FreeCAD.Vector(0,1,0)),2) in (0,3.14):
@@ -1239,23 +1238,23 @@ class gridTracker(Tracker):
def set(self,tool=False):
"""Move and rotate the grid according to the current working plane."""
self.reset()
- Q = FreeCAD.DraftWorkingPlane.getRotation().Rotation.Q
- P = FreeCAD.DraftWorkingPlane.position
+ wp = self._get_wp()
+ Q = wp.get_placement().Rotation.Q
+ P = wp.position
self.trans.rotation.setValue([Q[0], Q[1], Q[2], Q[3]])
self.trans.translation.setValue([P.x, P.y, P.z])
- self.displayHumanFigure()
- self.setAxesColor()
+ self.displayHumanFigure(wp)
+ self.setAxesColor(wp)
if tool:
self.on()
def getClosestNode(self, point):
"""Return the closest node from the given point."""
- # get the 2D coords.
- # point = FreeCAD.DraftWorkingPlane.projectPoint(point)
- pt = FreeCAD.DraftWorkingPlane.getLocalCoords(point)
+ wp = self._get_wp()
+ pt = wp.get_local_coords(point)
pu = round(pt.x / self.space, 0) * self.space
pv = round(pt.y / self.space, 0) * self.space
- pt = FreeCAD.DraftWorkingPlane.getGlobalCoords(Vector(pu, pv, 0))
+ pt = wp.get_global_coords(Vector(pu, pv, 0))
return pt
@@ -1287,7 +1286,7 @@ class boxTracker(Tracker):
"""Update the tracker."""
import DraftGeomUtils
if not normal:
- normal = FreeCAD.DraftWorkingPlane.axis
+ normal = self._get_wp().axis
if line:
if isinstance(line, list):
bp = line[0]
@@ -1403,10 +1402,10 @@ class archDimTracker(Tracker):
def setString(self, text=None):
"""Set the dim string to the given value or auto value."""
- plane = FreeCAD.DraftWorkingPlane
+ plane = self._get_wp()
p1 = Vector(self.pnts.getValues()[0].getValue())
p2 = Vector(self.pnts.getValues()[-1].getValue())
- self.norm.setValue(plane.getNormal())
+ self.norm.setValue(plane.axis)
# set the offset sign to prevent the dim line from intersecting the curve near the cursor
sign_dx = math.copysign(1, (p2.sub(p1)).x)
sign_dy = math.copysign(1, (p2.sub(p1)).y)
@@ -1421,7 +1420,7 @@ class archDimTracker(Tracker):
self.Distance = (p2.sub(p1)).Length
text = FreeCAD.Units.Quantity(self.Distance, FreeCAD.Units.Length).UserString
- self.matrix.setValue(*plane.getPlacement().Matrix.transposed().A)
+ self.matrix.setValue(*plane.get_placement().Matrix.transposed().A)
self.string.setValue(text.encode('utf8'))
# change the text position to external depending on the distance and scale values
volume = self.camera.getViewVolume()
@@ -1444,9 +1443,9 @@ class archDimTracker(Tracker):
def p1(self, point=None):
"""Set or get the first point of the dim."""
- plane = FreeCAD.DraftWorkingPlane
+ plane = self._get_wp()
if point:
- p1_proj = plane.projectPoint(point)
+ p1_proj = plane.project_point(point)
p1_proj_u = (p1_proj - plane.position).dot(plane.u.normalize())
p1_proj_v = (p1_proj - plane.position).dot(plane.v.normalize())
self.pnts.set1Value(0, p1_proj_u, p1_proj_v, 0)
@@ -1456,9 +1455,9 @@ class archDimTracker(Tracker):
def p2(self, point=None):
"""Set or get the second point of the dim."""
- plane = FreeCAD.DraftWorkingPlane
+ plane = self._get_wp()
if point:
- p2_proj = plane.projectPoint(point)
+ p2_proj = plane.project_point(point)
p2_proj_u = (p2_proj - plane.position).dot(plane.u.normalize())
p2_proj_v = (p2_proj - plane.position).dot(plane.v.normalize())
self.pnts.set1Value(1, p2_proj_u, p2_proj_v, 0)
diff --git a/src/Mod/Draft/draftmake/make_clone.py b/src/Mod/Draft/draftmake/make_clone.py
index d6158cd71e..4b6e338ef8 100644
--- a/src/Mod/Draft/draftmake/make_clone.py
+++ b/src/Mod/Draft/draftmake/make_clone.py
@@ -88,16 +88,13 @@ def make_clone(obj, delta=None, forcedraft=False):
base = utils.get_clone_base(obj[0])
cl.Label = prefix + base.Label
cl.CloneOf = base
- if hasattr(cl,"Material") and hasattr(obj[0],"Material"):
- cl.Material = obj[0].Material
if utils.get_type(obj[0]) != "BuildingPart":
cl.Placement = obj[0].Placement
- try:
- cl.Role = base.Role
- cl.Description = base.Description
- cl.Tag = base.Tag
- except Exception:
- pass
+ for prop in ("Description", "IfcType", "Material", "Subvolume", "Tag"):
+ try:
+ setattr(cl, prop, getattr(base, prop))
+ except Exception:
+ pass
if App.GuiUp:
gui_utils.format_object(cl, base)
# Workaround to trigger update of DiffuseColor:
diff --git a/src/Mod/Draft/draftmake/make_dimension.py b/src/Mod/Draft/draftmake/make_dimension.py
index aecd4b48c5..e6830bcc1f 100644
--- a/src/Mod/Draft/draftmake/make_dimension.py
+++ b/src/Mod/Draft/draftmake/make_dimension.py
@@ -36,13 +36,14 @@ This includes linear dimensions, radial dimensions, and angular dimensions.
import math
import FreeCAD as App
-import draftutils.utils as utils
-import draftutils.gui_utils as gui_utils
+import WorkingPlane
+from draftutils import gui_utils
+from draftutils import utils
from draftutils.messages import _msg, _wrn, _err
from draftutils.translate import translate
-from draftobjects.dimension import (LinearDimension,
- AngularDimension)
+
+from draftobjects.dimension import LinearDimension, AngularDimension
if App.GuiUp:
from draftviewproviders.view_dimension \
@@ -147,10 +148,7 @@ def make_dimension(p1, p2, p3=None, p4=None):
# depending on the first three parameter values
new_obj.Dimline = p3
- if hasattr(App, "DraftWorkingPlane"):
- normal = App.DraftWorkingPlane.axis
- else:
- normal = App.Vector(0, 0, 1)
+ normal = WorkingPlane.get_working_plane(update=False).axis
if App.GuiUp:
# invert the normal if we are viewing it from the back
@@ -536,11 +534,8 @@ def make_angular_dimension(center=App.Vector(0, 0, 0),
the circular arc.
normal: Base::Vector3, optional
- It defaults to `None`, in which case the `normal` is taken
- from the currently active `App.DraftWorkingPlane.axis`.
-
- If the working plane is not available, then the `normal`
- defaults to +Z or `Vector(0, 0, 1)`.
+ It defaults to `None`, in which case the axis of the current working
+ plane is used.
Returns
-------
@@ -608,10 +603,7 @@ def make_angular_dimension(center=App.Vector(0, 0, 0),
return None
if not normal:
- if hasattr(App, "DraftWorkingPlane"):
- normal = App.DraftWorkingPlane.axis
- else:
- normal = App.Vector(0, 0, 1)
+ normal = WorkingPlane.get_working_plane(update=False).axis
new_obj = App.ActiveDocument.addObject("App::FeaturePython",
"Dimension")
diff --git a/src/Mod/Draft/draftobjects/dimension.py b/src/Mod/Draft/draftobjects/dimension.py
index 1b375eb2da..484fc8e226 100644
--- a/src/Mod/Draft/draftobjects/dimension.py
+++ b/src/Mod/Draft/draftobjects/dimension.py
@@ -106,8 +106,9 @@ from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD as App
import DraftVecUtils
import DraftGeomUtils
-import draftutils.utils as utils
+import WorkingPlane
+from draftutils import utils
from draftutils.messages import _wrn
from draftutils.translate import translate
@@ -648,10 +649,10 @@ def measure_two_obj_angles(link_sub_1, link_sub_2):
start = obj1.Shape.Edges[n1].Curve.Direction
end = obj2.Shape.Edges[n2].Curve.Direction
- # We get the angle from the direction of the line to the U axis
- # of the working plane; we should be able to also use the V axis
- start_r = DraftVecUtils.angle(start, App.DraftWorkingPlane.u)
- end_r = DraftVecUtils.angle(end, App.DraftWorkingPlane.u)
+ # We get the angle from the U axis of the working plane
+ wp = WorkingPlane.get_working_plane(update=False)
+ start_r = DraftVecUtils.angle(start, wp.u)
+ end_r = DraftVecUtils.angle(end, wp.u)
start = math.degrees(start_r)
end = math.degrees(end_r)
diff --git a/src/Mod/Draft/drafttaskpanels/task_circulararray.py b/src/Mod/Draft/drafttaskpanels/task_circulararray.py
index 0a58701875..f3f7f17e8b 100644
--- a/src/Mod/Draft/drafttaskpanels/task_circulararray.py
+++ b/src/Mod/Draft/drafttaskpanels/task_circulararray.py
@@ -392,10 +392,8 @@ class TaskPanelCircularArray:
point: Base::Vector3
is a vector that arrives by the callback.
- plane: WorkingPlane
- is a `WorkingPlane` instance, for example,
- `App.DraftWorkingPlane`. It is not used at the moment,
- but could be used to set up the grid.
+ plane: WorkingPlane.PlaneGui
+ is a working plane instance. Not used at the moment.
mask: str
is a string that specifies which coordinate is being
edited. It is used to restrict edition of a single coordinate.
diff --git a/src/Mod/Draft/drafttaskpanels/task_polararray.py b/src/Mod/Draft/drafttaskpanels/task_polararray.py
index 81e3f8227e..f4888bd0e1 100644
--- a/src/Mod/Draft/drafttaskpanels/task_polararray.py
+++ b/src/Mod/Draft/drafttaskpanels/task_polararray.py
@@ -346,9 +346,7 @@ class TaskPanelPolarArray:
point :
is a vector that arrives by the callback.
plane :
- is a `WorkingPlane` instance, for example,
- `App.DraftWorkingPlane`. It is not used at the moment,
- but could be used to set up the grid.
+ is a `WorkingPlane.PlaneGui` instance. Not used at the moment.
mask :
is a string that specifies which coordinate is being
edited. It is used to restrict edition of a single coordinate.
diff --git a/src/Mod/Draft/draftviewproviders/view_wire.py b/src/Mod/Draft/draftviewproviders/view_wire.py
index 1b33202180..c8297c871e 100644
--- a/src/Mod/Draft/draftviewproviders/view_wire.py
+++ b/src/Mod/Draft/draftviewproviders/view_wire.py
@@ -39,6 +39,7 @@ from PySide.QtCore import QT_TRANSLATE_NOOP
import FreeCAD as App
import FreeCADGui as Gui
import DraftVecUtils
+import WorkingPlane
import draftgeoutils.wires as wires
import draftutils.utils as utils
import draftutils.gui_utils as gui_utils
@@ -152,20 +153,10 @@ class ViewProviderWire(ViewProviderDraft):
if not hasattr(self, "Object"):
return
- if hasattr(App, "DraftWorkingPlane"):
- App.DraftWorkingPlane.setup()
- origin = App.DraftWorkingPlane.position
- normal = App.DraftWorkingPlane.axis
- # Align the grid for visual feedback:
- if hasattr(Gui, "Snapper"):
- Gui.Snapper.setTrackers()
- else:
- origin = App.Vector(0, 0, 0)
- normal = App.Vector(0, 0, 1)
-
+ wp = WorkingPlane.get_working_plane()
flat_wire = wires.flattenWire(self.Object.Shape.Wires[0],
- origin=origin,
- normal=normal)
+ origin=wp.position,
+ normal=wp.axis)
doc = App.ActiveDocument
doc.openTransaction(translate("draft", "Flatten"))
diff --git a/src/Mod/Draft/importDXF.py b/src/Mod/Draft/importDXF.py
index 4ffd1a2622..c146e9a8ca 100644
--- a/src/Mod/Draft/importDXF.py
+++ b/src/Mod/Draft/importDXF.py
@@ -65,11 +65,6 @@ from Draft import _Dimension
from FreeCAD import Vector
from FreeCAD import Console as FCC
-# sets the default working plane if Draft hasn't been started yet
-if not hasattr(FreeCAD, "DraftWorkingPlane"):
- plane = WorkingPlane.plane()
- FreeCAD.DraftWorkingPlane = plane
-
gui = FreeCAD.GuiUp
draftui = None
if gui:
@@ -739,10 +734,10 @@ def placementFromDXFOCS(ent):
what is needed is a 3D vector defining the Z axis of the OCS,
and the elevation value over it.
- It uses `WorkingPlane.alignToPointAndAxis()` to align the working plane
+ It uses `WorkingPlane.align_to_point_and_axis()` to align the working plane
to the origin and to `ent.extrusion` (the plane's `axis`).
Then it gets the global coordinates of the entity
- by using `WorkingPlane.getGlobalCoords()`
+ by using `WorkingPlane.get_global_coords()`
and either `ent.elevation` (Z coordinate) or `ent.loc` a `(x,y,z)` tuple.
Parameters
@@ -760,11 +755,11 @@ def placementFromDXFOCS(ent):
See also
--------
- WorkingPlane.alignToPointAndAxis, WorkingPlane.getGlobalCoords
+ WorkingPlane.align_to_point_and_axis, WorkingPlane.get_global_coords
"""
- draftWPlane = FreeCAD.DraftWorkingPlane
- draftWPlane.alignToPointAndAxis(Vector(0.0, 0.0, 0.0),
- vec(ent.extrusion), 0.0)
+ draftWPlane = WorkingPlane.PlaneBase()
+ draftWPlane.align_to_point_and_axis(Vector(0.0, 0.0, 0.0),
+ vec(ent.extrusion), 0.0)
# Object Coordinate Systems (OCS)
# http://docs.autodesk.com/ACD/2011/ENU/filesDXF/WS1a9193826455f5ff18cb41610ec0a2e719-7941.htm
# Arbitrary Axis Algorithm
@@ -787,14 +782,12 @@ def placementFromDXFOCS(ent):
draftWPlane.v = draftWPlane.axis.cross(draftWPlane.u)
draftWPlane.v.normalize()
draftWPlane.position = Vector(0.0, 0.0, 0.0)
- draftWPlane.weak = False
- pl = FreeCAD.Placement()
- pl = draftWPlane.getPlacement()
+ pl = draftWPlane.get_placement()
if ((ent.type == "lwpolyline") or (ent.type == "polyline")):
- pl.Base = draftWPlane.getGlobalCoords(vec([0.0, 0.0, ent.elevation]))
+ pl.Base = draftWPlane.get_global_coords(vec([0.0, 0.0, ent.elevation]))
else:
- pl.Base = draftWPlane.getGlobalCoords(vec(ent.loc))
+ pl.Base = draftWPlane.get_global_coords(vec(ent.loc))
return pl
@@ -2305,7 +2298,7 @@ def processdxf(document, filename, getShapes=False, reComputeFlag=True):
edges.extend(s.Edges)
if len(edges) > (100):
FCC.PrintMessage(str(len(edges)) + " edges to join\n")
- if FreeCAD.GuiUp:
+ if gui:
d = QtGui.QMessageBox()
d.setText("Warning: High number of entities to join (>100)")
d.setInformativeText("This might take a long time "
@@ -2528,7 +2521,7 @@ def processdxf(document, filename, getShapes=False, reComputeFlag=True):
newob = doc.addObject("App::FeaturePython", "Dimension")
lay.addObject(newob)
_Dimension(newob)
- if FreeCAD.GuiUp:
+ if gui:
from Draft import _ViewProviderDimension
_ViewProviderDimension(newob.ViewObject)
newob.Start = p1
@@ -3526,8 +3519,7 @@ def export(objectslist, filename, nospline=False, lwPoly=False):
getDXFlibs()
if dxfLibrary:
global exportList
- exportList = objectslist
- exportList = Draft.get_group_contents(exportList)
+ exportList = Draft.get_group_contents(objectslist, spaces=True)
nlist = []
exportLayers = []
@@ -3609,36 +3601,30 @@ def export(objectslist, filename, nospline=False, lwPoly=False):
elif obtype == "PanelCut":
writePanelCut(ob, dxf, nospline, lwPoly)
- elif obtype == "Space":
+ elif obtype == "Space" and gui:
vobj = ob.ViewObject
- c = utils.get_rgb(vobj.TextColor)
- n = vobj.FontName
- a = 0
- if rotation != 0:
- a = math.radians(rotation)
+ rotation = math.degrees(ob.Placement.Rotation.Angle)
t1 = "".join(vobj.Proxy.text1.string.getValues())
t2 = "".join(vobj.Proxy.text2.string.getValues())
- scale = vobj.FirstLine.Value/vobj.FontSize.Value
- f1 = fontsize * scale
- if round(FreeCAD.DraftWorkingPlane.axis.getAngle(App.Vector(0,0,1)),2) not in [0,3.14]:
- # if not in XY view, place the label at center
- p2 = obj.Shape.CenterOfMass
- else:
- _v = vobj.Proxy.coords.translation.getValue().getValue()
- p2 = obj.Placement.multVec(App.Vector(_v))
+ h1 = vobj.FirstLine.Value
+ h2 = vobj.FontSize.Value
+ _v = vobj.Proxy.coords.translation.getValue().getValue()
_h = vobj.Proxy.header.translation.getValue().getValue()
+ p2 = FreeCAD.Vector(_v)
lspc = FreeCAD.Vector(_h)
- p1 = p2 + lspc
- dxf.append(dxfLibrary.Text(t1, p1, height=f1,
+ p1 = ob.Placement.multVec(p2 + lspc)
+ dxf.append(dxfLibrary.Text(t1, p1, height=h1 * 0.8,
+ rotation=rotation,
color=getACI(ob, text=True),
style='STANDARD',
layer=getStrGroup(ob)))
if t2:
ofs = FreeCAD.Vector(0, -lspc.Length, 0)
- if a:
+ if rotation:
Z = FreeCAD.Vector(0, 0, 1)
- ofs = FreeCAD.Rotation(Z, -rotation).multVec(ofs)
- dxf.append(dxfLibrary.Text(t2, p1.add(ofs), height=f1,
+ ofs = FreeCAD.Rotation(Z, rotation).multVec(ofs)
+ dxf.append(dxfLibrary.Text(t2, p1.add(ofs), height=h2 * 0.8,
+ rotation=rotation,
color=getACI(ob, text=True),
style='STANDARD',
layer=getStrGroup(ob)))
@@ -3653,7 +3639,7 @@ def export(objectslist, filename, nospline=False, lwPoly=False):
color=getACI(ob),
layer=getStrGroup(ob)))
h = 1
- if FreeCAD.GuiUp:
+ if gui:
vobj = ob.ViewObject
h = float(ob.ViewObject.FontSize)
for text in vobj.Proxy.getTextData():
@@ -4059,7 +4045,7 @@ def readPreferences():
"""
# reading parameters
p = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Draft")
- if FreeCAD.GuiUp and p.GetBool("dxfShowDialog", False):
+ if gui and p.GetBool("dxfShowDialog", False):
FreeCADGui.showPreferences("Import-Export", 3)
global dxfCreatePart, dxfCreateDraft, dxfCreateSketch
global dxfDiscretizeCurves, dxfStarBlocks
diff --git a/src/Mod/Draft/importSVG.py b/src/Mod/Draft/importSVG.py
index 588be1bf9c..2c5c12e477 100644
--- a/src/Mod/Draft/importSVG.py
+++ b/src/Mod/Draft/importSVG.py
@@ -1896,7 +1896,7 @@ def export(exportList, filename):
# raw-style exports do not translate the sketch
svg.write('\n' % ob.Name)
- svg.write(Draft.get_svg(ob))
+ svg.write(Draft.get_svg(ob, override=False))
_label_enc = str(ob.Label.encode('utf8'))
_label = _label_enc.replace('<', '<').replace('>', '>')
# replace('"', """)
diff --git a/src/Mod/Part/App/AppPartPy.cpp b/src/Mod/Part/App/AppPartPy.cpp
index 1ab082d699..6e219af4e9 100644
--- a/src/Mod/Part/App/AppPartPy.cpp
+++ b/src/Mod/Part/App/AppPartPy.cpp
@@ -607,7 +607,7 @@ public:
"* transform: if False, then skip obj's transformation. Use this if mat already include obj's\n"
" transformation matrix\n"
"* retType: 0: return TopoShape,\n"
- " 1: return (shape,subObj,mat), where subObj is the object referenced in 'subname',\n"
+ " 1: return (shape,mat,subObj), where subObj is the object referenced in 'subname',\n"
" and 'mat' is the accumulated transformation matrix of that sub-object.\n"
" 2: same as 1, but make sure 'subObj' is resolved if it is a link.\n"
"* refine: refine the returned shape"
diff --git a/src/Mod/Part/App/GeomPlate/CurveConstraintPy.xml b/src/Mod/Part/App/GeomPlate/CurveConstraintPy.xml
index 4e0e12b7d3..941d20c07a 100644
--- a/src/Mod/Part/App/GeomPlate/CurveConstraintPy.xml
+++ b/src/Mod/Part/App/GeomPlate/CurveConstraintPy.xml
@@ -77,32 +77,41 @@ Raises an exception if the curve is not on a surface
-
+ Allows you to set the G2 criterion. This is the law
+ defining the greatest difference in curvature allowed
+ between the constraint and the target surface. If this
+ criterion is not set, TolCurv, the curvature tolerance from
+ the constructor, is used.
+ Raises ConstructionError if the point is not on the surface
+
-
+ Returns a 3d curve associated the surface resulting of the constraints
-
+ loads a 2d curve associated the surface resulting of the constraints
+
-
+ Returns a 2d curve associated the surface resulting of the constraints
-
+ loads a 2d curve resulting from the normal projection of
+ the curve on the initial surface
-
+ Returns the projected curve resulting from the normal projection of the
+ curve on the initial surface
@@ -116,19 +125,22 @@ the number of points.
-
+ This function returns the first parameter of the curve.
+The first parameter is the lowest parametric value for the curve, which defines the starting point of the curve.
-
+ This function returns the last parameter of the curve.
+The last parameter is the highest parametric value for the curve, which defines the ending point of the curve.
-
+ This function returns the length of the curve.
+The length of the curve is a geometric property that indicates how long the curve is in the space.
diff --git a/src/Mod/Part/App/GeomPlate/PointConstraintPy.xml b/src/Mod/Part/App/GeomPlate/PointConstraintPy.xml
index bc357852b4..60c9699e3f 100644
--- a/src/Mod/Part/App/GeomPlate/PointConstraintPy.xml
+++ b/src/Mod/Part/App/GeomPlate/PointConstraintPy.xml
@@ -77,22 +77,26 @@ Raises an exception if the curve is not on a surface
-
+ Allows you to set the G2 criterion. This is the law
+ defining the greatest difference in curvature allowed between the
+ constraint and the target surface. If this criterion is not
+ set, TolCurv, the curvature tolerance from the constructor, is used.
+ Raises ConstructionError if the curve is not on a surface
-
+ Checks if there is a 2D point associated with the surface. It returns a boolean indicating whether such a point exists.
-
+ Allows you to set a 2D point on the surface. It takes a gp_Pnt2d as an argument, representing the 2D point to be associated with the surface.
-
+ Returns the 2D point on the surface. It returns a gp_Pnt2d representing the associated 2D point.
diff --git a/src/Mod/Part/Gui/SectionCutting.cpp b/src/Mod/Part/Gui/SectionCutting.cpp
index ddf2c15b7d..7e032f03cf 100644
--- a/src/Mod/Part/Gui/SectionCutting.cpp
+++ b/src/Mod/Part/Gui/SectionCutting.cpp
@@ -26,7 +26,7 @@
// to avoid compiler warnings of redefining contents of basic.h
// later by #include
-# define _USE_MATH_DEFINES
+# define _USE_MATH_DEFINES // NOLINT
# include
# include
@@ -43,6 +43,7 @@
#include
#include
#include
+#include
#include
#include
#include
@@ -66,146 +67,148 @@
using namespace PartGui;
-enum Refresh : bool
+namespace
{
- notXValue = false,
- notYValue = false,
- notZValue = false,
- notXRange = false,
- notYRange = false,
- notZRange = false,
- XValue = true,
- YValue = true,
- ZValue = true,
- XRange = true,
- YRange = true,
- ZRange = true
+struct Refresh
+{
+ static const bool notXValue = false;
+ static const bool notYValue = false;
+ static const bool notZValue = false;
+ static const bool notXRange = false;
+ static const bool notYRange = false;
+ static const bool notZRange = false;
+ //static const bool XValue = true;
+ static const bool YValue = true;
+ static const bool ZValue = true;
+ static const bool XRange = true;
+ static const bool YRange = true;
+ static const bool ZRange = true;
};
+}
+// NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
SectionCut::SectionCut(QWidget* parent)
: QDialog(parent)
, ui(new Ui_SectionCut)
{
// create widgets
ui->setupUi(this);
- ui->cutX->setRange(-INT_MAX, INT_MAX);
- ui->cutY->setRange(-INT_MAX, INT_MAX);
- ui->cutZ->setRange(-INT_MAX, INT_MAX);
+ initSpinBoxes();
// get all objects in the document
auto docGui = Gui::Application::Instance->activeDocument();
if (!docGui) {
- Base::Console().Error("SectionCut error: there is no document\n");
- return;
+ throw Base::RuntimeError("SectionCut error: there is no document");
}
doc = docGui->getDocument();
if (!doc) {
- Base::Console().Error("SectionCut error: there is no document\n");
- return;
+ throw Base::RuntimeError("SectionCut error: there is no document");
}
std::vector ObjectsList = doc->getObjects();
if (ObjectsList.empty()) {
- Base::Console().Error("SectionCut error: there are no objects in the document\n");
- return;
- }
- // now store those that are currently visible
- for (auto anObject : ObjectsList) {
- if (anObject->Visibility.getValue())
- ObjectsListVisible.emplace_back(anObject);
+ throw Base::RuntimeError("SectionCut error: there are no objects in the document");
}
+ // now store those that are currently visible
+ for (auto anObject : ObjectsList) {
+ if (anObject->Visibility.getValue()) {
+ ObjectsListVisible.emplace_back(anObject);
+ }
+ }
+
+ // if we can have existing cut boxes, take their values
+ // to access the flip state we must compare the bounding boxes of the cutbox and the compound
+ Base::BoundBox3d BoundCompound = collectObjects();
+ initControls(BoundCompound);
+
+ // hide existing cuts to check if there are objects to be cut visible
+ hideCutObjects();
+
+ initCutRanges();
+
+ setupConnections();
+
+ tryStartCutting();
+}
+
+void SectionCut::initSpinBoxes()
+{
+ ui->cutX->setRange(-INT_MAX, INT_MAX);
+ ui->cutY->setRange(-INT_MAX, INT_MAX);
+ ui->cutZ->setRange(-INT_MAX, INT_MAX);
+}
+
+void SectionCut::initControls(const Base::BoundBox3d& BoundCompound)
+{
// lambda function to set color and transparency
auto setColorTransparency = [&](Part::Box* pcBox) {
App::Color cutColor;
- long cutTransparency;
+ long cutTransparency{};
auto vpBox = dynamic_cast(
Gui::Application::Instance->getViewProvider(pcBox));
if (vpBox) {
cutColor = vpBox->ShapeColor.getValue();
cutTransparency = vpBox->Transparency.getValue();
ui->CutColor->setColor(cutColor.asValue());
- ui->CutTransparencyHS->setValue(cutTransparency);
+ ui->CutTransparencyHS->setValue(int(cutTransparency));
ui->CutTransparencyHS->setToolTip(QString::number(cutTransparency)
+ QString::fromLatin1(" %"));
}
};
- // if we can have existing cut boxes, take their values
- // to access the flip state we must compare the bounding boxes of the cutbox and the compound
- Base::BoundBox3d BoundCompound;
- Base::BoundBox3d BoundCutBox;
- if (doc->getObject(BoxXName) || doc->getObject(BoxYName) || doc->getObject(BoxZName)) {
- // automatic coloring must be disabled
- ui->autoCutfaceColorCB->setChecked(false);
- ui->autoBFColorCB->setChecked(false);
- if (doc->getObject(CompoundName)) {
- // get the object with the right name
- auto compoundObject = doc->getObject(CompoundName);
- // to later store the childs
- std::vector compoundChilds;
+ initZControls(BoundCompound, setColorTransparency);
+ initYControls(BoundCompound, setColorTransparency);
+ initXControls(BoundCompound, setColorTransparency);
+}
- // check if this is a BooleanFragments or a Part::Compound
- // Part::Compound is the case when there was only one object
- Part::Compound* pcCompoundPart = dynamic_cast(compoundObject);
- if (!pcCompoundPart) {
- // for more security check for validity accessing its ViewProvider
- auto pcCompoundBF = Gui::Application::Instance->getViewProvider(compoundObject);
- if (!pcCompoundBF) {
- Base::Console().Error(
- "SectionCut error: compound is incorrectly named, cannot proceed\n");
- return;
- }
- auto property = compoundObject->getPropertyByName("Shape");
- Part::PropertyPartShape* objectShape =
- static_cast(property);
- BoundCompound = objectShape->getBoundingBox();
- // for BooleanFragments we also need to set the checkbox, transparency and color
- ui->groupBoxIntersecting->setChecked(true);
- auto pcCompoundBFGO = dynamic_cast(pcCompoundBF);
- if (pcCompoundBFGO) {
- App::Color compoundColor = pcCompoundBFGO->ShapeColor.getValue();
- ui->BFragColor->setColor(compoundColor.asValue());
- int compoundTransparency = pcCompoundBFGO->Transparency.getValue();
- ui->BFragTransparencyHS->setValue(compoundTransparency);
- ui->BFragTransparencyHS->setToolTip(QString::number(compoundTransparency)
- + QString::fromLatin1(" %"));
- // Part::Cut ignores the cutbox transparency when it is set
- // to zero and the BooleanFragments transparency is not zero
- // therefore limit the cutbox transparency to 1 in this case
- if (compoundTransparency > 0)
- ui->CutTransparencyHS->setMinimum(1);
- else
- ui->CutTransparencyHS->setMinimum(0);
- }
- compoundChilds = pcCompoundBF->claimChildren();
- }
- else {
- BoundCompound = pcCompoundPart->Shape.getBoundingBox();
- pcCompoundPart->Links.getLinks(compoundChilds);
- }
- // make parent objects of links visible to handle the case that
- // the cutting is started when only an existing cut was visible
- for (auto aCompoundObj : compoundChilds) {
- App::Link* pcLink = dynamic_cast(aCompoundObj);
- auto LinkedObject = pcLink ? pcLink->getLink() : nullptr;
- if (LinkedObject) {
- // only if not already visible
- if (!(LinkedObject->Visibility.getValue())) {
- LinkedObject->Visibility.setValue(true);
- ObjectsListVisible.emplace_back(LinkedObject);
- }
- }
- }
+void SectionCut::initXControls(const Base::BoundBox3d& BoundCompound,
+ const std::function& setTransparency)
+{
+ Base::BoundBox3d BoundCutBox;
+ if (auto pcBox = findCutBox(BoxXName)) {
+ hasBoxX = true;
+ ui->groupBoxX->setChecked(true);
+ BoundCutBox = pcBox->Shape.getBoundingBox();
+ if (BoundCutBox.MinX > BoundCompound.MinX) {
+ ui->cutX->setValue(pcBox->Placement.getValue().getPosition().x);
+ ui->flipX->setChecked(true);
}
+ else {
+ ui->cutX->setValue(pcBox->Length.getValue()
+ + pcBox->Placement.getValue().getPosition().x);
+ ui->flipX->setChecked(false);
+ }
+ setTransparency(pcBox);
}
- if (doc->getObject(BoxZName)) {
- Part::Box* pcBox = dynamic_cast(doc->getObject(BoxZName));
- if (!pcBox) {
- Base::Console().Error(
- "SectionCut error: cut box is incorrectly named, cannot proceed\n");
- return;
+}
+
+void SectionCut::initYControls(const Base::BoundBox3d& BoundCompound,
+ const std::function& setTransparency)
+{
+ Base::BoundBox3d BoundCutBox;
+ if (auto pcBox = findCutBox(BoxYName)) {
+ hasBoxY = true;
+ ui->groupBoxY->setChecked(true);
+ BoundCutBox = pcBox->Shape.getBoundingBox();
+ if (BoundCutBox.MinY > BoundCompound.MinY) {
+ ui->cutY->setValue(pcBox->Placement.getValue().getPosition().y);
+ ui->flipY->setChecked(true);
}
+ else {
+ ui->cutY->setValue(pcBox->Width.getValue()
+ + pcBox->Placement.getValue().getPosition().y);
+ ui->flipY->setChecked(false);
+ }
+ setTransparency(pcBox);
+ }
+}
+
+void SectionCut::initZControls(const Base::BoundBox3d& BoundCompound,
+ const std::function& setTransparency)
+{
+ Base::BoundBox3d BoundCutBox;
+ if (auto pcBox = findCutBox(BoxZName)) {
hasBoxZ = true;
ui->groupBoxZ->setChecked(true);
// if z of cutbox bounding is greater than z of compound bounding
@@ -221,73 +224,103 @@ SectionCut::SectionCut(QWidget* parent)
ui->flipZ->setChecked(false);
}
// set color and transparency
- setColorTransparency(pcBox);
- }
- if (doc->getObject(BoxYName)) {
- Part::Box* pcBox = dynamic_cast(doc->getObject(BoxYName));
- if (!pcBox) {
- Base::Console().Error(
- "SectionCut error: cut box is incorrectly named, cannot proceed\n");
- return;
- }
- hasBoxY = true;
- ui->groupBoxY->setChecked(true);
- BoundCutBox = pcBox->Shape.getBoundingBox();
- if (BoundCutBox.MinY > BoundCompound.MinY) {
- ui->cutY->setValue(pcBox->Placement.getValue().getPosition().y);
- ui->flipY->setChecked(true);
- }
- else {
- ui->cutY->setValue(pcBox->Width.getValue()
- + pcBox->Placement.getValue().getPosition().y);
- ui->flipY->setChecked(false);
- }
- setColorTransparency(pcBox);
- }
- if (doc->getObject(BoxXName)) {
- Part::Box* pcBox = dynamic_cast(doc->getObject(BoxXName));
- if (!pcBox) {
- Base::Console().Error(
- "SectionCut error: cut box is incorrectly named, cannot proceed\n");
- return;
- }
- hasBoxX = true;
- ui->groupBoxX->setChecked(true);
- BoundCutBox = pcBox->Shape.getBoundingBox();
- if (BoundCutBox.MinX > BoundCompound.MinX) {
- ui->cutX->setValue(pcBox->Placement.getValue().getPosition().x);
- ui->flipX->setChecked(true);
- }
- else {
- ui->cutX->setValue(pcBox->Length.getValue()
- + pcBox->Placement.getValue().getPosition().x);
- ui->flipX->setChecked(false);
- }
- setColorTransparency(pcBox);
+ setTransparency(pcBox);
}
+}
- // hide existing cuts to check if there are objects to be cut visible
- if (doc->getObject(CutXName))
- doc->getObject(CutXName)->Visibility.setValue(false);
- if (doc->getObject(CutYName))
- doc->getObject(CutYName)->Visibility.setValue(false);
- if (doc->getObject(CutZName))
- doc->getObject(CutZName)->Visibility.setValue(false);
-
+void SectionCut::initCutRanges()
+{
// get bounding box
SbBox3f box = getViewBoundingBox();
- if (!box.isEmpty()) {
+ if (!box.isEmpty()) { // NOLINT
// if there is a cut box, perform the cut
if (hasBoxX || hasBoxY || hasBoxZ) {
// refresh only the range since we set the values above already
refreshCutRanges(box, Refresh::notXValue, Refresh::notYValue, Refresh::notZValue,
Refresh::XRange, Refresh::YRange, Refresh::ZRange);
}
- else
+ else {
refreshCutRanges(box);
+ }
}
- // the case of an empty box and having cuts will be handles later by startCutting(true)
+}
+void SectionCut::tryStartCutting()
+{
+ // if there is a cut, perform it
+ if (hasBoxX || hasBoxY || hasBoxZ) {
+ ui->RefreshCutPB->setEnabled(false);
+ startCutting(true);
+ }
+}
+
+Base::BoundBox3d SectionCut::collectObjects()
+{
+ Base::BoundBox3d BoundCompound;
+ if (doc->getObject(BoxXName) || doc->getObject(BoxYName) || doc->getObject(BoxZName)) {
+ // automatic coloring must be disabled
+ ui->autoCutfaceColorCB->setChecked(false);
+ ui->autoBFColorCB->setChecked(false);
+ if (doc->getObject(CompoundName)) {
+ // get the object with the right name
+ auto compoundObject = doc->getObject(CompoundName);
+ // to later store the childs
+ std::vector compoundChilds;
+
+ // check if this is a BooleanFragments or a Part::Compound
+ // Part::Compound is the case when there was only one object
+ auto pcCompoundPart = dynamic_cast(compoundObject);
+ auto pcPartFeature = dynamic_cast(compoundObject);
+ if (!pcCompoundPart && pcPartFeature) {
+ // for more security check for validity accessing its ViewProvider
+ auto pcCompoundBF = Gui::Application::Instance->getViewProvider(pcPartFeature);
+ if (!pcCompoundBF) {
+ throw Base::RuntimeError("SectionCut error: compound is incorrectly named, cannot proceed");
+ }
+
+ BoundCompound = pcPartFeature->Shape.getBoundingBox();
+ // for BooleanFragments we also need to set the checkbox, transparency and color
+ ui->groupBoxIntersecting->setChecked(true);
+ auto pcCompoundBFGO = dynamic_cast(pcCompoundBF);
+ if (pcCompoundBFGO) {
+ App::Color compoundColor = pcCompoundBFGO->ShapeColor.getValue();
+ ui->BFragColor->setColor(compoundColor.asValue());
+ long compoundTransparency = pcCompoundBFGO->Transparency.getValue();
+ ui->BFragTransparencyHS->setValue(int(compoundTransparency));
+ ui->BFragTransparencyHS->setToolTip(QString::number(compoundTransparency)
+ + QString::fromLatin1(" %"));
+ // Part::Cut ignores the cutbox transparency when it is set
+ // to zero and the BooleanFragments transparency is not zero
+ // therefore limit the cutbox transparency to 1 in this case
+ ui->CutTransparencyHS->setMinimum(compoundTransparency > 0 ? 1 : 0);
+ }
+ compoundChilds = pcCompoundBF->claimChildren();
+ }
+ else if (pcCompoundPart) {
+ BoundCompound = pcCompoundPart->Shape.getBoundingBox();
+ pcCompoundPart->Links.getLinks(compoundChilds);
+ }
+ // make parent objects of links visible to handle the case that
+ // the cutting is started when only an existing cut was visible
+ for (auto aCompoundObj : compoundChilds) {
+ auto pcLink = dynamic_cast(aCompoundObj);
+ auto LinkedObject = pcLink ? pcLink->getLink() : nullptr;
+ if (LinkedObject) {
+ // only if not already visible
+ if (!(LinkedObject->Visibility.getValue())) {
+ LinkedObject->Visibility.setValue(true);
+ ObjectsListVisible.emplace_back(LinkedObject);
+ }
+ }
+ }
+ }
+ }
+
+ return BoundCompound;
+}
+
+void SectionCut::setupConnections()
+{
connect(ui->groupBoxX, &QGroupBox::toggled, this, &SectionCut::onGroupBoxXtoggled);
connect(ui->groupBoxY, &QGroupBox::toggled, this, &SectionCut::onGroupBoxYtoggled);
connect(ui->groupBoxZ, &QGroupBox::toggled, this, &SectionCut::onGroupBoxZtoggled);
@@ -319,11 +352,18 @@ SectionCut::SectionCut(QWidget* parent)
this, &SectionCut::onBFragTransparencyHSMoved);
connect(ui->BFragTransparencyHS,&QSlider::valueChanged,
this, &SectionCut::onBFragTransparencyHSChanged);
+}
- // if there is a cut, perform it
- if (hasBoxX || hasBoxY || hasBoxZ) {
- ui->RefreshCutPB->setEnabled(false);
- startCutting(true);
+void SectionCut::hideCutObjects()
+{
+ if (auto obj = doc->getObject(CutXName)) {
+ obj->Visibility.setValue(false);
+ }
+ if (auto obj = doc->getObject(CutYName)) {
+ obj->Visibility.setValue(false);
+ }
+ if (auto obj = doc->getObject(CutZName)) {
+ obj->Visibility.setValue(false);
}
}
@@ -352,9 +392,10 @@ void SectionCut::startCutting(bool isInitial)
return;
}
// the document might have been changed
- if (doc != Gui::Application::Instance->activeDocument()->getDocument())
+ if (doc != Gui::Application::Instance->activeDocument()->getDocument()) {
// refresh documents list
onRefreshCutPBclicked();
+ }
App::DocumentObject* anObject = nullptr;
@@ -366,8 +407,9 @@ void SectionCut::startCutting(bool isInitial)
ObjectsListVisible.begin(), ObjectsListVisible.end(),
[anObject](const App::DocumentObjectT &obj) { return (obj.getObject() == anObject);
});
- if (found != ObjectsListVisible.end())
+ if (found != ObjectsListVisible.end()) {
ObjectsListVisible.erase(found);
+ }
doc->removeObject(objectName);
};
@@ -377,7 +419,7 @@ void SectionCut::startCutting(bool isInitial)
auto CompoundVP = dynamic_cast(
Gui::Application::Instance->getViewProvider(cutObject));
if (CompoundVP && compoundTransparency == -1) {
- compoundTransparency = CompoundVP->Transparency.getValue();
+ compoundTransparency = int(CompoundVP->Transparency.getValue());
}
};
@@ -391,20 +433,23 @@ void SectionCut::startCutting(bool isInitial)
storeTransparency(doc->getObject(CutZName));
deleteObject(CutZName);
}
- if (doc->getObject(BoxZName))
+ if (doc->getObject(BoxZName)) {
deleteObject(BoxZName);
+ }
if (doc->getObject(CutYName)) {
storeTransparency(doc->getObject(CutYName));
deleteObject(CutYName);
}
- if (doc->getObject(BoxYName))
+ if (doc->getObject(BoxYName)) {
deleteObject(BoxYName);
+ }
if (doc->getObject(CutXName)) {
storeTransparency(doc->getObject(CutXName));
deleteObject(CutXName);
}
- if (doc->getObject(BoxXName))
+ if (doc->getObject(BoxXName)) {
deleteObject(BoxXName);
+ }
if (doc->getObject(CompoundName)) {
// get the object with the right name
auto compoundObject = doc->getObject(CompoundName);
@@ -412,8 +457,8 @@ void SectionCut::startCutting(bool isInitial)
std::vector compoundChilds;
// check if this is a BooleanFragments or a Part::Compound
- Part::Compound* pcCompoundDelPart = dynamic_cast(compoundObject);
- Gui::ViewProvider* pcCompoundDelBF;
+ auto pcCompoundDelPart = dynamic_cast(compoundObject);
+ Gui::ViewProvider* pcCompoundDelBF{};
if (!pcCompoundDelPart) {
// check for BooleanFragments
pcCompoundDelBF = Gui::Application::Instance->getViewProvider(compoundObject);
@@ -433,8 +478,9 @@ void SectionCut::startCutting(bool isInitial)
ObjectsListVisible.begin(), ObjectsListVisible.end(),
[anObject](const App::DocumentObjectT &obj) { return (obj.getObject() == anObject);
});
- if (foundObj != ObjectsListVisible.end())
+ if (foundObj != ObjectsListVisible.end()) {
ObjectsListVisible.erase(foundObj);
+ }
doc->removeObject(CompoundName);
// now delete the objects that have been part of the compound
for (auto aChild : compoundChilds) {
@@ -443,8 +489,9 @@ void SectionCut::startCutting(bool isInitial)
[anObject](const App::DocumentObjectT &objInner) {
return (objInner.getObject() == anObject);
});
- if (foundObjInner != ObjectsListVisible.end())
+ if (foundObjInner != ObjectsListVisible.end()) {
ObjectsListVisible.erase((foundObjInner));
+ }
doc->removeObject(aChild->getNameInDocument());
}
}
@@ -452,8 +499,10 @@ void SectionCut::startCutting(bool isInitial)
// make all objects visible that have been visible when the dialog was called
// because we made them invisible when we created cuts
for (auto& aVisObject : ObjectsListVisible) {
- if (aVisObject.getObject()) // a formerly visible object might have been deleted
+ if (aVisObject.getObject()) {
+ // a formerly visible object might have been deleted
aVisObject.getObject()->Visibility.setValue(true);
+ }
else {
// we must refresh the ObjectsListVisible list
onRefreshCutPBclicked();
@@ -475,9 +524,7 @@ void SectionCut::startCutting(bool isInitial)
continue;
}
// we need all Link objects in App::Part for example for Assembly 4
- if (object->getTypeId() == Base::Type::fromName("App::Part")) {
- App::Part* pcPart = static_cast(object);
-
+ if (auto pcPart = dynamic_cast(object)) {
// collect all its link objects
auto groupObjects = pcPart->Group.getValue();
for (auto aGroupObject : groupObjects) {
@@ -489,7 +536,7 @@ void SectionCut::startCutting(bool isInitial)
}
}
// get all shapes that are also Part::Features
- if (object->getPropertyByName("Shape")
+ if (object->getPropertyByName("Shape") != nullptr
&& object->getTypeId().isDerivedFrom(
Base::Type::fromName("Part::Feature"))) {
// sort out 2D objects, datums, App:Parts, compounds and objects that are
@@ -502,16 +549,17 @@ void SectionCut::startCutting(bool isInitial)
Base::Type::fromName("PartDesign::Feature"))
&& !object->getTypeId().isDerivedFrom(
Base::Type::fromName("Part::Compound"))
- && object->getTypeId() != Base::Type::fromName("App::Part"))
+ && object->getTypeId() != Base::Type::fromName("App::Part")) {
ObjectsListCut.push_back(object);
+ }
}
// get Links that are derived from Part objects
- if (object->getTypeId() == Base::Type::fromName("App::Link")) {
- App::Link* pcLink = static_cast(object);
+ if (auto pcLink = dynamic_cast(object)) {
auto linkedObject = doc->getObject(pcLink->LinkedObject.getObjectName());
- if (linkedObject
- && linkedObject->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Feature")))
+ if (linkedObject != nullptr
+ && linkedObject->getTypeId().isDerivedFrom(Base::Type::fromName("Part::Feature"))) {
ObjectsListCut.push_back(object);
+ }
}
}
@@ -562,11 +610,13 @@ void SectionCut::startCutting(bool isInitial)
// we might have no objects that can be cut
if (ObjectsListCut.empty()) {
- if (isInitial)
+ if (isInitial) {
Base::Console().Error("SectionCut error: there are no visible objects to be cut\n");
- else
+ }
+ else {
Base::Console().Error(
"SectionCut error: there are no objects in the document that can be cut\n");
+ }
// block signals to be able to reset the cut group boxes without calling startCutting again
ui->groupBoxX->blockSignals(true);
ui->groupBoxY->blockSignals(true);
@@ -610,7 +660,7 @@ void SectionCut::startCutting(bool isInitial)
Gui::Application::Instance->getViewProvider(*ObjectsListCut.begin()));
if (vpFirstObject) {
cutColor = vpFirstObject->ShapeColor.getValue();
- cutTransparency = vpFirstObject->Transparency.getValue();
+ cutTransparency = int(vpFirstObject->Transparency.getValue());
}
// create link objects for all found elements
std::vector ObjectsListLinks;
@@ -619,37 +669,39 @@ void SectionCut::startCutting(bool isInitial)
std::string newName;
// since links to normal Part objects all have the document name "Link",
// use their label text instead
- if (itCuts->getTypeId() == Base::Type::fromName("App::Link"))
+ if (itCuts->getTypeId() == Base::Type::fromName("App::Link")) {
newName = itCuts->Label.getValue();
- else
+ }
+ else {
newName = itCuts->getNameInDocument();
- newName = newName + "_CutLink";
+ }
+ newName += "_CutLink";
- auto newObject = doc->addObject("App::Link", newName.c_str());
- if (!newObject) {
+ auto pcLink = dynamic_cast(doc->addObject("App::Link", newName.c_str()));
+ if (!pcLink) {
Base::Console().Error("SectionCut error: 'App::Link' could not be added\n");
return;
}
- App::Link* pcLink = static_cast(newObject);
+
// set the object to the created empty link object
pcLink->LinkedObject.setValue(itCuts);
// we want to get the link at the same position as the original
pcLink->LinkTransform.setValue(true);
// add link to list to later add this to the compound object
- ObjectsListLinks.push_back(newObject);
+ ObjectsListLinks.push_back(pcLink);
// if the object is part of an App::Part container,
// the link needs to get the container placement
auto parents = itCuts->getInList();
if (!parents.empty()) {
for (auto parent : parents) {
- if (parent->getTypeId() == Base::Type::fromName("App::Part")) {
- App::Part* pcPartParent = static_cast(parent);
+ if (auto pcPartParent = dynamic_cast(parent)) {
auto placement = Base::freecad_dynamic_cast(
pcPartParent->getPropertyByName("Placement"));
- if (placement)
+ if (placement) {
pcLink->Placement.setValue(placement->getValue());
+ }
}
}
}
@@ -662,33 +714,36 @@ void SectionCut::startCutting(bool isInitial)
auto vpObject = dynamic_cast(
Gui::Application::Instance->getViewProvider(itCuts));
if (vpObject) {
- if (cutColor != vpObject->ShapeColor.getValue())
+ if (cutColor != vpObject->ShapeColor.getValue()) {
autoColor = false;
- if (cutTransparency != vpObject->Transparency.getValue())
+ }
+ if (cutTransparency != vpObject->Transparency.getValue()) {
autoTransparency = false;
+ }
}
}
}
App::DocumentObject* CutCompoundBF = nullptr;
Part::Compound* CutCompoundPart = nullptr;
- App::DocumentObject* CutCompoundPartObj = nullptr;
// specify transparency for the compound
// if there was no compound, take the setting for the cut face
- if (ui->groupBoxIntersecting->isChecked())
+ if (ui->groupBoxIntersecting->isChecked()) {
compoundTransparency = ui->BFragTransparencyHS->value();
- if (compoundTransparency == -1)
+ }
+ if (compoundTransparency == -1) {
compoundTransparency = ui->CutTransparencyHS->value();
+ }
// create BooleanFragments and fill it
if (ui->groupBoxIntersecting->isChecked() && ObjectsListCut.size() > 1) {
CutCompoundBF = CreateBooleanFragments(doc);
// the BooleanFragment implementation requires to first add at least 2 objects
// before any other setting to the BooleanFragment object can be made
- App::PropertyLinkList* CutLinkList =
- dynamic_cast(CutCompoundBF->getPropertyByName("Objects"));
- if (!CutCompoundBF) {
+ auto CutLinkList = dynamic_cast(
+ CutCompoundBF ? CutCompoundBF->getPropertyByName("Objects") : nullptr);
+ if (!CutLinkList) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(CompoundName)
+ std::string(" could not be added\n")).c_str());
return;
@@ -708,18 +763,18 @@ void SectionCut::startCutting(bool isInitial)
}
else { // create Part::Compound and fill it
// if there is only one object to be cut, we cannot create a BooleanFragments object
- CutCompoundPartObj = doc->addObject("Part::Compound", CompoundName);
- if (!CutCompoundPartObj) {
+ CutCompoundPart = dynamic_cast(doc->addObject("Part::Compound", CompoundName));
+ if (!CutCompoundPart) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(CompoundName)
+ std::string(" could not be added\n")).c_str());
return;
}
- CutCompoundPart = static_cast(CutCompoundPartObj);
+
// add the link to the compound
CutCompoundPart->Links.setValue(ObjectsListLinks);
// set the transparency
auto vpCompound = dynamic_cast(
- Gui::Application::Instance->getViewProvider(CutCompoundPartObj));
+ Gui::Application::Instance->getViewProvider(CutCompoundPart));
vpCompound->Transparency.setValue(compoundTransparency);
CutCompoundPart->recomputeFeature();
}
@@ -730,13 +785,12 @@ void SectionCut::startCutting(bool isInitial)
if (object) {
object->Visibility.setValue(false);
}
- object->Visibility.setValue(false);
}
// the area in which we can cut is the size of the compound
// we get its size by its bounding box
SbBox3f CompoundBoundingBox = getViewBoundingBox();
- if (CompoundBoundingBox.isEmpty()) {
+ if (CompoundBoundingBox.isEmpty()) { // NOLINT
Base::Console().Error("SectionCut error: the CompoundBoundingBox is empty\n");
return;
}
@@ -815,19 +869,20 @@ void SectionCut::startCutting(bool isInitial)
auto setTransparency = [&](Part::Cut* pcCut) {
auto vpCut = dynamic_cast(
Gui::Application::Instance->getViewProvider(pcCut));
- if (vpCut)
+ if (vpCut) {
vpCut->Transparency.setValue(compoundTransparency);
+ }
};
if (ui->groupBoxX->isChecked()) {
// create a box
- auto CutBox = doc->addObject("Part::Box", BoxXName);
- if (!CutBox) {
+ auto pcBox = dynamic_cast(doc->addObject("Part::Box", BoxXName));
+ if (!pcBox) {
Base::Console().Error( (std::string("SectionCut error: ")
+ std::string(BoxXName) + std::string(" could not be added\n")).c_str() );
return;
}
- Part::Box* pcBox = static_cast(CutBox);
+
// it appears that because of internal rounding errors, the bounding box is sometimes
// a bit too small, for example for epplipsoides, thus make the box a bit larger
pcBox->Length.setValue(BoundingBoxSize[0] + 1.0);
@@ -845,10 +900,13 @@ void SectionCut::startCutting(bool isInitial)
// we don't set the value to ui->cutX because this would refresh the cut
// which we don't have yet, thus do this later
// set the box position
- if (!ui->flipX->isChecked())
+ if (!ui->flipX->isChecked()) {
BoxOriginSet.x = CutPosX - (BoundingBoxSize[0] + 1.0);
- else // flipped
+ }
+ else {
+ // flipped
BoxOriginSet.x = CutPosX;
+ }
// we made the box 1.0 larger that we can place it 0.5 below the bounding box
BoxOriginSet.y = BoundingBoxOrigin[1] - 0.5;
BoxOriginSet.z = BoundingBoxOrigin[2] - 0.5;
@@ -857,18 +915,20 @@ void SectionCut::startCutting(bool isInitial)
setPlaceColorTransparency(pcBox);
// create a cut feature
- auto CutFeature = doc->addObject("Part::Cut", CutXName);
- if (!CutFeature) {
+ auto pcCut = dynamic_cast(doc->addObject("Part::Cut", CutXName));
+ if (!pcCut) {
Base::Console().Error( (std::string("SectionCut error: ")
+ std::string(CutXName) + std::string(" could not be added\n")).c_str() );
return;
}
- Part::Cut* pcCut = static_cast(CutFeature);
- if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked()))
+
+ if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked())) {
pcCut->Base.setValue(CutCompoundPart);
- else
+ }
+ else {
pcCut->Base.setValue(CutCompoundBF);
- pcCut->Tool.setValue(CutBox);
+ }
+ pcCut->Tool.setValue(pcBox);
// we must set the compoundTransparency also for the cut
setTransparency(pcCut);
@@ -877,10 +937,12 @@ void SectionCut::startCutting(bool isInitial)
// recomputing recursively is especially for assemblies very time-consuming
// however there must be a final recursicve recompute and we do this at the end
// so only recomute recursively if there are no other cuts
- if (!ui->groupBoxY->isChecked() && !ui->groupBoxZ->isChecked())
+ if (!ui->groupBoxY->isChecked() && !ui->groupBoxZ->isChecked()) {
pcCut->recomputeFeature(true);
- else
+ }
+ else {
pcCut->recomputeFeature(false);
+ }
hasBoxX = true;
}
if (ui->groupBoxY->isChecked()) {
@@ -893,13 +955,13 @@ void SectionCut::startCutting(bool isInitial)
Refresh::notZValue, Refresh::notXRange, Refresh::YRange,
Refresh::notZRange);
}
- auto CutBox = doc->addObject("Part::Box", BoxYName);
- if (!CutBox) {
+ auto pcBox = dynamic_cast(doc->addObject("Part::Box", BoxYName));
+ if (!pcBox) {
Base::Console().Error((std::string("SectionCut error: ")
+ std::string(BoxYName) + std::string(" could not be added\n")).c_str() );
return;
}
- Part::Box* pcBox = static_cast(CutBox);
+
pcBox->Length.setValue(BoundingBoxSize[0] + 1.0);
pcBox->Width.setValue(BoundingBoxSize[1] + 1.0);
pcBox->Height.setValue(BoundingBoxSize[2] + 1.0);
@@ -912,40 +974,47 @@ void SectionCut::startCutting(bool isInitial)
}
// set the box position
BoxOriginSet.x = BoundingBoxOrigin[0] - 0.5;
- if (!ui->flipY->isChecked())
+ if (!ui->flipY->isChecked()) {
BoxOriginSet.y = CutPosY - (BoundingBoxSize[1] + 1.0);
- else // flipped
+ }
+ else {
+ // flipped
BoxOriginSet.y = CutPosY;
+ }
BoxOriginSet.z = BoundingBoxOrigin[2] - 0.5;
placement.setPosition(BoxOriginSet);
setPlaceColorTransparency(pcBox);
- auto CutFeature = doc->addObject("Part::Cut", CutYName);
- if (!CutFeature) {
+ auto pcCut = dynamic_cast(doc->addObject("Part::Cut", CutYName));
+ if (!pcCut) {
Base::Console().Error((std::string("SectionCut error: ")
+ std::string(CutYName) + std::string(" could not be added\n")).c_str() );
return;
}
- Part::Cut* pcCut = static_cast(CutFeature);
+
// if there is already a cut, we must take it as feature to be cut
if (hasBoxX) {
pcCut->Base.setValue(doc->getObject(CutXName));
}
else {
- if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked()))
+ if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked())) {
pcCut->Base.setValue(CutCompoundPart);
- else
+ }
+ else {
pcCut->Base.setValue(CutCompoundBF);
+ }
}
- pcCut->Tool.setValue(CutBox);
+ pcCut->Tool.setValue(pcBox);
setTransparency(pcCut);
// set the cut value
ui->cutY->setValue(CutPosY);
- if (!ui->groupBoxZ->isChecked())
+ if (!ui->groupBoxZ->isChecked()) {
pcCut->recomputeFeature(true);
- else
+ }
+ else {
pcCut->recomputeFeature(false);
+ }
hasBoxY = true;
}
if (ui->groupBoxZ->isChecked()) {
@@ -955,13 +1024,13 @@ void SectionCut::startCutting(bool isInitial)
Refresh::notZValue, Refresh::notXRange, Refresh::notYRange,
Refresh::ZRange);
}
- auto CutBox = doc->addObject("Part::Box", BoxZName);
- if (!CutBox) {
+ auto pcBox = dynamic_cast(doc->addObject("Part::Box", BoxZName));
+ if (!pcBox) {
Base::Console().Error((std::string("SectionCut error: ")
+ std::string(BoxZName) + std::string(" could not be added\n")).c_str() );
return;
}
- Part::Box* pcBox = static_cast(CutBox);
+
pcBox->Length.setValue(BoundingBoxSize[0] + 1.0);
pcBox->Width.setValue(BoundingBoxSize[1] + 1.0);
pcBox->Height.setValue(BoundingBoxSize[2] + 1.0);
@@ -975,20 +1044,23 @@ void SectionCut::startCutting(bool isInitial)
// set the box position
BoxOriginSet.x = BoundingBoxOrigin[0] - 0.5;
BoxOriginSet.y = BoundingBoxOrigin[1] - 0.5;
- if (!ui->flipY->isChecked())
+ if (!ui->flipY->isChecked()) {
BoxOriginSet.z = CutPosZ - (BoundingBoxSize[2] + 1.0);
- else // flipped
+ }
+ else {
+ // flipped
BoxOriginSet.z = CutPosZ;
+ }
placement.setPosition(BoxOriginSet);
setPlaceColorTransparency(pcBox);
- auto CutFeature = doc->addObject("Part::Cut", CutZName);
- if (!CutFeature) {
+ auto pcCut = dynamic_cast(doc->addObject("Part::Cut", CutZName));
+ if (!pcCut) {
Base::Console().Error( (std::string("SectionCut error: ")
+ std::string(CutZName) + std::string(" could not be added\n")).c_str() );
return;
}
- Part::Cut* pcCut = static_cast(CutFeature);
+
// if there is already a cut, we must take it as feature to be cut
if (hasBoxY) {
pcCut->Base.setValue(doc->getObject(CutYName));
@@ -997,12 +1069,14 @@ void SectionCut::startCutting(bool isInitial)
pcCut->Base.setValue(doc->getObject(CutXName));
}
else {
- if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked()))
+ if (ObjectsListCut.size() == 1 || !(ui->groupBoxIntersecting->isChecked())) {
pcCut->Base.setValue(CutCompoundPart);
- else
+ }
+ else {
pcCut->Base.setValue(CutCompoundBF);
+ }
}
- pcCut->Tool.setValue(CutBox);
+ pcCut->Tool.setValue(pcBox);
setTransparency(pcCut);
// set the cut value
@@ -1015,7 +1089,7 @@ void SectionCut::startCutting(bool isInitial)
SectionCut* SectionCut::makeDockWidget(QWidget* parent)
{
// embed this dialog into a QDockWidget
- SectionCut* sectionCut = new SectionCut(parent);
+ auto sectionCut = new SectionCut(parent);
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
// the dialog is designed that you can see the tree, thus put it to the right side
QDockWidget *dw =
@@ -1039,8 +1113,10 @@ SectionCut::~SectionCut()
// make all objects visible that have been visible when the dialog was called
// because we made them invisible when we created cuts
for (auto& aVisObj : ObjectsListVisible) {
- if (aVisObj.getObject())// a formerly visible object might have been deleted
+ if (aVisObj.getObject()) {
+ // a formerly visible object might have been deleted
aVisObj.getObject()->Visibility.setValue(true);
+ }
}
}
}
@@ -1048,7 +1124,7 @@ SectionCut::~SectionCut()
void SectionCut::reject()
{
QDialog::reject();
- QDockWidget* dw = qobject_cast(parent());
+ auto dw = qobject_cast(parent());
if (dw) {
dw->deleteLater();
}
@@ -1115,9 +1191,10 @@ void SectionCut::onCutXvalueChanged(double val)
auto CutBox = doc->getObject(BoxXName);
// when the value has been set after resetting the compound bounding box
// there is not yet a cut and we do nothing
- if (!CutBox)
+ if (!CutBox) {
return;
- Part::Box* pcBox = dynamic_cast(CutBox);
+ }
+ auto pcBox = dynamic_cast(CutBox);
if (!pcBox) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(BoxXName)
+ std::string(" is no Part::Box object. Cannot proceed.\n")).c_str());
@@ -1127,10 +1204,14 @@ void SectionCut::onCutXvalueChanged(double val)
Base::Placement placement = pcBox->Placement.getValue();
Base::Vector3d BoxPosition = placement.getPosition();
// change the placement
- if (!ui->flipX->isChecked())
+ if (!ui->flipX->isChecked()) {
BoxPosition.x = ui->cutX->value() - pcBox->Length.getValue();
- else //flipped
+ }
+ else {
+ //flipped
BoxPosition.x = ui->cutX->value();
+ }
+
placement.setPosition(BoxPosition);
pcBox->Placement.setValue(placement);
@@ -1167,16 +1248,16 @@ void SectionCut::onCutXvalueChanged(double val)
Refresh::notXRange, Refresh::YRange, Refresh::ZRange);
// the value of Y can now be outside or at the limit, in this case reset the value too
if ((ui->cutY->value() >= ui->cutY->maximum())
- || (ui->cutY->value() <= ui->cutY->minimum()))
+ || (ui->cutY->value() <= ui->cutY->minimum())) {
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::YValue, Refresh::ZValue,
Refresh::notXRange, Refresh::YRange, Refresh::ZRange);
+ }
// make the SectionCutY visible again
CutFeatureY->Visibility.setValue(true);
// make SectionCutX invisible again
CutObject->Visibility.setValue(false);
// recompute the cut
- Part::Cut* pcCutY = static_cast(CutFeatureY);
- pcCutY->recomputeFeature(true);
+ CutFeatureY->recomputeFeature(true);
}
else if (hasBoxZ) { // at least Z
// the main cut is Z, no matter if there is a cut in Y
@@ -1200,34 +1281,37 @@ void SectionCut::onCutXvalueChanged(double val)
Refresh::ZRange);
// the value of Y or Z can now be outside or at the limit, in this case reset the value too
if ((ui->cutY->value() >= ui->cutY->maximum())
- || (ui->cutY->value() <= ui->cutY->minimum()))
+ || (ui->cutY->value() <= ui->cutY->minimum())) {
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::YValue,
Refresh::notZValue, Refresh::notXRange, Refresh::YRange,
Refresh::ZRange);
+ }
if ((ui->cutZ->value() >= ui->cutZ->maximum())
- || (ui->cutZ->value() <= ui->cutZ->minimum()))
+ || (ui->cutZ->value() <= ui->cutZ->minimum())) {
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::notYValue,
Refresh::ZValue, Refresh::notXRange, Refresh::YRange,
Refresh::ZRange);
+ }
}
- else {// there is no Y cut yet so we can set the Y value too
+ else {
+ // there is no Y cut yet so we can set the Y value too
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::YValue,
Refresh::notZValue, Refresh::notXRange, Refresh::YRange,
Refresh::ZRange);
// the value of Z can now be outside or at the limit, in this case reset the value too
if ((ui->cutZ->value() >= ui->cutZ->maximum())
- || (ui->cutZ->value() <= ui->cutZ->minimum()))
+ || (ui->cutZ->value() <= ui->cutZ->minimum())) {
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::YValue,
Refresh::ZValue, Refresh::notXRange, Refresh::YRange,
Refresh::ZRange);
+ }
}
// make the SectionCutZ visible again
CutFeatureZ->Visibility.setValue(true);
// make SectionCutX invisible again
CutObject->Visibility.setValue(false);
// recompute the cut
- Part::Cut* pcCutZ = static_cast(CutFeatureZ);
- pcCutZ->recomputeFeature(true);
+ CutFeatureZ->recomputeFeature(true);
}
else { // just X
// refresh Y and Z limits + values
@@ -1235,7 +1319,7 @@ void SectionCut::onCutXvalueChanged(double val)
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::YValue, Refresh::ZValue,
Refresh::notXRange, Refresh::YRange, Refresh::ZRange);
// recompute the cut
- Part::Cut* pcCut = dynamic_cast(CutObject);
+ auto pcCut = dynamic_cast(CutObject);
if (!pcCut) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(CutZName)
+ std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
@@ -1276,9 +1360,10 @@ void SectionCut::onCutYvalueChanged(double val)
CutValueHelper(val, ui->cutY, ui->cutYHS);
auto CutBox = doc->getObject(BoxYName);
- if (!CutBox)
+ if (!CutBox) {
return;
- Part::Box* pcBox = dynamic_cast(CutBox);
+ }
+ auto pcBox = dynamic_cast(CutBox);
if (!pcBox) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(BoxYName)
+ std::string(" is no Part::Box object. Cannot proceed.\n")).c_str());
@@ -1286,10 +1371,14 @@ void SectionCut::onCutYvalueChanged(double val)
}
Base::Placement placement = pcBox->Placement.getValue();
Base::Vector3d BoxPosition = placement.getPosition();
- if (!ui->flipY->isChecked())
+ if (!ui->flipY->isChecked()) {
BoxPosition.y = ui->cutY->value() - pcBox->Width.getValue();
- else //flipped
+ }
+ else {
+ //flipped
BoxPosition.y = ui->cutY->value();
+ }
+
placement.setPosition(BoxPosition);
pcBox->Placement.setValue(placement);
@@ -1323,17 +1412,17 @@ void SectionCut::onCutYvalueChanged(double val)
Refresh::notXRange, Refresh::notYRange, Refresh::ZRange);
// the value of Z can now be outside or at the limit, in this case reset the value too
if ((ui->cutZ->value() >= ui->cutZ->maximum())
- || (ui->cutZ->value() <= ui->cutZ->minimum()))
+ || (ui->cutZ->value() <= ui->cutZ->minimum())) {
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::notYValue,
Refresh::ZValue, Refresh::notXRange, Refresh::notYRange,
Refresh::ZRange);
+ }
// make the SectionCutZ visible again
CutFeatureZ->Visibility.setValue(true);
// make SectionCutX invisible again
CutObject->Visibility.setValue(false);
// recompute the cut
- Part::Cut* pcCutZ = static_cast(CutFeatureZ);
- pcCutZ->recomputeFeature(true);
+ CutFeatureZ->recomputeFeature(true);
}
else { // just Y
// refresh Z limits + values
@@ -1341,7 +1430,7 @@ void SectionCut::onCutYvalueChanged(double val)
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::notYValue, Refresh::ZValue,
Refresh::notXRange, Refresh::notYRange, Refresh::ZRange);
// recompute the cut
- Part::Cut* pcCut = dynamic_cast(CutObject);
+ auto pcCut = dynamic_cast(CutObject);
if (!pcCut) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(CutZName)
+ std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
@@ -1354,14 +1443,17 @@ void SectionCut::onCutYvalueChanged(double val)
// if x-limit in box direction is larger than object, reset value to saved limit
if (hasBoxX) {
auto CutBoxX = doc->getObject(BoxXName);
- if (!CutBoxX)
+ if (!CutBoxX) {
return;
+ }
// first store the values
- double storedX;
- if (!ui->flipX->isChecked())
+ double storedX{};
+ if (!ui->flipX->isChecked()) {
storedX = ui->cutX->minimum();
- else
+ }
+ else {
storedX = ui->cutX->maximum();
+ }
// show the cutting box
CutBoxX->Visibility.setValue(true);
// set new XRange
@@ -1372,12 +1464,14 @@ void SectionCut::onCutYvalueChanged(double val)
// hide cutting box and compare resultwith stored value
CutBoxX->Visibility.setValue(false);
if (!ui->flipX->isChecked()) {
- if (storedX > ui->cutX->minimum())
+ if (storedX > ui->cutX->minimum()) {
ui->cutX->setMinimum(storedX);
+ }
}
else {
- if (storedX < ui->cutX->maximum())
+ if (storedX < ui->cutX->maximum()) {
ui->cutX->setMaximum(storedX);
+ }
}
}
}
@@ -1411,9 +1505,10 @@ void SectionCut::onCutZvalueChanged(double val)
CutValueHelper(val, ui->cutZ, ui->cutZHS);
auto CutBox = doc->getObject(BoxZName);
- if (!CutBox)
+ if (!CutBox) {
return;
- Part::Box* pcBox = dynamic_cast(CutBox);
+ }
+ auto pcBox = dynamic_cast(CutBox);
if (!pcBox) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(BoxZName)
+ std::string(" is no Part::Box object. Cannot proceed.\n")).c_str());
@@ -1421,10 +1516,13 @@ void SectionCut::onCutZvalueChanged(double val)
}
Base::Placement placement = pcBox->Placement.getValue();
Base::Vector3d BoxPosition = placement.getPosition();
- if (!ui->flipZ->isChecked())
+ if (!ui->flipZ->isChecked()) {
BoxPosition.z = ui->cutZ->value() - pcBox->Height.getValue();
- else //flipped
+ }
+ else {
+ //flipped
BoxPosition.z = ui->cutZ->value();
+ }
placement.setPosition(BoxPosition);
pcBox->Placement.setValue(placement);
@@ -1435,7 +1533,7 @@ void SectionCut::onCutZvalueChanged(double val)
startCutting();
return;
}
- Part::Cut* pcCut = dynamic_cast(CutObject);
+ auto pcCut = dynamic_cast(CutObject);
if (!pcCut) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(CutZName)
+ std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
@@ -1449,14 +1547,17 @@ void SectionCut::onCutZvalueChanged(double val)
SbBox3f CutBoundingBox;
if (hasBoxX) {
auto CutBoxX = doc->getObject(BoxXName);
- if (!CutBoxX)
+ if (!CutBoxX) {
return;
+ }
// first store the values
- double storedX;
- if (!ui->flipX->isChecked())
+ double storedX{};
+ if (!ui->flipX->isChecked()) {
storedX = ui->cutX->minimum();
- else
+ }
+ else {
storedX = ui->cutX->maximum();
+ }
// show the cutting box
CutBoxX->Visibility.setValue(true);
// set new XRange
@@ -1466,35 +1567,42 @@ void SectionCut::onCutZvalueChanged(double val)
// hide cutting box and compare resultwith stored value
CutBoxX->Visibility.setValue(false);
if (!ui->flipX->isChecked()) {
- if (storedX > ui->cutX->minimum())
+ if (storedX > ui->cutX->minimum()) {
ui->cutX->setMinimum(storedX);
+ }
}
else {
- if (storedX < ui->cutX->maximum())
+ if (storedX < ui->cutX->maximum()) {
ui->cutX->setMaximum(storedX);
+ }
}
}
if (hasBoxY) {
auto CutBoxY = doc->getObject(BoxYName);
- if (!CutBoxY)
+ if (!CutBoxY) {
return;
- double storedY;
- if (!ui->flipY->isChecked())
+ }
+ double storedY{};
+ if (!ui->flipY->isChecked()) {
storedY = ui->cutY->minimum();
- else
+ }
+ else {
storedY = ui->cutY->maximum();
+ }
CutBoxY->Visibility.setValue(true);
CutBoundingBox = getViewBoundingBox();
refreshCutRanges(CutBoundingBox, Refresh::notXValue, Refresh::notYValue, Refresh::notZValue,
Refresh::notXRange, Refresh::YRange, Refresh::notZRange);
CutBoxY->Visibility.setValue(false);
if (!ui->flipY->isChecked()) {
- if (storedY > ui->cutY->minimum())
+ if (storedY > ui->cutY->minimum()) {
ui->cutY->setMinimum(storedY);
+ }
}
else {
- if (storedY < ui->cutY->maximum())
+ if (storedY < ui->cutY->maximum()) {
ui->cutY->setMaximum(storedY);
+ }
}
}
}
@@ -1545,7 +1653,7 @@ void SectionCut::FlipClickedHelper(const char* BoxName)
startCutting();
return;
}
- Part::Box* pcBox = dynamic_cast(CutBox);
+ auto pcBox = dynamic_cast(CutBox);
if (!pcBox) {
Base::Console().Error((std::string("SectionCut error: ") + std::string(BoxName)
+ std::string(" is no Part::Box object. Cannot proceed.\n")).c_str());
@@ -1558,22 +1666,28 @@ void SectionCut::FlipClickedHelper(const char* BoxName)
switch (std::string(BoxName).back())
{
case 'X':
- if (ui->flipX->isChecked())
+ if (ui->flipX->isChecked()) {
BoxPosition.x = BoxPosition.x + pcBox->Length.getValue();
- else
+ }
+ else {
BoxPosition.x = BoxPosition.x - pcBox->Length.getValue();
+ }
break;
case 'Y':
- if (ui->flipY->isChecked())
+ if (ui->flipY->isChecked()) {
BoxPosition.y = BoxPosition.y + pcBox->Width.getValue();
- else
+ }
+ else {
BoxPosition.y = BoxPosition.y - pcBox->Width.getValue();
+ }
break;
case 'Z':
- if (ui->flipZ->isChecked())
+ if (ui->flipZ->isChecked()) {
BoxPosition.z = BoxPosition.z + pcBox->Height.getValue();
- else
+ }
+ else {
BoxPosition.z = BoxPosition.z - pcBox->Height.getValue();
+ }
break;
}
placement.setPosition(BoxPosition);
@@ -1584,65 +1698,21 @@ void SectionCut::onFlipXclicked()
{
FlipClickedHelper(BoxXName);
- auto CutObject = doc->getObject(CutXName);
- // there should be a cut, but maybe the user deleted it meanwhile
- if (!CutObject) {
- Base::Console().Warning((std::string("SectionCut warning: there is no ")
- + std::string(CutXName) + std::string(", trying to recreate it\n")).c_str());
- // recreate the box
- startCutting();
- return;
- }
-
- // if there is another cut, we must recalculate it too
- // the hierarchy is always Z->Y->X
- if (hasBoxY && !hasBoxZ) { // only Y
- auto CutFeatureY = doc->getObject(CutYName);
- if (!CutFeatureY) {
- Base::Console().Warning((std::string("SectionCut warning: the expected ")
- + std::string(CutYName)
- + std::string(" is missing, trying to recreate it\n"))
- .c_str());
- // recreate the box
- startCutting();
- return;
+ if (auto CutObject = flipCutObject(CutXName)) {
+ // if there is another cut, we must recalculate it too
+ // the hierarchy is always Z->Y->X
+ if (hasBoxY && !hasBoxZ) {
+ // only Y
+ CutObject = flipCutObject(CutYName);
}
- Part::Cut* pcCutY = dynamic_cast(CutFeatureY);
- if (!pcCutY) {
- Base::Console().Error((std::string("SectionCut error: ") + std::string(CutYName)
- + std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
- return;
+ else if ((!hasBoxY && hasBoxZ) || (hasBoxY && hasBoxZ)) {
+ // at least Z
+ CutObject = flipCutObject(CutZName);
}
- pcCutY->recomputeFeature(true);
- }
- else if ((!hasBoxY && hasBoxZ) || (hasBoxY && hasBoxZ)) { // at least Z
- // the main cut is Z, no matter if there is a cut in Y
- auto CutFeatureZ = doc->getObject(CutZName);
- if (!CutFeatureZ) {
- Base::Console().Warning((std::string("SectionCut warning: the expected ")
- + std::string(CutZName)
- + std::string(" is missing, trying to recreate it\n"))
- .c_str());
- // recreate the box
- startCutting();
- return;
+ if (auto cut = dynamic_cast(CutObject)) {
+ // only do this when there is no other box to save recomputes
+ cut->recomputeFeature(true);
}
- Part::Cut* pcCutZ = dynamic_cast(CutFeatureZ);
- if (!pcCutZ) {
- Base::Console().Error((std::string("SectionCut error: ") + std::string(CutZName)
- + std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
- return;
- }
- pcCutZ->recomputeFeature(true);
- }
- else { // only do this when there is no other box to save recomputes
- Part::Cut* pcCut = dynamic_cast(CutObject);
- if (!pcCut) {
- Base::Console().Error((std::string("SectionCut error: ") + std::string(CutXName)
- + std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
- return;
- }
- pcCut->recomputeFeature(true);
}
}
@@ -1650,36 +1720,15 @@ void SectionCut::onFlipYclicked()
{
FlipClickedHelper(BoxYName);
- auto CutObject = doc->getObject(CutYName);
- // there should be a cut, but maybe the user deleted it meanwhile
- if (!CutObject) {
- Base::Console().Warning((std::string("SectionCut warning: there is no ")
- + std::string(CutYName) + std::string(", trying to recreate it\n")).c_str());
- // recreate the box
- startCutting();
- return;
- }
-
- // if there is another cut, we must recalculate it too
- // we only need to check for Z since the hierarchy is always Z->Y->X
- if (hasBoxZ) {
- auto CutFeatureZ = doc->getObject(CutZName);
- Part::Cut* pcCutZ = dynamic_cast(CutFeatureZ);
- if (!pcCutZ) {
- Base::Console().Error((std::string("SectionCut error: ") + std::string(CutZName)
- + std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
- return;
+ if (auto CutObject = flipCutObject(CutYName)) {
+ // if there is another cut, we must recalculate it too
+ // we only need to check for Z since the hierarchy is always Z->Y->X
+ if (hasBoxZ) {
+ CutObject = findObject(CutZName);
}
- pcCutZ->recomputeFeature(true);
- }
- else {
- Part::Cut* pcCut = dynamic_cast(CutObject);
- if (!pcCut) {
- Base::Console().Error((std::string("SectionCut error: ") + std::string(CutYName)
- + std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
- return;
+ if (auto cut = dynamic_cast(CutObject)) {
+ cut->recomputeFeature(true);
}
- pcCut->recomputeFeature(true);
}
}
@@ -1687,22 +1736,42 @@ void SectionCut::onFlipZclicked()
{
FlipClickedHelper(BoxZName);
- auto CutObject = doc->getObject(CutZName);
+ if (auto CutObject = flipCutObject(CutZName)) {
+ CutObject->recomputeFeature(true);
+ }
+}
+
+Part::Box* SectionCut::findCutBox(const char* name) const
+{
+ if (auto obj = doc->getObject(name)) {
+ auto pcBox = dynamic_cast(obj);
+ if (!pcBox) {
+ throw Base::RuntimeError("SectionCut error: cut box is incorrectly named, cannot proceed");
+ }
+
+ return pcBox;
+ }
+
+ return nullptr;
+}
+
+App::DocumentObject* SectionCut::findObject(const char* objName) const
+{
+ return doc ? doc->getObject(objName) : nullptr;
+}
+
+App::DocumentObject* SectionCut::flipCutObject(const char* cutName)
+{
+ auto CutObject = findObject(cutName);
// there should be a cut, but maybe the user deleted it meanwhile
if (!CutObject) {
Base::Console().Warning((std::string("SectionCut warning: there is no ")
- + std::string(CutZName) + std::string(", trying to recreate it\n")).c_str());
+ + std::string(cutName) + std::string(", trying to recreate it\n")).c_str());
// recreate the box
startCutting();
- return;
}
- Part::Cut* pcCut = dynamic_cast(CutObject);
- if (!pcCut) {
- Base::Console().Error((std::string("SectionCut error: ") + std::string(CutZName)
- + std::string(" is no Part::Cut object. Cannot proceed.\n")).c_str());
- return;
- }
- pcCut->recomputeFeature(true);
+
+ return CutObject;
}
// changes the cutface color
@@ -1809,7 +1878,7 @@ void SectionCut::onBFragColorclicked()
// sets BooleanFragments color
void SectionCut::setBooleanFragmentsColor()
{
- App::DocumentObject* compoundObject;
+ App::DocumentObject* compoundObject{};
if (doc->getObject(CompoundName)) {
// get the object with the right name
compoundObject = doc->getObject(CompoundName);
@@ -1819,11 +1888,10 @@ void SectionCut::setBooleanFragmentsColor()
return;
}
// assure it is not a Part::Compound
- Part::Compound* pcCompound = dynamic_cast(compoundObject);
- Gui::ViewProvider* CompoundBFVP;
- if (!pcCompound) {
+ auto pcCompound = dynamic_cast(compoundObject);
+ if (!pcCompound && compoundObject) {
// check for valid BooleanFragments by accessing its ViewProvider
- CompoundBFVP = Gui::Application::Instance->getViewProvider(compoundObject);
+ auto CompoundBFVP = Gui::Application::Instance->getViewProvider(compoundObject);
if (!CompoundBFVP) {
Base::Console().Error("SectionCut error: cannot access ViewProvider of cut compound\n");
return;
@@ -1943,8 +2011,9 @@ void SectionCut::onRefreshCutPBclicked()
ui->groupBoxX->blockSignals(false);
}
// if there is a cut, disable the button
- if (hasBoxX || hasBoxY || hasBoxZ)
+ if (hasBoxX || hasBoxY || hasBoxZ) {
ui->RefreshCutPB->setEnabled(false);
+ }
}
SbBox3f SectionCut::getViewBoundingBox()
@@ -1955,7 +2024,7 @@ SbBox3f SectionCut::getViewBoundingBox()
Base::Console().Error("SectionCut error: there is no active document\n");
return Box; // return an empty box
}
- Gui::View3DInventor* view = dynamic_cast(docGui->getActiveView());
+ auto view = dynamic_cast(docGui->getActiveView());
if (!view) {
Base::Console().Error("SectionCut error: could not get the active view\n");
return Box; // return an empty box
@@ -1975,22 +2044,24 @@ void SectionCut::refreshCutRanges(SbBox3f BoundingBox,
bool forXValue, bool forYValue, bool forZValue,
bool forXRange, bool forYRange, bool forZRange)
{
- if (!BoundingBox.isEmpty()) {
+ if (!BoundingBox.isEmpty()) { // NOLINT
SbVec3f center = BoundingBox.getCenter();
int minDecimals = Base::UnitsApi::getDecimals();
- float lenx, leny, lenz;
+ float lenx{};
+ float leny{};
+ float lenz{};
BoundingBox.getSize(lenx, leny, lenz);
- int steps = 100;
+ const int steps = 100;
// set the ranges
- float rangeMin; // to silence a compiler warning we use a float
- float rangeMax;
+ float rangeMin{};
+ float rangeMax{};
if (forXRange) {
rangeMin = center[0] - (lenx / 2);
rangeMax = center[0] + (lenx / 2);
ui->cutX->setRange(rangeMin, rangeMax);
// determine the single step values
- lenx = lenx / steps;
+ lenx = lenx / float(steps);
int dim = static_cast(log10(lenx));
double singleStep = pow(10.0, dim);
ui->cutX->setSingleStep(singleStep);
@@ -1999,7 +2070,7 @@ void SectionCut::refreshCutRanges(SbBox3f BoundingBox,
rangeMin = center[1] - (leny / 2);
rangeMax = center[1] + (leny / 2);
ui->cutY->setRange(rangeMin, rangeMax);
- leny = leny / steps;
+ leny = leny / float(steps);
int dim = static_cast(log10(leny));
double singleStep = pow(10.0, dim);
ui->cutY->setSingleStep(singleStep);
@@ -2008,7 +2079,7 @@ void SectionCut::refreshCutRanges(SbBox3f BoundingBox,
rangeMin = center[2] - (lenz / 2);
rangeMax = center[2] + (lenz / 2);
ui->cutZ->setRange(rangeMin, rangeMax);
- lenz = lenz / steps;
+ lenz = lenz / float(steps);
int dim = static_cast(log10(lenz));
double singleStep = pow(10.0, dim);
ui->cutZ->setSingleStep(singleStep);
@@ -2035,6 +2106,7 @@ void SectionCut::refreshCutRanges(SbBox3f BoundingBox,
App::DocumentObject* SectionCut::CreateBooleanFragments(App::Document* doc)
{
+ // NOLINTBEGIN
// create the object
Gui::Command::doCommand(Gui::Command::Doc, "import FreeCAD");
Gui::Command::doCommand(Gui::Command::Doc, "from BOPTools import SplitFeatures");
@@ -2049,6 +2121,8 @@ App::DocumentObject* SectionCut::CreateBooleanFragments(App::Document* doc)
return nullptr;
}
return object;
+ // NOLINTEND
}
+// NOLINTEND(cppcoreguidelines-avoid-magic-numbers,readability-magic-numbers)
#include "moc_SectionCutting.cpp"
diff --git a/src/Mod/Part/Gui/SectionCutting.h b/src/Mod/Part/Gui/SectionCutting.h
index 6a33d8dad1..567b75fca4 100644
--- a/src/Mod/Part/Gui/SectionCutting.h
+++ b/src/Mod/Part/Gui/SectionCutting.h
@@ -23,13 +23,19 @@
#ifndef PARTGUI_SECTIONCUTTING_H
#define PARTGUI_SECTIONCUTTING_H
+#include
#include
#include
+#include
#include
class QDoubleSpinBox;
class QSlider;
+namespace Part {
+class Box;
+}
+
namespace PartGui {
class Ui_SectionCut;
@@ -71,6 +77,31 @@ protected Q_SLOTS:
public:
void reject() override;
+private:
+ void initSpinBoxes();
+ void initControls(const Base::BoundBox3d&);
+ void initXControls(const Base::BoundBox3d&, const std::function&);
+ void initYControls(const Base::BoundBox3d&, const std::function&);
+ void initZControls(const Base::BoundBox3d&, const std::function&);
+ void initCutRanges();
+ void setupConnections();
+ void tryStartCutting();
+ Base::BoundBox3d collectObjects();
+ void noDocumentActions();
+ void startCutting(bool isInitial = false);
+ static SbBox3f getViewBoundingBox();
+ void refreshCutRanges(SbBox3f, bool forXValue = true, bool forYValue = true, bool forZValue = true,
+ bool forXRange = true, bool forYRange = true, bool forZRange = true);
+ void CutValueHelper(double val, QDoubleSpinBox* SpinBox, QSlider* Slider);
+ void FlipClickedHelper(const char* BoxName);
+ void changeCutBoxColors();
+ App::DocumentObject* CreateBooleanFragments(App::Document* doc);
+ void setBooleanFragmentsColor();
+ Part::Box* findCutBox(const char* name) const;
+ App::DocumentObject* findObject(const char* objName) const;
+ void hideCutObjects();
+ App::DocumentObject* flipCutObject(const char* cutName);
+
private:
std::unique_ptr ui;
std::vector ObjectsListVisible;
@@ -79,13 +110,6 @@ private:
bool hasBoxY = false;
bool hasBoxZ = false;
bool hasBoxCustom = false;
- void noDocumentActions();
- void startCutting(bool isInitial = false);
- SbBox3f getViewBoundingBox();
- void refreshCutRanges(SbBox3f, bool forXValue = true, bool forYValue = true, bool forZValue = true,
- bool forXRange = true, bool forYRange = true, bool forZRange = true);
- void CutValueHelper(double val, QDoubleSpinBox* SpinBox, QSlider* Slider);
- void FlipClickedHelper(const char* BoxName);
const char* CompoundName = "SectionCutCompound";
const char* BoxXName = "SectionCutBoxX";
const char* BoxYName = "SectionCutBoxY";
@@ -93,9 +117,6 @@ private:
const char* CutXName = "SectionCutX";
const char* CutYName = "SectionCutY";
const char* CutZName = "SectionCutZ";
- void changeCutBoxColors();
- App::DocumentObject* CreateBooleanFragments(App::Document* doc);
- void setBooleanFragmentsColor();
};
} // namespace PartGui
diff --git a/src/Mod/Path/Path/Post/UtilsArguments.py b/src/Mod/Path/Path/Post/UtilsArguments.py
index b7559aa918..e91a0378cf 100644
--- a/src/Mod/Path/Path/Post/UtilsArguments.py
+++ b/src/Mod/Path/Path/Post/UtilsArguments.py
@@ -343,12 +343,6 @@ def init_shared_values(values: Values):
#
values["COMMENT_SYMBOL"] = "("
#
- # Variables storing the current position for the drill_translate routine.
- #
- values["CURRENT_X"] = 0.0
- values["CURRENT_Y"] = 0.0
- values["CURRENT_Z"] = 0.0
- #
# Default axis precision for metric is 3 digits after the decimal point.
# (see http://linuxcnc.org/docs/2.7/html/gcode/overview.html#_g_code_best_practices)
#
@@ -371,11 +365,6 @@ def init_shared_values(values: Values):
#
values["DRILL_CYCLES_TO_TRANSLATE"] = ["G73", "G81", "G82", "G83"]
#
- # The default value of drill retractations (CURRENT_Z).
- # The other possible value is G99.
- #
- values["DRILL_RETRACT_MODE"] = "G98"
- #
# If this is set to True, then M7, M8, and M9 commands
# to enable/disable coolant will be output.
#
diff --git a/src/Mod/Path/PathTests/TestRefactoredTestPostGCodes.py b/src/Mod/Path/PathTests/TestRefactoredTestPostGCodes.py
index 24f44d168f..4b8ddc9915 100644
--- a/src/Mod/Path/PathTests/TestRefactoredTestPostGCodes.py
+++ b/src/Mod/Path/PathTests/TestRefactoredTestPostGCodes.py
@@ -123,12 +123,18 @@ class TestRefactoredTestPostGCodes(PathTestUtils.PathTestBase):
"""Test G0 command Generation."""
self.compare_third_line(
"G0 X10 Y20 Z30 A40 B50 C60 U70 V80 W90",
- "G0 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 U70.000 V80.000 W90.000",
+ (
+ "G0 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 "
+ "U70.000 V80.000 W90.000"
+ ),
"",
)
self.compare_third_line(
"G00 X10 Y20 Z30 A40 B50 C60 U70 V80 W90",
- "G00 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 U70.000 V80.000 W90.000",
+ (
+ "G00 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 "
+ "U70.000 V80.000 W90.000"
+ ),
"",
)
@@ -136,23 +142,35 @@ class TestRefactoredTestPostGCodes(PathTestUtils.PathTestBase):
"""Test G1 command Generation."""
self.compare_third_line(
"G1 X10 Y20 Z30 A40 B50 C60 U70 V80 W90 F1.23456",
- "G1 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 U70.000 V80.000 W90.000 F74.074",
+ (
+ "G1 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 "
+ "U70.000 V80.000 W90.000 F74.074"
+ ),
"",
)
self.compare_third_line(
"G01 X10 Y20 Z30 A40 B50 C60 U70 V80 W90 F1.23456",
- "G01 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 U70.000 V80.000 W90.000 F74.074",
+ (
+ "G01 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 "
+ "U70.000 V80.000 W90.000 F74.074"
+ ),
"",
)
# Test argument order
self.compare_third_line(
"G1 F1.23456 Z30 V80 C60 W90 X10 B50 U70 Y20 A40",
- "G1 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 U70.000 V80.000 W90.000 F74.074",
+ (
+ "G1 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 "
+ "U70.000 V80.000 W90.000 F74.074"
+ ),
"",
)
self.compare_third_line(
"G1 X10 Y20 Z30 A40 B50 C60 U70 V80 W90 F1.23456",
- "G1 X0.3937 Y0.7874 Z1.1811 A1.5748 B1.9685 C2.3622 U2.7559 V3.1496 W3.5433 F2.9163",
+ (
+ "G1 X0.3937 Y0.7874 Z1.1811 A1.5748 B1.9685 C2.3622 "
+ "U2.7559 V3.1496 W3.5433 F2.9163"
+ ),
"--inches",
)
@@ -311,7 +329,10 @@ class TestRefactoredTestPostGCodes(PathTestUtils.PathTestBase):
self.compare_third_line("G28", "G28", "")
self.compare_third_line(
"G28 X10 Y20 Z30 A40 B50 C60 U70 V80 W90",
- "G28 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 U70.000 V80.000 W90.000",
+ (
+ "G28 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 "
+ "U70.000 V80.000 W90.000"
+ ),
"",
)
@@ -1233,7 +1254,10 @@ G90
"""Test G92 command Generation."""
self.compare_third_line(
"G92 X10 Y20 Z30 A40 B50 C60 U70 V80 W90",
- "G92 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 U70.000 V80.000 W90.000",
+ (
+ "G92 X10.000 Y20.000 Z30.000 A40.000 B50.000 C60.000 "
+ "U70.000 V80.000 W90.000"
+ ),
"",
)
diff --git a/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp b/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp
index eefa60b724..383a412da5 100644
--- a/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp
+++ b/src/Mod/Spreadsheet/Gui/AppSpreadsheetGui.cpp
@@ -111,7 +111,9 @@ PyMOD_INIT_FUNC(SpreadsheetGui)
// instantiating the commands
CreateSpreadsheetCommands();
+#if defined(Q_OS_WIN32)
QAccessible::installFactory(SpreadsheetGui::SheetTableViewAccessibleInterface::ifactory);
+#endif
SpreadsheetGui::ViewProviderSheet::init();
SpreadsheetGui::ViewProviderSheetPython::init();
diff --git a/src/Mod/TechDraw/Gui/QGIEdge.cpp b/src/Mod/TechDraw/Gui/QGIEdge.cpp
index 0e69c79982..65e559897a 100644
--- a/src/Mod/TechDraw/Gui/QGIEdge.cpp
+++ b/src/Mod/TechDraw/Gui/QGIEdge.cpp
@@ -32,9 +32,14 @@
#include
#include
#include
+#include
+#include
+#include
#include "QGIEdge.h"
+#include "QGIViewPart.h"
#include "PreferencesGui.h"
+#include "TaskLineDecor.h"
using namespace TechDrawGui;
@@ -51,7 +56,8 @@ QGIEdge::QGIEdge(int index) :
setFill(Qt::NoBrush);
}
-//NOTE this refers to Qt cosmetic lines
+// NOTE this refers to Qt cosmetic lines (a line with minimum width),
+// not FreeCAD cosmetic lines
void QGIEdge::setCosmetic(bool state)
{
// Base::Console().Message("QGIE::setCosmetic(%d)\n", state);
@@ -113,3 +119,15 @@ QPainterPath QGIEdge::shape() const
outline = stroker.createStroke(path());
return outline;
}
+
+void QGIEdge::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event)
+{
+ Q_UNUSED(event)
+ QGIView *parent = dynamic_cast(parentItem());
+ if (parent && parent->getViewObject() && parent->getViewObject()->isDerivedFrom(TechDraw::DrawViewPart::getClassTypeId())) {
+ TechDraw::DrawViewPart *baseFeat = static_cast(parent->getViewObject());
+ std::vector edgeName(1, DrawUtil::makeGeomName("Edge", getProjIndex()));
+
+ Gui::Control().showDialog(new TaskDlgLineDecor(baseFeat, edgeName));
+ }
+}
diff --git a/src/Mod/TechDraw/Gui/QGIEdge.h b/src/Mod/TechDraw/Gui/QGIEdge.h
index d8ed9b974b..1bc54dc2bc 100644
--- a/src/Mod/TechDraw/Gui/QGIEdge.h
+++ b/src/Mod/TechDraw/Gui/QGIEdge.h
@@ -54,6 +54,9 @@ public:
double getEdgeFuzz(void) const;
protected:
+
+ void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event) override;
+
int projIndex; //index of edge in Projection. must exist.
bool isCosmetic;
diff --git a/src/Mod/TechDraw/Gui/QGIPrimPath.cpp b/src/Mod/TechDraw/Gui/QGIPrimPath.cpp
index 1e9845269a..63679534ca 100644
--- a/src/Mod/TechDraw/Gui/QGIPrimPath.cpp
+++ b/src/Mod/TechDraw/Gui/QGIPrimPath.cpp
@@ -59,7 +59,8 @@ QGIPrimPath::QGIPrimPath():
m_colOverride = false;
m_colNormal = getNormalColor();
m_colCurrent = m_colNormal;
- m_styleCurrent = Qt::SolidLine;
+ m_styleNormal = Qt::SolidLine;
+ m_styleCurrent = m_styleNormal;
m_pen.setStyle(m_styleCurrent);
m_capStyle = prefCapStyle();
m_pen.setCapStyle(m_capStyle);
@@ -207,6 +208,7 @@ void QGIPrimPath::setWidth(double w)
void QGIPrimPath::setStyle(Qt::PenStyle s)
{
// Base::Console().Message("QGIPP::setStyle(QTPS: %d)\n", s);
+ m_styleNormal = s;
m_styleCurrent = s;
}
@@ -214,6 +216,7 @@ void QGIPrimPath::setStyle(int s)
{
// Base::Console().Message("QGIPP::setStyle(int: %d)\n", s);
m_styleCurrent = static_cast(s);
+ m_styleNormal = static_cast(s);
}
void QGIPrimPath::setNormalColor(QColor c)
@@ -308,6 +311,7 @@ void QGIPrimPath::paint ( QPainter * painter, const QStyleOptionGraphicsItem * o
m_pen.setWidthF(m_width);
m_pen.setColor(m_colCurrent);
+ m_pen.setStyle(m_styleCurrent);
setPen(m_pen);
m_brush.setColor(m_fillColorCurrent);
diff --git a/src/Mod/TechDraw/Gui/QGIViewPart.cpp b/src/Mod/TechDraw/Gui/QGIViewPart.cpp
index f7b7e13b6d..fe4e60d42a 100644
--- a/src/Mod/TechDraw/Gui/QGIViewPart.cpp
+++ b/src/Mod/TechDraw/Gui/QGIViewPart.cpp
@@ -289,8 +289,6 @@ void QGIViewPart::drawAllEdges()
item->setNormalColor(PreferencesGui::getAccessibleQColor(PreferencesGui::normalQColor()));
item->setStyle(Qt::SolidLine);
if ((*itGeom)->getCosmetic()) {
- item->setCosmetic(true);
-
// cosmetic edge - format appropriately
int source = (*itGeom)->source();
if (source == COSMETICEDGE) {
diff --git a/src/Mod/TechDraw/Gui/TaskDetail.cpp b/src/Mod/TechDraw/Gui/TaskDetail.cpp
index 6ad3622b98..18307fc2c1 100644
--- a/src/Mod/TechDraw/Gui/TaskDetail.cpp
+++ b/src/Mod/TechDraw/Gui/TaskDetail.cpp
@@ -435,7 +435,7 @@ void TaskDetail::createDetail()
Gui::Command::openCommand(QT_TRANSLATE_NOOP("Command", "Create Detail View"));
const std::string objectName{"Detail"};
- std::string m_detailName = m_doc->getUniqueObjectName(objectName.c_str());
+ m_detailName = m_doc->getUniqueObjectName(objectName.c_str());
std::string generatedSuffix {m_detailName.substr(objectName.length())};
Gui::Command::doCommand(Command::Doc, "App.activeDocument().addObject('TechDraw::DrawViewDetail', '%s')",
@@ -444,13 +444,12 @@ void TaskDetail::createDetail()
Gui::Command::doCommand(Command::Doc, "App.activeDocument().%s.translateLabel('DrawViewDetail', 'Detail', '%s')",
m_detailName.c_str(), m_detailName.c_str());
- App::DocumentObject *docObj = m_doc->getObject(m_detailName.c_str());
+ App::DocumentObject *docObj = m_baseFeat->getDocument()->getObject(m_detailName.c_str());
TechDraw::DrawViewDetail* dvd = dynamic_cast(docObj);
if (!dvd) {
throw Base::TypeError("TaskDetail - new detail view not found\n");
}
m_detailFeat = dvd;
-
dvd->Source.setValues(getBaseFeat()->Source.getValues());
Gui::Command::doCommand(Command::Doc, "App.activeDocument().%s.BaseView = App.activeDocument().%s",
@@ -564,8 +563,8 @@ DrawViewDetail* TaskDetail::getDetailFeat()
{
// Base::Console().Message("TD::getDetailFeat()\n");
- if (m_doc) {
- App::DocumentObject* detailObj = m_doc->getObject(m_detailName.c_str());
+ if (m_baseFeat) {
+ App::DocumentObject* detailObj = m_baseFeat->getDocument()->getObject(m_detailName.c_str());
if (detailObj) {
return static_cast(detailObj);
}
diff --git a/src/Mod/TechDraw/Gui/TaskLineDecor.cpp b/src/Mod/TechDraw/Gui/TaskLineDecor.cpp
index cb9b9a8679..13870a408a 100644
--- a/src/Mod/TechDraw/Gui/TaskLineDecor.cpp
+++ b/src/Mod/TechDraw/Gui/TaskLineDecor.cpp
@@ -35,7 +35,6 @@
#include
#include
#include
-#include
#include
#include "TaskLineDecor.h"
@@ -56,15 +55,16 @@ TaskLineDecor::TaskLineDecor(TechDraw::DrawViewPart* partFeat,
m_edges(edgeNames),
m_apply(true)
{
+ initializeRejectArrays();
+
getDefaults();
ui->setupUi(this);
+ initUi();
connect(ui->cb_Style, qOverload(&QComboBox::currentIndexChanged), this, &TaskLineDecor::onStyleChanged);
connect(ui->cc_Color, &ColorButton::changed, this, &TaskLineDecor::onColorChanged);
connect(ui->dsb_Weight, qOverload(&QuantitySpinBox::valueChanged), this, &TaskLineDecor::onWeightChanged);
connect(ui->cb_Visible, qOverload(&QComboBox::currentIndexChanged), this, &TaskLineDecor::onVisibleChanged);
-
- initUi();
}
TaskLineDecor::~TaskLineDecor()
@@ -94,6 +94,66 @@ void TaskLineDecor::initUi()
ui->cb_Visible->setCurrentIndex(m_visible);
}
+TechDraw::LineFormat *TaskLineDecor::getFormatAccessPtr(const std::string &edgeName, std::string *newFormatTag)
+{
+ BaseGeomPtr bg = m_partFeat->getEdge(edgeName);
+ if (bg) {
+ if (bg->getCosmetic()) {
+ if (bg->source() == SourceType::COSEDGE) {
+ TechDraw::CosmeticEdge *ce = m_partFeat->getCosmeticEdgeBySelection(edgeName);
+ if (ce) {
+ return &ce->m_format;
+ }
+ }
+ else if (bg->source() == SourceType::CENTERLINE) {
+ TechDraw::CenterLine *cl = m_partFeat->getCenterLineBySelection(edgeName);
+ if (cl) {
+ return &cl->m_format;
+ }
+ }
+ }
+ else {
+ TechDraw::GeomFormat *gf = m_partFeat->getGeomFormatBySelection(edgeName);
+ if (gf) {
+ return &gf->m_format;
+ }
+ else {
+ ViewProviderViewPart *viewPart = dynamic_cast(QGIView::getViewProvider(m_partFeat));
+ if (viewPart) {
+ TechDraw::LineFormat lineFormat(Qt::SolidLine, viewPart->LineWidth.getValue(), LineFormat::getDefEdgeColor(), true);
+ TechDraw::GeomFormat geomFormat(DrawUtil::getIndexFromName(edgeName), lineFormat);
+
+ std::string formatTag = m_partFeat->addGeomFormat(&geomFormat);
+ if (newFormatTag) {
+ *newFormatTag = formatTag;
+ }
+
+ return &m_partFeat->getGeomFormat(formatTag)->m_format;
+ }
+ }
+ }
+ }
+ return nullptr;
+}
+
+void TaskLineDecor::initializeRejectArrays()
+{
+ m_originalFormats.resize(m_edges.size());
+ m_createdFormatTags.resize(m_edges.size());
+
+ for (size_t i = 0; i < m_edges.size(); ++i) {
+ std::string newTag;
+ TechDraw::LineFormat *accessPtr = getFormatAccessPtr(m_edges[i], &newTag);
+
+ if (accessPtr) {
+ m_originalFormats[i] = *accessPtr;
+ if (!newTag.empty()) {
+ m_createdFormatTags[i] = newTag;
+ }
+ }
+ }
+}
+
void TaskLineDecor::getDefaults()
{
// Base::Console().Message("TLD::getDefaults()\n");
@@ -103,44 +163,12 @@ void TaskLineDecor::getDefaults()
m_visible = true;
//set defaults to format of 1st edge
- if (!m_edges.empty()) {
- int num = DrawUtil::getIndexFromName(m_edges.front());
- BaseGeomPtr bg = m_partFeat->getGeomByIndex(num);
- if (bg) {
- if (bg->getCosmetic()) {
- if (bg->source() == 1) {
- TechDraw::CosmeticEdge* ce = m_partFeat->getCosmeticEdgeBySelection(m_edges.front());
- m_style = ce->m_format.m_style;
- m_color = ce->m_format.m_color;
- m_weight = ce->m_format.m_weight;
- m_visible = ce->m_format.m_visible;
- } else if (bg->source() == 2) {
-// TechDraw::CenterLine* cl = m_partFeat->getCenterLine(bg->getCosmeticTag);
- TechDraw::CenterLine* cl = m_partFeat->getCenterLineBySelection(m_edges.front());
- m_style = cl->m_format.m_style;
- m_color = cl->m_format.m_color;
- m_weight = cl->m_format.m_weight;
- m_visible = cl->m_format.m_visible;
- }
- } else {
- TechDraw::GeomFormat* gf = m_partFeat->getGeomFormatBySelection(num);
- if (gf) {
- m_style = gf->m_format.m_style;
- m_color = gf->m_format.m_color;
- m_weight = gf->m_format.m_weight;
- m_visible = gf->m_format.m_visible;
- } else {
- Gui::ViewProvider* vp = QGIView::getViewProvider(m_partFeat);
- auto partVP = dynamic_cast(vp);
- if (partVP) {
- m_weight = partVP->LineWidth.getValue();
- m_style = Qt::SolidLine; // = 1
- m_color = LineFormat::getDefEdgeColor();
- m_visible = true;
- }
- }
- }
- }
+ if (!m_originalFormats.empty()) {
+ LineFormat &lf = m_originalFormats.front();
+ m_style = lf.m_style;
+ m_color = lf.m_color;
+ m_weight = lf.m_weight;
+ m_visible = lf.m_visible;
}
}
@@ -176,42 +204,12 @@ void TaskLineDecor::applyDecorations()
{
// Base::Console().Message("TLD::applyDecorations()\n");
for (auto& e: m_edges) {
- int num = DrawUtil::getIndexFromName(e);
- BaseGeomPtr bg = m_partFeat->getGeomByIndex(num);
- if (bg) {
- if (bg->getCosmetic()) {
- if (bg->source() == 1) {
- TechDraw::CosmeticEdge* ce = m_partFeat->getCosmeticEdgeBySelection(e);
- ce->m_format.m_style = m_style;
- ce->m_format.m_color = m_color;
- ce->m_format.m_weight = m_weight;
- ce->m_format.m_visible = m_visible;
- } else if (bg->source() == 2) {
-// TechDraw::CenterLine* cl = m_partFeat->getCenterLine(bg->getCosmeticTag());
- TechDraw::CenterLine* cl = m_partFeat->getCenterLineBySelection(e);
- cl->m_format.m_style = m_style;
- cl->m_format.m_color = m_color;
- cl->m_format.m_weight = m_weight;
- cl->m_format.m_visible = m_visible;
- }
- } else {
- TechDraw::GeomFormat* gf = m_partFeat->getGeomFormatBySelection(num);
- if (gf) {
- gf->m_format.m_style = m_style;
- gf->m_format.m_color = m_color;
- gf->m_format.m_weight = m_weight;
- gf->m_format.m_visible = m_visible;
- } else {
- TechDraw::LineFormat fmt(m_style,
- m_weight,
- m_color,
- m_visible);
- TechDraw::GeomFormat* newGF = new TechDraw::GeomFormat(num,
- fmt);
-// int idx =
- m_partFeat->addGeomFormat(newGF);
- }
- }
+ LineFormat *lf = getFormatAccessPtr(e);
+ if (lf) {
+ lf->m_style = m_style;
+ lf->m_color = m_color;
+ lf->m_weight = m_weight;
+ lf->m_visible = m_visible;
}
}
}
@@ -242,6 +240,21 @@ bool TaskLineDecor::reject()
if (!doc)
return false;
+ for (size_t i = 0; i < m_originalFormats.size(); ++i) {
+ std::string &formatTag = m_createdFormatTags[i];
+ if (formatTag.empty()) {
+ LineFormat *lf = getFormatAccessPtr(m_edges[i]);
+ if (lf) {
+ *lf = m_originalFormats[i];
+ }
+ }
+ else {
+ m_partFeat->removeGeomFormat(formatTag);
+ }
+ }
+
+ m_partFeat->requestPaint();
+
Gui::Command::doCommand(Gui::Command::Gui, "Gui.ActiveDocument.resetEdit()");
return false;
}
diff --git a/src/Mod/TechDraw/Gui/TaskLineDecor.h b/src/Mod/TechDraw/Gui/TaskLineDecor.h
index 9c58640c1a..c773a1a21e 100644
--- a/src/Mod/TechDraw/Gui/TaskLineDecor.h
+++ b/src/Mod/TechDraw/Gui/TaskLineDecor.h
@@ -26,7 +26,7 @@
#include
#include
#include
-
+#include
namespace App
{
@@ -62,6 +62,10 @@ protected Q_SLOTS:
protected:
void changeEvent(QEvent *e) override;
void initUi();
+
+ TechDraw::LineFormat *getFormatAccessPtr(const std::string &edgeName, std::string *newFormatTag = nullptr);
+ void initializeRejectArrays();
+
void applyDecorations();
void getDefaults();
@@ -69,6 +73,10 @@ private:
std::unique_ptr ui;
TechDraw::DrawViewPart* m_partFeat;
std::vector m_edges;
+
+ std::vector m_originalFormats;
+ std::vector m_createdFormatTags;
+
int m_style;
App::Color m_color;
double m_weight;
diff --git a/src/Tools/xmlformat/CMakeLists.txt b/src/Tools/xmlformat/CMakeLists.txt
new file mode 100644
index 0000000000..b06e4d0798
--- /dev/null
+++ b/src/Tools/xmlformat/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 3.14)
+
+project(xmlformat LANGUAGES CXX)
+
+set(CMAKE_INCLUDE_CURRENT_DIR ON)
+
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+find_package(QT NAMES Qt6 Qt5 COMPONENTS Core Xml REQUIRED)
+find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Xml REQUIRED)
+
+add_executable(xmlformat
+ main.cpp
+)
+target_link_libraries(xmlformat Qt${QT_VERSION_MAJOR}::Core
+ Qt${QT_VERSION_MAJOR}::Xml)
diff --git a/src/Tools/xmlformat/main.cpp b/src/Tools/xmlformat/main.cpp
new file mode 100644
index 0000000000..3948a27899
--- /dev/null
+++ b/src/Tools/xmlformat/main.cpp
@@ -0,0 +1,124 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+
+/***************************************************************************
+ * Copyright (c) 2023 Werner Mayer *
+ * *
+ * This file is part of FreeCAD. *
+ * *
+ * FreeCAD is free software: you can redistribute it and/or modify it *
+ * under the terms of the GNU Lesser General Public License as *
+ * published by the Free Software Foundation, either version 2.1 of the *
+ * License, or (at your option) any later version. *
+ * *
+ * FreeCAD 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 *
+ * Lesser General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU Lesser General Public *
+ * License along with FreeCAD. If not, see *
+ * . *
+ * *
+ **************************************************************************/
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+int main(int argc, char* argv[])
+{
+ QCoreApplication app(argc, argv);
+ QStringList args = QCoreApplication::arguments();
+ if (args.size() != 2) {
+ std::cerr << "Requires input file\n";
+ return -1;
+ }
+
+ QFile file(args[1]);
+ if (!file.open(QFile::ReadOnly)) {
+ std::cerr << "Failed to read file\n";
+ return -1;
+ }
+
+ QXmlStreamReader reader(file.readAll());
+ file.close();
+
+ if (!file.open(QFile::WriteOnly)) {
+ std::cerr << "Failed to write file\n";
+ return -1;
+ }
+
+ QXmlStreamWriter writer(&file);
+ writer.setAutoFormatting(true);
+ writer.setAutoFormattingIndent(4);
+
+ auto findAttr = [](const QXmlStreamAttributes& attr, const QString& name) {
+ for (int i = 0; i < attr.size(); ++i) {
+ if (attr.at(i).name() == name) {
+ return i;
+ }
+ }
+
+ return -1;
+ };
+
+ // ----------------------
+
+ auto sortAttr = [&findAttr](QXmlStreamAttributes& attr) {
+ QStringList list = {"Name",
+ "Namespace",
+ "Twin",
+ "TwinPointer",
+ "PythonName",
+ "FatherInclude",
+ "Include",
+ "Father",
+ "FatherNamespace"};
+ QXmlStreamAttributes sorted;
+ for (const auto& it : list) {
+ int index = findAttr(attr, it);
+ if (index > -1) {
+ sorted.append(attr.at(index));
+ attr.remove(index);
+ }
+ }
+
+ // add the rest
+ for (const auto& it : qAsConst(attr)) {
+ sorted.append(it);
+ }
+
+ return sorted;
+ };
+
+ // ----------------------
+
+ while (!reader.atEnd()) {
+ reader.readNext();
+ if (reader.isStartElement() && reader.name() == QLatin1String("PythonExport")) {
+ QXmlStreamAttributes attr = reader.attributes();
+ attr = sortAttr(attr);
+
+ writer.writeStartElement(QString("PythonExport"));
+ for (int i = 0; i < attr.size(); ++i) {
+ file.write("\n ");
+ writer.writeAttribute(attr.at(i));
+ }
+ }
+ else if (reader.isStartElement() && reader.name() == QLatin1String("UserDocu")) {
+ QString text = reader.readElementText().trimmed();
+ text.replace("\t", " ");
+ writer.writeTextElement(QString("UserDocu"), text);
+ }
+ else if (!reader.isWhitespace()) {
+ writer.writeCurrentToken(reader);
+ }
+ }
+
+ file.close();
+
+ return 0;
+}