FreeCAD

Форк
0
/
ViewProvider2DObject.cpp 
350 строк · 13.1 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2004 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

25
#ifndef _PreComp_
26
# include <cfloat>
27

28

29
# include <Inventor/nodes/SoAnnotation.h>
30
# include <Inventor/nodes/SoBaseColor.h>
31
# include <Inventor/nodes/SoDepthBuffer.h>
32
# include <Inventor/nodes/SoDrawStyle.h>
33
# include <Inventor/nodes/SoLineSet.h>
34
# include <Inventor/nodes/SoMaterial.h>
35
# include <Inventor/nodes/SoPickStyle.h>
36
# include <Inventor/nodes/SoSeparator.h>
37
# include <Inventor/nodes/SoVertexProperty.h>
38
#endif
39

40
#include <App/Application.h>
41
#include <Base/Console.h>
42
#include <Base/Parameter.h>
43
#include <Base/Reader.h>
44
#include <Gui/SoFCBoundingBox.h>
45

46
#include "ViewProvider2DObject.h"
47

48

49
using namespace PartGui;
50
using namespace std;
51

52
//**************************************************************************
53
// Construction/Destruction
54

55
const char* ViewProvider2DObjectGrid::GridStyleEnums[]= {"Dashed","Light",nullptr};
56
App::PropertyQuantityConstraint::Constraints ViewProvider2DObjectGrid::GridSizeRange = {0.001,DBL_MAX,1.0};
57

58
PROPERTY_SOURCE(PartGui::ViewProvider2DObjectGrid, PartGui::ViewProvider2DObject)
59

60
ViewProvider2DObjectGrid::ViewProvider2DObjectGrid()
61
{
62
    ADD_PROPERTY_TYPE(ShowGrid,(false),"Grid",(App::PropertyType)(App::Prop_None),"Switch the grid on/off");
63
    ADD_PROPERTY_TYPE(ShowOnlyInEditMode,(true),"Grid",(App::PropertyType)(App::Prop_None),"Show only while in edit mode");
64
    ADD_PROPERTY_TYPE(GridSize,(10.0),"Grid",(App::PropertyType)(App::Prop_None),"Gap size of the grid");
65
    ADD_PROPERTY_TYPE(GridStyle,(0L),"Grid",(App::PropertyType)(App::Prop_None),"Appearance style of the grid");
66
    ADD_PROPERTY_TYPE(TightGrid,(true),"Grid",(App::PropertyType)(App::Prop_None),"Switch the tight grid mode on/off");
67
    ADD_PROPERTY_TYPE(GridSnap,(false),"Grid",(App::PropertyType)(App::Prop_None),"Switch the grid snap on/off");
68
    ADD_PROPERTY_TYPE(GridAutoSize,(true),"Grid",(App::PropertyType)(App::Prop_Hidden),"Autosize grid based on shape boundbox");
69
    ADD_PROPERTY_TYPE(maxNumberOfLines,(10000),"Grid",(App::PropertyType)(App::Prop_None),"Maximum Number of Lines in grid");
70

71
    GridRoot = new SoAnnotation();
72
    GridRoot->ref();
73
    GridRoot->setName("GridRoot");
74
    MinX = MinY = -100;
75
    MaxX = MaxY = 100;
76
    GridStyle.setEnums(GridStyleEnums);
77
    GridSize.setConstraints(&GridSizeRange);
78

79
    pcRoot->addChild(GridRoot);
80

81
    sPixmap = "Part_2D_object";
82
}
83

84
ViewProvider2DObjectGrid::~ViewProvider2DObjectGrid()
85
{
86
     GridRoot->unref();
87
}
88

89

90
// **********************************************************************************
91

92
SoSeparator* ViewProvider2DObjectGrid::createGrid()
93
{
94
    float Step = GridSize.getValue(); //pow(10,floor(log10(Size/5.0)));
95
    float MiX, MaX, MiY, MaY;
96
    if (TightGrid.getValue()) {
97
        MiX = MinX - (MaxX-MinX)*0.2f;
98
        MaX = MaxX + (MaxX-MinX)*0.2f;
99
        MiY = MinY - (MaxY-MinY)*0.2f;
100
        MaY = MaxY + (MaxY-MinY)*0.2f;
101
    }
102
    else {
103
        // make sure that nine of the numbers are exactly zero because log(0)
104
        // is not defined
105
        float xMin = std::abs(MinX) < FLT_EPSILON ? 0.01f : MinX;
106
        float xMax = std::abs(MaxX) < FLT_EPSILON ? 0.01f : MaxX;
107
        float yMin = std::abs(MinY) < FLT_EPSILON ? 0.01f : MinY;
108
        float yMax = std::abs(MaxY) < FLT_EPSILON ? 0.01f : MaxY;
109
        MiX = -exp(ceil(log(std::abs(xMin))));
110
        MiX = std::min<float>(MiX,(float)-exp(ceil(log(std::abs(0.1f*xMax)))));
111
        MaX = exp(ceil(log(std::abs(xMax))));
112
        MaX = std::max<float>(MaX,(float)exp(ceil(log(std::abs(0.1f*xMin)))));
113
        MiY = -exp(ceil(log(std::abs(yMin))));
114
        MiY = std::min<float>(MiY,(float)-exp(ceil(log(std::abs(0.1f*yMax)))));
115
        MaY = exp(ceil(log(std::abs(yMax))));
116
        MaY = std::max<float>(MaY,(float)exp(ceil(log(std::abs(0.1f*yMin)))));
117
    }
118
    //Round the values otherwise grid is not aligned with center
119
    MiX = (floor(MiX / Step)-0.5) * Step;
120
    MaX = (ceil(MaX / Step)+0.5) * Step;
121
    MiY = (floor(MiY / Step)-0.5) * Step;
122
    MaY = (ceil(MaY / Step)+0.5) * Step;
123

124
    double zGrid = 0.0;                     // carpet-grid separation
125

126
    SoGroup *parent = new Gui::SoSkipBoundingGroup();
127
    Gui::coinRemoveAllChildren(GridRoot);
128
    GridRoot->addChild(parent);
129
    SoBaseColor *mycolor;
130
    SoVertexProperty *vts;
131

132

133
    // gridlines
134
    mycolor = new SoBaseColor;
135
    mycolor->rgb.setValue(0.7f, 0.7f ,0.7f);
136
    parent->addChild(mycolor);
137

138
    if (GridStyle.getValue() == 0) {
139
        ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Part");
140
        int pattern = hGrp->GetInt("GridLinePattern", 0x0f0f);
141
        SoDrawStyle* DefaultStyle = new SoDrawStyle;
142
        DefaultStyle->lineWidth = 1;
143
        DefaultStyle->linePattern = pattern;
144
        parent->addChild(DefaultStyle);
145
    }
146
    else {
147
        SoMaterial* LightStyle = new SoMaterial;
148
        LightStyle->transparency = 0.7f;
149
        parent->addChild(LightStyle);
150
    }
151

152
    SoPickStyle* PickStyle = new SoPickStyle;
153
    PickStyle->style = SoPickStyle::UNPICKABLE;
154
    parent->addChild(PickStyle);
155

156
    SoLineSet *grid = new SoLineSet;
157
    vts = new SoVertexProperty;
158
    grid->vertexProperty = vts;
159

160
    // vertical lines
161
    int vlines = static_cast<int>((MaX - MiX) / Step + 0.5f);
162

163
    // horizontal lines
164
    int hlines = static_cast<int>((MaY - MiY) / Step + 0.5f);
165

166
    int lines = vlines + hlines;
167

168
    if (lines > maxNumberOfLines.getValue()) {
169
        Base::Console().Warning("Grid Disabled: Requested number of lines %d is larger than the maximum configured of %d\n."
170
                                "Either increase the 'GridSize' property to a more reasonable value (recommended) or increase the 'maxNumberOfLines' property.\n", lines, maxNumberOfLines.getValue());
171
        parent->addChild(vts);
172
        parent->addChild(grid);
173
        return GridRoot;
174
    }
175

176
    // set the grid indices
177
    grid->numVertices.setNum(lines);
178
    int32_t* vertices = grid->numVertices.startEditing();
179
    for (int i=0; i<lines; i++)
180
        vertices[i] = 2;
181
    grid->numVertices.finishEditing();
182

183
    // set the grid coordinates
184
    vts->vertex.setNum(2*lines);
185
    SbVec3f* vertex_coords = vts->vertex.startEditing();
186

187
    // vertical lines
188
    int i_offset_x = static_cast<int>(MiX / Step);
189
    for (int i=0; i<vlines; i++) {
190
        vertex_coords[2*i].setValue((i+i_offset_x)*Step, MiY, zGrid);
191
        vertex_coords[2*i+1].setValue((i+i_offset_x)*Step, MaY, zGrid);
192
    }
193

194
    // horizontal lines
195
    int i_offset_y = static_cast<int>(MiY / Step);
196
    for (int i=vlines; i<lines; i++) {
197
        vertex_coords[2*i].setValue(MiX, (i-vlines+i_offset_y)*Step, zGrid);
198
        vertex_coords[2*i+1].setValue(MaX, (i-vlines+i_offset_y)*Step, zGrid);
199
    }
200
    vts->vertex.finishEditing();
201

202
    parent->addChild(vts);
203
    parent->addChild(grid);
204

205
    return GridRoot;
206
}
207

208
void ViewProvider2DObjectGrid::updateData(const App::Property* prop)
209
{
210
    ViewProvider2DObject::updateData(prop);
211

212
    if (prop->is<Part::PropertyPartShape>()) {
213
        if (GridAutoSize.getValue()) {
214
            Base::BoundBox3d bbox = static_cast<const Part::PropertyPartShape*>(prop)->getBoundingBox();
215
            if (!bbox.IsValid())
216
                return;
217
            Gui::coinRemoveAllChildren(GridRoot);
218
            Base::Placement place = static_cast<const Part::PropertyPartShape*>(prop)->getComplexData()->getPlacement();
219
            place.invert();
220
            Base::ViewOrthoProjMatrix proj(place.toMatrix());
221
            Base::BoundBox2d bbox2d = bbox.ProjectBox(&proj);
222
            this->MinX = bbox2d.MinX;
223
            this->MaxX = bbox2d.MaxX;
224
            this->MinY = bbox2d.MinY;
225
            this->MaxY = bbox2d.MaxY;
226
        }
227
        if (ShowGrid.getValue() && !(ShowOnlyInEditMode.getValue() && !this->isEditing()) ) {
228
            createGrid();
229
        }
230
        else {
231
            Gui::coinRemoveAllChildren(GridRoot);
232
        }
233
    }
234
}
235

236
void ViewProvider2DObjectGrid::onChanged(const App::Property* prop)
237
{
238
    // call father
239
    ViewProviderPart::onChanged(prop);
240

241
    if (prop == &ShowGrid || prop == &ShowOnlyInEditMode || prop == &Visibility) {
242
        if (ShowGrid.getValue() && ((Visibility.getValue() && !ShowOnlyInEditMode.getValue()) || this->isEditing()))
243
            createGrid();
244
        else
245
            Gui::coinRemoveAllChildren(GridRoot);
246
    }
247

248
    if ((prop == &GridSize) || (prop == &GridStyle) || (prop == &TightGrid)) {
249
        if (ShowGrid.getValue() && !(ShowOnlyInEditMode.getValue() && !this->isEditing())) {
250
            createGrid();
251
        }
252
    }
253
}
254

255
void ViewProvider2DObjectGrid::Restore(Base::XMLReader &reader)
256
{
257
    ViewProviderPart::Restore(reader);
258
}
259

260
void ViewProvider2DObjectGrid::handleChangedPropertyType(Base::XMLReader &reader,
261
                                                         const char * TypeName,
262
                                                         App::Property * prop)
263
{
264
    Base::Type inputType = Base::Type::fromName(TypeName);
265
    if (prop->isDerivedFrom<App::PropertyFloat>() &&
266
        inputType.isDerivedFrom(App::PropertyFloat::getClassTypeId())) {
267
        // Do not directly call the property's Restore method in case the implementation
268
        // has changed. So, create a temporary PropertyFloat object and assign the value.
269
        App::PropertyFloat floatProp;
270
        floatProp.Restore(reader);
271
        static_cast<App::PropertyFloat*>(prop)->setValue(floatProp.getValue());
272
    }
273
    else {
274
        ViewProviderPart::handleChangedPropertyType(reader, TypeName, prop);
275
    }
276
}
277

278
void ViewProvider2DObjectGrid::attach(App::DocumentObject *pcFeat)
279
{
280
    ViewProvider2DObject::attach(pcFeat);
281

282
    if (ShowGrid.getValue() && !(ShowOnlyInEditMode.getValue() && !this->isEditing()))
283
        createGrid();
284
}
285

286
bool ViewProvider2DObjectGrid::setEdit(int)
287
{
288
    if (ShowGrid.getValue())
289
        createGrid();
290

291
    return false;
292
}
293

294
void ViewProvider2DObjectGrid::unsetEdit(int)
295
{
296
    if (ShowGrid.getValue() && ShowOnlyInEditMode.getValue())
297
        Gui::coinRemoveAllChildren(GridRoot);
298
}
299

300
void ViewProvider2DObjectGrid::updateGridExtent(float minx, float maxx, float miny, float maxy)
301
{
302
    bool redraw = false;
303

304
    if (minx < MinX || maxx > MaxX || miny < MinY || maxy > MaxY)
305
        redraw = true;
306

307
    MinX = minx;
308
    MaxX = maxx;
309
    MinY = miny;
310
    MaxY = maxy;
311

312
    if (redraw && ShowGrid.getValue() && !(ShowOnlyInEditMode.getValue() && !this->isEditing()))
313
        createGrid();
314
}
315

316
// -----------------------------------------------------------------------
317

318
PROPERTY_SOURCE(PartGui::ViewProvider2DObject, PartGui::ViewProviderPart)
319

320
ViewProvider2DObject::ViewProvider2DObject() = default;
321

322
ViewProvider2DObject::~ViewProvider2DObject() = default;
323

324
std::vector<std::string> ViewProvider2DObject::getDisplayModes() const
325
{
326
    // get the modes of the father
327
    std::vector<std::string> StrList = ViewProviderGeometryObject::getDisplayModes();
328

329
    // add your own modes
330
    StrList.emplace_back("Flat Lines");
331
    //StrList.push_back("Shaded");
332
    StrList.emplace_back("Wireframe");
333
    StrList.emplace_back("Points");
334

335
    return StrList;
336
}
337

338
const char* ViewProvider2DObject::getDefaultDisplayMode() const
339
{
340
    return "Wireframe";
341
}
342

343
namespace Gui {
344
/// @cond DOXERR
345
PROPERTY_SOURCE_TEMPLATE(PartGui::ViewProvider2DObjectPython, PartGui::ViewProvider2DObject)
346
/// @endcond
347

348
// explicit template instantiation
349
template class PartGuiExport ViewProviderFeaturePythonT<PartGui::ViewProvider2DObject>;
350
}
351

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

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

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

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