Sketcher: Box Selection - refactor

==================================

Full refactor of this function without change of functionality (hopefully).
This commit is contained in:
Abdullah Tahiri
2023-11-11 18:03:16 +01:00
committed by abdullahtahiriyo
parent 811da8bb09
commit 55639df573
2 changed files with 133 additions and 489 deletions

View File

@@ -95,6 +95,20 @@ T getSketcherGeneralParameter(const std::string& string, T defaultvalue)
}
}
template<typename T>
T getPreferencesViewParameter(const std::string& string, T defaultvalue)
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath(
"User parameter:BaseApp/Preferences/View");
if constexpr (std::is_same_v<decltype(defaultvalue), unsigned int>) {
return static_cast<unsigned int>(hGrp->GetUnsigned(string.c_str(), defaultvalue));
}
else if constexpr (std::is_same_v<decltype(defaultvalue), int>) {
return static_cast<int>(hGrp->GetInt(string.c_str(), defaultvalue));
}
}
ViewProviderSketch::ParameterObserver::ParameterObserver(ViewProviderSketch& client)
: Client(client)
{}
@@ -343,6 +357,13 @@ void ViewProviderSketch::ParameterObserver::initParameters()
Client.setGridDivLineColor(color);
},
nullptr}},
{"SegmentsPerGeometry",
{[this, packedDefaultGridColor](const std::string& string,
[[maybe_unused]] App::Property* property) {
auto v = getPreferencesViewParameter(string, 50);
Client.viewProviderParameters.stdCountSegments = v;
},
nullptr}},
};
for (auto& val : parameterMap) {
@@ -2304,10 +2325,15 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s& startPos, const SbVec2s&
assert(int(geomlist.size()) == extGeoCount + intGeoCount);
assert(int(geomlist.size()) >= 2);
Base::Vector3d pnt0, pnt1, pnt2, pnt;
int VertexId =
-1;// the loop below should be in sync with the main loop in ViewProviderSketch::draw
// so that the vertex indices are calculated correctly
auto inBBCoords = [&Plm, &proj](const Base::Vector3d & point) {
Base::Vector3d pnt;
Plm.multVec(point, pnt);
return proj(pnt);
};
int VertexId = -1; // the loop below should be in sync with the main loop in
// ViewProviderSketch::draw so that the vertex indices are calculated
// correctly
int GeoId = 0;
bool touchMode = false;
@@ -2316,6 +2342,58 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s& startPos, const SbVec2s&
if (corners[0].getValue()[0] > corners[1].getValue()[0])
touchMode = true;
auto selectVertex = [this](int vertexid) {
std::stringstream ss;
ss << "Vertex" << vertexid;
addSelection2(ss.str());
};
auto selectEdge = [this](int edgeid) {
std::stringstream ss;
ss << "Edge" << edgeid;
addSelection2(ss.str());
};
auto selectVertexIfInsideBox = [&polygon, &VertexId, &selectVertex](const Base::Vector3d & point) {
if (polygon.Contains(Base::Vector2d(point.x, point.y))) {
selectVertex( VertexId + 1);
return true; // inside
}
return false; // outside
};
auto selectEdgeIfInsideBox = [&touchMode, &polygon, &GeoId, &inBBCoords, &selectEdge,
numSegments = viewProviderParameters.stdCountSegments](auto geo){
if constexpr (std::is_same<decltype(geo), Part::GeomBSplineCurve>::value) {
numSegments *= geo->countKnots(); // one less segments than knots
}
double segment = (geo->getLastParameter() - geo->getFirstParameter()) / numSegments;
bool bpolyInside = true;
for (int i = 0; i < numSegments; i++) {
Base::Vector3d pnt = geo->value(geo->getFirstParameter() + i * segment);
pnt = inBBCoords(pnt);
if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) {
bpolyInside = false;
if (!touchMode) {
break;
}
}
else if (touchMode) {
bpolyInside = true;
break;
}
}
if (bpolyInside) {
selectEdge(GeoId+1);
}
};
for (std::vector<Part::Geometry*>::const_iterator it = geomlist.begin();
it != geomlist.end() - 2;
++it, ++GeoId) {
@@ -2326,43 +2404,28 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s& startPos, const SbVec2s&
if ((*it)->is<Part::GeomPoint>()) {
// ----- Check if single point lies inside box selection -----/
const Part::GeomPoint* point = static_cast<const Part::GeomPoint*>(*it);
Plm.multVec(point->getPoint(), pnt0);
pnt0 = proj(pnt0);
VertexId += 1;
Base::Vector3d pnt0 = inBBCoords(point->getPoint());
VertexId++;
if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y))) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
}
selectVertexIfInsideBox(pnt0);
}
else if ((*it)->is<Part::GeomLineSegment>()) {
// ----- Check if line segment lies inside box selection -----/
const Part::GeomLineSegment* lineSeg = static_cast<const Part::GeomLineSegment*>(*it);
Plm.multVec(lineSeg->getStartPoint(), pnt1);
Plm.multVec(lineSeg->getEndPoint(), pnt2);
pnt1 = proj(pnt1);
pnt2 = proj(pnt2);
VertexId += 2;
Base::Vector3d pnt1 = inBBCoords(lineSeg->getStartPoint());
Base::Vector3d pnt2 = inBBCoords(lineSeg->getEndPoint());
bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y));
bool pnt2Inside = polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y));
if (pnt1Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId;
addSelection2(ss.str());
}
VertexId++;
bool pnt1Inside = selectVertexIfInsideBox(pnt1);
VertexId++;
bool pnt2Inside = selectVertexIfInsideBox(pnt2);
polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y));
polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y));
if (pnt2Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
}
if ((pnt1Inside && pnt2Inside) && !touchMode) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
selectEdge(GeoId+1);
}
// check if line intersects with polygon
else if (touchMode) {
@@ -2372,488 +2435,66 @@ void ViewProviderSketch::doBoxSelection(const SbVec2s& startPos, const SbVec2s&
std::list<Base::Polygon2d> resultList;
polygon.Intersect(lineAsPolygon, resultList);
if (!resultList.empty()) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
selectEdge(GeoId+1);
}
}
}
else if ((*it)->is<Part::GeomCircle>()) {
else if ((*it)->isDerivedFrom<Part::GeomConic>()) {
// ----- Check if circle lies inside box selection -----/
/// TODO: Make it impossible to miss the circle if it's big and the selection pretty
/// TODO: Make it impossible to miss the conic if it's big and the selection pretty
/// thin.
const Part::GeomCircle* circle = static_cast<const Part::GeomCircle*>(*it);
pnt0 = circle->getCenter();
VertexId += 1;
const Part::GeomConic* circle = static_cast<const Part::GeomConic*>(*it);
Base::Vector3d pnt0 = inBBCoords(circle->getCenter());
VertexId++;
Plm.multVec(pnt0, pnt0);
pnt0 = proj(pnt0);
bool pnt0Inside = selectVertexIfInsideBox(pnt0);
if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y)) || touchMode) {
if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y))) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
}
int countSegments = 12;
if (touchMode)
countSegments = 36;
float segment = float(2 * M_PI) / countSegments;
// circumscribed polygon radius
float radius = float(circle->getRadius()) / cos(segment / 2);
bool bpolyInside = true;
pnt0 = circle->getCenter();
float angle = 0.f;
for (int i = 0; i < countSegments; ++i, angle += segment) {
pnt = Base::Vector3d(
pnt0.x + radius * cos(angle), pnt0.y + radius * sin(angle), 0.f);
Plm.multVec(pnt, pnt);
pnt = proj(pnt);
if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) {
bpolyInside = false;
if (!touchMode)
break;
}
else if (touchMode) {
bpolyInside = true;
break;
}
}
if (bpolyInside) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
}
if (pnt0Inside || touchMode) {
selectEdgeIfInsideBox(circle);
}
}
else if ((*it)->is<Part::GeomEllipse>()) {
// ----- Check if ellipse lies inside box selection -----/
const Part::GeomEllipse* ellipse = static_cast<const Part::GeomEllipse*>(*it);
pnt0 = ellipse->getCenter();
VertexId += 1;
Plm.multVec(pnt0, pnt0);
pnt0 = proj(pnt0);
if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y)) || touchMode) {
if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y))) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
}
int countSegments = 12;
if (touchMode)
countSegments = 24;
double segment = (2 * M_PI) / countSegments;
// circumscribed polygon radius
double a = (ellipse->getMajorRadius()) / cos(segment / 2);
double b = (ellipse->getMinorRadius()) / cos(segment / 2);
Base::Vector3d majdir = ellipse->getMajorAxisDir();
Base::Vector3d mindir = Base::Vector3d(-majdir.y, majdir.x, 0.0);
bool bpolyInside = true;
pnt0 = ellipse->getCenter();
double angle = 0.;
for (int i = 0; i < countSegments; ++i, angle += segment) {
pnt = pnt0 + (cos(angle) * a) * majdir + sin(angle) * b * mindir;
Plm.multVec(pnt, pnt);
pnt = proj(pnt);
if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) {
bpolyInside = false;
if (!touchMode)
break;
}
else if (touchMode) {
bpolyInside = true;
break;
}
}
if (bpolyInside) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
}
}
}
else if ((*it)->is<Part::GeomArcOfCircle>()) {
else if ((*it)->isDerivedFrom<Part::GeomArcOfConic>()) {
// Check if arc lies inside box selection
const Part::GeomArcOfCircle* aoc = static_cast<const Part::GeomArcOfCircle*>(*it);
const Part::GeomArcOfConic* aoc = static_cast<const Part::GeomArcOfConic*>(*it);
pnt0 = aoc->getStartPoint(/*emulateCCW=*/true);
pnt1 = aoc->getEndPoint(/*emulateCCW=*/true);
pnt2 = aoc->getCenter();
VertexId += 3;
Base::Vector3d pnt0 = inBBCoords(aoc->getStartPoint(/*emulateCCW=*/true));
VertexId++;
bool pnt0Inside = selectVertexIfInsideBox(pnt0);
Plm.multVec(pnt0, pnt0);
Plm.multVec(pnt1, pnt1);
Plm.multVec(pnt2, pnt2);
pnt0 = proj(pnt0);
pnt1 = proj(pnt1);
pnt2 = proj(pnt2);
Base::Vector3d pnt1 = inBBCoords(aoc->getEndPoint(/*emulateCCW=*/true));
VertexId++;
bool pnt1Inside = selectVertexIfInsideBox(pnt1);
bool pnt0Inside = polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y));
bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y));
bool bpolyInside = true;
Base::Vector3d pnt2 = inBBCoords(aoc->getCenter());
VertexId++;
selectVertexIfInsideBox(pnt2);
if ((pnt0Inside && pnt1Inside) || touchMode) {
double startangle, endangle;
aoc->getRange(startangle, endangle, /*emulateCCW=*/true);
if (startangle > endangle)// if arc is reversed
std::swap(startangle, endangle);
double range = endangle - startangle;
int countSegments = std::max(2, int(12.0 * range / (2 * M_PI)));
if (touchMode)
countSegments = countSegments * 2.5;
float segment = float(range) / countSegments;
// circumscribed polygon radius
float radius = float(aoc->getRadius()) / cos(segment / 2);
pnt0 = aoc->getCenter();
float angle = float(startangle) + segment / 2;
for (int i = 0; i < countSegments; ++i, angle += segment) {
pnt = Base::Vector3d(
pnt0.x + radius * cos(angle), pnt0.y + radius * sin(angle), 0.f);
Plm.multVec(pnt, pnt);
pnt = proj(pnt);
if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) {
bpolyInside = false;
if (!touchMode)
break;
}
else if (touchMode) {
bpolyInside = true;
break;
}
}
if (bpolyInside) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
}
}
if (pnt0Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId - 1;
addSelection2(ss.str());
}
if (pnt1Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId;
addSelection2(ss.str());
}
if (polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y))) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
}
}
else if ((*it)->is<Part::GeomArcOfEllipse>()) {
// Check if arc lies inside box selection
const Part::GeomArcOfEllipse* aoe = static_cast<const Part::GeomArcOfEllipse*>(*it);
pnt0 = aoe->getStartPoint(/*emulateCCW=*/true);
pnt1 = aoe->getEndPoint(/*emulateCCW=*/true);
pnt2 = aoe->getCenter();
VertexId += 3;
Plm.multVec(pnt0, pnt0);
Plm.multVec(pnt1, pnt1);
Plm.multVec(pnt2, pnt2);
pnt0 = proj(pnt0);
pnt1 = proj(pnt1);
pnt2 = proj(pnt2);
bool pnt0Inside = polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y));
bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y));
bool bpolyInside = true;
if ((pnt0Inside && pnt1Inside) || touchMode) {
double startangle, endangle;
aoe->getRange(startangle, endangle, /*emulateCCW=*/true);
if (startangle > endangle)// if arc is reversed
std::swap(startangle, endangle);
double range = endangle - startangle;
int countSegments = std::max(2, int(12.0 * range / (2 * M_PI)));
if (touchMode)
countSegments = countSegments * 2.5;
double segment = (range) / countSegments;
// circumscribed polygon radius
double a = (aoe->getMajorRadius()) / cos(segment / 2);
double b = (aoe->getMinorRadius()) / cos(segment / 2);
Base::Vector3d majdir = aoe->getMajorAxisDir();
Base::Vector3d mindir = Base::Vector3d(-majdir.y, majdir.x, 0.0);
pnt0 = aoe->getCenter();
double angle = (startangle) + segment / 2;
for (int i = 0; i < countSegments; ++i, angle += segment) {
pnt = pnt0 + cos(angle) * a * majdir + sin(angle) * b * mindir;
Plm.multVec(pnt, pnt);
pnt = proj(pnt);
if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) {
bpolyInside = false;
if (!touchMode)
break;
}
else if (touchMode) {
bpolyInside = true;
break;
}
}
if (bpolyInside) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
}
}
if (pnt0Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId - 1;
addSelection2(ss.str());
}
if (pnt1Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId;
addSelection2(ss.str());
}
if (polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y))) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
}
}
else if ((*it)->is<Part::GeomArcOfHyperbola>()) {
// Check if arc lies inside box selection
const Part::GeomArcOfHyperbola* aoh = static_cast<const Part::GeomArcOfHyperbola*>(*it);
pnt0 = aoh->getStartPoint();
pnt1 = aoh->getEndPoint();
pnt2 = aoh->getCenter();
VertexId += 3;
Plm.multVec(pnt0, pnt0);
Plm.multVec(pnt1, pnt1);
Plm.multVec(pnt2, pnt2);
pnt0 = proj(pnt0);
pnt1 = proj(pnt1);
pnt2 = proj(pnt2);
bool pnt0Inside = polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y));
bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y));
bool bpolyInside = true;
if ((pnt0Inside && pnt1Inside) || touchMode) {
double startangle, endangle;
aoh->getRange(startangle, endangle, /*emulateCCW=*/true);
if (startangle > endangle)// if arc is reversed
std::swap(startangle, endangle);
double range = endangle - startangle;
int countSegments = std::max(2, int(12.0 * range / (2 * M_PI)));
if (touchMode)
countSegments = countSegments * 2.5;
float segment = float(range) / countSegments;
// circumscribed polygon radius
float a = float(aoh->getMajorRadius()) / cos(segment / 2);
float b = float(aoh->getMinorRadius()) / cos(segment / 2);
float phi = float(aoh->getAngleXU());
pnt0 = aoh->getCenter();
float angle = float(startangle) + segment / 2;
for (int i = 0; i < countSegments; ++i, angle += segment) {
pnt = Base::Vector3d(
pnt0.x + a * cosh(angle) * cos(phi) - b * sinh(angle) * sin(phi),
pnt0.y + a * cosh(angle) * sin(phi) + b * sinh(angle) * cos(phi),
0.f);
Plm.multVec(pnt, pnt);
pnt = proj(pnt);
if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) {
bpolyInside = false;
if (!touchMode)
break;
}
else if (touchMode) {
bpolyInside = true;
break;
}
}
if (bpolyInside) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
}
}
if (pnt0Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId - 1;
addSelection2(ss.str());
}
if (pnt1Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId;
addSelection2(ss.str());
}
if (polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y))) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
}
}
else if ((*it)->is<Part::GeomArcOfParabola>()) {
// Check if arc lies inside box selection
const Part::GeomArcOfParabola* aop = static_cast<const Part::GeomArcOfParabola*>(*it);
pnt0 = aop->getStartPoint();
pnt1 = aop->getEndPoint();
pnt2 = aop->getCenter();
VertexId += 3;
Plm.multVec(pnt0, pnt0);
Plm.multVec(pnt1, pnt1);
Plm.multVec(pnt2, pnt2);
pnt0 = proj(pnt0);
pnt1 = proj(pnt1);
pnt2 = proj(pnt2);
bool pnt0Inside = polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y));
bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y));
bool bpolyInside = true;
if ((pnt0Inside && pnt1Inside) || touchMode) {
double startangle, endangle;
aop->getRange(startangle, endangle, /*emulateCCW=*/true);
if (startangle > endangle)// if arc is reversed
std::swap(startangle, endangle);
double range = endangle - startangle;
int countSegments = std::max(2, int(12.0 * range / (2 * M_PI)));
if (touchMode)
countSegments = countSegments * 2.5;
float segment = float(range) / countSegments;
// In local coordinate system, value() of parabola is:
// P(U) = O + U*U/(4.*F)*XDir + U*YDir
// circumscribed polygon radius
float focal = float(aop->getFocal()) / cos(segment / 2);
float phi = float(aop->getAngleXU());
pnt0 = aop->getCenter();
float angle = float(startangle) + segment / 2;
for (int i = 0; i < countSegments; ++i, angle += segment) {
pnt = Base::Vector3d(
pnt0.x + angle * angle / 4 / focal * cos(phi) - angle * sin(phi),
pnt0.y + angle * angle / 4 / focal * sin(phi) + angle * cos(phi),
0.f);
Plm.multVec(pnt, pnt);
pnt = proj(pnt);
if (!polygon.Contains(Base::Vector2d(pnt.x, pnt.y))) {
bpolyInside = false;
if (!touchMode)
break;
}
else if (touchMode) {
bpolyInside = true;
break;
}
}
if (bpolyInside) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
}
}
if (pnt0Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId - 1;
addSelection2(ss.str());
}
if (pnt1Inside) {
std::stringstream ss;
ss << "Vertex" << VertexId;
addSelection2(ss.str());
}
if (polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y))) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
selectEdgeIfInsideBox(aoc);
}
}
else if ((*it)->is<Part::GeomBSplineCurve>()) {
const Part::GeomBSplineCurve* spline = static_cast<const Part::GeomBSplineCurve*>(*it);
// std::vector<Base::Vector3d> poles = spline->getPoles();
VertexId += 2;
Plm.multVec(spline->getStartPoint(), pnt1);
Plm.multVec(spline->getEndPoint(), pnt2);
pnt1 = proj(pnt1);
pnt2 = proj(pnt2);
Base::Vector3d pnt1 = inBBCoords(spline->getStartPoint());
VertexId++;
bool pnt1Inside = selectVertexIfInsideBox(pnt1);
bool pnt1Inside = polygon.Contains(Base::Vector2d(pnt1.x, pnt1.y));
bool pnt2Inside = polygon.Contains(Base::Vector2d(pnt2.x, pnt2.y));
if (pnt1Inside || (touchMode && pnt2Inside)) {
std::stringstream ss;
ss << "Vertex" << VertexId;
addSelection2(ss.str());
}
if (pnt2Inside || (touchMode && pnt1Inside)) {
std::stringstream ss;
ss << "Vertex" << VertexId + 1;
addSelection2(ss.str());
}
// This is a rather approximated approach. No it does not guarantee that the whole curve
// is boxed, specially for periodic curves, but it works reasonably well. Including all
// poles, which could be done, generally forces the user to select much more than the
// curve (all the poles) and it would not select the curve in cases where it is indeed
// comprised in the box. The implementation of the touch mode is also far from a
// desirable "touch" as it only recognizes touched points not the curve itself
if ((pnt1Inside && pnt2Inside) || (touchMode && (pnt1Inside || pnt2Inside))) {
std::stringstream ss;
ss << "Edge" << GeoId + 1;
addSelection2(ss.str());
Base::Vector3d pnt2 = inBBCoords(spline->getEndPoint());
VertexId++;
bool pnt2Inside = selectVertexIfInsideBox(pnt2);
if ((pnt1Inside && pnt2Inside) || touchMode) {
selectEdgeIfInsideBox(spline);
}
}
else {
Base::Console().DeveloperError("ViewProviderSketch::doBoxSelection",
"Geometry type is unsupported. Selection may be unsynchronised and fail.");
}
}
pnt0 = proj(Plm.getPosition());
Base::Vector3d pnt0 = proj(Plm.getPosition());
if (polygon.Contains(Base::Vector2d(pnt0.x, pnt0.y))) {
std::stringstream ss;
ss << "RootPoint";

View File

@@ -461,6 +461,9 @@ private:
false; // indicates whether the present virtual space view is the
// Real Space or the Virtual Space (virtual space 1 or 2)
bool buttonPress = false;
int stdCountSegments =
50; // preferences controlled default geometry sampling for selection
};
/** @brief Private struct grouping ViewProvider and RenderManager node, to be used as SoNode