Sketcher: EditModeCoinManager/DrawSkechHandler refactoring
====================================================== Creation of EditModeCoinManager class and helpers. In a nutshell: - EditModeCoinManager gets most of the content of struct EditData - Drawing is partly outsourced to EditModeCoinManager - EditModeCoinManager gets a nested Observer class to deal with parameters - A struct DrawingParameters is created to store all parameters used for drawing - EditModeCoinManager assume responsibility for determining the drawing size of the Axes - Preselection detection responsibility is moved to EditModeCoinManager. - Generation of constraint nodes and constraint drawing is moved to EditModeCoinManager. - Constraint generation parameters are refactored into ConstraintParameters. - Text rendering functions are moved to EditModeCoinManager. - Move HDPI resolution responsibility from VPSketch to EditModeCoinManager - Move responsibility to create the scenograph for edit mode to EditModeCoinManager - Move full updateColor responsibility to EditModeCoinManager - Allows for mapping N logical layers (LayerId of GeometryFacade) to M coin Layers (M<N). This is convenient as, unless the representation must be different, there is no point in creating coin layers (overhead). Refactoring of geometry drawing: - Determination of the curve values to draw are outsourced to OCC (SRP and remove code duplications). - Refactor specific drawing of each geometry type into a single template method, based on classes of geometry. - Drawing of geometry and constraints made agnostic of scale factors of BSpline weights so that a uniform treatment can be provided. Refactoring of Overlay Layer: - A new class EditModeInformationOverlayConverter is a full rewrite of the previous overlay routines. ViewProviderSketch: - Major cleanup due to migration of functionalities to EditModeCoinManager - Reduce public api of ViewProviderSketch due to refactor of DrawSketchHandler - Major addition of documentation - ShortcutListener implementation using new ViewProvider Attorney - Gets a parameter handling nested class to handle all parameters (observer) - Move rubberband to smart pointer - Refactor selection and preselection into nested classes - Removal of SEL_PARAMS macro. This macro was making the code unreadable as it "captured" a local stringstream that appeared unused. Substituted by local private member functions. - Remove EditData - Improve documentation - Refactor Preselection struct to remove magical numbers - Refactor Selection mechanism to remove hacks ViewProviderSketchDrawSketchHandlerAttorney: - new Attorney to limit access to ViewProviderSketch and reduce its public interface - In order to enforce a certain degree of encapsulation and promote a not too tight coupling, while still allowing well defined collaboration, DrawSketchHandler accesses ViewProviderSketch via this Attorney class. -DrawSketchHandler has the responsibility of drawing edit temporal curves and markers necessary to enable visual feedback to the user, as well as the UI interaction during such edits. This is its exclusive responsibility under the Single Responsibility Principle. - A plethora of speciliased handlers derive from DrawSketchHandler for each specialised editing (see for example all the handlers for creation of new geometry). These derived classes do * not * have direct access to the ViewProviderSketchDrawSketchHandlerAttorney. This is intentional to keep coupling under control. However, generic functionality requiring access to the Attorney can be implemented in DrawSketchHandler and used from its derived classes by virtue of the inheritance. This promotes a concentrating the coupling in a single point (and code reuse). EditModeCoinManager: - Refactor of updateConstraintColor - Multifield - new struct to identify a single element in a multifield field per layer - Move geometry management to delegate class EditModeCoinGeometryManager - Remove refactored code that was never used in the original ViewProviderSketch. CommandSketcherBSpline: - EditModeCoinManager automatically tracks parameter change and triggers the necessary redraw, rendering an explicit redraw obsolete and unnecessary. Rebase on top of master: - Commits added to master to ViewProviderSketch applied to EditModeCoinManager. - Memory leaks - wmayer - Constraint Diameter Symbol - OpenBrain - Minor bugfix to display angle constraints - syres Architecture Description ======================= * Encapsulation and collaboration - restricting friendship - reducing public interface Summary: - DrawSketchHandler to ViewProviderSketch friendship regulated via attorney. - ShortcutListener to ViewProviderSketch friendship regulated via attorney. - EditModeCoinManager (new class) to ViewProviderSketch friendship regulated via attorney. - ViewProviderSketch public interface is heavily reduced. In further detail: While access from ViewProviderSketch to other classes is regulated via their public interface, DrawSketchHandler, ShortcutListener and EditCoinManager (new class) access to ViewProviderSketch non-public interface via attorneys. Previously, it was an unrestricted access (friend classes). Now this interface is restricted and regulated via attorneys. This increases the encapsulation of ViewProviderSketch, reduces the coupling between classes and promotes an ordered growth. This I call the "collaboration interface". At the same time, ViewProviderSketch substantially reduces its public interface. Access from Command draw handlers (deriving from DrawSketchHandler) is intended to be restricted to the functionality exposed by DrawSketchHandler to its derived classes. However, this is still only partly enforced to keep the refactoring within limits. A further refactoring of DrawSketchHandler and derivatives is for future discussion. * Complexity and delegation Summary: - Complexity of coin node management is dealt with by delegation to helper classes and specialised objects. In further detail: ViewProviderSketch is halved in terms of code size. Higher level ViewProviderSketch functions remain * Automatic update of parameters - Parameter observer nested classes Summary: - ViewProviderSketch and CoinManager get their own observer nested classes to monitor the parameters relevant to them and automatically update on change. The split enables that each class deals only with parameters within their own responsibilities, effectively isolating the specifics and decoupling the implementations. It is more convenient as there is no need to leave edit mode to update parameters. It is more compact as it leverages core code. More information: https://forum.freecadweb.org/viewtopic.php?p=553257#p553257
This commit is contained in:
committed by
abdullahtahiriyo
parent
2f77d3bc95
commit
71c9dc3e0e
@@ -103,6 +103,20 @@ SET(SketcherGui_SRCS
|
||||
TaskSketcherValidation.h
|
||||
ShortcutListener.cpp
|
||||
ShortcutListener.h
|
||||
EditModeInformationOverlayCoinConverter.cpp
|
||||
EditModeInformationOverlayCoinConverter.h
|
||||
EditModeGeometryCoinConverter.cpp
|
||||
EditModeGeometryCoinConverter.h
|
||||
EditModeCoinManagerParameters.h
|
||||
EditModeCoinManagerParameters.cpp
|
||||
EditModeCoinManager.cpp
|
||||
EditModeCoinManager.h
|
||||
EditModeGeometryCoinManager.cpp
|
||||
EditModeGeometryCoinManager.h
|
||||
EditModeConstraintCoinManager.cpp
|
||||
EditModeConstraintCoinManager.h
|
||||
ViewProviderSketchCoinAttorney.cpp
|
||||
ViewProviderSketchCoinAttorney.h
|
||||
ViewProviderSketch.cpp
|
||||
ViewProviderSketch.h
|
||||
DrawSketchHandler.cpp
|
||||
|
||||
@@ -740,9 +740,9 @@ public:
|
||||
SelType newSelType = SelUnknown;
|
||||
|
||||
//For each SelType allowed, check if button is released there and assign it to selIdPair
|
||||
int VtId = sketchgui->getPreselectPoint();
|
||||
int CrvId = sketchgui->getPreselectCurve();
|
||||
int CrsId = sketchgui->getPreselectCross();
|
||||
int VtId = getPreselectPoint();
|
||||
int CrvId = getPreselectCurve();
|
||||
int CrsId = getPreselectCross();
|
||||
if (allowedSelTypes & (SelRoot | SelVertexOrRoot) && CrsId == 0) {
|
||||
selIdPair.GeoId = Sketcher::GeoEnum::RtPnt;
|
||||
selIdPair.PosId = Sketcher::PointPos::start;
|
||||
@@ -1809,8 +1809,8 @@ public:
|
||||
|
||||
virtual bool releaseButton(Base::Vector2d onSketchPos)
|
||||
{
|
||||
int VtId = sketchgui->getPreselectPoint();
|
||||
int CrsId = sketchgui->getPreselectCross();
|
||||
int VtId = getPreselectPoint();
|
||||
int CrsId = getPreselectCross();
|
||||
std::stringstream ss;
|
||||
int GeoId_temp;
|
||||
Sketcher::PointPos PosId_temp;
|
||||
|
||||
@@ -289,7 +289,7 @@ public:
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
EditCurve[1] = onSketchPos;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - EditCurve[0])) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
@@ -306,7 +306,7 @@ public:
|
||||
}
|
||||
else {
|
||||
EditCurve[1] = onSketchPos;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
return true;
|
||||
@@ -353,7 +353,7 @@ public:
|
||||
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
|
||||
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
|
||||
if(continuousMode){
|
||||
@@ -484,7 +484,7 @@ public:
|
||||
EditCurve[4] = EditCurve[0];
|
||||
}
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.0,0.0))) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
@@ -512,7 +512,7 @@ public:
|
||||
EditCurve[2] = onSketchPos;
|
||||
EditCurve[1] = Base::Vector2d(onSketchPos.x ,EditCurve[0].y);
|
||||
EditCurve[3] = Base::Vector2d(EditCurve[0].x,onSketchPos.y);
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
else if (constructionMethod == CenterAndCorner) {
|
||||
@@ -521,7 +521,7 @@ public:
|
||||
EditCurve[2] = onSketchPos;
|
||||
EditCurve[3] = Base::Vector2d(onSketchPos.x,EditCurve[0].y);
|
||||
EditCurve[4] = EditCurve[0];
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
}
|
||||
@@ -659,7 +659,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode=STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(5);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -855,7 +855,7 @@ public:
|
||||
text.sprintf(" (%.1fR %.1fX %.1fY)", radius, lengthX, lengthY);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f, 0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
@@ -1027,7 +1027,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(37);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -1366,7 +1366,7 @@ public:
|
||||
EditCurve[1] = EditCurve[0] + EditCurve[1];
|
||||
}
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
float length = (EditCurve[1] - EditCurve[0]).Length();
|
||||
float angle = (EditCurve[1] - EditCurve[0]).GetAngle(Base::Vector2d(1.f,0.f));
|
||||
@@ -1447,7 +1447,7 @@ public:
|
||||
EditCurve[30] = CenterPoint;
|
||||
EditCurve[31] = EditCurve[0];
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
SbString text;
|
||||
text.sprintf(" (%.1fR,%.1fdeg)", std::abs(arcRadius), arcAngle * 180 / M_PI);
|
||||
@@ -1508,7 +1508,7 @@ public:
|
||||
unsetCursor();
|
||||
resetPositionText();
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
|
||||
@@ -1525,7 +1525,7 @@ public:
|
||||
firstPosId=Sketcher::PointPos::none;
|
||||
previousPosId=Sketcher::PointPos::none;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -1542,14 +1542,14 @@ public:
|
||||
|
||||
Mode = STATUS_Do;
|
||||
|
||||
if (sketchgui->getPreselectPoint() != -1 && firstPosId != Sketcher::PointPos::none) {
|
||||
if (getPreselectPoint() != -1 && firstPosId != Sketcher::PointPos::none) {
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId;
|
||||
sketchgui->getSketchObject()->getGeoVertexIndex(sketchgui->getPreselectPoint(),GeoId,PosId);
|
||||
sketchgui->getSketchObject()->getGeoVertexIndex(getPreselectPoint(),GeoId,PosId);
|
||||
if (sketchgui->getSketchObject()->arePointsCoincident(GeoId,PosId,firstCurve,firstPosId))
|
||||
Mode = STATUS_Close;
|
||||
}
|
||||
else if (sketchgui->getPreselectCross() == 0 && firstPosId != Sketcher::PointPos::none) {
|
||||
else if (getPreselectCross() == 0 && firstPosId != Sketcher::PointPos::none) {
|
||||
// close line started at root point
|
||||
if (sketchgui->getSketchObject()->arePointsCoincident(-1,Sketcher::PointPos::start,firstCurve,firstPosId))
|
||||
Mode = STATUS_Close;
|
||||
@@ -1672,7 +1672,7 @@ public:
|
||||
|
||||
resetPositionText();
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
|
||||
@@ -1689,7 +1689,7 @@ public:
|
||||
firstPosId=Sketcher::PointPos::none;
|
||||
previousPosId=Sketcher::PointPos::none;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -1790,7 +1790,7 @@ public:
|
||||
previousPosId=Sketcher::PointPos::none;
|
||||
firstsegment=true;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
}
|
||||
@@ -1948,7 +1948,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fdeg)", radius, angle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
@@ -1973,7 +1973,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fdeg)", radius, arcAngle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0,0.0))) {
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
return;
|
||||
@@ -2014,7 +2014,7 @@ public:
|
||||
startAngle += arcAngle;
|
||||
}
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
applyCursor();
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
@@ -2071,7 +2071,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode=STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -2179,7 +2179,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fdeg)", (float) radius, (float) lineAngle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
@@ -2249,7 +2249,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fdeg)", (float) radius, (float) arcAngle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.0,0.0),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
@@ -2283,7 +2283,7 @@ public:
|
||||
else {
|
||||
EditCurve.resize(30);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
applyCursor();
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
@@ -2340,7 +2340,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode=STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -2538,7 +2538,7 @@ public:
|
||||
text.sprintf(" (%.1fR)", radius);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - EditCurve[0],
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
@@ -2604,7 +2604,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode=STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(34);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -2761,7 +2761,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fR)", semiMajorRadius,semiMajorRadius);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(editCurve);
|
||||
drawEdit(editCurve);
|
||||
// Suggestions for ellipse and curves are disabled because many tangent constraints
|
||||
// need an intermediate point or line.
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f),
|
||||
@@ -2778,7 +2778,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fR)", a, b);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(editCurve);
|
||||
drawEdit(editCurve);
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
@@ -2802,7 +2802,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fR)", semiMajorRadius,semiMajorRadius);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(editCurve);
|
||||
drawEdit(editCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - centroid,
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
@@ -2817,7 +2817,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fR)", a, b);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(editCurve);
|
||||
drawEdit(editCurve);
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, onSketchPos - centroid,
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
@@ -3395,7 +3395,7 @@ private:
|
||||
mode = STATUS_SEEK_PERIAPSIS;
|
||||
}
|
||||
editCurve.clear();
|
||||
sketchgui->drawEdit(editCurve);
|
||||
drawEdit(editCurve);
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
bool continuousMode = hGrp->GetBool("ContinuousCreationMode",true);
|
||||
@@ -3531,7 +3531,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fR)", radius,radius);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, onSketchPos - centerPoint,
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
@@ -3562,7 +3562,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fR)", a, b);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
return;
|
||||
@@ -3601,7 +3601,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fR,%.1fdeg)", a, b, arcAngle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr4);
|
||||
return;
|
||||
@@ -3758,7 +3758,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode=STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(34);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -3851,7 +3851,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fR)", radius,radius);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
@@ -3883,7 +3883,7 @@ public:
|
||||
setPositionText(onSketchPos, text);
|
||||
}
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
return;
|
||||
@@ -3933,7 +3933,7 @@ public:
|
||||
arcAngle=0.;
|
||||
}
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr4);
|
||||
return;
|
||||
@@ -4101,7 +4101,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(34);
|
||||
applyCursor();
|
||||
/* It is ok not to call to purgeHandler
|
||||
@@ -4196,7 +4196,7 @@ public:
|
||||
text.sprintf(" (F%.1f)", radius);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
@@ -4228,7 +4228,7 @@ public:
|
||||
text.sprintf(" (F%.1f)", focal);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
if (seekAutoConstraint(sugConstr3, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr3);
|
||||
@@ -4274,7 +4274,7 @@ public:
|
||||
arcAngle=0.;
|
||||
}
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr4, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr4);
|
||||
return;
|
||||
@@ -4400,7 +4400,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(34);
|
||||
applyCursor();
|
||||
/* It is ok not to call to purgeHandler
|
||||
@@ -4638,7 +4638,7 @@ public:
|
||||
|
||||
EditCurve[EditCurve.size()-1] = onSketchPos;
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
float length = (EditCurve[EditCurve.size()-1] - EditCurve[EditCurve.size()-2]).Length();
|
||||
float angle = (EditCurve[EditCurve.size()-1] - EditCurve[EditCurve.size()-2]).GetAngle(Base::Vector2d(1.f,0.f));
|
||||
@@ -4875,7 +4875,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_FIRST_CONTROLPOINT;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
|
||||
@@ -4928,7 +4928,7 @@ public:
|
||||
// This code disregards existing data and enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_FIRST_CONTROLPOINT;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
|
||||
@@ -5200,7 +5200,7 @@ public:
|
||||
text.sprintf(" (%.1fR,%.1fdeg)", (float) radius, (float) lineAngle * 180 / M_PI);
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (Mode == STATUS_SEEK_Second) {
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f),
|
||||
AutoConstraint::CURVE)) {
|
||||
@@ -5240,7 +5240,7 @@ public:
|
||||
else {
|
||||
EditCurve.resize(N);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
applyCursor();
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
@@ -5297,7 +5297,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode=STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -5694,7 +5694,7 @@ public:
|
||||
virtual bool releaseButton(Base::Vector2d onSketchPos)
|
||||
{
|
||||
bool construction=false;
|
||||
int VtId = sketchgui->getPreselectPoint();
|
||||
int VtId = getPreselectPoint();
|
||||
if (Mode == STATUS_SEEK_First && VtId != -1) {
|
||||
int GeoId;
|
||||
Sketcher::PointPos PosId=Sketcher::PointPos::none;
|
||||
@@ -5755,7 +5755,7 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
int GeoId = sketchgui->getPreselectCurve();
|
||||
int GeoId = getPreselectCurve();
|
||||
if (GeoId > -1) {
|
||||
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
|
||||
if (geom->getTypeId().isDerivedFrom(Part::GeomBoundedCurve::getClassTypeId())) {
|
||||
@@ -6080,7 +6080,7 @@ public:
|
||||
{
|
||||
Q_UNUSED(onSketchPos);
|
||||
|
||||
int GeoId = sketchgui->getPreselectCurve();
|
||||
int GeoId = getPreselectCurve();
|
||||
|
||||
if (GeoId > -1) {
|
||||
auto sk = static_cast<Sketcher::SketchObject *>(sketchgui->getObject());
|
||||
@@ -6106,12 +6106,12 @@ public:
|
||||
EditMarkers.emplace_back( end.x, end.y);
|
||||
}
|
||||
|
||||
sketchgui->drawEditMarkers(EditMarkers, 2); // maker augmented by two sizes (see supported marker sizes)
|
||||
drawEditMarkers(EditMarkers, 2); // maker augmented by two sizes (see supported marker sizes)
|
||||
}
|
||||
}
|
||||
else {
|
||||
EditMarkers.resize(0);
|
||||
sketchgui->drawEditMarkers(EditMarkers, 2);
|
||||
drawEditMarkers(EditMarkers, 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6123,7 +6123,7 @@ public:
|
||||
|
||||
virtual bool releaseButton(Base::Vector2d onSketchPos)
|
||||
{
|
||||
int GeoId = sketchgui->getPreselectCurve();
|
||||
int GeoId = getPreselectCurve();
|
||||
if (GeoId > -1) {
|
||||
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
|
||||
if (geom->getTypeId().isDerivedFrom(Part::GeomTrimmedCurve::getClassTypeId()) ||
|
||||
@@ -6144,7 +6144,7 @@ public:
|
||||
}
|
||||
|
||||
EditMarkers.resize(0);
|
||||
sketchgui->drawEditMarkers(EditMarkers);
|
||||
drawEditMarkers(EditMarkers);
|
||||
}
|
||||
else // exit the trimming tool if the user clicked on empty space
|
||||
sketchgui->purgeHandler(); // no code after this line, Handler get deleted in ViewProvider
|
||||
@@ -6295,7 +6295,7 @@ public:
|
||||
ExtendFromStart = onSketchPos.Distance(startPoint) < onSketchPos.Distance(endPoint);
|
||||
Increment = ExtendFromStart ? projection.Length() : projection.Length() - recenteredLine.Length();
|
||||
}
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
} else if (geom->getTypeId() == Part::GeomArcOfCircle::getClassTypeId()) {
|
||||
const Part::GeomArcOfCircle *arc = static_cast<const Part::GeomArcOfCircle *>(geom);
|
||||
@@ -6358,9 +6358,9 @@ public:
|
||||
double angle = modStartAngle + i * modArcAngle/30.0;
|
||||
EditCurve[i] = Base::Vector2d(center.x + radius * cos(angle), center.y + radius * sin(angle));
|
||||
}
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
}
|
||||
int curveId = sketchgui->getPreselectCurve();
|
||||
int curveId = getPreselectCurve();
|
||||
if (BaseGeoId != curveId && seekAutoConstraint(SugConstr, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(SugConstr);
|
||||
return;
|
||||
@@ -6378,7 +6378,7 @@ public:
|
||||
{
|
||||
Q_UNUSED(onSketchPos);
|
||||
if (Mode == STATUS_SEEK_First) {
|
||||
BaseGeoId = sketchgui->getPreselectCurve();
|
||||
BaseGeoId = getPreselectCurve();
|
||||
if (BaseGeoId > -1) {
|
||||
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(BaseGeoId);
|
||||
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()) {
|
||||
@@ -6429,7 +6429,7 @@ public:
|
||||
Mode=STATUS_SEEK_First;
|
||||
filterGate->setDisabled(false);
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(2);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -6560,7 +6560,7 @@ public:
|
||||
|
||||
virtual bool releaseButton(Base::Vector2d onSketchPos)
|
||||
{
|
||||
int GeoId = sketchgui->getPreselectCurve();
|
||||
int GeoId = getPreselectCurve();
|
||||
if (GeoId >= 0) {
|
||||
const Part::Geometry *geom = sketchgui->getSketchObject()->getGeometry(GeoId);
|
||||
if (geom->getTypeId() == Part::GeomLineSegment::getClassTypeId()
|
||||
@@ -6687,7 +6687,7 @@ public:
|
||||
|
||||
virtual void activated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
sketchgui->setAxisPickStyle(false);
|
||||
setAxisPickStyle(false);
|
||||
Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
|
||||
Gui::View3DInventorViewer *viewer;
|
||||
viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
|
||||
@@ -6703,7 +6703,8 @@ public:
|
||||
|
||||
virtual void deactivated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
sketchgui->setAxisPickStyle(true);
|
||||
Q_UNUSED(sketchgui);
|
||||
setAxisPickStyle(true);
|
||||
}
|
||||
|
||||
virtual void mouseMove(Base::Vector2d onSketchPos)
|
||||
@@ -6869,9 +6870,10 @@ public:
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
}
|
||||
|
||||
|
||||
virtual void activated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
sketchgui->setAxisPickStyle(false);
|
||||
setAxisPickStyle(false);
|
||||
Gui::MDIView *mdi = Gui::Application::Instance->activeDocument()->getActiveView();
|
||||
Gui::View3DInventorViewer *viewer;
|
||||
viewer = static_cast<Gui::View3DInventor *>(mdi)->getViewer();
|
||||
@@ -6887,7 +6889,8 @@ public:
|
||||
|
||||
virtual void deactivated(ViewProviderSketch *sketchgui)
|
||||
{
|
||||
sketchgui->setAxisPickStyle(true);
|
||||
Q_UNUSED(sketchgui);
|
||||
setAxisPickStyle(true);
|
||||
}
|
||||
|
||||
virtual void mouseMove(Base::Vector2d onSketchPos)
|
||||
@@ -7090,7 +7093,7 @@ public:
|
||||
text.sprintf(" (%.1fR %.1fL)", r, sqrt(dx * dx + dy * dy));
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(dx, dy), AutoConstraint::VERTEX_NO_TANGENCY)) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
@@ -7234,7 +7237,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode = STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(35);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
@@ -7359,7 +7362,7 @@ public:
|
||||
text.sprintf(" (%.1fR %.1fdeg)", radius, angle );
|
||||
setPositionText(onSketchPos, text);
|
||||
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr2, onSketchPos, Base::Vector2d(0.f,0.f))) {
|
||||
renderSuggestConstraintsCursor(sugConstr2);
|
||||
return;
|
||||
@@ -7427,7 +7430,7 @@ public:
|
||||
// This code enables the continuous creation mode.
|
||||
Mode=STATUS_SEEK_First;
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
EditCurve.resize(Corners+1);
|
||||
applyCursor();
|
||||
/* this is ok not to call to purgeHandler
|
||||
|
||||
@@ -82,12 +82,11 @@ void ActivateBSplineHandler(Gui::Document *doc,DrawSketchHandler *handler)
|
||||
}
|
||||
}
|
||||
|
||||
void ShowRestoreInformationLayer(SketcherGui::ViewProviderSketch* vp, char * visibleelementname)
|
||||
void ShowRestoreInformationLayer(const char * visibleelementname)
|
||||
{
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
bool status = hGrp->GetBool(visibleelementname, true);
|
||||
hGrp->SetBool(visibleelementname, !status);
|
||||
vp->showRestoreInformationLayer();
|
||||
}
|
||||
|
||||
// Show/Hide B-spline degree
|
||||
@@ -111,9 +110,7 @@ void CmdSketcherBSplineDegree::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
Gui::Document * doc = getActiveGuiDocument();
|
||||
SketcherGui::ViewProviderSketch* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
|
||||
ShowRestoreInformationLayer(vp, "BSplineDegreeVisible");
|
||||
ShowRestoreInformationLayer("BSplineDegreeVisible");
|
||||
}
|
||||
|
||||
bool CmdSketcherBSplineDegree::isActive(void)
|
||||
@@ -142,9 +139,7 @@ void CmdSketcherBSplinePolygon::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
Gui::Document * doc = getActiveGuiDocument();
|
||||
SketcherGui::ViewProviderSketch* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
|
||||
ShowRestoreInformationLayer(vp, "BSplineControlPolygonVisible");
|
||||
ShowRestoreInformationLayer("BSplineControlPolygonVisible");
|
||||
}
|
||||
|
||||
bool CmdSketcherBSplinePolygon::isActive(void)
|
||||
@@ -173,9 +168,7 @@ void CmdSketcherBSplineComb::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
Gui::Document * doc = getActiveGuiDocument();
|
||||
SketcherGui::ViewProviderSketch* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
|
||||
ShowRestoreInformationLayer(vp, "BSplineCombVisible");
|
||||
ShowRestoreInformationLayer("BSplineCombVisible");
|
||||
}
|
||||
|
||||
bool CmdSketcherBSplineComb::isActive(void)
|
||||
@@ -204,9 +197,7 @@ void CmdSketcherBSplineKnotMultiplicity::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
Gui::Document * doc = getActiveGuiDocument();
|
||||
SketcherGui::ViewProviderSketch* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
|
||||
ShowRestoreInformationLayer(vp, "BSplineKnotMultiplicityVisible");
|
||||
ShowRestoreInformationLayer("BSplineKnotMultiplicityVisible");
|
||||
}
|
||||
|
||||
bool CmdSketcherBSplineKnotMultiplicity::isActive(void)
|
||||
@@ -235,9 +226,7 @@ void CmdSketcherBSplinePoleWeight::activated(int iMsg)
|
||||
{
|
||||
Q_UNUSED(iMsg);
|
||||
|
||||
Gui::Document* doc = getActiveGuiDocument();
|
||||
SketcherGui::ViewProviderSketch* vp = static_cast<SketcherGui::ViewProviderSketch*>(doc->getInEdit());
|
||||
ShowRestoreInformationLayer(vp, "BSplinePoleWeightVisible");
|
||||
ShowRestoreInformationLayer("BSplinePoleWeightVisible");
|
||||
}
|
||||
|
||||
bool CmdSketcherBSplinePoleWeight::isActive(void)
|
||||
|
||||
@@ -1350,7 +1350,7 @@ public:
|
||||
setPositionText(endpoint, text);
|
||||
|
||||
EditCurve[1] = endpoint;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr1, endpoint, Base::Vector2d(0.0, 0.0), AutoConstraint::VERTEX)) {
|
||||
renderSuggestConstraintsCursor(sugConstr1);
|
||||
return;
|
||||
@@ -1362,7 +1362,7 @@ public:
|
||||
virtual bool pressButton(Base::Vector2d)
|
||||
{
|
||||
if (Mode == STATUS_SEEK_First) {
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
return true;
|
||||
@@ -1415,7 +1415,7 @@ public:
|
||||
|
||||
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
// no code after this line, Handler gets deleted in ViewProvider
|
||||
sketchgui->purgeHandler();
|
||||
@@ -1899,7 +1899,7 @@ public:
|
||||
setPositionText(endpoint, text);
|
||||
|
||||
EditCurve[1] = endpoint;
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
if (seekAutoConstraint(sugConstr1, endpoint, Base::Vector2d(0.0, 0.0), AutoConstraint::VERTEX))
|
||||
{
|
||||
renderSuggestConstraintsCursor(sugConstr1);
|
||||
@@ -1913,7 +1913,7 @@ public:
|
||||
virtual bool pressButton(Base::Vector2d)
|
||||
{
|
||||
if (Mode == STATUS_SEEK_First) {
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
Mode = STATUS_End;
|
||||
}
|
||||
return true;
|
||||
@@ -1952,7 +1952,7 @@ public:
|
||||
tryAutoRecomputeIfNotSolve(static_cast<Sketcher::SketchObject *>(sketchgui->getObject()));
|
||||
|
||||
EditCurve.clear();
|
||||
sketchgui->drawEdit(EditCurve);
|
||||
drawEdit(EditCurve);
|
||||
|
||||
// no code after this line, Handler is deleted in ViewProvider
|
||||
sketchgui->purgeHandler();
|
||||
|
||||
@@ -59,6 +59,56 @@ using namespace SketcherGui;
|
||||
using namespace Sketcher;
|
||||
|
||||
|
||||
/************************************ Attorney *******************************************/
|
||||
|
||||
inline void ViewProviderSketchDrawSketchHandlerAttorney::setPositionText(ViewProviderSketch &vp, const Base::Vector2d &Pos, const SbString &txt)
|
||||
{
|
||||
vp.setPositionText(Pos,txt);
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchDrawSketchHandlerAttorney::setPositionText(ViewProviderSketch &vp, const Base::Vector2d &Pos)
|
||||
{
|
||||
vp.setPositionText(Pos);
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchDrawSketchHandlerAttorney::resetPositionText(ViewProviderSketch &vp)
|
||||
{
|
||||
vp.resetPositionText();
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(ViewProviderSketch &vp, const std::vector<Base::Vector2d> &EditCurve)
|
||||
{
|
||||
vp.drawEdit(EditCurve);
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchDrawSketchHandlerAttorney::drawEditMarkers(ViewProviderSketch &vp, const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel)
|
||||
{
|
||||
vp.drawEditMarkers(EditMarkers, augmentationlevel);
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchDrawSketchHandlerAttorney::setAxisPickStyle(ViewProviderSketch &vp, bool on)
|
||||
{
|
||||
vp.setAxisPickStyle(on);
|
||||
}
|
||||
|
||||
inline int ViewProviderSketchDrawSketchHandlerAttorney::getPreselectPoint(const ViewProviderSketch &vp)
|
||||
{
|
||||
return vp.getPreselectPoint();
|
||||
}
|
||||
|
||||
inline int ViewProviderSketchDrawSketchHandlerAttorney::getPreselectCurve(const ViewProviderSketch &vp)
|
||||
{
|
||||
return vp.getPreselectCurve();
|
||||
}
|
||||
|
||||
inline int ViewProviderSketchDrawSketchHandlerAttorney::getPreselectCross(const ViewProviderSketch &vp)
|
||||
{
|
||||
return vp.getPreselectCross();
|
||||
}
|
||||
|
||||
/**************************** DrawSketchHandler *******************************************/
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// Construction/Destruction
|
||||
|
||||
@@ -69,8 +119,8 @@ DrawSketchHandler::~DrawSketchHandler() {}
|
||||
void DrawSketchHandler::quit(void)
|
||||
{
|
||||
assert(sketchgui);
|
||||
sketchgui->drawEdit(std::vector<Base::Vector2d>());
|
||||
sketchgui->drawEditMarkers(std::vector<Base::Vector2d>());
|
||||
drawEdit(std::vector<Base::Vector2d>());
|
||||
drawEditMarkers(std::vector<Base::Vector2d>());
|
||||
resetPositionText();
|
||||
|
||||
Gui::Selection().rmvSelectionGate();
|
||||
@@ -314,9 +364,9 @@ int DrawSketchHandler::seekAutoConstraint(std::vector<AutoConstraint> &suggested
|
||||
Base::Vector3d hitShapeDir = Base::Vector3d(0,0,0); // direction of hit shape (if it is a line, the direction of the line)
|
||||
|
||||
// Get Preselection
|
||||
int preSelPnt = sketchgui->getPreselectPoint();
|
||||
int preSelCrv = sketchgui->getPreselectCurve();
|
||||
int preSelCrs = sketchgui->getPreselectCross();
|
||||
int preSelPnt = getPreselectPoint();
|
||||
int preSelCrv = getPreselectCurve();
|
||||
int preSelCrs = getPreselectCross();
|
||||
int GeoId = GeoEnum::GeoUndef;
|
||||
|
||||
Sketcher::PointPos PosId = Sketcher::PointPos::none;
|
||||
@@ -691,16 +741,46 @@ void DrawSketchHandler::renderSuggestConstraintsCursor(std::vector<AutoConstrain
|
||||
|
||||
void DrawSketchHandler::setPositionText(const Base::Vector2d &Pos, const SbString &text)
|
||||
{
|
||||
sketchgui->setPositionText(Pos, text);
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::setPositionText(*sketchgui, Pos, text);
|
||||
}
|
||||
|
||||
|
||||
void DrawSketchHandler::setPositionText(const Base::Vector2d &Pos)
|
||||
{
|
||||
sketchgui->setPositionText(Pos);
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::setPositionText(*sketchgui,Pos);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::resetPositionText(void)
|
||||
{
|
||||
sketchgui->resetPositionText();
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::resetPositionText(*sketchgui);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::drawEdit(const std::vector<Base::Vector2d> &EditCurve)
|
||||
{
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::drawEdit(*sketchgui, EditCurve);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel)
|
||||
{
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::drawEditMarkers(*sketchgui, EditMarkers, augmentationlevel);
|
||||
}
|
||||
|
||||
void DrawSketchHandler::setAxisPickStyle(bool on)
|
||||
{
|
||||
ViewProviderSketchDrawSketchHandlerAttorney::setAxisPickStyle(*sketchgui, on);
|
||||
}
|
||||
|
||||
int DrawSketchHandler::getPreselectPoint(void) const
|
||||
{
|
||||
return ViewProviderSketchDrawSketchHandlerAttorney::getPreselectPoint(*sketchgui);
|
||||
}
|
||||
|
||||
int DrawSketchHandler::getPreselectCurve(void) const
|
||||
{
|
||||
return ViewProviderSketchDrawSketchHandlerAttorney::getPreselectCurve(*sketchgui);
|
||||
}
|
||||
|
||||
int DrawSketchHandler::getPreselectCross(void) const
|
||||
{
|
||||
return ViewProviderSketchDrawSketchHandlerAttorney::getPreselectCross(*sketchgui);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,28 @@ namespace SketcherGui {
|
||||
|
||||
class ViewProviderSketch;
|
||||
|
||||
/**
|
||||
* In order to enforce a certain degree of encapsulation and promote a not
|
||||
* too tight coupling, while still allowing well defined collaboration,
|
||||
* DrawSketchHandler accesses ViewProviderSketch via this Attorney class
|
||||
*/
|
||||
class ViewProviderSketchDrawSketchHandlerAttorney {
|
||||
private:
|
||||
static inline void setPositionText(ViewProviderSketch &vp, const Base::Vector2d &Pos, const SbString &txt);
|
||||
static inline void setPositionText(ViewProviderSketch &vp, const Base::Vector2d &Pos);
|
||||
static inline void resetPositionText(ViewProviderSketch &vp);
|
||||
static inline void drawEdit(ViewProviderSketch &vp, const std::vector<Base::Vector2d> &EditCurve);
|
||||
static inline void drawEditMarkers(ViewProviderSketch &vp, const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
|
||||
static inline void setAxisPickStyle(ViewProviderSketch &vp, bool on);
|
||||
|
||||
static inline int getPreselectPoint(const ViewProviderSketch &vp);
|
||||
static inline int getPreselectCurve(const ViewProviderSketch &vp);
|
||||
static inline int getPreselectCross(const ViewProviderSketch &vp);
|
||||
|
||||
friend class DrawSketchHandler;
|
||||
};
|
||||
|
||||
|
||||
// A Simple data type to hold basic information for suggested constraints
|
||||
struct AutoConstraint
|
||||
{
|
||||
@@ -56,6 +78,17 @@ struct AutoConstraint
|
||||
/** Handler to create new sketch geometry
|
||||
* This class has to be reimplemented to create geometry in the
|
||||
* sketcher while its in editing.
|
||||
*
|
||||
* DrawSketchHandler takes over the responsibility of drawing edit temporal curves and
|
||||
* markers necessary to enable visual feedback to the user, as well as the UI interaction during
|
||||
* such edits. This is its exclusive responsibility under the Single Responsibility Principle.
|
||||
*
|
||||
* A plethora of speciliased handlers derive from DrawSketchHandler for each specialised editing (see
|
||||
* for example all the handlers for creation of new geometry). These derived classes do * not * have
|
||||
* direct access to the ViewProviderSketchDrawSketchHandlerAttorney. This is intended to keep coupling
|
||||
* under control. However, generic functionality requiring access to the Attorney can be implemented
|
||||
* in DrawSketchHandler and used from its derived classes by virtue of the inheritance. This promotes a
|
||||
* concentrating the coupling in a single point (and code reuse).
|
||||
*/
|
||||
class SketcherGuiExport DrawSketchHandler
|
||||
{
|
||||
@@ -98,7 +131,7 @@ protected:
|
||||
/**
|
||||
* Sets a cursor for 3D inventor view.
|
||||
* pixmap as a cursor image in device independent pixels.
|
||||
*
|
||||
*
|
||||
* \param autoScale - set this to false if pixmap already scaled for HiDPI
|
||||
**/
|
||||
void setCursor(const QPixmap &pixmap, int x,int y, bool autoScale=true);
|
||||
@@ -113,6 +146,15 @@ protected:
|
||||
qreal devicePixelRatio();
|
||||
void setCrosshairCursor(const char* svgName);
|
||||
|
||||
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
|
||||
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
|
||||
void setAxisPickStyle(bool on);
|
||||
|
||||
int getPreselectPoint(void) const;
|
||||
int getPreselectCurve(void) const;
|
||||
int getPreselectCross(void) const;
|
||||
|
||||
|
||||
/**
|
||||
* Returns constraints icons scaled to width.
|
||||
**/
|
||||
|
||||
829
src/Mod/Sketcher/Gui/EditModeCoinManager.cpp
Normal file
829
src/Mod/Sketcher/Gui/EditModeCoinManager.cpp
Normal file
@@ -0,0 +1,829 @@
|
||||
/***************************************************************************
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoGroup.h>
|
||||
# include <Inventor/nodes/SoSwitch.h>
|
||||
# include <Inventor/nodes/SoMaterial.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoLineSet.h>
|
||||
# include <Inventor/nodes/SoFont.h>
|
||||
|
||||
# include <Inventor/nodes/SoMarkerSet.h>
|
||||
# include <Inventor/nodes/SoTranslation.h>
|
||||
# include <Inventor/nodes/SoText2.h>
|
||||
# include <Inventor/nodes/SoPickStyle.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/SoPickedPoint.h>
|
||||
# include <Inventor/details/SoPointDetail.h>
|
||||
# include <Inventor/details/SoDetail.h>
|
||||
# include <Inventor/details/SoLineDetail.h>
|
||||
|
||||
# include <Inventor/nodes/SoAnnotation.h>
|
||||
# include <Inventor/nodes/SoImage.h>
|
||||
# include <Inventor/nodes/SoInfo.h>
|
||||
|
||||
# include <Inventor/actions/SoRayPickAction.h>
|
||||
|
||||
# include <Inventor/SbVec3f.h>
|
||||
# include <Inventor/SbImage.h>
|
||||
|
||||
# include <memory>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include <Gui/Inventor/SmSwitchboard.h>
|
||||
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Mod/Sketcher/App/GeometryFacade.h>
|
||||
#include <Mod/Sketcher/App/SolverGeometryExtension.h>
|
||||
#include <Mod/Sketcher/App/GeoEnum.h>
|
||||
#include <Mod/Sketcher/App/Constraint.h>
|
||||
#include <Mod/Sketcher/App/GeoList.h>
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Tools2D.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
#include <Gui/Utilities.h>
|
||||
#include <Base/Converter.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
#include <App/ObjectIdentifier.h>
|
||||
|
||||
#include <Gui/SoFCBoundingBox.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Inventor/MarkerBitmaps.h>
|
||||
#include <Gui/Tools.h>
|
||||
|
||||
#include <qpainter.h>
|
||||
|
||||
#include "SoZoomTranslation.h"
|
||||
#include "SoDatumLabel.h"
|
||||
|
||||
#include "EditModeInformationOverlayCoinConverter.h"
|
||||
|
||||
#include "EditModeGeometryCoinConverter.h"
|
||||
|
||||
#include "ViewProviderSketch.h"
|
||||
|
||||
#include "ViewProviderSketchCoinAttorney.h"
|
||||
|
||||
#include "EditModeGeometryCoinManager.h"
|
||||
#include "EditModeConstraintCoinManager.h"
|
||||
|
||||
#include "EditModeCoinManager.h"
|
||||
|
||||
using namespace SketcherGui;
|
||||
using namespace Sketcher;
|
||||
|
||||
//**************************** ParameterObserver nested class ******************************
|
||||
EditModeCoinManager::ParameterObserver::ParameterObserver(EditModeCoinManager &client): Client(client)
|
||||
{
|
||||
initParameters();
|
||||
subscribeToParameters();
|
||||
}
|
||||
|
||||
EditModeCoinManager::ParameterObserver::~ParameterObserver()
|
||||
{
|
||||
unsubscribeToParameters();
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::initParameters()
|
||||
{
|
||||
// static map to avoid substantial if/else branching
|
||||
//
|
||||
// key->first => String of parameter,
|
||||
// key->second => Update function to be called for the parameter,
|
||||
str2updatefunction = {
|
||||
{"SegmentsPerGeometry",
|
||||
[this](const std::string & param){updateCurvedEdgeCountSegmentsParameter(param);}},
|
||||
{"BSplineDegreeVisible",
|
||||
[this](const std::string & param){updateOverlayVisibilityParameter<OverlayVisibilityParameter::BSplineDegree>(param);}},
|
||||
{"BSplineControlPolygonVisible",
|
||||
[this](const std::string & param){updateOverlayVisibilityParameter<OverlayVisibilityParameter::BSplineControlPolygonVisible>(param);}},
|
||||
{"BSplineCombVisible",
|
||||
[this](const std::string & param){updateOverlayVisibilityParameter<OverlayVisibilityParameter::BSplineCombVisible>(param);}},
|
||||
{"BSplineKnotMultiplicityVisible",
|
||||
[this](const std::string & param){updateOverlayVisibilityParameter<OverlayVisibilityParameter::BSplineKnotMultiplicityVisible>(param);}},
|
||||
{"BSplinePoleWeightVisible",
|
||||
[this](const std::string & param){updateOverlayVisibilityParameter<OverlayVisibilityParameter::BSplinePoleWeightVisible>(param);}},
|
||||
{"TopRenderGeometryId",
|
||||
[this](const std::string & param){updateLineRenderingOrderParameters(param);}},
|
||||
{"MidRenderGeometryId",
|
||||
[this](const std::string & param){updateLineRenderingOrderParameters(param);}},
|
||||
{"HideUnits",
|
||||
[this](const std::string & param){updateConstraintPresentationParameters(param);}},
|
||||
{"ShowDimensionalName",
|
||||
[this](const std::string & param){updateConstraintPresentationParameters(param);}},
|
||||
{"DimensionalStringFormat",
|
||||
[this](const std::string & param){updateConstraintPresentationParameters(param);}},
|
||||
{"ViewScalingFactor",
|
||||
[this](const std::string & param){updateElementSizeParameters(param);}},
|
||||
{"MarkerSize",
|
||||
[this](const std::string & param){updateElementSizeParameters(param);}},
|
||||
{"EditSketcherFontSize",
|
||||
[this](const std::string & param){updateElementSizeParameters(param);}},
|
||||
{"CreateLineColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.CreateCurveColor, param);}},
|
||||
{"EditedVertexColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.VertexColor, param);}},
|
||||
{"EditedEdgeColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.CurveColor, param);}},
|
||||
{"ConstructionColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.CurveDraftColor, param);}},
|
||||
{"InternalAlignedGeoColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.InternalAlignedGeoColor, param);}},
|
||||
{"FullyConstraintElementColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.FullyConstraintElementColor, param);}},
|
||||
{"FullyConstraintConstructionElementColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.FullyConstraintConstructionElementColor, param);}},
|
||||
{"FullyConstraintInternalAlignmentColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.FullyConstraintInternalAlignmentColor, param);}},
|
||||
{"FullyConstraintConstructionPointColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.FullyConstraintConstructionPointColor, param);}},
|
||||
{"FullyConstraintElementColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.FullyConstraintElementColor, param);}},
|
||||
{"InvalidSketchColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.InvalidSketchColor, param);}},
|
||||
{"FullyConstrainedColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.FullyConstrainedColor, param);}},
|
||||
{"ConstrainedDimColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.ConstrDimColor, param);}},
|
||||
{"ConstrainedIcoColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.ConstrIcoColor, param);}},
|
||||
{"NonDrivingConstrDimColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.NonDrivingConstrDimColor, param);}},
|
||||
{"ExprBasedConstrDimColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.ExprBasedConstrDimColor, param);}},
|
||||
{"DeactivatedConstrDimColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.DeactivatedConstrDimColor, param);}},
|
||||
{"ExternalColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.CurveExternalColor, param);}},
|
||||
{"HighlightColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.PreselectColor, param);}},
|
||||
{"SelectionColor",
|
||||
[this, drawingParameters = Client.drawingParameters](const std::string & param){updateColor(drawingParameters.SelectColor, param);}},
|
||||
};
|
||||
|
||||
for( auto & val : str2updatefunction){
|
||||
auto string = val.first;
|
||||
auto function = val.second;
|
||||
|
||||
function(string);
|
||||
}
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::updateCurvedEdgeCountSegmentsParameter(const std::string & parametername)
|
||||
{
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
int stdcountsegments = hGrp->GetInt(parametername.c_str(), 50);
|
||||
// value cannot be smaller than 6
|
||||
if (stdcountsegments < 6)
|
||||
stdcountsegments = 6;
|
||||
|
||||
Client.drawingParameters.curvedEdgeCountSegments = stdcountsegments;
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::updateLineRenderingOrderParameters(const std::string & parametername)
|
||||
{
|
||||
(void) parametername;
|
||||
|
||||
ParameterGrp::handle hGrpp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
|
||||
Client.drawingParameters.topRenderingGeometry = DrawingParameters::GeometryRendering (hGrpp->GetInt("TopRenderGeometryId",1));
|
||||
Client.drawingParameters.midRenderingGeometry = DrawingParameters::GeometryRendering (hGrpp->GetInt("MidRenderGeometryId",2));
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::updateConstraintPresentationParameters(const std::string & parametername)
|
||||
{
|
||||
(void) parametername;
|
||||
|
||||
ParameterGrp::handle hGrpskg = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
|
||||
Client.constraintParameters.bHideUnits = hGrpskg->GetBool("HideUnits", false);
|
||||
Client.constraintParameters.bShowDimensionalName = hGrpskg->GetBool("ShowDimensionalName", false);
|
||||
Client.constraintParameters.sDimensionalStringFormat = QString::fromStdString(hGrpskg->GetASCII("DimensionalStringFormat", "%N = %V"));
|
||||
}
|
||||
|
||||
template<EditModeCoinManager::ParameterObserver::OverlayVisibilityParameter visibilityparameter>
|
||||
void EditModeCoinManager::ParameterObserver::updateOverlayVisibilityParameter(const std::string & parametername)
|
||||
{
|
||||
ParameterGrp::handle hGrpsk = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
|
||||
if constexpr (visibilityparameter == OverlayVisibilityParameter::BSplineDegree)
|
||||
Client.overlayParameters.bSplineDegreeVisible = hGrpsk->GetBool(parametername.c_str(), true);
|
||||
else if constexpr (visibilityparameter == OverlayVisibilityParameter::BSplineControlPolygonVisible)
|
||||
Client.overlayParameters.bSplineControlPolygonVisible = hGrpsk->GetBool(parametername.c_str(), true);
|
||||
else if constexpr (visibilityparameter == OverlayVisibilityParameter::BSplineCombVisible)
|
||||
Client.overlayParameters.bSplineCombVisible = hGrpsk->GetBool(parametername.c_str(), true);
|
||||
else if constexpr (visibilityparameter == OverlayVisibilityParameter::BSplineKnotMultiplicityVisible)
|
||||
Client.overlayParameters.bSplineKnotMultiplicityVisible = hGrpsk->GetBool(parametername.c_str(), true);
|
||||
else if constexpr (visibilityparameter == OverlayVisibilityParameter::BSplinePoleWeightVisible)
|
||||
Client.overlayParameters.bSplinePoleWeightVisible = hGrpsk->GetBool(parametername.c_str(), true);
|
||||
|
||||
Client.overlayParameters.visibleInformationChanged = true;
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::updateElementSizeParameters(const std::string & parametername)
|
||||
{
|
||||
(void) parametername;
|
||||
|
||||
//Add scaling to Constraint icons
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
|
||||
double viewScalingFactor = hGrp->GetFloat("ViewScalingFactor", 1.0);
|
||||
viewScalingFactor = Base::clamp<double>(viewScalingFactor, 0.5, 5.0);
|
||||
|
||||
int markersize = hGrp->GetInt("MarkerSize", 7);
|
||||
|
||||
int defaultFontSizePixels = Client.defaultApplicationFontSizePixels(); // returns height in pixels, not points
|
||||
|
||||
int sketcherfontSize = hGrp->GetInt("EditSketcherFontSize", defaultFontSizePixels);
|
||||
|
||||
int dpi = Client.getApplicationLogicalDPIX();
|
||||
|
||||
// simple scaling factor for hardcoded pixel values in the Sketcher
|
||||
Client.drawingParameters.pixelScalingFactor = viewScalingFactor * dpi / 96; // 96 ppi is the standard pixel density for which pixel quantities were calculated
|
||||
|
||||
// Coin documentation indicates the size of a font is:
|
||||
// SoSFFloat SoFont::size Size of font. Defaults to 10.0.
|
||||
//
|
||||
// For 2D rendered bitmap fonts (like for SoText2), this value is the height of a character in screen pixels. For 3D text, this value is the world-space coordinates height of a character in the current units setting (see documentation for SoUnits node).
|
||||
//
|
||||
// However, with hdpi monitors, the coin font labels do not respect the size passed in pixels:
|
||||
// https://forum.freecadweb.org/viewtopic.php?f=3&t=54347&p=467610#p467610
|
||||
// https://forum.freecadweb.org/viewtopic.php?f=10&t=49972&start=40#p467471
|
||||
//
|
||||
// Because I (abdullah) have 96 dpi logical, 82 dpi physical, and I see a 35px font setting for a "1" in a datum label as 34px,
|
||||
// and I see kilsore and Elyas screenshots showing 41px and 61px in higher resolution monitors for the same configuration, I think
|
||||
// that coin pixel size has to be corrected by the logical dpi of the monitor. The rationale is that: a) it obviously needs dpi
|
||||
// correction, b) with physical dpi, the ratio of representation between kilsore and me is too far away.
|
||||
//
|
||||
// This means that the following correction does not have a documented basis, but appears necessary so that the Sketcher is usable in
|
||||
// HDPI monitors.
|
||||
|
||||
Client.drawingParameters.coinFontSize = std::lround(sketcherfontSize * 96.0f / dpi);
|
||||
Client.drawingParameters.constraintIconSize = std::lround(0.8 * sketcherfontSize);
|
||||
|
||||
// For marker size the global default is used.
|
||||
//
|
||||
// Rationale:
|
||||
// -> Other WBs use the default value as is
|
||||
// -> If a user has a HDPI, he will eventually change the value for the other WBs
|
||||
// -> If we correct the value here in addition, we would get two times a resize
|
||||
Client.drawingParameters.markerSize = markersize;
|
||||
|
||||
Client.updateInventorNodeSizes();
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::updateColor(SbColor &sbcolor, const std::string ¶metername)
|
||||
{
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
|
||||
float transparency = 0.f;
|
||||
unsigned long color = (unsigned long)(sbcolor.getPackedValue());
|
||||
color = hGrp->GetUnsigned(parametername.c_str(), color);
|
||||
sbcolor.setPackedValue((uint32_t)color, transparency);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::subscribeToParameters()
|
||||
{
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
hGrp->Attach(this);
|
||||
|
||||
ParameterGrp::handle hGrpsk = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
hGrpsk->Attach(this);
|
||||
|
||||
ParameterGrp::handle hGrpp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
hGrpp->Attach(this);
|
||||
|
||||
ParameterGrp::handle hGrpskg = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
hGrpskg->Attach(this);
|
||||
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::unsubscribeToParameters()
|
||||
{
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
hGrp->Detach(this);
|
||||
|
||||
ParameterGrp::handle hGrpsk = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
hGrpsk->Detach(this);
|
||||
|
||||
ParameterGrp::handle hGrpp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher/General");
|
||||
hGrpp->Detach(this);
|
||||
|
||||
ParameterGrp::handle hGrpskg = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/Mod/Sketcher");
|
||||
hGrpskg->Detach(this);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::ParameterObserver::OnChange(Base::Subject<const char*> &rCaller, const char * sReason)
|
||||
{
|
||||
(void) rCaller;
|
||||
|
||||
auto key = str2updatefunction.find(sReason);
|
||||
if( key != str2updatefunction.end() ) {
|
||||
auto string = key->first;
|
||||
auto function = key->second;
|
||||
|
||||
function(string);
|
||||
|
||||
Client.redrawViewProvider(); // redraw with non-temporal geometry
|
||||
}
|
||||
}
|
||||
|
||||
//**************************** EditModeCoinManager class ******************************
|
||||
|
||||
EditModeCoinManager::EditModeCoinManager(ViewProviderSketch &vp):viewProvider(vp) {
|
||||
|
||||
pEditModeConstraintCoinManager = std::make_unique<EditModeConstraintCoinManager>(viewProvider,
|
||||
drawingParameters,
|
||||
geometryLayerParameters,
|
||||
constraintParameters,
|
||||
editModeScenegraphNodes,
|
||||
coinMapping);
|
||||
|
||||
pEditModeGeometryCoinManager = std::make_unique<EditModeGeometryCoinManager>( viewProvider,
|
||||
drawingParameters,
|
||||
geometryLayerParameters,
|
||||
analysisResults,
|
||||
editModeScenegraphNodes,
|
||||
coinMapping);
|
||||
// Create Edit Mode Scenograph
|
||||
createEditModeInventorNodes();
|
||||
|
||||
// Create parameter observer and initialise watched parameters
|
||||
pObserver = std::make_unique<EditModeCoinManager::ParameterObserver>(*this);
|
||||
}
|
||||
|
||||
EditModeCoinManager::~EditModeCoinManager()
|
||||
{
|
||||
Gui::coinRemoveAllChildren(editModeScenegraphNodes.EditRoot);
|
||||
ViewProviderSketchCoinAttorney::removeNodeFromRoot(viewProvider, editModeScenegraphNodes.EditRoot);
|
||||
editModeScenegraphNodes.EditRoot->unref();
|
||||
}
|
||||
|
||||
/***** Temporary edit curves and markers *****/
|
||||
|
||||
void EditModeCoinManager::drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel)
|
||||
{
|
||||
// determine marker size
|
||||
int augmentedmarkersize = drawingParameters.markerSize;
|
||||
|
||||
auto supportedsizes = Gui::Inventor::MarkerBitmaps::getSupportedSizes("CIRCLE_LINE");
|
||||
|
||||
auto defaultmarker = std::find(supportedsizes.begin(), supportedsizes.end(), drawingParameters.markerSize);
|
||||
|
||||
if(defaultmarker != supportedsizes.end()) {
|
||||
auto validAugmentationLevels = std::distance(defaultmarker,supportedsizes.end());
|
||||
|
||||
if(augmentationlevel >= validAugmentationLevels)
|
||||
augmentationlevel = validAugmentationLevels - 1;
|
||||
|
||||
augmentedmarkersize = *std::next(defaultmarker, augmentationlevel);
|
||||
}
|
||||
|
||||
editModeScenegraphNodes.EditMarkerSet->markerIndex.startEditing();
|
||||
editModeScenegraphNodes.EditMarkerSet->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_LINE", augmentedmarkersize);
|
||||
|
||||
// add the points to set
|
||||
editModeScenegraphNodes.EditMarkersCoordinate->point.setNum(EditMarkers.size());
|
||||
editModeScenegraphNodes.EditMarkersMaterials->diffuseColor.setNum(EditMarkers.size());
|
||||
SbVec3f *verts = editModeScenegraphNodes.EditMarkersCoordinate->point.startEditing();
|
||||
SbColor *color = editModeScenegraphNodes.EditMarkersMaterials->diffuseColor.startEditing();
|
||||
|
||||
int i=0; // setting up the line set
|
||||
for (std::vector<Base::Vector2d>::const_iterator it = EditMarkers.begin(); it != EditMarkers.end(); ++it,i++) {
|
||||
verts[i].setValue(it->x, it->y, drawingParameters.zEdit);
|
||||
color[i] = drawingParameters.InformationColor;
|
||||
}
|
||||
|
||||
editModeScenegraphNodes.EditMarkersCoordinate->point.finishEditing();
|
||||
editModeScenegraphNodes.EditMarkersMaterials->diffuseColor.finishEditing();
|
||||
editModeScenegraphNodes.EditMarkerSet->markerIndex.finishEditing();
|
||||
}
|
||||
|
||||
void EditModeCoinManager::drawEdit(const std::vector<Base::Vector2d> &EditCurve)
|
||||
{
|
||||
editModeScenegraphNodes.EditCurveSet->numVertices.setNum(1);
|
||||
editModeScenegraphNodes.EditCurvesCoordinate->point.setNum(EditCurve.size());
|
||||
editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.setNum(EditCurve.size());
|
||||
SbVec3f *verts = editModeScenegraphNodes.EditCurvesCoordinate->point.startEditing();
|
||||
int32_t *index = editModeScenegraphNodes.EditCurveSet->numVertices.startEditing();
|
||||
SbColor *color = editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.startEditing();
|
||||
|
||||
int i=0; // setting up the line set
|
||||
for (std::vector<Base::Vector2d>::const_iterator it = EditCurve.begin(); it != EditCurve.end(); ++it,i++) {
|
||||
verts[i].setValue(it->x,it->y, drawingParameters.zEdit);
|
||||
color[i] = drawingParameters.CreateCurveColor;
|
||||
}
|
||||
|
||||
index[0] = EditCurve.size();
|
||||
editModeScenegraphNodes.EditCurvesCoordinate->point.finishEditing();
|
||||
editModeScenegraphNodes.EditCurveSet->numVertices.finishEditing();
|
||||
editModeScenegraphNodes.EditCurvesMaterials->diffuseColor.finishEditing();
|
||||
}
|
||||
|
||||
void EditModeCoinManager::setPositionText(const Base::Vector2d &Pos, const SbString &text)
|
||||
{
|
||||
editModeScenegraphNodes.textX->string = text;
|
||||
editModeScenegraphNodes.textPos->translation = SbVec3f(Pos.x, Pos.y, drawingParameters.zText);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::setPositionText(const Base::Vector2d &Pos)
|
||||
{
|
||||
SbString text;
|
||||
text.sprintf(" (%.1f,%.1f)", Pos.x, Pos.y);
|
||||
setPositionText(Pos,text);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::resetPositionText(void)
|
||||
{
|
||||
editModeScenegraphNodes.textX->string = "";
|
||||
}
|
||||
|
||||
void EditModeCoinManager::setAxisPickStyle(bool on)
|
||||
{
|
||||
if (on)
|
||||
editModeScenegraphNodes.pickStyleAxes->style = SoPickStyle::SHAPE;
|
||||
else
|
||||
editModeScenegraphNodes.pickStyleAxes->style = SoPickStyle::UNPICKABLE;
|
||||
}
|
||||
|
||||
EditModeCoinManager::PreselectionResult EditModeCoinManager::detectPreselection(SoPickedPoint * Point, const SbVec2s &cursorPos)
|
||||
{
|
||||
EditModeCoinManager::PreselectionResult result;
|
||||
|
||||
if(!Point)
|
||||
return result;
|
||||
|
||||
//Base::Console().Log("Point pick\n");
|
||||
SoPath *path = Point->getPath();
|
||||
SoNode *tail = path->getTail(); // Tail is directly the node containing points and curves
|
||||
|
||||
for(int l = 0; l < geometryLayerParameters.CoinLayers; l++) {
|
||||
// checking for a hit in the points
|
||||
if (tail == editModeScenegraphNodes.PointSet[l]) {
|
||||
const SoDetail *point_detail = Point->getDetail(editModeScenegraphNodes.PointSet[l]);
|
||||
if (point_detail && point_detail->getTypeId() == SoPointDetail::getClassTypeId()) {
|
||||
// get the index
|
||||
int pindex = static_cast<const SoPointDetail *>(point_detail)->getCoordinateIndex();
|
||||
result.PointIndex = coinMapping.getPointVertexId(pindex, l); // returns -1 for root, global VertexId for the rest of vertices.
|
||||
|
||||
if (result.PointIndex == -1)
|
||||
result.Cross = PreselectionResult::Axes::RootPoint;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
// checking for a hit in the curves
|
||||
if (tail == editModeScenegraphNodes.CurveSet[l]) {
|
||||
const SoDetail *curve_detail = Point->getDetail(editModeScenegraphNodes.CurveSet[l]);
|
||||
if (curve_detail && curve_detail->getTypeId() == SoLineDetail::getClassTypeId()) {
|
||||
// get the index
|
||||
int curveIndex = static_cast<const SoLineDetail *>(curve_detail)->getLineIndex();
|
||||
result.GeoIndex = coinMapping.getCurveGeoId(curveIndex, l);
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
// checking for a hit in the axes
|
||||
if (tail == editModeScenegraphNodes.RootCrossSet) {
|
||||
const SoDetail *cross_detail = Point->getDetail(editModeScenegraphNodes.RootCrossSet);
|
||||
if (cross_detail && cross_detail->getTypeId() == SoLineDetail::getClassTypeId()) {
|
||||
// get the index (reserve index 0 for root point)
|
||||
int CrossIndex = static_cast<const SoLineDetail *>(cross_detail)->getLineIndex();
|
||||
|
||||
if(CrossIndex == 0)
|
||||
result.Cross = PreselectionResult::Axes::HorizontalAxis;
|
||||
else if(CrossIndex == 1)
|
||||
result.Cross = PreselectionResult::Axes::VerticalAxis;
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
// checking if a constraint is hit
|
||||
result.ConstrIndices = pEditModeConstraintCoinManager->detectPreselectionConstr(Point, cursorPos);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
SoGroup* EditModeCoinManager::getSelectedConstraints()
|
||||
{
|
||||
SoGroup* group = new SoGroup();
|
||||
group->ref();
|
||||
|
||||
for (int i=0; i < editModeScenegraphNodes.constrGroup->getNumChildren(); i++) {
|
||||
if (ViewProviderSketchCoinAttorney::isConstraintSelected(viewProvider, i)) {
|
||||
SoSeparator *sep = pEditModeConstraintCoinManager->getConstraintIdSeparator(i);
|
||||
if (sep)
|
||||
group->addChild(sep);
|
||||
}
|
||||
}
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
/***** update coin nodes *****/
|
||||
|
||||
void EditModeCoinManager::processGeometryConstraintsInformationOverlay(const GeoListFacade & geolistfacade, bool rebuildinformationlayer)
|
||||
{
|
||||
overlayParameters.rebuildInformationLayer = rebuildinformationlayer;
|
||||
|
||||
pEditModeGeometryCoinManager->processGeometry(geolistfacade);
|
||||
|
||||
updateOverlayParameters();
|
||||
|
||||
processGeometryInformationOverlay(geolistfacade);
|
||||
|
||||
updateAxesLength();
|
||||
|
||||
updateGridExtent();
|
||||
|
||||
pEditModeConstraintCoinManager->processConstraints(geolistfacade);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::updateOverlayParameters()
|
||||
{
|
||||
if ( (analysisResults.combRepresentationScale > (2 * overlayParameters.currentBSplineCombRepresentationScale)) ||
|
||||
(analysisResults.combRepresentationScale < (overlayParameters.currentBSplineCombRepresentationScale / 2)))
|
||||
overlayParameters.currentBSplineCombRepresentationScale = analysisResults.combRepresentationScale ;
|
||||
}
|
||||
|
||||
void EditModeCoinManager::processGeometryInformationOverlay(const GeoListFacade & geolistfacade)
|
||||
{
|
||||
if(overlayParameters.rebuildInformationLayer) {
|
||||
// every time we start with empty information overlay
|
||||
Gui::coinRemoveAllChildren(editModeScenegraphNodes.infoGroup);
|
||||
}
|
||||
|
||||
auto ioconv = EditModeInformationOverlayCoinConverter(editModeScenegraphNodes.infoGroup, overlayParameters, drawingParameters);
|
||||
|
||||
// geometry information layer for bsplines, as they need a second round now that max curvature is known
|
||||
for (auto geoid : analysisResults.bsplineGeoIds) {
|
||||
const Part::Geometry *geo = geolistfacade.getGeometryFromGeoId(geoid);
|
||||
|
||||
ioconv.convert(geo, geoid);
|
||||
}
|
||||
|
||||
overlayParameters.visibleInformationChanged = false; // just updated
|
||||
}
|
||||
|
||||
void EditModeCoinManager::updateAxesLength()
|
||||
{
|
||||
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(0,SbVec3f(-analysisResults.boundingBoxMagnitudeOrder, 0.0f, drawingParameters.zCross));
|
||||
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(1,SbVec3f(analysisResults.boundingBoxMagnitudeOrder, 0.0f, drawingParameters.zCross));
|
||||
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(2,SbVec3f(0.0f, -analysisResults.boundingBoxMagnitudeOrder, drawingParameters.zCross));
|
||||
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(3,SbVec3f(0.0f, analysisResults.boundingBoxMagnitudeOrder, drawingParameters.zCross));
|
||||
}
|
||||
|
||||
void EditModeCoinManager::updateGridExtent()
|
||||
{
|
||||
float dMagF = analysisResults.boundingBoxMagnitudeOrder;
|
||||
|
||||
ViewProviderSketchCoinAttorney::updateGridExtent(viewProvider,-dMagF, dMagF, -dMagF, dMagF);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::updateColor()
|
||||
{
|
||||
auto geolistfacade = ViewProviderSketchCoinAttorney::getGeoListFacade(viewProvider);
|
||||
|
||||
updateColor(geolistfacade);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::updateColor(const GeoListFacade & geolistfacade)
|
||||
{
|
||||
bool sketchinvalid = ViewProviderSketchCoinAttorney::isSketchInvalid(viewProvider);
|
||||
|
||||
pEditModeGeometryCoinManager->updateGeometryColor(geolistfacade, sketchinvalid);
|
||||
|
||||
// update constraint color
|
||||
|
||||
auto constraints = ViewProviderSketchCoinAttorney::getConstraints(viewProvider);
|
||||
|
||||
if(ViewProviderSketchCoinAttorney::haveConstraintsInvalidGeometry(viewProvider))
|
||||
return;
|
||||
|
||||
pEditModeConstraintCoinManager->updateConstraintColor(constraints);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::createEditModeInventorNodes()
|
||||
{
|
||||
// 1 - Create the edit root node
|
||||
editModeScenegraphNodes.EditRoot = new SoSeparator;
|
||||
editModeScenegraphNodes.EditRoot->ref(); // Node is unref in the destructor of EditModeCoinManager
|
||||
editModeScenegraphNodes.EditRoot->setName("Sketch_EditRoot");
|
||||
ViewProviderSketchCoinAttorney::addNodeToRoot(viewProvider, editModeScenegraphNodes.EditRoot);
|
||||
editModeScenegraphNodes.EditRoot->renderCaching = SoSeparator::OFF ;
|
||||
|
||||
// Create Geometry Coin nodes ++++++++++++++++++++++++++++++++++++++
|
||||
pEditModeGeometryCoinManager->createEditModeInventorNodes();
|
||||
|
||||
// stuff for the RootCross lines +++++++++++++++++++++++++++++++++++++++
|
||||
SoGroup* crossRoot = new Gui::SoSkipBoundingGroup;
|
||||
editModeScenegraphNodes.pickStyleAxes = new SoPickStyle();
|
||||
editModeScenegraphNodes.pickStyleAxes->style = SoPickStyle::SHAPE;
|
||||
crossRoot->addChild(editModeScenegraphNodes.pickStyleAxes);
|
||||
editModeScenegraphNodes.EditRoot->addChild(crossRoot);
|
||||
auto MtlBind = new SoMaterialBinding;
|
||||
MtlBind->setName("RootCrossMaterialBinding");
|
||||
MtlBind->value = SoMaterialBinding::PER_FACE;
|
||||
crossRoot->addChild(MtlBind);
|
||||
|
||||
editModeScenegraphNodes.RootCrossDrawStyle = new SoDrawStyle;
|
||||
editModeScenegraphNodes.RootCrossDrawStyle->setName("RootCrossDrawStyle");
|
||||
editModeScenegraphNodes.RootCrossDrawStyle->lineWidth = 2 * drawingParameters.pixelScalingFactor;
|
||||
crossRoot->addChild(editModeScenegraphNodes.RootCrossDrawStyle);
|
||||
|
||||
editModeScenegraphNodes.RootCrossMaterials = new SoMaterial;
|
||||
editModeScenegraphNodes.RootCrossMaterials->setName("RootCrossMaterials");
|
||||
editModeScenegraphNodes.RootCrossMaterials->diffuseColor.set1Value(0, drawingParameters.CrossColorH);
|
||||
editModeScenegraphNodes.RootCrossMaterials->diffuseColor.set1Value(1, drawingParameters.CrossColorV);
|
||||
crossRoot->addChild(editModeScenegraphNodes.RootCrossMaterials);
|
||||
|
||||
editModeScenegraphNodes.RootCrossCoordinate = new SoCoordinate3;
|
||||
editModeScenegraphNodes.RootCrossCoordinate->setName("RootCrossCoordinate");
|
||||
crossRoot->addChild(editModeScenegraphNodes.RootCrossCoordinate);
|
||||
|
||||
editModeScenegraphNodes.RootCrossSet = new SoLineSet;
|
||||
editModeScenegraphNodes.RootCrossSet->setName("RootCrossLineSet");
|
||||
crossRoot->addChild(editModeScenegraphNodes.RootCrossSet);
|
||||
|
||||
// stuff for the EditCurves +++++++++++++++++++++++++++++++++++++++
|
||||
SoSeparator* editCurvesRoot = new SoSeparator;
|
||||
editModeScenegraphNodes.EditRoot->addChild(editCurvesRoot);
|
||||
editModeScenegraphNodes.EditCurvesMaterials = new SoMaterial;
|
||||
editModeScenegraphNodes.EditCurvesMaterials->setName("EditCurvesMaterials");
|
||||
editCurvesRoot->addChild(editModeScenegraphNodes.EditCurvesMaterials);
|
||||
|
||||
editModeScenegraphNodes.EditCurvesCoordinate = new SoCoordinate3;
|
||||
editModeScenegraphNodes.EditCurvesCoordinate->setName("EditCurvesCoordinate");
|
||||
editCurvesRoot->addChild(editModeScenegraphNodes.EditCurvesCoordinate);
|
||||
|
||||
editModeScenegraphNodes.EditCurvesDrawStyle = new SoDrawStyle;
|
||||
editModeScenegraphNodes.EditCurvesDrawStyle->setName("EditCurvesDrawStyle");
|
||||
editModeScenegraphNodes.EditCurvesDrawStyle->lineWidth = 3 * drawingParameters.pixelScalingFactor;
|
||||
editCurvesRoot->addChild(editModeScenegraphNodes.EditCurvesDrawStyle);
|
||||
|
||||
editModeScenegraphNodes.EditCurveSet = new SoLineSet;
|
||||
editModeScenegraphNodes.EditCurveSet->setName("EditCurveLineSet");
|
||||
editCurvesRoot->addChild(editModeScenegraphNodes.EditCurveSet);
|
||||
|
||||
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
|
||||
float transparency;
|
||||
SbColor cursorTextColor(0,0,1);
|
||||
cursorTextColor.setPackedValue((uint32_t)hGrp->GetUnsigned("CursorTextColor", cursorTextColor.getPackedValue()), transparency);
|
||||
|
||||
// stuff for the EditMarkers +++++++++++++++++++++++++++++++++++++++
|
||||
SoSeparator* editMarkersRoot = new SoSeparator;
|
||||
editModeScenegraphNodes.EditRoot->addChild(editMarkersRoot);
|
||||
editModeScenegraphNodes.EditMarkersMaterials = new SoMaterial;
|
||||
editModeScenegraphNodes.EditMarkersMaterials->setName("EditMarkersMaterials");
|
||||
editMarkersRoot->addChild(editModeScenegraphNodes.EditMarkersMaterials);
|
||||
|
||||
editModeScenegraphNodes.EditMarkersCoordinate = new SoCoordinate3;
|
||||
editModeScenegraphNodes.EditMarkersCoordinate->setName("EditMarkersCoordinate");
|
||||
editMarkersRoot->addChild(editModeScenegraphNodes.EditMarkersCoordinate);
|
||||
|
||||
editModeScenegraphNodes.EditMarkersDrawStyle = new SoDrawStyle;
|
||||
editModeScenegraphNodes.EditMarkersDrawStyle->setName("EditMarkersDrawStyle");
|
||||
editModeScenegraphNodes.EditMarkersDrawStyle->pointSize = 8 * drawingParameters.pixelScalingFactor;
|
||||
editMarkersRoot->addChild(editModeScenegraphNodes.EditMarkersDrawStyle);
|
||||
|
||||
editModeScenegraphNodes.EditMarkerSet = new SoMarkerSet;
|
||||
editModeScenegraphNodes.EditMarkerSet->setName("EditMarkerSet");
|
||||
editModeScenegraphNodes.EditMarkerSet->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_LINE", drawingParameters.markerSize);
|
||||
editMarkersRoot->addChild(editModeScenegraphNodes.EditMarkerSet);
|
||||
|
||||
// stuff for the edit coordinates ++++++++++++++++++++++++++++++++++++++
|
||||
SoSeparator *Coordsep = new SoSeparator();
|
||||
SoPickStyle* ps = new SoPickStyle();
|
||||
ps->style.setValue(SoPickStyle::UNPICKABLE);
|
||||
Coordsep->addChild(ps);
|
||||
Coordsep->setName("CoordSeparator");
|
||||
// no caching for frequently-changing data structures
|
||||
Coordsep->renderCaching = SoSeparator::OFF;
|
||||
|
||||
SoMaterial *CoordTextMaterials = new SoMaterial;
|
||||
CoordTextMaterials->setName("CoordTextMaterials");
|
||||
CoordTextMaterials->diffuseColor = cursorTextColor;
|
||||
Coordsep->addChild(CoordTextMaterials);
|
||||
|
||||
SoFont *font = new SoFont();
|
||||
font->size.setValue(drawingParameters.coinFontSize);
|
||||
|
||||
Coordsep->addChild(font);
|
||||
|
||||
editModeScenegraphNodes.textPos = new SoTranslation();
|
||||
Coordsep->addChild(editModeScenegraphNodes.textPos);
|
||||
|
||||
editModeScenegraphNodes.textX = new SoText2();
|
||||
editModeScenegraphNodes.textX->justification = SoText2::LEFT;
|
||||
editModeScenegraphNodes.textX->string = "";
|
||||
Coordsep->addChild(editModeScenegraphNodes.textX);
|
||||
editModeScenegraphNodes.EditRoot->addChild(Coordsep);
|
||||
|
||||
// coin nodes for the constraints +++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
pEditModeConstraintCoinManager->createEditModeInventorNodes();
|
||||
|
||||
// group node for the Geometry information visual +++++++++++++++++++++++++++++++++++
|
||||
MtlBind = new SoMaterialBinding;
|
||||
MtlBind->setName("InformationMaterialBinding");
|
||||
MtlBind->value = SoMaterialBinding::OVERALL ;
|
||||
editModeScenegraphNodes.EditRoot->addChild(MtlBind);
|
||||
|
||||
// use small line width for the information visual
|
||||
editModeScenegraphNodes.InformationDrawStyle = new SoDrawStyle;
|
||||
editModeScenegraphNodes.InformationDrawStyle->setName("InformationDrawStyle");
|
||||
editModeScenegraphNodes.InformationDrawStyle->lineWidth = 1 * drawingParameters.pixelScalingFactor;
|
||||
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.InformationDrawStyle);
|
||||
|
||||
// add the group where all the information entity has its SoSeparator
|
||||
editModeScenegraphNodes.infoGroup = new SoGroup();
|
||||
editModeScenegraphNodes.infoGroup->setName("InformationGroup");
|
||||
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.infoGroup);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::redrawViewProvider()
|
||||
{
|
||||
viewProvider.draw(false,false);
|
||||
}
|
||||
|
||||
/************************ Delegated constraint public interface **********/
|
||||
|
||||
// public function that triggers drawing of most constraint icons
|
||||
void EditModeCoinManager::drawConstraintIcons()
|
||||
{
|
||||
pEditModeConstraintCoinManager->drawConstraintIcons();
|
||||
}
|
||||
|
||||
void EditModeCoinManager::drawConstraintIcons(const GeoList & geolist)
|
||||
{
|
||||
pEditModeConstraintCoinManager->drawConstraintIcons(geolist);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::updateVirtualSpace()
|
||||
{
|
||||
pEditModeConstraintCoinManager->updateVirtualSpace();
|
||||
}
|
||||
|
||||
/************************ Resizing of coin nodes ************************/
|
||||
|
||||
int EditModeCoinManager::defaultApplicationFontSizePixels() const {
|
||||
return ViewProviderSketchCoinAttorney::defaultApplicationFontSizePixels(viewProvider);
|
||||
}
|
||||
|
||||
int EditModeCoinManager::getApplicationLogicalDPIX() const {
|
||||
return ViewProviderSketchCoinAttorney::getApplicationLogicalDPIX(viewProvider);
|
||||
}
|
||||
|
||||
void EditModeCoinManager::updateInventorNodeSizes()
|
||||
{
|
||||
for(int l = 0; l < geometryLayerParameters.CoinLayers; l++) {
|
||||
editModeScenegraphNodes.PointsDrawStyle[l]->pointSize = 8 * drawingParameters.pixelScalingFactor;
|
||||
editModeScenegraphNodes.PointSet[l]->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_FILLED", drawingParameters.markerSize);
|
||||
editModeScenegraphNodes.CurvesDrawStyle[l]->lineWidth = 3 * drawingParameters.pixelScalingFactor;
|
||||
}
|
||||
|
||||
editModeScenegraphNodes.RootCrossDrawStyle->lineWidth = 2 * drawingParameters.pixelScalingFactor;
|
||||
editModeScenegraphNodes.EditCurvesDrawStyle->lineWidth = 3 * drawingParameters.pixelScalingFactor;
|
||||
editModeScenegraphNodes.EditMarkersDrawStyle->pointSize = 8 * drawingParameters.pixelScalingFactor;
|
||||
editModeScenegraphNodes.EditMarkerSet->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_LINE", drawingParameters.markerSize);
|
||||
editModeScenegraphNodes.ConstraintDrawStyle->lineWidth = 1 * drawingParameters.pixelScalingFactor;
|
||||
editModeScenegraphNodes.InformationDrawStyle->lineWidth = 1 * drawingParameters.pixelScalingFactor;
|
||||
|
||||
pEditModeConstraintCoinManager->rebuildConstraintNodes();
|
||||
}
|
||||
|
||||
/************************ Edit node access ************************/
|
||||
|
||||
SoSeparator* EditModeCoinManager::getRootEditNode()
|
||||
{
|
||||
return editModeScenegraphNodes.EditRoot;
|
||||
}
|
||||
293
src/Mod/Sketcher/Gui/EditModeCoinManager.h
Normal file
293
src/Mod/Sketcher/Gui/EditModeCoinManager.h
Normal file
@@ -0,0 +1,293 @@
|
||||
/***************************************************************************
|
||||
* 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_EditModeCoinManager_H
|
||||
#define SKETCHERGUI_EditModeCoinManager_H
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
#include <App/Application.h>
|
||||
|
||||
#include "EditModeCoinManagerParameters.h"
|
||||
|
||||
#include <Mod/Sketcher/App/GeoList.h>
|
||||
|
||||
class SbVec3f;
|
||||
class SoRayPickAction;
|
||||
class SoPickedPoint;
|
||||
class SbVec3s;
|
||||
|
||||
namespace Base {
|
||||
template< typename T >
|
||||
class Vector3;
|
||||
|
||||
class Vector2d;
|
||||
|
||||
class Placement;
|
||||
}
|
||||
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace Sketcher {
|
||||
class Constraint;
|
||||
class PropertyConstraintList;
|
||||
};
|
||||
|
||||
namespace SketcherGui {
|
||||
|
||||
class ViewProviderSketch;
|
||||
class EditModeConstraintCoinManager;
|
||||
class EditModeGeometryCoinManager;
|
||||
|
||||
using GeoList = Sketcher::GeoList;
|
||||
using GeoListFacade = Sketcher::GeoListFacade;
|
||||
|
||||
/** @brief Helper class for managing the Coin nodes of ViewProviderSketch.
|
||||
* @details
|
||||
*
|
||||
* Given the substantial amount of code involved in coin node management, EditModeCoinManager
|
||||
* further delegates on other specialised helper classes. Some of them share the
|
||||
* ViewProviderSketchCoinAttorney, which defines the maximum coupling and minimum encapsulation.
|
||||
*
|
||||
* The most important such delegates are: EditModeGeometryCoinManager and EditModeConstraintCoinManager.
|
||||
*
|
||||
* EditModeCoinManager takes over the responsibility of creating the Coin (Inventor) scenograph
|
||||
* and modifying it, including all the drawing of geometry, constraints and overlay layer. This
|
||||
* is an exclusive responsibility under the Single Responsibility Principle.
|
||||
*
|
||||
* EditModeCoinManager exposes a public interface to be used by ViewProviderSketch. Where,
|
||||
* EditModeCoinManager needs special access to facilities of ViewProviderSketch in order to fulfil
|
||||
* its responsibility, this access is defined by ViewProviderSketchCoinAttorney.
|
||||
*
|
||||
* EditModeCoinManager is responsible, under the Single Responsibility Principle, to manage the coin
|
||||
* EditRoot node. This node is ref-ed on creation and unref-ed on destruction to ensure that its lifetime
|
||||
* matches the one of EditModecoinManager.
|
||||
*
|
||||
* EditRoot is added on request to pcRoot by ViewProviderSketch. The node pcRoot belongs, under the Single
|
||||
* Responsibility Principle, to ViewProviderSketch. EditModeCoinManager delegates addition and removal of
|
||||
* child notes of EditRoot to specialised helper classes.
|
||||
*
|
||||
* EditModeCoinManager is designed to define the span of time in which ViewProviderSketch is in edit mode.
|
||||
*
|
||||
* In addition to the scenograph, EditModeCoinManager is responsible for keeping any necessary mapping between
|
||||
* indices used at ViewProviderSketch level, and internal indexing used by EditModeCoinManager and its subclasses.
|
||||
*/
|
||||
class SketcherGuiExport EditModeCoinManager
|
||||
{
|
||||
/** @brief Class for monitoring changes in parameters affecting drawing and coin node generation
|
||||
* @details
|
||||
*
|
||||
* This nested class is a helper responsible for attaching to the parameters relevant for
|
||||
* EditModeCoinManager and its helpers, initialising the EditModeCoinManager to the current configuration
|
||||
* and handle in real time any change to their values.
|
||||
*/
|
||||
class ParameterObserver : public ParameterGrp::ObserverType
|
||||
{
|
||||
private:
|
||||
enum class OverlayVisibilityParameter {
|
||||
BSplineDegree,
|
||||
BSplineControlPolygonVisible,
|
||||
BSplineCombVisible,
|
||||
BSplineKnotMultiplicityVisible,
|
||||
BSplinePoleWeightVisible
|
||||
};
|
||||
|
||||
public:
|
||||
ParameterObserver(EditModeCoinManager & client);
|
||||
~ParameterObserver();
|
||||
|
||||
void subscribeToParameters();
|
||||
|
||||
void unsubscribeToParameters();
|
||||
|
||||
/** Observer for parameter group. */
|
||||
void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;
|
||||
|
||||
private:
|
||||
void initParameters();
|
||||
void updateCurvedEdgeCountSegmentsParameter(const std::string & parametername);
|
||||
void updateLineRenderingOrderParameters(const std::string & parametername);
|
||||
void updateConstraintPresentationParameters(const std::string & parametername);
|
||||
void updateElementSizeParameters(const std::string & parametername);
|
||||
void updateColor(SbColor &sbcolor, const std::string ¶metername);
|
||||
|
||||
template<OverlayVisibilityParameter visibilityparameter>
|
||||
void updateOverlayVisibilityParameter(const std::string & parametername);
|
||||
|
||||
private:
|
||||
std::map<std::string, std::function<void(const std::string &)>> str2updatefunction;
|
||||
EditModeCoinManager &Client;
|
||||
};
|
||||
|
||||
public:
|
||||
/** @brief This struct defines the information provided to other classes about preselection.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* PointIndex: Only Positive values corresponding to VertexId (are positive for both normal and external geometry)
|
||||
* GeoIndex: Same values as GeoId of GeoElementId, except for axes which are not included. -1 represents an invalid curve.
|
||||
*
|
||||
* In other words valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry
|
||||
*
|
||||
* Cross: Axes and RootPoint values as defined in the enum class.
|
||||
*
|
||||
*/
|
||||
struct PreselectionResult {
|
||||
enum SpecialValues {
|
||||
InvalidPoint = -1,
|
||||
InvalidCurve = -1,
|
||||
ExternalCurve = -3
|
||||
};
|
||||
|
||||
enum class Axes {
|
||||
None = -1,
|
||||
RootPoint = 0,
|
||||
HorizontalAxis = 1,
|
||||
VerticalAxis = 2
|
||||
};
|
||||
|
||||
int PointIndex = InvalidPoint;
|
||||
int GeoIndex = InvalidCurve; // valid values are 0,1,2,... for normal geometry and -3,-4,-5,... for external geometry
|
||||
Axes Cross = Axes::None;
|
||||
std::set<int> ConstrIndices;
|
||||
|
||||
inline void clear() {
|
||||
PointIndex = InvalidPoint;
|
||||
GeoIndex = InvalidCurve;
|
||||
Cross = Axes::None;
|
||||
ConstrIndices.clear();
|
||||
}
|
||||
};
|
||||
|
||||
public:
|
||||
explicit EditModeCoinManager(ViewProviderSketch &vp);
|
||||
~EditModeCoinManager();
|
||||
|
||||
/** @name Temporary edit curves and markers */
|
||||
//@{
|
||||
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel);
|
||||
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
|
||||
void setPositionText(const Base::Vector2d &Pos, const SbString &txt);
|
||||
void setPositionText(const Base::Vector2d &Pos);
|
||||
void resetPositionText(void);
|
||||
void setAxisPickStyle(bool on);
|
||||
//@}
|
||||
|
||||
/** @name handle preselection and selection of points */
|
||||
//@{
|
||||
PreselectionResult detectPreselection(SoPickedPoint * Point, const SbVec2s &cursorPos);
|
||||
/// The client is responsible for unref-ing the SoGroup to release the memory.
|
||||
SoGroup* getSelectedConstraints();
|
||||
//@}
|
||||
|
||||
/** @name update coin nodes*/
|
||||
void processGeometryConstraintsInformationOverlay(const GeoListFacade & geolistfacade, bool rebuildinformationlayer);
|
||||
|
||||
void updateVirtualSpace();
|
||||
|
||||
/// Draw all constraint icons
|
||||
/*! Except maybe the radius and lock ones? */
|
||||
void drawConstraintIcons();
|
||||
|
||||
// This specific overload is to use a specific geometry list, which may be a temporal one
|
||||
void drawConstraintIcons(const GeoList & geolist);
|
||||
//@}
|
||||
|
||||
/** @name coin node access*/
|
||||
SoSeparator* getRootEditNode();
|
||||
//@}
|
||||
|
||||
/** @name update coin colors*/
|
||||
//@{
|
||||
void updateColor();
|
||||
void updateColor(const GeoListFacade & geolistfacade); // overload to be used with temporal geometry.
|
||||
//@}
|
||||
|
||||
|
||||
/** @name change coin visualisation and behaviour*/
|
||||
//@{
|
||||
void updateGridExtent();
|
||||
//@}
|
||||
|
||||
private:
|
||||
// This function populates the coin nodes with the information of the current geometry
|
||||
void processGeometry(const GeoListFacade & geolistfacade);
|
||||
|
||||
// This function populates the geometry information layer of coin. It requires the analysis information
|
||||
// gathered during the processGeometry step, so it is not possible to run both in parallel.
|
||||
void processGeometryInformationOverlay(const GeoListFacade & geolistfacade);
|
||||
|
||||
// updates the Axes length to extend beyond the calculated bounding box magnitude
|
||||
void updateAxesLength();
|
||||
|
||||
// updates the parameters to be used for the Overlay information layer
|
||||
void updateOverlayParameters();
|
||||
|
||||
void updateGeometryColor(const GeoListFacade & geolistfacade, bool issketchinvalid);
|
||||
|
||||
// causes the ViewProvider to draw
|
||||
void redrawViewProvider();
|
||||
|
||||
int defaultApplicationFontSizePixels() const;
|
||||
|
||||
int getApplicationLogicalDPIX() const;
|
||||
|
||||
void updateInventorNodeSizes();
|
||||
|
||||
/** @name coin nodes creation*/
|
||||
void createEditModeInventorNodes();
|
||||
//@}
|
||||
|
||||
private:
|
||||
/// Reference to ViewProviderSketch in order to access the public and the Attorney Interface
|
||||
ViewProviderSketch & viewProvider;
|
||||
/// Observer to track all the needed parameters.
|
||||
std::unique_ptr<EditModeCoinManager::ParameterObserver> pObserver;
|
||||
|
||||
DrawingParameters drawingParameters;
|
||||
AnalysisResults analysisResults;
|
||||
OverlayParameters overlayParameters;
|
||||
ConstraintParameters constraintParameters;
|
||||
GeometryLayerParameters geometryLayerParameters;
|
||||
|
||||
/// The pointers to Coin Scenegraph
|
||||
EditModeScenegraphNodes editModeScenegraphNodes;
|
||||
|
||||
/// Mapping between external and internal indices
|
||||
CoinMapping coinMapping;
|
||||
|
||||
// Coin Helpers
|
||||
std::unique_ptr<EditModeConstraintCoinManager> pEditModeConstraintCoinManager;
|
||||
std::unique_ptr<EditModeGeometryCoinManager> pEditModeGeometryCoinManager;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SketcherGui
|
||||
|
||||
|
||||
#endif // SKETCHERGUI_EditModeCoinManager_H
|
||||
|
||||
79
src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.cpp
Normal file
79
src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
/***************************************************************************
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include "EditModeCoinManagerParameters.h"
|
||||
|
||||
using namespace SketcherGui;
|
||||
|
||||
SbColor DrawingParameters::InformationColor (0.0f,1.0f,0.0f); // #00FF00 -> ( 0,255, 0)
|
||||
SbColor DrawingParameters::CreateCurveColor (0.8f,0.8f,0.8f); // #CCCCCC -> (204,204,204)
|
||||
SbColor DrawingParameters::CrossColorH (0.8f,0.4f,0.4f); // #CC6666 -> (204,102,102)
|
||||
SbColor DrawingParameters::CrossColorV (0.47f,1.0f,0.51f); // #83FF83 -> (120,255,131)
|
||||
SbColor DrawingParameters::InvalidSketchColor (1.0f,0.42f,0.0f); // #FF6D00 -> (255,109, 0)
|
||||
SbColor DrawingParameters::FullyConstrainedColor (0.0f,1.0f,0.0f); // #00FF00 -> ( 0,255, 0)
|
||||
SbColor DrawingParameters::FullyConstraintInternalAlignmentColor (0.87f,0.87f,0.78f); // #DEDEC8 -> (222,222,200)
|
||||
SbColor DrawingParameters::InternalAlignedGeoColor (0.7f,0.7f,0.5f); // #B2B27F -> (178,178,127)
|
||||
SbColor DrawingParameters::FullyConstraintConstructionPointColor (1.0f,0.58f,0.50f); // #FF9580 -> (255,149,128)
|
||||
SbColor DrawingParameters::VertexColor (1.0f,0.149f,0.0f); // #FF2600 -> (255, 38, 0)
|
||||
SbColor DrawingParameters::FullyConstraintElementColor (0.50f,0.81f,0.62f); // #80D0A0 -> (128,208,160)
|
||||
SbColor DrawingParameters::CurveColor (1.0f,1.0f,1.0f); // #FFFFFF -> (255,255,255)
|
||||
SbColor DrawingParameters::PreselectColor (0.88f,0.88f,0.0f); // #E1E100 -> (225,225, 0)
|
||||
SbColor DrawingParameters::SelectColor (0.11f,0.68f,0.11f); // #1CAD1C -> ( 28,173, 28)
|
||||
SbColor DrawingParameters::PreselectSelectedColor (0.36f,0.48f,0.11f); // #5D7B1C -> ( 93,123, 28)
|
||||
SbColor DrawingParameters::CurveExternalColor (0.8f,0.2f,0.6f); // #CC3399 -> (204, 51,153)
|
||||
SbColor DrawingParameters::CurveDraftColor (0.0f,0.0f,0.86f); // #0000DC -> ( 0, 0,220)
|
||||
SbColor DrawingParameters::FullyConstraintConstructionElementColor (0.56f,0.66f,0.99f); // #8FA9FD -> (143,169,253)
|
||||
|
||||
SbColor DrawingParameters::ConstrDimColor (1.0f,0.149f,0.0f); // #FF2600 -> (255, 38, 0)
|
||||
SbColor DrawingParameters::ConstrIcoColor (1.0f,0.149f,0.0f); // #FF2600 -> (255, 38, 0)
|
||||
SbColor DrawingParameters::NonDrivingConstrDimColor (0.0f,0.149f,1.0f); // #0026FF -> ( 0, 38,255)
|
||||
SbColor DrawingParameters::ExprBasedConstrDimColor (1.0f,0.5f,0.149f); // #FF7F26 -> (255, 127,38)
|
||||
SbColor DrawingParameters::DeactivatedConstrDimColor (0.8f,0.8f,0.8f); // #CCCCCC -> (204,204,204)
|
||||
|
||||
QColor DrawingParameters::constrIcoColor( (int)(DrawingParameters::ConstrIcoColor [0] * 255.0f),
|
||||
(int)(DrawingParameters::ConstrIcoColor[1] * 255.0f),
|
||||
(int)(DrawingParameters::ConstrIcoColor[2] * 255.0f));
|
||||
|
||||
QColor DrawingParameters::nonDrivingConstrIcoColor( (int)(DrawingParameters::NonDrivingConstrDimColor[0] * 255.0f),
|
||||
(int)(DrawingParameters::NonDrivingConstrDimColor[1] * 255.0f),
|
||||
(int)(DrawingParameters::NonDrivingConstrDimColor[2] * 255.0f));
|
||||
|
||||
QColor DrawingParameters::constrIconSelColor ( (int)(DrawingParameters::SelectColor[0] * 255.0f),
|
||||
(int)(DrawingParameters::SelectColor[1] * 255.0f),
|
||||
(int)(DrawingParameters::SelectColor[2] * 255.0f));
|
||||
|
||||
QColor DrawingParameters::constrIconPreselColor ( (int)(DrawingParameters::PreselectColor[0] * 255.0f),
|
||||
(int)(DrawingParameters::PreselectColor[1] * 255.0f),
|
||||
(int)(DrawingParameters::PreselectColor[2] * 255.0f));
|
||||
|
||||
QColor DrawingParameters::constrIconDisabledColor ( (int)(DrawingParameters::DeactivatedConstrDimColor[0] * 255.0f),
|
||||
(int)(DrawingParameters::DeactivatedConstrDimColor[1] * 255.0f),
|
||||
(int)(DrawingParameters::DeactivatedConstrDimColor[2] * 255.0f));
|
||||
|
||||
const MultiFieldId MultiFieldId::Invalid = MultiFieldId();
|
||||
417
src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.h
Normal file
417
src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.h
Normal file
@@ -0,0 +1,417 @@
|
||||
/***************************************************************************
|
||||
* 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 zLowPoints = 0.010f; // Height used for bottom rendered points
|
||||
const float zHighPoints = 0.011f; // Height used for in-the-middle rendered points
|
||||
const float zHighlight = 0.012f; // Height for highlighted points (selected/preselected)
|
||||
const float zText = 0.012f; // 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
|
||||
|
||||
2385
src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp
Normal file
2385
src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.cpp
Normal file
File diff suppressed because it is too large
Load Diff
253
src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.h
Normal file
253
src/Mod/Sketcher/Gui/EditModeConstraintCoinManager.h
Normal file
@@ -0,0 +1,253 @@
|
||||
/***************************************************************************
|
||||
* 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_EditModeConstraintCoinManager_H
|
||||
#define SKETCHERGUI_EditModeConstraintCoinManager_H
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
#include <App/Application.h>
|
||||
|
||||
#include <Mod/Sketcher/App/GeoList.h>
|
||||
|
||||
#include "EditModeCoinManagerParameters.h"
|
||||
|
||||
class SbVec3f;
|
||||
class SoRayPickAction;
|
||||
class SoPickedPoint;
|
||||
class SbVec3s;
|
||||
|
||||
namespace Base {
|
||||
template< typename T >
|
||||
class Vector3;
|
||||
|
||||
class Vector2d;
|
||||
|
||||
class Placement;
|
||||
}
|
||||
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace Sketcher {
|
||||
class Constraint;
|
||||
class PropertyConstraintList;
|
||||
};
|
||||
|
||||
namespace SketcherGui {
|
||||
|
||||
class ViewProviderSketch;
|
||||
|
||||
using GeoList = Sketcher::GeoList;
|
||||
using GeoListFacade = Sketcher::GeoListFacade;
|
||||
|
||||
/** @brief Class for managing the Edit mode coin nodes of ViewProviderSketch relating to constraints.
|
||||
* @details To be documented.
|
||||
*
|
||||
*/
|
||||
class SketcherGuiExport EditModeConstraintCoinManager
|
||||
{
|
||||
private:
|
||||
/// Coin Node indices for constraints
|
||||
enum class ConstraintNodePosition {
|
||||
MaterialIndex = 0,
|
||||
DatumLabelIndex = 0,
|
||||
FirstTranslationIndex = 1,
|
||||
FirstIconIndex = 2,
|
||||
FirstConstraintIdIndex = 3,
|
||||
SecondTranslationIndex = 4,
|
||||
SecondIconIndex = 5,
|
||||
SecondConstraintIdIndex = 6
|
||||
};
|
||||
public:
|
||||
explicit EditModeConstraintCoinManager( ViewProviderSketch &vp,
|
||||
DrawingParameters & drawingParams,
|
||||
GeometryLayerParameters & geometryLayerParams,
|
||||
ConstraintParameters & constraintParams,
|
||||
EditModeScenegraphNodes & editModeScenegraph,
|
||||
CoinMapping & coinMap);
|
||||
~EditModeConstraintCoinManager();
|
||||
|
||||
|
||||
/** @name update coin nodes*/
|
||||
// geometry list to be used for constraints, which may be a temporal geometry
|
||||
void processConstraints(const GeoListFacade & geolistfacade);
|
||||
|
||||
void updateVirtualSpace();
|
||||
|
||||
/// Draw all constraint icons
|
||||
/*! Except maybe the radius and lock ones? */
|
||||
void drawConstraintIcons();
|
||||
|
||||
// This specific overload is to use a specific geometry list, which may be a temporal one
|
||||
void drawConstraintIcons(const GeoList & geolist);
|
||||
//@}
|
||||
|
||||
/** @name update coin colors*/
|
||||
//@{
|
||||
void updateConstraintColor(const std::vector<Sketcher::Constraint *> & constraints);
|
||||
//@}
|
||||
|
||||
/** @name coin nodes creation*/
|
||||
void rebuildConstraintNodes(void);
|
||||
//@}
|
||||
|
||||
std::set<int> detectPreselectionConstr( const SoPickedPoint *Point,
|
||||
const SbVec2s &cursorPos);
|
||||
|
||||
SoSeparator * getConstraintIdSeparator(int i);
|
||||
|
||||
void createEditModeInventorNodes();
|
||||
|
||||
private:
|
||||
void rebuildConstraintNodes(const GeoListFacade & geolistfacade); // with specific geometry
|
||||
|
||||
void rebuildConstraintNodes(const GeoListFacade & geolistfacade, const std::vector<Sketcher::Constraint *> constrlist, SbVec3f norm);
|
||||
|
||||
/// finds a free position for placing a constraint icon
|
||||
Base::Vector3d seekConstraintPosition(const Base::Vector3d &origPos,
|
||||
const Base::Vector3d &norm,
|
||||
const Base::Vector3d &dir, float step,
|
||||
const SoNode *constraint);
|
||||
|
||||
/// Return display string for constraint including hiding units if
|
||||
//requested.
|
||||
QString getPresentationString(const Sketcher::Constraint *constraint);
|
||||
|
||||
/// Returns the size that Coin should display the indicated image at
|
||||
SbVec3s getDisplayedSize(const SoImage *) const;
|
||||
|
||||
/** @name Protected helpers for drawing constraint icons*/
|
||||
//@{
|
||||
QString iconTypeFromConstraint(Sketcher::Constraint *constraint);
|
||||
|
||||
/// Returns a QColor object appropriate for constraint with given id
|
||||
/*! In the case of combined icons, the icon color is chosen based on
|
||||
* the constraint with the highest priority from constrColorPriority()
|
||||
*/
|
||||
QColor constrColor(int constraintId);
|
||||
/// Used by drawMergedConstraintIcons to decide what color to make icons
|
||||
/*! See constrColor() */
|
||||
int constrColorPriority(int constraintId);
|
||||
|
||||
// TODO: Review and refactor where these structs and types relating constraints
|
||||
// should actually go.
|
||||
|
||||
// helper data structures for the constraint rendering
|
||||
std::vector<Sketcher::ConstraintType> vConstrType;
|
||||
|
||||
// For each of the combined constraint icons drawn, also create a vector
|
||||
// of bounding boxes and associated constraint IDs, to go from the icon's
|
||||
// pixel coordinates to the relevant constraint IDs.
|
||||
//
|
||||
// The outside map goes from a string representation of a set of constraint
|
||||
// icons (like the one used by the constraint IDs we insert into the Coin
|
||||
// rendering tree) to a vector of those bounding boxes paired with relevant
|
||||
// constraint IDs.
|
||||
|
||||
using ConstrIconBB = std::pair<QRect, std::set<int> >;
|
||||
using ConstrIconBBVec = std::vector<ConstrIconBB>;
|
||||
|
||||
std::map<QString, ConstrIconBBVec> combinedConstrBoxes;
|
||||
|
||||
|
||||
/// Internal type used for drawing constraint icons
|
||||
struct constrIconQueueItem {
|
||||
/// Type of constraint the icon represents. Eg: "small/Constraint_PointOnObject_sm"
|
||||
QString type;
|
||||
|
||||
/// Internal constraint ID number
|
||||
/// These map to results of getSketchObject()->Constraints.getValues()
|
||||
int constraintId;
|
||||
|
||||
/// Label to be rendered with this icon, if any
|
||||
QString label;
|
||||
|
||||
/// Absolute coordinates of the constraint icon
|
||||
SbVec3f position;
|
||||
|
||||
/// Pointer to the SoImage object where the icon should be written
|
||||
SoImage *destination;
|
||||
|
||||
/// Pointer to SoInfo object where we store the constraint IDs that the icon refers to
|
||||
SoInfo *infoPtr;
|
||||
|
||||
/// Angle to rotate an icon
|
||||
double iconRotation;
|
||||
|
||||
bool visible;
|
||||
};
|
||||
|
||||
using IconQueue = std::vector<constrIconQueueItem>;
|
||||
|
||||
void combineConstraintIcons(IconQueue iconQueue);
|
||||
|
||||
/// Renders an icon for a single constraint and sends it to Coin
|
||||
void drawTypicalConstraintIcon(const constrIconQueueItem &i);
|
||||
|
||||
/// Combines multiple constraint icons and sends them to Coin
|
||||
void drawMergedConstraintIcons(IconQueue iconQueue);
|
||||
|
||||
/// Helper for drawMergedConstraintIcons and drawTypicalConstraintIcon
|
||||
QImage renderConstrIcon(const QString &type,
|
||||
const QColor &iconColor,
|
||||
const QStringList &labels,
|
||||
const QList<QColor> &labelColors,
|
||||
double iconRotation,
|
||||
//! Gets populated with bounding boxes (in icon
|
||||
//! image coordinates) for the icon at left, then
|
||||
//! labels for different constraints.
|
||||
std::vector<QRect> *boundingBoxes = NULL,
|
||||
//! If not NULL, gets set to the number of pixels
|
||||
//! that the text extends below the icon base.
|
||||
int *vPad = NULL);
|
||||
|
||||
/// Copies a QImage constraint icon into a SoImage*
|
||||
/*! Used by drawTypicalConstraintIcon() and drawMergedConstraintIcons() */
|
||||
void sendConstraintIconToCoin(const QImage &icon, SoImage *soImagePtr);
|
||||
|
||||
/// Essentially a version of sendConstraintIconToCoin, with a blank icon
|
||||
void clearCoinImage(SoImage *soImagePtr);
|
||||
//@}
|
||||
|
||||
private:
|
||||
ViewProviderSketch & viewProvider;
|
||||
|
||||
DrawingParameters & drawingParameters;
|
||||
GeometryLayerParameters & geometryLayerParameters;
|
||||
ConstraintParameters & constraintParameters;
|
||||
|
||||
EditModeScenegraphNodes & editModeScenegraphNodes;
|
||||
|
||||
CoinMapping & coinMapping;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SketcherGui
|
||||
|
||||
|
||||
#endif // SKETCHERGUI_EditModeConstraintCoinManager_H
|
||||
|
||||
388
src/Mod/Sketcher/Gui/EditModeGeometryCoinConverter.cpp
Normal file
388
src/Mod/Sketcher/Gui/EditModeGeometryCoinConverter.cpp
Normal file
@@ -0,0 +1,388 @@
|
||||
/***************************************************************************
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoGroup.h>
|
||||
# include <Inventor/nodes/SoSwitch.h>
|
||||
# include <Inventor/nodes/SoMaterial.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoLineSet.h>
|
||||
# include <Inventor/nodes/SoFont.h>
|
||||
|
||||
# include <Inventor/nodes/SoTranslation.h>
|
||||
# include <Inventor/nodes/SoText2.h>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
|
||||
#include <Base/UnitsApi.h>
|
||||
|
||||
#include "EditModeCoinManagerParameters.h"
|
||||
|
||||
#include "Mod/Sketcher/App/Constraint.h"
|
||||
|
||||
#include "EditModeGeometryCoinConverter.h"
|
||||
|
||||
|
||||
using namespace SketcherGui;
|
||||
|
||||
EditModeGeometryCoinConverter::EditModeGeometryCoinConverter( GeometryLayerNodes & geometrylayernodes,
|
||||
DrawingParameters & drawingparameters,
|
||||
GeometryLayerParameters& geometryLayerParams,
|
||||
CoinMapping & coinMap ):
|
||||
geometryLayerNodes(geometrylayernodes),
|
||||
drawingParameters(drawingparameters),
|
||||
geometryLayerParameters(geometryLayerParams),
|
||||
coinMapping(coinMap)
|
||||
{}
|
||||
|
||||
void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade & geolistfacade)
|
||||
{
|
||||
|
||||
// measurements
|
||||
bsplineGeoIds.clear();
|
||||
|
||||
// end information layer
|
||||
Coords.clear();
|
||||
Points.clear();
|
||||
Index.clear();
|
||||
|
||||
coinMapping.clear();
|
||||
|
||||
pointCounter.clear();
|
||||
curveCounter.clear();
|
||||
|
||||
for(int l=0; l<geometryLayerParameters.CoinLayers; l++){
|
||||
Coords.emplace_back();
|
||||
Points.emplace_back();
|
||||
Index.emplace_back();
|
||||
|
||||
coinMapping.CurvIdToGeoId.emplace_back();
|
||||
coinMapping.PointIdToGeoId.emplace_back();
|
||||
coinMapping.PointIdToVertexId.emplace_back();
|
||||
}
|
||||
|
||||
pointCounter.resize(geometryLayerParameters.CoinLayers,0);
|
||||
curveCounter.resize(geometryLayerParameters.CoinLayers,0);
|
||||
|
||||
// RootPoint
|
||||
// TODO: RootPoint is here added in layer0. However, this layer may be hidden. The point should,
|
||||
// when that functionality is provided, be added to the first visible layer, or may even a new
|
||||
// empty layer.
|
||||
Points[0].emplace_back(0.,0.,0.);
|
||||
coinMapping.PointIdToGeoId[0].push_back(-1); // root point
|
||||
coinMapping.PointIdToVertexId[0].push_back(-1); // VertexId is the reference used for point selection/preselection
|
||||
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(Sketcher::GeoElementId::RtPnt),
|
||||
std::forward_as_tuple(pointCounter[0]++, 0));
|
||||
|
||||
auto setTracking = [this] (int geoId, int coinLayer, EditModeGeometryCoinConverter::PointsMode pointmode, int numberCurves) {
|
||||
int numberPoints = 0;
|
||||
|
||||
if(pointmode == PointsMode::InsertSingle) {
|
||||
numberPoints = 1;
|
||||
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
|
||||
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
|
||||
}
|
||||
else if (pointmode == PointsMode::InsertStartEnd) {
|
||||
numberPoints = 2;
|
||||
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
|
||||
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
|
||||
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, Sketcher::PointPos::end),
|
||||
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
|
||||
}
|
||||
else if (pointmode == PointsMode::InsertMidOnly) {
|
||||
numberPoints = 1;
|
||||
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, Sketcher::PointPos::mid),
|
||||
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
|
||||
|
||||
|
||||
}
|
||||
else if (pointmode == PointsMode::InsertStartEndMid) {
|
||||
numberPoints = 3;
|
||||
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, Sketcher::PointPos::start),
|
||||
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
|
||||
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, Sketcher::PointPos::end),
|
||||
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
|
||||
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, Sketcher::PointPos::mid),
|
||||
std::forward_as_tuple(pointCounter[coinLayer]++, coinLayer));
|
||||
}
|
||||
|
||||
for(int i = 0; i < numberPoints; i++) {
|
||||
coinMapping.PointIdToGeoId[coinLayer].push_back(geoId);
|
||||
coinMapping.PointIdToVertexId[coinLayer].push_back(vertexCounter++);
|
||||
}
|
||||
|
||||
if(numberCurves > 0) // insert the first segment of the curve into the map
|
||||
coinMapping.GeoElementId2SetId.emplace( std::piecewise_construct,
|
||||
std::forward_as_tuple(geoId, Sketcher::PointPos::none),
|
||||
std::forward_as_tuple(static_cast<int>(coinMapping.CurvIdToGeoId[coinLayer].size()), coinLayer));
|
||||
|
||||
for(int i = 0; i < numberCurves; i++)
|
||||
coinMapping.CurvIdToGeoId[coinLayer].push_back(geoId);
|
||||
};
|
||||
|
||||
for (size_t i = 0 ; i < geolistfacade.geomlist.size()- 2; i++) {
|
||||
|
||||
const auto GeoId = geolistfacade.getGeoIdFromGeomListIndex(i);
|
||||
const auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId);
|
||||
const auto type = geom->getGeometry()->getTypeId();
|
||||
auto layerId = geom->getGeometryLayerId();
|
||||
|
||||
auto coinLayer = geometryLayerParameters.getCoinLayer(layerId);
|
||||
|
||||
if (type == Part::GeomPoint::getClassTypeId()) { // add a point
|
||||
convert< Part::GeomPoint,
|
||||
EditModeGeometryCoinConverter::PointsMode::InsertSingle,
|
||||
EditModeGeometryCoinConverter::CurveMode::NoCurve,
|
||||
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
|
||||
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertSingle, 0);
|
||||
}
|
||||
else if (type == Part::GeomLineSegment::getClassTypeId()) { // add a line
|
||||
convert< Part::GeomLineSegment,
|
||||
EditModeGeometryCoinConverter::PointsMode::InsertStartEnd,
|
||||
EditModeGeometryCoinConverter::CurveMode::StartEndPointsOnly,
|
||||
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
|
||||
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEnd, 1);
|
||||
}
|
||||
else if (type.isDerivedFrom(Part::GeomConic::getClassTypeId())) { // add a closed curve conic
|
||||
convert< Part::GeomConic,
|
||||
EditModeGeometryCoinConverter::PointsMode::InsertMidOnly,
|
||||
EditModeGeometryCoinConverter::CurveMode::ClosedCurve,
|
||||
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
|
||||
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertMidOnly, 1);
|
||||
}
|
||||
else if (type.isDerivedFrom(Part::GeomArcOfConic::getClassTypeId())) { // add an arc of conic
|
||||
convert< Part::GeomArcOfConic,
|
||||
EditModeGeometryCoinConverter::PointsMode::InsertStartEndMid,
|
||||
EditModeGeometryCoinConverter::CurveMode::OpenCurve,
|
||||
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitude>(geom, GeoId);
|
||||
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEndMid, 1);
|
||||
}
|
||||
else if (type == Part::GeomBSplineCurve::getClassTypeId()) { // add a bspline (a bounded curve that is not a conic)
|
||||
convert< Part::GeomBSplineCurve,
|
||||
EditModeGeometryCoinConverter::PointsMode::InsertStartEnd,
|
||||
EditModeGeometryCoinConverter::CurveMode::OpenCurve,
|
||||
EditModeGeometryCoinConverter::AnalyseMode::BoundingBoxMagnitudeAndBSplineCurvature>(geom, GeoId);
|
||||
setTracking(GeoId, coinLayer, EditModeGeometryCoinConverter::PointsMode::InsertStartEnd, 1);
|
||||
bsplineGeoIds.push_back(GeoId);
|
||||
}
|
||||
}
|
||||
|
||||
for(int l=0 ; l < geometryLayerParameters.CoinLayers ; l++) {
|
||||
|
||||
// Coin Nodes Editing
|
||||
geometryLayerNodes.CurvesCoordinate[l]->point.setNum(Coords[l].size());
|
||||
geometryLayerNodes.CurveSet[l]->numVertices.setNum(Index[l].size());
|
||||
geometryLayerNodes.CurvesMaterials[l]->diffuseColor.setNum(Index[l].size());
|
||||
geometryLayerNodes.PointsCoordinate[l]->point.setNum(Points[l].size());
|
||||
geometryLayerNodes.PointsMaterials[l]->diffuseColor.setNum(Points[l].size());
|
||||
|
||||
SbVec3f *verts = geometryLayerNodes.CurvesCoordinate[l]->point.startEditing();
|
||||
int32_t *index = geometryLayerNodes.CurveSet[l]->numVertices.startEditing();
|
||||
SbVec3f *pverts = geometryLayerNodes.PointsCoordinate[l]->point.startEditing();
|
||||
|
||||
int i=0; // setting up the line set
|
||||
for (std::vector<Base::Vector3d>::const_iterator it = Coords[l].begin(); it != Coords[l].end(); ++it,i++)
|
||||
verts[i].setValue(it->x,it->y,drawingParameters.zLowLines);
|
||||
|
||||
i=0; // setting up the indexes of the line set
|
||||
for (std::vector<unsigned int>::const_iterator it = Index[l].begin(); it != Index[l].end(); ++it,i++)
|
||||
index[i] = *it;
|
||||
|
||||
i=0; // setting up the point set
|
||||
for (std::vector<Base::Vector3d>::const_iterator it = Points[l].begin(); it != Points[l].end(); ++it,i++)
|
||||
pverts[i].setValue(it->x,it->y,drawingParameters.zLowPoints);
|
||||
|
||||
geometryLayerNodes.CurvesCoordinate[l]->point.finishEditing();
|
||||
geometryLayerNodes.CurveSet[l]->numVertices.finishEditing();
|
||||
geometryLayerNodes.PointsCoordinate[l]->point.finishEditing();
|
||||
}
|
||||
}
|
||||
|
||||
template < typename GeoType,
|
||||
EditModeGeometryCoinConverter::PointsMode pointmode,
|
||||
EditModeGeometryCoinConverter::CurveMode curvemode,
|
||||
EditModeGeometryCoinConverter::AnalyseMode analysemode >
|
||||
void EditModeGeometryCoinConverter::convert(const Sketcher::GeometryFacade * geometryfacade, [[maybe_unused]] int geoid) {
|
||||
auto geo = static_cast<const GeoType *>(geometryfacade->getGeometry());
|
||||
auto layerId = geometryfacade->getGeometryLayerId();
|
||||
|
||||
auto coinLayer = geometryLayerParameters.getCoinLayer(layerId);
|
||||
|
||||
auto addPoint = [&dMg = boundingBoxMaxMagnitude] (auto & pushvector, Base::Vector3d point) {
|
||||
|
||||
if constexpr (analysemode == AnalyseMode::BoundingBoxMagnitude || analysemode == AnalyseMode::BoundingBoxMagnitudeAndBSplineCurvature) {
|
||||
dMg = dMg>std::abs(point.x)?dMg:std::abs(point.x);
|
||||
dMg = dMg>std::abs(point.y)?dMg:std::abs(point.y);
|
||||
pushvector.push_back(point);
|
||||
}
|
||||
};
|
||||
|
||||
// Points
|
||||
if constexpr (pointmode == PointsMode::InsertSingle) {
|
||||
addPoint(Points[coinLayer], geo->getPoint());
|
||||
}
|
||||
else if constexpr (pointmode == PointsMode::InsertStartEnd) {
|
||||
addPoint(Points[coinLayer], geo->getStartPoint());
|
||||
addPoint(Points[coinLayer], geo->getEndPoint());
|
||||
}
|
||||
else if constexpr (pointmode == PointsMode::InsertStartEndMid) {
|
||||
// All in this group are Trimmed Curves (see Geometry.h)
|
||||
addPoint(Points[coinLayer], geo->getStartPoint(/*emulateCCW=*/true));
|
||||
addPoint(Points[coinLayer], geo->getEndPoint(/*emulateCCW=*/true));
|
||||
addPoint(Points[coinLayer], geo->getCenter());
|
||||
}
|
||||
else if constexpr (pointmode == PointsMode::InsertMidOnly) {
|
||||
addPoint(Points[coinLayer], geo->getCenter());
|
||||
}
|
||||
|
||||
// Curves
|
||||
if constexpr (curvemode == CurveMode::StartEndPointsOnly) {
|
||||
addPoint(Coords[coinLayer], geo->getStartPoint());
|
||||
addPoint(Coords[coinLayer], geo->getEndPoint());
|
||||
Index[coinLayer].push_back(2);
|
||||
}
|
||||
else if constexpr (curvemode == CurveMode::ClosedCurve) {
|
||||
double segment = (geo->getLastParameter() - geo->getFirstParameter()) / drawingParameters.curvedEdgeCountSegments;
|
||||
|
||||
for (int i=0; i < drawingParameters.curvedEdgeCountSegments; i++) {
|
||||
Base::Vector3d pnt = geo->value(i*segment);
|
||||
addPoint(Coords[coinLayer], pnt);
|
||||
}
|
||||
|
||||
Base::Vector3d pnt = geo->value(0);
|
||||
addPoint(Coords[coinLayer], pnt);
|
||||
|
||||
Index[coinLayer].push_back(drawingParameters.curvedEdgeCountSegments+1);
|
||||
}
|
||||
else if constexpr (curvemode == CurveMode::OpenCurve) {
|
||||
|
||||
double segment = (geo->getLastParameter() - geo->getFirstParameter()) / drawingParameters.curvedEdgeCountSegments;
|
||||
|
||||
for (int i=0; i < drawingParameters.curvedEdgeCountSegments; i++) {
|
||||
Base::Vector3d pnt = geo->value(geo->getFirstParameter() + i*segment);
|
||||
addPoint(Coords[coinLayer], pnt);
|
||||
}
|
||||
|
||||
Base::Vector3d pnt = geo->value(geo->getLastParameter());
|
||||
addPoint(Coords[coinLayer], pnt);
|
||||
|
||||
Index[coinLayer].push_back(drawingParameters.curvedEdgeCountSegments+1);
|
||||
|
||||
if constexpr (analysemode == AnalyseMode::BoundingBoxMagnitudeAndBSplineCurvature) {
|
||||
//***************************************************************************************************************
|
||||
// global information gathering for geometry information layer
|
||||
|
||||
std::vector<Base::Vector3d> poles = geo->getPoles();
|
||||
|
||||
Base::Vector3d midp = Base::Vector3d(0,0,0);
|
||||
|
||||
for (std::vector<Base::Vector3d>::iterator it = poles.begin(); it != poles.end(); ++it) {
|
||||
midp += (*it);
|
||||
}
|
||||
|
||||
midp /= poles.size();
|
||||
|
||||
double firstparam = geo->getFirstParameter();
|
||||
double lastparam = geo->getLastParameter();
|
||||
|
||||
const int ndiv = poles.size()>4?poles.size()*16:64;
|
||||
double step = (lastparam - firstparam ) / (ndiv -1);
|
||||
|
||||
std::vector<double> paramlist(ndiv);
|
||||
std::vector<Base::Vector3d> pointatcurvelist(ndiv);
|
||||
std::vector<double> curvaturelist(ndiv);
|
||||
std::vector<Base::Vector3d> normallist(ndiv);
|
||||
|
||||
double maxcurv = 0;
|
||||
double maxdisttocenterofmass = 0;
|
||||
|
||||
for (int i = 0; i < ndiv; i++) {
|
||||
paramlist[i] = firstparam + i * step;
|
||||
pointatcurvelist[i] = geo->pointAtParameter(paramlist[i]);
|
||||
|
||||
try {
|
||||
curvaturelist[i] = geo->curvatureAt(paramlist[i]);
|
||||
}
|
||||
catch(Base::CADKernelError &e) {
|
||||
// it is "just" a visualisation matter OCC could not calculate the curvature
|
||||
// terminating here would mean that the other shapes would not be drawn.
|
||||
// Solution: Report the issue and set dummy curvature to 0
|
||||
e.ReportException();
|
||||
Base::Console().Error("Curvature graph for B-Spline with GeoId=%d could not be calculated.\n", geoid); // TODO: Fix identification of curve.
|
||||
curvaturelist[i] = 0;
|
||||
}
|
||||
|
||||
if (curvaturelist[i] > maxcurv)
|
||||
maxcurv = curvaturelist[i];
|
||||
|
||||
double tempf = ( pointatcurvelist[i] - midp ).Length();
|
||||
|
||||
if (tempf > maxdisttocenterofmass)
|
||||
maxdisttocenterofmass = tempf;
|
||||
|
||||
}
|
||||
|
||||
double temprepscale = 0;
|
||||
if (maxcurv > 0)
|
||||
temprepscale = (0.5 * maxdisttocenterofmass) / maxcurv; // just a factor to make a comb reasonably visible
|
||||
|
||||
if (temprepscale > combrepscale)
|
||||
combrepscale = temprepscale;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
float EditModeGeometryCoinConverter::getBoundingBoxMaxMagnitude()
|
||||
{
|
||||
return boundingBoxMaxMagnitude;
|
||||
}
|
||||
|
||||
double EditModeGeometryCoinConverter::getCombRepresentationScale()
|
||||
{
|
||||
return combrepscale;
|
||||
}
|
||||
163
src/Mod/Sketcher/Gui/EditModeGeometryCoinConverter.h
Normal file
163
src/Mod/Sketcher/Gui/EditModeGeometryCoinConverter.h
Normal file
@@ -0,0 +1,163 @@
|
||||
/***************************************************************************
|
||||
* 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_GeometryCoinConverter_H
|
||||
#define SKETCHERGUI_GeometryCoinConverter_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Base {
|
||||
template< typename T >
|
||||
class Vector3;
|
||||
|
||||
class Vector2d;
|
||||
}
|
||||
|
||||
namespace Sketcher {
|
||||
enum ConstraintType : int;
|
||||
enum class PointPos : int;
|
||||
}
|
||||
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace SketcherGui {
|
||||
struct GeometryLayerNodes;
|
||||
struct DrawingParameters;
|
||||
class GeometryLayerParameters;
|
||||
struct CoinMapping;
|
||||
|
||||
/** @brief Class for creating the Geometry layer into coin nodes
|
||||
* @details
|
||||
* Responsibility:
|
||||
* To create and update GeometryLayer nodes provided as constructor parameter
|
||||
* for the provided geometry, taking into account the drawing parameters provided as
|
||||
* constructor parameters.
|
||||
*
|
||||
* Interface:
|
||||
* A single entry point convert(), performing the following flow:
|
||||
*
|
||||
* [Geometry] => Analysis => construct drawing elements => Create mappings GeoId coin => populate coin nodes
|
||||
*
|
||||
* Analysis performs analysis such as maximum boundingbox magnitude of all geometries and maximum curvature of BSplines
|
||||
*/
|
||||
class EditModeGeometryCoinConverter {
|
||||
// These internal private classes are used to parametrize the conversion of geometry into points and line sets (see template method convert)
|
||||
private:
|
||||
enum class PointsMode {
|
||||
InsertSingle,
|
||||
InsertStartEnd,
|
||||
InsertStartEndMid,
|
||||
InsertMidOnly
|
||||
};
|
||||
|
||||
enum class CurveMode {
|
||||
NoCurve,
|
||||
StartEndPointsOnly,
|
||||
ClosedCurve,
|
||||
OpenCurve
|
||||
};
|
||||
|
||||
enum class AnalyseMode {
|
||||
BoundingBoxMagnitude,
|
||||
BoundingBoxMagnitudeAndBSplineCurvature
|
||||
};
|
||||
|
||||
public:
|
||||
/** Constructs an GeometryCoinConverter responsible for
|
||||
* generating the points and line sets for drawing the geometry
|
||||
* defined by a GeometryLayer into the coin nodes provided by
|
||||
* GeometryLayerNodes.
|
||||
*
|
||||
* @param geometrylayernodes: The coin nodes to be populated with
|
||||
* the geometry
|
||||
*
|
||||
* @param drawingparameters: Parameters for drawing the overlay information
|
||||
*/
|
||||
EditModeGeometryCoinConverter( GeometryLayerNodes & geometrylayernodes,
|
||||
DrawingParameters & drawingparameters,
|
||||
GeometryLayerParameters& geometryLayerParams,
|
||||
CoinMapping & coinMap );
|
||||
|
||||
/**
|
||||
* converts the geometry defined by GeometryLayer into the coin nodes.
|
||||
*
|
||||
* @param geometry: the geometry to be processed
|
||||
*/
|
||||
void convert(const Sketcher::GeoListFacade & geolistfacade);
|
||||
|
||||
/**
|
||||
* returns the maximum of the vertical and horizontal magnitudes of the
|
||||
* coordinates of the points and lines added to coin by this layer (local responsibility).
|
||||
*/
|
||||
float getBoundingBoxMaxMagnitude();
|
||||
|
||||
/**
|
||||
* returns the Comb representation scale that should be used to represent
|
||||
* the B-Splines of this layer (local responsibility).
|
||||
*/
|
||||
double getCombRepresentationScale();
|
||||
|
||||
/**
|
||||
* returns the GeoIds of BSpline geometries
|
||||
*/
|
||||
auto getBSplineGeoIds(){ return std::move(bsplineGeoIds);}
|
||||
|
||||
private:
|
||||
template < typename GeoType, PointsMode pointmode, CurveMode curvemode, AnalyseMode analysemode >
|
||||
void convert(const Sketcher::GeometryFacade * geometryfacade, [[maybe_unused]] int geoId);
|
||||
|
||||
private:
|
||||
GeometryLayerNodes & geometryLayerNodes;
|
||||
|
||||
std::vector<std::vector<Base::Vector3d>> Coords;
|
||||
std::vector<std::vector<Base::Vector3d>> Points;
|
||||
std::vector<std::vector<unsigned int>> Index;
|
||||
|
||||
// temporal counters, one per layer
|
||||
std::vector<int> pointCounter;
|
||||
std::vector<int> curveCounter;
|
||||
|
||||
// temporal global vertex counter
|
||||
int vertexCounter = 0;
|
||||
|
||||
// Parameters
|
||||
DrawingParameters & drawingParameters;
|
||||
GeometryLayerParameters& geometryLayerParameters;
|
||||
// Mappings coin geoId
|
||||
CoinMapping & coinMapping;
|
||||
|
||||
// measurements
|
||||
float boundingBoxMaxMagnitude = 100;
|
||||
double combrepscale = 0; // the repscale that would correspond to this comb based only on this calculation.
|
||||
std::vector<int> bsplineGeoIds;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace SketcherGui
|
||||
|
||||
|
||||
#endif // SKETCHERGUI_GeometryCoinConverter_H
|
||||
|
||||
544
src/Mod/Sketcher/Gui/EditModeGeometryCoinManager.cpp
Normal file
544
src/Mod/Sketcher/Gui/EditModeGeometryCoinManager.cpp
Normal file
@@ -0,0 +1,544 @@
|
||||
/***************************************************************************
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoGroup.h>
|
||||
# include <Inventor/nodes/SoSwitch.h>
|
||||
# include <Inventor/nodes/SoMaterial.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoLineSet.h>
|
||||
# include <Inventor/nodes/SoFont.h>
|
||||
|
||||
# include <Inventor/nodes/SoMarkerSet.h>
|
||||
# include <Inventor/nodes/SoTranslation.h>
|
||||
# include <Inventor/nodes/SoText2.h>
|
||||
# include <Inventor/nodes/SoPickStyle.h>
|
||||
# include <Inventor/nodes/SoDrawStyle.h>
|
||||
# include <Inventor/SoPickedPoint.h>
|
||||
# include <Inventor/details/SoPointDetail.h>
|
||||
# include <Inventor/details/SoDetail.h>
|
||||
# include <Inventor/details/SoLineDetail.h>
|
||||
|
||||
# include <Inventor/nodes/SoAnnotation.h>
|
||||
# include <Inventor/nodes/SoImage.h>
|
||||
# include <Inventor/nodes/SoInfo.h>
|
||||
|
||||
# include <Inventor/actions/SoRayPickAction.h>
|
||||
|
||||
# include <Inventor/SbVec3f.h>
|
||||
# include <Inventor/SbImage.h>
|
||||
|
||||
# include <memory>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include <Gui/Inventor/SmSwitchboard.h>
|
||||
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Mod/Sketcher/App/GeometryFacade.h>
|
||||
#include <Mod/Sketcher/App/SolverGeometryExtension.h>
|
||||
#include <Mod/Sketcher/App/GeoEnum.h>
|
||||
#include <Mod/Sketcher/App/Constraint.h>
|
||||
#include <Mod/Sketcher/App/GeoList.h>
|
||||
|
||||
#include <Base/Exception.h>
|
||||
#include <Base/Tools2D.h>
|
||||
#include <Base/UnitsApi.h>
|
||||
#include <Gui/Utilities.h>
|
||||
#include <Base/Converter.h>
|
||||
#include <Base/Tools.h>
|
||||
|
||||
#include <Base/Vector3D.h>
|
||||
|
||||
#include <App/ObjectIdentifier.h>
|
||||
|
||||
#include <Gui/SoFCBoundingBox.h>
|
||||
#include <Gui/BitmapFactory.h>
|
||||
#include <Gui/Inventor/MarkerBitmaps.h>
|
||||
#include <Gui/Tools.h>
|
||||
|
||||
#include <qpainter.h>
|
||||
|
||||
#include "SoZoomTranslation.h"
|
||||
#include "SoDatumLabel.h"
|
||||
|
||||
#include "EditModeInformationOverlayCoinConverter.h"
|
||||
|
||||
#include "EditModeGeometryCoinConverter.h"
|
||||
|
||||
#include "ViewProviderSketch.h"
|
||||
|
||||
#include "ViewProviderSketchCoinAttorney.h"
|
||||
|
||||
#include "EditModeConstraintCoinManager.h"
|
||||
|
||||
#include "EditModeGeometryCoinManager.h"
|
||||
|
||||
using namespace SketcherGui;
|
||||
using namespace Sketcher;
|
||||
|
||||
//**************************** EditModeGeometryCoinManager class ******************************
|
||||
|
||||
EditModeGeometryCoinManager::EditModeGeometryCoinManager( ViewProviderSketch &vp,
|
||||
DrawingParameters & drawingParams,
|
||||
GeometryLayerParameters & geometryLayerParams,
|
||||
AnalysisResults & analysisResultStruct,
|
||||
EditModeScenegraphNodes & editModeScenegraph,
|
||||
CoinMapping & coinMap):
|
||||
viewProvider(vp),
|
||||
drawingParameters(drawingParams),
|
||||
geometryLayerParameters(geometryLayerParams),
|
||||
analysisResults(analysisResultStruct),
|
||||
editModeScenegraphNodes(editModeScenegraph),
|
||||
coinMapping(coinMap)
|
||||
{}
|
||||
|
||||
EditModeGeometryCoinManager::~EditModeGeometryCoinManager()
|
||||
{}
|
||||
|
||||
void EditModeGeometryCoinManager::processGeometry(const GeoListFacade & geolistfacade)
|
||||
{
|
||||
// enable all layers
|
||||
editModeScenegraphNodes.PointsGroup->enable.setNum(geometryLayerParameters.CoinLayers);
|
||||
editModeScenegraphNodes.CurvesGroup->enable.setNum(geometryLayerParameters.CoinLayers);
|
||||
SbBool *swsp = editModeScenegraphNodes.PointsGroup->enable.startEditing();
|
||||
SbBool *swsc = editModeScenegraphNodes.CurvesGroup->enable.startEditing();
|
||||
|
||||
for(int l=0; l<geometryLayerParameters.CoinLayers; l++){
|
||||
swsp[l] = true; // layer defaults to enabled
|
||||
swsc[l] = true; // layer defaults to enabled
|
||||
}
|
||||
|
||||
editModeScenegraphNodes.PointsGroup->enable.finishEditing();
|
||||
editModeScenegraphNodes.CurvesGroup->enable.finishEditing();
|
||||
|
||||
// Define the coin nodes that will be filled in with the geometry layers
|
||||
GeometryLayerNodes geometrylayernodes {
|
||||
editModeScenegraphNodes.PointsMaterials,
|
||||
editModeScenegraphNodes.PointsCoordinate,
|
||||
editModeScenegraphNodes.CurvesMaterials,
|
||||
editModeScenegraphNodes.CurvesCoordinate,
|
||||
editModeScenegraphNodes.CurveSet
|
||||
};
|
||||
|
||||
// process geometry layers
|
||||
EditModeGeometryCoinConverter gcconv(geometrylayernodes, drawingParameters, geometryLayerParameters, coinMapping);
|
||||
|
||||
gcconv.convert(geolistfacade);
|
||||
|
||||
// set cross coordinates
|
||||
editModeScenegraphNodes.RootCrossSet->numVertices.set1Value(0,2);
|
||||
editModeScenegraphNodes.RootCrossSet->numVertices.set1Value(1,2);
|
||||
|
||||
analysisResults.combRepresentationScale = gcconv.getCombRepresentationScale();
|
||||
analysisResults.boundingBoxMagnitudeOrder = exp(ceil(log(std::abs(gcconv.getBoundingBoxMaxMagnitude()))));
|
||||
analysisResults.bsplineGeoIds = gcconv.getBSplineGeoIds();
|
||||
}
|
||||
|
||||
void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade & geolistfacade, bool issketchinvalid)
|
||||
{
|
||||
// Lambdas for convenience retrieval of geometry information
|
||||
auto isConstructionGeom = [&geolistfacade](int GeoId) {
|
||||
auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId);
|
||||
if (geom)
|
||||
return geom->getConstruction();
|
||||
return false;
|
||||
};
|
||||
|
||||
auto isDefinedGeomPoint = [&geolistfacade](int GeoId) {
|
||||
auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId);
|
||||
if (geom)
|
||||
return geom->isGeoType(Part::GeomPoint::getClassTypeId()) && !geom->getConstruction();
|
||||
return false;
|
||||
};
|
||||
|
||||
auto isInternalAlignedGeom = [&geolistfacade](int GeoId) {
|
||||
auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId);
|
||||
if (geom) {
|
||||
return geom->isInternalAligned();
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
auto isFullyConstraintElement = [&geolistfacade](int GeoId) {
|
||||
auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId);
|
||||
|
||||
if(geom) {
|
||||
if(geom->hasExtension(Sketcher::SolverGeometryExtension::getClassTypeId())) {
|
||||
|
||||
auto solvext = std::static_pointer_cast<const Sketcher::SolverGeometryExtension>(
|
||||
geom->getExtension(Sketcher::SolverGeometryExtension::getClassTypeId()).lock());
|
||||
|
||||
return (solvext->getGeometry() == Sketcher::SolverGeometryExtension::FullyConstraint);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
// Update Colors
|
||||
|
||||
SbColor *crosscolor = editModeScenegraphNodes.RootCrossMaterials->diffuseColor.startEditing();
|
||||
|
||||
for(int l=0; l<geometryLayerParameters.CoinLayers; l++) {
|
||||
|
||||
int PtNum = editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.getNum();
|
||||
SbColor *pcolor = editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.startEditing();
|
||||
int CurvNum = editModeScenegraphNodes.CurvesMaterials[l]->diffuseColor.getNum();
|
||||
SbColor *color = editModeScenegraphNodes.CurvesMaterials[l]->diffuseColor.startEditing();
|
||||
|
||||
SbVec3f *verts = editModeScenegraphNodes.CurvesCoordinate[l]->point.startEditing();
|
||||
SbVec3f *pverts = editModeScenegraphNodes.PointsCoordinate[l]->point.startEditing();
|
||||
|
||||
float x,y,z;
|
||||
|
||||
// colors of the point set
|
||||
if( issketchinvalid ) {
|
||||
for (int i=0; i < PtNum; i++)
|
||||
pcolor[i] = drawingParameters.InvalidSketchColor;
|
||||
}
|
||||
else if (ViewProviderSketchCoinAttorney::isSketchFullyConstrained(viewProvider)) {
|
||||
for (int i=0; i < PtNum; i++)
|
||||
pcolor[i] = drawingParameters.FullyConstrainedColor;
|
||||
}
|
||||
else {
|
||||
for (int i=0; i < PtNum; i++) {
|
||||
int GeoId = coinMapping.getPointGeoId(i, l);
|
||||
|
||||
bool constrainedElement = isFullyConstraintElement(GeoId);
|
||||
|
||||
if(isInternalAlignedGeom(GeoId)) {
|
||||
if(constrainedElement)
|
||||
pcolor[i] = drawingParameters.FullyConstraintInternalAlignmentColor;
|
||||
else
|
||||
pcolor[i] = drawingParameters.InternalAlignedGeoColor;
|
||||
}
|
||||
else {
|
||||
if(!isDefinedGeomPoint(GeoId)) {
|
||||
|
||||
if(constrainedElement)
|
||||
pcolor[i] = drawingParameters.FullyConstraintConstructionPointColor;
|
||||
else
|
||||
pcolor[i] = drawingParameters.VertexColor;
|
||||
}
|
||||
else { // this is a defined GeomPoint
|
||||
if(constrainedElement)
|
||||
pcolor[i] = drawingParameters.FullyConstraintElementColor;
|
||||
else
|
||||
pcolor[i] = drawingParameters.CurveColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update rendering height of points
|
||||
|
||||
auto getRenderHeight = [this](DrawingParameters::GeometryRendering renderingtype, float toprendering, float midrendering, float lowrendering) {
|
||||
if(drawingParameters.topRenderingGeometry == renderingtype)
|
||||
return toprendering;
|
||||
else if(drawingParameters.midRenderingGeometry == renderingtype)
|
||||
return midrendering;
|
||||
else
|
||||
return lowrendering;
|
||||
};
|
||||
|
||||
float zNormPoint = getRenderHeight(DrawingParameters::GeometryRendering::NormalGeometry,
|
||||
drawingParameters.zHighPoints,
|
||||
drawingParameters.zLowPoints,
|
||||
drawingParameters.zLowPoints);
|
||||
|
||||
float zConstrPoint = getRenderHeight(DrawingParameters::GeometryRendering::Construction,
|
||||
drawingParameters.zHighPoints,
|
||||
drawingParameters.zLowPoints,
|
||||
drawingParameters.zLowPoints);
|
||||
|
||||
|
||||
for (int i=0; i < PtNum; i++) { // 0 is the origin
|
||||
pverts[i].getValue(x,y,z);
|
||||
auto geom = geolistfacade.getGeometryFacadeFromGeoId(coinMapping.getPointGeoId(i, l));
|
||||
if(geom && z < drawingParameters.zHighlight) {
|
||||
if(geom->getConstruction())
|
||||
pverts[i].setValue(x,y,zConstrPoint);
|
||||
else
|
||||
pverts[i].setValue(x,y,zNormPoint);
|
||||
}
|
||||
}
|
||||
|
||||
auto preselectpoint = ViewProviderSketchCoinAttorney::getPreselectPoint(viewProvider);
|
||||
auto preselectcross = ViewProviderSketchCoinAttorney::getPreselectCross(viewProvider);
|
||||
auto preselectcurve = ViewProviderSketchCoinAttorney::getPreselectCurve(viewProvider);
|
||||
|
||||
MultiFieldId preselectpointmfid;
|
||||
|
||||
if ( preselectcross == 0) {
|
||||
if(l == 0) // cross only in layer 0
|
||||
pcolor[0] = drawingParameters.PreselectColor;
|
||||
}
|
||||
else if (preselectpoint != -1) {
|
||||
preselectpointmfid = coinMapping.getIndexLayer(preselectpoint);
|
||||
if (l == preselectpointmfid.layerId && preselectpointmfid.fieldIndex < PtNum)
|
||||
pcolor[preselectpointmfid.fieldIndex] = drawingParameters.PreselectColor;
|
||||
}
|
||||
|
||||
ViewProviderSketchCoinAttorney::executeOnSelectionPointSet(viewProvider,
|
||||
[pcolor, PtNum, preselectpointmfid, layerId = l, &coinMapping = coinMapping, drawingParameters = this->drawingParameters](const int i) {
|
||||
auto pointindex = coinMapping.getIndexLayer(i);
|
||||
if (layerId == pointindex.layerId && pointindex.fieldIndex < PtNum) {
|
||||
pcolor[pointindex.fieldIndex] = (preselectpointmfid == pointindex)
|
||||
? drawingParameters.PreselectSelectedColor : drawingParameters.SelectColor;
|
||||
}
|
||||
});
|
||||
|
||||
// update colors and rendering height of the curves
|
||||
|
||||
float zNormLine = getRenderHeight(DrawingParameters::GeometryRendering::NormalGeometry,
|
||||
drawingParameters.zHighLines,
|
||||
drawingParameters.zMidLines,
|
||||
drawingParameters.zLowLines);
|
||||
|
||||
float zConstrLine = getRenderHeight(DrawingParameters::GeometryRendering::Construction,
|
||||
drawingParameters.zHighLines,
|
||||
drawingParameters.zMidLines,
|
||||
drawingParameters.zLowLines);
|
||||
|
||||
float zExtLine = getRenderHeight(DrawingParameters::GeometryRendering::ExternalGeometry,
|
||||
drawingParameters.zHighLines,
|
||||
drawingParameters.zMidLines,
|
||||
drawingParameters.zLowLines);
|
||||
|
||||
int j=0; // vertexindex
|
||||
|
||||
for (int i=0; i < CurvNum; i++) {
|
||||
int GeoId = coinMapping.getCurveGeoId(i, l);
|
||||
// CurvId has several vertices associated to 1 material
|
||||
//edit->CurveSet->numVertices => [i] indicates number of vertex for line i.
|
||||
int indexes = (editModeScenegraphNodes.CurveSet[l]->numVertices[i]);
|
||||
|
||||
bool selected = ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider, GeoId);
|
||||
bool preselected = (preselectcurve == GeoId);
|
||||
|
||||
bool constrainedElement = isFullyConstraintElement(GeoId);
|
||||
|
||||
if (selected && preselected) {
|
||||
color[i] = drawingParameters.PreselectSelectedColor;
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,drawingParameters.zHighLine);
|
||||
}
|
||||
}
|
||||
else if (selected){
|
||||
color[i] = drawingParameters.SelectColor;
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,drawingParameters.zHighLine);
|
||||
}
|
||||
}
|
||||
else if (preselected){
|
||||
color[i] = drawingParameters.PreselectColor;
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,drawingParameters.zHighLine);
|
||||
}
|
||||
}
|
||||
else if (GeoId <= Sketcher::GeoEnum::RefExt) { // external Geometry
|
||||
color[i] = drawingParameters.CurveExternalColor;
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,zExtLine);
|
||||
}
|
||||
}
|
||||
else if ( issketchinvalid ) {
|
||||
color[i] = drawingParameters.InvalidSketchColor;
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,zNormLine);
|
||||
}
|
||||
}
|
||||
else if (isConstructionGeom(GeoId)) {
|
||||
if(isInternalAlignedGeom(GeoId)) {
|
||||
if(constrainedElement)
|
||||
color[i] = drawingParameters.FullyConstraintInternalAlignmentColor;
|
||||
else
|
||||
color[i] = drawingParameters.InternalAlignedGeoColor;
|
||||
}
|
||||
else {
|
||||
if(constrainedElement)
|
||||
color[i] = drawingParameters.FullyConstraintConstructionElementColor;
|
||||
else
|
||||
color[i] = drawingParameters.CurveDraftColor;
|
||||
}
|
||||
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,zConstrLine);
|
||||
}
|
||||
}
|
||||
else if (ViewProviderSketchCoinAttorney::isSketchFullyConstrained(viewProvider)) {
|
||||
color[i] = drawingParameters.FullyConstrainedColor;
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,zNormLine);
|
||||
}
|
||||
}
|
||||
else if (isFullyConstraintElement(GeoId)) {
|
||||
color[i] = drawingParameters.FullyConstraintElementColor;
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,zNormLine);
|
||||
}
|
||||
}
|
||||
else {
|
||||
color[i] = drawingParameters.CurveColor;
|
||||
for (int k=j; j<k+indexes; j++) {
|
||||
verts[j].getValue(x,y,z);
|
||||
verts[j] = SbVec3f(x,y,zNormLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// colors of the cross
|
||||
if ( l == 0 ) { // only in layer 0
|
||||
if (ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider, Sketcher::GeoEnum::HAxis)) {
|
||||
crosscolor[0] = drawingParameters.SelectColor;
|
||||
}
|
||||
else if (preselectcross == 1) { // cross only in layer 0
|
||||
crosscolor[0] = drawingParameters.PreselectColor;
|
||||
}
|
||||
else {
|
||||
crosscolor[0] = drawingParameters.CrossColorH;
|
||||
}
|
||||
|
||||
if (ViewProviderSketchCoinAttorney::isCurveSelected(viewProvider, Sketcher::GeoEnum::VAxis)) {
|
||||
crosscolor[1] = drawingParameters.SelectColor;
|
||||
}
|
||||
else if (preselectcross == 2) {
|
||||
crosscolor[1] = drawingParameters.PreselectColor;
|
||||
}
|
||||
else {
|
||||
crosscolor[1] = drawingParameters.CrossColorV;
|
||||
}
|
||||
}
|
||||
|
||||
// end editing
|
||||
editModeScenegraphNodes.CurvesMaterials[l]->diffuseColor.finishEditing();
|
||||
editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.finishEditing();
|
||||
editModeScenegraphNodes.CurvesCoordinate[l]->point.finishEditing();
|
||||
editModeScenegraphNodes.CurveSet[l]->numVertices.finishEditing();
|
||||
}
|
||||
|
||||
editModeScenegraphNodes.RootCrossMaterials->diffuseColor.finishEditing();
|
||||
}
|
||||
|
||||
|
||||
void EditModeGeometryCoinManager::createEditModeInventorNodes()
|
||||
{
|
||||
// stuff for the points ++++++++++++++++++++++++++++++++++++++
|
||||
editModeScenegraphNodes.PointsGroup = new SmSwitchboard;
|
||||
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.PointsGroup);
|
||||
|
||||
auto concat = [](std::string string, int i) {
|
||||
return string+std::to_string(i);
|
||||
};
|
||||
|
||||
for(int i=0; i < geometryLayerParameters.CoinLayers; i++) {
|
||||
SoSeparator * sep = new SoSeparator;
|
||||
sep->ref();
|
||||
|
||||
auto somaterial = new SoMaterial;
|
||||
editModeScenegraphNodes.PointsMaterials.push_back(somaterial);
|
||||
editModeScenegraphNodes.PointsMaterials[i]->setName(concat("PointsMaterials_",i).c_str());
|
||||
sep->addChild(editModeScenegraphNodes.PointsMaterials[i]);
|
||||
|
||||
SoMaterialBinding *MtlBind = new SoMaterialBinding;
|
||||
MtlBind->setName(concat("PointsMaterialBinding",i).c_str());
|
||||
MtlBind->value = SoMaterialBinding::PER_VERTEX;
|
||||
sep->addChild(MtlBind);
|
||||
|
||||
auto coords = new SoCoordinate3;
|
||||
editModeScenegraphNodes.PointsCoordinate.push_back(coords);
|
||||
editModeScenegraphNodes.PointsCoordinate[i]->setName(concat("PointsCoordinate",i).c_str());
|
||||
sep->addChild(editModeScenegraphNodes.PointsCoordinate[i]);
|
||||
|
||||
auto drawstyle = new SoDrawStyle;
|
||||
editModeScenegraphNodes.PointsDrawStyle.push_back(drawstyle);
|
||||
editModeScenegraphNodes.PointsDrawStyle[i]->setName(concat("PointsDrawStyle",i).c_str());
|
||||
editModeScenegraphNodes.PointsDrawStyle[i]->pointSize = 8 * drawingParameters.pixelScalingFactor;
|
||||
sep->addChild(editModeScenegraphNodes.PointsDrawStyle[i]);
|
||||
|
||||
auto pointset = new SoMarkerSet;
|
||||
editModeScenegraphNodes.PointSet.push_back(pointset);
|
||||
editModeScenegraphNodes.PointSet[i]->setName(concat("PointSet",i).c_str());
|
||||
editModeScenegraphNodes.PointSet[i]->markerIndex = Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_FILLED", drawingParameters.markerSize);
|
||||
sep->addChild(editModeScenegraphNodes.PointSet[i]);
|
||||
|
||||
editModeScenegraphNodes.PointsGroup->addChild(sep);
|
||||
sep->unref();
|
||||
}
|
||||
|
||||
// stuff for the Curves +++++++++++++++++++++++++++++++++++++++
|
||||
editModeScenegraphNodes.CurvesGroup = new SmSwitchboard;
|
||||
editModeScenegraphNodes.EditRoot->addChild(editModeScenegraphNodes.CurvesGroup);
|
||||
|
||||
for(int i=0; i < geometryLayerParameters.CoinLayers; i++) {
|
||||
SoSeparator * sep = new SoSeparator;
|
||||
sep->ref();
|
||||
|
||||
auto somaterial = new SoMaterial;
|
||||
editModeScenegraphNodes.CurvesMaterials.push_back(somaterial);
|
||||
editModeScenegraphNodes.CurvesMaterials[i]->setName(concat("CurvesMaterials",i).c_str());
|
||||
sep->addChild(editModeScenegraphNodes.CurvesMaterials[i]);
|
||||
|
||||
auto MtlBind = new SoMaterialBinding;
|
||||
MtlBind->setName(concat("CurvesMaterialsBinding",i).c_str());
|
||||
MtlBind->value = SoMaterialBinding::PER_FACE;
|
||||
sep->addChild(MtlBind);
|
||||
|
||||
auto coords = new SoCoordinate3;
|
||||
editModeScenegraphNodes.CurvesCoordinate.push_back(coords);
|
||||
editModeScenegraphNodes.CurvesCoordinate[i]->setName(concat("CurvesCoordinate",i).c_str());
|
||||
sep->addChild(editModeScenegraphNodes.CurvesCoordinate[i]);
|
||||
|
||||
auto drawstyle = new SoDrawStyle;
|
||||
editModeScenegraphNodes.CurvesDrawStyle.push_back(drawstyle);
|
||||
editModeScenegraphNodes.CurvesDrawStyle[i]->setName(concat("CurvesDrawStyle",i).c_str());
|
||||
editModeScenegraphNodes.CurvesDrawStyle[i]->lineWidth = 3 * drawingParameters.pixelScalingFactor;
|
||||
|
||||
/* Demo code to introduce a dashed line
|
||||
if(i == 1) {
|
||||
editModeScenegraphNodes.CurvesDrawStyle[i]->linePattern = 0x3CF2;
|
||||
editModeScenegraphNodes.CurvesDrawStyle[i]->linePatternScaleFactor = 5;
|
||||
}*/
|
||||
|
||||
sep->addChild(editModeScenegraphNodes.CurvesDrawStyle[i]);
|
||||
|
||||
auto solineset = new SoLineSet;
|
||||
editModeScenegraphNodes.CurveSet.push_back(solineset);
|
||||
editModeScenegraphNodes.CurveSet[i]->setName(concat("CurvesLineSet",i).c_str());
|
||||
sep->addChild(editModeScenegraphNodes.CurveSet[i]);
|
||||
|
||||
editModeScenegraphNodes.CurvesGroup->addChild(sep);
|
||||
sep->unref();
|
||||
}
|
||||
|
||||
}
|
||||
123
src/Mod/Sketcher/Gui/EditModeGeometryCoinManager.h
Normal file
123
src/Mod/Sketcher/Gui/EditModeGeometryCoinManager.h
Normal file
@@ -0,0 +1,123 @@
|
||||
/***************************************************************************
|
||||
* 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_EditModeGeometryCoinManager_H
|
||||
#define SKETCHERGUI_EditModeGeometryCoinManager_H
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
#include <Base/Parameter.h>
|
||||
#include <App/Application.h>
|
||||
|
||||
#include "EditModeCoinManagerParameters.h"
|
||||
|
||||
#include <Mod/Sketcher/App/GeoList.h>
|
||||
|
||||
class SbVec3f;
|
||||
class SoRayPickAction;
|
||||
class SoPickedPoint;
|
||||
class SbVec3s;
|
||||
|
||||
namespace Base {
|
||||
template< typename T >
|
||||
class Vector3;
|
||||
|
||||
class Vector2d;
|
||||
|
||||
class Placement;
|
||||
}
|
||||
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace Sketcher {
|
||||
class Constraint;
|
||||
class PropertyConstraintList;
|
||||
};
|
||||
|
||||
namespace SketcherGui {
|
||||
|
||||
class ViewProviderSketch;
|
||||
class EditModeConstraintCoinManager;
|
||||
|
||||
using GeoList = Sketcher::GeoList;
|
||||
using GeoListFacade = Sketcher::GeoListFacade;
|
||||
|
||||
/** @brief Class for managing the Edit mode coin nodes of ViewProviderSketch relating to geometry.
|
||||
* @details
|
||||
*
|
||||
* EditModeGeometryCoinManager is a helper of EditModeCoinManager specialised in geometry management.
|
||||
*
|
||||
* Three main functions are delegated to it:
|
||||
* 1. Creation of Edit mode coin nodes to handle Geometry representation.
|
||||
* 2. Converting Sketcher geometry into Coin information.
|
||||
* 3. Updating the Geometry colors.
|
||||
*
|
||||
* Internally, EditModeGeometryCoinManager uses yet another class for geometry conversion,
|
||||
* GeometryCoinConverter.
|
||||
*
|
||||
*/
|
||||
class SketcherGuiExport EditModeGeometryCoinManager
|
||||
{
|
||||
|
||||
public:
|
||||
explicit EditModeGeometryCoinManager( ViewProviderSketch &vp,
|
||||
DrawingParameters & drawingParams,
|
||||
GeometryLayerParameters & geometryLayerParams,
|
||||
AnalysisResults & analysisResultStruct,
|
||||
EditModeScenegraphNodes & editModeScenegraph,
|
||||
CoinMapping & coinMap);
|
||||
~EditModeGeometryCoinManager();
|
||||
|
||||
|
||||
// This function populates the coin nodes with the information of the current geometry
|
||||
void processGeometry(const GeoListFacade & geolistfacade);
|
||||
|
||||
void updateGeometryColor(const GeoListFacade & geolistfacade, bool issketchinvalid);
|
||||
|
||||
/** @name coin nodes creation*/
|
||||
void createEditModeInventorNodes();
|
||||
//@}
|
||||
|
||||
|
||||
private:
|
||||
ViewProviderSketch & viewProvider;
|
||||
|
||||
DrawingParameters & drawingParameters;
|
||||
GeometryLayerParameters & geometryLayerParameters;
|
||||
AnalysisResults & analysisResults;
|
||||
|
||||
EditModeScenegraphNodes & editModeScenegraphNodes;
|
||||
|
||||
CoinMapping & coinMapping;
|
||||
|
||||
};
|
||||
|
||||
|
||||
} // namespace SketcherGui
|
||||
|
||||
|
||||
#endif // SKETCHERGUI_EditModeGeometryCoinManager_H
|
||||
|
||||
446
src/Mod/Sketcher/Gui/EditModeInformationOverlayCoinConverter.cpp
Normal file
446
src/Mod/Sketcher/Gui/EditModeInformationOverlayCoinConverter.cpp
Normal file
@@ -0,0 +1,446 @@
|
||||
/***************************************************************************
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
# include <Inventor/nodes/SoSeparator.h>
|
||||
# include <Inventor/nodes/SoGroup.h>
|
||||
# include <Inventor/nodes/SoSwitch.h>
|
||||
# include <Inventor/nodes/SoMaterial.h>
|
||||
# include <Inventor/nodes/SoCoordinate3.h>
|
||||
# include <Inventor/nodes/SoLineSet.h>
|
||||
# include <Inventor/nodes/SoFont.h>
|
||||
|
||||
# include <Inventor/nodes/SoTranslation.h>
|
||||
# include <Inventor/nodes/SoText2.h>
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include <Mod/Part/App/Geometry.h>
|
||||
#include <Base/Console.h>
|
||||
#include <Base/Exception.h>
|
||||
|
||||
#include <Base/UnitsApi.h>
|
||||
|
||||
#include "EditModeCoinManagerParameters.h"
|
||||
|
||||
#include "EditModeInformationOverlayCoinConverter.h"
|
||||
|
||||
|
||||
using namespace SketcherGui;
|
||||
|
||||
EditModeInformationOverlayCoinConverter::EditModeInformationOverlayCoinConverter(
|
||||
SoGroup * infogroup,
|
||||
OverlayParameters & overlayparameters,
|
||||
DrawingParameters & drawingparameters): infoGroup(infogroup),
|
||||
overlayParameters(overlayparameters),
|
||||
drawingParameters(drawingparameters),
|
||||
nodeId(0){
|
||||
|
||||
};
|
||||
|
||||
void EditModeInformationOverlayCoinConverter::convert(const Part::Geometry * geometry, int geoid) {
|
||||
|
||||
// at this point all calculations relate to BSplineCurves
|
||||
assert(geometry->getTypeId() == Part::GeomBSplineCurve::getClassTypeId());
|
||||
|
||||
calculate<CalculationType::BSplineDegree>(geometry, geoid);
|
||||
calculate<CalculationType::BSplineControlPolygon>(geometry, geoid);
|
||||
calculate<CalculationType::BSplineCurvatureComb>(geometry, geoid);
|
||||
calculate<CalculationType::BSplineKnotMultiplicity>(geometry, geoid);
|
||||
calculate<CalculationType::BSplinePoleWeight>(geometry, geoid);
|
||||
|
||||
addUpdateNode(degree);
|
||||
addUpdateNode(controlPolygon);
|
||||
addUpdateNode(curvatureComb);
|
||||
addUpdateNode(knotMultiplicity);
|
||||
addUpdateNode(poleWeights);
|
||||
|
||||
};
|
||||
|
||||
void EditModeInformationOverlayCoinConverter::addToInfoGroup(SoSwitch * sw) {
|
||||
infoGroup->addChild(sw);
|
||||
nodeId++;
|
||||
}
|
||||
|
||||
template < EditModeInformationOverlayCoinConverter::CalculationType calculation >
|
||||
void EditModeInformationOverlayCoinConverter::calculate(const Part::Geometry * geometry, [[maybe_unused]] int geoid) {
|
||||
const Part::GeomBSplineCurve *spline = static_cast<const Part::GeomBSplineCurve *>(geometry);
|
||||
|
||||
if constexpr (calculation == CalculationType::BSplineDegree ) {
|
||||
clearCalculation(degree);
|
||||
|
||||
std::vector<Base::Vector3d> poles = spline->getPoles();
|
||||
|
||||
degree.strings.clear();
|
||||
degree.positions.clear();
|
||||
|
||||
Base::Vector3d midp = Base::Vector3d(0,0,0);
|
||||
|
||||
for (auto val : poles)
|
||||
midp += val;
|
||||
|
||||
midp /= poles.size();
|
||||
|
||||
degree.strings.emplace_back(std::to_string(spline->getDegree()));
|
||||
degree.positions.emplace_back(midp);
|
||||
}
|
||||
else if constexpr (calculation == CalculationType::BSplineControlPolygon ) {
|
||||
|
||||
clearCalculation(controlPolygon);
|
||||
|
||||
std::vector<Base::Vector3d> poles = spline->getPoles();
|
||||
|
||||
controlPolygon.coordinates.clear();
|
||||
controlPolygon.indices.clear();
|
||||
|
||||
if (spline->isPeriodic())
|
||||
controlPolygon.coordinates.reserve(poles.size()+1);
|
||||
else
|
||||
controlPolygon.coordinates.reserve(poles.size());
|
||||
|
||||
for (auto & v : poles)
|
||||
controlPolygon.coordinates.emplace_back(v);
|
||||
|
||||
if (spline->isPeriodic())
|
||||
controlPolygon.coordinates.emplace_back(poles[0]);
|
||||
|
||||
controlPolygon.indices.push_back(poles.size()); // single continuous poligon starting at index 0
|
||||
}
|
||||
else if constexpr (calculation == CalculationType::BSplineCurvatureComb ) {
|
||||
|
||||
clearCalculation(curvatureComb);
|
||||
// curvature graph --------------------------------------------------------
|
||||
|
||||
// reimplementation of python source:
|
||||
// https://github.com/tomate44/CurvesWB/blob/master/ParametricComb.py
|
||||
// by FreeCAD user Chris_G
|
||||
|
||||
std::vector<Base::Vector3d> poles = spline->getPoles();
|
||||
|
||||
double firstparam = spline->getFirstParameter();
|
||||
double lastparam = spline->getLastParameter();
|
||||
|
||||
const int ndiv = poles.size()>4?poles.size()*16:64; // heuristic of number of division to fill in
|
||||
double step = (lastparam - firstparam) / (ndiv-1);
|
||||
|
||||
std::vector<Base::Vector3d> pointatcurvelist;
|
||||
std::vector<double> curvaturelist;
|
||||
std::vector<Base::Vector3d> normallist;
|
||||
|
||||
pointatcurvelist.reserve(ndiv);
|
||||
curvaturelist.reserve(ndiv);
|
||||
normallist.reserve(ndiv);
|
||||
|
||||
for(int i = 0; i < ndiv; i++) {
|
||||
double param = firstparam + i * step;
|
||||
pointatcurvelist.emplace_back(spline->value(param));
|
||||
|
||||
try {
|
||||
curvaturelist.emplace_back(spline->curvatureAt(param));
|
||||
}
|
||||
catch(Base::CADKernelError &e) {
|
||||
// it is "just" a visualisation matter OCC could not calculate the curvature
|
||||
// terminating here would mean that the other shapes would not be drawn.
|
||||
// Solution: Report the issue and set dummy curvature to 0
|
||||
e.ReportException();
|
||||
Base::Console().Error("Curvature graph for B-Spline with GeoId=%d could not be calculated.\n", geoid);
|
||||
curvaturelist.emplace_back(0);
|
||||
}
|
||||
|
||||
Base::Vector3d normal;
|
||||
try {
|
||||
spline->normalAt(param, normal);
|
||||
normallist.emplace_back(normal);
|
||||
}
|
||||
catch(Base::Exception&) {
|
||||
normallist.emplace_back(0,0,0);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Base::Vector3d> pointatcomblist;
|
||||
pointatcomblist.reserve(ndiv);
|
||||
|
||||
for(int i = 0; i < ndiv; i++) {
|
||||
pointatcomblist.emplace_back(pointatcurvelist[i] - overlayParameters.currentBSplineCombRepresentationScale * curvaturelist[i] * normallist[i]);
|
||||
}
|
||||
|
||||
curvatureComb.coordinates.reserve(3*ndiv); // 2*ndiv +1 points of ndiv separate segments + ndiv points for last segment
|
||||
curvatureComb.indices.reserve(ndiv+1); // ndiv separate segments of radials + 1 segment connecting at comb end
|
||||
|
||||
for(int i = 0; i < ndiv; i++) {
|
||||
// note emplace emplaces on the position BEFORE the iterator given.
|
||||
curvatureComb.coordinates.emplace_back(pointatcurvelist[i].x, pointatcurvelist[i].y, drawingParameters.zInfo); // radials
|
||||
curvatureComb.coordinates.emplace_back(pointatcomblist[i].x, pointatcomblist[i].y, drawingParameters.zInfo); // radials
|
||||
|
||||
curvatureComb.indices.emplace_back(2); // line
|
||||
}
|
||||
|
||||
for(int i = 0; i < ndiv; i++)
|
||||
curvatureComb.coordinates.emplace_back(pointatcomblist[i].x, pointatcomblist[i].y, drawingParameters.zInfo); // // comb endpoint closing segment
|
||||
|
||||
curvatureComb.indices.emplace_back(ndiv); // Comb line
|
||||
}
|
||||
else if constexpr (calculation == CalculationType::BSplineKnotMultiplicity ) {
|
||||
|
||||
clearCalculation(knotMultiplicity);
|
||||
std::vector<double> knots = spline->getKnots();
|
||||
std::vector<int> mult = spline->getMultiplicities();
|
||||
|
||||
for(size_t i=0; i<knots.size(); i++) {
|
||||
knotMultiplicity.positions.emplace_back(spline->pointAtParameter(knots[i]));
|
||||
|
||||
std::ostringstream stringStream;
|
||||
stringStream << "(" << mult[i] << ")";
|
||||
|
||||
knotMultiplicity.strings.emplace_back( stringStream.str());
|
||||
}
|
||||
}
|
||||
else if constexpr (calculation == CalculationType::BSplinePoleWeight ) {
|
||||
|
||||
clearCalculation(poleWeights);
|
||||
std::vector<Base::Vector3d> poles = spline->getPoles();
|
||||
auto weights = spline->getWeights();
|
||||
|
||||
for(size_t i=0; i<poles.size(); i++) {
|
||||
poleWeights.positions.emplace_back(poles[i]);
|
||||
|
||||
QString WeightString = QString::fromLatin1("[%1]").arg(weights[i], 0, 'f', Base::UnitsApi::getDecimals());
|
||||
|
||||
poleWeights.strings.emplace_back(WeightString.toStdString());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
template <typename Result>
|
||||
void EditModeInformationOverlayCoinConverter::addUpdateNode(const Result & result) {
|
||||
|
||||
if(overlayParameters.rebuildInformationLayer)
|
||||
addNode(result);
|
||||
else
|
||||
updateNode(result);
|
||||
}
|
||||
|
||||
template < EditModeInformationOverlayCoinConverter::CalculationType calculation >
|
||||
bool EditModeInformationOverlayCoinConverter::isVisible() {
|
||||
if constexpr ( calculation == CalculationType::BSplineDegree ) {
|
||||
return overlayParameters.bSplineDegreeVisible;
|
||||
}
|
||||
else if constexpr ( calculation == CalculationType::BSplineControlPolygon ) {
|
||||
return overlayParameters.bSplineControlPolygonVisible;
|
||||
}
|
||||
else if constexpr ( calculation == CalculationType::BSplineCurvatureComb ) {
|
||||
return overlayParameters.bSplineCombVisible;
|
||||
}
|
||||
else if constexpr ( calculation == CalculationType::BSplineKnotMultiplicity ) {
|
||||
return overlayParameters.bSplineKnotMultiplicityVisible;
|
||||
}
|
||||
else if constexpr ( calculation == CalculationType::BSplinePoleWeight ) {
|
||||
return overlayParameters.bSplinePoleWeightVisible;
|
||||
}
|
||||
}
|
||||
|
||||
template < typename Result >
|
||||
void EditModeInformationOverlayCoinConverter::setPolygon(const Result & result, SoLineSet *polygonlineset, SoCoordinate3 *polygoncoords) {
|
||||
|
||||
polygoncoords->point.setNum(result.coordinates.size());
|
||||
polygonlineset->numVertices.setNum(result.indices.size());
|
||||
|
||||
int32_t *index = polygonlineset->numVertices.startEditing();
|
||||
SbVec3f *vts = polygoncoords->point.startEditing();
|
||||
|
||||
for(size_t i = 0; i < result.coordinates.size(); i++)
|
||||
vts[i].setValue(result.coordinates[i].x, result.coordinates[i].y, drawingParameters.zInfo);
|
||||
|
||||
for(size_t i = 0; i < result.indices.size(); i++)
|
||||
index[i] = result.indices[i];
|
||||
|
||||
polygoncoords->point.finishEditing();
|
||||
polygonlineset->numVertices.finishEditing();
|
||||
}
|
||||
|
||||
template < int line >
|
||||
void EditModeInformationOverlayCoinConverter::setText(const std::string & string, SoText2 * text) {
|
||||
|
||||
if constexpr (line == 1) {
|
||||
text->string = SbString(string.c_str());
|
||||
}
|
||||
else {
|
||||
assert(line > 1);
|
||||
SoMFString label;
|
||||
for ( int l = 0; l < (line - 1) ; l++)
|
||||
label.set1Value(l, SbString(""));
|
||||
|
||||
label.set1Value(line-1, SbString(string.c_str()));
|
||||
text->string = label;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template < typename Result >
|
||||
void EditModeInformationOverlayCoinConverter::clearCalculation(Result & result) {
|
||||
if constexpr (Result::visualisationType == VisualisationType::Text) {
|
||||
result.positions.clear();
|
||||
result.strings.clear();
|
||||
}
|
||||
else if constexpr (Result::visualisationType == VisualisationType::Polygon) {
|
||||
result.coordinates.clear();
|
||||
result.indices.clear();
|
||||
}
|
||||
}
|
||||
|
||||
template < typename Result>
|
||||
void EditModeInformationOverlayCoinConverter::addNode(const Result & result) {
|
||||
|
||||
if constexpr (Result::visualisationType == VisualisationType::Text) {
|
||||
|
||||
for(size_t i = 0; i < result.strings.size(); i++) {
|
||||
|
||||
SoSwitch *sw = new SoSwitch();
|
||||
|
||||
sw->whichChild = isVisible<Result::calculationType>()?SO_SWITCH_ALL:SO_SWITCH_NONE;
|
||||
|
||||
SoSeparator *sep = new SoSeparator();
|
||||
sep->ref();
|
||||
// no caching for frequently-changing data structures
|
||||
sep->renderCaching = SoSeparator::OFF;
|
||||
|
||||
// every information visual node gets its own material for to-be-implemented preselection and selection
|
||||
SoMaterial *mat = new SoMaterial;
|
||||
mat->ref();
|
||||
mat->diffuseColor = drawingParameters.InformationColor;
|
||||
|
||||
SoTranslation *translate = new SoTranslation;
|
||||
|
||||
translate->translation.setValue(result.positions[i].x, result.positions[i].y, drawingParameters.zInfo);
|
||||
|
||||
SoFont *font = new SoFont;
|
||||
font->name.setValue("Helvetica");
|
||||
font->size.setValue(drawingParameters.coinFontSize);
|
||||
|
||||
SoText2 *text = new SoText2;
|
||||
|
||||
// since the first and last control point of a spline is also treated as knot and thus
|
||||
// can also have a displayed multiplicity, we must assure the multiplicity is not visibly overwritten
|
||||
// therefore be output the weight in a second line
|
||||
//
|
||||
// This could be made into a more generic form, but it is probably not worth the effort at this time.
|
||||
if constexpr ( Result::calculationType == CalculationType::BSplinePoleWeight )
|
||||
setText<2>(result.strings[i], text);
|
||||
else
|
||||
setText(result.strings[i], text);
|
||||
|
||||
sep->addChild(translate);
|
||||
sep->addChild(mat);
|
||||
sep->addChild(font);
|
||||
sep->addChild(text);
|
||||
|
||||
sw->addChild(sep);
|
||||
|
||||
addToInfoGroup(sw);
|
||||
sep->unref();
|
||||
mat->unref();
|
||||
}
|
||||
}
|
||||
else if constexpr (Result::visualisationType == VisualisationType::Polygon) {
|
||||
|
||||
SoSwitch *sw = new SoSwitch();
|
||||
|
||||
// hGrpsk->GetBool("BSplineControlPolygonVisible", true)
|
||||
sw->whichChild = isVisible<Result::calculationType>()?SO_SWITCH_ALL:SO_SWITCH_NONE;
|
||||
|
||||
SoSeparator *sep = new SoSeparator();
|
||||
sep->ref();
|
||||
// no caching for frequently-changing data structures
|
||||
sep->renderCaching = SoSeparator::OFF;
|
||||
|
||||
// every information visual node gets its own material for to-be-implemented preselection and selection
|
||||
SoMaterial *mat = new SoMaterial;
|
||||
mat->ref();
|
||||
mat->diffuseColor = drawingParameters.InformationColor;
|
||||
|
||||
SoLineSet *polygonlineset = new SoLineSet;
|
||||
SoCoordinate3 *polygoncoords = new SoCoordinate3;
|
||||
|
||||
setPolygon<Result>(result, polygonlineset, polygoncoords);
|
||||
|
||||
sep->addChild(mat);
|
||||
sep->addChild(polygoncoords);
|
||||
sep->addChild(polygonlineset);
|
||||
|
||||
sw->addChild(sep);
|
||||
|
||||
addToInfoGroup(sw);
|
||||
sep->unref();
|
||||
mat->unref();
|
||||
}
|
||||
}
|
||||
|
||||
template < typename Result >
|
||||
void EditModeInformationOverlayCoinConverter::updateNode(const Result & result) {
|
||||
|
||||
if constexpr (Result::visualisationType == VisualisationType::Text ) {
|
||||
|
||||
for(size_t i = 0; i < result.strings.size(); i++) {
|
||||
SoSwitch *sw = static_cast<SoSwitch *>(infoGroup->getChild(nodeId));
|
||||
|
||||
if (overlayParameters.visibleInformationChanged)
|
||||
sw->whichChild = isVisible<Result::calculationType>()?SO_SWITCH_ALL:SO_SWITCH_NONE;
|
||||
|
||||
SoSeparator *sep = static_cast<SoSeparator *>(sw->getChild(0));
|
||||
|
||||
static_cast<SoTranslation *>(sep->getChild(static_cast<int>(TextNodePosition::TextCoordinates)))->translation.setValue(result.positions[i].x, result.positions[i].y, drawingParameters.zInfo);
|
||||
|
||||
// since the first and last control point of a spline is also treated as knot and thus
|
||||
// can also have a displayed multiplicity, we must assure the multiplicity is not visibly overwritten
|
||||
// therefore be output the weight in a second line
|
||||
//
|
||||
// This could be made into a more generic form, but it is probably not worth the effort at this time.
|
||||
if constexpr ( Result::calculationType == CalculationType::BSplinePoleWeight )
|
||||
setText<2>(result.strings[i], static_cast<SoText2 *>(sep->getChild(static_cast<int>(TextNodePosition::TextInformation))));
|
||||
else
|
||||
setText(result.strings[i], static_cast<SoText2 *>(sep->getChild(static_cast<int>(TextNodePosition::TextInformation))));
|
||||
|
||||
nodeId++;
|
||||
}
|
||||
|
||||
}
|
||||
else if constexpr (Result::visualisationType == VisualisationType::Polygon) {
|
||||
|
||||
SoSwitch *sw = static_cast<SoSwitch *>(infoGroup->getChild(nodeId));
|
||||
|
||||
if(overlayParameters.visibleInformationChanged)
|
||||
sw->whichChild = isVisible<Result::calculationType>()?SO_SWITCH_ALL:SO_SWITCH_NONE;
|
||||
|
||||
SoSeparator *sep = static_cast<SoSeparator *>(sw->getChild(0));
|
||||
|
||||
SoCoordinate3 *polygoncoords = static_cast<SoCoordinate3 *>(sep->getChild(static_cast<int>(PolygonNodePosition::PolygonCoordinates)));
|
||||
|
||||
SoLineSet *polygonlineset = static_cast<SoLineSet *>(sep->getChild(static_cast<int>(PolygonNodePosition::PolygonLineSet)));
|
||||
|
||||
setPolygon(result, polygonlineset, polygoncoords);
|
||||
|
||||
nodeId++;
|
||||
}
|
||||
}
|
||||
202
src/Mod/Sketcher/Gui/EditModeInformationOverlayCoinConverter.h
Normal file
202
src/Mod/Sketcher/Gui/EditModeInformationOverlayCoinConverter.h
Normal file
@@ -0,0 +1,202 @@
|
||||
/***************************************************************************
|
||||
* 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_InformationOverlayCoinConverter_H
|
||||
#define SKETCHERGUI_InformationOverlayCoinConverter_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace Base {
|
||||
template< typename T >
|
||||
class Vector3;
|
||||
|
||||
class Vector2d;
|
||||
}
|
||||
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace SketcherGui {
|
||||
struct OverlayParameters;
|
||||
struct DrawingParameters;
|
||||
|
||||
/** @brief Class for creating the Overlay information layer
|
||||
* @details
|
||||
*
|
||||
* Responsibility:
|
||||
* To create and update the SoGroup provided as a constructor parameter,
|
||||
* taking into account the drawing and overlay parameters provided as
|
||||
* constructor parameters.
|
||||
*
|
||||
* Interface:
|
||||
* A single entry point convert(), performing the following flow:
|
||||
*
|
||||
* [Geometry] => Calculate => addUpdateNode
|
||||
*
|
||||
* Calculate is responsible for generating information directly usable by Coin (but with standard types that
|
||||
* would enable portability) in a predetermined internal Node structure format (e.g. StringNode, PolygonNode)
|
||||
* that can generically be used by the addUpdateNode.
|
||||
*
|
||||
* addUpdateNode is responsible for creating or updating the node structure (depending on overlayParameters.rebuildInformationLayer)
|
||||
*
|
||||
* Supported:
|
||||
* Currently it only supports information of Part::Geometry objects and implements calculations only for GeomBSplineCurve.
|
||||
*
|
||||
* Caveats:
|
||||
* - This class relies on the order of creation to perform the update. Any parallel execution that does not deterministically
|
||||
* maintain the order will result in undefined behaviour. This provides a reasonable tradeoff between complexity and the fact that
|
||||
* currently the information layer is generally so small that no parallel execution would actually result in a performance gain.
|
||||
*
|
||||
*/
|
||||
class EditModeInformationOverlayCoinConverter {
|
||||
private:
|
||||
|
||||
enum class CalculationType
|
||||
{
|
||||
BSplineDegree,
|
||||
BSplineControlPolygon,
|
||||
BSplineCurvatureComb,
|
||||
BSplineKnotMultiplicity,
|
||||
BSplinePoleWeight
|
||||
};
|
||||
enum class VisualisationType
|
||||
{
|
||||
Text,
|
||||
Polygon
|
||||
};
|
||||
|
||||
using Vector3d = Base::Vector3<double>;
|
||||
|
||||
private:
|
||||
// A Coin Node follows a VisualisationType, which defines how
|
||||
// the information is represented, and which member must be
|
||||
// filled into the struct for representation
|
||||
//
|
||||
// A struct containing the information to represent VisualisationType
|
||||
// must be provided per CalculationType
|
||||
//
|
||||
// a struct Node template enables to define the VisualisationType and
|
||||
// the CalculationType so that uniform treatment can be provided
|
||||
template< VisualisationType vtype, CalculationType ctype >
|
||||
struct Node {
|
||||
static constexpr VisualisationType visualisationType = vtype;
|
||||
static constexpr CalculationType calculationType = ctype;
|
||||
};
|
||||
|
||||
template< CalculationType ctype >
|
||||
struct NodeText : public Node<VisualisationType::Text, ctype> {
|
||||
std::vector<std::string> strings;
|
||||
std::vector<Vector3d> positions;
|
||||
};
|
||||
|
||||
template< CalculationType ctype >
|
||||
struct NodePolygon: public Node<VisualisationType::Polygon, ctype> {
|
||||
std::vector<Vector3d> coordinates;
|
||||
std::vector<int> indices;
|
||||
};
|
||||
|
||||
private:
|
||||
// Node Position in the Coin Scenograph for the different types of nodes
|
||||
enum class TextNodePosition {
|
||||
TextCoordinates = 0,
|
||||
TextInformation = 3
|
||||
};
|
||||
|
||||
enum class PolygonNodePosition {
|
||||
PolygonCoordinates = 1,
|
||||
PolygonLineSet = 2
|
||||
};
|
||||
|
||||
public:
|
||||
/** Constructs an InformationOverlayCoinConverter responsible for
|
||||
* generating (calculating) the information of a full geometry layer
|
||||
* overlay using the overlay and drawing parameters
|
||||
*
|
||||
* @param infogroup: The SoGroup to be populated with the coin nodes
|
||||
* generated from the calculated information.
|
||||
*
|
||||
* @param overlayparameters: Parameters for controlling the overlay
|
||||
* @param drawingparameters: Parameters for drawing the overlay information
|
||||
*/
|
||||
EditModeInformationOverlayCoinConverter( SoGroup * infogroup,
|
||||
OverlayParameters & overlayparameters,
|
||||
DrawingParameters & drawingparameters);
|
||||
|
||||
/**
|
||||
* extracts information from the geometry and converts it into an information overlay in the
|
||||
* SoGroup provided in the constructor.
|
||||
*
|
||||
* @param geometry: the geometry to be processed
|
||||
*/
|
||||
void convert(const Part::Geometry * geometry, int geoid);
|
||||
|
||||
private:
|
||||
template < CalculationType calculation >
|
||||
void calculate(const Part::Geometry * geometry, [[maybe_unused]] int geoid);
|
||||
|
||||
template <typename Result>
|
||||
void addUpdateNode(const Result & result);
|
||||
|
||||
template < CalculationType calculation >
|
||||
bool isVisible();
|
||||
|
||||
template < typename Result >
|
||||
void setPolygon(const Result & result, SoLineSet *polygonlineset, SoCoordinate3 *polygoncoords);
|
||||
|
||||
template < int line = 1 >
|
||||
void setText(const std::string & string, SoText2 * text);
|
||||
|
||||
void addToInfoGroup(SoSwitch * sw);
|
||||
|
||||
template < typename Result >
|
||||
void clearCalculation(Result & result);
|
||||
|
||||
template < typename Result>
|
||||
void addNode(const Result & result);
|
||||
|
||||
template < typename Result >
|
||||
void updateNode(const Result & result);
|
||||
|
||||
private:
|
||||
SoGroup * infoGroup;
|
||||
OverlayParameters & overlayParameters;
|
||||
DrawingParameters & drawingParameters;
|
||||
|
||||
// Calculations
|
||||
NodeText<CalculationType::BSplineDegree> degree;
|
||||
NodeText<CalculationType::BSplineKnotMultiplicity> knotMultiplicity;
|
||||
NodeText<CalculationType::BSplinePoleWeight> poleWeights;
|
||||
NodePolygon<CalculationType::BSplineControlPolygon> controlPolygon;
|
||||
NodePolygon<CalculationType::BSplineCurvatureComb> curvatureComb;
|
||||
|
||||
// Node Management
|
||||
int nodeId;
|
||||
};
|
||||
|
||||
|
||||
} // namespace SketcherGui
|
||||
|
||||
|
||||
#endif // SKETCHERGUI_InformationOverlayCoinConverter_H
|
||||
|
||||
@@ -32,6 +32,13 @@
|
||||
|
||||
using namespace SketcherGui;
|
||||
|
||||
// ******************** ViewProvider attorney *********************************************//
|
||||
inline void ViewProviderSketchShortcutListenerAttorney::deleteSelected(ViewProviderSketch & vp)
|
||||
{
|
||||
vp.deleteSelected();
|
||||
};
|
||||
|
||||
// ******************** ShortcutListener *********************************************//
|
||||
ShortcutListener::ShortcutListener(ViewProviderSketch * vp)
|
||||
{
|
||||
pViewProvider = vp;
|
||||
@@ -50,7 +57,7 @@ bool ShortcutListener::eventFilter(QObject *obj, QEvent *event) {
|
||||
switch (kevent->key()) {
|
||||
case Qt::Key_Delete:
|
||||
kevent->accept();
|
||||
pViewProvider->deleteSelected(); // this takes a list of objects
|
||||
ViewProviderSketchShortcutListenerAttorney::deleteSelected(*pViewProvider);
|
||||
return true;
|
||||
default:
|
||||
break;
|
||||
|
||||
@@ -31,6 +31,13 @@ namespace SketcherGui {
|
||||
|
||||
class ViewProviderSketch;
|
||||
|
||||
class ViewProviderSketchShortcutListenerAttorney {
|
||||
private:
|
||||
static inline void deleteSelected(ViewProviderSketch &vp);
|
||||
|
||||
|
||||
friend class ShortcutListener;
|
||||
};
|
||||
|
||||
class ShortcutListener: public QObject
|
||||
{
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -24,11 +24,11 @@
|
||||
#ifndef SKETCHERGUI_VIEWPROVIDERSKETCH_H
|
||||
#define SKETCHERGUI_VIEWPROVIDERSKETCH_H
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <Mod/Part/Gui/ViewProvider2DObject.h>
|
||||
#include <Mod/Part/Gui/ViewProviderAttachExtension.h>
|
||||
#include <Mod/Part/App/BodyBase.h>
|
||||
#include <Inventor/SbImage.h>
|
||||
#include <Inventor/SbColor.h>
|
||||
#include <Base/Tools2D.h>
|
||||
#include <Base/Placement.h>
|
||||
#include <Gui/Selection.h>
|
||||
@@ -39,11 +39,13 @@
|
||||
#include <Gui/Document.h>
|
||||
#include "ShortcutListener.h"
|
||||
|
||||
#include <Mod/Sketcher/App/GeoList.h>
|
||||
|
||||
class TopoDS_Shape;
|
||||
class TopoDS_Face;
|
||||
class SoSeparator;
|
||||
class SbLine;
|
||||
class SbVec2f;
|
||||
class SbVec3f;
|
||||
class SoCoordinate3;
|
||||
class SoInfo;
|
||||
@@ -52,6 +54,7 @@ class SoTransform;
|
||||
class SoLineSet;
|
||||
class SoMarkerSet;
|
||||
class SoPickedPoint;
|
||||
class SoRayPickAction;
|
||||
|
||||
class SoImage;
|
||||
class QImage;
|
||||
@@ -62,7 +65,9 @@ class SoTranslation;
|
||||
class SbString;
|
||||
class SbTime;
|
||||
|
||||
struct EditData;
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace Gui {
|
||||
class View3DInventorViewer;
|
||||
@@ -76,37 +81,320 @@ namespace Sketcher {
|
||||
|
||||
namespace SketcherGui {
|
||||
|
||||
class EditModeCoinManager;
|
||||
class DrawSketchHandler;
|
||||
|
||||
/** The Sketch ViewProvider
|
||||
* This class handles mainly the drawing and editing of the sketch.
|
||||
* It draws the geometry and the constraints applied to the sketch.
|
||||
* It uses the class DrawSketchHandler to facilitate the creation
|
||||
* of new geometry while editing.
|
||||
*/
|
||||
using GeoList = Sketcher::GeoList;
|
||||
using GeoListFacade = Sketcher::GeoListFacade;
|
||||
|
||||
/** @brief The Sketch ViewProvider
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* As any ViewProvider, this class is responsible for the view representation
|
||||
* of Sketches.
|
||||
*
|
||||
* Functionality inherited from parent classes deal with the majority of the
|
||||
* representation of a sketch when it is ** not ** in edit mode.
|
||||
*
|
||||
* This class handles mainly the drawing and editing of the sketch.
|
||||
*
|
||||
* The class delegates a substantial part of this functionality on two main
|
||||
* classes, DrawSketchHandler and EditModeCoinManager.
|
||||
*
|
||||
* In order to enforce a certain degree of encapsulation and promote a not
|
||||
* too tight coupling, while still allowing well defined collaboration,
|
||||
* DrawSketchHandler and EditModeCoinManager access ViewProviderSketch via
|
||||
* two Attorney classes (Attorney-Client pattern), ViewProviderSketchDrawSketchHandlerAttorney
|
||||
* and ViewProviderSketchCoinAttorney.
|
||||
*
|
||||
* Given the substantial amount of code involved in coin node management, EditModeCoinManager
|
||||
* further delegates on other specialised helper classes. Some of them share the
|
||||
* ViewProviderSketchCoinAttorney, which defines the maximum coupling and minimum encapsulation.
|
||||
*
|
||||
* DrawSketchHandler aids temporary edit mode drawing and is extensively used for the creation
|
||||
* of geometry.
|
||||
*
|
||||
* EditModeCoinManager takes over the responsibility of creating the Coin (Inventor) scenograph
|
||||
* and modifying it, including all the drawing of geometry, constraints and overlay layer. This
|
||||
* is an exclusive responsibility under the Single Responsibility Principle.
|
||||
*
|
||||
* EditModeCoinManager exposes a public interface to be used by ViewProviderSketch. Where,
|
||||
* EditModeCoinManager needs special access to facilities of ViewProviderSketch in order to fulfil
|
||||
* its responsibility, this access is defined by ViewProviderSketchCoinAttorney.
|
||||
*
|
||||
* Similarly, DrawSketchHandler takes over the responsibility of drawing edit temporal curves and
|
||||
* markers necessary to enable visual feedback to the user, as well as the UI interaction during
|
||||
* such edits. This is its exclusive responsibility under the Single Responsibility Principle.
|
||||
*
|
||||
* A plethora of speciliased handlers derive from DrawSketchHandler for each specialised editing (see
|
||||
* for example all the handlers for creation of new geometry). These derived classes do * not * have
|
||||
* direct access to the ViewProviderSketchDrawSketchHandlerAttorney. This is intended to keep coupling
|
||||
* under control. However, generic functionality requiring access to the Attorney can be implemented
|
||||
* in DrawSketchHandler and used from its derived classes by virtue of the inheritance. This promotes a
|
||||
* concentrating the coupling in a single point (and code reuse).
|
||||
*
|
||||
*/
|
||||
class SketcherGuiExport ViewProviderSketch : public PartGui::ViewProvider2DObjectGrid
|
||||
, public PartGui::ViewProviderAttachExtension
|
||||
, public Gui::SelectionObserver
|
||||
, public ParameterGrp::ObserverType
|
||||
{
|
||||
Q_DECLARE_TR_FUNCTIONS(SketcherGui::ViewProviderSketch)
|
||||
/// generates a warning message about constraint conflicts and appends it to the given message
|
||||
static QString appendConflictMsg(const std::vector<int> &conflicting);
|
||||
/// generates a warning message about redundant constraints and appends it to the given message
|
||||
static QString appendRedundantMsg(const std::vector<int> &redundant);
|
||||
/// generates a warning message about partially redundant constraints and appends it to the given message
|
||||
static QString appendPartiallyRedundantMsg(const std::vector<int> &partiallyredundant);
|
||||
/// generates a warning message about redundant constraints and appends it to the given message
|
||||
static QString appendMalformedMsg(const std::vector<int> &redundant);
|
||||
|
||||
PROPERTY_HEADER_WITH_OVERRIDE(SketcherGui::ViewProviderSketch);
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief
|
||||
* This nested class is responsible for attaching to the parameters relevant for
|
||||
* ViewProviderSketch, initialising the ViewProviderSketch to the current configuration
|
||||
* and handle in real time any change to their values.
|
||||
*/
|
||||
class ParameterObserver : public ParameterGrp::ObserverType
|
||||
{
|
||||
public:
|
||||
ParameterObserver(ViewProviderSketch & client);
|
||||
~ParameterObserver();
|
||||
|
||||
void initParameters();
|
||||
|
||||
void subscribeToParameters();
|
||||
|
||||
void unsubscribeToParameters();
|
||||
|
||||
/** Observer for parameter group. */
|
||||
void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;
|
||||
|
||||
private:
|
||||
|
||||
void updateBoolProperty(const std::string & string, App::Property * property, bool defaultvalue);
|
||||
void updateGridSize(const std::string & string, App::Property * property);
|
||||
|
||||
// Only for colors outside of edit mode, edit mode colors are handled by EditModeCoinManager.
|
||||
void updateColorProperty(const std::string & string, App::Property * property, float r, float g, float b);
|
||||
|
||||
void updateEscapeKeyBehaviour(const std::string & string, App::Property * property);
|
||||
|
||||
void updateAutoRecompute(const std::string & string, App::Property * property);
|
||||
|
||||
void updateRecalculateInitialSolutionWhileDragging(const std::string & string, App::Property * property);
|
||||
|
||||
private:
|
||||
ViewProviderSketch &Client;
|
||||
std::map<std::string, std::tuple<std::function<void(const std::string & string, App::Property *)>, App::Property * >> parameterMap;
|
||||
};
|
||||
|
||||
/** @name Classes storing the state of Dragging, Selection and Preselection
|
||||
* All these classes enable the identification of a Vertex, a Curve, the root
|
||||
* Point, axes, and constraints.
|
||||
*
|
||||
* A word on indices and ways to identify elements and parts of them:
|
||||
*
|
||||
* The Sketcher has a general main way to identify geometry, {GeoId, PointPos},
|
||||
* these can be provided as separate data, or using Sketcher::GeoElementId. The
|
||||
* latter defines comparison and equality operators enabling, for example to use
|
||||
* it as key in a std::map.
|
||||
*
|
||||
* While it is indeed possible to refer to any point using that nomenclature, creating
|
||||
* maps in certain circumnstances leads to a performance drawback. Additionally, the
|
||||
* legacy selection mechanism refers to positive indexed Vertices (for both normal and
|
||||
* external vertices). Both reasons discourage moving to a single identification. This
|
||||
* situation has been identified at different levels:
|
||||
*
|
||||
* (1) In sketch.cpp, the solver facade defining the interface with GCS, both
|
||||
* {GeoId, PointPos} and PointId are used.
|
||||
*
|
||||
* (2) In SketchObject.cpp, the actual document object, both {GeoId, PointPos} and VertexId
|
||||
* are used (see VertexId2GeoId and VertexId2GeoPosId).
|
||||
*
|
||||
* (3) In ViewProviderSketch, both {GeoId, PointPos} an Point indices are used (see these structures)
|
||||
*
|
||||
* (4) At CoinManager level, {GeoId, PointPos}, Point indices (for selection) and MultiFieldIds (specific
|
||||
* structure defining a coin multifield index and layer) are used.
|
||||
*
|
||||
* Using a single index instead of a multi-index field, allows mappings to be implemented via std::vectors
|
||||
* instead of std::maps. Direct mappings using std::vectors are accessed in constant time. Multi-index mappings
|
||||
* relying on std::maps involve a search for the key. This leads to a drop in performance.
|
||||
*
|
||||
* What are these indices and how do they relate each other?
|
||||
* 1. PointId, VertexId depend on the order of the geometries in the sketch. GeoList and GeoListFacade enable to
|
||||
* convert between indices.
|
||||
* 2. CurveId is basically the GeoId assuming PointPos to be PointPos::none (edge)
|
||||
* 3. Sometimes, Axes and root point are separated into a third index or enum. Legacy reasons aside, the root point
|
||||
* is has GeoId=-1, which is sometimes used as invalid value in positive only indices. Additionally, root point and
|
||||
* the Horizontal Axes both have GeoId=-1 (differing in PointPos only). Following the decision not to rely on PointPos,
|
||||
* creating a separate index, best when enum-ed, appears justified.
|
||||
*/
|
||||
//@{
|
||||
|
||||
/** @brief Class to store vector and item Id for dragging.
|
||||
*
|
||||
* @details
|
||||
* Ids are zero-indexed points and curves.
|
||||
*
|
||||
* The DragPoint indexing matches PreselectPoint indexing.
|
||||
*
|
||||
*/
|
||||
class Drag {
|
||||
public:
|
||||
enum SpecialValues {
|
||||
InvalidPoint = -1,
|
||||
InvalidCurve = -1
|
||||
};
|
||||
|
||||
Drag() {
|
||||
resetVector();
|
||||
resetIds();
|
||||
}
|
||||
|
||||
void resetVector() {
|
||||
xInit = 0;
|
||||
yInit = 0;
|
||||
relative = false;
|
||||
}
|
||||
|
||||
void resetIds() {
|
||||
DragPoint = InvalidPoint;
|
||||
DragCurve = InvalidCurve;
|
||||
DragConstraintSet.clear();
|
||||
}
|
||||
|
||||
bool isDragPointValid() { return DragPoint > InvalidPoint;}
|
||||
bool isDragCurveValid() { return DragCurve > InvalidCurve;}
|
||||
|
||||
double xInit, yInit; // starting point of the dragging operation
|
||||
bool relative; // whether the dragging move vector is relative or absolute
|
||||
|
||||
|
||||
int DragPoint; // dragged point id (only positive integers)
|
||||
int DragCurve; // dragged curve id (only positive integers), negative external curves cannot be dragged.
|
||||
std::set<int> DragConstraintSet; // dragged constraints ids
|
||||
};
|
||||
|
||||
// TODO: Selection and Preselection should use a same structure. Probably Drag should use the same structure too. To be refactored separately.
|
||||
|
||||
/** @brief Class to store preselected element ids.
|
||||
*
|
||||
* @details
|
||||
*
|
||||
* PreselectPoint is the positive VertexId.
|
||||
*
|
||||
* PreselectCurve is the GeoID, but without the Axes (indices -1 and -2).
|
||||
*
|
||||
* VertexN, with N = PreselectPoint + 1, same as DragPoint indexing (NOTE -1 is NOT the root point)
|
||||
*
|
||||
* EdgeN, with N = PreselectCurve + 1 for positive values ; ExternalEdgeN, with N = -PreselectCurve - 2
|
||||
*
|
||||
* The PreselectPoint indexing matches DragPoint indexing (it further includes negative edges, which are
|
||||
* not meaningful for Dragging).
|
||||
*
|
||||
*/
|
||||
class Preselection {
|
||||
public:
|
||||
enum SpecialValues {
|
||||
InvalidPoint = -1,
|
||||
InvalidCurve = -1,
|
||||
ExternalCurve = -3
|
||||
};
|
||||
|
||||
enum class Axes {
|
||||
None = -1,
|
||||
RootPoint = 0,
|
||||
HorizontalAxis = 1,
|
||||
VerticalAxis = 2
|
||||
};
|
||||
|
||||
Preselection() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset(){
|
||||
PreselectPoint = InvalidPoint;
|
||||
PreselectCurve = InvalidCurve;
|
||||
PreselectCross = Axes::None;
|
||||
PreselectConstraintSet.clear();
|
||||
blockedPreselection = false;
|
||||
}
|
||||
|
||||
bool isPreselectPointValid() const { return PreselectPoint > InvalidPoint;}
|
||||
bool isPreselectCurveValid() const { return PreselectCurve > InvalidCurve || PreselectCurve <= ExternalCurve;}
|
||||
bool isCrossPreselected() const { return PreselectCross != Axes::None;}
|
||||
bool isEdge() const { return PreselectCurve > InvalidCurve;}
|
||||
bool isExternalEdge() const { return PreselectCurve <= ExternalCurve;}
|
||||
|
||||
int getPreselectionVertexIndex() const { return PreselectPoint + 1;}
|
||||
int getPreselectionEdgeIndex() const { return PreselectCurve + 1;}
|
||||
int getPreselectionExternalEdgeIndex() const { return -PreselectCurve - 2;}
|
||||
|
||||
int PreselectPoint; // VertexN, with N = PreselectPoint + 1, same as DragPoint indexing (NOTE -1 is NOT the root point)
|
||||
int PreselectCurve; // EdgeN, with N = PreselectCurve + 1 for positive values ; ExternalEdgeN, with N = -PreselectCurve - 2
|
||||
Axes PreselectCross; // 0 => rootPoint, 1 => HAxis, 2 => VAxis
|
||||
std::set<int> PreselectConstraintSet; // ConstraintN, N = index + 1
|
||||
bool blockedPreselection;
|
||||
};
|
||||
|
||||
/** @brief Class to store selected element ids.
|
||||
*
|
||||
* @details
|
||||
* Selection follows yet a different mechanism than preselection.
|
||||
*
|
||||
* SelPointSet indices as PreselectPoint, with the addition that -1 is indeed the rootpoint.
|
||||
*
|
||||
* SelCurvSet indices as PreselectCurve, with the addition that -1 is the HAxis and -2 is the VAxis
|
||||
*
|
||||
*/
|
||||
class Selection {
|
||||
public:
|
||||
enum SpecialValues {
|
||||
RootPoint = -1,
|
||||
HorizontalAxis = -1,
|
||||
VerticalAxis = -2
|
||||
};
|
||||
|
||||
Selection() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
SelPointSet.clear();
|
||||
SelCurvSet.clear();
|
||||
SelConstraintSet.clear();
|
||||
}
|
||||
|
||||
std::set<int> SelPointSet; // Indices as PreselectPoint (and -1 for rootpoint)
|
||||
std::set<int> SelCurvSet; // also holds cross axes at -1 and -2
|
||||
std::set<int> SelConstraintSet; // ConstraintN, N = index + 1.
|
||||
};
|
||||
//@}
|
||||
|
||||
/** @brief Private struct maintaining information necessary for detecting double click.
|
||||
*/
|
||||
struct DoubleClick {
|
||||
static SbTime prvClickTime;
|
||||
static SbVec2s prvClickPos; //used by double-click-detector
|
||||
static SbVec2s prvCursorPos;
|
||||
static SbVec2s newCursorPos;
|
||||
};
|
||||
|
||||
/** @brief Private struct grouping ViewProvider parameters and internal variables
|
||||
*/
|
||||
struct ViewProviderParameters {
|
||||
bool handleEscapeButton = false;
|
||||
bool autoRecompute = false;
|
||||
bool recalculateInitialSolutionWhileDragging = false;
|
||||
|
||||
bool isShownVirtualSpace = false; // indicates whether the present virtual space view is the Real Space or the Virtual Space (virtual space 1 or 2)
|
||||
bool buttonPress = false;
|
||||
};
|
||||
|
||||
public:
|
||||
/// constructor
|
||||
ViewProviderSketch();
|
||||
/// destructor
|
||||
virtual ~ViewProviderSketch();
|
||||
|
||||
/** @name Properties */
|
||||
//@{
|
||||
App::PropertyBool Autoconstraints;
|
||||
App::PropertyBool AvoidRedundant;
|
||||
App::PropertyPythonObject TempoVis;
|
||||
@@ -117,40 +405,23 @@ public:
|
||||
App::PropertyBool ForceOrtho;
|
||||
App::PropertyBool SectionView;
|
||||
App::PropertyString EditingWorkbench;
|
||||
//@}
|
||||
|
||||
/// Draw all constraint icons
|
||||
/*! Except maybe the radius and lock ones? */
|
||||
void drawConstraintIcons();
|
||||
|
||||
/// draw the sketch in the inventor nodes
|
||||
/// temp => use temporary solver solution in SketchObject
|
||||
/// recreateinformationscenography => forces a rebuild of the information layer scenography
|
||||
void draw(bool temp=false, bool rebuildinformationlayer=true);
|
||||
|
||||
/// draw the edit curve
|
||||
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
|
||||
|
||||
/// draw the edit markers
|
||||
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
|
||||
|
||||
/// Is the view provider selectable
|
||||
bool isSelectable(void) const override;
|
||||
/// Observer message from the Selection
|
||||
virtual void onSelectionChanged(const Gui::SelectionChanges& msg) override;
|
||||
|
||||
/// Show/Hide nodes from information layer
|
||||
void showRestoreInformationLayer();
|
||||
|
||||
// TODO: It is difficult to imagine that these functions are necessary in the public interface. This requires review at a second stage and possibly
|
||||
// refactor it.
|
||||
/** @name handler control */
|
||||
//@{
|
||||
/// sets an DrawSketchHandler in control
|
||||
void activateHandler(DrawSketchHandler *newHandler);
|
||||
/// removes the active handler
|
||||
void purgeHandler(void);
|
||||
/// set the pick style of the sketch coordinate axes
|
||||
void setAxisPickStyle(bool on);
|
||||
//@}
|
||||
|
||||
|
||||
// TODO: SketchMode should be refactored. DrawSketchHandler, its inheritance and free functions should access this mode via the DrawSketchHandler
|
||||
// Attorney. I will not refactor this at this moment, as the refactor will be even more extensive and difficult to review. But this should be done
|
||||
// in a second stage.
|
||||
|
||||
/** @name modus handling */
|
||||
//@{
|
||||
/// mode table
|
||||
@@ -167,49 +438,42 @@ public:
|
||||
STATUS_SKETCH_StartRubberBand, /**< enum value for initiating a rubber band selection */
|
||||
STATUS_SKETCH_UseRubberBand /**< enum value when making a rubber band selection *//**< enum value a DrawSketchHandler is in control. */
|
||||
};
|
||||
|
||||
/// is called by GuiCommands to set the drawing mode
|
||||
void setSketchMode(SketchMode mode) {Mode = mode;}
|
||||
/// get the sketch mode
|
||||
SketchMode getSketchMode(void) const {return Mode;}
|
||||
//@}
|
||||
|
||||
/** @name helper functions */
|
||||
/** @name Drawing functions */
|
||||
//@{
|
||||
/// give the coordinates of a line on the sketch plane in sketcher (2D) coordinates
|
||||
void getCoordsOnSketchPlane(double &u, double &v, const SbVec3f &point,
|
||||
const SbVec3f &normal);
|
||||
|
||||
/// give projecting line of position
|
||||
void getProjectingLine(const SbVec2s&,
|
||||
const Gui::View3DInventorViewer *viewer,
|
||||
SbLine&) const;
|
||||
|
||||
/// helper to detect preselection
|
||||
bool detectPreselection(const SoPickedPoint *Point,
|
||||
const Gui::View3DInventorViewer *viewer,
|
||||
const SbVec2s &cursorPos);
|
||||
|
||||
/// Helper for detectPreselection(), for constraints only.
|
||||
std::set<int> detectPreselectionConstr(const SoPickedPoint *Point,
|
||||
const Gui::View3DInventorViewer *viewer,
|
||||
const SbVec2s &cursorPos);
|
||||
|
||||
/*! Look at the center of the bounding of all selected items */
|
||||
void centerSelection();
|
||||
|
||||
/// box selection method
|
||||
void doBoxSelection(const SbVec2s &startPos, const SbVec2s &endPos,
|
||||
const Gui::View3DInventorViewer *viewer);
|
||||
/// draw the sketch in the inventor nodes
|
||||
/// temp => use temporary solver solution in SketchObject
|
||||
/// recreateinformationscenography => forces a rebuild of the information overlay scenography
|
||||
void draw(bool temp=false, bool rebuildinformationoverlay=true);
|
||||
|
||||
/// helper change the color of the sketch according to selection and solver status
|
||||
void updateColor(void);
|
||||
//@}
|
||||
|
||||
/** @name Selection functions */
|
||||
//@{
|
||||
/// Is the view provider selectable
|
||||
bool isSelectable(void) const override;
|
||||
|
||||
/// Observer message from the Selection
|
||||
virtual void onSelectionChanged(const Gui::SelectionChanges& msg) override;
|
||||
//@}
|
||||
|
||||
/** @name Access to Sketch and Solver objects */
|
||||
//@{
|
||||
/// get the pointer to the sketch document object
|
||||
Sketcher::SketchObject *getSketchObject(void) const;
|
||||
|
||||
/** returns a const reference to the last solved sketch object. It guarantees that
|
||||
* the solver object does not lose synchronisation with the SketchObject properties.
|
||||
*
|
||||
* NOTE: Operations requiring write access to the solver must be done via SketchObject
|
||||
* NOTE: Operations requiring * write * access to the solver must be done via SketchObject
|
||||
* interface. See for example functions:
|
||||
* -> inline void setRecalculateInitialSolutionWhileMovingPoint(bool recalculateInitialSolutionWhileMovingPoint)
|
||||
* -> inline int initTemporaryMove(int geoId, PointPos pos, bool fine=true)
|
||||
@@ -217,22 +481,24 @@ public:
|
||||
* -> inline void updateSolverExtension(int geoId, std::unique_ptr<Part::GeometryExtension> && ext)
|
||||
*/
|
||||
const Sketcher::Sketch &getSolvedSketch(void) const;
|
||||
//@}
|
||||
|
||||
/// snap points x,y (mouse coordinates) onto grid if enabled
|
||||
void snapToGrid(double &x, double &y);
|
||||
/** @name miscelanea utilities */
|
||||
//@{
|
||||
/*! Look at the center of the bounding of all selected items */
|
||||
void centerSelection();
|
||||
/// returns the scale factor
|
||||
float getScaleFactor() const;
|
||||
//@}
|
||||
|
||||
/// moves a selected constraint
|
||||
void moveConstraint(int constNum, const Base::Vector2d &toPos);
|
||||
/// finds a free position for placing a constraint icon
|
||||
Base::Vector3d seekConstraintPosition(const Base::Vector3d &origPos,
|
||||
const Base::Vector3d &norm,
|
||||
const Base::Vector3d &dir, float step,
|
||||
const SoNode *constraint);
|
||||
|
||||
float getScaleFactor();
|
||||
int getPreselectPoint(void) const;
|
||||
int getPreselectCurve(void) const;
|
||||
int getPreselectCross(void) const;
|
||||
/** @name constraint Virtual Space visibility management */
|
||||
//@{
|
||||
/// updates the visibility of the virtual space of constraints
|
||||
void updateVirtualSpace(void);
|
||||
/// determines whether the constraints in the normal space or the ones in the virtual are to be shown
|
||||
void setIsShownVirtualSpace(bool isshownvirtualspace);
|
||||
/// returns whether the virtual space is being shown
|
||||
bool getIsShownVirtualSpace(void) const;
|
||||
//@}
|
||||
|
||||
/** @name base class implementer */
|
||||
@@ -257,238 +523,239 @@ public:
|
||||
virtual bool mouseButtonPressed(int Button, bool pressed, const SbVec2s& cursorPos, const Gui::View3DInventorViewer* viewer) override;
|
||||
//@}
|
||||
|
||||
void deleteSelected();
|
||||
|
||||
/// updates the visibility of the virtual space
|
||||
void updateVirtualSpace(void);
|
||||
void setIsShownVirtualSpace(bool isshownvirtualspace);
|
||||
bool getIsShownVirtualSpace(void) const;
|
||||
|
||||
/// Icons and Icon overlays
|
||||
/// Control the overlays appearing on the Tree and reflecting different sketcher states
|
||||
virtual QIcon mergeColorfulOverlayIcons (const QIcon & orig) const override;
|
||||
|
||||
friend class DrawSketchHandler;
|
||||
friend struct ::EditData;
|
||||
|
||||
/** @name Signals for controlling information in Task dialogs */
|
||||
//@{
|
||||
/// signals if the constraints list has changed
|
||||
boost::signals2::signal<void ()> signalConstraintsChanged;
|
||||
/// signals if the sketch has been set up
|
||||
boost::signals2::signal<void (const QString &state, const QString &msg, const QString &url, const QString &linkText)> signalSetUp;
|
||||
/// signals if the elements list has changed
|
||||
boost::signals2::signal<void ()> signalElementsChanged;
|
||||
//@}
|
||||
|
||||
/** Observer for parameter group. */
|
||||
void OnChange(Base::Subject<const char*> &rCaller, const char * sReason) override;
|
||||
|
||||
/** @name Attorneys for collaboration with helper classes */
|
||||
//@{
|
||||
friend class ViewProviderSketchDrawSketchHandlerAttorney;
|
||||
friend class ViewProviderSketchCoinAttorney;
|
||||
friend class ViewProviderSketchShortcutListenerAttorney;
|
||||
//@}
|
||||
protected:
|
||||
Base::Placement getEditingPlacement() const;
|
||||
|
||||
/** @name enter/exit edit mode */
|
||||
//@{
|
||||
virtual bool setEdit(int ModNum) override;
|
||||
virtual void unsetEdit(int ModNum) override;
|
||||
virtual void setEditViewer(Gui::View3DInventorViewer*, int ModNum) override;
|
||||
virtual void unsetEditViewer(Gui::View3DInventorViewer*) override;
|
||||
void deactivateHandler();
|
||||
/// update solver information based on last solving at SketchObject
|
||||
void UpdateSolverInformation(void);
|
||||
/// helper to detect whether the picked point lies on the sketch
|
||||
bool isPointOnSketch(const SoPickedPoint *pp) const;
|
||||
/// get called by the container whenever a property has been changed
|
||||
virtual void onChanged(const App::Property *prop) override;
|
||||
//@}
|
||||
|
||||
/** @name miscelanea editing functions */
|
||||
//@{
|
||||
/// purges the DrawHandler if existing and tidies up
|
||||
void deactivateHandler();
|
||||
/// get called if a subelement is double clicked while editing
|
||||
void editDoubleClicked(void);
|
||||
//@}
|
||||
|
||||
/// set up the edition data structure EditData
|
||||
void createEditInventorNodes(void);
|
||||
/// pointer to the edit data structure if the ViewProvider is in edit.
|
||||
EditData *edit;
|
||||
/// build up the visual of the constraints
|
||||
void rebuildConstraintsVisual(void);
|
||||
|
||||
void slotUndoDocument(const Gui::Document&);
|
||||
void slotRedoDocument(const Gui::Document&);
|
||||
|
||||
protected:
|
||||
boost::signals2::connection connectUndoDocument;
|
||||
boost::signals2::connection connectRedoDocument;
|
||||
|
||||
/// set icon & font sizes
|
||||
void initItemsSizes();
|
||||
/// subscribe to parameter groups as an observer
|
||||
void subscribeToParameters();
|
||||
/// unsubscribe to parameter groups as an observer
|
||||
void unsubscribeToParameters();
|
||||
/// updates the sizes of the edit mode inventor node
|
||||
void updateInventorNodeSizes();
|
||||
|
||||
void forceUpdateData();
|
||||
/** @name Solver Information */
|
||||
//@{
|
||||
/// update solver information based on last solving at SketchObject
|
||||
void UpdateSolverInformation(void);
|
||||
|
||||
/// Auxiliary function to generate messages about conflicting, redundant and malformed constraints
|
||||
static QString appendConstraintMsg( const QString & singularmsg,
|
||||
const QString & pluralmsg,
|
||||
const std::vector<int> &vector);
|
||||
|
||||
/// Return display string for constraint including hiding units if
|
||||
//requested.
|
||||
QString getPresentationString(const Sketcher::Constraint *constraint);
|
||||
|
||||
/** @name Protected helpers for drawing constraint icons*/
|
||||
//@{
|
||||
QString iconTypeFromConstraint(Sketcher::Constraint *constraint);
|
||||
|
||||
/// Returns a QColor object appropriate for constraint with given id
|
||||
/*! In the case of combined icons, the icon color is chosen based on
|
||||
* the constraint with the highest priority from constrColorPriority()
|
||||
*/
|
||||
QColor constrColor(int constraintId);
|
||||
/// Used by drawMergedConstraintIcons to decide what color to make icons
|
||||
/*! See constrColor() */
|
||||
int constrColorPriority(int constraintId);
|
||||
|
||||
/// Internal type used for drawing constraint icons
|
||||
struct constrIconQueueItem {
|
||||
/// Type of constraint the icon represents. Eg: "small/Constraint_PointOnObject_sm"
|
||||
QString type;
|
||||
|
||||
/// Internal constraint ID number
|
||||
/// These map to results of getSketchObject()->Constraints.getValues()
|
||||
int constraintId;
|
||||
|
||||
/// Label to be rendered with this icon, if any
|
||||
QString label;
|
||||
|
||||
/// Absolute coordinates of the constraint icon
|
||||
SbVec3f position;
|
||||
|
||||
/// Pointer to the SoImage object where the icon should be written
|
||||
SoImage *destination;
|
||||
|
||||
/// Pointer to SoInfo object where we store the constraint IDs that the icon refers to
|
||||
SoInfo *infoPtr;
|
||||
|
||||
/// Angle to rotate an icon
|
||||
double iconRotation;
|
||||
|
||||
bool visible;
|
||||
};
|
||||
|
||||
/// Internal type used for drawing constraint icons
|
||||
typedef std::vector<constrIconQueueItem> IconQueue;
|
||||
/// For constraint icon bounding boxes
|
||||
typedef std::pair<QRect, std::set<int> > ConstrIconBB;
|
||||
/// For constraint icon bounding boxes
|
||||
typedef std::vector<ConstrIconBB> ConstrIconBBVec;
|
||||
|
||||
void combineConstraintIcons(IconQueue iconQueue);
|
||||
|
||||
/// Renders an icon for a single constraint and sends it to Coin
|
||||
void drawTypicalConstraintIcon(const constrIconQueueItem &i);
|
||||
|
||||
/// Combines multiple constraint icons and sends them to Coin
|
||||
void drawMergedConstraintIcons(IconQueue iconQueue);
|
||||
|
||||
/// Helper for drawMergedConstraintIcons and drawTypicalConstraintIcon
|
||||
QImage renderConstrIcon(const QString &type,
|
||||
const QColor &iconColor,
|
||||
const QStringList &labels,
|
||||
const QList<QColor> &labelColors,
|
||||
double iconRotation,
|
||||
//! Gets populated with bounding boxes (in icon
|
||||
//! image coordinates) for the icon at left, then
|
||||
//! labels for different constraints.
|
||||
std::vector<QRect> *boundingBoxes = NULL,
|
||||
//! If not NULL, gets set to the number of pixels
|
||||
//! that the text extends below the icon base.
|
||||
int *vPad = NULL);
|
||||
|
||||
/// Copies a QImage constraint icon into a SoImage*
|
||||
/*! Used by drawTypicalConstraintIcon() and drawMergedConstraintIcons() */
|
||||
void sendConstraintIconToCoin(const QImage &icon, SoImage *soImagePtr);
|
||||
|
||||
/// Essentially a version of sendConstraintIconToCoin, with a blank icon
|
||||
void clearCoinImage(SoImage *soImagePtr);
|
||||
|
||||
/// Returns the size that Coin should display the indicated image at
|
||||
SbVec3s getDisplayedSize(const SoImage *) const;
|
||||
//@}
|
||||
|
||||
void setPositionText(const Base::Vector2d &Pos, const SbString &txt);
|
||||
void setPositionText(const Base::Vector2d &Pos);
|
||||
void resetPositionText(void);
|
||||
/** @name manage updates during undo/redo operations */
|
||||
//@{
|
||||
void slotUndoDocument(const Gui::Document&);
|
||||
void slotRedoDocument(const Gui::Document&);
|
||||
void forceUpdateData();
|
||||
//@}
|
||||
|
||||
// handle preselection and selection of points
|
||||
/** @name base class implementer */
|
||||
//@{
|
||||
/// get called by the container whenever a property has been changed
|
||||
virtual void onChanged(const App::Property *prop) override;
|
||||
//@}
|
||||
|
||||
private:
|
||||
/// function to handle OCCT BSpline weight calculation singularities and representation
|
||||
void scaleBSplinePoleCirclesAndUpdateSolverAndSketchObjectGeometry(
|
||||
GeoList & geolist,
|
||||
bool geometrywithmemoryallocation,
|
||||
std::vector<std::unique_ptr<Part::Geometry>> &deepCopiesToDelete);
|
||||
|
||||
/** @name geometry and coordinates auxiliary functions */
|
||||
//@{
|
||||
/// give the coordinates of a line on the sketch plane in sketcher (2D) coordinates
|
||||
void getCoordsOnSketchPlane(const SbVec3f &point, const SbVec3f &normal, double &u, double &v) const;
|
||||
|
||||
/// give projecting line of position
|
||||
void getProjectingLine(const SbVec2s&,
|
||||
const Gui::View3DInventorViewer *viewer,
|
||||
SbLine&) const;
|
||||
//@}
|
||||
|
||||
/** @name preselection functions */
|
||||
//@{
|
||||
/// helper to detect preselection
|
||||
bool detectAndShowPreselection (SoPickedPoint * Point, const SbVec2s &cursorPos);
|
||||
int getPreselectPoint(void) const;
|
||||
int getPreselectCurve(void) const;
|
||||
int getPreselectCross(void) const;
|
||||
void setPreselectPoint(int PreselectPoint);
|
||||
void setPreselectRootPoint();
|
||||
void resetPreselectPoint(void);
|
||||
|
||||
bool setPreselect(const std::string &subNameSuffix, float x = 0, float y = 0, float z = 0);
|
||||
//@}
|
||||
|
||||
/** @name Selection functions */
|
||||
//@{
|
||||
/// box selection method
|
||||
void doBoxSelection(const SbVec2s &startPos, const SbVec2s &endPos,
|
||||
const Gui::View3DInventorViewer *viewer);
|
||||
|
||||
void addSelectPoint(int SelectPoint);
|
||||
void removeSelectPoint(int SelectPoint);
|
||||
void clearSelectPoints(void);
|
||||
|
||||
bool isSelected(const std::string & ss) const;
|
||||
void rmvSelection(const std::string &subNameSuffix);
|
||||
bool addSelection(const std::string &subNameSuffix, float x = 0, float y = 0, float z = 0);
|
||||
bool addSelection2(const std::string &subNameSuffix, float x = 0, float y = 0, float z = 0);
|
||||
//@}
|
||||
|
||||
/** @name miscelanea utilities */
|
||||
//@{
|
||||
/// snap points x,y (mouse coordinates) onto grid if enabled
|
||||
void snapToGrid(double &x, double &y);
|
||||
|
||||
/// moves a selected constraint
|
||||
void moveConstraint(int constNum, const Base::Vector2d &toPos);
|
||||
|
||||
/// returns whether the sketch is in edit mode.
|
||||
bool isInEditMode() const;
|
||||
//@}
|
||||
|
||||
/** @name Attorney functions*/
|
||||
//@{
|
||||
/* private functions to decouple Attorneys and Clients from the internal implementation of
|
||||
the ViewProvider and its members, such as sketchObject (see friend attorney classes) and
|
||||
improve encapsulation.
|
||||
*/
|
||||
|
||||
//********* ViewProviderSketchCoinAttorney ***********************
|
||||
|
||||
bool constraintHasExpression(int constrid) const;
|
||||
|
||||
const std::vector<Sketcher::Constraint *> getConstraints() const;
|
||||
|
||||
// gets the list of geometry of the sketchobject or of the solver instance
|
||||
const GeoList getGeoList() const;
|
||||
|
||||
GeoListFacade getGeoListFacade() const;
|
||||
|
||||
Base::Placement getEditingPlacement() const;
|
||||
|
||||
std::unique_ptr<SoRayPickAction> getRayPickAction() const;
|
||||
|
||||
SbVec2f getScreenCoordinates(SbVec2f sketchcoordinates) const;
|
||||
|
||||
QFont getApplicationFont() const;
|
||||
|
||||
int defaultFontSizePixels() const;
|
||||
|
||||
int getApplicationLogicalDPIX() const;
|
||||
|
||||
double getRotation(SbVec3f pos0, SbVec3f pos1) const;
|
||||
|
||||
bool isSketchInvalid() const;
|
||||
|
||||
bool isSketchFullyConstrained() const;
|
||||
|
||||
bool haveConstraintsInvalidGeometry() const;
|
||||
|
||||
void addNodeToRoot(SoSeparator * node);
|
||||
|
||||
void removeNodeFromRoot(SoSeparator * node);
|
||||
|
||||
bool isConstraintPreselected(int constraintId) const;
|
||||
|
||||
bool isPointSelected(int pointId) const;
|
||||
|
||||
void executeOnSelectionPointSet(std::function<void(const int)> && operation) const;
|
||||
|
||||
bool isCurveSelected(int curveId) const;
|
||||
|
||||
bool isConstraintSelected(int constraintId) const;
|
||||
|
||||
//********* ViewProviderSketchShortcutListenerAttorney ***********//
|
||||
void deleteSelected();
|
||||
|
||||
//********* ViewProviderSketchDrawSketchHandlerAttorney **********//
|
||||
void setPositionText(const Base::Vector2d &Pos, const SbString &txt);
|
||||
void setPositionText(const Base::Vector2d &Pos);
|
||||
void resetPositionText(void);
|
||||
|
||||
/// draw the edit curve
|
||||
void drawEdit(const std::vector<Base::Vector2d> &EditCurve);
|
||||
/// draw the edit markers
|
||||
void drawEditMarkers(const std::vector<Base::Vector2d> &EditMarkers, unsigned int augmentationlevel = 0);
|
||||
/// set the pick style of the sketch coordinate axes
|
||||
void setAxisPickStyle(bool on);
|
||||
//@}
|
||||
|
||||
private:
|
||||
/** @name Solver message creation*/
|
||||
//@{
|
||||
/* private functions to decouple Attorneys and Clients from the internal implementation of
|
||||
the ViewProvider and its members, such as sketchObject (see friend attorney classes) and
|
||||
improve encapsulation.
|
||||
*/
|
||||
/// generates a warning message about constraint conflicts and appends it to the given message
|
||||
static QString appendConflictMsg(const std::vector<int> &conflicting);
|
||||
/// generates a warning message about redundant constraints and appends it to the given message
|
||||
static QString appendRedundantMsg(const std::vector<int> &redundant);
|
||||
/// generates a warning message about partially redundant constraints and appends it to the given message
|
||||
static QString appendPartiallyRedundantMsg(const std::vector<int> &partiallyredundant);
|
||||
/// generates a warning message about redundant constraints and appends it to the given message
|
||||
static QString appendMalformedMsg(const std::vector<int> &redundant);
|
||||
//@}
|
||||
|
||||
private:
|
||||
boost::signals2::connection connectUndoDocument;
|
||||
boost::signals2::connection connectRedoDocument;
|
||||
|
||||
// modes while sketching
|
||||
SketchMode Mode;
|
||||
|
||||
// colors
|
||||
static SbColor VertexColor;
|
||||
static SbColor CurveColor;
|
||||
static SbColor CreateCurveColor;
|
||||
static SbColor CurveDraftColor;
|
||||
static SbColor CurveExternalColor;
|
||||
static SbColor CrossColorV;
|
||||
static SbColor CrossColorH;
|
||||
static SbColor FullyConstrainedColor;
|
||||
static SbColor ConstrDimColor;
|
||||
static SbColor ConstrIcoColor;
|
||||
static SbColor NonDrivingConstrDimColor;
|
||||
static SbColor ExprBasedConstrDimColor;
|
||||
static SbColor PreselectColor;
|
||||
static SbColor SelectColor;
|
||||
static SbColor PreselectSelectedColor;
|
||||
static SbColor InformationColor;
|
||||
static SbColor DeactivatedConstrDimColor;
|
||||
static SbColor InternalAlignedGeoColor;
|
||||
static SbColor FullyConstraintElementColor;
|
||||
static SbColor FullyConstraintConstructionElementColor;
|
||||
static SbColor FullyConstraintInternalAlignmentColor;
|
||||
static SbColor FullyConstraintConstructionPointColor;
|
||||
static SbColor InvalidSketchColor;
|
||||
|
||||
static SbTime prvClickTime;
|
||||
static SbVec2s prvClickPos; //used by double-click-detector
|
||||
static SbVec2s prvCursorPos;
|
||||
static SbVec2s newCursorPos;
|
||||
|
||||
float zCross;
|
||||
//float zLines;
|
||||
//float zPoints;
|
||||
float zLowPoints;
|
||||
float zHighPoints;
|
||||
float zConstr;
|
||||
float zHighlight;
|
||||
float zText;
|
||||
float zEdit;
|
||||
float zHighLine;
|
||||
float zInfo;
|
||||
float zLowLines;
|
||||
float zMidLines;
|
||||
float zHighLines;
|
||||
|
||||
// reference coordinates for relative operations
|
||||
double xInit,yInit;
|
||||
bool relative;
|
||||
Drag drag;
|
||||
|
||||
Gui::Rubberband* rubberband;
|
||||
Preselection preselection;
|
||||
Selection selection;
|
||||
|
||||
// information layer variables
|
||||
bool visibleInformationChanged;
|
||||
double combrepscalehyst;
|
||||
std::unique_ptr<Gui::Rubberband> rubberband;
|
||||
|
||||
std::string editDocName;
|
||||
std::string editObjName;
|
||||
std::string editSubName;
|
||||
|
||||
// Virtual space variables
|
||||
bool isShownVirtualSpace; // indicates whether the present virtual space view is the Real Space or the Virtual Space (virtual space 1 or 2)
|
||||
|
||||
ShortcutListener* listener;
|
||||
|
||||
std::unique_ptr<EditModeCoinManager> editCoinManager;
|
||||
|
||||
std::unique_ptr<ViewProviderSketch::ParameterObserver> pObserver;
|
||||
|
||||
std::unique_ptr<DrawSketchHandler> sketchHandler;
|
||||
|
||||
ViewProviderParameters viewProviderParameters;
|
||||
};
|
||||
|
||||
} // namespace PartGui
|
||||
|
||||
35
src/Mod/Sketcher/Gui/ViewProviderSketchCoinAttorney.cpp
Normal file
35
src/Mod/Sketcher/Gui/ViewProviderSketchCoinAttorney.cpp
Normal file
@@ -0,0 +1,35 @@
|
||||
/***************************************************************************
|
||||
* 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 *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
|
||||
#include "PreCompiled.h"
|
||||
|
||||
#ifndef _PreComp_
|
||||
|
||||
#endif // #ifndef _PreComp_
|
||||
|
||||
#include "ViewProviderSketch.h"
|
||||
|
||||
#include "ViewProviderSketchCoinAttorney.h"
|
||||
|
||||
using namespace SketcherGui;
|
||||
using namespace Sketcher;
|
||||
257
src/Mod/Sketcher/Gui/ViewProviderSketchCoinAttorney.h
Normal file
257
src/Mod/Sketcher/Gui/ViewProviderSketchCoinAttorney.h
Normal file
@@ -0,0 +1,257 @@
|
||||
/***************************************************************************
|
||||
* 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_ViewProviderSketchCoinAttorney_H
|
||||
#define SKETCHERGUI_ViewProviderSketchCoinAttorney_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Inventor/SbVec2f.h>
|
||||
#include <Inventor/SbVec3f.h>
|
||||
#include <Inventor/actions/SoRayPickAction.h>
|
||||
|
||||
|
||||
namespace Base {
|
||||
template< typename T >
|
||||
class Vector3;
|
||||
|
||||
class Vector2d;
|
||||
|
||||
class Placement;
|
||||
}
|
||||
|
||||
namespace Part {
|
||||
class Geometry;
|
||||
}
|
||||
|
||||
namespace Sketcher {
|
||||
class Constraint;
|
||||
class PropertyConstraintList;
|
||||
};
|
||||
|
||||
namespace SketcherGui {
|
||||
|
||||
class ViewProviderSketch;
|
||||
|
||||
using GeoList = Sketcher::GeoList;
|
||||
using GeoListFacade = Sketcher::GeoListFacade;
|
||||
|
||||
/** @brief Attorney class for limiting access to viewprovider
|
||||
* @details
|
||||
* ViewProviderSketch delegates a substantial part of coin related visualisation to
|
||||
* ViewProviderSketchCoinAttorney during edit mode.
|
||||
*
|
||||
* Sometimes friend classes of ViewProviderSketchCoinAttorney need to access selected functionalities only available to ViewProviderSketch.
|
||||
*
|
||||
* This attorney class regulates which specific functionalities ViewProviderSketchCoinAttorney is able to access in
|
||||
* ViewProviderSketch.
|
||||
*
|
||||
* The objective is:
|
||||
* - to preserve as much as possible ViewProviderSketch encapsulation
|
||||
* - to promote as much as reasonably possible loose coupling between tightly related classes.
|
||||
* - to keep control over the interactions between these classes and easily identify the cooperation interface.
|
||||
*/
|
||||
class ViewProviderSketchCoinAttorney {
|
||||
private:
|
||||
static inline bool constraintHasExpression(const ViewProviderSketch &vp, int constrid);
|
||||
static inline const std::vector<Sketcher::Constraint *> getConstraints(const ViewProviderSketch & vp);
|
||||
static inline const GeoList getGeoList(const ViewProviderSketch & vp);
|
||||
static inline const GeoListFacade getGeoListFacade(const ViewProviderSketch & vp);
|
||||
static inline Base::Placement getEditingPlacement(const ViewProviderSketch & vp);
|
||||
static inline void updateGridExtent(ViewProviderSketch & vp, float minx, float maxx, float miny, float maxy);
|
||||
static inline bool isShownVirtualSpace(const ViewProviderSketch & vp);
|
||||
static inline std::unique_ptr<SoRayPickAction> getRayPickAction(const ViewProviderSketch & vp);
|
||||
|
||||
static inline float getScaleFactor(const ViewProviderSketch & vp);
|
||||
static inline SbVec2f getScreenCoordinates(const ViewProviderSketch & vp, SbVec2f sketchcoordinates);
|
||||
static inline QFont getApplicationFont(const ViewProviderSketch & vp);
|
||||
static inline double getRotation(const ViewProviderSketch & vp, SbVec3f pos0, SbVec3f pos1);
|
||||
static inline int defaultApplicationFontSizePixels(const ViewProviderSketch & vp);
|
||||
static inline int getApplicationLogicalDPIX(const ViewProviderSketch & vp);
|
||||
|
||||
static inline bool isSketchInvalid(const ViewProviderSketch & vp);
|
||||
static inline bool isSketchFullyConstrained(const ViewProviderSketch & vp);
|
||||
static inline bool haveConstraintsInvalidGeometry(const ViewProviderSketch & vp);
|
||||
|
||||
static inline void addNodeToRoot(ViewProviderSketch & vp, SoSeparator * node);
|
||||
|
||||
static inline void removeNodeFromRoot(ViewProviderSketch & vp, SoSeparator * node);
|
||||
|
||||
static inline int getPreselectPoint(const ViewProviderSketch &vp);
|
||||
static inline int getPreselectCurve(const ViewProviderSketch &vp);
|
||||
static inline int getPreselectCross(const ViewProviderSketch &vp);
|
||||
|
||||
static inline bool isConstraintPreselected(const ViewProviderSketch &vp, int constraintId);
|
||||
static inline bool isPointSelected(const ViewProviderSketch &vp, int pointId);
|
||||
static inline bool isCurveSelected(const ViewProviderSketch &vp, int curveId);
|
||||
static inline bool isConstraintSelected(const ViewProviderSketch &vp, int constraintId);
|
||||
|
||||
static inline void executeOnSelectionPointSet(const ViewProviderSketch &vp, std::function<void(const int)> && operation);
|
||||
|
||||
friend class EditModeCoinManager;
|
||||
friend class EditModeConstraintCoinManager;
|
||||
friend class EditModeGeometryCoinManager;
|
||||
};
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::constraintHasExpression(const ViewProviderSketch & vp, int constrid)
|
||||
{
|
||||
return vp.constraintHasExpression(constrid);
|
||||
};
|
||||
|
||||
inline const std::vector<Sketcher::Constraint *> ViewProviderSketchCoinAttorney::getConstraints(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.getConstraints();
|
||||
}
|
||||
|
||||
inline const GeoList ViewProviderSketchCoinAttorney::getGeoList(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.getGeoList();
|
||||
}
|
||||
|
||||
const GeoListFacade ViewProviderSketchCoinAttorney::getGeoListFacade(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.getGeoListFacade();
|
||||
}
|
||||
|
||||
inline Base::Placement ViewProviderSketchCoinAttorney::getEditingPlacement(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.getEditingPlacement();
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchCoinAttorney::updateGridExtent(ViewProviderSketch & vp, float minx, float maxx, float miny, float maxy)
|
||||
{
|
||||
vp.updateGridExtent(minx, maxx, miny, maxy);
|
||||
}
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::isShownVirtualSpace(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.viewProviderParameters.isShownVirtualSpace;
|
||||
}
|
||||
|
||||
inline std::unique_ptr<SoRayPickAction> ViewProviderSketchCoinAttorney::getRayPickAction(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.getRayPickAction();
|
||||
}
|
||||
|
||||
inline float ViewProviderSketchCoinAttorney::getScaleFactor(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.getScaleFactor();
|
||||
}
|
||||
|
||||
inline SbVec2f ViewProviderSketchCoinAttorney::getScreenCoordinates(const ViewProviderSketch & vp, SbVec2f sketchcoordinates)
|
||||
{
|
||||
return vp.getScreenCoordinates(sketchcoordinates);
|
||||
}
|
||||
|
||||
inline QFont ViewProviderSketchCoinAttorney::getApplicationFont(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.getApplicationFont();
|
||||
}
|
||||
|
||||
inline double ViewProviderSketchCoinAttorney::getRotation(const ViewProviderSketch & vp, SbVec3f pos0, SbVec3f pos1)
|
||||
{
|
||||
return vp.getRotation(pos0,pos1);
|
||||
}
|
||||
|
||||
inline int ViewProviderSketchCoinAttorney::defaultApplicationFontSizePixels(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.defaultFontSizePixels();
|
||||
}
|
||||
|
||||
inline int ViewProviderSketchCoinAttorney::getApplicationLogicalDPIX(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.getApplicationLogicalDPIX();
|
||||
}
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::isSketchInvalid(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.isSketchInvalid();
|
||||
}
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::isSketchFullyConstrained(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.isSketchFullyConstrained();
|
||||
}
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::haveConstraintsInvalidGeometry(const ViewProviderSketch & vp)
|
||||
{
|
||||
return vp.haveConstraintsInvalidGeometry();
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchCoinAttorney::addNodeToRoot(ViewProviderSketch & vp, SoSeparator * node)
|
||||
{
|
||||
vp.addNodeToRoot(node);
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchCoinAttorney::removeNodeFromRoot(ViewProviderSketch & vp, SoSeparator * node)
|
||||
{
|
||||
vp.removeNodeFromRoot(node);
|
||||
}
|
||||
|
||||
inline int ViewProviderSketchCoinAttorney::getPreselectPoint(const ViewProviderSketch &vp)
|
||||
{
|
||||
return vp.getPreselectPoint();
|
||||
}
|
||||
|
||||
inline int ViewProviderSketchCoinAttorney::getPreselectCurve(const ViewProviderSketch &vp)
|
||||
{
|
||||
return vp.getPreselectCurve();
|
||||
}
|
||||
|
||||
inline int ViewProviderSketchCoinAttorney::getPreselectCross(const ViewProviderSketch &vp)
|
||||
{
|
||||
return vp.getPreselectCross();
|
||||
}
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::isConstraintPreselected(const ViewProviderSketch &vp, int constraintId)
|
||||
{
|
||||
return vp.isConstraintPreselected(constraintId);
|
||||
}
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::isPointSelected(const ViewProviderSketch &vp, int pointId)
|
||||
{
|
||||
return vp.isPointSelected(pointId);
|
||||
}
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::isCurveSelected(const ViewProviderSketch &vp, int curveId)
|
||||
{
|
||||
return vp.isCurveSelected(curveId);
|
||||
}
|
||||
|
||||
inline bool ViewProviderSketchCoinAttorney::isConstraintSelected(const ViewProviderSketch &vp, int constraintId)
|
||||
{
|
||||
return vp.isConstraintSelected(constraintId);
|
||||
}
|
||||
|
||||
inline void ViewProviderSketchCoinAttorney::executeOnSelectionPointSet(const ViewProviderSketch &vp, std::function<void(const int)> && operation)
|
||||
{
|
||||
vp.executeOnSelectionPointSet(std::move(operation));
|
||||
}
|
||||
|
||||
} // namespace SketcherGui
|
||||
|
||||
|
||||
#endif // SKETCHERGUI_ViewProviderSketchCoinAttorney_H
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user