FreeCAD

Форк
0
/
SketchObject.cpp 
295 строк · 9.9 Кб
1
// SPDX-License-Identifier: LGPL-2.1-or-later
2

3
#include <gtest/gtest.h>
4

5
#include <FCConfig.h>
6

7
#include <App/Application.h>
8
#include <App/Document.h>
9
#include <App/Expression.h>
10
#include <App/ObjectIdentifier.h>
11
#include <Mod/Sketcher/App/GeoEnum.h>
12
#include <Mod/Sketcher/App/SketchObject.h>
13
#include <src/App/InitApplication.h>
14

15
class SketchObjectTest: public ::testing::Test
16
{
17
protected:
18
    static void SetUpTestSuite()
19
    {
20
        tests::initApplication();
21
    }
22

23
    void SetUp() override
24
    {
25
        _docName = App::GetApplication().getUniqueDocumentName("test");
26
        auto _doc = App::GetApplication().newDocument(_docName.c_str(), "testUser");
27
        // TODO: Do we add a body newName, or is just adding sketch sufficient for this test?
28
        _sketchobj =
29
            static_cast<Sketcher::SketchObject*>(_doc->addObject("Sketcher::SketchObject"));
30
    }
31

32
    void TearDown() override
33
    {
34
        App::GetApplication().closeDocument(_docName.c_str());
35
    }
36

37
    Sketcher::SketchObject* getObject()
38
    {
39
        return _sketchobj;
40
    }
41

42
private:
43
    // TODO: use shared_ptr or something else here?
44
    Sketcher::SketchObject* _sketchobj;
45
    std::string _docName;
46
    std::vector<const char*> allowedTypes {"Vertex",
47
                                           "Edge",
48
                                           "ExternalEdge",
49
                                           "H_Axis",
50
                                           "V_Axis",
51
                                           "RootPoint"};
52
};
53

54
TEST_F(SketchObjectTest, createSketchObject)  // NOLINT
55
{
56
    // Arrange
57

58
    // Act
59

60
    // Assert
61
}
62

63
TEST_F(SketchObjectTest, testGeoIdFromShapeTypeEdge)
64
{
65
    // Arrange
66
    // TODO: Do we need to separate existing vs non-existing?
67
    // It would need to be implemented in code as well.
68
    Data::IndexedName name("Edge", 1);
69
    int geoId;
70
    Sketcher::PointPos posId;
71

72
    // Act
73
    getObject()->geoIdFromShapeType(name, geoId, posId);
74

75
    // Assert
76
    EXPECT_EQ(geoId, 0);
77
    EXPECT_EQ(posId, Sketcher::PointPos::none);
78
}
79

80
TEST_F(SketchObjectTest, testGeoIdFromShapeTypeVertex)
81
{
82
    // Arrange
83
    // For operating on vertices, there is newName a check if the vertex exists.
84
    Base::Vector3d p1(0.0, 0.0, 0.0), p2(1.0, 0.0, 0.0);
85
    std::unique_ptr<Part::Geometry> geoline(new Part::GeomLineSegment());
86
    static_cast<Part::GeomLineSegment*>(geoline.get())->setPoints(p1, p2);
87
    getObject()->addGeometry(geoline.get());
88
    // TODO: Do we need to separate existing vs non-existing?
89
    // It would need to be implemented in code as well.
90
    Data::IndexedName name("Vertex", 1);
91
    int geoId;
92
    Sketcher::PointPos posId;
93

94
    // Act
95
    getObject()->geoIdFromShapeType(name, geoId, posId);
96

97
    // Assert
98
    EXPECT_EQ(geoId, 0);
99
    EXPECT_EQ(posId, Sketcher::PointPos::start);
100
}
101

102
TEST_F(SketchObjectTest, testGeoIdFromShapeTypeExternalEdge)
103
{
104
    // Arrange
105
    // TODO: Do we need to separate existing vs non-existing?
106
    // It would need to be implemented in code as well.
107
    Data::IndexedName name("ExternalEdge", 1);
108
    int geoId;
109
    Sketcher::PointPos posId;
110

111
    // Act
112
    getObject()->geoIdFromShapeType(name, geoId, posId);
113

114
    // Assert
115
    EXPECT_EQ(geoId, Sketcher::GeoEnum::RefExt);
116
    EXPECT_EQ(posId, Sketcher::PointPos::none);
117
}
118

119
TEST_F(SketchObjectTest, testGeoIdFromShapeTypeHAxis)
120
{
121
    // Arrange
122
    Data::IndexedName name("H_Axis");
123
    int geoId;
124
    Sketcher::PointPos posId;
125

126
    // Act
127
    getObject()->geoIdFromShapeType(name, geoId, posId);
128

129
    // Assert
130
    EXPECT_EQ(geoId, Sketcher::GeoEnum::HAxis);
131
    EXPECT_EQ(posId, Sketcher::PointPos::none);
132
}
133

134
TEST_F(SketchObjectTest, testGeoIdFromShapeTypeVAxis)
135
{
136
    // Arrange
137
    Data::IndexedName name("V_Axis");
138
    int geoId;
139
    Sketcher::PointPos posId;
140

141
    // Act
142
    getObject()->geoIdFromShapeType(name, geoId, posId);
143

144
    // Assert
145
    EXPECT_EQ(geoId, Sketcher::GeoEnum::VAxis);
146
    EXPECT_EQ(posId, Sketcher::PointPos::none);
147
}
148

149
TEST_F(SketchObjectTest, testGeoIdFromShapeTypeRootPoint)
150
{
151
    // Arrange
152
    Data::IndexedName name("RootPoint");
153
    int geoId;
154
    Sketcher::PointPos posId;
155

156
    // Act
157
    getObject()->geoIdFromShapeType(name, geoId, posId);
158

159
    // Assert
160
    EXPECT_EQ(geoId, Sketcher::GeoEnum::RtPnt);
161
    EXPECT_EQ(posId, Sketcher::PointPos::start);
162
}
163

164
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionNoUnits1)
165
{
166
    std::string expr = Sketcher::SketchObject::reverseAngleConstraintExpression("180 - 60");
167
    EXPECT_EQ(expr, std::string("60"));
168
}
169

170
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionNoUnits2)
171
{
172
    std::string expr = Sketcher::SketchObject::reverseAngleConstraintExpression("60");
173
    EXPECT_EQ(expr, std::string("180 - (60)"));
174
}
175

176
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionWithUnits1)
177
{
178
    std::string expr = Sketcher::SketchObject::reverseAngleConstraintExpression("180 ° - 60 °");
179
    EXPECT_EQ(expr, std::string("60 °"));
180
}
181

182
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionWithUnits2)
183
{
184
    std::string expr = Sketcher::SketchObject::reverseAngleConstraintExpression("60 °");
185
    EXPECT_EQ(expr, std::string("180 ° - (60 °)"));
186
}
187

188
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionWithUnits3)
189
{
190
    std::string expr = Sketcher::SketchObject::reverseAngleConstraintExpression("60 deg");
191
    EXPECT_EQ(expr, std::string("180 ° - (60 deg)"));
192
}
193

194
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionWithUnits4)
195
{
196
    std::string expr = Sketcher::SketchObject::reverseAngleConstraintExpression("1rad");
197
    EXPECT_EQ(expr, std::string("180 ° - (1rad)"));
198
}
199

200
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionApplyAndReverse1)
201
{
202
    std::string expr = "180";
203
    expr = Sketcher::SketchObject::reverseAngleConstraintExpression(expr);
204
    expr = Sketcher::SketchObject::reverseAngleConstraintExpression(expr);
205
    EXPECT_EQ(expr, std::string("(180)"));
206
}
207

208
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionApplyAndReverse2)
209
{
210
    std::string expr = "(30 + 15) * 2 / 3";
211
    expr = Sketcher::SketchObject::reverseAngleConstraintExpression(expr);
212
    expr = Sketcher::SketchObject::reverseAngleConstraintExpression(expr);
213
    EXPECT_EQ(expr, std::string("((30 + 15) * 2 / 3)"));
214
}
215

216
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionSimple)
217
{
218
    // Arrange
219
    auto constraint = new Sketcher::Constraint();  // Ownership will be transferred to the sketch
220
    constraint->Type = Sketcher::ConstraintType::Angle;
221
    auto id = getObject()->addConstraint(constraint);
222

223
    App::ObjectIdentifier path(App::ObjectIdentifier::parse(getObject(), "Constraints[0]"));
224
    std::shared_ptr<App::Expression> shared_expr(App::Expression::parse(getObject(), "0"));
225
    getObject()->setExpression(path, shared_expr);
226

227
    getObject()->setConstraintExpression(id, "180 - (60)");
228

229
    // Act
230
    getObject()->reverseAngleConstraintToSupplementary(constraint, id);
231

232
    // Assert
233
    EXPECT_EQ(std::string("60"), getObject()->getConstraintExpression(id));
234
}
235

236
TEST_F(SketchObjectTest, testReverseAngleConstraintToSupplementaryExpressionApplyAndReverse)
237
{
238
    // Arrange
239
    auto constraint = new Sketcher::Constraint();  // Ownership will be transferred to the sketch
240
    constraint->Type = Sketcher::ConstraintType::Angle;
241
    auto id = getObject()->addConstraint(constraint);
242

243
    App::ObjectIdentifier path(App::ObjectIdentifier::parse(getObject(), "Constraints[0]"));
244
    std::shared_ptr<App::Expression> shared_expr(App::Expression::parse(getObject(), "0"));
245
    getObject()->setExpression(path, shared_expr);
246

247
    getObject()->setConstraintExpression(id, "32 °");
248

249
    // Act
250
    getObject()->reverseAngleConstraintToSupplementary(constraint, id);
251
    getObject()->reverseAngleConstraintToSupplementary(constraint, id);
252

253
    // Assert
254
    EXPECT_EQ(std::string("32 °"), getObject()->getConstraintExpression(id));
255
}
256

257
TEST_F(SketchObjectTest, testGetElementName)
258
{
259
    // Arrange
260
    Base::Vector3d p1(0.0, 0.0, 0.0), p2(1.0, 0.0, 0.0);
261
    std::unique_ptr<Part::Geometry> geoline(new Part::GeomLineSegment());
262
    static_cast<Part::GeomLineSegment*>(geoline.get())->setPoints(p1, p2);
263
    auto id = getObject()->addGeometry(geoline.get());
264
    long tag;
265
    getObject()->getGeometryId(id, tag);  // We need to look up the tag that got assigned
266
    std::ostringstream oss;
267
    oss << "g" << tag;
268
    auto tagName = oss.str();
269
    getObject()->recomputeFeature();  // or ->execute()
270
    // Act
271
    // unless it's Export, we are really just testing the superclass App::GeoFeature::getElementName
272
    // call.
273
    auto forward_normal_name =
274
        getObject()->getElementName((tagName + ";SKT").c_str(),
275
                                    App::GeoFeature::ElementNameType::Normal);
276
    auto reverse_normal_name =
277
        getObject()->getElementName("Vertex2", App::GeoFeature::ElementNameType::Normal);
278
    auto reverse_export_name =
279
        getObject()->getElementName("Vertex1", App::GeoFeature::ElementNameType::Export);
280
    auto map = getObject()->Shape.getShape().getElementMap();
281
    ASSERT_EQ(map.size(), 3);
282
    EXPECT_STREQ(map[0].name.toString().c_str(), (tagName + ";SKT").c_str());
283
    EXPECT_EQ(map[0].index.toString(), "Edge1");
284
    EXPECT_STREQ(map[1].name.toString().c_str(), (tagName + "v1;SKT").c_str());
285
    EXPECT_EQ(map[1].index.toString(), "Vertex1");
286
    EXPECT_STREQ(map[2].name.toString().c_str(), (tagName + "v2;SKT").c_str());
287
    EXPECT_EQ(map[2].index.toString(), "Vertex2");
288
    // Assert
289
    EXPECT_STREQ(forward_normal_name.newName.c_str(), (";" + tagName + ";SKT.Edge1").c_str());
290
    EXPECT_STREQ(forward_normal_name.oldName.c_str(), "Edge1");
291
    EXPECT_STREQ(reverse_normal_name.newName.c_str(), (";" + tagName + "v2;SKT.Vertex2").c_str());
292
    EXPECT_STREQ(reverse_normal_name.oldName.c_str(), "Vertex2");
293
    EXPECT_STREQ(reverse_export_name.newName.c_str(), (";" + tagName + "v1;SKT.Vertex1").c_str());
294
    EXPECT_STREQ(reverse_export_name.oldName.c_str(), "Vertex1");
295
}
296

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

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

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

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