Files
create/src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.h
Abdullah Tahiri 1b91bf1883 EditCoinManager: Ensure rootpoint is higher than constraints
============================================================

Following new behaviour of highlighting root point on full constrained:
https://forum.freecadweb.org/viewtopic.php?p=555663#p555663

the rootpoint was lowered in virtual height with respect to the rest of points, so that
the color of any other overlapping point takes precedence.

However, this made it the same height as constraints, causing it to be unpickable in presence of
a colocated constraint:
https://forum.freecadweb.org/viewtopic.php?p=556114#p556114

Solution: Raise all points by one
2021-12-27 21:03:51 +01:00

419 lines
18 KiB
C++

/***************************************************************************
* Copyright (c) 2021 Abdullah Tahiri <abdullah.tahiri.yo@gmail.com> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef SKETCHERGUI_EditModeCoinManagerParameters_H
#define SKETCHERGUI_EditModeCoinManagerParameters_H
#ifndef _PreComp_
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoCoordinate3.h>
# include <Inventor/nodes/SoLineSet.h>
# include <Inventor/nodes/SoGroup.h>
# include <Inventor/nodes/SoMarkerSet.h>
# include <Inventor/nodes/SoText2.h>
# include <Inventor/nodes/SoPickStyle.h>
# include <Inventor/nodes/SoTranslation.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/SbColor.h>
#endif // #ifndef _PreComp_
#include <Gui/Inventor/SmSwitchboard.h>
#include <qstring.h>
#include <qcolor.h>
#include <Mod/Sketcher/App/GeoList.h>
#include <vector>
#include <map>
namespace Part {
class Geometry;
}
namespace SketcherGui {
/** @brief Struct for storing local drawing parameters
*
* Parameters based on user preferenced are auto loaded by EditCoinManager observer nested class.
*/
struct DrawingParameters {
/// Defines the number of segments to use to draw a curved edge
int curvedEdgeCountSegments;
/** @name Rendering Heights - virtual height introduced in the scenegraph to determine what is drawn on top of what*/
//@{
const float zEdit = 0.001f; // Height used by temporal edit curves
const float zCross = 0.001f; // Height used by the Axes
const float zInfo = 0.004f; // Height used by the Overlay information layer
const float zLowLines = 0.005f; // Height used for bottom rendered lines
const float zMidLines = 0.006f; // Height used for in-the-middle rendered lines
const float zHighLines = 0.007f; // Height used for on top rendered lines
const float zHighLine = 0.008f; // Height for highlighted lines (selected/preselected)
const float zConstr = 0.009f; // Height for rendering constraints
const float zRootPoint = 0.010f; // Height used for bottom rendered points
const float zLowPoints = 0.011f; // Height used for bottom rendered points
const float zHighPoints = 0.012f; // Height used for in-the-middle rendered points
const float zHighlight = 0.013f; // Height for highlighted points (selected/preselected)
const float zText = 0.013f; // Height for rendered text
//@}
/// Different categories of geometries that can be selected by the user to be rendered on top, in the middle or in the bottom
enum class GeometryRendering {
NormalGeometry = 1,
Construction = 2,
ExternalGeometry = 3
};
/** @name Rendering Order - defining what should be rendered on top and in the middle*/
//@{
GeometryRendering topRenderingGeometry = GeometryRendering::NormalGeometry;
GeometryRendering midRenderingGeometry = GeometryRendering::Construction;
//@}
/** @name Rendering Coin Colors **/
//@{
static SbColor InformationColor; // Information Overlay Color
static SbColor CreateCurveColor; // Color for Edit Curves during creation
static SbColor CrossColorH; // Color for the Horizontal Axis
static SbColor CrossColorV; // Color for the Vertical Axis
static SbColor InvalidSketchColor; // Color for rendering an invalid sketch
static SbColor FullyConstrainedColor; // Color for a fully constrained sketch
static SbColor FullyConstraintInternalAlignmentColor; // Color for fully constrained internal alignment geometry
static SbColor InternalAlignedGeoColor; // Color for non-fully constrained internal alignment geometry
static SbColor FullyConstraintConstructionPointColor; // Color for fully constrained construction points
static SbColor VertexColor; // Color for vertices
static SbColor FullyConstraintElementColor; // Color for a fully constrained element
static SbColor CurveColor; // Color for curves
static SbColor PreselectColor; // Color used for pre-selection
static SbColor PreselectSelectedColor; // Color used for pre-selection when geometry is already selected
static SbColor SelectColor; // Color used for selected geometry
static SbColor CurveExternalColor; // Color used for external geometry
static SbColor CurveDraftColor; // Color used for construction geometry
static SbColor FullyConstraintConstructionElementColor; // Color used for a fully constrained construction element
static SbColor ConstrDimColor; // Color used for a dimensional constraints
static SbColor ConstrIcoColor; // Color used for constraint icons
static SbColor NonDrivingConstrDimColor; // Color used for non-driving (reference) dimensional constraints
static SbColor ExprBasedConstrDimColor; // Color used for expression based dimensional constraints
static SbColor DeactivatedConstrDimColor; // Color used for deactivated dimensional constraints
//@}
/** @name Rendering Icon colors **/
//@{
static QColor constrIcoColor; // Icon color for constraints
static QColor nonDrivingConstrIcoColor; // Icon color for references (non-driving constraints)
static QColor constrIconSelColor; // Icon color for selected constraints
static QColor constrIconPreselColor; // Icon color for preselected constraints
static QColor constrIconDisabledColor; // Icon color for disabled constraints
//@}
/** @name Rendering sizes (also to support HDPI monitors) **/
//@{
double pixelScalingFactor = 1.0; // Scaling factor to be used for pixels
int coinFontSize = 17; // Font size to be used by coin
int constraintIconSize = 15; // Size of constraint icons
int markerSize = 7; // Size used for markers
//@}
};
/** @brief Struct for storing references to the scenegraph nodes necessary for geometry layers
*/
struct GeometryLayerNodes {
/** @name Point nodes*/
//@{
std::vector<SoMaterial *> & PointsMaterials; // The materials for the points/vertices
std::vector<SoCoordinate3 *>& PointsCoordinate; // The coordinates of the points/vertices
//@}
/** @name Curve nodes*/
//@{
std::vector<SoMaterial *> & CurvesMaterials; // The materials for the curves
std::vector<SoCoordinate3 *> & CurvesCoordinate; // The coordinates of the segments of the curves
std::vector<SoLineSet *> & CurveSet; // The set of curves
//@}
};
/** @brief
* Helper class to store together a field index of a coin multifield object and the coin geometry layer to
* which it belongs.
*
* @details
*
* @warning the layer is * not * the logical layer (the one of GeometryFacade), but the coin layer. See GeometryLayerParameters.
*
* Overloaded operators and specialisation of std::less enable it to be used in containers including ordered
* containers.
*/
class MultiFieldId {
public:
explicit constexpr MultiFieldId(int fieldindex = -1, int layerid = 0): fieldIndex(fieldindex),
layerId(layerid){}
MultiFieldId(const MultiFieldId & ) = default;
MultiFieldId & operator=(const MultiFieldId &) = default;
MultiFieldId(MultiFieldId && ) = default;
MultiFieldId & operator=(MultiFieldId &&) = default;
inline bool operator==(const MultiFieldId& obj) const
{
return this->fieldIndex == obj.fieldIndex && this->layerId == obj.layerId;
}
inline bool operator!=(const MultiFieldId& obj) const
{
return this->fieldIndex != obj.fieldIndex || this->layerId != obj.layerId;
}
int fieldIndex = -1;
int layerId = 0;
static const MultiFieldId Invalid;
};
} // namespace SketcherGui
namespace std
{
template<> struct less<SketcherGui::MultiFieldId>
{
bool operator() (const SketcherGui::MultiFieldId& lhs, const SketcherGui::MultiFieldId& rhs) const
{
return (lhs.layerId != rhs.layerId)?(lhs.layerId < rhs.layerId):(static_cast<int>(lhs.fieldIndex) < static_cast<int>(rhs.fieldIndex));
}
};
} // namespace std
namespace SketcherGui {
/** @brief
* Helper class to store geometry layers configuration
*
* CoinLayers is the number of * Coin * Geometry Layers. This
* is *not* necessarily the number of Geometry layers (logical layers).
*
* Logical layers (as stored in GeometryFacade) define a grouping of geometries.
* However, this does not mean that they are represented in coin in different layers.
* Only when there is a reason for such mapping is done so. For example, when the
* geometry have different drawing parameters.
*
* This means that there may be:
* 1. A N:N relationship between logical layers and coin layers.
* 2. A M:N relationship between logical layers and coin layers (M<N), including a 1:N relationship.
*/
class GeometryLayerParameters {
public:
GeometryLayerParameters() { reset();}
private:
enum CoinLayer {
Default = 0
};
public:
void reset() {
CoinLayers = 1;
logicalLayer2CoinLayer.clear();
logicalLayer2CoinLayer.push_back(Default); // Logical layer 1 always maps to CoinLayer 1
}
int getCoinLayer(int logicallayer) {
if(logicallayer < int(logicalLayer2CoinLayer.size()))
return logicalLayer2CoinLayer[logicallayer];
return Default;
}
int CoinLayers = 1; // defaults to a single Coin Geometry Layer.
private:
/// This maps a logicalLayer (the one of GeometryFacade) to a CoinLayer (the ones created in the scenegraph)
std::vector<int> logicalLayer2CoinLayer;
};
/** @brief Struct to hold the results of analysis performed on geometry
*/
struct AnalysisResults { // TODO: This needs to be refactored
double combRepresentationScale = 0; // used for information overlay (BSpline comb)
float boundingBoxMagnitudeOrder = 0; // used for grid extension
std::vector<int> bsplineGeoIds; // used for information overlay
};
/** @brief Struct adapted to store the parameters necessary to create and update
* the information overlay layer.
*/
struct OverlayParameters {
bool rebuildInformationLayer = false;
bool visibleInformationChanged = true;
double currentBSplineCombRepresentationScale = 0;
// Parameters (auto loaded by EditCoinManager observer nested class)
bool bSplineDegreeVisible;
bool bSplineControlPolygonVisible;
bool bSplineCombVisible;
bool bSplineKnotMultiplicityVisible;
bool bSplinePoleWeightVisible;
};
/** @brief Struct adapted to store the parameters necessary to create and update
* constraints.
*/
struct ConstraintParameters {
bool bHideUnits; // whether units should be hidden or not
bool bShowDimensionalName; // whether the name of dimensional constraints should be shown or not
QString sDimensionalStringFormat; // how to code strings of dimensional constraints
};
/** @brief Helper struct adapted to store the pointer to edit mode scenegraph objects.
*/
struct EditModeScenegraphNodes {
/** @name Point nodes*/
//@{
SoSeparator * EditRoot;
SmSwitchboard * PointsGroup;
std::vector<SoMaterial *> PointsMaterials;
std::vector<SoCoordinate3 *> PointsCoordinate;
std::vector<SoDrawStyle *> PointsDrawStyle;
std::vector<SoMarkerSet *> PointSet;
//@}
/** @name Curve nodes*/
//@{
SmSwitchboard * CurvesGroup;
std::vector<SoMaterial *> CurvesMaterials;
std::vector<SoCoordinate3 *> CurvesCoordinate;
std::vector<SoDrawStyle *> CurvesDrawStyle;
std::vector<SoLineSet *> CurveSet;
//@}
/** @name Axes nodes*/
/// @warning Root Point is added together with the Point nodes above
//@{
SoMaterial *RootCrossMaterials;
SoCoordinate3 *RootCrossCoordinate;
SoLineSet *RootCrossSet;
SoDrawStyle *RootCrossDrawStyle;
//@}
/** @name Temporal edit curve nodes - For geometry creation */
//@{
SoMaterial *EditCurvesMaterials;
SoCoordinate3 *EditCurvesCoordinate;
SoLineSet *EditCurveSet;
SoDrawStyle *EditCurvesDrawStyle;
SoPickStyle *pickStyleAxes;
//@}
/** @name Temporal edit markers nodes- For operation rendering, such as trimming green circles*/
//@{
SoMaterial *EditMarkersMaterials;
SoCoordinate3 *EditMarkersCoordinate;
SoMarkerSet *EditMarkerSet;
SoDrawStyle *EditMarkersDrawStyle;
//@}
/** @name Temporal edit text nodes*/
//@{
SoText2 *textX;
SoTranslation *textPos;
//@}
/** @name Constraint nodes*/
//@{
SmSwitchboard *constrGroup;
SoDrawStyle *ConstraintDrawStyle;
//@}
/** @name Information Overlay Layer nodes*/
//@{
SoGroup *infoGroup;
SoDrawStyle *InformationDrawStyle;
//@}
};
/** @brief Helper struct containing index conversions (mappings) between
* {GeoId, PointPos} and MF indices per layer, and VertexId and MF indices per layer.
*
* These are updated with every draw of the scenegraph.
*/
struct CoinMapping {
void clear() {
CurvIdToGeoId.clear();
PointIdToGeoId.clear();
GeoElementId2SetId.clear();
PointIdToVertexId.clear();
};
/// given the MF index of a curve and the coin layer in which it is drawn returns the GeoId of the curve
int getCurveGeoId(int curveindex, int layerindex) {return CurvIdToGeoId[layerindex][curveindex];}
/// given the MF index of a point and the coin layer in which it is drawn returns the GeoId of the point
int getPointGeoId(int pointindex, int layerindex) {return PointIdToGeoId[layerindex][pointindex];}
/// given the MF index of a point and the coin layer in which it is drawn returns the VertexId of the point
int getPointVertexId(int pointindex, int layerindex) {return PointIdToVertexId[layerindex][pointindex];}
/// given the {GeoId, PointPos} of a curve or point, returns MultiFieldId containing the MF index and the coin layer of the curve or point
MultiFieldId getIndexLayer(int geoid, Sketcher::PointPos pos) {
auto indexit = GeoElementId2SetId.find(Sketcher::GeoElementId(geoid, pos));
if (indexit != GeoElementId2SetId.end()) {
return indexit->second;
}
return MultiFieldId::Invalid;
}
/// given the VertexId of a point, returns MultiFieldId containing the MF index and the coin layer of the point
MultiFieldId getIndexLayer(int vertexId) {
for(size_t l=0; l<PointIdToVertexId.size(); l++) {
auto indexit = std::find(PointIdToVertexId[l].begin(), PointIdToVertexId[l].end(), vertexId);
if(indexit != PointIdToVertexId[l].end())
return MultiFieldId(std::distance(PointIdToVertexId[l].begin(),indexit),l);
}
return MultiFieldId::Invalid;
}
//* These map a MF index (second index) within a coin layer (first index) for points or curves to a GeoId */
std::vector<std::vector<int>> CurvIdToGeoId; // conversion of SoLineSet index to GeoId
std::vector<std::vector<int>> PointIdToGeoId; // conversion of SoCoordinate3 index to GeoId
//* This maps an MF index (second index) of a point within a coin layer (first index) to a global VertexId */
std::vector<std::vector<int>> PointIdToVertexId;
/// This maps GeoElementId index {GeoId, PointPos} to a {coin layer and MF index} of a curve or point.
std::map<Sketcher::GeoElementId,MultiFieldId> GeoElementId2SetId;
};
} // namespace SketcherGui
#endif // SKETCHERGUI_EditModeCoinManagerParameters_H