Open fuqifacai opened 11 months ago
Hi @fuqifacai !
Maybe I'm misunderstanding, but if your goal is to generate tessellated mesh geometry from a CityGML file, then you should use getVertices()
and getIndices()
instead of exteriorRing()
.
The OSG plugin is actually a nice example you could have a look at: https://github.com/jklimke/libcitygml/blob/3f66e6a2ba66404565e0029e3fd51671472af59e/osgplugin/ReaderWriterCityGML.cpp#L361
Thanks for your reply. The problem is I can not get any data from Polygon.getVertices() and getIndices(). they both return null or empty. I can only get some sort of vertex array info from exteriorRing object. The test gml file is which you listed on website: https://www.citygmlwiki.org/index.php?title=FZK_Haus Not sure this is because my test gml file has no vertex info actually , or ..my code is incorrect. I've checked your osg plugin code and sample codes .....
Hi again @fuqifacai
(By the way, I'm not the maintainer of this project - I'm just someone using it, so not everything I say might be 100% correct )
Hmm, that's weird. I was able to successfully get the data from getVertices/getIndices..
I'm wondering, have you created a valid Tesselator
and passed it to the citygml::load
function? I believe you'll need to build with LIBCITYGML_USE_OPENGL
enabled to use that.
This is how I initialise it in our application:
std::unique_ptr<TesselatorBase> tesselator = std::unique_ptr<TesselatorBase>(new Tesselator(nullptr));
std::shared_ptr<const citygml::CityModel> city = citygml::load(filePath, params, std::move(tesselator));
This is how it looks for me:
I'm afraid I can't share my full source code (since it belongs to my employer), but maybe I can set up a simple sample project if that's useful?
@mlavik1 Very appreciate your reply . That's very helpful and correct solution . I checked my codes and verified that the problem is that not created with a valid Tesselator object by enable LIBCITYGML_USE_OPENGL macro. Problem solved and result seems perfect. Thanks again .
@fuqifacai Oh, that's great! Glad I could help :grin: Wish you best of luck with your project!
@mlavik1 May I ask did you know why the building's top is red, how can I get this color info from the citygml file ? I've check the whole test file , still can not figure out where the color information is . Thanks for any advice .
Hi again @fuqifacai ,
So first of all: it seems to be common for some CityGML viewers to use a colour scheme where they set a default colour based on object type ("RoofSurface" is typically red).
However, in this case the CityGML contains some colour information.
When you've read the CityGML file you can call CityModel::themes()
to get a list of themes, and pick one (if it has any - not all models have that).
std::shared_ptr<const citygml::CityModel> city = citygml::load(filePath, params, std::move(tesselator));
const auto& themes = city->themes();
std::string theme = themes.size() > 0 ? themes[0] : ""; // I pick the first one, but if there are several themes you might want to support custom theme selection
Then, when you're processing the geometry you can call Polygon::getMaterialFor(theme)
to get the material, and then getDiffuse
to get the colour:
unsigned int polygonCount = geometry.getPolygonsCount();
for (unsigned int i = 0; i < polygonCount; ++i)
{
auto polygon = geometry.getPolygon(i);
const auto citygmlMaterial = polygon->getMaterialFor(theme);
if (citygmlMaterial)
{
auto col = citygmlMaterial->getDiffuse();
...
}
}
If the polygon has no material for the given theme, then you can call object.getTypeAsString()
and pick a default colour based on the type (roofs can be red, etc..).
I'm not 100% sure, but I believe getThemes()
will return a list containing one empty string if it has no themes (at least that's the case of this model), but you can still get the material by passing that empty string to polygon->getMaterialFor(theme)
Thanks for your detailed reply . why "RoofSurface" is typically red ?
Thanks for your detailed reply . why "RoofSurface" is typically red ?
No idea! I've just seen it in some software - though I don't have a lot of practical experience with CityGML yet (started working with it a few months ago). But if a CityGML has no colour data, it would look bad to colour everything white, so it might sense to add some default colours. Here's an example from CityJSON Ninja: (https://ninja.cityjson.org/)
But for this specific model that shouldn't be needed, since it already has materials.
Thanks for your detailed reply . why "RoofSurface" is typically red ?
Maybe i can help out here... It has its roots in the histrorical development of the CityGML Standard which was conducted in Germany. It is quite typical for roofs to have a red-ish color. This also facilitated visual debugging a lot ;-)
Finally understood. Thanks guy.
Hi : I can get the vertex info from test gml file by using below sample codes, however there is no index or indics for these vertex info. How can I get that ? My goal is to generate the mesh object by using vertex and index info. Thanks.
std::shared_ptr myPolygon = inGeometry.getPolygon(i);
std::shared_ptr myExternalLinearRing = tempPolygon->exteriorRing();
std::vector myExternalLinearVertices = myExternalLinearRing->getVertices();