1
/***************************************************************************
2
* Copyright (c) 2021 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com> *
4
* This file is part of the FreeCAD CAx development system. *
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. *
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. *
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 *
21
***************************************************************************/
23
#include "PreCompiled.h"
27
#include <Inventor/SbVec3f.h>
28
#include <Inventor/SoPickedPoint.h>
29
#include <Inventor/details/SoDetail.h>
30
#include <Inventor/details/SoLineDetail.h>
31
#include <Inventor/details/SoPointDetail.h>
32
#include <Inventor/nodes/SoCoordinate3.h>
33
#include <Inventor/nodes/SoDrawStyle.h>
34
#include <Inventor/nodes/SoFont.h>
35
#include <Inventor/nodes/SoGroup.h>
36
#include <Inventor/nodes/SoLineSet.h>
37
#include <Inventor/nodes/SoMarkerSet.h>
38
#include <Inventor/nodes/SoMaterial.h>
39
#include <Inventor/nodes/SoPickStyle.h>
40
#include <Inventor/nodes/SoSeparator.h>
41
#include <Inventor/nodes/SoText2.h>
42
#include <Inventor/nodes/SoTranslation.h>
43
#endif // #ifndef _PreComp_
45
#include <Base/Exception.h>
46
#include <Gui/Inventor/MarkerBitmaps.h>
47
#include <Gui/SoFCBoundingBox.h>
48
#include <Mod/Sketcher/App/Constraint.h>
49
#include <Mod/Sketcher/App/GeoList.h>
51
#include "EditModeCoinManager.h"
52
#include "EditModeConstraintCoinManager.h"
53
#include "EditModeGeometryCoinConverter.h"
54
#include "EditModeGeometryCoinManager.h"
55
#include "EditModeInformationOverlayCoinConverter.h"
57
#include "ViewProviderSketch.h"
58
#include "ViewProviderSketchCoinAttorney.h"
60
using namespace SketcherGui;
61
using namespace Sketcher;
63
//**************************** ParameterObserver nested class ******************************
64
EditModeCoinManager::ParameterObserver::ParameterObserver(EditModeCoinManager& client)
68
subscribeToParameters();
71
EditModeCoinManager::ParameterObserver::~ParameterObserver()
73
unsubscribeToParameters();
76
void EditModeCoinManager::ParameterObserver::initParameters()
78
// static map to avoid substantial if/else branching
80
// key->first => String of parameter,
81
// key->second => Update function to be called for the parameter,
82
str2updatefunction = {
83
{"SegmentsPerGeometry",
84
[this](const std::string& param) {
85
updateCurvedEdgeCountSegmentsParameter(param);
87
{"BSplineDegreeVisible",
88
[this](const std::string& param) {
89
updateOverlayVisibilityParameter<OverlayVisibilityParameter::BSplineDegree>(param);
91
{"BSplineControlPolygonVisible",
92
[this](const std::string& param) {
93
updateOverlayVisibilityParameter<
94
OverlayVisibilityParameter::BSplineControlPolygonVisible>(param);
96
{"BSplineCombVisible",
97
[this](const std::string& param) {
98
updateOverlayVisibilityParameter<OverlayVisibilityParameter::BSplineCombVisible>(
101
{"BSplineKnotMultiplicityVisible",
102
[this](const std::string& param) {
103
updateOverlayVisibilityParameter<
104
OverlayVisibilityParameter::BSplineKnotMultiplicityVisible>(param);
106
{"BSplinePoleWeightVisible",
107
[this](const std::string& param) {
108
updateOverlayVisibilityParameter<OverlayVisibilityParameter::BSplinePoleWeightVisible>(
111
{"ArcCircleHelperVisible",
112
[this](const std::string& param) {
113
updateOverlayVisibilityParameter<OverlayVisibilityParameter::ArcCircleHelperVisible>(
116
{"TopRenderGeometryId",
117
[this](const std::string& param) {
118
updateLineRenderingOrderParameters(param);
120
{"MidRenderGeometryId",
121
[this](const std::string& param) {
122
updateLineRenderingOrderParameters(param);
125
[this](const std::string& param) {
126
updateConstraintPresentationParameters(param);
128
{"ShowDimensionalName",
129
[this](const std::string& param) {
130
updateConstraintPresentationParameters(param);
132
{"DimensionalStringFormat",
133
[this](const std::string& param) {
134
updateConstraintPresentationParameters(param);
136
{"ViewScalingFactor",
137
[this](const std::string& param) {
138
updateElementSizeParameters(param);
141
[this](const std::string& param) {
142
updateElementSizeParameters(param);
144
{"EditSketcherFontSize",
145
[this](const std::string& param) {
146
updateElementSizeParameters(param);
149
[this, &drawingParameters = Client.drawingParameters](const std::string& param) {
150
updateWidth(drawingParameters.CurveWidth, param, 2);
152
{"ConstructionWidth",
153
[this, &drawingParameters = Client.drawingParameters](const std::string& param) {
154
updateWidth(drawingParameters.ConstructionWidth, param, 2);
157
[this, &drawingParameters = Client.drawingParameters](const std::string& param) {
158
updateWidth(drawingParameters.InternalWidth, param, 2);
161
[this, &drawingParameters = Client.drawingParameters](const std::string& param) {
162
updateWidth(drawingParameters.ExternalWidth, param, 2);
165
[this, &drawingParameters = Client.drawingParameters](const std::string& param) {
166
updatePattern(drawingParameters.CurvePattern, param, 0b1111111111111111);
168
{"ConstructionPattern",
169
[this, &drawingParameters = Client.drawingParameters](const std::string& param) {
170
updatePattern(drawingParameters.ConstructionPattern, param, 0b1111110011111100);
173
[this, &drawingParameters = Client.drawingParameters](const std::string& param) {
174
updatePattern(drawingParameters.InternalPattern, param, 0b1111110011111100);
177
[this, &drawingParameters = Client.drawingParameters](const std::string& param) {
178
updatePattern(drawingParameters.ExternalPattern, param, 0b1110010011100100);
181
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
182
updateColor(drawingParameters.CreateCurveColor, param);
185
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
186
updateColor(drawingParameters.CurveColor, param);
188
{"ConstructionColor",
189
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
190
updateColor(drawingParameters.CurveDraftColor, param);
192
{"InternalAlignedGeoColor",
193
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
194
updateColor(drawingParameters.InternalAlignedGeoColor, param);
196
{"FullyConstraintElementColor",
197
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
198
updateColor(drawingParameters.FullyConstraintElementColor, param);
200
{"FullyConstraintConstructionElementColor",
201
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
202
updateColor(drawingParameters.FullyConstraintConstructionElementColor, param);
204
{"FullyConstraintInternalAlignmentColor",
205
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
206
updateColor(drawingParameters.FullyConstraintInternalAlignmentColor, param);
208
{"FullyConstraintElementColor",
209
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
210
updateColor(drawingParameters.FullyConstraintElementColor, param);
212
{"InvalidSketchColor",
213
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
214
updateColor(drawingParameters.InvalidSketchColor, param);
216
{"FullyConstrainedColor",
217
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
218
updateColor(drawingParameters.FullyConstrainedColor, param);
220
{"ConstrainedDimColor",
221
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
222
updateColor(drawingParameters.ConstrDimColor, param);
224
{"ConstrainedIcoColor",
225
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
226
updateColor(drawingParameters.ConstrIcoColor, param);
228
{"NonDrivingConstrDimColor",
229
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
230
updateColor(drawingParameters.NonDrivingConstrDimColor, param);
232
{"ExprBasedConstrDimColor",
233
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
234
updateColor(drawingParameters.ExprBasedConstrDimColor, param);
236
{"DeactivatedConstrDimColor",
237
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
238
updateColor(drawingParameters.DeactivatedConstrDimColor, param);
241
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
242
updateColor(drawingParameters.CurveExternalColor, param);
245
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
246
updateColor(drawingParameters.PreselectColor, param);
249
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
250
updateColor(drawingParameters.SelectColor, param);
253
[this, drawingParameters = Client.drawingParameters](const std::string& param) {
254
updateColor(drawingParameters.CursorTextColor, param);
257
[this](const std::string& param) {
262
for (auto& val : str2updatefunction) {
263
auto string = val.first;
264
auto function = val.second;
270
void EditModeCoinManager::ParameterObserver::updateCurvedEdgeCountSegmentsParameter(
271
const std::string& parametername)
273
ParameterGrp::handle hGrp =
274
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
275
int stdcountsegments = hGrp->GetInt(parametername.c_str(), 50);
276
// value cannot be smaller than 6
277
if (stdcountsegments < 6) {
278
stdcountsegments = 6;
281
Client.drawingParameters.curvedEdgeCountSegments = stdcountsegments;
284
void EditModeCoinManager::ParameterObserver::updateLineRenderingOrderParameters(
285
const std::string& parametername)
289
ParameterGrp::handle hGrpp = App::GetApplication().GetParameterGroupByPath(
290
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
292
Client.drawingParameters.topRenderingGeometry =
293
DrawingParameters::GeometryRendering(hGrpp->GetInt("TopRenderGeometryId", 1));
294
Client.drawingParameters.midRenderingGeometry =
295
DrawingParameters::GeometryRendering(hGrpp->GetInt("MidRenderGeometryId", 2));
298
void EditModeCoinManager::ParameterObserver::updateConstraintPresentationParameters(
299
const std::string& parametername)
303
ParameterGrp::handle hGrpskg = App::GetApplication().GetParameterGroupByPath(
304
"User parameter:BaseApp/Preferences/Mod/Sketcher");
306
Client.constraintParameters.bHideUnits = hGrpskg->GetBool("HideUnits", false);
307
Client.constraintParameters.bShowDimensionalName =
308
hGrpskg->GetBool("ShowDimensionalName", false);
309
Client.constraintParameters.sDimensionalStringFormat =
310
QString::fromStdString(hGrpskg->GetASCII("DimensionalStringFormat", "%N = %V"));
313
template<EditModeCoinManager::ParameterObserver::OverlayVisibilityParameter visibilityparameter>
314
void EditModeCoinManager::ParameterObserver::updateOverlayVisibilityParameter(
315
const std::string& parametername)
317
ParameterGrp::handle hGrpsk = App::GetApplication().GetParameterGroupByPath(
318
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
320
if constexpr (visibilityparameter == OverlayVisibilityParameter::BSplineDegree) {
321
Client.overlayParameters.bSplineDegreeVisible =
322
hGrpsk->GetBool(parametername.c_str(), true);
324
else if constexpr (visibilityparameter
325
== OverlayVisibilityParameter::BSplineControlPolygonVisible) {
326
Client.overlayParameters.bSplineControlPolygonVisible =
327
hGrpsk->GetBool(parametername.c_str(), true);
329
else if constexpr (visibilityparameter == OverlayVisibilityParameter::BSplineCombVisible) {
330
Client.overlayParameters.bSplineCombVisible = hGrpsk->GetBool(parametername.c_str(), true);
332
else if constexpr (visibilityparameter
333
== OverlayVisibilityParameter::BSplineKnotMultiplicityVisible) {
334
Client.overlayParameters.bSplineKnotMultiplicityVisible =
335
hGrpsk->GetBool(parametername.c_str(), true);
337
else if constexpr (visibilityparameter
338
== OverlayVisibilityParameter::BSplinePoleWeightVisible) {
339
Client.overlayParameters.bSplinePoleWeightVisible =
340
hGrpsk->GetBool(parametername.c_str(), true);
342
else if constexpr (visibilityparameter == OverlayVisibilityParameter::ArcCircleHelperVisible) {
343
Client.overlayParameters.arcCircleHelperVisible =
344
hGrpsk->GetBool(parametername.c_str(), false);
347
Client.overlayParameters.visibleInformationChanged = true;
350
void EditModeCoinManager::ParameterObserver::updateElementSizeParameters(
351
const std::string& parametername)
355
// Add scaling to Constraint icons
356
ParameterGrp::handle hGrp =
357
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
359
double viewScalingFactor = hGrp->GetFloat("ViewScalingFactor", 1.0);
360
viewScalingFactor = Base::clamp<double>(viewScalingFactor, 0.5, 5.0);
362
int markersize = hGrp->GetInt("MarkerSize", 7);
364
int defaultFontSizePixels =
365
Client.defaultApplicationFontSizePixels(); // returns height in pixels, not points
367
int sketcherfontSize = hGrp->GetInt("EditSketcherFontSize", defaultFontSizePixels);
369
int dpi = Client.getApplicationLogicalDPIX();
371
// simple scaling factor for hardcoded pixel values in the Sketcher
372
Client.drawingParameters.pixelScalingFactor = viewScalingFactor * dpi
373
/ 96; // 96 ppi is the standard pixel density for which pixel quantities were calculated
376
// SoDatumLabel takes the size in points, not in pixels. This is because it uses QFont
377
// internally. Coin, at least our coin at this time, takes pixels, not points.
379
// DPI considerations:
380
// With hdpi monitors, the coin font labels do not respect the size passed in pixels:
381
// https://forum.freecad.org/viewtopic.php?f=3&t=54347&p=467610#p467610
382
// https://forum.freecad.org/viewtopic.php?f=10&t=49972&start=40#p467471
384
// Because I (abdullah) have 96 dpi logical, 82 dpi physical, and I see a 35px font setting for
385
// a "1" in a datum label as 34px, and I see kilsore and Elyas screenshots showing 41px and 61px
386
// in higher resolution monitors for the same configuration, I think that coin pixel size has to
387
// be corrected by the logical dpi of the monitor. The rationale is that: a) it obviously needs
388
// dpi correction, b) with physical dpi, the ratio of representation between kilsore and me is
391
// This means that the following correction does not have a documented basis, but appears
392
// necessary so that the Sketcher is usable in HDPI monitors.
394
Client.drawingParameters.coinFontSize =
395
std::lround(sketcherfontSize * 96.0f / dpi); // this is in pixels
396
Client.drawingParameters.labelFontSize = std::lround(
397
sketcherfontSize * 72.0f / dpi); // this is in points, as SoDatumLabel uses points
398
Client.drawingParameters.constraintIconSize = std::lround(0.8 * sketcherfontSize);
400
// For marker size the global default is used.
403
// -> Other WBs use the default value as is
404
// -> If a user has a HDPI, he will eventually change the value for the other WBs
405
// -> If we correct the value here in addition, we would get two times a resize
406
Client.drawingParameters.markerSize = markersize;
408
Client.updateInventorNodeSizes();
411
void EditModeCoinManager::ParameterObserver::updateWidth(int& width,
412
const std::string& parametername,
415
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
416
"User parameter:BaseApp/Preferences/Mod/Sketcher/View");
418
width = hGrp->GetInt(parametername.c_str(), def);
420
Client.updateInventorWidths();
423
void EditModeCoinManager::ParameterObserver::updatePattern(unsigned int& pattern,
424
const std::string& parametername,
427
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
428
"User parameter:BaseApp/Preferences/Mod/Sketcher/View");
430
pattern = hGrp->GetInt(parametername.c_str(), def);
432
Client.updateInventorPatterns();
435
void EditModeCoinManager::ParameterObserver::updateColor(SbColor& sbcolor,
436
const std::string& parametername)
438
ParameterGrp::handle hGrp =
439
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
441
float transparency = 0.f;
442
unsigned long color = (unsigned long)(sbcolor.getPackedValue());
443
color = hGrp->GetUnsigned(parametername.c_str(), color);
444
sbcolor.setPackedValue((uint32_t)color, transparency);
446
Client.updateInventorColors();
449
void EditModeCoinManager::ParameterObserver::updateUnit(const std::string& parametername)
451
Q_UNUSED(parametername);
452
// Nothing to do because we only need Client.redrawViewProvider(); that is already called in
456
void EditModeCoinManager::ParameterObserver::subscribeToParameters()
459
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
460
"User parameter:BaseApp/Preferences/View");
463
ParameterGrp::handle hGrpsk = App::GetApplication().GetParameterGroupByPath(
464
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
465
hGrpsk->Attach(this);
467
ParameterGrp::handle hGrpskg = App::GetApplication().GetParameterGroupByPath(
468
"User parameter:BaseApp/Preferences/Mod/Sketcher");
469
hGrpskg->Attach(this);
471
ParameterGrp::handle hGrpu = App::GetApplication().GetParameterGroupByPath(
472
"User parameter:BaseApp/Preferences/Units");
475
catch (const Base::ValueError& e) { // ensure that if parameter strings are not well-formed,
476
// the exception is not propagated
477
Base::Console().DeveloperError("EditModeCoinManager",
478
"Malformed parameter string: %s\n",
483
void EditModeCoinManager::ParameterObserver::unsubscribeToParameters()
486
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
487
"User parameter:BaseApp/Preferences/View");
490
ParameterGrp::handle hGrpsk = App::GetApplication().GetParameterGroupByPath(
491
"User parameter:BaseApp/Preferences/Mod/Sketcher/General");
492
hGrpsk->Detach(this);
494
ParameterGrp::handle hGrpskg = App::GetApplication().GetParameterGroupByPath(
495
"User parameter:BaseApp/Preferences/Mod/Sketcher");
496
hGrpskg->Detach(this);
498
ParameterGrp::handle hGrpu = App::GetApplication().GetParameterGroupByPath(
499
"User parameter:BaseApp/Preferences/Units");
502
catch (const Base::ValueError&
503
e) { // ensure that if parameter strings are not well-formed, the program is not
504
// terminated when calling the noexcept destructor.
505
Base::Console().DeveloperError("EditModeCoinManager",
506
"Malformed parameter string: %s\n",
511
void EditModeCoinManager::ParameterObserver::OnChange(Base::Subject<const char*>& rCaller,
516
auto key = str2updatefunction.find(sReason);
517
if (key != str2updatefunction.end()) {
518
auto string = key->first;
519
auto function = key->second;
523
Client.redrawViewProvider(); // redraw with non-temporal geometry
527
//**************************** EditModeCoinManager class ******************************
529
EditModeCoinManager::EditModeCoinManager(ViewProviderSketch& vp)
533
pEditModeConstraintCoinManager =
534
std::make_unique<EditModeConstraintCoinManager>(viewProvider,
536
geometryLayerParameters,
537
constraintParameters,
538
editModeScenegraphNodes,
541
pEditModeGeometryCoinManager =
542
std::make_unique<EditModeGeometryCoinManager>(viewProvider,
544
geometryLayerParameters,
546
editModeScenegraphNodes,
548
// Create Edit Mode Scenograph
549
createEditModeInventorNodes();
551
// Create parameter observer and initialise watched parameters
552
pObserver = std::make_unique<EditModeCoinManager::ParameterObserver>(*this);
555
EditModeCoinManager::~EditModeCoinManager()
557
Gui::coinRemoveAllChildren(editModeScenegraphNodes.EditRoot);
558
ViewProviderSketchCoinAttorney::removeNodeFromRoot(viewProvider,
559
editModeScenegraphNodes.EditRoot);
560
editModeScenegraphNodes.EditRoot->unref();
563
/***** Temporary edit curves and markers *****/
565
void EditModeCoinManager::drawEditMarkers(const std::vector<Base::Vector2d>& EditMarkers,
566
unsigned int augmentationlevel)
568
// determine marker size
569
int augmentedmarkersize = drawingParameters.markerSize;
571
auto supportedsizes = Gui::Inventor::MarkerBitmaps::getSupportedSizes("CIRCLE_LINE");
574
std::find(supportedsizes.begin(), supportedsizes.end(), drawingParameters.markerSize);
576
if (defaultmarker != supportedsizes.end()) {
577
auto validAugmentationLevels = std::distance(defaultmarker, supportedsizes.end());
579
if (augmentationlevel >= validAugmentationLevels) {
580
augmentationlevel = validAugmentationLevels - 1;
583
augmentedmarkersize = *std::next(defaultmarker, augmentationlevel);
586
editModeScenegraphNodes.EditMarkerSet->markerIndex.startEditing();
587
editModeScenegraphNodes.EditMarkerSet->markerIndex =
588
Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_LINE", augmentedmarkersize);
590
// add the points to set
591
editModeScenegraphNodes.EditMarkersCoordinate->point.setNum(EditMarkers.size());
592
editModeScenegraphNodes.EditMarkersMaterials->diffuseColor.setNum(EditMarkers.size());
593
SbVec3f* verts = editModeScenegraphNodes.EditMarkersCoordinate->point.startEditing();
594
SbColor* color = editModeScenegraphNodes.EditMarkersMaterials->diffuseColor.startEditing();
596
int i = 0; // setting up the line set
597
for (std::vector<Base::Vector2d>::const_iterator it = EditMarkers.begin();
598
it != EditMarkers.end();
600
verts[i].setValue(it->x,
602
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
603
* drawingParameters.zEdit);
604
color[i] = drawingParameters.InformationColor;
607
editModeScenegraphNodes.EditMarkersCoordinate->point.finishEditing();
608
editModeScenegraphNodes.EditMarkersMaterials->diffuseColor.finishEditing();
609
editModeScenegraphNodes.EditMarkerSet->markerIndex.finishEditing();
612
void EditModeCoinManager::drawEdit(const std::vector<Base::Vector2d>& EditCurve)
614
editModeScenegraphNodes.EditCurveSet->numVertices.setNum(1);
615
editModeScenegraphNodes.EditCurvesCoordinate->point.setNum(EditCurve.size());
616
editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.setNum(EditCurve.size());
617
SbVec3f* verts = editModeScenegraphNodes.EditCurvesCoordinate->point.startEditing();
618
int32_t* index = editModeScenegraphNodes.EditCurveSet->numVertices.startEditing();
619
SbColor* color = editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.startEditing();
621
int i = 0; // setting up the line set
622
for (std::vector<Base::Vector2d>::const_iterator it = EditCurve.begin(); it != EditCurve.end();
624
verts[i].setValue(it->x,
626
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
627
* drawingParameters.zEdit);
628
color[i] = drawingParameters.CreateCurveColor;
631
index[0] = EditCurve.size();
632
editModeScenegraphNodes.EditCurvesCoordinate->point.finishEditing();
633
editModeScenegraphNodes.EditCurveSet->numVertices.finishEditing();
634
editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.finishEditing();
637
void EditModeCoinManager::drawEdit(const std::list<std::vector<Base::Vector2d>>& list)
641
for (const auto& v : list) {
645
editModeScenegraphNodes.EditCurveSet->numVertices.setNum(list.size());
646
editModeScenegraphNodes.EditCurvesCoordinate->point.setNum(ncoords);
647
editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.setNum(ncoords);
648
SbVec3f* verts = editModeScenegraphNodes.EditCurvesCoordinate->point.startEditing();
649
int32_t* index = editModeScenegraphNodes.EditCurveSet->numVertices.startEditing();
650
SbColor* color = editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.startEditing();
654
for (const auto& v : list) {
655
for (const auto& p : v) {
656
verts[coordindex].setValue(
659
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
660
* drawingParameters.zEdit);
661
color[coordindex] = drawingParameters.CreateCurveColor;
664
index[indexindex] = v.size();
668
editModeScenegraphNodes.EditCurvesCoordinate->point.finishEditing();
669
editModeScenegraphNodes.EditCurveSet->numVertices.finishEditing();
670
editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.finishEditing();
673
void EditModeCoinManager::setPositionText(const Base::Vector2d& Pos, const SbString& text)
675
editModeScenegraphNodes.textX->string = text;
676
editModeScenegraphNodes.textPos->translation =
679
ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
680
* drawingParameters.zText);
683
void EditModeCoinManager::setPositionText(const Base::Vector2d& Pos)
685
if (showCursorCoords()) {
687
std::string xString = lengthToDisplayFormat(Pos.x, 1);
688
std::string yString = lengthToDisplayFormat(Pos.y, 1);
689
text.sprintf(" (%s, %s)", xString.c_str(), yString.c_str());
690
setPositionText(Pos, text);
694
void EditModeCoinManager::resetPositionText()
696
editModeScenegraphNodes.textX->string = "";
699
void EditModeCoinManager::setAxisPickStyle(bool on)
702
editModeScenegraphNodes.pickStyleAxes->style = SoPickStyle::SHAPE;
705
editModeScenegraphNodes.pickStyleAxes->style = SoPickStyle::UNPICKABLE;
709
EditModeCoinManager::PreselectionResult
710
EditModeCoinManager::detectPreselection(SoPickedPoint* Point, const SbVec2s& cursorPos)
712
EditModeCoinManager::PreselectionResult result;
718
// Base::Console().Log("Point pick\n");
719
SoPath* path = Point->getPath();
720
SoNode* tail = path->getTail(); // Tail is directly the node containing points and curves
722
for (int l = 0; l < geometryLayerParameters.getCoinLayerCount(); l++) {
723
// checking for a hit in the points
724
if (tail == editModeScenegraphNodes.PointSet[l]) {
725
const SoDetail* point_detail = Point->getDetail(editModeScenegraphNodes.PointSet[l]);
726
if (point_detail && point_detail->getTypeId() == SoPointDetail::getClassTypeId()) {
728
int pindex = static_cast<const SoPointDetail*>(point_detail)->getCoordinateIndex();
729
result.PointIndex = coinMapping.getPointVertexId(
731
l); // returns -1 for root, global VertexId for the rest of vertices.
733
if (result.PointIndex == -1) {
734
result.Cross = PreselectionResult::Axes::RootPoint;
741
// checking for a hit in the curves
742
for (int t = 0; t < geometryLayerParameters.getSubLayerCount(); t++) {
743
if (tail == editModeScenegraphNodes.CurveSet[l][t]) {
744
const SoDetail* curve_detail =
745
Point->getDetail(editModeScenegraphNodes.CurveSet[l][t]);
746
if (curve_detail && curve_detail->getTypeId() == SoLineDetail::getClassTypeId()) {
748
int curveIndex = static_cast<const SoLineDetail*>(curve_detail)->getLineIndex();
749
result.GeoIndex = coinMapping.getCurveGeoId(curveIndex, l, t);
756
// checking for a hit in the axes
757
if (tail == editModeScenegraphNodes.RootCrossSet) {
758
const SoDetail* cross_detail = Point->getDetail(editModeScenegraphNodes.RootCrossSet);
759
if (cross_detail && cross_detail->getTypeId() == SoLineDetail::getClassTypeId()) {
760
// get the index (reserve index 0 for root point)
761
int CrossIndex = static_cast<const SoLineDetail*>(cross_detail)->getLineIndex();
763
if (CrossIndex == 0) {
764
result.Cross = PreselectionResult::Axes::HorizontalAxis;
766
else if (CrossIndex == 1) {
767
result.Cross = PreselectionResult::Axes::VerticalAxis;
773
// checking if a constraint is hit
774
result.ConstrIndices =
775
pEditModeConstraintCoinManager->detectPreselectionConstr(Point, cursorPos);
780
SoGroup* EditModeCoinManager::getSelectedConstraints()
782
SoGroup* group = new SoGroup();
785
for (int i = 0; i < editModeScenegraphNodes.constrGroup->getNumChildren(); i++) {
786
if (ViewProviderSketchCoinAttorney::isConstraintSelected(viewProvider, i)) {
787
SoSeparator* sep = pEditModeConstraintCoinManager->getConstraintIdSeparator(i);
789
group->addChild(sep);
797
/***** update coin nodes *****/
799
void EditModeCoinManager::processGeometryConstraintsInformationOverlay(
800
const GeoListFacade& geolistfacade,
801
bool rebuildinformationlayer)
803
overlayParameters.rebuildInformationLayer = rebuildinformationlayer;
805
pEditModeGeometryCoinManager->processGeometry(geolistfacade);
807
updateOverlayParameters();
809
processGeometryInformationOverlay(geolistfacade);
813
pEditModeConstraintCoinManager->processConstraints(geolistfacade);
816
void EditModeCoinManager::updateOverlayParameters()
818
if ((analysisResults.combRepresentationScale
819
> (2 * overlayParameters.currentBSplineCombRepresentationScale))
820
|| (analysisResults.combRepresentationScale
821
< (overlayParameters.currentBSplineCombRepresentationScale / 2))) {
822
overlayParameters.currentBSplineCombRepresentationScale =
823
analysisResults.combRepresentationScale;
827
void EditModeCoinManager::processGeometryInformationOverlay(const GeoListFacade& geolistfacade)
829
if (overlayParameters.rebuildInformationLayer) {
830
// every time we start with empty information overlay
831
Gui::coinRemoveAllChildren(editModeScenegraphNodes.infoGroup);
834
auto ioconv = EditModeInformationOverlayCoinConverter(viewProvider,
835
editModeScenegraphNodes.infoGroup,
839
// geometry information layer for bsplines, as they need a second round now that max curvature
841
for (auto geoid : analysisResults.bsplineGeoIds) {
842
const Part::Geometry* geo = geolistfacade.getGeometryFromGeoId(geoid);
844
ioconv.convert(geo, geoid);
846
for (auto geoid : analysisResults.arcGeoIds) {
847
const Part::Geometry* geo = geolistfacade.getGeometryFromGeoId(geoid);
848
ioconv.convert(geo, geoid);
852
overlayParameters.visibleInformationChanged = false; // just updated
855
void EditModeCoinManager::updateAxesLength()
857
auto zCrossH = ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
858
* drawingParameters.zCross;
859
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(
861
SbVec3f(-analysisResults.boundingBoxMagnitudeOrder, 0.0f, zCrossH));
862
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(
864
SbVec3f(analysisResults.boundingBoxMagnitudeOrder, 0.0f, zCrossH));
865
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(
867
SbVec3f(0.0f, -analysisResults.boundingBoxMagnitudeOrder, zCrossH));
868
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(
870
SbVec3f(0.0f, analysisResults.boundingBoxMagnitudeOrder, zCrossH));
873
void EditModeCoinManager::updateColor()
875
auto geolistfacade = ViewProviderSketchCoinAttorney::getGeoListFacade(viewProvider);
877
updateColor(geolistfacade);
880
void EditModeCoinManager::updateColor(const GeoListFacade& geolistfacade)
882
bool sketchinvalid = ViewProviderSketchCoinAttorney::isSketchInvalid(viewProvider);
884
pEditModeGeometryCoinManager->updateGeometryColor(geolistfacade, sketchinvalid);
886
// update constraint color
888
auto constraints = ViewProviderSketchCoinAttorney::getConstraints(viewProvider);
890
if (ViewProviderSketchCoinAttorney::haveConstraintsInvalidGeometry(viewProvider)) {
894
pEditModeConstraintCoinManager->updateConstraintColor(constraints);
897
void EditModeCoinManager::setConstraintSelectability(bool enabled /* = true */)
899
pEditModeConstraintCoinManager->setConstraintSelectability(enabled);
903
void EditModeCoinManager::updateGeometryLayersConfiguration()
905
pEditModeGeometryCoinManager->updateGeometryLayersConfiguration();
908
void EditModeCoinManager::createEditModeInventorNodes()
910
// 1 - Create the edit root node
911
editModeScenegraphNodes.EditRoot = new SoSeparator;
912
editModeScenegraphNodes.EditRoot
913
->ref(); // Node is unref in the destructor of EditModeCoinManager
914
editModeScenegraphNodes.EditRoot->setName("Sketch_EditRoot");
915
ViewProviderSketchCoinAttorney::addNodeToRoot(viewProvider, editModeScenegraphNodes.EditRoot);
916
editModeScenegraphNodes.EditRoot->renderCaching = SoSeparator::OFF;
918
// Create Geometry Coin nodes ++++++++++++++++++++++++++++++++++++++
919
pEditModeGeometryCoinManager->createEditModeInventorNodes();
921
// stuff for the RootCross lines +++++++++++++++++++++++++++++++++++++++
922
SoGroup* crossRoot = new Gui::SoSkipBoundingGroup;
923
editModeScenegraphNodes.pickStyleAxes = new SoPickStyle();
924
editModeScenegraphNodes.pickStyleAxes->style = SoPickStyle::SHAPE;
925
crossRoot->addChild(editModeScenegraphNodes.pickStyleAxes);
926
editModeScenegraphNodes.EditRoot->addChild(crossRoot);
927
auto MtlBind = new SoMaterialBinding;
928
MtlBind->setName("RootCrossMaterialBinding");
929
MtlBind->value = SoMaterialBinding::PER_FACE;
930
crossRoot->addChild(MtlBind);
932
editModeScenegraphNodes.RootCrossDrawStyle = new SoDrawStyle;
933
editModeScenegraphNodes.RootCrossDrawStyle->setName("RootCrossDrawStyle");
934
editModeScenegraphNodes.RootCrossDrawStyle->lineWidth =
935
2 * drawingParameters.pixelScalingFactor;
936
crossRoot->addChild(editModeScenegraphNodes.RootCrossDrawStyle);
938
editModeScenegraphNodes.RootCrossMaterials = new SoMaterial;
939
editModeScenegraphNodes.RootCrossMaterials->setName("RootCrossMaterials");
940
editModeScenegraphNodes.RootCrossMaterials->diffuseColor.set1Value(
942
drawingParameters.CrossColorH);
943
editModeScenegraphNodes.RootCrossMaterials->diffuseColor.set1Value(
945
drawingParameters.CrossColorV);
946
crossRoot->addChild(editModeScenegraphNodes.RootCrossMaterials);
948
editModeScenegraphNodes.RootCrossCoordinate = new SoCoordinate3;
949
editModeScenegraphNodes.RootCrossCoordinate->setName("RootCrossCoordinate");
950
crossRoot->addChild(editModeScenegraphNodes.RootCrossCoordinate);
952
editModeScenegraphNodes.RootCrossSet = new SoLineSet;
953
editModeScenegraphNodes.RootCrossSet->setName("RootCrossLineSet");
954
crossRoot->addChild(editModeScenegraphNodes.RootCrossSet);
956
// stuff for the EditCurves +++++++++++++++++++++++++++++++++++++++
957
SoSeparator* editCurvesRoot = new SoSeparator;
958
editModeScenegraphNodes.EditRoot->addChild(editCurvesRoot);
959
editModeScenegraphNodes.EditCurvesMaterials = new SoMaterial;
960
editModeScenegraphNodes.EditCurvesMaterials->setName("EditCurvesMaterials");
961
editCurvesRoot->addChild(editModeScenegraphNodes.EditCurvesMaterials);
963
editModeScenegraphNodes.EditCurvesCoordinate = new SoCoordinate3;
964
editModeScenegraphNodes.EditCurvesCoordinate->setName("EditCurvesCoordinate");
965
editCurvesRoot->addChild(editModeScenegraphNodes.EditCurvesCoordinate);
967
editModeScenegraphNodes.EditCurvesDrawStyle = new SoDrawStyle;
968
editModeScenegraphNodes.EditCurvesDrawStyle->setName("EditCurvesDrawStyle");
969
editModeScenegraphNodes.EditCurvesDrawStyle->lineWidth =
970
3 * drawingParameters.pixelScalingFactor;
971
editCurvesRoot->addChild(editModeScenegraphNodes.EditCurvesDrawStyle);
973
editModeScenegraphNodes.EditCurveSet = new SoLineSet;
974
editModeScenegraphNodes.EditCurveSet->setName("EditCurveLineSet");
975
editCurvesRoot->addChild(editModeScenegraphNodes.EditCurveSet);
977
// stuff for the EditMarkers +++++++++++++++++++++++++++++++++++++++
978
SoSeparator* editMarkersRoot = new SoSeparator;
979
editModeScenegraphNodes.EditRoot->addChild(editMarkersRoot);
980
editModeScenegraphNodes.EditMarkersMaterials = new SoMaterial;
981
editModeScenegraphNodes.EditMarkersMaterials->setName("EditMarkersMaterials");
982
editMarkersRoot->addChild(editModeScenegraphNodes.EditMarkersMaterials);
984
editModeScenegraphNodes.EditMarkersCoordinate = new SoCoordinate3;
985
editModeScenegraphNodes.EditMarkersCoordinate->setName("EditMarkersCoordinate");
986
editMarkersRoot->addChild(editModeScenegraphNodes.EditMarkersCoordinate);
988
editModeScenegraphNodes.EditMarkersDrawStyle = new SoDrawStyle;
989
editModeScenegraphNodes.EditMarkersDrawStyle->setName("EditMarkersDrawStyle");
990
editModeScenegraphNodes.EditMarkersDrawStyle->pointSize =
991
8 * drawingParameters.pixelScalingFactor;
992
editMarkersRoot->addChild(editModeScenegraphNodes.EditMarkersDrawStyle);
994
editModeScenegraphNodes.EditMarkerSet = new SoMarkerSet;
995
editModeScenegraphNodes.EditMarkerSet->setName("EditMarkerSet");
996
editModeScenegraphNodes.EditMarkerSet->markerIndex =
997
Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_LINE", drawingParameters.markerSize);
998
editMarkersRoot->addChild(editModeScenegraphNodes.EditMarkerSet);
1000
// stuff for the edit coordinates ++++++++++++++++++++++++++++++++++++++
1001
SoSeparator* Coordsep = new SoSeparator();
1002
SoPickStyle* ps = new SoPickStyle();
1003
ps->style.setValue(SoPickStyle::UNPICKABLE);
1004
Coordsep->addChild(ps);
1005
Coordsep->setName("CoordSeparator");
1006
// no caching for frequently-changing data structures
1007
Coordsep->renderCaching = SoSeparator::OFF;
1009
editModeScenegraphNodes.textMaterial = new SoMaterial;
1010
editModeScenegraphNodes.textMaterial->setName("CoordTextMaterials");
1011
editModeScenegraphNodes.textMaterial->diffuseColor = drawingParameters.CursorTextColor;
1012
Coordsep->addChild(editModeScenegraphNodes.textMaterial);
1014
editModeScenegraphNodes.textFont = new SoFont();
1015
editModeScenegraphNodes.textFont->name.setValue("Helvetica");
1016
editModeScenegraphNodes.textFont->size.setValue(drawingParameters.coinFontSize);
1018
Coordsep->addChild(editModeScenegraphNodes.textFont);
1020
editModeScenegraphNodes.textPos = new SoTranslation();
1021
Coordsep->addChild(editModeScenegraphNodes.textPos);
1023
editModeScenegraphNodes.textX = new SoText2();
1024
editModeScenegraphNodes.textX->justification = SoText2::LEFT;
1025
editModeScenegraphNodes.textX->string = "";
1026
Coordsep->addChild(editModeScenegraphNodes.textX);
1027
editModeScenegraphNodes.EditRoot->addChild(Coordsep);
1029
// coin nodes for the constraints +++++++++++++++++++++++++++++++++++++++++++++++++++
1030
pEditModeConstraintCoinManager->createEditModeInventorNodes();
1032
// group node for the Geometry information visual +++++++++++++++++++++++++++++++++++
1033
MtlBind = new SoMaterialBinding;
1034
MtlBind->setName("InformationMaterialBinding");
1035
MtlBind->value = SoMaterialBinding::OVERALL;
1036
editModeScenegraphNodes.EditRoot->addChild(MtlBind);
1038
// use small line width for the information visual
1039
editModeScenegraphNodes.InformationDrawStyle = new SoDrawStyle;
1040
editModeScenegraphNodes.InformationDrawStyle->setName("InformationDrawStyle");
1041
editModeScenegraphNodes.InformationDrawStyle->lineWidth =
1042
1 * drawingParameters.pixelScalingFactor;
1043
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.InformationDrawStyle);
1045
// add the group where all the information entity has its SoSeparator
1046
editModeScenegraphNodes.infoGroup = new SoGroup();
1047
editModeScenegraphNodes.infoGroup->setName("InformationGroup");
1048
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.infoGroup);
1051
void EditModeCoinManager::redrawViewProvider()
1053
viewProvider.draw(false, false);
1056
/************************ Delegated constraint public interface **********/
1058
// public function that triggers drawing of most constraint icons
1059
void EditModeCoinManager::drawConstraintIcons()
1061
pEditModeConstraintCoinManager->drawConstraintIcons();
1064
void EditModeCoinManager::drawConstraintIcons(const GeoListFacade& geolistfacade)
1066
pEditModeConstraintCoinManager->drawConstraintIcons(geolistfacade);
1069
void EditModeCoinManager::updateVirtualSpace()
1071
pEditModeConstraintCoinManager->updateVirtualSpace();
1074
/************************ Resizing of coin nodes ************************/
1076
int EditModeCoinManager::defaultApplicationFontSizePixels() const
1078
return ViewProviderSketchCoinAttorney::defaultApplicationFontSizePixels(viewProvider);
1081
int EditModeCoinManager::getApplicationLogicalDPIX() const
1083
return ViewProviderSketchCoinAttorney::getApplicationLogicalDPIX(viewProvider);
1086
void EditModeCoinManager::updateInventorNodeSizes()
1088
auto layersconfiguration = viewProvider.VisualLayerList.getValues();
1090
updateInventorWidths();
1092
for (int l = 0; l < geometryLayerParameters.getCoinLayerCount(); l++) {
1093
editModeScenegraphNodes.PointsDrawStyle[l]->pointSize =
1094
8 * drawingParameters.pixelScalingFactor;
1095
editModeScenegraphNodes.PointSet[l]->markerIndex =
1096
Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_FILLED",
1097
drawingParameters.markerSize);
1100
editModeScenegraphNodes.RootCrossDrawStyle->lineWidth =
1101
2 * drawingParameters.pixelScalingFactor;
1102
editModeScenegraphNodes.EditCurvesDrawStyle->lineWidth =
1103
3 * drawingParameters.pixelScalingFactor;
1104
editModeScenegraphNodes.EditMarkersDrawStyle->pointSize =
1105
8 * drawingParameters.pixelScalingFactor;
1106
editModeScenegraphNodes.EditMarkerSet->markerIndex =
1107
Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_LINE", drawingParameters.markerSize);
1108
editModeScenegraphNodes.ConstraintDrawStyle->lineWidth =
1109
1 * drawingParameters.pixelScalingFactor;
1110
editModeScenegraphNodes.InformationDrawStyle->lineWidth =
1111
1 * drawingParameters.pixelScalingFactor;
1113
editModeScenegraphNodes.textFont->size.setValue(drawingParameters.coinFontSize);
1115
pEditModeConstraintCoinManager->rebuildConstraintNodes();
1118
void EditModeCoinManager::updateInventorWidths()
1120
editModeScenegraphNodes.CurvesDrawStyle->lineWidth =
1121
drawingParameters.CurveWidth * drawingParameters.pixelScalingFactor;
1122
editModeScenegraphNodes.CurvesConstructionDrawStyle->lineWidth =
1123
drawingParameters.ConstructionWidth * drawingParameters.pixelScalingFactor;
1124
editModeScenegraphNodes.CurvesInternalDrawStyle->lineWidth =
1125
drawingParameters.InternalWidth * drawingParameters.pixelScalingFactor;
1126
editModeScenegraphNodes.CurvesExternalDrawStyle->lineWidth =
1127
drawingParameters.ExternalWidth * drawingParameters.pixelScalingFactor;
1130
void EditModeCoinManager::updateInventorPatterns()
1132
editModeScenegraphNodes.CurvesDrawStyle->linePattern = drawingParameters.CurvePattern;
1133
editModeScenegraphNodes.CurvesConstructionDrawStyle->linePattern =
1134
drawingParameters.ConstructionPattern;
1135
editModeScenegraphNodes.CurvesInternalDrawStyle->linePattern =
1136
drawingParameters.InternalPattern;
1137
editModeScenegraphNodes.CurvesExternalDrawStyle->linePattern =
1138
drawingParameters.ExternalPattern;
1141
void EditModeCoinManager::updateInventorColors()
1143
editModeScenegraphNodes.RootCrossMaterials->diffuseColor.set1Value(
1145
drawingParameters.CrossColorH);
1146
editModeScenegraphNodes.RootCrossMaterials->diffuseColor.set1Value(
1148
drawingParameters.CrossColorV);
1149
editModeScenegraphNodes.textMaterial->diffuseColor = drawingParameters.CursorTextColor;
1152
/************************ Edit node access ************************/
1154
SoSeparator* EditModeCoinManager::getRootEditNode()
1156
return editModeScenegraphNodes.EditRoot;