FreeCAD

Форк
0
/
QGIViewPart.cpp 
1249 строк · 44.9 Кб
1
/***************************************************************************
2
 *   Copyright (c) 2013 Luke Parry <l.parry@warwick.ac.uk>                 *
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 <cmath>
26

27
#include <QPainterPath>
28
#include <QKeyEvent>
29
#include <qmath.h>
30
#endif// #ifndef _PreComp_
31

32
#include <App/Application.h>
33
#include <App/Document.h>
34
#include <Base/Console.h>
35
#include <Base/Parameter.h>
36
#include <Base/Vector3D.h>
37
#include <Gui/Selection.h>
38
#include <Mod/TechDraw/App/CenterLine.h>
39
#include <Mod/TechDraw/App/Cosmetic.h>
40
#include <Mod/TechDraw/App/DrawComplexSection.h>
41
#include <Mod/TechDraw/App/DrawGeomHatch.h>
42
#include <Mod/TechDraw/App/DrawHatch.h>
43
#include <Mod/TechDraw/App/DrawUtil.h>
44
#include <Mod/TechDraw/App/DrawViewDetail.h>
45
#include <Mod/TechDraw/App/DrawViewPart.h>
46
#include <Mod/TechDraw/App/DrawViewSection.h>
47
#include <Mod/TechDraw/App/Geometry.h>
48

49
#include "DrawGuiUtil.h"
50
#include "MDIViewPage.h"
51
#include "PreferencesGui.h"
52
#include "QGICMark.h"
53
#include "QGICenterLine.h"
54
#include "QGIEdge.h"
55
#include "QGIFace.h"
56
#include "QGIHighlight.h"
57
#include "QGIMatting.h"
58
#include "QGISectionLine.h"
59
#include "QGIVertex.h"
60
#include "QGIViewPart.h"
61
#include "Rez.h"
62
#include "ViewProviderGeomHatch.h"
63
#include "ViewProviderHatch.h"
64
#include "ViewProviderViewPart.h"
65
#include "ZVALUE.h"
66
#include "PathBuilder.h"
67

68
using namespace TechDraw;
69
using namespace TechDrawGui;
70
using namespace std;
71
using DU = DrawUtil;
72

73
#define GEOMETRYEDGE 0
74
#define COSMETICEDGE 1
75
#define CENTERLINE 2
76

77
const float lineScaleFactor = Rez::guiX(1.);// temp fiddle for devel
78

79
QGIViewPart::QGIViewPart()
80
{
81
    setCacheMode(QGraphicsItem::NoCache);
82
    setHandlesChildEvents(false);
83
    setAcceptHoverEvents(true);
84
    setFlag(QGraphicsItem::ItemIsSelectable, true);
85
    setFlag(QGraphicsItem::ItemIsMovable, true);
86
    setFlag(QGraphicsItem::ItemSendsScenePositionChanges, true);
87
    setFlag(QGraphicsItem::ItemSendsGeometryChanges, true);
88
    setFlag(QGraphicsItem::ItemIsFocusable, true);
89

90
    showSection = false;
91
    m_pathBuilder = new PathBuilder(this);
92
    m_dashedLineGenerator = new LineGenerator();
93
}
94

95
QGIViewPart::~QGIViewPart()
96
{
97
    tidy();
98
    delete m_pathBuilder;
99
    delete m_dashedLineGenerator;
100
}
101

102
QVariant QGIViewPart::itemChange(GraphicsItemChange change, const QVariant& value)
103
{
104
    if (change == ItemSelectedHasChanged && scene()) {
105
        //There's nothing special for QGIVP to do when selection changes!
106
    }
107
    else if (change == ItemSceneChange && scene()) {
108
        tidy();
109
    }
110
    return QGIView::itemChange(change, value);
111
}
112

113
bool QGIViewPart::sceneEventFilter(QGraphicsItem *watched, QEvent *event)
114
{
115
    // Base::Console().Message("QGIVP::sceneEventFilter - event: %d watchedtype: %d\n",
116
    //                         event->type(), watched->type() - QGraphicsItem::UserType);
117
    if (event->type() == QEvent::ShortcutOverride) {
118
        // if we accept this event, we should get a regular keystroke event next
119
        // which will be processed by QGVPage/QGVNavStyle keypress logic, but not forwarded to
120
        // Std_Delete
121
        QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
122
        if (keyEvent->key() == Qt::Key_Delete)  {
123
            bool success = removeSelectedCosmetic();
124
            if (success) {
125
                updateView(true);
126
                event->accept();
127
                return true;
128
            }
129
        }
130
    }
131

132
    return QGraphicsItem::sceneEventFilter(watched, event);
133
}
134

135
//! called when a DEL shortcut event is received.  If a cosmetic edge or vertex is
136
//! selected, remove it from the view.
137
bool QGIViewPart::removeSelectedCosmetic() const
138
{
139
    // Base::Console().Message("QGIVP::removeSelectedCosmetic()\n");
140
    char* defaultDocument{nullptr};
141
    std::vector<Gui::SelectionObject> selectionAll = Gui::Selection().getSelectionEx(
142
        defaultDocument, TechDraw::DrawViewPart::getClassTypeId(), Gui::ResolveMode::NoResolve);
143
    if (selectionAll.empty()) {
144
        return false;
145
    }
146
    Gui::SelectionObject firstSelection = selectionAll.front();
147
    App::DocumentObject* firstObject = selectionAll.front().getObject();
148
    std::vector<std::string> subElements = selectionAll.front().getSubNames();
149
    if (subElements.empty()) {
150
        return false;
151
    }
152
    auto dvp = static_cast<TechDraw::DrawViewPart*>(firstObject);
153
    auto subelement = subElements.front();
154
    std::string geomName = DU::getGeomTypeFromName(subelement);
155
    int index = DU::getIndexFromName(subelement);
156
    if (geomName == "Edge") {
157
        TechDraw::BaseGeomPtr base = dvp->getGeomByIndex(index);
158
        if (!base || base->getCosmeticTag().empty()) {
159
            return false;
160
        }
161
        if (base->source() == COSMETICEDGE) {
162
            dvp->removeCosmeticEdge(base->getCosmeticTag());
163
            dvp->refreshCEGeoms();
164
        } else if (base->source() == CENTERLINE) {
165
            dvp->removeCenterLine(base->getCosmeticTag());
166
            dvp->refreshCLGeoms();
167
        } else {
168
            Base::Console().Message("QGIVP::removeSelectedCosmetic - not a CE or a CL\n");
169
            return false;
170
        }
171
    } else if (geomName == "Vertex") {
172
        VertexPtr vert = dvp->getProjVertexByIndex(index);
173
        if (!vert || vert->getCosmeticTag().empty() )  {
174
            return false;
175
        }
176
        dvp->removeCosmeticVertex(vert->getCosmeticTag());
177
        dvp->refreshCVGeoms();
178
    }
179

180
    return true;
181
}
182

183

184
//obs?
185
void QGIViewPart::tidy()
186
{
187
    //Delete any leftover items
188
    for (QList<QGraphicsItem*>::iterator it = deleteItems.begin(); it != deleteItems.end(); ++it) {
189
        delete *it;
190
    }
191
    deleteItems.clear();
192
}
193

194
void QGIViewPart::setViewPartFeature(TechDraw::DrawViewPart* obj)
195
{
196
    if (!obj)
197
        return;
198

199
    setViewFeature(static_cast<TechDraw::DrawView*>(obj));
200
}
201

202
QPainterPath QGIViewPart::drawPainterPath(TechDraw::BaseGeomPtr baseGeom) const
203
{
204
    double rot = getViewObject()->Rotation.getValue();
205
    return m_pathBuilder->geomToPainterPath(baseGeom, rot);
206
}
207

208
void QGIViewPart::updateView(bool update)
209
{
210
    // Base::Console().Message("QGIVP::updateView() - %s\n", getViewObject()->getNameInDocument());
211
    auto viewPart(dynamic_cast<TechDraw::DrawViewPart*>(getViewObject()));
212
    if (!viewPart)
213
        return;
214
    auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
215
    if (!vp)
216
        return;
217

218
    if (update)
219
        draw();
220
    QGIView::updateView(update);
221
}
222

223
void QGIViewPart::draw()
224
{
225
    auto viewPart(dynamic_cast<TechDraw::DrawViewPart*>(getViewObject()));
226
    if (!viewPart) {
227
        return;
228
    }
229

230
    auto doc = viewPart->getDocument();
231
    if (!doc || doc->testStatus(App::Document::Status::Restoring)) {
232
        // if the document is still restoring, we may not have all the information
233
        // we need to draw the source objects, so we wait until restore is finished.
234
        // Base::Console().Message("QGIVP::draw - document is restoring, do not draw\n");
235
        return;
236
    }
237

238
    if (!isVisible())
239
        return;
240

241
    drawViewPart();
242
    drawAllHighlights();
243
    drawMatting();
244
    //this is old C/L
245
    drawCenterLines(true);//have to draw centerlines after border to get size correct.
246
    drawAllSectionLines();//same for section lines
247
}
248

249
void QGIViewPart::drawViewPart()
250
{
251
    auto viewPart(dynamic_cast<TechDraw::DrawViewPart*>(getViewObject()));
252
    if (!viewPart)
253
        return;
254
    //    Base::Console().Message("QGIVP::DVP() - %s / %s\n", viewPart->getNameInDocument(), viewPart->Label.getValue());
255
    if (!viewPart->hasGeometry()) {
256
        removePrimitives();//clean the slate
257
        removeDecorations();
258
        return;
259
    }
260

261
    auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
262
    if (!vp)
263
        return;
264

265
    prepareGeometryChange();
266
    removePrimitives();//clean the slate
267
    removeDecorations();
268

269
    if (viewPart->handleFaces() && !viewPart->CoarseView.getValue()) {
270
        drawAllFaces();
271
    }
272

273
    drawAllEdges();
274

275
    drawAllVertexes();
276
}
277

278
void QGIViewPart::drawAllFaces(void)
279
{
280
    // dvp already validated
281
    auto dvp(static_cast<TechDraw::DrawViewPart*>(getViewObject()));
282

283
    QColor faceColor;
284
    auto vpp = dynamic_cast<ViewProviderViewPart *>(getViewProvider(getViewObject()));
285
    if (vpp) {
286
        faceColor = vpp->FaceColor.getValue().asValue<QColor>();
287
        faceColor.setAlpha((100 - vpp->FaceTransparency.getValue())*255/100);
288
    }
289

290
    std::vector<TechDraw::DrawHatch*> regularHatches = dvp->getHatches();
291
    std::vector<TechDraw::DrawGeomHatch*> geomHatches = dvp->getGeomHatches();
292
    const std::vector<TechDraw::FacePtr>& faceGeoms = dvp->getFaceGeometry();
293
    int iFace(0);
294
    for (auto& face : faceGeoms) {
295
        QGIFace* newFace = drawFace(face, iFace);
296
        if (faceColor.isValid()) {
297
            newFace->setFillColor(faceColor);
298
            newFace->setFillMode(faceColor.alpha() ? QGIFace::PlainFill : QGIFace::NoFill);
299
        }
300

301
        TechDraw::DrawHatch* fHatch = faceIsHatched(iFace, regularHatches);
302
        TechDraw::DrawGeomHatch* fGeom = faceIsGeomHatched(iFace, geomHatches);
303
        if (fGeom) {
304
            // geometric hatch (from PAT hatch specification)
305
            newFace->isHatched(true);
306
            newFace->setFillMode(QGIFace::GeomHatchFill);
307
            std::vector<LineSet> lineSets = fGeom->getTrimmedLines(iFace);
308
            if (!lineSets.empty()) {
309
                // this face has geometric hatch lines
310
                newFace->clearLineSets();
311
                for (auto& ls : lineSets) {
312
                    newFace->addLineSet(ls);
313
                }
314
            }
315
            double hatchScale = fGeom->ScalePattern.getValue();
316
            if (hatchScale > 0.0) {
317
                newFace->setHatchScale(fGeom->ScalePattern.getValue());
318
            }
319
            newFace->setHatchRotation(fGeom->PatternRotation.getValue());
320
            newFace->setHatchOffset(fGeom->PatternOffset.getValue());
321
            newFace->setHatchFile(fGeom->PatIncluded.getValue());
322
            Gui::ViewProvider* gvp = QGIView::getViewProvider(fGeom);
323
            ViewProviderGeomHatch* geomVp = dynamic_cast<ViewProviderGeomHatch*>(gvp);
324
            if (geomVp) {
325
                newFace->setHatchColor(geomVp->ColorPattern.getValue());
326
                newFace->setLineWeight(geomVp->WeightPattern.getValue());
327
            }
328
        } else if (fHatch) {
329
            // svg or bitmap hatch
330
            newFace->isHatched(true);
331
            if (!fHatch->SvgIncluded.isEmpty()) {
332
                newFace->setHatchFile(fHatch->SvgIncluded.getValue());
333
            }
334
            if (fHatch->isSvgHatch()) {
335
                // svg tile hatch
336
                newFace->setFillMode(QGIFace::SvgFill);
337
                newFace->hideSvg(false);
338
            } else {
339
                //bitmap hatch
340
                newFace->setFillMode(QGIFace::BitmapFill);
341
            }
342

343
            // get the properties from the hatch viewprovider
344
            Gui::ViewProvider* gvp = QGIView::getViewProvider(fHatch);
345
            ViewProviderHatch* hatchVp = dynamic_cast<ViewProviderHatch*>(gvp);
346
            if (hatchVp) {
347
                if (hatchVp->HatchScale.getValue() > 0.0) {
348
                    newFace->setHatchScale(hatchVp->HatchScale.getValue());
349
                }
350
                newFace->setHatchColor(hatchVp->HatchColor.getValue());
351
                newFace->setHatchRotation(hatchVp->HatchRotation.getValue());
352
                newFace->setHatchOffset(hatchVp->HatchOffset.getValue());
353
            }
354
        }
355

356
        newFace->setDrawEdges(prefFaceEdges());
357
        newFace->setZValue(ZVALUE::FACE);
358
        newFace->setPrettyNormal();
359
        newFace->draw();
360
        iFace++;
361
    }
362
}
363

364
void QGIViewPart::drawAllEdges()
365
{
366
    // dvp and vp already validated
367
    auto dvp(static_cast<TechDraw::DrawViewPart*>(getViewObject()));
368
    auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
369

370
    const TechDraw::BaseGeomPtrVector& geoms = dvp->getEdgeGeometry();
371
    TechDraw::BaseGeomPtrVector::const_iterator itGeom = geoms.begin();
372
    QGIEdge* item;
373
    for (int iEdge = 0; itGeom != geoms.end(); itGeom++, iEdge++) {
374
        bool showItem = true;
375
        if (!showThisEdge(*itGeom)) {
376
            continue;
377
        }
378

379
        item = new QGIEdge(iEdge);
380
        addToGroup(item);      //item is created at scene(0, 0), not group(0, 0)
381
        item->setPath(drawPainterPath(*itGeom));
382
        item->setSource((*itGeom)->source());
383

384
        item->setNormalColor(PreferencesGui::getAccessibleQColor(PreferencesGui::normalQColor()));
385
        if ((*itGeom)->getCosmetic()) {
386
            // cosmetic edge - format appropriately
387
            int source = (*itGeom)->source();
388
            if (source == COSMETICEDGE) {
389
                std::string cTag = (*itGeom)->getCosmeticTag();
390
                showItem = formatGeomFromCosmetic(cTag, item);
391
            }
392
            else if (source == CENTERLINE) {
393
                std::string cTag = (*itGeom)->getCosmeticTag();
394
                showItem = formatGeomFromCenterLine(cTag, item);
395
            }
396
            else {
397
                Base::Console().Message("QGIVP::drawVP - cosmetic edge: %d is confused - source: %d\n",
398
                                        iEdge, source);
399
            }
400
        } else {
401
            // geometry edge - apply format if applicable
402
            TechDraw::GeomFormat* gf = dvp->getGeomFormatBySelection(iEdge);
403
            if (gf) {
404
                App::Color  color = Preferences::getAccessibleColor(gf->m_format.m_color);
405
                item->setNormalColor(color.asValue<QColor>());
406
                int lineNumber = gf->m_format.getLineNumber();
407
                int qtStyle = gf->m_format.m_style;
408
                item->setLinePen(m_dashedLineGenerator->getBestPen(lineNumber, (Qt::PenStyle)qtStyle,
409
                                                     gf->m_format.m_weight));
410
                // but we need to actually draw the lines in QGScene coords (0.1 mm).
411
                item->setWidth(Rez::guiX(gf->m_format.m_weight));
412
                showItem = gf->m_format.m_visible;
413
            } else {
414
                // unformatted line, draw as continuous line
415
                item->setLinePen(m_dashedLineGenerator->getLinePen(1, vp->LineWidth.getValue()));
416
                item->setWidth(Rez::guiX(vp->LineWidth.getValue()));
417
            }
418
        }
419

420
        if (!(*itGeom)->getHlrVisible()) {
421
            item->setLinePen(m_dashedLineGenerator->getLinePen(Preferences::HiddenLineStyle(),
422
                                                               vp->LineWidth.getValue()));
423
            item->setWidth(Rez::guiX(vp->HiddenWidth.getValue()));   //thin
424
            item->setZValue(ZVALUE::HIDEDGE);
425
        }
426

427
        if ((*itGeom)->getClassOfEdge()  == ecUVISO) {
428
            // we don't have a style option for iso-parametric lines so draw continuous
429
            item->setLinePen(m_dashedLineGenerator->getLinePen(1, vp->IsoWidth.getValue()));
430
            item->setWidth(Rez::guiX(vp->IsoWidth.getValue()));   //graphic
431
        }
432

433
        item->setPos(0.0, 0.0);//now at group(0, 0)
434
        item->setZValue(ZVALUE::EDGE);
435
        item->setPrettyNormal();
436

437
        if (!vp->ShowAllEdges.getValue() && !showItem) {
438
             //view level "show" status  && individual edge "show" status
439
             item->hide();
440
        }
441

442
        //debug a path
443
        //            QPainterPath edgePath=drawPainterPath(*itGeom);
444
        //            std::stringstream edgeId;
445
        //            edgeId << "QGIVP.edgePath" << i;
446
        //            dumpPath(edgeId.str().c_str(), edgePath);
447
    }
448
}
449

450
void QGIViewPart::drawAllVertexes()
451
{
452
    // dvp and vp already validated
453
    auto dvp(static_cast<TechDraw::DrawViewPart*>(getViewObject()));
454
    auto vp(static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject())));
455

456
    float lineWidth = vp->LineWidth.getValue() * lineScaleFactor;     //thick
457
    double vertexScaleFactor = Preferences::getPreferenceGroup("General")->GetFloat("VertexScale", 3.0);
458
    QColor vertexColor = PreferencesGui::getAccessibleQColor(PreferencesGui::vertexQColor());
459

460
    const std::vector<TechDraw::VertexPtr>& verts = dvp->getVertexGeometry();
461
    std::vector<TechDraw::VertexPtr>::const_iterator vert = verts.begin();
462
    for (int i = 0; vert != verts.end(); ++vert, i++) {
463
        if ((*vert)->isCenter()) {
464
            if (showCenterMarks()) {
465
                QGICMark* cmItem = new QGICMark(i);
466
                addToGroup(cmItem);
467
                cmItem->setPos(Rez::guiX((*vert)->x()), Rez::guiX((*vert)->y()));
468
                cmItem->setThick(0.5 * lineWidth);//need minimum?
469
                cmItem->setSize(lineWidth * vertexScaleFactor * vp->CenterScale.getValue());
470
                cmItem->setPrettyNormal();
471
                cmItem->setZValue(ZVALUE::VERTEX);
472
            }
473
        } else {
474
            //regular Vertex
475
            if (showVertices()) {
476
                QGIVertex* item = new QGIVertex(i);
477
                addToGroup(item);
478
                item->setPos(Rez::guiX((*vert)->x()), Rez::guiX((*vert)->y()));
479
                item->setNormalColor(vertexColor);
480
                item->setFillColor(vertexColor);
481
                item->setRadius(lineWidth * vertexScaleFactor);
482
                item->setPrettyNormal();
483
                item->setZValue(ZVALUE::VERTEX);
484
            }
485
        }
486
    }
487
}
488

489
bool QGIViewPart::showThisEdge(BaseGeomPtr geom)
490
{
491
    // dvp and vp already validated
492
    auto dvp(static_cast<TechDraw::DrawViewPart*>(getViewObject()));
493

494
    if (geom->getHlrVisible()) {
495
        if ((geom->getClassOfEdge()  == ecHARD) || (geom->getClassOfEdge()  == ecOUTLINE)
496
            || ((geom->getClassOfEdge()  == ecSMOOTH) && dvp->SmoothVisible.getValue())
497
            || ((geom->getClassOfEdge()  == ecSEAM) && dvp->SeamVisible.getValue())
498
            || ((geom->getClassOfEdge()  == ecUVISO) && dvp->IsoVisible.getValue())) {
499
            return true;
500
        }
501
    } else {
502
        if (((geom->getClassOfEdge()  == ecHARD) && (dvp->HardHidden.getValue()))
503
            || ((geom->getClassOfEdge()  == ecOUTLINE) && (dvp->HardHidden.getValue()))
504
            || ((geom->getClassOfEdge()  == ecSMOOTH) && (dvp->SmoothHidden.getValue()))
505
            || ((geom->getClassOfEdge()  == ecSEAM) && (dvp->SeamHidden.getValue()))
506
            || ((geom->getClassOfEdge()  == ecUVISO) && (dvp->IsoHidden.getValue()))) {
507
            return true;
508
        }
509
    }
510

511
    return false;
512
}
513

514
// returns true if vertex dots should be shown
515
bool QGIViewPart::showVertices()
516
{
517
    // dvp and vp already validated
518
    auto dvp(static_cast<TechDraw::DrawViewPart*>(getViewObject()));
519

520
    if (dvp->CoarseView.getValue()) {
521
        // never show vertices in CoarseView
522
        return false;
523
    }
524
    if (!getFrameState()) {
525
        // frames are off, don't show vertices
526
        return false;
527
    }
528

529
    return true;
530
}
531

532

533
// returns true if arc center marks should be shown
534
bool QGIViewPart::showCenterMarks()
535
{
536
    // dvp and vp already validated
537
    auto dvp(static_cast<TechDraw::DrawViewPart*>(getViewObject()));
538
    auto vp(static_cast<ViewProviderViewPart*>(getViewProvider(dvp)));
539

540
    if (!vp->ArcCenterMarks.getValue()) {
541
        // no center marks if view property is false
542
        return false;
543
    }
544

545
    if (getFrameState()) {
546
        // frames are on and view property is true
547
        return true;
548
    }
549

550
    if (prefPrintCenters()) {
551
        // frames are off, view property is true and Print Center Marks is true
552
        return true;
553
    }
554

555
    return false;
556
}
557

558

559
bool QGIViewPart::formatGeomFromCosmetic(std::string cTag, QGIEdge* item)
560
{
561
    //    Base::Console().Message("QGIVP::formatGeomFromCosmetic(%s)\n", cTag.c_str());
562
    bool result = true;
563
    auto partFeat(dynamic_cast<TechDraw::DrawViewPart*>(getViewObject()));
564
    TechDraw::CosmeticEdge* ce = partFeat ? partFeat->getCosmeticEdge(cTag) : nullptr;
565
    if (ce) {
566
        App::Color color = Preferences::getAccessibleColor(ce->m_format.m_color);
567
        item->setNormalColor(color.asValue<QColor>());
568
        item->setLinePen(m_dashedLineGenerator->getBestPen(ce->m_format.getLineNumber(),
569
                                                     (Qt::PenStyle)ce->m_format.m_style,
570
                                                     ce->m_format.m_weight));
571
        item->setWidth(Rez::guiX(ce->m_format.m_weight));
572
        result = ce->m_format.m_visible;
573
    }
574
    return result;
575
}
576

577

578
bool QGIViewPart::formatGeomFromCenterLine(std::string cTag, QGIEdge* item)
579
{
580
//    Base::Console().Message("QGIVP::formatGeomFromCenterLine()\n");
581
    bool result = true;
582
    auto partFeat(dynamic_cast<TechDraw::DrawViewPart*>(getViewObject()));
583
    TechDraw::CenterLine* cl = partFeat ? partFeat->getCenterLine(cTag) : nullptr;
584
    if (cl) {
585
        App::Color color = Preferences::getAccessibleColor(cl->m_format.m_color);
586
        item->setNormalColor(color.asValue<QColor>());
587
        item->setLinePen(m_dashedLineGenerator->getBestPen(cl->m_format.getLineNumber(),
588
                                                     (Qt::PenStyle)cl->m_format.m_style,
589
                                                     cl->m_format.m_weight));
590
        item->setWidth(Rez::guiX(cl->m_format.m_weight));
591
        result = cl->m_format.m_visible;
592
    }
593
    return result;
594
}
595

596
QGIFace* QGIViewPart::drawFace(TechDraw::FacePtr f, int idx)
597
{
598
    //    Base::Console().Message("QGIVP::drawFace - %d\n", idx);
599
    std::vector<TechDraw::Wire*> fWires = f->wires;
600
    QPainterPath facePath;
601
    for (std::vector<TechDraw::Wire*>::iterator wire = fWires.begin(); wire != fWires.end();
602
         ++wire) {
603
        TechDraw::BaseGeomPtrVector geoms = (*wire)->geoms;
604
        if (geoms.empty())
605
            continue;
606

607
        TechDraw::BaseGeomPtr firstGeom = geoms.front();
608
        QPainterPath wirePath;
609
        //QPointF startPoint(firstGeom->getStartPoint().x, firstGeom->getStartPoint().y);
610
        //wirePath.moveTo(startPoint);
611
        QPainterPath firstSeg = drawPainterPath(firstGeom);
612
        wirePath.connectPath(firstSeg);
613
        for (TechDraw::BaseGeomPtrVector::iterator edge = ((*wire)->geoms.begin()) + 1;
614
             edge != (*wire)->geoms.end(); ++edge) {
615
            QPainterPath edgePath = drawPainterPath(*edge);
616
            //handle section faces differently
617
            if (idx == -1) {
618
                QPointF wEnd = wirePath.currentPosition();
619
                auto element = edgePath.elementAt(0);
620
                QPointF eStart(element.x, element.y);
621
                QPointF eEnd = edgePath.currentPosition();
622
                QPointF sVec = wEnd - eStart;
623
                QPointF eVec = wEnd - eEnd;
624
                double sDist2 = sVec.x() * sVec.x() + sVec.y() * sVec.y();
625
                double eDist2 = eVec.x() * eVec.x() + eVec.y() * eVec.y();
626
                if (sDist2 > eDist2) {
627
                    edgePath = edgePath.toReversed();
628
                }
629
            }
630
            wirePath.connectPath(edgePath);
631
        }
632
        //        dumpPath("wirePath:", wirePath);
633
        facePath.addPath(wirePath);
634
    }
635
    facePath.setFillRule(Qt::OddEvenFill);
636

637
    QGIFace* gFace = new QGIFace(idx);
638
    addToGroup(gFace);
639
    gFace->setPos(0.0, 0.0);
640
    gFace->setOutline(facePath);
641
    //debug a path
642
    //std::stringstream faceId;
643
    //faceId << "facePath " << idx;
644
    //dumpPath(faceId.str().c_str(), facePath);
645

646
    return gFace;
647
}
648

649
//! Remove all existing QGIPrimPath items(Vertex, Edge, Face)
650
//note this triggers scene selectionChanged signal if vertex/edge/face is selected
651
void QGIViewPart::removePrimitives()
652
{
653
    QList<QGraphicsItem*> children = childItems();
654
    MDIViewPage* mdi = getMDIViewPage();
655
    if (mdi) {
656
        getMDIViewPage()->blockSceneSelection(true);
657
    }
658
    for (auto& c : children) {
659
        QGIPrimPath* prim = dynamic_cast<QGIPrimPath*>(c);
660
        if (prim) {
661
            prim->hide();
662
            scene()->removeItem(prim);
663
            delete prim;
664
        }
665
    }
666
    if (mdi) {
667
        getMDIViewPage()->blockSceneSelection(false);
668
    }
669
}
670

671
//! Remove all existing QGIDecoration items(SectionLine, SectionMark, ...)
672
void QGIViewPart::removeDecorations()
673
{
674
    QList<QGraphicsItem*> children = childItems();
675
    for (auto& c : children) {
676
        QGIDecoration* decor = dynamic_cast<QGIDecoration*>(c);
677
        QGIMatting* mat = dynamic_cast<QGIMatting*>(c);
678
        if (decor) {
679
            decor->hide();
680
            scene()->removeItem(decor);
681
            delete decor;
682
        }
683
        else if (mat) {
684
            mat->hide();
685
            scene()->removeItem(mat);
686
            delete mat;
687
        }
688
    }
689
}
690

691
void QGIViewPart::drawAllSectionLines()
692
{
693
    TechDraw::DrawViewPart* viewPart = static_cast<TechDraw::DrawViewPart*>(getViewObject());
694
    if (!viewPart)
695
        return;
696

697
    auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
698
    if (!vp)
699
        return;
700
    if (vp->ShowSectionLine.getValue()) {
701
        auto refs = viewPart->getSectionRefs();
702
        for (auto& r : refs) {
703
            if (r->isDerivedFrom(DrawComplexSection::getClassTypeId())) {
704
                drawComplexSectionLine(r, true);
705
            }
706
            else {
707
                drawSectionLine(r, true);
708
            }
709
        }
710
    }
711
}
712

713
void QGIViewPart::drawSectionLine(TechDraw::DrawViewSection* viewSection, bool b)
714
{
715
//    Base::Console().Message("QGIVP::drawSectionLine()\n");
716
    TechDraw::DrawViewPart* viewPart = static_cast<TechDraw::DrawViewPart*>(getViewObject());
717
    if (!viewPart)
718
        return;
719
    if (!viewSection)
720
        return;
721

722
    if (!viewSection->hasGeometry())
723
        return;
724

725
    auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
726
    if (!vp) {
727
        return;
728
    }
729

730
    if (b) {
731
        //find the ends of the section line
732
        double scale = viewPart->getScale();
733
        std::pair<Base::Vector3d, Base::Vector3d> sLineEnds = viewSection->sectionLineEnds();
734
        Base::Vector3d l1 = Rez::guiX(sLineEnds.first) * scale;
735
        Base::Vector3d l2 = Rez::guiX(sLineEnds.second) * scale;
736
        if (l1.IsEqual(l2, EWTOLERANCE) ) {
737
            Base::Console().Message("QGIVP::drawSectionLine - line endpoints are equal. No section line created.\n");
738
            return;
739
        }
740

741
        QGISectionLine* sectionLine = new QGISectionLine();
742
        addToGroup(sectionLine);
743
        sectionLine->setSymbol(const_cast<char*>(viewSection->SectionSymbol.getValue()));
744
        App::Color color = Preferences::getAccessibleColor(vp->SectionLineColor.getValue());
745
        sectionLine->setSectionColor(color.asValue<QColor>());
746
        sectionLine->setPathMode(false);
747

748
        //make the section line a little longer
749
        double fudge = 2.0 * Preferences::dimFontSizeMM();
750
        Base::Vector3d lineDir = l2 - l1;
751
        lineDir.Normalize();
752
        sectionLine->setEnds(l1 - lineDir * Rez::guiX(fudge), l2 + lineDir * Rez::guiX(fudge));
753

754
        //which way do the arrows point?
755
        Base::Vector3d arrowDir = viewSection->SectionNormal.getValue();
756
        arrowDir = -viewPart->projectPoint(arrowDir);      //arrows point reverse of sectionNormal
757
        sectionLine->setDirection(arrowDir.x, -arrowDir.y);//3d direction needs Y inversion
758

759
        if (vp->SectionLineMarks.getValue()) {
760
            ChangePointVector points = viewSection->getChangePointsFromSectionLine();
761
            //extend the changePoint locations to match the fudged section line ends
762
            QPointF location0 = points.front().getLocation() * scale;
763
            location0 = location0 - DU::toQPointF(lineDir) * fudge;
764
            QPointF location1 = points.back().getLocation() * scale;
765
            location1 = location1 + DU::toQPointF(lineDir) * fudge;
766
            //change points have Rez::guiX applied in sectionLine
767
            points.front().setLocation(location0);
768
            points.back().setLocation(location1);
769
            sectionLine->setChangePoints(points);
770
        }
771
        else {
772
            sectionLine->clearChangePoints();
773
        }
774

775
        //set the general parameters
776
        sectionLine->setPos(0.0, 0.0);
777
        // sectionLines are typically ISO 8 (long dash, short dash) or ISO 4 (long dash, dot)
778
        sectionLine->setLinePen(
779
                m_dashedLineGenerator->getLinePen((size_t)vp->SectionLineStyle.getValue(),
780
                                                    vp->HiddenWidth.getValue()));
781
        sectionLine->setWidth(Rez::guiX(vp->HiddenWidth.getValue()));
782
        double fontSize = Preferences::dimFontSizeMM();
783
        sectionLine->setFont(getFont(), fontSize);
784
        sectionLine->setZValue(ZVALUE::SECTIONLINE);
785
        sectionLine->setRotation(-viewPart->Rotation.getValue());
786
        sectionLine->draw();
787
    }
788
}
789

790
void QGIViewPart::drawComplexSectionLine(TechDraw::DrawViewSection* viewSection, bool b)
791
{
792
    Q_UNUSED(b);
793

794
    TechDraw::DrawViewPart* viewPart = static_cast<TechDraw::DrawViewPart*>(getViewObject());
795
    if (!viewPart)
796
        return;
797
    if (!viewSection)
798
        return;
799
    auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
800
    if (!vp) {
801
        return;
802
    }
803

804
    auto dcs = static_cast<DrawComplexSection*>(viewSection);
805
    std::pair<Base::Vector3d, Base::Vector3d> ends = dcs->sectionLineEnds();
806
    Base::Vector3d vStart = Rez::guiX(ends.first);//already scaled by dcs
807
    Base::Vector3d vEnd = Rez::guiX(ends.second);
808
    if (vStart.IsEqual(vEnd, EWTOLERANCE) ) {
809
        Base::Console().Message("QGIVP::drawComplexSectionLine - line endpoints are equal. No section line created.\n");
810
        return;
811
    }
812

813

814
    BaseGeomPtrVector edges = dcs->makeSectionLineGeometry();
815
    QPainterPath wirePath;
816
    QPainterPath firstSeg = drawPainterPath(edges.front());
817
    wirePath.connectPath(firstSeg);
818
    int edgeCount = edges.size();
819
    //NOTE: if the edges are not in nose to tail order, Qt will insert extra segments
820
    //that will overlap the segments we add. for interrupted line styles, this
821
    //will make the line look continuous.  This is prevented in
822
    //DrawComplexSection::makeSectionLineGeometry by calling makeNoseToTailWire
823
    for (int i = 1; i < edgeCount; i++) {
824
        QPainterPath edgePath = drawPainterPath(edges.at(i));
825
        wirePath.connectPath(edgePath);
826
    }
827

828

829
    QGISectionLine* sectionLine = new QGISectionLine();
830
    addToGroup(sectionLine);
831
    sectionLine->setSymbol(const_cast<char*>(viewSection->SectionSymbol.getValue()));
832
    App::Color color = Preferences::getAccessibleColor(vp->SectionLineColor.getValue());
833
    sectionLine->setSectionColor(color.asValue<QColor>());
834
    sectionLine->setPathMode(true);
835
    sectionLine->setPath(wirePath);
836
    sectionLine->setEnds(vStart, vEnd);
837
    if (vp->SectionLineMarks.getValue()) {
838
        sectionLine->setChangePoints(dcs->getChangePointsFromSectionLine());
839
    }
840
    else {
841
        sectionLine->clearChangePoints();
842
    }
843
    if (dcs->ProjectionStrategy.isValue("Offset")) {
844
        Base::Vector3d arrowDirOffset = viewSection->SectionNormal.getValue();
845
        arrowDirOffset =
846
            -viewPart->projectPoint(arrowDirOffset);//arrows are opposite section normal
847
        sectionLine->setDirection(arrowDirOffset.x, -arrowDirOffset.y);//invert y for Qt
848
    }
849
    else {
850
        std::pair<Base::Vector3d, Base::Vector3d> dirsAligned = dcs->sectionArrowDirs();
851
        dirsAligned.first = DrawUtil::invertY(dirsAligned.first);
852
        dirsAligned.second = DrawUtil::invertY(dirsAligned.second);
853
        sectionLine->setArrowDirections(dirsAligned.first, dirsAligned.second);
854
    }
855

856
    //set the general parameters
857
    sectionLine->setPos(0.0, 0.0);
858
    // sectionLines are typically ISO 8 (long dash, short dash) or ISO 4 (long dash, dot)
859
    sectionLine->setLinePen(
860
                            m_dashedLineGenerator->getLinePen((size_t)vp->SectionLineStyle.getValue(),
861
                                 vp->HiddenWidth.getValue()));
862
    sectionLine->setWidth(Rez::guiX(vp->HiddenWidth.getValue()));
863
    double fontSize = Preferences::dimFontSizeMM();
864
    sectionLine->setFont(getFont(), fontSize);
865
    sectionLine->setZValue(ZVALUE::SECTIONLINE);
866
    sectionLine->setRotation(-viewPart->Rotation.getValue());
867
    sectionLine->draw();
868
}
869

870
//TODO: use Cosmetic::CenterLine object for this to make it usable for dims.
871
// these are the view center lines (ie x,y axes)
872
void QGIViewPart::drawCenterLines(bool b)
873
{
874
    TechDraw::DrawViewPart* viewPart = dynamic_cast<TechDraw::DrawViewPart*>(getViewObject());
875
    if (!viewPart)
876
        return;
877

878
    auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
879
    if (!vp)
880
        return;
881

882
    if (b) {
883
        bool horiz = vp->HorizCenterLine.getValue();
884
        bool vert = vp->VertCenterLine.getValue();
885

886
        QGICenterLine* centerLine;
887
        double sectionSpan;
888
        double sectionFudge = Rez::guiX(10.0);
889
        double xVal, yVal;
890
        if (horiz) {
891
            centerLine = new QGICenterLine();
892
            addToGroup(centerLine);
893
            centerLine->setPos(0.0, 0.0);
894
            double width = Rez::guiX(viewPart->getBoxX());
895
            sectionSpan = width + sectionFudge;
896
            xVal = sectionSpan / 2.0;
897
            yVal = 0.0;
898
            centerLine->setIntersection(horiz && vert);
899
            centerLine->setBounds(-xVal, -yVal, xVal, yVal);
900
            centerLine->setLinePen(m_dashedLineGenerator->getLinePen((size_t)Preferences::CenterLineStyle(),
901
                                  vp->HiddenWidth.getValue()));
902
            centerLine->setWidth(Rez::guiX(vp->HiddenWidth.getValue()));
903
            centerLine->setColor(Qt::green);
904
            centerLine->setZValue(ZVALUE::SECTIONLINE);
905
            centerLine->draw();
906
        }
907
        if (vert) {
908
            centerLine = new QGICenterLine();
909
            addToGroup(centerLine);
910
            centerLine->setPos(0.0, 0.0);
911
            double height = Rez::guiX(viewPart->getBoxY());
912
            sectionSpan = height + sectionFudge;
913
            xVal = 0.0;
914
            yVal = sectionSpan / 2.0;
915
            centerLine->setIntersection(horiz && vert);
916
            centerLine->setBounds(-xVal, -yVal, xVal, yVal);
917
            centerLine->setLinePen(m_dashedLineGenerator->getLinePen((size_t)Preferences::CenterLineStyle(),
918
                                  vp->HiddenWidth.getValue()));
919
            centerLine->setWidth(Rez::guiX(vp->HiddenWidth.getValue()));
920
            centerLine->setColor(Qt::red);
921
            centerLine->setZValue(ZVALUE::SECTIONLINE);
922
            centerLine->draw();
923
        }
924
    }
925
}
926

927
void QGIViewPart::drawAllHighlights()
928
{
929
    // dvp and vp already validated
930
    auto dvp(static_cast<TechDraw::DrawViewPart*>(getViewObject()));
931

932
    auto drefs = dvp->getDetailRefs();
933
    for (auto& r : drefs) {
934
        drawHighlight(r, true);
935
    }
936
}
937

938
void QGIViewPart::drawHighlight(TechDraw::DrawViewDetail* viewDetail, bool b)
939
{
940
    TechDraw::DrawViewPart* viewPart = static_cast<TechDraw::DrawViewPart*>(getViewObject());
941
    if (!viewPart || !viewDetail) {
942
        return;
943
    }
944

945
    auto vp = static_cast<ViewProviderViewPart*>(getViewProvider(getViewObject()));
946
    if (!vp) {
947
        return;
948
    }
949
    auto vpDetail = static_cast<ViewProviderViewPart*>(getViewProvider(viewDetail));
950
    if (!vpDetail) {
951
        return;
952
    }
953

954
    if (!viewDetail->ShowHighlight.getValue()) {
955
        return;
956
    }
957

958
    if (b) {
959
        double fontSize = Preferences::labelFontSizeMM();
960
        QGIHighlight* highlight = new QGIHighlight();
961
        scene()->addItem(highlight);
962
        highlight->setReference(viewDetail->Reference.getValue());
963

964
        App::Color color = Preferences::getAccessibleColor(vp->HighlightLineColor.getValue());
965
        highlight->setColor(color.asValue<QColor>());
966
        highlight->setFeatureName(viewDetail->getNameInDocument());
967
        highlight->setInteractive(true);
968

969
        addToGroup(highlight);
970
        highlight->setPos(0.0, 0.0);//sb setPos(center.x, center.y)?
971

972
        Base::Vector3d center = viewDetail->AnchorPoint.getValue() * viewPart->getScale();
973
        double rotationRad = viewPart->Rotation.getValue() * M_PI / 180.0;
974
        center.RotateZ(rotationRad);
975

976
        double radius = viewDetail->Radius.getValue() * viewPart->getScale();
977
        highlight->setBounds(center.x - radius, center.y + radius, center.x + radius,
978
                             center.y - radius);
979
        highlight->setLinePen(m_dashedLineGenerator->getLinePen((size_t)vp->HighlightLineStyle.getValue(),
980
                             vp->IsoWidth.getValue()));
981
        highlight->setWidth(Rez::guiX(vp->IsoWidth.getValue()));
982
        highlight->setFont(getFont(), fontSize);
983
        highlight->setZValue(ZVALUE::HIGHLIGHT);
984
        highlight->setReferenceAngle(vpDetail->HighlightAdjust.getValue());
985

986
        //handle conversion of apparent X,Y to rotated
987
        QPointF rotCenter = highlight->mapFromParent(transformOriginPoint());
988
        highlight->setTransformOriginPoint(rotCenter);
989

990
        double rotation = viewPart->Rotation.getValue();
991
        highlight->setRotation(rotation);
992
        highlight->draw();
993
    }
994
}
995

996
void QGIViewPart::highlightMoved(QGIHighlight* highlight, QPointF newPos)
997
{
998
    std::string highlightName = highlight->getFeatureName();
999
    App::Document* doc = getViewObject()->getDocument();
1000
    App::DocumentObject* docObj = doc->getObject(highlightName.c_str());
1001
    auto detail = dynamic_cast<DrawViewDetail*>(docObj);
1002
    if (detail) {
1003
        auto oldAnchor = detail->AnchorPoint.getValue();
1004
        Base::Vector3d delta = Rez::appX(DrawUtil::toVector3d(newPos)) / getViewObject()->getScale();
1005
        delta = DrawUtil::invertY(delta);
1006
        detail->AnchorPoint.setValue(oldAnchor + delta);
1007
    }
1008
}
1009

1010
void QGIViewPart::drawMatting()
1011
{
1012
    auto viewPart(dynamic_cast<TechDraw::DrawViewPart*>(getViewObject()));
1013
    TechDraw::DrawViewDetail* dvd = nullptr;
1014
    if (viewPart && viewPart->isDerivedFrom(TechDraw::DrawViewDetail::getClassTypeId())) {
1015
        dvd = static_cast<TechDraw::DrawViewDetail*>(viewPart);
1016
    }
1017
    else {
1018
        return;
1019
    }
1020

1021
    if (!dvd->ShowMatting.getValue()) {
1022
        return;
1023
    }
1024

1025
    double scale = dvd->getScale();
1026
    double radius = dvd->Radius.getValue() * scale;
1027
    QGIMatting* mat = new QGIMatting();
1028
    addToGroup(mat);
1029
    mat->setRadius(Rez::guiX(radius));
1030
    mat->setPos(0.0, 0.0);
1031
    mat->draw();
1032
    mat->show();
1033
}
1034

1035
void QGIViewPart::toggleCache(bool state)
1036
{
1037
    QList<QGraphicsItem*> items = childItems();
1038
    for (QList<QGraphicsItem*>::iterator it = items.begin(); it != items.end(); it++) {
1039
        //(*it)->setCacheMode((state)? DeviceCoordinateCache : NoCache);        //TODO: fiddle cache settings if req'd for performance
1040
        Q_UNUSED(state);
1041
        (*it)->setCacheMode(NoCache);
1042
        (*it)->update();
1043
    }
1044
}
1045

1046
void QGIViewPart::toggleCosmeticLines(bool state)
1047
{
1048
    QList<QGraphicsItem*> items = childItems();
1049
    for (QList<QGraphicsItem*>::iterator it = items.begin(); it != items.end(); it++) {
1050
        QGIEdge* edge = dynamic_cast<QGIEdge*>(*it);
1051
        if (edge) {
1052
            edge->setCosmetic(state);
1053
        }
1054
    }
1055
}
1056

1057
//get hatchObj for face i if it exists
1058
TechDraw::DrawHatch* QGIViewPart::faceIsHatched(int i,
1059
                                                std::vector<TechDraw::DrawHatch*> hatchObjs) const
1060
{
1061
    TechDraw::DrawHatch* result = nullptr;
1062
    bool found = false;
1063
    for (auto& h : hatchObjs) {
1064
        const std::vector<std::string>& sourceNames = h->Source.getSubValues();
1065
        for (auto& s : sourceNames) {
1066
            int fdx = TechDraw::DrawUtil::getIndexFromName(s);
1067
            if (fdx == i) {
1068
                result = h;
1069
                found = true;
1070
                break;
1071
            }
1072
        }
1073
        if (found) {
1074
            break;
1075
        }
1076
    }
1077
    return result;
1078
}
1079

1080
TechDraw::DrawGeomHatch*
1081
QGIViewPart::faceIsGeomHatched(int i, std::vector<TechDraw::DrawGeomHatch*> geomObjs) const
1082
{
1083
    TechDraw::DrawGeomHatch* result = nullptr;
1084
    bool found = false;
1085
    for (auto& h : geomObjs) {
1086
        const std::vector<std::string>& sourceNames = h->Source.getSubValues();
1087
        for (auto& sn : sourceNames) {
1088
            int fdx = TechDraw::DrawUtil::getIndexFromName(sn);
1089
            if (fdx == i) {
1090
                result = h;
1091
                found = true;
1092
                break;
1093
            }
1094
            if (found) {
1095
                break;
1096
            }
1097
        }
1098
    }
1099
    return result;
1100
}
1101

1102

1103

1104
void QGIViewPart::dumpPath(const char* text, QPainterPath path)
1105
{
1106
    QPainterPath::Element elem;
1107
    Base::Console().Message(">>>%s has %d elements\n", text, path.elementCount());
1108
    const char* typeName;
1109
    for (int iElem = 0; iElem < path.elementCount(); iElem++) {
1110
        elem = path.elementAt(iElem);
1111
        if (elem.isMoveTo()) {
1112
            typeName = "MoveTo";
1113
        }
1114
        else if (elem.isLineTo()) {
1115
            typeName = "LineTo";
1116
        }
1117
        else if (elem.isCurveTo()) {
1118
            typeName = "CurveTo";
1119
        }
1120
        else {
1121
            typeName = "CurveData";
1122
        }
1123
        Base::Console().Message(">>>>> element %d: type:%d/%s pos(%.3f, %.3f) M:%d L:%d C:%d\n",
1124
                                iElem, static_cast<int>(elem.type), typeName, elem.x, elem.y, static_cast<int>(elem.isMoveTo()),
1125
                                static_cast<int>(elem.isLineTo()), static_cast<int>(elem.isCurveTo()));
1126
    }
1127
}
1128

1129
QRectF QGIViewPart::boundingRect() const
1130
{
1131
    //    return childrenBoundingRect();
1132
    //    return customChildrenBoundingRect();
1133
    return QGIView::boundingRect();
1134
}
1135
void QGIViewPart::paint(QPainter* painter, const QStyleOptionGraphicsItem* option, QWidget* widget)
1136
{
1137
    QStyleOptionGraphicsItem myOption(*option);
1138
    myOption.state &= ~QStyle::State_Selected;
1139

1140
    //    painter->drawRect(boundingRect());          //good for debugging
1141

1142
    QGIView::paint(painter, &myOption, widget);
1143
}
1144

1145
//QGIViewPart derived classes do not need a rotate view method as rotation is handled on App side.
1146
void QGIViewPart::rotateView() {}
1147

1148
bool QGIViewPart::prefFaceEdges()
1149
{
1150
    bool result = false;
1151
    result = Preferences::getPreferenceGroup("General")->GetBool("DrawFaceEdges", false);
1152
    return result;
1153
}
1154

1155
bool QGIViewPart::prefPrintCenters()
1156
{
1157
    bool printCenters = Preferences::getPreferenceGroup("Decorations")->GetBool("PrintCenterMarks", false);//true matches v0.18 behaviour
1158
    return printCenters;
1159
}
1160

1161
QGraphicsItem *QGIViewPart::getQGISubItemByName(const std::string &subName) const
1162
{
1163
    int scanType = 0;
1164
    try {
1165
        const std::string &subType = TechDraw::DrawUtil::getGeomTypeFromName(subName);
1166
        if (subType == "Vertex") {
1167
            scanType = QGIVertex::Type;
1168
        }
1169
        else if (subType == "Edge") {
1170
            scanType = QGIEdge::Type;
1171
        }
1172
        else if (subType == "Face") {
1173
            scanType = QGIFace::Type;
1174
        }
1175
    }
1176
    catch (Base::ValueError&) {
1177
        // No action
1178
    }
1179
    if (!scanType) {
1180
        return nullptr;
1181
    }
1182

1183
    int scanIndex = -1;
1184
    try {
1185
        scanIndex = TechDraw::DrawUtil::getIndexFromName(subName);
1186
    }
1187
    catch (Base::ValueError&) {
1188
        // No action
1189
    }
1190
    if (scanIndex < 0) {
1191
        return nullptr;
1192
    }
1193

1194
    for (auto child : childItems()) {
1195
        if (child->type() != scanType) {
1196
            continue;
1197
        }
1198

1199
        int projIndex;
1200
        switch (scanType) {
1201
            case QGIVertex::Type:
1202
                projIndex = static_cast<QGIVertex *>(child)->getProjIndex();
1203
                break;
1204
            case QGIEdge::Type:
1205
                projIndex = static_cast<QGIEdge *>(child)->getProjIndex();
1206
                break;
1207
            case QGIFace::Type:
1208
                projIndex = static_cast<QGIFace *>(child)->getProjIndex();
1209
                break;
1210
            default:
1211
                projIndex = -1;
1212
                break;
1213
        }
1214

1215
        if (projIndex == scanIndex) {
1216
            return child;
1217
        }
1218
    }
1219

1220
    return nullptr;
1221
}
1222

1223
bool QGIViewPart::getGroupSelection() {
1224
    return DrawGuiUtil::isSelectedInTree(this);
1225
}
1226

1227
void QGIViewPart::setGroupSelection(bool isSelected) {
1228
    DrawGuiUtil::setSelectedTree(this, isSelected);
1229
}
1230

1231
void QGIViewPart::setGroupSelection(bool isSelected, const std::vector<std::string> &subNames)
1232
{
1233
    if (subNames.empty()) {
1234
        setSelected(isSelected);
1235
        return;
1236
    }
1237

1238
    for (const std::string &subName : subNames) {
1239
        if (subName.empty()) {
1240
            setSelected(isSelected);
1241
            continue;
1242
        }
1243

1244
        QGraphicsItem *subItem = getQGISubItemByName(subName);
1245
        if (subItem) {
1246
            subItem->setSelected(isSelected);
1247
        }
1248
    }
1249
}
1250

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

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

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

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