DiscussionsIssue archiveOther usage issues

Archived discussion

Triangulation using C# wrapper by Gerhard Hofmann

Other usage issuesMon, 10/22/2007 - 11:0414 replies

Browse this forum
QuestionAuthor

I try to do triangulation of a box using the C# wrapper provided by Commenter-1. It fails with Access violation. Here is the code:

TopoDS.Shape topoShape = new BRepPrimAPI.MakeBox(200, 40, 40).Shape();
//BRepMesh.General.Mesh(topoShape, 0.1);
TopExp.Explorer ex = new TopExp.Explorer(topoShape, TopAbs.ShapeEnum.FACE, TopAbs.ShapeEnum.SHAPE);

// Loop all faces
while (ex.More())
{
// Triangulate current face
TopoDS.Face F = TopoDS.General.Face(ex.Current());
TopLoc.Location L = new TopLoc.Location();
Poly.Triangulation facing = BRep.Tool.Triangulation(F, L);
if (facing != null)
{
int nbtris = facing.NbTriangles();

-------

It fails on facing.NbTriangles() with exception "Access violation in OpenCascade". What am I doing wrong?

Discussion

14 archived replies

Posts are displayed in their archived order.

01Commenter-1

Hello John,

I checked some old code where I used the triangulation. After the construction of the Poly.Triangulation object I called:
Poly.Array1OfTriangle arrayOfTriangle = triangulation.Triangles();
TColgp.Array1OfPnt p3d = triangulation.Nodes();
I also tried BRepMesh.Discret, which also worked.
Let me know if triangulation.Triangles() works, if not I will try to run your code.
Commenter-1

02Author

Hello Gerhard,

Thank you for your reply. The call to Triangulation seems to work but exception occurs when I try to get count of triangles. The goal is to create 2 lists, one with vertices and one with triangles defined by those vertices (an indexed mesh). I have tried to convert C++ samples found in this forum to your C# wrapper. Complete code below:

------

using System;
using System.Collections.Generic;
using System.Text;

namespace OpenCASCADE
{
class Point3D
{
public double X;
public double Y;
public double Z;
}

class Mesh
{

public static void CreateMesh()
{

// The resulting lists containing vertices and triangle definition by index pointers to vertices
List vertices = new List();
List indecies = new List();

TopoDS.Shape topoShape = new BRepPrimAPI.MakeBox(200, 40, 40).Shape();
//BRepMesh.General.Mesh(topoShape, 0.1);
TopExp.Explorer ex = new TopExp.Explorer(topoShape, TopAbs.ShapeEnum.FACE, TopAbs.ShapeEnum.SHAPE);

// Loop all faces
while (ex.More())
{
// Triangulate current face
TopoDS.Face F = TopoDS.General.Face(ex.Current());
TopLoc.Location L = new TopLoc.Location();
Poly.Triangulation facing = BRep.Tool.Triangulation(F, L);
if (facing != null)
{
int nbtris = facing.NbTriangles();
//Poly.Array1OfTriangle tris = new Poly.Array1OfTriangle(1, nbtris);
Poly.Array1OfTriangle tris = facing.Triangles();
for (int i = 1; i <= nbtris; i++)
{
Poly.Triangle tri = tris.Value(i);
int index0 = 0, index1 = 0, index2 = 0;
tri.Get(ref index0, ref index1, ref index2);
indecies.Add(index0);
indecies.Add(index1);
indecies.Add(index2);
}

int nbnodes = facing.NbNodes();
//TColgp.Array1OfPnt nodes = new TColgp.Array1OfPnt(1, nbnodes);
TColgp.Array1OfPnt nodes = facing.Nodes();
for (int i = 1; i <= nbnodes; i++)
{
gp.Pnt node = nodes.Value(i);
Point3D p = new Point3D();
p.X = node.x;
p.Y = node.y;
p.Z = node.z;
vertices.Add(p);
}
}

ex.Next();
}

}
}

}

-----

The exception is "Access violation in OpenCascade" in the line "int nbtris = facing.NbTriangles();". I think I am using a pointer in the wrong way or something?

03Commenter-1

Hello John,
it is funny, when checking my old code there is never a call to NbTriangles, maybe I had the same problem. It is certainly not a wrong use of a pointer (which is not possible with this interface), it is more likely somethin uninitialized in that class which is only initialized after a call to a method, but I don't know...
So here is the code I used to accomplish the same task as you are trying to implement:

-------------
Poly.Triangulation triangulation = BRep.Tool.Triangulation(face, new TopLoc.Location());
Poly.Array1OfTriangle arrayOfTriangle = triangulation.Triangles();
TColgp.Array1OfPnt p3d = triangulation.Nodes();
points = new GeoPoint3D[p3d.Length()];
for (int i = 0; i < points.Length; ++i)
{
points[i] = p3d.Value(i + 1);
}
if (location != null)
{
gp.Trsf trsf = location.Transformation();
for (int i = 0; i < points.Length; ++i)
{
trsf.Transforms(out points[i].x, out points[i].y, out points[i].z);
}
}
TColgp.Array1OfPnt2d p2d = triangulation.UVNodes();
if (p2d != null)
{
uvpoints = new GeoPoint2D[p2d.Length()];
for (int i = 0; i < uvpoints.Length; ++i)
{
uvpoints[i] = p2d.Value(i + 1);
}
}
else
{
uvpoints = null;
}
triangles = new int[arrayOfTriangle.Length() * 3];
int l = arrayOfTriangle.Length();
for (int i = 0; i < l; ++i)
{
Poly.Triangle t = arrayOfTriangle.Value(i + 1);
triangles[3 * i] = t.Value(1) - 1;
triangles[3 * i + 1] = t.Value(2) - 1;
triangles[3 * i + 2] = t.Value(3) - 1;
}
--------------

Now I implemented the triangulation myself, because I needed more control and multithreading.

Commenter-1

04Commenter-1

... does it work this way ...?

05Author

Gerhard, thank you for your help and fast replies! Actually I did my own C++ DLL which is callable from C# and implemented the code in C++ instead and it worked.

06Commenter-2

I've got the same problem. "p3d.Length()" causes an access violation somewhere inside of the OpenCascade6.2.dll.

I need to use OCC for boolean operations and I have to get the result back to managed code. It Seems that I also have to write my own dll or is there any community code available?

Regards

07Commenter-3

Hi Willy
I have the same objective.

Did you find a solution?
Cheers

08Commenter-4

Hello, Gerhard!

I try your code:

TColgp.Array1OfPnt p3d = triangulation.Nodes();
// points = new GeoPoint3D[p3d.Length()];
gp.Pnt[] points = new gp.Pnt[p3d.Length()];
//(I suppose GeoPoint3D is gp.Pnt, is it?...)

It throws "Access violation" exception in the line:
"points = new gp.Pnt[p3d.Length()];", at the p3d.Length() method...

Looks like Array1Of...(Points or Triangles) class causes this problem... Maybe someone find solution, how to convert Shape to Mesh?

Thanks for your help, Gerhard! ...

09Commenter-1

Hello Artem,

probably triangulation.Nodes() returns an invalid Array1OfPnt. The GeoPoint3D our own class, but that doesn't make a difference. I would expect there is some problem with the face, actually I used this method for a while but it was too less control and not very reliable. So I wrote my own method. Do you always have the access violation when calling p3d.Length() or only in certain circumstances?

Commenter-1

P.S. write me an email when answering in the forum, the notification doesnt work

10Commenter-4

When I manually create and fill Array1OfPnt all works, so you are right, Nodes() returns invalid array. Thanks, I'll search another method

11Commenter-5

I also have this problem.

If the wrapper was open sourced we could find the problem and fix it.

Commenter-5

12Commenter-1

This is not a wrapper problem, try to make the same thing in C++ and you will get the same failure.
The wrapper code is automatically generated, so there would be no help in changing that code...
regards
Commenter-1

13Commenter-6

if anyone still needs it - the solution is to call

BRepMesh.General.Mesh(topoShape, 0.01);

prior to any triangulation

14Commenter-7

thanks a LOT, Pawel!