Quick Show Area Tool

Quick Show Area Tool

Kyudos
Advisor Advisor
4,528 Views
15 Replies
Message 1 of 16

Quick Show Area Tool

Kyudos
Advisor
Advisor

On a different platform, I created a "Show Area" tool that takes a point input, finds the boundaries around it, creates a temporary hatch, gets the area from that hatch and displays it for the user (deleting the hatch afterwards).

 

I can see that I could perhaps use HATCH or BOUNDARY, and they will give me the areas I want. So to quickly display the area of any enclosed space, I could use a similar approach to avoid 'polluting' the drawing with random hatches or polylines (i.e., use them to get the area then delete them).

 

Just to be sure I'm not missing a trick though - is there a better approach?

4,529 Views
15 Replies
Replies (15)
Message 2 of 16

Kyudos
Advisor
Advisor

Aha!  acedTraceBoundary!

 

However, from the docs:

 

resultingBoundarySet Contains the resulting boundary in form of AcDbPolyline* objects, if the operation is completed
sucessfully. When called with detectIslands set to false, the array contains only one entry, representing the outer
boundary. When called with detectIslands set to true, the array can contain multiple AcDbPolyline* entries. In this
case, the first entry is the outermost boundary, and the succeeding entries represent the islands found. 
 
This doesn't appear to be the case - the outer boundary always seems to be the last in the array. Is this reliable?
I want to subtract the island area(s) from the total. Can I rely on the outer area always being last, or should I find the largest area and subtract the rest?
0 Likes
Message 3 of 16

Kyudos
Advisor
Advisor

...and further it seems acedTraceBoundary ignores splines (but BOUNDARY doesn't?)

0 Likes
Message 4 of 16

Kyudos
Advisor
Advisor

So this very nearly does what I want - but can acedTraceBoundary be made to recognise splines? How does BOUNDARY do it?

0 Likes
Message 5 of 16

Anonymous
Not applicable

BPOLY or -BOUNDARY can return Polyline or Region types.

 

For the closed areas made of Spline, it returns a Region, you might need to convert Spline to Polyline.

 

HTH

0 Likes
Message 6 of 16

Kyudos
Advisor
Advisor

As I said earlier in the thread - I know how BOUNDARY works, but I'm trying to automate it. I could send command options to -BOUNDARY, but the region thing requires an extra response to accept, making the automation tricky. I would then have to find the just-added boundary, get it's area then remove the extraneous entity(s).

 

acedTraceBoundary appears to be as near an API equivalent of the BOUNDARY command as exists, but doesn't work the same way (i.e., it doesn't recognise splines).

 

What I'm asking (the AutoDesk guys, I guess) - is there a simple API method of replicating the initial function of BOUNDARY? (that is, the part that finds the boundary, including splines - I don't actually need (or want) to create the polys or regions) 

0 Likes
Message 7 of 16

Anonymous
Not applicable

I do not post here that often, so did not elaborate at all on my previous post.

 

I just had the time to do a test, using C# (have been a long time that do not use ARX), anyway.

 

TraceBoundary works for me on enclosed areas that include Splines, so on an example made with lines, that form an U shape on one of the ends the edge it is a spline, and inside for islands a rectangle and a circle.

 

If I use TraceBoundary, after the internal point, and true for island detection, returns 3 items, I just go and loop into each of these objects, returns a Region and two Polylines.

 

For the Region, I use Brep (AcBrBrep) and extract the area with brep.GetSurfaceArea().

For the other two Polylines, I convert them to Curve, then check if are curve.Closed, then I extract their area with curve.Area.

 

I can do this without adding to the database any of the items.

 

Also, to me the larger area will be the outer one, any other one returned will be islands, or maybe you can test if the internal point is not inside of any of these islands, but guess it is overhead.

 

HTH.-

0 Likes
Message 8 of 16

Kyudos
Advisor
Advisor

Interesting - that's definitely not the case with CPP ObjectArx. This for example:

 

AcGePoint3d startpt;
acedInitGet(NULL, NULL);
AcArray<int> viewportNumbers;
AcGiTransientManager* pTransientManager = acgiGetTransientManager();
while (acedGetPoint(NULL, _T("\nSelect point in area: "), (double*)(&startpt)) == RTNORM)
{
    bool b = pTransientManager->eraseTransients(kAcGiHighlight, 0, viewportNumbers);
    acedUpdateDisplay();

    AcDbVoidPtrArray Boundaries;
    bool detectIslands = Adesk::kTrue;
    es = acedTraceBoundary(startpt, detectIslands, Boundaries);

    if (es == Acad::eOk)
    {
        double dAreaTotal = 0.0L, dMaxArea = 0.0L, dArea = 0.0L;
        AcDbPolyline* poly = NULL;

        // Subtract the islands
        for (int i = 0; i < Boundaries.length(); i++)
        {
            AcDbEntity *pEnt = static_cast<AcDbEntity *>(Boundaries[i]);
            b = pTransientManager->addTransient(pEnt, kAcGiHighlight, 0, viewportNumbers);
            acedUpdateDisplay();

            poly = (AcDbPolyline*)Boundaries[i];
            es = poly->getArea(dArea);
            dAreaTotal += dArea;

            if (dArea > dMaxArea)
            {
                dMaxArea = dArea;
            }
        }

        acutPrintf(_T(" %.3f"), dMaxArea - (dAreaTotal - dMaxArea));
    }
    acedInitGet(NULL, NULL);
}

bool b = pTransientManager->eraseTransients(kAcGiHighlight, 0, viewportNumbers);

 

Doesn't detect splines, ellipses or elliptical arcs, but is fine with lines, normal arcs and arced polyline segments.

 

So it seems like the interface and the C# function don't use acedTraceBoundary. We are just theorising here, hence the need for some weigh-in from the AutoDesk peeps.

0 Likes
Message 9 of 16

Anonymous
Not applicable

I give it a try also with ARX, I am rusty now, last time was 10+ years ago, but the code below works for me (it is just something in progress), was curios too.

 

Works with a closed area formed with splines, ellipse, and normal lines too, and island entities with circle and rectangle.

	static void MyGroupTest1() {
		AcGePoint3d seedPt;
		acedGetPoint(NULL, ACRX_T("\nSelect internal point: "), asDblArray(seedPt));
		AcDbVoidPtrArray Boundaries;
		bool detectIslands = Adesk::kTrue;
		if (acedTraceBoundary(seedPt, detectIslands, Boundaries) == Acad::eOk) {
			AcDbBlockTableRecordPointer pCurSpace(acdbCurDwg()->currentSpaceId(), AcDb::kForWrite);

			vector<double> areas;

			if (pCurSpace.openStatus() == Acad::eOk) {
				for (int i = 0; i < Boundaries.length(); i++) {
					AcDbCurve *pCurve = static_cast<AcDbCurve *>(Boundaries[i]);

					if (pCurve->isKindOf(AcDbRegion::desc()))
					{
						AcDbRegion *pRegion = static_cast<AcDbRegion *>(Boundaries[i]);;
						AcBrBrep* pBrep = new AcBrBrep();
						if (AcBr::eOk == pBrep->set(*pRegion))
						{
							double area = 0.0f;
							if (AcBr::eOk == pBrep->getSurfaceArea(area))
							{
								areas.push_back(area);
							}
						}
					}
					else
					{
						double polyArea = 0.0f;

						if (Acad::eOk == pCurve->getArea(polyArea))
						{
							areas.push_back(polyArea);
						}
					}
					
					pCurSpace->appendAcDbEntity(pCurve);
					pCurve->close();
				}
			}
		}
	}

 

 

0 Likes
Message 10 of 16

Anonymous
Not applicable

By looking at your code, I think the issue it is the cast to AcDbPolyline, try with AcDbCurve.

 

HTH

0 Likes
Message 11 of 16

Kyudos
Advisor
Advisor

OK - I'm not using that Brep stuff, and it's not recognised by my build environment. Some investigation required!

0 Likes
Message 12 of 16

Anonymous
Not applicable

Try to first use the traceBoundary normally, with the AcDbCurve objects, to double check works by adding the new boundaries (this function will return Polylines and Regions, that's why the use of Brep Api for the region(s)).

 

For Brep, I end up adding these two libs under Linker/Input: acgex22.lib;acbr22.lib - these are under Utils/Brep

 

End up also adding all these includes in the .cpp entrypoint:

#include <brbrep.h>
#include <brbetrav.h>
#include <bredge.h>
#include "brgbl.h"
#include "brvtx.h"
#include "gegbl.h"
#include "brprops.h"
#include "brface.h"
#include "brtrav.h"
#include "brbetrav.h"
#include "rxobject.h"
#include "rxboiler.h"
#include "brbftrav.h"
#include "brbvtrav.h"
#include "brvetrav.h"
#include "brvltrav.h"
#include "brloop.h"
#include "breltrav.h"
#include "brfltrav.h"
#include "brletrav.h"
#include "gesurf.h"
#include <ol_errno.h>
#include <brgbl.h>

 

Just to make it work for me, I know there can be the arx wizard that can allow this: #define _BREP_SUPPORT_

 

HTH!

 

0 Likes
Message 13 of 16

Kyudos
Advisor
Advisor

I must be missing something - I've tried using curves and with BREP support, I just can't get it to recognise splines.

With four lines and a spline:

 

ShowArea.png

 

I only ever get this polyline boundary returned, no regions.  

0 Likes
Message 14 of 16

Kyudos
Advisor
Advisor

I have no idea why this should be the case - but it was the transaction that made the difference. If I don't put my code inside a transaction, it detects the spline and returns regions.

 

Thanks for you input - at least I now have some workable code!

 

EDIT: Well mostly working! I find my transient highlighting (as above) doesn't work / interact with ellipses or elliptical arcs (though the regions involved there still give the correct area).

0 Likes
Message 15 of 16

moogalm
Autodesk Support
Autodesk Support

Hi @Kyudos 

I have gone through the discussion.

Should I understand your question as acedTraceBoundary doesn't work with Ellipses, Elliptical Arcs and Splines?

 

Let me know if you need help on this.

0 Likes
Message 16 of 16

Kyudos
Advisor
Advisor

@moogalm acedTraceBoundary doesn't seem to work with Ellipses, Elliptical Arcs and Splines when used inside a transaction. 

 

If this is intentional (although I can't see why it would be) it should be explained in the documentation.

 

But, otherwise I now have it mostly working well (without a transaction). I am having some issues with the transient highlighting (as in the code above), but I think that might be a separate issue (in which case it probably deserves a seprate topic).

0 Likes