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.
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 variablepolyhedronIndices
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 functionconvertIfcFaceList
. 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, astringstream
with the vertex coordinates is formed and searched inside ofpolyhedronIndices
. If thestringstream
exists, the stored vertex index is used. Otherwise, the vertex is added topolyhedron
and thestringstream
is added topolyhedronIndices
. This task is done by the following sample code: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:
FaceConverterT::convertIfcFaceList
:FaceConverterT::addTriangleToPolyhedronData
FaceConverterT::triangulateFace
ItemData::mergePolyhedronsIntoOnePolyhedron
FaceConverterT::convertIfcBSplineSurface
ProfilConverterT::SearchExistingVertex
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 variablestd::vector<carve::geom3d::Vector> points
of the classcarve::input::PolyhedronData
, respectivelycarve::input::PolylineSetData
(points
is inherited from the classcarve::input::VertexData
where it's declared). Probably, the typestd::map<std::string, uint32_t>
was choosen to have access thefind
function ofstd::map
.To be accurate,
polyhedronIndices
should be a member variable inVertexData
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 functionmergePolyhedronsIntoOnePolyhedron
which works within this topic of topological merging is already there. The first idea was to keep and use the existing instances ofPolyhedronData
andPolylineSetData
. One disadvantage of this was, that we would need onepolyhedronIndices
-variable for each instance ofPolyhedronData
andPolylineSetData
, thus four vectors of them (forclosed_polyhedrons
,open_polyhedrons
,open_or_closed_polyhedrons
andpolylines
). Futhermore, assuming on function is in execution on one instance of a polyhedron, it will be quite difficult to determine the correspondingpolyhedronIndices
-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 vectorclosed_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 classItemData
would be an option. The disadvantage on this would be that the new variables and functions would be always visible in anItemData
-object. The second option would be a new class which is used similar to theItemData
-class during the collection of the polyhedron. If the collection is finished, the polyhedron would be handed over into the targetItemData
-object. About the parameter of the converter functions, one issue in this option could be the compatibility betweenItemData
-objects and objects of the new class._Originally posted by @christophKaiser in https://github.com/tumcms/Open-Infra-Platform/pull/462#discussion_r784876631_