std::string GetFilenameWithoutExtension(const filesystem::path& filePath) { auto extension = filePath.extension(); auto filename = filePath.filename(); return !extension.empty() ? filename.substr(0, filename.length() - extension.length() - 1) : filename; }
bool Parser::ParseWorkspace(const filesystem::path& filePath) { if (filePath.str().empty()) { std::cout << "invalid workspace filename" << std::endl; return false; } WorkingDirectory::SetCurrent(filePath.make_absolute().parent_path().str()); std::cout << "{ cwd : " << WorkingDirectory::GetCurrent() << " }" << std::endl; internal::EnsureDirectoryExists(outputDirectory_); auto workspace = JsonImporter::ImportWorkspace(pimpl_->GetFileManager(), filePath.filename()); return ParseWorkspace(workspace.get()); }
//! The function stores the specified file in the storage void file_collector::store_file(filesystem::path const& src_path) { // NOTE FOR THE FOLLOWING CODE: // Avoid using Boost.Filesystem functions that would call path::codecvt(). store_file() can be called // at process termination, and the global codecvt facet can already be destroyed at this point. // https://svn.boost.org/trac/boost/ticket/8642 // Let's construct the new file name file_info info; info.m_TimeStamp = filesystem::last_write_time(src_path); info.m_Size = filesystem::file_size(src_path); filesystem::path file_name_path = src_path.filename(); path_string_type file_name = file_name_path.native(); info.m_Path = m_StorageDir / file_name_path; // Check if the file is already in the target directory filesystem::path src_dir = src_path.has_parent_path() ? filesystem::system_complete(src_path.parent_path()) : m_BasePath; const bool is_in_target_dir = filesystem::equivalent(src_dir, m_StorageDir); if (!is_in_target_dir) { if (filesystem::exists(info.m_Path)) { // If the file already exists, try to mangle the file name // to ensure there's no conflict. I'll need to make this customizable some day. file_counter_formatter formatter(file_name.size(), 5); unsigned int n = 0; do { path_string_type alt_file_name = formatter(file_name, n++); info.m_Path = m_StorageDir / filesystem::path(alt_file_name); } while (filesystem::exists(info.m_Path) && n < (std::numeric_limits< unsigned int >::max)()); } // The directory should have been created in constructor, but just in case it got deleted since then... filesystem::create_directories(m_StorageDir); } BOOST_LOG_EXPR_IF_MT(lock_guard< mutex > lock(m_Mutex);)
//! Acquires file name string from the path static path_string_type filename_string(filesystem::path const& p) { return p.filename().string< path_string_type >(); }
void Scene::load(const filesystem::path &file) { size_t i; std::string message; if(!filesystem::exists(file)) throw std::runtime_error(std::string("File does not exists:") + file.string()); this->collada = new DAE; message = "Start loading COLLADA DOM from "; message += file.string(); this->scene_graph.printStatusMessage(message); this->dae_file_name = file; // load with full path domCOLLADA *dom = this->collada->open(file.string()); if(!dom) { delete this->collada; throw std::runtime_error(std::string("Error loading the COLLADA file ") + file.string() + ". Make sure it is COLLADA 1.4 or greater"); } this->scene_graph.printStatusMessage("Begin conditioning"); //if(kmzcleanup(this->collada, true)) // std::cout << " kmzcleanup complete\n"; int res = 0; this->scene_graph.printStatusMessage(" triangulating"); res = triangulate(this->collada); if(res) { std::ostringstream os; os << " triangulation returns error " << res << std::ends; this->scene_graph.printStatusMessage(os.str()); } else this->scene_graph.printStatusMessage(std::string(" triangulation complete")); /* this->scene_graph.printStatusMessage(std::string(" deindexing")); res = deindex(this->collada); if(res) { std::ostringstream os; os << " deindexer returns error " << res << std::ends; this->scene_graph.printStatusMessage(os.str()); } else this->scene_graph.printStatusMessage(std::string(" deindexing complete")); */ this->scene_graph.printStatusMessage(std::string("Finish conditioning.")); // Need to get the asset tag which will determine what vector x y or z is up. Typically y or z. domAssetRef asset = dom->getAsset(); this->scene_graph.printStatusMessage(std::string("File information:")); const domAsset::domContributor_Array &contributors = asset->getContributor_array(); for(i = 0; i < contributors.getCount(); ++i) { domAsset::domContributorRef c = contributors.get(i); this->scene_graph.printStatusMessage(std::string(" author:") + c->getAuthor()->getCharData()); this->scene_graph.printStatusMessage(std::string(" authoring tool:") + c->getAuthoring_tool()->getCharData()); } if(asset->getCreated()) this->scene_graph.printStatusMessage(std::string(" created: ") + asset->getCreated()->getCharData()); if(asset->getModified()) this->scene_graph.printStatusMessage(std::string(" modified: ") + asset->getModified()->getCharData()); if(asset->getUnit()) { std::ostringstream os; os << " units: " << asset->getUnit()->getMeter() << " meter (" << asset->getUnit()->getAttribute("name") << ")"; os << std::ends; this->scene_graph.printStatusMessage(os.str()); } if(asset->getUp_axis()) { domAsset::domUp_axis *up = dom->getAsset()->getUp_axis(); if(up) this->up_axis = up->getValue(); switch(this->up_axis) { case UPAXISTYPE_X_UP: this->scene_graph.printStatusMessage(std::string(" X axis is UP axis.")); break; case UPAXISTYPE_Y_UP: this->scene_graph.printStatusMessage(std::string(" Y axis is UP axis.")); break; case UPAXISTYPE_Z_UP: this->scene_graph.printStatusMessage(std::string(" Z axis is UP axis.")); break; default: break; } } this->scene_graph.printStatusMessage("Building libraries"); // Load the image for the default texture. const Image::ImageID image_key = {"default", ""}; bool inserted; Image::ImageList::iterator img_iter; tie(img_iter, inserted) = this->scene_graph.all_images.insert(std::make_pair(image_key, Image())); Image &img = img_iter->second; img.image = IMG_Load("default.tga"); if(!img.image) { scene_graph.all_images.erase(image_key); this->scene_graph.printStatusMessage("Can not load default.tga for the default texture."); } this->scene_graph.printStatusMessage(" Load image libraries"); const domLibrary_images_Array &ia = dom->getLibrary_images_array(); for(i = 0; i < ia.getCount(); ++i) this->readImageLibrary(ia[i]); this->scene_graph.printStatusMessage(" Load effect libraries"); const domLibrary_effects_Array &ea = dom->getLibrary_effects_array(); for(i = 0; i < ea.getCount(); i++) this->readEffectLibrary(ea[i]); this->scene_graph.printStatusMessage(" Load material libraries"); const domLibrary_materials_Array &ma = dom->getLibrary_materials_array(); for(i = 0; i < ma.getCount(); i++) this->readMaterialLibrary(ma[i]); this->scene_graph.printStatusMessage(" Load animation libraries"); const domLibrary_animations_Array &aa = dom->getLibrary_animations_array(); for(i = 0; i < aa.getCount(); i++) this->readAnimationLibrary(aa[i]); // Find the scene we want domCOLLADA::domSceneRef domScene = dom->getScene(); daeElement* defaultScene = NULL; if (domScene) if (domScene->getInstance_visual_scene()) if (domScene->getInstance_visual_scene()) defaultScene = domScene->getInstance_visual_scene()->getUrl().getElement(); if(defaultScene) this->readScene((domVisual_scene*)defaultScene); // If no lights were loaded, we need to make one so the scene won't be totally black if(this->scene_graph.all_lights.empty()) { // new Light this->scene_graph.printStatusMessage("Scene: no lights were loaded. Creating a default light"); const Light::LightID light_key = {"no_light_in_scene_default_light", dom->getDocumentURI()->getURI()}; bool inserted; Light::LightList::iterator light; tie(light, inserted) = scene_graph.all_lights.insert(std::make_pair(light_key, Light())); Light &default_light = light->second; default_light.type = Light::DIRECTIONAL; default_light.color = Color4f(1, 1, 1, 1); // new Node this->scene_graph.printStatusMessage("Scene: no instance_light found creating a node with an instance"); this->scene_graph.insertNode(this->scene_graph.root, "no_light_in_scene_default_node", "no_light_in_scene_default_node", "NONE"); // Read node transformations Node ¤t_node = *this->scene_graph.all_nodes.find("no_light_in_scene_default_node"); current_node.transformations.push_back(Transformation()); Transformation &transform = current_node.transformations.at(current_node.transformations.size() - 1); transform.type = Transformation::Translate; const Vector3 trans(-40.0, 40.0, 0.0); transform.transform = Transform3::translation(trans); // new InstanceLight InstanceLight instance_light; instance_light.abstract_light_ref = light->first; current_node.instance_lights.push_back(instance_light); this->scene_graph.light_nodes.push_back("no_light_in_scene_default_node"); } if(!this->scene_graph.all_cameras.empty()) { // Search for the first camera node Node::NodeMap &all_nodes = this->scene_graph.all_nodes; for(int n = 0; n < all_nodes.size(); ++n) { Node *node = all_nodes.getAtIndex(n); if(node->instance_cameras.size() > 0) { this->scene_graph.active_camera_info = std::make_pair(node, &(node->instance_cameras[0])); break; } } } else { this->scene_graph.printStatusMessage( "Scene: create a default camera and it is the first camera to use"); // new Camera const Camera::CameraID camera_key = {"no_camera_in_scene_default_camera", dom->getDocumentURI()->getURI()}; // Make the camera bool inserted; Camera::CameraList::iterator camera; tie(camera, inserted) = this->scene_graph.all_cameras.insert(std::make_pair(camera_key, Camera())); Camera &default_camera = camera->second; default_camera.Xfov = 45.0f; default_camera.Yfov = 45.0f; this->scene_graph.printStatusMessage( "Scene: creating a node with an instance of default camera"); // new Node this->scene_graph.insertNode(this->scene_graph.root, "no_camera_in_scene_default_node", "no_camera_in_scene_default_node", "NONE"); // Read node transformations Node ¤t_node = *this->scene_graph.all_nodes.find("no_camera_in_scene_default_node"); // Calculate approximate bounding box for the model Vector3 max(0,0,0); Vector3 min(0,0,0); for(Geometry::GeometryList::const_iterator g = this->scene_graph.all_geometries.begin(); g != this->scene_graph.all_geometries.end(); ++g) { // Points are stored as x/y/z tripples within this array for(Geometry::PointList::const_iterator p = g->second.points.begin(); p != g->second.points.end(); ++p) { // X if(*p > max.getX()) max.setX(*p); else if(*p < min.getX()) min.setX(*p); // Y ++p; if(*p > max.getY()) max.setY(*p); else if(*p < min.getY()) min.setY(*p); // Z ++p; if(*p > max.getZ()) max.setZ(*p); else if(*p < min.getZ()) min.setZ(*p); } } default_camera.ZNear = 1.0f; default_camera.ZFar = 1000.0f; current_node.transformations.push_back(Transformation()); Transformation &transform = current_node.transformations.at(current_node.transformations.size() - 1); transform.type = Transformation::LookAt; const Point3 eyePos(max.getX() * 0.5f, max.getY() * 0.5f, max.getZ() * 0.5f); const Point3 lookAtPos(min.getX(), min.getY(), min.getZ()); Vector3 upVec; upVec.setY(0); if(this->up_axis == UPAXISTYPE_Z_UP) { upVec.setX(0); upVec.setZ(1.0f); } else if(this->up_axis == UPAXISTYPE_X_UP) { upVec.setX(1.0f); upVec.setZ(0); } // Store transformation transform.matrix = inverse(Matrix4::lookAt(eyePos, lookAtPos, upVec)); current_node.local_matrix *= transform.matrix; // new InstanceCamera InstanceCamera instance_camera; instance_camera.abstract_camera_ref = camera->first; current_node.instance_cameras.push_back(instance_camera); this->scene_graph.active_camera_info = std::make_pair(¤t_node, &(current_node.instance_cameras.at(current_node.instance_cameras.size() - 1))); } this->scene_graph.printStatusMessage(std::string("COLLADA_DOM runtime database initialized from ") + file.filename().string()); }