From 78b4e4211c7a75bfff9cf02ad2b46e2fa4e78f56 Mon Sep 17 00:00:00 2001 From: PaddleStroke Date: Mon, 11 Aug 2025 19:09:15 +0200 Subject: [PATCH] Sketcher: Move root point to a SoSkipBoundingGroup (#22874) --- src/Mod/Sketcher/Gui/EditModeCoinManager.cpp | 42 ++++++++++ .../Gui/EditModeCoinManagerParameters.h | 16 +++- .../Gui/EditModeGeometryCoinConverter.cpp | 14 ---- .../Gui/EditModeGeometryCoinManager.cpp | 78 +++++++++++-------- 4 files changed, 104 insertions(+), 46 deletions(-) diff --git a/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp b/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp index 0e2218e61b..a200191bef 100644 --- a/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp +++ b/src/Mod/Sketcher/Gui/EditModeCoinManager.cpp @@ -737,6 +737,16 @@ EditModeCoinManager::detectPreselection(SoPickedPoint* Point, const SbVec2s& cur SoPath* path = Point->getPath(); SoNode* tail = path->getTail(); // Tail is directly the node containing points and curves + // checking for a hit on the separate Origin Point + if (tail == editModeScenegraphNodes.OriginPointSet) { + const SoDetail* point_detail = Point->getDetail(editModeScenegraphNodes.OriginPointSet); + if (point_detail && point_detail->getTypeId() == SoPointDetail::getClassTypeId()) { + result.PointIndex = -1; // The logical ID of the origin + result.Cross = PreselectionResult::Axes::RootPoint; + return result; + } + } + for (int l = 0; l < geometryLayerParameters.getCoinLayerCount(); l++) { // checking for a hit in the points if (tail == editModeScenegraphNodes.PointSet[l]) { @@ -965,6 +975,33 @@ void EditModeCoinManager::createEditModeInventorNodes() editModeScenegraphNodes.RootCrossSet->setName("RootCrossLineSet"); crossRoot->addChild(editModeScenegraphNodes.RootCrossSet); + // stuff for the Origin Point + SoGroup* originPointRoot = new Gui::SoSkipBoundingGroup; + originPointRoot->setName("OriginPointRoot_SkipBBox"); + editModeScenegraphNodes.EditRoot->addChild(originPointRoot); + + editModeScenegraphNodes.OriginPointMaterial = new SoMaterial; + editModeScenegraphNodes.OriginPointMaterial->setName("OriginPointMaterial"); + originPointRoot->addChild(editModeScenegraphNodes.OriginPointMaterial); + + editModeScenegraphNodes.OriginPointDrawStyle = new SoDrawStyle; + editModeScenegraphNodes.OriginPointDrawStyle->setName("OriginPointDrawStyle"); + editModeScenegraphNodes.OriginPointDrawStyle->pointSize = + 8 * drawingParameters.pixelScalingFactor; + originPointRoot->addChild(editModeScenegraphNodes.OriginPointDrawStyle); + + editModeScenegraphNodes.OriginPointCoordinate = new SoCoordinate3; + editModeScenegraphNodes.OriginPointCoordinate->setName("OriginPointCoordinate"); + // A default position, which will be updated later + editModeScenegraphNodes.OriginPointCoordinate->point.set1Value(0, SbVec3f(0.0f, 0.0f, 0.0f)); + originPointRoot->addChild(editModeScenegraphNodes.OriginPointCoordinate); + + editModeScenegraphNodes.OriginPointSet = new SoMarkerSet; + editModeScenegraphNodes.OriginPointSet->setName("OriginPointSet"); + editModeScenegraphNodes.OriginPointSet->markerIndex = + Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_FILLED", drawingParameters.markerSize); + originPointRoot->addChild(editModeScenegraphNodes.OriginPointSet); + // stuff for the EditCurves +++++++++++++++++++++++++++++++++++++++ SoSeparator* editCurvesRoot = new SoSeparator; editModeScenegraphNodes.EditRoot->addChild(editCurvesRoot); @@ -1132,6 +1169,11 @@ void EditModeCoinManager::updateInventorNodeSizes() drawingParameters.markerSize); } + editModeScenegraphNodes.OriginPointDrawStyle->pointSize = + 8 * drawingParameters.pixelScalingFactor; + editModeScenegraphNodes.OriginPointSet->markerIndex = + Gui::Inventor::MarkerBitmaps::getMarkerIndex("CIRCLE_FILLED", drawingParameters.markerSize); + editModeScenegraphNodes.RootCrossDrawStyle->lineWidth = 2 * drawingParameters.pixelScalingFactor; editModeScenegraphNodes.EditCurvesDrawStyle->lineWidth = diff --git a/src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.h b/src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.h index 4d6324491d..5305cdb15e 100644 --- a/src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.h +++ b/src/Mod/Sketcher/Gui/EditModeCoinManagerParameters.h @@ -410,6 +410,14 @@ struct EditModeScenegraphNodes std::vector PointSet; //@} + /** @name Origin Point nodes*/ + //@{ + SoMaterial* OriginPointMaterial; + SoCoordinate3* OriginPointCoordinate; + SoMarkerSet* OriginPointSet; + SoDrawStyle* OriginPointDrawStyle; + //@} + /** @name Curve nodes*/ //@{ SmSwitchboard* CurvesGroup; @@ -425,7 +433,6 @@ struct EditModeScenegraphNodes //@} /** @name Axes nodes*/ - /// @warning Root Point is added together with the Point nodes above //@{ SoMaterial* RootCrossMaterials; SoCoordinate3* RootCrossCoordinate; @@ -540,6 +547,10 @@ struct CoinMapping /// index and the coin layer of the curve or point MultiFieldId getIndexLayer(int geoid, Sketcher::PointPos pos) { + if (geoid == -1) { + return MultiFieldId(-1, 0, 0); + } + auto indexit = GeoElementId2SetId.find(Sketcher::GeoElementId(geoid, pos)); if (indexit != GeoElementId2SetId.end()) { @@ -553,6 +564,9 @@ struct CoinMapping /// layer of the point MultiFieldId getIndexLayer(int vertexId) { + if (vertexId == -1) { + return MultiFieldId(-1, 0, 0); + } for (size_t l = 0; l < PointIdToVertexId.size(); l++) { diff --git a/src/Mod/Sketcher/Gui/EditModeGeometryCoinConverter.cpp b/src/Mod/Sketcher/Gui/EditModeGeometryCoinConverter.cpp index b6daaab3c2..e9b5cf3ea3 100644 --- a/src/Mod/Sketcher/Gui/EditModeGeometryCoinConverter.cpp +++ b/src/Mod/Sketcher/Gui/EditModeGeometryCoinConverter.cpp @@ -81,20 +81,6 @@ void EditModeGeometryCoinConverter::convert(const Sketcher::GeoListFacade& geoli pointCounter.resize(geometryLayerParameters.getCoinLayerCount(), 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.PointIdToPosId[0].push_back(Sketcher::PointPos::start); - 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, diff --git a/src/Mod/Sketcher/Gui/EditModeGeometryCoinManager.cpp b/src/Mod/Sketcher/Gui/EditModeGeometryCoinManager.cpp index 0b3ad9da79..5486e5db9c 100644 --- a/src/Mod/Sketcher/Gui/EditModeGeometryCoinManager.cpp +++ b/src/Mod/Sketcher/Gui/EditModeGeometryCoinManager.cpp @@ -195,6 +195,20 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade& geoli auto viewOrientationFactor = ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider); + // Origin point + auto preselectcross = ViewProviderSketchCoinAttorney::getPreselectCross(viewProvider); + if (preselectcross == 0) { // 0 means the RootPoint is preselected + editModeScenegraphNodes.OriginPointMaterial->diffuseColor = + drawingParameters.PreselectColor; + } + else { + editModeScenegraphNodes.OriginPointMaterial->diffuseColor = + drawingParameters.FullyConstraintElementColor; + } + editModeScenegraphNodes.OriginPointCoordinate->point.set1Value( + 0, + SbVec3f(0, 0, viewOrientationFactor * drawingParameters.zRootPoint)); + for (auto l = 0; l < geometryLayerParameters.getCoinLayerCount(); l++) { float x, y, z; int PtNum = editModeScenegraphNodes.PointsMaterials[l]->diffuseColor.getNum(); @@ -224,7 +238,7 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade& geoli else if (issketchinvalid) { pcolor[i] = drawingParameters.InvalidSketchColor; } - else if (!(i == 0 && l == 0) && sketchFullyConstrained) { + else if (sketchFullyConstrained) { // root point is not coloured nor external pcolor[i] = drawingParameters.FullyConstrainedColor; } @@ -302,37 +316,32 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade& geoli drawingParameters.zMidPoints, drawingParameters.zMidPoints); - for (int i = 0; i < PtNum; i++) { // 0 is the origin - if (i == 0 && l == 0) { // reset root point to lowest - pverts[i].setValue(0, 0, viewOrientationFactor * drawingParameters.zRootPoint); + for (int i = 0; i < PtNum; i++) { + if (!coinMapping.isValidPointId(i, l)) { + continue; } - else { - if (!coinMapping.isValidPointId(i, l)) { - continue; + + int GeoId = coinMapping.getPointGeoId(i, l); + Sketcher::PointPos PosId = coinMapping.getPointPosId(i, l); + pverts[i].getValue(x, y, z); + auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId); + bool isExternal = GeoId < -1; + + if (geom) { + z = viewOrientationFactor * zNormPoint; + + if (isCoincident(GeoId, PosId)) { + z = viewOrientationFactor * drawingParameters.zLowPoints; } - - int GeoId = coinMapping.getPointGeoId(i, l); - Sketcher::PointPos PosId = coinMapping.getPointPosId(i, l); - pverts[i].getValue(x, y, z); - auto geom = geolistfacade.getGeometryFacadeFromGeoId(GeoId); - bool isExternal = GeoId < -1; - - if (geom) { - z = viewOrientationFactor * zNormPoint; - - if (isCoincident(GeoId, PosId)) { - z = viewOrientationFactor * drawingParameters.zLowPoints; + else { + if (isExternal || isInternalAlignedGeom(GeoId)) { + z = viewOrientationFactor * drawingParameters.zRootPoint; } - else { - if (isExternal || isInternalAlignedGeom(GeoId)) { - z = viewOrientationFactor * drawingParameters.zRootPoint; - } - else if (geom->getConstruction()) { - z = viewOrientationFactor * zConstrPoint; - } + else if (geom->getConstruction()) { + z = viewOrientationFactor * zConstrPoint; } - pverts[i].setValue(x, y, z); } + pverts[i].setValue(x, y, z); } } @@ -349,9 +358,8 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade& geoli MultiFieldId preselectpointmfid; if (preselectcross == 0) { - if (l == 0) { // cross only in layer 0 - pcolor[0] = drawingParameters.PreselectColor; - } + editModeScenegraphNodes.OriginPointMaterial->diffuseColor = + drawingParameters.PreselectColor; } else if (preselectpoint != -1) { preselectpointmfid = coinMapping.getIndexLayer(preselectpoint); @@ -367,7 +375,8 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade& geoli ViewProviderSketchCoinAttorney::executeOnSelectionPointSet( viewProvider, - [pcolor, + [this, + pcolor, pverts, PtNum, preselectpointmfid, @@ -377,6 +386,13 @@ void EditModeGeometryCoinManager::updateGeometryColor(const GeoListFacade& geoli raisePoint, viewOrientationFactor](const int i) { auto pointindex = coinMapping.getIndexLayer(i); + + if (pointindex.fieldIndex == -1) { // It's the origin + editModeScenegraphNodes.OriginPointMaterial->diffuseColor = + drawingParameters.SelectColor; + return; + } + if (layerId == pointindex.layerId && pointindex.fieldIndex >= 0 && pointindex.fieldIndex < PtNum) { pcolor[pointindex.fieldIndex] = (preselectpointmfid == pointindex)