Skip to content

Commit

Permalink
+ Get exact point on data model when picking in 3d view
Browse files Browse the repository at this point in the history
  • Loading branch information
wwmayer committed Nov 21, 2013
1 parent f5a4c28 commit 1333cb8
Show file tree
Hide file tree
Showing 8 changed files with 91 additions and 11 deletions.
34 changes: 24 additions & 10 deletions src/Gui/ManualAlignment.cpp
Expand Up @@ -1143,17 +1143,21 @@ void ManualAlignment::probePickedCallback(void * ud, SoEventCallback * n)
// Get the closest point to the camera of the whole scene.
// This point doesn't need to be part of this view provider.
Gui::WaitCursor wc;
const SoPickedPoint * point = n->getPickedPoint();
const SoPickedPoint * point = view->getPickedPoint(n);
if (point) {
Gui::ViewProvider* vp = static_cast<Gui::ViewProvider*>(view->getViewProviderByPath(point->getPath()));
if (vp && vp->getTypeId().isDerivedFrom(Gui::ViewProviderDocumentObject::getClassTypeId())) {
Gui::ViewProviderDocumentObject* that = static_cast<Gui::ViewProviderDocumentObject*>(vp);
self->applyPickedProbe(that, point);

const SbVec3f& vec = point->getPoint();
Gui::getMainWindow()->showMessage(
tr("Point picked at (%1,%2,%3)")
.arg(vec[0]).arg(vec[1]).arg(vec[2]));
if (self->applyPickedProbe(that, point)) {
const SbVec3f& vec = point->getPoint();
Gui::getMainWindow()->showMessage(
tr("Point picked at (%1,%2,%3)")
.arg(vec[0]).arg(vec[1]).arg(vec[2]));
}
else {
Gui::getMainWindow()->showMessage(
tr("No point was found on model"));
}
}
}
else {
Expand Down Expand Up @@ -1229,22 +1233,32 @@ void ManualAlignment::probePickedCallback(void * ud, SoEventCallback * n)
* This method stores the picked point \a pnt from the view provider \a prov. If enough points in both windows have been picked
* the alignment gets invoked.
*/
void ManualAlignment::applyPickedProbe(Gui::ViewProviderDocumentObject* prov, const SoPickedPoint* pnt)
bool ManualAlignment::applyPickedProbe(Gui::ViewProviderDocumentObject* prov, const SoPickedPoint* pnt)
{
const SbVec3f& vec = pnt->getPoint();
const SbVec3f& nor = pnt->getNormal();

// add to the list for the non-aligned view in the left view
if (myAlignModel.activeGroup().hasView(prov)) {
myAlignModel.activeGroup().addPoint(Base::Vector3d(vec[0],vec[1],vec[2]));
std::vector<Base::Vector3d> pts = prov->getPickedPoints(pnt);
if (pts.empty())
return false;
myAlignModel.activeGroup().addPoint(pts.front());
// Adds a point marker for the picked point.
d->picksepLeft->addChild(pickedPointsSubGraph(vec, nor, myAlignModel.activeGroup().countPoints()));
return true;
}
else if (myFixedGroup.hasView(prov)) {
myFixedGroup.addPoint(Base::Vector3d(vec[0],vec[1],vec[2]));
std::vector<Base::Vector3d> pts = prov->getPickedPoints(pnt);
if (pts.empty())
return false;
myFixedGroup.addPoint(pts.front());
// Adds a point marker for the picked point.
d->picksepRight->addChild(pickedPointsSubGraph(vec, nor, myFixedGroup.countPoints()));
return true;
}

return false;
}

#include "moc_ManualAlignment.cpp"
Expand Down
2 changes: 1 addition & 1 deletion src/Gui/ManualAlignment.h
Expand Up @@ -215,7 +215,7 @@ class GuiExport ManualAlignment : public QObject
/** @name Probe picking */
//@{
static void probePickedCallback(void * ud, SoEventCallback * n);
void applyPickedProbe(Gui::ViewProviderDocumentObject*, const SoPickedPoint* pnt);
bool applyPickedProbe(Gui::ViewProviderDocumentObject*, const SoPickedPoint* pnt);
//@}

protected Q_SLOTS:
Expand Down
8 changes: 8 additions & 0 deletions src/Gui/View3DInventorViewer.cpp
Expand Up @@ -1412,6 +1412,14 @@ SoPickedPoint* View3DInventorViewer::pickPoint(const SbVec2s& pos) const
return (pick ? new SoPickedPoint(*pick) : 0);
}

const SoPickedPoint* View3DInventorViewer::getPickedPoint(SoEventCallback * n) const
{
if (selectionRoot)
return selectionRoot->getPickedPoint(n->getAction());
else
return n->getPickedPoint();
}

SbBool View3DInventorViewer::pubSeekToPoint(const SbVec2s& pos)
{
return this->seekToPoint(pos);
Expand Down
1 change: 1 addition & 0 deletions src/Gui/View3DInventorViewer.h
Expand Up @@ -202,6 +202,7 @@ class GuiExport View3DInventorViewer : public SoQtViewer, public Gui::SelectionS
// calls a PickAction on the scene graph
bool pickPoint(const SbVec2s& pos,SbVec3f &point,SbVec3f &norm) const;
SoPickedPoint* pickPoint(const SbVec2s& pos) const;
const SoPickedPoint* getPickedPoint(SoEventCallback * n) const;
SbBool pubSeekToPoint(const SbVec2s& pos);
void pubSeekToPoint(const SbVec3f& pos);
//@}
Expand Down
9 changes: 9 additions & 0 deletions src/Gui/ViewProvider.cpp
Expand Up @@ -369,3 +369,12 @@ SoPickedPoint* ViewProvider::getPointOnRay(const SbVec3f& pos,const SbVec3f& dir
//return (pick ? pick->copy() : 0); // needs the same instance of CRT under MS Windows
return (pick ? new SoPickedPoint(*pick) : 0);
}

std::vector<Base::Vector3d> ViewProvider::getPickedPoints(const SoPickedPoint* pp) const
{
// the default implementation just returns the picked point from the visual representation
std::vector<Base::Vector3d> pts;
const SbVec3f& vec = pp->getPoint();
pts.push_back(Base::Vector3d(vec[0],vec[1],vec[2]));
return pts;
}
1 change: 1 addition & 0 deletions src/Gui/ViewProvider.h
Expand Up @@ -121,6 +121,7 @@ class GuiExport ViewProvider : public App::PropertyContainer
/// return a hit element to the selection path or 0
virtual std::string getElement(const SoDetail *) const { return std::string(); }
virtual SoDetail* getDetail(const char*) const { return 0; }
virtual std::vector<Base::Vector3d> getPickedPoints(const SoPickedPoint *) const;
/// return the higlight lines for a given element or the whole shape
virtual std::vector<Base::Vector3d> getSelectionShape(const char* Element) const
{ return std::vector<Base::Vector3d>(); };
Expand Down
46 changes: 46 additions & 0 deletions src/Mod/Part/Gui/ViewProviderExt.cpp
Expand Up @@ -27,6 +27,8 @@
# include <sstream>
# include <Poly_Polygon3D.hxx>
# include <BRepBndLib.hxx>
# include <BRepBuilderAPI_MakeVertex.hxx>
# include <BRepExtrema_DistShapeShape.hxx>
# include <BRepMesh.hxx>
# include <BRepMesh_IncrementalMesh.hxx>
# include <BRep_Tool.hxx>
Expand All @@ -51,6 +53,7 @@
# include <TopoDS_Wire.hxx>
# include <TopoDS_Face.hxx>
# include <TopoDS_Shape.hxx>
# include <TopoDS_Vertex.hxx>
# include <TopoDS_Iterator.hxx>
# include <TopExp_Explorer.hxx>
# include <TopExp.hxx>
Expand Down Expand Up @@ -472,6 +475,49 @@ SoDetail* ViewProviderPartExt::getDetail(const char* subelement) const
return detail;
}

std::vector<Base::Vector3d> ViewProviderPartExt::getPickedPoints(const SoPickedPoint* pp) const
{
try {
std::vector<Base::Vector3d> pts;
std::string element = this->getElement(pp->getDetail());
const Part::TopoShape& shape = static_cast<Part::Feature*>(getObject())->Shape.getShape();

TopoDS_Shape subShape = shape.getSubShape(element.c_str());

// get the point of the vertex directly
if (subShape.ShapeType() == TopAbs_VERTEX) {
const TopoDS_Vertex& v = TopoDS::Vertex(subShape);
gp_Pnt p = BRep_Tool::Pnt(v);
pts.push_back(Base::Vector3d(p.X(),p.Y(),p.Z()));
}
// get the nearest point on the edge
else if (subShape.ShapeType() == TopAbs_EDGE) {
const SbVec3f& vec = pp->getPoint();
BRepBuilderAPI_MakeVertex mkVert(gp_Pnt(vec[0],vec[1],vec[2]));
BRepExtrema_DistShapeShape distSS(subShape, mkVert.Vertex(), 0.1);
if (distSS.NbSolution() > 0) {
gp_Pnt p = distSS.PointOnShape1(1);
pts.push_back(Base::Vector3d(p.X(),p.Y(),p.Z()));
}
}
// get the nearest point on the face
else if (subShape.ShapeType() == TopAbs_FACE) {
const SbVec3f& vec = pp->getPoint();
BRepBuilderAPI_MakeVertex mkVert(gp_Pnt(vec[0],vec[1],vec[2]));
BRepExtrema_DistShapeShape distSS(subShape, mkVert.Vertex(), 0.1);
if (distSS.NbSolution() > 0) {
gp_Pnt p = distSS.PointOnShape1(1);
pts.push_back(Base::Vector3d(p.X(),p.Y(),p.Z()));
}
}

return pts;
}
catch (...) {
return ViewProvider::getPickedPoints(pp);
}
}

std::vector<Base::Vector3d> ViewProviderPartExt::getSelectionShape(const char* Element) const
{
return std::vector<Base::Vector3d>();
Expand Down
1 change: 1 addition & 0 deletions src/Mod/Part/Gui/ViewProviderExt.h
Expand Up @@ -101,6 +101,7 @@ class PartGuiExport ViewProviderPartExt : public Gui::ViewProviderGeometryObject
/// return a hit element to the selection path or 0
virtual std::string getElement(const SoDetail*) const;
virtual SoDetail* getDetail(const char*) const;
virtual std::vector<Base::Vector3d> getPickedPoints(const SoPickedPoint *) const;
/// return the higlight lines for a given element or the whole shape
virtual std::vector<Base::Vector3d> getSelectionShape(const char* Element) const;
//@}
Expand Down

0 comments on commit 1333cb8

Please sign in to comment.