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

Custom AcDbEntity Contain BlockReference subGetOsnapPoints Error

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
mengxiangge
482 Views, 2 Replies

Custom AcDbEntity Contain BlockReference subGetOsnapPoints Error

Dear developer:

  I have create create a custom entity which contain a AcDbBlockReference.

when i located it at origin(0,0,0), its osnap is right ,contain kOsModeNear and kOsModePerp.

but when i move the entity ,its snap begin make some error which its  kOsModeNear and kOsModePerp osnap is not effect.

  please tell me the reason which make this problem and tell me the way how to get the right osnap.

  i have attach a git from which you can know the error clearly.

  the code block is blow

// .h
class AsdkBlockReference : public AcDbEntity
{
public:
	ACRX_DECLARE_MEMBERS(AsdkBlockReference);
	AsdkBlockReference();
	~AsdkBlockReference();
	std::shared_ptr<AcDbBlockReference> mBlock_reference;
	AcGePoint3d mOrigin;
	AcGeMatrix3d mMatrix3d;
protected:
	virtual Adesk::Boolean  subWorldDraw(AcGiWorldDraw*);
	Acad::ErrorStatus       subTransformBy(const AcGeMatrix3d&);
	virtual Acad::ErrorStatus subGetOsnapPoints(AcDb::OsnapMode     osnapMode,
		Adesk::GsMarker     gsSelectionMark,
		const AcGePoint3d& pickPoint,
		const AcGePoint3d& lastPoint,
		const AcGeMatrix3d& viewXform,
		AcGePoint3dArray& snapPoints,
		AcDbIntArray& geomIds) const;
};
void addAsdkBlockReferenceObject();

// .cpp
#include "pch.h"
#include "AsdkBlockReference.h"

ACRX_DXF_DEFINE_MEMBERS_WITH_PROPERTIES(
    AsdkBlockReference, AcDbEntity,
    AcDb::kDHL_CURRENT, AcDb::kMReleaseCurrent,
    AcDbProxyEntity::kNoOperation,金地墙2,
    GemWallStyle Sample
    | Product Desc : A description for your object
    | Company : Your company name
    | WEB Address : Your company WEB site address,
    AsdkBlockReference::makeMembers
)
AcDbHandle AsdkBlockReference::mHandle = nullptr;

AsdkBlockReference::AsdkBlockReference()
{}

AsdkBlockReference::~AsdkBlockReference()
{}
Acad::ErrorStatus
AsdkBlockReference::subTransformBy(const AcGeMatrix3d& xfm)
{
    assertReadEnabled();
    mMatrix3d = xfm;
    if(mBlock_reference)
    {
        mBlock_reference->transformBy(xfm);
    }
    return Acad::eOk;
}
Adesk::Boolean AsdkBlockReference::subWorldDraw(AcGiWorldDraw* pW)
{
    assertReadEnabled();
    pW->geometry().draw(mBlock_reference->drawable());
    return Adesk::kTrue;
}
Acad::ErrorStatus AsdkBlockReference::subGetOsnapPoints(AcDb::OsnapMode     osnapMode,
    Adesk::GsMarker     gsSelectionMark,
    const AcGePoint3d& pickPoint,
    const AcGePoint3d& lastPoint,
    const AcGeMatrix3d& viewXform,
    AcGePoint3dArray& snapPoints,
    AcDbIntArray& geomIds) const
{
    auto ima = mMatrix3d.inverse();;
    auto pickBasePoint = const_cast<AcGePoint3d&>(pickPoint).transformBy(ima);

    auto lastBasePoint = const_cast<AcGePoint3d&>(lastPoint).transformBy(ima);
    return mBlock_reference->getOsnapPoints(osnapMode, gsSelectionMark, pickBasePoint, lastBasePoint, viewXform, snapPoints, geomIds);
}
void addAsdkBlockReferenceObject()
{
    ads_name      ename, sset;
    if (RTNORM == acedSSGet(NULL, NULL, NULL, NULL, sset))
    {
        struct resbuf* rb;
        if (acedSSNameX(&rb, sset, 0) != RTNORM)
        {
            acedSSFree(sset);
            return;
        }
        if (rb == NULL || rb->restype != RTLB)
        {
            assert(0);
            return ;
        }
        rb = rb->rbnext; // Bump up to the selection method, always after RTLB.
        rb = rb->rbnext; // Bump up to the first name, always after sel method.
        ename[0] = rb->resval.rlname[0];
        ename[1] = rb->resval.rlname[1];

        AcDbEntity* ent = NULL;
        AcDbObjectId polyId;
        acdbGetObjectId(polyId, ename);
        auto t = acdbOpenAcDbEntity(ent, polyId, AcDb::kForRead);        
    	auto tBlock = static_cast<AcDbBlockReference*>(ent);
        auto tBlockRecordId = tBlock->blockTableRecord();
        ent->close();

        AsdkBlockReference* pNewObj = new AsdkBlockReference;
        pNewObj->mOrigin = AcGePoint3d(0, 0, 0);
        auto pShareBlock = std::make_shared<AcDbBlockReference>(
            pNewObj->mOrigin, tBlockRecordId);
        pNewObj->mBlock_reference = pShareBlock;
        AcDbBlockTable* pBlockTable;
        acdbHostApplicationServices()->workingDatabase()
            ->getSymbolTable(pBlockTable, AcDb::kForRead);

        AcDbBlockTableRecord* pBlock;
        pBlockTable->getAt(ACDB_MODEL_SPACE, pBlock,
            AcDb::kForWrite);

        AcDbObjectId objId;
        auto es=pBlock->appendAcDbEntity(objId, pNewObj);

        pNewObj->recordGraphicsModified();    
        pBlock->close();
        pBlockTable->close();
        pNewObj->close(); 
    }   
}
Labels (1)
2 REPLIES 2
Message 2 of 3
daniel_cadext
in reply to: mengxiangge

I was able to get a sample to work,

there's another subGetOsnapPoints to override. it's weird that  just returning

ref.getOsnapPoints(osnapMode, gsSelectionMark, _pickPoint, _lastPoint, viewXform, snapPoints, geomIds, xform); doesn't work.

Anyway if this seems to work, hope it helps. maybe someone with more knowledge can help

 

 

Python for AutoCAD, Python wrappers for ARX https://github.com/CEXT-Dan/PyRx
Message 3 of 3
mengxiangge
in reply to: daniel_cadext

Dear daniel,

thanks your help! it's works .

i only call this method: ref.getOsnapPoints(osnapMode, gsSelectionMark, _pickPoint, _lastPoint, viewXform, snapPoints, geomIds, xform); 

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report