Fastes way to triangulate a scene

Fastes way to triangulate a scene

Anonymous
Not applicable
2,652 Views
8 Replies
Message 1 of 9

Fastes way to triangulate a scene

Anonymous
Not applicable

Hello,

I have a scene in autocad, composed mostly from triangles.

I want to export all triangles from autocad structures very fast for further processing.

I use this api which is very, slow when i have around 300 000 triangles, which is not much.

Moreover if i start to process independent calls to this on several cores i get crashes.

Please advise. Thank you

 

// conditionally set the mesh controls based on surface type
AcBrMesh2dControl meshCtrl;
meshCtrl.setElementShape(AcBr::kAllTriangles);

// make the mesh filter from the topology entity and the mesh controls
const AcBrEntity* meshEnt = (AcBrEntity*)&face;
AcBrMesh2dFilter meshFilter;
meshFilter.insert(make_pair(meshEnt, (const AcBrMesh2dControl)meshCtrl));

// generate the mesh, display any errors and attempt to dump all
// generated elements (most errors are not fatal so we want to do
// the best we can with whatever subset of the face was meshed).
AcBrMesh2d faceMesh;
if(faceMesh.generate(meshFilter) != eOk)
return false;

// traverse elements (triangles)
TVectorN<D3, 3> aPt;
AcBrMesh2dElement2dTraverser meshElemTrav;
meshElemTrav.setMesh(faceMesh);
for(; !meshElemTrav.done(); meshElemTrav.next())
{
// traverse nodes (points)
AcBrElement2dNodeTraverser elemNodeTrav;
elemNodeTrav.setElement(meshElemTrav);
aPt.setSize(0);
for(; !elemNodeTrav.done(); elemNodeTrav.next())
{
AcBrNode node;
elemNodeTrav.getNode(node);
AcGePoint3d p;
node.getPoint(p);
aPt.add().setValue(p.x, p.y, p.z);
}

//add triangle here
addTr(mesh, aPt[0], aPt[1], aPt[2]);
}

0 Likes
Accepted solutions (2)
2,653 Views
8 Replies
Replies (8)
Message 2 of 9

tbrammer
Advisor
Advisor
Accepted solution

@Anonymous wrote:

I have a scene in autocad, composed mostly from triangles.

I want to export all triangles from autocad structures very fast for further processing.


The AcBr classes serve for topolgy analysis. If you are not interested in the topology or the objects than this isn't the first choice for performant triangle extraction.

 

Do you know which entity classes appear in the drawings you have to process? If you have meshes it might be the best way to access the mesh data directly from the entity.

 

For solids and faces you can use

 

 

Acad::ErrorStatus acdbGetObjectMesh(
    AcDbObject * pObj, 
    const AcDbFaceterSettings * faceter, 
    AcGePoint3dArray& vertexArray, 
    AcArray<Adesk::Int32>& faceArray, 
    AcGiFaceData*& faceData
);

 

 

 

If you need a general purpose approach that works for all types of entities there are these two ways:

 

1. The "Entity To Faces" API

 

int acreRegisterCallout(AcReCallout *imp);
Acad::ErrorStatus acreEntityToFaces(ads_name ss, ACHAR** const name, int normal);

 

To use it, you have to derive a class from AcReCallout, and pass a pointer to an instance to acRegisterCallout(&myCallout).  Than call acreEntityToFaces(ss,,) with a selection set ss.

This will call your virtual methods of AcReCallout with giving you vertex and mesh data of the geometry.

 

2. Using worldDraw() with custom AcGiWorldDraw / AcGiWorldGeometry classes

This is a bunch of work, but it is the most flexible solution.

Each entity class within AutoCAD implements worldDraw(AcGiWorldDraw *wd) to draw itself with graphic primitives into an AcGiWorldGeometry like mesh() and shell().  You have to implement your own AcGiWorldGeometry class that extract the geometry of the meshes and shells.

 


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

0 Likes
Message 3 of 9

Anonymous
Not applicable

And these methods will be safe for reading only from many threads?

With the method, that i have posted above, we had random crashes.

Thanks

0 Likes
Message 4 of 9

tbrammer
Advisor
Advisor

@Anonymous wrote:

And these methods will be safe for reading only from many threads?

With the method, that i have posted above, we had random crashes.

Thanks


No. ObjectARX is generally not thread safe. You can't use the ObjectARX API in multiple threads.

 

You might try to do parallel processing by using N instances of the AutoCAD Core Console (ACC,  accoreconsole.exe in the AutoCAD installation directory). But this would involve loading the drawing into each instance of the ACC which might make the approach pointless for big DWGs. Maybe you can load the DWG first, split it into N smaller DWGs and let these be processed by N ACCs.

 

 


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

0 Likes
Message 5 of 9

Anonymous
Not applicable

Thank you for your answer

Where I can file a feature request about making object arx safe for concurrent reading ?

I expect if i open an object for reading and another one for reading the api should not produce side effects.

Synchronization is not needed at all.

I do not need to modify anything into the autocad during traversal and i need the autocad api to apis that make side effects.

 

Splitting the dwg file does not make sense. I have large buildings, may be a quarter of a small town there and i fire rays.

 

So far i think independent triangulation for solids with the tessellator works sort of fine from many threads. I did not get any crashes in autocad 2021.

 

0 Likes
Message 6 of 9

tbrammer
Advisor
Advisor

See ObjectARX docs:

 

Autodesk ObjectARX for AutoCAD 2020: Interoperability Guide

-> ObjectARX Programming Practices

  -> Avoid Multithreading:

 

ObjectARX is not thread-safe and multithreading is not supported. Many APIs called from externally created threads will cause unexpected results or terminate AutoCAD. APIs that perform user interface functions (for example, acutPrintf()) are particularly problematic and should never be called from an external thread. If threading is absolutely required, use proper synchronization techniques to avoid unnecessary CPU utilization and potential conflicts between shared resources.

 

Using other threads than the main thread for ObjectARX API calls is definitely a risk - even for readonly access.

May I remind you of your own statement:


@Anonymous wrote:
With the method, that i have posted above, we had random crashes.

I would suppose that the AcBr* methods are "readonly" too.


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

0 Likes
Message 7 of 9

Anonymous
Not applicable

Thank you very much, I understand this.

Where i can file a request to autodesk so this is changed in the next version of autocad.

This software is not set in stone.

Is there are a place for feature requests?

All the best

 

0 Likes
Message 8 of 9

tbrammer
Advisor
Advisor
Accepted solution

You could try to post in one of the "Ideas" forums.

Or on the AUGI wish list.

Or on the Autodesk product feedback site.

If you are ADN member you can directly contact the developer support and maybe raise a "Business Case".

 

But frankly speaking I would not set much hope in waiting for an AutoCAD release with thread-save ObjectARX.

I would recomment to develop a speed optimized single thread solution for data extraction.

Your "ray fire algorithm" still may use multithreading to process your data as long as it doesn't use the ObjectARX API.

 


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

0 Likes
Message 9 of 9

Anonymous
Not applicable

Thank you. I have accepted your solution. It will do the job.

About my timings.

I have around 2 000 000 triangles.

Extracting from Autocad takes 330 seconds, firing rays with RTX on 1070 GPU card and doing the results takes 60 seconds.

So extraction dominates.

 

 

0 Likes