mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-28 19:27:10 +00:00
Merge branch 'master' into v0.6.0
# Conflicts: # src/ifcconvert/IfcConvert.cpp # src/ifcgeom/IfcGeomRenderStyles.cpp # src/ifcparse/IfcParse.cpp
This commit is contained in:
@@ -425,6 +425,10 @@ IF(MSVC)
|
|||||||
# Disable overeager and false positives causing C4458 ("declaration of 'indentifier' hides class member"), at least for now.
|
# Disable overeager and false positives causing C4458 ("declaration of 'indentifier' hides class member"), at least for now.
|
||||||
ADD_DEFINITIONS(-wd4458)
|
ADD_DEFINITIONS(-wd4458)
|
||||||
ENDIF()
|
ENDIF()
|
||||||
|
# Enforce standards-conformance on VS > 2015, older Boost versions fail to compile with this
|
||||||
|
if (MSVC_VERSION GREATER 1900 AND (Boost_MAJOR_VERSION GREATER 1 OR Boost_MINOR_VERSION GREATER 66))
|
||||||
|
add_definitions(-permissive-)
|
||||||
|
endif()
|
||||||
# Link against the static VC runtime
|
# Link against the static VC runtime
|
||||||
# TODO Make this configurable
|
# TODO Make this configurable
|
||||||
IF("$ENV{CONDA_BUILD}" STREQUAL "")
|
IF("$ENV{CONDA_BUILD}" STREQUAL "")
|
||||||
|
|||||||
+2
-1
@@ -273,7 +273,8 @@ CMAKE_VERSION_2=CMAKE_VERSION[:CMAKE_VERSION.rindex('.')]
|
|||||||
OCE_LOCATION="https://github.com/tpaviot/oce/archive/OCE-%s.tar.gz" % (OCE_VERSION,)
|
OCE_LOCATION="https://github.com/tpaviot/oce/archive/OCE-%s.tar.gz" % (OCE_VERSION,)
|
||||||
BOOST_LOCATION="http://downloads.sourceforge.net/project/boost/boost/%s/boost_%s.tar.bz2" % (BOOST_VERSION, BOOST_VERSION_UNDERSCORE)
|
BOOST_LOCATION="http://downloads.sourceforge.net/project/boost/boost/%s/boost_%s.tar.bz2" % (BOOST_VERSION, BOOST_VERSION_UNDERSCORE)
|
||||||
OPENCOLLADA_LOCATION="https://github.com/KhronosGroup/OpenCOLLADA.git"
|
OPENCOLLADA_LOCATION="https://github.com/KhronosGroup/OpenCOLLADA.git"
|
||||||
OPENCOLLADA_COMMIT="f99d59e73e565a41715eaebc00c7664e1ee5e628"
|
#OPENCOLLADA_COMMIT="f99d59e73e565a41715eaebc00c7664e1ee5e628"
|
||||||
|
OPENCOLLADA_COMMIT="v1.6.63"
|
||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@
|
|||||||
|
|
||||||
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
|
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
|
||||||
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
||||||
|
#include "../ifcgeom_schema_agnostic/IfcGeomRenderStyles.h"
|
||||||
|
|
||||||
#include <Standard_Version.hxx>
|
#include <Standard_Version.hxx>
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <boost/program_options.hpp>
|
#include <boost/program_options.hpp>
|
||||||
|
#include <boost/make_shared.hpp>
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
@@ -177,6 +179,7 @@ int main(int argc, char** argv)
|
|||||||
exclusion_filter exclude_filter;
|
exclusion_filter exclude_filter;
|
||||||
exclusion_traverse_filter exclude_traverse_filter;
|
exclusion_traverse_filter exclude_traverse_filter;
|
||||||
std::string filter_filename;
|
std::string filter_filename;
|
||||||
|
std::string default_material_filename;
|
||||||
|
|
||||||
po::options_description geom_options("Geometry options");
|
po::options_description geom_options("Geometry options");
|
||||||
geom_options.add_options()
|
geom_options.add_options()
|
||||||
@@ -257,8 +260,10 @@ int main(int argc, char** argv)
|
|||||||
"Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")
|
"Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")
|
||||||
("generate-uvs",
|
("generate-uvs",
|
||||||
"Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
|
"Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
|
||||||
"Not guaranteed to work properly if used with --weld-vertices.");
|
"Not guaranteed to work properly if used with --weld-vertices.")
|
||||||
|
("default-material-file", po::value<std::string>(&default_material_filename),
|
||||||
|
"Specifies a material file that describes the material object types will have"
|
||||||
|
"if an object does not have any specified material in the IFC file.");
|
||||||
|
|
||||||
std::string bounds, offset_str;
|
std::string bounds, offset_str;
|
||||||
#ifdef HAVE_ICU
|
#ifdef HAVE_ICU
|
||||||
@@ -489,6 +494,17 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!default_material_filename.empty()) {
|
||||||
|
try {
|
||||||
|
IfcGeom::set_default_style_file(default_material_filename);
|
||||||
|
} catch (const std::exception& e) {
|
||||||
|
std::cerr << "[Error] Could not read default material file " << default_material_filename << ":" << std::endl;
|
||||||
|
std::cerr << e.what() << std::endl;
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// @todo Clean up this filter code further.
|
/// @todo Clean up this filter code further.
|
||||||
std::vector<geom_filter> used_filters;
|
std::vector<geom_filter> used_filters;
|
||||||
if (include_filter.type != geom_filter::UNUSED) { used_filters.push_back(include_filter); }
|
if (include_filter.type != geom_filter::UNUSED) { used_filters.push_back(include_filter); }
|
||||||
@@ -535,7 +551,7 @@ int main(int argc, char** argv)
|
|||||||
settings.set_deflection_tolerance(deflection_tolerance);
|
settings.set_deflection_tolerance(deflection_tolerance);
|
||||||
settings.precision = precision;
|
settings.precision = precision;
|
||||||
|
|
||||||
GeometrySerializer* serializer;
|
boost::shared_ptr<GeometrySerializer> serializer; /**< @todo use std::unique_ptr when possible */
|
||||||
if (output_extension == ".obj") {
|
if (output_extension == ".obj") {
|
||||||
// Do not use temp file for MTL as it's such a small file.
|
// Do not use temp file for MTL as it's such a small file.
|
||||||
const std::string mtl_filename = change_extension(output_filename, "mtl");
|
const std::string mtl_filename = change_extension(output_filename, "mtl");
|
||||||
@@ -543,28 +559,28 @@ int main(int argc, char** argv)
|
|||||||
Logger::Notice("Using world coords when writing WaveFront OBJ files");
|
Logger::Notice("Using world coords when writing WaveFront OBJ files");
|
||||||
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true);
|
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true);
|
||||||
}
|
}
|
||||||
serializer = new WaveFrontOBJSerializer(output_temp_filename, mtl_filename, settings);
|
serializer = boost::make_shared<WaveFrontOBJSerializer>(output_temp_filename, mtl_filename, settings);
|
||||||
#ifdef WITH_OPENCOLLADA
|
#ifdef WITH_OPENCOLLADA
|
||||||
} else if (output_extension == ".dae") {
|
} else if (output_extension == ".dae") {
|
||||||
serializer = new ColladaSerializer(output_temp_filename, settings);
|
serializer = boost::make_shared<ColladaSerializer>(output_temp_filename, settings);
|
||||||
#endif
|
#endif
|
||||||
} else if (output_extension == ".stp") {
|
} else if (output_extension == ".stp") {
|
||||||
serializer = new StepSerializer(output_temp_filename, settings);
|
serializer = boost::make_shared<StepSerializer>(output_temp_filename, settings);
|
||||||
} else if (output_extension == ".igs") {
|
} else if (output_extension == ".igs") {
|
||||||
#if OCC_VERSION_HEX < 0x60900
|
#if OCC_VERSION_HEX < 0x60900
|
||||||
// According to https://tracker.dev.opencascade.org/view.php?id=25689 something has been fixed in 6.9.0
|
// According to https://tracker.dev.opencascade.org/view.php?id=25689 something has been fixed in 6.9.0
|
||||||
IGESControl_Controller::Init(); // work around Open Cascade bug
|
IGESControl_Controller::Init(); // work around Open Cascade bug
|
||||||
#endif
|
#endif
|
||||||
serializer = new IgesSerializer(output_temp_filename, settings);
|
serializer = boost::make_shared<IgesSerializer>(output_temp_filename, settings);
|
||||||
} else if (output_extension == ".svg") {
|
} else if (output_extension == ".svg") {
|
||||||
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
|
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
|
||||||
serializer = new SvgSerializer(output_temp_filename, settings);
|
serializer = boost::make_shared<SvgSerializer>(output_temp_filename, settings);
|
||||||
if (vmap.count("section-height") != 0) {
|
if (vmap.count("section-height") != 0) {
|
||||||
Logger::Notice("Overriding section height");
|
Logger::Notice("Overriding section height");
|
||||||
static_cast<SvgSerializer*>(serializer)->setSectionHeight(section_height);
|
static_cast<SvgSerializer*>(serializer.get())->setSectionHeight(section_height);
|
||||||
}
|
}
|
||||||
if (bounding_width.is_initialized() && bounding_height.is_initialized()) {
|
if (bounding_width.is_initialized() && bounding_height.is_initialized()) {
|
||||||
static_cast<SvgSerializer*>(serializer)->setBoundingRectangle(bounding_width.get(), bounding_height.get());
|
static_cast<SvgSerializer*>(serializer.get())->setBoundingRectangle(bounding_width.get(), bounding_height.get());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "[Error] Unknown output filename extension '" + output_extension + "'\n";
|
std::cerr << "[Error] Unknown output filename extension '" + output_extension + "'\n";
|
||||||
@@ -573,13 +589,11 @@ int main(int argc, char** argv)
|
|||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE After this point, make sure to delete serializer upon application exit.
|
|
||||||
|
|
||||||
if (use_element_hierarchy && output_extension != ".dae") {
|
if (use_element_hierarchy && output_extension != ".dae") {
|
||||||
std::cerr << "[Error] --use-element-hierarchy can be used only with .dae output.\n";
|
std::cerr << "[Error] --use-element-hierarchy can be used only with .dae output.\n";
|
||||||
|
/// @todo Lots of duplicate error-and-exit code.
|
||||||
write_log(!quiet);
|
write_log(!quiet);
|
||||||
print_usage();
|
print_usage();
|
||||||
delete serializer;
|
|
||||||
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
@@ -600,7 +614,6 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!serializer->ready()) {
|
if (!serializer->ready()) {
|
||||||
delete serializer;
|
|
||||||
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
||||||
write_log(!quiet);
|
write_log(!quiet);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@@ -610,6 +623,8 @@ int main(int argc, char** argv)
|
|||||||
time(&start);
|
time(&start);
|
||||||
|
|
||||||
if (!init_input_file(input_filename, ifc_file, no_progress || quiet, mmap)) {
|
if (!init_input_file(input_filename, ifc_file, no_progress || quiet, mmap)) {
|
||||||
|
write_log(!quiet);
|
||||||
|
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -618,7 +633,6 @@ int main(int argc, char** argv)
|
|||||||
/// @todo It would be nice to know and print separate error prints for a case where we found no entities
|
/// @todo It would be nice to know and print separate error prints for a case where we found no entities
|
||||||
/// and for a case we found no entities that satisfy our filtering criteria.
|
/// and for a case we found no entities that satisfy our filtering criteria.
|
||||||
Logger::Error("No geometrical entities found");
|
Logger::Error("No geometrical entities found");
|
||||||
delete serializer;
|
|
||||||
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
||||||
write_log(!quiet);
|
write_log(!quiet);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@@ -641,7 +655,6 @@ int main(int argc, char** argv)
|
|||||||
if (center_model) {
|
if (center_model) {
|
||||||
if (site_local_placement || building_local_placement) {
|
if (site_local_placement || building_local_placement) {
|
||||||
Logger::Error("Cannot use --center-model together with --{site,building}-local-placement");
|
Logger::Error("Cannot use --center-model together with --{site,building}-local-placement");
|
||||||
delete serializer;
|
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -658,7 +671,6 @@ int main(int argc, char** argv)
|
|||||||
} else {
|
} else {
|
||||||
if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) {
|
if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) {
|
||||||
std::cerr << "[Error] Invalid use of --model-offset\n";
|
std::cerr << "[Error] Invalid use of --model-offset\n";
|
||||||
delete serializer;
|
|
||||||
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
std::remove(output_temp_filename.c_str()); /**< @todo Windows Unicode support */
|
||||||
print_options(serializer_options);
|
print_options(serializer_options);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
@@ -732,7 +744,8 @@ int main(int argc, char** argv)
|
|||||||
}
|
}
|
||||||
|
|
||||||
serializer->finalize();
|
serializer->finalize();
|
||||||
delete serializer;
|
// Make sure the dtor is explicitly run here (e.g. output files are closed before renaming them).
|
||||||
|
serializer.reset();
|
||||||
|
|
||||||
// Renaming might fail (e.g. maybe the existing file was open in a viewer application)
|
// Renaming might fail (e.g. maybe the existing file was open in a viewer application)
|
||||||
// Do not remove the temp file as user can salvage the conversion result from it.
|
// Do not remove the temp file as user can salvage the conversion result from it.
|
||||||
|
|||||||
@@ -387,7 +387,18 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l
|
|||||||
try {
|
try {
|
||||||
builder.Perform();
|
builder.Perform();
|
||||||
shape = builder.SewedShape();
|
shape = builder.SewedShape();
|
||||||
valid_shell = BRepCheck_Analyzer(shape).IsValid() != 0 && count(shape, TopAbs_SHELL) > 0;
|
|
||||||
|
{
|
||||||
|
BRepCheck_Analyzer ana(shape);
|
||||||
|
if (!ana.IsValid()) {
|
||||||
|
ShapeFix_Shape sfs(shape);
|
||||||
|
sfs.Perform();
|
||||||
|
shape = sfs.Shape();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BRepCheck_Analyzer ana(shape);
|
||||||
|
valid_shell = ana.IsValid() != 0 && count(shape, TopAbs_SHELL) > 0;
|
||||||
} catch (const Standard_Failure& e) {
|
} catch (const Standard_Failure& e) {
|
||||||
if (e.GetMessageString() && strlen(e.GetMessageString())) {
|
if (e.GetMessageString() && strlen(e.GetMessageString())) {
|
||||||
Logger::Error(e.GetMessageString());
|
Logger::Error(e.GetMessageString());
|
||||||
|
|||||||
@@ -270,10 +270,15 @@ namespace IfcGeom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (representations->size() == 0) {
|
if (representations->size() == 0) {
|
||||||
Logger::Message(Logger::LOG_ERROR, "No geometries found");
|
Logger::Message(Logger::LOG_ERROR, "No representations encountered in relevant contexts, using all");
|
||||||
return false;
|
representations = ifc_file->instances_by_type<IfcSchema::IfcRepresentation>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (representations->size() == 0) {
|
||||||
|
Logger::Message(Logger::LOG_ERROR, "No representations encountered, aborting");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
representation_iterator = representations->begin();
|
representation_iterator = representations->begin();
|
||||||
ifcproducts.reset();
|
ifcproducts.reset();
|
||||||
|
|
||||||
@@ -402,19 +407,30 @@ namespace IfcGeom {
|
|||||||
for (;;) {
|
for (;;) {
|
||||||
IfcSchema::IfcRepresentation* representation;
|
IfcSchema::IfcRepresentation* representation;
|
||||||
|
|
||||||
// Have we reached the end of our list of representations?
|
|
||||||
if ( representation_iterator == representations->end() ) {
|
if ( representation_iterator == representations->end() ) {
|
||||||
representations.reset();
|
representations.reset();
|
||||||
return 0;
|
return 0; // reached the end of our list of representations
|
||||||
}
|
}
|
||||||
representation = *representation_iterator;
|
representation = *representation_iterator;
|
||||||
|
|
||||||
// Has the list of IfcProducts for this representation been initialized?
|
|
||||||
if (!ifcproducts) {
|
if (!ifcproducts) {
|
||||||
|
// Init. the list of filtered IfcProducts for this representation
|
||||||
ifcproducts = IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
|
ifcproducts = IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
|
||||||
IfcSchema::IfcProduct::list::ptr unfiltered_products = kernel.products_represented_by(representation);
|
IfcSchema::IfcProduct::list::ptr unfiltered_products = kernel.products_represented_by(representation);
|
||||||
|
// Include only the desired products for processing.
|
||||||
|
for (IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt) {
|
||||||
|
IfcSchema::IfcProduct* prod = *jt;
|
||||||
|
if (boost::all(filters_, filter_match(prod))) {
|
||||||
|
ifcproducts->push(prod);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
geometry_reuse_ok_for_current_representation_ = reuse_ok_(unfiltered_products);
|
if (ifcproducts->size() == 0) {
|
||||||
|
_nextShape();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
geometry_reuse_ok_for_current_representation_ = reuse_ok_(ifcproducts);
|
||||||
|
|
||||||
IfcSchema::IfcRepresentationMap::list::ptr maps = representation->RepresentationMap();
|
IfcSchema::IfcRepresentationMap::list::ptr maps = representation->RepresentationMap();
|
||||||
|
|
||||||
@@ -432,13 +448,12 @@ namespace IfcGeom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if this represenation has (or will be) processed as part its mapped representation
|
||||||
bool representation_processed_as_mapped_item = false;
|
bool representation_processed_as_mapped_item = false;
|
||||||
|
IfcSchema::IfcRepresentation* representation_mapped_to = kernel.representation_mapped_to(representation);
|
||||||
IfcSchema::IfcRepresentation* representation_mapped_to = kernel.representation_mapped_to(representation);
|
|
||||||
if (representation_mapped_to) {
|
if (representation_mapped_to) {
|
||||||
// Check if this representation has (or will be) processed as part its mapped representation
|
representation_processed_as_mapped_item = geometry_reuse_ok_for_current_representation_ ||
|
||||||
representation_processed_as_mapped_item = ok_mapped_representations->contains(representation_mapped_to) ||
|
ok_mapped_representations->contains(representation_mapped_to);
|
||||||
reuse_ok_(kernel.products_represented_by(representation_mapped_to));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (representation_processed_as_mapped_item) {
|
if (representation_processed_as_mapped_item) {
|
||||||
@@ -447,14 +462,6 @@ namespace IfcGeom {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Filter the products based on the set of entities and/or names being included or excluded for processing.
|
|
||||||
for (IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt) {
|
|
||||||
IfcSchema::IfcProduct* prod = *jt;
|
|
||||||
if (boost::all(filters_, filter_match(prod))) {
|
|
||||||
ifcproducts->push(prod);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ifcproduct_iterator = ifcproducts->begin();
|
ifcproduct_iterator = ifcproducts->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,8 @@ namespace IfcGeom {
|
|||||||
boost::optional<double>& Specularity() { return specularity; }
|
boost::optional<double>& Specularity() { return specularity; }
|
||||||
};
|
};
|
||||||
|
|
||||||
IFC_GEOM_API const SurfaceStyle* get_default_style(const std::string& ifc_type);
|
IFC_GEOM_API const SurfaceStyle* get_default_style(const std::string& ifc_type);
|
||||||
|
IFC_GEOM_API void set_default_style_file(const std::string& json_file);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
#include "../ifcgeom_schema_agnostic/IfcGeomRenderStyles.h"
|
#include "../ifcgeom_schema_agnostic/IfcGeomRenderStyles.h"
|
||||||
|
|
||||||
|
#include <boost/property_tree/json_parser.hpp>
|
||||||
|
#include <boost/property_tree/ptree.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
|
namespace pt = boost::property_tree;
|
||||||
|
|
||||||
static std::map<std::string, IfcGeom::SurfaceStyle> default_materials;
|
static std::map<std::string, IfcGeom::SurfaceStyle> default_materials;
|
||||||
static IfcGeom::SurfaceStyle default_material;
|
static IfcGeom::SurfaceStyle default_material;
|
||||||
static bool default_materials_initialized = false;
|
static bool default_materials_initialized = false;
|
||||||
@@ -44,12 +49,72 @@ void InitDefaultMaterials() {
|
|||||||
default_materials_initialized = true;
|
default_materials_initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
boost::optional<IfcGeom::SurfaceStyle::ColorComponent> read_colour_component(const boost::optional<pt::ptree&> list) {
|
||||||
|
if (!list) {
|
||||||
|
return boost::none;
|
||||||
|
}
|
||||||
|
double rgb[3];
|
||||||
|
int i = 0;
|
||||||
|
for (pt::ptree::value_type &colour : list.get()) {
|
||||||
|
if (3 <= i) {
|
||||||
|
throw std::runtime_error("rgb array over 3 elements large");
|
||||||
|
}
|
||||||
|
rgb[i] = colour.second.get_value<double>();
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if (i != 3) {
|
||||||
|
throw std::runtime_error("rgb array less than 3 elements large (was " + std::to_string(i) + ")");
|
||||||
|
}
|
||||||
|
return IfcGeom::SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IfcGeom::set_default_style_file(const std::string& json_file) {
|
||||||
|
if (!default_materials_initialized) InitDefaultMaterials();
|
||||||
|
default_materials.clear();
|
||||||
|
|
||||||
|
pt::ptree root;
|
||||||
|
pt::read_json(json_file, root);
|
||||||
|
|
||||||
|
for (pt::ptree::value_type &material_pair : root) {
|
||||||
|
std::string name = material_pair.first;
|
||||||
|
default_materials.insert(std::make_pair(name, IfcGeom::SurfaceStyle(name)));
|
||||||
|
|
||||||
|
pt::ptree material = material_pair.second;
|
||||||
|
boost::optional<pt::ptree&> diffuse = material.get_child_optional("diffuse");
|
||||||
|
default_materials[name].Diffuse() = read_colour_component(diffuse);
|
||||||
|
|
||||||
|
boost::optional<pt::ptree&> specular = material.get_child_optional("specular");
|
||||||
|
default_materials[name].Specular() = read_colour_component(specular);
|
||||||
|
|
||||||
|
if (material.get_child_optional("specular-roughness")) {
|
||||||
|
default_materials[name].Specularity().reset(1.0 / material.get<double>("specular-roughness"));
|
||||||
|
}
|
||||||
|
if (material.get_child_optional("transparency")) {
|
||||||
|
default_materials[name].Transparency() = material.get<double>("transparency");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is "*" present? If yes, remove it and make it the default style.
|
||||||
|
std::map<std::string, IfcGeom::SurfaceStyle>::const_iterator it = default_materials.find("*");
|
||||||
|
if (it != default_materials.end()) {
|
||||||
|
IfcGeom::SurfaceStyle star = it->second;
|
||||||
|
default_material.Diffuse() = star.Diffuse();
|
||||||
|
default_material.Specular() = star.Specular();
|
||||||
|
default_material.Specularity() = star.Specularity();
|
||||||
|
default_material.Transparency() = star.Transparency();
|
||||||
|
default_materials.erase(it);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const IfcGeom::SurfaceStyle* IfcGeom::get_default_style(const std::string& s) {
|
const IfcGeom::SurfaceStyle* IfcGeom::get_default_style(const std::string& s) {
|
||||||
if (!default_materials_initialized) InitDefaultMaterials();
|
if (!default_materials_initialized) InitDefaultMaterials();
|
||||||
std::map<std::string, IfcGeom::SurfaceStyle>::const_iterator it = default_materials.find(s);
|
std::map<std::string, IfcGeom::SurfaceStyle>::const_iterator it = default_materials.find(s);
|
||||||
if (it == default_materials.end()) {
|
if (it == default_materials.end()) {
|
||||||
default_materials.insert(std::make_pair(s, IfcGeom::SurfaceStyle(s)));
|
default_materials.insert(std::make_pair(s, IfcGeom::SurfaceStyle(s)));
|
||||||
default_materials[s].Diffuse().reset(*default_material.Diffuse());
|
default_materials[s].Diffuse() = default_material.Diffuse();
|
||||||
|
default_materials[s].Specular() = default_material.Specular();
|
||||||
|
default_materials[s].Specularity() = default_material.Specularity();
|
||||||
|
default_materials[s].Transparency() = default_material.Transparency();
|
||||||
it = default_materials.find(s);
|
it = default_materials.find(s);
|
||||||
}
|
}
|
||||||
const IfcGeom::SurfaceStyle& surface_style = it->second;
|
const IfcGeom::SurfaceStyle& surface_style = it->second;
|
||||||
|
|||||||
@@ -1320,8 +1320,6 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
good_ = true;
|
|
||||||
|
|
||||||
tokens = new IfcSpfLexer(stream, this);
|
tokens = new IfcSpfLexer(stream, this);
|
||||||
_header.file(this);
|
_header.file(this);
|
||||||
_header.tryRead();
|
_header.tryRead();
|
||||||
@@ -1339,18 +1337,16 @@ void IfcFile::initialize_(IfcParse::IfcSpfStream* s) {
|
|||||||
} catch (const IfcParse::IfcException& e) {
|
} catch (const IfcParse::IfcException& e) {
|
||||||
Logger::Error(e);
|
Logger::Error(e);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema_ == 0 && schemas.front().substr(0, 4) == "IFC2") {
|
|
||||||
Logger::Message(Logger::LOG_ERROR, schemas.front() + " not supported, using IFC2X3 instead");
|
|
||||||
schema_ = IfcParse::schema_by_name("IFC2X3");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (schema_ == 0) {
|
if (schema_ == 0) {
|
||||||
schema_ = IfcParse::schema_by_name("IFC4");
|
Logger::Message(Logger::LOG_ERROR, "No support for file schema encountered ("
|
||||||
Logger::Message(Logger::LOG_ERROR, "Unable to deduce schema version from header identifiers, defaulting to IFC4");
|
+ boost::algorithm::join(schemas, ", ") + ")");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
good_ = true;
|
||||||
|
|
||||||
ifcroot_type_ = schema_->declaration_by_name("IfcRoot");
|
ifcroot_type_ = schema_->declaration_by_name("IfcRoot");
|
||||||
|
|
||||||
boost::circular_buffer<Token> token_stream(3, Token());
|
boost::circular_buffer<Token> token_stream(3, Token());
|
||||||
|
|||||||
Reference in New Issue
Block a user