ObjectARX
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Picking Point

5 REPLIES 5
SOLVED
Reply
Message 1 of 6
johnteng00
464 Views, 5 Replies

Picking Point

 

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

5 REPLIES 5
Message 2 of 6
johnteng00
in reply to: johnteng00

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

Message 3 of 6
norman.yuan
in reply to: johnteng00

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).

 

Norman Yuan

Drive CAD With Code

EESignature

Message 4 of 6
daniel_cadext
in reply to: johnteng00

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);
                    }
                }
            }
        }
    }
}

 

edges.png

 

edges2.png

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
Message 5 of 6
tbrammer
in reply to: norman.yuan

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:

  1. Use acedSSGet(L"_:S", NULL, NULL, NULL, sset) to do the selection. 
    Than acedSSNameX(&rb, sset, 0) will give you the 3D WCS pickpoint in the resbuf *rb list:
    [0] list-begin
    [1] 1 rint
    [2] 1504745003488-1504771237483 rlname
    [3] 50 rint
    [4] list-begin
    [5] 0 rint
    [6] 2520.16553,3274.38672,119.046524            <---- 3D pickpoint in WCS
    [7] -0.577350259,0.577350259,-0.577350259
    [8] list-end
    [9] list-end
  2. Derive a class MyInputPointMonitor from AcEdInputPointMonitor, implement 
    MyInputPointMonitor::monitorInputPoint(const AcEdInputPoint& input, AcEdInputPointMonitorResult& output)
    and store input.computedPoint() for the selected point.

Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 6 of 6
john4TMYX
in reply to: tbrammer

Hi Thomas,

 

Thank you very much. You are right. It works. Appreciated your help!

 

Regards

John

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

AutoCAD Inside the Factory


Autodesk Design & Make Report