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

AcDbCurve::createFromAcGeCurve crash

4 REPLIES 4
SOLVED
Reply
Message 1 of 5
chunyuran
578 Views, 4 Replies

AcDbCurve::createFromAcGeCurve crash

It happend when offsetting spline. But it's ok when offsetting line, polyline, circle and arc. Any ideas! Thanks.

 

ads_point pt;
ads_name ename;
if (acedEntSel(NULL, ename, pt) != RTNORM) return;

AcDbObjectId id;
acdbGetObjectId(id, ename);

 

AcDbEntityPointer pent(id, AcDb::kForRead);
pent.openStatus();
AcDbCurve* psp = AcDbCurve::cast(pent);
if (psp == NULL) return;

 

AcGeCurve3d* pGeCurve = NULL;
psp->getAcGeCurve(pGeCurve);
pent->close();

 

double offsetdist = 100.0;
AcGeVoidPointerArray arr;
pGeCurve->getTrimmedOffset(offsetdist, AcGeVector3d::kZAxis, arr, AcGe::kExtend);

 

delete pGeCurve;
pGeCurve = NULL;

 

AcAxDocLock lock;
for (int i = 0; i < arr.length(); ++i) {

AcGeCurve3d* pCurve = (AcGeCurve3d*)arr.at(i);

 

AcDbCurve* pNewcurve = NULL;
AcDbCurve::createFromAcGeCurve(*pCurve, (AcDbCurve*&)pNewcurve);
delete pCurve;


pNewcurve->setColorIndex(1);

{

// append to database
AcDbDatabase* pdb = acdbHostApplicationServices()->workingDatabase();
AcDbObjectId curid = pdb->currentSpaceId();

AcDbBlockTableRecordPointer pbtr(curid, AcDb::kForWrite);
pbtr.openStatus();
AcDbObjectId newid;
pbtr->appendAcDbEntity(newid, pNewcurve);

}
pNewcurve->close();

}

4 REPLIES 4
Message 2 of 5
tbrammer
in reply to: chunyuran

The problem is that AcDbCurve::createFromAcGeCurve(*pCurve, pNewcurve)  returns eInvalidInput for (some?) splines and leaves pNewcurve==NULL. You should always check the Acad::ErrorStatus!

 

Here is a possible workaround:

void cmdTestOffsetSpline()
{
	ads_point pt;
	ads_name ename;
	if (acedEntSel(NULL, ename, pt) != RTNORM)
		return;

	AcDbObjectId id;
	acdbGetObjectId(id, ename);

	AcDbEntityPointer pent(id, AcDb::kForRead);
	pent.openStatus();
	AcDbCurve* psp = AcDbCurve::cast(pent);
	if (psp == NULL) return;

	AcGeCurve3d* pGeCurve = NULL;
	Acad::ErrorStatus es = psp->getAcGeCurve(pGeCurve); //TB check ErrorStatus!
	pent->close();

	if (es || !pGeCurve) {  //TB check ErrorStatus!
		acutPrintf(L"\ngetAcGeCurve(crv)=%s, crv=%x", acadErrorStatusText(es), pGeCurve);
		return;
	}

	double offsetdist = 100.0;
	AcGeVoidPointerArray arr;
	pGeCurve->getTrimmedOffset(offsetdist, AcGeVector3d::kZAxis, arr, AcGe::kExtend);

	delete pGeCurve;
	pGeCurve = NULL;

	AcAxDocLock lock;
	for (int i = 0; i < arr.length(); ++i) {
		AcGeCurve3d* pCurve = (AcGeCurve3d*)arr.at(i);
		if (!pCurve)
			continue;
		AcGe::EntityId type = pCurve->type();
		AcDbCurve* pNewcurve = NULL;
		es = AcDbCurve::createFromAcGeCurve(*pCurve, pNewcurve); 
		if (!es) //TB check es! eInvalidInput is returned for splines!
			delete pCurve;
		else {
			if (type == AcGe::kCompositeCrv3d)  {
				AcGeNurbCurve3d* pFinalNurb = NULL;
				AcGePoint3d ptNurbEnd, ptEnd, ptStart;
				AcGeCompositeCurve3d *ccrv = (AcGeCompositeCurve3d*)pCurve;
				AcGeVoidPointerArray curveList;
				ccrv->getCurveList(curveList);
				for (void* vp : curveList)
				{
					AcGeNurbCurve3d *pNurb = NULL, *pTmpNurb = NULL;
					AcGeCurve3d* crv = (AcGeCurve3d*)vp;
					type = crv->type();
					if (type != AcGe::kNurbCurve3d) {
						double epsilon = AcGeContext::gTol.equalPoint();
						pTmpNurb = pNurb = new AcGeNurbCurve3d(*crv, epsilon);
					}
					else
						pNurb = (AcGeNurbCurve3d*)crv;

					if (!pFinalNurb) {
						pFinalNurb = pNurb;
						if (!pTmpNurb)
							crv = NULL; // don't delete crv!
					}
					else {
						if (pNurb->hasStartPoint(ptStart) && (ptStart==ptNurbEnd)) {
							pFinalNurb->joinWith(*pNurb);
							if (pFinalNurb->hasEndPoint(ptEnd))
								ptNurbEnd = ptEnd;
						}
					}
					if (pFinalNurb->hasEndPoint(ptEnd))
						ptNurbEnd = ptEnd;

					if (crv)
						delete crv;
				}
				if (pFinalNurb) {
					AcDbCurve* segment=NULL;
					es = AcDbCurve::createFromAcGeCurve(*pFinalNurb, pNewcurve);
					delete pFinalNurb;
				}
			}
		}

		if (pNewcurve)	{
			AcDbDatabase* pdb = acdbHostApplicationServices()->workingDatabase();
			pNewcurve->setDatabaseDefaults(pdb);
			pNewcurve->setColorIndex(1); {
				// append to database
				AcDbObjectId curid = pdb->currentSpaceId();

				AcDbBlockTableRecordPointer pbtr(curid, AcDb::kForWrite);
				pbtr.openStatus();
				AcDbObjectId newid;
				pbtr->appendAcDbEntity(newid, pNewcurve);
			}
			pNewcurve->close();
		}
	}
}

 

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 3 of 5
tbrammer
in reply to: chunyuran

I played a bit with the function using epsilon=0.1 which reduces the number of control points. But the resulting spline causes a crash in AcDbCurve::createFromAcGeCurve(*pCurve, pNewcurve) if I try to apply an offset to it.

This looks like a bug in AutoCAD. The drawing I used is attached. I started with the black spline. With epsilon=0.1  the function created the red spline. This in turn caused a crash. Everything seems to be fine with the red spline.


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

Message 4 of 5
chunyuran
in reply to: tbrammer

Thanks for your reply, tbrammer. Your code is very enlightened to me.

 

I tested on some random drawed spline in AutoCAD 2020. The first "AcDbCurve::createFromAcGeCurve" just crashed, not return anything like eInvalidInput.
Another thing in my case is that the type of AcGeCurve3d after "getTrimmedOffset" is always kOffsetCurve3d, and constructing a AcGeNurbCurve3d from AcGeOffsetCurve3d crashed also.

 

I'll try it again with a higher AutoCAD version.

Message 5 of 5
tbrammer
in reply to: chunyuran

That's exactly what I found in my tests with AutoCAD 2022. But I haven't tested with 2023.

I suppose there is a severe bug with spline offset curves. Autodesk engineers should have a look at this.

 
 

 

 


Thomas Brammer ● Software Developer ● imos AGLinkedIn
If an answer solves your problem please [ACCEPT SOLUTION]. Otherwise explain why not.

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report