Newer
Older
//==========================================================================
// AIDA Detector description implementation
//--------------------------------------------------------------------------
// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN)
// All rights reserved.
//
// For the licensing terms see $DD4hepINSTALL/LICENSE.
// For the list of contributors see $DD4hepINSTALL/doc/CREDITS.
//
// Author : M.Frank
//
//==========================================================================
/// Framework include files
#include <DD4hep/Printout.h>
Markus FRANK
committed
#include <DD4hep/Detector.h>
#include <DDCAD/ASSIMPReader.h>
/// Open Asset Importer Library
#include "assimp/scene.h"
#include "assimp/postprocess.h"
#include "assimp/Importer.hpp"
/// C/C++ include files
#include <sstream>
using namespace dd4hep;
using namespace dd4hep::cad;
Markus FRANK
committed
std::vector<std::unique_ptr<TGeoTessellated> >
ASSIMPReader::readShapes(const std::string& source, double unit_length) const
{
using Vertex = TessellatedSolid::Vertex;
Markus FRANK
committed
std::vector<std::unique_ptr<TGeoTessellated> > result;
std::unique_ptr<Assimp::Importer> importer = std::make_unique<Assimp::Importer>();
int aiflags = aiProcess_Triangulate|aiProcess_JoinIdenticalVertices|aiProcess_CalcTangentSpace;
auto scene = importer->ReadFile( source.c_str(), aiflags);
if ( !scene ) {
except("ASSIMPReader","+++ FileNotFound: %s",source.c_str());
}
bool dump_facets = ((flags>>8)&0x1) == 1;
for (unsigned int index = 0; index < scene->mNumMeshes; index++) {
aiMesh* mesh = scene->mMeshes[index];
if ( mesh->mNumFaces > 0 ) {
auto name = mesh->mName.C_Str();
const aiVector3D* v = mesh->mVertices;
std::vector<Vertex> vertices;
vertices.reserve(mesh->mNumVertices);
for(unsigned int i=0; i < mesh->mNumVertices; i++) {
vertices.emplace_back(Vertex(v[i].x*unit, v[i].y*unit, v[i].z*unit));
}
TessellatedSolid shape(name, vertices);
for(unsigned int i=0; i < mesh->mNumFaces; i++) {
const unsigned int* idx = mesh->mFaces[i].mIndices;
shape->AddFacet(idx[0], idx[1], idx[2]);
Markus FRANK
committed
}
if ( shape->GetNfacets() > 2 ) {
shape->CloseShape(true,true,true);
if ( dump_facets ) {
for( size_t i=0, n=shape->GetNfacets(); i < n; ++i ) {
const auto& facet = shape->GetFacet(i);
std::stringstream str;
str << facet;
printout(ALWAYS,"ASSIMPReader","++ Facet %4ld : %s",
i, str.str().c_str());
}
}
Markus FRANK
committed
result.emplace_back(std::unique_ptr<TGeoTessellated>(shape.ptr()));
continue;
}
delete shape.ptr();
}
}
printout(ALWAYS,"ASSIMPReader","+++ Read %ld meshes from %s",
Markus Frank
committed
result.size(), source.c_str());
Markus FRANK
committed
return result;
}
/// Read input file and create a volume-set
std::vector<std::unique_ptr<TGeoVolume> >
ASSIMPReader::readVolumes(const std::string& source, double unit_length) const
{
using Vertex = TessellatedSolid::Vertex;
Markus FRANK
committed
std::vector<std::unique_ptr<TGeoVolume> > result;
std::unique_ptr<Assimp::Importer> importer = std::make_unique<Assimp::Importer>();
bool dump_facets = ((flags>>8)&0x1) == 1;
int aiflags = aiProcess_Triangulate|aiProcess_JoinIdenticalVertices|aiProcess_CalcTangentSpace;
auto scene = importer->ReadFile( source.c_str(), aiflags);
char text[1048];
Markus FRANK
committed
if ( !scene ) {
except("ASSIMPReader","+++ FileNotFound: %s",source.c_str());
}
double unit = unit_length;
for (unsigned int index = 0; index < scene->mNumMeshes; index++) {
aiMesh* mesh = scene->mMeshes[index];
if ( mesh->mNumFaces > 0 ) {
std::string name = mesh->mName.C_Str();
Markus FRANK
committed
const aiVector3D* v = mesh->mVertices;
std::vector<Vertex> vertices;
vertices.reserve(mesh->mNumVertices);
for(unsigned int i=0; i < mesh->mNumVertices; i++) {
vertices.emplace_back(Vertex(v[i].x*unit, v[i].y*unit, v[i].z*unit));
}
TessellatedSolid shape(name,vertices);
for(unsigned int i=0; i < mesh->mNumFaces; i++) {
const unsigned int* idx = mesh->mFaces[i].mIndices;
shape->AddFacet(idx[0], idx[1], idx[2]);
}
if ( shape->GetNfacets() > 2 ) {
Markus Frank
committed
Material mat;
VisAttr vis;
Markus FRANK
committed
if ( scene->HasMaterials() ) {
aiMaterial* ai_mat = scene->mMaterials[mesh->mMaterialIndex];
mat_name = ai_mat->GetName().C_Str();
mat = detector.material(mat_name);
Markus FRANK
committed
}
Markus Frank
committed
if ( !mat.isValid() ) {
printout(ERROR, "ASSIMPReader",
"+++ %s: No material named '%s' FOUND. Will use Air. [Missing material]",
text, mat_name.c_str());
Markus Frank
committed
mat = detector.air();
}
if ( name.empty() ) {
::snprintf(text,sizeof(text),"tessellated_%ld", result.size());
text[sizeof(text)-1] = 0;
name = text;
}
Volume vol(name, Solid(shape.ptr()), mat);
Markus Frank
committed
if ( mesh->HasVertexColors(0) ) {
const aiColor4D* col = mesh->mColors[0];
if ( col ) {
for( const auto& _v : detector.visAttributes() ) {
float ca, cr, cg, cb, eps = 0.05;
VisAttr(_v.second).argb(ca, cr, cg, cb);
if( std::abs(col->a-ca) < eps && std::abs(col->r-cr) < eps &&
std::abs(col->g-cg) < eps && std::abs(col->b-cb) < eps ) {
vis = _v.second;
break;
}
}
if ( !vis.isValid() ) {
::snprintf(text,sizeof(text),"vis_%s_%p", name.c_str(), (void*)vol.ptr());
Markus Frank
committed
text[sizeof(text)-1] = 0;
vis = VisAttr(text);
vis.setColor(col->a,col->r,col->g,col->b);
detector.add(vis);
}
vol.setVisAttributes(vis);
}
}
printout(INFO,"ASSIMPReader",
"+++ %-17s Material: %-16s Viualization: %s",
vol.name(), mat.name(), vis.isValid() ? vis.name() : "NONE");
shape->CloseShape(true,true,true);
if ( dump_facets ) {
for( size_t i=0, n=shape->GetNfacets(); i < n; ++i ) {
const auto& facet = shape->GetFacet(i);
std::stringstream str;
str << facet;
printout(ALWAYS,"ASSIMPReader","++ Facet %4ld : %s",
i, str.str().c_str());
}
}
Markus FRANK
committed
result.emplace_back(std::unique_ptr<TGeoVolume>(vol.ptr()));
continue;
}
delete shape.ptr();
}
}
Markus FRANK
committed
printout(ALWAYS,"ASSIMPReader","+++ Read %ld meshes from %s",
Markus Frank
committed
result.size(), source.c_str());