FreeCAD

Форк
0
/
MeasureRadius.cpp 
190 строк · 6.0 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2023 WandererFan <wandererfan@gmail.com>                *
3
 *                                                                         *
4
 *   This file is part of FreeCAD.                                         *
5
 *                                                                         *
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.                       *
10
 *                                                                         *
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.                       *
15
 *                                                                         *
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/>.                                      *
19
 *                                                                         *
20
 **************************************************************************/
21

22
#include "PreCompiled.h"
23

24

25
#include <TopExp_Explorer.hxx>
26
#include <TopoDS.hxx>
27
#include <TopoDS_Edge.hxx>
28
#include <TopoDS_Wire.hxx>
29
#include <BRepAdaptor_Curve.hxx>
30
#include <BRepLProp_CLProps.hxx>
31

32
#include <App/Application.h>
33
#include <App/Document.h>
34
#include <App/MeasureManager.h>
35

36
#include <Mod/Part/App/PartFeature.h>
37

38
#include "MeasureRadius.h"
39

40

41
using namespace Measure;
42

43
PROPERTY_SOURCE(Measure::MeasureRadius, Measure::MeasureBase)
44

45

46
MeasureRadius::MeasureRadius()
47
{
48
    ADD_PROPERTY_TYPE(Element,
49
                      (nullptr),
50
                      "Measurement",
51
                      App::Prop_None,
52
                      "Element to get the radius from");
53
    Element.setScope(App::LinkScope::Global);
54
    Element.setAllowExternal(true);
55

56
    ADD_PROPERTY_TYPE(Radius,
57
                      (0.0),
58
                      "Measurement",
59
                      App::PropertyType(App::Prop_ReadOnly | App::Prop_Output),
60
                      "Radius of selection");
61
}
62

63
MeasureRadius::~MeasureRadius() = default;
64

65
//! validate all the object+subelement pairs in the selection. Must be circle or arc
66
//! and have a geometry handler available.  We only calculate radius if there is a
67
//! single valid item in the selection
68
bool MeasureRadius::isValidSelection(const App::MeasureSelection& selection)
69
{
70

71
    if (selection.empty() || selection.size() > 1) {
72
        // too few or too many selections
73
        return false;
74
    }
75

76
    auto element = selection.front();
77
    auto type = App::MeasureManager::getMeasureElementType(element);
78

79
    if (type == App::MeasureElementType::INVALID) {
80
        return false;
81
    }
82

83
    if (type != App::MeasureElementType::CIRCLE && type != App::MeasureElementType::ARC) {
84
        return false;
85
    }
86

87
    return true;
88
}
89

90
//! return true if the selection is particularly interesting to MeasureRadius.
91
//! In this case we claim circles and arcs.
92
bool MeasureRadius::isPrioritizedSelection(const App::MeasureSelection& selection)
93
{
94
    if (selection.size() != 1) {
95
        return false;
96
    }
97

98
    auto element = selection.front();
99
    auto type = App::MeasureManager::getMeasureElementType(element);
100

101
    if (type == App::MeasureElementType::CIRCLE || type == App::MeasureElementType::ARC) {
102
        return true;
103
    }
104

105
    return false;
106
}
107

108

109
//! Set properties from first item in selection. assumes a valid selection.
110
void MeasureRadius::parseSelection(const App::MeasureSelection& selection)
111
{
112
    auto element = selection.front();
113
    auto objT = element.object;
114

115
    std::vector<std::string> subElementList {objT.getSubName()};
116
    Element.setValue(objT.getObject(), subElementList);
117
}
118

119

120
App::DocumentObjectExecReturn* MeasureRadius::execute()
121
{
122
    auto info = getMeasureInfoFirst();
123
    if (!info || !info->valid) {
124
        return new App::DocumentObjectExecReturn("Cannot calculate radius");
125
    }
126

127
    Radius.setValue(info->radius);
128
    return DocumentObject::StdReturn;
129
}
130

131

132
void MeasureRadius::onChanged(const App::Property* prop)
133
{
134
    if (isRestoring() || isRemoving()) {
135
        return;
136
    }
137

138
    if (prop == &Element) {
139
        auto ret = recompute();
140
        delete ret;
141
    }
142

143
    MeasureBase::onChanged(prop);
144
}
145

146

147
//! return a placement (location + orientation) for the first element
148
Base::Placement MeasureRadius::getPlacement()
149
{
150
    auto loc = getMeasureInfoFirst()->pointOnCurve;
151
    auto p = Base::Placement();
152
    p.setPosition(loc);
153
    return p;
154
}
155

156

157
//! return the pointOnCurve element in MeasureRadiusInfo for the first element
158
Base::Vector3d MeasureRadius::getPointOnCurve() const
159
{
160
    return getMeasureInfoFirst()->pointOnCurve;
161
}
162

163
//! get the handler's result for the first element
164
Part::MeasureRadiusInfoPtr MeasureRadius::getMeasureInfoFirst() const
165
{
166
    const App::DocumentObject* object = Element.getValue();
167
    const std::vector<std::string>& subElements = Element.getSubValues();
168

169
    if (!object || subElements.empty()) {
170
        // NOLINTNEXTLINE(modernize-return-braced-init-list)
171
        return std::make_shared<Part::MeasureRadiusInfo>();
172
    }
173

174
    App::SubObjectT subject {object, subElements.front().c_str()};
175
    auto info = getMeasureInfo(subject);
176
    if (!info || !info->valid) {
177
        // NOLINTNEXTLINE(modernize-return-braced-init-list)
178
        return std::make_shared<Part::MeasureRadiusInfo>();
179
    }
180

181
    auto radiusInfo = std::dynamic_pointer_cast<Part::MeasureRadiusInfo>(info);
182
    return radiusInfo;
183
}
184

185
//! Return the object we are measuring
186
//! used by the viewprovider in determining visibility
187
std::vector<App::DocumentObject*> MeasureRadius::getSubject() const
188
{
189
    return {Element.getValue()};
190
}
191

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.