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

What's wrong with AcDb3dSolid?

6 REPLIES 6
Reply
Message 1 of 7
Anonymous
1162 Views, 6 Replies

What's wrong with AcDb3dSolid?

1. I define a customed command to excute the function:
void test()
{
AcDb3dSolid sod;
sod.createBox(10, 10, 10);

AcDb3dSolid sod2(sod);//copy constructor
AcDb3dSolid sod3;
sod3 = sod;//assignment operator
AcDb3dSolid sod4;
sod4.copyFrom(&sod);//copyFrom
}
it crash, only when i commented the copy constructor and the assignment operator, it works properly, so i guess the AcDb3dSolid's copy constructor and assignment operator works wrong.
2. I define a customed Entity named MyEntity, derived from AcDbEntity and override it properly. MyEntity has a data member of AcArray of AcDb3dSolid solids.
Then i defined a customed command to excute the follow function:
void test2()
{
MyEntity* pEnt = new MyEntity();
AcDb3dSolid sod;
sod.createBox(10, 10, 10);
pEnt->solids.append(sod);

...//append pEnt to the ModalSpace
}
it crash too, i see the AcArray's append method use the elem's copy constructor and assignment operator, so maybe the cause is the same as before.
3. I define a customed class named MyDb3dSolid, it has a data member of AcDb3dSolid solid, i implemented it's copy constructor and assignment operator uses the AcDb3dSolid's copyFrom method, and i aslo defined it's dwgOutFields/dwgInFields method uses the AcDb3dSolid's dwgOutFields/dwgInFields method. code like this:
class MyDb3dSolid
{
public:
MyDb3dSolid(){}
~MyDb3dSolid(){}
MyDb3dSolid(const MyDb3dSolid& mySod){this->soid.copyFrom(&(mySod.solid));}
MyDb3dSolid& operator = (const MyDb3dSolid& mySod){this->soid.copyFrom(&(mySod.solid)); return *this;}
Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const{return solid.dwgOutFields(pFiler);}
Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler){return solid.dwgInFields(pFiler);}
public:
AcDb3dSolid solid;
};
then i defined MyEntity's data member as AcArray of MyDb3dSolid solids, and excute the function too:
void test3()
{
MyEntity* pEnt = new MyEntity();
MyDb3dSolid mySod;
mySod.solid.createBox(10, 10, 10);
pEnt->solids.append(mySod);

...//append pEnt to the ModalSpace
}
it works like properly. but, whem i copy MyEntity in AutoCAD 2007 use Ctrl + C, something strange happen???
say i defined MyDb3dSolid' member function like this to print it's area:
Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const
{
double solidArea;solid.getArea(solidArea);acutPrintf(_T("\n out solid area:%f"), solidArea);
return solid.dwgOutFields(pFiler);
}
Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler)
{
Acad::ErrorStatus es = solid.dwgInFields(pFiler);
double solidArea;solid.getArea(solidArea);acutPrintf(_T("\n in solid area:%f"), solidArea);
return es;
}
when i copyclip MyEntity, in the command output window, it prints:
out solid area:600
in solid area:600
out solid area:0
in solid area:0

why???? the solid area becomes 0
how should i define AcDb3dSolid Array as MyEntity's data member???? Edited by: lodengo on Nov 22, 2009 8:38 AM
6 REPLIES 6
Message 2 of 7
Anonymous
in reply to: Anonymous

Have you verified that copyFrom() actually copies the the underlying
solid? Instead of expending so much energy on copying solids that were
created on the stack, why not just use a pointer to a solid that was created
on the heap? You can use a reference counter pointer class to manage it.

--
Owen Wengerd
President, ManuSoft <>
VP Americas, CADLock, Inc. <>
Message 3 of 7
Anonymous
in reply to: Anonymous

Unless something's changed that I don't know about (certainly possible),
AcDb3dSolid doesn't have a copy constructor nor an assignment operator.

wrote in message news:6293356@discussion.autodesk.com...
1. I define a customed command to excute the function:
void test()
{
AcDb3dSolid sod;
sod.createBox(10, 10, 10);

AcDb3dSolid sod2(sod);//copy constructor
AcDb3dSolid sod3;
sod3 = sod;//assignment operator
AcDb3dSolid sod4;
sod4.copyFrom(&sod);//copyFrom
}
it crash, only when i commented the copy constructor and the assignment
operator, it works properly, so i guess the AcDb3dSolid's copy constructor
and assignment operator works wrong.
2. I define a customed Entity named MyEntity, derived from AcDbEntity and
override it properly. MyEntity has a data member of AcArray of AcDb3dSolid
solids.
Then i defined a customed command to excute the follow function:
void test2()
{
MyEntity* pEnt = new MyEntity();
AcDb3dSolid sod;
sod.createBox(10, 10, 10);
pEnt->solids.append(sod);

...//append pEnt to the ModalSpace
}
it crash too, i see the AcArray's append method use the elem's copy
constructor and assignment operator, so maybe the cause is the same as
before.
3. I define a customed class named MyDb3dSolid, it has a data member of
AcDb3dSolid solid, i implemented it's copy constructor and assignment
operator uses the AcDb3dSolid's copyFrom method, and i aslo defined it's
dwgOutFields/dwgInFields method uses the AcDb3dSolid's
dwgOutFields/dwgInFields method. code like this:
class MyDb3dSolid
{
public:
MyDb3dSolid(){}
~MyDb3dSolid(){}
MyDb3dSolid(const MyDb3dSolid&
mySod){this->soid.copyFrom(&(mySod.solid));}
MyDb3dSolid& operator = (const MyDb3dSolid&
mySod){this->soid.copyFrom(&(mySod.solid)); return *this;}
Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const{return
solid.dwgOutFields(pFiler);}
Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler){return
solid.dwgInFields(pFiler);}
public:
AcDb3dSolid solid;
};
then i defined MyEntity's data member as AcArray of MyDb3dSolid solids, and
excute the function too:
void test3()
{
MyEntity* pEnt = new MyEntity();
MyDb3dSolid mySod;
mySod.solid.createBox(10, 10, 10);
pEnt->solids.append(mySod);

...//append pEnt to the ModalSpace
}
it works like properly. but, whem i copy MyEntity in AutoCAD 2007 use Ctrl +
C, something strange happen???
say i defined MyDb3dSolid' member function like this to print it's area:
Acad::ErrorStatus dwgOutFields(AcDbDwgFiler* pFiler) const
{
double solidArea;solid.getArea(solidArea);acutPrintf(_T("\n out solid
area:%f"), solidArea);
return solid.dwgOutFields(pFiler);
}
Acad::ErrorStatus dwgInFields(AcDbDwgFiler* pFiler)
{
Acad::ErrorStatus es = solid.dwgInFields(pFiler);
double solidArea;solid.getArea(solidArea);acutPrintf(_T("\n in solid
area:%f"), solidArea);
return es;
}
when i copyclip MyEntity, in the command output window, it prints:
out solid area:600
in solid area:600
out solid area:0
in solid area:0

why???? the solid area becomes 0
how should i define AcDb3dSolid Array as MyEntity's data member????

Edited by: lodengo on Nov 22, 2009 8:38 AM
Message 4 of 7
Anonymous
in reply to: Anonymous

Thank you for your reply, actually my purpose is define a customed entity which contains multi-AcDb3dSolid.
FYI:
I have verified that AcDb3dSolid's copyFrom() actually copies the the underlying solid.
I have tried use a pointer to a solid, but the issue is: during the "_copyclip" command excute on my customed entity, It's AcDb3dSolid-s
data member seems lose data, for me, it's solid area becomes 0.
///////////////////////////////////////////////////////////////////////////////////////////////////////////
see output:
dwgOut solid area 600.0000
dwgIn solid area 600.0000
dwgOut solid area 600.0000
dwgIn solid area 0.0000
dwgOut solid area 0.0000
///////////////////////////////////////////////////////////////////////////////////////////////////////////
code clip as below (now regardless the memory manage):
class DLLIMPEXP MyEntity : public AcDbEntity
{
public:
ACRX_DECLARE_MEMBERS(MyEntity) ;
protected:
static Adesk::UInt32 kCurrentVersionNumber ;
public:
MyEntity () ;
virtual ~MyEntity () ;

virtual Acad::ErrorStatus dwgOutFields (AcDbDwgFiler *pFiler) const ;
virtual Acad::ErrorStatus dwgInFields (AcDbDwgFiler *pFiler) ;

virtual Acad::ErrorStatus transformBy(const AcGeMatrix3d& xform);
virtual Adesk::Boolean worldDraw (AcGiWorldDraw *mode) ;
public:
AcDbLine ll;
AcArray solids;
} ;
Acad::ErrorStatus MyEntity::dwgOutFields (AcDbDwgFiler *pFiler) const
{
assertReadEnabled () ;
Acad::ErrorStatus es =AcDbEntity::dwgOutFields (pFiler) ;
if ( es != Acad::eOk ) return (es) ;

if ( (es =pFiler->writeUInt32 (MyEntity::kCurrentVersionNumber)) != Acad::eOk ) return (es) ;

ll.dwgOutFields(pFiler);

es = pFiler->writeUInt32(solids.length());
for (int i = 0; i < solids.length(); i++)
{
es = solids.at(i)->dwgOutFields(pFiler);
double a;solids.at(i)->getArea(a); acutPrintf(_T("\n dwgOut solid area %.4f"), a);
}
return (pFiler->filerStatus ()) ;
}

Acad::ErrorStatus MyEntity::dwgInFields (AcDbDwgFiler *pFiler)
{
assertWriteEnabled () ;

Acad::ErrorStatus es =AcDbEntity::dwgInFields (pFiler) ;
if ( es != Acad::eOk ) return (es) ;

Adesk::UInt32 version =0 ;
if ( (es =pFiler->readUInt32 (&version)) != Acad::eOk ) return (es) ;
if ( version > MyEntity::kCurrentVersionNumber ) return (Acad::eMakeMeProxy) ;

ll.dwgInFields(pFiler);

solids.removeAll();
Adesk::UInt32 n = 0;
es = pFiler->readUInt32(&n);
for (int i = 0; i < n; i++)
{
AcDb3dSolid* e = new AcDb3dSolid();
e->dwgInFields(pFiler);
solids.append(e);
double a;solids.at(i)->getArea(a); acutPrintf(_T("\n dwgIn solid area %.4f"), a);
}
return (pFiler->filerStatus ()) ;
}

//-----------------------------------------------------------------------------
//----- AcDbEntity protocols
Adesk::Boolean MyEntity::worldDraw (AcGiWorldDraw *mode)
{
assertReadEnabled () ;
return ll.worldDraw(mode);
}
Acad::ErrorStatus MyEntity::transformBy(const AcGeMatrix3d& xform)
{
assertWriteEnabled();
return ll.transformBy(xform);
}
//test command function
void test5()
{
MyEntity* pEnt = new MyEntity();
pEnt->ll.setStartPoint(AcGePoint3d(100, 100, 0));
pEnt->ll.setEndPoint(AcGePoint3d(500, 500, 0));

AcDb3dSolid* sod1 = new AcDb3dSolid();
sod1->createBox(10, 10, 10);

pEnt->solids.append(sod1);

appendEnt(pEnt);
}
Message 5 of 7
Anonymous
in reply to: Anonymous

I also try use Loki::SmartPtr as pointer type to manage memory, but the issue retain the same.
note the AcDbObjectPointer could not add to a AcArray.
Message 6 of 7
Anonymous
in reply to: Anonymous

First, i use the ObjectARX 2007.
I have looked up the define of AcDb3dSolid, in header file dbsol3d.h.
you are right, the AcDb3dSolid haven't customed defined it's own copy constructor nor assignment operator.
but it also not explicit forbid it's copy constructor nor assignment operator.
so it use the c++'s implicit copy constructor and assignment operator, which perform unproperly.

My purpose is define a customed entity which contains multi-AcDb3dSolid.
how to achieve that? (notice the copyclip of the entity also should copy it's solids as well)
Message 7 of 7
ExtraLine
in reply to: Anonymous

I just want to warm up this topic, and ask for an advice about good practice if custom entity have one or multiple AcDb3dSolid embeded.


If embeding is implemented using pointers on AcDb3DSolid, allocated on heap, there is a problem of copying to clipboard, as mr. lodengo described.


Is the only proper way of embending to make all AcDb3dSolids database residents ? (instead of C++ pointers, the custom entity will hold their hard pointers - Ids).

 

Tags (1)

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

Post to forums  

Autodesk Design & Make Report

”Boost