IfcConvert --precision option.

Sets the decimal precision to be used to format floating-point values, 15 by default.
Use a negative value to use the system's default precision (should be 6 typically).
Applicable for OBJ and DAE output. For DAE output, value >= 15 means that up to 16 decimals are used,
and any other value means that 6 or 7 decimals are used.
This commit is contained in:
Stinkfist0
2017-01-11 16:36:33 +02:00
committed by Thomas Krijnen
parent 2d58a1bc7c
commit ecff54c480
5 changed files with 36 additions and 15 deletions
+5 -3
View File
@@ -154,9 +154,11 @@ private:
COLLADASW::StreamWriter stream;
ColladaScene scene;
public:
ColladaExporter(const std::string& scene_name, const std::string& fn, ColladaSerializer *_serializer)
/// @param double_precision Whether to use "double precision" (up to 16 decimals) or not (6 or 7 decimals).
ColladaExporter(const std::string& scene_name, const std::string& fn, ColladaSerializer *_serializer,
bool double_precision)
: filename(fn)
, stream(filename, sizeof(real_t) == sizeof(double)) // utilise Collada stream's double precision feature
, stream(filename, double_precision)
, scene(scene_name, stream, _serializer)
, materials(stream, _serializer)
, geometries(stream, _serializer)
@@ -178,7 +180,7 @@ private:
public:
ColladaSerializer(const std::string& dae_filename, const SerializerSettings& settings)
: GeometrySerializer(settings)
, exporter("IfcOpenShell", dae_filename, this)
, exporter("IfcOpenShell", dae_filename, this, settings.precision >= 15)
{
exporter.serializer = this;
exporter.materials.serializer = this;
+7
View File
@@ -51,12 +51,19 @@ public:
};
SerializerSettings()
: precision(DEFAULT_PRECISION)
{
memset(offset, 0, sizeof(offset));
}
/// Optional offset that is applied to serialized objects, (0,0,0) by default.
double offset[3];
/// Sets the precision used to format floating-point values, 15 by default.
/// Use a negative value to use the system's default precision (should be 6 typically).
short precision;
static const short DEFAULT_PRECISION = 15;
};
class GeometrySerializer : public Serializer {
+16 -7
View File
@@ -192,7 +192,7 @@ int main(int argc, char** argv) {
"Disables computation of normals. Saves time and file size and is useful "
"in instances where you're going to recompute normals for the exported "
"model in other modelling application in any case.")
("deflection-tolerance", boost::program_options::value<double>(&deflection_tolerance),
("deflection-tolerance", boost::program_options::value<double>(&deflection_tolerance)->default_value(1e-3),
"Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")
("generate-uvs",
"Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
@@ -203,6 +203,7 @@ int main(int argc, char** argv) {
"--include --traverse --names \"Level 1\" includes entity with name \"Level 1\" and all of its children.");
std::string bounds;
short precision;
boost::program_options::options_description serializer_options("Serialization options");
serializer_options.add_options()
("bounds", boost::program_options::value<std::string>(&bounds),
@@ -219,7 +220,12 @@ int main(int argc, char** argv) {
"Applicable for OBJ and DAE output.")
("center-model",
"Centers the elements upon serialization by applying the center point of "
"all placements as an offset. Applicable for OBJ and DAE output.");
"all placements as an offset. Applicable for OBJ and DAE output.")
("precision", boost::program_options::value<short>(&precision)->default_value(SerializerSettings::DEFAULT_PRECISION),
"Sets the decimal precision to be used to format floating-point values, 15 by default. "
"Use a negative value to use the system's default precision (should be 6 typically). "
"Applicable for OBJ and DAE output. For DAE output, value >= 15 means that up to 16 decimals are used, "
" and any other value means that 6 or 7 decimals are used.");
boost::program_options::options_description cmdline_options;
cmdline_options.add(generic_options).add(fileio_options).add(geom_options).add(serializer_options);
@@ -236,7 +242,11 @@ int main(int argc, char** argv) {
std::cerr << "[Error] Unknown option '" << e.get_option_name() << "'" << std::endl << std::endl;
print_usage();
return 1;
} catch (...) {
} catch (const std::exception& e) {
std::cerr << "[Error] " << e.what() << "\n\n";
print_usage();
return 1;
} catch (...) {
// Catch other errors such as invalid command line syntax
print_usage();
return 1;
@@ -282,7 +292,6 @@ int main(int argc, char** argv) {
bool center_model = vmap.count("center-model") != 0 ;
const bool generate_uvs = vmap.count("generate-uvs") != 0 ;
const bool traverse = vmap.count("traverse") != 0;
const bool deflection_tolerance_specified = vmap.count("deflection-tolerance") != 0 ;
int bounding_width = -1, bounding_height = -1;
if (vmap.count("bounds") == 1) {
@@ -380,13 +389,13 @@ int main(int argc, char** argv) {
settings.set(IfcGeom::IteratorSettings::NO_NORMALS, no_normals);
settings.set(IfcGeom::IteratorSettings::GENERATE_UVS, generate_uvs);
settings.set(IfcGeom::IteratorSettings::TRAVERSE, traverse);
settings.set_deflection_tolerance(deflection_tolerance);
settings.set(SerializerSettings::USE_ELEMENT_NAMES, use_element_names);
settings.set(SerializerSettings::USE_ELEMENT_GUIDS, use_element_guids);
settings.set(SerializerSettings::USE_MATERIAL_NAMES, use_material_names);
settings.set(SerializerSettings::CENTER_MODEL, center_model);
if (deflection_tolerance_specified) {
settings.set_deflection_tolerance(deflection_tolerance);
}
settings.precision = precision;
GeometrySerializer* serializer;
if (output_extension == ".obj") {
+2 -3
View File
@@ -51,6 +51,7 @@ void WaveFrontOBJSerializer::writeMaterial(const IfcGeom::Material& style)
? style.original_name() : style.name());
IfcUtil::sanitate_material_name(material_name);
mtl_stream << "newmtl " << material_name << "\n";
if (style.hasDiffuse()) {
const double* diffuse = style.diffuse();
mtl_stream << "Kd " << diffuse[0] << " " << diffuse[1] << " " << diffuse[2] << "\n";
@@ -77,11 +78,9 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement<real_t>*
? o->name() : o->unique_id()));
obj_stream << "g " << name << "\n";
obj_stream << "s 1" << "\n";
obj_stream << std::setprecision(std::numeric_limits<double>::digits10);
const IfcGeom::Representation::Triangulation<real_t>& mesh = o->geometry();
const int vcount = (int)mesh.verts().size() / 3;
for ( std::vector<real_t>::const_iterator it = mesh.verts().begin(); it != mesh.verts().end(); ) {
const real_t x = *(it++) + (real_t)settings().offset[0];
+6 -2
View File
@@ -39,9 +39,13 @@ public:
: GeometrySerializer(settings)
, mtl_filename(mtl_filename)
, obj_stream(obj_filename.c_str())
, mtl_stream(mtl_filename.c_str())
, mtl_stream(mtl_filename.c_str())
, vcount_total(1)
{}
{
obj_stream << std::setprecision(settings.precision);
mtl_stream << std::setprecision(settings.precision);
}
virtual ~WaveFrontOBJSerializer() {}
bool ready();
void writeHeader();