diff --git a/code/IFCLoader.cpp b/code/IFCLoader.cpp index 82fbd75bd..1b60d4162 100644 --- a/code/IFCLoader.cpp +++ b/code/IFCLoader.cpp @@ -93,6 +93,7 @@ struct ConversionData { ConversionData(const STEP::DB& db, const IFC::IfcProject& proj, aiScene* out,const IFCImporter::Settings& settings) : len_scale(1.0) + , angle_scale(1.0) , db(db) , proj(proj) , out(out) @@ -104,7 +105,8 @@ struct ConversionData std::for_each(materials.begin(),materials.end(),delete_fun()); } - float len_scale; + float len_scale, angle_scale; + bool plane_angle_in_radians; const STEP::DB& db; const IFC::IfcProject& proj; @@ -172,6 +174,7 @@ void ProcessSpatialStructures(ConversionData& conv); aiNode* ProcessSpatialStructure(aiNode* parent, const IFC::IfcProduct& el ,ConversionData& conv); void ProcessProductRepresentation(const IFC::IfcProduct& el, aiNode* nd, ConversionData& conv); void MakeTreeRelative(ConversionData& conv); +void ConvertUnit(const EXPRESS::DataType* dt,ConversionData& conv); } // anon @@ -369,25 +372,61 @@ float ConvertSIPrefix(const std::string& prefix) } // ------------------------------------------------------------------------------------------------ -void SetUnits(ConversionData& conv) +void ConvertUnit(const IFC::IfcNamedUnit& unit,ConversionData& conv) { - // see if we can determine the coordinate space used to express - for(size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i ) { - try { - const EXPRESS::ENTITY& e = conv.proj.UnitsInContext->Units[i]->To(); - const IFC::IfcSIUnit& si = conv.db.MustGetObject(e).To(); + if(const IFC::IfcSIUnit* const si = unit.ToPtr()) { - if(si.UnitType == "LENGTHUNIT" && si.Prefix) { - conv.len_scale = ConvertSIPrefix(si.Prefix); - IFCImporter::LogDebug("got units used for lengths"); + if(si->UnitType == "LENGTHUNIT") { + conv.len_scale = si->Prefix ? ConvertSIPrefix(si->Prefix) : 1.f; + IFCImporter::LogDebug("got units used for lengths"); + } + if(si->UnitType == "PLANEANGLEUNIT") { + if (si->Name != "RADIAN") { + IFCImporter::LogWarn("expected base unit for angles to be radian"); } } - catch(std::bad_cast&) { - // not SI unit, not implemented - continue; + } + else if(const IFC::IfcConversionBasedUnit* const convu = unit.ToPtr()) { + + if(convu->UnitType == "PLANEANGLEUNIT") { + try { + conv.angle_scale = convu->ConversionFactor->ValueComponent->To(); + ConvertUnit(convu->ConversionFactor->UnitComponent,conv); + IFCImporter::LogDebug("got units used for angles"); + } + catch(std::bad_cast&) { + IFCImporter::LogError("skipping unknown IfcConversionBasedUnit.ValueComponent entry - expected REAL"); + } } } +} +// ------------------------------------------------------------------------------------------------ +void ConvertUnit(const EXPRESS::DataType* dt,ConversionData& conv) +{ + try { + const EXPRESS::ENTITY& e = dt->To(); + + const IFC::IfcNamedUnit& unit = e.ResolveSelect(conv.db); + if(unit.UnitType != "LENGTHUNIT" && unit.UnitType != "PLANEANGLEUNIT") { + return; + } + + ConvertUnit(unit,conv); + } + catch(std::bad_cast&) { + // not entity, somehow + IFCImporter::LogError("skipping unknown IfcUnit entry - expected entity"); + } +} + +// ------------------------------------------------------------------------------------------------ +void SetUnits(ConversionData& conv) +{ + // see if we can determine the coordinate space used to express. + for(size_t i = 0; i < conv.proj.UnitsInContext->Units.size(); ++i ) { + ConvertUnit(conv.proj.UnitsInContext->Units[i],conv); + } } // ------------------------------------------------------------------------------------------------ @@ -502,6 +541,18 @@ void ConvertAxisPlacement(aiMatrix4x4& out, const IFC::IfcAxis2Placement2D& in, AssignMatrixAxes(out,x,y,aiVector3D(0.f,0.f,1.f)); } +// ------------------------------------------------------------------------------------------------ +void ConvertAxisPlacement(aiVector3D& axis, aiVector3D& pos, const IFC::IfcAxis1Placement& in, ConversionData& conv) +{ + ConvertCartesianPoint(pos,in.Location); + if (in.Axis) { + ConvertDirection(axis,in.Axis.Get()); + } + else { + axis = aiVector3D(0.f,0.f,1.f); + } +} + // ------------------------------------------------------------------------------------------------ void ConvertAxisPlacement(aiMatrix4x4& out, const IFC::IfcAxis2Placement& in, ConversionData& conv) { @@ -790,7 +841,7 @@ void ProcessOpenProfile(const IFC::IfcArbitraryOpenProfileDef& def, TempMesh& me // ------------------------------------------------------------------------------------------------ void ProcessParametrizedProfile(const IFC::IfcParameterizedProfileDef& def, TempMesh& meshout, ConversionData& conv) { - if(const IFC::IfcRectangleProfileDef* cprofile = def.ToPtr()) { + if(const IFC::IfcRectangleProfileDef* const cprofile = def.ToPtr()) { const float x = cprofile->XDim*0.5f, y = cprofile->YDim*0.5f; meshout.verts.reserve(meshout.verts.size()+4); @@ -800,6 +851,22 @@ void ProcessParametrizedProfile(const IFC::IfcParameterizedProfileDef& def, Temp meshout.verts.push_back( aiVector3D( x,-y, 0.f )); meshout.vertcnt.push_back(4); } + else if( const IFC::IfcCircleProfileDef* const circle = def.ToPtr()) { + if( const IFC::IfcCircleHollowProfileDef* const hollow = def.ToPtr()) { + // TODO + } + const size_t segments = 32; + const float delta = AI_MATH_TWO_PI_F/segments, radius = circle->Radius; + + meshout.verts.reserve(segments); + + float angle = 0.f; + for(size_t i = 0; i < segments; ++i, angle += delta) { + meshout.verts.push_back( aiVector3D( cos(angle)*radius, sin(angle)*radius, 0.f )); + } + + meshout.vertcnt.push_back(segments); + } else { IFCImporter::LogWarn("skipping unknown IfcParameterizedProfileDef entity, type is " + def.GetClassName()); return; @@ -814,24 +881,145 @@ void ProcessParametrizedProfile(const IFC::IfcParameterizedProfileDef& def, Temp } // ------------------------------------------------------------------------------------------------ -void ProcessExtrudedAreaSolid(const IFC::IfcExtrudedAreaSolid& solid, TempMesh& result, ConversionData& conv) +bool ProcessProfile(const IFC::IfcProfileDef& prof, TempMesh& meshout, ConversionData& conv) { - TempMesh meshout; - if(const IFC::IfcArbitraryClosedProfileDef* cprofile = solid.SweptArea->ToPtr()) { + if(const IFC::IfcArbitraryClosedProfileDef* const cprofile = prof.ToPtr()) { ProcessClosedProfile(*cprofile,meshout,conv); } - else if(const IFC::IfcArbitraryOpenProfileDef* copen = solid.SweptArea->ToPtr()) { + else if(const IFC::IfcArbitraryOpenProfileDef* const copen = prof.ToPtr()) { ProcessOpenProfile(*copen,meshout,conv); } - else if(const IFC::IfcParameterizedProfileDef* cparam = solid.SweptArea->ToPtr()) { + else if(const IFC::IfcParameterizedProfileDef* const cparam = prof.ToPtr()) { ProcessParametrizedProfile(*cparam,meshout,conv); } else { - IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + solid.SweptArea->GetClassName()); + IFCImporter::LogWarn("skipping unknown IfcProfileDef entity, type is " + prof.GetClassName()); + return false; + } + return true; +} + +// ------------------------------------------------------------------------------------------------ +void FixupFaceOrientation(TempMesh& result) +{ + aiVector3D vavg; + BOOST_FOREACH(aiVector3D& v, result.verts) { + vavg += v; + } + + // fixup face orientation. + vavg /= static_cast( result.verts.size() ); + + size_t c = 0; + BOOST_FOREACH(unsigned int cnt, result.vertcnt) { + if (cnt>2){ + const aiVector3D& thisvert = result.verts[c]; + const aiVector3D normal((thisvert-result.verts[c+1])^(thisvert-result.verts[c+2])); + if (normal*(thisvert-vavg) < 0) { + std::reverse(result.verts.begin()+c,result.verts.begin()+cnt+c); + } + } + c += cnt; + } +} + +// ------------------------------------------------------------------------------------------------ +void ProcessRevolvedAreaSolid(const IFC::IfcRevolvedAreaSolid& solid, TempMesh& result, ConversionData& conv) +{ + TempMesh meshout; + + // first read the profile description + if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) { return; } - if(meshout.verts.size()<=1) { + aiVector3D axis, pos; + ConvertAxisPlacement(axis,pos,solid.Axis,conv); + + aiMatrix4x4 tb0,tb1; + aiMatrix4x4::Translation(pos,tb0); + aiMatrix4x4::Translation(-pos,tb1); + + const std::vector& in = meshout.verts; + const size_t size=in.size(); + + bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2; + const float max_angle = solid.Angle*conv.angle_scale; + if(fabs(max_angle) < 1e-3) { + if(has_area) { + result = meshout; + } + return; + } + + const unsigned int cnt_segments = std::max(2u,static_cast(16 * fabs(max_angle)/AI_MATH_HALF_PI_F)); + const float delta = max_angle/cnt_segments; + + has_area = has_area && fabs(max_angle) < AI_MATH_TWO_PI_F*0.99; + + result.verts.reserve(size*((cnt_segments+1)*4+(has_area?2:0))); + result.vertcnt.reserve(size*cnt_segments+2); + + aiMatrix4x4 rot; + rot = tb0 * aiMatrix4x4::Rotation(delta,axis,rot) * tb1; + + size_t base = 0; + std::vector& out = result.verts; + + // dummy data to simplify later processing + for(size_t i = 0; i < size; ++i) { + out.insert(out.end(),4,in[i]); + } + + for(unsigned int seg = 0; seg < cnt_segments; ++seg) { + for(size_t i = 0; i < size; ++i) { + const size_t next = (i+1)%size; + + result.vertcnt.push_back(4); + const aiVector3D& base_0 = out[base+i*4+3],base_1 = out[base+next*4+3]; + + out.push_back(base_0); + out.push_back(base_1); + out.push_back(rot*base_1); + out.push_back(rot*base_0); + } + base += size*4; + } + + out.erase(out.begin(),out.begin()+size*4); + + if(has_area) { + // leave the triangulation of the profile area to the ear cutting + // implementation in aiProcess_Triangulate - for now we just + // feed in two huge polygons. + base -= size*8; + for(size_t i = size; i--; ) { + out.push_back(out[base+i*4+3]); + } + for(size_t i = 0; i < size; ++i ) { + out.push_back(out[i*4]); + } + result.vertcnt.push_back(size); + result.vertcnt.push_back(size); + } + + aiMatrix4x4 trafo; + ConvertAxisPlacement(trafo, solid.Position,conv); + BOOST_FOREACH(aiVector3D& v, out) { + v *= trafo; + } + + FixupFaceOrientation(result); + IFCImporter::LogDebug("generate mesh procedurally by radial extrusion (IfcRevolvedAreaSolid)"); +} + +// ------------------------------------------------------------------------------------------------ +void ProcessExtrudedAreaSolid(const IFC::IfcExtrudedAreaSolid& solid, TempMesh& result, ConversionData& conv) +{ + TempMesh meshout; + + // first read the profile description + if(!ProcessProfile(*solid.SweptArea,meshout,conv) || meshout.verts.size()<=1) { return; } @@ -848,6 +1036,12 @@ void ProcessExtrudedAreaSolid(const IFC::IfcExtrudedAreaSolid& solid, TempMesh& const size_t size=in.size(); const bool has_area = solid.SweptArea->ProfileType == "AREA" && size>2; + if(solid.Depth < 1e-3) { + if(has_area) { + meshout = result; + } + return; + } result.verts.reserve(size*(has_area?4:2)); result.vertcnt.reserve(meshout.vertcnt.size()+2); @@ -866,7 +1060,7 @@ void ProcessExtrudedAreaSolid(const IFC::IfcExtrudedAreaSolid& solid, TempMesh& if(has_area) { // leave the triangulation of the profile area to the ear cutting // implementation in aiProcess_Triangulate - for now we just - // feed in a possibly huge polygon. + // feed in two huge polygons. for(size_t i = size; i--; ) { result.verts.push_back(in[i]+dir); } @@ -880,36 +1074,23 @@ void ProcessExtrudedAreaSolid(const IFC::IfcExtrudedAreaSolid& solid, TempMesh& aiMatrix4x4 trafo; ConvertAxisPlacement(trafo, solid.Position,conv); - aiVector3D vavg; BOOST_FOREACH(aiVector3D& v, result.verts) { v *= trafo; - vavg += v; - } - - // fixup face orientation. - vavg /= static_cast( result.verts.size() ); - - size_t c = 0; - BOOST_FOREACH(unsigned int cnt, result.vertcnt) { - if (cnt>2){ - const aiVector3D& thisvert = result.verts[c]; - const aiVector3D normal((thisvert-result.verts[c+1])^(thisvert-result.verts[c+2])); - if (normal*(thisvert-vavg) < 0) { - std::reverse(result.verts.begin()+c,result.verts.begin()+cnt+c); - } - } - c += cnt; } + FixupFaceOrientation(result); IFCImporter::LogDebug("generate mesh procedurally by extrusion (IfcExtrudedAreaSolid)"); } // ------------------------------------------------------------------------------------------------ void ProcessSweptAreaSolid(const IFC::IfcSweptAreaSolid& swept, TempMesh& meshout, ConversionData& conv) { - if(const IFC::IfcExtrudedAreaSolid* solid = swept.ToPtr()) { + if(const IFC::IfcExtrudedAreaSolid* const solid = swept.ToPtr()) { ProcessExtrudedAreaSolid(*solid,meshout,conv); } + else if(const IFC::IfcRevolvedAreaSolid* const rev = swept.ToPtr()) { + ProcessRevolvedAreaSolid(*rev,meshout,conv); + } else { IFCImporter::LogWarn("skipping unknown IfcSweptAreaSolid entity, type is " + swept.GetClassName()); } @@ -923,7 +1104,7 @@ void ProcessBoolean(const IFC::IfcBooleanResult& boolean, TempMesh& meshout, Con ProcessBoolean(*op0,meshout,conv); } else if (const IFC::IfcSweptAreaSolid* const swept = clip->FirstOperand->ResolveSelectPtr(conv.db)) { - //ProcessSweptAreaSolid(*swept,meshout,conv); + ProcessSweptAreaSolid(*swept,meshout,conv); // XXX } } @@ -1081,7 +1262,6 @@ bool ProcessGeometricItem(const IFC::IfcGeometricRepresentationItem& geo, std::v } catch(std::bad_cast&) { IFCImporter::LogWarn("unexpected type error, IfcShell ought to inherit from IfcConnectedFaceSet"); - continue; } } } @@ -1091,6 +1271,11 @@ bool ProcessGeometricItem(const IFC::IfcGeometricRepresentationItem& geo, std::v else if(const IFC::IfcManifoldSolidBrep* brep = geo.ToPtr()) { ProcessConnectedFaceSet(brep->Outer,meshtmp,conv); } + else if(const IFC::IfcFaceBasedSurfaceModel* surf = geo.ToPtr()) { + BOOST_FOREACH(const IFC::IfcConnectedFaceSet& fc, surf->FbsmFaces) { + ProcessConnectedFaceSet(fc,meshtmp,conv); + } + } else if(const IFC::IfcBooleanResult* boolean = geo.ToPtr()) { ProcessBoolean(*boolean,meshtmp,conv); } @@ -1214,7 +1399,7 @@ void ProcessMappedItem(const IFC::IfcMappedItem& mapped, aiNode* nd_src, std::ve const IFC::IfcRepresentation& repr = mapped.MappingSource->MappedRepresentation; BOOST_FOREACH(const IFC::IfcRepresentationItem& item, repr.Items) { if(!ProcessRepresentationItem(item,meshes,conv)) { - IFCImporter::LogWarn("skipping unknown IfcMappedItem entity, type is " + item.GetClassName()); + IFCImporter::LogWarn("skipping unknown mapped entity, type is " + item.GetClassName()); } } AssignAddedMeshes(meshes,nd.get(),conv); diff --git a/code/IFCReaderGen.cpp b/code/IFCReaderGen.cpp index 3123125d4..86927ad04 100644 --- a/code/IFCReaderGen.cpp +++ b/code/IFCReaderGen.cpp @@ -501,7 +501,7 @@ namespace { , SchemaEntry("ifcfaceouterbound",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcfeatureelementaddition",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcnamedunit",&STEP::ObjectHelper::Construct ) -, SchemaEntry("ifcconversionbasedunit",&STEP::ObjectHelper::Construct ) +, SchemaEntry("ifcconversionbasedunit",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcstructuralloadsingleforce",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcheatexchangertype",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcpresentationstyleassignment",&STEP::ObjectHelper::Construct ) @@ -637,7 +637,7 @@ namespace { , SchemaEntry("ifcdampertype",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcsiunit",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcsurfacestylelighting",&STEP::ObjectHelper::Construct ) -, SchemaEntry("ifcmeasurewithunit",&STEP::ObjectHelper::Construct ) +, SchemaEntry("ifcmeasurewithunit",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcmateriallayerset",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcdistributionelement",&STEP::ObjectHelper::Construct ) , SchemaEntry("ifcdistributioncontrolelement",&STEP::ObjectHelper::Construct ) @@ -1740,6 +1740,22 @@ template <> size_t GenericFill(const DB& db, const LIST& params, I return base; } // ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill(const DB& db, const LIST& params, IfcConversionBasedUnit* in) +{ + size_t base = GenericFill(db,params,static_cast(in)); + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcConversionBasedUnit"); } do { // convert the 'Name' argument + const DataType* arg = params[base++]; + try { GenericConvert( in->Name, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcConversionBasedUnit to be a `IfcLabel`")); } + } while(0); + do { // convert the 'ConversionFactor' argument + const DataType* arg = params[base++]; + try { GenericConvert( in->ConversionFactor, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcConversionBasedUnit to be a `IfcMeasureWithUnit`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- template <> size_t GenericFill(const DB& db, const LIST& params, IfcHeatExchangerType* in) { size_t base = GenericFill(db,params,static_cast(in)); @@ -1998,7 +2014,12 @@ template <> size_t GenericFill(const DB& db, const LIST& params template <> size_t GenericFill(const DB& db, const LIST& params, IfcAxis1Placement* in) { size_t base = GenericFill(db,params,static_cast(in)); -// this data structure is not used yet, so there is no code generated to fill its members + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcAxis1Placement"); } do { // convert the 'Axis' argument + const DataType* arg = params[base++]; + if (dynamic_cast(&*arg)) break; + try { GenericConvert( in->Axis, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcAxis1Placement to be a `IfcDirection`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- @@ -2420,7 +2441,12 @@ template <> size_t GenericFill(const DB& db, const LIST template <> size_t GenericFill(const DB& db, const LIST& params, IfcCircleProfileDef* in) { size_t base = GenericFill(db,params,static_cast(in)); -// this data structure is not used yet, so there is no code generated to fill its members + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcCircleProfileDef"); } do { // convert the 'Radius' argument + const DataType* arg = params[base++]; + if (dynamic_cast(&*arg)) { in->ObjectHelper::aux_is_derived[0]=true; break; } + try { GenericConvert( in->Radius, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcCircleProfileDef to be a `IfcPositiveLengthMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- @@ -2516,6 +2542,22 @@ template <> size_t GenericFill(const DB& db, const LIST& params, IfcS return base; } // ----------------------------------------------------------------------------------------------------------- +template <> size_t GenericFill(const DB& db, const LIST& params, IfcMeasureWithUnit* in) +{ + size_t base = 0; + if (params.GetSize() < 2) { throw STEP::TypeError("expected 2 arguments to IfcMeasureWithUnit"); } do { // convert the 'ValueComponent' argument + const DataType* arg = params[base++]; + try { GenericConvert( in->ValueComponent, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 0 to IfcMeasureWithUnit to be a `IfcValue`")); } + } while(0); + do { // convert the 'UnitComponent' argument + const DataType* arg = params[base++]; + try { GenericConvert( in->UnitComponent, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 1 to IfcMeasureWithUnit to be a `IfcUnit`")); } + } while(0); + return base; +} +// ----------------------------------------------------------------------------------------------------------- template <> size_t GenericFill(const DB& db, const LIST& params, IfcDistributionElement* in) { size_t base = GenericFill(db,params,static_cast(in)); @@ -3000,7 +3042,11 @@ template <> size_t GenericFill(const DB& db, const LIS template <> size_t GenericFill(const DB& db, const LIST& params, IfcCircleHollowProfileDef* in) { size_t base = GenericFill(db,params,static_cast(in)); -// this data structure is not used yet, so there is no code generated to fill its members + if (params.GetSize() < 5) { throw STEP::TypeError("expected 5 arguments to IfcCircleHollowProfileDef"); } do { // convert the 'WallThickness' argument + const DataType* arg = params[base++]; + try { GenericConvert( in->WallThickness, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 4 to IfcCircleHollowProfileDef to be a `IfcPositiveLengthMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- @@ -4195,7 +4241,16 @@ template <> size_t GenericFill(const DB& db, const LIST& p template <> size_t GenericFill(const DB& db, const LIST& params, IfcRevolvedAreaSolid* in) { size_t base = GenericFill(db,params,static_cast(in)); -// this data structure is not used yet, so there is no code generated to fill its members + if (params.GetSize() < 4) { throw STEP::TypeError("expected 4 arguments to IfcRevolvedAreaSolid"); } do { // convert the 'Axis' argument + const DataType* arg = params[base++]; + try { GenericConvert( in->Axis, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 2 to IfcRevolvedAreaSolid to be a `IfcAxis1Placement`")); } + } while(0); + do { // convert the 'Angle' argument + const DataType* arg = params[base++]; + try { GenericConvert( in->Angle, *arg, db ); break; } + catch (const TypeError& t) { throw TypeError(t.what() + std::string(" - expected argument 3 to IfcRevolvedAreaSolid to be a `IfcPlaneAngleMeasure`")); } + } while(0); return base; } // ----------------------------------------------------------------------------------------------------------- diff --git a/code/IFCReaderGen.h b/code/IFCReaderGen.h index 414d14273..7bbd2b96f 100644 --- a/code/IFCReaderGen.h +++ b/code/IFCReaderGen.h @@ -841,7 +841,7 @@ namespace IFC { struct IfcFaceOuterBound; struct IfcFeatureElementAddition; struct IfcNamedUnit; - typedef NotImplemented IfcConversionBasedUnit; // (not currently used by Assimp) + struct IfcConversionBasedUnit; typedef NotImplemented IfcStructuralLoadSingleForce; // (not currently used by Assimp) struct IfcHeatExchangerType; struct IfcPresentationStyleAssignment; @@ -977,7 +977,7 @@ namespace IFC { struct IfcDamperType; struct IfcSIUnit; typedef NotImplemented IfcSurfaceStyleLighting; // (not currently used by Assimp) - typedef NotImplemented IfcMeasureWithUnit; // (not currently used by Assimp) + struct IfcMeasureWithUnit; typedef NotImplemented IfcMaterialLayerSet; // (not currently used by Assimp) struct IfcDistributionElement; struct IfcDistributionControlElement; @@ -1813,6 +1813,12 @@ namespace IFC { IfcUnitEnum::Out UnitType; }; + // C++ wrapper for IfcConversionBasedUnit + struct IfcConversionBasedUnit : IfcNamedUnit, ObjectHelper { IfcConversionBasedUnit() : Object("IfcConversionBasedUnit") {} + IfcLabel::Out Name; + Lazy< IfcMeasureWithUnit > ConversionFactor; + }; + // C++ wrapper for IfcHeatExchangerType struct IfcHeatExchangerType : IfcEnergyConversionDeviceType, ObjectHelper { IfcHeatExchangerType() : Object("IfcHeatExchangerType") {} IfcHeatExchangerTypeEnum::Out PredefinedType; @@ -2246,7 +2252,7 @@ namespace IFC { Maybe< IfcIdentifier::Out > ResourceIdentifier; Maybe< IfcLabel::Out > ResourceGroup; Maybe< IfcResourceConsumptionEnum::Out > ResourceConsumption; - Maybe< Lazy< NotImplemented > > BaseQuantity; + Maybe< Lazy< IfcMeasureWithUnit > > BaseQuantity; }; // C++ wrapper for IfcConstructionEquipmentResource @@ -2310,6 +2316,12 @@ namespace IFC { IfcSIUnitName::Out Name; }; + // C++ wrapper for IfcMeasureWithUnit + struct IfcMeasureWithUnit : ObjectHelper { IfcMeasureWithUnit() : Object("IfcMeasureWithUnit") {} + IfcValue::Out ValueComponent; + IfcUnit::Out UnitComponent; + }; + // C++ wrapper for IfcDistributionElement struct IfcDistributionElement : IfcElement, ObjectHelper { IfcDistributionElement() : Object("IfcDistributionElement") {} @@ -3866,6 +3878,7 @@ namespace STEP { DECL_CONV_STUB(IfcFaceOuterBound); DECL_CONV_STUB(IfcFeatureElementAddition); DECL_CONV_STUB(IfcNamedUnit); + DECL_CONV_STUB(IfcConversionBasedUnit); DECL_CONV_STUB(IfcHeatExchangerType); DECL_CONV_STUB(IfcPresentationStyleAssignment); DECL_CONV_STUB(IfcFlowTreatmentDeviceType); @@ -3957,6 +3970,7 @@ namespace STEP { DECL_CONV_STUB(IfcLinearDimension); DECL_CONV_STUB(IfcDamperType); DECL_CONV_STUB(IfcSIUnit); + DECL_CONV_STUB(IfcMeasureWithUnit); DECL_CONV_STUB(IfcDistributionElement); DECL_CONV_STUB(IfcDistributionControlElement); DECL_CONV_STUB(IfcTransformerType); diff --git a/scripts/IFCImporter/entitylist.txt b/scripts/IFCImporter/entitylist.txt index 7a303b20d..d9aa5a602 100644 --- a/scripts/IFCImporter/entitylist.txt +++ b/scripts/IFCImporter/entitylist.txt @@ -8,6 +8,11 @@ # code generator. Also, the names of all used entities need to be present # in the source code for this to work. +IfcAxis1Placement +IfcMeasureWithUnit +IfcConversionBasedUnit +IfcRevolvedAreaSolid +IfcCircleHollowProfileDef IfcRepresentationMap IfcProductRepresentation IfcUnitAssignment