The position of the center coordinates that can be obtained by wire and face is different

Hello,
I am using OpenCascade V7.4.0 on 32bit windows.

I created a wire consisting of a straight line and an ellipse, converted the wire to a face, and used it in my application.
I calculated the center coordinates of the face from the converted face, but it didn't work.
When I calculated the value from the wire before conversion, I found that the value that can be obtained changes before and after conversion.
Why does changing wire to face change the value that can be obtained when surrounded by a boundy box?
Also, how can I find the correct center point coordinate value from face?

Please use the attached Brep file to reproduce the phenomenon.
Below is a sample code that causes the symptom in my environment.

    TopoDS_Wire wire;
    BRep_Builder builder;
    BRepTools::Read( wire, "BREP_FILE_PATH", builder );
    Bnd_Box bb_wire;
    BRepBndLib::Add( wire, bb_wire );
    bb_wire.SetGap( 0.0 );
    gp_Pnt wirePntCenter( ( bb_wire.CornerMax().X() + bb_wire.CornerMin().X() ) / 2.0,
                          ( bb_wire.CornerMax().Y() + bb_wire.CornerMin().Y() ) / 2.0,
                          ( bb_wire.CornerMax().Z() + bb_wire.CornerMin().Z() ) / 2.0 );

    // face
    BRepBuilderAPI_MakeFace makerFace( wire );
    TopoDS_Face face = makerFace.Face();
    Bnd_Box bb_face;
    BRepBndLib::Add( face, bb_face );
    bb_face.SetGap( 0.0 );
    gp_Pnt facePntCenter( ( bb_face.CornerMax().X() + bb_face.CornerMin().X() ) / 2.0,
                          ( bb_face.CornerMax().Y() + bb_face.CornerMin().Y() ) / 2.0,
                          ( bb_face.CornerMax().Z() + bb_face.CornerMin().Z() ) / 2.0 );

Best regards.

Keito

PS:Old Forum

https://old.opencascade.com/content/position-center-coordinates-can-be-o...

Attachments: 
Keito Okajima's picture

Thank you for answering in the old forum.
I tried the methods that you answered, but unfortunately neither method gave the expected results.
Also, the information I posted was lacking and misleading me. I'm sorry.

The figure I want to analyze this time is not a solid, but a plane figure that exists on one of the two-dimensional planes.
We need to capture the data of a shape drawn on a plane and need the exact coordinates of the center point, not the center of gravity of the shape.
The attachment is an image of what I want to do.

Apart from the boundy box, I tried to get the coordinate values from Face using UV vector and adapter Face.D1.
However, even with this method, the exact center coordinates could not be obtained.
Below is a sample source used in the calculation.

    BRepAdaptor_Surface adaptorFace( face );
    Standard_Real u1, u2, v1, v2;
    u1 = adaptorFace.FirstUParameter();
    u2 = adaptorFace.LastUParameter();
    v1 = adaptorFace.FirstVParameter();
    v2 = adaptorFace.LastVParameter();

    adaptorFace.D1( (u1+u2)/2, (v1+v2)/2, pntCenter, Vec1, Vec2 );

How can I find the exact center point of a face on a two-dimensional plane?

Best regards.

Keito

Attachments: 
Kirill Gavrilov's picture

> Why does changing wire to face change the value that can be obtained when surrounded by a boundy box?

The reason for the difference is a triangulation data used for Bounding Box calculations:

pload MODELING VISUALIZATION
restore wire.brep w
mkplane f w
bounding w
> -0.23339756042421284 -40.3200001001007 -69.544358869626549 40.40217232427338 40.320000101538511 0.37000010080451856
bounding w -noTriangulation
> 0.086602440375943168 -40.000000099300543 -69.232032402767089 40.086602640359516 40.000000100738355 0.050000100004362558
bounding f
> 0.086602440375943168 -40.000000099300543 -69.232032402767089 40.086602640359516 40.000000100738355 0.050000100004362558
bounding f -noTriangulation
> 0.086602440375943168 -40.000000099300543 -69.232032402767089 40.086602640359516 40.000000100738355 0.050000100004362558

BRepBndLib::Add() has an argument useTriangulation enabled by default:

>  void Add (const TopoDS_Shape& S, Bnd_Box& B, const Standard_Boolean useTriangulation = Standard_True);

It may look confusing in your case, but attached TopoDS_Wire indeed contains triangulation data (probably from original TopoDS_Face), but when creating a new Face from Wire, the Bounding Box calculations seem to be reject this triangulation data as new Face wasn't triangulated yet (BRepMesh wasn't called).

Keito Okajima's picture

Thank you for your answer.

As a result of measuring the center point after performing BRepMesh_IncrementalMesh () on the face, improvement was seen in the values ​​that can be obtained.

const Standard_Real aLinearDeflection = 0.01;
const Standard_Real anAngularDeflection = 0.5;
BRepMesh_IncrementalMesh aMesher (face, aLinearDeflection, Standard_False, anAngularDeflection, Standard_True);

I looked at the Open Cascade documentation and found only Incremental Mesh as the mesh method.
Are there other types of meshes?

https://dev.opencascade.org/doc/occt-7.4.0/overview/html/occt_user_guide...

Also, if possible, I would like to reflect the triangle division data that wire originally has on the face.
I wondered if I could try BRepTool :: Triangulation (), but I couldn't extract the information from the wire because the argument is TopoDS_Face.
Is there a way to extract the triangle division data from the wire and reflect it on the face?
Also, is there a good way to reflect the wire triangle division data when creating a face?

Best regards.

Keito

Kirill Gavrilov's picture

I looked at the Open Cascade documentation and found only Incremental Mesh as the mesh method. Are there other types of meshes?

Indeed, OCCT provides only one meshing algorithm. But there is also an Express Mesh component and external meshing algorithms.

Also, if possible, I would like to reflect the triangle division data that wire originally has on the face.

TopoDS_Edge may have Poly_Polygon3D and Poly_PolygonOnTriangulation representations created by Incremental Mesh algorithm.
Take a look onto BRep_Tool::Polygon3D() and BRep_Tool::PolygonOnTriangulation() methods.

Keito Okajima's picture

Thank you for your answer.

As a result of investigating based on the function you taught me, it was confirmed that the edge of the wire contains triangulation information.
Also, as a result of performing BRep_Tool :: Triangulation () on the face created from wire using BRepBuilderAPI_MakeFace,
It turns out that the Triangulation information seems to be gone.

  • When Bnd_Box was created for Wire, the triangulation information of the line segments that make up Wire was recognized.
  • When Bnd_Box is created in Face created by BRepBuilderAPI_MakeFace from Wire The return value of the BRep_Tool :: Triangulation () function was empty, and the Triangulation information was not used.
  • When Bnd_Box is created from Wire created by BRepTools :: OuterWire () from Face The Triangulation information of the line segments that make up the Wire was recognized, but the size of the BndBox is now the same as the Face.

Is there anything you can tell from the above information?

Best regards.

Keito