Saving custom entity, proxy object problem

Saving custom entity, proxy object problem

maisoui
Advocate Advocate
1,576 Views
10 Replies
Message 1 of 11

Saving custom entity, proxy object problem

maisoui
Advocate
Advocate

Hi,

 

I created a simple custom object deriving from AcDbEntity in a dbx, and I'm facing issues when I tried to save this entity in a previous dwg version. Here are the steps to reproduce the problem:

  1. Launch AutoCAD 2013 (or 2014) and load the dbx
  2. Create an instance of the custom entity
  3. Save the dwg in version 2013
  4. Restart AutoCAD 2013 (or 2014), but don't load the dbx
  5. Open the dwg created in step 3 (the custom object appears as PROXY OBJECT, it's normal)
  6. Save the dwg in version 2010 (with save as...)
  7. Launch AutoCAD 2010 (or 2011 or 2012) and load the dbx (compiled for the right version)
  8. Open the dwg created in step 6
  9. Custom object appears as PROXY OBJECT --> why ???

I read AutoCAD developer's guide (chapter Custom Objects -> Deriving from AcDbObject -> Object Version Support) about birth and filer version, but I didn't understand what I need to do. Does anyone have the same problem? Is this is a normal behavior of AutoCAD?

 

Regards,

--
Jonathan
0 Likes
1,577 Views
10 Replies
Replies (10)
Message 2 of 11

owenwengerd
Advisor
Advisor

Place a breakpoint in your dwgInFields() function to determine whether it is getting called as expected. If it isn't, then you haven't registered your AcRxClass correctly. If it is, step through it to determine why it returns an error.

--
Owen Wengerd
ManuSoft
0 Likes
Message 3 of 11

maisoui
Advocate
Advocate

Hi Owen,

 

The problem is that no breakpoint is hit in any dwgInFields() function. My dbx is correctly loaded (goes in On_kInitAppMsg and On_kLoadDwgMsg).

I checked that I use the same DWG_VERSION and MAINTENANCE_VERSION in the ACRX_DXF_DEFINE_MEMBERS macro.

I tried to extract info from AcDbObject and here is some lines:

 

AcDbObject

Class Name : AcDbZombieEntity

Birth DWG Version : 19 = kDHL_1012 (Release 13)

AcDbProxyEntity

Original Class Name : MyEntity

Original Class Name : MYENTITY

Application Description : ...

Proxy Flags : 3071

 

Everything is correct so why AutoCAD doen't call my dwgInField() functions?

Any idea?

 

--
Jonathan
0 Likes
Message 4 of 11

owenwengerd
Advisor
Advisor

It sounds like you're doing everything correctly, but obviously something is not correct somewhere. Write some test code that tries to do what AutoCAD does when it encounteres your entity: look up the class name in the system dictionary, use the returned class to call AcRxClass::create() and verify that you get back what you expect.

 

Offhand I can't think of any reason why AutoCAD would call any other member function before dwgInFields(), but if you have anything else overridden, you might try temporarily removing all except dwgInFields() to see if anything changes. Other than that, I'm out of ideas.

--
Owen Wengerd
ManuSoft
0 Likes
Message 5 of 11

maisoui
Advocate
Advocate

I followed your piece of advice and I created a very small dbx with one object (deriving AcDbObject) with only dwgInField and dwgOutField. I builded this dbx for AutoCAD 2010-11-12 and AutoCAD 2013-14 and I followed the steps I described in my first post. Result is the same!

 

After that, I wrote this code to make a test (getting my custom object from the dictionary):

 

...
AcDbObject * pObject = NULL;
if(pDictionary->getAt(_T("MYOBJECT1"), pObject, AcDb::kForRead) == Acad::eOk)
{
	if(pObject->isKindOf(AcDbProxyObject::desc()))
	{
		AcDbProxyObject * pProxyObject = static_cast<AcDbProxyObject *>(pObject);
		const ACHAR * originalClassName = pProxyObject->originalClassName();
		const ACHAR * originalDxfName = pProxyObject->originalDxfName();

		AcRxClass * pClass = AcRxClass::cast(acrxClassDictionary->at(originalClassName));
		MyObject1 * pObject1 = static_cast<MyObject1 *>(pClass->create()); // all is ok!
		delete pObject1;
	}

	pObject->close();

	Acad::ErrorStatus es = acdbResurrectMeNow(pObject->objectId()); // returns eCannotBeResurrected
}
...

Class name is correct because I was able to create an object with the correct type (my custom object class), but Proxy Object cannot be resurrected.

 

I don't understand the mechanism of AutoCAD. Maybe somebody of Autodesk can give us an explanation?

If anyone is interested, I can send my sample project.

 

Regards,

--
Jonathan
0 Likes
Message 6 of 11

owenwengerd
Advisor
Advisor

I noticed that your test code casts the returned object from AcRxClass::create without performing any check. One of the goals of the exercise was to verify that the returned object is what you expect and not something else. At the very least you should ensure that your custom object constructor is called, and that the returned pointer is the same object that was constructed. You should also use AcRxClass::cast() instead of static_cast.

 

I'd like to see your ACRX_DEFINE_MEMBERS macro. Please attach your sample project; if I get a chance I'll investigate.

--
Owen Wengerd
ManuSoft
0 Likes
Message 7 of 11

maisoui
Advocate
Advocate

Hi,

 

Yes sorry for this brutal cast, but I made needed checks in debug mode. This code is not intended to be distributed. Smiley Happy

I joined my simple project to this post.

 

Thank you for your help.

Regards,

--
Jonathan
0 Likes
Message 8 of 11

owenwengerd
Advisor
Advisor

I took a quick look at your sample project. Sorry, it's too much work for me to separate it into two projects for two different ObjectARX SDK versions, so I didn't bother trying to test anything. Have you tested without the custom birth version? I thought you had eliminated that from the equation, but I see it's still in your code.

--
Owen Wengerd
ManuSoft
0 Likes
Message 9 of 11

maisoui
Advocate
Advocate

Are you talking about using kDHL_CURRENT in my ACRX_DEFINE_MEMBERS? I tried a lot of combinations with arguments of ACRX_DEFINE_MEMBERS, but I always get the same result.

--
Jonathan
0 Likes
Message 10 of 11

owenwengerd
Advisor
Advisor

Yes, and use the ACRX_DEFINE_MEMBERS macro from the SDK to eliminate any potential unintended error introduced by your custom version.

--
Owen Wengerd
ManuSoft
0 Likes
Message 11 of 11

maisoui
Advocate
Advocate

It was a good idea, I tried with:

 

ACRX_DXF_DEFINE_MEMBERS(MyObject1, AcDbObject, AcDb::kDHL_1024, AcDb::kMRelease6, AcDbProxyEntity::kAllAllowedBits, MYOBJECT1, "SimpleObject|Product Desc: Object Enabler ...")

 

But I have no more success...

Once again, thank you for your suggestions.

--
Jonathan
0 Likes