1
/***************************************************************************
2
* Copyright (c) 2023 David Friedli <david[at]friedli-be.ch> *
4
* This file is part of FreeCAD. *
6
* FreeCAD is free software: you can redistribute it and/or modify it *
7
* under the terms of the GNU Lesser General Public License as *
8
* published by the Free Software Foundation, either version 2.1 of the *
9
* License, or (at your option) any later version. *
11
* FreeCAD is distributed in the hope that it will be useful, but *
12
* WITHOUT ANY WARRANTY; without even the implied warranty of *
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
14
* Lesser General Public License for more details. *
16
* You should have received a copy of the GNU Lesser General Public *
17
* License along with FreeCAD. If not, see *
18
* <https://www.gnu.org/licenses/>. *
20
**************************************************************************/
23
#include "PreCompiled.h"
25
#include <App/Application.h>
26
#include <App/Document.h>
27
#include <App/MeasureManager.h>
29
#include <Mod/Part/App/PartFeature.h>
31
#include "MeasureLength.h"
34
using namespace Measure;
36
PROPERTY_SOURCE(Measure::MeasureLength, Measure::MeasureBase)
39
MeasureLength::MeasureLength()
41
ADD_PROPERTY_TYPE(Elements,
45
"Elements to get the length from");
46
Elements.setScope(App::LinkScope::Global);
47
Elements.setAllowExternal(true);
49
ADD_PROPERTY_TYPE(Length,
52
App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
53
"Length of selection");
56
MeasureLength::~MeasureLength() = default;
59
bool MeasureLength::isValidSelection(const App::MeasureSelection& selection)
62
if (selection.empty()) {
66
for (auto element : selection) {
67
auto type = App::MeasureManager::getMeasureElementType(element);
69
if (type == App::MeasureElementType::INVALID) {
73
if ((type != App::MeasureElementType::LINESEGMENT && type != App::MeasureElementType::CIRCLE
74
&& type != App::MeasureElementType::ARC && type != App::MeasureElementType::CURVE)) {
81
void MeasureLength::parseSelection(const App::MeasureSelection& selection)
83
// Set properties from selection, method is only invoked when isValid Selection returns true
85
std::vector<App::DocumentObject*> objects;
86
std::vector<std::string> subElements;
88
for (auto element : selection) {
89
auto objT = element.object;
91
objects.push_back(objT.getObject());
92
subElements.push_back(objT.getSubName());
95
Elements.setValues(objects, subElements);
99
App::DocumentObjectExecReturn* MeasureLength::execute()
101
const std::vector<App::DocumentObject*>& objects = Elements.getValues();
102
const std::vector<std::string>& subElements = Elements.getSubValues();
106
// Loop through Elements and call the valid geometry handler
107
for (std::vector<App::DocumentObject*>::size_type i = 0; i < objects.size(); i++) {
109
App::SubObjectT subject {objects.at(i), subElements.at(i).c_str()};
110
auto info = getMeasureInfo(subject);
111
if (!info || !info->valid) {
112
return new App::DocumentObjectExecReturn("Cannot calculate length");
115
auto lengthInfo = std::dynamic_pointer_cast<Part::MeasureLengthInfo>(info);
116
result += lengthInfo->length;
119
Length.setValue(result);
120
return DocumentObject::StdReturn;
124
void MeasureLength::onChanged(const App::Property* prop)
126
if (isRestoring() || isRemoving()) {
130
if (prop == &Elements) {
131
auto ret = recompute();
135
MeasureBase::onChanged(prop);
139
Base::Placement MeasureLength::getPlacement()
141
const std::vector<App::DocumentObject*>& objects = Elements.getValues();
142
const std::vector<std::string>& subElements = Elements.getSubValues();
144
if (!objects.size() || !subElements.size()) {
145
return Base::Placement();
148
App::SubObjectT subject {objects.front(), subElements.front().c_str()};
149
auto info = getMeasureInfo(subject);
151
if (!info || !info->valid) {
154
auto lengthInfo = std::dynamic_pointer_cast<Part::MeasureLengthInfo>(info);
155
return lengthInfo->placement;
159
//! Return the object we are measuring
160
//! used by the viewprovider in determining visibility
161
std::vector<App::DocumentObject*> MeasureLength::getSubject() const
163
return Elements.getValues();