Files
create/src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.h

420 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 rendering the root point
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;
SoPickStyle *constrGrpSelect;
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