MeVisLab Toolbox Reference
WEM Debugging Hints

Important things to know

Because of the complexity of the WEM data structure, the implementation of a new algorithm can prove error prone. If the data structure is understood more deeply, and some implemented debugging helpers are used, the error detection - and prevention - can render more efficient.

Entry Numbers

In the main data structure, the WEM itself, all the pointers to the appendant nodes, edges and faces are stored in accordings internal vectors. By iterating over those vectors, an iteration over all the stored primitives can be realized. But sometimes it is necessary for an implementation to obtain the information from a primitives, at which index it is stored in its vector. This is where the WEMPrimitive::entryNumber comes in handy: it is simply the index number of the primitive in its according vector. The WEMVector itself keeps track of those entry numbers, and whenever a primitive is removed from its vector, all the other entry numbers are kept valid after such an operation. Note that the entry numbers do not remain static for a certain primitive if removals occur; a removal can indeed alter primitives' entry numbers both before and behind a removed primitive, due to the efficient implementation of the WEMVector.

\Em Entry numbers are heavily used in copying a WEM to another, since they are used as memory independant pointers. Also, these numbers are used in the generation of the OpenInventor scene graph for rendering with the SoWEMRenderer.

The entry numbers are used and displayed in the SoWEMDiagnosis module for a more easy bug hunt. Additionally, this module is capable of highlighting erroneous primitives in the rendered OpenInventor scene.

Pointer Links

The WEM data structure gains its power from the dense linkage of incident primitives via pointers. Of course, to produce a valid WEM, all pointer links have to be valid. Despite of that, it is possible to implement 'sparse' WEMs, consisting only of, say, nodes and edges, with no faces at all. This will leave the WEMNode::faces vector empty, and the WEMEdge::rFace and WEMEdge::lFace as NULL pointers. Such a WEM will be rendered without errors or crashes, just make sure that the 'Draw Edges' and/or 'Draw Nodes' options are checked on the SoWEMRenderer. But note, that some processing modules (like the WEMReducePolygons or WEMSubdivide) need existing and correctly set edges and faces, and will not function properly otherwise. Other modules, such as the WEMSmooth will work on those 'sparse' WEMs.

Node - Edge Ordering in WEMFaces

The WEMFaces need a certain ordering of their nodes and edges. The ordering of the nodes is important for normal calculation, and must thus be for all faces the same. We chose a clockwise ordering of nodes for the faces. In general, the edges do not have to be in a special order. However, modules like WEMReducePolygons presume a special ordering of a face's edges. This ordering must be clockwise, too, and must be aligned with the nodes. That means, that the first node must be the head or the tail of the first edge, the second node must be the head or tail of the second edge and so on. If the alignment is erroneous, the modules mentioned above will produce holes in the surface. The correct ordering and alignment can be checked by using the SoWEMDiagnosis module.

Miscellaneous Stuff

Time Measurement

All standard MLWEM modules provide a mechanism for measurement of the processing time. Modules generated by the module wizard also provide the automatic time measurement. This can be used to help implementing an algorithm more efficient or to estimate the time an application will need for certain computations.

All processing modules derived from WEMBaseOp have a field called 'elapsedTime'. This is available on the module's automatic panel. This field displays the time of the last processing run and can be used by an application to sum up the total computation time of a WEM processing pipeline.

To make things more convenient, there is a WEMPerformance macro module available. This module measures the processing time of all modules derived from WEMBaseOp, and displays them in a summary.

Note that the processing time comprises the time needed to copy a WEM, if the 'Use WEM Copy' option is used.

Check Integrity

For all WEMPrimitives, an according diagosis class is implemented. These are WEMNodeDiagnosis, WEMEdgeDiagnosis and WEMFaceDiagnosis. Each of these classes have a 'checkIntegrity' method that triggers the checking of the validity of the structure and its surrounding.

When implementing a new algorithm that involves the alteration of the WEM structure, it can be helpful to call the 'checkIntegrity' method for all those primitives that are locally modified. This way, errors can be detected as soon as they appear. When the algorithm is running correctly and does not corrupt the WEM's integrity, the 'checkIntegrity' calls can be taken out of the code again (since they are time consuming).