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

Quick Show Area Tool

15 REPLIES 15
Reply
Message 1 of 16
Kyudos
2601 Views, 15 Replies

Quick Show Area Tool

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?

15 REPLIES 15
Message 2 of 16
Kyudos
in reply to: Kyudos

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?
Message 3 of 16
Kyudos
in reply to: Kyudos

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

Message 4 of 16
Kyudos
in reply to: Kyudos

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

Message 5 of 16
Anonymous
in reply to: Kyudos

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

Message 6 of 16
Kyudos
in reply to: Anonymous

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) 

Message 7 of 16
Anonymous
in reply to: Kyudos

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.-

Message 8 of 16
Kyudos
in reply to: Anonymous

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.

Message 9 of 16
Anonymous
in reply to: Kyudos

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();
				}
			}
		}
	}

 

 

Message 10 of 16
Anonymous
in reply to: Kyudos

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

 

HTH

Message 11 of 16
Kyudos
in reply to: Anonymous

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

Message 12 of 16
Anonymous
in reply to: Kyudos

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!

 

Message 13 of 16
Kyudos
in reply to: Anonymous

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.  

Message 14 of 16
Kyudos
in reply to: Kyudos

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).

Message 15 of 16
moogalm
in reply to: Kyudos

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.

Message 16 of 16
Kyudos
in reply to: moogalm

@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).

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

Post to forums  

Forma Design Contest


AutoCAD Beta