============================================================ 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
419 lines
18 KiB
C++
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
|
|
|