IfcConvert: Unit names and magnitudes + cosmetic fixes

This commit is contained in:
Thomas Krijnen
2013-12-31 14:10:38 +00:00
parent 6b2dc3683a
commit 2bd37fd088
11 changed files with 106 additions and 18 deletions
+3 -4
View File
@@ -208,13 +208,12 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::write() {
closeLibrary(); closeLibrary();
} }
void ColladaSerializer::ColladaExporter::startDocument() { void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_name, float unit_magnitude) {
stream.startDocument(); stream.startDocument();
COLLADASW::Asset asset(&stream); COLLADASW::Asset asset(&stream);
asset.getContributor().mAuthoringTool = std::string("IfcOpenShell ") + IFCOPENSHELL_VERSION; asset.getContributor().mAuthoringTool = std::string("IfcOpenShell ") + IFCOPENSHELL_VERSION;
// TODO: Get the appropriate unit from the IFC file. asset.setUnit(unit_name, unit_magnitude);
asset.setUnit("meter", 1.0);
asset.setUpAxisType(COLLADASW::Asset::Z_UP); asset.setUpAxisType(COLLADASW::Asset::Z_UP);
asset.add(); asset.add();
} }
@@ -271,7 +270,7 @@ bool ColladaSerializer::ready() {
} }
void ColladaSerializer::writeHeader() { void ColladaSerializer::writeHeader() {
exporter.startDocument(); exporter.startDocument(unit_name, unit_magnitude);
} }
void ColladaSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) { void ColladaSerializer::writeTesselated(const IfcGeomObjects::IfcGeomObject* o) {
+7 -1
View File
@@ -135,11 +135,13 @@ private:
{} {}
std::vector<DeferredObject> deferreds; std::vector<DeferredObject> deferreds;
virtual ~ColladaExporter() {} virtual ~ColladaExporter() {}
void startDocument(); void startDocument(const std::string& unit_name, float unit_magnitude);
void writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector<float>& matrix, const std::vector<float>& vertices, const std::vector<float>& normals, const std::vector<int>& indices, const std::vector<int>& material_ids, const std::vector<IfcGeomObjects::Material>& materials); void writeTesselated(const std::string& guid, const std::string& name, const std::string& type, int obj_id, const std::vector<float>& matrix, const std::vector<float>& vertices, const std::vector<float>& normals, const std::vector<int>& indices, const std::vector<int>& material_ids, const std::vector<IfcGeomObjects::Material>& materials);
void endDocument(); void endDocument();
}; };
ColladaExporter exporter; ColladaExporter exporter;
std::string unit_name;
float unit_magnitude;
public: public:
ColladaSerializer(const std::string& dae_filename) ColladaSerializer(const std::string& dae_filename)
: GeometrySerializer() : GeometrySerializer()
@@ -151,6 +153,10 @@ public:
void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {} void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {}
void finalize(); void finalize();
bool isTesselated() const { return true; } bool isTesselated() const { return true; }
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
unit_name = name;
unit_magnitude = magnitude;
}
}; };
#endif #endif
+1
View File
@@ -31,6 +31,7 @@ public:
virtual ~GeometrySerializer() {} virtual ~GeometrySerializer() {}
virtual void writeTesselated(const IfcGeomObjects::IfcGeomObject* o) = 0; virtual void writeTesselated(const IfcGeomObjects::IfcGeomObject* o) = 0;
virtual void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) = 0; virtual void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) = 0;
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
}; };
#endif #endif
+30 -13
View File
@@ -69,6 +69,9 @@ std::string change_extension(const std::string& fn, const std::string& ext) {
} }
} }
static std::stringstream log_stream;
void write_log();
int main(int argc, char** argv) { int main(int argc, char** argv) {
boost::program_options::options_description generic_options; boost::program_options::options_description generic_options;
generic_options.add_options() generic_options.add_options()
@@ -180,11 +183,13 @@ int main(int argc, char** argv) {
*c = tolower(*c); *c = tolower(*c);
} }
Logger::SetOutput(&std::cout, &log_stream);
GeometrySerializer* serializer; GeometrySerializer* serializer;
if (output_extension == ".obj") { if (output_extension == ".obj") {
const std::string mtl_filename = output_filename.substr(0,output_filename.size()-3) + "mtl"; const std::string mtl_filename = output_filename.substr(0,output_filename.size()-3) + "mtl";
if (!use_world_coords) { if (!use_world_coords) {
Logger::Message(Logger::LOG_WARNING, "Use world coords settings ignored for WaveFront OBJ files"); Logger::Message(Logger::LOG_NOTICE, "Using world coords when writing WaveFront OBJ files");
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, true); IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS, true);
} }
serializer = new WaveFrontOBJSerializer(output_filename, mtl_filename); serializer = new WaveFrontOBJSerializer(output_filename, mtl_filename);
@@ -201,6 +206,7 @@ int main(int argc, char** argv) {
serializer = new IgesSerializer(output_filename); serializer = new IgesSerializer(output_filename);
} else { } else {
Logger::Message(Logger::LOG_ERROR, "Unknown output filename extension"); Logger::Message(Logger::LOG_ERROR, "Unknown output filename extension");
write_log();
printUsage(generic_options, geom_options); printUsage(generic_options, geom_options);
return 1; return 1;
} }
@@ -209,24 +215,32 @@ int main(int argc, char** argv) {
if (!serializer->ready()) { if (!serializer->ready()) {
Logger::Message(Logger::LOG_ERROR, "Unable to open output file for writing"); Logger::Message(Logger::LOG_ERROR, "Unable to open output file for writing");
write_log();
return 1; return 1;
} }
serializer->writeHeader();
if (!serializer->isTesselated()) { if (!serializer->isTesselated()) {
IfcGeomObjects::Settings(IfcGeomObjects::DISABLE_TRIANGULATION, true); IfcGeomObjects::Settings(IfcGeomObjects::DISABLE_TRIANGULATION, true);
if (weld_vertices) {
Logger::Message(Logger::LOG_NOTICE, "Weld vertices setting ignored when writing STEP or IGES files");
}
} }
// Stream for log messages, we don't want to interupt our new progress bar...
std::stringstream ss;
// Parse the file supplied in argv[1]. Returns true on succes. // Parse the file supplied in argv[1]. Returns true on succes.
if ( ! IfcGeomObjects::Init(input_filename,&std::cout,&ss) ) { if ( ! IfcGeomObjects::Init(input_filename, &std::cout, &log_stream) ) {
Logger::Message(Logger::LOG_ERROR, "Unable to parse .ifc file or no geometrical entities found"); Logger::Message(Logger::LOG_ERROR, "Unable to parse .ifc file or no geometrical entities found");
write_log();
return 1; return 1;
} }
if (convert_back_units) {
serializer->setUnitNameAndMagnitude(IfcGeomObjects::GetUnitName(), IfcGeomObjects::GetUnitMagnitude());
} else {
serializer->setUnitNameAndMagnitude("METER", 1.0f);
}
serializer->writeHeader();
std::set<std::string> materials; std::set<std::string> materials;
time_t start,end; time_t start,end;
@@ -269,14 +283,17 @@ int main(int argc, char** argv) {
Logger::Status("\rDone creating geometry "); Logger::Status("\rDone creating geometry ");
// Writes the material settings, defined in Materials.h write_log();
std::string log = ss.str();
if (!log.empty()) {
std::cerr << std::endl << "Log:" << std::endl;
std::cerr << ss.str();
}
time(&end); time(&end);
int dif = (int) difftime (end,start); int dif = (int) difftime (end,start);
printf ("\nConversion took %d seconds\n", dif ); printf ("\nConversion took %d seconds\n", dif );
}
void write_log() {
std::string log = log_stream.str();
if (!log.empty()) {
std::cerr << std::endl << "Log:" << std::endl;
std::cerr << log << std::endl;
}
} }
+7
View File
@@ -22,6 +22,7 @@
#include <IGESControl_Controller.hxx> #include <IGESControl_Controller.hxx>
#include <IGESControl_Writer.hxx> #include <IGESControl_Writer.hxx>
#include <Interface_Static.hxx>
#include "../ifcgeom/IfcGeomObjects.h" #include "../ifcgeom/IfcGeomObjects.h"
@@ -42,6 +43,12 @@ public:
void finalize() { void finalize() {
writer.Write(out_filename.c_str()); writer.Write(out_filename.c_str());
} }
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
const char* symbol = getSymbolForUnitMagnitude(magnitude);
if (symbol) {
Interface_Static::SetCVal("write.iges.unit", symbol);
}
}
}; };
#endif #endif
@@ -62,3 +62,22 @@ void OpenCascadeBasedSerializer::writeShapeModel(const IfcGeomObjects::IfcGeomSh
writeShape(moved_shape); writeShape(moved_shape);
} }
} }
#define RATHER_SMALL (1e-3)
#define ALMOST_THE_SAME(a,b) (fabs(a-b) < RATHER_SMALL)
const char* OpenCascadeBasedSerializer::getSymbolForUnitMagnitude(float mag) {
if (ALMOST_THE_SAME(mag, 0.001f)) {
return "MM";
} else if (ALMOST_THE_SAME(mag, 0.01f)) {
return "CM";
} else if (ALMOST_THE_SAME(mag, 1.0f)) {
return "M";
} else if (ALMOST_THE_SAME(mag, 0.3048f)) {
return "FT";
} else if (ALMOST_THE_SAME(mag, 0.0254f)) {
return "INCH";
} else {
return 0;
}
}
@@ -27,6 +27,7 @@
class OpenCascadeBasedSerializer : public GeometrySerializer { class OpenCascadeBasedSerializer : public GeometrySerializer {
protected: protected:
const std::string& out_filename; const std::string& out_filename;
const char* getSymbolForUnitMagnitude(float mag);
public: public:
explicit OpenCascadeBasedSerializer(const std::string& out_filename) explicit OpenCascadeBasedSerializer(const std::string& out_filename)
: GeometrySerializer() : GeometrySerializer()
+13
View File
@@ -22,6 +22,7 @@
#include <STEPControl_Controller.hxx> #include <STEPControl_Controller.hxx>
#include <STEPControl_Writer.hxx> #include <STEPControl_Writer.hxx>
#include <Interface_Static.hxx>
#include "../ifcgeom/IfcGeomObjects.h" #include "../ifcgeom/IfcGeomObjects.h"
@@ -37,10 +38,22 @@ public:
{} {}
virtual ~StepSerializer() {} virtual ~StepSerializer() {}
void writeShape(const TopoDS_Shape& shape) { void writeShape(const TopoDS_Shape& shape) {
std::stringstream ss;
std::streambuf *sb = std::cout.rdbuf(ss.rdbuf());
writer.Transfer(shape, STEPControl_AsIs); writer.Transfer(shape, STEPControl_AsIs);
std::cout.rdbuf(sb);
} }
void finalize() { void finalize() {
std::stringstream ss;
std::streambuf *sb = std::cout.rdbuf(ss.rdbuf());
writer.Write(out_filename.c_str()); writer.Write(out_filename.c_str());
std::cout.rdbuf(sb);
}
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {
const char* symbol = getSymbolForUnitMagnitude(magnitude);
if (symbol) {
Interface_Static::SetCVal("write.step.unit", symbol);
}
} }
}; };
+1
View File
@@ -49,6 +49,7 @@ public:
void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {} void writeShapeModel(const IfcGeomObjects::IfcGeomShapeModelObject* o) {}
void finalize() {} void finalize() {}
bool isTesselated() const { return true; } bool isTesselated() const { return true; }
void setUnitNameAndMagnitude(const std::string& name, float magnitude) {}
}; };
#endif #endif
+21
View File
@@ -605,6 +605,9 @@ void IfcGeomObjects::InitPrecision() {
} }
} }
static std::string unit_name = "METER";
static float unit_magnitude = 1.0f;
void IfcGeomObjects::InitUnits() { void IfcGeomObjects::InitUnits() {
// Set default units, set length to meters, angles to undefined // Set default units, set length to meters, angles to undefined
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,1.0); IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,1.0);
@@ -631,11 +634,13 @@ void IfcGeomObjects::InitUnits() {
} }
try { try {
for ( IfcUtil::IfcAbstractSelect::it it = units->begin(); it != units->end(); ++ it ) { for ( IfcUtil::IfcAbstractSelect::it it = units->begin(); it != units->end(); ++ it ) {
std::string current_unit_name = "";
const IfcUtil::IfcAbstractSelect::ptr base = *it; const IfcUtil::IfcAbstractSelect::ptr base = *it;
Ifc2x3::IfcSIUnit::ptr unit = Ifc2x3::IfcSIUnit::ptr(); Ifc2x3::IfcSIUnit::ptr unit = Ifc2x3::IfcSIUnit::ptr();
double value = 1.0f; double value = 1.0f;
if ( base->is(Ifc2x3::Type::IfcConversionBasedUnit) ) { if ( base->is(Ifc2x3::Type::IfcConversionBasedUnit) ) {
const Ifc2x3::IfcConversionBasedUnit::ptr u = reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcConversionBasedUnit>(base); const Ifc2x3::IfcConversionBasedUnit::ptr u = reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcConversionBasedUnit>(base);
current_unit_name = u->Name();
const Ifc2x3::IfcMeasureWithUnit::ptr u2 = u->ConversionFactor(); const Ifc2x3::IfcMeasureWithUnit::ptr u2 = u->ConversionFactor();
Ifc2x3::IfcUnit u3 = u2->UnitComponent(); Ifc2x3::IfcUnit u3 = u2->UnitComponent();
if ( u3->is(Ifc2x3::Type::IfcSIUnit) ) { if ( u3->is(Ifc2x3::Type::IfcSIUnit) ) {
@@ -655,6 +660,14 @@ void IfcGeomObjects::InitUnits() {
Ifc2x3::IfcUnitEnum::IfcUnitEnum type = unit->UnitType(); Ifc2x3::IfcUnitEnum::IfcUnitEnum type = unit->UnitType();
if ( type == Ifc2x3::IfcUnitEnum::IfcUnit_LENGTHUNIT ) { if ( type == Ifc2x3::IfcUnitEnum::IfcUnit_LENGTHUNIT ) {
IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,value); IfcGeom::SetValue(IfcGeom::GV_LENGTH_UNIT,value);
if (current_unit_name.empty()) {
if (unit->hasPrefix()) {
current_unit_name = Ifc2x3::IfcSIPrefix::ToString(unit->Prefix());
}
current_unit_name += Ifc2x3::IfcSIUnitName::ToString(unit->Name());
}
unit_magnitude = value;
unit_name = current_unit_name;
} else if ( type == Ifc2x3::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT ) { } else if ( type == Ifc2x3::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT ) {
IfcGeom::SetValue(IfcGeom::GV_PLANEANGLE_UNIT,value); IfcGeom::SetValue(IfcGeom::GV_PLANEANGLE_UNIT,value);
} }
@@ -740,6 +753,14 @@ int IfcGeomObjects::Progress() {
return 100 * done / total; return 100 * done / total;
} }
const std::string& IfcGeomObjects::GetUnitName() {
return unit_name;
}
const float IfcGeomObjects::GetUnitMagnitude() {
return unit_magnitude;
}
const std::string IfcGeomObjects::GetLog() { const std::string IfcGeomObjects::GetLog() {
return Logger::GetLog(); return Logger::GetLog();
} }
+3
View File
@@ -274,6 +274,9 @@ namespace IfcGeomObjects {
bool Next(); bool Next();
int Progress(); int Progress();
const std::string& GetUnitName();
const float GetUnitMagnitude();
const std::string GetLog(); const std::string GetLog();
IfcParse::IfcFile* GetFile(); IfcParse::IfcFile* GetFile();