Creating SubDMesh

Creating SubDMesh

Anonymous
Not applicable
2,922 Views
6 Replies
Message 1 of 7

Creating SubDMesh

Anonymous
Not applicable

Hello,

 

I've got some code (c#) which allows the user to select a block, and then will explode the block into a collection of points (held in a 3dpointcollection called 'pts'). It will then transform the points such that they are positioned at each vertex of a polyline (denoted 'poly') and also orientated to face along the next segment of the polyline (hopefully you are still with me, the screenshot below should explain a bit better).

 

cad temp.JPG

 

 

All the individual points are stored in a 3dpointcollection called 'MeshPts'. I now want to connect the points in a SubDMesh. I have had a look at Kean's demonstration and have come up with the following, however it doesn't display anything on screen.

 

 			int ep = Convert.ToInt32(poly.EndParam);

                         int[] ptr1 = new int[(pts.Count) * 2 + 1];
                         int[] ptr2 = new int[(pts.Count) * 2 + 1];
                         int[] ptr3 = new int[(pts.Count) * 2 + 1];

                         Int32Collection facearray = new Int32Collection();

                         for (int i = 0; i < ntri; i++)
                         {

                             facearray.Add(3);
                             facearray.Add(ptr1[i]);
                             facearray.Add(ptr2[i]);
                             facearray.Add(ptr3[i]);

                         }


                         SubDMesh sdm = new SubDMesh();

                         sdm.SetDatabaseDefaults();

                         sdm.SetSubDMesh(meshPts, facearray, 0);

                         btr.AppendEntity(sdm);

                         tr.AddNewlyCreatedDBObject(sdm, true);

 

I'm sort of running blind at the minute as I don't have any experience with meshes, only a very short time spent working with solid3d objects.

 

Please let me know if anything needs clarifying.

 

 

 

Full code so far is here:

 

 Point3dCollection polyPts = new Point3dCollection();
                            Polyline3d poly = tr.GetObject(psr1.ObjectId, OpenMode.ForRead) as Polyline3d;
                     
                            int ep = Convert.ToInt32(poly.EndParam);
                                                       
                            for (int q = 0; q <= ep; q++) //Open foreach to iterate through the 3D polyline
                            {
                                if(q != poly.EndParam)
                                {   Point3d pt1 = poly.GetPointAtParameter(q);
                                    int a = q + 1;
                                    Vector3d vec1 = pt1.GetVectorTo(poly.GetPointAtParameter(a));
                                    double angle = Vector3d.XAxis.GetAngleTo(vec1, Vector3d.ZAxis);
                                    
                                foreach (Point3d r in pts)
                                {
                                    Point3d t = new Point3d();
                                    Vector3d pt1Vec = pt1.GetAsVector();
                                    Vector3d insVec = ins.GetAsVector();
                                    Matrix3d rot = Matrix3d.Rotation(angle, zAz, pt1);
                                    t = r.Add(pt1Vec).Subtract(insVec);
                                    Point3d g = t.TransformBy(rot);
                                    meshPts.Add(g);

                                } //Close foreach
                                }
                               
                                                        
                            } //close for
                           


                         foreach (Point3d y in meshPts)
                    {
                        DBPoint b = new DBPoint(y);
                        btr.AppendEntity(b);
                        tr.AddNewlyCreatedDBObject(b, true);
                    
                         
                    }
                       
                         int[] ptr1 = new int[(pts.Count) * 2 + 1];
                         int[] ptr2 = new int[(pts.Count) * 2 + 1];
                         int[] ptr3 = new int[(pts.Count) * 2 + 1];

                         Int32Collection facearray = new Int32Collection();

                         for (int i = 0; i < ep; i++)
                         {

                             facearray.Add(3);
                             facearray.Add(ptr1[i]);
                             facearray.Add(ptr2[i]);
                             facearray.Add(ptr3[i]);

                         }


                         SubDMesh sdm = new SubDMesh();

                         sdm.SetDatabaseDefaults();

                         sdm.SetSubDMesh(meshPts, facearray, 0);

                         btr.AppendEntity(sdm);

                         tr.AddNewlyCreatedDBObject(sdm, true);






0 Likes
Accepted solutions (1)
2,923 Views
6 Replies
Replies (6)
Message 2 of 7

cgcamilo
Enthusiast
Enthusiast
Accepted solution

Hello,

 

By looking at the code provided it seems that you have an issue when filling "facearray". This is the error:

 

 

int[] ptr1 = new int[(pts.Count) * 2 + 1];
int[] ptr2 = new int[(pts.Count) * 2 + 1];
int[] ptr3 = new int[(pts.Count) * 2 + 1];

Int32Collection facearray = new Int32Collection();

for (int i = 0; i < ep; i++)
{

 facearray.Add(3);
 facearray.Add(ptr1[i]);
 facearray.Add(ptr2[i]);
 facearray.Add(ptr3[i]);

}

 

ptr1, ptr2 and ptr3 have no information. What you have to provide here is, for each triangle each vertex. And the vertex are indexes of the array of points.

 

For example. If you have a 3 points ( p1 = {0,0,0}, p2 = {1,0,0}, p3 = {0,1,0}
The facearray should be 

 

meshPts.add(p1);
meshPts.add(p2);
meshPts.add(p3);

facearray.add(3); <- number of points
facearray.add(0); <- first point (p1)
facearray.add(1); <- second point (p2)
facearray.add(2); <- third point (p3)

 

In your case you can try something like this:

for (int i = 0; i < pts.Count - 2; i++)
{

 facearray.Add(3);
 facearray.Add(0);
 facearray.Add(i+1);
 facearray.Add(i+2);

}

Hope it helps

Camilo Cifuentes
Message 3 of 7

JamesMaeding
Advisor
Advisor

Part of the trick with subd meshes is you have to first know the faces you want to make.

Then extract the verticies and keep them in a list.

Then you loop through the faces, and record what verticies occurred at each triangle vertex.

Then you can add the points to the subdmesh, and add faces which are lists of (integer) indicies.

 

I have done this extensively and it works for lots of faces, but best to keep down to 20,000 faces for each subdmesh for speed!


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

0 Likes
Message 4 of 7

Anonymous
Not applicable

Thanks very much, both, for your replies.

 

I think I now understand the concept behind the triangulation. Although I now need to devise a way of creating the triangles, as I think one of the points in each triangle will have to be at the next node along the polyline as per the drawing below.

 

In any case, I think I should be able to create something that works. If not, I'll have to go back to the drawing board.

 

Cheers guys.

 

0 Likes
Message 5 of 7

JamesMaeding
Advisor
Advisor

note that Ceometric.com sells .net libraries for efficient delunay triangulation of points.

Its not as fast as Civil3d for millions of points, but you would not care about that.

There are several non-optimized delunay triangulation sets of code hanging around that you could use for free.

Your challenge is to split up the points into sets for each pline seg, let's call those "walls".

You would take each wall, lay it down, and run the triangulation to get tris for that wall, then stand back up.

Then do remaining walls....

This is because the triangulation routines are not "3d", they are actually 2d, but keep the z values for the points.

The tris look the same from the top...

I have done this for a few things relating to 3d printing.

thx


internal protected virtual unsafe Human() : mostlyHarmless
I'm just here for the Shelties

Message 6 of 7

_gile
Consultant
Consultant

Hi,

 

You should have a look at this topic from Kean Walmsley blog.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 7 of 7

Anonymous
Not applicable

Thanks for the link. I've had a look through and tried to apply Kean's code but it produced a random set of faces and so the mesh didn't make much sense. In any case, I think I have found a way to do it now (in theory) so I will have a go at that.

0 Likes