FreeCAD

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

23
#include "PreCompiled.h"
24
#ifndef _PreComp_
25
# include <BRepPrimAPI_MakeBox.hxx>
26
# include <Precision.hxx>
27
#endif
28

29
#include <Base/Reader.h>
30

31
#include "FeaturePartBox.h"
32

33

34
using namespace Part;
35

36
PROPERTY_SOURCE(Part::Box, Part::Primitive)
37

38

39
Box::Box()
40
{
41
    ADD_PROPERTY_TYPE(Length,(10.0f),"Box",App::Prop_None,"The length of the box");
42
    ADD_PROPERTY_TYPE(Width ,(10.0f),"Box",App::Prop_None,"The width of the box");
43
    ADD_PROPERTY_TYPE(Height,(10.0f),"Box",App::Prop_None,"The height of the box");
44
}
45

46
short Box::mustExecute() const
47
{
48
    if (Length.isTouched() ||
49
        Height.isTouched() ||
50
        Width.isTouched() )
51
        return 1;
52
    return Primitive::mustExecute();
53
}
54

55
App::DocumentObjectExecReturn *Box::execute()
56
{
57
    double L = Length.getValue();
58
    double W = Width.getValue();
59
    double H = Height.getValue();
60

61
    if (L < Precision::Confusion())
62
        return new App::DocumentObjectExecReturn("Length of box too small");
63

64
    if (W < Precision::Confusion())
65
        return new App::DocumentObjectExecReturn("Width of box too small");
66

67
    if (H < Precision::Confusion())
68
        return new App::DocumentObjectExecReturn("Height of box too small");
69

70
    try {
71
        // Build a box using the dimension attributes
72
        BRepPrimAPI_MakeBox mkBox(L, W, H);
73
        TopoDS_Shape ResultShape = mkBox.Shape();
74
        this->Shape.setValue(ResultShape, false);
75
        return Primitive::execute();
76
    }
77
    catch (Standard_Failure& e) {
78
        return new App::DocumentObjectExecReturn(e.GetMessageString());
79
    }
80
}
81

82
/**
83
 * This method was added for backward-compatibility. In former versions
84
 * of Box we had the properties x,y,z and l,h,w which have changed to
85
 * Location -- as replacement for x,y and z and Length, Height and Width.
86
 */
87
void Box::Restore(Base::XMLReader &reader)
88
{
89
    reader.readElement("Properties");
90
    int Cnt = reader.getAttributeAsInteger("Count");
91
    int transientCount = 0;
92
    if(reader.hasAttribute("TransientCount"))
93
        transientCount = reader.getAttributeAsUnsigned("TransientCount");
94

95
    for (int i=0;i<transientCount; ++i) {
96
        reader.readElement("_Property");
97
        App::Property* prop = getPropertyByName(reader.getAttribute("name"));
98
        if(prop && reader.hasAttribute("status"))
99
            prop->setStatusValue(reader.getAttributeAsUnsigned("status"));
100
    }
101

102
    bool location_xyz = false;
103
    bool location_axis = false;
104
    bool distance_lhw = false;
105
    Base::Placement plm;
106
    App::PropertyDistance x,y,z;
107
    App::PropertyDistance l,w,h;
108
    App::PropertyVector Axis, Location;
109
    Axis.setValue(0.0f,0.0f,1.0f);
110
    for (int i=0 ;i<Cnt;i++) {
111
        reader.readElement("Property");
112
        const char* PropName = reader.getAttribute("name");
113
        const char* TypeName = reader.getAttribute("type");
114
        auto prop = dynamicProps.restore(*this,PropName,TypeName,reader);
115
        if(!prop)
116
            prop = getPropertyByName(PropName);
117

118
        std::bitset<32> status;
119
        if(reader.hasAttribute("status")) {
120
            status = reader.getAttributeAsUnsigned("status");
121
            if(prop)
122
                prop->setStatusValue(status.to_ulong());
123
        }
124
        if (prop && strcmp(prop->getTypeId().getName(), TypeName) == 0) {
125
            if (!prop->testStatus(App::Property::Transient)
126
                    && !status.test(App::Property::Transient)
127
                    && !status.test(App::Property::PropTransient)
128
                    && !(getPropertyType(prop) & App::Prop_Transient))
129
            {
130
                prop->Restore(reader);
131
            }
132
            reader.readEndElement("Property");
133
            continue;
134
        }
135
        if (!prop) {
136
            // in case this comes from an old document we must use the new properties
137
            if (strcmp(PropName, "l") == 0) {
138
                distance_lhw = true;
139
                prop = &l;
140
            }
141
            else if (strcmp(PropName, "w") == 0) {
142
                distance_lhw = true;
143
                prop = &h; // by mistake w was considered as height
144
            }
145
            else if (strcmp(PropName, "h") == 0) {
146
                distance_lhw = true;
147
                prop = &w; // by mistake h was considered as width
148
            }
149
            else if (strcmp(PropName, "x") == 0) {
150
                location_xyz = true;
151
                prop = &x;
152
            }
153
            else if (strcmp(PropName, "y") == 0) {
154
                location_xyz = true;
155
                prop = &y;
156
            }
157
            else if (strcmp(PropName, "z") == 0) {
158
                location_xyz = true;
159
                prop = &z;
160
            }
161
            else if (strcmp(PropName, "Axis") == 0) {
162
                location_axis = true;
163
                prop = &Axis;
164
            }
165
            else if (strcmp(PropName, "Location") == 0) {
166
                location_axis = true;
167
                prop = &Location;
168
            }
169
        }
170
        else if (strcmp(PropName, "Length") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
171
            distance_lhw = true;
172
            prop = &l;
173
        }
174
        else if (strcmp(PropName, "Height") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
175
            distance_lhw = true;
176
            prop = &h;
177
        }
178
        else if (strcmp(PropName, "Width") == 0 && strcmp(TypeName,"PropertyDistance") == 0) {
179
            distance_lhw = true;
180
            prop = &w;
181
        }
182

183
        // NOTE: We must also check the type of the current property because a subclass
184
        // of PropertyContainer might change the type of a property but not its name.
185
        // In this case we would force to read-in a wrong property type and the behaviour
186
        // would be undefined.
187
        std::string tn = TypeName;
188
        if (strcmp(TypeName,"PropertyDistance") == 0) // missing prefix App::
189
            tn = std::string("App::") + tn;
190
        if (prop && strcmp(prop->getTypeId().getName(), tn.c_str()) == 0)
191
            prop->Restore(reader);
192

193
        reader.readEndElement("Property");
194
    }
195

196
    if (distance_lhw) {
197
        this->Length.setValue(l.getValue());
198
        this->Height.setValue(h.getValue());
199
        this->Width.setValue(w.getValue());
200
    }
201

202
    // for 0.7 releases or earlier
203
    if (location_xyz) {
204
        plm.setPosition(Base::Vector3d(x.getValue(),y.getValue(),z.getValue()));
205
        this->Placement.setValue(this->Placement.getValue() * plm);
206
        this->Shape.setStatus(App::Property::User1, true); // override the shape's location later on
207
    }
208
    // for 0.8 releases
209
    else if (location_axis) {
210
        Base::Vector3d d = Axis.getValue();
211
        Base::Vector3d p = Location.getValue();
212
        Base::Rotation rot(Base::Vector3d(0.0,0.0,1.0),
213
                           Base::Vector3d(d.x,d.y,d.z));
214
        plm.setRotation(rot);
215
        plm.setPosition(Base::Vector3d(p.x,p.y,p.z));
216
        this->Placement.setValue(this->Placement.getValue() * plm);
217
        this->Shape.setStatus(App::Property::User1, true); // override the shape's location later on
218
    }
219

220
    reader.readEndElement("Properties");
221
}
222

223
void Box::onChanged(const App::Property* prop)
224
{
225
    if (prop == &Length || prop == &Width || prop == &Height) {
226
        if (!isRestoring()) {
227
            App::DocumentObjectExecReturn *ret = recompute();
228
            delete ret;
229
        }
230
    }
231
    else if (prop == &this->Shape) {
232
        // see Box::Restore
233
        if (this->Shape.testStatus(App::Property::User1)) {
234
            this->Shape.setStatus(App::Property::User1, false);
235
            App::DocumentObjectExecReturn *ret = recompute();
236
            delete ret;
237
            return;
238
        }
239
    }
240
    Part::Primitive::onChanged(prop);
241
}
242

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

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

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

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