Commit 784b447e authored by Dipl.-Ing. Jonas Stienen's avatar Dipl.-Ing. Jonas Stienen

WIP

parents 99ea164a f551232d
......@@ -76,13 +76,14 @@ namespace ITAGeo
*/
bool Store( const std::string& sGMLFilePath, bool bOverwrite = true ) const;
void GetBuildingMesh( const CCityBuilding* pBuilding, ITAGeo::CHalfedgeMeshModel* pBuildingMesh );
void GetBuildingMesh( const CCityBuilding* pBuilding, ITAGeo::CHalfedgeMeshModel* pBuildingMesh, const VistaVector3D v3Shift = VistaVector3D( 0.0f, 0.0f, 0.0f ) );
std::vector< const ITAGeo::CCityGMLModel::CCityBuilding* > GetBuildings() const;
void DistanceCulling( const double dDetourDistance, const ITAGeo::CPropagationAnchor& v3Source, const ITAGeo::CPropagationAnchor& v3Target, std::vector< const ITAGeo::CCityGMLModel::CCityBuilding* >& vpResidualBuildings );
void CalculateObjectCentroids();
std::vector< double > GetCityCenter() const;
protected:
CCityGMLPtr* m_pCityModel; //!< Encapsuled pointer to the city GML instance
......
......@@ -58,102 +58,71 @@ public:
//! Resolved for Polygons without Holes // throws Polygon Connectivity error at seemingly random points.
void ITAGeo::CCityGMLModel::GetBuildingMesh( const ITAGeo::CCityGMLModel::CCityBuilding* pBuilding, ITAGeo::CHalfedgeMeshModel* pMeshModel )
void ITAGeo::CCityGMLModel::GetBuildingMesh( const ITAGeo::CCityGMLModel::CCityBuilding* pBuilding, ITAGeo::CHalfedgeMeshModel* pMeshModel, const VistaVector3D v3Shift )
{
const citygml::CityObject& oCityRootObject = m_pCityModel->pCityModel->getRootCityObject( pBuilding->iNum - 1 );
const citygml::CityObject& oBuilding = m_pCityModel->pCityModel->getRootCityObject( pBuilding->iNum - 1 );
CITAMesh* pMesh = pMeshModel->GetMesh()->pTopLevelMesh;
for( unsigned int j = 0; j < oCityRootObject.getChildCityObjectsCount(); j++ )
std::vector< TVec3d > voPointCloud;
std::vector< CITAMesh::VertexHandle > vvhVertices;
CITAMesh::Point vpGlobalShift( v3Shift[ Vista::X ], v3Shift[ Vista::Y ], v3Shift[ Vista::Z ] );
std::cout << "Building mesh for object " << oBuilding.getId() << std::endl;
for( unsigned int j = 0; j < oBuilding.getChildCityObjectsCount(); j++ )
{
for( unsigned int k = 0; k < oCityRootObject.getChildCityObject( j ).getGeometriesCount(); k++ )
for( unsigned int k = 0; k < oBuilding.getChildCityObject( j ).getGeometriesCount(); k++ )
{
for( unsigned int l = 0; l < oCityRootObject.getChildCityObject( j ).getGeometry( k ).getPolygonsCount(); l++ )
for( unsigned int l = 0; l < oBuilding.getChildCityObject( j ).getGeometry( k ).getPolygonsCount(); l++ )
{
std::shared_ptr< const citygml::Polygon > pPolygon = oCityRootObject.getChildCityObject( j ).getGeometry( k ).getPolygon( l );
std::vector< TVec3d > vVertexPoints( pPolygon->getVertices() );
std::vector< CITAMesh::VertexHandle > vFaceVertices( vVertexPoints.size() );
std::vector< CITAMesh::Point > vMeshPoints( vVertexPoints.size() );
assert( vVertexPoints.size() > 2 );
assert( ( pPolygon->getIndices().size() % 3 ) == 0 );
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//! Necessary workaround for the duplicate Vertices (always consecutive) that citygml::Polygon::getVertices() occasionally produces.
// coordinates in the duplicates vary around the 10 decimal spot, hence the rounding to the 3rd spot
for( unsigned int m = 0; m < vVertexPoints.size(); m++ )
const citygml::CityObject& oBuildingPart = oBuilding.getChildCityObject( j );
std::shared_ptr<const citygml::Polygon> pPolygon = oBuildingPart.getGeometry( k ).getPolygon( l );
std::vector< TVec3d > vPolygonVertices = pPolygon->getVertices();
assert( vPolygonVertices.size() > 2 );
//! Actual Mesh conversion
std::vector<CITAMesh::VertexHandle> vFaceVertices;
// Multiple faces can share the same vertices, following loop makes sure only new vertices are added to mesh
for( unsigned int m = 0; m < vPolygonVertices.size() - 1; m++ )
{
/*
vVertexPoints[ m ].x = std::floor( vVertexPoints[ m ].x * 100000 + 0.5 ) / 100000;
vVertexPoints[ m ].y = std::floor( vVertexPoints[ m ].y * 100000 + 0.5 ) / 100000;
vVertexPoints[ m ].z = std::floor( vVertexPoints[ m ].z * 100000 + 0.5 ) / 100000;
*/
vFaceVertices[ m ] = CITAMesh::VertexHandle();
TVec3d& v( vPolygonVertices[ m ] );
vMeshPoints[ m ] = CityGMLPoint3DToITAMeshPoint( vVertexPoints[ m ] );
bool bVertexExists = false;
#if 0
for( CITAMesh::VertexIter it_v = pMesh->vertices_begin(); it_v != pMesh->vertices_end(); it_v++ )
bool bSkip = false;
for( size_t n = 0; n < voPointCloud.size(); n++ )
{
CITAMesh::VertexHandle vhVertex( *it_v );
const CITAMesh::Point ExistingPoint = pMesh->point( vhVertex );
if( vMeshPoints[ m ] == ExistingPoint )
const TVec3d& p( voPointCloud[ n ] );
if( v.x == p.x && v.y == p.y && v.z == p.z )
{
vFaceVertices[ m ] = vhVertex;
if( m > 1 )
if( vhVertex != vFaceVertices[ m - 1 ] )
;
bVertexExists = true;
break;
bSkip = true;
vFaceVertices.push_back( vvhVertices[ n ] );
}
}
#endif
if( !bVertexExists )
vFaceVertices[ m ] = pMesh->add_vertex( vMeshPoints[ m ] );
}
if( !bSkip )
{
CITAMesh::VertexHandle vh = pMesh->add_vertex( CityGMLPoint3DToITAMeshPoint( v ) + vpGlobalShift );
// Split polygons
for( size_t i = 0; i < pPolygon->getIndices().size(); i += 3 )
{
std::vector< CITAMesh::VertexHandle > vNewFaceVertices( 3 );
for( size_t j = 0; j < 3; j++ )
vNewFaceVertices[ j ] = vFaceVertices[ pPolygon->getIndices()[ i + j ] ];
voPointCloud.push_back( v );
vvhVertices.push_back( vh );
std::set<CITAMesh::VertexHandle> s( vNewFaceVertices.begin(), vNewFaceVertices.end() );
vNewFaceVertices.assign( s.begin(), s.end() );
if( vNewFaceVertices.size() != 3 )
{
std::cerr << "Invalid vertex list in " << oCityRootObject.getId() << " (skipping)" << std::endl;
}
else
{
pMesh->add_face( vNewFaceVertices );
vFaceVertices.push_back( vh );
}
}
// Unique check on vertex handles for new face
std::set< CITAMesh::VertexHandle > sVertexSet( vFaceVertices.begin(), vFaceVertices.end() );
std::vector< CITAMesh::VertexHandle > vPrunedFaceVertices;
vPrunedFaceVertices.assign( sVertexSet.begin(), sVertexSet.end() );
/* Split polygons
for( size_t i = 0; i < pPolygon->getIndices().size(); )
if( vPrunedFaceVertices.size() != vFaceVertices.size() )
{
std::vector< CITAMesh::VertexHandle > vNewFaceVertices;
for( size_t j = i; j < pPolygon->getIndices().size(); j++ )
{
if( pPolygon->getIndices()[ j ] == pPolygon->getIndices()[ i ] && vNewFaceVertices.size() > 2 )
{
break;
}
vNewFaceVertices.push_back( vFaceVertices[ pPolygon->getIndices()[ j ] ] );
}
if( vNewFaceVertices.size() > 2 )
{
pMesh->add_face( vNewFaceVertices ); // Last polygon
i += vNewFaceVertices.size();
}
std::cerr << "Found non-unique entries in linear ring at " << oBuildingPart.getId() << ", skipping building part." << std::endl;
continue;
}
*/
pMesh->add_face( vFaceVertices );
}
}
}
......@@ -294,6 +263,13 @@ void ITAGeo::CCityGMLModel::CalculateObjectCentroids()
}
}
std::vector< double > ITAGeo::CCityGMLModel::GetCityCenter() const
{
auto p = m_pCityModel->pCityModel->getEnvelope().getLowerBound();
const std::vector< double > v = { p.x, p.y, p.z };
return v;
}
/**
*@brief Creates list of objects that are relevant to the sound propagation, based on maximum propagation distance and sender & receiver positions
*
......
......@@ -54,15 +54,21 @@ using namespace std;
typedef OpenMesh::PolyMesh_ArrayKernelT<> CITAMesh;
// Resource (CC BY-SA 4.0 Filip Biljecki): https://3d.bk.tudelft.nl/biljecki/Random3Dcity.html
static vector< string > vsAachenCityFilePaths = {
static vector< string > vsAachenCityFilePaths =
{
//"corrupt_building_2"
"LoD2_293_5628_1_NW",
"LoD2_293_5629_1_NW",
"LoD2_294_5628_1_NW",
"LoD2_294_5629_1_NW",
//"LoD2_295_5628_1_NW",
// "LoD2_295_5629_1_NW"
};
const VistaVector3D v3GlobalExportShift( -293000.0f, -5628000.0f, 0.0f );
static string sExportFileName = "AachenCityCulling.skp";
// Resource (Land NRW, 2017, https://www.govdata.de/dl-de/by-2-0): https://www.opengeodata.nrw.de/produkte/geobasis/3d-gm/3d-gm_lod2/
//static string sCityGMLFilePath = "Aachen/LoD2_287_5631_1_NW_no_terrain_intersection.gml";
//static string sCityGMLFilePath = "3d - gm_lod2_05766012_Barntrup_EPSG25832_CityGML/LoD2_502_5760_1_NW.gml";
......@@ -82,7 +88,7 @@ int main( int, char** )
ITAGeo::CSensor oReceiver;
oReceiver.vPos.SetValues( 294605.0f, 5628758.0f, 164.0f );
cout << "Source: " << oSource.ToString() << endl;
cout << "Source: " << oSource.ToString() << endl;
cout << "Receiver: " << oReceiver.ToString() << endl;
vector< ITAGeo::CHalfedgeMeshModel* > vpRemainingBuildingModels;
......@@ -109,7 +115,7 @@ int main( int, char** )
for( size_t n = 0; n < vpCityBuildings.size(); n++ )
{
auto pBuildingModel = new ITAGeo::CHalfedgeMeshModel();
oModel.GetBuildingMesh( vpCityBuildings[ n ], pBuildingModel );
oModel.GetBuildingMesh( vpCityBuildings[ n ], pBuildingModel, v3GlobalExportShift );
voSketchUpCity.AddVisualizationMesh( pBuildingModel, "CityBuildings_" + sCityGMLFileName );
vpRemainingBuildingModels.push_back( pBuildingModel );
}
......@@ -125,14 +131,13 @@ int main( int, char** )
for( unsigned int i = 0; i < RemainingObjects.size(); i++ )
{
auto pBuildingModel = new ITAGeo::CHalfedgeMeshModel();
oModel.GetBuildingMesh( RemainingObjects[ i ], pBuildingModel );
oModel.GetBuildingMesh( RemainingObjects[ i ], pBuildingModel, v3GlobalExportShift );
voSketchUpCity.AddVisualizationMesh( pBuildingModel, "CullingAlgo_" + sCityGMLFileName );
vpAachenBuildingModels.push_back( pBuildingModel );
}
cout << "done." << endl;
}
string sExportFileName = "AachenCityCulling.skp";
cout << "Storing city as SketchUp file to " << sExportFileName << " ... ";
voSketchUpCity.Store( sExportFileName );
cout << "done." << endl;
......
......@@ -35,3 +35,5 @@ vista_install( ITAGeoHalfedgeSketchUpIOTest )
vista_create_default_info_file( ITAGeoHalfedgeSketchUpIOTest )
set_property( TARGET ITAGeoHalfedgeSketchUpIOTest PROPERTY FOLDER "ITAGeometricalAcoustics/Tests/ITAGeo/SketchUp" )
vista_set_target_msvc_arguments( ITAGeoHalfedgeSketchUpIOTest "resources/ITA_Building1.skp" "resources/ITA_Building1_converted.skp" )
......@@ -29,12 +29,20 @@
using namespace std;
using namespace ITAGeo;
int main( int, char** )
int main( int iArgsIn, char** ppcArgs )
{
VistaFileSystemFile oInFile( "SolidCube2017.skp" );
if( iArgsIn < 3 )
{
cout << "Syntax: infile.skp outfile.skp" << endl;
return 255;
}
VistaFileSystemFile oInFile( ppcArgs[ 1 ] );
assert( oInFile.Exists() );
VistaFileSystemFile oOutFile( "SolidCube2017_out.skp" );
oInFile.GetLocalName();
VistaFileSystemFile oOutFile( ppcArgs[ 2 ] );
if( oOutFile.Exists() )
cout << "[Warning] Output file exists, will overwrite." << endl;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment