Hi experts,
I am currently try to get the dgn mesh geometry and export to my system, which is to contruct a triangle mesh file(STL, OpenCTM,,,) but when I get the dgn mesh and write it to other file format, I found there will be
distortion, please see below screen shot, i also attach the code how i get the triangles and the dgn mode i used.
I am using Microstaion CE Update 7, 10.07.00.39.
this is the original model,
V4-2.dgn
and i use below apis to get the triangle mesh: there is only one mesh(PolyfaceHeaderPtr) within the dgn model,
pMesh->m_pMesh->Triangulate(); //pMesh->m_pMesh is a PolyfaceHeaderPtr
auto points = pMesh->m_pMesh->Point(); auto normals = pMesh->m_pMesh->Normal(); auto indexs = pMesh->m_pMesh->PointIndex(); pMesh->m_pointCoordsCount = points.size() * 3; pMesh->m_pointCoords = new double[points.size() * 3]; for (int index = 0; index < points.size(); ++index) { auto adjustPoint= points[index]; pMesh->m_pointCoords[index * 3] = adjustPoint.x; pMesh->m_pointCoords[index * 3 + 1] = adjustPoint.y; pMesh->m_pointCoords[index * 3 + 2] = adjustPoint.z; } pMesh->m_normalCoords = new double[normals.size() * 3]; pMesh->m_normalCoordsCount = normals.size() * 3; for (int index = 0; index < normals.size(); ++index) { pMesh->m_normalCoords[index * 3] = (normals[index].x); pMesh->m_normalCoords[index * 3 + 1] = (normals[index].y); pMesh->m_normalCoords[index * 3 + 2] = (normals[index].z); } size_t triangleCount = indexs.size() / 4; pMesh->m_indexAll = new int[triangleCount * 3]; int realIndex = 0; for (int index = 0; index < indexs.size(); ++index) { auto pointIndex = indexs[index]; if (pointIndex == 0) continue; if (pointIndex < 0) pointIndex = pointIndex * -1; pMesh->m_indexAll[realIndex] = (pointIndex - 1); realIndex++; }
I am not sure the index matrix is correct or not, but it works for most models.
and with above code i am able to get the triangle mesh data which i can save to a STL file, but the STL geometry seems lost some triangles at the edge which lead to the distortion.
the result stl mesh looks as below,
STL mesh no pt offset + normal 0 0 1.dgn
we can see the distortion on the edge, how we can remedy this distortion?
and I also try to export the dgn mesh to a stl file in Microstaion(with export command), and then import the stl file into a new dgn file,
export from Microstation.dgn
and the distortion is much worse.
so is there any way to fix this distortions when i want to get the triangle mesh from a dgn mesh?
by the way, I am using below options for mesh triangulate,
const double tollerance = 0.001; const int arcSegmentCount = 12;
DRange3d rangeBox; m_eh.GetDisplayHandler()->GetBasisRange(m_eh, rangeBox); double boxDistance = rangeBox.DiagonalDistance(); pFacetOptionsPtr->SetChordTolerance(boxDistance * tollerance); pFacetOptionsPtr->SetAngleTolerance(3.1415926 / arcSegmentCount); pFacetOptionsPtr->SetNormalsRequired(1);
Please add the below two lines for triangulation.
pFacetOptionsPtr->SetMaxPerFace(3); //Only apply to type 18/19 elementspFacetOptionsPtr->SetCurvedSurfaceMaxPerFace(3); //Important for SmartSolid
Rick cheng said:I am using Microstaion CE Update 7
That conflicts with the tags you have attached to your post: MicroStation V8i.
Another API you may like to consider is the ElementGraphicsProcessor. It works with all element types and gives you precise control over facet creation.
Regards, Jon Summers LA Solutions
thankk Fu for the reply, I add those two lines, but still get the same result.
is there any way to improve the triangle count to improve the accuracy?
I am currently use that class ElementGraphicsProcessor : public Bentley::DgnPlatform::IElementGraphicsProcessor,
in ElementGraphicsProcessor::_ProcessFacets(PolyfaceQueryCR facets, bool isFilled),
we will do the mesh (PolyfaceHeaderPtr) triangulate with below code:
pMesh->m_pMesh->Triangulate();
auto points = pMesh->m_pMesh->Point(); auto normals = pMesh->m_pMesh->Normal(); auto indexs = pMesh->m_pMesh->PointIndex();
and then i use the triangle points/indexs to export to an STL file, but the exported STL is not accurate, there are soma distortions,
I guess the inaccuracy is caused by the triangle is not enough, especially at the face boundary(near the edge). you can see from my screen shot,
there seems missing some triangle at the top face.
by the way I am do the trianglute in
BentleyStatus ElementGraphicsProcessor::_ProcessFacets(PolyfaceQueryCR facets, bool isFilled)
where class ElementGraphicsProcessor : public Bentley::DgnPlatform::IElementGraphicsProcessor.
There's an example delivered with the SDK:
examples\Elements\Polyfacetool
Thanks Jon for the reply, my requirement is that I have a Dgn model, which contain a Mesh element, I want to get the mesh element's triangle points, indexes, normals, and then with that triangles information, I need to write to other 3d model file format in my System. for example, I want to convert the Mesh element in dgn file, to a separate stl file, I will use the api to get the mesh triangles and then write the triangles into my stl file.
I do not think the sample helps me to triangulate the mesh in dgn, and then return all the triangle points, indexes, normals ...., anyway, thanks for the information.
Rick cheng said:I do not think the sample helps me to triangulate the mesh
Perhaps the example doesn't do what you want. However, the ElementGraphicsProcessor API provides that capability. It eliminates the detailed work you must do with the PolyfaceHeader API. I believe that it's used in MicroStation for just the kind of thing you want to achieve.