| 810 | } |
| 811 | |
| 812 | void mapping::initialize_units_() { |
| 813 | // Set default units, set length to meters, angles to undefined |
| 814 | length_unit_ = 1.; |
| 815 | angle_unit_ = -1.; |
| 816 | length_unit_name_ = "METER"; |
| 817 | |
| 818 | #ifdef SCHEMA_HAS_IfcContext |
| 819 | auto projects = file_->instances_by_type<IfcSchema::IfcContext>(); |
| 820 | #else |
| 821 | auto projects = file_->instances_by_type<IfcSchema::IfcProject>(); |
| 822 | #endif |
| 823 | IfcSchema::IfcUnitAssignment* unit_assignment = nullptr; |
| 824 | if (projects->size() == 1) { |
| 825 | auto* project = *projects->begin(); |
| 826 | unit_assignment = project->UnitsInContext(); |
| 827 | } else { |
| 828 | Logger::Warning("Not a single project or context in file"); |
| 829 | } |
| 830 | if (unit_assignment == nullptr) { |
| 831 | Logger::Warning("Unable to detect unit information"); |
| 832 | return; |
| 833 | } |
| 834 | |
| 835 | bool length_unit_encountered = false, angle_unit_encountered = false; |
| 836 | |
| 837 | try { |
| 838 | auto units = unit_assignment->Units(); |
| 839 | if (!units || !units->size()) { |
| 840 | Logger::Warning("No unit information found"); |
| 841 | } else { |
| 842 | for (auto it = units->begin(); it != units->end(); ++it) { |
| 843 | IfcSchema::IfcUnit* base = *it; |
| 844 | if (base->declaration().is(IfcSchema::IfcNamedUnit::Class())) { |
| 845 | IfcSchema::IfcNamedUnit* named_unit = base->as<IfcSchema::IfcNamedUnit>(); |
| 846 | if (named_unit->UnitType() == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT || |
| 847 | named_unit->UnitType() == IfcSchema::IfcUnitEnum::IfcUnit_PLANEANGLEUNIT) { |
| 848 | std::string current_unit_name; |
| 849 | const double current_unit_magnitude = IfcParse::get_SI_equivalent<IfcSchema>(named_unit); |
| 850 | if (current_unit_magnitude != 0.) { |
| 851 | if (named_unit->declaration().is(IfcSchema::IfcConversionBasedUnit::Class())) { |
| 852 | IfcSchema::IfcConversionBasedUnit* u = (IfcSchema::IfcConversionBasedUnit*)base; |
| 853 | current_unit_name = u->Name(); |
| 854 | } else if (named_unit->declaration().is(IfcSchema::IfcSIUnit::Class())) { |
| 855 | IfcSchema::IfcSIUnit* si_unit = named_unit->as<IfcSchema::IfcSIUnit>(); |
| 856 | if (si_unit->Prefix()) { |
| 857 | current_unit_name = IfcSchema::IfcSIPrefix::ToString(*si_unit->Prefix()); |
| 858 | } |
| 859 | current_unit_name += IfcSchema::IfcSIUnitName::ToString(si_unit->Name()); |
| 860 | } |
| 861 | if (named_unit->UnitType() == IfcSchema::IfcUnitEnum::IfcUnit_LENGTHUNIT) { |
| 862 | length_unit_name_ = current_unit_name; |
| 863 | length_unit_ = current_unit_magnitude; |
| 864 | length_unit_encountered = true; |
| 865 | } else { |
| 866 | angle_unit_ = current_unit_magnitude; |
| 867 | angle_unit_encountered = true; |
| 868 | } |
| 869 | } |