Measure: Reduce boilerplate code by adding some helper methods
This commit is contained in:
@@ -62,6 +62,27 @@ namespace App {
|
||||
return empty;
|
||||
}
|
||||
|
||||
MeasureHandler MeasureManager::getMeasureHandler(const App::MeasureSelectionItem& selectionItem) {
|
||||
auto objT = selectionItem.object;
|
||||
|
||||
App::DocumentObject* sub = objT.getSubObject();
|
||||
|
||||
const char* className = sub->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
return getMeasureHandler(mod.c_str());
|
||||
}
|
||||
|
||||
MeasureElementType MeasureManager::getMeasureElementType(const App::MeasureSelectionItem& selectionItem) {
|
||||
auto handler = getMeasureHandler(selectionItem);
|
||||
if (handler.module.empty()) {
|
||||
return App::MeasureElementType::INVALID;
|
||||
}
|
||||
|
||||
auto objT = selectionItem.object;
|
||||
return handler.typeCb(objT.getObject(), objT.getSubName().c_str());
|
||||
}
|
||||
|
||||
void MeasureManager::addMeasureType(MeasureType* measureType) {
|
||||
_mMeasureTypes.push_back(measureType);
|
||||
}
|
||||
|
||||
@@ -93,6 +93,8 @@ public:
|
||||
static void addMeasureHandler(const char* module, MeasureTypeMethod typeCb);
|
||||
static bool hasMeasureHandler(const char* module);
|
||||
static MeasureHandler getMeasureHandler(const char* module);
|
||||
static MeasureHandler getMeasureHandler(const App::MeasureSelectionItem& selectionItem);
|
||||
static MeasureElementType getMeasureElementType(const App::MeasureSelectionItem& selectionItem);
|
||||
static void addMeasureType(MeasureType* measureType);
|
||||
static void addMeasureType(std::string id, std::string label, std::string measureObj, MeasureValidateMethod validatorCb, MeasurePrioritizeMethod prioritizeCb);
|
||||
static void addMeasureType(const char* id, const char* label, const char* measureObj, MeasureValidateMethod validatorCb, MeasurePrioritizeMethod prioritizeCb);
|
||||
|
||||
@@ -61,19 +61,7 @@ bool MeasureAngle::isValidSelection(const App::MeasureSelection& selection)
|
||||
}
|
||||
|
||||
for (auto element : selection) {
|
||||
auto objT = element.object;
|
||||
|
||||
App::DocumentObject* ob = objT.getObject();
|
||||
const std::string& subName = objT.getSubName();
|
||||
const char* className = objT.getSubObject()->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
App::MeasureHandler handler = App::MeasureManager::getMeasureHandler(mod.c_str());
|
||||
App::MeasureElementType type = handler.typeCb(ob, subName.c_str());
|
||||
auto type = App::MeasureManager::getMeasureElementType(element);
|
||||
|
||||
if (type == App::MeasureElementType::INVALID) {
|
||||
return false;
|
||||
@@ -134,17 +122,12 @@ void MeasureAngle::parseSelection(const App::MeasureSelection& selection) {
|
||||
|
||||
|
||||
bool MeasureAngle::getVec(App::DocumentObject& ob, std::string& subName, Base::Vector3d& vecOut) {
|
||||
const char* className = ob.getSubObject(subName.c_str())->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
App::SubObjectT subject{&ob, subName.c_str()};
|
||||
auto info = getMeasureInfo(subject);
|
||||
if (!info || !info->valid) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto handler = getGeometryHandler(mod);
|
||||
App::SubObjectT subject{&ob, subName.c_str()};
|
||||
auto info = handler(subject);
|
||||
|
||||
auto angleInfo = std::dynamic_pointer_cast<Part::MeasureAngleInfo>(info);
|
||||
vecOut = angleInfo->orientation;
|
||||
return true;
|
||||
@@ -152,16 +135,12 @@ bool MeasureAngle::getVec(App::DocumentObject& ob, std::string& subName, Base::V
|
||||
|
||||
Base::Vector3d MeasureAngle::getLoc(App::DocumentObject& ob, std::string& subName)
|
||||
{
|
||||
const char* className = ob.getSubObject(subName.c_str())->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
auto handler = getGeometryHandler(mod);
|
||||
App::SubObjectT subject{&ob, subName.c_str()};
|
||||
auto info = handler(subject);
|
||||
auto info = getMeasureInfo(subject);
|
||||
if (!info || !info->valid) {
|
||||
return Base::Vector3d();
|
||||
}
|
||||
|
||||
auto angleInfo = std::dynamic_pointer_cast<Part::MeasureAngleInfo>(info);
|
||||
return angleInfo->position;
|
||||
}
|
||||
|
||||
@@ -56,19 +56,7 @@ bool MeasureArea::isValidSelection(const App::MeasureSelection& selection){
|
||||
}
|
||||
|
||||
for (auto element : selection) {
|
||||
auto objT = element.object;
|
||||
|
||||
App::DocumentObject* ob = objT.getObject();
|
||||
const std::string& subName = objT.getSubName();
|
||||
const char* className = objT.getSubObject()->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
App::MeasureHandler handler = App::MeasureManager::getMeasureHandler(mod.c_str());
|
||||
App::MeasureElementType type = handler.typeCb(ob, subName.c_str());
|
||||
auto type = App::MeasureManager::getMeasureElementType(element);
|
||||
|
||||
if (type == App::MeasureElementType::INVALID) {
|
||||
return false;
|
||||
@@ -114,19 +102,12 @@ void MeasureArea::recalculateArea()
|
||||
|
||||
// Loop through Elements and call the valid geometry handler
|
||||
for (std::vector<App::DocumentObject*>::size_type i=0; i<objects.size(); i++) {
|
||||
App::DocumentObject *object = objects.at(i);
|
||||
std::string subElement = subElements.at(i);
|
||||
App::SubObjectT subject{objects.at(i), subElements.at(i).c_str()};
|
||||
|
||||
// Get the Geometry handler based on the module
|
||||
const char* className = object->getSubObject(subElement.c_str())->getTypeId().getName();
|
||||
const std::string& mod = Base::Type::getModuleName(className);
|
||||
auto handler = getGeometryHandler(mod);
|
||||
if (!handler) {
|
||||
throw Base::RuntimeError("No geometry handler available for submitted element type");
|
||||
auto info = getMeasureInfo(subject);
|
||||
if (!info || !info->valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
App::SubObjectT subject{object, subElement.c_str()};
|
||||
auto info = handler(subject);
|
||||
auto areaInfo = std::dynamic_pointer_cast<Part::MeasureAreaInfo>(info);
|
||||
result += areaInfo->area;
|
||||
}
|
||||
@@ -143,7 +124,7 @@ void MeasureArea::onChanged(const App::Property* prop)
|
||||
if (prop == &Elements) {
|
||||
recalculateArea();
|
||||
}
|
||||
|
||||
|
||||
MeasureBase::onChanged(prop);
|
||||
}
|
||||
|
||||
@@ -156,18 +137,12 @@ Base::Placement MeasureArea::getPlacement() {
|
||||
return Base::Placement();
|
||||
}
|
||||
|
||||
App::DocumentObject* object = objects.front();
|
||||
std::string subElement = subElements.front();
|
||||
const char* className = object->getSubObject(subElement.c_str())->getTypeId().getName();
|
||||
const std::string& mod = Base::Type::getModuleName(className);
|
||||
App::SubObjectT subject{objects.front(), subElements.front().c_str()};
|
||||
|
||||
auto handler = getGeometryHandler(mod);
|
||||
if (!handler) {
|
||||
throw Base::RuntimeError("No geometry handler available for submitted element type");
|
||||
auto info = getMeasureInfo(subject);
|
||||
if (!info) {
|
||||
return {};
|
||||
}
|
||||
|
||||
App::SubObjectT subject{object, subElement.c_str()};
|
||||
auto info = handler(subject);
|
||||
auto areaInfo = std::dynamic_pointer_cast<Part::MeasureAreaInfo>(info);
|
||||
return areaInfo->placement;
|
||||
}
|
||||
|
||||
@@ -106,6 +106,23 @@ public:
|
||||
return _mGeometryHandlers[module];
|
||||
}
|
||||
|
||||
static Part::MeasureInfoPtr getMeasureInfo(App::SubObjectT& subObjT) {
|
||||
|
||||
App::DocumentObject* sub = subObjT.getSubObject();
|
||||
|
||||
// Get the Geometry handler based on the module
|
||||
const char* className = sub->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
auto handler = getGeometryHandler(mod);
|
||||
if (!handler) {
|
||||
Base::Console().Log("MeasureBaseExtendable::getMeasureInfo: No geometry handler available for submitted element type");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return handler(subObjT);
|
||||
}
|
||||
|
||||
static void addGeometryHandlers(const std::vector<std::string>& modules, GeometryHandler callback){
|
||||
// TODO: this will replace a callback with a later one. Should we check that there isn't already a
|
||||
// handler defined for this module?
|
||||
|
||||
@@ -76,20 +76,7 @@ bool MeasureDistance::isValidSelection(const App::MeasureSelection& selection){
|
||||
}
|
||||
|
||||
for (auto element : selection) {
|
||||
|
||||
auto objT = element.object;
|
||||
|
||||
App::DocumentObject* ob = objT.getObject();
|
||||
const std::string& subName = objT.getSubName();
|
||||
const char* className = objT.getSubObject()->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
App::MeasureHandler handler = App::MeasureManager::getMeasureHandler(mod.c_str());
|
||||
App::MeasureElementType type = handler.typeCb(ob, subName.c_str());
|
||||
auto type = App::MeasureManager::getMeasureElementType(element);
|
||||
|
||||
if (type == App::MeasureElementType::INVALID) {
|
||||
return false;
|
||||
@@ -152,17 +139,11 @@ bool MeasureDistance::getShape(App::PropertyLinkSub* prop, TopoDS_Shape& rShape)
|
||||
}
|
||||
|
||||
std::string subName = subs.at(0);
|
||||
const char* className = ob->getSubObject(subName.c_str())->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
auto handler = getGeometryHandler(mod);
|
||||
App::SubObjectT subject{ob, subName.c_str()};
|
||||
auto info = handler(subject);
|
||||
if (!info->valid) {
|
||||
|
||||
auto info = getMeasureInfo(subject);
|
||||
|
||||
if (!info || !info->valid) {
|
||||
return false;
|
||||
}
|
||||
auto distanceInfo = std::dynamic_pointer_cast<Part::MeasureDistanceInfo>(info);
|
||||
|
||||
@@ -58,19 +58,7 @@ bool MeasureLength::isValidSelection(const App::MeasureSelection& selection){
|
||||
}
|
||||
|
||||
for (auto element : selection) {
|
||||
auto objT = element.object;
|
||||
|
||||
App::DocumentObject* ob = objT.getObject();
|
||||
const std::string& subName = objT.getSubName();
|
||||
const char* className = objT.getSubObject()->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
App::MeasureHandler handler = App::MeasureManager::getMeasureHandler(mod.c_str());
|
||||
App::MeasureElementType type = handler.typeCb(ob, subName.c_str());
|
||||
auto type = App::MeasureManager::getMeasureElementType(element);
|
||||
|
||||
if (type == App::MeasureElementType::INVALID) {
|
||||
return false;
|
||||
@@ -91,7 +79,7 @@ void MeasureLength::parseSelection(const App::MeasureSelection& selection) {
|
||||
std::vector<std::string> subElements;
|
||||
|
||||
for (auto element : selection) {
|
||||
auto objT = element.object;
|
||||
auto objT = element.object;
|
||||
|
||||
objects.push_back(objT.getObject());
|
||||
subElements.push_back(objT.getSubName());
|
||||
@@ -116,19 +104,13 @@ void MeasureLength::recalculateLength()
|
||||
|
||||
// Loop through Elements and call the valid geometry handler
|
||||
for (std::vector<App::DocumentObject*>::size_type i=0; i<objects.size(); i++) {
|
||||
App::DocumentObject *object = objects.at(i);
|
||||
std::string subElement = subElements.at(i);
|
||||
|
||||
// Get the Geometry handler based on the module
|
||||
const char* className = object->getSubObject(subElement.c_str())->getTypeId().getName();
|
||||
const std::string& mod = Base::Type::getModuleName(className);
|
||||
auto handler = getGeometryHandler(mod);
|
||||
if (!handler) {
|
||||
throw Base::RuntimeError("No geometry handler available for submitted element type");
|
||||
App::SubObjectT subject{objects.at(i), subElements.at(i).c_str()};
|
||||
auto info = getMeasureInfo(subject);
|
||||
if (!info || !info->valid) {
|
||||
continue;
|
||||
}
|
||||
|
||||
App::SubObjectT subject{object, subElement.c_str()};
|
||||
auto info = handler(subject);
|
||||
auto lengthInfo = std::dynamic_pointer_cast<Part::MeasureLengthInfo>(info);
|
||||
result += lengthInfo->length;
|
||||
}
|
||||
@@ -158,18 +140,12 @@ Base::Placement MeasureLength::getPlacement() {
|
||||
return Base::Placement();
|
||||
}
|
||||
|
||||
App::DocumentObject* object = objects.front();
|
||||
std::string subElement = subElements.front();
|
||||
const char* className = object->getSubObject(subElement.c_str())->getTypeId().getName();
|
||||
const std::string& mod = Base::Type::getModuleName(className);
|
||||
|
||||
auto handler = getGeometryHandler(mod);
|
||||
if (!handler) {
|
||||
throw Base::RuntimeError("No geometry handler available for submitted element type");
|
||||
App::SubObjectT subject{objects.front(), subElements.front().c_str()};
|
||||
auto info = getMeasureInfo(subject);
|
||||
|
||||
if (!info || !info->valid) {
|
||||
return {};
|
||||
}
|
||||
|
||||
App::SubObjectT subject{object, subElement.c_str()};
|
||||
auto info = handler(subject);
|
||||
auto lengthInfo = std::dynamic_pointer_cast<Part::MeasureLengthInfo>(info);
|
||||
return lengthInfo->placement;
|
||||
}
|
||||
|
||||
@@ -58,19 +58,7 @@ bool MeasurePosition::isValidSelection(const App::MeasureSelection& selection){
|
||||
}
|
||||
|
||||
for (auto element : selection) {
|
||||
auto objT = element.object;
|
||||
|
||||
App::DocumentObject* ob = objT.getObject();
|
||||
const std::string& subName = objT.getSubName();
|
||||
const char* className = objT.getSubObject()->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
App::MeasureHandler handler = App::MeasureManager::getMeasureHandler(mod.c_str());
|
||||
App::MeasureElementType type = handler.typeCb(ob, subName.c_str());
|
||||
auto type = App::MeasureManager::getMeasureElementType(element);
|
||||
|
||||
if (type == App::MeasureElementType::INVALID) {
|
||||
return false;
|
||||
@@ -107,19 +95,13 @@ void MeasurePosition::recalculatePosition()
|
||||
const App::DocumentObject* object = Element.getValue();
|
||||
const std::vector<std::string>& subElements = Element.getSubValues();
|
||||
|
||||
// Get the position of the first point
|
||||
std::string subElement = subElements.front();
|
||||
|
||||
// Get the Geometry handler based on the module
|
||||
const char* className = object->getSubObject(subElement.c_str())->getTypeId().getName();
|
||||
const std::string& mod = Base::Type::getModuleName(className);
|
||||
auto handler = getGeometryHandler(mod);
|
||||
if (!handler) {
|
||||
throw Base::RuntimeError("No geometry handler available for submitted element type");
|
||||
App::SubObjectT subject{object, subElements.front().c_str()};
|
||||
auto info = getMeasureInfo(subject);
|
||||
|
||||
if (!info || !info->valid) {
|
||||
return;
|
||||
}
|
||||
|
||||
App::SubObjectT subject{object, subElement.c_str()};
|
||||
auto info = handler(subject);
|
||||
auto positionInfo = std::dynamic_pointer_cast<Part::MeasurePositionInfo>(info);
|
||||
Position.setValue(positionInfo->position);
|
||||
}
|
||||
|
||||
@@ -68,19 +68,7 @@ bool MeasureRadius::isValidSelection(const App::MeasureSelection& selection){
|
||||
}
|
||||
|
||||
auto element = selection.front();
|
||||
auto objT = element.object;
|
||||
|
||||
App::DocumentObject* ob = objT.getObject();
|
||||
const std::string& subName = objT.getSubName();
|
||||
const char* className = objT.getSubObject()->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
App::MeasureHandler handler = App::MeasureManager::getMeasureHandler(mod.c_str());
|
||||
App::MeasureElementType type = handler.typeCb(ob, subName.c_str());
|
||||
auto type = App::MeasureManager::getMeasureElementType(element);
|
||||
|
||||
if (type == App::MeasureElementType::INVALID) {
|
||||
return false;
|
||||
@@ -102,19 +90,7 @@ bool MeasureRadius::isPrioritizedSelection(const App::MeasureSelection& selectio
|
||||
}
|
||||
|
||||
auto element = selection.front();
|
||||
auto objT = element.object;
|
||||
|
||||
App::DocumentObject* ob = objT.getObject();
|
||||
const std::string& subName = objT.getSubName();
|
||||
const char* className = objT.getSubObject()->getTypeId().getName();
|
||||
std::string mod = Base::Type::getModuleName(className);
|
||||
|
||||
if (!hasGeometryHandler(mod)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
App::MeasureHandler handler = App::MeasureManager::getMeasureHandler(mod.c_str());
|
||||
App::MeasureElementType type = handler.typeCb(ob, subName.c_str());
|
||||
auto type = App::MeasureManager::getMeasureElementType(element);
|
||||
|
||||
if (type == App::MeasureElementType::CIRCLE
|
||||
|| type == App::MeasureElementType::ARC) {
|
||||
@@ -179,7 +155,7 @@ Base::Vector3d MeasureRadius::getPointOnCurve() const
|
||||
//! get the handler's result for the first element
|
||||
Part::MeasureRadiusInfoPtr MeasureRadius::getMeasureInfoFirst() const
|
||||
{
|
||||
const App::DocumentObject* object = Element.getValue();
|
||||
const App::DocumentObject* object = Element.getValue();
|
||||
const std::vector<std::string>& subElements = Element.getSubValues();
|
||||
|
||||
if (!object || subElements.empty()) {
|
||||
@@ -187,18 +163,13 @@ Part::MeasureRadiusInfoPtr MeasureRadius::getMeasureInfoFirst() const
|
||||
return std::make_shared<Part::MeasureRadiusInfo>();
|
||||
}
|
||||
|
||||
std::string subElement = subElements.front();
|
||||
const char* className = object->getSubObject(subElement.c_str())->getTypeId().getName();
|
||||
const std::string& mod = Base::Type::getModuleName(className);
|
||||
|
||||
auto handler = getGeometryHandler(mod);
|
||||
if (!handler) {
|
||||
throw Base::RuntimeError("No geometry handler available for submitted element type");
|
||||
App::SubObjectT subject{object, subElements.front().c_str()};
|
||||
auto info = getMeasureInfo(subject);
|
||||
if (!info || !info->valid) {
|
||||
// NOLINTNEXTLINE(modernize-return-braced-init-list)
|
||||
return std::make_shared<Part::MeasureRadiusInfo>();
|
||||
}
|
||||
|
||||
std::string obName = object->getNameInDocument();
|
||||
App::SubObjectT subject{object, subElement.c_str()};
|
||||
auto info = handler(subject);
|
||||
auto radiusInfo = std::dynamic_pointer_cast<Part::MeasureRadiusInfo>(info);
|
||||
return radiusInfo;
|
||||
}
|
||||
|
||||
@@ -185,13 +185,12 @@ void TaskMeasure::update() {
|
||||
if (measureTypes.size() > 0) {
|
||||
measureType = measureTypes.front();
|
||||
}
|
||||
|
||||
|
||||
if (!measureType) {
|
||||
|
||||
// Note: If there's no valid measure type we might just restart the selection,
|
||||
// however this requires enough coverage of measuretypes that we can access all of them
|
||||
|
||||
|
||||
// std::tuple<std::string, std::string> sel = selection.back();
|
||||
// clearSelection();
|
||||
// addElement(measureModule.c_str(), get<0>(sel).c_str(), get<1>(sel).c_str());
|
||||
@@ -215,7 +214,7 @@ void TaskMeasure::update() {
|
||||
if (measureType->isPython) {
|
||||
Base::PyGILStateLocker lock;
|
||||
auto pyMeasureClass = measureType->pythonClass;
|
||||
|
||||
|
||||
// Create a MeasurePython instance
|
||||
auto featurePython = doc->addObject("Measure::MeasurePython", measureType->label.c_str());
|
||||
setMeasureObject((Measure::MeasureBase*)featurePython);
|
||||
@@ -297,7 +296,7 @@ void TaskMeasure::reset() {
|
||||
// Reset tool state
|
||||
this->clearSelection();
|
||||
|
||||
// Should the explicit mode also be reset?
|
||||
// Should the explicit mode also be reset?
|
||||
// setModeSilent(nullptr);
|
||||
// explicitMode = false;
|
||||
|
||||
@@ -368,7 +367,7 @@ void TaskMeasure::onModeChanged(int index) {
|
||||
|
||||
void TaskMeasure::setModeSilent(App::MeasureType* mode) {
|
||||
modeSwitch->blockSignals(true);
|
||||
|
||||
|
||||
if (mode == nullptr) {
|
||||
modeSwitch->setCurrentIndex(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user