Extrusion

Hello all,

I’m trying to create and triangulate a simple cube in Open Cascade. I used the code from the bottle tutorial to help build the cube. I create a square profile and use BRepPrimAPI_MakePrism to extrude the profile into a cube.

The triangulation computes all the triangles as they should be except for the top side of the cube. The top face of the cube is computed as the same as the original profile, except that it has a reverse facing. So, it's in the same position as the profile: this creates an empty box rather than a cube.

Am I misunderstanding what BRepPrimAPI_MakePrism is supposed to do? If so, is there any way to perform a true extrusion?

Here is my code:

double dSize = 2.0;

//Create points
gp_Pnt oPoint1( dSize, 0.0, dSize );
gp_Pnt oPoint2( dSize, 0.0, -dSize );
gp_Pnt oPoint3( -dSize, 0.0, -dSize );
gp_Pnt oPoint4( -dSize, 0.0, dSize );

//Create segments
Handle( Geom_TrimmedCurve ) hSegment1 = GC_MakeSegment( oPoint1, oPoint2 );
Handle( Geom_TrimmedCurve ) hSegment2 = GC_MakeSegment( oPoint2, oPoint3 );
Handle( Geom_TrimmedCurve ) hSegment3 = GC_MakeSegment( oPoint3, oPoint4 );
Handle( Geom_TrimmedCurve ) hSegment4 = GC_MakeSegment( oPoint4, oPoint1 );

//Create edges
TopoDS_Edge oEdge1 = BRepBuilderAPI_MakeEdge( hSegment1 );
TopoDS_Edge oEdge2 = BRepBuilderAPI_MakeEdge( hSegment2 );
TopoDS_Edge oEdge3 = BRepBuilderAPI_MakeEdge( hSegment3 );
TopoDS_Edge oEdge4 = BRepBuilderAPI_MakeEdge( hSegment4 );

//Create wire profile
TopoDS_Wire oWireProfile = BRepBuilderAPI_MakeWire( oEdge1, oEdge2, oEdge3, oEdge4 );

//Create face profile
TopoDS_Face oFaceProfile = BRepBuilderAPI_MakeFace( oWireProfile );

//Extrude profile
gp_Vec oPrismVec( 0, dSize * 2.0, 0 );
TopoDS_Shape oBody = BRepPrimAPI_MakePrism( oFaceProfile, oPrismVec );

//Explore body to extract and triangulate faces.
for( TopExp_Explorer oBodyExplorer( oBody, TopAbs_FACE ) ; oBodyExplorer.More() ; oBodyExplorer.Next() )
{
TopoDS_Face oCurrentFace = TopoDS::Face( oBodyExplorer.Current() );

BRepMesh::Mesh( oCurrentFace, 0.5 );
TopLoc_Location oLocation;
Handle_Poly_Triangulation hCurrentTriangulation = BRep_Tool::Triangulation( oCurrentFace, oLocation );

if( !hCurrentTriangulation.IsNull() )
{
int iTriangleCount = hCurrentTriangulation->NbTriangles();
for( int iTriangleCursor = 1 ; iTriangleCursor {
Poly_Triangle oTriangle = ( hCurrentTriangulation->Triangles() )( iTriangleCursor );

gp_Pnt oTrianglePoint1 = ( hCurrentTriangulation->Nodes() )( oTriangle.Value( 1 ) );
gp_Pnt oTrianglePoint2 = ( hCurrentTriangulation->Nodes() )( oTriangle.Value( 2 ) );
gp_Pnt oTrianglePoint3 = ( hCurrentTriangulation->Nodes() )( oTriangle.Value( 3 ) );

qDebug() qDebug() qDebug() qDebug()

gp_Vec vU = gp_Vec( oTrianglePoint2.XYZ() ) - gp_Vec( oTrianglePoint1.XYZ() );
gp_Vec vV = gp_Vec( oTrianglePoint3.XYZ() ) - gp_Vec( oTrianglePoint1.XYZ() );

gp_Vec vNormal;

vNormal.SetX( vU.Y() * vV.Z() - vU.Z() * vV.Y() );
vNormal.SetY( vU.Z() * vV.X() - vU.X() * vV.Z() );
vNormal.SetZ( vU.X() * vV.Y() - vU.Y() * vV.X() );

vNormal.Normalize();

qDebug() }
}
}

qDebug() is a Qt method for printing to the console.

Output:

-----------Triangle-----------
Point 1 : 2 , 0 , -2
Point 2 : 2 , 0 , 2
Point 3 : 2 , 4 , 2
Normal : -1 , 0 , 0
-----------Triangle-----------
Point 1 : 2 , 0 , -2
Point 2 : 2 , 4 , 2
Point 3 : 2 , 4 , -2
Normal : -1 , 0 , 0
-----------Triangle-----------
Point 1 : -2 , 0 , -2
Point 2 : 2 , 0 , -2
Point 3 : 2 , 4 , -2
Normal : 0 , 0 , 1
-----------Triangle-----------
Point 1 : -2 , 0 , -2
Point 2 : 2 , 4 , -2
Point 3 : -2 , 4 , -2
Normal : 0 , 0 , 1
-----------Triangle-----------
Point 1 : -2 , 0 , 2
Point 2 : -2 , 0 , -2
Point 3 : -2 , 4 , -2
Normal : 1 , 0 , 0
-----------Triangle-----------
Point 1 : -2 , 0 , 2
Point 2 : -2 , 4 , -2
Point 3 : -2 , 4 , 2
Normal : 1 , 0 , 0
-----------Triangle-----------
Point 1 : 2 , 0 , 2
Point 2 : -2 , 0 , 2
Point 3 : -2 , 4 , 2
Normal : 0 , 0 , -1
-----------Triangle-----------
Point 1 : 2 , 0 , 2
Point 2 : -2 , 4 , 2
Point 3 : 2 , 4 , 2
Normal : 0 , 0 , -1
-----------Triangle-----------
Point 1 : 2 , 0 , -2
Point 2 : -2 , 0 , 2
Point 3 : -2 , 0 , -2
Normal : 0 , -1 , 0
-----------Triangle-----------
Point 1 : 2 , 0 , -2
Point 2 : 2 , 0 , 2
Point 3 : -2 , 0 , 2
Normal : 0 , -1 , 0
-----------Triangle-----------
Point 1 : 2 , 0 , -2
Point 2 : -2 , 0 , 2
Point 3 : -2 , 0 , -2
Normal : 0 , -1 , 0
-----------Triangle-----------
Point 1 : 2 , 0 , -2
Point 2 : 2 , 0 , 2
Point 3 : -2 , 0 , 2
Normal : 0 , -1 , 0

As you can see, the last two sets of two triangles are identical :(

Thanks,
Ian

Rob Bachrach's picture

Hi Ian,

The 2 end faces are actually exact copies of each other. The location (oLocation in your code) will be different for the 2 phases and adds your offset. You can create a transform (like gp_Trsf) from oLocation and then apply that transform to your node locations. This should give you the desired results.

Ian Clévy's picture

Thanks Rob, that makes sense :)