tumcms / Open-Infra-Platform

This is the official repository of the open-source Open Infra Platform software (as of April 2020).

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Refactoring of topological merging by parameter polyhedronIndices

christophKaiser opened this issue · comments

At the moment, there is no explicit function which converts the polyhedronIndices. However, thanks for your comment - it showed me the need of refactoring at this point. For another programmer, it isn't easy to see from where the variable polyhedronIndices comes from, how it has to be initialised, does it need some kine of default pre-set, and so on.

A few words about how it works right now
The variable std::map<std::string, uint32_t> polyhedronIndices is declared at one place - in this case inside the function convertIfcFaceList. From there it's passed by reference to all functions which work with it.

'Work' refers to the adding a vertex to polyhedron. In that case, a stringstream with the vertex coordinates is formed and searched inside of polyhedronIndices. If the stringstream exists, the stored vertex index is used. Otherwise, the vertex is added to polyhedron and the stringstream is added to polyhedronIndices. This task is done by the following sample code:

// set string id and search for existing vertex in polyhedron
std::stringstream vertexString;
vertexString << vertex3D.x << " " << vertex3D.y << " " << vertex3D.z;
auto itFound = polyhedronIndices.find(vertexString.str());

uint32_t index = 0;
if (itFound != polyhedronIndices.end()) {
	index = itFound->second;
}
else {
	index = polyhedron->addVertex(vertex3D);
	polyhedronIndices[vertexString.str()] = index;
}

// use index (depends on context)

The variable polyhedronIndices is passed by reference through the multiple function calls because its content is filled incrementally and reused in the next calls. In this way, it's responsible for the topological merge of coincident vertices.

The above sample code can be found at multiple places throughout the project - sometimes with little adaptions:

  • Subfunctions of FaceConverterT::convertIfcFaceList:
    • FaceConverterT::addTriangleToPolyhedronData
    • FaceConverterT::triangulateFace
    • ItemData::mergePolyhedronsIntoOnePolyhedron
  • Local use in FaceConverterT::convertIfcBSplineSurface
  • Local use in ProfilConverterT::SearchExistingVertex
  • Local use in SolidModelConverterT::convertIfcSpecificSolidModel (function is commented out)

Thoughts about how to refactor
Because the same task is done at multiple places in the project, it should be reduced into one central function. Within this change, the variable polyhedronIndices should be somehow bound to the corresponding polyhedron, hence another programmer don't has to care that much about this variable.

As one conclusion, the information in polyhedronIndices is just another representation of the content from the member variable std::vector<carve::geom3d::Vector> points of the class carve::input::PolyhedronData, respectively carve::input::PolylineSetData (points is inherited from the class carve::input::VertexData where it's declared). Probably, the type std::map<std::string, uint32_t> was choosen to have access the find function of std::map.

To be accurate, polyhedronIndices should be a member variable in VertexData and the above samle code becomes a memberfunction inside there. However, this is outside of our actual namespace.

Inside the namespace OIP, the class ItemData would be the next alternative for the member variable and its depending functions - the function mergePolyhedronsIntoOnePolyhedron which works within this topic of topological merging is already there. The first idea was to keep and use the existing instances of PolyhedronData and PolylineSetData. One disadvantage of this was, that we would need one polyhedronIndices-variable for each instance of PolyhedronData and PolylineSetData, thus four vectors of them (for closed_polyhedrons, open_polyhedrons, open_or_closed_polyhedrons and polylines). Futhermore, assuming on function is in execution on one instance of a polyhedron, it will be quite difficult to determine the corresponding polyhedronIndices-variable.

A second thought on resolving the determination issue would be the introduction of a new polyhedron instance / variable with its corresponding polyhedronIndices-variable. The job of this new instance would be to collect the geometry of one polyhedron; once the polyhedron is complet, its pointer would be handed over into the existing vector closed_polyhedrons. The sample code from above would be in the same class, where it can be explicitly called when this functionality should be used; otherwise this variables and functions about topological merging don't have to be called (like in the majority of converter functions which don't use this search methodology).
For the implementation of the new variables and functions could be two options: At first, an extension of the existing class ItemData would be an option. The disadvantage on this would be that the new variables and functions would be always visible in an ItemData-object.
The second option would be a new class which is used similar to the ItemData-class during the collection of the polyhedron. If the collection is finished, the polyhedron would be handed over into the target ItemData-object. About the parameter of the converter functions, one issue in this option could be the compatibility between ItemData-objects and objects of the new class.

Originally posted by @christophKaiser in #462 (comment)