How to use AcDbSurface::trimSurface() ?

How to use AcDbSurface::trimSurface() ?

Anonymous
Not applicable
1,256 Views
4 Replies
Message 1 of 5

How to use AcDbSurface::trimSurface() ?

Anonymous
Not applicable

Hi there,

 

I have a surface and set of curves on this surface. Below there is a code snippet where I try to trim surface with these curves. It doesn't work:

 

 

    AcDbObjectIdArray toolCurveIds;
    AcArray<AcGeVector3d> projVectors;
    for(int i = 0; i < trimCurveSet().GetSize(); ++i)
    {
        ...
	if(pCurve)
	{
	    AcDbObjectId curveId;
	    AcGeVector3d projVector;
	    if(m_pBtr->appendAcDbEntity(curveId, pEnt) == Acad::eOk)
	    {
		toolCurveIds.append(curveId);
		projVector = AcGeVector3d::kZAxis;
		projVectors.append(projVector);
		pEnt->close();
	    }
	    else delete pEnt;
	}
    }

    if(toolCurveIds.length())
    {
	AcDbObjectId surfaceId;
	if(m_pBtr->appendAcDbEntity(surfaceId, pSrf) == Acad::eOk)
	{
	    AcDbObjectIdArray toolIds;
	    AcGePoint3d pickPoint;
	    AcGeVector3d viewVector = AcGeVector3d::kZAxis;
	    bool bAutoExtend = false;
	    bool bAssociativeEnabled = false;

	    AcDbSurface::trimSurface(surfaceId, toolIds, toolCurveIds, projVectors, pickPoint, viewVector, bAutoExtend, bAssociativeEnabled);
	}
    }

 

I try to use AcDbSurface::trimSurface() but this method has a too short help information. I think that I use trimSurface() with wrong input data.

 

How to trim surface correctly? Working code examples are welcome.

 

Bayar

0 Likes
Accepted solutions (1)
1,257 Views
4 Replies
Replies (4)
Message 2 of 5

tbrammer
Advisor
Advisor
Accepted solution

Below some working sample code. I tried it with the attached TrimSurf.dwg.

Register void cmdTrim() as a command, load TrimSurf.dwg, select the cone when prompted to select a surface and the red circle or/and the blue pline when prompted to select trimming entities. The area around the point where you picked the surface will be removed.

This sample uses the current view direction as projection direction for all trimcurves.

 

 

static long ssetToObjIdArray(ads_name sset, AcDbObjectIdArray &objIdArr);

void cmdTrim()
{
	ads_point    pt;
	ads_name     ent;
	AcDbObjectId blankSurfaceId; //Original input surface to be trimmed.

	if (acedEntSel(_T("\nSelect surface: "), ent, pt) != RTNORM)
		return;

	if (acdbGetObjectId(blankSurfaceId, ent) != Acad::eOk) //ads_name-->AcDbObjectId
		return;

	// Is it a surface?
	Acad::ErrorStatus es;
	AcDbSurface *pSurf = 0;
	if ((es = acdbOpenObject(pSurf, blankSurfaceId, AcDb::kForRead)) == Acad::eOk)
	{
		pSurf->close(); // yep
	}
	else
	{
		acutPrintf(L"\nNot a surface.");
		return;
	}

	// transform pt from UCS to WCS 
	ads_point ptWcs, zAxis = { 0.0, 0.0, 1.0 }, vView;
	acdbUcs2Wcs(pt, ptWcs, Adesk::kFalse); 
	
	// calculate the current viewing direction
	struct resbuf wcs, dcs;
	wcs.restype = RTSHORT; wcs.resval.rint = 0;
	dcs.restype = RTSHORT; dcs.resval.rint = 2;
	acedTrans(zAxis, &dcs, &wcs, 1, vView);
	AcGeVector3d vViewDir(vView[X], vView[Y], vView[Z]);


	//AcDbObjectId  blankSurfaceId		//Original input surface to be trimmed.

	AcDbObjectIdArray toolIds;			//array of ids of cutting entities that their bodies will be directly 
										//used to trim the surface without further treatment such as projection.

	AcDbObjectIdArray toolCurveIds;		//array of ids of cutting curves that will be used to trim the surface 
										// by first projecting them to the surface

	AcArray<AcGeVector3d> projVectors;	//array of projection direction of each cutting curve in toolCurveIds, 
										//so the length of projVectors should be equal to the length of toolCurveIds

	AcGePoint3d pickPoint(ptWcs[X], ptWcs[Y], ptWcs[Z]);	//pick point that is used to specify which area of a surface should be trimmed.

	AcGeVector3d viewVector(vViewDir);	//when using pick point to find out which area to trim, caller should 
										//also specify the view direction which will be used form a ray starting 
										//from the pick point in the view direction and see which area is hit by the ray first.

	bool bAutoExtend = false;			//If this option is set then when a tool body consists of a single face 
										//with analytic geometry, the underlying geometry will be extended as 
										//much as possible to make sure the surface is trimmed.The tool body 
										//supplied will not be modified.

	bool bAssociativeEnabled = false;	//Specifies whether the surface trimming operation should be associative.

	// Select the trim-entities
	ads_name           sset = { 0,0 }; // The selectionset

	acutPrintf(_T("\nSelect trimming entities: "));
	if (acedSSGet(NULL, NULL, NULL, NULL, sset) == RTNORM)
	{
		ssetToObjIdArray(sset, toolCurveIds);
		// leave toolIds empty for this example. 
		acedSSFree(sset);
	}

	// Use Viewdir as projection direction
	int i, nCountTrimCurves = toolCurveIds.length();
	projVectors.setLogicalLength(nCountTrimCurves);
	for (i = 0; i < nCountTrimCurves; ++i)
		projVectors[i] = viewVector;
		
	bAutoExtend = false;
	bAssociativeEnabled = false;

	// Let's go:
	es = AcDbSurface::trimSurface(blankSurfaceId, toolIds, toolCurveIds, projVectors, pickPoint, viewVector, bAutoExtend, bAssociativeEnabled);
}

static long ssetToObjIdArray(ads_name sset, AcDbObjectIdArray &objIdArr)
{
	long selSetLen = 0, i;
	if (acedSSLength(sset, &selSetLen) != RTNORM)
		return -1;

	ads_name ename;
	AcDbObjectId objId;

	for (i = 0; i<selSetLen; i++)	  // Für alle Entities im Selection-Set 
	{
		if (acedSSName(sset, i, ename) == RTNORM)
		{
			if (acdbGetObjectId(objId, ename) == Acad::eOk)
				objIdArr.append(objId);
		}
	}
	return selSetLen;
}

 


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

Message 3 of 5

Anonymous
Not applicable

Thanks for response tbrammer!

 

I didn't know that surface should be close before trimming. Now my application be able to trim surface.  Need only describe properly input parameters for trimSurface(). So I use RealDWG, pick point, projecting / viewing vectors should be compute programmatically for each curve. Thanks again!

 

0 Likes
Message 4 of 5

tbrammer
Advisor
Advisor

Glad to hear that Smiley Happy.

 

 > I didn't know that surface should be close before trimming.

Whenever you call an ARX API function with the AcDbObjectId of the object to be modified you should close the object before. This is required because AutoCAD will try open it kForWrite itself. This will fails, if the object is still opened for you.

 

Please choose "accept as solution" for replies that solve your issues! Kudos are welcome as well Smiley Wink


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

0 Likes
Message 5 of 5

475867377
Advocate
Advocate

hi ,thank you for your help.i want to know how to convert the AcDbPolygonMesh to acdbsurface?like the command "meshsmooth".

0 Likes