Fri, 09/01/2023 - 01:30
Hi Team, I have been trying to get a visible representation of the GD&T data contained within a STEP(AP242) file by using XCAF
I am using the sample file 'nist_ctc_02_asme1_ap242-e2.stp' - attached in a .7z but also available from https://www.nist.gov/ctl/smart-connected-systems-division/smart-connected-manufacturing-systems-group/mbe-pmi-0
I can get the shape of the main 3D object, mesh it, and get the vertices and triangles. And I can see the GD&T information using the DimTol tool.. great!
But I'm quite stuck at the point of actually being able to see the labels. I have a screenshot attached from a different software that I am using as reference, so I know that the file contains the right information, but I'm hitting a wall here.
If someone knows how to get the tessellated presentation of the GD&T labels, that would be so wonderful. Thank you for your time!
Below I have pasted the C++ function I am using and the output when I run it:
C++
void testGDTFunction(const char* filePath) {
Standard_CString sFilePath = Standard_CString(filePath);
Handle(TDocStd_Document) document;
// Setup app
Handle(XCAFApp_Application) anApp = XCAFApp_Application::GetApplication();
BinXCAFDrivers::DefineFormat(anApp);
XmlXCAFDrivers::DefineFormat(anApp);
anApp->NewDocument("BinXCAF", document);
// Use reader to read file and transfer information (GD&T included) into document
cout << "Reading " << sFilePath << "... " << endl;
STEPCAFControl_Reader reader;
try {
reader.SetGDTMode(true);
reader.ReadFile(sFilePath);
reader.Transfer(document);
}
catch (exception ex) {
cout << "Exception while reading file '" << sFilePath << "': " << ex.what() << endl;
}
// Let's just grab the first document node for now
XCAFPrs_DocumentExplorer explorer(document, XCAFPrs_DocumentExplorerFlags_None);
const XCAFPrs_DocumentNode& curDocNode = explorer.Current();
// The shape tool gives us access to the incremental mesher so we can get the vertices, triangles and see our model
Handle(XCAFDoc_ShapeTool) shapeTool = XCAFDoc_DocumentTool::ShapeTool(document->Main());
TopoDS_Shape shape = shapeTool->GetShape(curDocNode.Label);
// PROOF OF CONCEPT FOR VISIBLE 3D SHAPE
if (!shape.IsNull()) {
BRepMesh_IncrementalMesh mesher(shape, .1);
mesher.Perform();
Standard_Integer numFaces = 0;
Standard_Integer numVertices = 0;
Standard_Integer numTriangles = 0;
for (TopExp_Explorer aExpFace(shape, TopAbs_FACE); aExpFace.More(); aExpFace.Next()) {
numFaces++;
TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
TopLoc_Location aLocation;
Handle(Poly_Triangulation) aTr = BRep_Tool::Triangulation(aFace, aLocation);
if (!aTr.IsNull()) {
Standard_Integer vertexCount = aTr->NbNodes();
numVertices += vertexCount;
Standard_Integer triangleCount = aTr->NbTriangles();
numTriangles += triangleCount;
}
}
cout << "Face Count: " << numFaces << ", Vertex Count: " << numVertices << ", Triangle Count: " << numTriangles << endl;
}
cout << endl;
// -- Not complete --
// PROOF OF CONCEPT FOR VISIBLE GD&T
// Get the DimTol (GD&T) list from the document
Handle(XCAFDoc_DimTolTool) dimTolTool = XCAFDoc_DocumentTool::DimTolTool(document->Main());
cout << "Dimension List:" << endl;
TDF_LabelSequence dimSeq;
dimTolTool->GetDimensionLabels(dimSeq);
for (Standard_Integer idx = dimSeq.Lower(); idx < dimSeq.Upper(); idx++) {
TDF_Label lab = dimSeq.Value(idx);
OutputLabelInfo(lab);
cout << endl;
Handle(XCAFDoc_Dimension) dim;
if (lab.FindAttribute(XCAFDoc_Dimension::GetID(), dim)) {
Handle(XCAFDimTolObjects_DimensionObject) dimObj = dim->GetObject();
cout << " [Presentation Name]: " << dimObj->GetPresentationName()->ToCString() << endl;
cout << " [Semantic Name]: " << dimObj->GetSemanticName()->ToCString() << endl;
cout << " [Type]: " << GetDimTolDimTypeFromEnum(dimObj->GetType()) << endl;
cout << " [Ref count]: " << dimObj->GetRefCount() << endl;
if (dimObj->IsDimWithRange()) { cout << ", [Range]: " << dimObj->GetLowerBound() << ", " << dimObj->GetUpperBound(); }
else if (dimObj->IsDimWithPlusMinusTolerance()) {
auto one = dimObj->GetValues();
auto two = dimObj->GetLowerTolValue();
auto thr = dimObj->GetUpperTolValue();
cout << " [+/- Tolerance]: " << dimObj->GetValue() << ", " << dimObj->GetLowerTolValue() << "-" << dimObj->GetUpperTolValue() << endl;
}
else if (dimObj->IsDimWithClassOfTolerance()) { cout << ", Has Class of Tolerance (not displaying)"; }
else { cout << " [Value]: " << dimObj->GetValue(); }
TopoDS_Shape presentationShape = dimObj->GetPresentation();
BRepMesh_IncrementalMesh mesher(presentationShape, .01);
mesher.Perform();
Standard_Integer numFaces = 0;
Standard_Integer numVertices = 0;
Standard_Integer numTriangles = 0;
for (TopExp_Explorer aExpFace(presentationShape, TopAbs_FACE); aExpFace.More(); aExpFace.Next()) {
numFaces++;
TopoDS_Face aFace = TopoDS::Face(aExpFace.Current());
TopLoc_Location aLocation;
Handle(Poly_Triangulation) aTr = BRep_Tool::Triangulation(aFace, aLocation);
if (!aTr.IsNull()) {
Standard_Integer vertexCount = aTr->NbNodes();
numVertices += vertexCount;
Standard_Integer triangleCount = aTr->NbTriangles();
numTriangles += triangleCount;
}
}
cout << " Face Count: " << numFaces << ", Vertex Count: " << numVertices << ", Triangle Count: " << numTriangles << endl;
}
cout << endl;
}
}
And the output. Notice the Face Count, Vertex Count, and Triangle Count of each dimension is 0:
Reading C:\data_path\nist_ctc_02_asme1_ap242-e2.stp...
Face Count: 637, Vertex Count: 33841, Triangle Count: 43920
Dimension List:
Name: diameter, Entry ID: 0:1:4:110, Tag: 110
[Presentation Name]: Linear Size.1
[Semantic Name]: diameter
[Type]: Size_Diameter
[Ref count]: 1
[+/- Tolerance]: 100, 0.15-0.15
Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: diameter, Entry ID: 0:1:4:111, Tag: 111
[Presentation Name]: Linear Size.2
[Semantic Name]: diameter
[Type]: Size_Diameter
[Ref count]: 1
[+/- Tolerance]: 52, 0.15-0.15
Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: diameter, Entry ID: 0:1:4:112, Tag: 112
[Presentation Name]: Linear Size.4
[Semantic Name]: diameter
[Type]: Size_Diameter
[Ref count]: 1
[+/- Tolerance]: 12, 0.05-0.05
Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: diameter, Entry ID: 0:1:4:113, Tag: 113
[Presentation Name]: Linear Size.5
[Semantic Name]: diameter
[Type]: Size_Diameter
[Ref count]: 1
[+/- Tolerance]: 12, 0.05-0.05
Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: diameter, Entry ID: 0:1:4:114, Tag: 114
[Presentation Name]: Linear Size.6
[Semantic Name]: diameter
[Type]: Size_Diameter
[Ref count]: 1
[+/- Tolerance]: 22, 0.1-0.1
Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: diameter, Entry ID: 0:1:4:115, Tag: 115
[Presentation Name]: Linear Size.7
[Semantic Name]: diameter
[Type]: Size_Diameter
[Ref count]: 1
[+/- Tolerance]: 22, 0.1-0.1
Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: diameter, Entry ID: 0:1:4:116, Tag: 116
[Presentation Name]: Linear Size.3
[Semantic Name]: diameter
[Type]: Size_Diameter
[Ref count]: 1
[+/- Tolerance]: 40, 0.15-0.15
Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: DGT:Dimension, Entry ID: 0:1:4:117, Tag: 117
[Presentation Name]: Simple Datum.7
[Semantic Name]: DGT:Dimension
[Type]: DimensionPresentation
[Ref count]: 1
[Value]: 0 Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: DGT:Dimension, Entry ID: 0:1:4:118, Tag: 118
[Presentation Name]: Simple Datum.8
[Semantic Name]: DGT:Dimension
[Type]: DimensionPresentation
[Ref count]: 1
[Value]: 0 Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: DGT:Dimension, Entry ID: 0:1:4:119, Tag: 119
[Presentation Name]: Simple Datum.10
[Semantic Name]: DGT:Dimension
[Type]: DimensionPresentation
[Ref count]: 1
[Value]: 0 Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: DGT:Dimension, Entry ID: 0:1:4:120, Tag: 120
[Presentation Name]: Simple Datum.11
[Semantic Name]: DGT:Dimension
[Type]: DimensionPresentation
[Ref count]: 1
[Value]: 0 Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: DGT:Dimension, Entry ID: 0:1:4:121, Tag: 121
[Presentation Name]: Text.2
[Semantic Name]: DGT:Dimension
[Type]: DimensionPresentation
[Ref count]: 1
[Value]: 0 Face Count: 0, Vertex Count: 0, Triangle Count: 0
Name: DGT:Dimension, Entry ID: 0:1:4:122, Tag: 122
[Presentation Name]: Simple Datum.5
[Semantic Name]: DGT:Dimension
[Type]: DimensionPresentation
[Ref count]: 1
[Value]: 0 Face Count: 0, Vertex Count: 0, Triangle Count: 0
Elapsed time: 14.5541 seconds
Fri, 09/01/2023 - 11:09
Hello,
If STEP file contains pre-tessellated representation of PMI - you be able to exctract them by XCAFDoc_DimTolTool::GetGDTPresentations(...). It method exctract shapes from PMI and bind with label. This type of PMI is not editable. For getting semantic(+AIS) PMI presentation you can buy PMIVis commercial component (PMI Visualization Component | PMI software (opencascade.com))
Best regards, Dmitrii.
Thu, 11/23/2023 - 07:24
Hi,Dimtrii.
When you say "It method exctract shapes from PMI and bind with label ",did you mean that this method is used to extract graphic PMI presentations?
I`ve tried to exctract PMI by these functions below
Handle(XCAFDoc_DimTolTool) gdtTool = XCAFDoc_DocumentTool::DimTolTool(doc->Main());
TDF_LabelSequence labels_datums, label_geoms, label_dims, label_dimTols;
gdtTool->GetDatumLabels(labels_datums);
gdtTool->GetDimensionLabels(label_dims);
gdtTool->GetGeomToleranceLabels(label_geoms);
I just got some label_dims from my stp file,and I`ve atached the screenshot below.
Then, I get the types of those label_dims, the types turns out to be of XCAFDimTolObjects_DimensionType_CommonLabel and XCAFDimTolObjects_DimensionType_DimensionPresentation.
Disappointingly,I got no numerical values by methods like GetLowerBound() or GetValue().Would you give me a hand please?
Best regards,Ji.
Fri, 09/01/2023 - 18:46
Thank you Dmitrii for your time, I've tried the approach you suggested
in the following code:
I think I am getting stuck on the part where I need to extract the vertices and triangles out from the shape. Is there a way to do this? Thank you again
Fri, 09/01/2023 - 19:00
Why you try to extract this?
There only wires (poly_polylines)
Best regards, Dmitrii.
Fri, 09/01/2023 - 19:13
The overall project is to create a plugin for Unity
I am triangulating everything and then marshalling it over to C#. I have the BRep data working well already. I just need to get the GD&T information, which appears to already be tessellated but I don't know how to access it
Fri, 09/01/2023 - 19:16
TopExp_Explorer aExpFace(aShape, TopAbs_EDGE) could help you, there no faces.
Best regards, Dmitrii.
Fri, 09/01/2023 - 20:08
Sorry, I think I'm a little confused
In the STEP file, I have tracked the GD&T down to a couple of entities:
The GD&T is already triangulated, is it getting converted into edges? Maybe I'm not accessing the right structures? Here's what my code outputs for this particular dimension:
And here is my code if it helps:
Fri, 09/01/2023 - 20:12
[# Attribs] 5 [Dimension] Linear Size.1 Compound Count: 1 Compsolid Count: 0 Edge Count: 5 Face Count: 0 Shape Count: 0 Shell Count: 0 Solid Count: 0 Vertex Count: 10 Wire Count: 3
Looks correct. Whats wrong? Wires with edges. It is correct and valid.
Best regards, Dmtrii.
Fri, 09/01/2023 - 20:26
I am stuck at the part where I can turn those edges into visible 3D information
The dimension should look like this:
I don't think 10 vertices and 5 edges is enough to capture this geometry. And in the STEP file, the dimension is pre-tessellated and contains hundreds of vertices
Fri, 09/01/2023 - 20:31
You are free to visualize them using DRAW. They are just a TopoDS_Shape.
edge - poly_polylines. That means that they are complex lines.
Best regards, Dmitrii.
Fri, 09/01/2023 - 20:36
I am creating a plugin for Unity, and Unity is going to handle the drawing. But unfortunately, Unity needs triangles.
Is there any way to get the pre-tessellated information?
Or is there a way to calculate the triangles from the shape?
Fri, 09/01/2023 - 21:35
TopoDS_Shape is a pre-tessellated presentation.
I'm a little confused. How you present PMI as a triangulation? It is not possible.
Red - TopoDS_Shapes as an Edge from your iteration. This file is public, you can share it.
Best regards, Dmitrii.
Fri, 09/01/2023 - 22:02
I am using a third-party program called CADExchanger as a reference, here is a screenshot from CADExchanger
Perhaps we are talking about different things when we say 'pre-tessellated'?
I am thinking of PMI that is represented as triangles in the STEP file itself. In the screenshot, you can see that the '1' in '100' is distorted. This is because I changed some of the coordinates that form the triangles:
I was able to change the coordinates and distort the '1'
There is a lot of text here, so I'm confused too
How is the TopoDS_Shape containing all of this information in only 10 vertices, 5 edges, and 3 wires?
Wed, 09/06/2023 - 18:16
Bumping this:
I've been trying to use the BRep_Tool class and the BRep_Tools class to try and get some geometric data from the edges, vertices, and wires. Not much luck so far. What is the correct approach to turn the edges, vertices, and wires into geometric information that can be visualized?
Wed, 09/06/2023 - 18:47
You need to handle type of Handle(Geom_Curve) checking ->IsKind(STANDARD_TYPE(Geom_Circle)) and then DownCast and getting data.
Or other option - convert curves to BSlines, and getting only BSpline. But probable the most part of edges contains only Geom_Lines or something simple.
Best regards, Dmitrii.
Wed, 09/06/2023 - 22:36
When you say convert curves to BSplines, are you referring to the Edges? What are Wires?