mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 07:09:22 +00:00
IfcConvert: Unit names and magnitudes + cosmetic fixes
This commit is contained in:
@@ -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) {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -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()
|
||||||
|
|||||||
@@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
Reference in New Issue
Block a user