Hi guys,
I develop addin based objectarx, c++ codes. I ask user to pick a entity like line or edge in the solid model, but I need to have the picking point in the 3D model space. How can I get the picking point on the selected entity? Is it possible to get user's picking point?
Regards
John
Solved! Go to Solution.
Solved by tbrammer. Go to Solution.
Hi guys,
If any experts from AutoDesk see this post, could you please reply to this question? whether it is possible or not to get the picking point from the user?
Thank you very much.
Regards
John
you would use acedEntSel()/acedNEntSel()/acedNEntSelP() method. If user picks an entity, the result not only includes the selected entity, but also the exact point user clicked (which may or may not falls on the entity selected, depending on the pick box's size).
That said, I believe the point returned acedEntSel is UCS. (just a FYI)
You can try using AcDbAssocPersSubentIdPE and iterate edges to map out the closest point on the closest edge to the pick point
Example (C++20)
static auto entsel()
{
AcDbObjectId id;
AcGePoint3d pnt;
ads_name name = { 0L };
int res = acedEntSel(L"\nSelect it: ", name, asDblArray(pnt));
if (auto es = acdbGetObjectId(id, name); es != eOk)
return std::make_tuple(Acad::PromptStatus::eError, id, pnt);
return std::make_tuple(Acad::PromptStatus(res), id, pnt);
}
static std::unique_ptr<AcGeCurve3d> getGeCurve(const AcDbCurve& pDbDurve, Acad::ErrorStatus &es)
{
AcGeCurve3d* pCurve = nullptr;
es = pDbDurve.getAcGeCurve(pCurve);
return std::unique_ptr<AcGeCurve3d>(pCurve);
}
static void AcRxPyApp_idoit(void)
{
Acad::ErrorStatus es = eOk;
auto [ps, id, pnt] = entsel();
if (ps == Acad::PromptStatus::eNormal)
{
AcDbEntityPointer pEntity(id);
auto* pe = AcDbAssocPersSubentIdPE::cast(pEntity->queryX(AcDbAssocPersSubentIdPE::desc()));
AcArray <AcDbSubentId> edgeIds;
es = pe->getAllSubentities(pEntity,AcDb::kEdgeSubentType,edgeIds);
for (int i = 0; i < edgeIds.length(); ++i)
{
AcDbFullSubentPath path(id, edgeIds[i]);
std::unique_ptr<AcDbEntity> pSubEntity(pEntity->subentPtr(path));
if (pSubEntity != NULL)
{
if (pSubEntity->isA()->isDerivedFrom(AcDbCurve::desc()))
{
AcDbCurve* pDbCurve = static_cast<AcDbCurve*>(pSubEntity.get());
if (auto curve = getGeCurve(*pDbCurve, es); es == eOk)
{
acedGrDraw(asDblArray(pnt), asDblArray(curve->closestPointTo(pnt)), 1, 0);
}
}
}
}
}
}
According to my experience the pickpoint returned from acedEntSel()/acedNEntSel()/acedNEntSelP() is the point in UCS that AutoCAD displays in the coordinates window on the status line in the moment of selection.
This point will usually have Z=0. If you pick a 3DSOLID at a 3D point that is not within the current UCS plane you won't get the expected result but a projection of the pickpoint to the UCS plane along the line of sight.
I know only these two ways to retrieve the correct 3D pickpoint:
Can't find what you're looking for? Ask the community or share your knowledge.