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

[ACAD 2013-2014] Block reference internal point identification

8 REPLIES 8
Reply
Message 1 of 9
gatti.massimo
588 Views, 8 Replies

[ACAD 2013-2014] Block reference internal point identification

Hi,

I'm developing an application which process a block diagram built with lines and blocks.

 

Blocks are inserted as AcDbBlockReference.

 

For each block I need to define, easily, an input point and an output point.

 

When the block is inserted as an AcdbBlockReference, I need to set also the scale factor to scale the insertion.

 

So, for each block, using the block editor I had defined 2 attributes "IN" and "OUT"

 

During the processing of the enities I can build the structure fast, using ssget.

 

Now I need to extend the acdbBlockreference class to implement:

-the deepclone for copy & paste

-the override for the snappoints

 

When I derive the class AcDbBlockReference, I can't use Attributes on the block, thus I need to put something else on the block definition to represent these two points.

 

(I can't use fixed points because I have to resize the block. The user, who create blocks must be able to add these points easily)

 

How can I do? Have I to add subentities on the block like a litte circle?

 

Thank you for your help.

 

Have a good day.

Massimo

 

 

8 REPLIES 8
Message 2 of 9
owenwengerd
in reply to: gatti.massimo

You haven't explained why you are deriving a new class from AcDbBlockReference, but doing so is almost certainly a bad idea and very likely the wrong way to solve the problem.

--
Owen Wengerd
ManuSoft
Message 3 of 9
gatti.massimo
in reply to: owenwengerd

I need to derive from AcDbBlockReference, in order to:

-manage copy and paste overriding the deepclone method of the acdbblockreference.

-manage the snap point of the block overriding the getosnappoint method.

 

I've already implemented the copy paste using the deepCloneObjects function, but I need to implement this feature with CTRL+C and CTRL+V and with the possibility to copy from one layer and paste to another layer.

 

Now I can't override the snap points of the blockreference, because I can't override the method getsnappoint without deriving from the acdbblockreference.

 

Someone adviced me to use the snappointoverrule, but I think it's a workaround and the need to implement the copy & paste push me to derive my custom class fromacdbblockreference..

 

Thank you for your time.

 

Regards

Massimo

Message 4 of 9
owenwengerd
in reply to: gatti.massimo

Sorry, I don't understand what you mean by "manage copy and paste" and "manage the snap point". In any case, it sounds like you have decided to create a derived class despite advice to the contrary.

--
Owen Wengerd
ManuSoft
Message 5 of 9
Nick1983
in reply to: owenwengerd

I have something similar (block digram for wiring), so comments :). 

1. use pure AcDbBlockReference

2. create data for in\out points in block coordinates (for block "name". i hope you have unique blocks with their own in\out points)

AcGeMatrix3d mat(pBlock->blockTransform());
mat.invert();
...
acedGetPoint(NULL,_T("\nSet point: "),asDblArray(pt));
acdbUcs2Wcs(asDblArray(pt), asDblArray(pt), false);
pt.transformBy(mat); // now point is in block coordinates
...

3. create your own snap (my piece of getOsnapInfo)

getOsnapInfo(...)
{
...
assert( pickedObject->isKindOf( AcDbBlockReference::desc() ));
AcDbBlockReference * pBlock = (AcDbBlockReference*)pickedObject;
ACHAR *BlockName;
AcDbDynBlockReference dynBlk(pBlock->objectId()); 
if (dynBlk.isDynamicBlock()) 
{ 
  AcDbBlockTableRecordPointer pBTR(dynBlk.dynamicBlockTableRecord(),AcDb::kForRead); 
  if (pBTR.openStatus() == Acad::eOk)
  { 
    pBTR->getName(BlockName); 
    pBTR->close();
  } 
} 
else 
{ 
  AcDbBlockTableRecordPointer pBTR(pBlock->blockTableRecord(),AcDb::kForRead); 
  pBTR->getName(BlockName); 
  pBTR->close();
}

BLOCKPOINTS_DATA pCurData = ptsData->getDataForBlock(BlockName); // my way to get points for needed block
AcGeMatrix3d mat(pBlock->blockTransform());
...
onePoint.transformBy(mat); // now my snap point is in WCS coords

snapPoints.append(onePoint); // add ALL in\out points to snapPoints array

}

 

that's enough if you don't want stretch "lines" when block moves. )))

but if you want stetch "lines", you have to use great quantity of different reactors.

 

---
#define QUESTION(b) (2*b)||(!(2*b)) © William Shakespeare
Message 6 of 9
gatti.massimo
in reply to: Nick1983

Hi,

 

thank you for your accurate answer.

 

I'm looking at the snap point..

 

I found this 

http://adndevblog.typepad.com/autocad/2012/12/how-to-implement-extension-osnap-for-an-entity.html

 

but I added the registration of my CustomOsnapInfo in this way

 

//Register protocol extension object (customOsnapInfo)
BlockOSnapInfo::rxInit();
acrxBuildClassHierarchy();
AcDbEntity::desc()->addX(BlockOSnapInfo::desc(), &_BlockOSnapInfo);
acdbCustomOsnapManager()->addCustomOsnapMode(&_CustomOsnapMode);

 

in the AcRx::AppRetCode On_kInitAppMsg (void *pkt)  of the ARX acrxEntryPoint..

 

I put a break point on the getOsnapInfo() function and I moved with the mouse curson on some of my objects, but the execution doesn't pass through the breakpoint.

 

Could I have put the osnap registration in the wrong module?

 

Thank you for your time.

 

Massimo

Message 7 of 9

Hi, I finally figured out with the custom osnap mode, but I have a question.

 

I decided to use the osnap point on my block references to force the user to pick only input or output point fo a block.

 

But, to use the custom osnap the user has to activate this mode with an input string everytime.. this is annoying.

 

How can I force to turn on this snap mode everytime a user is drawing an acdbline and snap to a blockreference?

 

Thank you for your help.

 

Best regards

Massimo

Message 8 of 9
Nick1983
in reply to: gatti.massimo

i use this code inside MY command

{
  int osmod = acdbHostApplicationServices()->workingAppSysvars()->osmode();
  acdbHostApplicationServices()->workingAppSysvars()->setOsmode(0);
  Acad::ErrorStatus es = acdbCustomOsnapManager()->activateOsnapMode(_T("MY_OSMODE"));

  // drawing "line"

  acdbHostApplicationServices()->workingAppSysvars()->setOsmode(osmod);
}

 IMHO, it's not a good idea to turn off all of users snaps when hi just want to create a line or polyline. but you can use AcEditorReactor.

commandWillStart - check if command is "line", if true, turn off all snaps and turn on yours

commandFailed, commandCancelled, commandEnded - if you modified snaps, set em back to previous state

---
#define QUESTION(b) (2*b)||(!(2*b)) © William Shakespeare
Message 9 of 9
gatti.massimo
in reply to: Nick1983

Ok,

 

I will make some tests on this,

 

thanks for the solution.

 

Massimo

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

Post to forums  

Autodesk Design & Make Report

”Boost