FreeCAD

Форк
0
/
Origin.cpp 
236 строк · 8.5 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2015 Stefan Tröger <stefantroeger@gmx.net>              *
3
 *   Copyright (c) 2015 Alexander Golubev (Fat-Zer) <fatzer2@gmail.com>    *
4
 *                                                                         *
5
 *   This file is part of the FreeCAD CAx development system.              *
6
 *                                                                         *
7
 *   This library is free software; you can redistribute it and/or         *
8
 *   modify it under the terms of the GNU Library General Public           *
9
 *   License as published by the Free Software Foundation; either          *
10
 *   version 2 of the License, or (at your option) any later version.      *
11
 *                                                                         *
12
 *   This library  is distributed in the hope that it will be useful,      *
13
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
14
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
15
 *   GNU Library General Public License for more details.                  *
16
 *                                                                         *
17
 *   You should have received a copy of the GNU Library General Public     *
18
 *   License along with this library; see the file COPYING.LIB. If not,    *
19
 *   write to the Free Software Foundation, Inc., 59 Temple Place,         *
20
 *   Suite 330, Boston, MA  02111-1307, USA                                *
21
 *                                                                         *
22
 ***************************************************************************/
23

24
#include "PreCompiled.h"
25

26
#ifndef _PreComp_
27
# include <string>
28
#endif
29

30
#include <App/Document.h>
31
#include <Base/Exception.h>
32
#include <Base/Placement.h>
33

34
#include "Origin.h"
35
#include "OriginFeature.h"
36

37

38
#ifndef M_PI
39
# define M_PI       3.14159265358979323846
40
#endif
41

42
using namespace App;
43

44

45
PROPERTY_SOURCE(App::Origin, App::DocumentObject)
46

47
Origin::Origin() : extension(this) {
48
    ADD_PROPERTY_TYPE ( OriginFeatures, (nullptr), 0, App::Prop_Hidden,
49
            "Axis and baseplanes controlled by the origin" );
50

51
    setStatus(App::NoAutoExpand,true);
52
    extension.initExtension(this);
53
}
54

55

56
Origin::~Origin() = default;
57

58
App::OriginFeature *Origin::getOriginFeature( const char *role) const {
59
    const auto & features = OriginFeatures.getValues ();
60
    auto featIt = std::find_if (features.begin(), features.end(),
61
            [role] (App::DocumentObject *obj) {
62
                return obj->isDerivedFrom ( App::OriginFeature::getClassTypeId () ) &&
63
                    strcmp (static_cast<App::OriginFeature *>(obj)->Role.getValue(), role) == 0;
64
            } );
65
    if (featIt != features.end()) {
66
        return static_cast<App::OriginFeature *>(*featIt);
67
    } else {
68

69
        std::stringstream err;
70
        err << "Origin \"" << getFullName () << "\" doesn't contain feature with role \""
71
            << role << '"';
72
        throw Base::RuntimeError ( err.str().c_str () );
73
    }
74
}
75

76
App::Line *Origin::getAxis( const char *role ) const {
77
    App::OriginFeature *feat = getOriginFeature (role);
78
    if ( feat->isDerivedFrom(App::Line::getClassTypeId () ) ) {
79
        return static_cast<App::Line *> (feat);
80
    } else {
81
        std::stringstream err;
82
        err << "Origin \"" << getFullName () << "\" contains bad Axis object for role \""
83
            << role << '"';
84
        throw Base::RuntimeError ( err.str().c_str () );
85
    }
86
}
87

88
App::Plane *Origin::getPlane( const char *role ) const {
89
    App::OriginFeature *feat = getOriginFeature (role);
90
    if ( feat->isDerivedFrom(App::Plane::getClassTypeId () ) ) {
91
        return static_cast<App::Plane *> (feat);
92
    } else {
93
        std::stringstream err;
94
        err << "Origin \"" << getFullName () << "\" contains bad Plane object for role \""
95
            << role << '"';
96
        throw Base::RuntimeError ( err.str().c_str () );
97
    }
98
}
99

100
bool Origin::hasObject (const DocumentObject *obj) const {
101
    const auto & features = OriginFeatures.getValues ();
102
    return std::find (features.begin(), features.end(), obj) != features.end ();
103
}
104

105
short Origin::mustExecute() const {
106
    if (OriginFeatures.isTouched ()) {
107
        return 1;
108
    } else {
109
        return DocumentObject::mustExecute();
110
    }
111
}
112

113
App::DocumentObjectExecReturn *Origin::execute() {
114
    try { // try to find all base axis and planes in the origin
115
        for (const char* role: AxisRoles) {
116
            App::Line *axis = getAxis (role);
117
            assert(axis);
118
            (void)axis;
119
        }
120
        for (const char* role: PlaneRoles) {
121
            App::Plane *plane = getPlane (role);
122
            assert(plane);
123
            (void)plane;
124
        }
125
    } catch (const Base::Exception &ex) {
126
        setError ();
127
        return new App::DocumentObjectExecReturn ( ex.what () );
128
    }
129

130
    return DocumentObject::execute ();
131
}
132

133
void Origin::setupObject () {
134
    const static struct {
135
        const Base::Type type;
136
        const char *role;
137
	const QString label;
138
        Base::Rotation rot;
139
    }
140
    setupData [] = {
141
        // clang-format off
142
        {App::Line::getClassTypeId(),  AxisRoles[0],  tr("X-axis"),   Base::Rotation()},
143
        {App::Line::getClassTypeId(),  AxisRoles[1],  tr("Y-axis"),   Base::Rotation(Base::Vector3d(1,1,1), M_PI*2/3)},
144
        {App::Line::getClassTypeId(),  AxisRoles[2],  tr("Z-axis"),   Base::Rotation(Base::Vector3d(1,-1,1), M_PI*2/3)},
145
        {App::Plane::getClassTypeId(), PlaneRoles[0], tr("XY-plane"), Base::Rotation()},
146
        {App::Plane::getClassTypeId(), PlaneRoles[1], tr("XZ-plane"), Base::Rotation(1.0, 0.0, 0.0, 1.0 )},
147
        {App::Plane::getClassTypeId(), PlaneRoles[2], tr("YZ-plane"), Base::Rotation(Base::Vector3d(1,1,1), M_PI*2/3)}
148
        // clang-format on
149
    };
150

151
    App::Document *doc = getDocument ();
152

153
    std::vector<App::DocumentObject *> links;
154
    for (auto data: setupData) {
155
        std::string objName = doc->getUniqueObjectName ( data.role );
156
        App::DocumentObject *featureObj = doc->addObject ( data.type.getName(), objName.c_str () );
157

158
        assert ( featureObj && featureObj->isDerivedFrom ( App::OriginFeature::getClassTypeId () ) );
159

160
	QByteArray byteArray = data.label.toUtf8();
161
        featureObj->Label.setValue(byteArray.constData());
162

163
        App::OriginFeature *feature = static_cast <App::OriginFeature *> ( featureObj );
164
        feature->Placement.setValue ( Base::Placement ( Base::Vector3d (), data.rot ) );
165
        feature->Role.setValue ( data.role );
166

167
        links.push_back (feature);
168
    }
169

170
    OriginFeatures.setValues (links);
171
}
172

173
void Origin::unsetupObject () {
174
    const auto &objsLnk = OriginFeatures.getValues ();
175
    // Copy to set to assert we won't call methode more then one time for each object
176
    std::set<App::DocumentObject *> objs (objsLnk.begin(), objsLnk.end());
177
    // Remove all controlled objects
178
    for (auto obj: objs ) {
179
        // Check that previous deletes wasn't inderectly removed one of our objects
180
        const auto &objsLnk = OriginFeatures.getValues ();
181
        if ( std::find(objsLnk.begin(), objsLnk.end(), obj) != objsLnk.end()) {
182
            if ( ! obj->isRemoving() ) {
183
                obj->getDocument()->removeObject (obj->getNameInDocument());
184
            }
185
        }
186
    }
187
}
188

189
// ----------------------------------------------------------------------------
190

191
Origin::OriginExtension::OriginExtension(Origin* obj)
192
    : obj(obj)
193
{
194
    Group.setStatus(Property::Transient, true);
195
}
196

197
void Origin::OriginExtension::initExtension(ExtensionContainer* obj) {
198
    App::GroupExtension::initExtension(obj);
199
}
200

201
bool Origin::OriginExtension::extensionGetSubObject(DocumentObject *&ret, const char *subname,
202
                                                    PyObject **pyobj, Base::Matrix4D *mat, bool, int depth) const {
203
    if (!subname || subname[0] == '\0') {
204
        return false;
205
    }
206

207
    // mapping of object name to role name
208
    std::string name(subname);
209
    for (int i=0; i<3; i++) {
210
        if (name.rfind(Origin::AxisRoles[i], 0) == 0) {
211
            name = Origin::AxisRoles[i];
212
            break;
213
        }
214
        if (name.rfind(Origin::PlaneRoles[i], 0) == 0) {
215
            name = Origin::PlaneRoles[i];
216
            break;
217
        }
218
    }
219

220
    try {
221
        ret = obj->getOriginFeature(name.c_str());
222
        if (!ret)
223
            return false;
224
        const char *dot = strchr(subname, '.');
225
        if (dot)
226
            subname = dot+1;
227
        else
228
            subname = "";
229
        ret = ret->getSubObject(subname, pyobj, mat, true, depth+1);
230
        return true;
231
    }
232
    catch (const Base::Exception& e) {
233
        e.ReportException();
234
        return false;
235
    }
236
}
237

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

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

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

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