Overview

The IFC mesher transforms IFC geometry and topology definitions into triangular meshes for display in OpenGL, WebGL and DirectX or for export to formats like STL, AMF, and 3MF. Other functions work with IFC style information, axis placements and points

Use the ifcx_mesh_make() or ifcx_mesh_make_all() functions to create meshes for IfcRepresentationItem objects. Meshing can take place in the background using multiple threads for speed and versions the "make" functions allow control over when the work must be completed.

Each mesh is linked to its source IFC object and the "make" function return a previously created mesh if one exists. Use ifcx_mesh_find() to just look for an existing mesh without creating one.

These functions return an IfcxMesh object, which is a subclass of RoseMesh with extra functions to return the IFC source objects for faces and edges.

The example below creates meshes for everything in a file. Then loops over all of the representatation items, and if a mesh was created for it, prints the mesh size.

RoseDesign * design;

// index the IFC style information so the mesher can find color
// information for solids and faces.
ifcx_style_tag(design);

// create meshes for everything in the design
ifcx_mesh_make_all(design);


// Print all of the meshes.  A real program would walk the IFC product
// structure and print the meshes in context with the products that they
// are associated with.
RoseCursor objs;
RoseObject * obj;

objs.traverse(d);
objs.domain(ROSE_DOMAIN(IfcRepresentation));
while ((obj=objs.next()) != 0)
{
    IfcRepresentation * rep = ROSE_CAST(IfcRepresentation,obj);
    SetOfIfcRepresentationItem * items = rep->Items();
    unsigned i,sz;

    for (i=0, sz=items->size(); i<sz; i++)
    {
	IfcRepresentationItem * it = items->get(i);

	IfcxMesh * mesh = ifcx_mesh_find(it, rep);
	if (mesh)
	{
            printf ("Item #%lu: mesh with %u triangles\n",
	            it->entity_id(), mesh->getFacetCount());
	}
    }
}

ifcx_mesh_can_make()

int ifcx_mesh_can_make(
	IfcRepresentationItem * item,
	IfcRepresentation * rep = 0
	);

The ifcx_mesh_can_make() function returns non-zero if a mesh can be created from the representation item, such as an IfcFacetedBrep or IfcExtrudedAreaSolid. It returns zero if no mesh can be made from the item, such as an IfcAxis2Placement3D. It also returns zero for an IfcMappedItem, since it is the underlying item that is meshed, not the mapping.

ifcx_mesh_delete()

void ifcx_mesh_delete(
	IfcRepresentationItem * item,
	IfcRepresentation * rep = 0,
	RoseMeshNotify * notify = 0
	);

The ifcx_mesh_delete() function deletes any mesh associated with the given representation item. If a representation or notify object are provided, only a mesh created with matching values will be deleted.

ifcx_mesh_delete_all()

void ifcx_mesh_delete_all(
	RoseDesign * design,
	RoseMeshNotify * notify = 0
	);

The ifcx_mesh_delete_all() function deletes all meshes associated with representation items in the design. If a notify object are provided, only meshes created with a matching value will be deleted.

This function is not usually needed. All meshes associated with the design will be automatically deleted when the design is deleted.

ifcx_mesh_detach()

IfcxMesh * ifcx_mesh_detach(
	IfcRepresentationItem * item,
	IfcRepresentation * rep = 0,
	RoseMeshNotify * notify = 0
	);

The ifcx_mesh_detach() function finds the mesh associated with the given representation item. The association is removed, no other calls will find it, and it becomes the responsibility of the caller to delete the mesh object when finished.

If a representation or notify object are provided, only a mesh created with matching values will be returned.

ifcx_mesh_estimated_bounds()

int ifcx_mesh_estimated_bounds(
	RoseBoundingBox * bbox,
	IfcFace * face,
	IfcRepresentation * rep
	);

The ifcx_mesh_estimated_bounds() function sets the bounding box to the bounds computed from the trim curves of a face.

ifcx_mesh_find()

IfcxMesh * ifcx_mesh_find(
    IfcRepresentationItem * item,
    IfcRepresentation * rep = 0,
    RoseMeshNotify * notify = 0
    );

The ifcx_mesh_find() function finds the mesh associated with the given representation item. If a representation or notify object are provided, only a mesh created with matching values will be returned.

ifcx_mesh_job_init()

IfcxMesh * ifcx_mesh_job_init(
	IfcRepresentationItem * item,
	IfcRepresentation * rep,
	RoseMeshOptions * opts,
	RoseMeshNotify * notify
	);

The ifcx_mesh_job_init() function is for internal use. Use one of the ifcx_mesh_make() functions instead. This creates a mesh and associates it with a representation item. It does not check if a mesh is already associated with the representation item and does not start the meshing process.

ifcx_mesh_make()

IfcxMesh * ifcx_mesh_make(          // return when done 
	IfcRepresentationItem * item,
	IfcRepresentation * rep,
	RoseMeshOptions * opts = 0,
	RoseMeshNotify * notify = 0
	);

IfcxMesh * ifcx_mesh_make_start(    // return after starting 
	IfcRepresentationItem * item,
	IfcRepresentation * rep,
	RoseMeshOptions * opts = 0,
	RoseMeshNotify * notify = 0
	);

IfcxMesh * ifcx_mesh_make_job(      // return immediately 
	IfcRepresentationItem * item,
	IfcRepresentation * rep,
	RoseMeshOptions * opts = 0,
	RoseMeshNotify * notify = 0
	);

The ifcx_mesh_make() functions find or create a mesh for the given representation item and representation. An options structure can be provided to control tolerance and other values used by the mesher. Meshing can take place in the background using multiple threads for speed. The three versions of this function allow control over when the work must be completed.

If the IFC style information has been previously indexed by calling ifcx_style_tag(), the meshes will have color information for solids and faces.

All of the functions first call ifcx_mesh_find() and will return an existing mesh object if present. If one can be made, they will create an empty mesh object and associate it with the representation item. The functions differ on what happens next.

The ifcx_mesh_make() function will create the contents and return the mesh when it is complete. It may use several threads, but still only works on one mesh at a time.

The ifcx_mesh_make_start() function will begin creating the contents as a background job and return the empty mesh immediately. The mesh may not be usable for some time, but you can start many items, then wait for them to complete. This will generally be faster on multi-core CPUs than doing it one at a time. Consider using ifcx_mesh_make_all() if you want to mesh everything in a file.

The ifcx_mesh_make_job() function will return the empty mesh immediately. Background work is prepared but has not begun. This is useful if you want to get everything ready, but may not need the mesh data until later. You can call start and wait functions when it is eventually needed.

A notify object can be provided to distinguish meshes made for a particular purpose and to get update messages as portions of meshes become available.

IfcRepresentationItem * it;
IfcRepresentation * rep;
IfcxMesh * mesh;

// prepare one mesh
mesh = ifcx_mesh_make(it, rep);
// do something -- ready to use


// batch prepare some meshes
for (i=0; i<sz; i++) {
    (void) ifcx_mesh_make_start(get_item(i), get_rep(i));
}
rose_mesh_wait_all();  // wait for everything to be done


// everything now completed, use them
for (i=0; i<sz; i++) {
    mesh = ifcx_mesh_find(get_item(i), get_rep(i));
    // do something -- ready to use
}

ifcx_mesh_make_all()

void ifcx_mesh_make_all(          // return when done 
	RoseDesign * design,
	RoseMeshOptions * opts = 0,
	RoseMeshNotify * notify = 0
	);

void ifcx_mesh_make_all_start(    // return after starting 
	RoseDesign * design,
	RoseMeshOptions * opts = 0,
	RoseMeshNotify * notify = 0
	);

void ifcx_mesh_make_all_job(      // return immediately 
	RoseDesign * design,
	RoseMeshOptions * opts = 0,
	RoseMeshNotify * notify = 0
	);

The ifcx_mesh_make_all() functions create meshes for everything in the design. An options structure can be provided to control tolerance and other values used by the mesher. After this function is called, ifcx_mesh_find() will return an existing mesh object for everything that can be meshed.

The three versions of this function allow control over when the work must be completed and follow the convention used by ifcx_mesh_make().

The ifcx_mesh_make_all() function will return when all meshes are complete. The ifcx_mesh_make_all_start() function will begin work on all meshes and then return. Call wait or wait all when you completed data. The ifcx_mesh_make_all_job() function prepares everything but you must start start and wait for meshes individually.

A notify object can be provided to distinguish meshes made for a particular purpose and to get update messages as portions of meshes become available.

RoseDesign *
IfcxMesh * mesh;

// prepare all meshes
ifcx_mesh_make_all(design);

// everything now completed, use them
for (i=0; i<sz; i++) {
    mesh = ifcx_mesh_find(get_item(i), get_rep(i));
    // do something -- ready to use
}



// ANOTHER POSSIBIILITY
// start background work on all meshes
ifcx_mesh_make_all_start(design);

( do other setup) 

// block until all meshes are ready
rose_mesh_job_wait_all();