Anyone worked with getCylinderAt API for point cloud pipe detection?

Anyone worked with getCylinderAt API for point cloud pipe detection?

hritikpawar16112000
Contributor Contributor
648 Views
5 Replies
Message 1 of 6

Anyone worked with getCylinderAt API for point cloud pipe detection?

hritikpawar16112000
Contributor
Contributor

Hi everyone,

I’m currently exploring the following API:


Acad::ErrorStatus getCylinderAt(
const AcGeMatrix3d& viewXform,
const AcGePoint3d& pickPt,
AcGePoint3d& origin,
AcGeVector3d& axis,
double& height,
double& radius
);

 

I wanted to know if anyone has worked with this function before.
Does this API return correct pipe geometry parameters (like radius, height, and axis direction) when the user clicks on a pipe region in a point cloud (RCP/RCS)?

I’m trying to detect cylindrical pipes from a point cloud by clicking on them — and would like to confirm whether this API reliably provides the cylinder parameters (radius, height, and axis) for that picked point.

Any examples or usage experience would be appreciated.
Thanks in advance!

0 Likes
649 Views
5 Replies
Replies (5)
Message 2 of 6

h_eger
Mentor
Mentor

What you want to do is what Faro already delivers

-

If my reply was helpful, please give a "Kudo" or click the "Accept as Solution" button below (or both).

Hartmut Eger
Senior Engineer
Anlagenplanung + Elektotechnik
XING | LinkedIn

EESignature



Message 3 of 6

hritikpawar16112000
Contributor
Contributor

i want to detect Pipe from RCP point and create Pipe

0 Likes
Message 4 of 6

tilo_pfliegner
Enthusiast
Enthusiast

In addition to what @h_eger said, the API you mention relies on pre-calculated cylinder primitives that are being created during the import process in ReCap. To my knowledge this has some restrictions, e.g. it only happens for structured laser scanning data.




Tilo Pfliegner
Message 5 of 6

hritikpawar16112000
Contributor
Contributor

Can anyone tell me how to correctly get the viewXform (view transformation matrix) in ObjectARX?

0 Likes
Message 6 of 6

hritikpawar16112000
Contributor
Contributor


#include "aced.h"
#include "dbents.h"
#include "dbapserv.h"
#include "acdocman.h"
#include "geassign.h"
#include "gemat3d.h"
#include "adslib.h"
#include "tchar.h"

// --- Helper: Build WCS → DCS view matrix ---
AcGeMatrix3d getCurrentViewTransform()
{
struct resbuf rbViewDir, rbTarget;
acedGetVar(_T("VIEWDIR"), &rbViewDir);
acedGetVar(_T("TARGET"), &rbTarget);

AcGeVector3d viewDir(
rbViewDir.resval.rpoint[X],
rbViewDir.resval.rpoint[Y],
rbViewDir.resval.rpoint[Z]);
AcGePoint3d target(
rbTarget.resval.rpoint[X],
rbTarget.resval.rpoint[Y],
rbTarget.resval.rpoint[Z]);

viewDir.normalize();

// Define up vector (Z-up by default)
AcGeVector3d up(0, 0, 1);
if (viewDir.isParallelTo(up))
up = AcGeVector3d(0, 1, 0);

AcGeVector3d xAxis = up.crossProduct(viewDir).normal();
AcGeVector3d yAxis = viewDir.crossProduct(xAxis).normal();

AcGeMatrix3d viewXform;
viewXform.setToIdentity();
viewXform.setCoordSystem(target, xAxis, yAxis, viewDir);

return viewXform;
}

// --- Main Command ---
void cmdGetCylinder()
{
acutPrintf(_T("\n🔍 Running GETCYLINDER command..."));

// 1️⃣ Ask user to select a Point Cloud
ads_name ename;
ads_point pickPt;
if (acedEntSel(_T("\nSelect Point Cloud: "), ename, pickPt) != RTNORM)
{
acutPrintf(_T("\n⚠️ Selection cancelled."));
return;
}

AcDbObjectId objId;
if (acdbGetObjectId(objId, ename) != Acad::eOk)
{
acutPrintf(_T("\n Failed to get object ID."));
return;
}

AcDbPointCloudEx* pCloud = nullptr;
if (acdbOpenObject(pCloud, objId, AcDb::kForRead) != Acad::eOk || !pCloud)
{
acutPrintf(_T("\n Could not open Point Cloud entity."));
return;
}

// 2️⃣ Get view transform (WCS → DCS)
AcGeMatrix3d viewXform = getCurrentViewTransform();

// 3️⃣ Ask user to click a point on screen
ads_point userPick;
if (acedGetPoint(nullptr, _T("\nPick a point on the cloud: "), userPick) != RTNORM)
{
acutPrintf(_T("\n⚠️ Pick cancelled."));
pCloud->close();
return;
}
AcGePoint3d pickPt3d(userPick[X], userPick[Y], userPick[Z]);

// 4️⃣ Detect Cylinder
AcGePoint3d origin;
AcGeVector3d axis;
double height = 0.0, radius = 0.0;

Acad::ErrorStatus es = pCloud->getCylinderAt(viewXform, pickPt3d, origin, axis, height, radius);

if (es == Acad::eOk)
{
acutPrintf(_T("\n Cylinder Detected!"));
acutPrintf(_T("\nOrigin: (%.3f, %.3f, %.3f)"), origin.x, origin.y, origin.z);
acutPrintf(_T("\nAxis: (%.3f, %.3f, %.3f)"), axis.x, axis.y, axis.z);
acutPrintf(_T("\nHeight: %.3f"), height);
acutPrintf(_T("\nRadius: %.3f"), radius);
}
else
{
acutPrintf(_T("\n⚠️ No cylinder found or API returned error (%d)."), es);
}

pCloud->close();
}

// --- Register Command ---
void initApp()
{
acedRegCmds->addCommand(_T("POINTCLOUD_CMDS"),
_T("GETCYLINDER"),
_T("GETCYLINDER"),
ACRX_CMD_MODAL,
cmdGetCylinder);
}

void unloadApp()
{
acedRegCmds->removeGroup(_T("POINTCLOUD_CMDS"));
}

extern "C" AcRx::AppRetCode acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)
{
switch (msg)
{
case AcRx::kInitAppMsg:
acrxDynamicLinker->unlockApplication(pkt);
acrxRegisterAppMDIAware(pkt);
initApp();
break;
case AcRx::kUnloadAppMsg:
unloadApp();
break;
}
return AcRx::kRetOK;
}

--------------------------------------------------------------------------------------------------------------------------
when i click on RCP points pipe (not real pipe it is point cloud pipe ) output from getCylinderAt  ePointNotOnEntity.