Sketcher infinite axes

This commit is contained in:
Florian Foinant-Willig
2024-11-18 23:09:20 +01:00
committed by Yorik van Havre
parent fbd7f7090c
commit 5969df37f4
6 changed files with 124 additions and 23 deletions

View File

@@ -91,6 +91,7 @@
#include <Base/Sequencer.h>
#include <Base/Tools.h>
#include <Base/UnitsApi.h>
#include <Base/Tools2D.h>
#include <Quarter/devices/InputDevice.h>
#include <Quarter/eventhandlers/EventFilter.h>
@@ -2657,8 +2658,76 @@ SbVec2f View3DInventorViewer::getNormalizedPosition(const SbVec2s& pnt) const
return {pX, pY};
}
SbVec3f View3DInventorViewer::getPointOnXYPlaneOfPlacement(const SbVec2s& pnt,
const Base::Placement& plc) const
Base::BoundBox2d View3DInventorViewer::getViewportOnXYPlaneOfPlacement(Base::Placement plc) const
{
auto projBBox = Base::BoundBox3d();
projBBox.SetVoid();
SoCamera* pCam = this->getSoRenderManager()->getCamera();
if (!pCam) {
// Return empty box.
return Base::BoundBox2d(0, 0, 0, 0);
}
Base::Vector3d pos = plc.getPosition();
Base::Rotation rot = plc.getRotation();
// Transform the plane LCS into the global one.
Base::Vector3d zAxis(0, 0, 1);
rot.multVec(zAxis, zAxis);
// Get the position and convert Base::Vector3d to SbVec3f
SbVec3f planeNormal(zAxis.x, zAxis.y, zAxis.z);
SbVec3f planePosition(pos.x, pos.y, pos.z);
SbPlane xyPlane(planeNormal, planePosition);
const SbViewportRegion& vp = this->getSoRenderManager()->getViewportRegion();
SbViewVolume vol = pCam->getViewVolume();
float fRatio = vp.getViewportAspectRatio();
float dX, dY;
vp.getViewportSize().getValue(dX, dY);
// Projects a pair of normalized coordinates on the XY plane.
auto projectPoint =
[&](float x, float y) {
if (fRatio > 1.f) {
x = (x - 0.5f * dX) * fRatio + 0.5f * dX;
}
else if (fRatio < 1.f) {
y = (y - 0.5f * dY) / fRatio + 0.5f * dY;
}
SbLine line;
vol.projectPointToLine(SbVec2f(x, y), line);
SbVec3f pt;
// Intersection point on the XY plane.
if (!xyPlane.intersect(line, pt)) {
return;
}
projBBox.Add(Base::convertTo<Base::Vector3d>(pt));
};
// Project the four corners of the viewport plane.
projectPoint(0.f, 0.f);
projectPoint(1.f, 0.f);
projectPoint(0.f, 1.f);
projectPoint(1.f, 1.f);
if (!projBBox.IsValid()) {
// Return empty box.
return Base::BoundBox2d(0, 0, 0, 0);
}
plc.invert();
Base::ViewOrthoProjMatrix proj(plc.toMatrix());
return projBBox.ProjectBox(&proj);
}
SbVec3f View3DInventorViewer::getPointOnXYPlaneOfPlacement(const SbVec2s& pnt, const Base::Placement& plc) const
{
SbVec2f pnt2d = getNormalizedPosition(pnt);
SoCamera* pCam = this->getSoRenderManager()->getCamera();

View File

@@ -67,6 +67,10 @@ class SoClipPlane;
namespace Quarter = SIM::Coin3D::Quarter;
namespace Base {
class BoundBox2d;
}
namespace Gui {
class ViewProvider;
@@ -311,6 +315,9 @@ public:
/** Returns the 3d point on the XY plane of a placement to the given 2d point. */
SbVec3f getPointOnXYPlaneOfPlacement(const SbVec2s&, const Base::Placement&) const;
/** Returns the bounding box on the XY plane of a placement to the given 2d point. */
Base::BoundBox2d getViewportOnXYPlaneOfPlacement(Base::Placement plc) const;
/** Returns the 2d coordinates on the viewport to the given 3d point. */
SbVec2s getPointOnViewport(const SbVec3f&) const;

View File

@@ -808,8 +808,6 @@ void EditModeCoinManager::processGeometryConstraintsInformationOverlay(
processGeometryInformationOverlay(geolistfacade);
updateAxesLength();
pEditModeConstraintCoinManager->processConstraints(geolistfacade);
}
@@ -852,22 +850,18 @@ void EditModeCoinManager::processGeometryInformationOverlay(const GeoListFacade&
overlayParameters.visibleInformationChanged = false; // just updated
}
void EditModeCoinManager::updateAxesLength()
void EditModeCoinManager::updateAxesLength(const Base::BoundBox2d& bb)
{
auto zCrossH = ViewProviderSketchCoinAttorney::getViewOrientationFactor(viewProvider)
* drawingParameters.zCross;
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(
0,
SbVec3f(-analysisResults.boundingBoxMagnitudeOrder, 0.0f, zCrossH));
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(
1,
SbVec3f(analysisResults.boundingBoxMagnitudeOrder, 0.0f, zCrossH));
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(
2,
SbVec3f(0.0f, -analysisResults.boundingBoxMagnitudeOrder, zCrossH));
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(
3,
SbVec3f(0.0f, analysisResults.boundingBoxMagnitudeOrder, zCrossH));
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(0,
SbVec3f(bb.MinX, 0.0f, zCrossH));
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(1,
SbVec3f(bb.MaxX, 0.0f, zCrossH));
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(2,
SbVec3f(0.0f, bb.MinY, zCrossH));
editModeScenegraphNodes.RootCrossCoordinate->point.set1Value(3,
SbVec3f(0.0f, bb.MaxY, zCrossH));
}
void EditModeCoinManager::updateColor()

View File

@@ -44,6 +44,8 @@ class Vector3;
class Vector2d;
class BoundBox2d;
class Placement;
} // namespace Base
@@ -256,6 +258,9 @@ public:
void setConstraintSelectability(bool enabled = true);
//@}
// Updates the Axes extension to span the specified area.
void updateAxesLength(const Base::BoundBox2d& bb);
private:
// This function populates the coin nodes with the information of the current geometry
void processGeometry(const GeoListFacade& geolistfacade);
@@ -265,9 +270,6 @@ private:
// 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();

View File

@@ -3459,8 +3459,10 @@ void ViewProviderSketch::setEditViewer(Gui::View3DInventorViewer* viewer, int Mo
viewer->setupEditingRoot();
cameraSensor.setData(new VPRender {this, viewer->getSoRenderManager()});
cameraSensor.attach(viewer->getSoRenderManager()->getSceneGraph());
auto *camSensorData = new VPRender {this, viewer->getSoRenderManager()};
cameraSensor.setData(camSensorData);
cameraSensor.setDeleteCallback(&ViewProviderSketch::camSensDeleteCB, camSensorData);
cameraSensor.attach(viewer->getCamera());
}
void ViewProviderSketch::unsetEditViewer(Gui::View3DInventorViewer* viewer)
@@ -3468,6 +3470,7 @@ void ViewProviderSketch::unsetEditViewer(Gui::View3DInventorViewer* viewer)
auto dataPtr = static_cast<VPRender*>(cameraSensor.getData());
delete dataPtr;
cameraSensor.setData(nullptr);
cameraSensor.setDeleteCallback(nullptr, nullptr);
cameraSensor.detach();
viewer->removeGraphicsItem(rubberband.get());
@@ -3475,6 +3478,22 @@ void ViewProviderSketch::unsetEditViewer(Gui::View3DInventorViewer* viewer)
viewer->setSelectionEnabled(true);
}
void ViewProviderSketch::camSensDeleteCB(void* data, SoSensor *s)
{
auto *proxyVPrdr = static_cast<VPRender*>(data);
if (!proxyVPrdr)
return;
// The camera object the observer was attached to is gone, try to re-attach the sensor
// to the new camera.
// This happens i.e. when the user switches the camera type from orthographic to
// perspective.
SoCamera *camera = proxyVPrdr->renderMgr->getCamera();
if (camera) {
static_cast<SoNodeSensor *>(s)->attach(camera);
}
}
void ViewProviderSketch::camSensCB(void* data, SoSensor*)
{
VPRender* proxyVPrdr = static_cast<VPRender*>(data);
@@ -3516,6 +3535,15 @@ void ViewProviderSketch::onCameraChanged(SoCamera* cam)
Base::Interpreter().runStringObject(cmdStr.toLatin1());
}
// Stretch the axes to cover the whole viewport.
Gui::View3DInventor* view = qobject_cast<Gui::View3DInventor*>(this->getActiveView());
if (view) {
Base::Placement plc = getEditingPlacement();
const Base::BoundBox2d vpBBox = view->getViewer()
->getViewportOnXYPlaneOfPlacement(plc);
editCoinManager->updateAxesLength(vpBBox);
}
drawGrid(true);
}

View File

@@ -717,7 +717,8 @@ protected:
void unsetEdit(int ModNum) override;
void setEditViewer(Gui::View3DInventorViewer*, int ModNum) override;
void unsetEditViewer(Gui::View3DInventorViewer*) override;
static void camSensCB(void* data, SoSensor*); // camera sensor callback
static void camSensCB(void* data, SoSensor*); // camera sensor callback
static void camSensDeleteCB(void* data, SoSensor*); // camera sensor callback
void onCameraChanged(SoCamera* cam);
//@}