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

Deriving from AcDbAttributeDefinition

18 REPLIES 18
Reply
Message 1 of 19
alex_b
664 Views, 18 Replies

Deriving from AcDbAttributeDefinition

Hi,

 

I need to modify an attribute's behaviour in a block, so I create a custom entity derived from AcDbAttributeDefinition and add it to a newly created block definition. (the only thing done in code is the custom entity).

The only overriden method is AcDbAttributeDefinition::worldDraw();

Now the result:

The block behaves normally, as far as I can tell, including transforms, save/open, explode, modifying the attribute values, etc.

but:

The block referrence calls the custom entity's worldDraw (AcDbAttributeDefinition-derived), which is logical but not what I need (what I need is access to the attribute value in the block referrence).

OTH' if I derive from AcDbAttribute, I can see no way to add the custom entity to a block definition/reference.

Did anyone try this before and can suggest a way out of this?

 Oh, and I'm doing this in Acad2008; should it make any difference?

Thanks,

 

alex

 

 

18 REPLIES 18
Message 2 of 19
owenwengerd
in reply to: alex_b

You'll have to call AcDbBlockReference::appendAttribute() to add your AcDbAttribute-derived entities to a block reference.

--
Owen Wengerd
ManuSoft
Message 3 of 19
alex_b
in reply to: owenwengerd

Owen,

 

Thanks for the tip.

I had to use it in a somewhat weird manner (without having a Attdef as part of the Block def, otherwise it didn't work as needed), like so:

- Create a block definition, just geometry, no attdefs.

- Create a custom entity derived from AcDbAttribute. The custom class overrides worldDraw() only, everything else is inherited.

- Create a block reference and append to it the custom 'attribute'.

It works as expected, up to a point:

- Construct, regen OK. Modify attribute value: OK

- Other actions - grips, move etc. - crash Autocad with a 'Access violation reading location...'; in disassembly I see it happens somwhere 

  in AcDbStub::openAcDbObject.

  Could it be that during these operations Autocad is trying to open the Attdef template object and of course there is nothing there (see above)?.

Any suggestions?

 

alex

Message 4 of 19
owenwengerd
in reply to: alex_b

The missing AcDbAttributeDefinition is not the problem, as that situation is quite common. If there isn't a bug in your code, then I guess it's most likely that the bug is in core code that assumes attributes are AcDbAttribute objects, although for a standard C cast this should not cause a problem as long as your class is derived from AcDbAttribute. If you want to experiment some more, try making your derived class appear to be an AcDbAttribute by removing the ACRX_DECLARE_MEMBERS functions.

--
Owen Wengerd
ManuSoft
Message 5 of 19
alex_b
in reply to: owenwengerd

Owen,

 

If I comment out the ACRX_DECLARE_MEMBERS macro, then ACRX_DEFINE_MEMBERS complains about missing desc(), isA() and rxinit().

If I comment out ACRX_DEFINE_MEMBERS also, then the linker can't resolve the rxinit() function.

The documentation says indeed that ACRX_DECLARE_MEMBERS is not required, but I'm confused.

Shoud I declare desc, isA, etc. manually and return the base class? What about rxinit?

About bugs:

  As far as the code works, including save/open there are probably no bugs. I even tried commenting out the overriden function with no result.

 I could post the code if you would take a look.

 The raised exception is not in my code at all.

 As for bugs in Acad core code, maybe the Autodesk people could comment?

 

Thanks,

 

alex

Message 6 of 19
owenwengerd
in reply to: alex_b

If that's the case, then your code is still trying to call that function. If it's a wizard generated project, you'll need to comment out the ACDB_REGISTER_OBJECT_ENTRY_AUTO macro as well.


@alex_b wrote:

If I comment out ACRX_DEFINE_MEMBERS also, then the linker can't resolve the rxinit() function.


 

--
Owen Wengerd
ManuSoft
Message 7 of 19
alex_b
in reply to: owenwengerd

Owen,

 

It has to call it. Otherwise, how will the custom class be added to the runtime classes?

I'm stuck here.

 

@owenwengerd wrote:

If that's the case, then your code is still trying to call that function. If it's a wizard generated project, you'll need to comment out the ACDB_REGISTER_OBJECT_ENTRY_AUTO macro as well.


@alex_b wrote:

If I comment out ACRX_DEFINE_MEMBERS also, then the linker can't resolve the rxinit() function.

alex

 


 

Message 8 of 19
owenwengerd
in reply to: alex_b


The point of this exercise is to not add the class to the runtime class dictionary, so that AutoCAD doesn't know it's a derived class.

 



@alex_b wrote:

Owen,

 

It has to call it. Otherwise, how will the custom class be added to the runtime classes?

I'm stuck here.

 

--
Owen Wengerd
ManuSoft
Message 9 of 19
alex_b
in reply to: owenwengerd

Owen,
Right, and it works fine while it lasts. Imean, by not adding the class to the runtime, the next time the dwg is opened, it is just an old plain attribute, the application doesn't recognize it, and we loose the overridden functionality. And I don't know how to re-create the connection.
It would be better to understand why - when we had a regular registered custom class - it bombed Acad, and fix that (assuming it's not core code), but I haven't a clue.
owenwengerd wrote:
  The point of this exercise is to not add the class to the runtime class dictionary, so that AutoCAD doesn't know it's a derived class.
alex

 



 

 

Message 10 of 19
owenwengerd
in reply to: alex_b

It sounds like you didn't really understand the purpose of performing the test, but at least now you have demonstrated that there is a bug in AutoCAD code and you can submit a bug report so Autodesk can fix it.

--
Owen Wengerd
ManuSoft
Message 11 of 19
alex_b
in reply to: owenwengerd

Owen,

 

I thought I understand that the purpose was to try to isolate the problem by hiding the custom object from Autocad's eyes.
Now I'm not so sure??

Anyway, this is academic, because it does not solve the main problem: deriving from AcDbAttribute.

We succeeded to find - maybe - a bug in Acad code, but I'm not an ADN member, so I cannot submit it. Is there any other mechanism to do it?

Maybe the Autodesk people are listening on this frequency.

For the time being, I can't see where to go from here.

N.B.. Strangely enough, a similar problem, similarly involving (honest) attributes and grips, occurred when I tried to use overrules on attributes; see this post:

http://through-the-interface.typepad.com/through_the_interface/2010/05/junes-plugin-of-the-month-dim...

Maybe they are all related.

 

Thanks,

 

alex

Message 12 of 19
Alexander.Rivilis
in reply to: alex_b

Alex!

Autodesk guys (especially ADN DevTech) are reading this forum. The problem is that even if this will be fixed in future versions, it will not affect AutoCAD 2008 you're talking about.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 13 of 19
owenwengerd
in reply to: alex_b

You're right Alex, the purpose was to isolate the unexpected Rx class as the cause of your crash. This is useful information if you need a solution, and can't wait for a fix from Autodesk. Yes, you can use that information in a bug report (use the CER tool that displays after the crash). In addition, knowing the cause of the crash might be helpful in finding a workaround. I'm not going to do your work for you, but if you need a solution, you now have an avenue to explore. For example, maybe you can implement your object's isA() function such that it pretends to be an AcDbAttribute during the time when AutoCAD's buggy code executes.

--
Owen Wengerd
ManuSoft
Message 14 of 19
alex_b
in reply to: Alexander.Rivilis

Alexander,
I wasn't expecting a fix for A2008.
The important thing to know is if it is indeed a bug in Autocad code (are they going to let us know?)
or in my code.
alex
@Alexander.Rivilis wrote:

Alex!

Autodesk guys (especially ADN DevTech) are reading this forum. The problem is that even if this will be fixed in future versions, it will not affect AutoCAD 2008 you're talking about.


 

Message 15 of 19
alex_b
in reply to: owenwengerd

Owen,

 

I just tried it in A2012 and it dosesn't crash anymore on MOVE, ROTATE, etc.
Apparently thed did make some modifications to the core code since A2008.

But, as we don't live in a perfect world, it now crashes on SAVE (which it didn't before).

I would think that, as the custom object is derived from AcDbAttribute and has no additional data members, it would be trivial for Acad to save it.
Instead it crashes in the core code, at label AcDbOwnerFiler::readUInt16.

I have to know what happens behind the scenes, during the SAVE command.

Also during subWorldDraw(), as there are some strange things happening there (not crashes, just strange).

Can you point me to some documentation, beyond the minimalistic info in OARX docs?

 

Thanks

 

alex

Message 16 of 19
owenwengerd
in reply to: alex_b

I'm not aware of any documentation. At this point you probably know more about it than anyone else outside of Autodesk.

--
Owen Wengerd
ManuSoft
Message 17 of 19
alex_b
in reply to: owenwengerd

Owen,

 

Assuming it wasn't irony, thank you for the compliment, but I don't feel like I know anything about the thing.
And I sincerely hope somebody knows more.

Anyway, what I am looking for is some detailed explanation of the filing process (in and out) for custom objects.

How does Acad recognize a custom object when it reads it from file, what special data is filed out, etc.

I'm pretty sure I read something along these lines a lomg time ago, but can't find it anymore.

Do you know why subWorldDraw() is called sometimes once, sometimes twice or even three times for the same object and for the same editor action?

This is all very puzzling.

 

alex

Message 18 of 19
owenwengerd
in reply to: alex_b

I realize that it sounds flippant, but there are only two ways to get authoritative answers about AutoCAD implementation details: get a job at Autodesk working on AutoCAD code, or reverse engineer it yourself. I don't mind sharing what I know if it is useful and relevant to a wider audience, but in this case I could write a book and in the end it still wouldn't solve your problem.

--
Owen Wengerd
ManuSoft
Message 19 of 19
alex_b
in reply to: owenwengerd

Owen,

 

I'll try following your advice (the 2nd alternative of course, there is not much of a chance of me getting a job at Adesk).

If I ever succeed solving this crazy thing, I'll post it here.

 

Thank you,

 

alex

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

Post to forums  

Autodesk Design & Make Report

”Boost